@dirstack/ui 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 (182) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +67 -0
  3. package/dist/components/animated-number.d.ts +18 -0
  4. package/dist/components/animated-number.d.ts.map +1 -0
  5. package/dist/components/animated-number.js +29 -0
  6. package/dist/components/animated-number.js.map +1 -0
  7. package/dist/components/avatar.d.ts +8 -0
  8. package/dist/components/avatar.d.ts.map +1 -0
  9. package/dist/components/avatar.js +27 -0
  10. package/dist/components/avatar.js.map +1 -0
  11. package/dist/components/badge.d.ts +58 -0
  12. package/dist/components/badge.d.ts.map +1 -0
  13. package/dist/components/badge.js +51 -0
  14. package/dist/components/badge.js.map +1 -0
  15. package/dist/components/button.d.ts +63 -0
  16. package/dist/components/button.d.ts.map +1 -0
  17. package/dist/components/button.js +66 -0
  18. package/dist/components/button.js.map +1 -0
  19. package/dist/components/callout.d.ts +41 -0
  20. package/dist/components/callout.d.ts.map +1 -0
  21. package/dist/components/callout.js +49 -0
  22. package/dist/components/callout.js.map +1 -0
  23. package/dist/components/card.d.ts +61 -0
  24. package/dist/components/card.d.ts.map +1 -0
  25. package/dist/components/card.js +67 -0
  26. package/dist/components/card.js.map +1 -0
  27. package/dist/components/chart.d.ts +32 -0
  28. package/dist/components/chart.d.ts.map +1 -0
  29. package/dist/components/chart.js +121 -0
  30. package/dist/components/chart.js.map +1 -0
  31. package/dist/components/copy-button.d.ts +22 -0
  32. package/dist/components/copy-button.d.ts.map +1 -0
  33. package/dist/components/copy-button.js +50 -0
  34. package/dist/components/copy-button.js.map +1 -0
  35. package/dist/components/copy-input.d.ts +13 -0
  36. package/dist/components/copy-input.d.ts.map +1 -0
  37. package/dist/components/copy-input.js +28 -0
  38. package/dist/components/copy-input.js.map +1 -0
  39. package/dist/components/detail-row.d.ts +93 -0
  40. package/dist/components/detail-row.d.ts.map +1 -0
  41. package/dist/components/detail-row.js +69 -0
  42. package/dist/components/detail-row.js.map +1 -0
  43. package/dist/components/dialog.d.ts +173 -0
  44. package/dist/components/dialog.d.ts.map +1 -0
  45. package/dist/components/dialog.js +139 -0
  46. package/dist/components/dialog.js.map +1 -0
  47. package/dist/components/empty-state.d.ts +96 -0
  48. package/dist/components/empty-state.d.ts.map +1 -0
  49. package/dist/components/empty-state.js +69 -0
  50. package/dist/components/empty-state.js.map +1 -0
  51. package/dist/components/entity-avatar.d.ts +77 -0
  52. package/dist/components/entity-avatar.d.ts.map +1 -0
  53. package/dist/components/entity-avatar.js +48 -0
  54. package/dist/components/entity-avatar.js.map +1 -0
  55. package/dist/components/form-row.d.ts +35 -0
  56. package/dist/components/form-row.d.ts.map +1 -0
  57. package/dist/components/form-row.js +46 -0
  58. package/dist/components/form-row.js.map +1 -0
  59. package/dist/components/form-section.d.ts +24 -0
  60. package/dist/components/form-section.d.ts.map +1 -0
  61. package/dist/components/form-section.js +39 -0
  62. package/dist/components/form-section.js.map +1 -0
  63. package/dist/components/form.d.ts +28 -0
  64. package/dist/components/form.d.ts.map +1 -0
  65. package/dist/components/form.js +88 -0
  66. package/dist/components/form.js.map +1 -0
  67. package/dist/components/heading.d.ts +44 -0
  68. package/dist/components/heading.d.ts.map +1 -0
  69. package/dist/components/heading.js +45 -0
  70. package/dist/components/heading.js.map +1 -0
  71. package/dist/components/input.d.ts +55 -0
  72. package/dist/components/input.d.ts.map +1 -0
  73. package/dist/components/input.js +33 -0
  74. package/dist/components/input.js.map +1 -0
  75. package/dist/components/kbd.d.ts +28 -0
  76. package/dist/components/kbd.d.ts.map +1 -0
  77. package/dist/components/kbd.js +31 -0
  78. package/dist/components/kbd.js.map +1 -0
  79. package/dist/components/label.d.ts +21 -0
  80. package/dist/components/label.d.ts.map +1 -0
  81. package/dist/components/label.js +21 -0
  82. package/dist/components/label.js.map +1 -0
  83. package/dist/components/menu.d.ts +22 -0
  84. package/dist/components/menu.d.ts.map +1 -0
  85. package/dist/components/menu.js +73 -0
  86. package/dist/components/menu.js.map +1 -0
  87. package/dist/components/nav-button.d.ts +34 -0
  88. package/dist/components/nav-button.d.ts.map +1 -0
  89. package/dist/components/nav-button.js +70 -0
  90. package/dist/components/nav-button.js.map +1 -0
  91. package/dist/components/nav.d.ts +44 -0
  92. package/dist/components/nav.d.ts.map +1 -0
  93. package/dist/components/nav.js +53 -0
  94. package/dist/components/nav.js.map +1 -0
  95. package/dist/components/number-input.d.ts +18 -0
  96. package/dist/components/number-input.d.ts.map +1 -0
  97. package/dist/components/number-input.js +25 -0
  98. package/dist/components/number-input.js.map +1 -0
  99. package/dist/components/page.d.ts +24 -0
  100. package/dist/components/page.d.ts.map +1 -0
  101. package/dist/components/page.js +24 -0
  102. package/dist/components/page.js.map +1 -0
  103. package/dist/components/pagination.d.ts +17 -0
  104. package/dist/components/pagination.d.ts.map +1 -0
  105. package/dist/components/pagination.js +63 -0
  106. package/dist/components/pagination.js.map +1 -0
  107. package/dist/components/popover.d.ts +8 -0
  108. package/dist/components/popover.d.ts.map +1 -0
  109. package/dist/components/popover.js +24 -0
  110. package/dist/components/popover.js.map +1 -0
  111. package/dist/components/search-input.d.ts +14 -0
  112. package/dist/components/search-input.d.ts.map +1 -0
  113. package/dist/components/search-input.js +36 -0
  114. package/dist/components/search-input.js.map +1 -0
  115. package/dist/components/section-header.d.ts +107 -0
  116. package/dist/components/section-header.d.ts.map +1 -0
  117. package/dist/components/section-header.js +147 -0
  118. package/dist/components/section-header.js.map +1 -0
  119. package/dist/components/select.d.ts +17 -0
  120. package/dist/components/select.d.ts.map +1 -0
  121. package/dist/components/select.js +94 -0
  122. package/dist/components/select.js.map +1 -0
  123. package/dist/components/skeleton.d.ts +5 -0
  124. package/dist/components/skeleton.d.ts.map +1 -0
  125. package/dist/components/skeleton.js +13 -0
  126. package/dist/components/skeleton.js.map +1 -0
  127. package/dist/components/stack.d.ts +54 -0
  128. package/dist/components/stack.d.ts.map +1 -0
  129. package/dist/components/stack.js +46 -0
  130. package/dist/components/stack.js.map +1 -0
  131. package/dist/components/stat-strip.d.ts +38 -0
  132. package/dist/components/stat-strip.d.ts.map +1 -0
  133. package/dist/components/stat-strip.js +57 -0
  134. package/dist/components/stat-strip.js.map +1 -0
  135. package/dist/components/steps.d.ts +19 -0
  136. package/dist/components/steps.d.ts.map +1 -0
  137. package/dist/components/steps.js +29 -0
  138. package/dist/components/steps.js.map +1 -0
  139. package/dist/components/switch.d.ts +6 -0
  140. package/dist/components/switch.d.ts.map +1 -0
  141. package/dist/components/switch.js +17 -0
  142. package/dist/components/switch.js.map +1 -0
  143. package/dist/components/tabs.d.ts +62 -0
  144. package/dist/components/tabs.d.ts.map +1 -0
  145. package/dist/components/tabs.js +64 -0
  146. package/dist/components/tabs.js.map +1 -0
  147. package/dist/components/textarea.d.ts +9 -0
  148. package/dist/components/textarea.d.ts.map +1 -0
  149. package/dist/components/textarea.js +18 -0
  150. package/dist/components/textarea.js.map +1 -0
  151. package/dist/components/toaster.d.ts +6 -0
  152. package/dist/components/toaster.d.ts.map +1 -0
  153. package/dist/components/toaster.js +37 -0
  154. package/dist/components/toaster.js.map +1 -0
  155. package/dist/components/tooltip.d.ts +15 -0
  156. package/dist/components/tooltip.d.ts.map +1 -0
  157. package/dist/components/tooltip.js +41 -0
  158. package/dist/components/tooltip.js.map +1 -0
  159. package/dist/lib/animation.d.ts +12 -0
  160. package/dist/lib/animation.d.ts.map +1 -0
  161. package/dist/lib/animation.js +14 -0
  162. package/dist/lib/animation.js.map +1 -0
  163. package/dist/lib/classes.d.ts +29 -0
  164. package/dist/lib/classes.d.ts.map +1 -0
  165. package/dist/lib/classes.js +39 -0
  166. package/dist/lib/classes.js.map +1 -0
  167. package/dist/lib/icons.d.ts +21 -0
  168. package/dist/lib/icons.d.ts.map +1 -0
  169. package/dist/lib/icons.js +43 -0
  170. package/dist/lib/icons.js.map +1 -0
  171. package/dist/lib/interactive.d.ts +41 -0
  172. package/dist/lib/interactive.d.ts.map +1 -0
  173. package/dist/lib/interactive.js +30 -0
  174. package/dist/lib/interactive.js.map +1 -0
  175. package/dist/lib/slot.d.ts +12 -0
  176. package/dist/lib/slot.d.ts.map +1 -0
  177. package/dist/lib/slot.js +19 -0
  178. package/dist/lib/slot.js.map +1 -0
  179. package/dist/lib/variants.d.ts +3 -0
  180. package/dist/lib/variants.js +3 -0
  181. package/dist/styles.css +169 -0
  182. package/package.json +112 -0
@@ -0,0 +1,22 @@
1
+ import { Kbd } from "./kbd.js";
2
+ import { ComponentProps } from "react";
3
+ import { Menu as Menu$1 } from "@base-ui/react/menu";
4
+ //#region src/components/menu.d.ts
5
+ declare const Menu: <Payload>(props: Menu$1.Root.Props<Payload>) => import("react").JSX.Element;
6
+ declare const MenuTrigger: Menu$1.Trigger;
7
+ declare const MenuGroup: import("react").ForwardRefExoticComponent<Omit<import("@base-ui/react").ContextMenuGroupProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
8
+ declare const MenuRadioGroup: import("react").NamedExoticComponent<Omit<import("@base-ui/react").ContextMenuRadioGroupProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
9
+ declare function MenuContent({ className, sideOffset, align, side, ...props }: Menu$1.Popup.Props & Pick<Menu$1.Positioner.Props, "align" | "side" | "sideOffset">): import("react").JSX.Element;
10
+ declare function MenuItem({ className, inset, ...props }: Menu$1.Item.Props & {
11
+ inset?: boolean;
12
+ }): import("react").JSX.Element;
13
+ declare function MenuCheckboxItem({ className, children, checked, ...props }: Menu$1.CheckboxItem.Props): import("react").JSX.Element;
14
+ declare function MenuRadioItem({ className, children, ...props }: Menu$1.RadioItem.Props): import("react").JSX.Element;
15
+ declare function MenuGroupLabel({ className, inset, ...props }: Menu$1.GroupLabel.Props & {
16
+ inset?: boolean;
17
+ }): import("react").JSX.Element;
18
+ declare function MenuSeparator({ className, ...props }: Menu$1.Separator.Props): import("react").JSX.Element;
19
+ declare function MenuShortcut({ className, ...props }: ComponentProps<typeof Kbd>): import("react").JSX.Element;
20
+ //#endregion
21
+ export { Menu, MenuCheckboxItem, MenuContent, MenuGroup, MenuGroupLabel, MenuItem, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuShortcut, MenuTrigger };
22
+ //# sourceMappingURL=menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menu.d.ts","names":[],"sources":["../../src/components/menu.tsx"],"mappings":";;;;cASM,OAAI,SAAA,OAAA,OAAA,KAAA,MAAA,6BAAA,IAAA;cACJ,aAAW,OAAA;cACX,2BAAS,0BAAA,8BAAA,gDAAA,cAAA;cACT,gCAAc,qBAAA,8BAAA,qDAAA,cAAA;iBAEX,cACP,WACA,YACA,OACA,SACG,SACF,OAAc,MAAM,QACrB,KAAK,OAAc,WAAW,0DAAuC,IAAA;iBAsB9D,WACP,WACA,UACG,SACF,OAAc,KAAK;EACpB;oBACD,IAAA;iBAaQ,mBACP,WACA,UACA,YACG,SACF,OAAc,aAAa,wBAAK,IAAA;iBAoB1B,gBAAgB,WAAW,aAAa,SAAS,OAAc,UAAU,wBAAK,IAAA;iBAmB9E,iBACP,WACA,UACG,SACF,OAAc,WAAW;EAC1B;oBACD,IAAA;iBASQ,gBAAgB,cAAc,SAAS,OAAc,UAAU,wBAAK,IAAA;iBAMpE,eAAe,cAAc,SAAS,sBAAsB,uBAAI,IAAA"}
@@ -0,0 +1,73 @@
1
+ "use client";
2
+ import { cn } from "../lib/variants.js";
3
+ import { CheckIcon, CircleIcon } from "../lib/icons.js";
4
+ import { eyebrowClasses, popoverAnimationClasses } from "../lib/classes.js";
5
+ import { Kbd } from "./kbd.js";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { Menu as Menu$1 } from "@base-ui/react/menu";
8
+ //#region src/components/menu.tsx
9
+ const Menu = Menu$1.Root;
10
+ const MenuTrigger = Menu$1.Trigger;
11
+ const MenuGroup = Menu$1.Group;
12
+ const MenuRadioGroup = Menu$1.RadioGroup;
13
+ function MenuContent({ className, sideOffset = 4, align, side, ...props }) {
14
+ return /* @__PURE__ */ jsx(Menu$1.Portal, { children: /* @__PURE__ */ jsx(Menu$1.Positioner, {
15
+ sideOffset,
16
+ align,
17
+ side,
18
+ className: "isolate z-50",
19
+ children: /* @__PURE__ */ jsx(Menu$1.Popup, {
20
+ className: cn("min-w-40 flex flex-col rounded-md border bg-popover p-1 text-popover-foreground shadow-sm backdrop-blur-xs", popoverAnimationClasses, className),
21
+ ...props
22
+ })
23
+ }) });
24
+ }
25
+ function MenuItem({ className, inset, ...props }) {
26
+ return /* @__PURE__ */ jsx(Menu$1.Item, {
27
+ className: cn("relative flex m-0 cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-control outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0", inset && "pl-8", className),
28
+ ...props
29
+ });
30
+ }
31
+ function MenuCheckboxItem({ className, children, checked, ...props }) {
32
+ return /* @__PURE__ */ jsxs(Menu$1.CheckboxItem, {
33
+ className: cn("relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-control outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50", className),
34
+ checked,
35
+ ...props,
36
+ children: [/* @__PURE__ */ jsx("span", {
37
+ className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center",
38
+ children: /* @__PURE__ */ jsx(Menu$1.CheckboxItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, {}) })
39
+ }), children]
40
+ });
41
+ }
42
+ function MenuRadioItem({ className, children, ...props }) {
43
+ return /* @__PURE__ */ jsxs(Menu$1.RadioItem, {
44
+ className: cn("relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-control outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50", className),
45
+ ...props,
46
+ children: [/* @__PURE__ */ jsx("span", {
47
+ className: "absolute left-2 flex size-3.5 items-center justify-center",
48
+ children: /* @__PURE__ */ jsx(Menu$1.RadioItemIndicator, { children: /* @__PURE__ */ jsx(CircleIcon, { className: "fill-current size-2" }) })
49
+ }), children]
50
+ });
51
+ }
52
+ function MenuGroupLabel({ className, inset, ...props }) {
53
+ return /* @__PURE__ */ jsx(Menu$1.GroupLabel, {
54
+ className: cn("px-2 pt-1.5 pb-1", eyebrowClasses, inset && "pl-8", className),
55
+ ...props
56
+ });
57
+ }
58
+ function MenuSeparator({ className, ...props }) {
59
+ return /* @__PURE__ */ jsx(Menu$1.Separator, {
60
+ className: cn("-mx-1 my-1 h-px bg-border", className),
61
+ ...props
62
+ });
63
+ }
64
+ function MenuShortcut({ className, ...props }) {
65
+ return /* @__PURE__ */ jsx(Kbd, {
66
+ className: cn("ml-auto", className),
67
+ ...props
68
+ });
69
+ }
70
+ //#endregion
71
+ export { Menu, MenuCheckboxItem, MenuContent, MenuGroup, MenuGroupLabel, MenuItem, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuShortcut, MenuTrigger };
72
+
73
+ //# sourceMappingURL=menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menu.js","names":["MenuPrimitive"],"sources":["../../src/components/menu.tsx"],"sourcesContent":["\"use client\"\n\nimport { Menu as MenuPrimitive } from \"@base-ui/react/menu\"\nimport type { ComponentProps } from \"react\"\nimport { Kbd } from \"~/components/kbd\"\nimport { eyebrowClasses, popoverAnimationClasses } from \"~/lib/classes\"\nimport { CheckIcon, CircleIcon } from \"~/lib/icons\"\nimport { cn } from \"~/lib/variants\"\n\nconst Menu = MenuPrimitive.Root\nconst MenuTrigger = MenuPrimitive.Trigger\nconst MenuGroup = MenuPrimitive.Group\nconst MenuRadioGroup = MenuPrimitive.RadioGroup\n\nfunction MenuContent({\n className,\n sideOffset = 4,\n align,\n side,\n ...props\n}: MenuPrimitive.Popup.Props &\n Pick<MenuPrimitive.Positioner.Props, \"align\" | \"side\" | \"sideOffset\">) {\n return (\n <MenuPrimitive.Portal>\n <MenuPrimitive.Positioner\n sideOffset={sideOffset}\n align={align}\n side={side}\n className=\"isolate z-50\"\n >\n <MenuPrimitive.Popup\n className={cn(\n \"min-w-40 flex flex-col rounded-md border bg-popover p-1 text-popover-foreground shadow-sm backdrop-blur-xs\",\n popoverAnimationClasses,\n className,\n )}\n {...props}\n />\n </MenuPrimitive.Positioner>\n </MenuPrimitive.Portal>\n )\n}\n\nfunction MenuItem({\n className,\n inset,\n ...props\n}: MenuPrimitive.Item.Props & {\n inset?: boolean\n}) {\n return (\n <MenuPrimitive.Item\n className={cn(\n \"relative flex m-0 cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-control outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0\",\n inset && \"pl-8\",\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: MenuPrimitive.CheckboxItem.Props) {\n return (\n <MenuPrimitive.CheckboxItem\n className={cn(\n \"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-control outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50\",\n className,\n )}\n checked={checked}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <MenuPrimitive.CheckboxItemIndicator>\n <CheckIcon />\n </MenuPrimitive.CheckboxItemIndicator>\n </span>\n {children}\n </MenuPrimitive.CheckboxItem>\n )\n}\n\nfunction MenuRadioItem({ className, children, ...props }: MenuPrimitive.RadioItem.Props) {\n return (\n <MenuPrimitive.RadioItem\n className={cn(\n \"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-control outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50\",\n className,\n )}\n {...props}\n >\n <span className=\"absolute left-2 flex size-3.5 items-center justify-center\">\n <MenuPrimitive.RadioItemIndicator>\n <CircleIcon className=\"fill-current size-2\" />\n </MenuPrimitive.RadioItemIndicator>\n </span>\n {children}\n </MenuPrimitive.RadioItem>\n )\n}\n\nfunction MenuGroupLabel({\n className,\n inset,\n ...props\n}: MenuPrimitive.GroupLabel.Props & {\n inset?: boolean\n}) {\n return (\n <MenuPrimitive.GroupLabel\n className={cn(\"px-2 pt-1.5 pb-1\", eyebrowClasses, inset && \"pl-8\", className)}\n {...props}\n />\n )\n}\n\nfunction MenuSeparator({ className, ...props }: MenuPrimitive.Separator.Props) {\n return (\n <MenuPrimitive.Separator className={cn(\"-mx-1 my-1 h-px bg-border\", className)} {...props} />\n )\n}\n\nfunction MenuShortcut({ className, ...props }: ComponentProps<typeof Kbd>) {\n return <Kbd className={cn(\"ml-auto\", className)} {...props} />\n}\n\nexport {\n Menu,\n MenuCheckboxItem,\n MenuContent,\n MenuGroup,\n MenuItem,\n MenuGroupLabel,\n MenuRadioGroup,\n MenuRadioItem,\n MenuSeparator,\n MenuShortcut,\n MenuTrigger,\n}\n"],"mappings":";;;;;;;;AASA,MAAM,OAAOA,OAAc;AAC3B,MAAM,cAAcA,OAAc;AAClC,MAAM,YAAYA,OAAc;AAChC,MAAM,iBAAiBA,OAAc;AAErC,SAAS,YAAY,EACnB,WACA,aAAa,GACb,OACA,MACA,GAAG,SAEoE;CACvE,OACE,oBAACA,OAAc,QAAf,EAAA,UACE,oBAACA,OAAc,YAAf;EACc;EACL;EACD;EACN,WAAU;EAEV,UAAA,oBAACA,OAAc,OAAf;GACE,WAAW,GACT,8GACA,yBACA,SACF;GACA,GAAI;EACL,CAAA;CACuB,CAAA,EACN,CAAA;AAE1B;AAEA,SAAS,SAAS,EAChB,WACA,OACA,GAAG,SAGF;CACD,OACE,oBAACA,OAAc,MAAf;EACE,WAAW,GACT,8PACA,SAAS,QACT,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,iBAAiB,EACxB,WACA,UACA,SACA,GAAG,SACgC;CACnC,OACE,qBAACA,OAAc,cAAf;EACE,WAAW,GACT,yNACA,SACF;EACS;EACT,GAAI;EANN,UAAA,CAQE,oBAAC,QAAD;GAAM,WAAU;GACd,UAAA,oBAACA,OAAc,uBAAf,EAAA,UACE,oBAAC,WAAD,CAAY,CAAA,EACuB,CAAA;EACjC,CAAA,GACL,QACyB;;AAEhC;AAEA,SAAS,cAAc,EAAE,WAAW,UAAU,GAAG,SAAwC;CACvF,OACE,qBAACA,OAAc,WAAf;EACE,WAAW,GACT,yNACA,SACF;EACA,GAAI;EALN,UAAA,CAOE,oBAAC,QAAD;GAAM,WAAU;GACd,UAAA,oBAACA,OAAc,oBAAf,EAAA,UACE,oBAAC,YAAD,EAAY,WAAU,sBAAuB,CAAA,EACb,CAAA;EAC9B,CAAA,GACL,QACsB;;AAE7B;AAEA,SAAS,eAAe,EACtB,WACA,OACA,GAAG,SAGF;CACD,OACE,oBAACA,OAAc,YAAf;EACE,WAAW,GAAG,oBAAoB,gBAAgB,SAAS,QAAQ,SAAS;EAC5E,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,cAAc,EAAE,WAAW,GAAG,SAAwC;CAC7E,OACE,oBAACA,OAAc,WAAf;EAAyB,WAAW,GAAG,6BAA6B,SAAS;EAAG,GAAI;CAAQ,CAAA;AAEhG;AAEA,SAAS,aAAa,EAAE,WAAW,GAAG,SAAqC;CACzE,OAAO,oBAAC,KAAD;EAAK,WAAW,GAAG,WAAW,SAAS;EAAG,GAAI;CAAQ,CAAA;AAC/D"}
@@ -0,0 +1,34 @@
1
+ import { VariantProps } from "../lib/variants.js";
2
+ import { Button } from "./button.js";
3
+ import { navItem } from "./nav.js";
4
+ import { ComponentProps, ReactNode } from "react";
5
+ //#region src/components/nav-button.d.ts
6
+ type NavButtonVariant = Exclude<NonNullable<VariantProps<typeof navItem>["variant"]>, "link">;
7
+ type NavButtonShellProps = Omit<ComponentProps<typeof Button>, "variant"> & {
8
+ leading: ReactNode;
9
+ variant?: NavButtonVariant;
10
+ };
11
+ type NavButtonProps = NavButtonShellProps & {
12
+ title: string;
13
+ avatar?: string;
14
+ };
15
+ /**
16
+ * Compact nav trigger: a 20px avatar, one line of text and whatever `suffix` the caller
17
+ * passes (usually a chevron). Secondary text belongs in the menu it opens.
18
+ */
19
+ declare function NavButton({ avatar, title, ...props }: Omit<NavButtonProps, "leading" | "children">): import("react").JSX.Element;
20
+ declare function NavButtonSkeleton({ variant, ...props }: Omit<NavButtonShellProps, "leading" | "children">): import("react").JSX.Element;
21
+ type NavIdentityProps = ComponentProps<"div"> & {
22
+ name: ReactNode;
23
+ /**
24
+ * The muted second line under the name: an email, a workspace slug.
25
+ */
26
+ detail: ReactNode;
27
+ };
28
+ /**
29
+ * Name over a muted detail line — the identity stack a nav menu's items and headers share.
30
+ */
31
+ declare function NavIdentity({ name, detail, className, ...props }: NavIdentityProps): import("react").JSX.Element;
32
+ //#endregion
33
+ export { NavButton, NavButtonSkeleton, NavIdentity };
34
+ //# sourceMappingURL=nav-button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nav-button.d.ts","names":[],"sources":["../../src/components/nav-button.tsx"],"mappings":";;;;;KAOK,mBAAmB,QAAQ,YAAY,oBAAoB;KAE3D,sBAAsB,KAAK,sBAAsB;EACpD,SAAS;EACT,UAAU;;KAuBP,iBAAiB;EACpB;EACA;;;;;;iBAOO,YAAY,QAAQ,UAAU,SAAS,KAAK,0DAAuC,IAAA;iBAQnF,oBACP,YACG,SACF,KAAK,+DAA4C,IAAA;KAa/C,mBAAmB;EACtB,MAAM;;;;EAKN,QAAQ;;;;;iBAMD,cAAc,MAAM,QAAQ,cAAc,SAAS,mCAAgB,IAAA"}
@@ -0,0 +1,70 @@
1
+ import { cn } from "../lib/variants.js";
2
+ import { Button } from "./button.js";
3
+ import { EntityAvatar } from "./entity-avatar.js";
4
+ import { navItem } from "./nav.js";
5
+ import { Skeleton } from "./skeleton.js";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ //#region src/components/nav-button.tsx
8
+ function NavButtonShell({ leading, variant = "flat", children, className, ...props }) {
9
+ return /* @__PURE__ */ jsx(Button, {
10
+ size: "md",
11
+ variant: "ghost",
12
+ prefix: leading,
13
+ className: navItem({
14
+ variant,
15
+ className
16
+ }),
17
+ ...props,
18
+ children: /* @__PURE__ */ jsx("span", {
19
+ className: "font-medium text-sm/tight",
20
+ children
21
+ })
22
+ });
23
+ }
24
+ /**
25
+ * Compact nav trigger: a 20px avatar, one line of text and whatever `suffix` the caller
26
+ * passes (usually a chevron). Secondary text belongs in the menu it opens.
27
+ */
28
+ function NavButton({ avatar, title, ...props }) {
29
+ return /* @__PURE__ */ jsx(NavButtonShell, {
30
+ leading: /* @__PURE__ */ jsx(EntityAvatar, {
31
+ size: "sm",
32
+ src: avatar,
33
+ name: title
34
+ }),
35
+ ...props,
36
+ children: title
37
+ });
38
+ }
39
+ function NavButtonSkeleton({ variant, ...props }) {
40
+ return /* @__PURE__ */ jsx(NavButtonShell, {
41
+ disabled: true,
42
+ variant,
43
+ leading: /* @__PURE__ */ jsx(Skeleton, { className: "size-5 rounded-sm" }),
44
+ ...props,
45
+ children: /* @__PURE__ */ jsx(Skeleton, {
46
+ className: "w-28",
47
+ children: "\xA0"
48
+ })
49
+ });
50
+ }
51
+ /**
52
+ * Name over a muted detail line — the identity stack a nav menu's items and headers share.
53
+ */
54
+ function NavIdentity({ name, detail, className, ...props }) {
55
+ return /* @__PURE__ */ jsxs("div", {
56
+ className: cn("flex min-w-0 flex-col", className),
57
+ ...props,
58
+ children: [/* @__PURE__ */ jsx("span", {
59
+ className: "truncate font-medium text-sm/tight",
60
+ children: name
61
+ }), /* @__PURE__ */ jsx("span", {
62
+ className: "truncate text-muted-foreground text-xs/tight",
63
+ children: detail
64
+ })]
65
+ });
66
+ }
67
+ //#endregion
68
+ export { NavButton, NavButtonSkeleton, NavIdentity };
69
+
70
+ //# sourceMappingURL=nav-button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nav-button.js","names":[],"sources":["../../src/components/nav-button.tsx"],"sourcesContent":["import type { ComponentProps, ReactNode } from \"react\"\nimport { Button } from \"~/components/button\"\nimport { EntityAvatar } from \"~/components/entity-avatar\"\nimport { navItem } from \"~/components/nav\"\nimport { Skeleton } from \"~/components/skeleton\"\nimport { cn, type VariantProps } from \"~/lib/variants\"\n\ntype NavButtonVariant = Exclude<NonNullable<VariantProps<typeof navItem>[\"variant\"]>, \"link\">\n\ntype NavButtonShellProps = Omit<ComponentProps<typeof Button>, \"variant\"> & {\n leading: ReactNode\n variant?: NavButtonVariant\n}\n\nfunction NavButtonShell({\n leading,\n variant = \"flat\",\n children,\n className,\n ...props\n}: NavButtonShellProps) {\n return (\n <Button\n size=\"md\"\n variant=\"ghost\"\n prefix={leading}\n className={navItem({ variant, className })}\n {...props}\n >\n <span className=\"font-medium text-sm/tight\">{children}</span>\n </Button>\n )\n}\n\ntype NavButtonProps = NavButtonShellProps & {\n title: string\n avatar?: string\n}\n\n/**\n * Compact nav trigger: a 20px avatar, one line of text and whatever `suffix` the caller\n * passes (usually a chevron). Secondary text belongs in the menu it opens.\n */\nfunction NavButton({ avatar, title, ...props }: Omit<NavButtonProps, \"leading\" | \"children\">) {\n return (\n <NavButtonShell leading={<EntityAvatar size=\"sm\" src={avatar} name={title} />} {...props}>\n {title}\n </NavButtonShell>\n )\n}\n\nfunction NavButtonSkeleton({\n variant,\n ...props\n}: Omit<NavButtonShellProps, \"leading\" | \"children\">) {\n return (\n <NavButtonShell\n disabled\n variant={variant}\n leading={<Skeleton className=\"size-5 rounded-sm\" />}\n {...props}\n >\n <Skeleton className=\"w-28\">&nbsp;</Skeleton>\n </NavButtonShell>\n )\n}\n\ntype NavIdentityProps = ComponentProps<\"div\"> & {\n name: ReactNode\n\n /**\n * The muted second line under the name: an email, a workspace slug.\n */\n detail: ReactNode\n}\n\n/**\n * Name over a muted detail line — the identity stack a nav menu's items and headers share.\n */\nfunction NavIdentity({ name, detail, className, ...props }: NavIdentityProps) {\n return (\n <div className={cn(\"flex min-w-0 flex-col\", className)} {...props}>\n <span className=\"truncate font-medium text-sm/tight\">{name}</span>\n <span className=\"truncate text-muted-foreground text-xs/tight\">{detail}</span>\n </div>\n )\n}\n\nexport { NavButton, NavButtonSkeleton, NavIdentity }\n"],"mappings":";;;;;;;AAcA,SAAS,eAAe,EACtB,SACA,UAAU,QACV,UACA,WACA,GAAG,SACmB;CACtB,OACE,oBAAC,QAAD;EACE,MAAK;EACL,SAAQ;EACR,QAAQ;EACR,WAAW,QAAQ;GAAE;GAAS;EAAU,CAAC;EACzC,GAAI;EAEJ,UAAA,oBAAC,QAAD;GAAM,WAAU;GAA6B;EAAe,CAAA;CACtD,CAAA;AAEZ;;;;;AAWA,SAAS,UAAU,EAAE,QAAQ,OAAO,GAAG,SAAuD;CAC5F,OACE,oBAAC,gBAAD;EAAgB,SAAS,oBAAC,cAAD;GAAc,MAAK;GAAK,KAAK;GAAQ,MAAM;EAAQ,CAAA;EAAG,GAAI;EAChF,UAAA;CACa,CAAA;AAEpB;AAEA,SAAS,kBAAkB,EACzB,SACA,GAAG,SACiD;CACpD,OACE,oBAAC,gBAAD;EACE,UAAA;EACS;EACT,SAAS,oBAAC,UAAD,EAAU,WAAU,oBAAqB,CAAA;EAClD,GAAI;EAEJ,UAAA,oBAAC,UAAD;GAAU,WAAU;GAAO,UAAA;EAAgB,CAAA;CAC7B,CAAA;AAEpB;;;;AAcA,SAAS,YAAY,EAAE,MAAM,QAAQ,WAAW,GAAG,SAA2B;CAC5E,OACE,qBAAC,OAAD;EAAK,WAAW,GAAG,yBAAyB,SAAS;EAAG,GAAI;EAA5D,UAAA,CACE,oBAAC,QAAD;GAAM,WAAU;GAAsC,UAAA;EAAW,CAAA,GACjE,oBAAC,QAAD;GAAM,WAAU;GAAgD,UAAA;EAAa,CAAA,CAC1E;;AAET"}
@@ -0,0 +1,44 @@
1
+ import { ComponentProps } from "react";
2
+ //#region src/components/nav.d.ts
3
+ export declare function Nav({ className, ...props }: ComponentProps<"nav">): import("react").JSX.Element;
4
+ /**
5
+ * Muted group label above a run of nav links.
6
+ */
7
+ export declare function NavLabel({ className, ...props }: ComponentProps<"p">): import("react").JSX.Element;
8
+ /**
9
+ * The one nav row, applied to a `ghost` `md` `Button`: every item starts from the same width,
10
+ * inset and gap, and each variant is the shape on top of it.
11
+ *
12
+ * `link` — a nav link or a settings tab: muted at rest, full color on hover, and a flat darker
13
+ * tint with dark text when active. The 16px icon sits centered in a 20px box, so labels start on
14
+ * the same column as a row that leads with a 20px avatar (10px inset + 20px avatar + 10px gap).
15
+ * The active state keys off `data-status="active"`, which router links set on their own and plain
16
+ * buttons set by hand, so the active color always wins over the resting one. Its tints are flat
17
+ * foreground over the canvas, so hover and active share the canvas hue exactly.
18
+ *
19
+ * `bordered` — a bordered row on a card surface, for a row that leads with its own visual and
20
+ * opens a menu.
21
+ *
22
+ * `flat` — the same row without the border or the surface.
23
+ */
24
+ export declare const navItem: import("tailwind-variants").TVReturnType<{
25
+ variant: {
26
+ link: string[];
27
+ bordered: string[];
28
+ flat: "[&>*:first-child]:ml-0 [&>*:last-child]:mr-0";
29
+ };
30
+ }, undefined, "w-full justify-start gap-2.5 px-2.5", {
31
+ variant: {
32
+ link: string[];
33
+ bordered: string[];
34
+ flat: "[&>*:first-child]:ml-0 [&>*:last-child]:mr-0";
35
+ };
36
+ }, undefined, import("tailwind-variants").TVReturnTypeLike<{
37
+ variant: {
38
+ link: string[];
39
+ bordered: string[];
40
+ flat: "[&>*:first-child]:ml-0 [&>*:last-child]:mr-0";
41
+ };
42
+ }, undefined>>;
43
+ //#endregion
44
+ //# sourceMappingURL=nav.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nav.d.ts","names":[],"sources":["../../src/components/nav.tsx"],"mappings":";;wBAIgB,MAAM,cAAc,SAAS,wCAAqB,IAAA;;;;wBAOlD,WAAW,cAAc,SAAS,sCAAmB,IAAA;;;;;;;;;;;;;;;;;qBA0BxD,qCAAO"}
@@ -0,0 +1,53 @@
1
+ import { cn, variants } from "../lib/variants.js";
2
+ import { eyebrowClasses } from "../lib/classes.js";
3
+ import { jsx } from "react/jsx-runtime";
4
+ //#region src/components/nav.tsx
5
+ function Nav({ className, ...props }) {
6
+ return /* @__PURE__ */ jsx("nav", {
7
+ className: cn("flex flex-col gap-0.5 px-3 py-2", className),
8
+ ...props
9
+ });
10
+ }
11
+ /**
12
+ * Muted group label above a run of nav links.
13
+ */
14
+ function NavLabel({ className, ...props }) {
15
+ return /* @__PURE__ */ jsx("p", {
16
+ className: cn("px-2.5 pt-1 pb-1.5", eyebrowClasses, className),
17
+ ...props
18
+ });
19
+ }
20
+ /**
21
+ * The affixes of a nav row that leads with its own visual (an avatar, a skeleton) sit flush
22
+ * against the row's inset, so the Button's optical pull-in is zeroed on both ends.
23
+ */
24
+ const navAffixClasses = "[&>*:first-child]:ml-0 [&>*:last-child]:mr-0";
25
+ /**
26
+ * The one nav row, applied to a `ghost` `md` `Button`: every item starts from the same width,
27
+ * inset and gap, and each variant is the shape on top of it.
28
+ *
29
+ * `link` — a nav link or a settings tab: muted at rest, full color on hover, and a flat darker
30
+ * tint with dark text when active. The 16px icon sits centered in a 20px box, so labels start on
31
+ * the same column as a row that leads with a 20px avatar (10px inset + 20px avatar + 10px gap).
32
+ * The active state keys off `data-status="active"`, which router links set on their own and plain
33
+ * buttons set by hand, so the active color always wins over the resting one. Its tints are flat
34
+ * foreground over the canvas, so hover and active share the canvas hue exactly.
35
+ *
36
+ * `bordered` — a bordered row on a card surface, for a row that leads with its own visual and
37
+ * opens a menu.
38
+ *
39
+ * `flat` — the same row without the border or the surface.
40
+ */
41
+ const navItem = variants({
42
+ base: "w-full justify-start gap-2.5 px-2.5",
43
+ variants: { variant: {
44
+ link: ["py-2 text-muted-foreground text-sm/tight hover:bg-foreground/3 hover:text-foreground [&>svg:first-child]:ml-0.5 [&>svg]:mr-0.5 [&>svg]:size-4 [&>svg]:shrink-0", "data-[status=active]:bg-foreground/5 data-[status=active]:text-foreground data-[status=active]:hover:bg-foreground/5"],
45
+ bordered: [navAffixClasses, "border-border bg-card hover:bg-card hover:border-ring"],
46
+ flat: navAffixClasses
47
+ } },
48
+ defaultVariants: { variant: "link" }
49
+ });
50
+ //#endregion
51
+ export { Nav, NavLabel, navItem };
52
+
53
+ //# sourceMappingURL=nav.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nav.js","names":[],"sources":["../../src/components/nav.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\"\nimport { eyebrowClasses } from \"~/lib/classes\"\nimport { cn, variants } from \"~/lib/variants\"\n\nexport function Nav({ className, ...props }: ComponentProps<\"nav\">) {\n return <nav className={cn(\"flex flex-col gap-0.5 px-3 py-2\", className)} {...props} />\n}\n\n/**\n * Muted group label above a run of nav links.\n */\nexport function NavLabel({ className, ...props }: ComponentProps<\"p\">) {\n return <p className={cn(\"px-2.5 pt-1 pb-1.5\", eyebrowClasses, className)} {...props} />\n}\n\n/**\n * The affixes of a nav row that leads with its own visual (an avatar, a skeleton) sit flush\n * against the row's inset, so the Button's optical pull-in is zeroed on both ends.\n */\nconst navAffixClasses = \"[&>*:first-child]:ml-0 [&>*:last-child]:mr-0\"\n\n/**\n * The one nav row, applied to a `ghost` `md` `Button`: every item starts from the same width,\n * inset and gap, and each variant is the shape on top of it.\n *\n * `link` — a nav link or a settings tab: muted at rest, full color on hover, and a flat darker\n * tint with dark text when active. The 16px icon sits centered in a 20px box, so labels start on\n * the same column as a row that leads with a 20px avatar (10px inset + 20px avatar + 10px gap).\n * The active state keys off `data-status=\"active\"`, which router links set on their own and plain\n * buttons set by hand, so the active color always wins over the resting one. Its tints are flat\n * foreground over the canvas, so hover and active share the canvas hue exactly.\n *\n * `bordered` — a bordered row on a card surface, for a row that leads with its own visual and\n * opens a menu.\n *\n * `flat` — the same row without the border or the surface.\n */\nexport const navItem = variants({\n base: \"w-full justify-start gap-2.5 px-2.5\",\n\n variants: {\n variant: {\n link: [\n \"py-2 text-muted-foreground text-sm/tight hover:bg-foreground/3 hover:text-foreground [&>svg:first-child]:ml-0.5 [&>svg]:mr-0.5 [&>svg]:size-4 [&>svg]:shrink-0\",\n \"data-[status=active]:bg-foreground/5 data-[status=active]:text-foreground data-[status=active]:hover:bg-foreground/5\",\n ],\n bordered: [navAffixClasses, \"border-border bg-card hover:bg-card hover:border-ring\"],\n flat: navAffixClasses,\n },\n },\n\n defaultVariants: {\n variant: \"link\",\n },\n})\n"],"mappings":";;;;AAIA,SAAgB,IAAI,EAAE,WAAW,GAAG,SAAgC;CAClE,OAAO,oBAAC,OAAD;EAAK,WAAW,GAAG,mCAAmC,SAAS;EAAG,GAAI;CAAQ,CAAA;AACvF;;;;AAKA,SAAgB,SAAS,EAAE,WAAW,GAAG,SAA8B;CACrE,OAAO,oBAAC,KAAD;EAAG,WAAW,GAAG,sBAAsB,gBAAgB,SAAS;EAAG,GAAI;CAAQ,CAAA;AACxF;;;;;AAMA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;AAkBxB,MAAa,UAAU,SAAS;CAC9B,MAAM;CAEN,UAAU,EACR,SAAS;EACP,MAAM,CACJ,kKACA,sHACF;EACA,UAAU,CAAC,iBAAiB,uDAAuD;EACnF,MAAM;CACR,EACF;CAEA,iBAAiB,EACf,SAAS,OACX;AACF,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { Input } from "./input.js";
2
+ import { ComponentProps } from "react";
3
+ //#region src/components/number-input.d.ts
4
+ type NumberInputProps = Omit<ComponentProps<typeof Input>, "value" | "onChange" | "type"> & {
5
+ value: number | null | undefined;
6
+ onValueChange: (value: number | null | undefined) => void;
7
+ integer?: boolean;
8
+ nullable?: boolean;
9
+ };
10
+ /**
11
+ * A numeric input for react-hook-form fields. A cleared input yields `undefined`
12
+ * (validates as required instead of "expected number, received NaN"), or `null`
13
+ * when `nullable`, for optional constraints edited via a partial patch where
14
+ * undefined means "leave unchanged" and only null clears the stored value.
15
+ */
16
+ export declare function NumberInput({ value, onValueChange, integer, nullable, ...props }: NumberInputProps): import("react").JSX.Element;
17
+ //#endregion
18
+ //# sourceMappingURL=number-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number-input.d.ts","names":[],"sources":["../../src/components/number-input.tsx"],"mappings":";;;KAGK,mBAAmB,KAAK,sBAAsB;EACjD;EACA,gBAAgB;EAChB;EACA;;;;;;;;wBASc,cACd,OACA,eACA,SACA,aACG,SACF,mCAAgB,IAAA"}
@@ -0,0 +1,25 @@
1
+ import { Input } from "./input.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region src/components/number-input.tsx
4
+ /**
5
+ * A numeric input for react-hook-form fields. A cleared input yields `undefined`
6
+ * (validates as required instead of "expected number, received NaN"), or `null`
7
+ * when `nullable`, for optional constraints edited via a partial patch where
8
+ * undefined means "leave unchanged" and only null clears the stored value.
9
+ */
10
+ function NumberInput({ value, onValueChange, integer, nullable, ...props }) {
11
+ function parse(raw) {
12
+ if (raw === "") return nullable ? null : void 0;
13
+ return integer ? Number.parseInt(raw, 10) : Number.parseFloat(raw);
14
+ }
15
+ return /* @__PURE__ */ jsx(Input, {
16
+ type: "number",
17
+ value: value ?? "",
18
+ onChange: (event) => onValueChange(parse(event.target.value)),
19
+ ...props
20
+ });
21
+ }
22
+ //#endregion
23
+ export { NumberInput };
24
+
25
+ //# sourceMappingURL=number-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number-input.js","names":[],"sources":["../../src/components/number-input.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\"\nimport { Input } from \"~/components/input\"\n\ntype NumberInputProps = Omit<ComponentProps<typeof Input>, \"value\" | \"onChange\" | \"type\"> & {\n value: number | null | undefined\n onValueChange: (value: number | null | undefined) => void\n integer?: boolean\n nullable?: boolean\n}\n\n/**\n * A numeric input for react-hook-form fields. A cleared input yields `undefined`\n * (validates as required instead of \"expected number, received NaN\"), or `null`\n * when `nullable`, for optional constraints edited via a partial patch where\n * undefined means \"leave unchanged\" and only null clears the stored value.\n */\nexport function NumberInput({\n value,\n onValueChange,\n integer,\n nullable,\n ...props\n}: NumberInputProps) {\n function parse(raw: string) {\n if (raw === \"\") return nullable ? null : undefined\n return integer ? Number.parseInt(raw, 10) : Number.parseFloat(raw)\n }\n\n return (\n <Input\n type=\"number\"\n value={value ?? \"\"}\n onChange={event => onValueChange(parse(event.target.value))}\n {...props}\n />\n )\n}\n"],"mappings":";;;;;;;;;AAgBA,SAAgB,YAAY,EAC1B,OACA,eACA,SACA,UACA,GAAG,SACgB;CACnB,SAAS,MAAM,KAAa;EAC1B,IAAI,QAAQ,IAAI,OAAO,WAAW,OAAO,KAAA;EACzC,OAAO,UAAU,OAAO,SAAS,KAAK,EAAE,IAAI,OAAO,WAAW,GAAG;CACnE;CAEA,OACE,oBAAC,OAAD;EACE,MAAK;EACL,OAAO,SAAS;EAChB,WAAU,UAAS,cAAc,MAAM,MAAM,OAAO,KAAK,CAAC;EAC1D,GAAI;CACL,CAAA;AAEL"}
@@ -0,0 +1,24 @@
1
+ import { VariantProps } from "../lib/variants.js";
2
+ import { ComponentProps } from "react";
3
+ //#region src/components/page.d.ts
4
+ declare const pageVariants: import("tailwind-variants").TVReturnType<{
5
+ width: {
6
+ narrow: "max-w-3xl";
7
+ };
8
+ }, undefined, "flex w-full flex-col gap-6", {
9
+ width: {
10
+ narrow: "max-w-3xl";
11
+ };
12
+ }, undefined, import("tailwind-variants").TVReturnTypeLike<{
13
+ width: {
14
+ narrow: "max-w-3xl";
15
+ };
16
+ }, undefined>>;
17
+ type PageProps = ComponentProps<"div"> & VariantProps<typeof pageVariants>;
18
+ /**
19
+ * The root of a workspace route: owns the vertical rhythm between the page header and its
20
+ * content, so no page sets its own top margins or gaps.
21
+ */
22
+ export declare function Page({ className, width, ...props }: PageProps): import("react").JSX.Element;
23
+ //#endregion
24
+ //# sourceMappingURL=page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page.d.ts","names":[],"sources":["../../src/components/page.tsx"],"mappings":";;;cAGM,0CAAY;;;;;;;;;;;;;KAab,YAAY,wBAAwB,oBAAoB;;;;;wBAM7C,OAAO,WAAW,UAAU,SAAS,4BAAS,IAAA"}
@@ -0,0 +1,24 @@
1
+ import { cn, variants } from "../lib/variants.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region src/components/page.tsx
4
+ const pageVariants = variants({
5
+ base: "flex w-full flex-col gap-6",
6
+ variants: { width: { narrow: "max-w-3xl" } }
7
+ });
8
+ /**
9
+ * The root of a workspace route: owns the vertical rhythm between the page header and its
10
+ * content, so no page sets its own top margins or gaps.
11
+ */
12
+ function Page({ className, width, ...props }) {
13
+ return /* @__PURE__ */ jsx("div", {
14
+ className: cn(pageVariants({
15
+ width,
16
+ className
17
+ })),
18
+ ...props
19
+ });
20
+ }
21
+ //#endregion
22
+ export { Page };
23
+
24
+ //# sourceMappingURL=page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page.js","names":[],"sources":["../../src/components/page.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\"\nimport { cn, variants, type VariantProps } from \"~/lib/variants\"\n\nconst pageVariants = variants({\n // One rhythm for every workspace page: the header, then each block, 24px apart.\n base: \"flex w-full flex-col gap-6\",\n\n variants: {\n width: {\n // Single-column forms and settings. Left off, the page runs full width: dashboards,\n // lists, detail pages.\n narrow: \"max-w-3xl\",\n },\n },\n})\n\ntype PageProps = ComponentProps<\"div\"> & VariantProps<typeof pageVariants>\n\n/**\n * The root of a workspace route: owns the vertical rhythm between the page header and its\n * content, so no page sets its own top margins or gaps.\n */\nexport function Page({ className, width, ...props }: PageProps) {\n return <div className={cn(pageVariants({ width, className }))} {...props} />\n}\n"],"mappings":";;;AAGA,MAAM,eAAe,SAAS;CAE5B,MAAM;CAEN,UAAU,EACR,OAAO,EAGL,QAAQ,YACV,EACF;AACF,CAAC;;;;;AAQD,SAAgB,KAAK,EAAE,WAAW,OAAO,GAAG,SAAoB;CAC9D,OAAO,oBAAC,OAAD;EAAK,WAAW,GAAG,aAAa;GAAE;GAAO;EAAU,CAAC,CAAC;EAAG,GAAI;CAAQ,CAAA;AAC7E"}
@@ -0,0 +1,17 @@
1
+ import { ComponentProps } from "react";
2
+ //#region src/components/pagination.d.ts
3
+ type PaginationProps = ComponentProps<"div"> & {
4
+ page: number;
5
+ pageCount: number;
6
+ total: number;
7
+ perPage: number;
8
+ onPageChange: (page: number) => void;
9
+ };
10
+ /**
11
+ * Offset-pagination controls for a list: a "Showing from–to of total" label and prev/next
12
+ * buttons. Presentational and router-agnostic — the caller wires `onPageChange` to its search
13
+ * params. Renders nothing when there's a single page.
14
+ */
15
+ export declare function Pagination({ page, pageCount, total, perPage, onPageChange, className, ...props }: PaginationProps): import("react").JSX.Element | null;
16
+ //#endregion
17
+ //# sourceMappingURL=pagination.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.d.ts","names":[],"sources":["../../src/components/pagination.tsx"],"mappings":";;KAaK,kBAAkB;EACrB;EACA;EACA;EACA;EACA,eAAe;;;;;;;wBAQD,aACd,MACA,WACA,OACA,SACA,cACA,cACG,SACF,kCAAe,IAAA"}
@@ -0,0 +1,63 @@
1
+ import { cn } from "../lib/variants.js";
2
+ import { ChevronLeftIcon, ChevronRightIcon } from "../lib/icons.js";
3
+ import { Button } from "./button.js";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ //#region src/components/pagination.tsx
6
+ /**
7
+ * 1-based row range shown on the current page, e.g. "26–50 of 42" → { from: 26, to: 42 }.
8
+ */
9
+ function pageRange(page, perPage, total) {
10
+ if (total === 0) return {
11
+ from: 0,
12
+ to: 0
13
+ };
14
+ return {
15
+ from: (page - 1) * perPage + 1,
16
+ to: Math.min(page * perPage, total)
17
+ };
18
+ }
19
+ /**
20
+ * Offset-pagination controls for a list: a "Showing from–to of total" label and prev/next
21
+ * buttons. Presentational and router-agnostic — the caller wires `onPageChange` to its search
22
+ * params. Renders nothing when there's a single page.
23
+ */
24
+ function Pagination({ page, pageCount, total, perPage, onPageChange, className, ...props }) {
25
+ if (pageCount <= 1) return null;
26
+ const { from, to } = pageRange(page, perPage, total);
27
+ return /* @__PURE__ */ jsxs("div", {
28
+ className: cn("flex items-center justify-between gap-4 pt-1", className),
29
+ ...props,
30
+ children: [/* @__PURE__ */ jsxs("p", {
31
+ className: "text-muted-foreground text-sm tabular-nums",
32
+ children: [
33
+ "Showing ",
34
+ from,
35
+ "–",
36
+ to,
37
+ " of ",
38
+ total
39
+ ]
40
+ }), /* @__PURE__ */ jsxs("div", {
41
+ className: "flex items-center gap-2",
42
+ children: [/* @__PURE__ */ jsx(Button, {
43
+ variant: "secondary",
44
+ size: "sm",
45
+ "aria-label": "Previous page",
46
+ disabled: page <= 1,
47
+ onClick: () => onPageChange(page - 1),
48
+ children: /* @__PURE__ */ jsx(ChevronLeftIcon, {})
49
+ }), /* @__PURE__ */ jsx(Button, {
50
+ variant: "secondary",
51
+ size: "sm",
52
+ "aria-label": "Next page",
53
+ disabled: page >= pageCount,
54
+ onClick: () => onPageChange(page + 1),
55
+ children: /* @__PURE__ */ jsx(ChevronRightIcon, {})
56
+ })]
57
+ })]
58
+ });
59
+ }
60
+ //#endregion
61
+ export { Pagination };
62
+
63
+ //# sourceMappingURL=pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.js","names":[],"sources":["../../src/components/pagination.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\"\nimport { Button } from \"~/components/button\"\nimport { ChevronLeftIcon, ChevronRightIcon } from \"~/lib/icons\"\nimport { cn } from \"~/lib/variants\"\n\n/**\n * 1-based row range shown on the current page, e.g. \"26–50 of 42\" → { from: 26, to: 42 }.\n */\nfunction pageRange(page: number, perPage: number, total: number) {\n if (total === 0) return { from: 0, to: 0 }\n return { from: (page - 1) * perPage + 1, to: Math.min(page * perPage, total) }\n}\n\ntype PaginationProps = ComponentProps<\"div\"> & {\n page: number\n pageCount: number\n total: number\n perPage: number\n onPageChange: (page: number) => void\n}\n\n/**\n * Offset-pagination controls for a list: a \"Showing from–to of total\" label and prev/next\n * buttons. Presentational and router-agnostic — the caller wires `onPageChange` to its search\n * params. Renders nothing when there's a single page.\n */\nexport function Pagination({\n page,\n pageCount,\n total,\n perPage,\n onPageChange,\n className,\n ...props\n}: PaginationProps) {\n if (pageCount <= 1) return null\n\n const { from, to } = pageRange(page, perPage, total)\n\n return (\n <div className={cn(\"flex items-center justify-between gap-4 pt-1\", className)} {...props}>\n <p className=\"text-muted-foreground text-sm tabular-nums\">\n Showing {from}–{to} of {total}\n </p>\n\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"secondary\"\n size=\"sm\"\n aria-label=\"Previous page\"\n disabled={page <= 1}\n onClick={() => onPageChange(page - 1)}\n >\n <ChevronLeftIcon />\n </Button>\n\n <Button\n variant=\"secondary\"\n size=\"sm\"\n aria-label=\"Next page\"\n disabled={page >= pageCount}\n onClick={() => onPageChange(page + 1)}\n >\n <ChevronRightIcon />\n </Button>\n </div>\n </div>\n )\n}\n"],"mappings":";;;;;;;;AAQA,SAAS,UAAU,MAAc,SAAiB,OAAe;CAC/D,IAAI,UAAU,GAAG,OAAO;EAAE,MAAM;EAAG,IAAI;CAAE;CACzC,OAAO;EAAE,OAAO,OAAO,KAAK,UAAU;EAAG,IAAI,KAAK,IAAI,OAAO,SAAS,KAAK;CAAE;AAC/E;;;;;;AAeA,SAAgB,WAAW,EACzB,MACA,WACA,OACA,SACA,cACA,WACA,GAAG,SACe;CAClB,IAAI,aAAa,GAAG,OAAO;CAE3B,MAAM,EAAE,MAAM,OAAO,UAAU,MAAM,SAAS,KAAK;CAEnD,OACE,qBAAC,OAAD;EAAK,WAAW,GAAG,gDAAgD,SAAS;EAAG,GAAI;EAAnF,UAAA,CACE,qBAAC,KAAD;GAAG,WAAU;GAAb,UAAA;IAA0D;IAC/C;IAAK;IAAE;IAAG;IAAK;GACvB;EAEH,CAAA,GAAA,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,QAAD;IACE,SAAQ;IACR,MAAK;IACL,cAAW;IACX,UAAU,QAAQ;IAClB,eAAe,aAAa,OAAO,CAAC;IAEpC,UAAA,oBAAC,iBAAD,CAAkB,CAAA;GACZ,CAAA,GAER,oBAAC,QAAD;IACE,SAAQ;IACR,MAAK;IACL,cAAW;IACX,UAAU,QAAQ;IAClB,eAAe,aAAa,OAAO,CAAC;IAEpC,UAAA,oBAAC,kBAAD,CAAmB,CAAA;GACb,CAAA,CACL;EACF,CAAA,CAAA;;AAET"}
@@ -0,0 +1,8 @@
1
+ import { Popover as Popover$1 } from "@base-ui/react/popover";
2
+ //#region src/components/popover.d.ts
3
+ declare const Popover: typeof Popover$1.Root;
4
+ declare const PopoverTrigger: Popover$1.Trigger;
5
+ declare function PopoverContent({ className, align, side, sideOffset, ...props }: Popover$1.Popup.Props & Pick<Popover$1.Positioner.Props, "align" | "side" | "sideOffset">): import("react").JSX.Element;
6
+ //#endregion
7
+ export { Popover, PopoverContent, PopoverTrigger };
8
+ //# sourceMappingURL=popover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"popover.d.ts","names":[],"sources":["../../src/components/popover.tsx"],"mappings":";;cAMM,gBAAO,UAAA;cACP,gBAAc,UAAA;iBAEX,iBACP,WACA,OACA,MACA,eACG,SACF,UAAiB,MAAM,QACxB,KAAK,UAAiB,WAAW,0DAAuC,IAAA"}
@@ -0,0 +1,24 @@
1
+ "use client";
2
+ import { cn } from "../lib/variants.js";
3
+ import { popoverAnimationClasses } from "../lib/classes.js";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import { Popover as Popover$1 } from "@base-ui/react/popover";
6
+ //#region src/components/popover.tsx
7
+ const Popover = Popover$1.Root;
8
+ const PopoverTrigger = Popover$1.Trigger;
9
+ function PopoverContent({ className, align = "center", side, sideOffset = 4, ...props }) {
10
+ return /* @__PURE__ */ jsx(Popover$1.Portal, { children: /* @__PURE__ */ jsx(Popover$1.Positioner, {
11
+ align,
12
+ side,
13
+ sideOffset,
14
+ className: "isolate z-50",
15
+ children: /* @__PURE__ */ jsx(Popover$1.Popup, {
16
+ className: cn("min-w-72 w-(--anchor-width) rounded-md border bg-popover p-4 text-popover-foreground shadow-md backdrop-blur-xs outline-hidden", popoverAnimationClasses, className),
17
+ ...props
18
+ })
19
+ }) });
20
+ }
21
+ //#endregion
22
+ export { Popover, PopoverContent, PopoverTrigger };
23
+
24
+ //# sourceMappingURL=popover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"popover.js","names":["PopoverPrimitive"],"sources":["../../src/components/popover.tsx"],"sourcesContent":["\"use client\"\n\nimport { Popover as PopoverPrimitive } from \"@base-ui/react/popover\"\nimport { popoverAnimationClasses } from \"~/lib/classes\"\nimport { cn } from \"~/lib/variants\"\n\nconst Popover = PopoverPrimitive.Root\nconst PopoverTrigger = PopoverPrimitive.Trigger\n\nfunction PopoverContent({\n className,\n align = \"center\",\n side,\n sideOffset = 4,\n ...props\n}: PopoverPrimitive.Popup.Props &\n Pick<PopoverPrimitive.Positioner.Props, \"align\" | \"side\" | \"sideOffset\">) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Positioner\n align={align}\n side={side}\n sideOffset={sideOffset}\n className=\"isolate z-50\"\n >\n <PopoverPrimitive.Popup\n className={cn(\n \"min-w-72 w-(--anchor-width) rounded-md border bg-popover p-4 text-popover-foreground shadow-md backdrop-blur-xs outline-hidden\",\n popoverAnimationClasses,\n className,\n )}\n {...props}\n />\n </PopoverPrimitive.Positioner>\n </PopoverPrimitive.Portal>\n )\n}\n\nexport { Popover, PopoverContent, PopoverTrigger }\n"],"mappings":";;;;;;AAMA,MAAM,UAAUA,UAAiB;AACjC,MAAM,iBAAiBA,UAAiB;AAExC,SAAS,eAAe,EACtB,WACA,QAAQ,UACR,MACA,aAAa,GACb,GAAG,SAEuE;CAC1E,OACE,oBAACA,UAAiB,QAAlB,EAAA,UACE,oBAACA,UAAiB,YAAlB;EACS;EACD;EACM;EACZ,WAAU;EAEV,UAAA,oBAACA,UAAiB,OAAlB;GACE,WAAW,GACT,kIACA,yBACA,SACF;GACA,GAAI;EACL,CAAA;CAC0B,CAAA,EACN,CAAA;AAE7B"}
@@ -0,0 +1,14 @@
1
+ import { Input } from "./input.js";
2
+ import { ComponentProps } from "react";
3
+ //#region src/components/search-input.d.ts
4
+ type SearchInputProps = Omit<ComponentProps<typeof Input>, "value" | "onChange"> & {
5
+ value: string;
6
+ onValueChange: (value: string) => void;
7
+ };
8
+ /**
9
+ * Text input with a leading search icon and a clear button once it holds a value. Labels and
10
+ * placeholders come from the caller.
11
+ */
12
+ export declare function SearchInput({ value, onValueChange, className, ...props }: SearchInputProps): import("react").JSX.Element;
13
+ //#endregion
14
+ //# sourceMappingURL=search-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-input.d.ts","names":[],"sources":["../../src/components/search-input.tsx"],"mappings":";;;KAMK,mBAAmB,KAAK,sBAAsB;EACjD;EACA,gBAAgB;;;;;;wBAOF,cAAc,OAAO,eAAe,cAAc,SAAS,mCAAgB,IAAA"}