@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
package/dist/ui/input.js CHANGED
@@ -1,9 +1,18 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
+ import { useIsInsideInputGroup } from "./input-group.js";
3
4
  import { jsx } from "react/jsx-runtime";
4
5
  import { Input as Input$1 } from "@base-ui/react/input";
5
6
  //#region src/ui/input.tsx
6
7
  function Input({ size = "md", className, ...props }) {
8
+ if (useIsInsideInputGroup()) return /* @__PURE__ */ jsx(Input$1, {
9
+ "data-control-ui": "input-group",
10
+ "data-control-family": "field",
11
+ "data-field-kind": "input-group",
12
+ "data-slot": "input",
13
+ className: cn("h-full min-w-0 flex-1", className),
14
+ ...props
15
+ });
7
16
  return /* @__PURE__ */ jsx(Input$1, {
8
17
  "data-control-ui": "input",
9
18
  "data-slot": "root",
package/dist/ui/item.js CHANGED
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
3
  import { Separator } from "./separator.js";
4
- import { useRender } from "@base-ui/react/use-render";
5
4
  import { jsx } from "react/jsx-runtime";
5
+ import { useRender } from "@base-ui/react/use-render";
6
6
  //#region src/ui/item.tsx
7
7
  const itemVariants = [
8
8
  "default",
@@ -1,4 +1,5 @@
1
1
  import { cn } from "../lib/cn.js";
2
+ import { ScrollArea } from "./scroll-area.js";
2
3
  import { Code, CodeActions, CodeContent, CodeCopy, CodeHeader, CodeTitle } from "./code.js";
3
4
  import { CodeDiff } from "./code-diff.js";
4
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -159,14 +160,16 @@ function MarkdownTable({ className, children, node: _node, ...props }) {
159
160
  "data-control-ui": "markdown",
160
161
  "data-control-family": "markdown",
161
162
  "data-slot": "table-scroll",
162
- className: "overflow-x-auto",
163
- children: /* @__PURE__ */ jsx("table", {
164
- "data-control-ui": "markdown",
165
- "data-control-family": "markdown",
166
- "data-slot": "table",
167
- className: cn("w-full", className),
168
- ...props,
169
- children
163
+ children: /* @__PURE__ */ jsx(ScrollArea, {
164
+ lockAxis: "y",
165
+ children: /* @__PURE__ */ jsx("table", {
166
+ "data-control-ui": "markdown",
167
+ "data-control-family": "markdown",
168
+ "data-slot": "table",
169
+ className: cn("w-full", className),
170
+ ...props,
171
+ children
172
+ })
170
173
  })
171
174
  });
172
175
  }
@@ -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";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
- import { useRender } from "@base-ui/react/use-render";
4
3
  import { jsx } from "react/jsx-runtime";
4
+ import { useRender } from "@base-ui/react/use-render";
5
5
  import { Collapsible } from "@base-ui/react/collapsible";
6
6
  //#region src/ui/morphing-panel.tsx
7
7
  function MorphingPanelTriggerElement({ triggerProps, open, render, className, children }) {
@@ -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, jsxs } from "react/jsx-runtime";
6
6
  import { NavigationMenu as NavigationMenu$1 } from "@base-ui/react/navigation-menu";
@@ -62,7 +62,7 @@ export type NumberFieldScrubAreaProps = ComponentProps<"span"> & {
62
62
  } & {
63
63
  style?: CSSProperties & FieldKnobStyle;
64
64
  };
65
- export declare function NumberField({ size, value, defaultValue, children, ...props }: NumberFieldProps): import("react").JSX.Element;
65
+ export declare function NumberField({ size, value, defaultValue, className, children, ...props }: NumberFieldProps): import("react").JSX.Element;
66
66
  export declare function NumberFieldGroup({ className, children, ...props }: NumberFieldGroupProps): import("react").JSX.Element;
67
67
  export declare function NumberFieldInput({ className, ...props }: NumberFieldInputProps): import("react").JSX.Element;
68
68
  export declare function NumberFieldDecrement({ className, children, ...props }: NumberFieldDecrementProps): import("react").JSX.Element;
@@ -1,16 +1,18 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
+ import { useIsInsideInputGroup } from "./input-group.js";
3
4
  import { createContext, useContext } from "react";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
6
  import { NumberField as NumberField$1 } from "@base-ui/react/number-field";
6
7
  //#region src/ui/number-field.tsx
7
8
  const NumberFieldSizeContext = createContext("md");
8
- function NumberField({ size = "md", value, defaultValue, children, ...props }) {
9
+ function NumberField({ size = "md", value, defaultValue, className, children, ...props }) {
9
10
  return /* @__PURE__ */ jsx(NumberFieldSizeContext.Provider, {
10
11
  value: size,
11
12
  children: /* @__PURE__ */ jsx(NumberField$1.Root, {
12
13
  value,
13
14
  defaultValue,
15
+ className: cn("flex flex-col items-start gap-1.5", className),
14
16
  ...props,
15
17
  children
16
18
  })
@@ -18,6 +20,15 @@ function NumberField({ size = "md", value, defaultValue, children, ...props }) {
18
20
  }
19
21
  function NumberFieldGroup({ className, children, ...props }) {
20
22
  const size = useContext(NumberFieldSizeContext);
23
+ if (useIsInsideInputGroup()) return /* @__PURE__ */ jsx(NumberField$1.Group, {
24
+ "data-control-ui": "number-field",
25
+ "data-field-kind": "number-field",
26
+ "data-slot": "group",
27
+ "data-control-family": "field",
28
+ className: cn("inline-flex items-stretch overflow-hidden", className),
29
+ ...props,
30
+ children
31
+ });
21
32
  return /* @__PURE__ */ jsx(NumberField$1.Group, {
22
33
  "data-control-ui": "number-field",
23
34
  "data-field-kind": "number-field",
@@ -70,7 +81,7 @@ function NumberFieldScrubArea({ className, children, ...props }) {
70
81
  "data-control-family": "field",
71
82
  "data-field-kind": "number-field",
72
83
  "data-slot": "scrub-area",
73
- className: cn("cursor-ew-resize touch-pan-y select-none", className),
84
+ className: cn("inline-flex shrink-0 cursor-ew-resize touch-pan-y select-none items-center [&>svg]:size-3.5 [&>svg]:shrink-0", className),
74
85
  ...props,
75
86
  children: [children, /* @__PURE__ */ jsx(NumberField$1.ScrubAreaCursor, {
76
87
  "data-control-ui": "number-field",
@@ -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 { normalizePhoneInputText, normalizePhoneInputValue } from "../lib/phone-input-format.js";
6
5
  import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "./command.js";
6
+ import { normalizePhoneInputText, normalizePhoneInputValue } from "../lib/phone-input-format.js";
7
7
  import { useState } from "react";
8
8
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
- import PhoneNumberInput, { getCountryCallingCode, parsePhoneNumber } from "react-phone-number-input/max";
10
9
  import flags from "react-phone-number-input/flags";
10
+ import PhoneNumberInput, { getCountryCallingCode, parsePhoneNumber } from "react-phone-number-input/max";
11
11
  //#region src/ui/phone-input.tsx
12
12
  const FLAG_COMPONENTS = flags;
13
13
  const PhoneNumberInputWithRef = PhoneNumberInput;
@@ -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 { Popover as Popover$1 } from "@base-ui/react/popover";
@@ -25,4 +25,5 @@ export type RadioProps = Omit<{
25
25
  };
26
26
  export declare function RadioGroup<TValue extends string = string>({ className, orientation, ...props }: RadioGroupProps<TValue>): import("react").JSX.Element;
27
27
  export declare function Radio({ className, disabled, ...props }: RadioProps): import("react").JSX.Element;
28
+ export declare function RadioGroupItem({ className, htmlFor, children, ...props }: ComponentProps<"label">): import("react").JSX.Element;
28
29
  //#endregion
@@ -33,5 +33,15 @@ function Radio({ className, disabled, ...props }) {
33
33
  })
34
34
  });
35
35
  }
36
+ function RadioGroupItem({ className, htmlFor, children, ...props }) {
37
+ return /* @__PURE__ */ jsx("label", {
38
+ htmlFor,
39
+ "data-control-ui": "radio-group",
40
+ "data-slot": "label",
41
+ className: cn("flex cursor-pointer items-start gap-2.5 rounded-(--radius-control) p-2 text-body has-[[data-disabled]]:cursor-not-allowed [&>[data-control-family=choice]]:mt-[calc((1lh_-_var(--spacing)*4)/2)]", className),
42
+ ...props,
43
+ children
44
+ });
45
+ }
36
46
  //#endregion
37
- export { Radio, RadioGroup };
47
+ export { Radio, RadioGroup, RadioGroupItem };
@@ -49,7 +49,24 @@ export type ResizableHandleProps = Omit<ComponentProps<"div">, "role" | "tabInde
49
49
  disableDoubleClick?: boolean;
50
50
  style?: CSSProperties & ResizableKnobStyle;
51
51
  };
52
- export declare function ResizablePanelGroup({ className, orientation, variant, children, ...props }: ResizablePanelGroupProps): import("react").JSX.Element;
52
+ export type ResizableFloatingPanelSide = "left" | "right";
53
+ export type ResizableSeparatorState = "inactive" | "hover" | "focus" | "active";
54
+ type ResizableFloatingPanelStyle = CSSProperties & ResizableKnobStyle & {
55
+ "--resizable-floating-width"?: string;
56
+ };
57
+ export type ResizableFloatingPanelProps = Omit<ComponentProps<"div">, "style"> & {
58
+ side?: ResizableFloatingPanelSide;
59
+ size?: number;
60
+ defaultSize?: number;
61
+ onSizeChange?: (size: number) => void;
62
+ minSize?: number;
63
+ maxSize?: number;
64
+ handleVariant?: ResizableHandleVariant;
65
+ handleLabel?: string;
66
+ style?: ResizableFloatingPanelStyle;
67
+ };
68
+ export declare function ResizablePanelGroup({ className, orientation, variant, disableCursor, children, ...props }: ResizablePanelGroupProps): import("react").JSX.Element;
53
69
  export declare function ResizablePanel({ className, ...props }: ResizablePanelProps): import("react").JSX.Element;
54
70
  export declare function ResizableHandle({ className, variant, withHandle, children, ...props }: ResizableHandleProps): import("react").JSX.Element;
71
+ export declare function ResizableFloatingPanel({ side, size: controlledSize, defaultSize, onSizeChange, minSize, maxSize, handleVariant, handleLabel, className, style, children, ...props }: ResizableFloatingPanelProps): import("react").JSX.Element;
55
72
  //#endregion
@@ -1,13 +1,24 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
- import { createContext, useContext } from "react";
3
+ import { createContext, useContext, useRef, useState } from "react";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  import { Group, Panel, Separator } from "react-resizable-panels";
6
6
  //#region src/ui/resizable.tsx
7
- const OrientationContext = createContext("horizontal");
8
- function ResizablePanelGroup({ className, orientation = "horizontal", variant = "framed", children, ...props }) {
9
- return /* @__PURE__ */ jsx(OrientationContext.Provider, {
10
- value: orientation,
7
+ const ResizableGroupContext = createContext({
8
+ orientation: "horizontal",
9
+ disableCursor: false
10
+ });
11
+ const FLOATING_KEYBOARD_STEP_PX = 10;
12
+ const FLOATING_ARROW_DIRECTIONS = {
13
+ ArrowLeft: -1,
14
+ ArrowRight: 1
15
+ };
16
+ function ResizablePanelGroup({ className, orientation = "horizontal", variant = "framed", disableCursor = false, children, ...props }) {
17
+ return /* @__PURE__ */ jsx(ResizableGroupContext.Provider, {
18
+ value: {
19
+ orientation,
20
+ disableCursor
21
+ },
11
22
  children: /* @__PURE__ */ jsx(Group, {
12
23
  "data-control-ui": "resizable",
13
24
  "data-control-family": "resizable",
@@ -15,6 +26,7 @@ function ResizablePanelGroup({ className, orientation = "horizontal", variant =
15
26
  "data-surface": "panel",
16
27
  "data-variant": variant,
17
28
  orientation,
29
+ disableCursor: true,
18
30
  className: cn("flex h-full w-full", className),
19
31
  ...props,
20
32
  children
@@ -31,13 +43,15 @@ function ResizablePanel({ className, ...props }) {
31
43
  });
32
44
  }
33
45
  function ResizableHandle({ className, variant = "solid", withHandle, children, ...props }) {
34
- const axis = useContext(OrientationContext) === "horizontal" ? "vertical" : "horizontal";
46
+ const { orientation, disableCursor } = useContext(ResizableGroupContext);
47
+ const axis = orientation === "horizontal" ? "vertical" : "horizontal";
35
48
  return /* @__PURE__ */ jsxs(Separator, {
36
49
  "data-control-ui": "resizable",
37
50
  "data-control-family": "resizable",
38
51
  "data-slot": "handle",
39
52
  "data-variant": variant,
40
53
  "data-axis": axis,
54
+ "data-cursor": disableCursor ? "none" : void 0,
41
55
  className: cn("relative flex items-center justify-center", axis === "vertical" ? "w-px touch-pan-y" : "h-px touch-pan-x", className),
42
56
  ...props,
43
57
  children: [withHandle ? /* @__PURE__ */ jsx("span", {
@@ -51,6 +65,112 @@ function ResizableHandle({ className, variant = "solid", withHandle, children, .
51
65
  }) : null, children]
52
66
  });
53
67
  }
68
+ function ResizableFloatingPanel({ side = "right", size: controlledSize, defaultSize = 280, onSizeChange, minSize = 160, maxSize = 640, handleVariant = "hover", handleLabel = "Resize panel", className, style, children, ...props }) {
69
+ const [uncontrolledSize, setUncontrolledSize] = useState(defaultSize);
70
+ const [hovered, setHovered] = useState(false);
71
+ const [focused, setFocused] = useState(false);
72
+ const [resizing, setResizing] = useState(false);
73
+ const panelRef = useRef(null);
74
+ const resizeRef = useRef(null);
75
+ const size = controlledSize ?? uncontrolledSize;
76
+ const growthPerPointerPx = side === "right" ? -1 : 1;
77
+ function changeSize(next) {
78
+ const clamped = Math.round(Math.min(Math.max(next, minSize), maxSize));
79
+ if (clamped === size) return;
80
+ if (controlledSize === void 0) setUncontrolledSize(clamped);
81
+ onSizeChange?.(clamped);
82
+ }
83
+ function beginResize(event) {
84
+ const panel = panelRef.current;
85
+ if (!panel || !event.isPrimary || event.button !== 0) return;
86
+ event.preventDefault();
87
+ event.currentTarget.focus({ preventScroll: true });
88
+ event.currentTarget.setPointerCapture(event.pointerId);
89
+ resizeRef.current = {
90
+ pointerId: event.pointerId,
91
+ startX: event.clientX,
92
+ startSize: panel.getBoundingClientRect().width
93
+ };
94
+ setResizing(true);
95
+ }
96
+ function updateResize(event) {
97
+ const session = resizeRef.current;
98
+ if (session?.pointerId !== event.pointerId) return;
99
+ changeSize(session.startSize + (event.clientX - session.startX) * growthPerPointerPx);
100
+ }
101
+ function endResize(event) {
102
+ if (resizeRef.current?.pointerId !== event.pointerId) return;
103
+ resizeRef.current = null;
104
+ setResizing(false);
105
+ }
106
+ function resizeWithKeyboard(event) {
107
+ const arrowDirection = FLOATING_ARROW_DIRECTIONS[event.key];
108
+ const step = event.shiftKey ? 50 : FLOATING_KEYBOARD_STEP_PX;
109
+ if (arrowDirection) changeSize(size + arrowDirection * step * growthPerPointerPx);
110
+ else if (event.key === "Home") changeSize(minSize);
111
+ else if (event.key === "End") changeSize(maxSize);
112
+ else return;
113
+ event.preventDefault();
114
+ }
115
+ let separatorState = "inactive";
116
+ if (resizing) separatorState = "active";
117
+ else if (focused) separatorState = "focus";
118
+ else if (hovered) separatorState = "hover";
119
+ const panelStyle = {
120
+ ...style,
121
+ "--resizable-floating-width": `${size}px`
122
+ };
123
+ return /* @__PURE__ */ jsxs("div", {
124
+ ref: panelRef,
125
+ ...props,
126
+ "data-control-ui": "resizable",
127
+ "data-control-family": "resizable",
128
+ "data-slot": "floating",
129
+ "data-side": side,
130
+ className: cn("absolute inset-y-2 isolate flex w-(--resizable-floating-width) max-w-[calc(100%-1rem)] flex-col", side === "right" ? "right-2" : "left-2", className),
131
+ style: panelStyle,
132
+ children: [
133
+ /* @__PURE__ */ jsx("div", {
134
+ "aria-hidden": "true",
135
+ "data-control-ui": "resizable",
136
+ "data-control-family": "popup",
137
+ "data-popup-kind": "resizable",
138
+ "data-popup-part": "surface",
139
+ "data-popup-static": "",
140
+ "data-surface": "floating",
141
+ "data-slot": "surface",
142
+ className: "pointer-events-none absolute inset-0 -z-1"
143
+ }),
144
+ children,
145
+ /* @__PURE__ */ jsx("div", {
146
+ role: "separator",
147
+ tabIndex: 0,
148
+ "aria-label": handleLabel,
149
+ "aria-orientation": "vertical",
150
+ "aria-valuenow": size,
151
+ "aria-valuemin": minSize,
152
+ "aria-valuemax": maxSize,
153
+ "data-control-ui": "resizable",
154
+ "data-control-family": "resizable",
155
+ "data-slot": "handle",
156
+ "data-variant": handleVariant,
157
+ "data-axis": "vertical",
158
+ "data-separator": separatorState,
159
+ className: cn("absolute inset-y-0 w-px touch-none after:absolute after:inset-y-0 after:-inset-x-1 after:content-['']", side === "right" ? "left-0" : "right-0"),
160
+ onPointerDown: beginResize,
161
+ onPointerMove: updateResize,
162
+ onPointerUp: endResize,
163
+ onPointerCancel: endResize,
164
+ onPointerEnter: () => setHovered(true),
165
+ onPointerLeave: () => setHovered(false),
166
+ onFocus: () => setFocused(true),
167
+ onBlur: () => setFocused(false),
168
+ onKeyDown: resizeWithKeyboard,
169
+ onDoubleClick: () => changeSize(defaultSize)
170
+ })
171
+ ]
172
+ });
173
+ }
54
174
  function GripIcon({ className }) {
55
175
  return /* @__PURE__ */ jsxs("svg", {
56
176
  viewBox: "0 0 4 16",
@@ -79,4 +199,4 @@ function GripIcon({ className }) {
79
199
  });
80
200
  }
81
201
  //#endregion
82
- export { ResizableHandle, ResizablePanel, ResizablePanelGroup };
202
+ export { ResizableFloatingPanel, ResizableHandle, ResizablePanel, ResizablePanelGroup };
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
3
  import { Button } from "./button.js";
4
+ import { Drawer, DrawerBody, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger } from "./drawer.js";
4
5
  import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "./dialog.js";
5
- import { Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger } from "./drawer.js";
6
6
  import { createContext, useContext, useState, useSyncExternalStore } from "react";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
8
  //#region src/ui/responsive-dialog.tsx
@@ -81,9 +81,12 @@ function ResponsiveDialogContent({ className, dialogClassName, drawerClassName,
81
81
  children
82
82
  });
83
83
  return /* @__PURE__ */ jsxs(DrawerContent, {
84
- className: cn("relative pb-[max(1rem,env(safe-area-inset-bottom))]", className, drawerClassName),
84
+ className: cn("relative", className, drawerClassName),
85
85
  ...props,
86
- children: [children, showCloseButton ? /* @__PURE__ */ jsxs(ResponsiveDialogClose, {
86
+ children: [/* @__PURE__ */ jsx(DrawerBody, {
87
+ padding: "none",
88
+ children
89
+ }), showCloseButton ? /* @__PURE__ */ jsxs(ResponsiveDialogClose, {
87
90
  variant: "ghost",
88
91
  size: "xs",
89
92
  className: "absolute right-3 top-3 w-[var(--control-h-xs)] px-0",
@@ -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 { stepAfter, stepBefore, tourPosition } from "./rich-tooltip-tour.js";
6
6
  import { createContext, useContext, useEffect, useState } from "react";
@@ -1,6 +1,7 @@
1
1
  import { ScrollAreaKnobStyle } from "../knob-contracts/scroll-area-knobs.js";
2
2
  import { ProgressiveBlurProps } from "./progressive-blur.js";
3
3
  import { CSSProperties, ComponentProps, Ref } from "react";
4
+ import { ScrollArea as ScrollArea$1 } from "@base-ui/react/scroll-area";
4
5
  //#region src/ui/scroll-area.d.ts
5
6
  export declare const scrollAreaScrollbarVisibilities: readonly ["scroll", "hover", "always"];
6
7
  export type ScrollAreaScrollbarVisibility = (typeof scrollAreaScrollbarVisibilities)[number];
@@ -9,11 +10,13 @@ export type ScrollAreaViewportProps = Omit<ComponentProps<"div">, "children" | "
9
10
  "data-control-ui"?: string;
10
11
  "data-control-family"?: string;
11
12
  "data-slot"?: string;
13
+ render?: ComponentProps<typeof ScrollArea$1.Viewport>["render"];
12
14
  };
13
15
  export type ScrollAreaProps = Omit<ComponentProps<"div">, "style"> & {
14
16
  style?: CSSProperties & ScrollAreaKnobStyle;
15
17
  } & {
16
18
  viewportClassName?: string;
19
+ contentClassName?: string;
17
20
  viewportProps?: ScrollAreaViewportProps;
18
21
  viewportRef?: Ref<HTMLDivElement>;
19
22
  maxHeight?: string;
@@ -23,5 +26,5 @@ export type ScrollAreaProps = Omit<ComponentProps<"div">, "style"> & {
23
26
  lockAxis?: ScrollAreaLockAxis;
24
27
  scrollbarVisibility?: ScrollAreaScrollbarVisibility;
25
28
  };
26
- export declare function ScrollArea({ className, viewportClassName, viewportProps, viewportRef, maxHeight, mask, blur, blurProps, lockAxis, scrollbarVisibility, children, style, ...props }: ScrollAreaProps): import("react").JSX.Element;
29
+ export declare function ScrollArea({ className, viewportClassName, contentClassName, viewportProps, viewportRef, maxHeight, mask, blur, blurProps, lockAxis, scrollbarVisibility, children, style, ...props }: ScrollAreaProps): import("react").JSX.Element;
27
30
  //#endregion
@@ -35,7 +35,7 @@ function viewportStyle(maxHeight, lockX, lockY) {
35
35
  ...lockY ? { overflowY: "hidden" } : {}
36
36
  };
37
37
  }
38
- function ScrollArea({ className, viewportClassName, viewportProps, viewportRef, maxHeight, mask = true, blur, blurProps, lockAxis, scrollbarVisibility = "scroll", children, style, ...props }) {
38
+ function ScrollArea({ className, viewportClassName, contentClassName, viewportProps, viewportRef, maxHeight, mask = true, blur, blurProps, lockAxis, scrollbarVisibility = "hover", children, style, ...props }) {
39
39
  const skin = useSkin();
40
40
  const resolvedBlur = blur ?? skin.scrollAreaBlur ?? false;
41
41
  const lockX = lockAxis === "x" || lockAxis === "both";
@@ -72,6 +72,7 @@ function ScrollArea({ className, viewportClassName, viewportProps, viewportRef,
72
72
  "data-control-ui": "scroll-area",
73
73
  "data-control-family": "scroll-area",
74
74
  "data-slot": "content",
75
+ className: contentClassName,
75
76
  style: { minWidth: 0 },
76
77
  children
77
78
  })
@@ -2,6 +2,7 @@ import { ControlledChoice } from "../control-props.js";
2
2
  import { ControlSize } from "../control-variants.js";
3
3
  import { ButtonKnobStyle } from "../knob-contracts/button-knobs.js";
4
4
  import { PopupKnobStyle } from "../knob-contracts/popup-knobs.js";
5
+ import { FieldKnobStyle } from "../knob-contracts/field-knobs.js";
5
6
  import { CSSProperties, ComponentProps, ReactNode } from "react";
6
7
  import { Select as Select$1 } from "@base-ui/react/select";
7
8
  //#region src/ui/select.d.ts
@@ -21,7 +22,7 @@ export type SelectProps<TValue extends string = string> = Omit<ControlledChoice<
21
22
  export declare const selectTriggerVariants: readonly ["surface", "ghost"];
22
23
  export type SelectTriggerVariant = (typeof selectTriggerVariants)[number];
23
24
  export type SelectTriggerProps = Omit<ComponentProps<"button">, "style"> & {
24
- style?: CSSProperties & ButtonKnobStyle;
25
+ style?: CSSProperties & FieldKnobStyle & ButtonKnobStyle;
25
26
  } & {
26
27
  size?: ControlSize;
27
28
  variant?: SelectTriggerVariant;
package/dist/ui/select.js CHANGED
@@ -1,7 +1,9 @@
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 { Button } from "./button.js";
6
+ import { ScrollArea } from "./scroll-area.js";
5
7
  import { popupItemStructureClasses } from "../surface-variants.js";
6
8
  import { jsx, jsxs } from "react/jsx-runtime";
7
9
  import { Select as Select$1 } from "@base-ui/react/select";
@@ -16,46 +18,58 @@ function Select({ children, onValueChange, ...props }) {
16
18
  children
17
19
  });
18
20
  }
21
+ const selectTriggerLayoutClasses = "group relative isolate inline-flex shrink-0 items-center justify-between overflow-visible";
22
+ function SelectIcon() {
23
+ return /* @__PURE__ */ jsx(Select$1.Icon, {
24
+ "data-control-ui": "select",
25
+ "data-control-family": "popup",
26
+ "data-popup-kind": "select",
27
+ "data-slot": "icon",
28
+ className: "relative z-[1]",
29
+ children: /* @__PURE__ */ jsx("svg", {
30
+ viewBox: "0 0 12 12",
31
+ className: "size-3",
32
+ "aria-hidden": "true",
33
+ fill: "none",
34
+ children: /* @__PURE__ */ jsx("path", {
35
+ d: "M3 4.5 6 7.5 9 4.5",
36
+ stroke: "currentColor",
37
+ strokeWidth: "1.3",
38
+ strokeLinecap: "round",
39
+ strokeLinejoin: "round"
40
+ })
41
+ })
42
+ });
43
+ }
19
44
  function SelectTrigger({ size = "sm", variant = "surface", className, children, disabled, ...props }) {
45
+ if (variant === "ghost") return /* @__PURE__ */ jsxs(Select$1.Trigger, {
46
+ render: /* @__PURE__ */ jsx(Button, {
47
+ variant: "ghost",
48
+ size
49
+ }),
50
+ className: cn(selectTriggerLayoutClasses, className),
51
+ disabled,
52
+ ...props,
53
+ children: [children, /* @__PURE__ */ jsx(SelectIcon, {})]
54
+ });
20
55
  return /* @__PURE__ */ jsxs(Select$1.Trigger, {
21
56
  "data-control-ui": "select",
22
- "data-control-family": "button",
23
- "data-popup-kind": "select",
57
+ "data-control-family": "field",
58
+ "data-field-kind": "select",
24
59
  "data-slot": "trigger",
25
60
  "data-control": "true",
26
61
  "data-size": size,
27
- "data-variant": variant,
28
- "data-tone": "neutral",
29
- "data-shape": "default",
30
- className: cn("group relative isolate inline-flex shrink-0 items-center justify-between overflow-visible", className),
62
+ className: cn(selectTriggerLayoutClasses, className),
31
63
  disabled,
32
64
  ...props,
33
65
  children: [/* @__PURE__ */ jsx("span", {
34
- "data-control-ui": "button",
35
- "data-control-family": "button",
36
- "data-slot": "content",
37
- className: "relative z-[1] inline-flex min-w-0 items-center justify-center gap-[inherit]",
38
- children
39
- }), /* @__PURE__ */ jsx(Select$1.Icon, {
40
66
  "data-control-ui": "select",
41
- "data-control-family": "popup",
42
- "data-popup-kind": "select",
43
- "data-slot": "icon",
44
- className: "relative z-[1]",
45
- children: /* @__PURE__ */ jsx("svg", {
46
- viewBox: "0 0 12 12",
47
- className: "size-3",
48
- "aria-hidden": "true",
49
- fill: "none",
50
- children: /* @__PURE__ */ jsx("path", {
51
- d: "M3 4.5 6 7.5 9 4.5",
52
- stroke: "currentColor",
53
- strokeWidth: "1.3",
54
- strokeLinecap: "round",
55
- strokeLinejoin: "round"
56
- })
57
- })
58
- })]
67
+ "data-control-family": "field",
68
+ "data-field-kind": "select",
69
+ "data-slot": "value",
70
+ className: "inline-flex min-w-0 items-center gap-[inherit]",
71
+ children
72
+ }), /* @__PURE__ */ jsx(SelectIcon, {})]
59
73
  });
60
74
  }
61
75
  function SelectValue({ children, ...props }) {
@@ -82,12 +96,19 @@ function SelectContent({ className, children, alignItemWithTrigger = false, ...p
82
96
  "data-surface": "floating",
83
97
  "data-control-family": "popup",
84
98
  "data-popup-part": "list-surface",
85
- className: cn("max-h-[min(20rem,var(--available-height))] min-w-[var(--anchor-width)] overflow-y-auto", className),
99
+ className: cn("grid max-h-[min(20rem,var(--available-height))] min-w-[var(--anchor-width)] grid-rows-[minmax(0,1fr)]", className),
86
100
  ...props,
87
- children
101
+ children: /* @__PURE__ */ jsx(ScrollArea, {
102
+ lockAxis: "x",
103
+ viewportProps: { render: renderListAsScrollViewport },
104
+ children
105
+ })
88
106
  })
89
107
  }) });
90
108
  }
109
+ function renderListAsScrollViewport({ role: _role, tabIndex: _tabIndex, ...viewportProps }) {
110
+ return /* @__PURE__ */ jsx(Select$1.List, { ...viewportProps });
111
+ }
91
112
  function SelectItem({ className, children, disabled, ...props }) {
92
113
  return /* @__PURE__ */ jsxs(Select$1.Item, {
93
114
  "data-control-ui": "select",
@@ -99,6 +120,10 @@ function SelectItem({ className, children, disabled, ...props }) {
99
120
  className: cn(popupItemStructureClasses, className),
100
121
  ...props,
101
122
  children: [/* @__PURE__ */ jsx(Select$1.ItemText, {
123
+ "data-control-ui": "select",
124
+ "data-control-family": "popup",
125
+ "data-popup-kind": "select",
126
+ "data-slot": "item-text",
102
127
  className: "flex min-w-0 flex-1 items-center",
103
128
  children
104
129
  }), /* @__PURE__ */ jsx("span", {
package/dist/ui/sheet.js CHANGED
@@ -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, jsxs } from "react/jsx-runtime";
6
6
  import { Dialog } from "@base-ui/react/dialog";
@@ -5,8 +5,8 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip.js";
5
5
  import { useSidebar } from "./sidebar-provider.js";
6
6
  import { TrackHighlight } from "../extensions/track-highlight.js";
7
7
  import { createContext, useContext } from "react";
8
- import { useRender } from "@base-ui/react/use-render";
9
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
+ import { useRender } from "@base-ui/react/use-render";
10
10
  import { cva } from "class-variance-authority";
11
11
  //#region src/ui/sidebar-menu.tsx
12
12
  const sidebarMenuButtonVariants = ["default", "outline"];