up storybook main button
This commit is contained in:
parent
4af14e6e34
commit
d5610f38be
15 changed files with 339 additions and 547 deletions
7
airwatch/.storybook/src/ExampleDocumentation.mdx
Normal file
7
airwatch/.storybook/src/ExampleDocumentation.mdx
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { Meta } from '@storybook/addon-docs/blocks';
|
||||
|
||||
{/* 👇 Documentation-only page */}
|
||||
|
||||
<Meta title="Documentation" />
|
||||
hey yo
|
||||
{/* 👇 Component documentation page */}
|
20
airwatch/src/app/buttons/main-button/main-button.html
Normal file
20
airwatch/src/app/buttons/main-button/main-button.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
<button
|
||||
[ngClass]="{
|
||||
'is-disabled': disabled
|
||||
}"
|
||||
class="sae-main-button is-{{kind}} is-size-{{size}}"
|
||||
>
|
||||
|
||||
@if (icon && inconPosition !== "right") {
|
||||
<i class="ri ri-{{icon}}"></i>
|
||||
}
|
||||
<span class="label">
|
||||
{{ label }}
|
||||
</span>
|
||||
@if (divider) {
|
||||
<span class="pipe">|</span>
|
||||
}
|
||||
@if (icon && inconPosition == "right") {
|
||||
<i class="ri ri-{{icon}}"></i>
|
||||
}
|
||||
</button>
|
|
@ -1,14 +1,16 @@
|
|||
@use "sae-lib/src/styles/shadows.scss";
|
||||
@use "sae-lib/src/styles/states.scss";
|
||||
@use "sae-lib/src/styles/variables.scss";
|
||||
@use "sae-lib/src/styles/variables.scss" as variables;
|
||||
@use "sass:color";
|
||||
|
||||
|
||||
:host {
|
||||
display: inline-block;
|
||||
font-family: Barlow;
|
||||
|
||||
|
||||
button {
|
||||
background: shadows.$primary-color;
|
||||
//background: shadows.$primary-color;
|
||||
color: shadows.$neutral-white;
|
||||
border-radius: shadows.$radius-main;
|
||||
padding: 1rem 2rem;
|
||||
|
@ -23,47 +25,108 @@
|
|||
}
|
||||
|
||||
&:hover, &:active, &:focus {
|
||||
background: shadows.$main-bg-color-active;
|
||||
color: shadows.$main-color-active;
|
||||
transition: all 0.25s ease;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: var(--Gradient, linear-gradient(77deg, #073A7C -4.23%, #1767AD 51.8%, #255B8E 87.72%));
|
||||
}
|
||||
|
||||
&.is-size {
|
||||
&-large {
|
||||
padding: 17px 24px;
|
||||
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
&-medium {
|
||||
padding: 14px 18px;
|
||||
border-radius: var(--radius-2, 8px);
|
||||
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
&-small {
|
||||
padding: 14px 10px;
|
||||
border-radius: var(--radius-2, 8px);
|
||||
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 20px;
|
||||
|
||||
}
|
||||
|
||||
&-extrasm {
|
||||
padding: 10px 10px;
|
||||
border-radius: var(--radius-2, 4px);
|
||||
color: var(--Colors-Blanc, #FFF);
|
||||
|
||||
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
line-height: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
// state colors
|
||||
&.is-primary {
|
||||
background-color: variables.$primary-color;
|
||||
background: var(--Gradient, linear-gradient(77deg, #073A7C -4.23%, #1767AD 51.8%, #255B8E 87.72%));
|
||||
color: variables.$neutral-white;
|
||||
border-color: color.adjust(variables.$primary-color, $lightness: - 10%);
|
||||
|
||||
&:hover {
|
||||
background: var(--Hover, linear-gradient(70deg, #073A7C 43.99%, #1767AD 94.38%, #255B8E 126.68%));
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
background-color: #BED7EE;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-secondary {
|
||||
background-color: variables.$secondary-color;
|
||||
background-color: variables.$neutral-white;
|
||||
color: variables.$neutral-white;
|
||||
|
||||
&.is-disabled {
|
||||
background-color: #BED7EE;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-warning {
|
||||
&.is-ghost {
|
||||
background: variables.$neutral-white;
|
||||
color: variables.$warning-color-text;
|
||||
color: #255B8E;
|
||||
border: 0;
|
||||
|
||||
&:focus {
|
||||
background: variables.$neutral-white;
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
background-color: #BED7EE;
|
||||
color: #BED7EE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&.is-info {
|
||||
background: variables.$info-color;
|
||||
color: variables.$neutral-white;
|
||||
border-color: color.adjust(variables.$info-color, $lightness: -50%);
|
||||
}
|
||||
|
||||
&.is-success {
|
||||
background: variables.$success-color;
|
||||
color: variables.$neutral-white;
|
||||
border-color: color.adjust(variables.$success-color, $lightness: -50%);
|
||||
}
|
||||
|
||||
&.is-error {
|
||||
background: rgba(variables.$danger-color, 10%);
|
||||
color: variables.$danger-color;
|
||||
&.is-link {
|
||||
background: variables.$neutral-white;
|
||||
color: #255B8E;
|
||||
border: 0;
|
||||
|
||||
.label {
|
||||
text-decoration: underline;
|
||||
text-decoration-color: variables.$primary-color;
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
background-color: #BED7EE;
|
||||
color: #BED7EE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,27 +1,19 @@
|
|||
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: 'composants/boutons/MainButton',
|
||||
component: MainButton,
|
||||
tags: ['autodocs'],
|
||||
decorators: [
|
||||
moduleMetadata({
|
||||
imports: [CommonModule],
|
||||
providers: []
|
||||
})
|
||||
],
|
||||
argTypes: {
|
||||
disabled: {control: 'boolean'},
|
||||
divider: {control: 'boolean'},
|
||||
label: {control: 'text'},
|
||||
icon: {control: 'text'},
|
||||
kind: {
|
||||
control: 'select',
|
||||
options: ['', 'primary', 'secondary', 'info', 'success', 'warning', 'danger'],
|
||||
description: 'Style du bouton'
|
||||
},
|
||||
inconPosition: {control: 'select', options: ['left', 'right']},
|
||||
size: {control: 'select', options: ['', 'large', 'medium', 'small', 'extrasm']},
|
||||
kind: {control: 'select', options: ['', 'primary', 'secondary', 'ghost', 'link']},
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -29,66 +21,146 @@ export default meta;
|
|||
type Story = StoryObj<MainButton>;
|
||||
|
||||
// More on writing stories with args: https://storybook.js.org/docs/angular/writing-stories/args
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
label: 'Call to action',
|
||||
kind: 'primary',
|
||||
size: 'large',
|
||||
disabled: false,
|
||||
divider: true,
|
||||
icon: 'arrow-right-line',
|
||||
inconPosition: 'right',
|
||||
},
|
||||
};
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {
|
||||
label: 'Button',
|
||||
icon: 'home-line-2',
|
||||
kind: 'primary'
|
||||
label: 'Primary Button',
|
||||
kind: 'primary',
|
||||
size: 'medium',
|
||||
disabled: false,
|
||||
divider: false,
|
||||
icon: '',
|
||||
inconPosition: 'left',
|
||||
},
|
||||
};
|
||||
|
||||
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',
|
||||
kind: 'secondary',
|
||||
size: 'medium',
|
||||
disabled: false,
|
||||
divider: false,
|
||||
icon: '',
|
||||
kind: 'primary'
|
||||
inconPosition: 'left',
|
||||
},
|
||||
};
|
||||
|
||||
export const Ghost: Story = {
|
||||
args: {
|
||||
label: 'Ghost Button',
|
||||
kind: 'ghost',
|
||||
size: 'medium',
|
||||
disabled: false,
|
||||
divider: false,
|
||||
icon: '',
|
||||
inconPosition: 'left',
|
||||
},
|
||||
};
|
||||
|
||||
export const Link: Story = {
|
||||
args: {
|
||||
label: 'Link Button',
|
||||
kind: 'link',
|
||||
size: 'medium',
|
||||
disabled: false,
|
||||
divider: false,
|
||||
icon: '',
|
||||
inconPosition: 'left',
|
||||
},
|
||||
};
|
||||
|
||||
export const WithIcon: Story = {
|
||||
args: {
|
||||
label: 'Button with icon',
|
||||
icon: 'user-line',
|
||||
kind: ''
|
||||
label: 'Button with Icon',
|
||||
kind: 'primary',
|
||||
size: 'medium',
|
||||
disabled: false,
|
||||
divider: false,
|
||||
icon: 'arrow-right-line',
|
||||
inconPosition: 'left',
|
||||
},
|
||||
};
|
||||
|
||||
export const WithIconRight: Story = {
|
||||
args: {
|
||||
label: 'Button with Icon Right',
|
||||
kind: 'primary',
|
||||
size: 'medium',
|
||||
disabled: false,
|
||||
divider: false,
|
||||
icon: 'arrow-right-line',
|
||||
inconPosition: 'right',
|
||||
},
|
||||
};
|
||||
|
||||
export const WithDivider: Story = {
|
||||
args: {
|
||||
label: 'Button with Divider',
|
||||
kind: 'primary',
|
||||
size: 'medium',
|
||||
disabled: false,
|
||||
divider: true,
|
||||
icon: 'arrow-right-line',
|
||||
inconPosition: 'right',
|
||||
},
|
||||
};
|
||||
|
||||
export const Disabled: Story = {
|
||||
args: {
|
||||
label: 'Disabled Button',
|
||||
kind: 'primary',
|
||||
size: 'medium',
|
||||
disabled: true,
|
||||
divider: false,
|
||||
icon: '',
|
||||
inconPosition: 'left',
|
||||
},
|
||||
};
|
||||
|
||||
export const Large: Story = {
|
||||
args: {
|
||||
label: 'Large Button',
|
||||
kind: 'primary',
|
||||
size: 'large',
|
||||
disabled: false,
|
||||
divider: false,
|
||||
icon: '',
|
||||
inconPosition: 'left',
|
||||
},
|
||||
};
|
||||
|
||||
export const Small: Story = {
|
||||
args: {
|
||||
label: 'Small Button',
|
||||
kind: 'primary',
|
||||
size: 'small',
|
||||
disabled: false,
|
||||
divider: false,
|
||||
icon: '',
|
||||
inconPosition: 'left',
|
||||
},
|
||||
};
|
||||
|
||||
export const ExtraSmall: Story = {
|
||||
args: {
|
||||
label: 'Extra Small Button',
|
||||
kind: 'primary',
|
||||
size: 'extrasm',
|
||||
disabled: false,
|
||||
divider: false,
|
||||
icon: '',
|
||||
inconPosition: 'left',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,28 +1,22 @@
|
|||
import {Component, Input} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {ButtonKindType, ButtonSizeType, inconPositionKindType} from 'sae-lib/buttons/main-button/main-button';
|
||||
|
||||
export type ButtonKind = '' | 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'danger';
|
||||
|
||||
@Component({
|
||||
selector: 'app-main-button',
|
||||
standalone: true,
|
||||
imports: [CommonModule],
|
||||
template: `
|
||||
<button class="is-{{kind}}">
|
||||
|
||||
@if (icon) {
|
||||
<i class="ri ri-{{icon}}"></i>
|
||||
}
|
||||
<span class="label">
|
||||
|
||||
{{ label }}
|
||||
</span>
|
||||
</button>
|
||||
`,
|
||||
templateUrl: './main-button.html',
|
||||
styleUrl: './main-button.scss'
|
||||
})
|
||||
export class MainButton {
|
||||
|
||||
@Input() disabled: boolean = false;
|
||||
@Input() divider: boolean = false;
|
||||
@Input() label: string = '';
|
||||
@Input() icon: string = '';
|
||||
@Input() kind: ButtonKind = '';
|
||||
@Input() inconPosition: inconPositionKindType = 'left';
|
||||
@Input() size: ButtonSizeType = '';
|
||||
@Input() kind: ButtonKindType = '';
|
||||
}
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
import type { Meta, StoryObj } from '@storybook/angular';
|
||||
import { ConversationItem } from './conversation-item';
|
||||
import { moduleMetadata } from '@storybook/angular';
|
||||
import { NgClass, NgIf, DatePipe } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { ChatbotConversation } from '../../services/conversations.service';
|
||||
|
||||
// More on how to set up stories at: https://storybook.js.org/docs/angular/writing-stories/introduction
|
||||
const meta: Meta<ConversationItem> = {
|
||||
title: 'composants/conversation/ConversationItem',
|
||||
component: ConversationItem,
|
||||
tags: ['autodocs'],
|
||||
decorators: [
|
||||
moduleMetadata({
|
||||
imports: [NgClass, NgIf, DatePipe, FormsModule],
|
||||
providers: []
|
||||
})
|
||||
],
|
||||
argTypes: {
|
||||
isActive: { control: 'boolean' },
|
||||
onSelect: { action: 'selected' },
|
||||
onShare: { action: 'shared' },
|
||||
onRename: { action: 'renamed' },
|
||||
onPin: { action: 'pinned' },
|
||||
onDelete: { action: 'deleted' }
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<ConversationItem>;
|
||||
|
||||
// Create a mock conversation
|
||||
const createMockConversation = (name: string, description: string, pinned: boolean = false): ChatbotConversation => {
|
||||
const conversation = new ChatbotConversation();
|
||||
conversation.name = name;
|
||||
conversation.description = description;
|
||||
conversation.pinned = pinned;
|
||||
conversation.lastMessageDate = new Date();
|
||||
return conversation;
|
||||
};
|
||||
|
||||
// Default story
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
conversation: createMockConversation('Project Discussion', 'Latest updates on the project timeline'),
|
||||
isActive: false
|
||||
},
|
||||
};
|
||||
|
||||
// Active conversation
|
||||
export const Active: Story = {
|
||||
args: {
|
||||
conversation: createMockConversation('Project Discussion', 'Latest updates on the project timeline'),
|
||||
isActive: true
|
||||
},
|
||||
};
|
||||
|
||||
// Pinned conversation
|
||||
export const Pinned: Story = {
|
||||
args: {
|
||||
conversation: createMockConversation('Important Meeting', 'CEO quarterly update', true),
|
||||
isActive: false
|
||||
},
|
||||
};
|
||||
|
||||
// Long name and description
|
||||
export const LongContent: Story = {
|
||||
args: {
|
||||
conversation: createMockConversation(
|
||||
'Very Long Conversation Name That Should Truncate',
|
||||
'This is a very long description that should demonstrate how the component handles overflow text in the description area of the conversation item component',
|
||||
),
|
||||
isActive: false
|
||||
},
|
||||
};
|
|
@ -1,186 +0,0 @@
|
|||
import type { Meta, StoryObj } from '@storybook/angular';
|
||||
import { moduleMetadata } from '@storybook/angular';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MainButton } from '../../../../my-workspace/projects/sae-lib/buttons/main-button/main-button';
|
||||
|
||||
// More on how to set up stories at: https://storybook.js.org/docs/angular/writing-stories/introduction
|
||||
const meta: Meta<MainButton> = {
|
||||
title: 'composants/boutons/SaeMainButton',
|
||||
component: MainButton,
|
||||
tags: ['autodocs'],
|
||||
decorators: [
|
||||
moduleMetadata({
|
||||
imports: [CommonModule],
|
||||
providers: []
|
||||
})
|
||||
],
|
||||
argTypes: {
|
||||
label: { control: 'text' },
|
||||
icon: { control: 'text' },
|
||||
kind: {
|
||||
control: 'select',
|
||||
options: ['', 'primary', 'secondary', 'ghost', 'link'],
|
||||
description: 'Style du bouton'
|
||||
},
|
||||
size: {
|
||||
control: 'select',
|
||||
options: ['', 'large', 'medium', 'small', 'extrasm'],
|
||||
description: 'Taille du bouton'
|
||||
},
|
||||
inconPosition: {
|
||||
control: 'select',
|
||||
options: ['left', 'right'],
|
||||
description: 'Position de l\'icône'
|
||||
},
|
||||
disabled: { control: 'boolean' },
|
||||
divider: { control: 'boolean' }
|
||||
},
|
||||
};
|
||||
|
||||
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',
|
||||
kind: 'primary',
|
||||
size: 'medium',
|
||||
inconPosition: 'left',
|
||||
disabled: false,
|
||||
divider: false
|
||||
},
|
||||
};
|
||||
|
||||
export const Secondary: Story = {
|
||||
args: {
|
||||
label: 'Secondary Button',
|
||||
icon: 'settings-line',
|
||||
kind: 'secondary',
|
||||
size: 'medium',
|
||||
inconPosition: 'left',
|
||||
disabled: false,
|
||||
divider: false
|
||||
},
|
||||
};
|
||||
|
||||
export const Ghost: Story = {
|
||||
args: {
|
||||
label: 'Ghost Button',
|
||||
icon: 'ghost-line',
|
||||
kind: 'ghost',
|
||||
size: 'medium',
|
||||
inconPosition: 'left',
|
||||
disabled: false,
|
||||
divider: false
|
||||
},
|
||||
};
|
||||
|
||||
export const Link: Story = {
|
||||
args: {
|
||||
label: 'Link Button',
|
||||
icon: 'link',
|
||||
kind: 'link',
|
||||
size: 'medium',
|
||||
inconPosition: 'left',
|
||||
disabled: false,
|
||||
divider: false
|
||||
},
|
||||
};
|
||||
|
||||
export const Large: Story = {
|
||||
args: {
|
||||
label: 'Large Button',
|
||||
icon: 'arrow-up-line',
|
||||
kind: 'primary',
|
||||
size: 'large',
|
||||
inconPosition: 'left',
|
||||
disabled: false,
|
||||
divider: false
|
||||
},
|
||||
};
|
||||
|
||||
export const Small: Story = {
|
||||
args: {
|
||||
label: 'Small Button',
|
||||
icon: 'arrow-down-line',
|
||||
kind: 'primary',
|
||||
size: 'small',
|
||||
inconPosition: 'left',
|
||||
disabled: false,
|
||||
divider: false
|
||||
},
|
||||
};
|
||||
|
||||
export const ExtraSmall: Story = {
|
||||
args: {
|
||||
label: 'Extra Small Button',
|
||||
icon: 'arrow-left-line',
|
||||
kind: 'primary',
|
||||
size: 'extrasm',
|
||||
inconPosition: 'left',
|
||||
disabled: false,
|
||||
divider: false
|
||||
},
|
||||
};
|
||||
|
||||
export const RightIcon: Story = {
|
||||
args: {
|
||||
label: 'Button with Right Icon',
|
||||
icon: 'arrow-right-line',
|
||||
kind: 'primary',
|
||||
size: 'medium',
|
||||
inconPosition: 'right',
|
||||
disabled: false,
|
||||
divider: false
|
||||
},
|
||||
};
|
||||
|
||||
export const WithoutIcon: Story = {
|
||||
args: {
|
||||
label: 'Button without icon',
|
||||
icon: '',
|
||||
kind: 'primary',
|
||||
size: 'medium',
|
||||
inconPosition: 'left',
|
||||
disabled: false,
|
||||
divider: false
|
||||
},
|
||||
};
|
||||
|
||||
export const Disabled: Story = {
|
||||
args: {
|
||||
label: 'Disabled Button',
|
||||
icon: 'close-line',
|
||||
kind: 'primary',
|
||||
size: 'medium',
|
||||
inconPosition: 'left',
|
||||
disabled: true,
|
||||
divider: false
|
||||
},
|
||||
};
|
||||
|
||||
export const WithDivider: Story = {
|
||||
args: {
|
||||
label: 'Button with Divider',
|
||||
icon: 'menu-line',
|
||||
kind: 'primary',
|
||||
size: 'medium',
|
||||
inconPosition: 'left',
|
||||
disabled: false,
|
||||
divider: true
|
||||
},
|
||||
};
|
||||
|
||||
export const GhostDisabled: Story = {
|
||||
args: {
|
||||
label: 'Disabled Ghost Button',
|
||||
icon: 'ghost-line',
|
||||
kind: 'ghost',
|
||||
size: 'medium',
|
||||
inconPosition: 'left',
|
||||
disabled: true,
|
||||
divider: false
|
||||
},
|
||||
};
|
|
@ -25,31 +25,19 @@ We'll use a three-level hierarchy to organize our stories:
|
|||
## Naming Convention
|
||||
|
||||
Story titles should follow this pattern:
|
||||
|
||||
```
|
||||
{Top-level}/{Sub-category}/{ComponentName}
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
- `UI/Buttons/MainButton`
|
||||
- `UI/Feedback/AlertBox`
|
||||
- `Chatbot/Conversation/ConversationItem`
|
||||
- `Chatbot/Messages/MessageBox`
|
||||
- `Design/Colors/ColorDisplay`
|
||||
|
||||
## Examples of New Category Structure
|
||||
|
||||
| Current Title | New Title |
|
||||
|---------------|-----------|
|
||||
| UI/Buttons/MainButton | composants/boutons/MainButton |
|
||||
| UI/Buttons/ToggleButton | composants/boutons/ToggleButton |
|
||||
| UI/Inputs/PromptInput | composants/inputs/PromptInput |
|
||||
| UI/Feedback/AlertBox | composants/feedback/AlertBox |
|
||||
| Design/Colors/ColorDisplay | fondations/couleurs/ColorDisplay |
|
||||
| UI/Navigation/Navbar | patterns/breadcrumbs/Navbar |
|
||||
| Chatbot/Conversation/ConversationItem | composants/conversation/ConversationItem |
|
||||
| Chatbot/Actions/ExportChatButton | composants/boutons/ExportChatButton |
|
||||
| Chatbot/Messages/MessageBox | composants/conversation/MessageBox |
|
||||
|
||||
## Implementation
|
||||
|
||||
To change a component's category, update the `title` property in its story file:
|
||||
|
@ -63,6 +51,7 @@ const meta: Meta<MyComponent> = {
|
|||
```
|
||||
|
||||
This new structure will make it easier to:
|
||||
|
||||
1. Find related components
|
||||
2. Understand the purpose and context of each component
|
||||
3. Maintain a consistent organization as the component library grows
|
||||
|
|
|
@ -1,153 +0,0 @@
|
|||
/**
|
||||
* Script to update Storybook story categories according to the new hierarchical structure
|
||||
*
|
||||
* Usage:
|
||||
* 1. Run with Node.js: node update-story-categories.js
|
||||
* 2. The script will scan all .stories.ts files and suggest category updates
|
||||
* 3. You can review and apply the changes
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const {execSync} = require('child_process');
|
||||
|
||||
// Define the mapping from old categories to new categories
|
||||
const categoryMapping = {
|
||||
// UI Components to composants/boutons
|
||||
'UI/Buttons/ExportChatButton': 'composants/boutons/ExportChatButton',
|
||||
'UI/Buttons/MainButton': 'composants/boutons/MainButton',
|
||||
'UI/Buttons/ToggleButton': 'composants/boutons/ToggleButton',
|
||||
'Chatbot/Actions/ExportChatButton': 'composants/boutons/ExportChatButton',
|
||||
'Components/Buttons/ExportChatButton': 'composants/boutons/ExportChatButton',
|
||||
'Components/MainButton': 'composants/boutons/MainButton',
|
||||
'Components/ToggleButton': 'composants/boutons/ToggleButton',
|
||||
'Components/FeedbackButton': 'composants/boutons/FeedbackButton',
|
||||
|
||||
// UI Feedback to composants/feedback
|
||||
'UI/Feedback/AlertBox': 'composants/feedback/AlertBox',
|
||||
'UI/Feedback/FeedbackButton': 'composants/boutons/FeedbackButton',
|
||||
'Components/AlertBox': 'composants/feedback/AlertBox',
|
||||
|
||||
// Design to fondations
|
||||
'Design/Colors/ColorDisplay': 'fondations/couleurs/ColorDisplay',
|
||||
'Design/Brand/Logo': 'fondations/brand/Logo',
|
||||
'Components/Logo': 'fondations/brand/Logo',
|
||||
'Components/ColorDisplay': 'fondations/couleurs/ColorDisplay',
|
||||
|
||||
// UI Navigation to patterns/breadcrumbs
|
||||
'UI/Navigation/Navbar': 'patterns/breadcrumbs/Navbar',
|
||||
'Navigation/DsNavbar': 'patterns/breadcrumbs/Navbar',
|
||||
|
||||
// Chatbot Components to composants
|
||||
'Chatbot/Conversation/ConversationItem': 'composants/conversation/ConversationItem',
|
||||
'Chatbot/Feedback/WarningBugs': 'composants/feedback/WarningBugs',
|
||||
'Chatbot/Messages/MessageBox': 'composants/conversation/MessageBox',
|
||||
'Chatbot/Input/PromptInput': 'composants/inputs/PromptInput',
|
||||
'Chatbot/Input/NewInput': 'composants/inputs/NewInput',
|
||||
'Chatbot/Sources/SourceBlock': 'composants/conversation/SourceBlock',
|
||||
'Chatbot/ConversationItem': 'composants/conversation/ConversationItem',
|
||||
'Chatbot/WarningBugs': 'composants/feedback/WarningBugs',
|
||||
'Components/MessageBox': 'composants/conversation/MessageBox',
|
||||
'Components/PromptInput': 'composants/inputs/PromptInput',
|
||||
'Components/NewInput': 'composants/inputs/NewInput',
|
||||
'Components/SourceBlock': 'composants/conversation/SourceBlock',
|
||||
|
||||
// App
|
||||
'App/Features/Chatbot': 'composants/conversation/Chatbot',
|
||||
'App/Chatbot': 'composants/conversation/Chatbot',
|
||||
};
|
||||
|
||||
// Find all story files
|
||||
const findStoryFiles = () => {
|
||||
try {
|
||||
const result = execSync(
|
||||
'find /home/poule/encrypted/stockage-syncable/www/development/html/ng-implementation/airwatch/src -name "*.stories.ts"'
|
||||
).toString();
|
||||
return result.split('\n').filter(Boolean);
|
||||
} catch (error) {
|
||||
console.error('Error finding story files:', error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
// Extract current category from a story file
|
||||
const extractCurrentCategory = (filePath) => {
|
||||
try {
|
||||
const content = fs.readFileSync(filePath, 'utf8');
|
||||
const match = content.match(/title:\s*['"]([^'"]+)['"]/);
|
||||
return match ? match[1] : null;
|
||||
} catch (error) {
|
||||
console.error(`Error reading file ${filePath}:`, error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// Update category in a story file
|
||||
const updateCategory = (filePath, oldCategory, newCategory) => {
|
||||
try {
|
||||
let content = fs.readFileSync(filePath, 'utf8');
|
||||
content = content.replace(
|
||||
`title: '${oldCategory}'`,
|
||||
`title: '${newCategory}'`
|
||||
);
|
||||
fs.writeFileSync(filePath, content, 'utf8');
|
||||
console.log(`✅ Updated ${filePath}: ${oldCategory} -> ${newCategory}`);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(`Error updating file ${filePath}:`, error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Main function
|
||||
const main = () => {
|
||||
console.log('🔍 Finding story files...');
|
||||
const storyFiles = findStoryFiles();
|
||||
console.log(`Found ${storyFiles.length} story files.`);
|
||||
|
||||
let updated = 0;
|
||||
let skipped = 0;
|
||||
let notMapped = 0;
|
||||
|
||||
storyFiles.forEach(filePath => {
|
||||
const currentCategory = extractCurrentCategory(filePath);
|
||||
if (!currentCategory) {
|
||||
console.log(`⚠️ Could not extract category from ${filePath}`);
|
||||
skipped++;
|
||||
return;
|
||||
}
|
||||
|
||||
const newCategory = categoryMapping[currentCategory];
|
||||
if (!newCategory) {
|
||||
console.log(`ℹ️ No mapping defined for category: ${currentCategory} in ${filePath}`);
|
||||
notMapped++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentCategory === newCategory) {
|
||||
console.log(`ℹ️ Category already up to date: ${currentCategory} in ${filePath}`);
|
||||
skipped++;
|
||||
return;
|
||||
}
|
||||
|
||||
const success = updateCategory(filePath, currentCategory, newCategory);
|
||||
if (success) {
|
||||
updated++;
|
||||
} else {
|
||||
skipped++;
|
||||
}
|
||||
});
|
||||
|
||||
console.log('\n📊 Summary:');
|
||||
console.log(`Total files: ${storyFiles.length}`);
|
||||
console.log(`Updated: ${updated}`);
|
||||
console.log(`Skipped: ${skipped}`);
|
||||
console.log(`Not mapped: ${notMapped}`);
|
||||
|
||||
if (notMapped > 0) {
|
||||
console.log('\n⚠️ Some categories were not mapped. Please update the categoryMapping object in the script.');
|
||||
}
|
||||
};
|
||||
|
||||
// Run the script
|
||||
main();
|
Loading…
Add table
Add a link
Reference in a new issue