@shohojdhara/atomix 0.3.15 → 0.4.0
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 +20924 -2611
- 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.map +1 -1
- package/dist/core.js.map +1 -1
- package/dist/forms.js.map +1 -1
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +144 -18
- package/dist/index.esm.js +110 -55
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +110 -55
- 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 +1 -1
- package/src/components/Accordion/Accordion.stories.tsx +32 -23
- package/src/components/Accordion/Accordion.test.tsx +70 -50
- package/src/components/Accordion/Accordion.tsx +99 -94
- 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 +62 -60
- 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 +109 -16
- 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 +313 -299
- package/src/components/EdgePanel/EdgePanel.stories.tsx +6 -19
- package/src/components/EdgePanel/EdgePanel.tsx +1 -3
- 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.tsx +184 -182
- package/src/components/Form/Textarea.test.tsx +27 -32
- package/src/components/Hero/Hero.stories.tsx +56 -23
- package/src/components/Hero/Hero.tsx +201 -55
- package/src/components/Icon/index.ts +7 -1
- package/src/components/List/List.tsx +19 -23
- package/src/components/Modal/Modal.stories.tsx +2 -1
- package/src/components/Modal/Modal.tsx +130 -127
- 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/Tabs/Tabs.stories.tsx +12 -9
- package/src/components/Tabs/Tabs.tsx +74 -72
- 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/shared-mouse-tracker.ts +13 -14
- package/src/lib/composables/useAtomixGlass.ts +106 -49
- 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 +106 -104
- 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 +172 -71
- package/src/lib/types/partProps.ts +1 -1
- package/src/lib/utils/__tests__/csv.test.ts +1 -1
- 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 +2 -2
- 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.button.scss +51 -21
- package/src/styles/02-tools/_tools.utility-api.scss +30 -18
- 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 -46
package/package.json
CHANGED
|
@@ -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>
|
|
@@ -396,28 +394,22 @@ export const ControlledState: Story = {
|
|
|
396
394
|
title: 'Controlled Accordion',
|
|
397
395
|
children: <p>This accordion is controlled by external state.</p>,
|
|
398
396
|
},
|
|
399
|
-
render:
|
|
397
|
+
render: args => {
|
|
400
398
|
const [open, setOpen] = React.useState(false);
|
|
401
399
|
return (
|
|
402
400
|
<div>
|
|
403
|
-
<button
|
|
404
|
-
className="c-btn c-btn--primary u-mb-3"
|
|
405
|
-
onClick={() => setOpen(prev => !prev)}
|
|
406
|
-
>
|
|
401
|
+
<button className="c-btn c-btn--primary u-mb-3" onClick={() => setOpen(prev => !prev)}>
|
|
407
402
|
Toggle Accordion (Controlled)
|
|
408
403
|
</button>
|
|
409
|
-
<Accordion
|
|
410
|
-
{...args}
|
|
411
|
-
isOpen={open}
|
|
412
|
-
onOpenChange={setOpen}
|
|
413
|
-
/>
|
|
404
|
+
<Accordion {...args} isOpen={open} onOpenChange={setOpen} />
|
|
414
405
|
</div>
|
|
415
406
|
);
|
|
416
407
|
},
|
|
417
408
|
parameters: {
|
|
418
409
|
docs: {
|
|
419
410
|
description: {
|
|
420
|
-
story:
|
|
411
|
+
story:
|
|
412
|
+
'This story demonstrates a controlled Accordion using the `isOpen` and `onOpenChange` props.',
|
|
421
413
|
},
|
|
422
414
|
},
|
|
423
415
|
},
|
|
@@ -489,8 +481,14 @@ export const GlassEffect: Story = {
|
|
|
489
481
|
children: <p>This accordion has a glass morphism effect applied.</p>,
|
|
490
482
|
glass: true,
|
|
491
483
|
},
|
|
492
|
-
render:
|
|
493
|
-
<div
|
|
484
|
+
render: args => (
|
|
485
|
+
<div
|
|
486
|
+
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"
|
|
487
|
+
style={{
|
|
488
|
+
backgroundImage:
|
|
489
|
+
'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)',
|
|
490
|
+
}}
|
|
491
|
+
>
|
|
494
492
|
<div className="u-w-full u-max-w-md">
|
|
495
493
|
<Accordion {...args} />
|
|
496
494
|
</div>
|
|
@@ -499,7 +497,8 @@ export const GlassEffect: Story = {
|
|
|
499
497
|
parameters: {
|
|
500
498
|
docs: {
|
|
501
499
|
description: {
|
|
502
|
-
story:
|
|
500
|
+
story:
|
|
501
|
+
'This story demonstrates an Accordion with glass morphism effect enabled against a gradient background.',
|
|
503
502
|
},
|
|
504
503
|
},
|
|
505
504
|
},
|
|
@@ -516,8 +515,16 @@ export const GlassCustom: Story = {
|
|
|
516
515
|
mode: 'polar',
|
|
517
516
|
} as GlassProps,
|
|
518
517
|
},
|
|
519
|
-
render:
|
|
520
|
-
<div
|
|
518
|
+
render: args => (
|
|
519
|
+
<div
|
|
520
|
+
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"
|
|
521
|
+
style={{
|
|
522
|
+
backgroundImage:
|
|
523
|
+
'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)',
|
|
524
|
+
backgroundSize: '120%',
|
|
525
|
+
animation: 'gradient 15s ease infinite',
|
|
526
|
+
}}
|
|
527
|
+
>
|
|
521
528
|
<style>
|
|
522
529
|
{`
|
|
523
530
|
@keyframes gradient {
|
|
@@ -538,7 +545,8 @@ export const GlassCustom: Story = {
|
|
|
538
545
|
parameters: {
|
|
539
546
|
docs: {
|
|
540
547
|
description: {
|
|
541
|
-
story:
|
|
548
|
+
story:
|
|
549
|
+
'This story demonstrates an Accordion with custom glass morphism settings against a scenic background image.',
|
|
542
550
|
},
|
|
543
551
|
},
|
|
544
552
|
},
|
|
@@ -567,7 +575,8 @@ export const KeyboardNavigation: Story = {
|
|
|
567
575
|
title: 'Keyboard Accessible',
|
|
568
576
|
children: (
|
|
569
577
|
<p>
|
|
570
|
-
This accordion is fully operable via keyboard navigation. Press Tab to focus and Enter/Space
|
|
578
|
+
This accordion is fully operable via keyboard navigation. Press Tab to focus and Enter/Space
|
|
579
|
+
to toggle.
|
|
571
580
|
</p>
|
|
572
581
|
),
|
|
573
582
|
},
|
|
@@ -578,4 +587,4 @@ export const KeyboardNavigation: Story = {
|
|
|
578
587
|
},
|
|
579
588
|
},
|
|
580
589
|
},
|
|
581
|
-
};
|
|
590
|
+
};
|
|
@@ -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
|
});
|
|
@@ -1,120 +1,125 @@
|
|
|
1
1
|
import React, { ReactNode, useId, memo } from 'react';
|
|
2
2
|
import { ACCORDION } from '../../lib/constants/components';
|
|
3
3
|
import { useAccordion } from '../../lib/composables/useAccordion';
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
AccordionProps as AccordionPropsType,
|
|
6
|
+
AtomixGlassProps,
|
|
7
|
+
} from '../../lib/types/components';
|
|
5
8
|
import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
|
|
6
9
|
|
|
7
10
|
export type AccordionProps = AccordionPropsType;
|
|
8
11
|
|
|
9
|
-
export const Accordion: React.FC<AccordionProps> = memo(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
onOpenChange,
|
|
15
|
-
onOpen,
|
|
16
|
-
onClose,
|
|
17
|
-
disabled = false,
|
|
18
|
-
iconPosition = 'right',
|
|
19
|
-
icon,
|
|
20
|
-
className = '',
|
|
21
|
-
style,
|
|
22
|
-
glass,
|
|
23
|
-
}) => {
|
|
24
|
-
// Generate unique IDs for accessibility
|
|
25
|
-
const instanceId = useId();
|
|
26
|
-
const buttonId = `accordion-header-${instanceId}`;
|
|
27
|
-
const panelId = `accordion-panel-${instanceId}`;
|
|
28
|
-
|
|
29
|
-
// Use composable hook for logic/state
|
|
30
|
-
const {
|
|
31
|
-
state,
|
|
32
|
-
toggle,
|
|
33
|
-
updatePanelHeight,
|
|
34
|
-
panelRef,
|
|
35
|
-
contentRef,
|
|
36
|
-
generateClassNames,
|
|
37
|
-
generateHeaderClassNames,
|
|
38
|
-
} = useAccordion({
|
|
39
|
-
defaultOpen,
|
|
40
|
-
disabled,
|
|
41
|
-
iconPosition,
|
|
12
|
+
export const Accordion: React.FC<AccordionProps> = memo(
|
|
13
|
+
({
|
|
14
|
+
title,
|
|
15
|
+
children,
|
|
16
|
+
defaultOpen = false,
|
|
42
17
|
isOpen: controlledOpen,
|
|
43
18
|
onOpenChange,
|
|
44
19
|
onOpen,
|
|
45
20
|
onClose,
|
|
46
|
-
|
|
21
|
+
disabled = false,
|
|
22
|
+
iconPosition = 'right',
|
|
23
|
+
icon,
|
|
24
|
+
className = '',
|
|
25
|
+
style,
|
|
26
|
+
glass,
|
|
27
|
+
}) => {
|
|
28
|
+
// Generate unique IDs for accessibility
|
|
29
|
+
const instanceId = useId();
|
|
30
|
+
const buttonId = `accordion-header-${instanceId}`;
|
|
31
|
+
const panelId = `accordion-panel-${instanceId}`;
|
|
47
32
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
</i>
|
|
67
|
-
);
|
|
33
|
+
// Use composable hook for logic/state
|
|
34
|
+
const {
|
|
35
|
+
state,
|
|
36
|
+
toggle,
|
|
37
|
+
updatePanelHeight,
|
|
38
|
+
panelRef,
|
|
39
|
+
contentRef,
|
|
40
|
+
generateClassNames,
|
|
41
|
+
generateHeaderClassNames,
|
|
42
|
+
} = useAccordion({
|
|
43
|
+
defaultOpen,
|
|
44
|
+
disabled,
|
|
45
|
+
iconPosition,
|
|
46
|
+
isOpen: controlledOpen,
|
|
47
|
+
onOpenChange,
|
|
48
|
+
onOpen,
|
|
49
|
+
onClose,
|
|
50
|
+
});
|
|
68
51
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
className=
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
52
|
+
// Default icon
|
|
53
|
+
const defaultIcon = (
|
|
54
|
+
<i className="c-accordion__icon" aria-hidden="true">
|
|
55
|
+
<svg
|
|
56
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
57
|
+
width="24"
|
|
58
|
+
height="24"
|
|
59
|
+
viewBox="0 0 24 24"
|
|
60
|
+
fill="none"
|
|
61
|
+
stroke="currentColor"
|
|
62
|
+
strokeWidth="2"
|
|
63
|
+
strokeLinecap="round"
|
|
64
|
+
strokeLinejoin="round"
|
|
65
|
+
aria-hidden="true"
|
|
66
|
+
focusable="false"
|
|
67
|
+
>
|
|
68
|
+
<polyline points="6 9 12 15 18 9"></polyline>
|
|
69
|
+
</svg>
|
|
70
|
+
</i>
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const accordionContent = (
|
|
87
74
|
<div
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
ref={panelRef as React.RefObject<HTMLDivElement>}
|
|
91
|
-
role="region"
|
|
92
|
-
aria-labelledby={buttonId}
|
|
75
|
+
className={generateClassNames(className) + (glass ? ' c-accordion--glass' : '')}
|
|
76
|
+
style={style}
|
|
93
77
|
>
|
|
78
|
+
<button
|
|
79
|
+
id={buttonId}
|
|
80
|
+
className={generateHeaderClassNames()}
|
|
81
|
+
onClick={toggle}
|
|
82
|
+
aria-expanded={state.isOpen}
|
|
83
|
+
aria-controls={panelId}
|
|
84
|
+
aria-disabled={disabled}
|
|
85
|
+
disabled={disabled}
|
|
86
|
+
type="button"
|
|
87
|
+
>
|
|
88
|
+
<span className="c-accordion__title">{title}</span>
|
|
89
|
+
{icon || defaultIcon}
|
|
90
|
+
</button>
|
|
94
91
|
<div
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
id={panelId}
|
|
93
|
+
className={ACCORDION.SELECTORS.PANEL.replace('.', '')}
|
|
94
|
+
ref={panelRef as React.RefObject<HTMLDivElement>}
|
|
95
|
+
role="region"
|
|
96
|
+
aria-labelledby={buttonId}
|
|
97
97
|
>
|
|
98
|
-
|
|
98
|
+
<div
|
|
99
|
+
className={ACCORDION.SELECTORS.BODY.replace('.', '')}
|
|
100
|
+
ref={contentRef as React.RefObject<HTMLDivElement>}
|
|
101
|
+
>
|
|
102
|
+
{children}
|
|
103
|
+
</div>
|
|
99
104
|
</div>
|
|
100
105
|
</div>
|
|
101
|
-
|
|
102
|
-
);
|
|
106
|
+
);
|
|
103
107
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
if (glass) {
|
|
109
|
+
// Default glass settings for accordions
|
|
110
|
+
const defaultGlassProps = {
|
|
111
|
+
displacementScale: 20,
|
|
112
|
+
elasticity: 0,
|
|
113
|
+
};
|
|
110
114
|
|
|
111
|
-
|
|
115
|
+
const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
|
|
112
116
|
|
|
113
|
-
|
|
114
|
-
|
|
117
|
+
return <AtomixGlass {...glassProps}>{accordionContent}</AtomixGlass>;
|
|
118
|
+
}
|
|
115
119
|
|
|
116
|
-
|
|
117
|
-
}
|
|
120
|
+
return accordionContent;
|
|
121
|
+
}
|
|
122
|
+
);
|
|
118
123
|
|
|
119
124
|
// Set display name for debugging
|
|
120
125
|
Accordion.displayName = 'Accordion';
|
|
@@ -35,12 +35,7 @@ const GlassFilterComponent: React.FC<GlassFilterProps> = ({
|
|
|
35
35
|
aria-hidden="true"
|
|
36
36
|
>
|
|
37
37
|
<defs>
|
|
38
|
-
<radialGradient
|
|
39
|
-
id={`${id}-edge-mask`}
|
|
40
|
-
cx="50%"
|
|
41
|
-
cy="50%"
|
|
42
|
-
r="50%"
|
|
43
|
-
>
|
|
38
|
+
<radialGradient id={`${id}-edge-mask`} cx="50%" cy="50%" r="50%">
|
|
44
39
|
<stop offset="0%" stopColor="black" stopOpacity="0" />
|
|
45
40
|
<stop
|
|
46
41
|
offset={`${Math.max(30, 80 - aberrationIntensity * 2)}%`}
|
|
@@ -49,14 +44,7 @@ const GlassFilterComponent: React.FC<GlassFilterProps> = ({
|
|
|
49
44
|
/>
|
|
50
45
|
<stop offset="100%" stopColor="white" stopOpacity="1" />
|
|
51
46
|
</radialGradient>
|
|
52
|
-
<filter
|
|
53
|
-
id={id}
|
|
54
|
-
x="-35%"
|
|
55
|
-
y="-35%"
|
|
56
|
-
width="170%"
|
|
57
|
-
height="170%"
|
|
58
|
-
colorInterpolationFilters="sRGB"
|
|
59
|
-
>
|
|
47
|
+
<filter id={id} x="-35%" y="-35%" width="170%" height="170%" colorInterpolationFilters="sRGB">
|
|
60
48
|
<feImage
|
|
61
49
|
id={`${id}-image`}
|
|
62
50
|
x="0"
|
|
@@ -64,7 +52,13 @@ const GlassFilterComponent: React.FC<GlassFilterProps> = ({
|
|
|
64
52
|
width="100%"
|
|
65
53
|
height="100%"
|
|
66
54
|
result="DISPLACEMENT_MAP"
|
|
67
|
-
href={getDisplacementMap(
|
|
55
|
+
href={getDisplacementMap(
|
|
56
|
+
mode,
|
|
57
|
+
displacementMap,
|
|
58
|
+
polarDisplacementMap,
|
|
59
|
+
prominentDisplacementMap,
|
|
60
|
+
shaderMapUrl
|
|
61
|
+
)}
|
|
68
62
|
preserveAspectRatio="xMidYMid slice"
|
|
69
63
|
/>
|
|
70
64
|
|
|
@@ -178,4 +172,3 @@ export const GlassFilter = memo(GlassFilterComponent, (prevProps, nextProps) =>
|
|
|
178
172
|
prevProps.blurAmount === nextProps.blurAmount
|
|
179
173
|
);
|
|
180
174
|
});
|
|
181
|
-
|
|
@@ -45,7 +45,9 @@ export const calculateMouseInfluence = (mouseOffset: MousePosition): number => {
|
|
|
45
45
|
return 0;
|
|
46
46
|
}
|
|
47
47
|
// Bounded calculation — keeps the glass effect subtle and stable
|
|
48
|
-
const influence =
|
|
48
|
+
const influence =
|
|
49
|
+
Math.sqrt(mouseOffset.x * mouseOffset.x + mouseOffset.y * mouseOffset.y) /
|
|
50
|
+
CONSTANTS.MOUSE_INFLUENCE_DIVISOR;
|
|
49
51
|
return Math.min(0.8, influence); // Tighter cap to prevent blur/filter blow-out
|
|
50
52
|
};
|
|
51
53
|
|
|
@@ -59,7 +61,7 @@ export const calculateOverLightIntensity = (
|
|
|
59
61
|
if (!mouseOffset || typeof mouseOffset.x !== 'number' || typeof mouseOffset.y !== 'number') {
|
|
60
62
|
return baseIntensity;
|
|
61
63
|
}
|
|
62
|
-
|
|
64
|
+
|
|
63
65
|
// Calculate additional intensity based on mouse position
|
|
64
66
|
const mouseInfluence = calculateMouseInfluence(mouseOffset);
|
|
65
67
|
return Math.min(1.0, baseIntensity * (1 + mouseInfluence * 0.3));
|
|
@@ -260,4 +262,3 @@ export const getDisplacementMap = (
|
|
|
260
262
|
return displacementMap;
|
|
261
263
|
}
|
|
262
264
|
};
|
|
263
|
-
|