diff --git a/code/frameworks/angular/template/components/button.component.ts b/code/frameworks/angular/template/components/button.component.ts new file mode 100644 index 00000000000..3d0efd6af2f --- /dev/null +++ b/code/frameworks/angular/template/components/button.component.ts @@ -0,0 +1,53 @@ +import { Component, Input, Output, EventEmitter } from '@angular/core'; + +@Component({ + selector: 'storybook-button', + template: ` `, + styleUrls: ['./button.css'], +}) +export default class ButtonComponent { + /** + * Is this the principal call to action on the page? + */ + @Input() + primary = false; + + /** + * What background color to use + */ + @Input() + backgroundColor?: string; + + /** + * How large should the button be? + */ + @Input() + size: 'small' | 'medium' | 'large' = 'medium'; + + /** + * Button contents + * + * @required + */ + @Input() + label = 'Button'; + + /** + * Optional click handler + */ + @Output() + onClick = new EventEmitter(); + + public get classes(): string[] { + const mode = this.primary ? 'storybook-button--primary' : 'storybook-button--secondary'; + + return ['storybook-button', `storybook-button--${this.size}`, mode]; + } +} diff --git a/code/frameworks/angular/template/components/button.css b/code/frameworks/angular/template/components/button.css new file mode 100644 index 00000000000..dc91dc76370 --- /dev/null +++ b/code/frameworks/angular/template/components/button.css @@ -0,0 +1,30 @@ +.storybook-button { + font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-weight: 700; + border: 0; + border-radius: 3em; + cursor: pointer; + display: inline-block; + line-height: 1; +} +.storybook-button--primary { + color: white; + background-color: #1ea7fd; +} +.storybook-button--secondary { + color: #333; + background-color: transparent; + box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset; +} +.storybook-button--small { + font-size: 12px; + padding: 10px 16px; +} +.storybook-button--medium { + font-size: 14px; + padding: 11px 20px; +} +.storybook-button--large { + font-size: 16px; + padding: 12px 24px; +} diff --git a/code/frameworks/angular/template/components/index.js b/code/frameworks/angular/template/components/index.js new file mode 100644 index 00000000000..5ae9ef153d8 --- /dev/null +++ b/code/frameworks/angular/template/components/index.js @@ -0,0 +1,5 @@ +import globalThis from 'global'; + +import Button from './button.component'; + +globalThis.Components = { Button }; diff --git a/code/frameworks/angular/template/stories/child.component.ts b/code/frameworks/angular/template/stories/child.component.ts new file mode 100644 index 00000000000..4666ec952ad --- /dev/null +++ b/code/frameworks/angular/template/stories/child.component.ts @@ -0,0 +1,20 @@ +import { Component, Input, Output, EventEmitter } from '@angular/core'; + +@Component({ + selector: 'child-component', + template: ` + Child
+ Input text: {{ childText }}
+ Output :
+ Private text: {{ childPrivateText }}
+ `, +}) +export default class ChildComponent { + @Input() + childText = ''; + + childPrivateText = ''; + + @Output() + onClickChild = new EventEmitter(); +} diff --git a/code/frameworks/angular/template/stories/decorators.stories.ts b/code/frameworks/angular/template/stories/decorators.stories.ts new file mode 100644 index 00000000000..1f4b61b9bec --- /dev/null +++ b/code/frameworks/angular/template/stories/decorators.stories.ts @@ -0,0 +1,117 @@ +// your-component.stories.ts + +import { componentWrapperDecorator, Meta, moduleMetadata } from '@storybook/angular'; +import ChildComponent from './child.component'; +import ParentComponent from './parent.component'; + +export default { + title: 'Core / Decorators / ComponentWrapperDecorator', + component: ChildComponent, + decorators: [ + componentWrapperDecorator( + (story) => `Grandparent
${story}
` + ), + ], + args: { childText: 'Child text', childPrivateText: 'Child private text' }, + argTypes: { onClickChild: { action: 'onClickChild' } }, +} as Meta; + +export const WithTemplate = (args) => ({ + template: `Child Template`, + props: { + ...args, + }, +}); + +export const WithComponent = (args) => ({ + props: { + ...args, + }, +}); + +export const WithLegacyComponent = (args) => ({ + component: ChildComponent, + props: { + ...args, + }, +}); + +export const WithComponentWrapperDecorator = (args) => ({ + component: ChildComponent, + props: { + ...args, + }, +}); +WithComponentWrapperDecorator.decorators = [ + moduleMetadata({ declarations: [ParentComponent] }), + componentWrapperDecorator(ParentComponent), +]; + +export const WithComponentWrapperDecoratorAndProps = (args) => ({ + component: ChildComponent, + props: { + ...args, + }, +}); +WithComponentWrapperDecoratorAndProps.decorators = [ + moduleMetadata({ declarations: [ParentComponent] }), + componentWrapperDecorator(ParentComponent, { + parentText: 'Parent text', + onClickParent: () => { + console.log('onClickParent'); + }, + }), +]; + +export const WithComponentWrapperDecoratorAndArgs = (args) => ({ + component: ChildComponent, + props: { + ...args, + }, +}); +WithComponentWrapperDecoratorAndArgs.argTypes = { + parentText: { control: { type: 'text' } }, + onClickParent: { action: 'onClickParent' }, +}; +WithComponentWrapperDecoratorAndArgs.decorators = [ + moduleMetadata({ declarations: [ParentComponent] }), + componentWrapperDecorator(ParentComponent, ({ args }) => ({ + parentText: args.parentText, + onClickParent: args.onClickParent, + })), +]; + +export const WithCustomDecorator = (args) => ({ + template: `Child Template`, + props: { + ...args, + }, +}); +WithCustomDecorator.decorators = [ + (storyFunc) => { + const story = storyFunc(); + + return { + ...story, + template: `Custom Decorator
${story.template}
`, + }; + }, +]; + +export const AngularLegacyRendering = (args) => ({ + template: `Child Template`, + props: { + ...args, + }, +}); +AngularLegacyRendering.parameters = { angularLegacyRendering: true }; +AngularLegacyRendering.decorators = [ + (storyFunc) => { + const story = storyFunc(); + + return { + ...story, + template: `Custom Decorator
${story.template}
`, + }; + }, +]; diff --git a/code/frameworks/angular/template/stories/parent.component.ts b/code/frameworks/angular/template/stories/parent.component.ts new file mode 100644 index 00000000000..f49ce1bb187 --- /dev/null +++ b/code/frameworks/angular/template/stories/parent.component.ts @@ -0,0 +1,18 @@ +import { Component, Input, Output, EventEmitter } from '@angular/core'; + +@Component({ + selector: 'parent-component', + template: ` + Parent
+ Input text: {{ parentText }}
+ Output :
+
+ `, +}) +export default class ParentComponent { + @Input() + parentText = ''; + + @Output() + onClickParent = new EventEmitter(); +}