@repobit/dex-system-design 0.22.12 β†’ 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 +32 -0
  2. package/package.json +3 -2
  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
@@ -2,102 +2,251 @@ import { html } from 'lit';
2
2
  import './radio.js';
3
3
 
4
4
  export default {
5
- title: 'Atoms/Radio',
6
- component: 'bd-radio',
7
- tags: ['autodocs'], // πŸ‘‰ Asta 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/Radio',
6
+ tags : ['autodocs'],
7
+ parameters: {
8
+ docs: {
9
+ description: {
10
+ component: `
11
+ Two radio components are available:
12
+
13
+ - \`<bd-radio>\` β€” a standard radio button (once selected, stays selected; dispatches value on change)
14
+ - \`<bd-toggle-radio>\` β€” a toggleable radio that can be unchecked again (behaves like a checkbox with radio styling)
15
+
16
+ ### Usage
17
+ \`\`\`html
18
+ <bd-radio name="plan" value="basic" label="Basic Plan"></bd-radio>
19
+ <bd-radio name="plan" value="premium" label="Premium Plan" checked></bd-radio>
20
+ <bd-toggle-radio name="addon" value="vpn" label="Add VPN"></bd-toggle-radio>
21
+ \`\`\`
22
+
23
+ ### Key Differences
24
+ | Feature | bd-radio | bd-toggle-radio |
25
+ |---|---|---|
26
+ | Can be unchecked | No | Yes |
27
+ | role | \`radio\` | \`checkbox\` |
28
+ | change detail | \`{ value }\` always | \`{ value }\` or \`null\` when unchecked |
29
+
30
+ ### Accessibility
31
+ - Both use \`role\`, \`aria-checked\`, \`aria-disabled\`
32
+ - Keyboard: Space and Enter toggle the state
33
+ - Focus ring appears only on keyboard Tab navigation
34
+ - \`tabindex="-1"\` when disabled
35
+
36
+ ### Events
37
+ - \`change\` β€” CustomEvent with \`detail: { value }\`
38
+ `
39
+ }
40
+ }
14
41
  },
42
+ argTypes: {
43
+ label: {
44
+ control : 'text',
45
+ description: 'Visible label text rendered next to the radio',
46
+ table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'Content' }
47
+ },
48
+ name: {
49
+ control : 'text',
50
+ description: 'Form group name for the radio',
51
+ table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'Form' }
52
+ },
53
+ value: {
54
+ control : 'text',
55
+ description: 'Value emitted in the change event detail',
56
+ table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'Form' }
57
+ },
58
+ checked: {
59
+ control : 'boolean',
60
+ description: 'Whether the radio is selected',
61
+ table : { type: { summary: 'boolean' }, defaultValue: { summary: 'false' }, category: 'State' }
62
+ },
63
+ disabled: {
64
+ control : 'boolean',
65
+ description: 'Disables interaction and applies disabled styles',
66
+ table : { type: { summary: 'boolean' }, defaultValue: { summary: 'false' }, category: 'State' }
67
+ }
68
+ }
15
69
  };
16
70
 
17
- // πŸ‘‡ Template de bazΔƒ
18
- const Template = ({ name, value, label, checked, disabled }) => html`
71
+ const radioArgs = { label: 'Select this option', name: 'plan', value: 'basic', checked: false, disabled: false };
72
+
73
+ const renderRadio = (args) => html`
19
74
  <bd-radio
20
- .name=${name}
21
- .value=${value}
22
- .label=${label}
23
- .checked=${checked}
24
- .disabled=${disabled}
75
+ label="${args.label}"
76
+ name="${args.name}"
77
+ value="${args.value}"
78
+ ?checked="${args.checked}"
79
+ ?disabled="${args.disabled}"
25
80
  ></bd-radio>
26
81
  `;
27
82
 
28
- // πŸ‘‰ Exemples BdRadio
29
- export const Default = Template.bind({});
30
- Default.args = {
31
- name: 'group1',
32
- value: 'default',
33
- label: 'Radio 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: 'Radio 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: 'Radio 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: 'Radio disabled & checked',
61
- checked: true,
62
- disabled: true,
63
- };
64
-
65
- // ------------------------------
66
- // BdToggleRadio
67
- // ------------------------------
68
- export const ToggleRadio = ({ name, value, label, checked, disabled }) => html`
83
+ const renderToggle = (args) => html`
69
84
  <bd-toggle-radio
70
- .name=${name}
71
- .value=${value}
72
- .label=${label}
73
- .checked=${checked}
74
- .disabled=${disabled}
85
+ label="${args.label}"
86
+ name="${args.name}"
87
+ value="${args.value}"
88
+ ?checked="${args.checked}"
89
+ ?disabled="${args.disabled}"
75
90
  ></bd-toggle-radio>
76
91
  `;
77
92
 
78
- ToggleRadio.args = {
79
- name: 'toggle-group',
80
- value: 'toggle1',
81
- label: 'Toggle radio',
82
- checked: false,
83
- disabled: false,
93
+ // ─── bd-radio Stories ──────────────────────────────────────────────────────
94
+
95
+ export const RadioDefault = {
96
+ name : 'Radio β€” Default (Unchecked)',
97
+ render : () => html`<bd-radio name="plan" value="basic" label="Basic Plan"></bd-radio>`,
98
+ parameters: { docs: { description: { story: 'Default unchecked radio button.' } } }
99
+ };
100
+
101
+ export const RadioChecked = {
102
+ name : 'Radio β€” Checked',
103
+ render : () => html`<bd-radio name="plan" value="premium" label="Premium Plan" checked></bd-radio>`,
104
+ parameters: { docs: { description: { story: 'Radio pre-selected via the `checked` attribute.' } } }
105
+ };
106
+
107
+ export const RadioDisabled = {
108
+ name : 'Radio β€” Disabled (Unchecked)',
109
+ render : () => html`<bd-radio name="plan" value="enterprise" label="Enterprise (unavailable)" disabled></bd-radio>`,
110
+ parameters: { docs: { description: { story: 'Disabled radio β€” not interactable, `tabindex="-1"`, `aria-disabled="true"`.' } } }
111
+ };
112
+
113
+ export const RadioDisabledChecked = {
114
+ name : 'Radio β€” Disabled (Checked)',
115
+ render : () => html`<bd-radio name="plan" value="locked" label="Locked selection" checked disabled></bd-radio>`,
116
+ parameters: { docs: { description: { story: 'Disabled radio in the checked/selected state β€” locked selection.' } } }
117
+ };
118
+
119
+ export const RadioAllStates = {
120
+ name : 'Radio β€” All States',
121
+ render: () => html`
122
+ <div style="display:flex; flex-direction:column; gap:12px;">
123
+ <bd-radio name="s1" value="1" label="Unchecked"></bd-radio>
124
+ <bd-radio name="s2" value="2" label="Checked" checked></bd-radio>
125
+ <bd-radio name="s3" value="3" label="Disabled unchecked" disabled></bd-radio>
126
+ <bd-radio name="s4" value="4" label="Disabled checked" checked disabled></bd-radio>
127
+ </div>
128
+ `,
129
+ parameters: { docs: { description: { story: 'All four radio states: unchecked, checked, disabled unchecked, disabled checked.' } } }
84
130
  };
85
131
 
86
- export const ToggleChecked = ToggleRadio.bind({});
87
- ToggleChecked.args = {
88
- ...ToggleRadio.args,
89
- checked: true,
132
+ export const RadioGroup = {
133
+ name : 'Radio β€” Group (Single Select)',
134
+ render: () => html`
135
+ <fieldset style="border:none; padding:0;">
136
+ <legend style="font-weight:600; margin-bottom:12px;">Choose your plan</legend>
137
+ <div style="display:flex; flex-direction:column; gap:8px;">
138
+ <bd-radio name="plan" value="basic" label="Basic β€” 1 device" checked></bd-radio>
139
+ <bd-radio name="plan" value="standard" label="Standard β€” 3 devices"></bd-radio>
140
+ <bd-radio name="plan" value="premium" label="Premium β€” 5 devices"></bd-radio>
141
+ <bd-radio name="plan" value="unlimited" label="Unlimited devices" disabled></bd-radio>
142
+ </div>
143
+ </fieldset>
144
+ `,
145
+ parameters: { docs: { description: { story: 'A group of radio buttons sharing the same `name`. Only one can be selected at a time. Note: mutual exclusivity requires a parent controller β€” `bd-radio` does not auto-deselect siblings.' } } }
90
146
  };
91
147
 
92
- export const ToggleDisabled = ToggleRadio.bind({});
93
- ToggleDisabled.args = {
94
- ...ToggleRadio.args,
95
- disabled: true,
148
+ export const RadioKeyboard = {
149
+ name : 'Radio β€” Keyboard Navigation',
150
+ render: () => html`
151
+ <p style="font-size:14px; margin-bottom:8px;">Tab to focus, Space or Enter to select.</p>
152
+ <div style="display:flex; flex-direction:column; gap:8px;">
153
+ <bd-radio name="kb" value="a" label="Option A"></bd-radio>
154
+ <bd-radio name="kb" value="b" label="Option B"></bd-radio>
155
+ <bd-radio name="kb" value="c" label="Option C"></bd-radio>
156
+ </div>
157
+ `,
158
+ parameters: { docs: { description: { story: 'Focus ring appears only via keyboard Tab navigation. Clicking with mouse does not show the focus ring.' } } }
96
159
  };
97
160
 
98
- export const ToggleDisabledChecked = ToggleRadio.bind({});
99
- ToggleDisabledChecked.args = {
100
- ...ToggleRadio.args,
101
- checked: true,
102
- disabled: true,
161
+ // ─── bd-toggle-radio Stories ───────────────────────────────────────────────
162
+
163
+ export const ToggleRadioDefault = {
164
+ name : 'ToggleRadio β€” Default (Unchecked)',
165
+ render : () => html`<bd-toggle-radio name="addon" value="vpn" label="Add VPN"></bd-toggle-radio>`,
166
+ parameters: { docs: { description: { story: 'Default unchecked toggle radio. Unlike `bd-radio`, clicking again will uncheck it.' } } }
167
+ };
168
+
169
+ export const ToggleRadioChecked = {
170
+ name : 'ToggleRadio β€” Checked',
171
+ render : () => html`<bd-toggle-radio name="addon" value="vpn" label="VPN Enabled" checked></bd-toggle-radio>`,
172
+ parameters: { docs: { description: { story: 'Toggle radio pre-checked. Clicking toggles it off and emits `{ value: null }`.' } } }
173
+ };
174
+
175
+ export const ToggleRadioDisabled = {
176
+ name : 'ToggleRadio β€” Disabled',
177
+ render : () => html`<bd-toggle-radio name="addon" value="parental" label="Parental Controls (unavailable)" disabled></bd-toggle-radio>`,
178
+ parameters: { docs: { description: { story: 'Disabled toggle radio β€” cannot be interacted with.' } } }
179
+ };
180
+
181
+ export const ToggleRadioDisabledChecked = {
182
+ name : 'ToggleRadio β€” Disabled Checked',
183
+ render : () => html`<bd-toggle-radio name="addon" value="firewall" label="Firewall (always on)" checked disabled></bd-toggle-radio>`,
184
+ parameters: { docs: { description: { story: 'Disabled toggle in the checked state β€” locked feature.' } } }
185
+ };
186
+
187
+ export const ToggleRadioAllStates = {
188
+ name : 'ToggleRadio β€” All States',
189
+ render: () => html`
190
+ <div style="display:flex; flex-direction:column; gap:12px;">
191
+ <bd-toggle-radio name="t1" value="1" label="Unchecked"></bd-toggle-radio>
192
+ <bd-toggle-radio name="t2" value="2" label="Checked" checked></bd-toggle-radio>
193
+ <bd-toggle-radio name="t3" value="3" label="Disabled unchecked" disabled></bd-toggle-radio>
194
+ <bd-toggle-radio name="t4" value="4" label="Disabled checked" checked disabled></bd-toggle-radio>
195
+ </div>
196
+ `,
197
+ parameters: { docs: { description: { story: 'All four toggle radio states side by side.' } } }
103
198
  };
199
+
200
+ export const ToggleRadioGroup = {
201
+ name : 'ToggleRadio β€” Add-on Group',
202
+ render: () => html`
203
+ <fieldset style="border:none; padding:0;">
204
+ <legend style="font-weight:600; margin-bottom:12px;">Optional add-ons</legend>
205
+ <div style="display:flex; flex-direction:column; gap:8px;">
206
+ <bd-toggle-radio name="addon" value="vpn" label="VPN Protection" checked></bd-toggle-radio>
207
+ <bd-toggle-radio name="addon" value="password" label="Password Manager"></bd-toggle-radio>
208
+ <bd-toggle-radio name="addon" value="parental" label="Parental Controls"></bd-toggle-radio>
209
+ </div>
210
+ </fieldset>
211
+ `,
212
+ parameters: { docs: { description: { story: 'Multiple toggle radios as independent on/off add-on selectors. Each can be toggled independently.' } } }
213
+ };
214
+
215
+ // ─── Combined ──────────────────────────────────────────────────────────────
216
+
217
+ export const BothTypes = {
218
+ name : 'Both Types Side by Side',
219
+ render: () => html`
220
+ <div style="display:flex; gap:48px; flex-wrap:wrap;">
221
+ <div>
222
+ <p style="font-weight:600; margin-bottom:8px;">bd-radio (stays selected)</p>
223
+ <div style="display:flex; flex-direction:column; gap:8px;">
224
+ <bd-radio name="compare" value="a" label="Option A" checked></bd-radio>
225
+ <bd-radio name="compare" value="b" label="Option B"></bd-radio>
226
+ </div>
227
+ </div>
228
+ <div>
229
+ <p style="font-weight:600; margin-bottom:8px;">bd-toggle-radio (can uncheck)</p>
230
+ <div style="display:flex; flex-direction:column; gap:8px;">
231
+ <bd-toggle-radio name="toggle-compare" value="x" label="Toggle X" checked></bd-toggle-radio>
232
+ <bd-toggle-radio name="toggle-compare" value="y" label="Toggle Y"></bd-toggle-radio>
233
+ </div>
234
+ </div>
235
+ </div>
236
+ `,
237
+ parameters: { docs: { description: { story: 'Side-by-side comparison of `bd-radio` and `bd-toggle-radio` behavior.' } } }
238
+ };
239
+
240
+ export const PlaygroundRadio = {
241
+ name : 'πŸ› Playground β€” Radio',
242
+ args : { ...radioArgs },
243
+ render : renderRadio,
244
+ parameters: { docs: { description: { story: 'Interactive playground for `bd-radio`. Toggle checked, disabled, and edit label/value via Controls.' } } }
245
+ };
246
+
247
+ export const PlaygroundToggleRadio = {
248
+ name : 'πŸ› Playground β€” ToggleRadio',
249
+ args : { ...radioArgs, label: 'Toggle this option' },
250
+ render : renderToggle,
251
+ parameters: { docs: { description: { story: 'Interactive playground for `bd-toggle-radio`. Toggle checked, disabled, and edit label/value via Controls.' } } }
252
+ };
@@ -1,18 +1,134 @@
1
1
  import { html } from 'lit';
2
- import './tabs.js';
2
+ import './tabs.js';
3
3
 
4
4
  export default {
5
- title: 'Components/Tabs',
6
- component: 'bd-tabs-component',
7
- decorators: [
8
- (story) => html`<div class="tabs">${story()}</div>`,
9
- ],
5
+ title : 'Components/TabsComponent',
6
+ tags : ['autodocs'],
10
7
  parameters: {
11
- layout: 'centered',
8
+ docs: {
9
+ description: {
10
+ component: `
11
+ **TabsComponent** is a Lit component that renders a four-tab feature showcase with image, heading, description, and a "Find out more" link.
12
+
13
+ ### Usage
14
+ \`\`\`html
15
+ <bd-tabs-component></bd-tabs-component>
16
+ \`\`\`
17
+
18
+ ### Tabs
19
+ | Index | Title |
20
+ |---|---|
21
+ | 0 | Privacy Protection |
22
+ | 1 | Identity Protection |
23
+ | 2 | Device Protection |
24
+ | 3 | Financial Insurance |
25
+
26
+ ### Structure
27
+ - A \`<bd-highlight>\` heading with subtitle
28
+ - A row of tab buttons (icon + label), each with \`role="tab"\` and \`aria-selected\`
29
+ - A card with left image (\`<picture>\` with WebP/PNG sources) and right content (heading + description + link)
30
+
31
+ ### Behavior
32
+ - Clicking a tab updates \`selectedTab\` and re-renders the card content
33
+ - Image sources include width/format/optimize query params for responsive loading
34
+ - Active tab has \`bd-selected\` class and \`aria-selected="true"\`
35
+
36
+ ### Accessibility
37
+ - Tab buttons have \`role="tab"\`, \`aria-selected\`, \`aria-controls\`, and \`id\` attributes
38
+ - Content panel has \`aria-labelledby\` linked to the heading
39
+ `
40
+ }
41
+ }
12
42
  },
43
+ argTypes: {
44
+ selectedTab: {
45
+ control : { type: 'select' },
46
+ options : [0, 1, 2, 3],
47
+ description: 'Index of the initially selected tab (0–3)',
48
+ table : { type: { summary: 'number' }, defaultValue: { summary: '0' }, category: 'State' }
49
+ }
50
+ }
13
51
  };
14
52
 
15
- const Template = () => html`<bd-tabs-component></bd-tabs-component>`;
53
+ // ─── Stories ───────────────────────────────────────────────────────────────
54
+
55
+ export const Default = {
56
+ name : 'Default (Tab 0 β€” Privacy Protection)',
57
+ render : () => html`<bd-tabs-component></bd-tabs-component>`,
58
+ parameters: { docs: { description: { story: 'Default state with the first tab (Privacy Protection) selected.' } } }
59
+ };
60
+
61
+ export const Tab1Selected = {
62
+ name : 'Tab 1 β€” Identity Protection',
63
+ render: () => {
64
+ const el = document.createElement('bd-tabs-component');
65
+ el.selectedTab = 1;
66
+ return el;
67
+ },
68
+ parameters: { docs: { description: { story: 'Component initialized with the Identity Protection tab selected.' } } }
69
+ };
70
+
71
+ export const Tab2Selected = {
72
+ name : 'Tab 2 β€” Device Protection',
73
+ render: () => {
74
+ const el = document.createElement('bd-tabs-component');
75
+ el.selectedTab = 2;
76
+ return el;
77
+ },
78
+ parameters: { docs: { description: { story: 'Component initialized with the Device Protection tab selected.' } } }
79
+ };
16
80
 
17
- export const Default = Template.bind({});
18
- Default.storyName = 'Tabs Component';
81
+ export const Tab3Selected = {
82
+ name : 'Tab 3 β€” Financial Insurance',
83
+ render: () => {
84
+ const el = document.createElement('bd-tabs-component');
85
+ el.selectedTab = 3;
86
+ return el;
87
+ },
88
+ parameters: { docs: { description: { story: 'Component initialized with the Financial Insurance tab selected.' } } }
89
+ };
90
+
91
+ export const AllTabsOverview = {
92
+ name : 'All Tabs Overview',
93
+ render: () => html`
94
+ <div style="display:flex; flex-direction:column; gap:64px;">
95
+ <div>
96
+ <p style="font-weight:600; margin-bottom:8px;">Tab 0 β€” Privacy Protection</p>
97
+ <bd-tabs-component></bd-tabs-component>
98
+ </div>
99
+ </div>
100
+ <p style="font-size:14px; margin-top:16px; color:#666;">
101
+ Click the tab buttons above to switch between Privacy, Identity, Device, and Financial Insurance tabs.
102
+ </p>
103
+ `,
104
+ parameters: { docs: { description: { story: 'Full interactive component. Click each tab to see the content switch between the four protection categories.' } } }
105
+ };
106
+
107
+ export const MobileView = {
108
+ name : 'Mobile View (375px)',
109
+ render : () => html`<bd-tabs-component></bd-tabs-component>`,
110
+ parameters: {
111
+ viewport: { defaultViewport: 'mobile1' },
112
+ docs : { description: { story: 'Tabs component at 375px. Tests tab button layout, image sizing, and content reflow on small screens.' } }
113
+ }
114
+ };
115
+
116
+ export const TabletView = {
117
+ name : 'Tablet View (768px)',
118
+ render : () => html`<bd-tabs-component></bd-tabs-component>`,
119
+ parameters: {
120
+ viewport: { defaultViewport: 'tablet' },
121
+ docs : { description: { story: 'Tabs component at 768px tablet width.' } }
122
+ }
123
+ };
124
+
125
+ export const Playground = {
126
+ name : 'πŸ› Playground',
127
+ args : { selectedTab: 0 },
128
+ render: (args) => {
129
+ const el = document.createElement('bd-tabs-component');
130
+ el.selectedTab = args.selectedTab;
131
+ return el;
132
+ },
133
+ parameters: { docs: { description: { story: 'Interactive playground. Use the Controls panel to select which tab is initially active (0–3).' } } }
134
+ };