Add Signal based stories for supported Angular sandboxes

This commit is contained in:
Valentin Palkovic 2024-03-17 14:27:07 +01:00
parent 1b9b54d7d2
commit 22a40ae041
6 changed files with 256 additions and 0 deletions

View File

@ -0,0 +1,51 @@
import { Component, Input, Output, EventEmitter, input } from '@angular/core';
@Component({
// Needs to be a different name to the CLI template button
selector: 'storybook-signal-button',
template: ` <button
type="button"
(click)="onClick.emit($event)"
[ngClass]="classes"
[ngStyle]="{ 'background-color': backgroundColor }"
>
{{ label() }}
</button>`,
styleUrls: ['./button.css'],
})
export default class SignalButtonComponent {
/**
* Is this the principal call to action on the page?
*/
primary = input(false);
/**
* What background color to use
*/
@Input()
backgroundColor?: string;
/**
* How large should the button be?
*/
size = input('medium', {
transform: (val: 'small' | 'medium') => val,
});
/**
* Button contents
*/
label = input.required({ transform: (val: string) => val.trim() });
/**
* Optional click handler
*/
@Output()
onClick = new EventEmitter<Event>();
public get classes(): string[] {
const mode = this.primary() ? 'storybook-button--primary' : 'storybook-button--secondary';
return ['storybook-button', `storybook-button--${this.size()}`, mode];
}
}

View File

@ -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;
}

View File

@ -0,0 +1,47 @@
import { Meta, StoryObj } from '@storybook/angular';
import { fn } from '@storybook/test';
import SignalButtonComponent from './button.component';
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
const meta: Meta<SignalButtonComponent> = {
component: SignalButtonComponent,
tags: ['autodocs'],
argTypes: {
backgroundColor: {
control: 'color',
},
},
// Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args
args: { onClick: fn() },
};
export default meta;
type Story = StoryObj<SignalButtonComponent>;
// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
export const Primary: Story = {
args: {
primary: true,
label: 'Button',
},
};
export const Secondary: Story = {
args: {
label: 'Button',
},
};
export const Medium: Story = {
args: {
size: 'medium',
label: 'Button',
},
};
export const Small: Story = {
args: {
size: 'small',
label: 'Button',
},
};

View File

@ -0,0 +1,51 @@
import { Component, Input, Output, EventEmitter, input } from '@angular/core';
@Component({
// Needs to be a different name to the CLI template button
selector: 'storybook-signal-button',
template: ` <button
type="button"
(click)="onClick.emit($event)"
[ngClass]="classes"
[ngStyle]="{ 'background-color': backgroundColor }"
>
{{ label() }}
</button>`,
styleUrls: ['./button.css'],
})
export default class SignalButtonComponent {
/**
* Is this the principal call to action on the page?
*/
primary = input(false);
/**
* What background color to use
*/
@Input()
backgroundColor?: string;
/**
* How large should the button be?
*/
size = input('medium', {
transform: (val: 'small' | 'medium') => val,
});
/**
* Button contents
*/
label = input.required({ transform: (val: string) => val.trim() });
/**
* Optional click handler
*/
@Output()
onClick = new EventEmitter<Event>();
public get classes(): string[] {
const mode = this.primary() ? 'storybook-button--primary' : 'storybook-button--secondary';
return ['storybook-button', `storybook-button--${this.size()}`, mode];
}
}

View File

@ -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;
}

View File

@ -0,0 +1,47 @@
import { Meta, StoryObj } from '@storybook/angular';
import { fn } from '@storybook/test';
import SignalButtonComponent from './button.component';
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
const meta: Meta<SignalButtonComponent> = {
component: SignalButtonComponent,
tags: ['autodocs'],
argTypes: {
backgroundColor: {
control: 'color',
},
},
// Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args
args: { onClick: fn() },
};
export default meta;
type Story = StoryObj<SignalButtonComponent>;
// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
export const Primary: Story = {
args: {
primary: true,
label: 'Button',
},
};
export const Secondary: Story = {
args: {
label: 'Button',
},
};
export const Medium: Story = {
args: {
size: 'medium',
label: 'Button',
},
};
export const Small: Story = {
args: {
size: 'small',
label: 'Button',
},
};