@ctrl-ui/react 0.8.6 → 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 +3 -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 +18 -0
  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 +1 -1
  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,12 +1,12 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
3
  import { useSkin } from "../skin-provider.js";
4
- import { SIDEBAR_COOKIE_NAME } from "../control-props.js";
5
4
  import { TooltipProvider } from "./tooltip.js";
5
+ import { SIDEBAR_COOKIE_NAME } from "../control-props.js";
6
6
  import { useIsMobile } from "../hooks/use-mobile.js";
7
7
  import { createContext, useContext, useEffect, useLayoutEffect, useRef, useState } from "react";
8
- import { useRender } from "@base-ui/react/use-render";
9
8
  import { jsx } from "react/jsx-runtime";
9
+ import { useRender } from "@base-ui/react/use-render";
10
10
  //#region src/ui/sidebar-provider.tsx
11
11
  const SIDEBAR_COOKIE_MAX_AGE = 604800;
12
12
  const SIDEBAR_WIDTH = "16rem";
@@ -2,8 +2,8 @@
2
2
  import { cn } from "../lib/cn.js";
3
3
  import { useSidebar, useSidebarElements, useSidebarSurface } from "./sidebar-provider.js";
4
4
  import { useEffect, useLayoutEffect, useRef, useState } from "react";
5
- import { useRender } from "@base-ui/react/use-render";
6
5
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
6
+ import { useRender } from "@base-ui/react/use-render";
7
7
  //#region src/ui/sidebar-resize-rail.tsx
8
8
  const DRAG_THRESHOLD_PX = 5;
9
9
  const KEYBOARD_STEP_PX = 10;
@@ -8,9 +8,9 @@ import { SidebarProvider, SidebarSurfaceContext, useSidebar, useSidebarElements,
8
8
  import { SidebarResizeRail } from "./sidebar-resize-rail.js";
9
9
  import { SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarMenu, SidebarMenuAction, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, sidebarMenuButtonSizes, sidebarMenuButtonVariants } from "./sidebar-menu.js";
10
10
  import { useState } from "react";
11
- import { useRender } from "@base-ui/react/use-render";
12
11
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
13
12
  import { PanelLeftIcon } from "lucide-react";
13
+ import { useRender } from "@base-ui/react/use-render";
14
14
  import { createPortal } from "react-dom";
15
15
  //#region src/ui/sidebar.tsx
16
16
  const SIDEBAR_WIDTH_MOBILE = "18rem";
@@ -1,5 +1,5 @@
1
1
  import { TableOfContentsKnobStyle } from "../knob-contracts/table-of-contents-knobs.js";
2
- import { CSSProperties, ComponentProps } from "react";
2
+ import { CSSProperties, ComponentProps, ReactNode } from "react";
3
3
  //#region src/ui/table-of-contents.d.ts
4
4
  export type TocItem = {
5
5
  href: string;
@@ -7,7 +7,7 @@ export type TocItem = {
7
7
  level?: number;
8
8
  children?: TocItem[];
9
9
  };
10
- export declare const tableOfContentsVariants: readonly ["background", "trail", "both"];
10
+ export declare const tableOfContentsVariants: readonly ["range", "progress"];
11
11
  export type TableOfContentsVariant = (typeof tableOfContentsVariants)[number];
12
12
  export type TableOfContentsProps = Omit<Omit<ComponentProps<"nav">, "children">, "style"> & {
13
13
  style?: CSSProperties & TableOfContentsKnobStyle;
@@ -15,7 +15,8 @@ export type TableOfContentsProps = Omit<Omit<ComponentProps<"nav">, "children">,
15
15
  items: TocItem[];
16
16
  label?: string;
17
17
  variant?: TableOfContentsVariant;
18
+ indicator?: ReactNode;
18
19
  };
19
20
  export declare function useVisibleSections(ids: string[]): string[];
20
- export declare function TableOfContents({ items, label, variant, className, style, ...props }: TableOfContentsProps): import("react").JSX.Element | null;
21
+ export declare function TableOfContents({ items, label, variant, indicator, className, style, ...props }: TableOfContentsProps): import("react").JSX.Element | null;
21
22
  //#endregion
@@ -1,17 +1,10 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
- import { TrackHighlight } from "../extensions/track-highlight.js";
4
- import { useEffect, useState } from "react";
3
+ import { useEffect, useRef, useState } from "react";
5
4
  import { jsx, jsxs } from "react/jsx-runtime";
6
5
  //#region src/ui/table-of-contents.tsx
7
- const tableOfContentsVariants = [
8
- "background",
9
- "trail",
10
- "both"
11
- ];
6
+ const tableOfContentsVariants = ["range", "progress"];
12
7
  const DETECTION_MARGIN = "-80px 0px -20% 0px";
13
- const TOC_ITEM_SELECTOR = "[data-control-ui=\"table-of-contents\"][data-slot=\"item\"]";
14
- const TOC_ACTIVE_SELECTOR = "[data-control-ui=\"table-of-contents\"][data-slot=\"item\"][data-active]";
15
8
  function getScrollContainer(el) {
16
9
  let node = el.parentElement;
17
10
  while (node) {
@@ -72,22 +65,96 @@ function normalizeItems(items, baseLevel, fallbackLevel = 2, nestingDepth = 0) {
72
65
  function flattenItems(items) {
73
66
  return items.flatMap((item) => [item, ...flattenItems(item.children ?? [])]);
74
67
  }
75
- function activeIdsInRange(visibleIds, targetIds) {
76
- let firstIndex = targetIds.length;
77
- let lastIndex = -1;
78
- for (const id of visibleIds) {
79
- const index = targetIds.indexOf(id);
80
- if (index < 0) continue;
81
- firstIndex = Math.min(firstIndex, index);
82
- lastIndex = Math.max(lastIndex, index);
68
+ function findActiveItems(visibleIds, flatItems, targetIds) {
69
+ const indexes = visibleIds.map((id) => targetIds.indexOf(id)).filter((index) => index >= 0);
70
+ if (indexes.length === 0) return [];
71
+ return flatItems.slice(Math.min(...indexes), Math.max(...indexes) + 1);
72
+ }
73
+ function readLengthKnob(style, knob) {
74
+ return Number.parseFloat(style.getPropertyValue(knob)) || 0;
75
+ }
76
+ function inDocumentOrder([, a], [, b]) {
77
+ return a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
78
+ }
79
+ function measureRail(track, itemElements) {
80
+ const style = getComputedStyle(track);
81
+ const indentSize = readLengthKnob(style, "--cui-table-of-contents-item-indent-size");
82
+ const strokeInset = Math.max(readLengthKnob(style, "--cui-table-of-contents-rail-size"), readLengthKnob(style, "--cui-table-of-contents-trail-size")) / 2;
83
+ const isRtl = style.direction === "rtl";
84
+ const points = [];
85
+ let length = 0;
86
+ const lineTo = (x, y) => {
87
+ const previous = points.at(-1);
88
+ if (previous) length += Math.hypot(x - previous.x, y - previous.y);
89
+ points.push({
90
+ x,
91
+ y
92
+ });
93
+ return length;
94
+ };
95
+ const stops = /* @__PURE__ */ new Map();
96
+ for (const [href, item] of [...itemElements].sort(inDocumentOrder)) {
97
+ const inlineOffset = Number(item.dataset.depth) * indentSize + strokeInset;
98
+ const x = isRtl ? track.clientWidth - inlineOffset : inlineOffset;
99
+ const top = item.offsetTop;
100
+ const previous = points.at(-1);
101
+ const topStop = lineTo(previous?.x ?? x, top);
102
+ if (previous && previous.x !== x) lineTo(x, top + Math.min(indentSize, item.offsetHeight / 2));
103
+ stops.set(href, {
104
+ top: topStop,
105
+ center: lineTo(x, top + item.offsetHeight / 2),
106
+ bottom: lineTo(x, top + item.offsetHeight)
107
+ });
83
108
  }
84
- if (lastIndex < 0) return /* @__PURE__ */ new Set();
85
- return new Set(targetIds.slice(firstIndex, lastIndex + 1));
109
+ return {
110
+ path: points.map(({ x, y }, index) => `${index === 0 ? "M" : "L"}${x} ${y}`).join(""),
111
+ length,
112
+ stops
113
+ };
114
+ }
115
+ function useRailGeometry(trackRef, itemElements) {
116
+ const [rail, setRail] = useState(null);
117
+ useEffect(() => {
118
+ const track = trackRef.current;
119
+ if (!track) return;
120
+ const measure = () => setRail(measureRail(track, itemElements));
121
+ const resizeObserver = new ResizeObserver(measure);
122
+ const mutationObserver = new MutationObserver(measure);
123
+ resizeObserver.observe(track);
124
+ mutationObserver.observe(track, {
125
+ subtree: true,
126
+ childList: true,
127
+ attributeFilter: ["data-depth"]
128
+ });
129
+ return () => {
130
+ resizeObserver.disconnect();
131
+ mutationObserver.disconnect();
132
+ };
133
+ }, [trackRef, itemElements]);
134
+ return rail;
135
+ }
136
+ function trailStyle(rail, activeItems, variant) {
137
+ const firstStop = rail.stops.get(activeItems[0]?.href ?? "");
138
+ const lastStop = rail.stops.get(activeItems.at(-1)?.href ?? "");
139
+ const start = variant === "progress" ? 0 : firstStop?.top ?? 0;
140
+ const end = variant === "progress" ? firstStop?.center ?? 0 : lastStop?.bottom ?? 0;
141
+ return {
142
+ "--_toc-rail-length": `${rail.length}px`,
143
+ "--_toc-trail-start": `${start}px`,
144
+ "--_toc-trail-length": `${Math.max(0, end - start)}px`,
145
+ "--_toc-indicator-distance": `${firstStop?.center ?? 0}px`
146
+ };
86
147
  }
87
- function TableOfContents({ items, label = "On this page", variant = "both", className, style, ...props }) {
148
+ function TableOfContents({ items, label = "On this page", variant = "range", indicator, className, style, ...props }) {
149
+ const trackRef = useRef(null);
150
+ const [itemElements] = useState(() => /* @__PURE__ */ new Map());
88
151
  const normalizedItems = normalizeItems(items, Math.min(...collectLevels(items), 2));
89
- const targetIds = flattenItems(normalizedItems).map((item) => item.href.replace(/^#/, ""));
90
- const activeSet = activeIdsInRange(useVisibleSections(targetIds), targetIds);
152
+ const flatItems = flattenItems(normalizedItems);
153
+ const targetIds = flatItems.map((item) => item.href.replace(/^#/, ""));
154
+ const activeItems = findActiveItems(useVisibleSections(targetIds), flatItems, targetIds);
155
+ const activeHrefs = new Set(activeItems.map((item) => item.href));
156
+ const rail = useRailGeometry(trackRef, itemElements);
157
+ const hasActiveSection = activeItems.length > 0;
91
158
  if (items.length === 0) return null;
92
159
  return /* @__PURE__ */ jsxs("nav", {
93
160
  "data-control-ui": "table-of-contents",
@@ -104,58 +171,70 @@ function TableOfContents({ items, label = "On this page", variant = "both", clas
104
171
  "data-slot": "label",
105
172
  children: label
106
173
  }), /* @__PURE__ */ jsxs("div", {
174
+ ref: trackRef,
107
175
  "data-control-ui": "table-of-contents",
108
176
  "data-control-family": "table-of-contents",
109
177
  "data-slot": "track",
110
- className: "relative isolate",
178
+ className: "relative",
179
+ style: rail ? trailStyle(rail, activeItems, variant) : void 0,
111
180
  children: [
112
- /* @__PURE__ */ jsx("span", {
181
+ rail && /* @__PURE__ */ jsxs("svg", {
113
182
  "aria-hidden": true,
114
- "data-control-ui": "table-of-contents",
115
- "data-control-family": "table-of-contents",
116
- "data-slot": "rail",
117
- className: "pointer-events-none absolute inset-y-0 start-0 -z-20"
118
- }),
119
- /* @__PURE__ */ jsx(TrackHighlight, {
120
- "data-variant": variant,
121
- itemSelector: TOC_ITEM_SELECTOR,
122
- activeSelector: TOC_ACTIVE_SELECTOR,
123
- range: true,
124
- followHover: false,
125
- children: variant !== "background" && /* @__PURE__ */ jsx("div", {
126
- "aria-hidden": true,
183
+ className: "pointer-events-none absolute inset-0 size-full overflow-visible",
184
+ children: [/* @__PURE__ */ jsx("path", {
185
+ "data-control-ui": "table-of-contents",
186
+ "data-control-family": "table-of-contents",
187
+ "data-slot": "rail",
188
+ d: rail.path
189
+ }), /* @__PURE__ */ jsx("path", {
127
190
  "data-control-ui": "table-of-contents",
128
191
  "data-control-family": "table-of-contents",
129
192
  "data-slot": "trail",
130
- className: "absolute inset-y-0 start-0"
131
- })
193
+ "data-visible": hasActiveSection || void 0,
194
+ d: rail.path
195
+ })]
132
196
  }),
133
197
  /* @__PURE__ */ jsx(TocList, {
134
198
  items: normalizedItems,
135
- activeSet,
136
- variant,
199
+ activeHrefs,
200
+ itemElements,
137
201
  root: true
202
+ }),
203
+ rail && indicator && /* @__PURE__ */ jsx("span", {
204
+ "aria-hidden": true,
205
+ "data-control-ui": "table-of-contents",
206
+ "data-control-family": "table-of-contents",
207
+ "data-slot": "indicator",
208
+ "data-visible": hasActiveSection || void 0,
209
+ className: "pointer-events-none absolute top-0 left-0",
210
+ style: { offsetPath: `path("${rail.path}")` },
211
+ children: indicator
138
212
  })
139
213
  ]
140
214
  })]
141
215
  });
142
216
  }
143
- function TocList({ items, activeSet, variant, root = false }) {
217
+ function TocList({ items, activeHrefs, itemElements, root = false }) {
144
218
  return /* @__PURE__ */ jsx("ul", {
145
219
  "data-control-ui": "table-of-contents",
146
220
  "data-control-family": "table-of-contents",
147
221
  "data-slot": "list",
148
222
  "data-nested": root ? void 0 : "true",
149
223
  children: items.map((item) => {
150
- const targetId = item.href.replace(/^#/, "");
151
- const isActive = activeSet.has(targetId);
224
+ const isActive = activeHrefs.has(item.href);
152
225
  const itemStyle = { "--_toc-depth": item.depth };
153
226
  return /* @__PURE__ */ jsxs("li", { children: [/* @__PURE__ */ jsx("a", {
227
+ ref: (element) => {
228
+ if (!element) return;
229
+ itemElements.set(item.href, element);
230
+ return () => {
231
+ itemElements.delete(item.href);
232
+ };
233
+ },
154
234
  "data-control-ui": "table-of-contents",
155
235
  "data-control-family": "table-of-contents",
156
236
  "data-slot": "item",
157
237
  "data-active": isActive || void 0,
158
- "data-variant": variant,
159
238
  "data-level": item.level,
160
239
  "data-depth": item.depth,
161
240
  "aria-current": isActive ? "location" : void 0,
@@ -165,8 +244,8 @@ function TocList({ items, activeSet, variant, root = false }) {
165
244
  children: item.label
166
245
  }), item.children && /* @__PURE__ */ jsx(TocList, {
167
246
  items: item.children,
168
- activeSet,
169
- variant
247
+ activeHrefs,
248
+ itemElements
170
249
  })] }, item.href);
171
250
  })
172
251
  });
package/dist/ui/table.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { cn } from "../lib/cn.js";
2
+ import { ScrollArea } from "./scroll-area.js";
2
3
  import { jsx } from "react/jsx-runtime";
3
4
  //#region src/ui/table.tsx
4
5
  function Table({ className, ...props }) {
@@ -6,13 +7,16 @@ function Table({ className, ...props }) {
6
7
  "data-control-ui": "table",
7
8
  "data-control-family": "table",
8
9
  "data-slot": "container",
9
- className: "relative w-full overflow-x-auto",
10
- children: /* @__PURE__ */ jsx("table", {
11
- "data-control-ui": "table",
12
- "data-control-family": "table",
13
- "data-slot": "root",
14
- className: cn("w-full caption-bottom", className),
15
- ...props
10
+ className: "relative w-full",
11
+ children: /* @__PURE__ */ jsx(ScrollArea, {
12
+ lockAxis: "y",
13
+ children: /* @__PURE__ */ jsx("table", {
14
+ "data-control-ui": "table",
15
+ "data-control-family": "table",
16
+ "data-slot": "root",
17
+ className: cn("w-full caption-bottom", className),
18
+ ...props
19
+ })
16
20
  })
17
21
  });
18
22
  }
package/dist/ui/toast.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 { Button } from "./button.js";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -15,6 +15,6 @@ export type ToggleGroupProps<TValue extends string = string> = Omit<ComponentPro
15
15
  orientation?: "horizontal" | "vertical";
16
16
  indicator?: HoverIndicator;
17
17
  };
18
- export declare function Toggle({ variant, size, tone, active, showCheck, className, pressed, defaultPressed, onPressedChange, value, disabled, children, ...props }: ToggleProps): import("react").JSX.Element;
18
+ export declare function Toggle({ variant, size, tone, active, iconOnly, showCheck, className, pressed, defaultPressed, onPressedChange, value, disabled, children, ...props }: ToggleProps): import("react").JSX.Element;
19
19
  export declare function ToggleGroup<TValue extends string = string>({ className, orientation, indicator, children, ...props }: ToggleGroupProps<TValue>): import("react").JSX.Element;
20
20
  //#endregion
package/dist/ui/toggle.js CHANGED
@@ -8,7 +8,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
8
8
  import { Toggle as Toggle$1 } from "@base-ui/react/toggle";
9
9
  import { ToggleGroup as ToggleGroup$1 } from "@base-ui/react/toggle-group";
10
10
  //#region src/ui/toggle.tsx
11
- function Toggle({ variant = "surface", size = "sm", tone = "neutral", active, showCheck = false, className, pressed, defaultPressed, onPressedChange, value, disabled, children, ...props }) {
11
+ function Toggle({ variant = "surface", size = "sm", tone = "neutral", active, iconOnly = false, showCheck = false, className, pressed, defaultPressed, onPressedChange, value, disabled, children, ...props }) {
12
12
  const tracksHover = useContext(ButtonTrackContext);
13
13
  return /* @__PURE__ */ jsx(Toggle$1, {
14
14
  "data-track-item": tracksHover ? "" : void 0,
@@ -30,6 +30,7 @@ function Toggle({ variant = "surface", size = "sm", tone = "neutral", active, sh
30
30
  "data-variant": variant,
31
31
  "data-tone": tone,
32
32
  "data-size": size,
33
+ "data-icon-only": iconOnly ? "true" : void 0,
33
34
  className: cn(buttonStructureClasses, renderProps.className, className),
34
35
  children: /* @__PURE__ */ jsxs("span", {
35
36
  "data-control-ui": "toggle",
@@ -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 { Tooltip as Tooltip$1 } from "@base-ui/react/tooltip";
package/dist/ui/tree.js CHANGED
@@ -3,9 +3,9 @@ import { cn } from "../lib/cn.js";
3
3
  import { useSkin } from "../skin-provider.js";
4
4
  import { TrackHighlight } from "../extensions/track-highlight.js";
5
5
  import { Children, createContext, isValidElement, useContext, useRef, useState } from "react";
6
- import { useRender } from "@base-ui/react/use-render";
7
6
  import { jsx, jsxs } from "react/jsx-runtime";
8
7
  import { ChevronRightIcon } from "lucide-react";
8
+ import { useRender } from "@base-ui/react/use-render";
9
9
  import { Collapsible } from "@base-ui/react/collapsible";
10
10
  //#region src/ui/tree.tsx
11
11
  const TYPEAHEAD_TIMEOUT = 500;
@@ -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 { ScrollArea } from "./scroll-area.js";
5
6
  import { popupItemStructureClasses } from "../surface-variants.js";
6
7
  import { jsx } from "react/jsx-runtime";
7
8
  import { Popover } from "@base-ui/react/popover";
@@ -33,8 +34,11 @@ function TriggerMenu({ open, onOpenChange, anchorRect, side = "top", align = "st
33
34
  "data-popup-part": "list-surface",
34
35
  initialFocus: false,
35
36
  finalFocus: false,
36
- className: cn("max-h-[min(18rem,var(--available-height))] w-64 max-w-[var(--available-width)] overflow-y-auto", className),
37
- children
37
+ className: cn("grid max-h-[min(18rem,var(--available-height))] w-64 max-w-[var(--available-width)] grid-rows-[minmax(0,1fr)]", className),
38
+ children: /* @__PURE__ */ jsx(ScrollArea, {
39
+ lockAxis: "x",
40
+ children
41
+ })
38
42
  })
39
43
  }) })
40
44
  });
package/dist/user-ask.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { cn } from "./lib/cn.js";
3
- import { Button } from "./ui/button.js";
4
3
  import { useUserAsk } from "./hooks/use-user-ask.js";
4
+ import { Button } from "./ui/button.js";
5
5
  import { Kbd } from "./ui/kbd.js";
6
6
  import { createContext, useContext, useEffect, useId, useRef } from "react";
7
7
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ctrl-ui/react",
3
- "version": "0.8.6",
3
+ "version": "0.8.7",
4
4
  "description": "Control UI components, blocks, and primitives with neutral defaults and consumer-owned themes.",
5
5
  "license": "MIT",
6
6
  "repository": {