@tulipfarm/sprout 0.0.0-stage → 0.1.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 (306) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +183 -2
  3. package/dist/components/accordion.d.ts +28 -0
  4. package/dist/components/accordion.js +26 -0
  5. package/dist/components/alert-dialog.d.ts +60 -0
  6. package/dist/components/alert-dialog.js +69 -0
  7. package/dist/components/alert.d.ts +30 -0
  8. package/dist/components/alert.js +35 -0
  9. package/dist/components/aspect-ratio.d.ts +7 -0
  10. package/dist/components/aspect-ratio.js +6 -0
  11. package/dist/components/attachment.d.ts +118 -0
  12. package/dist/components/attachment.js +285 -0
  13. package/dist/components/avatar.d.ts +32 -0
  14. package/dist/components/avatar.js +73 -0
  15. package/dist/components/badge.d.ts +21 -0
  16. package/dist/components/badge.js +27 -0
  17. package/dist/components/brand-icon.d.ts +28 -0
  18. package/dist/components/brand-icon.js +78 -0
  19. package/dist/components/breadcrumb.d.ts +29 -0
  20. package/dist/components/breadcrumb.js +44 -0
  21. package/dist/components/button-group.d.ts +28 -0
  22. package/dist/components/button-group.js +36 -0
  23. package/dist/components/button.d.ts +79 -0
  24. package/dist/components/button.js +93 -0
  25. package/dist/components/calendar.d.ts +27 -0
  26. package/dist/components/calendar.js +107 -0
  27. package/dist/components/canvas.d.ts +78 -0
  28. package/dist/components/canvas.js +180 -0
  29. package/dist/components/card.d.ts +43 -0
  30. package/dist/components/card.js +42 -0
  31. package/dist/components/carousel.d.ts +57 -0
  32. package/dist/components/carousel.js +422 -0
  33. package/dist/components/chart.d.ts +112 -0
  34. package/dist/components/chart.js +172 -0
  35. package/dist/components/chat-confirmation.d.ts +42 -0
  36. package/dist/components/chat-confirmation.js +62 -0
  37. package/dist/components/chat-plan.d.ts +21 -0
  38. package/dist/components/chat-plan.js +35 -0
  39. package/dist/components/chat-sources.d.ts +64 -0
  40. package/dist/components/chat-sources.js +66 -0
  41. package/dist/components/checkbox.d.ts +16 -0
  42. package/dist/components/checkbox.js +17 -0
  43. package/dist/components/choice-list.d.ts +53 -0
  44. package/dist/components/choice-list.js +36 -0
  45. package/dist/components/code-block.d.ts +35 -0
  46. package/dist/components/code-block.js +95 -0
  47. package/dist/components/collapsible.d.ts +24 -0
  48. package/dist/components/collapsible.js +27 -0
  49. package/dist/components/combobox.d.ts +95 -0
  50. package/dist/components/combobox.js +106 -0
  51. package/dist/components/command.d.ts +94 -0
  52. package/dist/components/command.js +414 -0
  53. package/dist/components/context-menu.d.ts +57 -0
  54. package/dist/components/context-menu.js +60 -0
  55. package/dist/components/dialog.d.ts +60 -0
  56. package/dist/components/dialog.js +79 -0
  57. package/dist/components/direction.d.ts +6 -0
  58. package/dist/components/direction.js +6 -0
  59. package/dist/components/dropdown-menu.d.ts +62 -0
  60. package/dist/components/dropdown-menu.js +59 -0
  61. package/dist/components/field.d.ts +117 -0
  62. package/dist/components/field.js +150 -0
  63. package/dist/components/file-viewer.d.ts +120 -0
  64. package/dist/components/file-viewer.js +373 -0
  65. package/dist/components/form.d.ts +87 -0
  66. package/dist/components/form.js +55 -0
  67. package/dist/components/glass-banner.d.ts +27 -0
  68. package/dist/components/glass-banner.js +116 -0
  69. package/dist/components/gradient-banner.d.ts +37 -0
  70. package/dist/components/gradient-banner.js +43 -0
  71. package/dist/components/hover-card.d.ts +27 -0
  72. package/dist/components/hover-card.js +26 -0
  73. package/dist/components/input-group.d.ts +68 -0
  74. package/dist/components/input-group.js +88 -0
  75. package/dist/components/input-otp.d.ts +38 -0
  76. package/dist/components/input-otp.js +43 -0
  77. package/dist/components/input.d.ts +16 -0
  78. package/dist/components/input.js +18 -0
  79. package/dist/components/kbd.d.ts +12 -0
  80. package/dist/components/kbd.js +11 -0
  81. package/dist/components/label.d.ts +8 -0
  82. package/dist/components/label.js +10 -0
  83. package/dist/components/mention-list.d.ts +54 -0
  84. package/dist/components/mention-list.js +31 -0
  85. package/dist/components/menubar.d.ts +64 -0
  86. package/dist/components/menubar.js +68 -0
  87. package/dist/components/message-actions.d.ts +34 -0
  88. package/dist/components/message-actions.js +68 -0
  89. package/dist/components/message-response.d.ts +20 -0
  90. package/dist/components/message-response.js +46 -0
  91. package/dist/components/message-scroller.d.ts +71 -0
  92. package/dist/components/message-scroller.js +217 -0
  93. package/dist/components/message.d.ts +49 -0
  94. package/dist/components/message.js +59 -0
  95. package/dist/components/navigation-menu.d.ts +45 -0
  96. package/dist/components/navigation-menu.js +54 -0
  97. package/dist/components/notice-banner.d.ts +14 -0
  98. package/dist/components/notice-banner.js +11 -0
  99. package/dist/components/page-content.d.ts +7 -0
  100. package/dist/components/page-content.js +9 -0
  101. package/dist/components/page-header.d.ts +37 -0
  102. package/dist/components/page-header.js +53 -0
  103. package/dist/components/pagination.d.ts +29 -0
  104. package/dist/components/pagination.js +29 -0
  105. package/dist/components/plan-outline.d.ts +60 -0
  106. package/dist/components/plan-outline.js +108 -0
  107. package/dist/components/popover.d.ts +34 -0
  108. package/dist/components/popover.js +35 -0
  109. package/dist/components/progress.d.ts +27 -0
  110. package/dist/components/progress.js +35 -0
  111. package/dist/components/prompt-list.d.ts +23 -0
  112. package/dist/components/prompt-list.js +11 -0
  113. package/dist/components/questionnaire.d.ts +148 -0
  114. package/dist/components/questionnaire.js +1001 -0
  115. package/dist/components/radio-group.d.ts +16 -0
  116. package/dist/components/radio-group.js +21 -0
  117. package/dist/components/reasoning-effort.d.ts +24 -0
  118. package/dist/components/reasoning-effort.js +269 -0
  119. package/dist/components/resizable.d.ts +67 -0
  120. package/dist/components/resizable.js +536 -0
  121. package/dist/components/result-card.d.ts +58 -0
  122. package/dist/components/result-card.js +88 -0
  123. package/dist/components/review-card.d.ts +62 -0
  124. package/dist/components/review-card.js +49 -0
  125. package/dist/components/rich-text-editor.d.ts +51 -0
  126. package/dist/components/rich-text-editor.js +248 -0
  127. package/dist/components/schema-diagram.d.ts +52 -0
  128. package/dist/components/schema-diagram.js +226 -0
  129. package/dist/components/scroll-area.d.ts +22 -0
  130. package/dist/components/scroll-area.js +19 -0
  131. package/dist/components/search-dialog.d.ts +103 -0
  132. package/dist/components/search-dialog.js +64 -0
  133. package/dist/components/search-field.d.ts +17 -0
  134. package/dist/components/search-field.js +27 -0
  135. package/dist/components/select.d.ts +57 -0
  136. package/dist/components/select.js +57 -0
  137. package/dist/components/selection-slot.d.ts +18 -0
  138. package/dist/components/selection-slot.js +53 -0
  139. package/dist/components/separator.d.ts +48 -0
  140. package/dist/components/separator.js +54 -0
  141. package/dist/components/settings-list.d.ts +26 -0
  142. package/dist/components/settings-list.js +17 -0
  143. package/dist/components/sheet.d.ts +70 -0
  144. package/dist/components/sheet.js +77 -0
  145. package/dist/components/sidebar.d.ts +70 -0
  146. package/dist/components/sidebar.js +187 -0
  147. package/dist/components/skeleton.d.ts +31 -0
  148. package/dist/components/skeleton.js +32 -0
  149. package/dist/components/slider.d.ts +17 -0
  150. package/dist/components/slider.js +24 -0
  151. package/dist/components/spinner.d.ts +37 -0
  152. package/dist/components/spinner.js +43 -0
  153. package/dist/components/state-panel-samples.d.ts +25 -0
  154. package/dist/components/state-panel-samples.js +423 -0
  155. package/dist/components/state-panel.d.ts +35 -0
  156. package/dist/components/state-panel.js +29 -0
  157. package/dist/components/state-sample.d.ts +63 -0
  158. package/dist/components/state-sample.js +42 -0
  159. package/dist/components/switch.d.ts +12 -0
  160. package/dist/components/switch.js +14 -0
  161. package/dist/components/table-nuqs.d.ts +16 -0
  162. package/dist/components/table-nuqs.js +59 -0
  163. package/dist/components/table.d.ts +120 -0
  164. package/dist/components/table.js +663 -0
  165. package/dist/components/tabs.d.ts +37 -0
  166. package/dist/components/tabs.js +36 -0
  167. package/dist/components/textarea.d.ts +18 -0
  168. package/dist/components/textarea.js +19 -0
  169. package/dist/components/toast.d.ts +45 -0
  170. package/dist/components/toast.js +83 -0
  171. package/dist/components/toggle-group.d.ts +30 -0
  172. package/dist/components/toggle-group.js +39 -0
  173. package/dist/components/toggle.d.ts +27 -0
  174. package/dist/components/toggle.js +21 -0
  175. package/dist/components/tool-activity.d.ts +79 -0
  176. package/dist/components/tool-activity.js +226 -0
  177. package/dist/components/toolbar-status.d.ts +21 -0
  178. package/dist/components/toolbar-status.js +14 -0
  179. package/dist/components/tooltip.d.ts +31 -0
  180. package/dist/components/tooltip.js +99 -0
  181. package/dist/components/typed-text.d.ts +17 -0
  182. package/dist/components/typed-text.js +56 -0
  183. package/dist/index.d.ts +88 -0
  184. package/dist/index.js +88 -0
  185. package/dist/internal/brand-glyphs.d.ts +342 -0
  186. package/dist/internal/brand-glyphs.js +238 -0
  187. package/dist/internal/classes.d.ts +3 -0
  188. package/dist/internal/classes.js +20 -0
  189. package/dist/internal/fieldset.d.ts +6 -0
  190. package/dist/internal/fieldset.js +38 -0
  191. package/dist/internal/file-kind.d.ts +4 -0
  192. package/dist/internal/file-kind.js +62 -0
  193. package/dist/internal/languages.d.ts +7 -0
  194. package/dist/internal/languages.js +1010 -0
  195. package/dist/internal/message-scroller.d.ts +102 -0
  196. package/dist/internal/message-scroller.js +637 -0
  197. package/dist/internal/pressable.d.ts +2 -0
  198. package/dist/internal/pressable.js +29 -0
  199. package/dist/internal/syntax.d.ts +14 -0
  200. package/dist/internal/syntax.js +137 -0
  201. package/dist/styles/accordion.css +102 -0
  202. package/dist/styles/alert-dialog.css +198 -0
  203. package/dist/styles/alert.css +149 -0
  204. package/dist/styles/aspect-ratio.css +8 -0
  205. package/dist/styles/attachment.css +720 -0
  206. package/dist/styles/avatar.css +186 -0
  207. package/dist/styles/badge.css +178 -0
  208. package/dist/styles/brand-icon.css +104 -0
  209. package/dist/styles/breadcrumb.css +121 -0
  210. package/dist/styles/button-group.css +113 -0
  211. package/dist/styles/button.css +380 -0
  212. package/dist/styles/calendar.css +295 -0
  213. package/dist/styles/canvas.css +327 -0
  214. package/dist/styles/card.css +146 -0
  215. package/dist/styles/carousel.css +107 -0
  216. package/dist/styles/chart.css +227 -0
  217. package/dist/styles/chat-confirmation.css +29 -0
  218. package/dist/styles/chat-plan.css +109 -0
  219. package/dist/styles/chat-sources.css +191 -0
  220. package/dist/styles/checkbox.css +123 -0
  221. package/dist/styles/choice-list.css +343 -0
  222. package/dist/styles/code-block.css +211 -0
  223. package/dist/styles/collapsible.css +72 -0
  224. package/dist/styles/combobox.css +347 -0
  225. package/dist/styles/command.css +233 -0
  226. package/dist/styles/context-menu.css +151 -0
  227. package/dist/styles/dialog.css +237 -0
  228. package/dist/styles/dropdown-menu.css +150 -0
  229. package/dist/styles/field.css +341 -0
  230. package/dist/styles/file-viewer.css +278 -0
  231. package/dist/styles/form.css +155 -0
  232. package/dist/styles/glass-banner.css +308 -0
  233. package/dist/styles/gradient-banner.css +256 -0
  234. package/dist/styles/hover-card.css +95 -0
  235. package/dist/styles/index.css +262 -0
  236. package/dist/styles/input-group.css +290 -0
  237. package/dist/styles/input-otp.css +138 -0
  238. package/dist/styles/input.css +99 -0
  239. package/dist/styles/kbd.css +59 -0
  240. package/dist/styles/label.css +89 -0
  241. package/dist/styles/mention-list.css +166 -0
  242. package/dist/styles/menubar.css +226 -0
  243. package/dist/styles/message-actions.css +83 -0
  244. package/dist/styles/message-response.css +176 -0
  245. package/dist/styles/message-scroller.css +136 -0
  246. package/dist/styles/message.css +310 -0
  247. package/dist/styles/navigation-menu.css +291 -0
  248. package/dist/styles/notice-banner.css +68 -0
  249. package/dist/styles/page-content.css +21 -0
  250. package/dist/styles/page-header.css +156 -0
  251. package/dist/styles/pagination.css +72 -0
  252. package/dist/styles/plan-outline.css +393 -0
  253. package/dist/styles/popover.css +140 -0
  254. package/dist/styles/progress.css +93 -0
  255. package/dist/styles/prompt-list.css +165 -0
  256. package/dist/styles/questionnaire.css +323 -0
  257. package/dist/styles/radio-group.css +120 -0
  258. package/dist/styles/reasoning-effort.css +157 -0
  259. package/dist/styles/resizable.css +108 -0
  260. package/dist/styles/result-card.css +215 -0
  261. package/dist/styles/review-card.css +235 -0
  262. package/dist/styles/rich-text-editor.css +169 -0
  263. package/dist/styles/schema-diagram.css +419 -0
  264. package/dist/styles/scroll-area.css +77 -0
  265. package/dist/styles/search-dialog.css +363 -0
  266. package/dist/styles/search-field.css +17 -0
  267. package/dist/styles/select.css +285 -0
  268. package/dist/styles/selection-slot.css +31 -0
  269. package/dist/styles/separator.css +206 -0
  270. package/dist/styles/settings-list.css +81 -0
  271. package/dist/styles/sheet.css +361 -0
  272. package/dist/styles/sidebar.css +363 -0
  273. package/dist/styles/skeleton.css +80 -0
  274. package/dist/styles/slider.css +142 -0
  275. package/dist/styles/spinner.css +39 -0
  276. package/dist/styles/state-panel-samples.css +41 -0
  277. package/dist/styles/state-panel.css +182 -0
  278. package/dist/styles/state-sample.css +285 -0
  279. package/dist/styles/switch.css +128 -0
  280. package/dist/styles/table.css +604 -0
  281. package/dist/styles/tabs.css +223 -0
  282. package/dist/styles/textarea.css +78 -0
  283. package/dist/styles/themes/chatgpt.css +125 -0
  284. package/dist/styles/themes/claude.css +125 -0
  285. package/dist/styles/themes/cloudflare.css +125 -0
  286. package/dist/styles/themes/discord.css +125 -0
  287. package/dist/styles/themes/github.css +125 -0
  288. package/dist/styles/themes/grok.css +125 -0
  289. package/dist/styles/themes/linear.css +126 -0
  290. package/dist/styles/themes/neutral.css +125 -0
  291. package/dist/styles/themes/notion.css +125 -0
  292. package/dist/styles/themes/perplexity.css +125 -0
  293. package/dist/styles/themes/raycast.css +125 -0
  294. package/dist/styles/themes/spotify.css +125 -0
  295. package/dist/styles/themes/stripe.css +125 -0
  296. package/dist/styles/themes/supabase.css +125 -0
  297. package/dist/styles/themes/tulipfarm.css +125 -0
  298. package/dist/styles/themes/vercel.css +126 -0
  299. package/dist/styles/toast.css +197 -0
  300. package/dist/styles/toggle-group.css +161 -0
  301. package/dist/styles/toggle.css +119 -0
  302. package/dist/styles/tool-activity.css +396 -0
  303. package/dist/styles/toolbar-status.css +52 -0
  304. package/dist/styles/tooltip.css +122 -0
  305. package/dist/styles/typed-text.css +17 -0
  306. package/package.json +443 -4
@@ -0,0 +1,35 @@
1
+ import type { ComponentType, HTMLAttributes, ReactNode } from "react";
2
+ export declare const statePanelKindNames: readonly ["empty", "loading", "success", "unavailable", "error"];
3
+ export type StatePanelKind = (typeof statePanelKindNames)[number];
4
+ export type StatePanelHeading = "h1" | "h2" | "h3" | "h4";
5
+ export type StatePanelIcon = ComponentType<{
6
+ size?: number;
7
+ }>;
8
+ interface StatePanelBaseProps extends Omit<HTMLAttributes<HTMLElement>, "title" | "children" | "role"> {
9
+ title: ReactNode;
10
+ description: ReactNode;
11
+ /** Heading element for `title`. Match the surrounding document outline. */
12
+ heading?: StatePanelHeading | undefined;
13
+ /**
14
+ * Icon for `empty` and `unavailable`. Pass `null` to show no icon.
15
+ * Other kinds use a fixed icon.
16
+ */
17
+ icon?: StatePanelIcon | null | undefined;
18
+ /** Actions or guidance shown below the description. */
19
+ children?: ReactNode;
20
+ }
21
+ export type StatePanelProps = StatePanelBaseProps & ({
22
+ kind: "empty";
23
+ /** Decorative preview of the filled state. Switches to the split layout. */
24
+ sample?: ReactNode;
25
+ } | {
26
+ kind: "loading" | "success" | "unavailable";
27
+ sample?: never;
28
+ } | {
29
+ kind: "error";
30
+ /** Errors always offer a recovery action or guidance. */
31
+ children: ReactNode;
32
+ sample?: never;
33
+ });
34
+ export declare function StatePanel({ kind, title, description, heading: Heading, icon, children, sample, className, ...props }: StatePanelProps): import("react").JSX.Element;
35
+ export * from "./state-panel-samples.js";
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Check } from "reicon-react/icons/Check";
3
+ import { Inbox } from "reicon-react/icons/Inbox";
4
+ import { Loader } from "reicon-react/icons/Loader";
5
+ import { Warning } from "reicon-react/icons/Warning";
6
+ import { cn } from "../internal/classes.js";
7
+ export const statePanelKindNames = [
8
+ "empty",
9
+ "loading",
10
+ "success",
11
+ "unavailable",
12
+ "error",
13
+ ];
14
+ const roles = {
15
+ error: "alert",
16
+ loading: "status",
17
+ success: "status",
18
+ };
19
+ function Media({ kind, Icon }) {
20
+ return (_jsx("div", { "data-slot": "state-panel-media", className: "sprout-state-panel-media", "aria-hidden": "true", children: kind === "loading" ? (_jsx(Loader, { size: 16, className: "sprout-state-panel-spinner" })) : kind === "success" ? (_jsx(Check, { size: 20 })) : kind === "error" ? (_jsx(Warning, { size: 20, className: "sprout-state-panel-danger" })) : (_jsx(Icon, { size: 20 })) }));
21
+ }
22
+ export function StatePanel({ kind, title, description, heading: Heading = "h2", icon = Inbox, children, sample, className, ...props }) {
23
+ const media = icon === null && (kind === "empty" || kind === "unavailable") ? null : (_jsx(Media, { kind: kind, Icon: icon ?? Inbox }));
24
+ const hasActions = children !== undefined && children !== null && children !== false;
25
+ if (sample)
26
+ return (_jsx("section", { "data-slot": "state-panel", "data-kind": kind, "data-layout": "sample", ...props, className: cn("sprout-state-panel", className), children: _jsxs("div", { className: "sprout-state-panel-card", children: [_jsxs("div", { className: "sprout-state-panel-copy", children: [media, _jsxs("div", { className: "sprout-state-panel-text", children: [_jsx(Heading, { className: "sprout-state-panel-title", children: title }), _jsx("p", { className: "sprout-state-panel-description", children: description })] }), hasActions && (_jsx("div", { "data-slot": "state-panel-actions", className: "sprout-state-panel-actions", children: children }))] }), _jsx("div", { "data-slot": "state-panel-sample", className: "sprout-state-panel-sample", "aria-hidden": "true", inert: true, children: _jsx("div", { className: "sprout-state-panel-sample-window", children: sample }) })] }) }));
27
+ return (_jsxs("div", { "data-slot": "state-panel", "data-kind": kind, "data-layout": "centered", ...props, className: cn("sprout-state-panel", className), children: [media, _jsxs("div", { role: roles[kind], "aria-atomic": "true", className: "sprout-state-panel-text", children: [_jsx(Heading, { className: "sprout-state-panel-title", children: title }), _jsx("p", { className: "sprout-state-panel-description", children: description })] }), hasActions && (_jsx("div", { "data-slot": "state-panel-actions", className: "sprout-state-panel-actions", children: children }))] }));
28
+ }
29
+ export * from "./state-panel-samples.js";
@@ -0,0 +1,63 @@
1
+ import { type ComponentType, type HTMLAttributes, type ReactNode } from "react";
2
+ export type SampleIcon = ComponentType<{
3
+ size?: number;
4
+ }>;
5
+ export interface SampleWindowProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
6
+ /** Page icon at the start of the title bar. */
7
+ icon: SampleIcon;
8
+ /** Breadcrumb parts. The last part is the current page. */
9
+ trail: readonly string[];
10
+ /** Tab labels. The first tab is shown as selected. */
11
+ tabs?: readonly string[] | undefined;
12
+ /** Chip at the end of the title bar. */
13
+ label?: ReactNode;
14
+ children: ReactNode;
15
+ }
16
+ export declare function SampleWindow({ icon: Icon, trail, tabs, label, children, className, ...props }: SampleWindowProps): import("react").JSX.Element;
17
+ export declare const sampleColumnSizeNames: readonly ["wide", "default", "narrow"];
18
+ export type SampleColumnSize = (typeof sampleColumnSizeNames)[number];
19
+ export type SampleColumn = {
20
+ label: string;
21
+ size?: SampleColumnSize;
22
+ };
23
+ export interface SampleTableProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
24
+ columns: readonly SampleColumn[];
25
+ rows: readonly (readonly ReactNode[])[];
26
+ }
27
+ export declare function SampleTable({ columns, rows, className, ...props }: SampleTableProps): import("react").JSX.Element;
28
+ export type SampleListItem = {
29
+ leading?: ReactNode;
30
+ title: string;
31
+ detail?: string;
32
+ trailing?: ReactNode;
33
+ };
34
+ export interface SampleListProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
35
+ items: readonly SampleListItem[];
36
+ }
37
+ export declare function SampleList({ items, className, ...props }: SampleListProps): import("react").JSX.Element;
38
+ export declare const sampleTextToneNames: readonly ["default", "strong", "muted", "link", "mono"];
39
+ export type SampleTextTone = (typeof sampleTextToneNames)[number];
40
+ export interface SampleTextProps extends HTMLAttributes<HTMLSpanElement> {
41
+ tone?: SampleTextTone | undefined;
42
+ children: ReactNode;
43
+ }
44
+ export declare function SampleText({ tone, className, ...props }: SampleTextProps): import("react").JSX.Element;
45
+ export declare const sampleMarkToneNames: readonly ["red", "orange", "green", "blue", "violet", "teal"];
46
+ export type SampleMarkTone = (typeof sampleMarkToneNames)[number];
47
+ export declare const sampleMarkSizeNames: readonly ["sm", "md"];
48
+ export type SampleMarkSize = (typeof sampleMarkSizeNames)[number];
49
+ export interface SampleMarkProps extends Omit<HTMLAttributes<HTMLSpanElement>, "children"> {
50
+ tone: SampleMarkTone;
51
+ size?: SampleMarkSize | undefined;
52
+ }
53
+ export declare function SampleMark({ tone, size, className, ...props }: SampleMarkProps): import("react").JSX.Element;
54
+ export declare const sampleBarWidthNames: readonly ["sm", "md", "lg"];
55
+ export type SampleBarWidth = (typeof sampleBarWidthNames)[number];
56
+ export interface SampleBarProps extends Omit<HTMLAttributes<HTMLSpanElement>, "children"> {
57
+ width?: SampleBarWidth | undefined;
58
+ }
59
+ export declare function SampleBar({ width, className, ...props }: SampleBarProps): import("react").JSX.Element;
60
+ export interface SampleIconTileProps extends Omit<HTMLAttributes<HTMLSpanElement>, "children"> {
61
+ icon: SampleIcon;
62
+ }
63
+ export declare function SampleIconTile({ icon: Icon, className, ...props }: SampleIconTileProps): import("react").JSX.Element;
@@ -0,0 +1,42 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Fragment, } from "react";
3
+ import { cn } from "../internal/classes.js";
4
+ export function SampleWindow({ icon: Icon, trail, tabs, label = "Example", children, className, ...props }) {
5
+ return (_jsxs("div", { "data-slot": "state-sample", ...props, className: cn("sprout-state-sample", className), children: [_jsxs("div", { className: "sprout-state-sample-bar", children: [_jsx("span", { className: "sprout-state-sample-icon", "aria-hidden": "true", children: _jsx(Icon, { size: 14 }) }), trail.map((part, index) => (_jsxs(Fragment, { children: [index > 0 && (_jsx("span", { className: "sprout-state-sample-faint", "aria-hidden": "true", children: "/" })), _jsx("span", { className: "sprout-state-sample-crumb", "data-current": index === trail.length - 1 ? "" : undefined, children: part })] }, index))), _jsx("span", { className: "sprout-state-sample-faint", "aria-hidden": "true", children: "\u00B7\u00B7\u00B7" }), _jsx("span", { className: "sprout-state-sample-label", children: label })] }), tabs && tabs.length > 0 && (_jsx("div", { className: "sprout-state-sample-tabs", children: tabs.map((tab, index) => (_jsx("span", { className: "sprout-state-sample-tab", "data-selected": index === 0 ? "" : undefined, children: tab }, index))) })), children] }));
6
+ }
7
+ export const sampleColumnSizeNames = ["wide", "default", "narrow"];
8
+ export function SampleTable({ columns, rows, className, ...props }) {
9
+ return (_jsxs("div", { "data-slot": "state-sample-table", ...props, className: cn("sprout-state-sample-table", className), children: [_jsxs("div", { className: "sprout-state-sample-head", children: [_jsx("span", { className: "sprout-state-sample-check", "aria-hidden": "true" }), columns.map((column, index) => (_jsx("span", { className: "sprout-state-sample-cell", "data-size": column.size ?? "default", children: column.label }, index)))] }), rows.map((row, rowIndex) => (_jsxs("div", { className: "sprout-state-sample-row", children: [_jsx("span", { className: "sprout-state-sample-check", "aria-hidden": "true" }), row.map((cell, cellIndex) => (_jsx("span", { className: "sprout-state-sample-cell", "data-size": columns[cellIndex]?.size ?? "default", children: cell }, cellIndex)))] }, rowIndex)))] }));
10
+ }
11
+ export function SampleList({ items, className, ...props }) {
12
+ return (_jsx("div", { "data-slot": "state-sample-list", ...props, className: cn("sprout-state-sample-list", className), children: items.map((item, index) => (_jsxs("div", { className: "sprout-state-sample-item", children: [item.leading && (_jsx("span", { className: "sprout-state-sample-leading", children: item.leading })), _jsxs("span", { className: "sprout-state-sample-copy", children: [_jsx("span", { className: "sprout-state-sample-title", children: item.title }), item.detail && (_jsx("span", { className: "sprout-state-sample-detail", children: item.detail }))] }), item.trailing && (_jsx("span", { className: "sprout-state-sample-trailing", children: item.trailing }))] }, index))) }));
13
+ }
14
+ export const sampleTextToneNames = [
15
+ "default",
16
+ "strong",
17
+ "muted",
18
+ "link",
19
+ "mono",
20
+ ];
21
+ export function SampleText({ tone = "default", className, ...props }) {
22
+ return (_jsx("span", { "data-slot": "state-sample-text", "data-tone": tone, ...props, className: cn("sprout-state-sample-text", className) }));
23
+ }
24
+ export const sampleMarkToneNames = [
25
+ "red",
26
+ "orange",
27
+ "green",
28
+ "blue",
29
+ "violet",
30
+ "teal",
31
+ ];
32
+ export const sampleMarkSizeNames = ["sm", "md"];
33
+ export function SampleMark({ tone, size = "sm", className, ...props }) {
34
+ return (_jsx("span", { "data-slot": "state-sample-mark", "data-tone": tone, "data-size": size, "aria-hidden": "true", ...props, className: cn("sprout-state-sample-mark", className) }));
35
+ }
36
+ export const sampleBarWidthNames = ["sm", "md", "lg"];
37
+ export function SampleBar({ width = "md", className, ...props }) {
38
+ return (_jsx("span", { "data-slot": "state-sample-bar", "data-width": width, "aria-hidden": "true", ...props, className: cn("sprout-state-sample-placeholder", className) }));
39
+ }
40
+ export function SampleIconTile({ icon: Icon, className, ...props }) {
41
+ return (_jsx("span", { "data-slot": "state-sample-icon-tile", "aria-hidden": "true", ...props, className: cn("sprout-state-sample-icon-tile", className), children: _jsx(Icon, { size: 14 }) }));
42
+ }
@@ -0,0 +1,12 @@
1
+ import { Switch as BaseSwitch } from "@base-ui/react/switch";
2
+ export declare const switchSizeNames: readonly ["default", "sm"];
3
+ export type SwitchSize = (typeof switchSizeNames)[number];
4
+ export interface SwitchProps extends BaseSwitch.Root.Props {
5
+ /** `default` is a 32 × 18px track. `sm` is a 24 × 14px track. */
6
+ size?: SwitchSize | undefined;
7
+ }
8
+ /**
9
+ * An on/off switch for a setting that applies right away. Name it with a
10
+ * wrapping `Label`, a `Label htmlFor` pointing at its `id`, or `aria-label`.
11
+ */
12
+ export declare function Switch({ size, className, disabled, ref, ...props }: SwitchProps): import("react").JSX.Element;
@@ -0,0 +1,14 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { Switch as BaseSwitch } from "@base-ui/react/switch";
4
+ import { cn, stateClassName } from "../internal/classes.js";
5
+ import { useFieldsetDisabled } from "../internal/fieldset.js";
6
+ export const switchSizeNames = ["default", "sm"];
7
+ /**
8
+ * An on/off switch for a setting that applies right away. Name it with a
9
+ * wrapping `Label`, a `Label htmlFor` pointing at its `id`, or `aria-label`.
10
+ */
11
+ export function Switch({ size = "default", className, disabled, ref, ...props }) {
12
+ const [fieldsetDisabled, fieldsetRef] = useFieldsetDisabled(ref);
13
+ return (_jsx(BaseSwitch.Root, { "data-slot": "switch", "data-size": size, ...props, ref: fieldsetRef, disabled: disabled || fieldsetDisabled, className: stateClassName(cn("sprout-switch", `sprout-switch-size-${size}`), className), children: _jsx(BaseSwitch.Thumb, { "data-slot": "switch-thumb", className: "sprout-switch-thumb" }) }));
14
+ }
@@ -0,0 +1,16 @@
1
+ import type { TableState } from "./table.js";
2
+ export interface TableUrlStateOptions {
3
+ /** Prefixes every query key, for pages with more than one Table. */
4
+ prefix?: string;
5
+ /** Page size used when the URL has none. */
6
+ pageSize?: number;
7
+ }
8
+ /**
9
+ * Keeps a Table's View state (sort, filters, search, grouping, page) in the
10
+ * URL with nuqs, so a shared link opens the same view. Spread the result into
11
+ * `<Table {...useTableUrlState()} />`. Needs a nuqs adapter higher in the tree.
12
+ */
13
+ export declare function useTableUrlState({ prefix, pageSize, }?: TableUrlStateOptions): {
14
+ state: Partial<TableState>;
15
+ onStateChange: (next: TableState) => undefined;
16
+ };
@@ -0,0 +1,59 @@
1
+ "use client";
2
+ import { createParser, parseAsArrayOf, parseAsInteger, parseAsJson, parseAsString, useQueryStates, } from "nuqs";
3
+ const parseAsSorting = createParser({
4
+ parse: (value) => value
5
+ .split(",")
6
+ .filter(Boolean)
7
+ .map((part) => {
8
+ const [id = "", dir] = part.split(".");
9
+ return { id, desc: dir === "desc" };
10
+ }),
11
+ serialize: (sorting) => sorting.map((s) => `${s.id}.${s.desc ? "desc" : "asc"}`).join(","),
12
+ });
13
+ const isFilters = (value) => Array.isArray(value) &&
14
+ value.every((f) => typeof f === "object" && f !== null && typeof f.id === "string")
15
+ ? value
16
+ : null;
17
+ /**
18
+ * Keeps a Table's View state (sort, filters, search, grouping, page) in the
19
+ * URL with nuqs, so a shared link opens the same view. Spread the result into
20
+ * `<Table {...useTableUrlState()} />`. Needs a nuqs adapter higher in the tree.
21
+ */
22
+ export function useTableUrlState({ prefix = "", pageSize = 10, } = {}) {
23
+ const [query, setQuery] = useQueryStates({
24
+ sort: parseAsSorting.withDefault([]),
25
+ filters: parseAsJson(isFilters).withDefault([]),
26
+ q: parseAsString.withDefault(""),
27
+ group: parseAsArrayOf(parseAsString).withDefault([]),
28
+ page: parseAsInteger.withDefault(1),
29
+ size: parseAsInteger.withDefault(pageSize),
30
+ }, {
31
+ urlKeys: {
32
+ sort: `${prefix}sort`,
33
+ filters: `${prefix}filters`,
34
+ q: `${prefix}q`,
35
+ group: `${prefix}group`,
36
+ page: `${prefix}page`,
37
+ size: `${prefix}size`,
38
+ },
39
+ });
40
+ const state = {
41
+ sorting: query.sort,
42
+ columnFilters: query.filters,
43
+ globalFilter: query.q,
44
+ grouping: query.group,
45
+ pagination: {
46
+ pageIndex: Math.max(0, query.page - 1),
47
+ pageSize: query.size,
48
+ },
49
+ };
50
+ const onStateChange = (next) => void setQuery({
51
+ sort: next.sorting.length ? next.sorting : null,
52
+ filters: next.columnFilters.length ? next.columnFilters : null,
53
+ q: next.globalFilter || null,
54
+ group: next.grouping.length ? next.grouping : null,
55
+ page: next.pagination.pageIndex ? next.pagination.pageIndex + 1 : null,
56
+ size: next.pagination.pageSize === pageSize ? null : next.pagination.pageSize,
57
+ });
58
+ return { state, onStateChange };
59
+ }
@@ -0,0 +1,120 @@
1
+ import { type ReactNode } from "react";
2
+ import { type ColumnFiltersState, type ColumnOrderState, type ColumnPinningState, type ColumnSizingState, type ColumnVisibilityState, type ExpandedState, type GroupingState, type PaginationState, type RowData, type SortingState } from "@tanstack/react-table";
3
+ export declare const tableVariantNames: readonly ["plain", "grid"];
4
+ export declare const tableNarrowNames: readonly ["scroll", "stack"];
5
+ export declare const tableAlignNames: readonly ["left", "right"];
6
+ export declare const tableFilterNames: readonly ["text", "number", "select", "date", "boolean"];
7
+ export declare const tableEditNames: readonly ["text", "number", "select", "date", "checkbox"];
8
+ export declare const tableAggregateNames: readonly ["sum", "count", "min", "max", "mean"];
9
+ export type TableVariant = (typeof tableVariantNames)[number];
10
+ export type TableNarrow = (typeof tableNarrowNames)[number];
11
+ export type TableAlign = (typeof tableAlignNames)[number];
12
+ export type TableFilter = (typeof tableFilterNames)[number];
13
+ export type TableEdit = (typeof tableEditNames)[number];
14
+ export type TableAggregate = (typeof tableAggregateNames)[number];
15
+ export interface TableOption {
16
+ label: string;
17
+ value: string;
18
+ }
19
+ export interface TableColumn<Row> {
20
+ key: keyof Row & string;
21
+ header: string;
22
+ /** Shows an info button next to the header whose tooltip explains the column. */
23
+ hint?: string;
24
+ /** Custom cell content. Sorting, filtering, and editing still use `row[key]`. */
25
+ cell?: (row: Row) => ReactNode;
26
+ /** `"right"` aligns numbers and dates to the end of the column. */
27
+ align?: TableAlign;
28
+ /** Starting width in pixels. Columns without one share the free space. */
29
+ width?: number;
30
+ sort?: boolean;
31
+ filter?: TableFilter;
32
+ /** Choices for `filter: "select"` and `edit: "select"`. */
33
+ options?: TableOption[];
34
+ edit?: TableEdit;
35
+ /** Lets people group rows by this column from the Toolbar. */
36
+ group?: boolean;
37
+ /** Shown on group rows and in the footer total row. */
38
+ aggregate?: TableAggregate;
39
+ /** Formats aggregate values. Defaults to `toLocaleString()`. */
40
+ formatAggregate?: (value: number) => ReactNode;
41
+ pin?: "left" | "right";
42
+ hidden?: boolean;
43
+ }
44
+ /**
45
+ * The View state (sort, filters, search, grouping, page) and the Layout
46
+ * (widths, order, pinning, hidden columns).
47
+ */
48
+ export interface TableState {
49
+ sorting: SortingState;
50
+ columnFilters: ColumnFiltersState;
51
+ globalFilter: string;
52
+ grouping: GroupingState;
53
+ expanded: ExpandedState;
54
+ pagination: PaginationState;
55
+ columnSizing: ColumnSizingState;
56
+ columnOrder: ColumnOrderState;
57
+ columnPinning: ColumnPinningState;
58
+ columnVisibility: ColumnVisibilityState;
59
+ }
60
+ export declare const tableLayoutKeys: readonly ["columnSizing", "columnOrder", "columnPinning", "columnVisibility"];
61
+ export interface TableProps<Row> {
62
+ /** Names the table, and the scrolling region when it overflows. */
63
+ "aria-label": string;
64
+ data: Row[];
65
+ columns: TableColumn<Row>[];
66
+ getRowId: (row: Row) => string;
67
+ /** Names a row in control labels, like "Select Invoices". Defaults to the row id. */
68
+ rowLabel?: (row: Row) => string;
69
+ /**
70
+ * `"plain"` is borderless. `"grid"` frames the table in a bordered
71
+ * `ScrollArea` capped at 60dvh, with column dividers and a pinned header.
72
+ */
73
+ variant?: TableVariant;
74
+ /** On narrow containers, `"scroll"` scrolls sideways and `"stack"` turns rows into cards. */
75
+ narrow?: TableNarrow;
76
+ caption?: ReactNode;
77
+ /** The server sorts, filters, and pages. Pass `rowCount` and handle `onStateChange`. */
78
+ manual?: boolean;
79
+ rowCount?: number;
80
+ /** Controls any part of the state. Anything left out stays internal. */
81
+ state?: Partial<TableState>;
82
+ onStateChange?: (state: TableState) => void;
83
+ /** Saves the Layout to localStorage under this key. */
84
+ persistKey?: string;
85
+ /** Shows a search field in the Toolbar. */
86
+ searchable?: boolean;
87
+ /** Shows the Columns menu for hiding, pinning, and resetting columns. */
88
+ columnMenu?: boolean;
89
+ resizable?: boolean;
90
+ /** Lets people drag column headers to reorder them. */
91
+ reorderable?: boolean;
92
+ selectable?: boolean;
93
+ onSelectionChange?: (ids: string[]) => void;
94
+ /** Splits rows into pages of this size. */
95
+ pageSize?: number;
96
+ /** Renders only the rows in view, inside a scroll box capped at 60dvh. */
97
+ virtual?: boolean;
98
+ /** Adds drag handles to rows. Indexes are positions in `data`. */
99
+ onRowReorder?: (from: number, to: number) => void;
100
+ getSubRows?: (row: Row) => Row[] | undefined;
101
+ /** Adds an Edit action that opens Row edit. A rejected promise keeps the row open and shows the error. */
102
+ onRowSave?: (row: Row, changes: Partial<Row>) => void | Promise<void>;
103
+ /** Makes the first cell a link whose hit area covers the row. */
104
+ getRowHref?: (row: Row) => string;
105
+ /** Makes the first cell a button whose hit area covers the row. */
106
+ onRowClick?: (row: Row) => void;
107
+ /** Accepts files dragged onto a row. */
108
+ onRowDrop?: (row: Row, files: File[]) => void;
109
+ /** Content for the pinned trailing actions cell. */
110
+ actions?: (row: Row) => ReactNode;
111
+ loading?: boolean;
112
+ empty?: ReactNode;
113
+ className?: string;
114
+ }
115
+ /**
116
+ * A data table. Pass rows and column settings; it renders the header, body,
117
+ * Toolbar, and footer, and runs sorting, filtering, grouping, selection,
118
+ * paging, Row edit, and Layout changes for you.
119
+ */
120
+ export declare function Table<R extends RowData>(props: TableProps<R>): import("react").JSX.Element;