@shohojdhara/atomix 0.2.3 → 0.2.5
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/README.md +19 -0
- package/dist/atomix.css +1703 -1544
- package/dist/atomix.min.css +4 -4
- package/dist/index.d.ts +1465 -963
- package/dist/index.esm.js +16289 -25908
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +15650 -21780
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/themes/applemix.css +15008 -0
- package/dist/themes/applemix.min.css +72 -0
- package/dist/themes/boomdevs.css +1608 -1450
- package/dist/themes/boomdevs.min.css +5 -5
- package/dist/themes/esrar.css +1702 -1543
- package/dist/themes/esrar.min.css +4 -4
- package/dist/themes/flashtrade.css +15159 -0
- package/dist/themes/flashtrade.min.css +86 -0
- package/dist/themes/mashroom.css +1699 -1540
- package/dist/themes/mashroom.min.css +7 -7
- package/dist/themes/shaj-default.css +1693 -1534
- package/dist/themes/shaj-default.min.css +4 -4
- package/package.json +6 -17
- package/src/components/Accordion/Accordion.stories.tsx +662 -21
- package/src/components/Accordion/Accordion.tsx +21 -14
- package/src/components/AtomixGlass/AtomixGlass.test.tsx +106 -72
- package/src/components/AtomixGlass/AtomixGlass.tsx +529 -1195
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +400 -0
- package/src/components/AtomixGlass/GlassFilter.tsx +156 -0
- package/src/components/AtomixGlass/README.md +124 -2
- package/src/components/AtomixGlass/atomixGLass.old.tsx +1266 -0
- package/src/components/AtomixGlass/glass-utils.ts +263 -0
- package/src/components/AtomixGlass/shader-utils.ts +792 -68
- package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +1250 -0
- package/src/components/AtomixGlass/stories/Examples.stories.tsx +5768 -0
- package/src/components/AtomixGlass/stories/Modes.stories.tsx +1065 -0
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +1129 -0
- package/src/components/AtomixGlass/stories/ShaderVariants.stories.tsx +395 -0
- package/src/components/AtomixGlass/stories/shared-components.tsx +301 -0
- package/src/components/AtomixGlass/utils.ts +3 -3
- package/src/components/Avatar/Avatar.tsx +3 -0
- package/src/components/Avatar/AvatarGroup.tsx +2 -1
- package/src/components/Badge/Badge.stories.tsx +76 -55
- package/src/components/Badge/Badge.tsx +12 -14
- package/src/components/Breadcrumb/Breadcrumb.tsx +23 -4
- package/src/components/Button/Button.stories.tsx +501 -20
- package/src/components/Button/Button.tsx +5 -8
- package/src/components/Callout/Callout.stories.tsx +86 -35
- package/src/components/Callout/Callout.tsx +31 -9
- package/src/components/Card/Card.stories.tsx +565 -2
- package/src/components/Card/Card.tsx +15 -4
- package/src/components/Card/ElevationCard.tsx +2 -0
- package/src/components/Chart/AnimatedChart.tsx +179 -156
- package/src/components/Chart/AreaChart.tsx +123 -12
- package/src/components/Chart/BarChart.tsx +91 -100
- package/src/components/Chart/BaseChart.tsx +80 -0
- package/src/components/Chart/BubbleChart.tsx +114 -290
- package/src/components/Chart/CandlestickChart.tsx +282 -622
- package/src/components/Chart/Chart.stories.tsx +576 -179
- package/src/components/Chart/Chart.tsx +374 -75
- package/src/components/Chart/ChartRenderer.tsx +371 -220
- package/src/components/Chart/ChartToolbar.tsx +372 -61
- package/src/components/Chart/ChartTooltip.tsx +33 -18
- package/src/components/Chart/DonutChart.tsx +172 -254
- package/src/components/Chart/FunnelChart.tsx +169 -240
- package/src/components/Chart/GaugeChart.tsx +224 -392
- package/src/components/Chart/HeatmapChart.tsx +302 -440
- package/src/components/Chart/LineChart.tsx +148 -103
- package/src/components/Chart/MultiAxisChart.tsx +267 -395
- package/src/components/Chart/PieChart.tsx +114 -64
- package/src/components/Chart/RadarChart.tsx +202 -218
- package/src/components/Chart/ScatterChart.tsx +111 -97
- package/src/components/Chart/TreemapChart.tsx +147 -222
- package/src/components/Chart/WaterfallChart.tsx +253 -291
- package/src/components/Chart/index.ts +11 -9
- package/src/components/Chart/types.ts +85 -9
- package/src/components/Chart/utils.ts +66 -0
- package/src/components/ColorModeToggle/ColorModeToggle.tsx +6 -3
- package/src/components/Countdown/Countdown.tsx +4 -0
- package/src/components/DataTable/DataTable.tsx +2 -1
- package/src/components/DatePicker/DatePicker.stories.tsx +689 -12
- package/src/components/DatePicker/DatePicker.tsx +3 -9
- package/src/components/DatePicker/types.ts +5 -0
- package/src/components/Dropdown/Dropdown.stories.tsx +32 -25
- package/src/components/Dropdown/Dropdown.tsx +26 -28
- package/src/components/EdgePanel/EdgePanel.stories.tsx +473 -2
- package/src/components/EdgePanel/EdgePanel.tsx +101 -13
- package/src/components/Footer/Footer.stories.tsx +187 -60
- package/src/components/Footer/Footer.test.tsx +134 -0
- package/src/components/Footer/Footer.tsx +133 -34
- package/src/components/Footer/FooterLink.tsx +1 -1
- package/src/components/Footer/FooterSection.tsx +53 -36
- package/src/components/Footer/FooterSocialLink.tsx +32 -29
- package/src/components/Footer/README.md +82 -3
- package/src/components/Footer/index.ts +1 -1
- package/src/components/Form/Checkbox.stories.tsx +13 -5
- package/src/components/Form/Checkbox.tsx +3 -6
- package/src/components/Form/Form.stories.tsx +10 -3
- package/src/components/Form/Form.tsx +2 -0
- package/src/components/Form/FormGroup.tsx +2 -1
- package/src/components/Form/Input.stories.tsx +12 -11
- package/src/components/Form/Input.tsx +97 -95
- package/src/components/Form/Radio.stories.tsx +22 -7
- package/src/components/Form/Radio.tsx +3 -6
- package/src/components/Form/Select.stories.tsx +21 -6
- package/src/components/Form/Select.tsx +3 -5
- package/src/components/Form/Textarea.stories.tsx +13 -11
- package/src/components/Form/Textarea.tsx +88 -86
- package/src/components/Hero/Hero.stories.tsx +2 -3
- package/src/components/Hero/Hero.tsx +5 -6
- package/src/components/Icon/Icon.tsx +12 -1
- package/src/components/List/List.tsx +2 -1
- package/src/components/List/ListGroup.tsx +2 -1
- package/src/components/Messages/Messages.stories.tsx +113 -0
- package/src/components/Messages/Messages.tsx +52 -9
- package/src/components/Modal/Modal.stories.tsx +48 -32
- package/src/components/Modal/Modal.tsx +19 -24
- package/src/components/Navigation/Menu/MegaMenu.tsx +2 -2
- package/src/components/Navigation/Menu/Menu.tsx +2 -2
- package/src/components/Navigation/Nav/Nav.stories.tsx +469 -0
- package/src/components/Navigation/Nav/Nav.tsx +22 -4
- package/src/components/Navigation/Nav/NavDropdown.tsx +10 -1
- package/src/components/Navigation/Navbar/Navbar.stories.tsx +413 -0
- package/src/components/Navigation/Navbar/Navbar.tsx +70 -29
- package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +340 -0
- package/src/components/Navigation/SideMenu/SideMenu.tsx +29 -2
- package/src/components/Pagination/Pagination.stories.tsx +13 -6
- package/src/components/Pagination/Pagination.tsx +7 -6
- package/src/components/PhotoViewer/PhotoViewer.tsx +2 -1
- package/src/components/Popover/Popover.stories.tsx +32 -24
- package/src/components/Popover/Popover.tsx +4 -1
- package/src/components/ProductReview/ProductReview.tsx +8 -2
- package/src/components/Progress/Progress.tsx +19 -3
- package/src/components/Rating/Rating.stories.tsx +11 -6
- package/src/components/Rating/Rating.tsx +3 -5
- package/src/components/River/River.tsx +5 -5
- package/src/components/SectionIntro/SectionIntro.tsx +8 -2
- package/src/components/Slider/Slider.stories.tsx +4 -4
- package/src/components/Slider/Slider.tsx +4 -3
- package/src/components/Spinner/Spinner.tsx +19 -3
- package/src/components/Steps/Steps.stories.tsx +5 -4
- package/src/components/Steps/Steps.tsx +8 -5
- package/src/components/Tab/Tab.stories.tsx +4 -3
- package/src/components/Tab/Tab.tsx +8 -6
- package/src/components/Testimonial/Testimonial.tsx +8 -2
- package/src/components/Todo/Todo.tsx +2 -1
- package/src/components/Toggle/Toggle.stories.tsx +5 -4
- package/src/components/Toggle/Toggle.tsx +8 -5
- package/src/components/Tooltip/Tooltip.stories.tsx +40 -30
- package/src/components/Tooltip/Tooltip.tsx +9 -2
- package/src/components/Upload/Upload.stories.tsx +252 -0
- package/src/components/Upload/Upload.tsx +92 -53
- package/src/components/VideoPlayer/VideoPlayer.tsx +3 -1
- package/src/components/index.ts +0 -4
- package/src/layouts/Grid/Grid.stories.tsx +10 -23
- package/src/layouts/Grid/Grid.tsx +20 -1
- package/src/layouts/Grid/GridCol.tsx +76 -48
- package/src/lib/composables/useAtomixGlass.ts +861 -44
- package/src/lib/composables/useBarChart.ts +21 -4
- package/src/lib/composables/useChart.ts +227 -370
- package/src/lib/composables/useChartExport.ts +19 -78
- package/src/lib/composables/useChartToolbar.ts +11 -21
- package/src/lib/composables/useEdgePanel.ts +125 -71
- package/src/lib/composables/useFooter.ts +3 -3
- package/src/lib/composables/useGlassContainer.ts +16 -7
- package/src/lib/composables/useLineChart.ts +11 -2
- package/src/lib/composables/usePieChart.ts +4 -14
- package/src/lib/composables/useRiver.ts +5 -0
- package/src/lib/composables/useSlider.ts +62 -24
- package/src/lib/composables/useVideoPlayer.ts +60 -63
- package/src/lib/constants/components.ts +147 -32
- package/src/lib/types/components.ts +355 -25
- package/src/lib/utils/displacement-generator.ts +55 -49
- package/src/lib/utils/icons.ts +1 -1
- package/src/lib/utils/index.ts +16 -10
- package/src/styles/01-settings/_settings.accordion.scss +19 -19
- package/src/styles/01-settings/_settings.animations.scss +5 -5
- package/src/styles/01-settings/_settings.avatar-group.scss +1 -1
- package/src/styles/01-settings/_settings.avatar.scss +17 -17
- package/src/styles/01-settings/_settings.background.scss +0 -3
- package/src/styles/01-settings/_settings.badge.scss +1 -1
- package/src/styles/01-settings/_settings.breadcrumb.scss +1 -1
- package/src/styles/01-settings/_settings.card.scss +1 -1
- package/src/styles/01-settings/_settings.chart.scss +65 -2
- package/src/styles/01-settings/_settings.dropdown.scss +1 -1
- package/src/styles/01-settings/_settings.edge-panel.scss +1 -1
- package/src/styles/01-settings/_settings.footer.scss +35 -42
- package/src/styles/01-settings/_settings.input.scss +1 -1
- package/src/styles/01-settings/_settings.list.scss +1 -1
- package/src/styles/01-settings/_settings.rating.scss +1 -1
- package/src/styles/01-settings/_settings.tabs.scss +1 -1
- package/src/styles/01-settings/_settings.upload.scss +6 -5
- package/src/styles/02-tools/_tools.animations.scss +4 -5
- package/src/styles/02-tools/_tools.background.scss +1 -13
- package/src/styles/02-tools/_tools.glass.scss +0 -1
- package/src/styles/02-tools/_tools.utility-api.scss +91 -48
- package/src/styles/03-generic/_generic.root.scss +1 -4
- package/src/styles/04-elements/_elements.body.scss +0 -1
- package/src/styles/06-components/_components.atomix-glass.scss +249 -0
- package/src/styles/06-components/_components.badge.scss +8 -23
- package/src/styles/06-components/_components.button.scss +8 -3
- package/src/styles/06-components/_components.callout.scss +10 -5
- package/src/styles/06-components/_components.card.scss +2 -14
- package/src/styles/06-components/_components.chart.scss +969 -1449
- package/src/styles/06-components/_components.dropdown.scss +19 -7
- package/src/styles/06-components/_components.edge-panel.scss +103 -0
- package/src/styles/06-components/_components.footer.scss +166 -85
- package/src/styles/06-components/_components.input.scss +8 -9
- package/src/styles/06-components/_components.list.scss +1 -0
- package/src/styles/06-components/_components.messages.scss +176 -0
- package/src/styles/06-components/_components.modal.scss +16 -4
- package/src/styles/06-components/_components.navbar.scss +12 -1
- package/src/styles/06-components/_components.side-menu.scss +5 -0
- package/src/styles/06-components/_components.skeleton.scss +8 -6
- package/src/styles/06-components/_components.upload.scss +219 -4
- package/src/styles/06-components/old.chart.styles.scss +1 -30
- package/src/styles/99-utilities/_index.scss +1 -0
- package/src/styles/99-utilities/_utilities.glass-fixes.scss +1 -0
- package/src/styles/99-utilities/_utilities.scss +1 -1
- package/src/components/AtomixGlass/AtomixGlass.stories.tsx +0 -3011
- package/src/components/AtomixGlass/AtomixGlassComprehensivePreview.stories.tsx +0 -1369
- package/src/components/Chart/AdvancedChart.tsx +0 -624
- package/src/components/Chart/LineChartNew.tsx +0 -167
- package/src/components/Chart/RealTimeChart.tsx +0 -436
- package/src/components/DatePicker/DatePicker copy.tsx +0 -551
|
@@ -178,9 +178,15 @@ export function useChartExport() {
|
|
|
178
178
|
rows.push(row);
|
|
179
179
|
});
|
|
180
180
|
|
|
181
|
-
// Convert to CSV string
|
|
181
|
+
// Convert to CSV string with sanitization
|
|
182
182
|
const csvContent = rows
|
|
183
|
-
.map(row => row.map(cell =>
|
|
183
|
+
.map(row => row.map(cell => {
|
|
184
|
+
// Sanitize cell content to prevent CSV injection
|
|
185
|
+
const sanitized = String(cell).replace(/[\r\n\t]/g, ' ').replace(/"/g, '""');
|
|
186
|
+
// Prevent formula injection by prefixing dangerous characters
|
|
187
|
+
const dangerous = /^[=+\-@]/;
|
|
188
|
+
return `"${dangerous.test(sanitized) ? `'${sanitized}` : sanitized}"`;
|
|
189
|
+
}).join(','))
|
|
184
190
|
.join('\n');
|
|
185
191
|
|
|
186
192
|
// Download
|
|
@@ -297,17 +303,21 @@ export function useChartExport() {
|
|
|
297
303
|
break;
|
|
298
304
|
case 'email':
|
|
299
305
|
window.open(
|
|
300
|
-
`mailto:?subject=${encodeURIComponent(
|
|
306
|
+
`mailto:?subject=${encodeURIComponent(message)}&body=${encodeURIComponent(`${message} ${url}`)}`,
|
|
301
307
|
'_blank'
|
|
302
308
|
);
|
|
303
309
|
break;
|
|
304
310
|
case 'copy-link':
|
|
305
|
-
|
|
311
|
+
if (navigator.clipboard) {
|
|
306
312
|
await navigator.clipboard.writeText(url);
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
313
|
+
} else {
|
|
314
|
+
// Fallback for older browsers
|
|
315
|
+
const textArea = document.createElement('textarea');
|
|
316
|
+
textArea.value = url;
|
|
317
|
+
document.body.appendChild(textArea);
|
|
318
|
+
textArea.select();
|
|
319
|
+
document.execCommand('copy');
|
|
320
|
+
document.body.removeChild(textArea);
|
|
311
321
|
}
|
|
312
322
|
break;
|
|
313
323
|
}
|
|
@@ -316,77 +326,8 @@ export function useChartExport() {
|
|
|
316
326
|
[]
|
|
317
327
|
);
|
|
318
328
|
|
|
319
|
-
// Copy chart as image to clipboard
|
|
320
|
-
const copyToClipboard = useCallback(
|
|
321
|
-
async (svgElement: SVGSVGElement, options: Partial<ExportOptions> = {}): Promise<void> => {
|
|
322
|
-
try {
|
|
323
|
-
const canvas = await svgToCanvas(svgElement, { format: 'png', ...options });
|
|
324
|
-
|
|
325
|
-
canvas.toBlob(async blob => {
|
|
326
|
-
if (blob && navigator.clipboard && window.ClipboardItem) {
|
|
327
|
-
try {
|
|
328
|
-
await navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })]);
|
|
329
|
-
console.log('Chart copied to clipboard');
|
|
330
|
-
} catch (error) {
|
|
331
|
-
console.error('Failed to copy to clipboard:', error);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
}, 'image/png');
|
|
335
|
-
} catch (error) {
|
|
336
|
-
console.error('Failed to copy chart:', error);
|
|
337
|
-
throw error;
|
|
338
|
-
}
|
|
339
|
-
},
|
|
340
|
-
[svgToCanvas]
|
|
341
|
-
);
|
|
342
|
-
|
|
343
|
-
// Print chart
|
|
344
|
-
const printChart = useCallback(
|
|
345
|
-
async (svgElement: SVGSVGElement, options: Partial<ExportOptions> = {}): Promise<void> => {
|
|
346
|
-
try {
|
|
347
|
-
const canvas = await svgToCanvas(svgElement, { format: 'png', ...options });
|
|
348
|
-
const dataUrl = canvas.toDataURL('image/png');
|
|
349
|
-
|
|
350
|
-
const printWindow = window.open('', '_blank');
|
|
351
|
-
if (printWindow) {
|
|
352
|
-
printWindow.document.write(`
|
|
353
|
-
<html>
|
|
354
|
-
<head>
|
|
355
|
-
<title>Chart Print</title>
|
|
356
|
-
<style>
|
|
357
|
-
body { margin: 0; padding: 20px; text-align: center; }
|
|
358
|
-
img { max-width: 100%; height: auto; }
|
|
359
|
-
</style>
|
|
360
|
-
</head>
|
|
361
|
-
<body>
|
|
362
|
-
<img src="${dataUrl}" alt="Chart" />
|
|
363
|
-
</body>
|
|
364
|
-
</html>
|
|
365
|
-
`);
|
|
366
|
-
printWindow.document.close();
|
|
367
|
-
printWindow.focus();
|
|
368
|
-
printWindow.print();
|
|
369
|
-
}
|
|
370
|
-
} catch (error) {
|
|
371
|
-
console.error('Failed to print chart:', error);
|
|
372
|
-
throw error;
|
|
373
|
-
}
|
|
374
|
-
},
|
|
375
|
-
[svgToCanvas]
|
|
376
|
-
);
|
|
377
|
-
|
|
378
329
|
return {
|
|
379
330
|
exportChart,
|
|
380
331
|
shareChart,
|
|
381
|
-
copyToClipboard,
|
|
382
|
-
printChart,
|
|
383
|
-
|
|
384
|
-
// Individual export methods
|
|
385
|
-
exportAsPNG,
|
|
386
|
-
exportAsSVG,
|
|
387
|
-
exportAsPDF,
|
|
388
|
-
exportAsCSV,
|
|
389
|
-
exportAsJSON,
|
|
390
|
-
exportAsXLSX,
|
|
391
332
|
};
|
|
392
|
-
}
|
|
333
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback, useEffect, useState } from 'react';
|
|
1
|
+
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
2
|
import { ChartToolbarAction, ChartToolbarGroup } from '../../components/Chart/ChartToolbar';
|
|
3
3
|
import { ChartType } from '../../components/Chart/types';
|
|
4
4
|
|
|
@@ -107,10 +107,16 @@ export function useChartToolbar(
|
|
|
107
107
|
case 'line':
|
|
108
108
|
case 'area':
|
|
109
109
|
case 'bar':
|
|
110
|
+
case 'horizontal-bar':
|
|
110
111
|
case 'scatter':
|
|
112
|
+
case 'bubble':
|
|
113
|
+
case 'funnel':
|
|
114
|
+
case 'waterfall':
|
|
115
|
+
case 'candlestick':
|
|
111
116
|
return {
|
|
112
117
|
...baseDefaults,
|
|
113
118
|
zoom: true,
|
|
119
|
+
pan: true,
|
|
114
120
|
reset: true,
|
|
115
121
|
};
|
|
116
122
|
|
|
@@ -132,31 +138,15 @@ export function useChartToolbar(
|
|
|
132
138
|
grid: false,
|
|
133
139
|
};
|
|
134
140
|
|
|
135
|
-
case 'heatmap':
|
|
136
|
-
case 'treemap':
|
|
137
|
-
return {
|
|
138
|
-
...baseDefaults,
|
|
139
|
-
zoom: true,
|
|
140
|
-
pan: true,
|
|
141
|
-
grid: false,
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
case 'candlestick':
|
|
145
|
-
return {
|
|
146
|
-
...baseDefaults,
|
|
147
|
-
zoom: true,
|
|
148
|
-
pan: true,
|
|
149
|
-
reset: true,
|
|
150
|
-
grid: true,
|
|
151
|
-
};
|
|
152
|
-
|
|
153
141
|
default:
|
|
154
142
|
return baseDefaults;
|
|
155
143
|
}
|
|
156
144
|
}, [chartType]);
|
|
157
145
|
|
|
158
|
-
// Merge configurations
|
|
159
|
-
const finalDefaults =
|
|
146
|
+
// Merge configurations with memoization
|
|
147
|
+
const finalDefaults = useMemo(() => {
|
|
148
|
+
return { ...getChartDefaults(), ...defaults };
|
|
149
|
+
}, [getChartDefaults, defaults]);
|
|
160
150
|
|
|
161
151
|
const enhancedHandlers = {
|
|
162
152
|
onRefresh: useCallback(() => {
|
|
@@ -16,6 +16,7 @@ export function useEdgePanel(initialProps?: Partial<EdgePanelProps>) {
|
|
|
16
16
|
backdrop: true,
|
|
17
17
|
closeOnBackdropClick: true,
|
|
18
18
|
closeOnEscape: true,
|
|
19
|
+
glass: undefined,
|
|
19
20
|
...initialProps,
|
|
20
21
|
};
|
|
21
22
|
|
|
@@ -97,94 +98,143 @@ export function useEdgePanel(initialProps?: Partial<EdgePanelProps>) {
|
|
|
97
98
|
/**
|
|
98
99
|
* Open the panel
|
|
99
100
|
*/
|
|
100
|
-
const openPanel = useCallback(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
101
|
+
const openPanel = useCallback(
|
|
102
|
+
(useFadeAnimation = false) => {
|
|
103
|
+
setIsOpen(true);
|
|
104
|
+
document.body.classList.add('is-edgepanel-open');
|
|
105
|
+
|
|
106
|
+
if (containerRef.current) {
|
|
107
|
+
const { mode } = defaultProps;
|
|
108
|
+
|
|
109
|
+
// Only add animation if not in 'none' mode
|
|
110
|
+
if (mode !== 'none') {
|
|
111
|
+
if (useFadeAnimation) {
|
|
112
|
+
// Add fade animation class
|
|
113
|
+
containerRef.current.classList.add('is-fade-animating');
|
|
114
|
+
|
|
115
|
+
// Force a reflow before starting the animation
|
|
116
|
+
void containerRef.current.offsetHeight;
|
|
117
|
+
|
|
118
|
+
// Remove animation class after animation completes
|
|
119
|
+
const container = containerRef.current;
|
|
120
|
+
setTimeout(() => {
|
|
121
|
+
if (container) {
|
|
122
|
+
container.classList.remove('is-fade-animating');
|
|
123
|
+
}
|
|
124
|
+
}, EDGE_PANEL.ANIMATION_DURATION);
|
|
125
|
+
} else {
|
|
126
|
+
// Add transform animation class
|
|
127
|
+
containerRef.current.classList.add('is-animating');
|
|
128
|
+
|
|
129
|
+
// Force a reflow before starting the animation
|
|
130
|
+
void containerRef.current.offsetHeight;
|
|
131
|
+
|
|
132
|
+
// Remove animation class after animation completes
|
|
133
|
+
const container = containerRef.current;
|
|
134
|
+
setTimeout(() => {
|
|
135
|
+
if (container) {
|
|
136
|
+
container.classList.remove('is-animating');
|
|
137
|
+
}
|
|
138
|
+
}, EDGE_PANEL.ANIMATION_DURATION);
|
|
120
139
|
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
140
|
+
}
|
|
123
141
|
|
|
124
|
-
|
|
125
|
-
|
|
142
|
+
// Set transform or opacity based on animation type
|
|
143
|
+
if (useFadeAnimation) {
|
|
144
|
+
containerRef.current.style.opacity = '1';
|
|
145
|
+
containerRef.current.style.transform = ''; // Remove transform for fade
|
|
146
|
+
} else {
|
|
147
|
+
containerRef.current.style.transform = 'translate(0)';
|
|
148
|
+
}
|
|
126
149
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
150
|
+
// If push mode, adjust body padding
|
|
151
|
+
if (defaultProps.mode === 'push') {
|
|
152
|
+
adjustBodyPadding();
|
|
153
|
+
}
|
|
130
154
|
}
|
|
131
|
-
}
|
|
132
155
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
156
|
+
if (defaultProps.onOpenChange) {
|
|
157
|
+
defaultProps.onOpenChange(true);
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
[defaultProps, adjustBodyPadding]
|
|
161
|
+
);
|
|
137
162
|
|
|
138
163
|
/**
|
|
139
164
|
* Close the panel
|
|
140
165
|
*/
|
|
141
|
-
const closePanel = useCallback(
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
166
|
+
const closePanel = useCallback(
|
|
167
|
+
(useFadeAnimation = false) => {
|
|
168
|
+
if (containerRef.current) {
|
|
169
|
+
const { position, mode } = defaultProps;
|
|
170
|
+
|
|
171
|
+
// Only add animation if not in 'none' mode
|
|
172
|
+
if (mode !== 'none') {
|
|
173
|
+
if (useFadeAnimation) {
|
|
174
|
+
// Add fade out animation class
|
|
175
|
+
containerRef.current.classList.add('is-fade-animating-out');
|
|
176
|
+
|
|
177
|
+
// Capture container for setTimeout
|
|
178
|
+
const container = containerRef.current;
|
|
179
|
+
|
|
180
|
+
setTimeout(() => {
|
|
181
|
+
if (container) {
|
|
182
|
+
container.classList.remove('is-fade-animating-out');
|
|
183
|
+
}
|
|
184
|
+
}, EDGE_PANEL.ANIMATION_DURATION);
|
|
185
|
+
} else {
|
|
186
|
+
// Add transform animation class
|
|
187
|
+
containerRef.current.classList.add('is-animating-out');
|
|
188
|
+
|
|
189
|
+
// Capture container for setTimeout
|
|
190
|
+
const container = containerRef.current;
|
|
191
|
+
|
|
192
|
+
setTimeout(() => {
|
|
193
|
+
if (container) {
|
|
194
|
+
container.classList.remove('is-animating-out');
|
|
195
|
+
}
|
|
196
|
+
}, EDGE_PANEL.ANIMATION_DURATION);
|
|
156
197
|
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
198
|
+
}
|
|
159
199
|
|
|
160
|
-
|
|
161
|
-
|
|
200
|
+
// Set transform or opacity based on animation type
|
|
201
|
+
if (useFadeAnimation) {
|
|
202
|
+
containerRef.current.style.opacity = '0';
|
|
203
|
+
containerRef.current.style.transform = ''; // Remove transform for fade
|
|
204
|
+
} else {
|
|
205
|
+
// Then set transform
|
|
206
|
+
containerRef.current.style.transform = position
|
|
207
|
+
? EDGE_PANEL.TRANSFORM_VALUES[position]
|
|
208
|
+
: '';
|
|
209
|
+
}
|
|
162
210
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
211
|
+
// Reset body padding if push mode
|
|
212
|
+
if (defaultProps.mode === 'push') {
|
|
213
|
+
resetBodyPadding();
|
|
214
|
+
}
|
|
167
215
|
|
|
168
|
-
|
|
169
|
-
|
|
216
|
+
// Wait for animation to complete before hiding
|
|
217
|
+
const hideDelay = mode === 'none' ? 0 : EDGE_PANEL.ANIMATION_DURATION;
|
|
218
|
+
|
|
219
|
+
setTimeout(() => {
|
|
220
|
+
setIsOpen(false);
|
|
221
|
+
document.body.classList.remove('is-edgepanel-open');
|
|
170
222
|
|
|
171
|
-
|
|
223
|
+
if (defaultProps.onOpenChange) {
|
|
224
|
+
defaultProps.onOpenChange(false);
|
|
225
|
+
}
|
|
226
|
+
}, hideDelay);
|
|
227
|
+
} else {
|
|
172
228
|
setIsOpen(false);
|
|
173
229
|
document.body.classList.remove('is-edgepanel-open');
|
|
174
230
|
|
|
175
231
|
if (defaultProps.onOpenChange) {
|
|
176
232
|
defaultProps.onOpenChange(false);
|
|
177
233
|
}
|
|
178
|
-
}, hideDelay);
|
|
179
|
-
} else {
|
|
180
|
-
setIsOpen(false);
|
|
181
|
-
document.body.classList.remove('is-edgepanel-open');
|
|
182
|
-
|
|
183
|
-
if (defaultProps.onOpenChange) {
|
|
184
|
-
defaultProps.onOpenChange(false);
|
|
185
234
|
}
|
|
186
|
-
}
|
|
187
|
-
|
|
235
|
+
},
|
|
236
|
+
[defaultProps, resetBodyPadding]
|
|
237
|
+
);
|
|
188
238
|
|
|
189
239
|
/**
|
|
190
240
|
* Handle Escape key press
|
|
@@ -232,9 +282,13 @@ export function useEdgePanel(initialProps?: Partial<EdgePanelProps>) {
|
|
|
232
282
|
|
|
233
283
|
if (!isOpen && (mode === 'slide' || mode === 'push') && position) {
|
|
234
284
|
containerRef.current.style.transform = EDGE_PANEL.TRANSFORM_VALUES[position];
|
|
285
|
+
// Set initial opacity for fade animations
|
|
286
|
+
if (defaultProps.glass) {
|
|
287
|
+
containerRef.current.style.opacity = '0';
|
|
288
|
+
}
|
|
235
289
|
}
|
|
236
290
|
}
|
|
237
|
-
}, [defaultProps.mode, defaultProps.position, isOpen]);
|
|
291
|
+
}, [defaultProps.mode, defaultProps.position, defaultProps.glass, isOpen]);
|
|
238
292
|
|
|
239
293
|
/**
|
|
240
294
|
* Sync with prop changes
|
|
@@ -242,12 +296,12 @@ export function useEdgePanel(initialProps?: Partial<EdgePanelProps>) {
|
|
|
242
296
|
useEffect(() => {
|
|
243
297
|
if (defaultProps.isOpen !== undefined && defaultProps.isOpen !== isOpen) {
|
|
244
298
|
if (defaultProps.isOpen) {
|
|
245
|
-
openPanel();
|
|
299
|
+
openPanel(!!defaultProps.glass);
|
|
246
300
|
} else {
|
|
247
|
-
closePanel();
|
|
301
|
+
closePanel(!!defaultProps.glass);
|
|
248
302
|
}
|
|
249
303
|
}
|
|
250
|
-
}, [defaultProps.isOpen, closePanel, isOpen, openPanel]);
|
|
304
|
+
}, [defaultProps.isOpen, closePanel, isOpen, openPanel, defaultProps.glass]);
|
|
251
305
|
|
|
252
306
|
return {
|
|
253
307
|
isOpen,
|
|
@@ -14,8 +14,6 @@ export interface UseFooterOptions {
|
|
|
14
14
|
className?: string;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
17
|
export function useFooter(options: UseFooterOptions = {}) {
|
|
20
18
|
const {
|
|
21
19
|
layout = FOOTER.DEFAULTS.LAYOUT,
|
|
@@ -38,6 +36,7 @@ export function useFooter(options: UseFooterOptions = {}) {
|
|
|
38
36
|
`c-footer--${variant}`,
|
|
39
37
|
FOOTER.CLASSES[size.toUpperCase() as keyof typeof FOOTER.CLASSES] || FOOTER.CLASSES.MD,
|
|
40
38
|
sticky && FOOTER.CLASSES.STICKY,
|
|
39
|
+
showNewsletter && 'c-footer--with-newsletter',
|
|
41
40
|
className,
|
|
42
41
|
];
|
|
43
42
|
return classes.filter(Boolean).join(' ');
|
|
@@ -81,5 +80,6 @@ export function useFooter(options: UseFooterOptions = {}) {
|
|
|
81
80
|
handleNewsletterSubmit,
|
|
82
81
|
handleBackToTop,
|
|
83
82
|
socialLinks,
|
|
83
|
+
showNewsletter,
|
|
84
84
|
};
|
|
85
|
-
}
|
|
85
|
+
}
|
|
@@ -18,7 +18,10 @@ export function useGlassContainer(props: GlassContainerProps) {
|
|
|
18
18
|
const [isHovered, setIsHovered] = useState(false);
|
|
19
19
|
const [isActive, setIsActive] = useState(false);
|
|
20
20
|
const [currentGlassSize, setCurrentGlassSize] = useState(glassSize);
|
|
21
|
-
const [internalGlobalMousePos, setInternalGlobalMousePos] = useState<MousePosition>({
|
|
21
|
+
const [internalGlobalMousePos, setInternalGlobalMousePos] = useState<MousePosition>({
|
|
22
|
+
x: 0,
|
|
23
|
+
y: 0,
|
|
24
|
+
});
|
|
22
25
|
const [internalMouseOffset, setInternalMouseOffset] = useState<MousePosition>({ x: 0, y: 0 });
|
|
23
26
|
|
|
24
27
|
// Use external mouse position if provided, otherwise use internal
|
|
@@ -29,7 +32,7 @@ export function useGlassContainer(props: GlassContainerProps) {
|
|
|
29
32
|
const handleMouseMove = useCallback(
|
|
30
33
|
(e: MouseEvent) => {
|
|
31
34
|
const container = mouseContainer?.current || glassRef.current;
|
|
32
|
-
if (!container) return;
|
|
35
|
+
if (!container) return undefined;
|
|
33
36
|
|
|
34
37
|
const rect = container.getBoundingClientRect();
|
|
35
38
|
const centerX = rect.left + rect.width / 2;
|
|
@@ -50,10 +53,10 @@ export function useGlassContainer(props: GlassContainerProps) {
|
|
|
50
53
|
|
|
51
54
|
// Set up mouse tracking if no external mouse position is provided
|
|
52
55
|
useEffect(() => {
|
|
53
|
-
if (externalGlobalMousePos && externalMouseOffset) return;
|
|
56
|
+
if (externalGlobalMousePos && externalMouseOffset) return undefined;
|
|
54
57
|
|
|
55
58
|
const container = mouseContainer?.current || glassRef.current;
|
|
56
|
-
if (!container) return;
|
|
59
|
+
if (!container) return undefined;
|
|
57
60
|
|
|
58
61
|
container.addEventListener('mousemove', handleMouseMove);
|
|
59
62
|
return () => container.removeEventListener('mousemove', handleMouseMove);
|
|
@@ -89,8 +92,14 @@ export function useGlassContainer(props: GlassContainerProps) {
|
|
|
89
92
|
const normalizedY = deltaY / centerDistance;
|
|
90
93
|
const stretchIntensity = Math.min(centerDistance / 300, 1) * elasticity * fadeInFactor;
|
|
91
94
|
|
|
92
|
-
const scaleX =
|
|
93
|
-
|
|
95
|
+
const scaleX =
|
|
96
|
+
1 +
|
|
97
|
+
Math.abs(normalizedX) * stretchIntensity * 0.3 -
|
|
98
|
+
Math.abs(normalizedY) * stretchIntensity * 0.15;
|
|
99
|
+
const scaleY =
|
|
100
|
+
1 +
|
|
101
|
+
Math.abs(normalizedY) * stretchIntensity * 0.3 -
|
|
102
|
+
Math.abs(normalizedX) * stretchIntensity * 0.15;
|
|
94
103
|
|
|
95
104
|
return `scaleX(${Math.max(0.8, scaleX)}) scaleY(${Math.max(0.8, scaleY)})`;
|
|
96
105
|
}, [globalMousePos, elasticity, currentGlassSize]);
|
|
@@ -165,4 +174,4 @@ export function useGlassContainer(props: GlassContainerProps) {
|
|
|
165
174
|
};
|
|
166
175
|
}
|
|
167
176
|
|
|
168
|
-
export default useGlassContainer;
|
|
177
|
+
export default useGlassContainer;
|
|
@@ -122,6 +122,8 @@ export function useLineChart(datasets: ChartDataset[], options: LineChartOptions
|
|
|
122
122
|
pointIndex: number;
|
|
123
123
|
x: number;
|
|
124
124
|
y: number;
|
|
125
|
+
clientX?: number;
|
|
126
|
+
clientY?: number;
|
|
125
127
|
} | null>(null);
|
|
126
128
|
|
|
127
129
|
// Calculate moving averages
|
|
@@ -251,8 +253,15 @@ export function useLineChart(datasets: ChartDataset[], options: LineChartOptions
|
|
|
251
253
|
|
|
252
254
|
// Point hover handlers
|
|
253
255
|
const handlePointHover = useCallback(
|
|
254
|
-
(
|
|
255
|
-
|
|
256
|
+
(
|
|
257
|
+
datasetIndex: number,
|
|
258
|
+
pointIndex: number,
|
|
259
|
+
x: number,
|
|
260
|
+
y: number,
|
|
261
|
+
clientX: number,
|
|
262
|
+
clientY: number
|
|
263
|
+
) => {
|
|
264
|
+
setHoveredPoint({ datasetIndex, pointIndex, x, y, clientX, clientY });
|
|
256
265
|
},
|
|
257
266
|
[]
|
|
258
267
|
);
|
|
@@ -245,20 +245,10 @@ export function usePieChart(data: ChartDataPoint[], options: PieChartOptions = {
|
|
|
245
245
|
requestAnimationFrame(animate);
|
|
246
246
|
}, [options.enableAnimations, options.animationDuration]);
|
|
247
247
|
|
|
248
|
-
// Slice
|
|
249
|
-
const handleSliceHover = useCallback(
|
|
250
|
-
(index
|
|
251
|
-
|
|
252
|
-
setHoveredSlice(index);
|
|
253
|
-
|
|
254
|
-
// Store client coordinates for tooltip positioning
|
|
255
|
-
if (clientX !== undefined && clientY !== undefined && slices[index]) {
|
|
256
|
-
slices[index].clientX = clientX;
|
|
257
|
-
slices[index].clientY = clientY;
|
|
258
|
-
}
|
|
259
|
-
},
|
|
260
|
-
[options.enableHoverEffects, slices]
|
|
261
|
-
);
|
|
248
|
+
// Slice hover handlers
|
|
249
|
+
const handleSliceHover = useCallback((index: number, clientX: number, clientY: number) => {
|
|
250
|
+
setHoveredSlice(index);
|
|
251
|
+
}, []);
|
|
262
252
|
|
|
263
253
|
const handleSliceLeave = useCallback(() => {
|
|
264
254
|
setHoveredSlice(null);
|