@franco_roura/module-01 0.0.0-stage → 1.0.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 (222) hide show
  1. package/LICENSE-APACHE +202 -0
  2. package/LICENSE-MIT +21 -0
  3. package/README.md +64 -2
  4. package/dist/charts.d.ts +3 -0
  5. package/dist/charts.js +3 -0
  6. package/dist/components/alert-dialog.d.ts +19 -0
  7. package/dist/components/alert-dialog.js +101 -0
  8. package/dist/components/alert-dialog.js.map +1 -0
  9. package/dist/components/amount.d.ts +24 -0
  10. package/dist/components/amount.js +27 -0
  11. package/dist/components/amount.js.map +1 -0
  12. package/dist/components/appearance-pickers.d.ts +9 -0
  13. package/dist/components/appearance-pickers.js +65 -0
  14. package/dist/components/appearance-pickers.js.map +1 -0
  15. package/dist/components/badge.d.ts +10 -0
  16. package/dist/components/badge.js +28 -0
  17. package/dist/components/badge.js.map +1 -0
  18. package/dist/components/budget-meter.d.ts +18 -0
  19. package/dist/components/budget-meter.js +38 -0
  20. package/dist/components/budget-meter.js.map +1 -0
  21. package/dist/components/button.d.ts +13 -0
  22. package/dist/components/button.js +54 -0
  23. package/dist/components/button.js.map +1 -0
  24. package/dist/components/calendar.d.ts +7 -0
  25. package/dist/components/calendar.js +52 -0
  26. package/dist/components/calendar.js.map +1 -0
  27. package/dist/components/category-icon.d.ts +33 -0
  28. package/dist/components/category-icon.js +49 -0
  29. package/dist/components/category-icon.js.map +1 -0
  30. package/dist/components/chart.d.ts +44 -0
  31. package/dist/components/chart.js +147 -0
  32. package/dist/components/chart.js.map +1 -0
  33. package/dist/components/charts.d.ts +52 -0
  34. package/dist/components/charts.js +482 -0
  35. package/dist/components/charts.js.map +1 -0
  36. package/dist/components/checkbox.d.ts +5 -0
  37. package/dist/components/checkbox.js +21 -0
  38. package/dist/components/checkbox.js.map +1 -0
  39. package/dist/components/combobox.d.ts +32 -0
  40. package/dist/components/combobox.js +100 -0
  41. package/dist/components/combobox.js.map +1 -0
  42. package/dist/components/command.d.ts +19 -0
  43. package/dist/components/command.js +86 -0
  44. package/dist/components/command.js.map +1 -0
  45. package/dist/components/cta-banner.d.ts +14 -0
  46. package/dist/components/cta-banner.js +39 -0
  47. package/dist/components/cta-banner.js.map +1 -0
  48. package/dist/components/date-picker.d.ts +19 -0
  49. package/dist/components/date-picker.js +107 -0
  50. package/dist/components/date-picker.js.map +1 -0
  51. package/dist/components/dialog.d.ts +18 -0
  52. package/dist/components/dialog.js +99 -0
  53. package/dist/components/dialog.js.map +1 -0
  54. package/dist/components/dropdown-menu.d.ts +26 -0
  55. package/dist/components/dropdown-menu.js +123 -0
  56. package/dist/components/dropdown-menu.js.map +1 -0
  57. package/dist/components/field.d.ts +30 -0
  58. package/dist/components/field.js +53 -0
  59. package/dist/components/field.js.map +1 -0
  60. package/dist/components/footer.d.ts +18 -0
  61. package/dist/components/footer.js +40 -0
  62. package/dist/components/footer.js.map +1 -0
  63. package/dist/components/fx-converter.d.ts +22 -0
  64. package/dist/components/fx-converter.js +91 -0
  65. package/dist/components/fx-converter.js.map +1 -0
  66. package/dist/components/hero.d.ts +28 -0
  67. package/dist/components/hero.js +83 -0
  68. package/dist/components/hero.js.map +1 -0
  69. package/dist/components/hud.d.ts +41 -0
  70. package/dist/components/hud.js +108 -0
  71. package/dist/components/hud.js.map +1 -0
  72. package/dist/components/input.d.ts +4 -0
  73. package/dist/components/input.js +14 -0
  74. package/dist/components/input.js.map +1 -0
  75. package/dist/components/label.d.ts +5 -0
  76. package/dist/components/label.js +15 -0
  77. package/dist/components/label.js.map +1 -0
  78. package/dist/components/media-card.d.ts +29 -0
  79. package/dist/components/media-card.js +80 -0
  80. package/dist/components/media-card.js.map +1 -0
  81. package/dist/components/money-input.d.ts +10 -0
  82. package/dist/components/money-input.js +30 -0
  83. package/dist/components/money-input.js.map +1 -0
  84. package/dist/components/multi-combobox.d.ts +27 -0
  85. package/dist/components/multi-combobox.js +101 -0
  86. package/dist/components/multi-combobox.js.map +1 -0
  87. package/dist/components/nav-bar.d.ts +21 -0
  88. package/dist/components/nav-bar.js +44 -0
  89. package/dist/components/nav-bar.js.map +1 -0
  90. package/dist/components/panel.d.ts +27 -0
  91. package/dist/components/panel.js +49 -0
  92. package/dist/components/panel.js.map +1 -0
  93. package/dist/components/popover.d.ts +11 -0
  94. package/dist/components/popover.js +56 -0
  95. package/dist/components/popover.js.map +1 -0
  96. package/dist/components/select.d.ts +16 -0
  97. package/dist/components/select.js +128 -0
  98. package/dist/components/select.js.map +1 -0
  99. package/dist/components/separator.d.ts +5 -0
  100. package/dist/components/separator.js +17 -0
  101. package/dist/components/separator.js.map +1 -0
  102. package/dist/components/sheet.d.ts +15 -0
  103. package/dist/components/sheet.js +87 -0
  104. package/dist/components/sheet.js.map +1 -0
  105. package/dist/components/skeleton.d.ts +3 -0
  106. package/dist/components/skeleton.js +13 -0
  107. package/dist/components/skeleton.js.map +1 -0
  108. package/dist/components/sonner.d.ts +5 -0
  109. package/dist/components/sonner.js +44 -0
  110. package/dist/components/sonner.js.map +1 -0
  111. package/dist/components/spec-readout.d.ts +11 -0
  112. package/dist/components/spec-readout.js +25 -0
  113. package/dist/components/spec-readout.js.map +1 -0
  114. package/dist/components/split-flap.d.ts +12 -0
  115. package/dist/components/split-flap.js +77 -0
  116. package/dist/components/split-flap.js.map +1 -0
  117. package/dist/components/tabs.d.ts +12 -0
  118. package/dist/components/tabs.js +47 -0
  119. package/dist/components/tabs.js.map +1 -0
  120. package/dist/components/tag.d.ts +16 -0
  121. package/dist/components/tag.js +26 -0
  122. package/dist/components/tag.js.map +1 -0
  123. package/dist/components/terminal.d.ts +10 -0
  124. package/dist/components/terminal.js +20 -0
  125. package/dist/components/terminal.js.map +1 -0
  126. package/dist/components/textarea.d.ts +4 -0
  127. package/dist/components/textarea.js +13 -0
  128. package/dist/components/textarea.js.map +1 -0
  129. package/dist/components/timeline-entry.d.ts +26 -0
  130. package/dist/components/timeline-entry.js +63 -0
  131. package/dist/components/timeline-entry.js.map +1 -0
  132. package/dist/components/toggle-group.d.ts +10 -0
  133. package/dist/components/toggle-group.js +49 -0
  134. package/dist/components/toggle-group.js.map +1 -0
  135. package/dist/components/toggle.d.ts +10 -0
  136. package/dist/components/toggle.js +37 -0
  137. package/dist/components/toggle.js.map +1 -0
  138. package/dist/components/tooltip.d.ts +8 -0
  139. package/dist/components/tooltip.js +36 -0
  140. package/dist/components/tooltip.js.map +1 -0
  141. package/dist/finance.d.ts +10 -0
  142. package/dist/finance.js +10 -0
  143. package/dist/index.d.ts +33 -0
  144. package/dist/index.js +33 -0
  145. package/dist/lib/category-icons.d.ts +80 -0
  146. package/dist/lib/category-icons.js +102 -0
  147. package/dist/lib/category-icons.js.map +1 -0
  148. package/dist/lib/fault.d.ts +7 -0
  149. package/dist/lib/fault.js +28 -0
  150. package/dist/lib/fault.js.map +1 -0
  151. package/dist/lib/form-flow.d.ts +15 -0
  152. package/dist/lib/form-flow.js +50 -0
  153. package/dist/lib/form-flow.js.map +1 -0
  154. package/dist/lib/fx.d.ts +39 -0
  155. package/dist/lib/fx.js +98 -0
  156. package/dist/lib/fx.js.map +1 -0
  157. package/dist/lib/money.d.ts +19 -0
  158. package/dist/lib/money.js +55 -0
  159. package/dist/lib/money.js.map +1 -0
  160. package/dist/lib/use-media-query.d.ts +3 -0
  161. package/dist/lib/use-media-query.js +15 -0
  162. package/dist/lib/use-media-query.js.map +1 -0
  163. package/dist/lib/utils.d.ts +3 -0
  164. package/dist/lib/utils.js +26 -0
  165. package/dist/lib/utils.js.map +1 -0
  166. package/dist/site.d.ts +10 -0
  167. package/dist/site.js +10 -0
  168. package/dist/styles.css +2 -0
  169. package/dist/theme.css +391 -0
  170. package/dist/tokens.css +181 -0
  171. package/guidelines/AlertDialog.md +9 -0
  172. package/guidelines/Amount.md +10 -0
  173. package/guidelines/AppearancePickers.md +8 -0
  174. package/guidelines/Badge.md +11 -0
  175. package/guidelines/BudgetMeter.md +11 -0
  176. package/guidelines/Button.md +16 -0
  177. package/guidelines/Calendar.md +8 -0
  178. package/guidelines/CategoryIcon.md +10 -0
  179. package/guidelines/Charts.md +12 -0
  180. package/guidelines/Checkbox.md +8 -0
  181. package/guidelines/Combobox.md +18 -0
  182. package/guidelines/Command.md +8 -0
  183. package/guidelines/Crosshair.md +7 -0
  184. package/guidelines/CtaBanner.md +8 -0
  185. package/guidelines/DatePicker.md +11 -0
  186. package/guidelines/Dialog.md +9 -0
  187. package/guidelines/DropdownMenu.md +9 -0
  188. package/guidelines/Field.md +22 -0
  189. package/guidelines/Footer.md +7 -0
  190. package/guidelines/FxConverter.md +12 -0
  191. package/guidelines/GlassPanel.md +8 -0
  192. package/guidelines/Grill.md +7 -0
  193. package/guidelines/Hero.md +9 -0
  194. package/guidelines/HudLabel.md +8 -0
  195. package/guidelines/Input.md +9 -0
  196. package/guidelines/Label.md +7 -0
  197. package/guidelines/MediaCard.md +8 -0
  198. package/guidelines/MoneyInput.md +10 -0
  199. package/guidelines/MultiCombobox.md +11 -0
  200. package/guidelines/NavBar.md +10 -0
  201. package/guidelines/Panel.md +10 -0
  202. package/guidelines/Popover.md +8 -0
  203. package/guidelines/README.md +100 -0
  204. package/guidelines/SectionHeader.md +9 -0
  205. package/guidelines/Select.md +9 -0
  206. package/guidelines/Separator.md +8 -0
  207. package/guidelines/Sheet.md +9 -0
  208. package/guidelines/Skeleton.md +8 -0
  209. package/guidelines/SpecReadout.md +7 -0
  210. package/guidelines/SplitFlap.md +9 -0
  211. package/guidelines/StatusLed.md +8 -0
  212. package/guidelines/Tabs.md +9 -0
  213. package/guidelines/Tag.md +9 -0
  214. package/guidelines/Terminal.md +7 -0
  215. package/guidelines/Textarea.md +8 -0
  216. package/guidelines/TickRuler.md +8 -0
  217. package/guidelines/TimelineEntry.md +8 -0
  218. package/guidelines/Toaster.md +9 -0
  219. package/guidelines/Toggle.md +9 -0
  220. package/guidelines/Tooltip.md +8 -0
  221. package/package.json +103 -4
  222. package/tokens/tokens.json +739 -0
@@ -0,0 +1,108 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ // src/components/hud.tsx
4
+ /** 12px plus-mark used as a registration mark on corners and frames. Decorative. */
5
+ function Crosshair({ tone, className, ...props }) {
6
+ return /* @__PURE__ */ jsxs("svg", {
7
+ "aria-hidden": true,
8
+ viewBox: "0 0 12 12",
9
+ className: cn("size-3 shrink-0", tone === "signal" ? "text-signal-ink" : "text-hud-mark", className),
10
+ ...props,
11
+ children: [/* @__PURE__ */ jsx("path", {
12
+ d: "M6 0v12M0 6h12",
13
+ stroke: "currentColor",
14
+ strokeWidth: "1.25",
15
+ fill: "none"
16
+ }), /* @__PURE__ */ jsx("circle", {
17
+ cx: "6",
18
+ cy: "6",
19
+ r: "2.5",
20
+ stroke: "currentColor",
21
+ strokeWidth: "1.25",
22
+ fill: "none"
23
+ })]
24
+ });
25
+ }
26
+ /** Mono overline: signal code chip, label, a seam rule and an optional end marker. */
27
+ function HudLabel({ code, end, rule = true, className, children, ...props }) {
28
+ return /* @__PURE__ */ jsxs("div", {
29
+ className: cn("hud flex items-center gap-3 text-ink-soft", className),
30
+ ...props,
31
+ children: [
32
+ code && /* @__PURE__ */ jsx("span", {
33
+ className: "rounded-xs bg-signal px-1.5 py-0.5 text-ink",
34
+ children: code
35
+ }),
36
+ /* @__PURE__ */ jsx("span", { children }),
37
+ rule && /* @__PURE__ */ jsx("span", {
38
+ "aria-hidden": true,
39
+ className: "h-px min-w-6 flex-1 bg-seam"
40
+ }),
41
+ end !== void 0 && /* @__PURE__ */ jsx("span", { children: end })
42
+ ]
43
+ });
44
+ }
45
+ /** Measurement-tape strip: major ticks every 40px, minor every 8px. Decorative. */
46
+ function TickRuler({ labels, className }) {
47
+ return /* @__PURE__ */ jsxs("div", {
48
+ "aria-hidden": true,
49
+ className: cn("text-hud-mark", className),
50
+ children: [/* @__PURE__ */ jsx("div", {
51
+ className: "h-3.5",
52
+ style: {
53
+ backgroundImage: "repeating-linear-gradient(90deg, var(--color-hud-mark) 0 1px, transparent 1px 40px), repeating-linear-gradient(90deg, var(--color-seam) 0 1px, transparent 1px 8px)",
54
+ backgroundSize: "100% 14px, 100% 7px",
55
+ backgroundRepeat: "no-repeat"
56
+ }
57
+ }), labels && labels.length > 0 && /* @__PURE__ */ jsx("div", {
58
+ className: "hud-sm mt-0.5 flex justify-between",
59
+ children: labels.map((l) => /* @__PURE__ */ jsx("span", { children: l }, l))
60
+ })]
61
+ });
62
+ }
63
+ /** LED dot with a word next to it. Color never carries the meaning alone. */
64
+ function StatusLed({ tone = "on", className, children, ...props }) {
65
+ return /* @__PURE__ */ jsxs("span", {
66
+ className: cn("hud inline-flex items-center gap-2 text-ink", className),
67
+ ...props,
68
+ children: [/* @__PURE__ */ jsx("span", {
69
+ "aria-hidden": true,
70
+ className: cn("size-2 shrink-0 rounded-full", tone === "on" && "bg-led-on shadow-[0_0_0_3px_rgba(31,164,90,0.18)]", tone === "signal" && "bg-signal shadow-[0_0_0_3px_var(--color-signal-tint)]", tone === "off" && "bg-seam")
71
+ }), children]
72
+ });
73
+ }
74
+ /** Pegboard slots: the product grill. Decorative. */
75
+ function Grill({ count = 6, slotWidth, gap, tone, className }) {
76
+ return /* @__PURE__ */ jsx("div", {
77
+ "aria-hidden": true,
78
+ className: cn("flex flex-wrap gap-2.5", className),
79
+ style: gap ? { gap } : void 0,
80
+ children: Array.from({ length: count }, (_, i) => /* @__PURE__ */ jsx("span", {
81
+ style: slotWidth ? { width: slotWidth } : void 0,
82
+ className: cn("h-2.5 w-9 rounded-full", tone === "on-signal" ? "bg-signal-shade shadow-[inset_0_2px_4px_rgba(0,0,0,0.18)]" : tone === "signal" ? "bg-signal shadow-[inset_0_2px_4px_rgba(0,0,0,0.14)]" : "bg-shell-recess shadow-press")
83
+ }, i))
84
+ });
85
+ }
86
+ /** Section heading: HUD label with code above a Michroma title and an optional aside. */
87
+ function SectionHeader({ title, code, label, aside, ruler = false, as: Tag = "h1", className }) {
88
+ return /* @__PURE__ */ jsxs("div", {
89
+ className: cn("flex flex-col gap-3", className),
90
+ children: [
91
+ (code || label) && /* @__PURE__ */ jsx(HudLabel, {
92
+ code,
93
+ children: label
94
+ }),
95
+ /* @__PURE__ */ jsxs("div", {
96
+ className: "flex flex-wrap items-end justify-between gap-4",
97
+ children: [/* @__PURE__ */ jsx(Tag, {
98
+ className: "font-display text-display-md text-ink sm:text-display-lg",
99
+ children: title
100
+ }), aside]
101
+ }),
102
+ ruler && /* @__PURE__ */ jsx(TickRuler, {})
103
+ ]
104
+ });
105
+ }
106
+ export { Crosshair, Grill, HudLabel, SectionHeader, StatusLed, TickRuler };
107
+
108
+ //# sourceMappingURL=hud.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hud.js","names":[],"sources":["../../src/components/hud.tsx"],"sourcesContent":["import { cn } from \"../lib/utils\";\nimport type * as React from \"react\";\n\n/** 12px plus-mark used as a registration mark on corners and frames. Decorative. */\nexport function Crosshair({\n tone,\n className,\n ...props\n}: React.ComponentProps<\"svg\"> & { tone?: \"signal\" }) {\n return (\n <svg\n aria-hidden\n viewBox=\"0 0 12 12\"\n className={cn(\n \"size-3 shrink-0\",\n tone === \"signal\" ? \"text-signal-ink\" : \"text-hud-mark\",\n className,\n )}\n {...props}\n >\n <path d=\"M6 0v12M0 6h12\" stroke=\"currentColor\" strokeWidth=\"1.25\" fill=\"none\" />\n <circle cx=\"6\" cy=\"6\" r=\"2.5\" stroke=\"currentColor\" strokeWidth=\"1.25\" fill=\"none\" />\n </svg>\n );\n}\n\n/** Mono overline: signal code chip, label, a seam rule and an optional end marker. */\nexport function HudLabel({\n code,\n end,\n rule = true,\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & { code?: string; end?: React.ReactNode; rule?: boolean }) {\n return (\n <div className={cn(\"hud flex items-center gap-3 text-ink-soft\", className)} {...props}>\n {code && <span className=\"rounded-xs bg-signal px-1.5 py-0.5 text-ink\">{code}</span>}\n <span>{children}</span>\n {rule && <span aria-hidden className=\"h-px min-w-6 flex-1 bg-seam\" />}\n {end !== undefined && <span>{end}</span>}\n </div>\n );\n}\n\n/** Measurement-tape strip: major ticks every 40px, minor every 8px. Decorative. */\nexport function TickRuler({ labels, className }: { labels?: string[]; className?: string }) {\n return (\n <div aria-hidden className={cn(\"text-hud-mark\", className)}>\n <div\n className=\"h-3.5\"\n style={{\n backgroundImage:\n \"repeating-linear-gradient(90deg, var(--color-hud-mark) 0 1px, transparent 1px 40px), repeating-linear-gradient(90deg, var(--color-seam) 0 1px, transparent 1px 8px)\",\n backgroundSize: \"100% 14px, 100% 7px\",\n backgroundRepeat: \"no-repeat\",\n }}\n />\n {labels && labels.length > 0 && (\n <div className=\"hud-sm mt-0.5 flex justify-between\">\n {labels.map((l) => (\n <span key={l}>{l}</span>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/** LED dot with a word next to it. Color never carries the meaning alone. */\nexport function StatusLed({\n tone = \"on\",\n className,\n children,\n ...props\n}: React.ComponentProps<\"span\"> & { tone?: \"on\" | \"signal\" | \"off\" }) {\n return (\n <span className={cn(\"hud inline-flex items-center gap-2 text-ink\", className)} {...props}>\n <span\n aria-hidden\n className={cn(\n \"size-2 shrink-0 rounded-full\",\n tone === \"on\" && \"bg-led-on shadow-[0_0_0_3px_rgba(31,164,90,0.18)]\",\n tone === \"signal\" && \"bg-signal shadow-[0_0_0_3px_var(--color-signal-tint)]\",\n tone === \"off\" && \"bg-seam\",\n )}\n />\n {children}\n </span>\n );\n}\n\n/** Pegboard slots: the product grill. Decorative. */\nexport function Grill({\n count = 6,\n slotWidth,\n gap,\n tone,\n className,\n}: {\n count?: number;\n /** Slot width in px. Defaults to 36. */\n slotWidth?: number;\n /** Gap between slots as a CSS length. Defaults to 10px. */\n gap?: string;\n tone?: \"signal\" | \"on-signal\";\n className?: string;\n}) {\n return (\n <div\n aria-hidden\n className={cn(\"flex flex-wrap gap-2.5\", className)}\n style={gap ? { gap } : undefined}\n >\n {Array.from({ length: count }, (_, i) => (\n <span\n key={i}\n style={slotWidth ? { width: slotWidth } : undefined}\n className={cn(\n \"h-2.5 w-9 rounded-full\",\n tone === \"on-signal\"\n ? \"bg-signal-shade shadow-[inset_0_2px_4px_rgba(0,0,0,0.18)]\"\n : tone === \"signal\"\n ? \"bg-signal shadow-[inset_0_2px_4px_rgba(0,0,0,0.14)]\"\n : \"bg-shell-recess shadow-press\",\n )}\n />\n ))}\n </div>\n );\n}\n\n/** Section heading: HUD label with code above a Michroma title and an optional aside. */\nexport function SectionHeader({\n title,\n code,\n label,\n aside,\n ruler = false,\n as: Tag = \"h1\",\n className,\n}: {\n title: React.ReactNode;\n code?: string;\n label?: React.ReactNode;\n aside?: React.ReactNode;\n ruler?: boolean;\n as?: \"h1\" | \"h2\" | \"h3\";\n className?: string;\n}) {\n return (\n <div className={cn(\"flex flex-col gap-3\", className)}>\n {(code || label) && <HudLabel code={code}>{label}</HudLabel>}\n <div className=\"flex flex-wrap items-end justify-between gap-4\">\n <Tag className=\"font-display text-display-md text-ink sm:text-display-lg\">{title}</Tag>\n {aside}\n </div>\n {ruler && <TickRuler />}\n </div>\n );\n}\n"],"mappings":";;;;AAIA,SAAgB,UAAU,EACxB,MACA,WACA,GAAG,SACiD;CACpD,OACE,qBAAC,OAAD;EACE,eAAA;EACA,SAAQ;EACR,WAAW,GACT,mBACA,SAAS,WAAW,oBAAoB,iBACxC,SACF;EACA,GAAI;EARN,UAAA,CAUE,oBAAC,QAAD;GAAM,GAAE;GAAiB,QAAO;GAAe,aAAY;GAAO,MAAK;EAAQ,CAAA,GAC/E,oBAAC,UAAD;GAAQ,IAAG;GAAI,IAAG;GAAI,GAAE;GAAM,QAAO;GAAe,aAAY;GAAO,MAAK;EAAQ,CAAA,CACjF;;AAET;;AAGA,SAAgB,SAAS,EACvB,MACA,KACA,OAAO,MACP,WACA,UACA,GAAG,SACsF;CACzF,OACE,qBAAC,OAAD;EAAK,WAAW,GAAG,6CAA6C,SAAS;EAAG,GAAI;EAAhF,UAAA;GACG,QAAQ,oBAAC,QAAD;IAAM,WAAU;IAA+C,UAAA;GAAW,CAAA;GACnF,oBAAC,QAAD,EAAO,SAAe,CAAA;GACrB,QAAQ,oBAAC,QAAD;IAAM,eAAA;IAAY,WAAU;GAA+B,CAAA;GACnE,QAAQ,KAAA,KAAa,oBAAC,QAAD,EAAA,UAAO,IAAU,CAAA;EACpC;;AAET;;AAGA,SAAgB,UAAU,EAAE,QAAQ,aAAwD;CAC1F,OACE,qBAAC,OAAD;EAAK,eAAA;EAAY,WAAW,GAAG,iBAAiB,SAAS;EAAzD,UAAA,CACE,oBAAC,OAAD;GACE,WAAU;GACV,OAAO;IACL,iBACE;IACF,gBAAgB;IAChB,kBAAkB;GACpB;EACD,CAAA,GACA,UAAU,OAAO,SAAS,KACzB,oBAAC,OAAD;GAAK,WAAU;GACZ,UAAA,OAAO,KAAK,MACX,oBAAC,QAAD,EAAA,UAAe,EAAQ,GAAZ,CAAY,CACxB;EACE,CAAA,CAEJ;;AAET;;AAGA,SAAgB,UAAU,EACxB,OAAO,MACP,WACA,UACA,GAAG,SACiE;CACpE,OACE,qBAAC,QAAD;EAAM,WAAW,GAAG,+CAA+C,SAAS;EAAG,GAAI;EAAnF,UAAA,CACE,oBAAC,QAAD;GACE,eAAA;GACA,WAAW,GACT,gCACA,SAAS,QAAQ,qDACjB,SAAS,YAAY,yDACrB,SAAS,SAAS,SACpB;EACD,CAAA,GACA,QACG;;AAEV;;AAGA,SAAgB,MAAM,EACpB,QAAQ,GACR,WACA,KACA,MACA,aASC;CACD,OACE,oBAAC,OAAD;EACE,eAAA;EACA,WAAW,GAAG,0BAA0B,SAAS;EACjD,OAAO,MAAM,EAAE,IAAI,IAAI,KAAA;EAEtB,UAAA,MAAM,KAAK,EAAE,QAAQ,MAAM,IAAI,GAAG,MACjC,oBAAC,QAAD;GAEE,OAAO,YAAY,EAAE,OAAO,UAAU,IAAI,KAAA;GAC1C,WAAW,GACT,0BACA,SAAS,cACL,8DACA,SAAS,WACP,wDACA,8BACR;EACD,GAVM,CAUN,CACF;CACE,CAAA;AAET;;AAGA,SAAgB,cAAc,EAC5B,OACA,MACA,OACA,OACA,QAAQ,OACR,IAAI,MAAM,MACV,aASC;CACD,OACE,qBAAC,OAAD;EAAK,WAAW,GAAG,uBAAuB,SAAS;EAAnD,UAAA;IACI,QAAQ,UAAU,oBAAC,UAAD;IAAgB;IAAO,UAAA;GAAgB,CAAA;GAC3D,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,KAAD;KAAK,WAAU;KAA4D,UAAA;IAAW,CAAA,GACrF,KACE;;GACJ,SAAS,oBAAC,WAAD,CAAY,CAAA;EACnB;;AAET"}
@@ -0,0 +1,4 @@
1
+ import * as React from "react";
2
+ declare function Input({ className, type, ...props }: React.ComponentProps<"input">): React.JSX.Element;
3
+ export { Input };
4
+ //# sourceMappingURL=input.d.ts.map
@@ -0,0 +1,14 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ // src/components/input.tsx
4
+ function Input({ className, type, ...props }) {
5
+ return /* @__PURE__ */ jsx("input", {
6
+ type,
7
+ "data-slot": "input",
8
+ className: cn("h-control-height w-full min-w-0 rounded-md border border-transparent bg-shell-recess px-4 text-body-md text-ink shadow-press transition-[box-shadow,border-color] outline-none placeholder:text-ink-soft disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50", "file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-label file:text-ink", "focus-visible:border-signal-ink focus-visible:ring-[3px] focus-visible:ring-ring/30", "aria-invalid:border-danger aria-invalid:bg-danger-tint aria-invalid:ring-danger/20", className),
9
+ ...props
10
+ });
11
+ }
12
+ export { Input };
13
+
14
+ //# sourceMappingURL=input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input.js","names":[],"sources":["../../src/components/input.tsx"],"sourcesContent":["import { cn } from \"../lib/utils\";\nimport type * as React from \"react\";\n\n// Inputs are sunken wells: shell-recess fill, pressed shadow, radius-md.\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <input\n type={type}\n data-slot=\"input\"\n className={cn(\n \"h-control-height w-full min-w-0 rounded-md border border-transparent bg-shell-recess px-4 text-body-md text-ink shadow-press transition-[box-shadow,border-color] outline-none placeholder:text-ink-soft disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\",\n \"file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-label file:text-ink\",\n \"focus-visible:border-signal-ink focus-visible:ring-[3px] focus-visible:ring-ring/30\",\n \"aria-invalid:border-danger aria-invalid:bg-danger-tint aria-invalid:ring-danger/20\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Input };\n"],"mappings":";;;AAIA,SAAS,MAAM,EAAE,WAAW,MAAM,GAAG,SAAwC;CAC3E,OACE,oBAAC,SAAD;EACQ;EACN,aAAU;EACV,WAAW,GACT,yRACA,6FACA,uFACA,sFACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
@@ -0,0 +1,5 @@
1
+ import { Label } from "radix-ui";
2
+ import * as React from "react";
3
+ declare function Label$1({ className, ...props }: React.ComponentProps<typeof Label.Root>): React.JSX.Element;
4
+ export { Label$1 as Label };
5
+ //# sourceMappingURL=label.d.ts.map
@@ -0,0 +1,15 @@
1
+ "use client";
2
+ import { cn } from "../lib/utils.js";
3
+ import { Label } from "radix-ui";
4
+ import { jsx } from "react/jsx-runtime";
5
+ // src/components/label.tsx
6
+ function Label$1({ className, ...props }) {
7
+ return /* @__PURE__ */ jsx(Label.Root, {
8
+ "data-slot": "label",
9
+ className: cn("flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50", className),
10
+ ...props
11
+ });
12
+ }
13
+ export { Label$1 as Label };
14
+
15
+ //# sourceMappingURL=label.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"label.js","names":["Label","LabelPrimitive"],"sources":["../../src/components/label.tsx"],"sourcesContent":["\"use client\";\n\nimport { cn } from \"../lib/utils\";\nimport { Label as LabelPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\n\nfunction Label({ className, ...props }: React.ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n \"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Label };\n"],"mappings":";;;;;AAMA,SAASA,QAAM,EAAE,WAAW,GAAG,SAA2D;CACxF,OACE,oBAACC,MAAe,MAAhB;EACE,aAAU;EACV,WAAW,GACT,uNACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
@@ -0,0 +1,29 @@
1
+ import { TagProps } from "./tag.js";
2
+ import * as React from "react";
3
+ export type MediaCardLink = {
4
+ label: string;
5
+ href: string;
6
+ target?: string;
7
+ };
8
+ export type MediaCardProps = {
9
+ title: React.ReactNode;
10
+ /** Entry code on the media frame, e.g. "C-01". */
11
+ code?: string;
12
+ image?: string;
13
+ imageAlt?: string;
14
+ /** What it is, in HUD type: "Product", "Case study". */
15
+ kind?: string;
16
+ /** "Live" gets a green LED; anything else is a tint tag unless `statusTone` says otherwise. */
17
+ status?: string;
18
+ statusTone?: TagProps["tone"];
19
+ description?: React.ReactNode;
20
+ tags?: string[];
21
+ links?: MediaCardLink[];
22
+ /** Left offset of the hinge tab. Vary it from card to card. */
23
+ hingeLeft?: string;
24
+ className?: string;
25
+ style?: React.CSSProperties;
26
+ };
27
+ /** A product, project or story as a product shot: media on a studio backdrop, then kind, title, tags and links. */
28
+ export declare function MediaCard({ title, code, image, imageAlt, kind, status, statusTone, description, tags, links, hingeLeft, className, style }: MediaCardProps): React.JSX.Element;
29
+ //# sourceMappingURL=media-card.d.ts.map
@@ -0,0 +1,80 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import { Button } from "./button.js";
3
+ import { Crosshair } from "./hud.js";
4
+ import { HingeTab } from "./panel.js";
5
+ import { Tag } from "./tag.js";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ // src/components/media-card.tsx
8
+ /** A product, project or story as a product shot: media on a studio backdrop, then kind, title, tags and links. */
9
+ function MediaCard({ title, code, image, imageAlt = "", kind, status, statusTone, description, tags, links, hingeLeft = "28px", className, style }) {
10
+ const live = status?.toLowerCase() === "live";
11
+ return /* @__PURE__ */ jsxs("article", {
12
+ className: cn("relative drop-float", className),
13
+ style,
14
+ children: [/* @__PURE__ */ jsx(HingeTab, { style: { left: hingeLeft } }), /* @__PURE__ */ jsxs("div", {
15
+ className: "relative flex h-full flex-col gap-3 rounded-lg bg-shell notch-md px-3.5 pt-3.5 pb-6",
16
+ children: [
17
+ /* @__PURE__ */ jsxs("div", {
18
+ className: "relative aspect-[16/10] overflow-hidden rounded-md bg-studio",
19
+ children: [
20
+ image && /* @__PURE__ */ jsx("img", {
21
+ src: image,
22
+ alt: imageAlt,
23
+ className: "block size-full object-cover"
24
+ }),
25
+ /* @__PURE__ */ jsx(Crosshair, { className: "absolute top-3 left-3 text-ink/45" }),
26
+ /* @__PURE__ */ jsx(Crosshair, { className: "absolute right-3 bottom-3 text-ink/45" }),
27
+ code && /* @__PURE__ */ jsx("span", {
28
+ className: "hud-sm absolute top-3 right-[30px] text-ink",
29
+ children: code
30
+ })
31
+ ]
32
+ }),
33
+ /* @__PURE__ */ jsxs("div", {
34
+ className: "flex items-center justify-between px-2.5 pt-2",
35
+ children: [/* @__PURE__ */ jsx("span", {
36
+ className: "hud text-ink-soft",
37
+ children: kind
38
+ }), status && /* @__PURE__ */ jsx(Tag, {
39
+ tone: statusTone ?? (live ? void 0 : "tint"),
40
+ led: live,
41
+ children: status
42
+ })]
43
+ }),
44
+ /* @__PURE__ */ jsxs("div", {
45
+ className: "flex flex-col gap-2 px-2.5",
46
+ children: [/* @__PURE__ */ jsx("h3", {
47
+ className: "font-display text-display-sm text-ink",
48
+ children: title
49
+ }), description && /* @__PURE__ */ jsx("p", {
50
+ className: "text-body-sm text-ink-soft",
51
+ children: description
52
+ })]
53
+ }),
54
+ tags && tags.length > 0 && /* @__PURE__ */ jsx("div", {
55
+ className: "flex flex-wrap gap-1.5 px-2.5",
56
+ children: tags.map((tag) => /* @__PURE__ */ jsx(Tag, {
57
+ tone: "outline",
58
+ children: tag
59
+ }, tag))
60
+ }),
61
+ links && links.length > 0 && /* @__PURE__ */ jsx("div", {
62
+ className: "mt-auto flex gap-2 px-1",
63
+ children: links.map((link) => /* @__PURE__ */ jsx(Button, {
64
+ variant: "bracket",
65
+ asChild: true,
66
+ children: /* @__PURE__ */ jsx("a", {
67
+ href: link.href,
68
+ target: link.target,
69
+ rel: link.target === "_blank" ? "noopener noreferrer" : void 0,
70
+ children: link.label
71
+ })
72
+ }, link.label))
73
+ })
74
+ ]
75
+ })]
76
+ });
77
+ }
78
+ export { MediaCard };
79
+
80
+ //# sourceMappingURL=media-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-card.js","names":[],"sources":["../../src/components/media-card.tsx"],"sourcesContent":["import type * as React from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"./button\";\nimport { Crosshair } from \"./hud\";\nimport { HingeTab } from \"./panel\";\nimport { Tag, type TagProps } from \"./tag\";\n\nexport type MediaCardLink = {\n label: string;\n href: string;\n target?: string;\n};\n\nexport type MediaCardProps = {\n title: React.ReactNode;\n /** Entry code on the media frame, e.g. \"C-01\". */\n code?: string;\n image?: string;\n imageAlt?: string;\n /** What it is, in HUD type: \"Product\", \"Case study\". */\n kind?: string;\n /** \"Live\" gets a green LED; anything else is a tint tag unless `statusTone` says otherwise. */\n status?: string;\n statusTone?: TagProps[\"tone\"];\n description?: React.ReactNode;\n tags?: string[];\n links?: MediaCardLink[];\n /** Left offset of the hinge tab. Vary it from card to card. */\n hingeLeft?: string;\n className?: string;\n style?: React.CSSProperties;\n};\n\n/** A product, project or story as a product shot: media on a studio backdrop, then kind, title, tags and links. */\nexport function MediaCard({\n title,\n code,\n image,\n imageAlt = \"\",\n kind,\n status,\n statusTone,\n description,\n tags,\n links,\n hingeLeft = \"28px\",\n className,\n style,\n}: MediaCardProps) {\n const live = status?.toLowerCase() === \"live\";\n return (\n <article className={cn(\"relative drop-float\", className)} style={style}>\n <HingeTab style={{ left: hingeLeft }} />\n <div className=\"relative flex h-full flex-col gap-3 rounded-lg bg-shell notch-md px-3.5 pt-3.5 pb-6\">\n <div className=\"relative aspect-[16/10] overflow-hidden rounded-md bg-studio\">\n {image && <img src={image} alt={imageAlt} className=\"block size-full object-cover\" />}\n <Crosshair className=\"absolute top-3 left-3 text-ink/45\" />\n <Crosshair className=\"absolute right-3 bottom-3 text-ink/45\" />\n {code && <span className=\"hud-sm absolute top-3 right-[30px] text-ink\">{code}</span>}\n </div>\n <div className=\"flex items-center justify-between px-2.5 pt-2\">\n <span className=\"hud text-ink-soft\">{kind}</span>\n {status && (\n <Tag tone={statusTone ?? (live ? undefined : \"tint\")} led={live}>\n {status}\n </Tag>\n )}\n </div>\n <div className=\"flex flex-col gap-2 px-2.5\">\n <h3 className=\"font-display text-display-sm text-ink\">{title}</h3>\n {description && <p className=\"text-body-sm text-ink-soft\">{description}</p>}\n </div>\n {tags && tags.length > 0 && (\n <div className=\"flex flex-wrap gap-1.5 px-2.5\">\n {tags.map((tag) => (\n <Tag key={tag} tone=\"outline\">\n {tag}\n </Tag>\n ))}\n </div>\n )}\n {links && links.length > 0 && (\n <div className=\"mt-auto flex gap-2 px-1\">\n {links.map((link) => (\n <Button key={link.label} variant=\"bracket\" asChild>\n <a\n href={link.href}\n target={link.target}\n rel={link.target === \"_blank\" ? \"noopener noreferrer\" : undefined}\n >\n {link.label}\n </a>\n </Button>\n ))}\n </div>\n )}\n </div>\n </article>\n );\n}\n"],"mappings":";;;;;;;;AAkCA,SAAgB,UAAU,EACxB,OACA,MACA,OACA,WAAW,IACX,MACA,QACA,YACA,aACA,MACA,OACA,YAAY,QACZ,WACA,SACiB;CACjB,MAAM,OAAO,QAAQ,YAAY,MAAM;CACvC,OACE,qBAAC,WAAD;EAAS,WAAW,GAAG,uBAAuB,SAAS;EAAU;EAAjE,UAAA,CACE,oBAAC,UAAD,EAAU,OAAO,EAAE,MAAM,UAAU,EAAI,CAAA,GACvC,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACE,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MACG,SAAS,oBAAC,OAAD;OAAK,KAAK;OAAO,KAAK;OAAU,WAAU;MAAgC,CAAA;MACpF,oBAAC,WAAD,EAAW,WAAU,oCAAqC,CAAA;MAC1D,oBAAC,WAAD,EAAW,WAAU,wCAAyC,CAAA;MAC7D,QAAQ,oBAAC,QAAD;OAAM,WAAU;OAA+C,UAAA;MAAW,CAAA;KAChF;;IACL,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,oBAAC,QAAD;MAAM,WAAU;MAAqB,UAAA;KAAW,CAAA,GAC/C,UACC,oBAAC,KAAD;MAAK,MAAM,eAAe,OAAO,KAAA,IAAY;MAAS,KAAK;MACxD,UAAA;KACE,CAAA,CAEJ;;IACL,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,oBAAC,MAAD;MAAI,WAAU;MAAyC,UAAA;KAAU,CAAA,GAChE,eAAe,oBAAC,KAAD;MAAG,WAAU;MAA8B,UAAA;KAAe,CAAA,CACvE;;IACJ,QAAQ,KAAK,SAAS,KACrB,oBAAC,OAAD;KAAK,WAAU;KACZ,UAAA,KAAK,KAAK,QACT,oBAAC,KAAD;MAAe,MAAK;MACjB,UAAA;KACE,GAFK,GAEL,CACN;IACE,CAAA;IAEN,SAAS,MAAM,SAAS,KACvB,oBAAC,OAAD;KAAK,WAAU;KACZ,UAAA,MAAM,KAAK,SACV,oBAAC,QAAD;MAAyB,SAAQ;MAAU,SAAA;MACzC,UAAA,oBAAC,KAAD;OACE,MAAM,KAAK;OACX,QAAQ,KAAK;OACb,KAAK,KAAK,WAAW,WAAW,wBAAwB,KAAA;OAEvD,UAAA,KAAK;MACL,CAAA;KACG,GARK,KAAK,KAQV,CACT;IACE,CAAA;GAEJ;EACE,CAAA,CAAA;;AAEb"}
@@ -0,0 +1,10 @@
1
+ import * as React from "react";
2
+ /**
3
+ * Decimal amount input with the currency code as a suffix. The value is the raw string the user
4
+ * typed; parse it with `parseAmount` from lib/money. On phones the figure is amount-lg: inputs under
5
+ * 16px make mobile browsers zoom in on focus.
6
+ */
7
+ export declare function MoneyInput({ currency, className, ...props }: Omit<React.ComponentProps<"input">, "type"> & {
8
+ currency: string;
9
+ }): React.JSX.Element;
10
+ //# sourceMappingURL=money-input.d.ts.map
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ import { cn } from "../lib/utils.js";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ // src/components/money-input.tsx
5
+ /**
6
+ * Decimal amount input with the currency code as a suffix. The value is the raw string the user
7
+ * typed; parse it with `parseAmount` from lib/money. On phones the figure is amount-lg: inputs under
8
+ * 16px make mobile browsers zoom in on focus.
9
+ */
10
+ function MoneyInput({ currency, className, ...props }) {
11
+ return /* @__PURE__ */ jsxs("div", {
12
+ "data-slot": "money-input",
13
+ "data-fault-part": true,
14
+ className: cn("flex h-control-height w-full items-center rounded-md border border-transparent bg-shell-recess shadow-press transition-[box-shadow,border-color] focus-within:border-signal-ink focus-within:ring-[3px] focus-within:ring-ring/30 has-[[aria-invalid=true]]:border-danger has-[[aria-invalid=true]]:bg-danger-tint", className),
15
+ children: [/* @__PURE__ */ jsx("input", {
16
+ type: "text",
17
+ inputMode: "decimal",
18
+ autoComplete: "off",
19
+ placeholder: "0.00",
20
+ className: "tabular h-full min-w-0 flex-1 bg-transparent pl-4 text-right text-amount-md text-ink outline-none max-sm:text-amount-lg placeholder:text-ink-soft disabled:opacity-50",
21
+ ...props
22
+ }), /* @__PURE__ */ jsx("span", {
23
+ className: "hud px-3 text-ink-soft",
24
+ children: currency
25
+ })]
26
+ });
27
+ }
28
+ export { MoneyInput };
29
+
30
+ //# sourceMappingURL=money-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"money-input.js","names":[],"sources":["../../src/components/money-input.tsx"],"sourcesContent":["\"use client\";\n\nimport { cn } from \"../lib/utils\";\nimport type * as React from \"react\";\n\n/**\n * Decimal amount input with the currency code as a suffix. The value is the raw string the user\n * typed; parse it with `parseAmount` from lib/money. On phones the figure is amount-lg: inputs under\n * 16px make mobile browsers zoom in on focus.\n */\nexport function MoneyInput({\n currency,\n className,\n ...props\n}: Omit<React.ComponentProps<\"input\">, \"type\"> & { currency: string }) {\n return (\n <div\n data-slot=\"money-input\"\n data-fault-part\n className={cn(\n \"flex h-control-height w-full items-center rounded-md border border-transparent bg-shell-recess shadow-press transition-[box-shadow,border-color] focus-within:border-signal-ink focus-within:ring-[3px] focus-within:ring-ring/30 has-[[aria-invalid=true]]:border-danger has-[[aria-invalid=true]]:bg-danger-tint\",\n className,\n )}\n >\n <input\n type=\"text\"\n inputMode=\"decimal\"\n autoComplete=\"off\"\n placeholder=\"0.00\"\n className=\"tabular h-full min-w-0 flex-1 bg-transparent pl-4 text-right text-amount-md text-ink outline-none max-sm:text-amount-lg placeholder:text-ink-soft disabled:opacity-50\"\n {...props}\n />\n <span className=\"hud px-3 text-ink-soft\">{currency}</span>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AAUA,SAAgB,WAAW,EACzB,UACA,WACA,GAAG,SACkE;CACrE,OACE,qBAAC,OAAD;EACE,aAAU;EACV,mBAAA;EACA,WAAW,GACT,sTACA,SACF;EANF,UAAA,CAQE,oBAAC,SAAD;GACE,MAAK;GACL,WAAU;GACV,cAAa;GACb,aAAY;GACZ,WAAU;GACV,GAAI;EACL,CAAA,GACD,oBAAC,QAAD;GAAM,WAAU;GAA0B,UAAA;EAAe,CAAA,CACtD;;AAET"}
@@ -0,0 +1,27 @@
1
+ import { ComboboxGroup } from "./combobox.js";
2
+ /**
3
+ * Searchable multi-choice picker where nothing selected means "all". Stays open while you
4
+ * toggle options; Escape or a click outside closes it back onto the trigger, and Tab moves on.
5
+ * Typing on the focused trigger opens it with that text as the search, like Combobox.
6
+ */
7
+ export declare function MultiCombobox<T>({ id, value, onChange, options, groups, getKey, getSearchText, renderOption, allLabel, noun, searchPlaceholder, emptyText, invalid, disabled, className, contentClassName }: {
8
+ id?: string;
9
+ value: string[];
10
+ onChange: (keys: string[]) => void;
11
+ options?: T[];
12
+ groups?: ComboboxGroup<T>[];
13
+ getKey: (option: T) => string;
14
+ getSearchText?: (option: T) => string;
15
+ renderOption: (option: T) => React.ReactNode;
16
+ /** Trigger text when nothing is selected, e.g. "All wallets". */
17
+ allLabel: string;
18
+ /** Plural noun for the count, e.g. "wallets" → "3 wallets". */
19
+ noun: string;
20
+ searchPlaceholder?: string;
21
+ emptyText?: React.ReactNode;
22
+ invalid?: boolean;
23
+ disabled?: boolean;
24
+ className?: string;
25
+ contentClassName?: string;
26
+ }): import("react").JSX.Element;
27
+ //# sourceMappingURL=multi-combobox.d.ts.map
@@ -0,0 +1,101 @@
1
+ "use client";
2
+ import { cn } from "../lib/utils.js";
3
+ import { Button } from "./button.js";
4
+ import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "./command.js";
5
+ import { Popover, PopoverContent, PopoverTrigger } from "./popover.js";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { Check, ChevronsUpDown } from "lucide-react";
8
+ import { useState } from "react";
9
+ // src/components/multi-combobox.tsx
10
+ /**
11
+ * Searchable multi-choice picker where nothing selected means "all". Stays open while you
12
+ * toggle options; Escape or a click outside closes it back onto the trigger, and Tab moves on.
13
+ * Typing on the focused trigger opens it with that text as the search, like Combobox.
14
+ */
15
+ function MultiCombobox({ id, value, onChange, options, groups, getKey, getSearchText, renderOption, allLabel, noun, searchPlaceholder = "Search…", emptyText = "Nothing found.", invalid, disabled, className, contentClassName }) {
16
+ const [open, setOpen] = useState(false);
17
+ const [query, setQuery] = useState("");
18
+ const sections = groups ?? [{ options: options ?? [] }];
19
+ const all = sections.flatMap((g) => g.options);
20
+ const search = getSearchText ?? getKey;
21
+ const only = value.length === 1 ? all.find((o) => getKey(o) === value[0]) : void 0;
22
+ const toggle = (k) => onChange(value.includes(k) ? value.filter((v) => v !== k) : [...value, k]);
23
+ return /* @__PURE__ */ jsxs(Popover, {
24
+ open,
25
+ onOpenChange: (next) => {
26
+ if (next) setQuery("");
27
+ setOpen(next);
28
+ },
29
+ children: [/* @__PURE__ */ jsx(PopoverTrigger, {
30
+ asChild: true,
31
+ children: /* @__PURE__ */ jsxs(Button, {
32
+ id,
33
+ type: "button",
34
+ variant: "outline",
35
+ role: "combobox",
36
+ "aria-expanded": open,
37
+ "aria-invalid": invalid || void 0,
38
+ disabled,
39
+ className: cn("w-full justify-between px-3", className),
40
+ onKeyDown: (e) => {
41
+ if (!open && e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey && e.key !== " ") {
42
+ e.preventDefault();
43
+ setQuery(e.key);
44
+ setOpen(true);
45
+ }
46
+ },
47
+ children: [/* @__PURE__ */ jsx("span", {
48
+ className: "flex min-w-0 items-center gap-2",
49
+ children: value.length === 0 ? /* @__PURE__ */ jsx("span", {
50
+ className: "truncate",
51
+ children: allLabel
52
+ }) : only ? renderOption(only) : /* @__PURE__ */ jsxs("span", {
53
+ className: "truncate",
54
+ children: [
55
+ value.length,
56
+ " ",
57
+ noun
58
+ ]
59
+ })
60
+ }), /* @__PURE__ */ jsx(ChevronsUpDown, {
61
+ className: "size-4 shrink-0 text-ink-soft",
62
+ strokeWidth: 1.25
63
+ })]
64
+ })
65
+ }), /* @__PURE__ */ jsxs(PopoverContent, {
66
+ align: "start",
67
+ className: cn("w-(--radix-popover-trigger-width) min-w-64 p-0", contentClassName),
68
+ children: [/* @__PURE__ */ jsxs(Command, { children: [/* @__PURE__ */ jsx(CommandInput, {
69
+ placeholder: searchPlaceholder,
70
+ value: query,
71
+ onValueChange: setQuery
72
+ }), /* @__PURE__ */ jsxs(CommandList, { children: [/* @__PURE__ */ jsx(CommandEmpty, { children: emptyText }), sections.map((g, i) => /* @__PURE__ */ jsx(CommandGroup, {
73
+ heading: g.heading,
74
+ children: g.options.map((o) => {
75
+ const k = getKey(o);
76
+ return /* @__PURE__ */ jsxs(CommandItem, {
77
+ value: `${search(o)} ${k}`,
78
+ onSelect: () => toggle(k),
79
+ "aria-selected": value.includes(k),
80
+ children: [renderOption(o), value.includes(k) && /* @__PURE__ */ jsx(Check, {
81
+ className: "ml-auto size-4",
82
+ strokeWidth: 1.25
83
+ })]
84
+ }, k);
85
+ })
86
+ }, g.heading ?? i))] })] }), value.length > 0 && /* @__PURE__ */ jsx("div", {
87
+ className: "border-t border-seam p-2",
88
+ children: /* @__PURE__ */ jsxs(Button, {
89
+ type: "button",
90
+ variant: "ghost",
91
+ size: "xs",
92
+ onClick: () => onChange([]),
93
+ children: ["Use ", allLabel.toLowerCase()]
94
+ })
95
+ })]
96
+ })]
97
+ });
98
+ }
99
+ export { MultiCombobox };
100
+
101
+ //# sourceMappingURL=multi-combobox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multi-combobox.js","names":[],"sources":["../../src/components/multi-combobox.tsx"],"sourcesContent":["\"use client\";\n\nimport { cn } from \"../lib/utils\";\nimport { Check, ChevronsUpDown } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { Button } from \"./button\";\nimport type { ComboboxGroup } from \"./combobox\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"./command\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\";\n\n/**\n * Searchable multi-choice picker where nothing selected means \"all\". Stays open while you\n * toggle options; Escape or a click outside closes it back onto the trigger, and Tab moves on.\n * Typing on the focused trigger opens it with that text as the search, like Combobox.\n */\nexport function MultiCombobox<T>({\n id,\n value,\n onChange,\n options,\n groups,\n getKey,\n getSearchText,\n renderOption,\n allLabel,\n noun,\n searchPlaceholder = \"Search…\",\n emptyText = \"Nothing found.\",\n invalid,\n disabled,\n className,\n contentClassName,\n}: {\n id?: string;\n value: string[];\n onChange: (keys: string[]) => void;\n options?: T[];\n groups?: ComboboxGroup<T>[];\n getKey: (option: T) => string;\n getSearchText?: (option: T) => string;\n renderOption: (option: T) => React.ReactNode;\n /** Trigger text when nothing is selected, e.g. \"All wallets\". */\n allLabel: string;\n /** Plural noun for the count, e.g. \"wallets\" → \"3 wallets\". */\n noun: string;\n searchPlaceholder?: string;\n emptyText?: React.ReactNode;\n invalid?: boolean;\n disabled?: boolean;\n className?: string;\n contentClassName?: string;\n}) {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState(\"\");\n const sections: ComboboxGroup<T>[] = groups ?? [{ options: options ?? [] }];\n const all = sections.flatMap((g) => g.options);\n const search = getSearchText ?? getKey;\n const only = value.length === 1 ? all.find((o) => getKey(o) === value[0]) : undefined;\n const toggle = (k: string) =>\n onChange(value.includes(k) ? value.filter((v) => v !== k) : [...value, k]);\n\n return (\n <Popover\n open={open}\n onOpenChange={(next) => {\n if (next) setQuery(\"\");\n setOpen(next);\n }}\n >\n <PopoverTrigger asChild>\n <Button\n id={id}\n type=\"button\"\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n aria-invalid={invalid || undefined}\n disabled={disabled}\n className={cn(\"w-full justify-between px-3\", className)}\n onKeyDown={(e) => {\n if (\n !open &&\n e.key.length === 1 &&\n !e.ctrlKey &&\n !e.metaKey &&\n !e.altKey &&\n e.key !== \" \"\n ) {\n e.preventDefault();\n setQuery(e.key);\n setOpen(true);\n }\n }}\n >\n <span className=\"flex min-w-0 items-center gap-2\">\n {value.length === 0 ? (\n <span className=\"truncate\">{allLabel}</span>\n ) : only ? (\n renderOption(only)\n ) : (\n <span className=\"truncate\">\n {value.length} {noun}\n </span>\n )}\n </span>\n <ChevronsUpDown className=\"size-4 shrink-0 text-ink-soft\" strokeWidth={1.25} />\n </Button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n className={cn(\"w-(--radix-popover-trigger-width) min-w-64 p-0\", contentClassName)}\n >\n <Command>\n <CommandInput placeholder={searchPlaceholder} value={query} onValueChange={setQuery} />\n <CommandList>\n <CommandEmpty>{emptyText}</CommandEmpty>\n {sections.map((g, i) => (\n <CommandGroup key={g.heading ?? i} heading={g.heading}>\n {g.options.map((o) => {\n const k = getKey(o);\n return (\n <CommandItem\n key={k}\n value={`${search(o)} ${k}`}\n onSelect={() => toggle(k)}\n aria-selected={value.includes(k)}\n >\n {renderOption(o)}\n {value.includes(k) && <Check className=\"ml-auto size-4\" strokeWidth={1.25} />}\n </CommandItem>\n );\n })}\n </CommandGroup>\n ))}\n </CommandList>\n </Command>\n {value.length > 0 && (\n <div className=\"border-t border-seam p-2\">\n <Button type=\"button\" variant=\"ghost\" size=\"xs\" onClick={() => onChange([])}>\n Use {allLabel.toLowerCase()}\n </Button>\n </div>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAsBA,SAAgB,cAAiB,EAC/B,IACA,OACA,UACA,SACA,QACA,QACA,eACA,cACA,UACA,MACA,oBAAoB,WACpB,YAAY,kBACZ,SACA,UACA,WACA,oBAoBC;CACD,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,CAAC,OAAO,YAAY,SAAS,EAAE;CACrC,MAAM,WAA+B,UAAU,CAAC,EAAE,SAAS,WAAW,CAAC,EAAE,CAAC;CAC1E,MAAM,MAAM,SAAS,SAAS,MAAM,EAAE,OAAO;CAC7C,MAAM,SAAS,iBAAiB;CAChC,MAAM,OAAO,MAAM,WAAW,IAAI,IAAI,MAAM,MAAM,OAAO,CAAC,MAAM,MAAM,EAAE,IAAI,KAAA;CAC5E,MAAM,UAAU,MACd,SAAS,MAAM,SAAS,CAAC,IAAI,MAAM,QAAQ,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;CAE3E,OACE,qBAAC,SAAD;EACQ;EACN,eAAe,SAAS;GACtB,IAAI,MAAM,SAAS,EAAE;GACrB,QAAQ,IAAI;EACd;EALF,UAAA,CAOE,oBAAC,gBAAD;GAAgB,SAAA;GACd,UAAA,qBAAC,QAAD;IACM;IACJ,MAAK;IACL,SAAQ;IACR,MAAK;IACL,iBAAe;IACf,gBAAc,WAAW,KAAA;IACf;IACV,WAAW,GAAG,+BAA+B,SAAS;IACtD,YAAY,MAAM;KAChB,IACE,CAAC,QACD,EAAE,IAAI,WAAW,KACjB,CAAC,EAAE,WACH,CAAC,EAAE,WACH,CAAC,EAAE,UACH,EAAE,QAAQ,KACV;MACA,EAAE,eAAe;MACjB,SAAS,EAAE,GAAG;MACd,QAAQ,IAAI;KACd;IACF;IAtBF,UAAA,CAwBE,oBAAC,QAAD;KAAM,WAAU;KACb,UAAA,MAAM,WAAW,IAChB,oBAAC,QAAD;MAAM,WAAU;MAAY,UAAA;KAAe,CAAA,IACzC,OACF,aAAa,IAAI,IAEjB,qBAAC,QAAD;MAAM,WAAU;MAAhB,UAAA;OACG,MAAM;OAAO;OAAE;MACZ;;IAEJ,CAAA,GACN,oBAAC,gBAAD;KAAgB,WAAU;KAAgC,aAAa;IAAO,CAAA,CACxE;;EACM,CAAA,GAChB,qBAAC,gBAAD;GACE,OAAM;GACN,WAAW,GAAG,kDAAkD,gBAAgB;GAFlF,UAAA,CAIE,qBAAC,SAAD,EAAA,UAAA,CACE,oBAAC,cAAD;IAAc,aAAa;IAAmB,OAAO;IAAO,eAAe;GAAW,CAAA,GACtF,qBAAC,aAAD,EAAA,UAAA,CACE,oBAAC,cAAD,EAAA,UAAe,UAAwB,CAAA,GACtC,SAAS,KAAK,GAAG,MAChB,oBAAC,cAAD;IAAmC,SAAS,EAAE;IAC3C,UAAA,EAAE,QAAQ,KAAK,MAAM;KACpB,MAAM,IAAI,OAAO,CAAC;KAClB,OACE,qBAAC,aAAD;MAEE,OAAO,GAAG,OAAO,CAAC,EAAE,GAAG;MACvB,gBAAgB,OAAO,CAAC;MACxB,iBAAe,MAAM,SAAS,CAAC;MAJjC,UAAA,CAMG,aAAa,CAAC,GACd,MAAM,SAAS,CAAC,KAAK,oBAAC,OAAD;OAAO,WAAU;OAAiB,aAAa;MAAO,CAAA,CACjE;KAPN,GAAA,CAOM;IAEjB,CAAC;GACW,GAfK,EAAE,WAAW,CAelB,CACf,CACU,EAAA,CAAA,CACN,EAAA,CAAA,GACR,MAAM,SAAS,KACd,oBAAC,OAAD;IAAK,WAAU;IACb,UAAA,qBAAC,QAAD;KAAQ,MAAK;KAAS,SAAQ;KAAQ,MAAK;KAAK,eAAe,SAAS,CAAC,CAAC;KAA1E,UAAA,CAA6E,QACtE,SAAS,YAAY,CACpB;;GACL,CAAA,CAEO;EACT,CAAA,CAAA;;AAEb"}
@@ -0,0 +1,21 @@
1
+ import * as React from "react";
2
+ export type NavItem = {
3
+ label: string;
4
+ href: string;
5
+ active?: boolean;
6
+ /** Hidden on phones, e.g. a link the user menu also offers. */
7
+ desktopOnly?: boolean;
8
+ };
9
+ /**
10
+ * Floating frosted stadium bar: brand on the left, numbered links, an end slot (user menu).
11
+ * `renderLink` lets the app use its router's Link component.
12
+ */
13
+ export declare function NavBar({ brand, serial, links, end, renderLink, className }: {
14
+ brand: React.ReactNode;
15
+ serial?: React.ReactNode;
16
+ links: NavItem[];
17
+ end?: React.ReactNode;
18
+ renderLink?: (item: NavItem, props: React.ComponentProps<"a">) => React.ReactNode;
19
+ className?: string;
20
+ }): React.JSX.Element;
21
+ //# sourceMappingURL=nav-bar.d.ts.map
@@ -0,0 +1,44 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { Fragment as Fragment$1 } from "react";
4
+ // src/components/nav-bar.tsx
5
+ /**
6
+ * Floating frosted stadium bar: brand on the left, numbered links, an end slot (user menu).
7
+ * `renderLink` lets the app use its router's Link component.
8
+ */
9
+ function NavBar({ brand, serial, links, end, renderLink = (item, props) => /* @__PURE__ */ jsx("a", {
10
+ href: item.href,
11
+ ...props
12
+ }), className }) {
13
+ return /* @__PURE__ */ jsxs("nav", {
14
+ "aria-label": "Main",
15
+ className: cn("glass flex h-nav-height items-center gap-2 rounded-full pr-2.5 pl-4 sm:gap-6 sm:pl-6", className),
16
+ children: [
17
+ /* @__PURE__ */ jsxs("div", {
18
+ className: "flex shrink-0 flex-col gap-0.5",
19
+ children: [/* @__PURE__ */ jsx("span", {
20
+ className: "font-display text-display-sm whitespace-nowrap text-ink",
21
+ children: brand
22
+ }), serial !== void 0 && /* @__PURE__ */ jsx("span", {
23
+ className: "hud-sm hidden text-ink-soft sm:block",
24
+ children: serial
25
+ })]
26
+ }),
27
+ /* @__PURE__ */ jsx("div", {
28
+ className: "ml-auto flex min-w-0 items-center sm:gap-1",
29
+ children: links.map((item, i) => /* @__PURE__ */ jsx(Fragment$1, { children: renderLink(item, {
30
+ "aria-current": item.active ? "page" : void 0,
31
+ className: cn("inline-flex items-center gap-1.5 rounded-full px-2 py-2 text-label whitespace-nowrap text-ink hover:bg-shell-recess sm:px-3.5", item.active && "text-signal-ink", item.desktopOnly && "max-sm:hidden"),
32
+ children: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
33
+ className: "hud-sm hidden text-ink-soft md:inline",
34
+ children: String(i + 1).padStart(2, "0")
35
+ }), item.label] })
36
+ }) }, item.href))
37
+ }),
38
+ end
39
+ ]
40
+ });
41
+ }
42
+ export { NavBar };
43
+
44
+ //# sourceMappingURL=nav-bar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nav-bar.js","names":["Fragment"],"sources":["../../src/components/nav-bar.tsx"],"sourcesContent":["import { cn } from \"../lib/utils\";\nimport type * as React from \"react\";\nimport { Fragment } from \"react\";\n\nexport type NavItem = {\n label: string;\n href: string;\n active?: boolean;\n /** Hidden on phones, e.g. a link the user menu also offers. */\n desktopOnly?: boolean;\n};\n\n/**\n * Floating frosted stadium bar: brand on the left, numbered links, an end slot (user menu).\n * `renderLink` lets the app use its router's Link component.\n */\nexport function NavBar({\n brand,\n serial,\n links,\n end,\n renderLink = (item, props) => <a href={item.href} {...props} />,\n className,\n}: {\n brand: React.ReactNode;\n serial?: React.ReactNode;\n links: NavItem[];\n end?: React.ReactNode;\n renderLink?: (item: NavItem, props: React.ComponentProps<\"a\">) => React.ReactNode;\n className?: string;\n}) {\n return (\n <nav\n aria-label=\"Main\"\n className={cn(\n \"glass flex h-nav-height items-center gap-2 rounded-full pr-2.5 pl-4 sm:gap-6 sm:pl-6\",\n className,\n )}\n >\n <div className=\"flex shrink-0 flex-col gap-0.5\">\n <span className=\"font-display text-display-sm whitespace-nowrap text-ink\">{brand}</span>\n {serial !== undefined && (\n <span className=\"hud-sm hidden text-ink-soft sm:block\">{serial}</span>\n )}\n </div>\n <div className=\"ml-auto flex min-w-0 items-center sm:gap-1\">\n {links.map((item, i) => (\n <Fragment key={item.href}>\n {renderLink(item, {\n \"aria-current\": item.active ? \"page\" : undefined,\n className: cn(\n \"inline-flex items-center gap-1.5 rounded-full px-2 py-2 text-label whitespace-nowrap text-ink hover:bg-shell-recess sm:px-3.5\",\n item.active && \"text-signal-ink\",\n item.desktopOnly && \"max-sm:hidden\",\n ),\n children: (\n <>\n <span className=\"hud-sm hidden text-ink-soft md:inline\">\n {String(i + 1).padStart(2, \"0\")}\n </span>\n {item.label}\n </>\n ),\n })}\n </Fragment>\n ))}\n </div>\n {end}\n </nav>\n );\n}\n"],"mappings":";;;;;;;;AAgBA,SAAgB,OAAO,EACrB,OACA,QACA,OACA,KACA,cAAc,MAAM,UAAU,oBAAC,KAAD;CAAG,MAAM,KAAK;CAAM,GAAI;AAAQ,CAAA,GAC9D,aAQC;CACD,OACE,qBAAC,OAAD;EACE,cAAW;EACX,WAAW,GACT,wFACA,SACF;EALF,UAAA;GAOE,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,QAAD;KAAM,WAAU;KAA2D,UAAA;IAAY,CAAA,GACtF,WAAW,KAAA,KACV,oBAAC,QAAD;KAAM,WAAU;KAAwC,UAAA;IAAa,CAAA,CAEpE;;GACL,oBAAC,OAAD;IAAK,WAAU;IACZ,UAAA,MAAM,KAAK,MAAM,MAChB,oBAACA,YAAD,EAAA,UACG,WAAW,MAAM;KAChB,gBAAgB,KAAK,SAAS,SAAS,KAAA;KACvC,WAAW,GACT,iIACA,KAAK,UAAU,mBACf,KAAK,eAAe,eACtB;KACA,UACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,QAAD;MAAM,WAAU;MACb,UAAA,OAAO,IAAI,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;KAC1B,CAAA,GACL,KAAK,KACN,EAAA,CAAA;IAEN,CAAC,EACO,GAjBK,KAAK,IAiBV,CACX;GACE,CAAA;GACJ;EACE;;AAET"}
@@ -0,0 +1,27 @@
1
+ import * as React from "react";
2
+ type Notch = "sm" | "md" | "lg" | false;
3
+ export type PanelProps = React.ComponentProps<"div"> & {
4
+ /** Microprint in the top-left corner, e.g. "W-01 · USD". */
5
+ serial?: React.ReactNode;
6
+ /** The one chamfered corner (top-right). */
7
+ notch?: Notch;
8
+ /** Sunken shell-recess fill instead of shell. */
9
+ recess?: boolean;
10
+ /** Registration crosshair in the bottom-right corner. */
11
+ cross?: boolean;
12
+ /** Left offset of a signal hinge tab on the top edge, e.g. "24px" or "60%". */
13
+ hinge?: string;
14
+ /** Classes for the inner body (padding, layout). */
15
+ bodyClassName?: string;
16
+ };
17
+ /**
18
+ * The molded white part: rounded shell, one notched corner, optional serial, crosshair and hinge.
19
+ * The float shadow is a drop-shadow filter on the wrapper so the notch keeps it.
20
+ */
21
+ export declare function Panel({ serial, notch, recess, cross, hinge, className, bodyClassName, children, ...props }: PanelProps): React.JSX.Element;
22
+ /** Small signal stadium sitting on a part's top edge, like a hinge. One per part. */
23
+ export declare function HingeTab({ className, ...props }: React.ComponentProps<"span">): React.JSX.Element;
24
+ /** Frosted clear plastic over color: nav bars and floating toolbars. */
25
+ export declare function GlassPanel({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
26
+ export {};
27
+ //# sourceMappingURL=panel.d.ts.map