@shohojdhara/atomix 0.3.14 → 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/CHANGELOG.md +20 -0
- package/build-tools/EXAMPLES.md +372 -0
- package/build-tools/README.md +242 -0
- package/build-tools/__tests__/error-handler.test.js +230 -0
- package/build-tools/__tests__/index.test.js +141 -0
- package/build-tools/__tests__/rollup-plugin.test.js +194 -0
- package/build-tools/__tests__/utils.test.js +161 -0
- package/build-tools/__tests__/vite-plugin.test.js +129 -0
- package/build-tools/__tests__/webpack-loader.test.js +190 -0
- package/build-tools/error-handler.js +308 -0
- package/build-tools/index.d.ts +44 -0
- package/build-tools/index.js +88 -0
- package/build-tools/package.json +50 -0
- package/build-tools/rollup-plugin.js +236 -0
- package/build-tools/types.d.ts +163 -0
- package/build-tools/utils.js +203 -0
- package/build-tools/vite-plugin.js +161 -0
- package/build-tools/webpack-loader.js +123 -0
- package/dist/atomix.css +21044 -2618
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +77 -3
- package/dist/atomix.min.css.map +1 -1
- package/dist/build-tools/EXAMPLES.md +372 -0
- package/dist/build-tools/README.md +242 -0
- package/dist/build-tools/__tests__/error-handler.test.js +230 -0
- package/dist/build-tools/__tests__/index.test.js +141 -0
- package/dist/build-tools/__tests__/rollup-plugin.test.js +194 -0
- package/dist/build-tools/__tests__/utils.test.js +161 -0
- package/dist/build-tools/__tests__/vite-plugin.test.js +129 -0
- package/dist/build-tools/__tests__/webpack-loader.test.js +190 -0
- package/dist/build-tools/error-handler.js +308 -0
- package/dist/build-tools/index.d.ts +44 -0
- package/dist/build-tools/index.js +88 -0
- package/dist/build-tools/package.json +50 -0
- package/dist/build-tools/rollup-plugin.js +236 -0
- package/dist/build-tools/types.d.ts +163 -0
- package/dist/build-tools/utils.js +203 -0
- package/dist/build-tools/vite-plugin.js +161 -0
- package/dist/build-tools/webpack-loader.js +123 -0
- package/dist/charts.d.ts +1 -1
- package/dist/charts.js +86 -57
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.js +136 -112
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +2 -5
- package/dist/forms.js +140 -128
- package/dist/forms.js.map +1 -1
- package/dist/heavy.d.ts +1 -1
- package/dist/heavy.js +136 -112
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +152 -78
- package/dist/index.esm.js +346 -340
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +359 -353
- 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 +23 -8
- package/scripts/atomix-cli.js +170 -73
- package/scripts/cli/__tests__/README.md +81 -0
- package/scripts/cli/__tests__/basic.test.js +115 -0
- package/scripts/cli/__tests__/component-generator.test.js +332 -0
- package/scripts/cli/__tests__/integration.test.js +327 -0
- package/scripts/cli/__tests__/test-setup.js +133 -0
- package/scripts/cli/__tests__/token-manager.test.js +251 -0
- package/scripts/cli/__tests__/utils.test.js +161 -0
- package/scripts/cli/component-generator.js +253 -299
- package/scripts/cli/dependency-checker.js +355 -0
- package/scripts/cli/interactive-init.js +46 -5
- package/scripts/cli/template-manager.js +0 -2
- package/scripts/cli/templates/common-templates.js +636 -0
- package/scripts/cli/templates/composable-templates.js +148 -126
- package/scripts/cli/templates/index.js +23 -16
- package/scripts/cli/templates/project-templates.js +151 -23
- package/scripts/cli/templates/react-templates.js +280 -210
- package/scripts/cli/templates/scss-templates.js +90 -91
- package/scripts/cli/templates/testing-templates.js +206 -27
- package/scripts/cli/templates/testing-utils.js +278 -0
- package/scripts/cli/templates/types-templates.js +70 -56
- package/scripts/cli/theme-bridge.js +8 -2
- package/scripts/cli/token-manager.js +318 -206
- package/scripts/cli/utils.js +0 -1
- package/src/components/Accordion/Accordion.stories.tsx +358 -850
- 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/AtomixGlass.tsx +80 -39
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +103 -81
- package/src/components/AtomixGlass/GlassFilter.tsx +9 -16
- package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +8 -7
- package/src/components/AtomixGlass/glass-utils.ts +6 -5
- package/src/components/AtomixGlass/shader-utils.ts +133 -52
- package/src/components/AtomixGlass/stories/Customization.stories.tsx +131 -0
- package/src/components/AtomixGlass/stories/Examples.stories.tsx +2957 -2853
- package/src/components/AtomixGlass/stories/Modes.stories.tsx +1 -1
- package/src/components/AtomixGlass/stories/Overview.stories.tsx +348 -0
- package/src/components/AtomixGlass/stories/Performance.stories.tsx +103 -0
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +51 -36
- package/src/components/AtomixGlass/stories/{ShaderVariants.stories.tsx → Shaders.stories.tsx} +2 -2
- package/src/components/AtomixGlass/stories/shared-components.tsx +90 -190
- package/src/components/Avatar/Avatar.stories.tsx +195 -0
- package/src/components/Avatar/Avatar.tsx +58 -56
- package/src/components/Badge/Badge.stories.tsx +122 -352
- package/src/components/Badge/Badge.test.tsx +41 -41
- package/src/components/Badge/Badge.tsx +64 -62
- package/src/components/Block/Block.stories.tsx +30 -11
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +142 -23
- package/src/components/Breadcrumb/Breadcrumb.tsx +62 -60
- package/src/components/Button/Button.stories.tsx +454 -1126
- package/src/components/Button/Button.test.tsx +123 -0
- package/src/components/Button/Button.tsx +88 -60
- package/src/components/Button/ButtonGroup.stories.tsx +376 -215
- package/src/components/Button/ButtonGroup.tsx +4 -15
- package/src/components/Callout/Callout.stories.tsx +316 -568
- package/src/components/Card/Card.stories.tsx +292 -81
- 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 +153 -16
- 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 +152 -66
- package/src/components/ColorModeToggle/ColorModeToggle.tsx +15 -3
- package/src/components/Countdown/Countdown.stories.tsx +114 -7
- package/src/components/DataTable/DataTable.stories.tsx +349 -144
- package/src/components/DataTable/DataTable.test.tsx +26 -148
- package/src/components/DataTable/DataTable.tsx +485 -456
- package/src/components/DatePicker/DatePicker.stories.tsx +310 -1066
- package/src/components/DatePicker/DatePicker.tsx +31 -26
- package/src/components/Dropdown/Dropdown.stories.tsx +153 -36
- package/src/components/Dropdown/Dropdown.tsx +313 -299
- package/src/components/EdgePanel/EdgePanel.stories.tsx +221 -25
- package/src/components/EdgePanel/EdgePanel.tsx +1 -3
- package/src/components/Footer/Footer.stories.tsx +396 -327
- package/src/components/Footer/Footer.tsx +130 -128
- package/src/components/Footer/FooterLink.tsx +2 -2
- package/src/components/Form/Checkbox.stories.tsx +140 -6
- package/src/components/Form/Checkbox.test.tsx +63 -0
- package/src/components/Form/Checkbox.tsx +122 -78
- package/src/components/Form/Form.stories.tsx +110 -19
- package/src/components/Form/FormGroup.stories.tsx +127 -4
- 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 +146 -17
- package/src/components/Form/Radio.tsx +68 -66
- package/src/components/Form/Select.stories.tsx +140 -8
- package/src/components/Form/Select.tsx +184 -182
- package/src/components/Form/Textarea.stories.tsx +149 -6
- package/src/components/Form/Textarea.test.tsx +27 -32
- package/src/components/Hero/Hero.stories.tsx +372 -38
- package/src/components/Hero/Hero.tsx +201 -55
- package/src/components/Icon/index.ts +7 -1
- package/src/components/List/List.stories.tsx +141 -3
- package/src/components/List/List.tsx +19 -23
- package/src/components/Modal/Modal.stories.tsx +183 -43
- 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 +354 -97
- package/src/components/Popover/Popover.tsx +41 -37
- package/src/components/Progress/Progress.stories.tsx +160 -7
- package/src/components/River/River.stories.tsx +3 -2
- package/src/components/SectionIntro/SectionIntro.stories.tsx +239 -47
- package/src/components/Slider/Slider.stories.tsx +12 -4
- package/src/components/Spinner/Spinner.stories.tsx +104 -8
- package/src/components/Spinner/Spinner.test.tsx +23 -23
- package/src/components/Spinner/Spinner.tsx +43 -46
- package/src/components/Steps/Steps.stories.tsx +173 -42
- package/src/components/Tabs/Tabs.stories.tsx +141 -12
- package/src/components/Tabs/Tabs.tsx +74 -72
- package/src/components/Testimonial/Testimonial.stories.tsx +120 -3
- package/src/components/Todo/Todo.stories.tsx +198 -9
- package/src/components/Toggle/Toggle.stories.tsx +137 -36
- package/src/components/Toggle/Toggle.test.tsx +65 -70
- package/src/components/Toggle/Toggle.tsx +4 -1
- package/src/components/Tooltip/Tooltip.stories.tsx +194 -100
- package/src/components/Tooltip/Tooltip.tsx +104 -106
- package/src/components/Upload/Upload.stories.tsx +241 -150
- 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/README.md +2 -2
- package/src/lib/__tests__/theme-tools.test.ts +219 -0
- package/src/lib/composables/index.ts +2 -2
- package/src/lib/composables/shared-mouse-tracker.ts +13 -14
- package/src/lib/composables/useAtomixGlass.ts +126 -97
- package/src/lib/composables/useChartExport.ts +3 -8
- package/src/lib/composables/useDataTable.ts +72 -43
- 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/components.ts +9 -32
- 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 +107 -105
- 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 +45 -0
- package/src/lib/utils/componentUtils.ts +8 -12
- package/src/lib/utils/csv.ts +19 -0
- package/src/lib/utils/dataTableExport.ts +2 -15
- 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 +1 -1
- package/src/styles/01-settings/_settings.accordion.scss +28 -7
- package/src/styles/01-settings/_settings.colors.scss +11 -11
- 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 +4 -4
- package/src/styles/02-tools/_tools.button.scss +51 -21
- package/src/styles/02-tools/_tools.utility-api.scss +38 -12
- package/src/styles/03-generic/_generic.root.scss +4 -3
- package/src/styles/06-components/_components.accordion.scss +56 -14
- 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 +25 -17
- 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/_index.scss +2 -0
- 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 +2 -0
- 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 +45 -0
- package/src/styles/99-utilities/_utilities.text.scss +67 -46
- package/themes/dark-complementary/README.md +98 -0
- package/themes/dark-complementary/index.scss +158 -0
- package/themes/default-light/README.md +81 -0
- package/themes/default-light/index.scss +154 -0
- package/themes/high-contrast/README.md +105 -0
- package/themes/high-contrast/index.scss +172 -0
- package/themes/test-theme/README.md +38 -0
- package/themes/test-theme/index.scss +47 -0
- package/scripts/cli/templates-original-backup.js +0 -1655
- package/scripts/cli/templates_backup.js +0 -684
- package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +0 -1438
- package/src/lib/composables/useButton.ts +0 -93
- package/src/lib/composables/useCheckbox.ts +0 -70
|
@@ -149,143 +149,145 @@ export const Footer = forwardRef<HTMLElement, FooterProps>(
|
|
|
149
149
|
|
|
150
150
|
const footerContent = (
|
|
151
151
|
<div className={containerClass}>
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
{/* Footer Sections */}
|
|
196
|
-
{children && (
|
|
197
|
-
<GridCol
|
|
198
|
-
{...(getResponsiveColumnProps('content') as any)}
|
|
199
|
-
className="c-footer__content"
|
|
200
|
-
>
|
|
201
|
-
<Grid
|
|
202
|
-
className="c-footer__sections"
|
|
203
|
-
alignItems={layout === 'centered' || layout === 'stacked' ? 'center' : undefined}
|
|
204
|
-
>
|
|
205
|
-
{React.Children.map(children, child => {
|
|
206
|
-
// Check if the child is a valid React element
|
|
207
|
-
if (React.isValidElement(child)) {
|
|
208
|
-
// Clone the element and pass the showNewsletter prop
|
|
209
|
-
return React.cloneElement(child, { showNewsletter } as any);
|
|
210
|
-
}
|
|
211
|
-
return child;
|
|
212
|
-
})}
|
|
213
|
-
</Grid>
|
|
214
|
-
</GridCol>
|
|
215
|
-
)}
|
|
152
|
+
{/* Main Footer Content */}
|
|
153
|
+
<Grid
|
|
154
|
+
className={sectionsClass}
|
|
155
|
+
alignItems="start"
|
|
156
|
+
justifyContent={layout === 'centered' ? 'center' : undefined}
|
|
157
|
+
>
|
|
158
|
+
{/* Brand Section */}
|
|
159
|
+
{(brand || brandLogo || brandDescription) && (
|
|
160
|
+
<GridCol {...(getResponsiveColumnProps('brand') as any)} className={brandClass}>
|
|
161
|
+
{brandLogo && (
|
|
162
|
+
<div className="c-footer__brand-logo">
|
|
163
|
+
{typeof brandLogo === 'string' ? (
|
|
164
|
+
<img src={brandLogo} alt={'Brand Logo'} />
|
|
165
|
+
) : (
|
|
166
|
+
brandLogo
|
|
167
|
+
)}
|
|
168
|
+
</div>
|
|
169
|
+
)}
|
|
170
|
+
{brand && (
|
|
171
|
+
<div className="c-footer__brand-name">
|
|
172
|
+
{typeof brand === 'string' ? <h3>{brand}</h3> : brand}
|
|
173
|
+
</div>
|
|
174
|
+
)}
|
|
175
|
+
{brandDescription && (
|
|
176
|
+
<div className="c-footer__brand-description">{brandDescription}</div>
|
|
177
|
+
)}
|
|
178
|
+
{socialLinks.length > 0 && (
|
|
179
|
+
<div className="c-footer__social" data-testid="footer-social-links">
|
|
180
|
+
{socialLinks.map((link, index) => (
|
|
181
|
+
<FooterSocialLink
|
|
182
|
+
key={`${link.platform}-${index}`}
|
|
183
|
+
platform={link.platform}
|
|
184
|
+
url={link.url}
|
|
185
|
+
icon={link.icon}
|
|
186
|
+
label={link.label}
|
|
187
|
+
size={size}
|
|
188
|
+
/>
|
|
189
|
+
))}
|
|
190
|
+
</div>
|
|
191
|
+
)}
|
|
192
|
+
</GridCol>
|
|
193
|
+
)}
|
|
216
194
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
195
|
+
{/* Footer Sections */}
|
|
196
|
+
{children && (
|
|
197
|
+
<GridCol
|
|
198
|
+
{...(getResponsiveColumnProps('content') as any)}
|
|
199
|
+
className="c-footer__content"
|
|
200
|
+
>
|
|
201
|
+
<Grid
|
|
202
|
+
className="c-footer__sections"
|
|
203
|
+
alignItems={layout === 'centered' || layout === 'stacked' ? 'center' : undefined}
|
|
222
204
|
>
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}}
|
|
235
|
-
>
|
|
236
|
-
<div className="c-footer__newsletter-input-group">
|
|
237
|
-
<Input
|
|
238
|
-
type="email"
|
|
239
|
-
name="email"
|
|
240
|
-
className="c-footer__newsletter-input"
|
|
241
|
-
placeholder={newsletterPlaceholder}
|
|
242
|
-
required
|
|
243
|
-
/>
|
|
244
|
-
<Button type="submit" className="c-footer__newsletter-button">
|
|
245
|
-
{newsletterButtonText}
|
|
246
|
-
</Button>
|
|
247
|
-
</div>
|
|
248
|
-
</Form>
|
|
249
|
-
</GridCol>
|
|
250
|
-
)}
|
|
251
|
-
</Grid>
|
|
205
|
+
{React.Children.map(children, child => {
|
|
206
|
+
// Check if the child is a valid React element
|
|
207
|
+
if (React.isValidElement(child)) {
|
|
208
|
+
// Clone the element and pass the showNewsletter prop
|
|
209
|
+
return React.cloneElement(child, { showNewsletter } as any);
|
|
210
|
+
}
|
|
211
|
+
return child;
|
|
212
|
+
})}
|
|
213
|
+
</Grid>
|
|
214
|
+
</GridCol>
|
|
215
|
+
)}
|
|
252
216
|
|
|
253
|
-
{
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
{
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
aria-label={backToTopText}
|
|
263
|
-
>
|
|
264
|
-
<span className="c-footer__back-to-top-icon">↑</span>
|
|
265
|
-
<span className="c-footer__back-to-top-text">{backToTopText}</span>
|
|
266
|
-
</Button>
|
|
217
|
+
{/* Newsletter Section */}
|
|
218
|
+
{showNewsletter && (
|
|
219
|
+
<GridCol
|
|
220
|
+
{...(getResponsiveColumnProps('newsletter') as any)}
|
|
221
|
+
className="c-footer__newsletter"
|
|
222
|
+
>
|
|
223
|
+
<h4 className="c-footer__newsletter-title">{newsletterTitle}</h4>
|
|
224
|
+
{newsletterDescription && (
|
|
225
|
+
<p className="c-footer__newsletter-description">{newsletterDescription}</p>
|
|
267
226
|
)}
|
|
268
|
-
|
|
227
|
+
<Form
|
|
228
|
+
className="c-footer__newsletter-form"
|
|
229
|
+
onSubmit={e => {
|
|
230
|
+
e.preventDefault();
|
|
231
|
+
const formData = new FormData(e.currentTarget);
|
|
232
|
+
const email = formData.get('email') as string;
|
|
233
|
+
if (email) handleNewsletterSubmit(email);
|
|
234
|
+
}}
|
|
235
|
+
>
|
|
236
|
+
<div className="c-footer__newsletter-input-group">
|
|
237
|
+
<Input
|
|
238
|
+
type="email"
|
|
239
|
+
name="email"
|
|
240
|
+
className="c-footer__newsletter-input"
|
|
241
|
+
placeholder={newsletterPlaceholder}
|
|
242
|
+
required
|
|
243
|
+
/>
|
|
244
|
+
<Button type="submit" className="c-footer__newsletter-button">
|
|
245
|
+
{newsletterButtonText}
|
|
246
|
+
</Button>
|
|
247
|
+
</div>
|
|
248
|
+
</Form>
|
|
249
|
+
</GridCol>
|
|
269
250
|
)}
|
|
270
|
-
</
|
|
251
|
+
</Grid>
|
|
252
|
+
|
|
253
|
+
{(copyright || showBackToTop) && (
|
|
254
|
+
<div className={bottomClass}>
|
|
255
|
+
{copyright && <div className="c-footer__copyright">{copyright}</div>}
|
|
256
|
+
{showBackToTop && (
|
|
257
|
+
<Button
|
|
258
|
+
variant="ghost"
|
|
259
|
+
className="c-footer__back-to-top"
|
|
260
|
+
onClick={handleBackToTop}
|
|
261
|
+
disabled={disabled}
|
|
262
|
+
aria-label={backToTopText}
|
|
263
|
+
>
|
|
264
|
+
<span className="c-footer__back-to-top-icon">↑</span>
|
|
265
|
+
<span className="c-footer__back-to-top-text">{backToTopText}</span>
|
|
266
|
+
</Button>
|
|
267
|
+
)}
|
|
268
|
+
</div>
|
|
269
|
+
)}
|
|
270
|
+
</div>
|
|
271
271
|
);
|
|
272
272
|
|
|
273
273
|
return (
|
|
274
|
-
<footer
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
)
|
|
286
|
-
|
|
274
|
+
<footer
|
|
275
|
+
ref={ref}
|
|
276
|
+
className={footerClass + ` c-footer ${glass ? 'c-footer--glass' : ''}`}
|
|
277
|
+
{...props}
|
|
278
|
+
>
|
|
279
|
+
{glass ? (
|
|
280
|
+
<AtomixGlass {...(glass as unknown as AtomixGlassProps)} elasticity={0}>
|
|
281
|
+
<div className="c-footer__glass">{footerContent}</div>
|
|
282
|
+
</AtomixGlass>
|
|
283
|
+
) : (
|
|
284
|
+
footerContent
|
|
285
|
+
)}
|
|
286
|
+
</footer>
|
|
287
|
+
);
|
|
288
|
+
}
|
|
287
289
|
);
|
|
288
290
|
|
|
289
291
|
Footer.displayName = 'Footer';
|
|
290
292
|
|
|
291
|
-
export default Footer;
|
|
293
|
+
export default Footer;
|
|
@@ -55,7 +55,7 @@ export const FooterLink = forwardRef<HTMLAnchorElement, FooterLinkProps>(
|
|
|
55
55
|
...(href && !disabled ? { to: href } : {}),
|
|
56
56
|
...linkProps,
|
|
57
57
|
};
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
return (
|
|
60
60
|
<Component {...componentProps}>
|
|
61
61
|
{icon && <span className="c-footer__link-icon">{icon}</span>}
|
|
@@ -77,4 +77,4 @@ export const FooterLink = forwardRef<HTMLAnchorElement, FooterLinkProps>(
|
|
|
77
77
|
|
|
78
78
|
FooterLink.displayName = 'FooterLink';
|
|
79
79
|
|
|
80
|
-
export default FooterLink;
|
|
80
|
+
export default FooterLink;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { fn } from '@storybook/test';
|
|
3
|
+
import { useState } from 'react';
|
|
2
4
|
import { Checkbox } from './Checkbox';
|
|
3
5
|
|
|
6
|
+
// Mock event handlers
|
|
7
|
+
const mockOnChange = fn();
|
|
8
|
+
|
|
4
9
|
const meta = {
|
|
5
10
|
title: 'Components/Form/Checkbox',
|
|
6
11
|
component: Checkbox,
|
|
@@ -8,8 +13,66 @@ const meta = {
|
|
|
8
13
|
layout: 'centered',
|
|
9
14
|
docs: {
|
|
10
15
|
description: {
|
|
11
|
-
component:
|
|
12
|
-
|
|
16
|
+
component: `
|
|
17
|
+
# Checkbox
|
|
18
|
+
|
|
19
|
+
## Overview
|
|
20
|
+
|
|
21
|
+
Checkbox component allows users to select one or more options from a set. It supports checked, unchecked, and indeterminate states, and can be used in forms or as standalone controls. Checkboxes provide clear visual feedback and support keyboard navigation.
|
|
22
|
+
|
|
23
|
+
## Features
|
|
24
|
+
|
|
25
|
+
- Checked, unchecked, and indeterminate states
|
|
26
|
+
- Label support
|
|
27
|
+
- Disabled state
|
|
28
|
+
- Validation states (valid/invalid)
|
|
29
|
+
- Glass morphism effect
|
|
30
|
+
- Accessible design
|
|
31
|
+
- Responsive behavior
|
|
32
|
+
|
|
33
|
+
## Accessibility
|
|
34
|
+
|
|
35
|
+
- Keyboard support: Navigate and toggle with keyboard
|
|
36
|
+
- Screen reader: State and label announced properly
|
|
37
|
+
- ARIA support: Proper roles and properties for checkbox components
|
|
38
|
+
- Focus management: Visible focus indicators maintained
|
|
39
|
+
|
|
40
|
+
## Usage Examples
|
|
41
|
+
|
|
42
|
+
### Basic Usage
|
|
43
|
+
|
|
44
|
+
\`\`\`tsx
|
|
45
|
+
<Checkbox
|
|
46
|
+
label="Option label"
|
|
47
|
+
checked={isChecked}
|
|
48
|
+
onChange={setChecked}
|
|
49
|
+
/>
|
|
50
|
+
\`\`\`
|
|
51
|
+
|
|
52
|
+
### Indeterminate State
|
|
53
|
+
|
|
54
|
+
\`\`\`tsx
|
|
55
|
+
<Checkbox
|
|
56
|
+
label="Option label"
|
|
57
|
+
indeterminate={true}
|
|
58
|
+
/>
|
|
59
|
+
\`\`\`
|
|
60
|
+
|
|
61
|
+
## API Reference
|
|
62
|
+
|
|
63
|
+
### Props
|
|
64
|
+
|
|
65
|
+
| Prop | Type | Default | Description |
|
|
66
|
+
| ---- | ---- | ------- | ----------- |
|
|
67
|
+
| label | ReactNode | - | Checkbox label text or element |
|
|
68
|
+
| checked | boolean | false | Whether the checkbox is checked |
|
|
69
|
+
| disabled | boolean | false | Whether the checkbox is disabled |
|
|
70
|
+
| invalid | boolean | false | Whether the checkbox is invalid |
|
|
71
|
+
| valid | boolean | false | Whether the checkbox is valid |
|
|
72
|
+
| indeterminate | boolean | false | Whether the checkbox is in indeterminate state |
|
|
73
|
+
| glass | boolean \| AtomixGlassProps | false | Enable glass morphism effect |
|
|
74
|
+
| onChange | (event: ChangeEvent<HTMLInputElement>) => void | - | Callback when checkbox state changes |
|
|
75
|
+
`,
|
|
13
76
|
},
|
|
14
77
|
},
|
|
15
78
|
},
|
|
@@ -17,31 +80,63 @@ const meta = {
|
|
|
17
80
|
argTypes: {
|
|
18
81
|
label: {
|
|
19
82
|
control: 'text',
|
|
20
|
-
description: 'Checkbox label text',
|
|
83
|
+
description: 'Checkbox label text or element',
|
|
84
|
+
table: {
|
|
85
|
+
type: { summary: 'ReactNode' },
|
|
86
|
+
defaultValue: { summary: '-' },
|
|
87
|
+
},
|
|
21
88
|
},
|
|
22
89
|
checked: {
|
|
23
90
|
control: 'boolean',
|
|
24
91
|
description: 'Whether the checkbox is checked',
|
|
92
|
+
table: {
|
|
93
|
+
type: { summary: 'boolean' },
|
|
94
|
+
defaultValue: { summary: 'false' },
|
|
95
|
+
},
|
|
25
96
|
},
|
|
26
97
|
disabled: {
|
|
27
98
|
control: 'boolean',
|
|
28
99
|
description: 'Whether the checkbox is disabled',
|
|
100
|
+
table: {
|
|
101
|
+
type: { summary: 'boolean' },
|
|
102
|
+
defaultValue: { summary: 'false' },
|
|
103
|
+
},
|
|
29
104
|
},
|
|
30
105
|
invalid: {
|
|
31
106
|
control: 'boolean',
|
|
32
107
|
description: 'Whether the checkbox is invalid',
|
|
108
|
+
table: {
|
|
109
|
+
type: { summary: 'boolean' },
|
|
110
|
+
defaultValue: { summary: 'false' },
|
|
111
|
+
},
|
|
33
112
|
},
|
|
34
113
|
valid: {
|
|
35
114
|
control: 'boolean',
|
|
36
115
|
description: 'Whether the checkbox is valid',
|
|
116
|
+
table: {
|
|
117
|
+
type: { summary: 'boolean' },
|
|
118
|
+
defaultValue: { summary: 'false' },
|
|
119
|
+
},
|
|
37
120
|
},
|
|
38
121
|
indeterminate: {
|
|
39
122
|
control: 'boolean',
|
|
40
123
|
description: 'Whether the checkbox is in indeterminate state',
|
|
124
|
+
table: {
|
|
125
|
+
type: { summary: 'boolean' },
|
|
126
|
+
defaultValue: { summary: 'false' },
|
|
127
|
+
},
|
|
41
128
|
},
|
|
42
129
|
glass: {
|
|
43
|
-
control: 'boolean',
|
|
130
|
+
control: { type: 'boolean' },
|
|
44
131
|
description: 'Enable glass morphism effect',
|
|
132
|
+
table: {
|
|
133
|
+
type: { summary: 'boolean | AtomixGlassProps' },
|
|
134
|
+
defaultValue: { summary: 'false' },
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
onChange: {
|
|
138
|
+
action: 'changed',
|
|
139
|
+
description: 'Callback when checkbox state changes',
|
|
45
140
|
},
|
|
46
141
|
},
|
|
47
142
|
} satisfies Meta<typeof Checkbox>;
|
|
@@ -50,9 +145,17 @@ export default meta;
|
|
|
50
145
|
type Story = StoryObj<typeof meta>;
|
|
51
146
|
|
|
52
147
|
// Basic checkbox
|
|
53
|
-
export const
|
|
148
|
+
export const BasicUsage: Story = {
|
|
54
149
|
args: {
|
|
55
150
|
label: 'Accept terms and conditions',
|
|
151
|
+
onChange: mockOnChange,
|
|
152
|
+
},
|
|
153
|
+
parameters: {
|
|
154
|
+
docs: {
|
|
155
|
+
description: {
|
|
156
|
+
story: 'Basic checkbox with label.',
|
|
157
|
+
},
|
|
158
|
+
},
|
|
56
159
|
},
|
|
57
160
|
};
|
|
58
161
|
|
|
@@ -61,11 +164,19 @@ export const Checked: Story = {
|
|
|
61
164
|
args: {
|
|
62
165
|
label: 'Accept terms and conditions',
|
|
63
166
|
checked: true,
|
|
167
|
+
onChange: mockOnChange,
|
|
168
|
+
},
|
|
169
|
+
parameters: {
|
|
170
|
+
docs: {
|
|
171
|
+
description: {
|
|
172
|
+
story: 'Checked checkbox state.',
|
|
173
|
+
},
|
|
174
|
+
},
|
|
64
175
|
},
|
|
65
176
|
};
|
|
66
177
|
|
|
67
178
|
// Checkbox states
|
|
68
|
-
export const
|
|
179
|
+
export const AllStates: Story = {
|
|
69
180
|
render: (args: any) => (
|
|
70
181
|
<div className="u-flex u-flex-column u-gap-3">
|
|
71
182
|
<Checkbox label="Default checkbox" />
|
|
@@ -77,12 +188,27 @@ export const States: Story = {
|
|
|
77
188
|
<Checkbox label="Indeterminate checkbox" indeterminate />
|
|
78
189
|
</div>
|
|
79
190
|
),
|
|
191
|
+
parameters: {
|
|
192
|
+
docs: {
|
|
193
|
+
description: {
|
|
194
|
+
story: 'Checkbox in all available states.',
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
},
|
|
80
198
|
};
|
|
81
199
|
|
|
82
200
|
// Without label
|
|
83
201
|
export const WithoutLabel: Story = {
|
|
84
202
|
args: {
|
|
85
203
|
'aria-label': 'Checkbox without visible label',
|
|
204
|
+
onChange: mockOnChange,
|
|
205
|
+
},
|
|
206
|
+
parameters: {
|
|
207
|
+
docs: {
|
|
208
|
+
description: {
|
|
209
|
+
story: 'Checkbox without visible label, using aria-label.',
|
|
210
|
+
},
|
|
211
|
+
},
|
|
86
212
|
},
|
|
87
213
|
};
|
|
88
214
|
|
|
@@ -91,6 +217,7 @@ export const Glass: Story = {
|
|
|
91
217
|
args: {
|
|
92
218
|
label: 'Glass Checkbox',
|
|
93
219
|
glass: true,
|
|
220
|
+
onChange: mockOnChange,
|
|
94
221
|
},
|
|
95
222
|
render: (args: any) => (
|
|
96
223
|
<div
|
|
@@ -107,6 +234,13 @@ export const Glass: Story = {
|
|
|
107
234
|
<Checkbox {...args} />
|
|
108
235
|
</div>
|
|
109
236
|
),
|
|
237
|
+
parameters: {
|
|
238
|
+
docs: {
|
|
239
|
+
description: {
|
|
240
|
+
story: 'Checkbox with glass morphism effect.',
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
},
|
|
110
244
|
};
|
|
111
245
|
|
|
112
246
|
// Glass with custom settings
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
2
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
3
|
+
import { axe, toHaveNoViolations } from 'jest-axe';
|
|
4
|
+
import { Checkbox } from './Checkbox';
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
expect.extend(toHaveNoViolations);
|
|
8
|
+
|
|
9
|
+
// Mock AtomixGlass
|
|
10
|
+
vi.mock('../AtomixGlass/AtomixGlass', () => ({
|
|
11
|
+
AtomixGlass: ({ children }: any) => <div>{children}</div>,
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
describe('Checkbox Component', () => {
|
|
15
|
+
it('renders correctly with label', () => {
|
|
16
|
+
render(<Checkbox label="Accept Terms" />);
|
|
17
|
+
// In current implementation, if no ID is provided, htmlFor is undefined, so label is not associated.
|
|
18
|
+
// screen.getByLabelText might fail or might not find the input.
|
|
19
|
+
// Let's see.
|
|
20
|
+
expect(screen.getByText('Accept Terms')).toBeInTheDocument();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('associates label with input when ID is provided', () => {
|
|
24
|
+
render(<Checkbox label="Subscribe" id="subscribe-check" />);
|
|
25
|
+
expect(screen.getByLabelText('Subscribe')).toBeInTheDocument();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('associates label with input WITHOUT ID', () => {
|
|
29
|
+
// This tests my proposed improvement: wrapping input in label or auto-ID
|
|
30
|
+
render(<Checkbox label="No ID Checkbox" />);
|
|
31
|
+
// If not associated, this throws
|
|
32
|
+
expect(screen.getByLabelText('No ID Checkbox')).toBeInTheDocument();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('handles checked state', () => {
|
|
36
|
+
const handleChange = vi.fn();
|
|
37
|
+
render(<Checkbox checked onChange={handleChange} label="Checked" id="checked-id" />);
|
|
38
|
+
const input = screen.getByLabelText('Checked');
|
|
39
|
+
expect(input).toBeChecked();
|
|
40
|
+
|
|
41
|
+
fireEvent.click(input);
|
|
42
|
+
expect(handleChange).toHaveBeenCalledTimes(1);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('forwards ref', () => {
|
|
46
|
+
const ref = React.createRef<HTMLInputElement>();
|
|
47
|
+
render(<Checkbox ref={ref} label="Ref Checkbox" />);
|
|
48
|
+
expect(ref.current).toBeInstanceOf(HTMLInputElement);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('handles indeterminate state', () => {
|
|
52
|
+
// This might need manual DOM check as indeterminate is a property, not attribute
|
|
53
|
+
const { getByRole } = render(<Checkbox indeterminate label="Indeterminate" id="indet" />);
|
|
54
|
+
const input = getByRole('checkbox') as HTMLInputElement;
|
|
55
|
+
expect(input.indeterminate).toBe(true);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should have no accessibility violations', async () => {
|
|
59
|
+
const { container } = render(<Checkbox label="Accessible Checkbox" id="a11y-check" />);
|
|
60
|
+
const results = await axe(container);
|
|
61
|
+
expect(results).toHaveNoViolations();
|
|
62
|
+
});
|
|
63
|
+
});
|