ressurect storybook buttons
This commit is contained in:
parent
458ad64931
commit
681d8ecb0b
14 changed files with 108 additions and 361 deletions
|
@ -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: {}
|
||||
|
|
|
@ -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' },
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
33
old-sae-airwatch/package-lock.json
generated
33
old-sae-airwatch/package-lock.json
generated
|
@ -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",
|
||||
|
|
|
@ -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: ''
|
||||
},
|
||||
};
|
|
@ -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? */
|
||||
|
|
|
@ -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>();
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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 = {};
|
|
@ -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' };
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
},
|
||||
};
|
|
@ -1,3 +0,0 @@
|
|||
export interface User {
|
||||
name: string;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue