@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.
Files changed (106) hide show
  1. package/dist/accordion/index.d.ts +95 -0
  2. package/dist/accordion/index.js +143 -0
  3. package/dist/accordion/index.js.map +1 -0
  4. package/dist/background/index.d.ts +149 -0
  5. package/dist/background/index.js +200 -0
  6. package/dist/background/index.js.map +1 -0
  7. package/dist/banner/index.d.ts +101 -0
  8. package/dist/banner/index.js +81 -0
  9. package/dist/banner/index.js.map +1 -0
  10. package/dist/blurred-video-backdrop/index.d.ts +233 -0
  11. package/dist/blurred-video-backdrop/index.js +266 -0
  12. package/dist/blurred-video-backdrop/index.js.map +1 -0
  13. package/dist/button/index.d.ts +180 -0
  14. package/dist/button/index.js +169 -0
  15. package/dist/button/index.js.map +1 -0
  16. package/dist/button-B2g5fH9b.d.ts +152 -0
  17. package/dist/card/index.d.ts +406 -0
  18. package/dist/card/index.js +219 -0
  19. package/dist/card/index.js.map +1 -0
  20. package/dist/card-grid/index.d.ts +90 -0
  21. package/dist/card-grid/index.js +74 -0
  22. package/dist/card-grid/index.js.map +1 -0
  23. package/dist/component-registry.md +136 -2
  24. package/dist/dev-toolbar/index.d.ts +8 -0
  25. package/dist/dev-toolbar/index.js +206 -0
  26. package/dist/dev-toolbar/index.js.map +1 -0
  27. package/dist/dialog/index.d.ts +268 -0
  28. package/dist/dialog/index.js +288 -0
  29. package/dist/dialog/index.js.map +1 -0
  30. package/dist/faq-section/index.d.ts +47 -0
  31. package/dist/faq-section/index.js +152 -0
  32. package/dist/faq-section/index.js.map +1 -0
  33. package/dist/grid-overlay/index.d.ts +10 -0
  34. package/dist/grid-overlay/index.js +38 -0
  35. package/dist/grid-overlay/index.js.map +1 -0
  36. package/dist/hero/index.d.ts +462 -0
  37. package/dist/hero/index.js +494 -0
  38. package/dist/hero/index.js.map +1 -0
  39. package/dist/hooks/index.d.ts +150 -0
  40. package/dist/hooks/index.js +339 -0
  41. package/dist/hooks/index.js.map +1 -0
  42. package/dist/index.d.ts +46 -5339
  43. package/dist/index.js +157 -4080
  44. package/dist/index.js.map +1 -1
  45. package/dist/input/index.d.ts +404 -0
  46. package/dist/input/index.js +393 -0
  47. package/dist/input/index.js.map +1 -0
  48. package/dist/navbar/index.d.ts +68 -0
  49. package/dist/navbar/index.js +227 -0
  50. package/dist/navbar/index.js.map +1 -0
  51. package/dist/ndstudio-footer/index.d.ts +32 -0
  52. package/dist/ndstudio-footer/index.js +35 -0
  53. package/dist/ndstudio-footer/index.js.map +1 -0
  54. package/dist/pager-control/index.d.ts +173 -0
  55. package/dist/pager-control/index.js +267 -0
  56. package/dist/pager-control/index.js.map +1 -0
  57. package/dist/popover/index.d.ts +200 -0
  58. package/dist/popover/index.js +290 -0
  59. package/dist/popover/index.js.map +1 -0
  60. package/dist/prose/index.d.ts +39 -0
  61. package/dist/prose/index.js +56 -0
  62. package/dist/prose/index.js.map +1 -0
  63. package/dist/quote-block/index.d.ts +156 -0
  64. package/dist/quote-block/index.js +321 -0
  65. package/dist/quote-block/index.js.map +1 -0
  66. package/dist/river/index.d.ts +100 -0
  67. package/dist/river/index.js +107 -0
  68. package/dist/river/index.js.map +1 -0
  69. package/dist/select/index.d.ts +188 -0
  70. package/dist/select/index.js +295 -0
  71. package/dist/select/index.js.map +1 -0
  72. package/dist/theme/index.d.ts +149 -0
  73. package/dist/theme/index.js +211 -0
  74. package/dist/theme/index.js.map +1 -0
  75. package/dist/theme-CzBPUlh_.d.ts +332 -0
  76. package/dist/tooltip/index.d.ts +166 -0
  77. package/dist/tooltip/index.js +200 -0
  78. package/dist/tooltip/index.js.map +1 -0
  79. package/dist/tout/index.d.ts +157 -0
  80. package/dist/tout/index.js +315 -0
  81. package/dist/tout/index.js.map +1 -0
  82. package/dist/two-column-section/index.d.ts +122 -0
  83. package/dist/two-column-section/index.js +121 -0
  84. package/dist/two-column-section/index.js.map +1 -0
  85. package/dist/us-gov-banner/index.d.ts +141 -0
  86. package/dist/us-gov-banner/index.js +74 -0
  87. package/dist/us-gov-banner/index.js.map +1 -0
  88. package/dist/use-captions-AkKlJhov.d.ts +71 -0
  89. package/dist/utils/index.d.ts +7 -0
  90. package/dist/utils/index.js +12 -0
  91. package/dist/utils/index.js.map +1 -0
  92. package/dist/video-dialog/index.d.ts +106 -0
  93. package/dist/video-dialog/index.js +1305 -0
  94. package/dist/video-dialog/index.js.map +1 -0
  95. package/dist/video-player/index.d.ts +115 -0
  96. package/dist/video-player/index.js +879 -0
  97. package/dist/video-player/index.js.map +1 -0
  98. package/dist/video-player-qxf-BURH.d.ts +236 -0
  99. package/dist/video-with-backdrop/index.d.ts +267 -0
  100. package/dist/video-with-backdrop/index.js +1284 -0
  101. package/dist/video-with-backdrop/index.js.map +1 -0
  102. package/package.json +13 -2
  103. package/src/components/organisms/us-gov-banner/us-gov-banner.tsx +5 -27
  104. package/src/theme/hooks.ts +2 -0
  105. package/src/theme/index.ts +2 -0
  106. 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-01-20T19:14:31.863Z
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"]}