@botiverse/raft-ui 0.0.0-stage → 0.7.1

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 (41) hide show
  1. package/CHANGELOG.md +576 -0
  2. package/LICENSE +21 -0
  3. package/README.md +103 -2
  4. package/codemods/package-name.mjs +168 -0
  5. package/codemods/token-names.mjs +150 -0
  6. package/dist/cn.d.mts +5 -0
  7. package/dist/cn.mjs +48 -0
  8. package/dist/components/combobox-select/combobox-select.css +286 -0
  9. package/dist/components/float-button/float-button.css +316 -0
  10. package/dist/components/steps/otter-indicator.css +141 -0
  11. package/dist/components/steps/steps.css +370 -0
  12. package/dist/components/timeline/timeline.css +255 -0
  13. package/dist/dialog-CY6S-Xqf.mjs +505 -0
  14. package/dist/fonts.css +13 -0
  15. package/dist/foundation.css +623 -0
  16. package/dist/index-B3_j9XYd.d.mts +329 -0
  17. package/dist/index.d.mts +5114 -0
  18. package/dist/index.mjs +16442 -0
  19. package/dist/style.css +1315 -0
  20. package/dist/styles.css +444 -0
  21. package/dist/tokens.json +3811 -0
  22. package/dist/wip.d.mts +92 -0
  23. package/dist/wip.mjs +517 -0
  24. package/package.json +92 -3
  25. package/skills/raft-ui-critique/SKILL.md +167 -0
  26. package/skills/raft-ui-critique/agents/openai.yaml +4 -0
  27. package/skills/raft-ui-critique/references/theme-lenses.md +69 -0
  28. package/skills/raft-ui-guide/SKILL.md +96 -0
  29. package/skills/raft-ui-guide/agents/openai.yaml +4 -0
  30. package/skills/raft-ui-guide/rules/adoption.md +55 -0
  31. package/skills/raft-ui-guide/rules/composition.md +14 -0
  32. package/skills/raft-ui-guide/rules/conversation.md +15 -0
  33. package/skills/raft-ui-guide/rules/display.md +14 -0
  34. package/skills/raft-ui-guide/rules/feedback.md +13 -0
  35. package/skills/raft-ui-guide/rules/forms.md +13 -0
  36. package/skills/raft-ui-guide/rules/layout.md +15 -0
  37. package/skills/raft-ui-guide/rules/lookup.md +78 -0
  38. package/skills/raft-ui-guide/rules/overlays.md +13 -0
  39. package/skills/raft-ui-guide/rules/overview.md +30 -0
  40. package/skills/raft-ui-guide/rules/styling.md +17 -0
  41. package/skills/raft-ui-guide/rules/technical-overview.md +80 -0
@@ -0,0 +1,505 @@
1
+ import { cn } from "./cn.mjs";
2
+ import { Dialog } from "@base-ui/react/dialog";
3
+ import { X } from "lucide-react";
4
+ import { tv } from "tailwind-variants/lite";
5
+ import { createContext, use } from "react";
6
+ import { Button } from "@base-ui/react/button";
7
+ import { mergeProps } from "@base-ui/react/merge-props";
8
+ import { useRender } from "@base-ui/react/use-render";
9
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
10
+ //#region src/lib/tv.ts
11
+ const tv$1 = ((options) => {
12
+ const recipe = tv(options);
13
+ const wrappedRecipe = ((props) => {
14
+ const result = recipe(props);
15
+ if (result == null || typeof result === "string") return cn(result);
16
+ return Object.fromEntries(Object.entries(result).map(([slotName, slot]) => [slotName, (slotProps) => cn(slot(slotProps))]));
17
+ });
18
+ return Object.assign(wrappedRecipe, recipe);
19
+ });
20
+ //#endregion
21
+ //#region src/lib/theme/theme-context.ts
22
+ const ThemeStateContext = createContext({
23
+ mode: "light",
24
+ resolvedMode: "light",
25
+ setMode: () => void 0
26
+ });
27
+ //#endregion
28
+ //#region src/lib/theme/use-theme.ts
29
+ /** Read and update the colour mode. */
30
+ function useTheme() {
31
+ return use(ThemeStateContext);
32
+ }
33
+ //#endregion
34
+ //#region src/lib/theme/theme-scope.ts
35
+ /**
36
+ * Carry the provider's resolved mode (`light` / `dark`) onto content that
37
+ * renders outside its subtree (a portal), so a dark island's popup stays dark.
38
+ */
39
+ function resolveThemeScopeProps({ className, ...props }, { resolvedMode }) {
40
+ const resolvedClassName = typeof className === "function" ? (state) => cn(className(state), resolvedMode) : typeof className === "string" ? cn(className, resolvedMode) : className ?? resolvedMode;
41
+ return {
42
+ ...props,
43
+ className: resolvedClassName
44
+ };
45
+ }
46
+ function useThemeScopeProps(props) {
47
+ return resolveThemeScopeProps(props, useTheme());
48
+ }
49
+ //#endregion
50
+ //#region src/lib/default-native-button.ts
51
+ function defaultNativeButton(render) {
52
+ if (!render || typeof render !== "object" || !("type" in render)) return;
53
+ const element = render;
54
+ if (typeof element.type === "string") return element.type === "button";
55
+ }
56
+ //#endregion
57
+ //#region src/components/spinner/spinner.tsx
58
+ const SPINNER_STYLE = `
59
+ @keyframes raft-spinner-pixel {
60
+ 0%,
61
+ 24% {
62
+ opacity: 1;
63
+ }
64
+ 25%,
65
+ 100% {
66
+ opacity: 0.2;
67
+ }
68
+ }
69
+
70
+ [data-slot="spinner"] [data-spinner-pixel] {
71
+ animation: raft-spinner-pixel 1s steps(1) infinite;
72
+ }
73
+
74
+ [data-slot="spinner"] [data-spinner-pixel]:nth-child(2) {
75
+ animation-delay: 0.25s;
76
+ }
77
+
78
+ [data-slot="spinner"] [data-spinner-pixel]:nth-child(4) {
79
+ animation-delay: 0.5s;
80
+ }
81
+
82
+ [data-slot="spinner"] [data-spinner-pixel]:nth-child(3) {
83
+ animation-delay: 0.75s;
84
+ }
85
+
86
+ @media (prefers-reduced-motion: reduce) {
87
+ [data-slot="spinner"] [data-spinner-pixel] {
88
+ animation: none;
89
+ }
90
+
91
+ [data-slot="spinner"] [data-spinner-pixel]:first-child {
92
+ opacity: 1;
93
+ }
94
+ }
95
+ `;
96
+ const spinner = tv$1({
97
+ slots: {
98
+ root: [
99
+ "relative inline-flex shrink-0 items-center justify-center",
100
+ "leading-none text-current",
101
+ "[--spinner-pixel:5px] [--spinner-gap:2px]"
102
+ ],
103
+ ring: ["shrink-0", "grid size-auto grid-cols-[repeat(2,var(--spinner-pixel))] gap-(--spinner-gap)"],
104
+ pixel: ["block size-(--spinner-pixel) rounded-[1px] bg-current opacity-20"]
105
+ },
106
+ variants: {
107
+ size: {
108
+ xs: { root: ["[--spinner-pixel:4px] [--spinner-gap:1.5px]"] },
109
+ sm: {},
110
+ md: { root: ["[--spinner-pixel:6px] [--spinner-gap:2px]"] },
111
+ lg: { root: ["[--spinner-pixel:8px] [--spinner-gap:3px]"] }
112
+ },
113
+ variant: {
114
+ default: {},
115
+ inverse: { root: ["text-foreground-inverse"] }
116
+ }
117
+ },
118
+ defaultVariants: { size: "sm" }
119
+ });
120
+ const spinnerStyle = /* @__PURE__ */ jsx("style", {
121
+ href: "raft-ui-spinner",
122
+ precedence: "default",
123
+ children: SPINNER_STYLE
124
+ });
125
+ function Spinner({ size = "sm", variant = "default", className, render, ...props }) {
126
+ const { root, ring, pixel } = spinner({
127
+ size,
128
+ variant
129
+ });
130
+ const children = /* @__PURE__ */ jsxs(Fragment$1, { children: [spinnerStyle, /* @__PURE__ */ jsxs("span", {
131
+ "data-spinner-grid": "",
132
+ "aria-hidden": "true",
133
+ className: ring(),
134
+ children: [
135
+ /* @__PURE__ */ jsx("span", {
136
+ "data-spinner-pixel": "",
137
+ className: pixel()
138
+ }),
139
+ /* @__PURE__ */ jsx("span", {
140
+ "data-spinner-pixel": "",
141
+ className: pixel()
142
+ }),
143
+ /* @__PURE__ */ jsx("span", {
144
+ "data-spinner-pixel": "",
145
+ className: pixel()
146
+ }),
147
+ /* @__PURE__ */ jsx("span", {
148
+ "data-spinner-pixel": "",
149
+ className: pixel()
150
+ })
151
+ ]
152
+ })] });
153
+ const defaultProps = {
154
+ role: "status",
155
+ "aria-label": "Loading",
156
+ className: root({ className }),
157
+ children
158
+ };
159
+ return useRender({
160
+ defaultTagName: "span",
161
+ render,
162
+ props: mergeProps(defaultProps, props),
163
+ state: {
164
+ slot: "spinner",
165
+ size
166
+ }
167
+ });
168
+ }
169
+ //#endregion
170
+ //#region src/components/button/button.tsx
171
+ const sticker = (fill) => [`border-sticker-ink ${fill} text-sticker-ink ring-[1.5px] ring-sticker-edge`, "hover:press-overlay-sticker active:press-overlay-sticker"];
172
+ const outline = (ink) => [`border-line-strong bg-layer-card ${ink}`, "hover:press-overlay active:press-overlay"];
173
+ const textMd = [
174
+ "h-8 gap-2 rounded-control px-3 py-0 text-footnote",
175
+ "has-data-[icon=inline-start]:pl-2.5 has-data-[icon=inline-end]:pr-2.5",
176
+ "[&_svg:not([class*='size-'])]:size-4 **:data-icon:size-[1em]",
177
+ "after:absolute after:inset-x-0 after:-inset-y-1.5"
178
+ ];
179
+ const iconMd = ["size-8 rounded-control p-0 [&_svg:not([class*='size-'])]:size-[18px]", "after:absolute after:-inset-1.5"];
180
+ const buttonVariants = tv$1({
181
+ slots: {
182
+ root: [
183
+ "relative inline-flex shrink-0 items-center justify-center",
184
+ "whitespace-nowrap select-none",
185
+ "rounded-none border-[1.5px] font-sans font-bold shadow-none",
186
+ "transition-colors duration-100",
187
+ "outline-[1px] outline-offset-2 outline-transparent focus-visible:outline-transparent",
188
+ "focus-visible:shadow-focus",
189
+ "data-[loading=true]:cursor-wait data-[loading=true]:opacity-100",
190
+ "[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
191
+ "disabled:pointer-events-none aria-disabled:cursor-not-allowed",
192
+ "disabled:transform-none aria-disabled:transform-none",
193
+ "aria-disabled:hover:translate-none",
194
+ "aria-disabled:active:translate-none aria-disabled:active:scale-none",
195
+ "disabled:opacity-100 aria-disabled:opacity-100",
196
+ "disabled:border-line-hairline disabled:bg-fill-muted disabled:bg-none disabled:text-foreground-disabled disabled:ring-0",
197
+ "aria-disabled:border-line-hairline aria-disabled:bg-fill-muted aria-disabled:bg-none aria-disabled:text-foreground-disabled aria-disabled:ring-0"
198
+ ],
199
+ content: "relative z-10 inline-flex items-center justify-center gap-[inherit] data-[loading=true]:invisible",
200
+ loadingIndicator: "pointer-events-none absolute inset-0 z-10 flex items-center justify-center"
201
+ },
202
+ variants: {
203
+ variant: {
204
+ primary: { root: sticker("bg-attention-400") },
205
+ accent: { root: sticker("bg-attention-400") },
206
+ warning: { root: sticker("bg-warning") },
207
+ danger: { root: sticker("bg-danger") },
208
+ default: { root: outline("text-foreground") },
209
+ outline: { root: outline("text-foreground") },
210
+ information: { root: outline("text-foreground") },
211
+ muted: { root: outline("text-foreground") },
212
+ success: { root: outline("text-foreground") },
213
+ "danger-secondary": { root: outline("text-danger-strong") },
214
+ "danger-outline": { root: outline("text-danger-strong") },
215
+ ghost: { root: ["border-transparent bg-transparent text-foreground", "hover:bg-fill-pressed active:bg-fill-pressed"] },
216
+ "on-frame": { root: [
217
+ "border-transparent bg-transparent text-foreground-on-frame",
218
+ "hover:bg-fill-frame-pressed active:bg-fill-frame-pressed",
219
+ "aria-expanded:bg-fill-frame-pressed data-popup-open:bg-fill-frame-pressed",
220
+ "disabled:border-transparent disabled:bg-transparent",
221
+ "aria-disabled:border-transparent aria-disabled:bg-transparent"
222
+ ] },
223
+ link: { root: [
224
+ "border-transparent bg-transparent text-foreground",
225
+ "underline decoration-[1.5px] underline-offset-[3px]",
226
+ "hover:decoration-attention-500 aria-disabled:hover:no-underline"
227
+ ] }
228
+ },
229
+ size: {
230
+ xs: { root: textMd },
231
+ sm: { root: textMd },
232
+ md: { root: textMd },
233
+ lg: { root: [
234
+ "h-11 gap-2 rounded-control px-4 py-0 text-subhead",
235
+ "has-data-[icon=inline-start]:pl-3.5 has-data-[icon=inline-end]:pr-3.5",
236
+ "[&_svg:not([class*='size-'])]:size-[18px] **:data-icon:size-[1em]"
237
+ ] },
238
+ xl: { root: ["h-13 gap-2 rounded-control px-5 py-0 text-body", "[&_svg:not([class*='size-'])]:size-[18px] **:data-icon:size-[1em]"] },
239
+ inline: { root: ["h-auto gap-1 border-0 p-0 align-baseline leading-[inherit] whitespace-normal", "**:data-icon:size-[1em]"] },
240
+ "icon-xs": { root: iconMd },
241
+ "icon-sm": { root: iconMd },
242
+ "icon-md": { root: iconMd },
243
+ "icon-lg": { root: "size-11 rounded-control p-0 [&_svg:not([class*='size-'])]:size-[22px]" }
244
+ }
245
+ },
246
+ defaultVariants: {
247
+ variant: "default",
248
+ size: "md"
249
+ },
250
+ compoundVariants: [
251
+ {
252
+ variant: "link",
253
+ class: { root: "px-0" }
254
+ },
255
+ {
256
+ variant: "ghost",
257
+ size: [
258
+ "icon-xs",
259
+ "icon-sm",
260
+ "icon-md",
261
+ "icon-lg"
262
+ ],
263
+ class: { root: ["disabled:border-transparent disabled:bg-transparent", "aria-disabled:border-transparent aria-disabled:bg-transparent"] }
264
+ },
265
+ {
266
+ variant: "on-frame",
267
+ size: [
268
+ "xs",
269
+ "sm",
270
+ "md"
271
+ ],
272
+ class: { root: "h-9 px-2.5 text-subhead after:-inset-y-1" }
273
+ },
274
+ {
275
+ variant: "on-frame",
276
+ size: [
277
+ "icon-xs",
278
+ "icon-sm",
279
+ "icon-md"
280
+ ],
281
+ class: { root: "size-9 after:-inset-1 [&_svg:not([class*='size-'])]:size-5" }
282
+ }
283
+ ]
284
+ });
285
+ function Button$1({ variant, size, loading = false, loadingLabel = "Loading", disabled, className, children, render, nativeButton, ...props }) {
286
+ const { root, content, loadingIndicator } = buttonVariants({
287
+ variant,
288
+ size
289
+ });
290
+ return /* @__PURE__ */ jsxs(Button, {
291
+ ...props,
292
+ render,
293
+ nativeButton: nativeButton ?? defaultNativeButton(render),
294
+ "data-slot": "button",
295
+ className: root({ className }),
296
+ "data-loading": loading ? "true" : void 0,
297
+ disabled: disabled || loading,
298
+ ...loading ? { "aria-disabled": true } : {},
299
+ children: [loading ? /* @__PURE__ */ jsx("span", {
300
+ "data-slot": "button-loading-indicator",
301
+ className: loadingIndicator(),
302
+ children: /* @__PURE__ */ jsx(Spinner, { "aria-label": loadingLabel })
303
+ }) : null, /* @__PURE__ */ jsx("span", {
304
+ "data-slot": "button-content",
305
+ "data-loading": loading ? "true" : void 0,
306
+ className: content(),
307
+ children
308
+ })]
309
+ });
310
+ }
311
+ //#endregion
312
+ //#region src/components/dialog/dialog.tsx
313
+ const dialog = tv$1({
314
+ slots: {
315
+ overlay: ["fixed inset-0 z-50 bg-layer-backdrop"],
316
+ content: [
317
+ "fixed top-1/2 left-1/2 z-50 flex w-[calc(100%-2rem)] -translate-1/2 flex-col",
318
+ "max-h-[calc(100dvh-2rem)] outline-none",
319
+ "overflow-clip rounded-dialog bg-layer-popover text-foreground",
320
+ "shadow-float ring-1 ring-line-seam"
321
+ ],
322
+ header: ["grid shrink-0 grid-cols-[minmax(0,1fr)_max-content] items-center min-w-0", "gap-2 px-5 pt-5"],
323
+ body: [
324
+ "min-w-0 flex-1 overflow-y-auto",
325
+ "px-5 pt-1.5 pb-5 first:pt-5",
326
+ "font-sans text-subhead text-foreground-muted"
327
+ ],
328
+ footer: ["flex shrink-0 items-center justify-end", "gap-2 px-5 pb-5 first:pt-5 [[data-slot=dialog-header]+&]:pt-5"],
329
+ title: ["m-0 min-w-0 text-foreground", "font-sans text-headline font-bold"],
330
+ description: ["m-0", "font-sans text-subhead text-foreground-muted"]
331
+ },
332
+ variants: {
333
+ size: {
334
+ sm: { content: ["max-w-sm"] },
335
+ md: { content: ["max-w-md"] },
336
+ lg: { content: ["max-w-lg"] },
337
+ wide: { content: ["max-w-4xl h-[min(760px,calc(100dvh-2rem))]"] }
338
+ },
339
+ bar: {
340
+ false: {},
341
+ true: {
342
+ header: ["flex h-14 shrink-0 items-center gap-2 border-b px-5 py-0", "border-line-seam pt-0 [&>[data-slot=dialog-close]]:my-0"],
343
+ body: ["flex min-h-0 flex-1 overflow-hidden p-0", "px-0 pt-0 pb-0 first:pt-0 text-foreground"],
344
+ footer: ["shrink-0 border-t px-5 py-3", "border-line-seam pt-3 pb-3 first:pt-3 [[data-slot=dialog-header]+&]:pt-3"]
345
+ }
346
+ },
347
+ layer: {
348
+ 0: {
349
+ overlay: [],
350
+ content: []
351
+ },
352
+ 1: {
353
+ overlay: ["z-60"],
354
+ content: ["z-60"]
355
+ }
356
+ }
357
+ },
358
+ defaultVariants: {
359
+ size: "md",
360
+ bar: false
361
+ }
362
+ });
363
+ function Dialog$1(props) {
364
+ return /* @__PURE__ */ jsx(Dialog.Root, {
365
+ "data-slot": "dialog",
366
+ ...props
367
+ });
368
+ }
369
+ function DialogTrigger(props) {
370
+ return /* @__PURE__ */ jsx(Dialog.Trigger, {
371
+ "data-slot": "dialog-trigger",
372
+ ...props
373
+ });
374
+ }
375
+ function DialogPortal(props) {
376
+ return /* @__PURE__ */ jsx(Dialog.Portal, {
377
+ "data-slot": "dialog-portal",
378
+ ...useThemeScopeProps(props)
379
+ });
380
+ }
381
+ function DialogOverlay({ className, layer, ...props }) {
382
+ const { overlay } = dialog({ layer });
383
+ return /* @__PURE__ */ jsx(Dialog.Backdrop, {
384
+ "data-slot": "dialog-overlay",
385
+ className: overlay({ className }),
386
+ ...props
387
+ });
388
+ }
389
+ function DialogContent({ className, children, portalProps, overlay, size, layer, ...props }) {
390
+ const { content } = dialog({
391
+ size,
392
+ layer
393
+ });
394
+ const overlayProps = typeof overlay === "object" ? overlay : {};
395
+ return /* @__PURE__ */ jsxs(DialogPortal, {
396
+ ...portalProps,
397
+ children: [overlay === false ? null : /* @__PURE__ */ jsx(DialogOverlay, {
398
+ layer,
399
+ ...overlayProps
400
+ }), /* @__PURE__ */ jsx(Dialog.Popup, {
401
+ "data-slot": "dialog-content",
402
+ className: content({ className }),
403
+ ...props,
404
+ children
405
+ })]
406
+ });
407
+ }
408
+ function DialogClose({ className, variant, size, children, render, "aria-label": ariaLabel, ...props }) {
409
+ if (render) return /* @__PURE__ */ jsx(Dialog.Close, {
410
+ "data-slot": "dialog-close",
411
+ render,
412
+ "aria-label": ariaLabel,
413
+ ...props,
414
+ children
415
+ });
416
+ return /* @__PURE__ */ jsx(Dialog.Close, {
417
+ "data-slot": "dialog-close",
418
+ render: /* @__PURE__ */ jsx(Button$1, {
419
+ variant: variant ?? "ghost",
420
+ size: size ?? "icon-md",
421
+ "aria-label": ariaLabel ?? "Close",
422
+ className: cn("-my-1.5 -mr-1.5", className)
423
+ }),
424
+ ...props,
425
+ children: children ?? /* @__PURE__ */ jsx(X, { className: "size-4.5" })
426
+ });
427
+ }
428
+ function DialogHeader({ className, bar = false, ...props }) {
429
+ const { header } = dialog({ bar });
430
+ return /* @__PURE__ */ jsx("div", {
431
+ "data-slot": "dialog-header",
432
+ className: header({ className }),
433
+ ...props
434
+ });
435
+ }
436
+ function DialogBody({ className, bar = false, ...props }) {
437
+ const { body } = dialog({ bar });
438
+ return /* @__PURE__ */ jsx("div", {
439
+ "data-slot": "dialog-body",
440
+ className: body({ className }),
441
+ ...props
442
+ });
443
+ }
444
+ function DialogFooter({ className, bar = false, ...props }) {
445
+ const { footer } = dialog({ bar });
446
+ return /* @__PURE__ */ jsx("div", {
447
+ "data-slot": "dialog-footer",
448
+ className: footer({ className }),
449
+ ...props
450
+ });
451
+ }
452
+ function DialogTitle({ className, ...props }) {
453
+ const { title } = dialog();
454
+ return /* @__PURE__ */ jsx(Dialog.Title, {
455
+ "data-slot": "dialog-title",
456
+ className: title({ className }),
457
+ ...props
458
+ });
459
+ }
460
+ function DialogDescription({ className, ...props }) {
461
+ const { description } = dialog();
462
+ return /* @__PURE__ */ jsx(Dialog.Description, {
463
+ "data-slot": "dialog-description",
464
+ className: description({ className }),
465
+ ...props
466
+ });
467
+ }
468
+ const dialogSurface = tv$1({ slots: { root: [
469
+ "flex min-w-0 flex-col outline-none",
470
+ "overflow-clip rounded-dialog bg-layer-popover text-foreground",
471
+ "shadow-float ring-1 ring-line-seam"
472
+ ] } });
473
+ /**
474
+ * The dialog's frame — the popover layer, the dialog radius, the seam ring
475
+ * and the float shadow — for a centred modal whose lifecycle the app owns
476
+ * (its own backdrop, Escape and focus handling). It neither positions nor
477
+ * animates itself: the host centres it, and a centred modal has no motion.
478
+ * DialogContent draws the same frame for a Base UI dialog.
479
+ */
480
+ function DialogSurface({ className, render, ...props }) {
481
+ const { root } = dialogSurface();
482
+ return useRender({
483
+ defaultTagName: "div",
484
+ render,
485
+ props: mergeProps({
486
+ "data-slot": "dialog-surface",
487
+ className: root({ className })
488
+ }, props)
489
+ });
490
+ }
491
+ const dialogNav = tv$1({ slots: { root: ["flex shrink-0 flex-col overflow-y-auto", "w-52 gap-0.5 border-r border-line-seam p-2 max-md:hidden"] } });
492
+ /** The section list of a wide (`size="wide"`) dialog, inside a `bar` body. */
493
+ function DialogNav({ className, render, ...props }) {
494
+ const { root } = dialogNav();
495
+ return useRender({
496
+ defaultTagName: "nav",
497
+ render,
498
+ props: mergeProps({
499
+ "data-slot": "dialog-nav",
500
+ className: root({ className })
501
+ }, props)
502
+ });
503
+ }
504
+ //#endregion
505
+ export { tv$1 as S, defaultNativeButton as _, DialogDescription as a, useTheme as b, DialogNav as c, DialogSurface as d, DialogTitle as f, Spinner as g, buttonVariants as h, DialogContent as i, DialogOverlay as l, Button$1 as m, DialogBody as n, DialogFooter as o, DialogTrigger as p, DialogClose as r, DialogHeader as s, Dialog$1 as t, DialogPortal as u, resolveThemeScopeProps as v, ThemeStateContext as x, useThemeScopeProps as y };
package/dist/fonts.css ADDED
@@ -0,0 +1,13 @@
1
+ @import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300..700&family=Space+Mono:wght@400;700&display=swap");
2
+
3
+ /* Raft Design System: Space Grotesk is what people say, Space Mono is what
4
+ machines write. CJK falls back to PingFang / Source Han Sans. */
5
+ :where(:root) {
6
+ --heading-font:
7
+ "Space Grotesk", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC",
8
+ system-ui, sans-serif;
9
+ --sans-font:
10
+ "Space Grotesk", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC",
11
+ system-ui, sans-serif;
12
+ --mono-font: "Space Mono", ui-monospace, "SF Mono", Menlo, monospace;
13
+ }