@shohojdhara/atomix 0.2.2 → 0.2.4
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/dist/atomix.css +714 -646
- package/dist/atomix.min.css +5 -5
- package/dist/index.d.ts +794 -146
- package/dist/index.esm.js +12052 -6091
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +5133 -2674
- 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/boomdevs.css +662 -594
- package/dist/themes/boomdevs.min.css +7 -7
- package/dist/themes/esrar.css +714 -646
- package/dist/themes/esrar.min.css +6 -6
- package/dist/themes/mashroom.css +707 -642
- package/dist/themes/mashroom.min.css +7 -7
- package/dist/themes/shaj-default.css +707 -642
- package/dist/themes/shaj-default.min.css +6 -6
- package/package.json +66 -15
- package/src/components/Accordion/Accordion.stories.tsx +800 -0
- package/src/components/Accordion/Accordion.tsx +33 -5
- package/src/components/AtomixGlass/AtomixGlass.stories.tsx +1230 -0
- package/src/components/AtomixGlass/AtomixGlass.test.tsx +199 -0
- package/src/components/AtomixGlass/AtomixGlass.tsx +1343 -0
- package/src/components/AtomixGlass/README.md +134 -0
- package/src/components/AtomixGlass/index.ts +10 -0
- package/src/components/AtomixGlass/shader-utils.ts +696 -0
- package/src/components/AtomixGlass/stories/Examples.stories.tsx +5800 -0
- package/src/components/AtomixGlass/stories/Modes.stories.tsx +1065 -0
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +1066 -0
- package/src/components/AtomixGlass/stories/ShaderVariants.stories.tsx +397 -0
- package/src/components/AtomixGlass/stories/shared-components.tsx +310 -0
- package/src/components/AtomixGlass/utils.ts +8 -0
- package/src/components/Badge/Badge.stories.tsx +170 -0
- package/src/components/Badge/Badge.tsx +31 -4
- package/src/components/Button/Button.stories.tsx +826 -0
- package/src/components/Button/Button.tsx +34 -3
- package/src/components/Button/README.md +216 -0
- package/src/components/Callout/Callout.stories.tsx +813 -78
- package/src/components/Callout/Callout.test.tsx +368 -0
- package/src/components/Callout/Callout.tsx +43 -6
- package/src/components/Callout/README.md +409 -0
- package/src/components/Card/Card.stories.tsx +699 -0
- package/src/components/Card/Card.tsx +19 -3
- package/src/components/DatePicker/DatePicker copy.tsx +551 -0
- package/src/components/DatePicker/DatePicker.stories.tsx +877 -1
- package/src/components/DatePicker/DatePicker.tsx +379 -332
- package/src/components/DatePicker/readme.md +110 -1
- package/src/components/DatePicker/types.ts +8 -0
- package/src/components/Dropdown/Dropdown.stories.tsx +145 -0
- package/src/components/Dropdown/Dropdown.tsx +34 -5
- package/src/components/EdgePanel/EdgePanel.stories.tsx +476 -3
- package/src/components/EdgePanel/EdgePanel.tsx +86 -13
- package/src/components/Form/Checkbox.stories.tsx +101 -0
- package/src/components/Form/Checkbox.tsx +26 -2
- package/src/components/Form/Input.stories.tsx +124 -0
- package/src/components/Form/Input.tsx +36 -7
- package/src/components/Form/Radio.stories.tsx +139 -0
- package/src/components/Form/Radio.tsx +26 -2
- package/src/components/Form/Select.stories.tsx +110 -0
- package/src/components/Form/Select.tsx +26 -2
- package/src/components/Form/Textarea.stories.tsx +104 -0
- package/src/components/Form/Textarea.tsx +36 -7
- package/src/components/Hero/Hero.stories.tsx +54 -1
- package/src/components/Hero/Hero.tsx +70 -11
- package/src/components/Messages/Messages.stories.tsx +113 -0
- package/src/components/Messages/Messages.tsx +51 -9
- package/src/components/Modal/Modal.stories.tsx +237 -0
- package/src/components/Modal/Modal.tsx +63 -35
- package/src/components/Navigation/Nav/Nav.stories.tsx +469 -0
- package/src/components/Navigation/Nav/Nav.tsx +17 -4
- package/src/components/Navigation/Navbar/Navbar.stories.tsx +413 -0
- package/src/components/Navigation/Navbar/Navbar.tsx +66 -28
- package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +340 -0
- package/src/components/Navigation/SideMenu/SideMenu.tsx +28 -2
- package/src/components/Pagination/Pagination.stories.tsx +101 -0
- package/src/components/Pagination/Pagination.tsx +25 -1
- package/src/components/Popover/Popover.stories.tsx +94 -0
- package/src/components/Popover/Popover.tsx +30 -4
- package/src/components/Progress/Progress.tsx +17 -2
- package/src/components/Rating/Rating.stories.tsx +112 -0
- package/src/components/Rating/Rating.tsx +25 -1
- package/src/components/Spinner/Spinner.tsx +17 -2
- package/src/components/Steps/Steps.stories.tsx +119 -0
- package/src/components/Steps/Steps.tsx +32 -1
- package/src/components/Tab/Tab.stories.tsx +88 -0
- package/src/components/Tab/Tab.tsx +32 -1
- package/src/components/Toggle/Toggle.stories.tsx +92 -0
- package/src/components/Toggle/Toggle.tsx +32 -1
- package/src/components/Tooltip/Tooltip.stories.tsx +131 -0
- package/src/components/Tooltip/Tooltip.tsx +43 -7
- package/src/components/VideoPlayer/VideoPlayer.stories.tsx +1002 -196
- package/src/components/VideoPlayer/VideoPlayer.tsx +161 -4
- package/src/components/index.ts +1 -0
- package/src/lib/composables/index.ts +4 -0
- package/src/lib/composables/useAtomixGlass.ts +71 -0
- package/src/lib/composables/useBarChart.ts +14 -4
- package/src/lib/composables/useButton.ts +3 -1
- package/src/lib/composables/useCallout.ts +4 -1
- package/src/lib/composables/useChart.ts +223 -370
- package/src/lib/composables/useChartToolbar.ts +11 -20
- package/src/lib/composables/useEdgePanel.ts +81 -35
- package/src/lib/composables/useGlassContainer.ts +168 -0
- package/src/lib/composables/useLineChart.ts +4 -2
- package/src/lib/composables/usePieChart.ts +4 -14
- package/src/lib/constants/components.ts +89 -0
- package/src/lib/types/components.ts +448 -14
- package/src/lib/utils/displacement-generator.ts +86 -0
- package/src/styles/01-settings/_settings.background.scss +8 -7
- package/src/styles/01-settings/_settings.callout.scss +7 -7
- package/src/styles/01-settings/_settings.edge-panel.scss +1 -1
- package/src/styles/02-tools/_tools.animations.scss +19 -0
- package/src/styles/02-tools/_tools.background.scss +19 -17
- package/src/styles/02-tools/_tools.glass.scss +1 -0
- package/src/styles/02-tools/_tools.utility-api.scss +62 -27
- package/src/styles/03-generic/_generic.root.scss +3 -2
- package/src/styles/04-elements/_elements.body.scss +0 -18
- package/src/styles/06-components/_components.accordion.scss +16 -0
- package/src/styles/06-components/_components.atomix-glass.scss +72 -0
- package/src/styles/06-components/_components.badge.scss +21 -0
- package/src/styles/06-components/_components.button.scss +10 -0
- package/src/styles/06-components/_components.callout.scss +46 -2
- package/src/styles/06-components/_components.card.scss +17 -0
- package/src/styles/06-components/_components.chart.scss +1 -1
- package/src/styles/06-components/_components.datepicker.scss +18 -0
- package/src/styles/06-components/_components.dropdown.scss +7 -1
- package/src/styles/06-components/_components.edge-panel.scss +101 -0
- package/src/styles/06-components/_components.hero.scss +1 -2
- package/src/styles/06-components/_components.input.scss +31 -1
- package/src/styles/06-components/_components.messages.scss +176 -0
- package/src/styles/06-components/_components.modal.scss +13 -3
- 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.video-player.scss +48 -26
- package/src/styles/06-components/_index.scss +1 -0
- package/src/styles/99-utilities/_index.scss +1 -0
- package/src/styles/99-utilities/_utilities.glass-fixes.scss +49 -0
- package/src/styles/99-utilities/_utilities.opacity.scss +1 -1
- package/dist/themes/yabai.css +0 -15207
- package/dist/themes/yabai.min.css +0 -189
|
@@ -17,6 +17,7 @@ import { useVideoPlayer } from '../../lib/composables/useVideoPlayer';
|
|
|
17
17
|
import { VIDEO_PLAYER } from '../../lib/constants/components';
|
|
18
18
|
import { VideoPlayerProps } from '../../lib/types/components';
|
|
19
19
|
import { extractYouTubeId, isYouTubeUrl } from '../../lib/utils';
|
|
20
|
+
import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Advanced Video Player Component
|
|
@@ -51,6 +52,9 @@ export const VideoPlayer = forwardRef<HTMLVideoElement, VideoPlayerProps>(
|
|
|
51
52
|
subtitles,
|
|
52
53
|
quality,
|
|
53
54
|
ambientMode = false,
|
|
55
|
+
glass = false,
|
|
56
|
+
glassOpacity = 1,
|
|
57
|
+
glassContent,
|
|
54
58
|
...props
|
|
55
59
|
},
|
|
56
60
|
ref
|
|
@@ -59,6 +63,7 @@ export const VideoPlayer = forwardRef<HTMLVideoElement, VideoPlayerProps>(
|
|
|
59
63
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
60
64
|
const canvasRef = useRef<HTMLCanvasElement>(null);
|
|
61
65
|
const iframeRef = useRef<HTMLIFrameElement>(null);
|
|
66
|
+
const [containerBorderRadius, setContainerBorderRadius] = useState<number>(8);
|
|
62
67
|
|
|
63
68
|
// Determine video source and type
|
|
64
69
|
const isYouTube = type === 'youtube' || youtubeId || (src && isYouTubeUrl(src));
|
|
@@ -115,6 +120,10 @@ export const VideoPlayer = forwardRef<HTMLVideoElement, VideoPlayerProps>(
|
|
|
115
120
|
const [activeSubtitle, setActiveSubtitle] = useState<string | null>(
|
|
116
121
|
subtitles?.find(sub => sub.default)?.srcLang || null
|
|
117
122
|
);
|
|
123
|
+
const [videoDimensions, setVideoDimensions] = useState<{ width: number; height: number }>({
|
|
124
|
+
width: 0,
|
|
125
|
+
height: 0,
|
|
126
|
+
});
|
|
118
127
|
|
|
119
128
|
const handleProgressClick = useCallback(
|
|
120
129
|
(e: React.MouseEvent<HTMLDivElement>) => {
|
|
@@ -225,12 +234,107 @@ export const VideoPlayer = forwardRef<HTMLVideoElement, VideoPlayerProps>(
|
|
|
225
234
|
return undefined;
|
|
226
235
|
}, [subtitles, setSubtitle, videoRef]);
|
|
227
236
|
|
|
237
|
+
// Track video/iframe dimensions for AtomixGlass
|
|
238
|
+
useEffect(() => {
|
|
239
|
+
const updateDimensions = () => {
|
|
240
|
+
if (isYouTube && iframeRef.current) {
|
|
241
|
+
const iframe = iframeRef.current;
|
|
242
|
+
const rect = iframe.getBoundingClientRect();
|
|
243
|
+
setVideoDimensions({ width: rect.width, height: rect.height });
|
|
244
|
+
} else if (videoRef.current) {
|
|
245
|
+
const video = videoRef.current;
|
|
246
|
+
const rect = video.getBoundingClientRect();
|
|
247
|
+
setVideoDimensions({ width: rect.width, height: rect.height });
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
// Initial measurement with slight delay to ensure element is rendered
|
|
252
|
+
const initialTimer = setTimeout(updateDimensions, 100);
|
|
253
|
+
|
|
254
|
+
// Use ResizeObserver to track size changes
|
|
255
|
+
const resizeObserver = new ResizeObserver(updateDimensions);
|
|
256
|
+
|
|
257
|
+
if (isYouTube && iframeRef.current) {
|
|
258
|
+
const iframe = iframeRef.current;
|
|
259
|
+
resizeObserver.observe(iframe);
|
|
260
|
+
|
|
261
|
+
// Listen for iframe load event
|
|
262
|
+
const handleIframeLoad = () => updateDimensions();
|
|
263
|
+
iframe.addEventListener('load', handleIframeLoad);
|
|
264
|
+
|
|
265
|
+
return () => {
|
|
266
|
+
clearTimeout(initialTimer);
|
|
267
|
+
resizeObserver.disconnect();
|
|
268
|
+
iframe.removeEventListener('load', handleIframeLoad);
|
|
269
|
+
};
|
|
270
|
+
} else if (videoRef.current) {
|
|
271
|
+
const video = videoRef.current;
|
|
272
|
+
resizeObserver.observe(video);
|
|
273
|
+
|
|
274
|
+
// Listen for video metadata loaded event
|
|
275
|
+
const handleLoadedMetadata = () => updateDimensions();
|
|
276
|
+
video.addEventListener('loadedmetadata', handleLoadedMetadata);
|
|
277
|
+
|
|
278
|
+
return () => {
|
|
279
|
+
clearTimeout(initialTimer);
|
|
280
|
+
resizeObserver.disconnect();
|
|
281
|
+
video.removeEventListener('loadedmetadata', handleLoadedMetadata);
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Also listen for window resize
|
|
286
|
+
window.addEventListener('resize', updateDimensions);
|
|
287
|
+
|
|
288
|
+
return () => {
|
|
289
|
+
clearTimeout(initialTimer);
|
|
290
|
+
resizeObserver.disconnect();
|
|
291
|
+
window.removeEventListener('resize', updateDimensions);
|
|
292
|
+
};
|
|
293
|
+
}, [isYouTube, videoRef, iframeRef]);
|
|
294
|
+
|
|
228
295
|
const handleContainerClick = useCallback(() => {
|
|
229
296
|
if (containerRef.current) {
|
|
230
297
|
containerRef.current.focus();
|
|
231
298
|
}
|
|
232
299
|
}, []);
|
|
233
300
|
|
|
301
|
+
// Detect container border radius
|
|
302
|
+
useEffect(() => {
|
|
303
|
+
const detectBorderRadius = () => {
|
|
304
|
+
if (!containerRef.current) return;
|
|
305
|
+
|
|
306
|
+
const computedStyle = window.getComputedStyle(containerRef.current);
|
|
307
|
+
const borderRadius = computedStyle.borderRadius || computedStyle.borderTopLeftRadius;
|
|
308
|
+
|
|
309
|
+
// Parse the border radius value (remove 'px' and convert to number)
|
|
310
|
+
const radiusValue = parseFloat(borderRadius);
|
|
311
|
+
if (!isNaN(radiusValue)) {
|
|
312
|
+
setContainerBorderRadius(radiusValue);
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
// Detect border radius immediately
|
|
317
|
+
detectBorderRadius();
|
|
318
|
+
|
|
319
|
+
// Create ResizeObserver to watch for style changes
|
|
320
|
+
let resizeObserver: ResizeObserver | null = null;
|
|
321
|
+
if (typeof ResizeObserver !== 'undefined' && containerRef.current) {
|
|
322
|
+
resizeObserver = new ResizeObserver(detectBorderRadius);
|
|
323
|
+
resizeObserver.observe(containerRef.current);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Also listen for window resize (in case styles change)
|
|
327
|
+
window.addEventListener('resize', detectBorderRadius);
|
|
328
|
+
|
|
329
|
+
return () => {
|
|
330
|
+
window.removeEventListener('resize', detectBorderRadius);
|
|
331
|
+
if (resizeObserver && containerRef.current) {
|
|
332
|
+
resizeObserver.unobserve(containerRef.current);
|
|
333
|
+
resizeObserver.disconnect();
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
}, []);
|
|
337
|
+
|
|
234
338
|
const handleKeyDown = useCallback(
|
|
235
339
|
(e: React.KeyboardEvent) => {
|
|
236
340
|
switch (e.key) {
|
|
@@ -271,7 +375,7 @@ export const VideoPlayer = forwardRef<HTMLVideoElement, VideoPlayerProps>(
|
|
|
271
375
|
return (
|
|
272
376
|
<div
|
|
273
377
|
ref={containerRef}
|
|
274
|
-
className={`${VIDEO_PLAYER.CLASSES.BASE} ${isYouTube ? VIDEO_PLAYER.CLASSES.YOUTUBE : ''} ${ambientMode ? VIDEO_PLAYER.CLASSES.AMBIENT : ''} ${className}`}
|
|
378
|
+
className={`${VIDEO_PLAYER.CLASSES.BASE} ${isYouTube ? VIDEO_PLAYER.CLASSES.YOUTUBE : ''} ${ambientMode ? VIDEO_PLAYER.CLASSES.AMBIENT : ''} ${glass ? VIDEO_PLAYER.CLASSES.GLASS : ''} ${className}`}
|
|
275
379
|
style={{
|
|
276
380
|
width,
|
|
277
381
|
height,
|
|
@@ -313,11 +417,13 @@ export const VideoPlayer = forwardRef<HTMLVideoElement, VideoPlayerProps>(
|
|
|
313
417
|
) : (
|
|
314
418
|
<video
|
|
315
419
|
ref={element => {
|
|
316
|
-
videoRef.current
|
|
420
|
+
if (videoRef && videoRef.current !== element) {
|
|
421
|
+
(videoRef as React.MutableRefObject<HTMLVideoElement | null>).current = element;
|
|
422
|
+
}
|
|
317
423
|
if (typeof ref === 'function') {
|
|
318
424
|
ref(element);
|
|
319
|
-
} else if (ref) {
|
|
320
|
-
ref.current = element;
|
|
425
|
+
} else if (ref && ref.current !== element) {
|
|
426
|
+
(ref as React.MutableRefObject<HTMLVideoElement | null>).current = element;
|
|
321
427
|
}
|
|
322
428
|
}}
|
|
323
429
|
className={VIDEO_PLAYER.CLASSES.VIDEO}
|
|
@@ -350,9 +456,60 @@ export const VideoPlayer = forwardRef<HTMLVideoElement, VideoPlayerProps>(
|
|
|
350
456
|
</div>
|
|
351
457
|
)}
|
|
352
458
|
|
|
459
|
+
{/* Glass overlay - positioned between video and controls */}
|
|
460
|
+
{glass && (
|
|
461
|
+
<div className={VIDEO_PLAYER.CLASSES.GLASS_OVERLAY}>
|
|
462
|
+
<AtomixGlass
|
|
463
|
+
{...(typeof glass === 'boolean' ? {} : glass)}
|
|
464
|
+
style={{
|
|
465
|
+
borderRadius: 'inherit',
|
|
466
|
+
}}
|
|
467
|
+
mouseContainer={containerRef}
|
|
468
|
+
displacementScale={30}
|
|
469
|
+
blurAmount={0}
|
|
470
|
+
saturation={100}
|
|
471
|
+
aberrationIntensity={0}
|
|
472
|
+
cornerRadius={containerBorderRadius}
|
|
473
|
+
elasticity={0}
|
|
474
|
+
>
|
|
475
|
+
{!glassContent && (
|
|
476
|
+
<div
|
|
477
|
+
style={{
|
|
478
|
+
width: videoDimensions.width > 0 ? `${videoDimensions.width}px` : '100%',
|
|
479
|
+
height: videoDimensions.height > 0 ? `${videoDimensions.height}px` : '100%',
|
|
480
|
+
display: 'flex',
|
|
481
|
+
alignItems: 'center',
|
|
482
|
+
justifyContent: 'center',
|
|
483
|
+
background: 'transparent',
|
|
484
|
+
}}
|
|
485
|
+
>
|
|
486
|
+
{/* Glass effect background */}
|
|
487
|
+
</div>
|
|
488
|
+
)}
|
|
489
|
+
</AtomixGlass>
|
|
490
|
+
</div>
|
|
491
|
+
)}
|
|
492
|
+
|
|
493
|
+
{/* Custom glass content overlay */}
|
|
494
|
+
{glass && glassContent && (
|
|
495
|
+
<div
|
|
496
|
+
className={VIDEO_PLAYER.CLASSES.GLASS_CONTENT}
|
|
497
|
+
style={{
|
|
498
|
+
display: 'flex',
|
|
499
|
+
alignItems: 'center',
|
|
500
|
+
justifyContent: 'center',
|
|
501
|
+
}}
|
|
502
|
+
>
|
|
503
|
+
{glassContent}
|
|
504
|
+
</div>
|
|
505
|
+
)}
|
|
506
|
+
|
|
353
507
|
{controls && !isYouTube && (
|
|
354
508
|
<div
|
|
355
509
|
className={`${VIDEO_PLAYER.CLASSES.CONTROLS} ${showControls ? VIDEO_PLAYER.CLASSES.CONTROLS_VISIBLE : ''}`}
|
|
510
|
+
style={{
|
|
511
|
+
zIndex: glass ? 3 : 'auto',
|
|
512
|
+
}}
|
|
356
513
|
>
|
|
357
514
|
<div className={VIDEO_PLAYER.CLASSES.PROGRESS_CONTAINER}>
|
|
358
515
|
<div className={VIDEO_PLAYER.CLASSES.PROGRESS_BAR} onClick={handleProgressClick}>
|
package/src/components/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export type { SliderProps, VideoPlayerProps } from '../lib/types/components';
|
|
2
2
|
export { default as Accordion, type AccordionProps } from './Accordion/Accordion';
|
|
3
3
|
export { default as AtomixLogo, type AtomixLogoProps } from './AtomixLogo/AtomixLogo';
|
|
4
|
+
export { default as AtomixGlass, type AtomixGlassProps } from './AtomixGlass';
|
|
4
5
|
export { default as Avatar, type AvatarProps } from './Avatar/Avatar';
|
|
5
6
|
export { default as AvatarGroup, type AvatarGroupProps } from './Avatar/AvatarGroup';
|
|
6
7
|
export { default as Badge, type BadgeProps } from './Badge/Badge';
|
|
@@ -32,6 +32,10 @@ export * from './useTodo';
|
|
|
32
32
|
export * from './useCheckbox';
|
|
33
33
|
export * from './useForm';
|
|
34
34
|
export * from './useFormGroup';
|
|
35
|
+
|
|
36
|
+
// GlassContainer composables
|
|
37
|
+
export * from './useGlassContainer';
|
|
38
|
+
export * from './useAtomixGlass';
|
|
35
39
|
export * from './useInput';
|
|
36
40
|
export * from './useRadio';
|
|
37
41
|
export * from './useSelect';
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface UseAtomixGlassOptions {
|
|
4
|
+
size?: 'sm' | 'md' | 'lg';
|
|
5
|
+
mode?: 'standard' | 'polar' | 'prominent' | 'shader';
|
|
6
|
+
overLight?: boolean;
|
|
7
|
+
clickable?: boolean;
|
|
8
|
+
active?: boolean;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface UseAtomixGlassReturn {
|
|
13
|
+
generateGlassClass: (options: UseAtomixGlassOptions) => string;
|
|
14
|
+
generateElementClass: (element: string, modifier?: string) => string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Hook for generating AtomixGlass CSS classes following BEM methodology
|
|
19
|
+
*/
|
|
20
|
+
export function useAtomixGlass(): UseAtomixGlassReturn {
|
|
21
|
+
// Generate CSS class for the main glass component
|
|
22
|
+
const generateGlassClass = useCallback((options: UseAtomixGlassOptions) => {
|
|
23
|
+
const classes = ['c-atomix-glass'];
|
|
24
|
+
|
|
25
|
+
// Add size modifier
|
|
26
|
+
if (options.size && options.size !== 'md') {
|
|
27
|
+
classes.push(`c-atomix-glass--${options.size}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Add mode modifier
|
|
31
|
+
if (options.mode && options.mode !== 'standard') {
|
|
32
|
+
classes.push(`c-atomix-glass--${options.mode}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Add state modifiers
|
|
36
|
+
if (options.clickable) {
|
|
37
|
+
classes.push('c-atomix-glass--clickable');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (options.overLight) {
|
|
41
|
+
classes.push('c-atomix-glass--over-light');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (options.active) {
|
|
45
|
+
classes.push('c-atomix-glass--active');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Add custom className
|
|
49
|
+
if (options.className) {
|
|
50
|
+
classes.push(options.className);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return classes.filter(Boolean).join(' ');
|
|
54
|
+
}, []);
|
|
55
|
+
|
|
56
|
+
// Generate CSS class for elements
|
|
57
|
+
const generateElementClass = useCallback((element: string, modifier?: string) => {
|
|
58
|
+
const baseClass = `c-atomix-glass__${element}`;
|
|
59
|
+
|
|
60
|
+
if (modifier) {
|
|
61
|
+
return `${baseClass}--${modifier}`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return baseClass;
|
|
65
|
+
}, []);
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
generateGlassClass,
|
|
69
|
+
generateElementClass,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -101,8 +101,10 @@ export function useBarChart(datasets: ChartDataset[], options: BarChartOptions =
|
|
|
101
101
|
const [hoveredBar, setHoveredBar] = useState<{
|
|
102
102
|
datasetIndex: number;
|
|
103
103
|
pointIndex: number;
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
chartX: number;
|
|
105
|
+
chartY: number;
|
|
106
|
+
clientX: number;
|
|
107
|
+
clientY: number;
|
|
106
108
|
} | null>(null);
|
|
107
109
|
|
|
108
110
|
const [animationProgress, setAnimationProgress] = useState(0);
|
|
@@ -119,6 +121,7 @@ export function useBarChart(datasets: ChartDataset[], options: BarChartOptions =
|
|
|
119
121
|
): BarDimensions[] => {
|
|
120
122
|
if (!datasets.length) return [];
|
|
121
123
|
|
|
124
|
+
// Use provided dimensions and padding (from ChartRenderer scales)
|
|
122
125
|
const innerWidth = width - padding.left - padding.right;
|
|
123
126
|
const innerHeight = height - padding.top - padding.bottom;
|
|
124
127
|
const numCategories = datasets[0]?.data?.length || 0;
|
|
@@ -270,8 +273,15 @@ export function useBarChart(datasets: ChartDataset[], options: BarChartOptions =
|
|
|
270
273
|
|
|
271
274
|
// Bar hover handlers
|
|
272
275
|
const handleBarHover = useCallback(
|
|
273
|
-
(datasetIndex: number, pointIndex: number,
|
|
274
|
-
setHoveredBar({
|
|
276
|
+
(datasetIndex: number, pointIndex: number, chartX: number, chartY: number, clientX: number, clientY: number) => {
|
|
277
|
+
setHoveredBar({
|
|
278
|
+
datasetIndex,
|
|
279
|
+
pointIndex,
|
|
280
|
+
chartX,
|
|
281
|
+
chartY,
|
|
282
|
+
clientX,
|
|
283
|
+
clientY
|
|
284
|
+
});
|
|
275
285
|
},
|
|
276
286
|
[]
|
|
277
287
|
);
|
|
@@ -27,6 +27,7 @@ export function useButton(initialProps?: Partial<ButtonProps>) {
|
|
|
27
27
|
disabled = defaultProps.disabled,
|
|
28
28
|
rounded = defaultProps.rounded,
|
|
29
29
|
iconOnly = false,
|
|
30
|
+
glass = defaultProps.glass,
|
|
30
31
|
className = '',
|
|
31
32
|
} = props;
|
|
32
33
|
|
|
@@ -34,8 +35,9 @@ export function useButton(initialProps?: Partial<ButtonProps>) {
|
|
|
34
35
|
const iconOnlyClass = iconOnly ? 'c-btn--icon' : '';
|
|
35
36
|
const roundedClass = rounded ? 'c-btn--rounded' : '';
|
|
36
37
|
const disabledClass = disabled ? 'c-btn--disabled' : '';
|
|
38
|
+
const glassClass = glass ? 'c-btn--glass' : '';
|
|
37
39
|
|
|
38
|
-
return `c-btn c-btn--${variant} ${sizeClass} ${iconOnlyClass} ${roundedClass} ${disabledClass} ${className}`.trim();
|
|
40
|
+
return `c-btn c-btn--${variant} ${sizeClass} ${iconOnlyClass} ${roundedClass} ${disabledClass} ${glassClass} ${className}`.trim();
|
|
39
41
|
};
|
|
40
42
|
|
|
41
43
|
/**
|
|
@@ -11,6 +11,7 @@ export function useCallout(initialProps?: Partial<CalloutProps>) {
|
|
|
11
11
|
variant: 'primary',
|
|
12
12
|
oneLine: false,
|
|
13
13
|
toast: false,
|
|
14
|
+
glass: false,
|
|
14
15
|
...initialProps,
|
|
15
16
|
};
|
|
16
17
|
|
|
@@ -24,14 +25,16 @@ export function useCallout(initialProps?: Partial<CalloutProps>) {
|
|
|
24
25
|
variant = defaultProps.variant,
|
|
25
26
|
oneLine = defaultProps.oneLine,
|
|
26
27
|
toast = defaultProps.toast,
|
|
28
|
+
glass = defaultProps.glass,
|
|
27
29
|
className = '',
|
|
28
30
|
} = props;
|
|
29
31
|
|
|
30
32
|
const oneLineClass = oneLine ? 'c-callout--oneline' : '';
|
|
31
33
|
const toastClass = toast ? 'c-callout--toast' : '';
|
|
32
34
|
const variantClass = variant ? `c-callout--${variant}` : '';
|
|
35
|
+
const glassClass = glass ? 'c-callout--glass' : '';
|
|
33
36
|
|
|
34
|
-
return `c-callout ${variantClass} ${oneLineClass} ${toastClass} ${className}`.trim();
|
|
37
|
+
return `c-callout ${variantClass} ${oneLineClass} ${toastClass} ${glassClass} ${className}`.trim();
|
|
35
38
|
};
|
|
36
39
|
|
|
37
40
|
/**
|