@ctrl-ui/react 0.9.17 → 0.9.18

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 (63) hide show
  1. package/dist/action-bar.d.ts +2 -2
  2. package/dist/action-bar.js +34 -15
  3. package/dist/activity.d.ts +1 -1
  4. package/dist/activity.js +1 -1
  5. package/dist/audio-device-select.js +1 -1
  6. package/dist/audio-recorder.js +1 -1
  7. package/dist/blocks/agent-run-sidebar.js +1 -1
  8. package/dist/blocks/agent-run.js +1 -1
  9. package/dist/blocks/coding-agent.js +1 -1
  10. package/dist/blocks/design-canvas-inspector.js +1 -1
  11. package/dist/blocks/design-canvas.js +1 -1
  12. package/dist/blocks/discussion.js +1 -1
  13. package/dist/blocks/file-explorer.js +1 -1
  14. package/dist/blocks/settings.js +1 -1
  15. package/dist/blocks/theme-toggle.js +1 -1
  16. package/dist/chat-composer-attachment.js +1 -1
  17. package/dist/chat-composer.js +1 -1
  18. package/dist/chat-layout.js +1 -1
  19. package/dist/context.js +1 -1
  20. package/dist/filter-bar/parts.js +1 -1
  21. package/dist/inline-citation.js +1 -1
  22. package/dist/knob-contracts/sidebar-knobs.d.ts +1 -1
  23. package/dist/knob-contracts/sidebar-knobs.js +7 -0
  24. package/dist/markdown-editor/context.d.ts +2 -0
  25. package/dist/markdown-editor/drag-handle.js +1 -1
  26. package/dist/markdown-editor/extensions.d.ts +14 -4
  27. package/dist/markdown-editor/extensions.js +39 -34
  28. package/dist/markdown-editor/suggestions.js +4 -5
  29. package/dist/markdown-editor/toolbar.d.ts +1 -1
  30. package/dist/markdown-editor/toolbar.js +5 -6
  31. package/dist/markdown-editor.d.ts +7 -1
  32. package/dist/markdown-editor.js +16 -6
  33. package/dist/source-badge.js +1 -1
  34. package/dist/styles/index.css +1 -0
  35. package/dist/styles/recipes/action-bar.css +12 -3
  36. package/dist/styles/recipes/popup-controls.css +3 -3
  37. package/dist/styles/recipes/sidebar-panes.css +192 -0
  38. package/dist/styles/recipes/sidebar-parts.css +61 -3
  39. package/dist/task-list.js +1 -1
  40. package/dist/tool-approval.js +1 -1
  41. package/dist/ui/accordion.js +1 -1
  42. package/dist/ui/breadcrumb.js +1 -1
  43. package/dist/ui/code.js +1 -1
  44. package/dist/ui/dropzone.js +1 -1
  45. package/dist/ui/emoji-picker.js +1 -1
  46. package/dist/ui/flow.js +1 -1
  47. package/dist/ui/hover-card.d.ts +3 -1
  48. package/dist/ui/hover-card.js +2 -2
  49. package/dist/ui/infinite-canvas.js +1 -1
  50. package/dist/ui/pagination.js +1 -1
  51. package/dist/ui/rich-tooltip.js +1 -1
  52. package/dist/ui/sidebar-menu.js +6 -6
  53. package/dist/ui/sidebar-mobile.js +1 -1
  54. package/dist/ui/sidebar-provider.d.ts +2 -0
  55. package/dist/ui/sidebar-provider.js +7 -1
  56. package/dist/ui/sidebar.d.ts +12 -0
  57. package/dist/ui/sidebar.js +34 -9
  58. package/dist/ui/spinner.js +1 -1
  59. package/dist/ui/stepper.js +1 -1
  60. package/dist/ui/toast.js +1 -1
  61. package/dist/ui/tree.js +1 -1
  62. package/dist/user-ask.js +1 -1
  63. package/package.json +1 -1
@@ -2,7 +2,7 @@
2
2
  import { cn } from "../lib/cn.js";
3
3
  import { useSkin } from "../skin-provider.js";
4
4
  import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip.js";
5
- import { SidebarSurfaceContext, useSidebar } from "./sidebar-provider.js";
5
+ import { SidebarIconRailContext, SidebarSurfaceContext, useSidebarIconOnly } from "./sidebar-provider.js";
6
6
  import { TrackHighlight } from "../extensions/track-highlight.js";
7
7
  import { createContext, useContext, useRef, useState } from "react";
8
8
  import { useRender } from "@base-ui/react/use-render";
@@ -111,9 +111,9 @@ function SidebarMenuBadge({ className, ...props }) {
111
111
  });
112
112
  }
113
113
  function SidebarMenuButton({ render, isActive = false, variant = "default", size = "default", tooltip, className, children, ref, ...props }) {
114
- const { isMobile, state } = useSidebar();
115
114
  const surface = useContext(SidebarSurfaceContext);
116
- const tooltipEnabled = !isMobile && state === "collapsed" && surface?.collapsible === "icon";
115
+ const inIconRail = useContext(SidebarIconRailContext);
116
+ const iconOnly = useSidebarIconOnly();
117
117
  const indicator = useContext(SidebarMenuContext);
118
118
  const buttonRef = useRef(null);
119
119
  const [textLabel, setTextLabel] = useState("");
@@ -137,16 +137,16 @@ function SidebarMenuButton({ render, isActive = false, variant = "default", size
137
137
  children
138
138
  }
139
139
  });
140
- if (!tooltip && surface?.collapsible !== "icon") return button;
140
+ if (!tooltip && !inIconRail && surface?.collapsible !== "icon") return button;
141
141
  return /* @__PURE__ */ jsxs(Tooltip, {
142
- disabled: !tooltipEnabled,
142
+ disabled: !iconOnly,
143
143
  onOpenChange: (open) => {
144
144
  if (open && !tooltip) setTextLabel(buttonRef.current?.textContent?.trim() ?? "");
145
145
  },
146
146
  children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: button }), /* @__PURE__ */ jsx(TooltipContent, {
147
147
  side: surface?.side === "right" ? "inline-start" : "inline-end",
148
148
  align: "center",
149
- hidden: !tooltipEnabled,
149
+ hidden: !iconOnly,
150
150
  children: tooltip ?? textLabel
151
151
  })]
152
152
  });
@@ -2,9 +2,9 @@
2
2
  import { cn } from "../lib/cn.js";
3
3
  import { useSidebar, useSidebarElements } from "./sidebar-provider.js";
4
4
  import { SidebarMenuButton } from "./sidebar-menu.js";
5
+ import { MenuIcon } from "lucide-react";
5
6
  import { useRender } from "@base-ui/react/use-render";
6
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
- import { MenuIcon } from "lucide-react";
8
8
  //#region src/ui/sidebar-mobile.tsx
9
9
  function SidebarMobileNav({ variant = "bar", "aria-label": label = "Mobile navigation", className, style, ...props }) {
10
10
  const { layout } = useSidebar();
@@ -37,12 +37,14 @@ export declare const SidebarSurfaceContext: import("react").Context<{
37
37
  collapsible: "offcanvas" | "icon" | "none";
38
38
  railContainer: HTMLDivElement | null;
39
39
  } | null>;
40
+ export declare const SidebarIconRailContext: import("react").Context<boolean>;
40
41
  export declare function useSidebarElements(): SidebarElements;
41
42
  export declare function useSidebarSurface(): {
42
43
  side: "left" | "right";
43
44
  collapsible: "offcanvas" | "icon" | "none";
44
45
  railContainer: HTMLDivElement | null;
45
46
  };
47
+ export declare function useSidebarIconOnly(): boolean;
46
48
  export declare function useSidebar(): SidebarContextProps;
47
49
  export type SidebarProviderProps = Omit<ComponentProps<"div">, "style"> & {
48
50
  defaultOpen?: boolean;
@@ -12,6 +12,7 @@ const SIDEBAR_KEYBOARD_SHORTCUT = "b";
12
12
  const SIDEBAR_MOBILE_BREAKPOINT = "--breakpoint-sidebar";
13
13
  const SidebarElementsContext = createContext(null);
14
14
  const SidebarSurfaceContext = createContext(null);
15
+ const SidebarIconRailContext = createContext(false);
15
16
  function useSidebarElements() {
16
17
  const elements = useContext(SidebarElementsContext);
17
18
  if (!elements) throw new Error("Sidebar parts must be used within a SidebarProvider.");
@@ -22,6 +23,11 @@ function useSidebarSurface() {
22
23
  if (!surface) throw new Error("SidebarRail must be used within a Sidebar.");
23
24
  return surface;
24
25
  }
26
+ function useSidebarIconOnly() {
27
+ const { isMobile, state } = useSidebar();
28
+ const surface = useContext(SidebarSurfaceContext);
29
+ return useContext(SidebarIconRailContext) || !isMobile && state === "collapsed" && surface?.collapsible === "icon";
30
+ }
25
31
  function focusOutsideCollapsedContent({ offcanvasRef, railRef, triggerRef }) {
26
32
  const container = offcanvasRef.current;
27
33
  if (!container?.contains(document.activeElement)) return;
@@ -157,4 +163,4 @@ function SidebarProvider({ defaultOpen = true, open: openProp, onOpenChange, def
157
163
  });
158
164
  }
159
165
  //#endregion
160
- export { SidebarProvider, SidebarSurfaceContext, useSidebar, useSidebarElements, useSidebarSurface };
166
+ export { SidebarIconRailContext, SidebarProvider, SidebarSurfaceContext, useSidebar, useSidebarElements, useSidebarIconOnly, useSidebarSurface };
@@ -19,6 +19,16 @@ export type SidebarInsetProps = Omit<ComponentProps<"main">, "style" | "id"> & {
19
19
  style?: CSSProperties & SidebarKnobStyle;
20
20
  };
21
21
  type SidebarSurfaceStyle = CSSProperties & SidebarKnobStyle;
22
+ export type SidebarIconRailLayer = "sidebar" | "raised";
23
+ export type SidebarPanelLayer = "sidebar" | "raised" | "content";
24
+ export type SidebarIconRailProps = Omit<ComponentProps<"div">, "style"> & {
25
+ layer?: SidebarIconRailLayer;
26
+ style?: SidebarSurfaceStyle;
27
+ };
28
+ export type SidebarPanelProps = Omit<ComponentProps<"div">, "style"> & {
29
+ layer?: SidebarPanelLayer;
30
+ style?: SidebarSurfaceStyle;
31
+ };
22
32
  export type SidebarProps = Omit<ComponentProps<"div">, "style"> & {
23
33
  side?: "left" | "right";
24
34
  variant?: SidebarLayout;
@@ -40,6 +50,8 @@ export declare function SidebarHeader({ className, divider, ...props }: Componen
40
50
  export declare function SidebarFooter({ className, ...props }: ComponentProps<"div"> & {
41
51
  style?: CSSProperties & SidebarKnobStyle;
42
52
  }): import("react").JSX.Element;
53
+ export declare function SidebarIconRail({ layer, className, ...props }: SidebarIconRailProps): import("react").JSX.Element;
54
+ export declare function SidebarPanel({ layer, className, ...props }: SidebarPanelProps): import("react").JSX.Element;
43
55
  export declare function SidebarContent({ className, children, ...props }: ComponentProps<"div">): import("react").JSX.Element;
44
56
  //#endregion
45
57
  export { SidebarGroup, SidebarGroupContent, type SidebarGroupContentProps, SidebarGroupLabel, type SidebarGroupLabelProps, type SidebarLayoutMode, SidebarMenu, SidebarMenuAction, type SidebarMenuActionProps, SidebarMenuBadge, type SidebarMenuBadgeProps, SidebarMenuButton, type SidebarMenuButtonProps, type SidebarMenuButtonSize, type SidebarMenuButtonVariant, SidebarMenuItem, SidebarMenuSub, SidebarMobileNav, SidebarMobileNavItem, type SidebarMobileNavProps, SidebarMobileTrigger, type SidebarMobileTriggerProps, SidebarProvider, type SidebarProviderProps, type SidebarSelectionIndicator, type SidebarStyle, sidebarMenuButtonSizes, sidebarMenuButtonVariants, useSidebar };
@@ -5,14 +5,14 @@ import { Button } from "./button.js";
5
5
  import { ScrollArea } from "./scroll-area.js";
6
6
  import { Drawer, DrawerBody, DrawerClose, DrawerContent, DrawerFooter, DrawerHeader, DrawerTitle } from "./drawer.js";
7
7
  import { Sheet, SheetContent, SheetHeader, SheetTitle } from "./sheet.js";
8
- import { SidebarProvider, SidebarSurfaceContext, useSidebar, useSidebarElements, useSidebarSurface } from "./sidebar-provider.js";
8
+ import { SidebarIconRailContext, SidebarProvider, SidebarSurfaceContext, useSidebar, useSidebarElements, useSidebarIconOnly, useSidebarSurface } from "./sidebar-provider.js";
9
9
  import { SidebarResizeRail } from "./sidebar-resize-rail.js";
10
10
  import { SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, sidebarMenuButtonSizes, sidebarMenuButtonVariants } from "./sidebar-menu.js";
11
11
  import { SidebarMobileNav, SidebarMobileNavItem, SidebarMobileTrigger } from "./sidebar-mobile.js";
12
+ import { PanelLeftIcon } from "lucide-react";
12
13
  import { useState } from "react";
13
14
  import { useRender } from "@base-ui/react/use-render";
14
15
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
15
- import { PanelLeftIcon } from "lucide-react";
16
16
  import { createPortal } from "react-dom";
17
17
  //#region src/ui/sidebar.tsx
18
18
  const SIDEBAR_WIDTH_MOBILE = "18rem";
@@ -58,7 +58,7 @@ function SidebarSurface({ variant, mobileVariant = "sheet", label = "Navigation"
58
58
  "data-control-ui": "sidebar",
59
59
  "data-control-family": "sidebar",
60
60
  "data-slot": "inner",
61
- className: "flex h-full w-full flex-col",
61
+ className: "flex h-full w-full",
62
62
  inert: state === "collapsed" && collapsible === "offcanvas",
63
63
  children
64
64
  }), /* @__PURE__ */ jsx("div", {
@@ -85,7 +85,7 @@ function SidebarSurface({ variant, mobileVariant = "sheet", label = "Navigation"
85
85
  "data-surface": "panel",
86
86
  "data-variant": resolvedVariant,
87
87
  "data-side": side,
88
- className: cn("group relative flex h-full w-(--sidebar-width) flex-col", className),
88
+ className: cn("group relative flex h-full w-(--sidebar-width)", className),
89
89
  style,
90
90
  ...props,
91
91
  children: [children, /* @__PURE__ */ jsx("div", {
@@ -137,7 +137,7 @@ function SidebarMobileSurface({ mobileVariant, label, variant, ref, className, c
137
137
  "data-control-ui": "sidebar",
138
138
  "data-control-family": "sidebar",
139
139
  "data-slot": "inner",
140
- className: "flex min-h-0 flex-1 flex-col",
140
+ className: "flex min-h-0 flex-1",
141
141
  children
142
142
  })
143
143
  });
@@ -300,10 +300,35 @@ function SidebarFooter({ className, ...props }) {
300
300
  ...props
301
301
  });
302
302
  }
303
- function SidebarContent({ className, children, ...props }) {
304
- const { state, isMobile } = useSidebar();
303
+ function SidebarIconRail({ layer = "sidebar", className, ...props }) {
304
+ return /* @__PURE__ */ jsx(SidebarIconRailContext.Provider, {
305
+ value: true,
306
+ children: /* @__PURE__ */ jsx("div", {
307
+ "data-control-ui": "sidebar",
308
+ "data-control-family": "sidebar",
309
+ "data-slot": "icon-rail",
310
+ "data-layer": layer,
311
+ "data-collapsible": "icon",
312
+ className: cn("group flex min-h-0 flex-col", className),
313
+ ...props
314
+ })
315
+ });
316
+ }
317
+ function SidebarPanel({ layer = "sidebar", className, ...props }) {
318
+ const { isMobile, state } = useSidebar();
305
319
  const { collapsible } = useSidebarSurface();
306
- const iconOnly = !isMobile && state === "collapsed" && collapsible === "icon";
320
+ return /* @__PURE__ */ jsx("div", {
321
+ "data-control-ui": "sidebar",
322
+ "data-control-family": "sidebar",
323
+ "data-slot": "panel",
324
+ "data-layer": layer,
325
+ inert: !isMobile && state === "collapsed" && collapsible === "icon",
326
+ className: cn("flex min-h-0 min-w-0 flex-col", className),
327
+ ...props
328
+ });
329
+ }
330
+ function SidebarContent({ className, children, ...props }) {
331
+ const iconOnly = useSidebarIconOnly();
307
332
  return /* @__PURE__ */ jsx(ScrollArea, {
308
333
  "data-control-ui": "sidebar",
309
334
  "data-slot": "content",
@@ -322,4 +347,4 @@ function SidebarContent({ className, children, ...props }) {
322
347
  });
323
348
  }
324
349
  //#endregion
325
- export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMobileNav, SidebarMobileNavItem, SidebarMobileTrigger, SidebarProvider, SidebarRail, SidebarTrigger, sidebarMenuButtonSizes, sidebarMenuButtonVariants, useSidebar };
350
+ export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarIconRail, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMobileNav, SidebarMobileNavItem, SidebarMobileTrigger, SidebarPanel, SidebarProvider, SidebarRail, SidebarTrigger, sidebarMenuButtonSizes, sidebarMenuButtonVariants, useSidebar };
@@ -1,6 +1,6 @@
1
1
  import { cn } from "../lib/cn.js";
2
- import { jsx, jsxs } from "react/jsx-runtime";
3
2
  import { Loader2 } from "lucide-react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
4
  //#region src/ui/spinner.tsx
5
5
  function Spinner({ size = "sm", label = "Loading", className, ...props }) {
6
6
  return /* @__PURE__ */ jsxs("span", {
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
+ import { CheckIcon, CircleAlertIcon } from "lucide-react";
3
4
  import { createContext, useContext, useEffect, useId, useState } from "react";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
- import { CheckIcon, CircleAlertIcon } from "lucide-react";
6
6
  //#region src/ui/stepper.tsx
7
7
  const StepperContext = createContext(null);
8
8
  function useStepper() {
package/dist/ui/toast.js CHANGED
@@ -4,8 +4,8 @@ import { controlEffectsAttribute } from "../skin.js";
4
4
  import { useSkin } from "../skin-provider.js";
5
5
  import { Button } from "./button.js";
6
6
  import { PopupCloseButton } from "../popup-parts.js";
7
- import { jsx, jsxs } from "react/jsx-runtime";
8
7
  import { CircleCheckIcon, CircleXIcon, InfoIcon, TriangleAlertIcon } from "lucide-react";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
9
  import { Toast } from "@base-ui/react/toast";
10
10
  //#region src/ui/toast.tsx
11
11
  const toastManager = Toast.createToastManager();
package/dist/ui/tree.js CHANGED
@@ -2,10 +2,10 @@
2
2
  import { cn } from "../lib/cn.js";
3
3
  import { useSkin } from "../skin-provider.js";
4
4
  import { TrackHighlight } from "../extensions/track-highlight.js";
5
+ import { ChevronRightIcon } from "lucide-react";
5
6
  import { Children, createContext, isValidElement, useContext, useEffect, useId, useRef, useState } from "react";
6
7
  import { useRender } from "@base-ui/react/use-render";
7
8
  import { jsx, jsxs } from "react/jsx-runtime";
8
- import { ChevronRightIcon } from "lucide-react";
9
9
  import { Collapsible } from "@base-ui/react/collapsible";
10
10
  //#region src/ui/tree.tsx
11
11
  const TYPEAHEAD_TIMEOUT = 500;
package/dist/user-ask.js CHANGED
@@ -4,9 +4,9 @@ import { Button } from "./ui/button.js";
4
4
  import { LiveStatus } from "./ui/live-status.js";
5
5
  import { Kbd } from "./ui/kbd.js";
6
6
  import { useUserAsk } from "./hooks/use-user-ask.js";
7
+ import { Check, ChevronLeft, ChevronRight, PencilLine } from "lucide-react";
7
8
  import { createContext, useContext, useEffect, useId, useRef } from "react";
8
9
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
- import { Check, ChevronLeft, ChevronRight, PencilLine } from "lucide-react";
10
10
  //#region src/user-ask.tsx
11
11
  const UserAskContext = createContext(null);
12
12
  function useUserAskContext() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ctrl-ui/react",
3
- "version": "0.9.17",
3
+ "version": "0.9.18",
4
4
  "description": "100+ React components for Tailwind CSS and shadcn/ui: pickers, trees, editors, canvases, app templates, and AI chat surfaces, with neutral defaults and consumer-owned themes.",
5
5
  "keywords": [
6
6
  "react",