@repobit/dex-system-design 0.22.11 → 0.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/package.json +4 -3
  3. package/src/components/Button/button.stories.js +292 -120
  4. package/src/components/accordion/accordion-bg.css.js +7 -2
  5. package/src/components/accordion/accordion-bg.stories.js +268 -449
  6. package/src/components/accordion/accordion.stories.js +259 -265
  7. package/src/components/anchor/anchor.stories.js +160 -159
  8. package/src/components/awards/awards-icon.js +44 -0
  9. package/src/components/awards/awards.css.js +328 -0
  10. package/src/components/awards/awards.js +224 -0
  11. package/src/components/awards/awards.stories.js +447 -0
  12. package/src/components/back/back.stories.js +100 -375
  13. package/src/components/badge/badge.stories.js +241 -129
  14. package/src/components/breadcrumb/breadcrumb.stories.js +218 -219
  15. package/src/components/cards/card.stories.js +174 -622
  16. package/src/components/carousel/carousel.stories.js +196 -225
  17. package/src/components/checkbox/checkbox.stories.js +136 -51
  18. package/src/components/compare/compare.css.js +237 -0
  19. package/src/components/compare/compare.js +253 -0
  20. package/src/components/compare/compare.stories.js +372 -0
  21. package/src/components/display/display.stories.js +91 -297
  22. package/src/components/divider/divider.stories.js +160 -342
  23. package/src/components/footer/footer.stories.js +177 -402
  24. package/src/components/header/header.stories.js +130 -338
  25. package/src/components/heading/heading.js +8 -5
  26. package/src/components/heading/heading.stories.js +162 -471
  27. package/src/components/highlight/highlight.stories.js +153 -38
  28. package/src/components/image/image.stories.js +135 -563
  29. package/src/components/input/custom-form.stories.js +761 -224
  30. package/src/components/link/link.js +29 -12
  31. package/src/components/link/link.stories.js +130 -468
  32. package/src/components/modal/modal.stories.js +174 -28
  33. package/src/components/paragraph/paragraph.css.js +10 -1
  34. package/src/components/paragraph/paragraph.stories.js +85 -410
  35. package/src/components/picture/picture.stories.js +147 -561
  36. package/src/components/radio/radio.stories.js +230 -81
  37. package/src/components/tabs/tabs.stories.js +126 -10
  38. package/src/components/termsOfUse/terms.stories.js +223 -8
  39. package/src/tokens/tokens.js +1 -0
@@ -1,233 +1,204 @@
1
- import { html } from "lit";
2
- import "../heading/heading.js";
3
- import "../paragraph/paragraph.js";
4
-
5
- import "./carousel.js";
1
+ import { html } from 'lit';
2
+ import './carousel.js';
6
3
 
7
4
  export default {
8
- title : "Components/Carousel Section",
9
- component: "bd-carousel-section",
10
- tags : ["autodocs"],
11
- argTypes : {
12
- title: { control: "text" },
13
-
14
- // Item 1
15
- item1Title : { control: "text", name: "Item 1 Title" },
16
- item1SubTitle : { control: "text", name: "Item 1 SubTitle" },
17
- item1ModalText: { control: "text", name: "Item 1 Modal Text" },
18
- item1Icon : { control: "text", name: "Item 1 Icon" },
19
- item1Content : { control: "text", name: "Item 1 Content (use \\n\\n for paragraphs)" },
20
-
21
- // Item 2
22
- item2Title : { control: "text", name: "Item 2 Title" },
23
- item2SubTitle : { control: "text", name: "Item 2 SubTitle" },
24
- item2ModalText: { control: "text", name: "Item 2 Modal Text" },
25
- item2Icon : { control: "text", name: "Item 2 Icon" },
26
- item2Content : { control: "text", name: "Item 2 Content (use \\n\\n for paragraphs)" },
27
-
28
- // Item 3
29
- item3Title : { control: "text", name: "Item 3 Title" },
30
- item3SubTitle : { control: "text", name: "Item 3 SubTitle" },
31
- item3ModalText: { control: "text", name: "Item 3 Modal Text" },
32
- item3Icon : { control: "text", name: "Item 3 Icon" },
33
- item3Content : { control: "text", name: "Item 3 Content (use \\n\\n for paragraphs)" },
34
-
35
- // Item 4
36
- item4Title : { control: "text", name: "Item 4 Title" },
37
- item4SubTitle : { control: "text", name: "Item 4 SubTitle" },
38
- item4ModalText: { control: "text", name: "Item 4 Modal Text" },
39
- item4Icon : { control: "text", name: "Item 4 Icon" },
40
- item4Content : { control: "text", name: "Item 4 Content (use \\n\\n for paragraphs)" },
41
-
42
- // Item 5
43
- item5Title : { control: "text", name: "Item 5 Title" },
44
- item5SubTitle : { control: "text", name: "Item 5 SubTitle" },
45
- item5ModalText: { control: "text", name: "Item 5 Modal Text" },
46
- item5Icon : { control: "text", name: "Item 5 Icon" },
47
- item5Content : { control: "text", name: "Item 5 Content (use \\n\\n for paragraphs)" },
48
-
49
- // Item 6
50
- item6Title : { control: "text", name: "Item 6 Title" },
51
- item6SubTitle : { control: "text", name: "Item 6 SubTitle" },
52
- item6ModalText: { control: "text", name: "Item 6 Modal Text" },
53
- item6Icon : { control: "text", name: "Item 6 Icon" },
54
- item6Content : { control: "text", name: "Item 6 Content (use \\n\\n for paragraphs)" },
55
-
56
- // Item 7
57
- item7Title : { control: "text", name: "Item 7 Title" },
58
- item7SubTitle : { control: "text", name: "Item 7 SubTitle" },
59
- item7ModalText: { control: "text", name: "Item 7 Modal Text" },
60
- item7Icon : { control: "text", name: "Item 7 Icon" },
61
- item7Content : { control: "text", name: "Item 7 Content (use \\n\\n for paragraphs)" },
62
-
63
- // Item 8
64
- item8Title : { control: "text", name: "Item 8 Title" },
65
- item8SubTitle : { control: "text", name: "Item 8 SubTitle" },
66
- item8ModalText: { control: "text", name: "Item 8 Modal Text" },
67
- item8Icon : { control: "text", name: "Item 8 Icon" },
68
- item8Content : { control: "text", name: "Item 8 Content (use \\n\\n for paragraphs)" }
5
+ title : 'Components/Carousel',
6
+ tags : ['autodocs'],
7
+ parameters: {
8
+ docs: {
9
+ description: {
10
+ component: `
11
+ **CustomCarousel** and **CarouselItem** are Lit components for a scrollable, draggable card carousel with modal support.
12
+
13
+ - \`<bd-carousel-section>\` scrollable container with left/right arrows and optional title
14
+ - \`<bd-carousel-item>\` individual card with icon, slotted content, and a \`+\` button to open a modal
15
+
16
+ ### Usage
17
+ \`\`\`html
18
+ <bd-carousel-section title="Security Features">
19
+ <bd-carousel-item title="VPN" icon="/assets/vpn.svg" modalText="Our VPN protects your connection.">
20
+ <p>Unlimited VPN included</p>
21
+ </bd-carousel-item>
22
+ </bd-carousel-section>
23
+ \`\`\`
24
+
25
+ ### Behavior
26
+ - Left/right arrows scroll by one item width with smooth scroll
27
+ - Arrows disable automatically at scroll boundaries
28
+ - Click and drag (mouse + touch) supported for scrolling
29
+ - Clicking \`+\` on an item fires \`open-modal\` custom event, caught by the carousel to show \`<bd-modal>\`
30
+ - Modal closes via \`close-modal\` event
31
+
32
+ ### Keyboard Support
33
+ - Arrow buttons respond to Enter/Space
34
+ - \`+\` button on items responds to Enter/Space
35
+ `
36
+ }
37
+ }
38
+ },
39
+ argTypes: {
40
+ title: {
41
+ control : 'text',
42
+ description: 'Optional section title rendered as `<h1>` above the carousel track',
43
+ table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'CarouselSection' }
44
+ },
45
+ itemTitle: {
46
+ control : 'text',
47
+ description: 'Title of a carousel item, shown in the modal header',
48
+ table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'CarouselItem' }
49
+ },
50
+ itemIcon: {
51
+ control : 'text',
52
+ description: 'Path to the icon image shown at the top of a carousel item',
53
+ table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'CarouselItem' }
54
+ },
55
+ modalText: {
56
+ control : 'text',
57
+ description: 'Text passed to the modal when the `+` button is clicked',
58
+ table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'CarouselItem' }
59
+ }
69
60
  }
70
61
  };
71
62
 
72
- const renderParagraphs = (text) =>
73
- text
74
- ? text.split("\n\n").map(
75
- (paragraph) => html`<bd-p>${paragraph}</bd-p>`
76
- )
77
- : null;
78
-
79
- const Template = (args) => html`
80
- <bd-carousel-section title="${args.title}">
81
- <bd-carousel-item
82
- title="${args.item1Title}"
83
- subTitle="${args.item1SubTitle}"
84
- modalText="${args.item1ModalText}"
85
- icon="${args.item1Icon}"
86
- >
87
- <bd-h as="h4" padding="10px 0">${args.item1Title}</bd-h>
88
- ${renderParagraphs(args.item1Content)}
89
- </bd-carousel-item>
90
-
91
- <bd-carousel-item
92
- title="${args.item2Title}"
93
- subTitle="${args.item2SubTitle}"
94
- modalText="${args.item2ModalText}"
95
- icon="${args.item2Icon}"
96
- >
97
- <bd-h as="h4" padding="10px 0">${args.item2Title}</bd-h>
98
- ${renderParagraphs(args.item2Content)}
99
- </bd-carousel-item>
100
-
101
- <bd-carousel-item
102
- title="${args.item3Title}"
103
- subTitle="${args.item3SubTitle}"
104
- modalText="${args.item3ModalText}"
105
- icon="${args.item3Icon}"
106
- >
107
- <bd-h as="h4" padding="10px 0">${args.item3Title}</bd-h>
108
- ${renderParagraphs(args.item3Content)}
109
- </bd-carousel-item>
110
-
111
- <bd-carousel-item
112
- title="${args.item4Title}"
113
- subTitle="${args.item4SubTitle}"
114
- modalText="${args.item4ModalText}"
115
- icon="${args.item4Icon}"
116
- >
117
- <bd-h as="h4" padding="10px 0">${args.item4Title}</bd-h>
118
- ${renderParagraphs(args.item4Content)}
119
- </bd-carousel-item>
120
-
121
- <bd-carousel-item
122
- title="${args.item5Title}"
123
- subTitle="${args.item5SubTitle}"
124
- modalText="${args.item5ModalText}"
125
- icon="${args.item5Icon}"
126
- >
127
- <bd-h as="h4" padding="10px 0">${args.item5Title}</bd-h>
128
- ${renderParagraphs(args.item5Content)}
129
- </bd-carousel-item>
130
-
131
- <bd-carousel-item
132
- title="${args.item6Title}"
133
- subTitle="${args.item6SubTitle}"
134
- modalText="${args.item6ModalText}"
135
- icon="${args.item6Icon}"
136
- >
137
- <bd-h as="h4" padding="10px 0">${args.item6Title}</bd-h>
138
- ${renderParagraphs(args.item6Content)}
139
- </bd-carousel-item>
140
-
141
- <bd-carousel-item
142
- title="${args.item7Title}"
143
- subTitle="${args.item7SubTitle}"
144
- modalText="${args.item7ModalText}"
145
- icon="${args.item7Icon}"
146
- >
147
- <bd-h as="h4" padding="10px 0">${args.item7Title}</bd-h>
148
- ${renderParagraphs(args.item7Content)}
149
- </bd-carousel-item>
150
-
151
- <bd-carousel-item
152
- title="${args.item8Title}"
153
- subTitle="${args.item8SubTitle}"
154
- modalText="${args.item8ModalText}"
155
- icon="${args.item8Icon}"
156
- >
157
- <bd-h as="h4" padding="10px 0">${args.item8Title}</bd-h>
158
- ${renderParagraphs(args.item8Content)}
159
- </bd-carousel-item>
160
- </bd-carousel-section>
63
+ const sampleItems = [
64
+ { title: 'VPN Protection', icon: '/assets/vpn.svg', modalText: 'Our VPN encrypts your internet traffic and hides your IP address.', content: 'Unlimited encrypted VPN traffic' },
65
+ { title: 'Antivirus', icon: '/assets/antivirus.svg', modalText: 'Real-time antivirus protection against all known and emerging threats.', content: 'Award-winning threat detection' },
66
+ { title: 'Password Manager', icon: '/assets/password.svg', modalText: 'Store and autofill all your passwords securely across all devices.', content: 'Secure password vault' },
67
+ { title: 'Parental Controls', icon: '/assets/parental.svg', modalText: 'Monitor and control your children\'s online activity and screen time.', content: 'Advanced content filtering' },
68
+ { title: 'Anti-Phishing', icon: '/assets/phishing.svg', modalText: 'Detects and blocks phishing websites before they can steal your data.', content: 'Real-time phishing protection' },
69
+ { title: 'Webcam Protection', icon: '/assets/webcam.svg', modalText: 'Prevents unauthorized apps from accessing your webcam.', content: 'Webcam & mic access control' }
70
+ ];
71
+
72
+ const renderItem = (item) => html`
73
+ <bd-carousel-item title="${item.title}" icon="${item.icon}" modalText="${item.modalText}">
74
+ <p>${item.content}</p>
75
+ </bd-carousel-item>
161
76
  `;
162
77
 
163
- export const Default = Template.bind({});
164
- Default.args = {
165
- title: "Need help? We've got answers!",
166
-
167
- item1Title: "Scam Copilot Bot",
168
- item1SubTitle:
169
- "Specialized AI chatbot that helps you identify suspicious online interactions so you don't become a victim",
170
- item1ModalText:
171
- "Specialized AI chatbot that helps you identify suspicious online interactions so you don't become a victim",
172
- item1Icon : "/assets/light-carousel-img1.png",
173
- item1Content: `Specialized AI chatbot that helps you identify suspicious online interactions so you don't become a victim.\n\nSpecialized AI chatbot that helps you identify suspicious online interactions so you don't become a victim.\n\nTest Scam Copilot Bot`,
174
-
175
- item2Title : "Scam Wave Alerts",
176
- item2SubTitle : "Proactively informs you about scam outbreaks in your region",
177
- item2ModalText: "Proactively informs you about scam outbreaks in your region",
178
- item2Icon : "/assets/light-carousel-img1.png",
179
- item2Content : "Proactively informs you about scam outbreaks in your region.",
180
-
181
- item3Title: "AI-Powered Scam Check",
182
- item3SubTitle:
183
- "AI-driven tool that instantly evaluates the legitimacy of any link, message, or online interaction",
184
- item3ModalText:
185
- "AI-driven tool that instantly evaluates the legitimacy of any link, message, or online interaction",
186
- item3Icon: "/assets/light-carousel-img1.png",
187
- item3Content:
188
- "AI-driven tool that instantly evaluates the legitimacy of any link, message, or online interaction.",
189
-
190
- item4Title: "Educational Resources",
191
- item4SubTitle:
192
- "Access a wealth of information and best practices to stay informed and vigilant against scams",
193
- item4ModalText:
194
- "Access a wealth of information and best practices to stay informed and vigilant against scams",
195
- item4Icon: "/assets/light-carousel-img1.png",
196
- item4Content:
197
- "Access a wealth of information and best practices to stay informed and vigilant against scams.",
198
-
199
- item5Title: "Phishing Simulator",
200
- item5SubTitle:
201
- "Simulates phishing attacks to help you recognize and respond appropriately to real threats",
202
- item5ModalText:
203
- "Simulates phishing attacks to help you recognize and respond appropriately to real threats",
204
- item5Icon: "/assets/light-carousel-img1.png",
205
- item5Content:
206
- "Simulates phishing attacks to help you recognize and respond appropriately to real threats.",
207
-
208
- item6Title: "Real-Time Scam Updates",
209
- item6SubTitle:
210
- "Stay ahead with up-to-the-minute alerts on the latest scams targeting your region or industry",
211
- item6ModalText:
212
- "Stay ahead with up-to-the-minute alerts on the latest scams targeting your region or industry",
213
- item6Icon: "/assets/light-carousel-img1.png",
214
- item6Content:
215
- "Stay ahead with up-to-the-minute alerts on the latest scams targeting your region or industry.",
216
-
217
- item7Title: "Community Reporting Hub",
218
- item7SubTitle:
219
- "A platform where users can report scams and share experiences to help protect others",
220
- item7ModalText:
221
- "A platform where users can report scams and share experiences to help protect others",
222
- item7Icon : "/assets/light-carousel-img1.png",
223
- item7Content: "A platform where users can report scams and share experiences to help protect others.",
224
-
225
- item8Title: "Fraud Prevention Workshops",
226
- item8SubTitle:
227
- "Interactive workshops that educate users on identifying and avoiding scams",
228
- item8ModalText:
229
- "Interactive workshops that educate users on identifying and avoiding scams",
230
- item8Icon: "/assets/light-carousel-img1.png",
231
- item8Content:
232
- "Interactive workshops that educate users on identifying and avoiding scams."
78
+ // ─── Stories ───────────────────────────────────────────────────────────────
79
+
80
+ export const Default = {
81
+ name : 'Default (6 items)',
82
+ render: () => html`
83
+ <bd-carousel-section title="Security Features">
84
+ ${sampleItems.map(renderItem)}
85
+ </bd-carousel-section>
86
+ `,
87
+ parameters: { docs: { description: { story: '6-item carousel with title. Scroll with arrows or drag.' } } }
88
+ };
89
+
90
+ export const NoTitle = {
91
+ name : 'No Section Title',
92
+ render: () => html`
93
+ <bd-carousel-section>
94
+ ${sampleItems.map(renderItem)}
95
+ </bd-carousel-section>
96
+ `,
97
+ parameters: { docs: { description: { story: 'Carousel without a title — the header `<div>` is conditionally omitted.' } } }
98
+ };
99
+
100
+ export const FewItems = {
101
+ name : 'Few Items (2)',
102
+ render: () => html`
103
+ <bd-carousel-section title="Features">
104
+ ${sampleItems.slice(0, 2).map(renderItem)}
105
+ </bd-carousel-section>
106
+ `,
107
+ parameters: { docs: { description: { story: 'Only 2 items right arrow should be disabled if all items fit in view.' } } }
108
+ };
109
+
110
+ export const SingleItem = {
111
+ name : 'Single Item (edge case)',
112
+ render: () => html`
113
+ <bd-carousel-section title="Features">
114
+ ${renderItem(sampleItems[0])}
115
+ </bd-carousel-section>
116
+ `,
117
+ parameters: { docs: { description: { story: 'Edge case with a single item. Both arrows should be disabled.' } } }
118
+ };
119
+
120
+ export const NoIcon = {
121
+ name : 'Items Without Icons',
122
+ render: () => html`
123
+ <bd-carousel-section title="Features">
124
+ ${sampleItems.slice(0, 4).map(item => html`
125
+ <bd-carousel-item title="${item.title}" modalText="${item.modalText}">
126
+ <p>${item.content}</p>
127
+ </bd-carousel-item>
128
+ `)}
129
+ </bd-carousel-section>
130
+ `,
131
+ parameters: { docs: { description: { story: 'Items with no `icon` prop — the `<img>` is conditionally omitted.' } } }
132
+ };
133
+
134
+ export const RichSlottedContent = {
135
+ name : 'Rich Slotted Content',
136
+ render: () => html`
137
+ <bd-carousel-section title="Features">
138
+ <bd-carousel-item title="VPN" icon="/assets/vpn.svg" modalText="Full VPN details here.">
139
+ <ul>
140
+ <li>Unlimited bandwidth</li>
141
+ <li>200+ server locations</li>
142
+ <li>No-log policy</li>
143
+ </ul>
144
+ </bd-carousel-item>
145
+ <bd-carousel-item title="Antivirus" icon="/assets/antivirus.svg" modalText="Antivirus details here.">
146
+ <p>Real-time protection</p>
147
+ <a href="#">Learn more</a>
148
+ </bd-carousel-item>
149
+ <bd-carousel-item title="Parental Controls" icon="/assets/parental.svg" modalText="Parental control details.">
150
+ <p>Safe browsing for kids</p>
151
+ <p>Screen time management</p>
152
+ </bd-carousel-item>
153
+ </bd-carousel-section>
154
+ `,
155
+ parameters: { docs: { description: { story: 'Items with lists, links, and multiple paragraphs as slotted content.' } } }
156
+ };
157
+
158
+ export const ModalTrigger = {
159
+ name : 'Modal — Click + to Open',
160
+ render: () => html`
161
+ <p style="font-size:14px; margin-bottom:12px;">Click the <strong>+</strong> button on any card to open the modal.</p>
162
+ <bd-carousel-section title="Features">
163
+ ${sampleItems.slice(0, 3).map(renderItem)}
164
+ </bd-carousel-section>
165
+ `,
166
+ parameters: { docs: { description: { story: 'Demonstrates the modal flow. Click `+` on a card to fire `open-modal`, which renders `<bd-modal>` with the item\'s title and modalText.' } } }
167
+ };
168
+
169
+ export const MobileView = {
170
+ name : 'Mobile View (375px)',
171
+ render: () => html`
172
+ <bd-carousel-section title="Security Features">
173
+ ${sampleItems.map(renderItem)}
174
+ </bd-carousel-section>
175
+ `,
176
+ parameters: {
177
+ viewport: { defaultViewport: 'mobile1' },
178
+ docs : { description: { story: 'Carousel at 375px. Touch drag scrolling is supported.' } }
179
+ }
180
+ };
181
+
182
+ export const Playground = {
183
+ name: '🛝 Playground',
184
+ args: {
185
+ title : 'Security Features',
186
+ itemTitle: 'VPN Protection',
187
+ itemIcon : '/assets/vpn.svg',
188
+ modalText: 'Our VPN encrypts your connection and protects your privacy.'
189
+ },
190
+ render: (args) => html`
191
+ <bd-carousel-section title="${args.title}">
192
+ <bd-carousel-item title="${args.itemTitle}" icon="${args.itemIcon}" modalText="${args.modalText}">
193
+ <p>Slotted content for this item.</p>
194
+ </bd-carousel-item>
195
+ <bd-carousel-item title="Antivirus" icon="/assets/antivirus.svg" modalText="Real-time antivirus protection.">
196
+ <p>Award-winning threat detection</p>
197
+ </bd-carousel-item>
198
+ <bd-carousel-item title="Parental Controls" icon="/assets/parental.svg" modalText="Monitor your children's activity.">
199
+ <p>Advanced content filtering</p>
200
+ </bd-carousel-item>
201
+ </bd-carousel-section>
202
+ `,
203
+ parameters: { docs: { description: { story: 'Interactive playground. Modify the section title and first item props via Controls.' } } }
233
204
  };
@@ -2,62 +2,147 @@ import { html } from 'lit';
2
2
  import './checkbox.js';
3
3
 
4
4
  export default {
5
- title: 'Atoms/Checkbox',
6
- component: 'bd-checkbox',
7
- tags: ['autodocs'], // activează Docs
8
- argTypes: {
9
- name: { control: 'text' },
10
- value: { control: 'text' },
11
- label: { control: 'text' },
12
- checked: { control: 'boolean' },
13
- disabled: { control: 'boolean' },
5
+ title : 'Components/Checkbox',
6
+ tags : ['autodocs'],
7
+ parameters: {
8
+ docs: {
9
+ description: {
10
+ component: `
11
+ **BdCheckbox** is a fully accessible Lit checkbox component.
12
+
13
+ ### Usage
14
+ \`\`\`html
15
+ <bd-checkbox label="Accept terms" name="terms" value="accepted"></bd-checkbox>
16
+ <bd-checkbox label="Disabled" disabled></bd-checkbox>
17
+ <bd-checkbox label="Pre-checked" checked></bd-checkbox>
18
+ \`\`\`
19
+
20
+ ### Accessibility
21
+ - Uses \`role="checkbox"\` with \`aria-checked\` and \`aria-disabled\`
22
+ - Keyboard support: Space and Enter toggle the checkbox
23
+ - Focus ring appears only on keyboard navigation (Tab), not on mouse click
24
+ - \`tabindex="-1"\` when disabled
25
+
26
+ ### Events
27
+ - \`change\` — fires with \`detail: { value }\` where value is the checkbox's \`value\` prop when checked, or \`null\` when unchecked
28
+ `
29
+ }
30
+ }
14
31
  },
32
+ argTypes: {
33
+ label: {
34
+ control : 'text',
35
+ description: 'Visible text label rendered next to the checkbox',
36
+ table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'Content' }
37
+ },
38
+ name: {
39
+ control : 'text',
40
+ description: 'Form field name',
41
+ table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'Form' }
42
+ },
43
+ value: {
44
+ control : 'text',
45
+ description: 'Value emitted in the `change` event detail when checked',
46
+ table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'Form' }
47
+ },
48
+ checked: {
49
+ control : 'boolean',
50
+ description: 'Whether the checkbox is checked',
51
+ table : { type: { summary: 'boolean' }, defaultValue: { summary: 'false' }, category: 'State' }
52
+ },
53
+ disabled: {
54
+ control : 'boolean',
55
+ description: 'Disables interaction and applies disabled styles',
56
+ table : { type: { summary: 'boolean' }, defaultValue: { summary: 'false' }, category: 'State' }
57
+ }
58
+ }
15
59
  };
16
60
 
17
- // Template de bază
18
- const Template = ({ name, value, label, checked, disabled }) => html`
61
+ const render = (args) => html`
19
62
  <bd-checkbox
20
- .name=${name}
21
- .value=${value}
22
- .label=${label}
23
- .checked=${checked}
24
- .disabled=${disabled}
63
+ label="${args.label}"
64
+ name="${args.name}"
65
+ value="${args.value}"
66
+ ?checked="${args.checked}"
67
+ ?disabled="${args.disabled}"
25
68
  ></bd-checkbox>
26
69
  `;
27
70
 
28
- // Exemple BdCheckbox
29
- export const Default = Template.bind({});
30
- Default.args = {
31
- name: 'group1',
32
- value: 'default',
33
- label: 'Checkbox normal',
34
- checked: false,
35
- disabled: false,
36
- };
37
-
38
- export const Checked = Template.bind({});
39
- Checked.args = {
40
- name: 'group1',
41
- value: 'checked',
42
- label: 'Checkbox checked',
43
- checked: true,
44
- disabled: false,
45
- };
46
-
47
- export const Disabled = Template.bind({});
48
- Disabled.args = {
49
- name: 'group1',
50
- value: 'disabled',
51
- label: 'Checkbox disabled',
52
- checked: false,
53
- disabled: true,
54
- };
55
-
56
- export const DisabledChecked = Template.bind({});
57
- DisabledChecked.args = {
58
- name: 'group1',
59
- value: 'disabled-checked',
60
- label: 'Checkbox disabled & checked',
61
- checked: true,
62
- disabled: true,
71
+ const defaultArgs = { label: 'Accept terms and conditions', name: 'terms', value: 'accepted', checked: false, disabled: false };
72
+
73
+ // ─── Stories ───────────────────────────────────────────────────────────────
74
+
75
+ export const Default = {
76
+ name : 'Default (Unchecked)',
77
+ render : () => html`<bd-checkbox label="Accept terms and conditions" name="terms" value="accepted"></bd-checkbox>`,
78
+ parameters: { docs: { description: { story: 'Default unchecked checkbox.' } } }
79
+ };
80
+
81
+ export const Checked = {
82
+ name : 'Checked',
83
+ render : () => html`<bd-checkbox label="I agree to the privacy policy" name="privacy" value="agreed" checked></bd-checkbox>`,
84
+ parameters: { docs: { description: { story: 'Checkbox pre-checked via the `checked` attribute.' } } }
85
+ };
86
+
87
+ export const Disabled = {
88
+ name : 'Disabled (Unchecked)',
89
+ render : () => html`<bd-checkbox label="This option is unavailable" name="unavailable" value="n/a" disabled></bd-checkbox>`,
90
+ parameters: { docs: { description: { story: 'Disabled checkbox — not interactable, `tabindex="-1"`, `aria-disabled="true"`.' } } }
63
91
  };
92
+
93
+ export const DisabledChecked = {
94
+ name : 'Disabled (Checked)',
95
+ render : () => html`<bd-checkbox label="Already selected (locked)" name="locked" value="locked" checked disabled></bd-checkbox>`,
96
+ parameters: { docs: { description: { story: 'Disabled checkbox in the checked state — locked selection.' } } }
97
+ };
98
+
99
+ export const NoLabel = {
100
+ name : 'No Label',
101
+ render : () => html`<bd-checkbox name="no-label" value="yes"></bd-checkbox>`,
102
+ parameters: { docs: { description: { story: 'Checkbox with no visible label text.' } } }
103
+ };
104
+
105
+ export const AllStates = {
106
+ name : 'All States',
107
+ render: () => html`
108
+ <div style="display:flex; flex-direction:column; gap:12px;">
109
+ <bd-checkbox label="Unchecked" name="s1" value="1"></bd-checkbox>
110
+ <bd-checkbox label="Checked" name="s2" value="2" checked></bd-checkbox>
111
+ <bd-checkbox label="Disabled unchecked" name="s3" value="3" disabled></bd-checkbox>
112
+ <bd-checkbox label="Disabled checked" name="s4" value="4" checked disabled></bd-checkbox>
113
+ </div>
114
+ `,
115
+ parameters: { docs: { description: { story: 'All four checkbox states side by side: unchecked, checked, disabled unchecked, disabled checked.' } } }
116
+ };
117
+
118
+ export const Group = {
119
+ name : 'Checkbox Group',
120
+ render: () => html`
121
+ <fieldset style="border:none; padding:0;">
122
+ <legend style="font-weight:600; margin-bottom:12px;">Select your platforms</legend>
123
+ <div style="display:flex; flex-direction:column; gap:8px;">
124
+ <bd-checkbox label="Windows" name="platform" value="windows" checked></bd-checkbox>
125
+ <bd-checkbox label="macOS" name="platform" value="macos"></bd-checkbox>
126
+ <bd-checkbox label="Android" name="platform" value="android" checked></bd-checkbox>
127
+ <bd-checkbox label="iOS" name="platform" value="ios"></bd-checkbox>
128
+ </div>
129
+ </fieldset>
130
+ `,
131
+ parameters: { docs: { description: { story: 'A group of checkboxes simulating a multi-select form field.' } } }
132
+ };
133
+
134
+ export const KeyboardFocus = {
135
+ name : 'Keyboard Focus',
136
+ render: () => html`
137
+ <p style="font-size:14px; margin-bottom:8px;">Tab to focus, Space or Enter to toggle.</p>
138
+ <bd-checkbox label="Keyboard accessible checkbox" name="kb" value="kb"></bd-checkbox>
139
+ `,
140
+ parameters: { docs: { description: { story: 'Focus ring appears only via keyboard Tab navigation. Clicking with mouse does not show the focus ring.' } } }
141
+ };
142
+
143
+ export const Playground = {
144
+ name : '🛝 Playground',
145
+ args : { ...defaultArgs },
146
+ render,
147
+ parameters: { docs: { description: { story: 'Interactive playground. Toggle checked, disabled, and edit label/value via Controls.' } } }
148
+ };