beez-ui 2.5.0 → 2.6.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 (92) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/THIRD_PARTY_NOTICES.md +1 -1
  3. package/dist/components/alert-dialog.d.ts +15 -4
  4. package/dist/components/alert-dialog.js +84 -44
  5. package/dist/components/alert.d.ts +30 -9
  6. package/dist/components/alert.js +360 -39
  7. package/dist/components/avatar.d.ts +33 -10
  8. package/dist/components/avatar.js +110 -30
  9. package/dist/components/badge.d.ts +39 -7
  10. package/dist/components/badge.js +348 -24
  11. package/dist/components/calendar.d.ts +29 -2
  12. package/dist/components/calendar.js +1035 -223
  13. package/dist/components/card.d.ts +17 -1
  14. package/dist/components/card.js +34 -8
  15. package/dist/components/carousel.d.ts +29 -2
  16. package/dist/components/carousel.js +471 -90
  17. package/dist/components/checkbox.d.ts +13 -2
  18. package/dist/components/checkbox.js +301 -41
  19. package/dist/components/dialog-surface.d.ts +27 -0
  20. package/dist/components/dialog-surface.js +137 -0
  21. package/dist/components/dialog.d.ts +21 -4
  22. package/dist/components/dialog.js +163 -96
  23. package/dist/components/dropdown-menu.d.ts +30 -16
  24. package/dist/components/dropdown-menu.js +139 -83
  25. package/dist/components/hover-card.d.ts +46 -3
  26. package/dist/components/hover-card.js +423 -60
  27. package/dist/components/pagination.d.ts +32 -14
  28. package/dist/components/pagination.js +136 -59
  29. package/dist/components/popover.d.ts +14 -5
  30. package/dist/components/popover.js +78 -36
  31. package/dist/components/radio-group.d.ts +19 -3
  32. package/dist/components/radio-group.js +400 -57
  33. package/dist/components/select.d.ts +17 -6
  34. package/dist/components/select.js +83 -71
  35. package/dist/components/sheet.js +37 -26
  36. package/dist/components/sidebar.js +11 -0
  37. package/dist/components/skeleton.d.ts +19 -5
  38. package/dist/components/skeleton.js +434 -14
  39. package/dist/components/switch.d.ts +14 -4
  40. package/dist/components/switch.js +424 -40
  41. package/dist/components/tabs.d.ts +38 -5
  42. package/dist/components/tabs.js +564 -97
  43. package/dist/components/themed-toaster.d.ts +6 -2
  44. package/dist/components/themed-toaster.js +80 -50
  45. package/dist/components/tooltip.d.ts +33 -2
  46. package/dist/components/tooltip.js +197 -69
  47. package/dist/constants/alert.d.ts +12 -0
  48. package/dist/constants/alert.js +9 -0
  49. package/dist/constants/avatar.d.ts +10 -0
  50. package/dist/constants/avatar.js +7 -0
  51. package/dist/constants/badge.d.ts +6 -0
  52. package/dist/constants/badge.js +6 -0
  53. package/dist/constants/calendar.d.ts +24 -0
  54. package/dist/constants/calendar.js +22 -0
  55. package/dist/constants/carousel.d.ts +37 -0
  56. package/dist/constants/carousel.js +53 -0
  57. package/dist/constants/checkbox.d.ts +17 -0
  58. package/dist/constants/checkbox.js +17 -0
  59. package/dist/constants/dialog.d.ts +6 -0
  60. package/dist/constants/dialog.js +6 -0
  61. package/dist/constants/dropdown-menu.d.ts +5 -0
  62. package/dist/constants/dropdown-menu.js +5 -0
  63. package/dist/constants/hover-card.d.ts +37 -0
  64. package/dist/constants/hover-card.js +85 -0
  65. package/dist/constants/pagination.d.ts +9 -0
  66. package/dist/constants/pagination.js +9 -0
  67. package/dist/constants/popover.d.ts +7 -0
  68. package/dist/constants/popover.js +39 -0
  69. package/dist/constants/radio-group.d.ts +10 -0
  70. package/dist/constants/radio-group.js +10 -0
  71. package/dist/constants/select.d.ts +3 -0
  72. package/dist/constants/select.js +3 -0
  73. package/dist/constants/skeleton.d.ts +17 -0
  74. package/dist/constants/skeleton.js +17 -0
  75. package/dist/constants/switch.d.ts +44 -0
  76. package/dist/constants/switch.js +49 -0
  77. package/dist/constants/tabs.d.ts +17 -0
  78. package/dist/constants/tabs.js +17 -0
  79. package/dist/constants/toast.d.ts +3 -0
  80. package/dist/constants/toast.js +3 -0
  81. package/dist/constants/tooltip.d.ts +13 -0
  82. package/dist/constants/tooltip.js +52 -0
  83. package/dist/lib/toast-layer.d.ts +24 -0
  84. package/dist/lib/toast-layer.js +76 -0
  85. package/dist/motion/arc-floating-slot.d.ts +40 -0
  86. package/dist/motion/arc-floating-slot.js +167 -0
  87. package/dist/motion/glide-indicator.d.ts +6 -7
  88. package/dist/motion/glide-indicator.js +5 -3
  89. package/dist/motion/overlay-warmth.d.ts +24 -0
  90. package/dist/motion/overlay-warmth.js +70 -0
  91. package/dist/styles.css +1 -1
  92. package/package.json +1 -1
@@ -1,4 +1,15 @@
1
- import * as React from "react";
1
+ import type { ComponentProps } from "react";
2
2
  import { Checkbox as CheckboxPrimitive } from "radix-ui";
3
- declare function Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxPrimitive.Root>): React.JSX.Element;
3
+ export type CheckboxProps = ComponentProps<typeof CheckboxPrimitive.Root> & {
4
+ /** Visible label beside the box, tied to it with `htmlFor`. */
5
+ label?: string;
6
+ /** Helper copy under the label, linked through `aria-describedby`. */
7
+ description?: string;
8
+ };
9
+ /**
10
+ * A choice that can be on, off or indeterminate, controlled or uncontrolled like Radix's checkbox.
11
+ * @param checkboxProps - Every Radix checkbox prop, including `ref`, plus optional Arc `label` and `description`.
12
+ * @returns The labelled field when `label` or `description` is passed, otherwise the bare control.
13
+ */
14
+ declare function Checkbox({ className, label, description, id, checked, defaultChecked, onCheckedChange, "aria-describedby": ariaDescribedBy, ...props }: CheckboxProps): import("react").JSX.Element;
4
15
  export { Checkbox };
@@ -1,64 +1,324 @@
1
1
  "use client";
2
2
  import { c as _c } from "react/compiler-runtime";
3
- import * as React from "react";
3
+ /**
4
+ * Arc's Checkbox (https://uiarc.dev, MIT License, see THIRD_PARTY_NOTICES.md): an 18px square whose fill springs in
5
+ * while the check draws itself, and whose check morphs into the dash of the indeterminate state instead of swapping.
6
+ * Only the square answers a press, so the hit area and the label never move. With a `label` or `description` it renders
7
+ * Arc's labelled field; without them it renders the bare control, for rows, tables and forms that place their own
8
+ * label.
9
+ */
10
+ import { useId, useState } from "react";
4
11
  import { Checkbox as CheckboxPrimitive } from "radix-ui";
5
- import { CheckIcon } from "lucide-react";
6
- import { MotionSlot } from "../motion/motion-slot.js";
12
+ import { motion } from "motion/react";
13
+ import { CHECKBOX_DESCRIPTION_ID_SUFFIX, CHECKBOX_FILL_HIDDEN_SCALE, CHECKBOX_MARK_PATH, CHECKBOX_MARK_STROKE_WIDTH, CHECKBOX_MARK_VIEW_BOX } from "../constants/checkbox.js";
14
+ import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
7
15
  import { cn } from "../lib/utils.js";
8
- import { jsx as _jsx } from "react/jsx-runtime";
16
+ import { ARC_DURATION, ARC_EASE, ARC_SPRING_MORPH, ARC_SPRING_SNAPPY } from "../motion/arc-tokens.js";
17
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
18
+ /**
19
+ * Arc's control recipe. The bare box keeps its 18px layout box and widens its hit area to 44px with a pseudo-element,
20
+ * so existing rows keep their spacing; the labelled field gives the box Arc's full control height instead. The square
21
+ * dips on press, hover answers only on hover-capable fine pointers, and keyboard focus uses the theme's outline.
22
+ */
23
+ const checkboxClassName = "peer group/checkbox relative grid shrink-0 cursor-pointer place-items-center rounded-(--radius-control) border-0 bg-transparent p-0 text-(--control-glyph) [-webkit-tap-highlight-color:transparent] group-has-disabled/field:opacity-50 disabled:cursor-not-allowed disabled:opacity-50 not-data-[labelled]:size-[18px] not-data-[labelled]:rounded-[5px] not-data-[labelled]:after:absolute not-data-[labelled]:after:-inset-[13px] data-[labelled]:size-(--control-height-md) hover-fine:data-[state=unchecked]:not-disabled:[&_[data-slot=checkbox-visual]]:border-text-muted active:not-disabled:[&_[data-slot=checkbox-visual]]:scale-95 active:not-disabled:[&_[data-slot=checkbox-visual]]:[transition:border-color_var(--duration-fast)_var(--ease-standard),scale_var(--duration-instant)_var(--ease-standard)] data-[state=checked]:[&_[data-slot=checkbox-visual]]:border-(--control-on) data-[state=indeterminate]:[&_[data-slot=checkbox-visual]]:border-(--control-on) aria-invalid:data-[state=unchecked]:[&_[data-slot=checkbox-visual]]:border-danger motion-reduce:[&_[data-slot=checkbox-visual]]:scale-100 motion-reduce:[&_[data-slot=checkbox-visual]]:transition-none";
24
+ /** The square: a border on the surface that the fill covers when checked. */
25
+ const visualClassName = "relative block size-[18px] rounded-[5px] border border-border-strong bg-surface [transition:border-color_var(--duration-fast)_var(--ease-standard),scale_var(--duration-spring)_var(--ease-spring)]";
26
+ /**
27
+ * A choice that can be on, off or indeterminate, controlled or uncontrolled like Radix's checkbox.
28
+ * @param checkboxProps - Every Radix checkbox prop, including `ref`, plus optional Arc `label` and `description`.
29
+ * @returns The labelled field when `label` or `description` is passed, otherwise the bare control.
30
+ */
9
31
  function Checkbox(t0) {
10
- const $ = _c(9);
32
+ const $ = _c(65);
33
+ let ariaDescribedBy;
34
+ let checked;
11
35
  let className;
36
+ let defaultChecked;
37
+ let description;
38
+ let id;
39
+ let label;
40
+ let onCheckedChange;
12
41
  let props;
13
42
  if ($[0] !== t0) {
14
- ({className, ...props} = t0);
43
+ ({className, label, description, id, checked, defaultChecked, onCheckedChange, "aria-describedby": ariaDescribedBy, ...props} = t0);
15
44
  $[0] = t0;
16
- $[1] = className;
17
- $[2] = props;
18
- } else {
19
- className = $[1];
20
- props = $[2];
21
- }
22
- let t1;
23
- if ($[3] !== className) {
24
- t1 = cn("peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input shadow-xs transition-[color,background-color,border-color,box-shadow] outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary", className);
45
+ $[1] = ariaDescribedBy;
46
+ $[2] = checked;
25
47
  $[3] = className;
26
- $[4] = t1;
48
+ $[4] = defaultChecked;
49
+ $[5] = description;
50
+ $[6] = id;
51
+ $[7] = label;
52
+ $[8] = onCheckedChange;
53
+ $[9] = props;
27
54
  } else {
28
- t1 = $[4];
55
+ ariaDescribedBy = $[1];
56
+ checked = $[2];
57
+ className = $[3];
58
+ defaultChecked = $[4];
59
+ description = $[5];
60
+ id = $[6];
61
+ label = $[7];
62
+ onCheckedChange = $[8];
63
+ props = $[9];
29
64
  }
65
+ const generatedId = useId();
66
+ const controlId = id ?? generatedId;
67
+ const descriptionId = `${controlId}-${CHECKBOX_DESCRIPTION_ID_SUFFIX}`;
68
+ const reduceMotion = usePrefersReducedMotion();
69
+ const [uncontrolledState, setUncontrolledState] = useState(defaultChecked ?? false);
70
+ const state = checked ?? uncontrolledState;
71
+ const isOn = state !== false;
72
+ const isField = Boolean(label || description);
73
+ const t1 = isOn ? ARC_DURATION.instant : ARC_DURATION.fast;
30
74
  let t2;
31
- if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
32
- t2 = /* @__PURE__ */ _jsx(MotionSlot, {
33
- kind: "check",
34
- children: /* @__PURE__ */ _jsx(CheckboxPrimitive.Indicator, {
35
- forceMount: true,
75
+ if ($[10] === Symbol.for("react.memo_cache_sentinel")) {
76
+ t2 = [...ARC_EASE.standard];
77
+ $[10] = t2;
78
+ } else {
79
+ t2 = $[10];
80
+ }
81
+ let t3;
82
+ if ($[11] !== t1) {
83
+ t3 = {
84
+ duration: t1,
85
+ ease: t2
86
+ };
87
+ $[11] = t1;
88
+ $[12] = t3;
89
+ } else {
90
+ t3 = $[12];
91
+ }
92
+ const fade = t3;
93
+ let t4;
94
+ if ($[13] !== ariaDescribedBy || $[14] !== description || $[15] !== descriptionId) {
95
+ t4 = [ariaDescribedBy, description ? descriptionId : undefined].filter(Boolean).join(" ") || undefined;
96
+ $[13] = ariaDescribedBy;
97
+ $[14] = description;
98
+ $[15] = descriptionId;
99
+ $[16] = t4;
100
+ } else {
101
+ t4 = $[16];
102
+ }
103
+ const describedBy = t4;
104
+ const t5 = isField ? "" : undefined;
105
+ let t6;
106
+ if ($[17] !== className) {
107
+ t6 = cn(checkboxClassName, className);
108
+ $[17] = className;
109
+ $[18] = t6;
110
+ } else {
111
+ t6 = $[18];
112
+ }
113
+ const t7 = isField ? controlId : id;
114
+ let t8;
115
+ if ($[19] !== checked || $[20] !== onCheckedChange) {
116
+ t8 = (nextState) => {
117
+ if (checked === undefined) {
118
+ setUncontrolledState(nextState);
119
+ }
120
+ onCheckedChange?.(nextState);
121
+ };
122
+ $[19] = checked;
123
+ $[20] = onCheckedChange;
124
+ $[21] = t8;
125
+ } else {
126
+ t8 = $[21];
127
+ }
128
+ const t9 = isOn ? 1 : 0;
129
+ const t10 = isOn ? 1 : CHECKBOX_FILL_HIDDEN_SCALE;
130
+ let t11;
131
+ if ($[22] !== t10 || $[23] !== t9) {
132
+ t11 = {
133
+ opacity: t9,
134
+ scale: t10
135
+ };
136
+ $[22] = t10;
137
+ $[23] = t9;
138
+ $[24] = t11;
139
+ } else {
140
+ t11 = $[24];
141
+ }
142
+ let t12;
143
+ if ($[25] !== fade || $[26] !== reduceMotion) {
144
+ t12 = reduceMotion ? { duration: 0 } : {
145
+ scale: ARC_SPRING_SNAPPY,
146
+ opacity: fade
147
+ };
148
+ $[25] = fade;
149
+ $[26] = reduceMotion;
150
+ $[27] = t12;
151
+ } else {
152
+ t12 = $[27];
153
+ }
154
+ let t13;
155
+ if ($[28] !== t11 || $[29] !== t12) {
156
+ t13 = /* @__PURE__ */ _jsx(motion.span, {
157
+ className: "absolute -inset-px rounded-[inherit] bg-(--control-on)",
158
+ initial: false,
159
+ animate: t11,
160
+ transition: t12
161
+ });
162
+ $[28] = t11;
163
+ $[29] = t12;
164
+ $[30] = t13;
165
+ } else {
166
+ t13 = $[30];
167
+ }
168
+ const t14 = state === "indeterminate" ? CHECKBOX_MARK_PATH.dash : CHECKBOX_MARK_PATH.check;
169
+ const t15 = isOn ? 1 : 0;
170
+ const t16 = isOn ? 1 : 0;
171
+ let t17;
172
+ if ($[31] !== t14 || $[32] !== t15 || $[33] !== t16) {
173
+ t17 = {
174
+ d: t14,
175
+ pathLength: t15,
176
+ opacity: t16
177
+ };
178
+ $[31] = t14;
179
+ $[32] = t15;
180
+ $[33] = t16;
181
+ $[34] = t17;
182
+ } else {
183
+ t17 = $[34];
184
+ }
185
+ let t18;
186
+ if ($[35] !== fade || $[36] !== reduceMotion) {
187
+ t18 = reduceMotion ? { duration: 0 } : {
188
+ d: ARC_SPRING_MORPH,
189
+ pathLength: ARC_SPRING_SNAPPY,
190
+ opacity: fade
191
+ };
192
+ $[35] = fade;
193
+ $[36] = reduceMotion;
194
+ $[37] = t18;
195
+ } else {
196
+ t18 = $[37];
197
+ }
198
+ let t19;
199
+ if ($[38] !== t17 || $[39] !== t18) {
200
+ t19 = /* @__PURE__ */ _jsx(CheckboxPrimitive.Indicator, {
201
+ forceMount: true,
202
+ asChild: true,
203
+ children: /* @__PURE__ */ _jsx("svg", {
36
204
  "data-slot": "checkbox-indicator",
37
- className: "grid place-content-center text-current transition-none data-unchecked:opacity-0 [&>svg]:size-3.5",
38
- children: /* @__PURE__ */ _jsx(CheckIcon, {})
205
+ className: "absolute -inset-px size-[18px] overflow-visible",
206
+ viewBox: CHECKBOX_MARK_VIEW_BOX,
207
+ fill: "none",
208
+ focusable: "false",
209
+ children: /* @__PURE__ */ _jsx(motion.path, {
210
+ initial: false,
211
+ animate: t17,
212
+ transition: t18,
213
+ stroke: "currentColor",
214
+ strokeWidth: CHECKBOX_MARK_STROKE_WIDTH,
215
+ strokeLinecap: "round",
216
+ strokeLinejoin: "round"
217
+ })
39
218
  })
40
219
  });
41
- $[5] = t2;
220
+ $[38] = t17;
221
+ $[39] = t18;
222
+ $[40] = t19;
42
223
  } else {
43
- t2 = $[5];
224
+ t19 = $[40];
44
225
  }
45
- let t3;
46
- if ($[6] !== props || $[7] !== t1) {
47
- t3 = /* @__PURE__ */ _jsx(MotionSlot, {
48
- kind: "toggle",
49
- children: /* @__PURE__ */ _jsx(CheckboxPrimitive.Root, {
50
- "data-slot": "checkbox",
51
- className: t1,
52
- ...props,
53
- children: t2
54
- })
226
+ let t20;
227
+ if ($[41] !== t13 || $[42] !== t19) {
228
+ t20 = /* @__PURE__ */ _jsxs("span", {
229
+ "data-slot": "checkbox-visual",
230
+ className: visualClassName,
231
+ "aria-hidden": "true",
232
+ children: [t13, t19]
233
+ });
234
+ $[41] = t13;
235
+ $[42] = t19;
236
+ $[43] = t20;
237
+ } else {
238
+ t20 = $[43];
239
+ }
240
+ let t21;
241
+ if ($[44] !== describedBy || $[45] !== props || $[46] !== state || $[47] !== t20 || $[48] !== t5 || $[49] !== t6 || $[50] !== t7 || $[51] !== t8) {
242
+ t21 = /* @__PURE__ */ _jsx(CheckboxPrimitive.Root, {
243
+ "data-slot": "checkbox",
244
+ "data-labelled": t5,
245
+ className: t6,
246
+ ...props,
247
+ id: t7,
248
+ checked: state,
249
+ "aria-describedby": describedBy,
250
+ onCheckedChange: t8,
251
+ children: t20
252
+ });
253
+ $[44] = describedBy;
254
+ $[45] = props;
255
+ $[46] = state;
256
+ $[47] = t20;
257
+ $[48] = t5;
258
+ $[49] = t6;
259
+ $[50] = t7;
260
+ $[51] = t8;
261
+ $[52] = t21;
262
+ } else {
263
+ t21 = $[52];
264
+ }
265
+ const control = t21;
266
+ if (!isField) {
267
+ return control;
268
+ }
269
+ let t22;
270
+ if ($[53] !== controlId || $[54] !== label) {
271
+ t22 = label ? /* @__PURE__ */ _jsx("label", {
272
+ htmlFor: controlId,
273
+ "data-slot": "checkbox-label",
274
+ className: "cursor-pointer text-sm leading-(--leading-body) font-medium text-foreground",
275
+ children: label
276
+ }) : null;
277
+ $[53] = controlId;
278
+ $[54] = label;
279
+ $[55] = t22;
280
+ } else {
281
+ t22 = $[55];
282
+ }
283
+ let t23;
284
+ if ($[56] !== description || $[57] !== descriptionId) {
285
+ t23 = description ? /* @__PURE__ */ _jsx("span", {
286
+ id: descriptionId,
287
+ "data-slot": "checkbox-description",
288
+ className: "text-xs leading-(--leading-body) text-text-muted",
289
+ children: description
290
+ }) : null;
291
+ $[56] = description;
292
+ $[57] = descriptionId;
293
+ $[58] = t23;
294
+ } else {
295
+ t23 = $[58];
296
+ }
297
+ let t24;
298
+ if ($[59] !== t22 || $[60] !== t23) {
299
+ t24 = /* @__PURE__ */ _jsxs("div", {
300
+ className: "ml-px grid min-w-0 gap-0.5 pt-[calc((var(--control-height-md)-var(--text-sm)*var(--leading-body))/2)]",
301
+ children: [t22, t23]
302
+ });
303
+ $[59] = t22;
304
+ $[60] = t23;
305
+ $[61] = t24;
306
+ } else {
307
+ t24 = $[61];
308
+ }
309
+ let t25;
310
+ if ($[62] !== control || $[63] !== t24) {
311
+ t25 = /* @__PURE__ */ _jsxs("div", {
312
+ "data-slot": "checkbox-field",
313
+ className: "inline-flex min-w-0 items-start",
314
+ children: [control, t24]
55
315
  });
56
- $[6] = props;
57
- $[7] = t1;
58
- $[8] = t3;
316
+ $[62] = control;
317
+ $[63] = t24;
318
+ $[64] = t25;
59
319
  } else {
60
- t3 = $[8];
320
+ t25 = $[64];
61
321
  }
62
- return t3;
322
+ return t25;
63
323
  }
64
324
  export { Checkbox };
@@ -0,0 +1,27 @@
1
+ import type { ReactNode } from "react";
2
+ /** Arc's overlay: a near-black scrim at 46% with a 7px backdrop blur where the engine supports it. */
3
+ export declare const dialogOverlayClassName = "fixed inset-0 isolate z-50 bg-[oklch(10%_0_0/0.46)] supports-backdrop-filter:backdrop-blur-[7px]";
4
+ /**
5
+ * Arc's panel: raised surface, hairline border, surface radius and floating shadow, padded on Arc's 24px step.
6
+ * Placement, width and scrolling stay with each dialog.
7
+ */
8
+ export declare const dialogSurfaceClassName = "z-50 gap-(--space-5) rounded-(--radius-surface) border border-border bg-surface-raised p-(--space-6) text-sm leading-(--leading-body) text-foreground shadow-(--shadow-floating) outline-none";
9
+ /** Edge-to-edge action row: bleeds through the panel padding and sits under a hairline like Arc's header divider. */
10
+ export declare const dialogFooterClassName = "-mx-(--space-6) -mb-(--space-6) flex flex-col-reverse gap-(--space-2) rounded-b-[calc(var(--radius-surface)-1px)] border-t border-border bg-surface-muted/50 px-(--space-6) py-(--space-4) sm:flex-row sm:justify-end";
11
+ /** Arc's title: body font at 18px, medium weight, body leading so a heading reset never shrinks it. */
12
+ export declare const dialogTitleClassName = "font-sans text-lg leading-(--leading-body) font-medium tracking-(--tracking-body) [overflow-wrap:anywhere]";
13
+ /** Arc's description: secondary text at 14px on body leading. */
14
+ export declare const dialogDescriptionClassName = "text-sm leading-(--leading-body) text-text-secondary [overflow-wrap:anywhere] *:[a]:underline *:[a]:underline-offset-3 hover-fine:*:[a]:text-foreground";
15
+ /**
16
+ * Arc's compact close button: 32px, bordered, half-tinted, quiet until a fine pointer hovers it. Press feedback comes
17
+ * from `ControlButton`.
18
+ */
19
+ export declare const dialogCloseButtonClassName = "size-(--space-8) rounded-(--radius-control) border-border bg-surface-muted/50 text-text-secondary hover-fine:bg-surface-muted hover-fine:text-foreground [&_svg:not([class*='size-'])]:size-4";
20
+ /**
21
+ * Arc's text swap: when a dialog's title or description text changes while it is open, the new copy rises in and the
22
+ * old copy lifts out. The first render is static, so server HTML and the opening frame never animate the copy.
23
+ * @param children - Copy of the title or description. Only plain text and numbers animate when they change.
24
+ * @param asChild - Whether the primitive renders the consumer's element, which must then receive it untouched.
25
+ * @returns The copy, wrapped for the swap when it is plain text.
26
+ */
27
+ export declare function withDialogSwapText(children: ReactNode, asChild?: boolean): ReactNode;
@@ -0,0 +1,137 @@
1
+ "use client";
2
+ import { c as _c } from "react/compiler-runtime";
3
+ /**
4
+ * Arc's Dialog surface (https://uiarc.dev, MIT License, see THIRD_PARTY_NOTICES.md), shared by `Dialog` and
5
+ * `AlertDialog`: the dimmed, blurred overlay, the raised panel with Arc's surface radius, border and floating shadow,
6
+ * the title and description type, the bordered close button and the text swap that animates a title or description
7
+ * changed while the dialog is open. Internal: the entrance stays beez-ui's center morph, not Arc's rise.
8
+ */
9
+ import { AnimatePresence, motion, useIsPresent } from "motion/react";
10
+ import { DIALOG_TEXT_SWAP_OFFSET_EM } from "../constants/dialog.js";
11
+ import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
12
+ import { ARC_BLUR, ARC_DURATION, ARC_EASE } from "../motion/arc-tokens.js";
13
+ import { jsx as _jsx } from "react/jsx-runtime";
14
+ /** Arc's overlay: a near-black scrim at 46% with a 7px backdrop blur where the engine supports it. */
15
+ export const dialogOverlayClassName = "fixed inset-0 isolate z-50 bg-[oklch(10%_0_0/0.46)] supports-backdrop-filter:backdrop-blur-[7px]";
16
+ /**
17
+ * Arc's panel: raised surface, hairline border, surface radius and floating shadow, padded on Arc's 24px step.
18
+ * Placement, width and scrolling stay with each dialog.
19
+ */
20
+ export const dialogSurfaceClassName = "z-50 gap-(--space-5) rounded-(--radius-surface) border border-border bg-surface-raised p-(--space-6) text-sm leading-(--leading-body) text-foreground shadow-(--shadow-floating) outline-none";
21
+ /** Edge-to-edge action row: bleeds through the panel padding and sits under a hairline like Arc's header divider. */
22
+ export const dialogFooterClassName = "-mx-(--space-6) -mb-(--space-6) flex flex-col-reverse gap-(--space-2) rounded-b-[calc(var(--radius-surface)-1px)] border-t border-border bg-surface-muted/50 px-(--space-6) py-(--space-4) sm:flex-row sm:justify-end";
23
+ /** Arc's title: body font at 18px, medium weight, body leading so a heading reset never shrinks it. */
24
+ export const dialogTitleClassName = "font-sans text-lg leading-(--leading-body) font-medium tracking-(--tracking-body) [overflow-wrap:anywhere]";
25
+ /** Arc's description: secondary text at 14px on body leading. */
26
+ export const dialogDescriptionClassName = "text-sm leading-(--leading-body) text-text-secondary [overflow-wrap:anywhere] *:[a]:underline *:[a]:underline-offset-3 hover-fine:*:[a]:text-foreground";
27
+ /**
28
+ * Arc's compact close button: 32px, bordered, half-tinted, quiet until a fine pointer hovers it. Press feedback comes
29
+ * from `ControlButton`.
30
+ */
31
+ export const dialogCloseButtonClassName = "size-(--space-8) rounded-(--radius-control) border-border bg-surface-muted/50 text-text-secondary hover-fine:bg-surface-muted hover-fine:text-foreground [&_svg:not([class*='size-'])]:size-4";
32
+ /**
33
+ * One version of the copy. While it lifts out it turns inert and hidden from assistive technology, so the dialog's
34
+ * accessible name never reads the old and the new copy together.
35
+ * @param props - The copy to render and the ref `AnimatePresence` injects to pop the leaving copy out of layout.
36
+ * @returns The animated copy.
37
+ */
38
+ function DialogSwapTextItem(t0) {
39
+ const $ = _c(13);
40
+ const { children, ref } = t0;
41
+ const isPresent = useIsPresent();
42
+ const shouldReduceMotion = usePrefersReducedMotion();
43
+ const t1 = isPresent ? undefined : true;
44
+ const t2 = !isPresent || undefined;
45
+ let t3;
46
+ if ($[0] !== shouldReduceMotion) {
47
+ t3 = shouldReduceMotion ? false : {
48
+ opacity: 0,
49
+ y: `${DIALOG_TEXT_SWAP_OFFSET_EM.enter}em`,
50
+ filter: `blur(${ARC_BLUR.soft}px)`
51
+ };
52
+ $[0] = shouldReduceMotion;
53
+ $[1] = t3;
54
+ } else {
55
+ t3 = $[1];
56
+ }
57
+ let t4;
58
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
59
+ t4 = {
60
+ opacity: 1,
61
+ y: 0,
62
+ filter: "blur(0px)"
63
+ };
64
+ $[2] = t4;
65
+ } else {
66
+ t4 = $[2];
67
+ }
68
+ let t5;
69
+ if ($[3] !== shouldReduceMotion) {
70
+ t5 = shouldReduceMotion ? {
71
+ opacity: 0,
72
+ transition: { duration: 0 }
73
+ } : {
74
+ opacity: 0,
75
+ y: `${DIALOG_TEXT_SWAP_OFFSET_EM.exit}em`,
76
+ filter: `blur(${ARC_BLUR.subtle}px)`,
77
+ transition: {
78
+ duration: ARC_DURATION.fast,
79
+ ease: [...ARC_EASE.standard]
80
+ }
81
+ };
82
+ $[3] = shouldReduceMotion;
83
+ $[4] = t5;
84
+ } else {
85
+ t5 = $[4];
86
+ }
87
+ let t6;
88
+ if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
89
+ t6 = {
90
+ duration: ARC_DURATION.standard,
91
+ ease: [...ARC_EASE.enter]
92
+ };
93
+ $[5] = t6;
94
+ } else {
95
+ t6 = $[5];
96
+ }
97
+ let t7;
98
+ if ($[6] !== children || $[7] !== ref || $[8] !== t1 || $[9] !== t2 || $[10] !== t3 || $[11] !== t5) {
99
+ t7 = /* @__PURE__ */ _jsx(motion.span, {
100
+ ref,
101
+ "data-slot": "dialog-swap-text",
102
+ className: "block",
103
+ "aria-hidden": t1,
104
+ inert: t2,
105
+ initial: t3,
106
+ animate: t4,
107
+ exit: t5,
108
+ transition: t6,
109
+ children
110
+ });
111
+ $[6] = children;
112
+ $[7] = ref;
113
+ $[8] = t1;
114
+ $[9] = t2;
115
+ $[10] = t3;
116
+ $[11] = t5;
117
+ $[12] = t7;
118
+ } else {
119
+ t7 = $[12];
120
+ }
121
+ return t7;
122
+ }
123
+ /**
124
+ * Arc's text swap: when a dialog's title or description text changes while it is open, the new copy rises in and the
125
+ * old copy lifts out. The first render is static, so server HTML and the opening frame never animate the copy.
126
+ * @param children - Copy of the title or description. Only plain text and numbers animate when they change.
127
+ * @param asChild - Whether the primitive renders the consumer's element, which must then receive it untouched.
128
+ * @returns The copy, wrapped for the swap when it is plain text.
129
+ */
130
+ export function withDialogSwapText(children, asChild = false) {
131
+ if (asChild || typeof children !== "string" && typeof children !== "number") return children;
132
+ return /* @__PURE__ */ _jsx(AnimatePresence, {
133
+ mode: "popLayout",
134
+ initial: false,
135
+ children: /* @__PURE__ */ _jsx(DialogSwapTextItem, { children }, String(children))
136
+ });
137
+ }
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Arc's Dialog (https://uiarc.dev, MIT License, see THIRD_PARTY_NOTICES.md): a focused surface for decisions that need
3
+ * attention, on Arc's overlay, raised panel, title and description type and bordered close button, with Arc's swap of
4
+ * a title or description changed while open. It keeps beez-ui's composable parts, the center morph entrance and the
5
+ * viewport close button placement instead of Arc's single `title`/`description` content and rise entrance.
6
+ */
1
7
  import * as React from "react";
2
8
  import { Dialog as DialogPrimitive } from "radix-ui";
3
9
  declare function Dialog({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>): React.JSX.Element;
@@ -20,9 +26,15 @@ declare function DialogContent({ className, children, showCloseButton, closeButt
20
26
  showCloseButton?: boolean;
21
27
  closeButtonPlacement?: DialogCloseButtonPlacement;
22
28
  }): React.JSX.Element;
29
+ /**
30
+ * Stacks the title and description. While the panel shows its own close button, the header keeps Arc's gap to it so
31
+ * long copy never runs under the button.
32
+ * @param props - Native div properties and optional consumer overrides.
33
+ * @returns The header block.
34
+ */
23
35
  declare function DialogHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
24
36
  /**
25
- * Separates dialog actions with a bordered footer matching the content padding.
37
+ * Separates dialog actions with an edge-to-edge footer under a hairline, bleeding through the panel padding.
26
38
  * @param props - Primitive properties and optional consumer overrides.
27
39
  * @returns The styled primitive with its original interaction contract.
28
40
  */
@@ -30,10 +42,15 @@ declare function DialogFooter({ className, showCloseButton, children, ...props }
30
42
  showCloseButton?: boolean;
31
43
  }): React.JSX.Element;
32
44
  /**
33
- * Renders dialog headings with the shared font at the compact default size.
45
+ * Renders the dialog heading in Arc's title type. Plain text that changes while open swaps with Arc's rise.
46
+ * @param props - Primitive properties and optional consumer overrides.
47
+ * @returns The styled primitive with its original interaction contract.
48
+ */
49
+ declare function DialogTitle({ className, children, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>): React.JSX.Element;
50
+ /**
51
+ * Renders the dialog description in Arc's secondary text. Plain text that changes while open swaps with Arc's rise.
34
52
  * @param props - Primitive properties and optional consumer overrides.
35
53
  * @returns The styled primitive with its original interaction contract.
36
54
  */
37
- declare function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>): React.JSX.Element;
38
- declare function DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>): React.JSX.Element;
55
+ declare function DialogDescription({ className, children, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>): React.JSX.Element;
39
56
  export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, };