@ctrl-ui/react 0.8.18 → 0.8.20

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 (106) hide show
  1. package/README.md +7 -0
  2. package/dist/action-bar.js +2 -2
  3. package/dist/audio-device-select.js +5 -2
  4. package/dist/blocks/coding-agent.js +22 -12
  5. package/dist/blocks/design-canvas-inspector.js +6 -3
  6. package/dist/blocks/design-canvas.js +20 -10
  7. package/dist/blocks/discussion-markdown-input.d.ts +14 -0
  8. package/dist/blocks/discussion-markdown-input.js +36 -0
  9. package/dist/blocks/discussion.d.ts +9 -3
  10. package/dist/blocks/discussion.js +82 -16
  11. package/dist/blocks/file-explorer.js +46 -24
  12. package/dist/blocks/settings.js +10 -6
  13. package/dist/chat-composer-editor/extensions/mention.d.ts +1 -1
  14. package/dist/chat-message.d.ts +13 -0
  15. package/dist/chat-message.js +198 -3
  16. package/dist/filter-bar/editor.js +5 -2
  17. package/dist/knob-contracts/flow-knobs.d.ts +4 -0
  18. package/dist/knob-contracts/flow-knobs.js +32 -0
  19. package/dist/knob-contracts/item-knobs.d.ts +1 -1
  20. package/dist/knob-contracts/item-knobs.js +4 -1
  21. package/dist/knob-contracts/label-knobs.d.ts +4 -0
  22. package/dist/knob-contracts/label-knobs.js +4 -0
  23. package/dist/knob-contracts/markdown-editor-knobs.d.ts +4 -0
  24. package/dist/knob-contracts/markdown-editor-knobs.js +17 -0
  25. package/dist/knob-contracts/morphing-panel-knobs.d.ts +1 -1
  26. package/dist/knob-contracts/morphing-panel-knobs.js +2 -1
  27. package/dist/knob-contracts/resize-handle-knobs.d.ts +4 -0
  28. package/dist/knob-contracts/resize-handle-knobs.js +12 -0
  29. package/dist/knob-contracts/sidebar-knobs.d.ts +1 -1
  30. package/dist/knob-contracts/sidebar-knobs.js +10 -0
  31. package/dist/knob-contracts/switch-knobs.d.ts +1 -1
  32. package/dist/knob-contracts/switch-knobs.js +1 -0
  33. package/dist/lib/canvas-grid.d.ts +4 -0
  34. package/dist/lib/canvas-grid.js +5 -0
  35. package/dist/markdown-editor/context.d.ts +22 -0
  36. package/dist/markdown-editor/context.js +10 -0
  37. package/dist/markdown-editor/drag-handle.d.ts +6 -0
  38. package/dist/markdown-editor/drag-handle.js +126 -0
  39. package/dist/markdown-editor/extensions.d.ts +10 -0
  40. package/dist/markdown-editor/extensions.js +139 -0
  41. package/dist/markdown-editor/suggestions.d.ts +12 -0
  42. package/dist/markdown-editor/suggestions.js +235 -0
  43. package/dist/markdown-editor/toolbar.d.ts +9 -0
  44. package/dist/markdown-editor/toolbar.js +339 -0
  45. package/dist/markdown-editor/uploads.d.ts +23 -0
  46. package/dist/markdown-editor/uploads.js +32 -0
  47. package/dist/markdown-editor/use-image-uploads.d.ts +12 -0
  48. package/dist/markdown-editor/use-image-uploads.js +120 -0
  49. package/dist/markdown-editor.d.ts +27 -0
  50. package/dist/markdown-editor.js +202 -0
  51. package/dist/styles/index.css +9 -4
  52. package/dist/styles/recipes/chat-message-edit.css +105 -0
  53. package/dist/styles/recipes/code.css +4 -0
  54. package/dist/styles/recipes/field.css +1 -1
  55. package/dist/styles/recipes/flow.css +304 -0
  56. package/dist/styles/recipes/infinite-canvas.css +1 -1
  57. package/dist/styles/recipes/item.css +39 -2
  58. package/dist/styles/recipes/label.css +19 -0
  59. package/dist/styles/recipes/markdown-editor.css +234 -0
  60. package/dist/styles/recipes/morphing-panel.css +53 -12
  61. package/dist/styles/recipes/page-layout.css +11 -1
  62. package/dist/styles/recipes/resize-handle.css +126 -0
  63. package/dist/styles/recipes/sidebar-mobile.css +171 -0
  64. package/dist/styles/recipes/switch.css +17 -5
  65. package/dist/styles/recipes/toolbar.css +8 -1
  66. package/dist/styles/theme.css +1 -0
  67. package/dist/ui/autocomplete.js +1 -1
  68. package/dist/ui/code.js +1 -0
  69. package/dist/ui/color-picker.js +1 -1
  70. package/dist/ui/combobox.d.ts +1 -1
  71. package/dist/ui/combobox.js +1 -1
  72. package/dist/ui/dockable-panel.js +1 -1
  73. package/dist/ui/flow.d.ts +51 -0
  74. package/dist/ui/flow.js +153 -0
  75. package/dist/ui/infinite-canvas.js +3 -3
  76. package/dist/ui/item.d.ts +5 -3
  77. package/dist/ui/item.js +2 -1
  78. package/dist/ui/label.d.ts +8 -0
  79. package/dist/ui/label.js +14 -0
  80. package/dist/ui/markdown.d.ts +2 -1
  81. package/dist/ui/markdown.js +3 -3
  82. package/dist/ui/morphing-panel.d.ts +21 -4
  83. package/dist/ui/morphing-panel.js +152 -36
  84. package/dist/ui/resize-handle.d.ts +11 -0
  85. package/dist/ui/resize-handle.js +26 -0
  86. package/dist/ui/sidebar-mobile.d.ts +17 -0
  87. package/dist/ui/sidebar-mobile.js +70 -0
  88. package/dist/ui/sidebar-provider.d.ts +1 -0
  89. package/dist/ui/sidebar-provider.js +3 -0
  90. package/dist/ui/sidebar.d.ts +3 -1
  91. package/dist/ui/sidebar.js +101 -49
  92. package/dist/ui/toolbar.d.ts +3 -1
  93. package/dist/ui/toolbar.js +2 -1
  94. package/dist/ui/typography.d.ts +47 -0
  95. package/dist/ui/typography.js +61 -0
  96. package/dist/ui/use-switch-drag.js +1 -1
  97. package/package.json +41 -1
  98. package/dist/environment-variables.d.ts +0 -125
  99. package/dist/environment-variables.js +0 -512
  100. package/dist/hooks/use-environment-variables.d.ts +0 -50
  101. package/dist/hooks/use-environment-variables.js +0 -188
  102. package/dist/knob-contracts/environment-variables-knobs.d.ts +0 -4
  103. package/dist/knob-contracts/environment-variables-knobs.js +0 -12
  104. package/dist/lib/env-file.d.ts +0 -27
  105. package/dist/lib/env-file.js +0 -218
  106. package/dist/styles/recipes/environment-variables.css +0 -170
@@ -3,10 +3,12 @@ import { cn } from "../lib/cn.js";
3
3
  import { useSkin } from "../skin-provider.js";
4
4
  import { Button } from "./button.js";
5
5
  import { ScrollArea } from "./scroll-area.js";
6
+ import { Drawer, DrawerBody, DrawerClose, DrawerContent, DrawerFooter, DrawerHeader, DrawerTitle } from "./drawer.js";
6
7
  import { Sheet, SheetContent, SheetHeader, SheetTitle } from "./sheet.js";
7
8
  import { SidebarProvider, SidebarSurfaceContext, useSidebar, useSidebarElements, useSidebarSurface } from "./sidebar-provider.js";
8
9
  import { SidebarResizeRail } from "./sidebar-resize-rail.js";
9
10
  import { SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, sidebarMenuButtonSizes, sidebarMenuButtonVariants } from "./sidebar-menu.js";
11
+ import { SidebarMobileNav, SidebarMobileNavItem, SidebarMobileTrigger } from "./sidebar-mobile.js";
10
12
  import { useState } from "react";
11
13
  import { useRender } from "@base-ui/react/use-render";
12
14
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
@@ -34,12 +36,13 @@ function Sidebar({ side = "left", collapsible = "offcanvas", ...props }) {
34
36
  })
35
37
  });
36
38
  }
37
- function SidebarSurface({ variant, label = "Navigation", ref, className, children, style, railContainerRef, ...props }) {
39
+ function SidebarSurface({ variant, mobileVariant = "sheet", label = "Navigation", ref, className, children, style, railContainerRef, ...props }) {
38
40
  const { side, collapsible } = useSidebarSurface();
39
- const { offcanvasRef, triggerRef } = useSidebarElements();
41
+ const { offcanvasRef } = useSidebarElements();
40
42
  const skin = useSkin();
41
- const { isMobile, state, openMobile, setOpenMobile, layout, sidebarId } = useSidebar();
43
+ const { isMobile, state, layout, sidebarId } = useSidebar();
42
44
  const resolvedVariant = variant ?? skin.sidebarLayout ?? "sidebar";
45
+ const padded = resolvedVariant === "floating" || resolvedVariant === "inset";
43
46
  const container = useRender({
44
47
  defaultTagName: "div",
45
48
  ref: collapsible === "offcanvas" ? [ref ?? null, offcanvasRef] : ref,
@@ -50,7 +53,7 @@ function SidebarSurface({ variant, label = "Navigation", ref, className, childre
50
53
  "data-control-family": "sidebar",
51
54
  "data-slot": "container",
52
55
  tabIndex: -1,
53
- className: cn(layout === "contained" ? "absolute h-full" : "fixed h-svh", "inset-y-0 z-10 hidden w-(--sidebar-width) lg:flex", side === "left" ? "start-0" : "end-0", resolvedVariant === "floating" || resolvedVariant === "inset" ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)", className),
56
+ className: cn(layout === "contained" ? "absolute h-full" : "fixed h-svh", "inset-y-0 z-10 hidden w-(--sidebar-width) lg:flex", side === "left" ? "start-0" : "end-0", padded ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)", className),
54
57
  children: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
55
58
  "data-control-ui": "sidebar",
56
59
  "data-control-family": "sidebar",
@@ -64,6 +67,16 @@ function SidebarSurface({ variant, label = "Navigation", ref, className, childre
64
67
  })] })
65
68
  }
66
69
  });
70
+ if (isMobile && (collapsible !== "none" || mobileVariant === "drawer")) return /* @__PURE__ */ jsx(SidebarMobileSurface, {
71
+ ...props,
72
+ ref,
73
+ mobileVariant,
74
+ label,
75
+ variant: resolvedVariant,
76
+ className,
77
+ style,
78
+ children
79
+ });
67
80
  if (collapsible === "none") return /* @__PURE__ */ jsxs("div", {
68
81
  ref,
69
82
  "data-control-ui": "sidebar",
@@ -80,46 +93,6 @@ function SidebarSurface({ variant, label = "Navigation", ref, className, childre
80
93
  className: "contents"
81
94
  })]
82
95
  });
83
- if (isMobile) {
84
- const mobileSheetStyle = {
85
- "--sidebar-width": SIDEBAR_WIDTH_MOBILE,
86
- ...style
87
- };
88
- return /* @__PURE__ */ jsx(Sheet, {
89
- open: openMobile,
90
- onOpenChange: setOpenMobile,
91
- children: /* @__PURE__ */ jsxs(SheetContent, {
92
- side,
93
- finalFocus: triggerRef,
94
- className: "w-(--sidebar-width) gap-0 p-0",
95
- style: mobileSheetStyle,
96
- children: [/* @__PURE__ */ jsx(SheetHeader, {
97
- className: "sr-only",
98
- children: /* @__PURE__ */ jsx(SheetTitle, { children: label })
99
- }), /* @__PURE__ */ jsx("div", {
100
- ref,
101
- id: sidebarId,
102
- "data-control-ui": "sidebar",
103
- "data-control-family": "sidebar",
104
- "data-slot": "root",
105
- "data-surface": "panel",
106
- "data-variant": resolvedVariant,
107
- "data-mobile": "",
108
- "data-side": side,
109
- className: cn("flex min-h-0 flex-1 flex-col", className),
110
- style,
111
- ...props,
112
- children: /* @__PURE__ */ jsx("div", {
113
- "data-control-ui": "sidebar",
114
- "data-control-family": "sidebar",
115
- "data-slot": "inner",
116
- className: "flex min-h-0 flex-1 flex-col",
117
- children
118
- })
119
- })]
120
- })
121
- });
122
- }
123
96
  return /* @__PURE__ */ jsxs("div", {
124
97
  className: cn("group peer hidden lg:block", side === "right" && "order-last"),
125
98
  "data-control-ui": "sidebar",
@@ -135,13 +108,87 @@ function SidebarSurface({ variant, label = "Navigation", ref, className, childre
135
108
  "data-control-ui": "sidebar",
136
109
  "data-control-family": "sidebar",
137
110
  "data-slot": "gap",
138
- className: cn("relative w-(--sidebar-width)", "group-data-[collapsible=offcanvas]:w-0", resolvedVariant === "floating" || resolvedVariant === "inset" ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)")
111
+ className: cn("relative w-(--sidebar-width)", "group-data-[collapsible=offcanvas]:w-0", padded ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)")
139
112
  }), container]
140
113
  });
141
114
  }
115
+ function SidebarMobileSurface({ mobileVariant, label, variant, ref, className, children, style, ...props }) {
116
+ const { side } = useSidebarSurface();
117
+ const { openMobile, setOpenMobile, sidebarId } = useSidebar();
118
+ const { activeTriggerRef, triggerRef, insetRef } = useSidebarElements();
119
+ function finalFocus() {
120
+ const trigger = activeTriggerRef.current ?? triggerRef.current;
121
+ return trigger?.isConnected && trigger.checkVisibility() ? trigger : insetRef.current;
122
+ }
123
+ const mobileContent = /* @__PURE__ */ jsx("div", {
124
+ ref,
125
+ id: sidebarId,
126
+ "data-control-ui": "sidebar",
127
+ "data-control-family": "sidebar",
128
+ "data-slot": "root",
129
+ "data-surface": "panel",
130
+ "data-variant": variant,
131
+ "data-mobile": "",
132
+ "data-side": side,
133
+ className: cn("flex min-h-0 flex-1 flex-col", className),
134
+ style,
135
+ ...props,
136
+ children: /* @__PURE__ */ jsx("div", {
137
+ "data-control-ui": "sidebar",
138
+ "data-control-family": "sidebar",
139
+ "data-slot": "inner",
140
+ className: "flex min-h-0 flex-1 flex-col",
141
+ children
142
+ })
143
+ });
144
+ if (mobileVariant === "drawer") return /* @__PURE__ */ jsx(Drawer, {
145
+ open: openMobile,
146
+ onOpenChange: setOpenMobile,
147
+ children: /* @__PURE__ */ jsxs(DrawerContent, {
148
+ side: "bottom",
149
+ finalFocus,
150
+ className: "max-h-[85dvh]",
151
+ children: [
152
+ /* @__PURE__ */ jsx(DrawerHeader, {
153
+ className: "sr-only",
154
+ children: /* @__PURE__ */ jsx(DrawerTitle, { children: label })
155
+ }),
156
+ /* @__PURE__ */ jsx(DrawerBody, {
157
+ padding: "none",
158
+ children: mobileContent
159
+ }),
160
+ /* @__PURE__ */ jsx(DrawerFooter, { children: /* @__PURE__ */ jsx(DrawerClose, {
161
+ render: /* @__PURE__ */ jsx(Button, {
162
+ variant: "surface",
163
+ size: "lg"
164
+ }),
165
+ children: "Close menu"
166
+ }) })
167
+ ]
168
+ })
169
+ });
170
+ const mobileSheetStyle = {
171
+ "--sidebar-width": SIDEBAR_WIDTH_MOBILE,
172
+ ...style
173
+ };
174
+ return /* @__PURE__ */ jsx(Sheet, {
175
+ open: openMobile,
176
+ onOpenChange: setOpenMobile,
177
+ children: /* @__PURE__ */ jsxs(SheetContent, {
178
+ side,
179
+ finalFocus,
180
+ className: "w-(--sidebar-width) gap-0 p-0",
181
+ style: mobileSheetStyle,
182
+ children: [/* @__PURE__ */ jsx(SheetHeader, {
183
+ className: "sr-only",
184
+ children: /* @__PURE__ */ jsx(SheetTitle, { children: label })
185
+ }), mobileContent]
186
+ })
187
+ });
188
+ }
142
189
  function SidebarTrigger({ className, onClick, size = "sm", label = "Toggle sidebar", ref, ...props }) {
143
190
  const { toggleSidebar, isMobile, openMobile, open, keyboardShortcut, sidebarId } = useSidebar();
144
- const { triggerRef, railRef } = useSidebarElements();
191
+ const { triggerRef, activeTriggerRef, railRef } = useSidebarElements();
145
192
  const shortcutKey = keyboardShortcut?.toUpperCase();
146
193
  return useRender({
147
194
  defaultTagName: "button",
@@ -162,6 +209,7 @@ function SidebarTrigger({ className, onClick, size = "sm", label = "Toggle sideb
162
209
  onClick: (event) => {
163
210
  onClick?.(event);
164
211
  if (event.defaultPrevented) return;
212
+ activeTriggerRef.current = event.currentTarget;
165
213
  toggleSidebar();
166
214
  if (isMobile || open) return;
167
215
  const trigger = event.currentTarget;
@@ -229,7 +277,7 @@ function SidebarInset({ className, render, ref, ...props }) {
229
277
  "data-control-ui": "sidebar",
230
278
  "data-control-family": "sidebar",
231
279
  "data-slot": "inset",
232
- className: cn("relative flex min-w-0 w-full flex-1 flex-col", className)
280
+ className: cn("relative flex min-h-0 min-w-0 w-full flex-1 flex-col", className)
233
281
  }
234
282
  });
235
283
  }
@@ -252,12 +300,16 @@ function SidebarFooter({ className, ...props }) {
252
300
  });
253
301
  }
254
302
  function SidebarContent({ className, children, ...props }) {
303
+ const { state, isMobile } = useSidebar();
304
+ const { collapsible } = useSidebarSurface();
305
+ const iconOnly = !isMobile && state === "collapsed" && collapsible === "icon";
255
306
  return /* @__PURE__ */ jsx(ScrollArea, {
256
307
  "data-control-ui": "sidebar",
257
308
  "data-slot": "content",
258
309
  className: cn("min-h-0 flex-1 group-data-[collapsible=icon]:overflow-hidden", className),
259
310
  lockAxis: "x",
260
- viewportClassName: "overscroll-contain",
311
+ scrollbarGutter: iconOnly ? "auto" : void 0,
312
+ viewportClassName: "overscroll-y-contain",
261
313
  ...props,
262
314
  children: /* @__PURE__ */ jsx("div", {
263
315
  "data-control-ui": "sidebar",
@@ -269,4 +321,4 @@ function SidebarContent({ className, children, ...props }) {
269
321
  });
270
322
  }
271
323
  //#endregion
272
- export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarProvider, SidebarRail, SidebarTrigger, sidebarMenuButtonSizes, sidebarMenuButtonVariants, useSidebar };
324
+ export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMobileNav, SidebarMobileNavItem, SidebarMobileTrigger, SidebarProvider, SidebarRail, SidebarTrigger, sidebarMenuButtonSizes, sidebarMenuButtonVariants, useSidebar };
@@ -3,10 +3,12 @@ import { Toolbar as Toolbar$1 } from "@base-ui/react/toolbar";
3
3
  import { CSSProperties, ComponentProps } from "react";
4
4
  //#region src/ui/toolbar.d.ts
5
5
  export type ToolbarVariant = "default" | "inverse" | "floating";
6
+ export type ToolbarChrome = "standalone" | "embedded";
6
7
  export type ToolbarLinkVariant = "default" | "track";
7
8
  export type ToolbarProps = Omit<ComponentProps<"div">, "style"> & {
8
9
  orientation?: "horizontal" | "vertical";
9
10
  variant?: ToolbarVariant;
11
+ chrome?: ToolbarChrome;
10
12
  style?: CSSProperties & ToolbarKnobStyle;
11
13
  };
12
14
  export type ToolbarButtonProps = Omit<ComponentProps<"button">, "style"> & {
@@ -28,7 +30,7 @@ export type ToolbarSeparatorProps = Omit<ComponentProps<"div">, "style"> & {
28
30
  export type ToolbarInputProps = Omit<ComponentProps<"input">, "style"> & {
29
31
  style?: CSSProperties & ToolbarKnobStyle;
30
32
  };
31
- export declare function Toolbar({ orientation, variant, className, children, ...props }: ToolbarProps): import("react").JSX.Element;
33
+ export declare function Toolbar({ orientation, variant, chrome, className, children, ...props }: ToolbarProps): import("react").JSX.Element;
32
34
  type RefinedToolbarButtonProps = ToolbarButtonProps & Pick<ComponentProps<typeof Toolbar$1.Button>, "render">;
33
35
  export declare function ToolbarButton({ iconOnly, className, ...props }: RefinedToolbarButtonProps): import("react").JSX.Element;
34
36
  type RefinedToolbarLinkProps = ToolbarLinkProps & Pick<ComponentProps<typeof Toolbar$1.Link>, "render">;
@@ -3,13 +3,14 @@ import { cn } from "../lib/cn.js";
3
3
  import { Toolbar as Toolbar$1 } from "@base-ui/react/toolbar";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region src/ui/toolbar.tsx
6
- function Toolbar({ orientation = "horizontal", variant = "default", className, children, ...props }) {
6
+ function Toolbar({ orientation = "horizontal", variant = "default", chrome = "standalone", className, children, ...props }) {
7
7
  return /* @__PURE__ */ jsxs(Toolbar$1.Root, {
8
8
  orientation,
9
9
  "data-control-ui": "toolbar",
10
10
  "data-control-family": "toolbar",
11
11
  "data-slot": "root",
12
12
  "data-variant": variant,
13
+ "data-chrome": chrome,
13
14
  className: cn("group/toolbar inline-flex", orientation === "vertical" ? "flex-col items-stretch" : "items-center", className),
14
15
  ...props,
15
16
  children: [variant === "floating" && /* @__PURE__ */ jsx("div", {
@@ -0,0 +1,47 @@
1
+ import { ComponentProps, HTMLAttributes, Ref } from "react";
2
+ //#region src/ui/typography.d.ts
3
+ declare const sizeClassNames: {
4
+ readonly display: "text-display";
5
+ readonly "heading-1": "text-heading-1";
6
+ readonly "heading-2": "text-heading-2";
7
+ readonly "heading-3": "text-heading-3";
8
+ readonly "heading-4": "text-heading-4";
9
+ readonly "body-lg": "text-body-lg";
10
+ readonly body: "text-body";
11
+ readonly label: "text-label";
12
+ readonly caption: "text-caption";
13
+ readonly micro: "text-micro";
14
+ };
15
+ declare const toneClassNames: {
16
+ readonly default: undefined;
17
+ readonly foreground: "text-foreground";
18
+ readonly muted: "text-muted-foreground";
19
+ readonly primary: "text-primary-text";
20
+ readonly destructive: "text-destructive-text";
21
+ };
22
+ declare const weightClassNames: {
23
+ readonly normal: "font-normal";
24
+ readonly medium: "font-medium";
25
+ readonly semibold: "font-semibold";
26
+ };
27
+ export type TypeSize = keyof typeof sizeClassNames;
28
+ export type TypeTone = keyof typeof toneClassNames;
29
+ export type TextWeight = keyof typeof weightClassNames;
30
+ export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
31
+ export type HeadingProps = ComponentProps<"h1"> & {
32
+ level: HeadingLevel;
33
+ size?: TypeSize;
34
+ weight?: TextWeight;
35
+ tone?: TypeTone;
36
+ };
37
+ export declare function Heading({ level, size, weight, tone, className, ...props }: HeadingProps): import("react").JSX.Element;
38
+ export type TextTag = "p" | "span" | "div" | "small" | "strong" | "em" | "code" | "li" | "dt" | "dd" | "figcaption" | "legend" | "blockquote";
39
+ export type TextProps = HTMLAttributes<HTMLElement> & {
40
+ ref?: Ref<HTMLElement>;
41
+ as?: TextTag;
42
+ size?: TypeSize;
43
+ weight?: TextWeight;
44
+ tone?: TypeTone;
45
+ };
46
+ export declare function Text({ as: Tag, size, weight, tone, className, ref, ...props }: TextProps): import("react").JSX.Element;
47
+ //#endregion
@@ -0,0 +1,61 @@
1
+ import { cn } from "../lib/cn.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region src/ui/typography.tsx
4
+ const sizeClassNames = {
5
+ display: "text-display",
6
+ "heading-1": "text-heading-1",
7
+ "heading-2": "text-heading-2",
8
+ "heading-3": "text-heading-3",
9
+ "heading-4": "text-heading-4",
10
+ "body-lg": "text-body-lg",
11
+ body: "text-body",
12
+ label: "text-label",
13
+ caption: "text-caption",
14
+ micro: "text-micro"
15
+ };
16
+ const toneClassNames = {
17
+ default: void 0,
18
+ foreground: "text-foreground",
19
+ muted: "text-muted-foreground",
20
+ primary: "text-primary-text",
21
+ destructive: "text-destructive-text"
22
+ };
23
+ const weightClassNames = {
24
+ normal: "font-normal",
25
+ medium: "font-medium",
26
+ semibold: "font-semibold"
27
+ };
28
+ const headingSizeByLevel = {
29
+ 1: "heading-1",
30
+ 2: "heading-2",
31
+ 3: "heading-3",
32
+ 4: "heading-4",
33
+ 5: "heading-4",
34
+ 6: "heading-4"
35
+ };
36
+ function Heading({ level, size = headingSizeByLevel[level], weight, tone = "default", className, ...props }) {
37
+ const Tag = `h${level}`;
38
+ return /* @__PURE__ */ jsx(Tag, {
39
+ "data-control-ui": "typography",
40
+ "data-control-family": "typography",
41
+ "data-slot": "heading",
42
+ className: cn(sizeClassNames[size], weight ? weightClassNames[weight] : void 0, toneClassNames[tone], className),
43
+ ...props
44
+ });
45
+ }
46
+ function attachRef(ref, node) {
47
+ if (typeof ref === "function") return ref(node);
48
+ if (ref) ref.current = node;
49
+ }
50
+ function Text({ as: Tag = "span", size = "body", weight, tone = "default", className, ref, ...props }) {
51
+ return /* @__PURE__ */ jsx(Tag, {
52
+ ref: ref ? (node) => attachRef(ref, node) : void 0,
53
+ "data-control-ui": "typography",
54
+ "data-control-family": "typography",
55
+ "data-slot": "text",
56
+ className: cn(sizeClassNames[size], weight ? weightClassNames[weight] : void 0, toneClassNames[tone], className),
57
+ ...props
58
+ });
59
+ }
60
+ //#endregion
61
+ export { Heading, Text };
@@ -25,7 +25,7 @@ function useSwitchDrag() {
25
25
  if (!(event.isPrimary && event.button === 0 && !isSwitchLocked(root)) || !thumbRef.current) return;
26
26
  setDragProgress(null);
27
27
  const styles = getComputedStyle(root);
28
- const travel = root.clientWidth - Number.parseFloat(styles.paddingLeft) - Number.parseFloat(styles.paddingRight) - thumbRef.current.offsetWidth;
28
+ const travel = root.clientWidth - Number.parseFloat(styles.paddingLeft) - Number.parseFloat(styles.paddingRight) - Number.parseFloat(styles.getPropertyValue("--cui-switch-thumb-inline-size"));
29
29
  if (travel <= 0) return;
30
30
  const progress = root.hasAttribute("data-checked") ? 1 : 0;
31
31
  gestureRef.current = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ctrl-ui/react",
3
- "version": "0.8.18",
3
+ "version": "0.8.20",
4
4
  "description": "Control UI components, blocks, and primitives with neutral defaults and consumer-owned themes.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -36,6 +36,16 @@
36
36
  "peerDependencies": {
37
37
  "@base-ui/react": "^1.8.0",
38
38
  "@tanstack/react-virtual": "^3.14.13",
39
+ "@xyflow/react": "^12.12.0",
40
+ "@tiptap/core": "3.31.4",
41
+ "@tiptap/extension-image": "3.31.4",
42
+ "@tiptap/extension-list": "3.31.4",
43
+ "@tiptap/extension-paragraph": "3.31.4",
44
+ "@tiptap/extension-table": "3.31.4",
45
+ "@tiptap/markdown": "3.31.4",
46
+ "@tiptap/pm": "3.31.4",
47
+ "@tiptap/react": "3.31.4",
48
+ "@tiptap/starter-kit": "3.31.4",
39
49
  "class-variance-authority": "^0.7.1",
40
50
  "clsx": "^2.1.1",
41
51
  "cmdk": "^1.1.1",
@@ -61,9 +71,39 @@
61
71
  "zod": "^4.6.5"
62
72
  },
63
73
  "peerDependenciesMeta": {
74
+ "@xyflow/react": {
75
+ "optional": true
76
+ },
64
77
  "@tanstack/react-virtual": {
65
78
  "optional": true
66
79
  },
80
+ "@tiptap/core": {
81
+ "optional": true
82
+ },
83
+ "@tiptap/extension-image": {
84
+ "optional": true
85
+ },
86
+ "@tiptap/extension-list": {
87
+ "optional": true
88
+ },
89
+ "@tiptap/extension-paragraph": {
90
+ "optional": true
91
+ },
92
+ "@tiptap/extension-table": {
93
+ "optional": true
94
+ },
95
+ "@tiptap/markdown": {
96
+ "optional": true
97
+ },
98
+ "@tiptap/pm": {
99
+ "optional": true
100
+ },
101
+ "@tiptap/react": {
102
+ "optional": true
103
+ },
104
+ "@tiptap/starter-kit": {
105
+ "optional": true
106
+ },
67
107
  "cmdk": {
68
108
  "optional": true
69
109
  },
@@ -1,125 +0,0 @@
1
- import { Button } from "./ui/button.js";
2
- import { EnvironmentVariableRow, EnvironmentVariablesController, UseEnvironmentVariablesOptions } from "./hooks/use-environment-variables.js";
3
- import { EnvironmentVariablesKnobStyle } from "./knob-contracts/environment-variables-knobs.js";
4
- import { CSSProperties, ComponentProps, ReactNode } from "react";
5
- //#region src/environment-variables.d.ts
6
- export type EnvironmentVariablesRowErrors = Record<number, {
7
- key?: ReactNode;
8
- value?: ReactNode;
9
- }>;
10
- export type EnvironmentVariablesSubmitPayload<TRow extends EnvironmentVariableRow = EnvironmentVariableRow> = {
11
- rows: TRow[];
12
- variables: Record<string, string>;
13
- envFileText: string;
14
- reset: () => void;
15
- };
16
- export type EnvironmentVariablesRootProps<TRow extends EnvironmentVariableRow = EnvironmentVariableRow> = Omit<ComponentProps<"form">, "onSubmit"> & {
17
- editor: EnvironmentVariablesController<TRow>;
18
- disabled?: boolean;
19
- readOnly?: boolean;
20
- rowErrors?: EnvironmentVariablesRowErrors;
21
- keyLabel?: ReactNode;
22
- valueLabel?: ReactNode;
23
- keyPlaceholder?: string;
24
- valuePlaceholder?: string;
25
- duplicateKeyMessage?: ReactNode;
26
- revealValueLabel?: (key: string) => string;
27
- onSubmit?: (payload: EnvironmentVariablesSubmitPayload<TRow>) => void | Promise<void>;
28
- } & {
29
- style?: CSSProperties & EnvironmentVariablesKnobStyle;
30
- };
31
- export declare function EnvironmentVariablesRoot<TRow extends EnvironmentVariableRow = EnvironmentVariableRow>({ editor, disabled, readOnly, rowErrors, keyLabel, valueLabel, keyPlaceholder, valuePlaceholder, duplicateKeyMessage, revealValueLabel, onSubmit, className, children, ...props }: EnvironmentVariablesRootProps<TRow>): import("react").JSX.Element;
32
- export type EnvironmentVariablesProps<TRow extends EnvironmentVariableRow = EnvironmentVariableRow> = Omit<EnvironmentVariablesRootProps<TRow>, "editor"> & UseEnvironmentVariablesOptions<TRow> & {
33
- editor?: EnvironmentVariablesController<TRow>;
34
- title?: ReactNode;
35
- description?: ReactNode;
36
- error?: ReactNode;
37
- submitLabel?: ReactNode;
38
- resetLabel?: ReactNode;
39
- addLabel?: ReactNode;
40
- hideDefaultActions?: boolean;
41
- };
42
- declare function EnvironmentVariablesComponent<TRow extends EnvironmentVariableRow = EnvironmentVariableRow>({ editor: providedEditor, initialRows, rows, onRowsChange, createDefaultRow, createRow, getEditableRows, getPreservedRows, maxUploadSize, title, description, error, submitLabel, resetLabel, addLabel, hideDefaultActions, children, onSubmit, ...props }: EnvironmentVariablesProps<TRow>): import("react").JSX.Element;
43
- export type EnvironmentVariablesHeaderProps = ComponentProps<"div"> & {
44
- title?: ReactNode;
45
- description?: ReactNode;
46
- } & {
47
- style?: CSSProperties & EnvironmentVariablesKnobStyle;
48
- };
49
- export declare function EnvironmentVariablesHeader({ title, description, className, children, ...props }: EnvironmentVariablesHeaderProps): import("react").JSX.Element | null;
50
- export type EnvironmentVariablesToolbarProps = ComponentProps<"div"> & {
51
- style?: CSSProperties & EnvironmentVariablesKnobStyle;
52
- };
53
- export declare function EnvironmentVariablesToolbar({ className, children, ...props }: EnvironmentVariablesToolbarProps): import("react").JSX.Element | null;
54
- export type EnvironmentVariablesUploadButtonProps = ComponentProps<typeof Button> & {
55
- inputLabel?: string;
56
- };
57
- export declare function EnvironmentVariablesUploadButton({ inputLabel, children, variant, size, disabled, onClick, ...props }: EnvironmentVariablesUploadButtonProps): import("react").JSX.Element;
58
- export type EnvironmentVariablesRowsProps = ComponentProps<"div"> & {
59
- rowErrors?: EnvironmentVariablesRowErrors;
60
- } & {
61
- style?: CSSProperties & EnvironmentVariablesKnobStyle;
62
- };
63
- export declare function EnvironmentVariablesRows({ rowErrors, className, children, ...props }: EnvironmentVariablesRowsProps): import("react").JSX.Element;
64
- export type EnvironmentVariablesRowProps = Omit<ComponentProps<"div">, "children"> & {
65
- row: EnvironmentVariableRow;
66
- index: number;
67
- rowErrors?: EnvironmentVariablesRowErrors;
68
- } & {
69
- style?: CSSProperties & EnvironmentVariablesKnobStyle;
70
- };
71
- export declare function EnvironmentVariablesRow({ row, index, rowErrors, className, ...props }: EnvironmentVariablesRowProps): import("react").JSX.Element;
72
- export type EnvironmentVariablesAddButtonProps = ComponentProps<typeof Button>;
73
- export declare function EnvironmentVariablesAddButton({ children, variant, size, disabled, onClick, ...props }: EnvironmentVariablesAddButtonProps): import("react").JSX.Element | null;
74
- export type EnvironmentVariablesResetButtonProps = ComponentProps<typeof Button>;
75
- export declare function EnvironmentVariablesResetButton({ children, variant, size, disabled, onClick, ...props }: EnvironmentVariablesResetButtonProps): import("react").JSX.Element | null;
76
- export type EnvironmentVariablesSubmitButtonProps = ComponentProps<typeof Button>;
77
- export declare function EnvironmentVariablesSubmitButton({ children, variant, tone, size, disabled, ...props }: EnvironmentVariablesSubmitButtonProps): import("react").JSX.Element | null;
78
- export type EnvironmentVariablesActionsProps = ComponentProps<"div"> & {
79
- style?: CSSProperties & EnvironmentVariablesKnobStyle;
80
- };
81
- export declare function EnvironmentVariablesActions({ className, ...props }: EnvironmentVariablesActionsProps): import("react").JSX.Element;
82
- export type EnvironmentVariablesMessageProps = Omit<ComponentProps<"div">, "style"> & {
83
- error?: ReactNode;
84
- style?: CSSProperties & EnvironmentVariablesKnobStyle;
85
- };
86
- export declare function EnvironmentVariablesMessage({ error, className, children, ...props }: EnvironmentVariablesMessageProps): import("react").JSX.Element | null;
87
- export type EnvironmentVariablesDuplicateKeysErrorProps = Omit<EnvironmentVariablesMessageProps, "error"> & {
88
- message?: ReactNode;
89
- };
90
- export declare function EnvironmentVariablesDuplicateKeysError({ message, ...props }: EnvironmentVariablesDuplicateKeysErrorProps): import("react").JSX.Element | null;
91
- export type EnvironmentVariablesUploadErrorProps = Omit<EnvironmentVariablesMessageProps, "error">;
92
- export declare function EnvironmentVariablesUploadError(props: EnvironmentVariablesUploadErrorProps): import("react").JSX.Element;
93
- export type EnvironmentVariablesReadOnlyListProps = ComponentProps<"div"> & {
94
- rows?: readonly EnvironmentVariableRow[];
95
- emptyMessage?: ReactNode;
96
- } & {
97
- style?: CSSProperties & EnvironmentVariablesKnobStyle;
98
- };
99
- export declare function EnvironmentVariablesReadOnlyList({ rows, emptyMessage, className, children, ...props }: EnvironmentVariablesReadOnlyListProps): import("react").JSX.Element;
100
- export type EnvironmentVariablesReadOnlyItemProps = Omit<ComponentProps<"div">, "style"> & {
101
- name: ReactNode;
102
- value?: ReactNode;
103
- revealed?: boolean;
104
- hiddenValueLabel?: string;
105
- style?: CSSProperties & EnvironmentVariablesKnobStyle;
106
- };
107
- export declare function EnvironmentVariablesReadOnlyItem({ name, value, revealed, hiddenValueLabel, className, ...props }: EnvironmentVariablesReadOnlyItemProps): import("react").JSX.Element;
108
- export declare const EnvironmentVariables: typeof EnvironmentVariablesComponent & {
109
- Root: typeof EnvironmentVariablesRoot;
110
- Header: typeof EnvironmentVariablesHeader;
111
- Toolbar: typeof EnvironmentVariablesToolbar;
112
- UploadButton: typeof EnvironmentVariablesUploadButton;
113
- UploadError: typeof EnvironmentVariablesUploadError;
114
- Rows: typeof EnvironmentVariablesRows;
115
- Row: typeof EnvironmentVariablesRow;
116
- AddButton: typeof EnvironmentVariablesAddButton;
117
- ResetButton: typeof EnvironmentVariablesResetButton;
118
- SubmitButton: typeof EnvironmentVariablesSubmitButton;
119
- Actions: typeof EnvironmentVariablesActions;
120
- Message: typeof EnvironmentVariablesMessage;
121
- DuplicateKeysError: typeof EnvironmentVariablesDuplicateKeysError;
122
- ReadOnlyList: typeof EnvironmentVariablesReadOnlyList;
123
- ReadOnlyItem: typeof EnvironmentVariablesReadOnlyItem;
124
- };
125
- //#endregion