@shohojdhara/atomix 0.3.15 → 0.4.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.
- package/build-tools/index.d.ts +31 -30
- package/build-tools/package.json +4 -21
- package/dist/atomix.css +20234 -2027
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +76 -2
- package/dist/atomix.min.css.map +1 -1
- package/dist/build-tools/index.d.ts +31 -30
- package/dist/build-tools/package.json +4 -21
- package/dist/charts.js +4 -5
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +87 -10
- package/dist/core.js +673 -480
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +15 -3
- package/dist/forms.js +530 -97
- package/dist/forms.js.map +1 -1
- package/dist/heavy.js +5 -6
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +644 -277
- package/dist/index.esm.js +1948 -1347
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +3333 -2728
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/layout.js.map +1 -1
- package/dist/theme.d.ts +9 -9
- package/dist/theme.js.map +1 -1
- package/package.json +2 -2
- package/scripts/atomix-cli.js +10 -1
- package/scripts/cli/__tests__/utils.test.js +6 -2
- package/scripts/cli/migration-tools.js +2 -2
- package/scripts/cli/theme-bridge.js +7 -9
- package/scripts/cli/utils.js +2 -1
- package/src/components/Accordion/Accordion.stories.tsx +72 -23
- package/src/components/Accordion/Accordion.test.tsx +70 -50
- package/src/components/Accordion/Accordion.tsx +219 -96
- package/src/components/Accordion/AccordionCompound.test.tsx +70 -0
- package/src/components/AtomixGlass/AtomixGlass.test.tsx +1 -1
- package/src/components/AtomixGlass/GlassFilter.tsx +9 -16
- package/src/components/AtomixGlass/glass-utils.ts +4 -3
- package/src/components/AtomixGlass/shader-utils.ts +128 -52
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +1 -1
- package/src/components/AtomixGlass/stories/Shaders.stories.tsx +1 -1
- package/src/components/Avatar/Avatar.stories.tsx +45 -62
- package/src/components/Avatar/Avatar.tsx +58 -56
- package/src/components/Badge/Badge.stories.tsx +20 -9
- package/src/components/Badge/Badge.test.tsx +41 -41
- package/src/components/Badge/Badge.tsx +64 -62
- package/src/components/Block/Block.stories.tsx +14 -4
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +9 -8
- package/src/components/Breadcrumb/Breadcrumb.tsx +173 -65
- package/src/components/Breadcrumb/BreadcrumbCompound.test.tsx +84 -0
- package/src/components/Button/Button.stories.tsx +13 -22
- package/src/components/Button/Button.test.tsx +97 -81
- package/src/components/Button/Button.tsx +46 -14
- package/src/components/Button/ButtonGroup.stories.tsx +37 -32
- package/src/components/Button/ButtonGroup.tsx +4 -15
- package/src/components/Callout/Callout.stories.tsx +166 -918
- package/src/components/Callout/Callout.tsx +196 -84
- package/src/components/Callout/CalloutCompound.test.tsx +72 -0
- package/src/components/Card/Card.stories.tsx +67 -36
- package/src/components/Card/Card.tsx +30 -14
- package/src/components/Chart/AreaChart.tsx +1 -1
- package/src/components/Chart/CandlestickChart.tsx +23 -16
- package/src/components/Chart/Chart.stories.tsx +4 -9
- package/src/components/Chart/Chart.tsx +40 -44
- package/src/components/Chart/ChartRenderer.tsx +39 -12
- package/src/components/Chart/ChartToolbar.tsx +21 -5
- package/src/components/Chart/DonutChart.tsx +1 -1
- package/src/components/Chart/FunnelChart.tsx +4 -1
- package/src/components/Chart/GaugeChart.tsx +3 -1
- package/src/components/Chart/HeatmapChart.tsx +50 -37
- package/src/components/Chart/LineChart.tsx +3 -2
- package/src/components/Chart/MultiAxisChart.tsx +24 -16
- package/src/components/Chart/RadarChart.tsx +19 -17
- package/src/components/Chart/ScatterChart.tsx +29 -21
- package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +6 -2
- package/src/components/ColorModeToggle/ColorModeToggle.tsx +15 -3
- package/src/components/Countdown/Countdown.stories.tsx +7 -7
- package/src/components/DataTable/DataTable.stories.tsx +43 -38
- package/src/components/DataTable/DataTable.test.tsx +26 -148
- package/src/components/DataTable/DataTable.tsx +485 -456
- package/src/components/DatePicker/DatePicker.stories.tsx +32 -47
- package/src/components/DatePicker/DatePicker.tsx +31 -26
- package/src/components/Dropdown/Dropdown.stories.tsx +2 -5
- package/src/components/Dropdown/Dropdown.tsx +425 -298
- package/src/components/Dropdown/DropdownCompound.test.tsx +64 -0
- package/src/components/EdgePanel/EdgePanel.stories.tsx +6 -19
- package/src/components/EdgePanel/EdgePanel.tsx +163 -113
- package/src/components/EdgePanel/EdgePanelCompound.test.tsx +53 -0
- package/src/components/Footer/Footer.stories.tsx +21 -16
- package/src/components/Footer/Footer.tsx +130 -128
- package/src/components/Footer/FooterLink.tsx +2 -2
- package/src/components/Form/Checkbox.test.tsx +49 -49
- package/src/components/Form/Checkbox.tsx +108 -100
- package/src/components/Form/Form.stories.tsx +2 -10
- package/src/components/Form/Input.stories.tsx +22 -39
- package/src/components/Form/Input.test.tsx +38 -44
- package/src/components/Form/Radio.stories.tsx +6 -12
- package/src/components/Form/Radio.tsx +68 -66
- package/src/components/Form/Select.stories.tsx +23 -0
- package/src/components/Form/Select.test.tsx +99 -0
- package/src/components/Form/Select.tsx +239 -186
- package/src/components/Form/SelectOption.tsx +88 -0
- package/src/components/Form/Textarea.test.tsx +27 -32
- package/src/components/Hero/Hero.stories.tsx +93 -23
- package/src/components/Hero/Hero.test.tsx +142 -0
- package/src/components/Hero/Hero.tsx +343 -58
- package/src/components/Icon/index.ts +7 -1
- package/src/components/List/List.test.tsx +62 -0
- package/src/components/List/List.tsx +32 -25
- package/src/components/List/ListItem.tsx +20 -0
- package/src/components/Modal/Modal.stories.tsx +67 -2
- package/src/components/Modal/Modal.tsx +208 -125
- package/src/components/Modal/ModalCompound.test.tsx +94 -0
- package/src/components/Navigation/Menu/MegaMenu.tsx +70 -70
- package/src/components/Navigation/Nav/NavDropdown.tsx +1 -5
- package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +128 -28
- package/src/components/Navigation/SideMenu/SideMenu.tsx +5 -7
- package/src/components/Navigation/SideMenu/SideMenuItem.tsx +4 -5
- package/src/components/Pagination/Pagination.stories.tsx +7 -4
- package/src/components/Pagination/Pagination.tsx +199 -202
- package/src/components/PhotoViewer/PhotoViewer.tsx +4 -1
- package/src/components/Popover/Popover.stories.tsx +99 -192
- package/src/components/Popover/Popover.tsx +41 -37
- package/src/components/Progress/Progress.stories.tsx +35 -44
- package/src/components/River/River.stories.tsx +2 -1
- package/src/components/SectionIntro/SectionIntro.stories.tsx +71 -71
- package/src/components/Slider/Slider.stories.tsx +12 -4
- package/src/components/Spinner/Spinner.stories.tsx +3 -1
- package/src/components/Spinner/Spinner.test.tsx +23 -23
- package/src/components/Spinner/Spinner.tsx +43 -46
- package/src/components/Steps/Steps.stories.tsx +8 -6
- package/src/components/Steps/Steps.tsx +124 -21
- package/src/components/Steps/StepsCompound.test.tsx +81 -0
- package/src/components/Tabs/Tabs.stories.tsx +12 -9
- package/src/components/Tabs/Tabs.tsx +230 -75
- package/src/components/Tabs/TabsCompound.test.tsx +64 -0
- package/src/components/Toggle/Toggle.stories.tsx +27 -13
- package/src/components/Toggle/Toggle.test.tsx +65 -70
- package/src/components/Toggle/Toggle.tsx +4 -1
- package/src/components/Tooltip/Tooltip.stories.tsx +24 -20
- package/src/components/Tooltip/Tooltip.tsx +104 -106
- package/src/components/Upload/Upload.stories.tsx +129 -127
- package/src/components/Upload/Upload.tsx +287 -283
- package/src/components/VideoPlayer/VideoPlayer.tsx +6 -1
- package/src/components/index.ts +13 -2
- package/src/layouts/Grid/Grid.stories.tsx +9 -3
- package/src/layouts/MasonryGrid/MasonryGrid.tsx +5 -1
- package/src/lib/__tests__/theme-tools.test.ts +32 -6
- package/src/lib/composables/index.ts +0 -4
- package/src/lib/composables/shared-mouse-tracker.ts +13 -14
- package/src/lib/composables/useAtomixGlass.ts +102 -60
- package/src/lib/composables/useChartExport.ts +1 -1
- package/src/lib/composables/useDataTable.ts +29 -17
- package/src/lib/composables/useHero.ts +58 -14
- package/src/lib/composables/useHeroBackgroundSlider.ts +2 -9
- package/src/lib/composables/useInput.ts +10 -8
- package/src/lib/composables/useSideMenu.ts +6 -5
- package/src/lib/composables/useTooltip.ts +1 -2
- package/src/lib/composables/useVideoPlayer.ts +44 -35
- package/src/lib/config/index.ts +154 -154
- package/src/lib/constants/cssVariables.ts +29 -29
- package/src/lib/hooks/__tests__/useComponentCustomization.test.ts +2 -6
- package/src/lib/hooks/index.ts +1 -1
- package/src/lib/hooks/useComponentCustomization.ts +11 -17
- package/src/lib/hooks/usePerformanceMonitor.ts +6 -7
- package/src/lib/patterns/__tests__/slots.test.ts +1 -1
- package/src/lib/patterns/index.ts +1 -1
- package/src/lib/patterns/slots.tsx +8 -13
- package/src/lib/storybook/InteractiveDemo.tsx +13 -18
- package/src/lib/storybook/PreviewContainer.tsx +1 -1
- package/src/lib/storybook/VariantsGrid.tsx +3 -7
- package/src/lib/storybook/index.ts +1 -1
- package/src/lib/theme/adapters/cssVariableMapper.ts +47 -74
- package/src/lib/theme/adapters/index.ts +3 -9
- package/src/lib/theme/adapters/themeAdapter.ts +41 -26
- package/src/lib/theme/config/index.ts +1 -1
- package/src/lib/theme/config/types.ts +2 -2
- package/src/lib/theme/config/validator.ts +10 -5
- package/src/lib/theme/constants/constants.ts +2 -2
- package/src/lib/theme/constants/index.ts +1 -2
- package/src/lib/theme/core/__tests__/createTheme.test.ts +20 -22
- package/src/lib/theme/core/composeTheme.ts +32 -26
- package/src/lib/theme/core/createTheme.ts +1 -1
- package/src/lib/theme/core/createThemeObject.ts +308 -301
- package/src/lib/theme/core/index.ts +3 -3
- package/src/lib/theme/devtools/CLI.ts +105 -111
- package/src/lib/theme/devtools/Comparator.tsx +50 -32
- package/src/lib/theme/devtools/DesignTokensCustomizer.stories.tsx +50 -48
- package/src/lib/theme/devtools/DesignTokensCustomizer.tsx +257 -63
- package/src/lib/theme/devtools/Inspector.tsx +75 -60
- package/src/lib/theme/devtools/LiveEditor.tsx +97 -76
- package/src/lib/theme/devtools/Preview.tsx +150 -106
- package/src/lib/theme/devtools/ThemeValidator.ts +29 -21
- package/src/lib/theme/devtools/index.ts +3 -9
- package/src/lib/theme/devtools/useHistory.ts +23 -21
- package/src/lib/theme/errors/errors.ts +12 -11
- package/src/lib/theme/errors/index.ts +2 -7
- package/src/lib/theme/generators/generateCSS.ts +9 -13
- package/src/lib/theme/generators/generateCSSNested.ts +1 -6
- package/src/lib/theme/generators/generateCSSVariables.ts +673 -630
- package/src/lib/theme/generators/index.ts +1 -4
- package/src/lib/theme/i18n/index.ts +1 -1
- package/src/lib/theme/i18n/rtl.ts +13 -13
- package/src/lib/theme/index.ts +7 -16
- package/src/lib/theme/runtime/ThemeApplicator.ts +4 -4
- package/src/lib/theme/runtime/ThemeContext.tsx +1 -1
- package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +19 -23
- package/src/lib/theme/runtime/ThemeProvider.tsx +230 -239
- package/src/lib/theme/runtime/__tests__/ThemeProvider.integration.test.tsx +1 -1
- package/src/lib/theme/runtime/__tests__/ThemeProvider.test.tsx +24 -29
- package/src/lib/theme/runtime/index.ts +2 -5
- package/src/lib/theme/runtime/useTheme.ts +18 -18
- package/src/lib/theme/runtime/useThemeTokens.ts +22 -22
- package/src/lib/theme/test/testTheme.ts +15 -16
- package/src/lib/theme/tokens/index.ts +2 -7
- package/src/lib/theme/tokens/tokens.ts +25 -24
- package/src/lib/theme/types.ts +428 -411
- package/src/lib/theme/utils/__tests__/themeValidation.test.ts +3 -3
- package/src/lib/theme/utils/componentTheming.ts +18 -18
- package/src/lib/theme/utils/domUtils.ts +277 -289
- package/src/lib/theme/utils/index.ts +1 -2
- package/src/lib/theme/utils/injectCSS.ts +10 -14
- package/src/lib/theme/utils/naming.ts +20 -16
- package/src/lib/theme/utils/themeHelpers.ts +10 -12
- package/src/lib/theme/utils/themeUtils.ts +85 -86
- package/src/lib/theme/utils/themeValidation.ts +82 -33
- package/src/lib/theme-tools.ts +8 -6
- package/src/lib/types/components.ts +180 -73
- package/src/lib/types/partProps.ts +1 -1
- package/src/lib/utils/__tests__/componentUtils.test.ts +57 -2
- package/src/lib/utils/__tests__/csv.test.ts +1 -1
- package/src/lib/utils/__tests__/themeNaming.test.ts +117 -0
- package/src/lib/utils/componentUtils.ts +8 -12
- package/src/lib/utils/csv.ts +3 -1
- package/src/lib/utils/dataTableExport.ts +1 -5
- package/src/lib/utils/fontPreloader.ts +10 -19
- package/src/lib/utils/icons.ts +4 -1
- package/src/lib/utils/index.ts +2 -6
- package/src/lib/utils/memoryMonitor.ts +10 -8
- package/src/lib/utils/themeNaming.ts +3 -3
- package/src/styles/01-settings/_index.scss +0 -1
- package/src/styles/01-settings/_settings.colors.scss +8 -8
- package/src/styles/01-settings/_settings.design-tokens.scss +61 -50
- package/src/styles/01-settings/_settings.navbar.scss +1 -1
- package/src/styles/01-settings/_settings.spacing.scss +3 -4
- package/src/styles/01-settings/_settings.tooltip.scss +1 -1
- package/src/styles/01-settings/_settings.typography.scss +1 -1
- package/src/styles/02-tools/_tools.breakpoints.scss +1 -1
- package/src/styles/02-tools/_tools.button.scss +51 -21
- package/src/styles/02-tools/_tools.utility-api.scss +36 -24
- package/src/styles/03-generic/_generic.root.scss +4 -3
- package/src/styles/06-components/_components.atomix-glass.scss +13 -9
- package/src/styles/06-components/_components.button.scss +16 -4
- package/src/styles/06-components/_components.callout.scss +27 -21
- package/src/styles/06-components/_components.card.scss +5 -14
- package/src/styles/06-components/_components.chart.scss +22 -19
- package/src/styles/06-components/_components.checkbox.scss +3 -1
- package/src/styles/06-components/_components.color-mode-toggle.scss +3 -1
- package/src/styles/06-components/_components.edge-panel.scss +9 -2
- package/src/styles/06-components/_components.footer.scss +1 -1
- package/src/styles/06-components/_components.side-menu.scss +5 -5
- package/src/styles/06-components/_components.toggle.scss +18 -0
- package/src/styles/06-components/_index.scss +1 -1
- package/src/styles/06-components/old.chart.styles.scss +0 -2
- package/src/styles/99-utilities/_utilities.border.scss +69 -27
- package/src/styles/99-utilities/_utilities.display.scss +1 -1
- package/src/styles/99-utilities/_utilities.opacity.scss +10 -0
- package/src/styles/99-utilities/_utilities.position.scss +16 -9
- package/src/styles/99-utilities/_utilities.scss +1 -1
- package/src/styles/99-utilities/_utilities.sizes.scss +47 -18
- package/src/styles/99-utilities/_utilities.spacing.scss +118 -66
- package/src/styles/99-utilities/_utilities.text-gradient.scss +30 -30
- package/src/styles/99-utilities/_utilities.text.scss +67 -47
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shohojdhara/atomix",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Atomix Design System - A modern component library for web applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
|
@@ -302,4 +302,4 @@
|
|
|
302
302
|
"publishConfig": {
|
|
303
303
|
"access": "public"
|
|
304
304
|
}
|
|
305
|
-
}
|
|
305
|
+
}
|
package/scripts/atomix-cli.js
CHANGED
|
@@ -78,6 +78,15 @@ const packageJson = JSON.parse(
|
|
|
78
78
|
// CLI Configuration
|
|
79
79
|
const DEBUG = process.env.ATOMIX_DEBUG === 'true' || process.argv.includes('--debug');
|
|
80
80
|
|
|
81
|
+
const SENSITIVE_KEYS = /password|secret|token|api[-_]?key|access[-_]?key|auth[-_]?token|authorization|credential/i;
|
|
82
|
+
|
|
83
|
+
function sensitiveDataReplacer(key, value) {
|
|
84
|
+
if (key && SENSITIVE_KEYS.test(key)) {
|
|
85
|
+
return '***REDACTED***';
|
|
86
|
+
}
|
|
87
|
+
return value;
|
|
88
|
+
}
|
|
89
|
+
|
|
81
90
|
/**
|
|
82
91
|
* Debug logger
|
|
83
92
|
*/
|
|
@@ -85,7 +94,7 @@ function debug(message, data = null) {
|
|
|
85
94
|
if (DEBUG) {
|
|
86
95
|
console.log(chalk.gray(`[DEBUG] ${message}`));
|
|
87
96
|
if (data) {
|
|
88
|
-
console.log(chalk.gray(JSON.stringify(data,
|
|
97
|
+
console.log(chalk.gray(JSON.stringify(data, sensitiveDataReplacer, 2)));
|
|
89
98
|
}
|
|
90
99
|
}
|
|
91
100
|
}
|
|
@@ -115,12 +115,16 @@ describe('CLI Utils', () => {
|
|
|
115
115
|
'command | pipe',
|
|
116
116
|
'`substitution`',
|
|
117
117
|
'$(command)',
|
|
118
|
-
'input > /dev/null'
|
|
118
|
+
'input > /dev/null',
|
|
119
|
+
'"quoted"',
|
|
120
|
+
"'singlequoted'",
|
|
121
|
+
'" $(whoami) "',
|
|
122
|
+
"' ; rm -rf / '"
|
|
119
123
|
];
|
|
120
124
|
|
|
121
125
|
dangerousInputs.forEach(input => {
|
|
122
126
|
const sanitized = sanitizeInput(input);
|
|
123
|
-
expect(sanitized).not.toMatch(/[
|
|
127
|
+
expect(sanitized).not.toMatch(/[;&|`$<>\\"']/);
|
|
124
128
|
});
|
|
125
129
|
});
|
|
126
130
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Helps migrate from other design systems and CSS frameworks
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { readFile, writeFile, readdir,
|
|
6
|
+
import { readFile, writeFile, readdir, lstat } from 'fs/promises';
|
|
7
7
|
import { join, extname, relative } from 'path';
|
|
8
8
|
import chalk from 'chalk';
|
|
9
9
|
import ora from 'ora';
|
|
@@ -329,7 +329,7 @@ async function getAllFiles(dir, extensions = []) {
|
|
|
329
329
|
|
|
330
330
|
for (const entry of entries) {
|
|
331
331
|
const fullPath = join(currentPath, entry);
|
|
332
|
-
const stats = await
|
|
332
|
+
const stats = await lstat(fullPath);
|
|
333
333
|
|
|
334
334
|
if (stats.isDirectory()) {
|
|
335
335
|
// Skip node_modules and hidden directories
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Bridges the TypeScript theme devtools CLI (src/lib/theme/devtools/CLI.ts) with the main JavaScript CLI.
|
|
5
5
|
*
|
|
6
|
-
* @dependency
|
|
6
|
+
* @dependency tsx
|
|
7
7
|
* Theme subcommands (atomix theme validate|list|inspect|compare|export|create) run the TypeScript
|
|
8
|
-
* theme CLI via
|
|
9
|
-
* npm install --save-dev
|
|
10
|
-
* If
|
|
8
|
+
* theme CLI via tsx. Ensure tsx is installed in the project when using these commands:
|
|
9
|
+
* npm install --save-dev tsx
|
|
10
|
+
* If tsx is missing, theme subcommands will fail; run `atomix doctor` to check availability.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { spawn } from 'child_process';
|
|
@@ -29,13 +29,11 @@ export async function executeThemeCommand(command, args = [], options = {}) {
|
|
|
29
29
|
// Path to the theme CLI
|
|
30
30
|
const themeCliPath = join(__dirname, '../../src/lib/theme/devtools/CLI.ts');
|
|
31
31
|
|
|
32
|
-
// Use
|
|
33
|
-
const
|
|
32
|
+
// Use tsx to execute TypeScript CLI
|
|
33
|
+
const tsxPath = join(__dirname, '../../node_modules/.bin/tsx');
|
|
34
34
|
|
|
35
35
|
return new Promise((resolve, reject) => {
|
|
36
|
-
const child = spawn(
|
|
37
|
-
'--esm',
|
|
38
|
-
'--experimental-specifier-resolution=node',
|
|
36
|
+
const child = spawn(tsxPath, [
|
|
39
37
|
themeCliPath,
|
|
40
38
|
command,
|
|
41
39
|
...args
|
package/scripts/cli/utils.js
CHANGED
|
@@ -175,8 +175,9 @@ export function sanitizeInput(input) {
|
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
// Remove any shell metacharacters that could be dangerous
|
|
178
|
+
// Added single and double quotes to the blacklist to prevent shell injection
|
|
178
179
|
return input
|
|
179
|
-
.replace(/[;&|`$<>\\]/g, '')
|
|
180
|
+
.replace(/[;&|`$<>\\"']/g, '')
|
|
180
181
|
.replace(/\0/g, '') // Remove null bytes
|
|
181
182
|
.trim();
|
|
182
183
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
3
|
import { fn } from '@storybook/test';
|
|
4
|
-
import { Accordion } from './Accordion';
|
|
4
|
+
import { Accordion } from './Accordion';
|
|
5
5
|
import { ACCORDION } from '../../lib/constants/components';
|
|
6
6
|
import type { AtomixGlassProps } from '../../lib/types/components';
|
|
7
7
|
|
|
@@ -29,9 +29,7 @@ const mockHandlers = {
|
|
|
29
29
|
// Sample content for stories
|
|
30
30
|
const sampleContent = (
|
|
31
31
|
<div>
|
|
32
|
-
<p>
|
|
33
|
-
This accordion contains rich HTML content including headings, paragraphs, and lists.
|
|
34
|
-
</p>
|
|
32
|
+
<p>This accordion contains rich HTML content including headings, paragraphs, and lists.</p>
|
|
35
33
|
<ul>
|
|
36
34
|
<li>
|
|
37
35
|
List item with <a href="#">link</a>
|
|
@@ -65,6 +63,7 @@ The Accordion component provides an expandable/collapsible container for content
|
|
|
65
63
|
- Glass morphism effect support
|
|
66
64
|
- Keyboard navigation support
|
|
67
65
|
- Disabled state handling
|
|
66
|
+
- **Compound Component Pattern** (new)
|
|
68
67
|
|
|
69
68
|
## Accessibility
|
|
70
69
|
|
|
@@ -83,6 +82,19 @@ The Accordion component provides an expandable/collapsible container for content
|
|
|
83
82
|
</Accordion>
|
|
84
83
|
\`\`\`
|
|
85
84
|
|
|
85
|
+
### Compound Component Usage
|
|
86
|
+
|
|
87
|
+
\`\`\`tsx
|
|
88
|
+
<Accordion>
|
|
89
|
+
<Accordion.Header>
|
|
90
|
+
<span>Custom Header Content</span>
|
|
91
|
+
</Accordion.Header>
|
|
92
|
+
<Accordion.Body>
|
|
93
|
+
<p>Content goes here</p>
|
|
94
|
+
</Accordion.Body>
|
|
95
|
+
</Accordion>
|
|
96
|
+
\`\`\`
|
|
97
|
+
|
|
86
98
|
### With Custom Icon
|
|
87
99
|
|
|
88
100
|
\`\`\`tsx
|
|
@@ -268,6 +280,32 @@ export const WithAllProps: Story = {
|
|
|
268
280
|
},
|
|
269
281
|
};
|
|
270
282
|
|
|
283
|
+
export const CompoundUsage: Story = {
|
|
284
|
+
render: args => (
|
|
285
|
+
<Accordion {...args}>
|
|
286
|
+
<Accordion.Header>
|
|
287
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
288
|
+
<strong>Custom Header Layout</strong>
|
|
289
|
+
<span style={{ fontSize: '0.8em', color: '#666' }}>(with subtitle)</span>
|
|
290
|
+
</div>
|
|
291
|
+
</Accordion.Header>
|
|
292
|
+
<Accordion.Body>
|
|
293
|
+
<p>
|
|
294
|
+
This accordion uses the Compound Component pattern (Accordion.Header and Accordion.Body).
|
|
295
|
+
This allows for complete control over the header layout and content structure.
|
|
296
|
+
</p>
|
|
297
|
+
</Accordion.Body>
|
|
298
|
+
</Accordion>
|
|
299
|
+
),
|
|
300
|
+
parameters: {
|
|
301
|
+
docs: {
|
|
302
|
+
description: {
|
|
303
|
+
story: 'Demonstrates the Compound Component usage pattern for custom header layouts.',
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
};
|
|
308
|
+
|
|
271
309
|
// ============================================================================
|
|
272
310
|
// VARIANTS & STATES STORIES
|
|
273
311
|
// ============================================================================
|
|
@@ -396,28 +434,22 @@ export const ControlledState: Story = {
|
|
|
396
434
|
title: 'Controlled Accordion',
|
|
397
435
|
children: <p>This accordion is controlled by external state.</p>,
|
|
398
436
|
},
|
|
399
|
-
render:
|
|
437
|
+
render: args => {
|
|
400
438
|
const [open, setOpen] = React.useState(false);
|
|
401
439
|
return (
|
|
402
440
|
<div>
|
|
403
|
-
<button
|
|
404
|
-
className="c-btn c-btn--primary u-mb-3"
|
|
405
|
-
onClick={() => setOpen(prev => !prev)}
|
|
406
|
-
>
|
|
441
|
+
<button className="c-btn c-btn--primary u-mb-3" onClick={() => setOpen(prev => !prev)}>
|
|
407
442
|
Toggle Accordion (Controlled)
|
|
408
443
|
</button>
|
|
409
|
-
<Accordion
|
|
410
|
-
{...args}
|
|
411
|
-
isOpen={open}
|
|
412
|
-
onOpenChange={setOpen}
|
|
413
|
-
/>
|
|
444
|
+
<Accordion {...args} isOpen={open} onOpenChange={setOpen} />
|
|
414
445
|
</div>
|
|
415
446
|
);
|
|
416
447
|
},
|
|
417
448
|
parameters: {
|
|
418
449
|
docs: {
|
|
419
450
|
description: {
|
|
420
|
-
story:
|
|
451
|
+
story:
|
|
452
|
+
'This story demonstrates a controlled Accordion using the `isOpen` and `onOpenChange` props.',
|
|
421
453
|
},
|
|
422
454
|
},
|
|
423
455
|
},
|
|
@@ -489,8 +521,14 @@ export const GlassEffect: Story = {
|
|
|
489
521
|
children: <p>This accordion has a glass morphism effect applied.</p>,
|
|
490
522
|
glass: true,
|
|
491
523
|
},
|
|
492
|
-
render:
|
|
493
|
-
<div
|
|
524
|
+
render: args => (
|
|
525
|
+
<div
|
|
526
|
+
className="u-bg-cover u-bg-center u-p-8 u-rounded-xl u-min-h-97vh u-flex u-items-center u-justify-center"
|
|
527
|
+
style={{
|
|
528
|
+
backgroundImage:
|
|
529
|
+
'url(https://images.unsplash.com/photo-1759915995309-404c743bfbf9?q=80&w=3270&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D)',
|
|
530
|
+
}}
|
|
531
|
+
>
|
|
494
532
|
<div className="u-w-full u-max-w-md">
|
|
495
533
|
<Accordion {...args} />
|
|
496
534
|
</div>
|
|
@@ -499,7 +537,8 @@ export const GlassEffect: Story = {
|
|
|
499
537
|
parameters: {
|
|
500
538
|
docs: {
|
|
501
539
|
description: {
|
|
502
|
-
story:
|
|
540
|
+
story:
|
|
541
|
+
'This story demonstrates an Accordion with glass morphism effect enabled against a gradient background.',
|
|
503
542
|
},
|
|
504
543
|
},
|
|
505
544
|
},
|
|
@@ -516,8 +555,16 @@ export const GlassCustom: Story = {
|
|
|
516
555
|
mode: 'polar',
|
|
517
556
|
} as GlassProps,
|
|
518
557
|
},
|
|
519
|
-
render:
|
|
520
|
-
<div
|
|
558
|
+
render: args => (
|
|
559
|
+
<div
|
|
560
|
+
className="u-bg-cover u-bg-center u-p-8 u-rounded-xl u-min-h-97vh u-flex u-items-center u-justify-center"
|
|
561
|
+
style={{
|
|
562
|
+
backgroundImage:
|
|
563
|
+
'url(https://images.unsplash.com/photo-1754147965582-edcb63324a81?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D)',
|
|
564
|
+
backgroundSize: '120%',
|
|
565
|
+
animation: 'gradient 15s ease infinite',
|
|
566
|
+
}}
|
|
567
|
+
>
|
|
521
568
|
<style>
|
|
522
569
|
{`
|
|
523
570
|
@keyframes gradient {
|
|
@@ -538,7 +585,8 @@ export const GlassCustom: Story = {
|
|
|
538
585
|
parameters: {
|
|
539
586
|
docs: {
|
|
540
587
|
description: {
|
|
541
|
-
story:
|
|
588
|
+
story:
|
|
589
|
+
'This story demonstrates an Accordion with custom glass morphism settings against a scenic background image.',
|
|
542
590
|
},
|
|
543
591
|
},
|
|
544
592
|
},
|
|
@@ -567,7 +615,8 @@ export const KeyboardNavigation: Story = {
|
|
|
567
615
|
title: 'Keyboard Accessible',
|
|
568
616
|
children: (
|
|
569
617
|
<p>
|
|
570
|
-
This accordion is fully operable via keyboard navigation. Press Tab to focus and Enter/Space
|
|
618
|
+
This accordion is fully operable via keyboard navigation. Press Tab to focus and Enter/Space
|
|
619
|
+
to toggle.
|
|
571
620
|
</p>
|
|
572
621
|
),
|
|
573
622
|
},
|
|
@@ -578,4 +627,4 @@ export const KeyboardNavigation: Story = {
|
|
|
578
627
|
},
|
|
579
628
|
},
|
|
580
629
|
},
|
|
581
|
-
};
|
|
630
|
+
};
|
|
@@ -4,54 +4,74 @@ import { Accordion } from './Accordion';
|
|
|
4
4
|
import React from 'react';
|
|
5
5
|
|
|
6
6
|
describe('Accordion Component', () => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
7
|
+
it('renders correctly with title', () => {
|
|
8
|
+
render(<Accordion title="Test Accordion">Content</Accordion>);
|
|
9
|
+
expect(screen.getByText('Test Accordion')).toBeInTheDocument();
|
|
10
|
+
expect(screen.getByText('Content')).toBeInTheDocument();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('toggles when clicked', () => {
|
|
14
|
+
const onOpenChange = vi.fn();
|
|
15
|
+
render(
|
|
16
|
+
<Accordion title="Test" onOpenChange={onOpenChange}>
|
|
17
|
+
Content
|
|
18
|
+
</Accordion>
|
|
19
|
+
);
|
|
20
|
+
const button = screen.getByRole('button');
|
|
21
|
+
|
|
22
|
+
fireEvent.click(button);
|
|
23
|
+
expect(onOpenChange).toHaveBeenCalledWith(true);
|
|
24
|
+
expect(button).toHaveAttribute('aria-expanded', 'true');
|
|
25
|
+
|
|
26
|
+
fireEvent.click(button);
|
|
27
|
+
expect(onOpenChange).toHaveBeenCalledWith(false);
|
|
28
|
+
expect(button).toHaveAttribute('aria-expanded', 'false');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('calls legacy onOpen/onClose handlers', () => {
|
|
32
|
+
const onOpen = vi.fn();
|
|
33
|
+
const onClose = vi.fn();
|
|
34
|
+
render(
|
|
35
|
+
<Accordion title="Test" onOpen={onOpen} onClose={onClose}>
|
|
36
|
+
Content
|
|
37
|
+
</Accordion>
|
|
38
|
+
);
|
|
39
|
+
const button = screen.getByRole('button');
|
|
40
|
+
|
|
41
|
+
fireEvent.click(button);
|
|
42
|
+
expect(onOpen).toHaveBeenCalled();
|
|
43
|
+
|
|
44
|
+
fireEvent.click(button);
|
|
45
|
+
expect(onClose).toHaveBeenCalled();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('handles controlled state', () => {
|
|
49
|
+
const onOpenChange = vi.fn();
|
|
50
|
+
const { rerender } = render(
|
|
51
|
+
<Accordion title="Test" isOpen={false} onOpenChange={onOpenChange}>
|
|
52
|
+
Content
|
|
53
|
+
</Accordion>
|
|
54
|
+
);
|
|
55
|
+
const button = screen.getByRole('button');
|
|
56
|
+
|
|
57
|
+
fireEvent.click(button);
|
|
58
|
+
expect(onOpenChange).toHaveBeenCalledWith(true);
|
|
59
|
+
expect(button).toHaveAttribute('aria-expanded', 'false'); // Should not change internally
|
|
60
|
+
|
|
61
|
+
rerender(
|
|
62
|
+
<Accordion title="Test" isOpen={true} onOpenChange={onOpenChange}>
|
|
63
|
+
Content
|
|
64
|
+
</Accordion>
|
|
65
|
+
);
|
|
66
|
+
expect(button).toHaveAttribute('aria-expanded', 'true');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('supports glass effect', () => {
|
|
70
|
+
const { container } = render(
|
|
71
|
+
<Accordion title="Test" glass>
|
|
72
|
+
Content
|
|
73
|
+
</Accordion>
|
|
74
|
+
);
|
|
75
|
+
expect(container.querySelector('.c-accordion--glass')).toBeInTheDocument();
|
|
76
|
+
});
|
|
57
77
|
});
|