@donotdev/components 0.0.16 → 0.0.18
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/advanced/Bento/Bento.d.ts +1 -1
- package/dist/advanced/Bento/Bento.js +1 -1
- package/dist/advanced/Code/CodeContent.d.ts.map +1 -1
- package/dist/advanced/Code/CodeContent.js +23 -6
- package/dist/advanced/Code/CodeSkeleton.js +4 -4
- package/dist/advanced/ImageGallery/ImageGallery.d.ts.map +1 -1
- package/dist/advanced/ImageGallery/ImageGallery.js +11 -5
- package/dist/advanced/JsonViewer/JsonViewer.d.ts +1 -1
- package/dist/advanced/JsonViewer/JsonViewer.d.ts.map +1 -1
- package/dist/advanced/JsonViewer/JsonViewer.js +9 -3
- package/dist/atomic/ActionButton/index.js +2 -2
- package/dist/atomic/ActionButton/useAction.d.ts.map +1 -1
- package/dist/atomic/ActionButton/useAction.js +18 -5
- package/dist/atomic/Alert/index.d.ts +1 -1
- package/dist/atomic/Alert/index.d.ts.map +1 -1
- package/dist/atomic/Alert/index.js +1 -1
- package/dist/atomic/Badge/index.d.ts +1 -1
- package/dist/atomic/Button/index.d.ts +2 -2
- package/dist/atomic/Button/index.d.ts.map +1 -1
- package/dist/atomic/CallToAction/index.d.ts +2 -1
- package/dist/atomic/CallToAction/index.d.ts.map +1 -1
- package/dist/atomic/CallToAction/index.js +2 -1
- package/dist/atomic/Combobox/index.d.ts.map +1 -1
- package/dist/atomic/Combobox/index.js +3 -3
- package/dist/atomic/CopyToClipboard/index.d.ts.map +1 -1
- package/dist/atomic/CopyToClipboard/index.js +20 -4
- package/dist/atomic/Dialog/index.js +1 -1
- package/dist/atomic/DropdownMenu/DropdownMenuPrimitive.d.ts.map +1 -1
- package/dist/atomic/DropdownMenu/DropdownMenuPrimitive.js +5 -21
- package/dist/atomic/DropdownMenu/index.d.ts.map +1 -1
- package/dist/atomic/DropdownMenu/index.js +7 -17
- package/dist/atomic/Grid/GridArea.d.ts +2 -2
- package/dist/atomic/Grid/GridArea.js +2 -2
- package/dist/atomic/Grid/index.d.ts +39 -22
- package/dist/atomic/Grid/index.d.ts.map +1 -1
- package/dist/atomic/Grid/index.js +56 -27
- package/dist/atomic/HeroSection/index.d.ts +3 -0
- package/dist/atomic/HeroSection/index.d.ts.map +1 -1
- package/dist/atomic/HeroSection/index.js +5 -2
- package/dist/atomic/HoverCard/HoverCardPrimitive.d.ts.map +1 -1
- package/dist/atomic/HoverCard/HoverCardPrimitive.js +1 -1
- package/dist/atomic/HoverCard/index.d.ts +19 -4
- package/dist/atomic/HoverCard/index.d.ts.map +1 -1
- package/dist/atomic/HoverCard/index.js +24 -5
- package/dist/atomic/Icons/Icon.d.ts.map +1 -1
- package/dist/atomic/Icons/Icon.js +11 -10
- package/dist/atomic/InfiniteScroll/index.d.ts +4 -2
- package/dist/atomic/InfiniteScroll/index.d.ts.map +1 -1
- package/dist/atomic/InfiniteScroll/index.js +2 -2
- package/dist/atomic/Pagination/index.js +1 -1
- package/dist/atomic/Popover/PopoverPrimitive.d.ts +1 -1
- package/dist/atomic/Popover/PopoverPrimitive.d.ts.map +1 -1
- package/dist/atomic/Popover/PopoverPrimitive.js +2 -2
- package/dist/atomic/Popover/index.d.ts +2 -2
- package/dist/atomic/Popover/index.d.ts.map +1 -1
- package/dist/atomic/Rating/index.d.ts +1 -1
- package/dist/atomic/Rating/index.d.ts.map +1 -1
- package/dist/atomic/Section/index.d.ts +9 -6
- package/dist/atomic/Section/index.d.ts.map +1 -1
- package/dist/atomic/Section/index.js +3 -2
- package/dist/atomic/Select/index.d.ts.map +1 -1
- package/dist/atomic/Select/index.js +2 -3
- package/dist/atomic/Stack/index.d.ts +2 -2
- package/dist/atomic/Stack/index.js +2 -2
- package/dist/atomic/Stepper/index.d.ts +5 -1
- package/dist/atomic/Stepper/index.d.ts.map +1 -1
- package/dist/atomic/Stepper/index.js +9 -6
- package/dist/atomic/Table/index.d.ts +27 -5
- package/dist/atomic/Table/index.d.ts.map +1 -1
- package/dist/atomic/Table/index.js +55 -6
- package/dist/atomic/Tabs/index.d.ts +1 -1
- package/dist/atomic/Tag/index.d.ts +1 -1
- package/dist/atomic/Text/index.d.ts +2 -0
- package/dist/atomic/Text/index.d.ts.map +1 -1
- package/dist/atomic/Text/index.js +2 -1
- package/dist/atomic/Toaster/ToastPrimitive.d.ts +1 -1
- package/dist/atomic/Toaster/ToastPrimitive.d.ts.map +1 -1
- package/dist/atomic/Toaster/ToastPrimitive.js +1 -13
- package/dist/atomic/Toggle/index.d.ts +1 -1
- package/dist/atomic/index.d.ts +1 -1
- package/dist/atomic/index.d.ts.map +1 -1
- package/dist/hooks/useToast.d.ts.map +1 -1
- package/dist/hooks/useToast.js +18 -3
- package/dist/hooks/useViewportVisibility.d.ts.map +1 -1
- package/dist/hooks/useViewportVisibility.js +10 -12
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -4
- package/dist/styles/index.css +259 -96
- package/dist/types.d.ts +1 -1
- package/dist/utils/constants.d.ts +13 -0
- package/dist/utils/constants.d.ts.map +1 -1
- package/dist/utils/constants.js +12 -0
- package/dist/utils/intersectionObserver.d.ts.map +1 -1
- package/dist/utils/intersectionObserver.js +1 -11
- package/dist/utils/variants.d.ts +1 -1
- package/package.json +3 -3
|
@@ -11,7 +11,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
11
11
|
* @author AMBROISE PARK Consulting
|
|
12
12
|
*/
|
|
13
13
|
import { ChevronRight, Check } from 'lucide-react';
|
|
14
|
-
import { Children
|
|
14
|
+
import { Children } from 'react';
|
|
15
15
|
import { DropdownMenuPrimitive, DropdownMenuTriggerPrimitive, DropdownMenuContentPrimitive, DropdownMenuItemPrimitive, DropdownMenuSubPrimitive, DropdownMenuSubTriggerPrimitive, DropdownMenuSubContentPrimitive, DropdownMenuPortalPrimitive, DropdownMenuLabelPrimitive, DropdownMenuSeparatorPrimitive, } from './DropdownMenuPrimitive';
|
|
16
16
|
import { cn } from '../../utils/helpers';
|
|
17
17
|
import ScrollArea from '../ScrollArea';
|
|
@@ -48,22 +48,12 @@ const getIconOnlyAriaLabel = (hasIcon, hasLabel, label, fallback) => {
|
|
|
48
48
|
const DropdownMenu = ({ trigger, items = [], children, contentWidth, contentAlign = 'start', open, onOpenChange, }) => {
|
|
49
49
|
if (!trigger)
|
|
50
50
|
return null;
|
|
51
|
-
// Normalize children to ensure keys (React.Children.toArray handles this automatically)
|
|
52
51
|
const normalizedChildren = children ? Children.toArray(children) : [];
|
|
53
|
-
// Wrap children in DropdownMenuItemPrimitive
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (isValidElement(child) &&
|
|
59
|
-
child.props?.['data-role'] === 'menu-item') {
|
|
60
|
-
// Already a menu item, don't wrap
|
|
61
|
-
return child;
|
|
62
|
-
}
|
|
63
|
-
// Wrap child in DropdownMenuItemPrimitive for auto-close behavior
|
|
64
|
-
// Using asChild merges props correctly with the child component
|
|
65
|
-
return (_jsx(DropdownMenuItemPrimitive, { className: "dndev-interactive", asChild: true, children: child }, index));
|
|
66
|
-
});
|
|
52
|
+
// Wrap children in DropdownMenuItemPrimitive (without asChild).
|
|
53
|
+
// Radix renders its own wrapper element with proper onSelect → auto-close.
|
|
54
|
+
// asChild doesn't work here because components (GoTo, ThemeToggle, etc.)
|
|
55
|
+
// don't forward Radix's merged event handlers to the DOM.
|
|
56
|
+
const wrappedChildren = normalizedChildren.map((child, index) => (_jsx(DropdownMenuItemPrimitive, { children: child }, index)));
|
|
67
57
|
const content = (_jsxs(_Fragment, { children: [wrappedChildren, items.length > 0 &&
|
|
68
58
|
items.map((item, index) => {
|
|
69
59
|
// Label item
|
|
@@ -84,7 +74,7 @@ const DropdownMenu = ({ trigger, items = [], children, contentWidth, contentAlig
|
|
|
84
74
|
!hasSubLabel && { 'data-display': 'compact' }), children: [Icon && _jsx(Icon, {}), _jsx("span", { children: submenuItem.label }), _jsx(ChevronRight, { className: "dndev-dropdown-menu-trailing" })] }), _jsx(DropdownMenuPortalPrimitive, { children: _jsx(DropdownMenuSubContentPrimitive, { className: cn('dndev-floating dndev-z-tooltip', submenuItem.subContent
|
|
85
75
|
? 'dndev-dropdown-sub-content-custom'
|
|
86
76
|
: ''), children: submenuItem.subContent ||
|
|
87
|
-
submenuItem.subItems
|
|
77
|
+
submenuItem.subItems?.map((subItem, subIndex) => {
|
|
88
78
|
// Handle label/separator in submenu
|
|
89
79
|
if (subItem.type === 'label') {
|
|
90
80
|
return (_jsx(DropdownMenuLabelPrimitive, { className: cn('dndev-menu-label', subItem.className), children: subItem.label }, subIndex));
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* @example
|
|
10
10
|
* ```tsx
|
|
11
11
|
* // Generic grid areas (default)
|
|
12
|
-
* <Grid areas="left center right"
|
|
12
|
+
* <Grid areas="left center right" cols=fr">
|
|
13
13
|
* <GridArea name="left">{leftContent}</GridArea>
|
|
14
14
|
* <GridArea name="center">{centerContent}</GridArea>
|
|
15
15
|
* <GridArea name="right">{rightContent}</GridArea>
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* @example
|
|
20
20
|
* ```tsx
|
|
21
21
|
* // Semantic grid layout
|
|
22
|
-
* <Grid areas="header main sidebar footer"
|
|
22
|
+
* <Grid areas="header main sidebar footer" cols=r">
|
|
23
23
|
* <GridArea as="header" name="header">Header</GridArea>
|
|
24
24
|
* <GridArea as="main" name="main">Main Content</GridArea>
|
|
25
25
|
* <GridArea as="aside" name="sidebar">Sidebar</GridArea>
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* @example
|
|
11
11
|
* ```tsx
|
|
12
12
|
* // Generic grid areas (default)
|
|
13
|
-
* <Grid areas="left center right"
|
|
13
|
+
* <Grid areas="left center right" cols=fr">
|
|
14
14
|
* <GridArea name="left">{leftContent}</GridArea>
|
|
15
15
|
* <GridArea name="center">{centerContent}</GridArea>
|
|
16
16
|
* <GridArea name="right">{rightContent}</GridArea>
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* @example
|
|
21
21
|
* ```tsx
|
|
22
22
|
* // Semantic grid layout
|
|
23
|
-
* <Grid areas="header main sidebar footer"
|
|
23
|
+
* <Grid areas="header main sidebar footer" cols=r">
|
|
24
24
|
* <GridArea as="header" name="header">Header</GridArea>
|
|
25
25
|
* <GridArea as="main" name="main">Main Content</GridArea>
|
|
26
26
|
* <GridArea as="aside" name="sidebar">Sidebar</GridArea>
|
|
@@ -5,29 +5,37 @@
|
|
|
5
5
|
* @example
|
|
6
6
|
* ```tsx
|
|
7
7
|
* // Fixed 3-column grid
|
|
8
|
-
* <Grid cols={3}
|
|
8
|
+
* <Grid cols={3}>
|
|
9
9
|
* <Card />
|
|
10
10
|
* <Card />
|
|
11
11
|
* <Card />
|
|
12
12
|
* </Grid>
|
|
13
13
|
*
|
|
14
|
-
* // Responsive
|
|
15
|
-
*
|
|
16
|
-
* <Grid cols={[1, 1, 2, 3]} gap="medium">
|
|
14
|
+
* // Responsive equal columns: [mobile, tablet, laptop, desktop]
|
|
15
|
+
* <Grid cols={[1, 1, 2, 3]}>
|
|
17
16
|
* <Card />
|
|
18
17
|
* <Card />
|
|
19
18
|
* <Card />
|
|
20
19
|
* </Grid>
|
|
21
20
|
*
|
|
22
|
-
* //
|
|
23
|
-
* <Grid
|
|
21
|
+
* // Custom column template (static)
|
|
22
|
+
* <Grid cols="1fr auto 1fr" areas="left center right">
|
|
24
23
|
* <GridArea name="left">{left}</GridArea>
|
|
25
24
|
* <GridArea name="center">{center}</GridArea>
|
|
26
25
|
* <GridArea name="right">{right}</GridArea>
|
|
27
26
|
* </Grid>
|
|
27
|
+
*
|
|
28
|
+
* // Custom column template (responsive) + responsive areas
|
|
29
|
+
* <Grid
|
|
30
|
+
* cols={["1fr", "1fr", "1fr 3fr", "1fr 3fr"]}
|
|
31
|
+
* areas={['"a" "b"', '"a" "b"', '"a b"', '"a b"']}
|
|
32
|
+
* >
|
|
33
|
+
* <GridArea name="a">{left}</GridArea>
|
|
34
|
+
* <GridArea name="b">{right}</GridArea>
|
|
35
|
+
* </Grid>
|
|
28
36
|
* ```
|
|
29
37
|
*
|
|
30
|
-
* @version 0.0.
|
|
38
|
+
* @version 0.0.5
|
|
31
39
|
* @since 0.0.1
|
|
32
40
|
* @author AMBROISE PARK Consulting
|
|
33
41
|
*/
|
|
@@ -38,6 +46,15 @@ import './Grid.css';
|
|
|
38
46
|
* @example [1, 1, 2, 3] - 1 col on mobile/tablet, 2 on laptop, 3 on desktop
|
|
39
47
|
*/
|
|
40
48
|
export type ResponsiveCols = [number, number, number, number];
|
|
49
|
+
/**
|
|
50
|
+
* Responsive template array: [mobile, tablet, laptop, desktop]
|
|
51
|
+
* @example ["1fr", "1fr", "1fr 3fr", "1fr 3fr"] - stacked on mobile/tablet, 1:3 ratio on laptop/desktop
|
|
52
|
+
*/
|
|
53
|
+
export type ResponsiveTemplate = [string, string, string, string];
|
|
54
|
+
/**
|
|
55
|
+
* Unified column type: equal columns (number) or custom template (string), static or responsive
|
|
56
|
+
*/
|
|
57
|
+
export type GridCols = number | string | ResponsiveCols | ResponsiveTemplate;
|
|
41
58
|
/**
|
|
42
59
|
* Grid-specific props (layout directives)
|
|
43
60
|
*/
|
|
@@ -49,15 +66,18 @@ interface GridOwnProps {
|
|
|
49
66
|
*/
|
|
50
67
|
as?: ElementType;
|
|
51
68
|
/**
|
|
52
|
-
*
|
|
53
|
-
* - number: fixed columns (
|
|
54
|
-
* -
|
|
69
|
+
* Column layout — unified prop for all column patterns:
|
|
70
|
+
* - number: fixed equal columns → repeat(N, 1fr)
|
|
71
|
+
* - string: custom template → raw grid-template-columns value
|
|
72
|
+
* - [number x4]: responsive equal columns per breakpoint
|
|
73
|
+
* - [string x4]: responsive custom template per breakpoint
|
|
55
74
|
* @default 1
|
|
56
|
-
* @example 3 - always 3 columns
|
|
57
|
-
* @example
|
|
58
|
-
* @example [1,
|
|
75
|
+
* @example 3 - always 3 equal columns
|
|
76
|
+
* @example "1fr 3fr" - custom ratio
|
|
77
|
+
* @example [1, 1, 2, 3] - responsive equal: 1 mobile/tablet, 2 laptop, 3 desktop
|
|
78
|
+
* @example ["1fr", "1fr", "1fr 3fr", "1fr 3fr"] - responsive template: stacked mobile, 1:3 desktop
|
|
59
79
|
*/
|
|
60
|
-
cols?:
|
|
80
|
+
cols?: GridCols;
|
|
61
81
|
/**
|
|
62
82
|
* Spacing between items
|
|
63
83
|
* @default 'medium'
|
|
@@ -76,15 +96,12 @@ interface GridOwnProps {
|
|
|
76
96
|
/**
|
|
77
97
|
* Named grid areas (CSS grid-template-areas)
|
|
78
98
|
* Use with GridArea component for semantic grid layouts
|
|
79
|
-
*
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
* Grid template columns (CSS grid-template-columns)
|
|
84
|
-
* Required when using `areas` prop
|
|
85
|
-
* @example "1fr auto 1fr", "1fr auto", "200px 1fr"
|
|
99
|
+
* - string: static areas (same on all breakpoints)
|
|
100
|
+
* - [mobile, tablet, laptop, desktop]: responsive areas per breakpoint
|
|
101
|
+
* @example "left center right"
|
|
102
|
+
* @example ['"a" "b"', '"a" "b"', '"a b"', '"a b"'] - stacked mobile, side-by-side desktop
|
|
86
103
|
*/
|
|
87
|
-
|
|
104
|
+
areas?: string | ResponsiveTemplate;
|
|
88
105
|
/** Content */
|
|
89
106
|
children: ReactNode;
|
|
90
107
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atomic/Grid/index.tsx"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atomic/Grid/index.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AAIf,OAAO,YAAY,CAAC;AAEpB;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAE9D;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,cAAc,GAAG,kBAAkB,CAAC;AAE7E;;GAEG;AACH,UAAU,YAAY;IACpB;;;;OAIG;IACH,EAAE,CAAC,EAAE,WAAW,CAAC;IAEjB;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAEhB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IAE5C;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;IAE/C;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;IAEjD;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAAC;IAEpC,cAAc;IACd,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,WAAW,GAAG,KAAK,IAAI,YAAY,GACjE,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,MAAM,YAAY,CAAC,CAAC;AAErD;;;;;GAKG;AACH,QAAA,MAAM,IAAI,uHA8ET,CAAC;AAIF,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,YAAY,CAAC;AACjD,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,eAAe,IAAI,CAAC"}
|
|
@@ -6,29 +6,37 @@
|
|
|
6
6
|
* @example
|
|
7
7
|
* ```tsx
|
|
8
8
|
* // Fixed 3-column grid
|
|
9
|
-
* <Grid cols={3}
|
|
9
|
+
* <Grid cols={3}>
|
|
10
10
|
* <Card />
|
|
11
11
|
* <Card />
|
|
12
12
|
* <Card />
|
|
13
13
|
* </Grid>
|
|
14
14
|
*
|
|
15
|
-
* // Responsive
|
|
16
|
-
*
|
|
17
|
-
* <Grid cols={[1, 1, 2, 3]} gap="medium">
|
|
15
|
+
* // Responsive equal columns: [mobile, tablet, laptop, desktop]
|
|
16
|
+
* <Grid cols={[1, 1, 2, 3]}>
|
|
18
17
|
* <Card />
|
|
19
18
|
* <Card />
|
|
20
19
|
* <Card />
|
|
21
20
|
* </Grid>
|
|
22
21
|
*
|
|
23
|
-
* //
|
|
24
|
-
* <Grid
|
|
22
|
+
* // Custom column template (static)
|
|
23
|
+
* <Grid cols="1fr auto 1fr" areas="left center right">
|
|
25
24
|
* <GridArea name="left">{left}</GridArea>
|
|
26
25
|
* <GridArea name="center">{center}</GridArea>
|
|
27
26
|
* <GridArea name="right">{right}</GridArea>
|
|
28
27
|
* </Grid>
|
|
28
|
+
*
|
|
29
|
+
* // Custom column template (responsive) + responsive areas
|
|
30
|
+
* <Grid
|
|
31
|
+
* cols={["1fr", "1fr", "1fr 3fr", "1fr 3fr"]}
|
|
32
|
+
* areas={['"a" "b"', '"a" "b"', '"a b"', '"a b"']}
|
|
33
|
+
* >
|
|
34
|
+
* <GridArea name="a">{left}</GridArea>
|
|
35
|
+
* <GridArea name="b">{right}</GridArea>
|
|
36
|
+
* </Grid>
|
|
29
37
|
* ```
|
|
30
38
|
*
|
|
31
|
-
* @version 0.0.
|
|
39
|
+
* @version 0.0.5
|
|
32
40
|
* @since 0.0.1
|
|
33
41
|
* @author AMBROISE PARK Consulting
|
|
34
42
|
*/
|
|
@@ -42,38 +50,59 @@ import './Grid.css';
|
|
|
42
50
|
* Polymorphic CSS Grid layout primitive.
|
|
43
51
|
* Can render as any HTML element while maintaining grid layout.
|
|
44
52
|
*/
|
|
45
|
-
const Grid = forwardRef(({ as = 'div', cols = 1, gap = GAP_VARIANT.MEDIUM, align = 'stretch', justify = 'stretch', areas,
|
|
53
|
+
const Grid = forwardRef(({ as = 'div', cols = 1, gap = GAP_VARIANT.MEDIUM, align = 'stretch', justify = 'stretch', areas, className, style, children, ...props }, ref) => {
|
|
46
54
|
const Component = as;
|
|
47
|
-
//
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
// Detect which cols variant we're dealing with
|
|
56
|
+
const isArray = Array.isArray(cols);
|
|
57
|
+
const isResponsiveEqual = isArray && typeof cols[0] === 'number';
|
|
58
|
+
const isResponsiveTpl = isArray && typeof cols[0] === 'string';
|
|
59
|
+
const isStaticTpl = typeof cols === 'string';
|
|
60
|
+
const isResponsiveAreas = Array.isArray(areas);
|
|
52
61
|
const customStyle = {
|
|
53
62
|
display: 'grid',
|
|
54
63
|
width: '100%',
|
|
55
|
-
// Set CSS custom properties for responsive columns
|
|
56
|
-
'--grid-cols-mobile': colsMobile,
|
|
57
|
-
'--grid-cols-tablet': colsTablet,
|
|
58
|
-
'--grid-cols-laptop': colsLaptop,
|
|
59
|
-
'--grid-cols-desktop': colsDesktop,
|
|
60
64
|
...style,
|
|
61
|
-
...(areas
|
|
62
|
-
? {
|
|
63
|
-
gridTemplateAreas: areas.trim().startsWith('"')
|
|
64
|
-
? areas
|
|
65
|
-
: `"${areas}"`,
|
|
66
|
-
}
|
|
67
|
-
: {}),
|
|
68
|
-
...(templateColumns && { gridTemplateColumns: templateColumns }),
|
|
69
65
|
};
|
|
66
|
+
if (isResponsiveTpl) {
|
|
67
|
+
const tpl = cols;
|
|
68
|
+
customStyle['--grid-tpl-mobile'] = tpl[0];
|
|
69
|
+
customStyle['--grid-tpl-tablet'] = tpl[1];
|
|
70
|
+
customStyle['--grid-tpl-laptop'] = tpl[2];
|
|
71
|
+
customStyle['--grid-tpl-desktop'] = tpl[3];
|
|
72
|
+
}
|
|
73
|
+
else if (isStaticTpl) {
|
|
74
|
+
customStyle.gridTemplateColumns = cols;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const [m, t, l, d] = isResponsiveEqual
|
|
78
|
+
? cols
|
|
79
|
+
: [cols, cols, cols, cols];
|
|
80
|
+
customStyle['--grid-cols-mobile'] = m;
|
|
81
|
+
customStyle['--grid-cols-tablet'] = t;
|
|
82
|
+
customStyle['--grid-cols-laptop'] = l;
|
|
83
|
+
customStyle['--grid-cols-desktop'] = d;
|
|
84
|
+
}
|
|
85
|
+
if (isResponsiveAreas) {
|
|
86
|
+
const fmt = (v) => (v.trim().startsWith('"') ? v : `"${v}"`);
|
|
87
|
+
customStyle['--grid-areas-mobile'] = fmt(areas[0]);
|
|
88
|
+
customStyle['--grid-areas-tablet'] = fmt(areas[1]);
|
|
89
|
+
customStyle['--grid-areas-laptop'] = fmt(areas[2]);
|
|
90
|
+
customStyle['--grid-areas-desktop'] = fmt(areas[3]);
|
|
91
|
+
}
|
|
92
|
+
else if (typeof areas === 'string') {
|
|
93
|
+
customStyle.gridTemplateAreas = areas.trim().startsWith('"')
|
|
94
|
+
? areas
|
|
95
|
+
: `"${areas}"`;
|
|
96
|
+
}
|
|
70
97
|
return createElement(Component, {
|
|
71
98
|
ref,
|
|
72
99
|
className: cn('dndev-grid-component', className),
|
|
73
100
|
'data-gap': gap,
|
|
74
101
|
'data-align': align,
|
|
75
102
|
'data-justify': justify,
|
|
76
|
-
'data-responsive':
|
|
103
|
+
'data-responsive': isResponsiveEqual ? 'true' : undefined,
|
|
104
|
+
'data-responsive-tpl': isResponsiveTpl ? 'true' : undefined,
|
|
105
|
+
'data-responsive-areas': isResponsiveAreas ? 'true' : undefined,
|
|
77
106
|
style: customStyle,
|
|
78
107
|
...props,
|
|
79
108
|
}, children);
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
*/
|
|
23
23
|
import { type VariantProps } from 'class-variance-authority';
|
|
24
24
|
import { type ElementType, type ComponentPropsWithRef, type ReactNode } from 'react';
|
|
25
|
+
import { type Tone } from '../../utils/constants';
|
|
25
26
|
import './HeroSection.css';
|
|
26
27
|
declare const heroSectionVariants: (props?: ({
|
|
27
28
|
variant?: "primary" | "accent" | "subtle" | null | undefined;
|
|
@@ -39,6 +40,8 @@ interface HeroSectionOwnProps extends VariantProps<typeof heroSectionVariants> {
|
|
|
39
40
|
fullHeight?: boolean;
|
|
40
41
|
/** Content alignment @default 'center' */
|
|
41
42
|
align?: 'start' | 'center' | 'end';
|
|
43
|
+
/** Tone system for background colors (matches Section/CallToAction) */
|
|
44
|
+
tone?: Tone;
|
|
42
45
|
/** Content */
|
|
43
46
|
children?: ReactNode;
|
|
44
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atomic/HeroSection/index.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atomic/HeroSection/index.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,EAAQ,KAAK,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAMxD,OAAO,mBAAmB,CAAC;AAE3B,QAAA,MAAM,mBAAmB;;8EAWvB,CAAC;AAEH,UAAU,mBAAoB,SAAQ,YAAY,CAAC,OAAO,mBAAmB,CAAC;IAC5E,mDAAmD;IACnD,EAAE,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,KAAK,CAAC;IAClC,iBAAiB;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,2BAA2B;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACnC,uEAAuE;IACvE,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,cAAc;IACd,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,WAAW,GAAG,SAAS,IAC5D,mBAAmB,GACjB,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,MAAM,mBAAmB,CAAC,CAAC;AAE9D,QAAA,MAAM,WAAW,kIAgEhB,CAAC;AAIF,eAAe,WAAW,CAAC"}
|
|
@@ -24,6 +24,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
24
24
|
*/
|
|
25
25
|
import { cva } from 'class-variance-authority';
|
|
26
26
|
import { createElement, forwardRef, } from 'react';
|
|
27
|
+
import { TONE } from '../../utils/constants';
|
|
27
28
|
import { cn } from '../../utils/helpers';
|
|
28
29
|
import Badge, { BADGE_VARIANT } from '../Badge';
|
|
29
30
|
import Stack from '../Stack';
|
|
@@ -41,11 +42,13 @@ const heroSectionVariants = cva('', {
|
|
|
41
42
|
variant: 'primary',
|
|
42
43
|
},
|
|
43
44
|
});
|
|
44
|
-
const HeroSection = forwardRef(function HeroSection({ as = 'section', badge, title, subtitle, variant, fullHeight = false, align = 'center', children, className, ...props }, ref) {
|
|
45
|
+
const HeroSection = forwardRef(function HeroSection({ as = 'section', badge, title, subtitle, variant, fullHeight = false, align = 'center', tone = TONE.GHOST, children, className, ...props }, ref) {
|
|
45
46
|
return createElement(as, {
|
|
46
47
|
ref,
|
|
47
48
|
className: cn('dndev-hero-section', className),
|
|
48
49
|
'data-text-align': align,
|
|
50
|
+
'data-variant': variant || undefined,
|
|
51
|
+
'data-tone': tone,
|
|
49
52
|
style: {
|
|
50
53
|
...(fullHeight
|
|
51
54
|
? {
|
|
@@ -56,7 +59,7 @@ const HeroSection = forwardRef(function HeroSection({ as = 'section', badge, tit
|
|
|
56
59
|
...props.style,
|
|
57
60
|
},
|
|
58
61
|
...props,
|
|
59
|
-
}, _jsxs(Stack, {
|
|
62
|
+
}, _jsxs(Stack, { children: [badge && _jsx(Badge, { variant: BADGE_VARIANT.ACCENT, children: badge }), title && (_jsx(Text, { as: "div", level: "h1", className: "dndev-hero-title", "data-gradient-text": variant === 'subtle' ? undefined : variant || 'primary', children: title })), subtitle && (_jsx(Text, { as: "p", level: "body", className: "dndev-hero-subtitle", children: subtitle })), children] }));
|
|
60
63
|
});
|
|
61
64
|
HeroSection.displayName = 'HeroSection';
|
|
62
65
|
export default HeroSection;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HoverCardPrimitive.d.ts","sourceRoot":"","sources":["../../../src/atomic/HoverCard/HoverCardPrimitive.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,KAAK,cAAc,MAAM,4BAA4B,CAAC;AAI7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAE5C,QAAA,MAAM,kBAAkB,GAAI,yBAGzB,cAAc,CAAC,cAAc,4CAE/B,CAAC;AAEF,QAAA,MAAM,gBAAgB,oIAAyB,CAAC;AAEhD,QAAA,MAAM,gBAAgB,GAAI,4CAKvB,cAAc,CAAC,OAAO,cAAc,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"HoverCardPrimitive.d.ts","sourceRoot":"","sources":["../../../src/atomic/HoverCard/HoverCardPrimitive.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,KAAK,cAAc,MAAM,4BAA4B,CAAC;AAI7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAE5C,QAAA,MAAM,kBAAkB,GAAI,yBAGzB,cAAc,CAAC,cAAc,4CAE/B,CAAC;AAEF,QAAA,MAAM,gBAAgB,oIAAyB,CAAC;AAEhD,QAAA,MAAM,gBAAgB,GAAI,4CAKvB,cAAc,CAAC,OAAO,cAAc,CAAC,OAAO,CAAC,4CAW/C,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -13,7 +13,7 @@ import { cn } from '../../utils/helpers';
|
|
|
13
13
|
const HoverCardPrimitive = ({ openDelay = 0, ...props }) => (_jsx(RadixHoverCard.Root, { openDelay: openDelay, ...props }));
|
|
14
14
|
const HoverCardTrigger = RadixHoverCard.Trigger;
|
|
15
15
|
const HoverCardContent = ({ className, align = 'center', sideOffset = 4, ...props }) => {
|
|
16
|
-
return (_jsx(RadixHoverCard.Content, { align: align, sideOffset: sideOffset, className: cn(className), ...props }));
|
|
16
|
+
return (_jsx(RadixHoverCard.Portal, { children: _jsx(RadixHoverCard.Content, { align: align, sideOffset: sideOffset, className: cn(className), ...props }) }));
|
|
17
17
|
};
|
|
18
18
|
export { HoverCardPrimitive };
|
|
19
19
|
export { HoverCardTrigger, HoverCardContent };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { type CardProps } from '../Card';
|
|
1
2
|
import type { ReactNode } from 'react';
|
|
2
|
-
export interface HoverCardProps {
|
|
3
|
+
export interface HoverCardProps extends Pick<CardProps, 'title' | 'subtitle' | 'content' | 'footer' | 'icon' | 'variant'> {
|
|
3
4
|
/** Trigger element (button, text, avatar, etc.) */
|
|
4
5
|
trigger?: ReactNode;
|
|
5
|
-
/** HoverCard content */
|
|
6
|
+
/** HoverCard content (alternative to content prop, for full control) */
|
|
6
7
|
children?: ReactNode;
|
|
7
8
|
/** Controlled open state */
|
|
8
9
|
open?: boolean;
|
|
@@ -23,11 +24,25 @@ export interface HoverCardProps {
|
|
|
23
24
|
}
|
|
24
25
|
/**
|
|
25
26
|
* Accessible hover card component.
|
|
26
|
-
* Shows rich content on hover
|
|
27
|
+
* Shows rich content on hover using Radix HoverCard primitive.
|
|
28
|
+
*
|
|
29
|
+
* ⚠️ **Desktop only**: This component uses hover events and does not support touch/click interactions.
|
|
30
|
+
* For mobile/click support, use {@link Popover} instead.
|
|
31
|
+
*
|
|
32
|
+
* Accepts Card props (title, subtitle, content, footer, variant, icon) and renders a Card internally.
|
|
27
33
|
*
|
|
28
34
|
* @component
|
|
29
35
|
* @example
|
|
30
36
|
* ```tsx
|
|
37
|
+
* // Using Card props
|
|
38
|
+
* <HoverCard
|
|
39
|
+
* trigger={<Avatar src="..." />}
|
|
40
|
+
* title="John Doe"
|
|
41
|
+
* subtitle="Software Engineer"
|
|
42
|
+
* content="Building amazing products"
|
|
43
|
+
* />
|
|
44
|
+
*
|
|
45
|
+
* // Using children for full control
|
|
31
46
|
* <HoverCard trigger={<Avatar src="..." />}>
|
|
32
47
|
* <Stack gap="tight">
|
|
33
48
|
* <Text>John Doe</Text>
|
|
@@ -38,6 +53,6 @@ export interface HoverCardProps {
|
|
|
38
53
|
* @param {HoverCardProps} props - The props for the hover card
|
|
39
54
|
* @returns {JSX.Element} The rendered hover card
|
|
40
55
|
*/
|
|
41
|
-
declare function HoverCard({ trigger, children, open, onOpenChange, openDelay, closeDelay, align, side, sideOffset, className, }: HoverCardProps): import("react/jsx-runtime").JSX.Element;
|
|
56
|
+
declare function HoverCard({ trigger, title, subtitle, content, footer, icon, variant, children, open, onOpenChange, openDelay, closeDelay, align, side, sideOffset, className, }: HoverCardProps): import("react/jsx-runtime").JSX.Element;
|
|
42
57
|
export default HoverCard;
|
|
43
58
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atomic/HoverCard/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atomic/HoverCard/index.tsx"],"names":[],"mappings":"AAmBA,OAAa,EAAE,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AAG/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,cAAe,SAAQ,IAAI,CAC1C,SAAS,EACT,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CACjE;IACC,mDAAmD;IACnD,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,4BAA4B;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,uCAAuC;IACvC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,gCAAgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACnC,8BAA8B;IAC9B,IAAI,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC3C,4BAA4B;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,iBAAS,SAAS,CAAC,EACjB,OAAO,EACP,KAAK,EACL,QAAQ,EACR,OAAO,EACP,MAAM,EACN,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,IAAI,EACJ,YAAY,EACZ,SAAa,EACb,UAAc,EACd,KAAgB,EAChB,IAAe,EACf,UAAc,EACd,SAAS,GACV,EAAE,cAAc,2CAqChB;AAED,eAAe,SAAS,CAAC"}
|
|
@@ -2,21 +2,38 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
// packages/components/src/atomic/HoverCard/index.tsx
|
|
3
3
|
/**
|
|
4
4
|
* @fileoverview HoverCard component
|
|
5
|
-
* @description Accessible hover card component built on Radix UI primitives
|
|
5
|
+
* @description Accessible hover card component built on Radix UI primitives.
|
|
6
|
+
* Accepts Card props and renders a Card internally.
|
|
6
7
|
*
|
|
7
|
-
* @version 0.0.
|
|
8
|
+
* @version 0.0.2
|
|
8
9
|
* @since 0.0.1
|
|
9
10
|
* @author AMBROISE PARK Consulting
|
|
10
11
|
*/
|
|
12
|
+
import { useState } from 'react';
|
|
11
13
|
import { HoverCardPrimitive, HoverCardTrigger, HoverCardContent, } from './HoverCardPrimitive';
|
|
14
|
+
import Card, {} from '../Card';
|
|
12
15
|
import { cn } from '../../utils/helpers';
|
|
13
16
|
/**
|
|
14
17
|
* Accessible hover card component.
|
|
15
|
-
* Shows rich content on hover
|
|
18
|
+
* Shows rich content on hover using Radix HoverCard primitive.
|
|
19
|
+
*
|
|
20
|
+
* ⚠️ **Desktop only**: This component uses hover events and does not support touch/click interactions.
|
|
21
|
+
* For mobile/click support, use {@link Popover} instead.
|
|
22
|
+
*
|
|
23
|
+
* Accepts Card props (title, subtitle, content, footer, variant, icon) and renders a Card internally.
|
|
16
24
|
*
|
|
17
25
|
* @component
|
|
18
26
|
* @example
|
|
19
27
|
* ```tsx
|
|
28
|
+
* // Using Card props
|
|
29
|
+
* <HoverCard
|
|
30
|
+
* trigger={<Avatar src="..." />}
|
|
31
|
+
* title="John Doe"
|
|
32
|
+
* subtitle="Software Engineer"
|
|
33
|
+
* content="Building amazing products"
|
|
34
|
+
* />
|
|
35
|
+
*
|
|
36
|
+
* // Using children for full control
|
|
20
37
|
* <HoverCard trigger={<Avatar src="..." />}>
|
|
21
38
|
* <Stack gap="tight">
|
|
22
39
|
* <Text>John Doe</Text>
|
|
@@ -27,7 +44,9 @@ import { cn } from '../../utils/helpers';
|
|
|
27
44
|
* @param {HoverCardProps} props - The props for the hover card
|
|
28
45
|
* @returns {JSX.Element} The rendered hover card
|
|
29
46
|
*/
|
|
30
|
-
function HoverCard({ trigger, children, open, onOpenChange, openDelay = 0, closeDelay = 0, align = 'center', side = 'bottom', sideOffset = 4, className, }) {
|
|
31
|
-
|
|
47
|
+
function HoverCard({ trigger, title, subtitle, content, footer, icon, variant, children, open, onOpenChange, openDelay = 0, closeDelay = 0, align = 'center', side = 'bottom', sideOffset = 4, className, }) {
|
|
48
|
+
const hasCardProps = !!(title || subtitle || content || footer || icon || variant);
|
|
49
|
+
const cardContent = hasCardProps ? (_jsx(Card, { title: title, subtitle: subtitle, content: content, footer: footer, icon: icon, variant: variant })) : (children);
|
|
50
|
+
return (_jsxs(HoverCardPrimitive, { open: open, onOpenChange: onOpenChange, openDelay: openDelay, closeDelay: closeDelay, children: [trigger && _jsx(HoverCardTrigger, { asChild: true, children: trigger }), _jsx(HoverCardContent, { align: align, side: side, sideOffset: sideOffset, className: cn('dndev-z-tooltip dndev-hovercard-content', !hasCardProps && 'dndev-surface', className), children: cardContent })] }));
|
|
32
51
|
}
|
|
33
52
|
export default HoverCard;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../../src/atomic/Icons/Icon.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEtD,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;IACvD,kEAAkE;IAClE,QAAQ,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;IAC3D,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,QAAA,MAAM,IAAI,EAAE,aAAa,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../../src/atomic/Icons/Icon.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEtD,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;IACvD,kEAAkE;IAClE,QAAQ,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;IAC3D,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,QAAA,MAAM,IAAI,EAAE,aAAa,CAAC,SAAS,CA4FlC,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -12,6 +12,14 @@ import { cn } from '../../utils/helpers';
|
|
|
12
12
|
const Icon = ({ icon, fallback, className, ariaHidden = false, }) => {
|
|
13
13
|
// Memoize icon resolution to avoid recalculation
|
|
14
14
|
const iconToRender = useMemo(() => icon || fallback, [icon, fallback]);
|
|
15
|
+
// Memoize emoji check — must be unconditional (Rules of Hooks)
|
|
16
|
+
const isEmoji = useMemo(() => {
|
|
17
|
+
if (typeof iconToRender !== 'string')
|
|
18
|
+
return false;
|
|
19
|
+
// If it's a valid identifier pattern, it's NOT an emoji (it's a Lucide icon name)
|
|
20
|
+
const isValidIdentifier = /^[a-zA-Z0-9_-]+$/.test(iconToRender);
|
|
21
|
+
return !isValidIdentifier;
|
|
22
|
+
}, [iconToRender]);
|
|
15
23
|
if (!iconToRender)
|
|
16
24
|
return null;
|
|
17
25
|
const sizeClass = 'dndev-size-md';
|
|
@@ -25,21 +33,14 @@ const Icon = ({ icon, fallback, className, ariaHidden = false, }) => {
|
|
|
25
33
|
}
|
|
26
34
|
// Type 2: String (emoji only - no dynamic icon name lookup for tree-shaking)
|
|
27
35
|
if (typeof iconToRender === 'string') {
|
|
28
|
-
// Check if string is an emoji (not a valid identifier)
|
|
29
|
-
// Valid identifiers: alphanumeric, underscore, hyphen (Lucide icon names)
|
|
30
|
-
// Emojis: anything else (Unicode symbols, emojis, etc.)
|
|
31
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
32
|
-
const isEmoji = useMemo(() => {
|
|
33
|
-
// If it's a valid identifier pattern, it's NOT an emoji (it's a Lucide icon name)
|
|
34
|
-
const isValidIdentifier = /^[a-zA-Z0-9_-]+$/.test(iconToRender);
|
|
35
|
-
return !isValidIdentifier;
|
|
36
|
-
}, [iconToRender]);
|
|
37
36
|
if (isEmoji) {
|
|
38
37
|
return (_jsx("span", { className: cn('dndev-inline-flex dndev-items-center dndev-justify-center', sizeClass, className), "aria-hidden": ariaHidden, children: iconToRender }));
|
|
39
38
|
}
|
|
40
39
|
// Non-emoji string: Not supported (would require full lucide-react import)
|
|
41
40
|
// Use Icon from @donotdev/ui for dynamic string icon resolution
|
|
42
|
-
|
|
41
|
+
if (process.env.NODE_ENV === 'development') {
|
|
42
|
+
console.warn(`Icon component from @donotdev/components does not support Lucide icon name strings. Use Icon from @donotdev/ui for dynamic string resolution, or import the icon component directly. Received: "${iconToRender}"`);
|
|
43
|
+
}
|
|
43
44
|
return null;
|
|
44
45
|
}
|
|
45
46
|
// Type 3: ReactNode (custom content)
|
|
@@ -11,7 +11,9 @@ import './InfiniteScroll.css';
|
|
|
11
11
|
export interface InfiniteScrollProps<T> {
|
|
12
12
|
items: T[];
|
|
13
13
|
renderItem: (item: T, index: number) => ReactNode;
|
|
14
|
-
|
|
14
|
+
/** Extract a stable key for each item. Falls back to index when not provided. */
|
|
15
|
+
keyExtractor?: (item: T, index: number) => string | number;
|
|
16
|
+
loadMore: () => void | Promise<void>;
|
|
15
17
|
hasMore: boolean;
|
|
16
18
|
loading?: boolean;
|
|
17
19
|
loadingComponent?: ReactNode;
|
|
@@ -23,6 +25,6 @@ export interface InfiniteScrollProps<T> {
|
|
|
23
25
|
gridCols?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
24
26
|
gap?: 'none' | 'tight' | 'medium' | 'large';
|
|
25
27
|
}
|
|
26
|
-
declare const InfiniteScroll: <T>({ items, renderItem, loadMore, hasMore, loading, loadingComponent, endMessage, threshold, rootMargin, className, itemClassName, gridCols, gap, }: InfiniteScrollProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
declare const InfiniteScroll: <T>({ items, renderItem, keyExtractor, loadMore, hasMore, loading, loadingComponent, endMessage, threshold, rootMargin, className, itemClassName, gridCols, gap, }: InfiniteScrollProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
27
29
|
export default InfiniteScroll;
|
|
28
30
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atomic/InfiniteScroll/index.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAMf,OAAO,sBAAsB,CAAC;AAE9B,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IAClD,QAAQ,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atomic/InfiniteScroll/index.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAMf,OAAO,sBAAsB,CAAC;AAE9B,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IAClD,iFAAiF;IACjF,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAAC;IAC3D,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;CAC7C;AAED,QAAA,MAAM,cAAc,GAAI,CAAC,EAAG,gKAezB,mBAAmB,CAAC,CAAC,CAAC,4CAuGxB,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
|
@@ -14,7 +14,7 @@ import { cn, observeElement } from '../../utils';
|
|
|
14
14
|
import Spinner from '../Spinner';
|
|
15
15
|
import Stack from '../Stack';
|
|
16
16
|
import './InfiniteScroll.css';
|
|
17
|
-
const InfiniteScroll = ({ items, renderItem, loadMore, hasMore, loading = false, loadingComponent, endMessage, threshold = 0.1, rootMargin = '100px', className, itemClassName, gridCols = 3, gap = GAP_VARIANT.MEDIUM, }) => {
|
|
17
|
+
const InfiniteScroll = ({ items, renderItem, keyExtractor, loadMore, hasMore, loading = false, loadingComponent, endMessage, threshold = 0.1, rootMargin = '100px', className, itemClassName, gridCols = 3, gap = GAP_VARIANT.MEDIUM, }) => {
|
|
18
18
|
const [isLoading, setIsLoading] = useState(false);
|
|
19
19
|
const loadMoreRef = useRef(null);
|
|
20
20
|
const handleLoadMore = useCallback(async () => {
|
|
@@ -48,6 +48,6 @@ const InfiniteScroll = ({ items, renderItem, loadMore, hasMore, loading = false,
|
|
|
48
48
|
}[gap];
|
|
49
49
|
const defaultLoadingComponent = (_jsx(Stack, { align: "center", justify: "center", className: "dndev-py-lg", children: _jsxs(Stack, { direction: "row", align: "center", gap: "tight", className: "dndev-infinite-scroll-loading-container", children: [_jsx(Spinner, {}), _jsx("span", { children: "Loading more..." })] }) }));
|
|
50
50
|
const defaultEndMessage = (_jsx(Stack, { align: "center", justify: "center", className: "dndev-py-lg", children: _jsxs("div", { className: "dndev-text-center dndev-infinite-scroll-end-title", children: [_jsx("p", { className: "dndev-text-lg dndev-font-medium", children: "\uD83C\uDF89 You've seen it all!" }), _jsx("p", { className: "dndev-text-sm dndev-infinite-scroll-end-text", children: "That's everything we have to showcase." })] }) }));
|
|
51
|
-
return (_jsxs("div", { className: cn('dndev-grid dndev-gap-md', className), children: [_jsx("div", { className: "dndev-infinite-scroll-grid", "data-cols": gridCols, style: gapStyle, children: items.map((item, index) => (_jsx("div", { className: itemClassName, children: renderItem(item, index) }, index))) }), hasMore && (_jsx(Stack, { ref: loadMoreRef, justify: "center", className: "dndev-py-md", children: loading || isLoading ? (loadingComponent || defaultLoadingComponent) : (_jsx("div", { className: "dndev-text-sm dndev-infinite-scroll-more-text", children: "Scroll down to load more..." })) })), !hasMore && items.length > 0 && (_jsx(Stack, { justify: "center", className: "dndev-infinite-scroll-end-container", children: endMessage || defaultEndMessage }))] }));
|
|
51
|
+
return (_jsxs("div", { className: cn('dndev-grid dndev-gap-md', className), children: [_jsx("div", { className: "dndev-infinite-scroll-grid", "data-cols": gridCols, style: gapStyle, children: items.map((item, index) => (_jsx("div", { className: itemClassName, children: renderItem(item, index) }, keyExtractor ? keyExtractor(item, index) : index))) }), hasMore && (_jsx(Stack, { ref: loadMoreRef, justify: "center", className: "dndev-py-md", children: loading || isLoading ? (loadingComponent || defaultLoadingComponent) : (_jsx("div", { className: "dndev-text-sm dndev-infinite-scroll-more-text", children: "Scroll down to load more..." })) })), !hasMore && items.length > 0 && (_jsx(Stack, { justify: "center", className: "dndev-infinite-scroll-end-container", children: endMessage || defaultEndMessage }))] }));
|
|
52
52
|
};
|
|
53
53
|
export default InfiniteScroll;
|
|
@@ -44,7 +44,7 @@ showNavigation = true, previousLabel = 'Previous', nextLabel = 'Next', itemsPerP
|
|
|
44
44
|
pageSizeOptions = [
|
|
45
45
|
{ value: '12', label: '12' },
|
|
46
46
|
{ value: '36', label: '36' },
|
|
47
|
-
{ value: '
|
|
47
|
+
{ value: 'all', label: String(total) },
|
|
48
48
|
];
|
|
49
49
|
}
|
|
50
50
|
else {
|