@ctrl-ui/react 0.8.5 → 0.8.7

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 (152) hide show
  1. package/dist/action-bar.js +1 -1
  2. package/dist/activity.js +1 -1
  3. package/dist/blocks/coding-agent.js +16 -19
  4. package/dist/blocks/design-canvas-data.d.ts +32 -0
  5. package/dist/blocks/design-canvas-data.js +100 -0
  6. package/dist/blocks/design-canvas-inspector.d.ts +8 -0
  7. package/dist/blocks/design-canvas-inspector.js +238 -0
  8. package/dist/blocks/design-canvas.d.ts +17 -0
  9. package/dist/blocks/design-canvas.js +346 -0
  10. package/dist/blocks/file-explorer.js +2 -2
  11. package/dist/blocks/settings.js +2 -2
  12. package/dist/chat-composer-attachment.d.ts +9 -3
  13. package/dist/chat-composer-attachment.js +27 -10
  14. package/dist/chat-composer-editor.js +20 -4
  15. package/dist/chat-composer.d.ts +1 -1
  16. package/dist/chat-composer.js +4 -3
  17. package/dist/chat-layout.js +32 -19
  18. package/dist/context.js +1 -1
  19. package/dist/dynamic-notification.js +1 -1
  20. package/dist/environment-variables.js +1 -1
  21. package/dist/filter-bar/context.d.ts +32 -0
  22. package/dist/filter-bar/context.js +11 -0
  23. package/dist/filter-bar/editor.d.ts +14 -0
  24. package/dist/filter-bar/editor.js +204 -0
  25. package/dist/filter-bar/model.d.ts +9 -0
  26. package/dist/filter-bar/model.js +48 -0
  27. package/dist/filter-bar/motion.d.ts +10 -0
  28. package/dist/filter-bar/motion.js +84 -0
  29. package/dist/filter-bar/parts.d.ts +19 -0
  30. package/dist/filter-bar/parts.js +233 -0
  31. package/dist/filter-bar/types.d.ts +53 -0
  32. package/dist/filter-bar/types.js +0 -0
  33. package/dist/filter-bar.d.ts +27 -0
  34. package/dist/filter-bar.js +304 -0
  35. package/dist/hooks/use-chat-composer.d.ts +3 -1
  36. package/dist/hooks/use-chat-composer.js +2 -2
  37. package/dist/hooks/use-dropzone.d.ts +7 -4
  38. package/dist/hooks/use-dropzone.js +34 -3
  39. package/dist/inline-attachment.js +8 -14
  40. package/dist/inline-citation.js +1 -1
  41. package/dist/knob-contracts/chat-layout-knobs.d.ts +1 -1
  42. package/dist/knob-contracts/chat-layout-knobs.js +2 -1
  43. package/dist/knob-contracts/choice-knobs.d.ts +1 -1
  44. package/dist/knob-contracts/choice-knobs.js +1 -0
  45. package/dist/knob-contracts/collapsible-knobs.d.ts +1 -1
  46. package/dist/knob-contracts/collapsible-knobs.js +1 -1
  47. package/dist/knob-contracts/filter-bar-knobs.d.ts +4 -0
  48. package/dist/knob-contracts/filter-bar-knobs.js +16 -0
  49. package/dist/knob-contracts/infinite-canvas-knobs.d.ts +1 -1
  50. package/dist/knob-contracts/infinite-canvas-knobs.js +3 -0
  51. package/dist/knob-contracts/page-layout-knobs.d.ts +1 -1
  52. package/dist/knob-contracts/page-layout-knobs.js +4 -1
  53. package/dist/knob-contracts/popup-knobs.d.ts +1 -1
  54. package/dist/knob-contracts/popup-knobs.js +1 -0
  55. package/dist/knob-contracts/table-of-contents-knobs.d.ts +1 -1
  56. package/dist/knob-contracts/table-of-contents-knobs.js +3 -5
  57. package/dist/lib/phone-input-format.js +1 -1
  58. package/dist/markdown-block.js +11 -7
  59. package/dist/scripts/contrast-eval.js +5 -4
  60. package/dist/styles/index.css +5 -4
  61. package/dist/styles/recipes/button-group.css +1 -1
  62. package/dist/styles/recipes/button.css +2 -2
  63. package/dist/styles/recipes/chat-composer.css +14 -6
  64. package/dist/styles/recipes/chat-layout.css +29 -2
  65. package/dist/styles/recipes/choice.css +10 -3
  66. package/dist/styles/recipes/code-diff.css +16 -4
  67. package/dist/styles/recipes/code.css +11 -5
  68. package/dist/styles/recipes/collapsible.css +37 -0
  69. package/dist/styles/recipes/color-picker.css +12 -2
  70. package/dist/styles/recipes/dockable-panel.css +11 -3
  71. package/dist/styles/recipes/field-parts.css +62 -0
  72. package/dist/styles/recipes/field.css +28 -6
  73. package/dist/styles/recipes/filter-bar.css +174 -0
  74. package/dist/styles/recipes/infinite-canvas.css +51 -3
  75. package/dist/styles/recipes/inline-attachment.css +6 -1
  76. package/dist/styles/recipes/page-layout.css +36 -2
  77. package/dist/styles/recipes/pagination.css +1 -1
  78. package/dist/styles/recipes/popup-controls.css +16 -0
  79. package/dist/styles/recipes/popup-drawer.css +34 -32
  80. package/dist/styles/recipes/popup-lists.css +11 -2
  81. package/dist/styles/recipes/popup.css +10 -12
  82. package/dist/styles/recipes/range.css +1 -1
  83. package/dist/styles/recipes/resizable.css +34 -0
  84. package/dist/styles/recipes/spinner.css +4 -0
  85. package/dist/styles/recipes/table-of-contents.css +42 -42
  86. package/dist/styles/recipes/tabs.css +21 -0
  87. package/dist/styles/recipes/track-highlight.css +2 -1
  88. package/dist/styles/recipes/transcript-divider.css +2 -2
  89. package/dist/styles/theme.css +250 -91
  90. package/dist/ui/alert-dialog.js +1 -1
  91. package/dist/ui/autocomplete.js +5 -1
  92. package/dist/ui/button.js +2 -2
  93. package/dist/ui/checkbox-group.js +1 -1
  94. package/dist/ui/code-diff.js +1 -1
  95. package/dist/ui/code.js +3 -3
  96. package/dist/ui/collapsible.js +1 -1
  97. package/dist/ui/color-picker.js +2 -2
  98. package/dist/ui/combobox-disabled-selection.d.ts +1 -1
  99. package/dist/ui/combobox-disabled-selection.js +2 -1
  100. package/dist/ui/combobox.d.ts +5 -23
  101. package/dist/ui/combobox.js +26 -14
  102. package/dist/ui/command.js +9 -1
  103. package/dist/ui/context-menu.js +1 -1
  104. package/dist/ui/dialog.js +1 -1
  105. package/dist/ui/dockable-panel.js +18 -10
  106. package/dist/ui/drawer.d.ts +7 -4
  107. package/dist/ui/drawer.js +36 -23
  108. package/dist/ui/dropdown-menu.js +1 -1
  109. package/dist/ui/dropzone.d.ts +3 -1
  110. package/dist/ui/dropzone.js +3 -1
  111. package/dist/ui/field.js +1 -1
  112. package/dist/ui/hover-card.js +1 -1
  113. package/dist/ui/infinite-canvas.d.ts +11 -0
  114. package/dist/ui/infinite-canvas.js +82 -7
  115. package/dist/ui/input-group.d.ts +2 -1
  116. package/dist/ui/input-group.js +12 -3
  117. package/dist/ui/input.js +9 -0
  118. package/dist/ui/item.js +1 -1
  119. package/dist/ui/markdown-elements.js +11 -8
  120. package/dist/ui/menubar.js +1 -1
  121. package/dist/ui/morphing-panel.js +1 -1
  122. package/dist/ui/navigation-menu.js +1 -1
  123. package/dist/ui/number-field.d.ts +1 -1
  124. package/dist/ui/number-field.js +13 -2
  125. package/dist/ui/phone-input.js +2 -2
  126. package/dist/ui/popover.js +1 -1
  127. package/dist/ui/radio-group.d.ts +1 -0
  128. package/dist/ui/radio-group.js +11 -1
  129. package/dist/ui/resizable.d.ts +18 -1
  130. package/dist/ui/resizable.js +127 -7
  131. package/dist/ui/responsive-dialog.js +6 -3
  132. package/dist/ui/rich-tooltip.js +1 -1
  133. package/dist/ui/scroll-area.d.ts +4 -1
  134. package/dist/ui/scroll-area.js +2 -1
  135. package/dist/ui/select.d.ts +2 -1
  136. package/dist/ui/select.js +58 -33
  137. package/dist/ui/sheet.js +1 -1
  138. package/dist/ui/sidebar-menu.js +1 -1
  139. package/dist/ui/sidebar-provider.js +2 -2
  140. package/dist/ui/sidebar-resize-rail.js +1 -1
  141. package/dist/ui/sidebar.js +1 -1
  142. package/dist/ui/table-of-contents.d.ts +4 -3
  143. package/dist/ui/table-of-contents.js +126 -47
  144. package/dist/ui/table.js +11 -7
  145. package/dist/ui/toast.js +1 -1
  146. package/dist/ui/toggle.d.ts +1 -1
  147. package/dist/ui/toggle.js +2 -1
  148. package/dist/ui/tooltip.js +1 -1
  149. package/dist/ui/tree.js +1 -1
  150. package/dist/ui/trigger-menu.js +7 -3
  151. package/dist/user-ask.js +1 -1
  152. package/package.json +1 -1
@@ -1,9 +1,10 @@
1
1
  "use client";
2
- import { cn } from "../lib/cn.js";
3
2
  import { controlEffectsAttribute } from "../skin.js";
3
+ import { cn } from "../lib/cn.js";
4
4
  import { useSkin } from "../skin-provider.js";
5
+ import { ScrollArea } from "./scroll-area.js";
5
6
  import { popupItemStructureClasses } from "../surface-variants.js";
6
- import { emitComboboxValueChange } from "./combobox-disabled-selection.js";
7
+ import { shouldAcceptComboboxValueChange } from "./combobox-disabled-selection.js";
7
8
  import { createContext, use, useEffect, useState } from "react";
8
9
  import { jsx, jsxs } from "react/jsx-runtime";
9
10
  import { Combobox as Combobox$1 } from "@base-ui/react/combobox";
@@ -21,8 +22,8 @@ function Combobox({ children, onValueChange, autoHighlight = true, ...props }) {
21
22
  children: /* @__PURE__ */ jsx(Combobox$1.Root, {
22
23
  autoHighlight,
23
24
  ...props,
24
- onValueChange: onValueChange ? (value) => {
25
- if (!Array.isArray(value)) emitComboboxValueChange(value, disabledValues, onValueChange);
25
+ onValueChange: onValueChange ? (value, eventDetails) => {
26
+ if (shouldAcceptComboboxValueChange(value, disabledValues, props.multiple)) onValueChange(value, eventDetails);
26
27
  } : void 0,
27
28
  children
28
29
  })
@@ -76,7 +77,7 @@ function ComboboxInput({ size = "md", className, ...props }) {
76
77
  }), /* @__PURE__ */ jsx(ComboboxTrigger, { className: "absolute right-1.5 top-1/2 -translate-y-1/2" })]
77
78
  });
78
79
  }
79
- function ComboboxContent({ className, children, sideOffset = 6, ...props }) {
80
+ function ComboboxContent({ className, children, sideOffset = 6, anchor, ...props }) {
80
81
  const skin = useSkin();
81
82
  return /* @__PURE__ */ jsx(Combobox$1.Portal, { children: /* @__PURE__ */ jsx(Combobox$1.Positioner, {
82
83
  "data-control-ui": "combobox",
@@ -88,6 +89,7 @@ function ComboboxContent({ className, children, sideOffset = 6, ...props }) {
88
89
  side: "bottom",
89
90
  align: "start",
90
91
  sideOffset,
92
+ anchor,
91
93
  className: "z-(--z-popup)",
92
94
  children: /* @__PURE__ */ jsx(Combobox$1.Popup, {
93
95
  "data-control-ui": "combobox",
@@ -103,15 +105,21 @@ function ComboboxContent({ className, children, sideOffset = 6, ...props }) {
103
105
  }) });
104
106
  }
105
107
  function ComboboxList({ className, children, ...props }) {
106
- return /* @__PURE__ */ jsx(Combobox$1.List, {
107
- "data-control-ui": "combobox",
108
- "data-popup-kind": "combobox",
109
- "data-slot": "list",
110
- "data-control-family": "popup",
111
- "data-popup-part": "list-content",
112
- className: cn("max-h-[min(18rem,var(--available-height))] overflow-y-auto overscroll-contain", className),
113
- ...props,
114
- children
108
+ return /* @__PURE__ */ jsx(ScrollArea, {
109
+ className: "w-full",
110
+ viewportClassName: "overscroll-contain",
111
+ maxHeight: "min(18rem, var(--available-height))",
112
+ lockAxis: "x",
113
+ children: /* @__PURE__ */ jsx(Combobox$1.List, {
114
+ "data-control-ui": "combobox",
115
+ "data-popup-kind": "combobox",
116
+ "data-slot": "list",
117
+ "data-control-family": "popup",
118
+ "data-popup-part": "list-content",
119
+ className,
120
+ ...props,
121
+ children
122
+ })
115
123
  });
116
124
  }
117
125
  function ComboboxEmpty({ className, children, ...props }) {
@@ -145,6 +153,10 @@ function ComboboxItem({ className, children, disabled, value, ...props }) {
145
153
  className: cn(popupItemStructureClasses, className),
146
154
  ...props,
147
155
  children: [/* @__PURE__ */ jsx("span", {
156
+ "data-control-ui": "combobox",
157
+ "data-control-family": "popup",
158
+ "data-popup-kind": "combobox",
159
+ "data-slot": "item-text",
148
160
  className: "flex min-w-0 flex-1 items-center truncate",
149
161
  children
150
162
  }), /* @__PURE__ */ jsx("span", {
@@ -4,6 +4,7 @@ import { ScrollArea } from "./scroll-area.js";
4
4
  import { popupItemStructureClasses } from "../surface-variants.js";
5
5
  import { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "./empty.js";
6
6
  import { Dialog, DialogContent, DialogDescription, DialogTitle } from "./dialog.js";
7
+ import { useEffect, useRef } from "react";
7
8
  import { jsx, jsxs } from "react/jsx-runtime";
8
9
  import { Command as Command$1, useCommandState } from "cmdk";
9
10
  //#region src/ui/command.tsx
@@ -104,7 +105,14 @@ function CommandListSurface({ hasResults, ...props }) {
104
105
  }
105
106
  function CommandList({ className, children, ...props }) {
106
107
  const hasResults = useCommandState((state) => state.filtered.count > 0);
108
+ const search = useCommandState((state) => state.search);
109
+ const viewportRef = useRef(null);
110
+ useEffect(() => {
111
+ const frame = requestAnimationFrame(() => viewportRef.current?.scrollTo({ top: 0 }));
112
+ return () => cancelAnimationFrame(frame);
113
+ }, [search]);
107
114
  return /* @__PURE__ */ jsx(ScrollArea, {
115
+ viewportRef,
108
116
  maxHeight: "min(360px, var(--available-height, 360px))",
109
117
  className: "min-h-0 w-full",
110
118
  children: /* @__PURE__ */ jsx(Command$1.List, {
@@ -166,7 +174,7 @@ function CommandGroup({ className, ...props }) {
166
174
  "data-control-family": "popup",
167
175
  "data-popup-kind": "command",
168
176
  "data-slot": "group",
169
- className: cn("p-[var(--popover-padding)]", className),
177
+ className,
170
178
  ...props
171
179
  });
172
180
  }
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { cn } from "../lib/cn.js";
3
2
  import { controlEffectsAttribute } from "../skin.js";
3
+ import { cn } from "../lib/cn.js";
4
4
  import { useSkin } from "../skin-provider.js";
5
5
  import { popupItemStructureClasses } from "../surface-variants.js";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
package/dist/ui/dialog.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { cn } from "../lib/cn.js";
3
2
  import { controlEffectsAttribute, skinAdornment } from "../skin.js";
3
+ import { cn } from "../lib/cn.js";
4
4
  import { useSkin } from "../skin-provider.js";
5
5
  import { Button } from "./button.js";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1,9 +1,10 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
3
  import { Button } from "./button.js";
4
+ import { ScrollArea } from "./scroll-area.js";
4
5
  import { useIsMobile } from "../hooks/use-mobile.js";
6
+ import { Drawer, DrawerBody, DrawerContent } from "./drawer.js";
5
7
  import { clampDockablePanelPosition, dockablePanelSideAt, oppositeDockablePanelSide } from "./dockable-panel-geometry.js";
6
- import { Drawer, DrawerContent } from "./drawer.js";
7
8
  import { createContext, use, useRef, useState } from "react";
8
9
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
10
  //#region src/ui/dockable-panel.tsx
@@ -128,14 +129,16 @@ function DockablePanel({ open: openProp, defaultOpen = true, onOpenChange, place
128
129
  children: /* @__PURE__ */ jsx(DrawerContent, {
129
130
  "data-dockable-panel-root": "",
130
131
  "data-placement": placement,
131
- padding: "none",
132
132
  variant: "floating",
133
133
  surface: "card",
134
134
  "aria-label": ariaLabel,
135
135
  className: cn("max-h-[min(82vh,42rem)] gap-0 overflow-hidden", className),
136
136
  style,
137
137
  ...props,
138
- children
138
+ children: /* @__PURE__ */ jsx(DrawerBody, {
139
+ padding: "none",
140
+ children
141
+ })
139
142
  })
140
143
  })
141
144
  });
@@ -303,13 +306,18 @@ function DockablePanelClose({ className, children, "aria-label": ariaLabel = "Cl
303
306
  });
304
307
  }
305
308
  function DockablePanelContent({ padding = "default", className, ...props }) {
306
- return /* @__PURE__ */ jsx("div", {
307
- "data-control-ui": "dockable-panel",
308
- "data-control-family": "dockable-panel",
309
- "data-slot": "content",
310
- "data-padding": padding,
311
- className: cn("min-h-0 flex-1 overflow-y-auto", className),
312
- ...props
309
+ return /* @__PURE__ */ jsx(ScrollArea, {
310
+ className: "flex min-h-0 flex-1 flex-col",
311
+ viewportClassName: "min-h-0 flex-1",
312
+ lockAxis: "x",
313
+ children: /* @__PURE__ */ jsx("div", {
314
+ "data-control-ui": "dockable-panel",
315
+ "data-control-family": "dockable-panel",
316
+ "data-slot": "content",
317
+ "data-padding": padding,
318
+ className,
319
+ ...props
320
+ })
313
321
  });
314
322
  }
315
323
  function DockablePanelDropZone({ side, active, style }) {
@@ -4,8 +4,8 @@ import { Drawer as Drawer$1 } from "@base-ui/react/drawer";
4
4
  //#region src/ui/drawer.d.ts
5
5
  export declare const drawerSides: readonly ["bottom", "top", "right", "left"];
6
6
  export type DrawerSide = (typeof drawerSides)[number];
7
- export declare const drawerContentPaddings: readonly ["default", "none"];
8
- export type DrawerContentPadding = (typeof drawerContentPaddings)[number];
7
+ export declare const drawerBodyPaddings: readonly ["default", "none"];
8
+ export type DrawerBodyPadding = (typeof drawerBodyPaddings)[number];
9
9
  export declare const drawerContentSurfaces: readonly ["background", "card"];
10
10
  export type DrawerContentSurface = (typeof drawerContentSurfaces)[number];
11
11
  export declare const drawerContentVariants: readonly ["edge", "floating"];
@@ -19,9 +19,8 @@ export declare function DrawerTrigger({ className, ...props }: ComponentProps<ty
19
19
  export declare function DrawerClose({ className, ...props }: ComponentProps<typeof Drawer$1.Close> & {
20
20
  style?: CSSProperties & PopupKnobStyle;
21
21
  }): import("react").JSX.Element;
22
- export declare function DrawerContent({ className, children, side, padding, surface, variant, style, ...props }: Omit<ComponentProps<typeof Drawer$1.Popup>, "style"> & {
22
+ export declare function DrawerContent({ className, children, side, surface, variant, style, ...props }: Omit<ComponentProps<typeof Drawer$1.Popup>, "style"> & {
23
23
  side?: DrawerSide;
24
- padding?: DrawerContentPadding;
25
24
  surface?: DrawerContentSurface;
26
25
  variant?: DrawerContentVariant;
27
26
  style?: CSSProperties & PopupKnobStyle;
@@ -29,6 +28,10 @@ export declare function DrawerContent({ className, children, side, padding, surf
29
28
  export declare function DrawerHeader({ className, ...props }: ComponentProps<"div"> & {
30
29
  style?: CSSProperties & PopupKnobStyle;
31
30
  }): import("react").JSX.Element;
31
+ export declare function DrawerBody({ className, padding, ...props }: Omit<ComponentProps<typeof Drawer$1.Content>, "style"> & {
32
+ padding?: DrawerBodyPadding;
33
+ style?: CSSProperties & PopupKnobStyle;
34
+ }): import("react").JSX.Element;
32
35
  export declare function DrawerFooter({ className, ...props }: ComponentProps<"div"> & {
33
36
  style?: CSSProperties & PopupKnobStyle;
34
37
  }): import("react").JSX.Element;
package/dist/ui/drawer.js CHANGED
@@ -1,7 +1,8 @@
1
1
  "use client";
2
- import { cn } from "../lib/cn.js";
3
2
  import { controlEffectsAttribute } from "../skin.js";
3
+ import { cn } from "../lib/cn.js";
4
4
  import { useSkin } from "../skin-provider.js";
5
+ import { createContext, useContext } from "react";
5
6
  import { jsx, jsxs } from "react/jsx-runtime";
6
7
  import { Drawer as Drawer$1 } from "@base-ui/react/drawer";
7
8
  //#region src/ui/drawer.tsx
@@ -11,7 +12,7 @@ const drawerSides = [
11
12
  "right",
12
13
  "left"
13
14
  ];
14
- const drawerContentPaddings = ["default", "none"];
15
+ const drawerBodyPaddings = ["default", "none"];
15
16
  const drawerContentSurfaces = ["background", "card"];
16
17
  const drawerContentVariants = ["edge", "floating"];
17
18
  const swipeFor = {
@@ -58,11 +59,16 @@ const placement = {
58
59
  }
59
60
  }
60
61
  };
62
+ const DrawerModalContext = createContext(true);
61
63
  function Drawer(props) {
62
- const { side = "bottom", swipeDirection, ...rest } = props;
63
- return /* @__PURE__ */ jsx(Drawer$1.Root, {
64
- swipeDirection: swipeDirection ?? swipeFor[side],
65
- ...rest
64
+ const { side = "bottom", swipeDirection, modal = true, ...rest } = props;
65
+ return /* @__PURE__ */ jsx(DrawerModalContext, {
66
+ value: modal === true,
67
+ children: /* @__PURE__ */ jsx(Drawer$1.Root, {
68
+ swipeDirection: swipeDirection ?? swipeFor[side],
69
+ modal,
70
+ ...rest
71
+ })
66
72
  });
67
73
  }
68
74
  function DrawerTrigger({ className, ...props }) {
@@ -83,11 +89,15 @@ function DrawerClose({ className, ...props }) {
83
89
  ...props
84
90
  });
85
91
  }
86
- function DrawerContent({ className, children, side = "bottom", padding = "default", surface = "background", variant = "edge", style, ...props }) {
92
+ function DrawerContent({ className, children, side = "bottom", surface = "background", variant = "edge", style, ...props }) {
87
93
  const skin = useSkin();
94
+ const modal = useContext(DrawerModalContext);
88
95
  const place = placement[variant][side];
89
96
  const grabbable = side === "bottom" || side === "top";
90
- const backdropStyle = style ? { "--cui-popup-backdrop-background": style["--cui-popup-backdrop-background"] } : void 0;
97
+ const backdropStyle = style ? {
98
+ "--cui-popup-backdrop-background": style["--cui-popup-backdrop-background"],
99
+ "--cui-popup-backdrop-blur": style["--cui-popup-backdrop-blur"]
100
+ } : void 0;
91
101
  return /* @__PURE__ */ jsxs(Drawer$1.Portal, { children: [/* @__PURE__ */ jsx(Drawer$1.Backdrop, {
92
102
  "data-control-ui": "drawer",
93
103
  "data-control-family": "popup",
@@ -96,7 +106,7 @@ function DrawerContent({ className, children, side = "bottom", padding = "defaul
96
106
  "data-slot": "backdrop",
97
107
  "data-skin": skin.id,
98
108
  "data-effects": controlEffectsAttribute(skin.effects),
99
- className: "fixed inset-0 z-(--z-overlay)",
109
+ className: cn("fixed inset-0 z-(--z-overlay)", !modal && "pointer-events-none"),
100
110
  style: backdropStyle
101
111
  }), /* @__PURE__ */ jsx(Drawer$1.Viewport, {
102
112
  "data-control-ui": "drawer",
@@ -107,7 +117,7 @@ function DrawerContent({ className, children, side = "bottom", padding = "defaul
107
117
  "data-variant": variant,
108
118
  "data-skin": skin.id,
109
119
  "data-effects": controlEffectsAttribute(skin.effects),
110
- className: cn("fixed inset-0 z-(--z-modal) flex", place.viewport),
120
+ className: cn("fixed inset-0 z-(--z-modal) flex", place.viewport, !modal && "pointer-events-none"),
111
121
  children: /* @__PURE__ */ jsxs(Drawer$1.Popup, {
112
122
  "data-control-ui": "drawer",
113
123
  "data-control-family": "popup",
@@ -116,10 +126,9 @@ function DrawerContent({ className, children, side = "bottom", padding = "defaul
116
126
  "data-slot": "content",
117
127
  "data-side": side,
118
128
  "data-surface": "modal",
119
- "data-padding": padding,
120
129
  "data-surface-variant": surface,
121
130
  "data-variant": variant,
122
- className: cn("flex flex-col", place.popup, className),
131
+ className: cn("flex flex-col", place.popup, !modal && "pointer-events-auto", className),
123
132
  style,
124
133
  ...props,
125
134
  children: [grabbable ? /* @__PURE__ */ jsx("div", {
@@ -128,14 +137,7 @@ function DrawerContent({ className, children, side = "bottom", padding = "defaul
128
137
  "data-popup-kind": "drawer",
129
138
  "data-slot": "handle",
130
139
  className: "shrink-0"
131
- }) : null, /* @__PURE__ */ jsx(Drawer$1.Content, {
132
- "data-control-ui": "drawer",
133
- "data-control-family": "popup",
134
- "data-popup-kind": "drawer",
135
- "data-slot": "scroll",
136
- className: "flex min-h-0 flex-1 flex-col overflow-y-auto",
137
- children
138
- })]
140
+ }) : null, children]
139
141
  })
140
142
  })] });
141
143
  }
@@ -145,7 +147,18 @@ function DrawerHeader({ className, ...props }) {
145
147
  "data-control-family": "popup",
146
148
  "data-popup-kind": "drawer",
147
149
  "data-slot": "header",
148
- className: cn("flex flex-col", className),
150
+ className: cn("flex shrink-0 flex-col", className),
151
+ ...props
152
+ });
153
+ }
154
+ function DrawerBody({ className, padding = "default", ...props }) {
155
+ return /* @__PURE__ */ jsx(Drawer$1.Content, {
156
+ "data-control-ui": "drawer",
157
+ "data-control-family": "popup",
158
+ "data-popup-kind": "drawer",
159
+ "data-slot": "body",
160
+ "data-padding": padding,
161
+ className: cn("flex min-h-0 flex-1 flex-col overflow-y-auto", className),
149
162
  ...props
150
163
  });
151
164
  }
@@ -155,7 +168,7 @@ function DrawerFooter({ className, ...props }) {
155
168
  "data-control-family": "popup",
156
169
  "data-popup-kind": "drawer",
157
170
  "data-slot": "footer",
158
- className: cn("mt-auto flex flex-col", className),
171
+ className: cn("mt-auto flex shrink-0 flex-col sm:flex-row sm:justify-end", className),
159
172
  ...props
160
173
  });
161
174
  }
@@ -180,4 +193,4 @@ function DrawerDescription({ className, ...props }) {
180
193
  });
181
194
  }
182
195
  //#endregion
183
- export { Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger, drawerContentPaddings, drawerContentSurfaces, drawerContentVariants, drawerSides };
196
+ export { Drawer, DrawerBody, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger, drawerBodyPaddings, drawerContentSurfaces, drawerContentVariants, drawerSides };
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { cn } from "../lib/cn.js";
3
2
  import { controlEffectsAttribute } from "../skin.js";
3
+ import { cn } from "../lib/cn.js";
4
4
  import { useSkin } from "../skin-provider.js";
5
5
  import { popupItemStructureClasses } from "../surface-variants.js";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -11,6 +11,8 @@ export type DropzoneProps = Omit<ComponentProps<"div">, "defaultValue" | "onChan
11
11
  onValueChange?: (value: readonly File[], details: DropzoneValueChangeDetails) => void;
12
12
  policy?: DropzonePolicy;
13
13
  disabled?: boolean;
14
+ drag?: boolean;
15
+ paste?: boolean;
14
16
  getFilesFromEvent?: DropzoneGetFilesFromEvent;
15
17
  onDrop?: (details: DropzoneDropDetails) => void;
16
18
  onError?: (error: Error) => void;
@@ -52,7 +54,7 @@ export type DropzoneRemoveProps = ComponentProps<typeof Button> & {
52
54
  };
53
55
  export type DropzoneClearProps = ComponentProps<typeof Button>;
54
56
  export declare function useDropzoneContext(): DropzoneContextValue;
55
- export declare function Dropzone({ value, defaultValue, onValueChange, policy, disabled, getFilesFromEvent, onDrop, onError, className, children, ...props }: DropzoneProps): import("react").JSX.Element;
57
+ export declare function Dropzone({ value, defaultValue, onValueChange, policy, disabled, drag, paste, getFilesFromEvent, onDrop, onError, className, children, ...props }: DropzoneProps): import("react").JSX.Element;
56
58
  export declare function DropzoneArea({ className, ...props }: DropzoneAreaProps): import("react").JSX.Element;
57
59
  export declare function DropzoneInput({ className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...props }: DropzoneInputProps): import("react").JSX.Element;
58
60
  export declare function DropzoneTrigger({ className, children, onClick, disabled, ...props }: DropzoneTriggerProps): import("react").JSX.Element;
@@ -24,7 +24,7 @@ function useDropzoneContext() {
24
24
  if (!context) throw new Error("Dropzone parts must be used inside Dropzone.");
25
25
  return context;
26
26
  }
27
- function Dropzone({ value, defaultValue, onValueChange, policy, disabled, getFilesFromEvent, onDrop, onError, className, children, ...props }) {
27
+ function Dropzone({ value, defaultValue, onValueChange, policy, disabled, drag, paste, getFilesFromEvent, onDrop, onError, className, children, ...props }) {
28
28
  const [globalOverlayCount, setGlobalOverlayCount] = useState(0);
29
29
  const [registerGlobalOverlay] = useState(() => () => {
30
30
  let registered = true;
@@ -41,6 +41,8 @@ function Dropzone({ value, defaultValue, onValueChange, policy, disabled, getFil
41
41
  onValueChange,
42
42
  policy,
43
43
  disabled,
44
+ drag,
45
+ paste,
44
46
  getFilesFromEvent,
45
47
  onDrop,
46
48
  onError,
package/dist/ui/field.js CHANGED
@@ -2,9 +2,9 @@
2
2
  import { cn } from "../lib/cn.js";
3
3
  import { Separator } from "./separator.js";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
- import { cva } from "class-variance-authority";
6
5
  import { Field as Field$1 } from "@base-ui/react/field";
7
6
  import { Fieldset } from "@base-ui/react/fieldset";
7
+ import { cva } from "class-variance-authority";
8
8
  //#region src/ui/field.tsx
9
9
  const fieldVariants = cva("group/field flex w-full", {
10
10
  variants: { orientation: {
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { cn } from "../lib/cn.js";
3
2
  import { controlEffectsAttribute } from "../skin.js";
3
+ import { cn } from "../lib/cn.js";
4
4
  import { useSkin } from "../skin-provider.js";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  import { PreviewCard } from "@base-ui/react/preview-card";
@@ -22,6 +22,16 @@ export type InfiniteCanvasProps = Omit<ComponentProps<"section">, "onChange" | "
22
22
  export type InfiniteCanvasContentProps = ComponentProps<"div"> & {
23
23
  style?: CSSProperties & InfiniteCanvasKnobStyle;
24
24
  };
25
+ export type InfiniteCanvasPoint = {
26
+ x: number;
27
+ y: number;
28
+ };
29
+ export type InfiniteCanvasItemProps = Omit<ComponentProps<"div">, "style"> & {
30
+ x: number;
31
+ y: number;
32
+ onPositionChange?: (position: InfiniteCanvasPoint) => void;
33
+ style?: CSSProperties & InfiniteCanvasKnobStyle;
34
+ };
25
35
  export type InfiniteCanvasControlsProps = Omit<ComponentProps<"div">, "children" | "style"> & {
26
36
  style?: CSSProperties & InfiniteCanvasKnobStyle;
27
37
  };
@@ -35,5 +45,6 @@ type InfiniteCanvasContextValue = {
35
45
  export declare function useInfiniteCanvas(): InfiniteCanvasContextValue;
36
46
  export declare function InfiniteCanvas({ transform: controlledTransform, defaultTransform, onTransformChange, minScale: minScaleProp, maxScale: maxScaleProp, className, children, style, onPointerDown, onPointerMove, onPointerUp, onPointerCancel, onWheel, onKeyDown, "aria-label": ariaLabel, ...props }: InfiniteCanvasProps): import("react").JSX.Element;
37
47
  export declare function InfiniteCanvasContent({ className, style, ...props }: InfiniteCanvasContentProps): import("react").JSX.Element;
48
+ export declare function InfiniteCanvasItem({ x, y, onPositionChange, className, style, onPointerDown, onPointerMove, onPointerUp, onPointerCancel, ...props }: InfiniteCanvasItemProps): import("react").JSX.Element;
38
49
  export declare function InfiniteCanvasControls({ className, ...props }: InfiniteCanvasControlsProps): import("react").JSX.Element;
39
50
  //#endregion
@@ -14,6 +14,9 @@ const DEFAULT_MIN_SCALE = .35;
14
14
  const DEFAULT_MAX_SCALE = 2.5;
15
15
  const KEYBOARD_PAN_STEP = 32;
16
16
  const GRID_SIZE = 24;
17
+ const WHEEL_ZOOM_SPEED = .004;
18
+ const MAX_WHEEL_ZOOM_DELTA = 50;
19
+ const NOTCHED_WHEEL_DELTA = 40;
17
20
  const KEYBOARD_PAN_DIRECTIONS = {
18
21
  ArrowLeft: {
19
22
  x: -1,
@@ -45,10 +48,13 @@ function zoomAroundPoint(transform, nextScale, point) {
45
48
  scale: nextScale
46
49
  };
47
50
  }
51
+ function wheelDeltaMultiplier(event, viewportHeight) {
52
+ if (event.deltaMode === WheelEvent.DOM_DELTA_LINE) return 16;
53
+ if (event.deltaMode === WheelEvent.DOM_DELTA_PAGE) return viewportHeight;
54
+ return 1;
55
+ }
48
56
  function panFromWheel(transform, event, viewportHeight) {
49
- let deltaMultiplier = 1;
50
- if (event.deltaMode === WheelEvent.DOM_DELTA_LINE) deltaMultiplier = 16;
51
- else if (event.deltaMode === WheelEvent.DOM_DELTA_PAGE) deltaMultiplier = viewportHeight;
57
+ const deltaMultiplier = wheelDeltaMultiplier(event, viewportHeight);
52
58
  const horizontalDelta = event.shiftKey && event.deltaX === 0 ? event.deltaY : event.deltaX;
53
59
  const verticalDelta = event.shiftKey && event.deltaX === 0 ? 0 : event.deltaY;
54
60
  return {
@@ -67,6 +73,7 @@ function InfiniteCanvas({ transform: controlledTransform, defaultTransform = DEF
67
73
  const maxScale = Math.max(minScale, maxScaleProp);
68
74
  const [uncontrolledTransform, setUncontrolledTransform] = useState(defaultTransform);
69
75
  const [panning, setPanning] = useState(false);
76
+ const [easing, setEasing] = useState(false);
70
77
  const panRef = useRef(null);
71
78
  const rootRef = useRef(null);
72
79
  const transform = controlledTransform ?? uncontrolledTransform;
@@ -74,7 +81,8 @@ function InfiniteCanvas({ transform: controlledTransform, defaultTransform = DEF
74
81
  useEffect(() => {
75
82
  transformRef.current = transform;
76
83
  }, [transform]);
77
- function commitTransform(next, reason) {
84
+ function commitTransform(next, reason, eased = reason === "control" || reason === "keyboard") {
85
+ setEasing(eased);
78
86
  const bounded = {
79
87
  ...next,
80
88
  scale: clampScale(next.scale, minScale, maxScale)
@@ -152,7 +160,11 @@ function InfiniteCanvas({ transform: controlledTransform, defaultTransform = DEF
152
160
  x: event.clientX - bounds.left,
153
161
  y: event.clientY - bounds.top
154
162
  };
155
- commitTransform(zoomAroundPoint(currentTransform, clampScale(currentTransform.scale * Math.exp(-event.deltaY * .004), minScale, maxScale), point), "wheel");
163
+ const zoomDelta = event.deltaY * wheelDeltaMultiplier(event, root.clientHeight);
164
+ const boundedZoomDelta = Math.min(Math.max(zoomDelta, -50), MAX_WHEEL_ZOOM_DELTA);
165
+ const nextScale = clampScale(currentTransform.scale * Math.exp(-boundedZoomDelta * WHEEL_ZOOM_SPEED), minScale, maxScale);
166
+ const notchedWheel = Math.abs(zoomDelta) >= NOTCHED_WHEEL_DELTA;
167
+ commitTransform(zoomAroundPoint(currentTransform, nextScale, point), "wheel", notchedWheel);
156
168
  return;
157
169
  }
158
170
  commitTransform(panFromWheel(currentTransform, event, root.clientHeight), "wheel");
@@ -203,6 +215,7 @@ function InfiniteCanvas({ transform: controlledTransform, defaultTransform = DEF
203
215
  "data-control-family": "infinite-canvas",
204
216
  "data-slot": "root",
205
217
  "data-panning": panning || void 0,
218
+ "data-easing": easing || void 0,
206
219
  "aria-label": ariaLabel,
207
220
  role: "application",
208
221
  "aria-keyshortcuts": "ArrowLeft ArrowRight ArrowUp ArrowDown + - 0",
@@ -233,6 +246,68 @@ function InfiniteCanvasContent({ className, style, ...props }) {
233
246
  }
234
247
  });
235
248
  }
249
+ function InfiniteCanvasItem({ x, y, onPositionChange, className, style, onPointerDown, onPointerMove, onPointerUp, onPointerCancel, ...props }) {
250
+ const { transform } = useInfiniteCanvas();
251
+ const dragRef = useRef(null);
252
+ const [dragging, setDragging] = useState(false);
253
+ function beginDrag(event) {
254
+ onPointerDown?.(event);
255
+ if (event.defaultPrevented || !onPositionChange || !event.isPrimary || event.button !== 0) return;
256
+ event.currentTarget.setPointerCapture(event.pointerId);
257
+ dragRef.current = {
258
+ pointerId: event.pointerId,
259
+ startPointer: {
260
+ x: event.clientX,
261
+ y: event.clientY
262
+ },
263
+ startPosition: {
264
+ x,
265
+ y
266
+ }
267
+ };
268
+ setDragging(true);
269
+ }
270
+ function updateDrag(event) {
271
+ onPointerMove?.(event);
272
+ const drag = dragRef.current;
273
+ if (event.defaultPrevented || !drag || drag.pointerId !== event.pointerId) return;
274
+ onPositionChange?.({
275
+ x: drag.startPosition.x + (event.clientX - drag.startPointer.x) / transform.scale,
276
+ y: drag.startPosition.y + (event.clientY - drag.startPointer.y) / transform.scale
277
+ });
278
+ }
279
+ function finishDrag(event) {
280
+ if (dragRef.current?.pointerId !== event.pointerId) return;
281
+ if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
282
+ dragRef.current = null;
283
+ setDragging(false);
284
+ }
285
+ function endDrag(event) {
286
+ onPointerUp?.(event);
287
+ finishDrag(event);
288
+ }
289
+ function cancelDrag(event) {
290
+ onPointerCancel?.(event);
291
+ finishDrag(event);
292
+ }
293
+ return /* @__PURE__ */ jsx("div", {
294
+ ...props,
295
+ "data-control-ui": "infinite-canvas",
296
+ "data-control-family": "infinite-canvas",
297
+ "data-slot": "item",
298
+ "data-dragging": dragging || void 0,
299
+ className: cn("absolute", onPositionChange && "cursor-grab touch-none data-dragging:cursor-grabbing", className),
300
+ style: {
301
+ ...style,
302
+ left: x,
303
+ top: y
304
+ },
305
+ onPointerDown: beginDrag,
306
+ onPointerMove: updateDrag,
307
+ onPointerUp: endDrag,
308
+ onPointerCancel: cancelDrag
309
+ });
310
+ }
236
311
  function InfiniteCanvasControls({ className, ...props }) {
237
312
  const canvas = useInfiniteCanvas();
238
313
  const percentage = Math.round(canvas.transform.scale * 100);
@@ -240,7 +315,7 @@ function InfiniteCanvasControls({ className, ...props }) {
240
315
  "data-control-ui": "infinite-canvas",
241
316
  "data-control-family": "infinite-canvas",
242
317
  "data-slot": "controls",
243
- className: cn("absolute right-3 bottom-3 z-40 flex items-center", className),
318
+ className: cn("absolute z-40 flex items-center", className),
244
319
  ...props,
245
320
  children: [
246
321
  /* @__PURE__ */ jsx(Button, {
@@ -276,4 +351,4 @@ function InfiniteCanvasControls({ className, ...props }) {
276
351
  });
277
352
  }
278
353
  //#endregion
279
- export { InfiniteCanvas, InfiniteCanvasContent, InfiniteCanvasControls, useInfiniteCanvas };
354
+ export { InfiniteCanvas, InfiniteCanvasContent, InfiniteCanvasControls, InfiniteCanvasItem, useInfiniteCanvas };
@@ -12,7 +12,8 @@ export type InputGroupProps = Omit<ComponentProps<"div">, "style"> & {
12
12
  export type InputGroupAddonProps = ComponentProps<"span"> & {
13
13
  style?: CSSProperties & FieldKnobStyle;
14
14
  };
15
- export declare function InputGroup({ size, className, render, children, ...props }: InputGroupProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
15
+ export declare function useIsInsideInputGroup(): boolean;
16
+ export declare function InputGroup({ size, className, render, children, ...props }: InputGroupProps): import("react").JSX.Element;
16
17
  export declare function InputGroupAddon({ className, ...props }: InputGroupAddonProps): import("react").JSX.Element;
17
18
  export declare function InputGroupInput({ className, ...props }: ComponentProps<"input"> & {
18
19
  style?: CSSProperties & FieldKnobStyle;
@@ -1,11 +1,16 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
- import { useRender } from "@base-ui/react/use-render";
3
+ import { createContext, use } from "react";
4
4
  import { jsx } from "react/jsx-runtime";
5
+ import { useRender } from "@base-ui/react/use-render";
5
6
  //#region src/ui/input-group.tsx
7
+ const InputGroupSurfaceContext = createContext(false);
8
+ function useIsInsideInputGroup() {
9
+ return use(InputGroupSurfaceContext);
10
+ }
6
11
  function InputGroup({ size = "md", className, render, children, ...props }) {
7
12
  const classes = cn("flex min-w-0 w-full items-center overflow-hidden", className);
8
- return useRender({
13
+ const group = useRender({
9
14
  defaultTagName: "div",
10
15
  render,
11
16
  props: {
@@ -19,6 +24,10 @@ function InputGroup({ size = "md", className, render, children, ...props }) {
19
24
  children
20
25
  }
21
26
  });
27
+ return /* @__PURE__ */ jsx(InputGroupSurfaceContext, {
28
+ value: true,
29
+ children: group
30
+ });
22
31
  }
23
32
  function InputGroupAddon({ className, ...props }) {
24
33
  return /* @__PURE__ */ jsx("span", {
@@ -41,4 +50,4 @@ function InputGroupInput({ className, ...props }) {
41
50
  });
42
51
  }
43
52
  //#endregion
44
- export { InputGroup, InputGroupAddon, InputGroupInput };
53
+ export { InputGroup, InputGroupAddon, InputGroupInput, useIsInsideInputGroup };