ressurect storybook buttons

This commit is contained in:
Tykayn 2025-08-19 14:27:59 +02:00 committed by tykayn
parent 458ad64931
commit 681d8ecb0b
14 changed files with 108 additions and 361 deletions

View file

@ -12,7 +12,6 @@ const config: StorybookConfig = {
// '@storybook/addon-controls' - no longer exists in Storybook 9.0+
// ... autres addons
],
staticDirs: ['../../my-workspace/projects/sae-lib/public'],
framework: {
name: '@storybook/angular',
options: {}

View file

@ -10,17 +10,6 @@ const preview: Preview = {
date: /Date$/i,
},
},
// viewport: {
// viewports: INITIAL_VIEWPORTS,
// defaultViewport: 'responsive',
// },
backgrounds: {
default: 'light',
values: [
{ name: 'light', value: '#f8f9fa' },
{ name: 'dark', value: '#333333' },
],
},
},
};

View file

@ -34,8 +34,6 @@
"@angular/compiler-cli": "^20.1.0",
"@angular/localize": "^20.1.2",
"@mdx-js/loader": "^3.1.0",
"@storybook/addon-backgrounds": "^9.0.8",
"@storybook/addon-controls": "^9.0.8",
"@storybook/addon-docs": "^9.0.17",
"@storybook/addon-links": "^9.0.17",
"@storybook/addon-viewport": "^9.0.8",
@ -5292,26 +5290,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/@storybook/addon-backgrounds": {
"version": "9.0.8",
"resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-9.0.8.tgz",
"integrity": "sha512-4Vvr4wYHtiZ8UVWdCahK0XEMU4zNgInnNcVQ31YkUg41MVSY+aoZqtNuxOuRbFzUtjL9/aVsbY0Sg9Lp1/EJ4g==",
"dev": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/storybook"
}
},
"node_modules/@storybook/addon-controls": {
"version": "9.0.8",
"resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-9.0.8.tgz",
"integrity": "sha512-6MY9QeBv2vNmBXH+ONmbpp/Gu/odSxriN1+BAY+il9OyXZBMq3OiDsjoH7xY5V7PGr+0XhZfOLkamvx3q+lQTg==",
"dev": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/storybook"
}
},
"node_modules/@storybook/addon-docs": {
"version": "9.0.17",
"resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-9.0.17.tgz",
@ -5358,6 +5336,17 @@
}
}
},
"node_modules/@storybook/addon-viewport": {
"version": "9.0.8",
"resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-9.0.8.tgz",
"integrity": "sha512-HgIFDzNXvMx0zQBM5mhwBoAJlrF9KRlxNCZnJbqrFLCJO4Ps2PMtB0HRGHcg0gm3RLcqyps0DpiF7wll3udb7Q==",
"dev": true,
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/storybook"
}
},
"node_modules/@storybook/addon-vitest": {
"version": "9.0.17",
"resolved": "https://registry.npmjs.org/@storybook/addon-vitest/-/addon-vitest-9.0.17.tgz",

View file

@ -0,0 +1,94 @@
import type {Meta, StoryObj} from '@storybook/angular';
import {MainButton} from './main-button';
import {moduleMetadata} from '@storybook/angular';
import {CommonModule} from '@angular/common';
// More on how to set up stories at: https://storybook.js.org/docs/angular/writing-stories/introduction
const meta: Meta<MainButton> = {
title: 'Components/MainButton',
component: MainButton,
tags: ['autodocs'],
decorators: [
moduleMetadata({
imports: [CommonModule],
providers: []
})
],
argTypes: {
label: {control: 'text'},
icon: {control: 'text'},
kind: {
control: 'select',
options: ['', 'primary', 'secondary', 'info', 'success', 'warning', 'danger'],
description: 'Style du bouton'
},
},
};
export default meta;
type Story = StoryObj<MainButton>;
// More on writing stories with args: https://storybook.js.org/docs/angular/writing-stories/args
export const Primary: Story = {
args: {
label: 'Button',
icon: 'home-line-2',
kind: 'primary'
},
};
export const Secondary: Story = {
args: {
label: 'Secondary Button',
icon: 'settings-line',
kind: 'secondary'
},
};
export const Info: Story = {
args: {
label: 'Info Button',
icon: 'information-line',
kind: 'info'
},
};
export const Success: Story = {
args: {
label: 'Success Button',
icon: 'check-line',
kind: 'success'
},
};
export const Warning: Story = {
args: {
label: 'Warning Button',
icon: 'alert-line',
kind: 'warning'
},
};
export const Danger: Story = {
args: {
label: 'Danger Button',
icon: 'close-circle-line',
kind: 'danger'
},
};
export const WithoutIcon: Story = {
args: {
label: 'Button without icon',
icon: '',
kind: 'primary'
},
};
export const WithIcon: Story = {
args: {
label: 'Button with icon',
icon: 'user-line',
kind: ''
},
};

View file

@ -13,7 +13,7 @@ import { Component, Input, Output, EventEmitter } from '@angular/core';
>
{{ label }}
</button>`,
styleUrls: ['./button.css'],
// styleUrls: ['./button.css'],
})
export class ButtonComponent {
/** Is this the principal call to action on the page? */

View file

@ -1,76 +0,0 @@
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ButtonComponent } from './button.component';
import type { User } from './user';
@Component({
selector: 'storybook-header',
standalone: true,
imports: [CommonModule, ButtonComponent],
template: `<header>
<div class="storybook-header">
<div>
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fillRule="evenodd">
<path
d="M10 0h12a10 10 0 0110 10v12a10 10 0 01-10 10H10A10 10 0 010 22V10A10 10 0 0110 0z"
fill="#FFF"
/>
<path
d="M5.3 10.6l10.4 6v11.1l-10.4-6v-11zm11.4-6.2l9.7 5.5-9.7 5.6V4.4z"
fill="#555AB9"
/>
<path d="M27.2 10.6v11.2l-10.5 6V16.5l10.5-6zM15.7 4.4v11L6 10l9.7-5.5z" fill="#91BAF8" />
</g>
</svg>
<h1>Acme</h1>
</div>
<div>
<div *ngIf="user">
<span class="welcome">
Welcome, <b>{{ user.name }}</b
>!
</span>
<storybook-button
*ngIf="user"
size="small"
(onClick)="onLogout.emit($event)"
label="Log out"
></storybook-button>
</div>
<div *ngIf="!user">
<storybook-button
*ngIf="!user"
size="small"
class="margin-left"
(onClick)="onLogin.emit($event)"
label="Log in"
></storybook-button>
<storybook-button
*ngIf="!user"
size="small"
[primary]="true"
class="margin-left"
(onClick)="onCreateAccount.emit($event)"
label="Sign up"
></storybook-button>
</div>
</div>
</div>
</header>`,
styleUrls: ['./header.css'],
})
export class HeaderComponent {
@Input()
user: User | null = null;
@Output()
onLogin = new EventEmitter<Event>();
@Output()
onLogout = new EventEmitter<Event>();
@Output()
onCreateAccount = new EventEmitter<Event>();
}

View file

@ -1,32 +0,0 @@
.storybook-header {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
padding: 15px 20px;
font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
.storybook-header svg {
display: inline-block;
vertical-align: top;
}
.storybook-header h1 {
display: inline-block;
vertical-align: top;
margin: 6px 0 6px 10px;
font-weight: 700;
font-size: 20px;
line-height: 1;
}
.storybook-header button + button {
margin-left: 10px;
}
.storybook-header .welcome {
margin-right: 10px;
color: #333;
font-size: 14px;
}

View file

@ -1,33 +0,0 @@
import type { Meta, StoryObj } from '@storybook/angular';
import { fn } from 'storybook/test';
import { HeaderComponent } from './header.component';
const meta: Meta<HeaderComponent> = {
title: 'Example/Header',
component: HeaderComponent,
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
tags: ['autodocs'],
parameters: {
// More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
layout: 'fullscreen',
},
args: {
onLogin: fn(),
onLogout: fn(),
onCreateAccount: fn(),
},
};
export default meta;
type Story = StoryObj<HeaderComponent>;
export const LoggedIn: Story = {
args: {
user: {
name: 'Jane Doe',
},
},
};
export const LoggedOut: Story = {};

View file

@ -1,82 +0,0 @@
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HeaderComponent } from './header.component';
import type { User } from './user';
@Component({
selector: 'storybook-page',
standalone: true,
imports: [CommonModule, HeaderComponent],
template: `<article>
<storybook-header
[user]="user"
(onLogout)="doLogout()"
(onLogin)="doLogin()"
(onCreateAccount)="doCreateAccount()"
></storybook-header>
<section class="storybook-page">
<h2>Pages in Storybook</h2>
<p>
We recommend building UIs with a
<a href="https://componentdriven.org" target="_blank" rel="noopener noreferrer">
<strong>component-driven</strong>
</a>
process starting with atomic components and ending with pages.
</p>
<p>
Render pages with mock data. This makes it easy to build and review page states without
needing to navigate to them in your app. Here are some handy patterns for managing page data
in Storybook:
</p>
<ul>
<li>
Use a higher-level connected component. Storybook helps you compose such data from the
"args" of child component stories
</li>
<li>
Assemble data in the page component from your services. You can mock these services out
using Storybook.
</li>
</ul>
<p>
Get a guided tutorial on component-driven development at
<a href="https://storybook.js.org/tutorials/" target="_blank" rel="noopener noreferrer">
Storybook tutorials
</a>
. Read more in the
<a href="https://storybook.js.org/docs" target="_blank" rel="noopener noreferrer"> docs </a>
.
</p>
<div class="tip-wrapper">
<span class="tip">Tip</span> Adjust the width of the canvas with the
<svg width="10" height="10" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fillRule="evenodd">
<path
d="M1.5 5.2h4.8c.3 0 .5.2.5.4v5.1c-.1.2-.3.3-.4.3H1.4a.5.5 0 01-.5-.4V5.7c0-.3.2-.5.5-.5zm0-2.1h6.9c.3 0 .5.2.5.4v7a.5.5 0 01-1 0V4H1.5a.5.5 0 010-1zm0-2.1h9c.3 0 .5.2.5.4v9.1a.5.5 0 01-1 0V2H1.5a.5.5 0 010-1zm4.3 5.2H2V10h3.8V6.2z"
id="a"
fill="#999"
/>
</g>
</svg>
Viewports addon in the toolbar
</div>
</section>
</article>`,
styleUrls: ['./page.css'],
})
export class PageComponent {
user: User | null = null;
doLogout() {
this.user = null;
}
doLogin() {
this.user = { name: 'Jane Doe' };
}
doCreateAccount() {
this.user = { name: 'Jane Doe' };
}
}

View file

@ -1,68 +0,0 @@
.storybook-page {
margin: 0 auto;
padding: 48px 20px;
max-width: 600px;
color: #333;
font-size: 14px;
line-height: 24px;
font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
.storybook-page h2 {
display: inline-block;
vertical-align: top;
margin: 0 0 4px;
font-weight: 700;
font-size: 32px;
line-height: 1;
}
.storybook-page p {
margin: 1em 0;
}
.storybook-page a {
color: inherit;
}
.storybook-page ul {
margin: 1em 0;
padding-left: 30px;
}
.storybook-page li {
margin-bottom: 8px;
}
.storybook-page .tip {
display: inline-block;
vertical-align: top;
margin-right: 10px;
border-radius: 1em;
background: #e7fdd8;
padding: 4px 12px;
color: #357a14;
font-weight: 700;
font-size: 11px;
line-height: 12px;
}
.storybook-page .tip-wrapper {
margin-top: 40px;
margin-bottom: 40px;
font-size: 13px;
line-height: 20px;
}
.storybook-page .tip-wrapper svg {
display: inline-block;
vertical-align: top;
margin-top: 3px;
margin-right: 4px;
width: 12px;
height: 12px;
}
.storybook-page .tip-wrapper svg path {
fill: #1ea7fd;
}

View file

@ -1,32 +0,0 @@
import type { Meta, StoryObj } from '@storybook/angular';
import { expect, userEvent, within } from 'storybook/test';
import { PageComponent } from './page.component';
const meta: Meta<PageComponent> = {
title: 'Example/Page',
component: PageComponent,
parameters: {
// More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
layout: 'fullscreen',
},
};
export default meta;
type Story = StoryObj<PageComponent>;
export const LoggedOut: Story = {};
// More on component testing: https://storybook.js.org/docs/writing-tests/interaction-testing
export const LoggedIn: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const loginButton = canvas.getByRole('button', { name: /Log in/i });
await expect(loginButton).toBeInTheDocument();
await userEvent.click(loginButton);
await expect(loginButton).not.toBeInTheDocument();
const logoutButton = canvas.getByRole('button', { name: /Log out/i });
await expect(logoutButton).toBeInTheDocument();
},
};

View file

@ -1,3 +0,0 @@
export interface User {
name: string;
}