@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,36 @@
1
+ import { cn } from "../lib/variants.js";
2
+ import { SearchIcon, XIcon } from "../lib/icons.js";
3
+ import { Button } from "./button.js";
4
+ import { Input } from "./input.js";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ //#region src/components/search-input.tsx
7
+ /**
8
+ * Text input with a leading search icon and a clear button once it holds a value. Labels and
9
+ * placeholders come from the caller.
10
+ */
11
+ function SearchInput({ value, onValueChange, className, ...props }) {
12
+ return /* @__PURE__ */ jsxs("div", {
13
+ className: cn("relative", className),
14
+ children: [
15
+ /* @__PURE__ */ jsx(SearchIcon, { className: "pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-muted-foreground" }),
16
+ /* @__PURE__ */ jsx(Input, {
17
+ value,
18
+ className: "px-9",
19
+ onChange: (event) => onValueChange(event.target.value),
20
+ ...props
21
+ }),
22
+ value.length > 0 && /* @__PURE__ */ jsx(Button, {
23
+ variant: "ghost",
24
+ size: "sm",
25
+ "aria-label": "Clear search",
26
+ prefix: /* @__PURE__ */ jsx(XIcon, {}),
27
+ className: "absolute top-1/2 right-1 -translate-y-1/2",
28
+ onClick: () => onValueChange("")
29
+ })
30
+ ]
31
+ });
32
+ }
33
+ //#endregion
34
+ export { SearchInput };
35
+
36
+ //# sourceMappingURL=search-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-input.js","names":[],"sources":["../../src/components/search-input.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\"\nimport { Button } from \"~/components/button\"\nimport { Input } from \"~/components/input\"\nimport { SearchIcon, XIcon } from \"~/lib/icons\"\nimport { cn } from \"~/lib/variants\"\n\ntype SearchInputProps = Omit<ComponentProps<typeof Input>, \"value\" | \"onChange\"> & {\n value: string\n onValueChange: (value: string) => void\n}\n\n/**\n * Text input with a leading search icon and a clear button once it holds a value. Labels and\n * placeholders come from the caller.\n */\nexport function SearchInput({ value, onValueChange, className, ...props }: SearchInputProps) {\n return (\n <div className={cn(\"relative\", className)}>\n <SearchIcon className=\"pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-muted-foreground\" />\n\n <Input\n value={value}\n className=\"px-9\"\n onChange={event => onValueChange(event.target.value)}\n {...props}\n />\n\n {value.length > 0 && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Clear search\"\n prefix={<XIcon />}\n className=\"absolute top-1/2 right-1 -translate-y-1/2\"\n onClick={() => onValueChange(\"\")}\n />\n )}\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;AAeA,SAAgB,YAAY,EAAE,OAAO,eAAe,WAAW,GAAG,SAA2B;CAC3F,OACE,qBAAC,OAAD;EAAK,WAAW,GAAG,YAAY,SAAS;EAAxC,UAAA;GACE,oBAAC,YAAD,EAAY,WAAU,4FAA6F,CAAA;GAEnH,oBAAC,OAAD;IACS;IACP,WAAU;IACV,WAAU,UAAS,cAAc,MAAM,OAAO,KAAK;IACnD,GAAI;GACL,CAAA;GAEA,MAAM,SAAS,KACd,oBAAC,QAAD;IACE,SAAQ;IACR,MAAK;IACL,cAAW;IACX,QAAQ,oBAAC,OAAD,CAAQ,CAAA;IAChB,WAAU;IACV,eAAe,cAAc,EAAE;GAChC,CAAA;EAEA;;AAET"}
@@ -0,0 +1,107 @@
1
+ import { VariantProps } from "../lib/variants.js";
2
+ import { Stack } from "./stack.js";
3
+ import { HeadingProps } from "./heading.js";
4
+ import { useRender } from "@base-ui/react/use-render";
5
+ import { ComponentProps, ReactNode } from "react";
6
+ //#region src/components/section-header.d.ts
7
+ declare const sectionHeaderVariants: import("tailwind-variants").TVReturnType<{
8
+ alignment: {
9
+ left: "justify-between text-start";
10
+ center: "justify-center text-center";
11
+ };
12
+ size: {
13
+ page: "gap-y-3 gap-x-6 lg:gap-x-12";
14
+ card: "gap-y-2 gap-x-6";
15
+ panel: "gap-y-2 gap-x-6";
16
+ hero: "gap-y-3 gap-x-6 lg:gap-x-12";
17
+ };
18
+ wrap: {
19
+ true: "flex-wrap";
20
+ false: "flex-nowrap";
21
+ };
22
+ }, undefined, "flex items-center w-full min-w-0", {
23
+ alignment: {
24
+ left: "justify-between text-start";
25
+ center: "justify-center text-center";
26
+ };
27
+ size: {
28
+ page: "gap-y-3 gap-x-6 lg:gap-x-12";
29
+ card: "gap-y-2 gap-x-6";
30
+ panel: "gap-y-2 gap-x-6";
31
+ hero: "gap-y-3 gap-x-6 lg:gap-x-12";
32
+ };
33
+ wrap: {
34
+ true: "flex-wrap";
35
+ false: "flex-nowrap";
36
+ };
37
+ }, undefined, import("tailwind-variants").TVReturnTypeLike<{
38
+ alignment: {
39
+ left: "justify-between text-start";
40
+ center: "justify-center text-center";
41
+ };
42
+ size: {
43
+ page: "gap-y-3 gap-x-6 lg:gap-x-12";
44
+ card: "gap-y-2 gap-x-6";
45
+ panel: "gap-y-2 gap-x-6";
46
+ hero: "gap-y-3 gap-x-6 lg:gap-x-12";
47
+ };
48
+ wrap: {
49
+ true: "flex-wrap";
50
+ false: "flex-nowrap";
51
+ };
52
+ }, undefined>>;
53
+ type SectionHeaderProps = Omit<useRender.ComponentProps<"div">, "title"> & Omit<VariantProps<typeof sectionHeaderVariants>, "wrap"> & {
54
+ /**
55
+ * Keep the title block and the actions on one line instead of wrapping them.
56
+ */
57
+ wrap?: boolean;
58
+ /**
59
+ * Title block. Given any of `title`/`description`/`leading`/`actions`, the header renders
60
+ * its own `SectionHeaderBody` (empty if there is nothing but actions, so they still sit right);
61
+ * leave them all out to compose the body by hand, e.g. an entity header with dot-joined
62
+ * meta or the dashboard greeting.
63
+ */
64
+ title?: ReactNode;
65
+ description?: ReactNode;
66
+ actions?: ReactNode;
67
+ /**
68
+ * Leading visual beside the title, e.g. an entity avatar.
69
+ */
70
+ leading?: ReactNode;
71
+ };
72
+ /**
73
+ * The one header for every surface in the app: pages, cards, list panels, dialogs and settings
74
+ * sections. Pass `title`/`description`/`actions` for the standard block, or compose
75
+ * `SectionHeaderBody` + `SectionHeaderActions` as children when the content is bespoke.
76
+ */
77
+ declare function SectionHeader({ className, alignment, size, wrap, title, description, actions, leading, children, render, ...props }: SectionHeaderProps): import("react").JSX.Element;
78
+ /**
79
+ * The page title. Its visual size and semantic level both follow the header's `size`, so a
80
+ * page heading stays the route's single `<h1>` while cards and panels render `<h2>`s. Pass
81
+ * `size`/`as` to override either one on its own.
82
+ */
83
+ declare function SectionHeaderTitle({ size, as, ...props }: HeadingProps): import("react").JSX.Element;
84
+ type SectionHeaderBodyProps = ComponentProps<"div"> & {
85
+ /**
86
+ * Leading visual, e.g. an entity avatar.
87
+ */
88
+ leading?: ReactNode;
89
+ };
90
+ /**
91
+ * The one title block for every header in the app (pages, cards, dialogs, settings sections):
92
+ * an optional leading visual beside a column of `SectionHeaderTitle` + `SectionHeaderDescription`. Change the
93
+ * spacing here and it changes everywhere.
94
+ */
95
+ declare function SectionHeaderBody({ leading, children, className, ...props }: SectionHeaderBodyProps): import("react").JSX.Element;
96
+ /**
97
+ * The muted line under a title. Wraps by default; pass `truncate` for one-line entity meta.
98
+ */
99
+ declare function SectionHeaderDescription({ className, ...props }: ComponentProps<"p">): import("react").JSX.Element;
100
+ /**
101
+ * Right-aligned actions. Stops shrinking when the header is `wrap={false}`, so a long title
102
+ * truncates instead of squeezing the buttons.
103
+ */
104
+ declare function SectionHeaderActions({ className, ...props }: ComponentProps<typeof Stack>): import("react").JSX.Element;
105
+ //#endregion
106
+ export { SectionHeader, SectionHeaderActions, SectionHeaderBody, SectionHeaderDescription, SectionHeaderTitle };
107
+ //# sourceMappingURL=section-header.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"section-header.d.ts","names":[],"sources":["../../src/components/section-header.tsx"],"mappings":";;;;;;cAOM,mDAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA8CtB,qBAAqB,KAAK,UAAU,kCACvC,KAAK,oBAAoB;;;;EAIvB;;;;;;;EAOA,QAAQ;EACR,cAAc;EACd,UAAU;;;;EAIV,UAAU;;;;;;;iBAQL,gBACP,WACA,WACA,MACA,MACA,OACA,aACA,SACA,SACA,UACA,WACG,SACF,qCAAkB,IAAA;;;;;;iBAmCZ,qBAAqB,MAAM,OAAO,SAAS,+BAAY,IAAA;KAM3D,yBAAyB;;;;EAI5B,UAAU;;;;;;;iBAQH,oBAAoB,SAAS,UAAU,cAAc,SAAS,yCAAsB,IAAA;;;;iBAYpF,2BAA2B,cAAc,SAAS,sCAAmB,IAAA;;;;;iBAQrE,uBAAuB,cAAc,SAAS,sBAAsB,yBAAM,IAAA"}
@@ -0,0 +1,147 @@
1
+ import { cn, variants } from "../lib/variants.js";
2
+ import { Stack } from "./stack.js";
3
+ import { Heading } from "./heading.js";
4
+ import { descriptionClasses } from "../lib/classes.js";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ import { useRender } from "@base-ui/react/use-render";
7
+ import { createContext, use } from "react";
8
+ //#region src/components/section-header.tsx
9
+ const sectionHeaderVariants = variants({
10
+ base: "flex items-center w-full min-w-0",
11
+ variants: {
12
+ alignment: {
13
+ left: "justify-between text-start",
14
+ center: "justify-center text-center"
15
+ },
16
+ size: {
17
+ page: "gap-y-3 gap-x-6 lg:gap-x-12",
18
+ card: "gap-y-2 gap-x-6",
19
+ panel: "gap-y-2 gap-x-6",
20
+ hero: "gap-y-3 gap-x-6 lg:gap-x-12"
21
+ },
22
+ wrap: {
23
+ true: "flex-wrap",
24
+ false: "flex-nowrap"
25
+ }
26
+ },
27
+ defaultVariants: {
28
+ alignment: "left",
29
+ wrap: true
30
+ }
31
+ });
32
+ /**
33
+ * The title each header scale gets, alongside the spacing the variant above gives it: `page`
34
+ * for a route heading, `card` for a standalone card, `panel` for a dashboard or list panel,
35
+ * `hero` for the centered auth and callback screens. The `as` entry keeps the heading outline
36
+ * intact — one `<h1>` per route, `<h2>` for everything nested inside it.
37
+ */
38
+ const sectionHeaderTitles = {
39
+ page: {
40
+ size: "h3",
41
+ as: "h1"
42
+ },
43
+ card: {
44
+ size: "h4",
45
+ as: "h2"
46
+ },
47
+ panel: {
48
+ size: "h5",
49
+ as: "h2"
50
+ },
51
+ hero: {
52
+ size: "h2",
53
+ as: "h1"
54
+ }
55
+ };
56
+ const SectionHeaderContext = createContext({
57
+ size: "page",
58
+ wrap: true
59
+ });
60
+ /**
61
+ * The one header for every surface in the app: pages, cards, list panels, dialogs and settings
62
+ * sections. Pass `title`/`description`/`actions` for the standard block, or compose
63
+ * `SectionHeaderBody` + `SectionHeaderActions` as children when the content is bespoke.
64
+ */
65
+ function SectionHeader({ className, alignment = "left", size = "page", wrap = true, title, description, actions, leading, children, render, ...props }) {
66
+ const element = useRender({
67
+ render,
68
+ defaultTagName: "div",
69
+ props: {
70
+ className: cn(sectionHeaderVariants({
71
+ alignment,
72
+ size,
73
+ wrap,
74
+ className
75
+ })),
76
+ children: /* @__PURE__ */ jsxs(Fragment, { children: [
77
+ (title || description || leading || actions) && /* @__PURE__ */ jsxs(SectionHeaderBody, {
78
+ leading,
79
+ className: cn(alignment === "center" && "justify-center"),
80
+ children: [title && /* @__PURE__ */ jsx(SectionHeaderTitle, { children: title }), description && /* @__PURE__ */ jsx(SectionHeaderDescription, { children: description })]
81
+ }),
82
+ actions && /* @__PURE__ */ jsx(SectionHeaderActions, { children: actions }),
83
+ children
84
+ ] }),
85
+ ...props
86
+ }
87
+ });
88
+ return /* @__PURE__ */ jsx(SectionHeaderContext, {
89
+ value: {
90
+ size,
91
+ wrap
92
+ },
93
+ children: element
94
+ });
95
+ }
96
+ /**
97
+ * The page title. Its visual size and semantic level both follow the header's `size`, so a
98
+ * page heading stays the route's single `<h1>` while cards and panels render `<h2>`s. Pass
99
+ * `size`/`as` to override either one on its own.
100
+ */
101
+ function SectionHeaderTitle({ size, as, ...props }) {
102
+ const preset = sectionHeaderTitles[use(SectionHeaderContext).size];
103
+ return /* @__PURE__ */ jsx(Heading, {
104
+ size: size ?? preset.size,
105
+ as: as ?? preset.as,
106
+ ...props
107
+ });
108
+ }
109
+ /**
110
+ * The one title block for every header in the app (pages, cards, dialogs, settings sections):
111
+ * an optional leading visual beside a column of `SectionHeaderTitle` + `SectionHeaderDescription`. Change the
112
+ * spacing here and it changes everywhere.
113
+ */
114
+ function SectionHeaderBody({ leading, children, className, ...props }) {
115
+ return /* @__PURE__ */ jsxs("div", {
116
+ className: cn("flex min-w-0 flex-1 items-center gap-3", className),
117
+ ...props,
118
+ children: [leading, /* @__PURE__ */ jsx("div", {
119
+ className: "flex min-w-0 flex-col gap-1.5",
120
+ children
121
+ })]
122
+ });
123
+ }
124
+ /**
125
+ * The muted line under a title. Wraps by default; pass `truncate` for one-line entity meta.
126
+ */
127
+ function SectionHeaderDescription({ className, ...props }) {
128
+ return /* @__PURE__ */ jsx("p", {
129
+ className: cn(descriptionClasses, className),
130
+ ...props
131
+ });
132
+ }
133
+ /**
134
+ * Right-aligned actions. Stops shrinking when the header is `wrap={false}`, so a long title
135
+ * truncates instead of squeezing the buttons.
136
+ */
137
+ function SectionHeaderActions({ className, ...props }) {
138
+ const { wrap } = use(SectionHeaderContext);
139
+ return /* @__PURE__ */ jsx(Stack, {
140
+ className: cn("-my-0.5", !wrap && "shrink-0", className),
141
+ ...props
142
+ });
143
+ }
144
+ //#endregion
145
+ export { SectionHeader, SectionHeaderActions, SectionHeaderBody, SectionHeaderDescription, SectionHeaderTitle };
146
+
147
+ //# sourceMappingURL=section-header.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"section-header.js","names":[],"sources":["../../src/components/section-header.tsx"],"sourcesContent":["import { useRender } from \"@base-ui/react/use-render\"\nimport { type ComponentProps, createContext, type ReactNode, use } from \"react\"\nimport { Heading, type HeadingProps } from \"~/components/heading\"\nimport { Stack } from \"~/components/stack\"\nimport { descriptionClasses } from \"~/lib/classes\"\nimport { variants, cn, type VariantProps } from \"~/lib/variants\"\n\nconst sectionHeaderVariants = variants({\n base: \"flex items-center w-full min-w-0\",\n\n variants: {\n alignment: {\n left: \"justify-between text-start\",\n center: \"justify-center text-center\",\n },\n size: {\n page: \"gap-y-3 gap-x-6 lg:gap-x-12\",\n card: \"gap-y-2 gap-x-6\",\n panel: \"gap-y-2 gap-x-6\",\n hero: \"gap-y-3 gap-x-6 lg:gap-x-12\",\n },\n wrap: {\n true: \"flex-wrap\",\n false: \"flex-nowrap\",\n },\n },\n\n defaultVariants: {\n alignment: \"left\",\n wrap: true,\n },\n})\n\ntype SectionHeaderSize = NonNullable<VariantProps<typeof sectionHeaderVariants>[\"size\"]>\n\n/**\n * The title each header scale gets, alongside the spacing the variant above gives it: `page`\n * for a route heading, `card` for a standalone card, `panel` for a dashboard or list panel,\n * `hero` for the centered auth and callback screens. The `as` entry keeps the heading outline\n * intact — one `<h1>` per route, `<h2>` for everything nested inside it.\n */\nconst sectionHeaderTitles = {\n page: { size: \"h3\", as: \"h1\" },\n card: { size: \"h4\", as: \"h2\" },\n panel: { size: \"h5\", as: \"h2\" },\n hero: { size: \"h2\", as: \"h1\" },\n} as const satisfies Record<SectionHeaderSize, { size: HeadingProps[\"size\"]; as: string }>\n\nconst SectionHeaderContext = createContext<{ size: SectionHeaderSize; wrap: boolean }>({\n size: \"page\",\n wrap: true,\n})\n\ntype SectionHeaderProps = Omit<useRender.ComponentProps<\"div\">, \"title\"> &\n Omit<VariantProps<typeof sectionHeaderVariants>, \"wrap\"> & {\n /**\n * Keep the title block and the actions on one line instead of wrapping them.\n */\n wrap?: boolean\n /**\n * Title block. Given any of `title`/`description`/`leading`/`actions`, the header renders\n * its own `SectionHeaderBody` (empty if there is nothing but actions, so they still sit right);\n * leave them all out to compose the body by hand, e.g. an entity header with dot-joined\n * meta or the dashboard greeting.\n */\n title?: ReactNode\n description?: ReactNode\n actions?: ReactNode\n /**\n * Leading visual beside the title, e.g. an entity avatar.\n */\n leading?: ReactNode\n }\n\n/**\n * The one header for every surface in the app: pages, cards, list panels, dialogs and settings\n * sections. Pass `title`/`description`/`actions` for the standard block, or compose\n * `SectionHeaderBody` + `SectionHeaderActions` as children when the content is bespoke.\n */\nfunction SectionHeader({\n className,\n alignment = \"left\",\n size = \"page\",\n wrap = true,\n title,\n description,\n actions,\n leading,\n children,\n render,\n ...props\n}: SectionHeaderProps) {\n const element = useRender({\n render,\n defaultTagName: \"div\",\n props: {\n className: cn(sectionHeaderVariants({ alignment, size, wrap, className })),\n children: (\n <>\n {(title || description || leading || actions) && (\n <SectionHeaderBody\n leading={leading}\n className={cn(alignment === \"center\" && \"justify-center\")}\n >\n {title && <SectionHeaderTitle>{title}</SectionHeaderTitle>}\n {description && <SectionHeaderDescription>{description}</SectionHeaderDescription>}\n </SectionHeaderBody>\n )}\n\n {actions && <SectionHeaderActions>{actions}</SectionHeaderActions>}\n\n {children}\n </>\n ),\n ...props,\n },\n })\n\n return <SectionHeaderContext value={{ size, wrap }}>{element}</SectionHeaderContext>\n}\n\n/**\n * The page title. Its visual size and semantic level both follow the header's `size`, so a\n * page heading stays the route's single `<h1>` while cards and panels render `<h2>`s. Pass\n * `size`/`as` to override either one on its own.\n */\nfunction SectionHeaderTitle({ size, as, ...props }: HeadingProps) {\n const preset = sectionHeaderTitles[use(SectionHeaderContext).size]\n\n return <Heading size={size ?? preset.size} as={as ?? preset.as} {...props} />\n}\n\ntype SectionHeaderBodyProps = ComponentProps<\"div\"> & {\n /**\n * Leading visual, e.g. an entity avatar.\n */\n leading?: ReactNode\n}\n\n/**\n * The one title block for every header in the app (pages, cards, dialogs, settings sections):\n * an optional leading visual beside a column of `SectionHeaderTitle` + `SectionHeaderDescription`. Change the\n * spacing here and it changes everywhere.\n */\nfunction SectionHeaderBody({ leading, children, className, ...props }: SectionHeaderBodyProps) {\n return (\n <div className={cn(\"flex min-w-0 flex-1 items-center gap-3\", className)} {...props}>\n {leading}\n <div className=\"flex min-w-0 flex-col gap-1.5\">{children}</div>\n </div>\n )\n}\n\n/**\n * The muted line under a title. Wraps by default; pass `truncate` for one-line entity meta.\n */\nfunction SectionHeaderDescription({ className, ...props }: ComponentProps<\"p\">) {\n return <p className={cn(descriptionClasses, className)} {...props} />\n}\n\n/**\n * Right-aligned actions. Stops shrinking when the header is `wrap={false}`, so a long title\n * truncates instead of squeezing the buttons.\n */\nfunction SectionHeaderActions({ className, ...props }: ComponentProps<typeof Stack>) {\n const { wrap } = use(SectionHeaderContext)\n\n return <Stack className={cn(\"-my-0.5\", !wrap && \"shrink-0\", className)} {...props} />\n}\n\nexport {\n SectionHeader,\n SectionHeaderTitle,\n SectionHeaderBody,\n SectionHeaderDescription,\n SectionHeaderActions,\n}\n"],"mappings":";;;;;;;;AAOA,MAAM,wBAAwB,SAAS;CACrC,MAAM;CAEN,UAAU;EACR,WAAW;GACT,MAAM;GACN,QAAQ;EACV;EACA,MAAM;GACJ,MAAM;GACN,MAAM;GACN,OAAO;GACP,MAAM;EACR;EACA,MAAM;GACJ,MAAM;GACN,OAAO;EACT;CACF;CAEA,iBAAiB;EACf,WAAW;EACX,MAAM;CACR;AACF,CAAC;;;;;;;AAUD,MAAM,sBAAsB;CAC1B,MAAM;EAAE,MAAM;EAAM,IAAI;CAAK;CAC7B,MAAM;EAAE,MAAM;EAAM,IAAI;CAAK;CAC7B,OAAO;EAAE,MAAM;EAAM,IAAI;CAAK;CAC9B,MAAM;EAAE,MAAM;EAAM,IAAI;CAAK;AAC/B;AAEA,MAAM,uBAAuB,cAA0D;CACrF,MAAM;CACN,MAAM;AACR,CAAC;;;;;;AA4BD,SAAS,cAAc,EACrB,WACA,YAAY,QACZ,OAAO,QACP,OAAO,MACP,OACA,aACA,SACA,SACA,UACA,QACA,GAAG,SACkB;CACrB,MAAM,UAAU,UAAU;EACxB;EACA,gBAAgB;EAChB,OAAO;GACL,WAAW,GAAG,sBAAsB;IAAE;IAAW;IAAM;IAAM;GAAU,CAAC,CAAC;GACzE,UACE,qBAAA,UAAA,EAAA,UAAA;KACI,SAAS,eAAe,WAAW,YACnC,qBAAC,mBAAD;KACW;KACT,WAAW,GAAG,cAAc,YAAY,gBAAgB;KAF1D,UAAA,CAIG,SAAS,oBAAC,oBAAD,EAAA,UAAqB,MAA0B,CAAA,GACxD,eAAe,oBAAC,0BAAD,EAAA,UAA2B,YAAsC,CAAA,CAChE;;IAGpB,WAAW,oBAAC,sBAAD,EAAA,UAAuB,QAA8B,CAAA;IAEhE;GACD,EAAA,CAAA;GAEJ,GAAG;EACL;CACF,CAAC;CAED,OAAO,oBAAC,sBAAD;EAAsB,OAAO;GAAE;GAAM;EAAK;EAAI,UAAA;CAA8B,CAAA;AACrF;;;;;;AAOA,SAAS,mBAAmB,EAAE,MAAM,IAAI,GAAG,SAAuB;CAChE,MAAM,SAAS,oBAAoB,IAAI,oBAAoB,CAAC,CAAC;CAE7D,OAAO,oBAAC,SAAD;EAAS,MAAM,QAAQ,OAAO;EAAM,IAAI,MAAM,OAAO;EAAI,GAAI;CAAQ,CAAA;AAC9E;;;;;;AAcA,SAAS,kBAAkB,EAAE,SAAS,UAAU,WAAW,GAAG,SAAiC;CAC7F,OACE,qBAAC,OAAD;EAAK,WAAW,GAAG,0CAA0C,SAAS;EAAG,GAAI;EAA7E,UAAA,CACG,SACD,oBAAC,OAAD;GAAK,WAAU;GAAiC;EAAc,CAAA,CAC3D;;AAET;;;;AAKA,SAAS,yBAAyB,EAAE,WAAW,GAAG,SAA8B;CAC9E,OAAO,oBAAC,KAAD;EAAG,WAAW,GAAG,oBAAoB,SAAS;EAAG,GAAI;CAAQ,CAAA;AACtE;;;;;AAMA,SAAS,qBAAqB,EAAE,WAAW,GAAG,SAAuC;CACnF,MAAM,EAAE,SAAS,IAAI,oBAAoB;CAEzC,OAAO,oBAAC,OAAD;EAAO,WAAW,GAAG,WAAW,CAAC,QAAQ,YAAY,SAAS;EAAG,GAAI;CAAQ,CAAA;AACtF"}
@@ -0,0 +1,17 @@
1
+ import { VariantProps } from "../lib/variants.js";
2
+ import { inputVariants } from "./input.js";
3
+ import { Select as Select$1 } from "@base-ui/react/select";
4
+ //#region src/components/select.d.ts
5
+ declare const Select: typeof Select$1.Root;
6
+ declare const SelectGroup: import("react").ForwardRefExoticComponent<Omit<import("@base-ui/react").SelectGroupProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
7
+ declare const SelectValue: import("react").ForwardRefExoticComponent<Omit<import("@base-ui/react").SelectValueProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
8
+ declare function SelectTrigger({ children, className, hover, focus, size, ...props }: Select$1.Trigger.Props & VariantProps<typeof inputVariants>): import("react").JSX.Element;
9
+ declare function SelectScrollUpButton({ className, ...props }: Select$1.ScrollUpArrow.Props): import("react").JSX.Element;
10
+ declare function SelectScrollDownButton({ className, ...props }: Select$1.ScrollDownArrow.Props): import("react").JSX.Element;
11
+ declare function SelectContent({ className, children, align, side, sideOffset, alignItemWithTrigger, ...props }: Select$1.Popup.Props & Pick<Select$1.Positioner.Props, "align" | "side" | "sideOffset" | "alignItemWithTrigger">): import("react").JSX.Element;
12
+ declare function SelectLabel({ className, ...props }: Select$1.GroupLabel.Props): import("react").JSX.Element;
13
+ declare function SelectItem({ className, children, label, ...props }: Select$1.Item.Props): import("react").JSX.Element;
14
+ declare function SelectSeparator({ className, ...props }: Select$1.Separator.Props): import("react").JSX.Element;
15
+ //#endregion
16
+ export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue };
17
+ //# sourceMappingURL=select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.d.ts","names":[],"sources":["../../src/components/select.tsx"],"mappings":";;;;cAQM,eAAM,SAAA;cACN,6BAAW,0BAAA,8BAAA,2CAAA,cAAA;cACX,6BAAW,0BAAA,8BAAA,2CAAA,cAAA;iBAER,gBACP,UACA,WACA,OACA,OACA,SACG,SACF,SAAgB,QAAQ,QAAQ,oBAAoB,iCAAc,IAAA;iBAmB5D,uBAAuB,cAAc,SAAS,SAAgB,cAAc,wBAAK,IAAA;iBAWjF,yBAAyB,cAAc,SAAS,SAAgB,gBAAgB,wBAAK,IAAA;iBAqBrF,gBACP,WACA,UACA,OACA,MACA,YACA,yBACG,SACF,SAAgB,MAAM,QACvB,KACE,SAAgB,WAAW,mFAE5B,IAAA;iBA2BM,cAAc,cAAc,SAAS,SAAgB,WAAW,wBAAK,IAAA;iBASrE,aAAa,WAAW,UAAU,UAAU,SAAS,SAAgB,KAAK,wBAAK,IAAA;iBAoB/E,kBAAkB,cAAc,SAAS,SAAgB,UAAU,wBAAK,IAAA"}
@@ -0,0 +1,94 @@
1
+ "use client";
2
+ import { cn, variants } from "../lib/variants.js";
3
+ import { CheckIcon, ChevronDownIcon, ChevronUpIcon, ChevronsUpDownIcon } from "../lib/icons.js";
4
+ import { popoverAnimationClasses } from "../lib/classes.js";
5
+ import { inputVariants } from "./input.js";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { Select as Select$1 } from "@base-ui/react/select";
8
+ //#region src/components/select.tsx
9
+ const Select = Select$1.Root;
10
+ const SelectGroup = Select$1.Group;
11
+ const SelectValue = Select$1.Value;
12
+ function SelectTrigger({ children, className, hover = true, focus = true, size, ...props }) {
13
+ return /* @__PURE__ */ jsxs(Select$1.Trigger, {
14
+ className: cn(inputVariants({
15
+ hover,
16
+ focus,
17
+ size
18
+ }), "flex items-center justify-between", className),
19
+ ...props,
20
+ children: [/* @__PURE__ */ jsx("span", {
21
+ className: "truncate",
22
+ children
23
+ }), /* @__PURE__ */ jsx(Select$1.Icon, { render: /* @__PURE__ */ jsx(ChevronsUpDownIcon, { className: "ml-1 size-4 shrink-0 opacity-50" }) })]
24
+ });
25
+ }
26
+ function SelectScrollUpButton({ className, ...props }) {
27
+ return /* @__PURE__ */ jsx(Select$1.ScrollUpArrow, {
28
+ className: cn("flex cursor-pointer items-center justify-center py-1", className),
29
+ ...props,
30
+ children: /* @__PURE__ */ jsx(ChevronUpIcon, {})
31
+ });
32
+ }
33
+ function SelectScrollDownButton({ className, ...props }) {
34
+ return /* @__PURE__ */ jsx(Select$1.ScrollDownArrow, {
35
+ className: cn("flex cursor-pointer items-center justify-center py-1", className),
36
+ ...props,
37
+ children: /* @__PURE__ */ jsx(ChevronDownIcon, {})
38
+ });
39
+ }
40
+ const selectScrollButtonVariants = variants({
41
+ base: "absolute inset-x-0 z-10 bg-background animate-in fade-in-0 duration-300",
42
+ variants: { position: {
43
+ top: "top-0 mask-b-from-0",
44
+ bottom: "bottom-0 mask-t-from-0"
45
+ } }
46
+ });
47
+ function SelectContent({ className, children, align, side, sideOffset = 4, alignItemWithTrigger = false, ...props }) {
48
+ return /* @__PURE__ */ jsx(Select$1.Portal, { children: /* @__PURE__ */ jsx(Select$1.Positioner, {
49
+ sideOffset,
50
+ align,
51
+ side,
52
+ alignItemWithTrigger,
53
+ className: "isolate z-50",
54
+ children: /* @__PURE__ */ jsxs(Select$1.Popup, {
55
+ className: cn("relative z-50 isolate max-h-(--available-height) min-w-(--anchor-width) overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md backdrop-blur-xs", !alignItemWithTrigger && popoverAnimationClasses, className),
56
+ ...props,
57
+ children: [
58
+ /* @__PURE__ */ jsx(SelectScrollUpButton, { className: selectScrollButtonVariants({ position: "top" }) }),
59
+ /* @__PURE__ */ jsx(Select$1.List, {
60
+ className: "p-1",
61
+ children
62
+ }),
63
+ /* @__PURE__ */ jsx(SelectScrollDownButton, { className: selectScrollButtonVariants({ position: "bottom" }) })
64
+ ]
65
+ })
66
+ }) });
67
+ }
68
+ function SelectLabel({ className, ...props }) {
69
+ return /* @__PURE__ */ jsx(Select$1.GroupLabel, {
70
+ className: cn("px-2 py-1.5 text-sm font-medium", className),
71
+ ...props
72
+ });
73
+ }
74
+ function SelectItem({ className, children, label, ...props }) {
75
+ return /* @__PURE__ */ jsxs(Select$1.Item, {
76
+ label: label ?? (typeof children === "string" ? children : void 0),
77
+ className: cn("relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-control text-secondary-foreground outline-none focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50", className),
78
+ ...props,
79
+ children: [/* @__PURE__ */ jsx("span", {
80
+ className: "absolute left-2 flex size-3.5 items-center justify-center",
81
+ children: /* @__PURE__ */ jsx(Select$1.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) })
82
+ }), /* @__PURE__ */ jsx(Select$1.ItemText, { children })]
83
+ });
84
+ }
85
+ function SelectSeparator({ className, ...props }) {
86
+ return /* @__PURE__ */ jsx(Select$1.Separator, {
87
+ className: cn("-mx-1 my-1 h-px bg-border", className),
88
+ ...props
89
+ });
90
+ }
91
+ //#endregion
92
+ export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue };
93
+
94
+ //# sourceMappingURL=select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.js","names":["SelectPrimitive"],"sources":["../../src/components/select.tsx"],"sourcesContent":["\"use client\"\n\nimport { Select as SelectPrimitive } from \"@base-ui/react/select\"\nimport { inputVariants } from \"~/components/input\"\nimport { popoverAnimationClasses } from \"~/lib/classes\"\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon, ChevronsUpDownIcon } from \"~/lib/icons\"\nimport { variants, cn, type VariantProps } from \"~/lib/variants\"\n\nconst Select = SelectPrimitive.Root\nconst SelectGroup = SelectPrimitive.Group\nconst SelectValue = SelectPrimitive.Value\n\nfunction SelectTrigger({\n children,\n className,\n hover = true,\n focus = true,\n size,\n ...props\n}: SelectPrimitive.Trigger.Props & VariantProps<typeof inputVariants>) {\n return (\n <SelectPrimitive.Trigger\n className={cn(\n inputVariants({ hover, focus, size }),\n \"flex items-center justify-between\",\n className,\n )}\n {...props}\n >\n <span className=\"truncate\">{children}</span>\n\n <SelectPrimitive.Icon\n render={<ChevronsUpDownIcon className=\"ml-1 size-4 shrink-0 opacity-50\" />}\n />\n </SelectPrimitive.Trigger>\n )\n}\n\nfunction SelectScrollUpButton({ className, ...props }: SelectPrimitive.ScrollUpArrow.Props) {\n return (\n <SelectPrimitive.ScrollUpArrow\n className={cn(\"flex cursor-pointer items-center justify-center py-1\", className)}\n {...props}\n >\n <ChevronUpIcon />\n </SelectPrimitive.ScrollUpArrow>\n )\n}\n\nfunction SelectScrollDownButton({ className, ...props }: SelectPrimitive.ScrollDownArrow.Props) {\n return (\n <SelectPrimitive.ScrollDownArrow\n className={cn(\"flex cursor-pointer items-center justify-center py-1\", className)}\n {...props}\n >\n <ChevronDownIcon />\n </SelectPrimitive.ScrollDownArrow>\n )\n}\n\nconst selectScrollButtonVariants = variants({\n base: \"absolute inset-x-0 z-10 bg-background animate-in fade-in-0 duration-300\",\n variants: {\n position: {\n top: \"top-0 mask-b-from-0\",\n bottom: \"bottom-0 mask-t-from-0\",\n },\n },\n})\n\nfunction SelectContent({\n className,\n children,\n align,\n side,\n sideOffset = 4,\n alignItemWithTrigger = false,\n ...props\n}: SelectPrimitive.Popup.Props &\n Pick<\n SelectPrimitive.Positioner.Props,\n \"align\" | \"side\" | \"sideOffset\" | \"alignItemWithTrigger\"\n >) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Positioner\n sideOffset={sideOffset}\n align={align}\n side={side}\n alignItemWithTrigger={alignItemWithTrigger}\n className=\"isolate z-50\"\n >\n <SelectPrimitive.Popup\n className={cn(\n \"relative z-50 isolate max-h-(--available-height) min-w-(--anchor-width) overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md backdrop-blur-xs\",\n !alignItemWithTrigger && popoverAnimationClasses,\n className,\n )}\n {...props}\n >\n <SelectScrollUpButton className={selectScrollButtonVariants({ position: \"top\" })} />\n <SelectPrimitive.List className=\"p-1\">{children}</SelectPrimitive.List>\n <SelectScrollDownButton className={selectScrollButtonVariants({ position: \"bottom\" })} />\n </SelectPrimitive.Popup>\n </SelectPrimitive.Positioner>\n </SelectPrimitive.Portal>\n )\n}\n\nfunction SelectLabel({ className, ...props }: SelectPrimitive.GroupLabel.Props) {\n return (\n <SelectPrimitive.GroupLabel\n className={cn(\"px-2 py-1.5 text-sm font-medium\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectItem({ className, children, label, ...props }: SelectPrimitive.Item.Props) {\n return (\n <SelectPrimitive.Item\n label={label ?? (typeof children === \"string\" ? children : undefined)}\n className={cn(\n \"relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-control text-secondary-foreground outline-none 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 <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n )\n}\n\nfunction SelectSeparator({ className, ...props }: SelectPrimitive.Separator.Props) {\n return (\n <SelectPrimitive.Separator className={cn(\"-mx-1 my-1 h-px bg-border\", className)} {...props} />\n )\n}\n\nexport {\n Select,\n SelectGroup,\n SelectValue,\n SelectTrigger,\n SelectContent,\n SelectLabel,\n SelectItem,\n SelectSeparator,\n SelectScrollUpButton,\n SelectScrollDownButton,\n}\n"],"mappings":";;;;;;;;AAQA,MAAM,SAASA,SAAgB;AAC/B,MAAM,cAAcA,SAAgB;AACpC,MAAM,cAAcA,SAAgB;AAEpC,SAAS,cAAc,EACrB,UACA,WACA,QAAQ,MACR,QAAQ,MACR,MACA,GAAG,SACkE;CACrE,OACE,qBAACA,SAAgB,SAAjB;EACE,WAAW,GACT,cAAc;GAAE;GAAO;GAAO;EAAK,CAAC,GACpC,qCACA,SACF;EACA,GAAI;EANN,UAAA,CAQE,oBAAC,QAAD;GAAM,WAAU;GAAY;EAAe,CAAA,GAE3C,oBAACA,SAAgB,MAAjB,EACE,QAAQ,oBAAC,oBAAD,EAAoB,WAAU,kCAAmC,CAAA,EAC1E,CAAA,CACsB;;AAE7B;AAEA,SAAS,qBAAqB,EAAE,WAAW,GAAG,SAA8C;CAC1F,OACE,oBAACA,SAAgB,eAAjB;EACE,WAAW,GAAG,wDAAwD,SAAS;EAC/E,GAAI;EAEJ,UAAA,oBAAC,eAAD,CAAgB,CAAA;CACa,CAAA;AAEnC;AAEA,SAAS,uBAAuB,EAAE,WAAW,GAAG,SAAgD;CAC9F,OACE,oBAACA,SAAgB,iBAAjB;EACE,WAAW,GAAG,wDAAwD,SAAS;EAC/E,GAAI;EAEJ,UAAA,oBAAC,iBAAD,CAAkB,CAAA;CACa,CAAA;AAErC;AAEA,MAAM,6BAA6B,SAAS;CAC1C,MAAM;CACN,UAAU,EACR,UAAU;EACR,KAAK;EACL,QAAQ;CACV,EACF;AACF,CAAC;AAED,SAAS,cAAc,EACrB,WACA,UACA,OACA,MACA,aAAa,GACb,uBAAuB,OACvB,GAAG,SAKA;CACH,OACE,oBAACA,SAAgB,QAAjB,EAAA,UACE,oBAACA,SAAgB,YAAjB;EACc;EACL;EACD;EACgB;EACtB,WAAU;EAEV,UAAA,qBAACA,SAAgB,OAAjB;GACE,WAAW,GACT,2KACA,CAAC,wBAAwB,yBACzB,SACF;GACA,GAAI;GANN,UAAA;IAQE,oBAAC,sBAAD,EAAsB,WAAW,2BAA2B,EAAE,UAAU,MAAM,CAAC,EAAI,CAAA;IACnF,oBAACA,SAAgB,MAAjB;KAAsB,WAAU;KAAO;IAA+B,CAAA;IACtE,oBAAC,wBAAD,EAAwB,WAAW,2BAA2B,EAAE,UAAU,SAAS,CAAC,EAAI,CAAA;GACnE;;CACG,CAAA,EACN,CAAA;AAE5B;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAA2C;CAC9E,OACE,oBAACA,SAAgB,YAAjB;EACE,WAAW,GAAG,mCAAmC,SAAS;EAC1D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,WAAW,EAAE,WAAW,UAAU,OAAO,GAAG,SAAqC;CACxF,OACE,qBAACA,SAAgB,MAAjB;EACE,OAAO,UAAU,OAAO,aAAa,WAAW,WAAW,KAAA;EAC3D,WAAW,GACT,wPACA,SACF;EACA,GAAI;EANN,UAAA,CAQE,oBAAC,QAAD;GAAM,WAAU;GACd,UAAA,oBAACA,SAAgB,eAAjB,EAAA,UACE,oBAAC,WAAD,EAAW,WAAU,SAAU,CAAA,EACF,CAAA;EAC3B,CAAA,GACN,oBAACA,SAAgB,UAAjB,EAA2B,SAAmC,CAAA,CAC1C;;AAE1B;AAEA,SAAS,gBAAgB,EAAE,WAAW,GAAG,SAA0C;CACjF,OACE,oBAACA,SAAgB,WAAjB;EAA2B,WAAW,GAAG,6BAA6B,SAAS;EAAG,GAAI;CAAQ,CAAA;AAElG"}
@@ -0,0 +1,5 @@
1
+ import { ComponentProps } from "react";
2
+ //#region src/components/skeleton.d.ts
3
+ export declare function Skeleton({ className, ...props }: ComponentProps<"div">): import("react").JSX.Element;
4
+ //#endregion
5
+ //# sourceMappingURL=skeleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton.d.ts","names":[],"sources":["../../src/components/skeleton.tsx"],"mappings":";;wBAGgB,WAAW,cAAc,SAAS,wCAAqB,IAAA"}
@@ -0,0 +1,13 @@
1
+ import { cn } from "../lib/variants.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region src/components/skeleton.tsx
4
+ function Skeleton({ className, ...props }) {
5
+ return /* @__PURE__ */ jsx("div", {
6
+ className: cn("animate-pulse rounded-md bg-foreground/10", className),
7
+ ...props
8
+ });
9
+ }
10
+ //#endregion
11
+ export { Skeleton };
12
+
13
+ //# sourceMappingURL=skeleton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton.js","names":[],"sources":["../../src/components/skeleton.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\"\nimport { cn } from \"~/lib/variants\"\n\nexport function Skeleton({ className, ...props }: ComponentProps<\"div\">) {\n return <div className={cn(\"animate-pulse rounded-md bg-foreground/10\", className)} {...props} />\n}\n"],"mappings":";;;AAGA,SAAgB,SAAS,EAAE,WAAW,GAAG,SAAgC;CACvE,OAAO,oBAAC,OAAD;EAAK,WAAW,GAAG,6CAA6C,SAAS;EAAG,GAAI;CAAQ,CAAA;AACjG"}
@@ -0,0 +1,54 @@
1
+ import { VariantProps } from "../lib/variants.js";
2
+ import { useRender } from "@base-ui/react/use-render";
3
+ //#region src/components/stack.d.ts
4
+ declare const stackVariants: import("tailwind-variants").TVReturnType<{
5
+ size: {
6
+ xs: "gap-1";
7
+ sm: "gap-x-2 gap-y-1";
8
+ md: "gap-x-3 gap-y-2";
9
+ lg: "gap-x-4 gap-y-3";
10
+ };
11
+ direction: {
12
+ row: "flex-row items-center place-content-start";
13
+ column: "flex-col items-start";
14
+ };
15
+ wrap: {
16
+ true: "flex-wrap";
17
+ false: "";
18
+ };
19
+ }, undefined, "flex", {
20
+ size: {
21
+ xs: "gap-1";
22
+ sm: "gap-x-2 gap-y-1";
23
+ md: "gap-x-3 gap-y-2";
24
+ lg: "gap-x-4 gap-y-3";
25
+ };
26
+ direction: {
27
+ row: "flex-row items-center place-content-start";
28
+ column: "flex-col items-start";
29
+ };
30
+ wrap: {
31
+ true: "flex-wrap";
32
+ false: "";
33
+ };
34
+ }, undefined, import("tailwind-variants").TVReturnTypeLike<{
35
+ size: {
36
+ xs: "gap-1";
37
+ sm: "gap-x-2 gap-y-1";
38
+ md: "gap-x-3 gap-y-2";
39
+ lg: "gap-x-4 gap-y-3";
40
+ };
41
+ direction: {
42
+ row: "flex-row items-center place-content-start";
43
+ column: "flex-col items-start";
44
+ };
45
+ wrap: {
46
+ true: "flex-wrap";
47
+ false: "";
48
+ };
49
+ }, undefined>>;
50
+ type StackProps = useRender.ComponentProps<"div"> & VariantProps<typeof stackVariants>;
51
+ declare function Stack({ className, render, size, direction, wrap, ...props }: StackProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
52
+ //#endregion
53
+ export { Stack };
54
+ //# sourceMappingURL=stack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack.d.ts","names":[],"sources":["../../src/components/stack.tsx"],"mappings":";;;cAGM,2CAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA2Bd,aAAa,UAAU,wBAAwB,oBAAoB;iBAE/D,QAAQ,WAAW,QAAQ,MAAM,WAAW,SAAS,SAAS,6BAAU,+CAAA"}
@@ -0,0 +1,46 @@
1
+ import { cn, variants } from "../lib/variants.js";
2
+ import { useRender } from "@base-ui/react/use-render";
3
+ //#region src/components/stack.tsx
4
+ const stackVariants = variants({
5
+ base: "flex",
6
+ variants: {
7
+ size: {
8
+ xs: "gap-1",
9
+ sm: "gap-x-2 gap-y-1",
10
+ md: "gap-x-3 gap-y-2",
11
+ lg: "gap-x-4 gap-y-3"
12
+ },
13
+ direction: {
14
+ row: "flex-row items-center place-content-start",
15
+ column: "flex-col items-start"
16
+ },
17
+ wrap: {
18
+ true: "flex-wrap",
19
+ false: ""
20
+ }
21
+ },
22
+ defaultVariants: {
23
+ size: "md",
24
+ direction: "row",
25
+ wrap: true
26
+ }
27
+ });
28
+ function Stack({ className, render, size, direction, wrap, ...props }) {
29
+ return useRender({
30
+ render,
31
+ defaultTagName: "div",
32
+ props: {
33
+ className: cn(stackVariants({
34
+ size,
35
+ direction,
36
+ wrap,
37
+ className
38
+ })),
39
+ ...props
40
+ }
41
+ });
42
+ }
43
+ //#endregion
44
+ export { Stack };
45
+
46
+ //# sourceMappingURL=stack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack.js","names":[],"sources":["../../src/components/stack.tsx"],"sourcesContent":["import { useRender } from \"@base-ui/react/use-render\"\nimport { variants, cn, type VariantProps } from \"~/lib/variants\"\n\nconst stackVariants = variants({\n base: \"flex\",\n\n variants: {\n size: {\n xs: \"gap-1\",\n sm: \"gap-x-2 gap-y-1\",\n md: \"gap-x-3 gap-y-2\",\n lg: \"gap-x-4 gap-y-3\",\n },\n direction: {\n row: \"flex-row items-center place-content-start\",\n column: \"flex-col items-start\",\n },\n wrap: {\n true: \"flex-wrap\",\n false: \"\",\n },\n },\n\n defaultVariants: {\n size: \"md\",\n direction: \"row\",\n wrap: true,\n },\n})\n\ntype StackProps = useRender.ComponentProps<\"div\"> & VariantProps<typeof stackVariants>\n\nfunction Stack({ className, render, size, direction, wrap, ...props }: StackProps) {\n return useRender({\n render,\n defaultTagName: \"div\",\n props: { className: cn(stackVariants({ size, direction, wrap, className })), ...props },\n })\n}\n\nexport { Stack }\n"],"mappings":";;;AAGA,MAAM,gBAAgB,SAAS;CAC7B,MAAM;CAEN,UAAU;EACR,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN;EACA,WAAW;GACT,KAAK;GACL,QAAQ;EACV;EACA,MAAM;GACJ,MAAM;GACN,OAAO;EACT;CACF;CAEA,iBAAiB;EACf,MAAM;EACN,WAAW;EACX,MAAM;CACR;AACF,CAAC;AAID,SAAS,MAAM,EAAE,WAAW,QAAQ,MAAM,WAAW,MAAM,GAAG,SAAqB;CACjF,OAAO,UAAU;EACf;EACA,gBAAgB;EAChB,OAAO;GAAE,WAAW,GAAG,cAAc;IAAE;IAAM;IAAW;IAAM;GAAU,CAAC,CAAC;GAAG,GAAG;EAAM;CACxF,CAAC;AACH"}
@@ -0,0 +1,38 @@
1
+ import { VariantProps } from "../lib/variants.js";
2
+ import { Format } from "@number-flow/react";
3
+ import { useRender } from "@base-ui/react/use-render";
4
+ import { ComponentProps } from "react";
5
+ //#region src/components/stat-strip.d.ts
6
+ declare const stripVariants: import("tailwind-variants").TVReturnType<{
7
+ variant: {
8
+ plain: "overflow-clip rounded-xl border bg-card shadow-xs";
9
+ track: "rounded-xl bg-background p-1.5 sm:gap-x-[13px]";
10
+ };
11
+ }, undefined, "group/strip grid grid-cols-2 gap-y-1 max-sm:[&>*:last-child:nth-child(odd)]:col-span-2 sm:flex sm:flex-wrap sm:gap-y-0", {
12
+ variant: {
13
+ plain: "overflow-clip rounded-xl border bg-card shadow-xs";
14
+ track: "rounded-xl bg-background p-1.5 sm:gap-x-[13px]";
15
+ };
16
+ }, undefined, import("tailwind-variants").TVReturnTypeLike<{
17
+ variant: {
18
+ plain: "overflow-clip rounded-xl border bg-card shadow-xs";
19
+ track: "rounded-xl bg-background p-1.5 sm:gap-x-[13px]";
20
+ };
21
+ }, undefined>>;
22
+ type StatStripProps = ComponentProps<"div"> & VariantProps<typeof stripVariants>;
23
+ declare function StatStrip({ className, variant, ...props }: StatStripProps): import("react").JSX.Element;
24
+ type StatStripItemProps = Omit<useRender.ComponentProps<"div">, "children"> & {
25
+ label: string;
26
+ value: string | number;
27
+ format?: Format;
28
+ hint?: string;
29
+ /**
30
+ * Marks the item as the one driving the panel beside it. Pass `render={<button ... />}`
31
+ * to make it selectable.
32
+ */
33
+ selected?: boolean;
34
+ };
35
+ declare function StatStripItem({ label, value, format, hint, selected, render, className, ...props }: StatStripItemProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
36
+ //#endregion
37
+ export { StatStrip, StatStripItem };
38
+ //# sourceMappingURL=stat-strip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stat-strip.d.ts","names":[],"sources":["../../src/components/stat-strip.tsx"],"mappings":";;;;;cAOM,2CAAa;;;;;;;;;;;;;;;;KAmBd,iBAAiB,wBAAwB,oBAAoB;iBAEzD,YAAY,WAAW,YAAY,SAAS,iCAAc,IAAA;KAU9D,qBAAqB,KAAK,UAAU;EACvC;EACA;EACA,SAAS;EACT;;;;;EAKA;;iBAGO,gBACP,OACA,OACA,QACA,MACA,UACA,QACA,cACG,SACF,qCAAkB,+CAAA"}