@nationaldesignstudio/react 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/accordion/index.d.ts +95 -0
- package/dist/accordion/index.js +143 -0
- package/dist/accordion/index.js.map +1 -0
- package/dist/background/index.d.ts +149 -0
- package/dist/background/index.js +200 -0
- package/dist/background/index.js.map +1 -0
- package/dist/banner/index.d.ts +101 -0
- package/dist/banner/index.js +81 -0
- package/dist/banner/index.js.map +1 -0
- package/dist/blurred-video-backdrop/index.d.ts +233 -0
- package/dist/blurred-video-backdrop/index.js +266 -0
- package/dist/blurred-video-backdrop/index.js.map +1 -0
- package/dist/button/index.d.ts +180 -0
- package/dist/button/index.js +169 -0
- package/dist/button/index.js.map +1 -0
- package/dist/button-B2g5fH9b.d.ts +152 -0
- package/dist/card/index.d.ts +406 -0
- package/dist/card/index.js +219 -0
- package/dist/card/index.js.map +1 -0
- package/dist/card-grid/index.d.ts +90 -0
- package/dist/card-grid/index.js +74 -0
- package/dist/card-grid/index.js.map +1 -0
- package/dist/component-registry.md +136 -2
- package/dist/dev-toolbar/index.d.ts +8 -0
- package/dist/dev-toolbar/index.js +206 -0
- package/dist/dev-toolbar/index.js.map +1 -0
- package/dist/dialog/index.d.ts +268 -0
- package/dist/dialog/index.js +288 -0
- package/dist/dialog/index.js.map +1 -0
- package/dist/faq-section/index.d.ts +47 -0
- package/dist/faq-section/index.js +152 -0
- package/dist/faq-section/index.js.map +1 -0
- package/dist/grid-overlay/index.d.ts +10 -0
- package/dist/grid-overlay/index.js +38 -0
- package/dist/grid-overlay/index.js.map +1 -0
- package/dist/hero/index.d.ts +462 -0
- package/dist/hero/index.js +494 -0
- package/dist/hero/index.js.map +1 -0
- package/dist/hooks/index.d.ts +150 -0
- package/dist/hooks/index.js +339 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.d.ts +46 -5339
- package/dist/index.js +157 -4080
- package/dist/index.js.map +1 -1
- package/dist/input/index.d.ts +404 -0
- package/dist/input/index.js +393 -0
- package/dist/input/index.js.map +1 -0
- package/dist/navbar/index.d.ts +68 -0
- package/dist/navbar/index.js +227 -0
- package/dist/navbar/index.js.map +1 -0
- package/dist/ndstudio-footer/index.d.ts +32 -0
- package/dist/ndstudio-footer/index.js +35 -0
- package/dist/ndstudio-footer/index.js.map +1 -0
- package/dist/pager-control/index.d.ts +173 -0
- package/dist/pager-control/index.js +267 -0
- package/dist/pager-control/index.js.map +1 -0
- package/dist/popover/index.d.ts +200 -0
- package/dist/popover/index.js +290 -0
- package/dist/popover/index.js.map +1 -0
- package/dist/prose/index.d.ts +39 -0
- package/dist/prose/index.js +56 -0
- package/dist/prose/index.js.map +1 -0
- package/dist/quote-block/index.d.ts +156 -0
- package/dist/quote-block/index.js +321 -0
- package/dist/quote-block/index.js.map +1 -0
- package/dist/river/index.d.ts +100 -0
- package/dist/river/index.js +107 -0
- package/dist/river/index.js.map +1 -0
- package/dist/select/index.d.ts +188 -0
- package/dist/select/index.js +295 -0
- package/dist/select/index.js.map +1 -0
- package/dist/theme/index.d.ts +149 -0
- package/dist/theme/index.js +211 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme-CzBPUlh_.d.ts +332 -0
- package/dist/tooltip/index.d.ts +166 -0
- package/dist/tooltip/index.js +200 -0
- package/dist/tooltip/index.js.map +1 -0
- package/dist/tout/index.d.ts +157 -0
- package/dist/tout/index.js +315 -0
- package/dist/tout/index.js.map +1 -0
- package/dist/two-column-section/index.d.ts +122 -0
- package/dist/two-column-section/index.js +121 -0
- package/dist/two-column-section/index.js.map +1 -0
- package/dist/us-gov-banner/index.d.ts +141 -0
- package/dist/us-gov-banner/index.js +74 -0
- package/dist/us-gov-banner/index.js.map +1 -0
- package/dist/use-captions-AkKlJhov.d.ts +71 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.js +12 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/video-dialog/index.d.ts +106 -0
- package/dist/video-dialog/index.js +1305 -0
- package/dist/video-dialog/index.js.map +1 -0
- package/dist/video-player/index.d.ts +115 -0
- package/dist/video-player/index.js +879 -0
- package/dist/video-player/index.js.map +1 -0
- package/dist/video-player-qxf-BURH.d.ts +236 -0
- package/dist/video-with-backdrop/index.d.ts +267 -0
- package/dist/video-with-backdrop/index.js +1284 -0
- package/dist/video-with-backdrop/index.js.map +1 -0
- package/package.json +13 -2
- package/src/components/organisms/us-gov-banner/us-gov-banner.tsx +5 -27
- package/src/theme/hooks.ts +2 -0
- package/src/theme/index.ts +2 -0
- package/src/theme/theme-provider.tsx +2 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as tailwind_variants from 'tailwind-variants';
|
|
2
|
+
import { VariantProps } from 'tailwind-variants';
|
|
3
|
+
import * as tailwind_variants_dist_config_js from 'tailwind-variants/dist/config.js';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* CardGrid component for displaying cards in a responsive grid layout
|
|
8
|
+
*
|
|
9
|
+
* Variants:
|
|
10
|
+
* - A: 3 columns on desktop, 2 on tablet, 1 on mobile
|
|
11
|
+
* - B: 2 columns on desktop/tablet, 1 on mobile
|
|
12
|
+
*
|
|
13
|
+
* Uses the 24-column grid system with grid-container as root.
|
|
14
|
+
*/
|
|
15
|
+
declare const cardGridVariants: tailwind_variants.TVReturnType<{
|
|
16
|
+
variant: {
|
|
17
|
+
A: string;
|
|
18
|
+
B: string;
|
|
19
|
+
};
|
|
20
|
+
}, undefined, string[], tailwind_variants_dist_config_js.TVConfig<{
|
|
21
|
+
variant: {
|
|
22
|
+
A: string;
|
|
23
|
+
B: string;
|
|
24
|
+
};
|
|
25
|
+
}, {
|
|
26
|
+
variant: {
|
|
27
|
+
A: string;
|
|
28
|
+
B: string;
|
|
29
|
+
};
|
|
30
|
+
}>, {
|
|
31
|
+
variant: {
|
|
32
|
+
A: string;
|
|
33
|
+
B: string;
|
|
34
|
+
};
|
|
35
|
+
}, undefined, tailwind_variants.TVReturnType<{
|
|
36
|
+
variant: {
|
|
37
|
+
A: string;
|
|
38
|
+
B: string;
|
|
39
|
+
};
|
|
40
|
+
}, undefined, string[], tailwind_variants_dist_config_js.TVConfig<{
|
|
41
|
+
variant: {
|
|
42
|
+
A: string;
|
|
43
|
+
B: string;
|
|
44
|
+
};
|
|
45
|
+
}, {
|
|
46
|
+
variant: {
|
|
47
|
+
A: string;
|
|
48
|
+
B: string;
|
|
49
|
+
};
|
|
50
|
+
}>, unknown, unknown, undefined>>;
|
|
51
|
+
interface CardGridProps extends React.HTMLAttributes<HTMLElement>, VariantProps<typeof cardGridVariants> {
|
|
52
|
+
/**
|
|
53
|
+
* The title text displayed above the cards
|
|
54
|
+
*/
|
|
55
|
+
title: string;
|
|
56
|
+
/**
|
|
57
|
+
* The card elements to display in the grid
|
|
58
|
+
*/
|
|
59
|
+
cards: React.ReactNode[];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* CardGrid component for displaying cards in a responsive grid layout.
|
|
63
|
+
*
|
|
64
|
+
* Uses the 24-column grid system with grid-container as root.
|
|
65
|
+
*
|
|
66
|
+
* Layout (Variant A):
|
|
67
|
+
* - Mobile (sm): Single column, py-72
|
|
68
|
+
* - Tablet (md): 2 columns, gap-56 between title and cards, gap-y-20 between cards
|
|
69
|
+
* - Desktop (lg+): 3 columns, py-128, gap-64 between title and cards, gap-y-20 between cards
|
|
70
|
+
*
|
|
71
|
+
* Layout (Variant B):
|
|
72
|
+
* - Mobile (sm): Single column, py-72
|
|
73
|
+
* - Tablet (md): 2 columns, gap-56 between title and cards, gap-y-20 between cards
|
|
74
|
+
* - Desktop (lg+): 2 columns, py-128, gap-64 between title and cards, gap-y-20 between cards
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```tsx
|
|
78
|
+
* <CardGrid
|
|
79
|
+
* variant="A"
|
|
80
|
+
* title="Featured Cards"
|
|
81
|
+
* cards={[
|
|
82
|
+
* <Card key="1">...</Card>,
|
|
83
|
+
* <Card key="2">...</Card>,
|
|
84
|
+
* ]}
|
|
85
|
+
* />
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
declare const CardGrid: React.ForwardRefExoticComponent<CardGridProps & React.RefAttributes<HTMLElement>>;
|
|
89
|
+
|
|
90
|
+
export { CardGrid, type CardGridProps, cardGridVariants };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { tv, cnBase } from 'tailwind-variants';
|
|
3
|
+
import { clsx } from 'clsx';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
// src/components/sections/card-grid/card-grid.tsx
|
|
7
|
+
function cn(...inputs) {
|
|
8
|
+
return cnBase(clsx(inputs));
|
|
9
|
+
}
|
|
10
|
+
var cardGridVariants = tv({
|
|
11
|
+
// Base styles - grid-container for proper grid context - uses primitive spacing tokens
|
|
12
|
+
base: [
|
|
13
|
+
"grid-container",
|
|
14
|
+
// Small (mobile): 72px y padding
|
|
15
|
+
"py-72",
|
|
16
|
+
// Large (desktop): 128px y padding
|
|
17
|
+
"lg:py-128"
|
|
18
|
+
],
|
|
19
|
+
variants: {
|
|
20
|
+
variant: {
|
|
21
|
+
A: "",
|
|
22
|
+
B: ""
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
defaultVariants: {
|
|
26
|
+
variant: "A"
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
var CardGrid = React.forwardRef(
|
|
30
|
+
({ className, variant, title, cards, ...props }, ref) => {
|
|
31
|
+
return /* @__PURE__ */ jsxs(
|
|
32
|
+
"section",
|
|
33
|
+
{
|
|
34
|
+
ref,
|
|
35
|
+
className: cardGridVariants({ variant, class: className }),
|
|
36
|
+
...props,
|
|
37
|
+
children: [
|
|
38
|
+
/* @__PURE__ */ jsx(
|
|
39
|
+
"h2",
|
|
40
|
+
{
|
|
41
|
+
className: cn(
|
|
42
|
+
"col-full",
|
|
43
|
+
"typography-h4 text-gray-900",
|
|
44
|
+
// Gap after title: mobile default, md: 56px, lg: 64px
|
|
45
|
+
"mb-36 md:mb-56 lg:mb-64"
|
|
46
|
+
),
|
|
47
|
+
children: title
|
|
48
|
+
}
|
|
49
|
+
),
|
|
50
|
+
/* @__PURE__ */ jsx(
|
|
51
|
+
"div",
|
|
52
|
+
{
|
|
53
|
+
className: cn(
|
|
54
|
+
"col-full",
|
|
55
|
+
// Mobile: single column
|
|
56
|
+
"grid grid-cols-1 gap-20",
|
|
57
|
+
// Tablet: 2 columns
|
|
58
|
+
"md:grid-cols-2",
|
|
59
|
+
// Desktop: 3 columns for variant A, 2 columns for variant B
|
|
60
|
+
variant === "A" && "lg:grid-cols-3"
|
|
61
|
+
),
|
|
62
|
+
children: React.Children.toArray(cards).map((card) => /* @__PURE__ */ jsx("div", { children: card }, card.key))
|
|
63
|
+
}
|
|
64
|
+
)
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
CardGrid.displayName = "CardGrid";
|
|
71
|
+
|
|
72
|
+
export { CardGrid, cardGridVariants };
|
|
73
|
+
//# sourceMappingURL=index.js.map
|
|
74
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/utils.ts","../../src/components/sections/card-grid/card-grid.tsx"],"names":["twMerge"],"mappings":";;;;;;AAKO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAOA,MAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACMA,IAAM,mBAAmB,EAAA,CAAG;AAAA;AAAA,EAE3B,IAAA,EAAM;AAAA,IACL,gBAAA;AAAA;AAAA,IAEA,OAAA;AAAA;AAAA,IAEA;AAAA,GACD;AAAA,EACA,QAAA,EAAU;AAAA,IACT,OAAA,EAAS;AAAA,MACR,CAAA,EAAG,EAAA;AAAA,MACH,CAAA,EAAG;AAAA;AACJ,GACD;AAAA,EACA,eAAA,EAAiB;AAAA,IAChB,OAAA,EAAS;AAAA;AAEX,CAAC;AA0CD,IAAM,QAAA,GAAiB,KAAA,CAAA,UAAA;AAAA,EACtB,CAAC,EAAE,SAAA,EAAW,OAAA,EAAS,OAAO,KAAA,EAAO,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACxD,IAAA,uBACC,IAAA;AAAA,MAAC,SAAA;AAAA,MAAA;AAAA,QACA,GAAA;AAAA,QACA,WAAW,gBAAA,CAAiB,EAAE,OAAA,EAAS,KAAA,EAAO,WAAW,CAAA;AAAA,QACxD,GAAG,KAAA;AAAA,QAGJ,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,IAAA;AAAA,YAAA;AAAA,cACA,SAAA,EAAW,EAAA;AAAA,gBACV,UAAA;AAAA,gBACA,6BAAA;AAAA;AAAA,gBAEA;AAAA,eACD;AAAA,cAEC,QAAA,EAAA;AAAA;AAAA,WACF;AAAA,0BAGA,GAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACA,SAAA,EAAW,EAAA;AAAA,gBACV,UAAA;AAAA;AAAA,gBAEA,yBAAA;AAAA;AAAA,gBAEA,gBAAA;AAAA;AAAA,gBAEA,YAAY,GAAA,IAAO;AAAA,eACpB;AAAA,cAEC,QAAA,EAAM,KAAA,CAAA,QAAA,CAAS,OAAA,CAAQ,KAAK,CAAA,CAAE,GAAA,CAAI,CAAC,IAAA,qBACnC,GAAA,CAAC,KAAA,EAAA,EAA4C,QAAA,EAAA,IAAA,EAAA,EAAlC,IAAA,CAA4B,GAAW,CAClD;AAAA;AAAA;AACF;AAAA;AAAA,KACD;AAAA,EAEF;AACD;AACA,QAAA,CAAS,WAAA,GAAc,UAAA","file":"index.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { cnBase as twMerge } from \"tailwind-variants\";\n\nexport { twMerge };\n\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { cn } from \"@/lib/utils\";\n\n/**\n * CardGrid component for displaying cards in a responsive grid layout\n *\n * Variants:\n * - A: 3 columns on desktop, 2 on tablet, 1 on mobile\n * - B: 2 columns on desktop/tablet, 1 on mobile\n *\n * Uses the 24-column grid system with grid-container as root.\n */\nconst cardGridVariants = tv({\n\t// Base styles - grid-container for proper grid context - uses primitive spacing tokens\n\tbase: [\n\t\t\"grid-container\",\n\t\t// Small (mobile): 72px y padding\n\t\t\"py-72\",\n\t\t// Large (desktop): 128px y padding\n\t\t\"lg:py-128\",\n\t],\n\tvariants: {\n\t\tvariant: {\n\t\t\tA: \"\",\n\t\t\tB: \"\",\n\t\t},\n\t},\n\tdefaultVariants: {\n\t\tvariant: \"A\",\n\t},\n});\n\nexport interface CardGridProps\n\textends React.HTMLAttributes<HTMLElement>,\n\t\tVariantProps<typeof cardGridVariants> {\n\t/**\n\t * The title text displayed above the cards\n\t */\n\ttitle: string;\n\t/**\n\t * The card elements to display in the grid\n\t */\n\tcards: React.ReactNode[];\n}\n\n/**\n * CardGrid component for displaying cards in a responsive grid layout.\n *\n * Uses the 24-column grid system with grid-container as root.\n *\n * Layout (Variant A):\n * - Mobile (sm): Single column, py-72\n * - Tablet (md): 2 columns, gap-56 between title and cards, gap-y-20 between cards\n * - Desktop (lg+): 3 columns, py-128, gap-64 between title and cards, gap-y-20 between cards\n *\n * Layout (Variant B):\n * - Mobile (sm): Single column, py-72\n * - Tablet (md): 2 columns, gap-56 between title and cards, gap-y-20 between cards\n * - Desktop (lg+): 2 columns, py-128, gap-64 between title and cards, gap-y-20 between cards\n *\n * @example\n * ```tsx\n * <CardGrid\n * variant=\"A\"\n * title=\"Featured Cards\"\n * cards={[\n * <Card key=\"1\">...</Card>,\n * <Card key=\"2\">...</Card>,\n * ]}\n * />\n * ```\n */\nconst CardGrid = React.forwardRef<HTMLElement, CardGridProps>(\n\t({ className, variant, title, cards, ...props }, ref) => {\n\t\treturn (\n\t\t\t<section\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cardGridVariants({ variant, class: className })}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{/* Title - col-full within grid - uses primitive spacing tokens */}\n\t\t\t\t<h2\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"col-full\",\n\t\t\t\t\t\t\"typography-h4 text-gray-900\",\n\t\t\t\t\t\t// Gap after title: mobile default, md: 56px, lg: 64px\n\t\t\t\t\t\t\"mb-36 md:mb-56 lg:mb-64\",\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t{title}\n\t\t\t\t</h2>\n\n\t\t\t\t{/* Inner grid for cards - uses primitive spacing tokens */}\n\t\t\t\t<div\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"col-full\",\n\t\t\t\t\t\t// Mobile: single column\n\t\t\t\t\t\t\"grid grid-cols-1 gap-20\",\n\t\t\t\t\t\t// Tablet: 2 columns\n\t\t\t\t\t\t\"md:grid-cols-2\",\n\t\t\t\t\t\t// Desktop: 3 columns for variant A, 2 columns for variant B\n\t\t\t\t\t\tvariant === \"A\" && \"lg:grid-cols-3\",\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t{React.Children.toArray(cards).map((card) => (\n\t\t\t\t\t\t<div key={(card as React.ReactElement).key}>{card}</div>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t</section>\n\t\t);\n\t},\n);\nCardGrid.displayName = \"CardGrid\";\n\nexport { CardGrid, cardGridVariants };\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Component Registry
|
|
2
2
|
|
|
3
3
|
> Auto-generated component metadata for AI/agent consumption.
|
|
4
|
-
> Generated: 2026-
|
|
4
|
+
> Generated: 2026-02-09T17:11:36.752Z
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -386,7 +386,7 @@ className="font-semibold" // Font weight 600
|
|
|
386
386
|
```tsx
|
|
387
387
|
<div className="w-[700px]">
|
|
388
388
|
<Card layout="horizontal">
|
|
389
|
-
<CardImage />
|
|
389
|
+
<CardImage layout="horizontal" />
|
|
390
390
|
<CardContent>
|
|
391
391
|
<CardBody>
|
|
392
392
|
<CardEyebrow>Eyebrow</CardEyebrow>
|
|
@@ -413,6 +413,80 @@ className="font-semibold" // Font weight 600
|
|
|
413
413
|
</div>
|
|
414
414
|
```
|
|
415
415
|
|
|
416
|
+
```tsx
|
|
417
|
+
<div className="w-[300px]">
|
|
418
|
+
<Card layout="profile">
|
|
419
|
+
<CardImage
|
|
420
|
+
layout="profile"
|
|
421
|
+
src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=400&q=80"
|
|
422
|
+
alt="Team member"
|
|
423
|
+
/>
|
|
424
|
+
<CardContent>
|
|
425
|
+
<CardBody>
|
|
426
|
+
<CardEyebrow>Director</CardEyebrow>
|
|
427
|
+
<CardTitle>Jane Smith</CardTitle>
|
|
428
|
+
<CardDescription>
|
|
429
|
+
Leading our strategic initiatives and partnerships.
|
|
430
|
+
</CardDescription>
|
|
431
|
+
</CardBody>
|
|
432
|
+
</CardContent>
|
|
433
|
+
</Card>
|
|
434
|
+
</div>
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
```tsx
|
|
438
|
+
<div className="w-[500px]">
|
|
439
|
+
<Card layout="compact">
|
|
440
|
+
<CardImage
|
|
441
|
+
layout="compact"
|
|
442
|
+
src="https://images.unsplash.com/photo-1504711434969-e33886168f5c?w=200&q=80"
|
|
443
|
+
alt="News thumbnail"
|
|
444
|
+
/>
|
|
445
|
+
<CardContent className="p-0">
|
|
446
|
+
<CardBody>
|
|
447
|
+
<CardEyebrow>News</CardEyebrow>
|
|
448
|
+
<CardTitle className="typography-h6">
|
|
449
|
+
New Policy Update Released
|
|
450
|
+
</CardTitle>
|
|
451
|
+
<CardLink>Read More</CardLink>
|
|
452
|
+
</CardBody>
|
|
453
|
+
</CardContent>
|
|
454
|
+
</Card>
|
|
455
|
+
</div>
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
```tsx
|
|
459
|
+
<div className="flex w-[500px] flex-col gap-16">
|
|
460
|
+
{[
|
|
461
|
+
{ id: "policy", title: "Policy Update Released", category: "News" },
|
|
462
|
+
{
|
|
463
|
+
id: "report",
|
|
464
|
+
title: "Quarterly Report Available",
|
|
465
|
+
category: "Reports",
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
id: "meeting",
|
|
469
|
+
title: "Community Meeting Scheduled",
|
|
470
|
+
category: "Events",
|
|
471
|
+
},
|
|
472
|
+
].map((item) => (
|
|
473
|
+
<Card key={item.id} layout="compact">
|
|
474
|
+
<CardImage
|
|
475
|
+
layout="compact"
|
|
476
|
+
src={`https://images.unsplash.com/photo-1504711434969-e33886168f5c?w=200&q=80`}
|
|
477
|
+
/>
|
|
478
|
+
<CardContent className="p-0">
|
|
479
|
+
<CardBody>
|
|
480
|
+
<CardEyebrow>{item.category}</CardEyebrow>
|
|
481
|
+
<CardTitle className="typography-h6">{item.title}</CardTitle>
|
|
482
|
+
<CardLink>Read More</CardLink>
|
|
483
|
+
</CardBody>
|
|
484
|
+
</CardContent>
|
|
485
|
+
</Card>
|
|
486
|
+
))}
|
|
487
|
+
</div>
|
|
488
|
+
```
|
|
489
|
+
|
|
416
490
|
```tsx
|
|
417
491
|
<div className="w-[418px]">
|
|
418
492
|
<Card>
|
|
@@ -565,6 +639,12 @@ className="font-semibold" // Font weight 600
|
|
|
565
639
|
Values: `dark`, `light`
|
|
566
640
|
- `top`: React.ReactNode
|
|
567
641
|
Content for the top slot (full-width, no padding).
|
|
642
|
+
- `indicator`: React.ReactNode
|
|
643
|
+
```tsx
|
|
644
|
+
<Hero indicator={<ChevronDown className="animate-bounce" />}>
|
|
645
|
+
<h1>Welcome</h1>
|
|
646
|
+
</Hero>
|
|
647
|
+
```
|
|
568
648
|
- `background`: React.ReactNode | string
|
|
569
649
|
Background for the hero. Can be:
|
|
570
650
|
- `overlayOpacity`: number
|
|
@@ -594,6 +674,60 @@ className="font-semibold" // Font weight 600
|
|
|
594
674
|
<Hero variant="A3" title="Hero A3" />
|
|
595
675
|
```
|
|
596
676
|
|
|
677
|
+
```tsx
|
|
678
|
+
<Hero contentAlign="top" title="Content at Top" background="#1a1a1a" />
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
```tsx
|
|
682
|
+
<Hero contentAlign="center" title="Content Centered" background="#1a1a1a" />
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
```tsx
|
|
686
|
+
<Hero
|
|
687
|
+
contentAlign="bottom"
|
|
688
|
+
title="Content at Bottom"
|
|
689
|
+
background="#1a1a1a"
|
|
690
|
+
/>
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
```tsx
|
|
694
|
+
<Hero
|
|
695
|
+
title="Scroll Down"
|
|
696
|
+
background="#1a1a1a"
|
|
697
|
+
indicator={<ArrowDownIcon />}
|
|
698
|
+
/>
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
```tsx
|
|
702
|
+
<Hero
|
|
703
|
+
title="Scroll Down"
|
|
704
|
+
background="#1a1a1a"
|
|
705
|
+
indicator={
|
|
706
|
+
<div className="animate-bounce">
|
|
707
|
+
<ArrowDownIcon />
|
|
708
|
+
</div>
|
|
709
|
+
}
|
|
710
|
+
/>
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
```tsx
|
|
714
|
+
<Hero
|
|
715
|
+
title="Welcome"
|
|
716
|
+
background={
|
|
717
|
+
<HeroBackground.Image
|
|
718
|
+
src="https://images.unsplash.com/photo-1451187580459-43490279c0fa?w=1920&q=80"
|
|
719
|
+
position="center"
|
|
720
|
+
/>
|
|
721
|
+
}
|
|
722
|
+
overlayOpacity={0.4}
|
|
723
|
+
indicator={
|
|
724
|
+
<div className="flex size-48 animate-bounce items-center justify-center rounded-full border border-white/50">
|
|
725
|
+
<ArrowDownIcon />
|
|
726
|
+
</div>
|
|
727
|
+
}
|
|
728
|
+
/>
|
|
729
|
+
```
|
|
730
|
+
|
|
597
731
|
```tsx
|
|
598
732
|
<Hero variant="A1" title="Color Background" background="#2563eb" />
|
|
599
733
|
```
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface DevToolbarProps {
|
|
4
|
+
defaultExpanded?: boolean;
|
|
5
|
+
}
|
|
6
|
+
declare function DevToolbar({ defaultExpanded }: DevToolbarProps): react_jsx_runtime.JSX.Element;
|
|
7
|
+
|
|
8
|
+
export { DevToolbar, type DevToolbarProps };
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useState, useRef, useCallback, useEffect } from 'react';
|
|
3
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
// src/components/dev-tools/dev-toolbar/dev-toolbar.tsx
|
|
6
|
+
function GridOverlay({
|
|
7
|
+
columnOpacity = 0.15,
|
|
8
|
+
borderOpacity = 0.3,
|
|
9
|
+
visible = true
|
|
10
|
+
}) {
|
|
11
|
+
const columns = Array.from({ length: 24 }, (_, i) => i);
|
|
12
|
+
return /* @__PURE__ */ jsx(
|
|
13
|
+
"div",
|
|
14
|
+
{
|
|
15
|
+
className: `
|
|
16
|
+
fixed inset-0 z-[9998] pointer-events-none overflow-hidden
|
|
17
|
+
transition-opacity duration-300 ease-out
|
|
18
|
+
${visible ? "opacity-100" : "opacity-0"}
|
|
19
|
+
`,
|
|
20
|
+
"aria-hidden": "true",
|
|
21
|
+
"data-testid": "grid-overlay",
|
|
22
|
+
children: /* @__PURE__ */ jsx("div", { className: "h-full w-full max-w-[90rem] mx-auto px-[var(--spatial-grid-small-margin)] md:px-[var(--spatial-grid-medium-margin)] lg:px-[var(--spatial-grid-large-margin)]", children: /* @__PURE__ */ jsx("div", { className: "h-full grid grid-cols-4 md:grid-cols-12 lg:grid-cols-24 gap-[var(--spatial-grid-small-gutter)] md:gap-[var(--spatial-grid-medium-gutter)] lg:gap-[var(--spatial-grid-large-gutter)]", children: columns.map((index) => /* @__PURE__ */ jsx(
|
|
23
|
+
"div",
|
|
24
|
+
{
|
|
25
|
+
className: "h-full border border-red-500",
|
|
26
|
+
style: {
|
|
27
|
+
backgroundColor: `rgb(239 68 68 / ${columnOpacity})`,
|
|
28
|
+
borderColor: `rgb(239 68 68 / ${borderOpacity})`
|
|
29
|
+
},
|
|
30
|
+
"data-column": index + 1
|
|
31
|
+
},
|
|
32
|
+
index
|
|
33
|
+
)) }) })
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
function GridIcon({ active }) {
|
|
38
|
+
return /* @__PURE__ */ jsxs(
|
|
39
|
+
"svg",
|
|
40
|
+
{
|
|
41
|
+
width: "20",
|
|
42
|
+
height: "20",
|
|
43
|
+
viewBox: "0 0 20 20",
|
|
44
|
+
fill: "none",
|
|
45
|
+
stroke: "currentColor",
|
|
46
|
+
strokeWidth: active ? "2" : "1.5",
|
|
47
|
+
"aria-hidden": "true",
|
|
48
|
+
children: [
|
|
49
|
+
/* @__PURE__ */ jsx("rect", { x: "2", y: "2", width: "16", height: "16", rx: "2" }),
|
|
50
|
+
/* @__PURE__ */ jsx("line", { x1: "7", y1: "2", x2: "7", y2: "18" }),
|
|
51
|
+
/* @__PURE__ */ jsx("line", { x1: "13", y1: "2", x2: "13", y2: "18" })
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
var DRAG_THRESHOLD = 3;
|
|
57
|
+
function DevToolbar({ defaultExpanded = false }) {
|
|
58
|
+
const [isExpanded, setIsExpanded] = useState(defaultExpanded);
|
|
59
|
+
const [showGrid, setShowGrid] = useState(false);
|
|
60
|
+
const [position, setPosition] = useState({ x: 0, y: 0 });
|
|
61
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
62
|
+
const hasDraggedRef = useRef(false);
|
|
63
|
+
const dragRef = useRef(null);
|
|
64
|
+
const toolbarRef = useRef(null);
|
|
65
|
+
const toggleGrid = useCallback(() => setShowGrid((prev) => !prev), []);
|
|
66
|
+
const toggleExpanded = useCallback(() => setIsExpanded((prev) => !prev), []);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
const handleKeyDown = (e) => {
|
|
69
|
+
if ((e.ctrlKey || e.metaKey) && e.key === "g") {
|
|
70
|
+
e.preventDefault();
|
|
71
|
+
toggleGrid();
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
75
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
76
|
+
}, [toggleGrid]);
|
|
77
|
+
const handleDragStart = useCallback(
|
|
78
|
+
(clientX, clientY) => {
|
|
79
|
+
setIsDragging(true);
|
|
80
|
+
hasDraggedRef.current = false;
|
|
81
|
+
dragRef.current = {
|
|
82
|
+
startX: clientX,
|
|
83
|
+
startY: clientY,
|
|
84
|
+
startPosX: position.x,
|
|
85
|
+
startPosY: position.y
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
[position]
|
|
89
|
+
);
|
|
90
|
+
const handleDragMove = useCallback(
|
|
91
|
+
(clientX, clientY) => {
|
|
92
|
+
if (!isDragging || !dragRef.current) return;
|
|
93
|
+
const deltaX = clientX - dragRef.current.startX;
|
|
94
|
+
const deltaY = clientY - dragRef.current.startY;
|
|
95
|
+
if (Math.abs(deltaX) > DRAG_THRESHOLD || Math.abs(deltaY) > DRAG_THRESHOLD) {
|
|
96
|
+
hasDraggedRef.current = true;
|
|
97
|
+
}
|
|
98
|
+
setPosition({
|
|
99
|
+
x: dragRef.current.startPosX + deltaX,
|
|
100
|
+
y: dragRef.current.startPosY - deltaY
|
|
101
|
+
});
|
|
102
|
+
},
|
|
103
|
+
[isDragging]
|
|
104
|
+
);
|
|
105
|
+
const handleDragEnd = useCallback(() => {
|
|
106
|
+
setIsDragging(false);
|
|
107
|
+
dragRef.current = null;
|
|
108
|
+
}, []);
|
|
109
|
+
useEffect(() => {
|
|
110
|
+
if (!isDragging) return;
|
|
111
|
+
const handleMouseMove = (e) => handleDragMove(e.clientX, e.clientY);
|
|
112
|
+
const handleTouchMove = (e) => {
|
|
113
|
+
if (e.touches[0])
|
|
114
|
+
handleDragMove(e.touches[0].clientX, e.touches[0].clientY);
|
|
115
|
+
};
|
|
116
|
+
const handleEnd = () => handleDragEnd();
|
|
117
|
+
window.addEventListener("mousemove", handleMouseMove);
|
|
118
|
+
window.addEventListener("mouseup", handleEnd);
|
|
119
|
+
window.addEventListener("touchmove", handleTouchMove);
|
|
120
|
+
window.addEventListener("touchend", handleEnd);
|
|
121
|
+
return () => {
|
|
122
|
+
window.removeEventListener("mousemove", handleMouseMove);
|
|
123
|
+
window.removeEventListener("mouseup", handleEnd);
|
|
124
|
+
window.removeEventListener("touchmove", handleTouchMove);
|
|
125
|
+
window.removeEventListener("touchend", handleEnd);
|
|
126
|
+
};
|
|
127
|
+
}, [isDragging, handleDragMove, handleDragEnd]);
|
|
128
|
+
const handleBarMouseDown = (e) => {
|
|
129
|
+
e.preventDefault();
|
|
130
|
+
handleDragStart(e.clientX, e.clientY);
|
|
131
|
+
};
|
|
132
|
+
const handleBarTouchStart = (e) => {
|
|
133
|
+
if (e.touches[0]) {
|
|
134
|
+
handleDragStart(e.touches[0].clientX, e.touches[0].clientY);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
const handleBarClick = () => {
|
|
138
|
+
if (!hasDraggedRef.current) {
|
|
139
|
+
toggleExpanded();
|
|
140
|
+
}
|
|
141
|
+
hasDraggedRef.current = false;
|
|
142
|
+
};
|
|
143
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
144
|
+
showGrid && /* @__PURE__ */ jsx(GridOverlay, {}),
|
|
145
|
+
/* @__PURE__ */ jsx(
|
|
146
|
+
"div",
|
|
147
|
+
{
|
|
148
|
+
ref: toolbarRef,
|
|
149
|
+
className: "fixed bottom-4 left-1/2 z-[9999]",
|
|
150
|
+
style: {
|
|
151
|
+
transform: `translate(calc(-50% + ${position.x}px), ${-position.y}px)`
|
|
152
|
+
},
|
|
153
|
+
"data-testid": "dev-toolbar",
|
|
154
|
+
children: /* @__PURE__ */ jsxs(
|
|
155
|
+
"div",
|
|
156
|
+
{
|
|
157
|
+
className: `bg-gray-1100 rounded-radius-16 shadow-lg flex flex-col items-center overflow-hidden px-12 py-8 ${isExpanded ? "gap-4" : ""}`,
|
|
158
|
+
children: [
|
|
159
|
+
/* @__PURE__ */ jsx(
|
|
160
|
+
"div",
|
|
161
|
+
{
|
|
162
|
+
className: `
|
|
163
|
+
grid transition-all duration-300 ease-out
|
|
164
|
+
${isExpanded ? "grid-rows-[1fr] opacity-100" : "grid-rows-[0fr] opacity-0"}
|
|
165
|
+
`,
|
|
166
|
+
children: /* @__PURE__ */ jsx("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
167
|
+
"button",
|
|
168
|
+
{
|
|
169
|
+
type: "button",
|
|
170
|
+
onClick: toggleGrid,
|
|
171
|
+
className: `
|
|
172
|
+
size-40 rounded-full flex items-center justify-center transition-colors
|
|
173
|
+
${showGrid ? "text-gray-50" : "text-gray-400 hover:text-gray-50 hover:bg-alpha-white-10"}
|
|
174
|
+
`,
|
|
175
|
+
title: "Toggle Grid (\u2318G)",
|
|
176
|
+
"aria-label": "Toggle grid overlay",
|
|
177
|
+
children: /* @__PURE__ */ jsx(GridIcon, { active: showGrid })
|
|
178
|
+
}
|
|
179
|
+
) })
|
|
180
|
+
}
|
|
181
|
+
),
|
|
182
|
+
/* @__PURE__ */ jsx(
|
|
183
|
+
"button",
|
|
184
|
+
{
|
|
185
|
+
type: "button",
|
|
186
|
+
onMouseDown: handleBarMouseDown,
|
|
187
|
+
onTouchStart: handleBarTouchStart,
|
|
188
|
+
onClick: handleBarClick,
|
|
189
|
+
className: `
|
|
190
|
+
w-32 h-4 bg-gray-50 rounded-full transition-opacity
|
|
191
|
+
${isDragging ? "opacity-100 cursor-grabbing" : "opacity-60 hover:opacity-100 cursor-grab"}
|
|
192
|
+
`,
|
|
193
|
+
"aria-label": isExpanded ? "Close dev tools" : "Open dev tools"
|
|
194
|
+
}
|
|
195
|
+
)
|
|
196
|
+
]
|
|
197
|
+
}
|
|
198
|
+
)
|
|
199
|
+
}
|
|
200
|
+
)
|
|
201
|
+
] });
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export { DevToolbar };
|
|
205
|
+
//# sourceMappingURL=index.js.map
|
|
206
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/dev-tools/grid-overlay/grid-overlay.tsx","../../src/components/dev-tools/dev-toolbar/dev-toolbar.tsx"],"names":["jsx"],"mappings":"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","file":"index.js","sourcesContent":["export interface GridOverlayProps {\n\tcolumnOpacity?: number;\n\tborderOpacity?: number;\n\tvisible?: boolean;\n}\n\nexport function GridOverlay({\n\tcolumnOpacity = 0.15,\n\tborderOpacity = 0.3,\n\tvisible = true,\n}: GridOverlayProps) {\n\tconst columns = Array.from({ length: 24 }, (_, i) => i);\n\n\treturn (\n\t\t<div\n\t\t\tclassName={`\n\t\t\t\tfixed inset-0 z-[9998] pointer-events-none overflow-hidden\n\t\t\t\ttransition-opacity duration-300 ease-out\n\t\t\t\t${visible ? \"opacity-100\" : \"opacity-0\"}\n\t\t\t`}\n\t\t\taria-hidden=\"true\"\n\t\t\tdata-testid=\"grid-overlay\"\n\t\t>\n\t\t\t<div className=\"h-full w-full max-w-[90rem] mx-auto px-[var(--spatial-grid-small-margin)] md:px-[var(--spatial-grid-medium-margin)] lg:px-[var(--spatial-grid-large-margin)]\">\n\t\t\t\t<div className=\"h-full grid grid-cols-4 md:grid-cols-12 lg:grid-cols-24 gap-[var(--spatial-grid-small-gutter)] md:gap-[var(--spatial-grid-medium-gutter)] lg:gap-[var(--spatial-grid-large-gutter)]\">\n\t\t\t\t\t{columns.map((index) => (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tkey={index}\n\t\t\t\t\t\t\tclassName=\"h-full border border-red-500\"\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\tbackgroundColor: `rgb(239 68 68 / ${columnOpacity})`,\n\t\t\t\t\t\t\t\tborderColor: `rgb(239 68 68 / ${borderOpacity})`,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tdata-column={index + 1}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { GridOverlay } from \"../grid-overlay\";\n\nfunction GridIcon({ active }: { active?: boolean }) {\n\treturn (\n\t\t<svg\n\t\t\twidth=\"20\"\n\t\t\theight=\"20\"\n\t\t\tviewBox=\"0 0 20 20\"\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeWidth={active ? \"2\" : \"1.5\"}\n\t\t\taria-hidden=\"true\"\n\t\t>\n\t\t\t<rect x=\"2\" y=\"2\" width=\"16\" height=\"16\" rx=\"2\" />\n\t\t\t<line x1=\"7\" y1=\"2\" x2=\"7\" y2=\"18\" />\n\t\t\t<line x1=\"13\" y1=\"2\" x2=\"13\" y2=\"18\" />\n\t\t</svg>\n\t);\n}\n\nexport interface DevToolbarProps {\n\tdefaultExpanded?: boolean;\n}\n\nconst DRAG_THRESHOLD = 3;\n\nexport function DevToolbar({ defaultExpanded = false }: DevToolbarProps) {\n\tconst [isExpanded, setIsExpanded] = useState(defaultExpanded);\n\tconst [showGrid, setShowGrid] = useState(false);\n\tconst [position, setPosition] = useState({ x: 0, y: 0 });\n\tconst [isDragging, setIsDragging] = useState(false);\n\tconst hasDraggedRef = useRef(false);\n\tconst dragRef = useRef<{\n\t\tstartX: number;\n\t\tstartY: number;\n\t\tstartPosX: number;\n\t\tstartPosY: number;\n\t} | null>(null);\n\tconst toolbarRef = useRef<HTMLDivElement>(null);\n\n\tconst toggleGrid = useCallback(() => setShowGrid((prev) => !prev), []);\n\tconst toggleExpanded = useCallback(() => setIsExpanded((prev) => !prev), []);\n\n\tuseEffect(() => {\n\t\tconst handleKeyDown = (e: KeyboardEvent) => {\n\t\t\tif ((e.ctrlKey || e.metaKey) && e.key === \"g\") {\n\t\t\t\te.preventDefault();\n\t\t\t\ttoggleGrid();\n\t\t\t}\n\t\t};\n\n\t\twindow.addEventListener(\"keydown\", handleKeyDown);\n\t\treturn () => window.removeEventListener(\"keydown\", handleKeyDown);\n\t}, [toggleGrid]);\n\n\tconst handleDragStart = useCallback(\n\t\t(clientX: number, clientY: number) => {\n\t\t\tsetIsDragging(true);\n\t\t\thasDraggedRef.current = false;\n\t\t\tdragRef.current = {\n\t\t\t\tstartX: clientX,\n\t\t\t\tstartY: clientY,\n\t\t\t\tstartPosX: position.x,\n\t\t\t\tstartPosY: position.y,\n\t\t\t};\n\t\t},\n\t\t[position],\n\t);\n\n\tconst handleDragMove = useCallback(\n\t\t(clientX: number, clientY: number) => {\n\t\t\tif (!isDragging || !dragRef.current) return;\n\n\t\t\tconst deltaX = clientX - dragRef.current.startX;\n\t\t\tconst deltaY = clientY - dragRef.current.startY;\n\n\t\t\tif (\n\t\t\t\tMath.abs(deltaX) > DRAG_THRESHOLD ||\n\t\t\t\tMath.abs(deltaY) > DRAG_THRESHOLD\n\t\t\t) {\n\t\t\t\thasDraggedRef.current = true;\n\t\t\t}\n\n\t\t\tsetPosition({\n\t\t\t\tx: dragRef.current.startPosX + deltaX,\n\t\t\t\ty: dragRef.current.startPosY - deltaY,\n\t\t\t});\n\t\t},\n\t\t[isDragging],\n\t);\n\n\tconst handleDragEnd = useCallback(() => {\n\t\tsetIsDragging(false);\n\t\tdragRef.current = null;\n\t}, []);\n\n\tuseEffect(() => {\n\t\tif (!isDragging) return;\n\n\t\tconst handleMouseMove = (e: MouseEvent) =>\n\t\t\thandleDragMove(e.clientX, e.clientY);\n\t\tconst handleTouchMove = (e: TouchEvent) => {\n\t\t\tif (e.touches[0])\n\t\t\t\thandleDragMove(e.touches[0].clientX, e.touches[0].clientY);\n\t\t};\n\t\tconst handleEnd = () => handleDragEnd();\n\n\t\twindow.addEventListener(\"mousemove\", handleMouseMove);\n\t\twindow.addEventListener(\"mouseup\", handleEnd);\n\t\twindow.addEventListener(\"touchmove\", handleTouchMove);\n\t\twindow.addEventListener(\"touchend\", handleEnd);\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"mousemove\", handleMouseMove);\n\t\t\twindow.removeEventListener(\"mouseup\", handleEnd);\n\t\t\twindow.removeEventListener(\"touchmove\", handleTouchMove);\n\t\t\twindow.removeEventListener(\"touchend\", handleEnd);\n\t\t};\n\t}, [isDragging, handleDragMove, handleDragEnd]);\n\n\tconst handleBarMouseDown = (e: React.MouseEvent) => {\n\t\te.preventDefault();\n\t\thandleDragStart(e.clientX, e.clientY);\n\t};\n\n\tconst handleBarTouchStart = (e: React.TouchEvent) => {\n\t\tif (e.touches[0]) {\n\t\t\thandleDragStart(e.touches[0].clientX, e.touches[0].clientY);\n\t\t}\n\t};\n\n\tconst handleBarClick = () => {\n\t\tif (!hasDraggedRef.current) {\n\t\t\ttoggleExpanded();\n\t\t}\n\t\thasDraggedRef.current = false;\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t{showGrid && <GridOverlay />}\n\n\t\t\t<div\n\t\t\t\tref={toolbarRef}\n\t\t\t\tclassName=\"fixed bottom-4 left-1/2 z-[9999]\"\n\t\t\t\tstyle={{\n\t\t\t\t\ttransform: `translate(calc(-50% + ${position.x}px), ${-position.y}px)`,\n\t\t\t\t}}\n\t\t\t\tdata-testid=\"dev-toolbar\"\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName={`bg-gray-1100 rounded-radius-16 shadow-lg flex flex-col items-center overflow-hidden px-12 py-8 ${isExpanded ? \"gap-4\" : \"\"}`}\n\t\t\t\t>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={`\n\t\t\t\t\t\t\tgrid transition-all duration-300 ease-out\n\t\t\t\t\t\t\t${isExpanded ? \"grid-rows-[1fr] opacity-100\" : \"grid-rows-[0fr] opacity-0\"}\n\t\t\t\t\t\t`}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div className=\"overflow-hidden\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tonClick={toggleGrid}\n\t\t\t\t\t\t\t\tclassName={`\n\t\t\t\t\t\t\t\t\tsize-40 rounded-full flex items-center justify-center transition-colors\n\t\t\t\t\t\t\t\t\t${\n\t\t\t\t\t\t\t\t\t\tshowGrid\n\t\t\t\t\t\t\t\t\t\t\t? \"text-gray-50\"\n\t\t\t\t\t\t\t\t\t\t\t: \"text-gray-400 hover:text-gray-50 hover:bg-alpha-white-10\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t`}\n\t\t\t\t\t\t\t\ttitle=\"Toggle Grid (⌘G)\"\n\t\t\t\t\t\t\t\taria-label=\"Toggle grid overlay\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<GridIcon active={showGrid} />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonMouseDown={handleBarMouseDown}\n\t\t\t\t\t\tonTouchStart={handleBarTouchStart}\n\t\t\t\t\t\tonClick={handleBarClick}\n\t\t\t\t\t\tclassName={`\n\t\t\t\t\t\t\tw-32 h-4 bg-gray-50 rounded-full transition-opacity\n\t\t\t\t\t\t\t${isDragging ? \"opacity-100 cursor-grabbing\" : \"opacity-60 hover:opacity-100 cursor-grab\"}\n\t\t\t\t\t\t`}\n\t\t\t\t\t\taria-label={isExpanded ? \"Close dev tools\" : \"Open dev tools\"}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</>\n\t);\n}\n"]}
|