@ctrl-ui/react 0.8.4 → 0.8.5

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 (134) hide show
  1. package/dist/audio-visualizer.js +1 -1
  2. package/dist/chat-composer-editor/extensions/mention.js +4 -0
  3. package/dist/chat-layout.d.ts +5 -0
  4. package/dist/chat-layout.js +61 -20
  5. package/dist/chat-message.d.ts +5 -0
  6. package/dist/chat-message.js +19 -2
  7. package/dist/context.js +0 -2
  8. package/dist/email/email-brand.d.ts +60 -0
  9. package/dist/email/email-brand.js +101 -0
  10. package/dist/email/email-code.d.ts +18 -0
  11. package/dist/email/email-code.js +172 -0
  12. package/dist/email/email-footer.d.ts +63 -0
  13. package/dist/email/email-footer.js +98 -0
  14. package/dist/email/email.d.ts +60 -11
  15. package/dist/email/email.js +155 -24
  16. package/dist/email/templates.d.ts +54 -9
  17. package/dist/email/templates.js +314 -116
  18. package/dist/email/theme.d.ts +13 -5
  19. package/dist/email/theme.js +30 -8
  20. package/dist/hooks/use-chat-message.d.ts +1 -0
  21. package/dist/hooks/use-chat-message.js +1 -0
  22. package/dist/hooks/use-chat-thread-scroll.d.ts +8 -0
  23. package/dist/hooks/use-chat-thread-scroll.js +66 -0
  24. package/dist/hooks/use-user-ask.d.ts +6 -4
  25. package/dist/hooks/use-user-ask.js +56 -17
  26. package/dist/inline-attachment.js +1 -1
  27. package/dist/knob-contracts/action-bar-knobs.d.ts +1 -1
  28. package/dist/knob-contracts/action-bar-knobs.js +1 -1
  29. package/dist/knob-contracts/activity-knobs.d.ts +1 -1
  30. package/dist/knob-contracts/activity-knobs.js +2 -1
  31. package/dist/knob-contracts/audio-visualizer-knobs.d.ts +1 -1
  32. package/dist/knob-contracts/audio-visualizer-knobs.js +1 -0
  33. package/dist/knob-contracts/chat-composer-attachment-knobs.d.ts +1 -1
  34. package/dist/knob-contracts/chat-composer-attachment-knobs.js +2 -0
  35. package/dist/knob-contracts/chat-composer-knobs.d.ts +1 -1
  36. package/dist/knob-contracts/chat-composer-knobs.js +1 -0
  37. package/dist/knob-contracts/chat-layout-knobs.d.ts +1 -1
  38. package/dist/knob-contracts/chat-layout-knobs.js +2 -1
  39. package/dist/knob-contracts/chat-message-knobs.d.ts +1 -1
  40. package/dist/knob-contracts/chat-message-knobs.js +3 -1
  41. package/dist/knob-contracts/context-knobs.d.ts +1 -1
  42. package/dist/knob-contracts/context-knobs.js +3 -0
  43. package/dist/knob-contracts/inline-attachment-knobs.d.ts +1 -1
  44. package/dist/knob-contracts/inline-attachment-knobs.js +4 -0
  45. package/dist/knob-contracts/inline-citation-knobs.d.ts +1 -1
  46. package/dist/knob-contracts/inline-citation-knobs.js +3 -1
  47. package/dist/knob-contracts/page-layout-knobs.d.ts +4 -0
  48. package/dist/knob-contracts/page-layout-knobs.js +15 -0
  49. package/dist/knob-contracts/table-of-contents-knobs.d.ts +1 -1
  50. package/dist/knob-contracts/table-of-contents-knobs.js +3 -3
  51. package/dist/knob-contracts/task-list-knobs.d.ts +1 -1
  52. package/dist/knob-contracts/task-list-knobs.js +4 -0
  53. package/dist/knob-contracts/user-ask-knobs.d.ts +1 -1
  54. package/dist/knob-contracts/user-ask-knobs.js +4 -0
  55. package/dist/lib/phone-input-format.js +1 -1
  56. package/dist/markdown-block.js +1 -1
  57. package/dist/styles/index.css +2 -1
  58. package/dist/styles/recipes/action-bar.css +37 -5
  59. package/dist/styles/recipes/activity.css +36 -3
  60. package/dist/styles/recipes/alert.css +2 -0
  61. package/dist/styles/recipes/audio-visualizer.css +8 -1
  62. package/dist/styles/recipes/button-group.css +8 -0
  63. package/dist/styles/recipes/button.css +15 -0
  64. package/dist/styles/recipes/calendar.css +21 -0
  65. package/dist/styles/recipes/card.css +2 -0
  66. package/dist/styles/recipes/chat-composer-attachment.css +33 -2
  67. package/dist/styles/recipes/chat-composer.css +16 -2
  68. package/dist/styles/recipes/chat-layout.css +25 -1
  69. package/dist/styles/recipes/chat-message.css +69 -2
  70. package/dist/styles/recipes/choice.css +12 -0
  71. package/dist/styles/recipes/code-diff.css +1 -0
  72. package/dist/styles/recipes/code.css +25 -0
  73. package/dist/styles/recipes/context.css +30 -18
  74. package/dist/styles/recipes/dynamic-notification-input.css +6 -0
  75. package/dist/styles/recipes/dynamic-notification.css +1 -0
  76. package/dist/styles/recipes/environment-variables.css +1 -0
  77. package/dist/styles/recipes/field-parts.css +2 -0
  78. package/dist/styles/recipes/field.css +6 -0
  79. package/dist/styles/recipes/gradient-editor.css +17 -0
  80. package/dist/styles/recipes/inline-attachment.css +57 -14
  81. package/dist/styles/recipes/inline-citation.css +44 -6
  82. package/dist/styles/recipes/item.css +3 -1
  83. package/dist/styles/recipes/markdown-block.css +1 -0
  84. package/dist/styles/recipes/markdown.css +7 -0
  85. package/dist/styles/recipes/page-layout.css +203 -0
  86. package/dist/styles/recipes/pagination.css +16 -0
  87. package/dist/styles/recipes/popup-drawer.css +3 -1
  88. package/dist/styles/recipes/popup-toast.css +2 -0
  89. package/dist/styles/recipes/popup.css +8 -12
  90. package/dist/styles/recipes/range.css +24 -2
  91. package/dist/styles/recipes/rich-tooltip.css +1 -0
  92. package/dist/styles/recipes/source-badge.css +20 -0
  93. package/dist/styles/recipes/table-of-contents.css +10 -10
  94. package/dist/styles/recipes/tabs.css +16 -0
  95. package/dist/styles/recipes/task-list.css +61 -8
  96. package/dist/styles/recipes/thread-rail.css +19 -13
  97. package/dist/styles/recipes/toolbar.css +21 -0
  98. package/dist/styles/recipes/transcript-divider.css +1 -0
  99. package/dist/styles/recipes/user-ask.css +59 -16
  100. package/dist/styles/theme.css +34 -0
  101. package/dist/thread-rail.js +1 -1
  102. package/dist/ui/alert-dialog.js +2 -2
  103. package/dist/ui/autocomplete.js +1 -1
  104. package/dist/ui/color-picker.js +4 -4
  105. package/dist/ui/combobox.js +1 -1
  106. package/dist/ui/command.d.ts +5 -3
  107. package/dist/ui/command.js +27 -3
  108. package/dist/ui/context-menu.js +2 -2
  109. package/dist/ui/dialog.js +2 -2
  110. package/dist/ui/drawer.js +2 -2
  111. package/dist/ui/dropdown-menu.js +1 -1
  112. package/dist/ui/dropzone.js +4 -1
  113. package/dist/ui/gradient-editor.js +2 -2
  114. package/dist/ui/hover-card.js +1 -1
  115. package/dist/ui/infinite-canvas.js +1 -0
  116. package/dist/ui/menubar.js +2 -2
  117. package/dist/ui/navigation-menu.js +1 -1
  118. package/dist/ui/number-field.js +1 -1
  119. package/dist/ui/page-layout.d.ts +44 -0
  120. package/dist/ui/page-layout.js +108 -0
  121. package/dist/ui/phone-input.js +4 -4
  122. package/dist/ui/popover.js +1 -1
  123. package/dist/ui/resizable.js +1 -1
  124. package/dist/ui/rich-tooltip.js +1 -1
  125. package/dist/ui/select.js +1 -1
  126. package/dist/ui/sheet.js +2 -2
  127. package/dist/ui/sidebar-resize-rail.js +1 -1
  128. package/dist/ui/slider.js +1 -1
  129. package/dist/ui/toast.js +2 -2
  130. package/dist/ui/tooltip.js +1 -1
  131. package/dist/ui/trigger-menu.js +1 -1
  132. package/dist/user-ask.d.ts +5 -3
  133. package/dist/user-ask.js +38 -13
  134. package/package.json +3 -2
@@ -43,7 +43,7 @@ function AlertDialogContent({ className, children, ...props }) {
43
43
  "data-popup-part": "backdrop",
44
44
  "data-skin": skin.id,
45
45
  "data-effects": controlEffectsAttribute(skin.effects),
46
- className: "fixed inset-0 z-[70]"
46
+ className: "fixed inset-0 z-(--z-overlay)"
47
47
  }), /* @__PURE__ */ jsx(AlertDialog$1.Popup, {
48
48
  "data-skin": skin.id,
49
49
  "data-effects": controlEffectsAttribute(skin.effects),
@@ -53,7 +53,7 @@ function AlertDialogContent({ className, children, ...props }) {
53
53
  "data-control-family": "popup",
54
54
  "data-popup-part": "surface",
55
55
  "data-surface": "modal",
56
- className: cn("fixed left-1/2 top-[12vh] z-[71] grid w-[calc(100%-2rem)] max-w-md -translate-x-1/2", className),
56
+ className: cn("fixed left-1/2 top-[12vh] z-(--z-modal) grid w-[calc(100%-2rem)] max-w-md -translate-x-1/2", className),
57
57
  ...props,
58
58
  children
59
59
  })] });
@@ -68,7 +68,7 @@ function AutocompleteContent({ className, children, sideOffset = 6, ...props })
68
68
  side: "bottom",
69
69
  align: "start",
70
70
  sideOffset,
71
- className: "z-[80]",
71
+ className: "z-(--z-popup)",
72
72
  children: /* @__PURE__ */ jsx(Autocomplete$1.Popup, {
73
73
  "data-control-ui": "autocomplete",
74
74
  "data-popup-kind": "autocomplete",
@@ -4,9 +4,9 @@ import { controlEffectsAttribute } from "../skin.js";
4
4
  import { useSkin } from "../skin-provider.js";
5
5
  import { Button } from "./button.js";
6
6
  import { Input } from "./input.js";
7
- import { useColorArea } from "../hooks/use-color-area.js";
8
7
  import { formatColor, getChannels, hsvaToRgba, parseColor, pointToHueSat, pointToSaturationValue, setChannel } from "../lib/color.js";
9
8
  import { TARGET_RATIO, contrastOf, fixColorForContrast, nextFixLevel, wcagLevels } from "../lib/contrast.js";
9
+ import { useColorArea } from "../hooks/use-color-area.js";
10
10
  import { NumberField, NumberFieldGroup, NumberFieldInput } from "./number-field.js";
11
11
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./select.js";
12
12
  import { createContext, useContext, useEffect, useRef, useState, useSyncExternalStore } from "react";
@@ -191,7 +191,7 @@ function ColorPickerContent({ className, children, side = "bottom", align = "cen
191
191
  side,
192
192
  align,
193
193
  sideOffset,
194
- className: "z-[80]",
194
+ className: "z-(--z-popup)",
195
195
  children: /* @__PURE__ */ jsx(Popover.Popup, {
196
196
  "data-control-ui": "color-picker",
197
197
  "data-popup-kind": "color-picker",
@@ -326,7 +326,7 @@ function ColorPickerHue({ className, "aria-label": ariaLabel, "aria-labelledby":
326
326
  step: 1,
327
327
  disabled,
328
328
  onValueChange: (next) => setHsva({ h: Array.isArray(next) ? next[0] : next }),
329
- className: cn("relative flex w-full touch-none select-none items-center", className),
329
+ className: cn("relative flex w-full touch-pan-y select-none items-center", className),
330
330
  ...props,
331
331
  children: /* @__PURE__ */ jsx(Slider.Control, {
332
332
  className: "flex h-full w-full items-center",
@@ -365,7 +365,7 @@ function ColorPickerAlpha({ className, "aria-label": ariaLabel, "aria-labelledby
365
365
  step: .01,
366
366
  disabled,
367
367
  onValueChange: (next) => setHsva({ a: Array.isArray(next) ? next[0] : next }),
368
- className: cn("relative flex w-full touch-none select-none items-center", className),
368
+ className: cn("relative flex w-full touch-pan-y select-none items-center", className),
369
369
  ...props,
370
370
  children: /* @__PURE__ */ jsx(Slider.Control, {
371
371
  className: "flex h-full w-full items-center",
@@ -88,7 +88,7 @@ function ComboboxContent({ className, children, sideOffset = 6, ...props }) {
88
88
  side: "bottom",
89
89
  align: "start",
90
90
  sideOffset,
91
- className: "z-[80]",
91
+ className: "z-(--z-popup)",
92
92
  children: /* @__PURE__ */ jsx(Combobox$1.Popup, {
93
93
  "data-control-ui": "combobox",
94
94
  "data-popup-kind": "combobox",
@@ -1,6 +1,6 @@
1
1
  import { PopupKnobStyle } from "../knob-contracts/popup-knobs.js";
2
2
  import { Dialog } from "./dialog.js";
3
- import { CSSProperties, ComponentProps } from "react";
3
+ import { CSSProperties, ComponentProps, ReactNode } from "react";
4
4
  import { Command as Command$1 } from "cmdk";
5
5
  //#region src/ui/command.d.ts
6
6
  export type CommandChrome = "standalone" | "embedded";
@@ -22,10 +22,12 @@ export declare function CommandInput({ className, ...props }: CommandInputProps)
22
22
  export declare function CommandList({ className, children, ...props }: ComponentProps<typeof Command$1.List> & {
23
23
  style?: CSSProperties & PopupKnobStyle;
24
24
  }): import("react").JSX.Element;
25
- export type CommandEmptyProps = Omit<ComponentProps<typeof Command$1.Empty>, "style"> & {
25
+ export type CommandEmptyProps = Omit<ComponentProps<typeof Command$1.Empty>, "style" | "title"> & {
26
26
  style?: CSSProperties & PopupKnobStyle;
27
+ title?: ReactNode;
28
+ description?: ReactNode;
27
29
  };
28
- export declare function CommandEmpty({ className, children, ...props }: CommandEmptyProps): import("react").JSX.Element;
30
+ export declare function CommandEmpty({ className, children, title, description, ...props }: CommandEmptyProps): import("react").JSX.Element;
29
31
  export type CommandGroupProps = Omit<ComponentProps<typeof Command$1.Group>, "style"> & {
30
32
  style?: CSSProperties & PopupKnobStyle;
31
33
  };
@@ -2,6 +2,7 @@
2
2
  import { cn } from "../lib/cn.js";
3
3
  import { ScrollArea } from "./scroll-area.js";
4
4
  import { popupItemStructureClasses } from "../surface-variants.js";
5
+ import { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "./empty.js";
5
6
  import { Dialog, DialogContent, DialogDescription, DialogTitle } from "./dialog.js";
6
7
  import { jsx, jsxs } from "react/jsx-runtime";
7
8
  import { Command as Command$1, useCommandState } from "cmdk";
@@ -20,7 +21,7 @@ function Command({ chrome = "standalone", className, ...props }) {
20
21
  ...props
21
22
  });
22
23
  }
23
- function CommandDialog({ title = "Command palette", description = "Search for a command to run...", children, className, commandProps, ...props }) {
24
+ function CommandDialog({ title = "Command palette", description = "Search for a command to run…", children, className, commandProps, ...props }) {
24
25
  return /* @__PURE__ */ jsx(Dialog, {
25
26
  ...props,
26
27
  children: /* @__PURE__ */ jsxs(DialogContent, {
@@ -121,7 +122,7 @@ function CommandList({ className, children, ...props }) {
121
122
  })
122
123
  });
123
124
  }
124
- function CommandEmpty({ className, children, ...props }) {
125
+ function CommandEmpty({ className, children, title = "No results found", description = "Try a different search term.", ...props }) {
125
126
  return /* @__PURE__ */ jsx(Command$1.Empty, {
126
127
  asChild: true,
127
128
  "data-control-ui": "command",
@@ -132,10 +133,33 @@ function CommandEmpty({ className, children, ...props }) {
132
133
  ...props,
133
134
  children: /* @__PURE__ */ jsx("div", {
134
135
  role: "status",
135
- children
136
+ children: children ?? /* @__PURE__ */ jsx(Empty, { children: /* @__PURE__ */ jsxs(EmptyHeader, { children: [
137
+ /* @__PURE__ */ jsx(EmptyMedia, { children: /* @__PURE__ */ jsx(CommandEmptyIcon, {}) }),
138
+ /* @__PURE__ */ jsx(EmptyTitle, { children: title }),
139
+ description ? /* @__PURE__ */ jsx(EmptyDescription, { children: description }) : null
140
+ ] }) })
136
141
  })
137
142
  });
138
143
  }
144
+ function CommandEmptyIcon() {
145
+ return /* @__PURE__ */ jsxs("svg", {
146
+ viewBox: "0 0 16 16",
147
+ "aria-hidden": "true",
148
+ fill: "none",
149
+ children: [/* @__PURE__ */ jsx("circle", {
150
+ cx: "7",
151
+ cy: "7",
152
+ r: "4.25",
153
+ stroke: "currentColor",
154
+ strokeWidth: "1.3"
155
+ }), /* @__PURE__ */ jsx("path", {
156
+ d: "m10.5 10.5 3 3",
157
+ stroke: "currentColor",
158
+ strokeWidth: "1.3",
159
+ strokeLinecap: "round"
160
+ })]
161
+ });
162
+ }
139
163
  function CommandGroup({ className, ...props }) {
140
164
  return /* @__PURE__ */ jsx(Command$1.Group, {
141
165
  "data-control-ui": "command",
@@ -39,7 +39,7 @@ function ContextMenuContent({ className, children, ...props }) {
39
39
  return /* @__PURE__ */ jsx(ContextMenu$1.Portal, { children: /* @__PURE__ */ jsx(ContextMenu$1.Positioner, {
40
40
  "data-skin": skin.id,
41
41
  "data-effects": controlEffectsAttribute(skin.effects),
42
- className: "z-[80]",
42
+ className: "z-(--z-popup)",
43
43
  children: /* @__PURE__ */ jsx(ContextMenu$1.Popup, {
44
44
  "data-control-ui": "context-menu",
45
45
  "data-popup-kind": "context-menu",
@@ -185,7 +185,7 @@ function ContextMenuSubContent({ className, children, ...props }) {
185
185
  return /* @__PURE__ */ jsx(ContextMenu$1.Portal, { children: /* @__PURE__ */ jsx(ContextMenu$1.Positioner, {
186
186
  "data-skin": skin.id,
187
187
  "data-effects": controlEffectsAttribute(skin.effects),
188
- className: "z-[80]",
188
+ className: "z-(--z-popup)",
189
189
  sideOffset: -4,
190
190
  alignOffset: -5,
191
191
  children: /* @__PURE__ */ jsx(ContextMenu$1.Popup, {
package/dist/ui/dialog.js CHANGED
@@ -43,7 +43,7 @@ function DialogContent({ className, children, showCloseButton = true, ...props }
43
43
  "data-popup-part": "backdrop",
44
44
  "data-skin": skin.id,
45
45
  "data-effects": controlEffectsAttribute(skin.effects),
46
- className: "fixed inset-0 z-[70]"
46
+ className: "fixed inset-0 z-(--z-overlay)"
47
47
  }), /* @__PURE__ */ jsxs(Dialog$1.Popup, {
48
48
  "data-skin": skin.id,
49
49
  "data-effects": controlEffectsAttribute(skin.effects),
@@ -53,7 +53,7 @@ function DialogContent({ className, children, showCloseButton = true, ...props }
53
53
  "data-control-family": "popup",
54
54
  "data-popup-part": "surface",
55
55
  "data-surface": "modal",
56
- className: cn("fixed left-1/2 top-[12vh] z-[71] grid w-[calc(100%-2rem)] max-w-lg -translate-x-1/2", className),
56
+ className: cn("fixed left-1/2 top-[12vh] z-(--z-modal) grid w-[calc(100%-2rem)] max-w-lg -translate-x-1/2", className),
57
57
  ...props,
58
58
  children: [
59
59
  skinAdornment(skin, "dialog", "titlebar", {}),
package/dist/ui/drawer.js CHANGED
@@ -96,7 +96,7 @@ function DrawerContent({ className, children, side = "bottom", padding = "defaul
96
96
  "data-slot": "backdrop",
97
97
  "data-skin": skin.id,
98
98
  "data-effects": controlEffectsAttribute(skin.effects),
99
- className: "fixed inset-0 z-[70]",
99
+ className: "fixed inset-0 z-(--z-overlay)",
100
100
  style: backdropStyle
101
101
  }), /* @__PURE__ */ jsx(Drawer$1.Viewport, {
102
102
  "data-control-ui": "drawer",
@@ -107,7 +107,7 @@ function DrawerContent({ className, children, side = "bottom", padding = "defaul
107
107
  "data-variant": variant,
108
108
  "data-skin": skin.id,
109
109
  "data-effects": controlEffectsAttribute(skin.effects),
110
- className: cn("fixed inset-0 z-[71] flex", place.viewport),
110
+ className: cn("fixed inset-0 z-(--z-modal) flex", place.viewport),
111
111
  children: /* @__PURE__ */ jsxs(Drawer$1.Popup, {
112
112
  "data-control-ui": "drawer",
113
113
  "data-control-family": "popup",
@@ -42,7 +42,7 @@ function DropdownMenuContent({ className, children, side = "bottom", sideOffset
42
42
  collisionBoundary,
43
43
  collisionPadding,
44
44
  collisionAvoidance,
45
- className: "z-[80]",
45
+ className: "z-(--z-popup)",
46
46
  children: /* @__PURE__ */ jsx(Menu.Popup, {
47
47
  "data-control-ui": "dropdown-menu",
48
48
  "data-slot": "content",
@@ -272,7 +272,10 @@ function DefaultFile({ file }) {
272
272
  /* @__PURE__ */ jsxs(ItemContent, { children: [/* @__PURE__ */ jsx(ItemTitle, {
273
273
  className: "wrap-anywhere",
274
274
  children: file.name
275
- }), /* @__PURE__ */ jsx(ItemDescription, { children: formatDropzoneFileSize(file.size) })] }),
275
+ }), /* @__PURE__ */ jsx(ItemDescription, {
276
+ className: "tabular-nums",
277
+ children: formatDropzoneFileSize(file.size)
278
+ })] }),
276
279
  /* @__PURE__ */ jsx(ItemActions, { children: /* @__PURE__ */ jsx(DropzoneRemove, { file }) })
277
280
  ]
278
281
  });
@@ -116,7 +116,7 @@ function GradientEditorTrack({ className, children, style, "aria-label": ariaLab
116
116
  "data-slot": "track",
117
117
  "aria-label": ariaLabelledBy === void 0 ? ariaLabel ?? "Gradient stops" : ariaLabel,
118
118
  "aria-labelledby": ariaLabelledBy,
119
- className: cn("relative m-0 min-w-0 w-full cursor-copy p-0", className),
119
+ className: cn("relative m-0 min-w-0 w-full cursor-copy touch-pan-y p-0", className),
120
120
  style: {
121
121
  ...style,
122
122
  backgroundImage: stripe
@@ -214,7 +214,7 @@ function GradientEditorStop({ stop, className, style, onPointerDown, onKeyDown,
214
214
  onFocus: handleFocus,
215
215
  onKeyDown: handleKeyDown,
216
216
  onDoubleClick: handleDoubleClick,
217
- className: cn("-translate-x-1/2 absolute top-1/2 -translate-y-1/2 cursor-grab overflow-hidden active:cursor-grabbing", className),
217
+ className: cn("-translate-x-1/2 absolute top-1/2 -translate-y-1/2 cursor-grab touch-pan-y overflow-hidden active:cursor-grabbing", className),
218
218
  style: {
219
219
  ...style,
220
220
  left: `${stop.position * 100}%`,
@@ -30,7 +30,7 @@ function HoverCardContent({ className, children, side = "bottom", align = "cente
30
30
  side,
31
31
  align,
32
32
  sideOffset,
33
- className: "z-[80]",
33
+ className: "z-(--z-popup)",
34
34
  children: /* @__PURE__ */ jsx(PreviewCard.Popup, {
35
35
  "data-control-ui": "hover-card",
36
36
  "data-popup-kind": "hover-card",
@@ -257,6 +257,7 @@ function InfiniteCanvasControls({ className, ...props }) {
257
257
  type: "button",
258
258
  size: "sm",
259
259
  variant: "ghost",
260
+ className: "tabular-nums",
260
261
  "aria-label": `Reset canvas zoom, currently ${percentage}%`,
261
262
  onClick: () => canvas.reset("control"),
262
263
  children: [percentage, "%"]
@@ -46,7 +46,7 @@ function MenubarContent({ className, children, ...props }) {
46
46
  side: "bottom",
47
47
  align: "start",
48
48
  sideOffset: 6,
49
- className: "z-[80]",
49
+ className: "z-(--z-popup)",
50
50
  children: /* @__PURE__ */ jsx(Menu.Popup, {
51
51
  "data-control-ui": "menubar",
52
52
  "data-popup-kind": "menubar",
@@ -147,7 +147,7 @@ function MenubarSubContent({ className, children, ...props }) {
147
147
  align: "start",
148
148
  sideOffset: -4,
149
149
  alignOffset: -5,
150
- className: "z-[80]",
150
+ className: "z-(--z-popup)",
151
151
  children: /* @__PURE__ */ jsx(Menu.Popup, {
152
152
  "data-control-ui": "menubar",
153
153
  "data-popup-kind": "menubar",
@@ -113,7 +113,7 @@ function NavigationMenuViewport({ className, ...props }) {
113
113
  right: 16
114
114
  },
115
115
  collisionAvoidance: { side: "none" },
116
- className: "z-[80] h-[var(--positioner-height)] w-[var(--positioner-width)] max-w-[var(--available-width)] before:absolute before:inset-x-0 before:top-[-8px] before:h-2 before:content-['']",
116
+ className: "z-(--z-popup) h-[var(--positioner-height)] w-[var(--positioner-width)] max-w-[var(--available-width)] before:absolute before:inset-x-0 before:top-[-8px] before:h-2 before:content-['']",
117
117
  children: /* @__PURE__ */ jsx(NavigationMenu$1.Popup, {
118
118
  "data-control-ui": "navigation-menu",
119
119
  "data-control-family": "popup",
@@ -70,7 +70,7 @@ function NumberFieldScrubArea({ className, children, ...props }) {
70
70
  "data-control-family": "field",
71
71
  "data-field-kind": "number-field",
72
72
  "data-slot": "scrub-area",
73
- className: cn("cursor-ew-resize select-none", className),
73
+ className: cn("cursor-ew-resize touch-pan-y select-none", className),
74
74
  ...props,
75
75
  children: [children, /* @__PURE__ */ jsx(NumberField$1.ScrubAreaCursor, {
76
76
  "data-control-ui": "number-field",
@@ -0,0 +1,44 @@
1
+ import { ScrollAreaProps } from "./scroll-area.js";
2
+ import { PageLayoutKnobStyle } from "../knob-contracts/page-layout-knobs.js";
3
+ import { CSSProperties, ComponentProps, ReactNode } from "react";
4
+ //#region src/ui/page-layout.d.ts
5
+ export declare const pageWidths: readonly ["prose", "content", "wide", "full"];
6
+ export type PageWidth = (typeof pageWidths)[number];
7
+ export declare const pageScrollModes: readonly ["page", "inset", "none"];
8
+ export type PageScrollMode = (typeof pageScrollModes)[number];
9
+ export type PageScroll = PageScrollMode | "auto";
10
+ export declare const pageHeaderVariants: readonly ["flow", "sticky", "floating"];
11
+ export type PageHeaderVariant = (typeof pageHeaderVariants)[number];
12
+ type PageStyle = CSSProperties & PageLayoutKnobStyle;
13
+ export declare function usePageScroll(scroll?: PageScroll): PageScrollMode;
14
+ export type PageLayoutProps = Omit<ComponentProps<"div">, "style"> & {
15
+ scroll?: PageScroll;
16
+ width?: PageWidth;
17
+ scrollViewportRef?: ScrollAreaProps["viewportRef"];
18
+ style?: PageStyle;
19
+ };
20
+ export declare function PageLayout({ scroll, width, scrollViewportRef, children, className, ...props }: PageLayoutProps): import("react").JSX.Element;
21
+ export type PageHeaderProps = Omit<ComponentProps<"header">, "style"> & {
22
+ variant?: PageHeaderVariant;
23
+ style?: PageStyle;
24
+ };
25
+ export declare function PageHeader({ variant, className, ...props }: PageHeaderProps): import("react").JSX.Element;
26
+ export type PageTitleProps = Omit<ComponentProps<"h1">, "style"> & {
27
+ style?: PageStyle;
28
+ };
29
+ export declare function PageTitle({ className, ...props }: PageTitleProps): import("react").JSX.Element;
30
+ export type PageDescriptionProps = Omit<ComponentProps<"p">, "style"> & {
31
+ style?: PageStyle;
32
+ };
33
+ export declare function PageDescription({ className, ...props }: PageDescriptionProps): import("react").JSX.Element;
34
+ export type PageActionsProps = Omit<ComponentProps<"div">, "style"> & {
35
+ style?: PageStyle;
36
+ };
37
+ export declare function PageActions({ className, ...props }: PageActionsProps): import("react").JSX.Element;
38
+ export type PageBodyProps = Omit<ComponentProps<"div">, "style"> & {
39
+ aside?: ReactNode;
40
+ contentClassName?: string;
41
+ style?: PageStyle;
42
+ };
43
+ export declare function PageBody({ aside, contentClassName, children, className, ...props }: PageBodyProps): import("react").JSX.Element;
44
+ //#endregion
@@ -0,0 +1,108 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { useSkin } from "../skin-provider.js";
4
+ import { ScrollArea } from "./scroll-area.js";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ //#region src/ui/page-layout.tsx
7
+ const pageWidths = [
8
+ "prose",
9
+ "content",
10
+ "wide",
11
+ "full"
12
+ ];
13
+ const pageScrollModes = [
14
+ "page",
15
+ "inset",
16
+ "none"
17
+ ];
18
+ const pageHeaderVariants = [
19
+ "flow",
20
+ "sticky",
21
+ "floating"
22
+ ];
23
+ function usePageScroll(scroll = "auto") {
24
+ const skin = useSkin();
25
+ if (scroll !== "auto") return scroll;
26
+ return skin.sidebarLayout === "page" ? "page" : "inset";
27
+ }
28
+ function PageLayout({ scroll = "auto", width = "prose", scrollViewportRef, children, className, ...props }) {
29
+ const resolvedScroll = usePageScroll(scroll);
30
+ const scrollsInset = resolvedScroll === "inset";
31
+ return /* @__PURE__ */ jsx("div", {
32
+ "data-control-ui": "page-layout",
33
+ "data-control-family": "page-layout",
34
+ "data-slot": "root",
35
+ "data-scroll": resolvedScroll,
36
+ "data-width": width,
37
+ className: cn("flex w-full flex-col", resolvedScroll !== "page" && "min-h-0 flex-1 overflow-hidden", className),
38
+ ...props,
39
+ children: scrollsInset ? /* @__PURE__ */ jsx(ScrollArea, {
40
+ className: "min-h-0 flex-1",
41
+ viewportClassName: "scroll-smooth motion-reduce:scroll-auto",
42
+ viewportRef: scrollViewportRef,
43
+ lockAxis: "x",
44
+ children
45
+ }) : children
46
+ });
47
+ }
48
+ function PageHeader({ variant = "flow", className, ...props }) {
49
+ return /* @__PURE__ */ jsx("header", {
50
+ "data-control-ui": "page-layout",
51
+ "data-control-family": "page-layout",
52
+ "data-slot": "header",
53
+ "data-variant": variant,
54
+ className,
55
+ ...props
56
+ });
57
+ }
58
+ function PageTitle({ className, ...props }) {
59
+ return /* @__PURE__ */ jsx("h1", {
60
+ "data-control-ui": "page-layout",
61
+ "data-control-family": "page-layout",
62
+ "data-slot": "title",
63
+ className: cn("text-balance", className),
64
+ ...props
65
+ });
66
+ }
67
+ function PageDescription({ className, ...props }) {
68
+ return /* @__PURE__ */ jsx("p", {
69
+ "data-control-ui": "page-layout",
70
+ "data-control-family": "page-layout",
71
+ "data-slot": "description",
72
+ className: cn("text-pretty", className),
73
+ ...props
74
+ });
75
+ }
76
+ function PageActions({ className, ...props }) {
77
+ return /* @__PURE__ */ jsx("div", {
78
+ "data-control-ui": "page-layout",
79
+ "data-control-family": "page-layout",
80
+ "data-slot": "actions",
81
+ className: cn("flex items-center gap-2", className),
82
+ ...props
83
+ });
84
+ }
85
+ function PageBody({ aside, contentClassName, children, className, ...props }) {
86
+ return /* @__PURE__ */ jsxs("div", {
87
+ "data-control-ui": "page-layout",
88
+ "data-control-family": "page-layout",
89
+ "data-slot": "body",
90
+ "data-aside": aside ? "" : void 0,
91
+ className,
92
+ ...props,
93
+ children: [/* @__PURE__ */ jsx("div", {
94
+ "data-control-ui": "page-layout",
95
+ "data-control-family": "page-layout",
96
+ "data-slot": "content",
97
+ className: cn("min-w-0", contentClassName),
98
+ children
99
+ }), aside ? /* @__PURE__ */ jsx("aside", {
100
+ "data-control-ui": "page-layout",
101
+ "data-control-family": "page-layout",
102
+ "data-slot": "aside",
103
+ children: aside
104
+ }) : null]
105
+ });
106
+ }
107
+ //#endregion
108
+ export { PageActions, PageBody, PageDescription, PageHeader, PageLayout, PageTitle, pageHeaderVariants, pageScrollModes, pageWidths, usePageScroll };
@@ -2,12 +2,12 @@
2
2
  import { cn } from "../lib/cn.js";
3
3
  import { Popover, PopoverContent, PopoverTrigger } from "./popover.js";
4
4
  import { InputGroup, InputGroupAddon, InputGroupInput } from "./input-group.js";
5
- import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "./command.js";
6
5
  import { normalizePhoneInputText, normalizePhoneInputValue } from "../lib/phone-input-format.js";
6
+ import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "./command.js";
7
7
  import { useState } from "react";
8
8
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
- import flags from "react-phone-number-input/flags";
10
9
  import PhoneNumberInput, { getCountryCallingCode, parsePhoneNumber } from "react-phone-number-input/max";
10
+ import flags from "react-phone-number-input/flags";
11
11
  //#region src/ui/phone-input.tsx
12
12
  const FLAG_COMPONENTS = flags;
13
13
  const PhoneNumberInputWithRef = PhoneNumberInput;
@@ -35,7 +35,7 @@ function PhoneInputControl({ className, normalizationCountry, onChange, onNative
35
35
  }
36
36
  });
37
37
  }
38
- function PhoneCountrySelect({ value, options, onChange, onFocus, onBlur, disabled, readOnly, "aria-label": ariaLabel = "Country", searchPlaceholder = "Search country...", emptyMessage = "No country found.", knobStyle }) {
38
+ function PhoneCountrySelect({ value, options, onChange, onFocus, onBlur, disabled, readOnly, "aria-label": ariaLabel = "Country", searchPlaceholder = "Search country…", emptyMessage, knobStyle }) {
39
39
  const countryStyle = knobStyle;
40
40
  const triggerStyle = knobStyle;
41
41
  const metadataStyle = knobStyle;
@@ -75,7 +75,7 @@ function PhoneCountrySelect({ value, options, onChange, onFocus, onBlur, disable
75
75
  children: [/* @__PURE__ */ jsx(CommandInput, {
76
76
  "aria-label": searchPlaceholder,
77
77
  placeholder: searchPlaceholder
78
- }), /* @__PURE__ */ jsxs(CommandList, { children: [/* @__PURE__ */ jsx(CommandEmpty, { children: emptyMessage }), /* @__PURE__ */ jsx(CommandGroup, { children: options.map((option) => {
78
+ }), /* @__PURE__ */ jsxs(CommandList, { children: [/* @__PURE__ */ jsx(CommandEmpty, { title: emptyMessage }), /* @__PURE__ */ jsx(CommandGroup, { children: options.map((option) => {
79
79
  const callingCode = option.value ? `+${getCountryCallingCode(option.value)}` : "";
80
80
  const selected = option.value === value;
81
81
  return /* @__PURE__ */ jsxs(CommandItem, {
@@ -30,7 +30,7 @@ function PopoverContent({ className, children, side = "bottom", align = "center"
30
30
  align,
31
31
  sideOffset,
32
32
  collisionPadding,
33
- className: "z-[80]",
33
+ className: "z-(--z-popup)",
34
34
  children: /* @__PURE__ */ jsx(Popover$1.Popup, {
35
35
  "data-control-ui": "popover",
36
36
  "data-popup-kind": "popover",
@@ -38,7 +38,7 @@ function ResizableHandle({ className, variant = "solid", withHandle, children, .
38
38
  "data-slot": "handle",
39
39
  "data-variant": variant,
40
40
  "data-axis": axis,
41
- className: cn("relative flex items-center justify-center", axis === "vertical" ? "w-px" : "h-px", className),
41
+ className: cn("relative flex items-center justify-center", axis === "vertical" ? "w-px touch-pan-y" : "h-px touch-pan-x", className),
42
42
  ...props,
43
43
  children: [withHandle ? /* @__PURE__ */ jsx("span", {
44
44
  "data-control-ui": "resizable",
@@ -151,7 +151,7 @@ function RichTooltipContent({ className, children, side = "bottom", align = "cen
151
151
  sideOffset,
152
152
  anchor,
153
153
  collisionPadding,
154
- className: "z-[80]",
154
+ className: "z-(--z-popup)",
155
155
  children: /* @__PURE__ */ jsxs(Popover.Popup, {
156
156
  "data-control-ui": "rich-tooltip",
157
157
  "data-popup-kind": "rich-tooltip",
package/dist/ui/select.js CHANGED
@@ -74,7 +74,7 @@ function SelectContent({ className, children, alignItemWithTrigger = false, ...p
74
74
  align: "start",
75
75
  sideOffset: 6,
76
76
  alignItemWithTrigger,
77
- className: "z-[80]",
77
+ className: "z-(--z-popup)",
78
78
  children: /* @__PURE__ */ jsx(Select$1.Popup, {
79
79
  "data-control-ui": "select",
80
80
  "data-popup-kind": "select",
package/dist/ui/sheet.js CHANGED
@@ -28,7 +28,7 @@ function SheetContent({ className, children, side = "right", ...props }) {
28
28
  "data-popup-part": "backdrop",
29
29
  "data-skin": skin.id,
30
30
  "data-effects": controlEffectsAttribute(skin.effects),
31
- className: "fixed inset-0 z-[70]"
31
+ className: "fixed inset-0 z-(--z-overlay)"
32
32
  }), /* @__PURE__ */ jsx(Dialog.Popup, {
33
33
  "data-skin": skin.id,
34
34
  "data-effects": controlEffectsAttribute(skin.effects),
@@ -38,7 +38,7 @@ function SheetContent({ className, children, side = "right", ...props }) {
38
38
  "data-slot": "content",
39
39
  "data-popup-part": "surface",
40
40
  "data-surface": "modal",
41
- className: cn("fixed inset-y-0 z-[71] flex h-full w-3/4 max-w-sm flex-col", side === "left" ? "left-0" : "right-0", className),
41
+ className: cn("fixed inset-y-0 z-(--z-modal) flex h-full w-3/4 max-w-sm flex-col", side === "left" ? "left-0" : "right-0", className),
42
42
  ...props,
43
43
  "data-side": side,
44
44
  children
@@ -179,7 +179,7 @@ function SidebarResizeRail({ className, ref, onPointerDown, onClick, onKeyDown,
179
179
  onPointerDown: handlePointerDown,
180
180
  onClick: handleClick,
181
181
  onKeyDown: handleKeyDown,
182
- className: cn("absolute inset-y-0 z-20 hidden cursor-col-resize touch-none outline-hidden group-data-[side=left]:-right-1 group-data-[side=right]:-left-1 group-data-[side=left]:group-data-[collapsible=offcanvas]:-right-2 group-data-[side=right]:group-data-[collapsible=offcanvas]:-left-2 lg:block", className),
182
+ className: cn("absolute inset-y-0 z-20 hidden cursor-col-resize touch-pan-y outline-hidden group-data-[side=left]:-right-1 group-data-[side=right]:-left-1 group-data-[side=left]:group-data-[collapsible=offcanvas]:-right-2 group-data-[side=right]:group-data-[collapsible=offcanvas]:-left-2 lg:block", className),
183
183
  children: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
184
184
  ref: widthMeasureRef,
185
185
  "aria-hidden": true,
package/dist/ui/slider.js CHANGED
@@ -37,7 +37,7 @@ function Slider({ className, variant = "default", label, showValue, formatValue,
37
37
  disabled,
38
38
  onValueChange,
39
39
  onValueCommitted,
40
- className: cn("group relative flex cursor-pointer touch-none select-none items-center data-[disabled]:cursor-not-allowed", orientation === "vertical" ? "min-h-20 w-fit" : "w-full", className),
40
+ className: cn("group relative flex cursor-pointer select-none items-center data-[disabled]:cursor-not-allowed", orientation === "vertical" ? "min-h-20 w-fit touch-pan-x" : "w-full touch-pan-y", className),
41
41
  style,
42
42
  ...props,
43
43
  children: [/* @__PURE__ */ jsx(Slider$1.Control, {
package/dist/ui/toast.js CHANGED
@@ -43,7 +43,7 @@ function ToastList({ rootStyle, indicatorStyle, actionStyle, closeStyle }) {
43
43
  style: rootStyle,
44
44
  "data-slot": "root",
45
45
  "data-surface": "floating",
46
- className: cn("[--gap:0.75rem] [--peek:0.75rem] [--scale:calc(max(0,1-(var(--toast-index)*0.1)))] [--shrink:calc(1-var(--scale))] [--height:var(--toast-frontmost-height,var(--toast-height))] [--offset-y:calc(var(--toast-offset-y)*-1+calc(var(--toast-index)*var(--gap)*-1)+var(--toast-swipe-movement-y))]", "absolute right-0 bottom-0 left-auto z-[calc(1000-var(--toast-index))] h-[var(--height)] w-full select-none data-[expanded]:h-[var(--toast-height)]", "after:absolute after:top-full after:left-0 after:h-[calc(var(--gap)+1px)] after:w-full after:content-['']"),
46
+ className: cn("[--gap:0.75rem] [--peek:0.75rem] [--scale:calc(max(0,1-(var(--toast-index)*0.1)))] [--shrink:calc(1-var(--scale))] [--height:var(--toast-frontmost-height,var(--toast-height))] [--offset-y:calc(var(--toast-offset-y)*-1+calc(var(--toast-index)*var(--gap)*-1)+var(--toast-swipe-movement-y))]", "absolute right-0 bottom-0 left-auto z-[calc(var(--z-toast)-var(--toast-index))] h-[var(--height)] w-full select-none data-[expanded]:h-[var(--toast-height)]", "after:absolute after:top-full after:left-0 after:h-[calc(var(--gap)+1px)] after:w-full after:content-['']"),
47
47
  children: /* @__PURE__ */ jsxs(Toast.Content, {
48
48
  "data-control-ui": "toast",
49
49
  "data-control-family": "popup",
@@ -125,7 +125,7 @@ function Toaster({ className, timeout, limit, rootStyle, indicatorStyle, actionS
125
125
  "data-slot": "viewport",
126
126
  "data-skin": skin.id,
127
127
  "data-effects": controlEffectsAttribute(skin.effects),
128
- className: cn("fixed right-4 bottom-4 z-[95] mx-auto w-[calc(100vw-2rem)] sm:right-6 sm:bottom-6 sm:w-[22.5rem]", className),
128
+ className: cn("fixed right-4 bottom-4 z-(--z-toast) mx-auto w-[calc(100vw-2rem)] sm:right-6 sm:bottom-6 sm:w-[22.5rem]", className),
129
129
  children: /* @__PURE__ */ jsx(ToastList, {
130
130
  rootStyle,
131
131
  indicatorStyle,
@@ -46,7 +46,7 @@ function TooltipContent({ className, children, side = "top", sideOffset = 8, ali
46
46
  "data-slot": "positioner",
47
47
  "data-skin": skin.id,
48
48
  "data-effects": controlEffectsAttribute(skin.effects),
49
- className: "z-[90]",
49
+ className: "z-(--z-tooltip)",
50
50
  ...positionerProps,
51
51
  children: /* @__PURE__ */ jsxs(Tooltip$1.Popup, {
52
52
  ref,
@@ -23,7 +23,7 @@ function TriggerMenu({ open, onOpenChange, anchorRect, side = "top", align = "st
23
23
  side,
24
24
  align,
25
25
  sideOffset,
26
- className: "z-[80]",
26
+ className: "z-(--z-popup)",
27
27
  children: /* @__PURE__ */ jsx(Popover.Popup, {
28
28
  "data-control-ui": "trigger-menu",
29
29
  "data-popup-kind": "trigger-menu",