@ctrl-ui/react 0.8.10 → 0.8.12

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 (98) hide show
  1. package/dist/action-bar.js +2 -2
  2. package/dist/activity.js +1 -1
  3. package/dist/blocks/design-canvas-inspector.js +2 -2
  4. package/dist/blocks/design-canvas.js +2 -2
  5. package/dist/blocks/discussion.js +1 -1
  6. package/dist/blocks/file-explorer.js +2 -2
  7. package/dist/blocks/settings.js +3 -3
  8. package/dist/chat-composer-editor/extensions/mention.js +1 -1
  9. package/dist/chat-composer.js +1 -1
  10. package/dist/chat-layout.js +1 -1
  11. package/dist/context.js +1 -1
  12. package/dist/dynamic-notification.js +1 -1
  13. package/dist/email/theme.js +1 -1
  14. package/dist/filter-bar/parts.js +1 -1
  15. package/dist/filter-bar.js +1 -1
  16. package/dist/inline-citation.js +1 -1
  17. package/dist/knob-contracts/emoji-picker-knobs.d.ts +1 -1
  18. package/dist/knob-contracts/emoji-picker-knobs.js +1 -0
  19. package/dist/knob-contracts/icon-picker-knobs.d.ts +4 -0
  20. package/dist/knob-contracts/icon-picker-knobs.js +9 -0
  21. package/dist/knob-contracts/markdown-knobs.d.ts +1 -1
  22. package/dist/knob-contracts/markdown-knobs.js +3 -1
  23. package/dist/knob-contracts/tabs-knobs.d.ts +1 -1
  24. package/dist/knob-contracts/tabs-knobs.js +2 -0
  25. package/dist/lib/phone-input-format.js +1 -1
  26. package/dist/skin.d.ts +2 -0
  27. package/dist/styles/index.css +3 -1
  28. package/dist/styles/recipes/accordion.css +13 -1
  29. package/dist/styles/recipes/badge.css +1 -0
  30. package/dist/styles/recipes/button.css +20 -4
  31. package/dist/styles/recipes/code.css +0 -15
  32. package/dist/styles/recipes/collapsible.css +15 -0
  33. package/dist/styles/recipes/emoji-picker.css +84 -1
  34. package/dist/styles/recipes/field.css +15 -2
  35. package/dist/styles/recipes/icon-picker.css +101 -0
  36. package/dist/styles/recipes/markdown.css +66 -0
  37. package/dist/styles/recipes/popup-motion.css +10 -0
  38. package/dist/styles/recipes/scroll-area.css +53 -27
  39. package/dist/styles/recipes/tabs-motion.css +99 -0
  40. package/dist/styles/recipes/tabs.css +38 -10
  41. package/dist/styles/recipes/tree.css +13 -1
  42. package/dist/ui/alert-dialog.js +1 -1
  43. package/dist/ui/alert.js +1 -1
  44. package/dist/ui/autocomplete.js +1 -1
  45. package/dist/ui/breadcrumb.js +1 -1
  46. package/dist/ui/button.d.ts +6 -3
  47. package/dist/ui/button.js +10 -6
  48. package/dist/ui/card.js +1 -1
  49. package/dist/ui/code-diff.js +1 -1
  50. package/dist/ui/code.js +2 -2
  51. package/dist/ui/collapsible.js +1 -2
  52. package/dist/ui/color-picker.js +1 -1
  53. package/dist/ui/combobox.js +1 -1
  54. package/dist/ui/context-menu.js +1 -1
  55. package/dist/ui/dialog.js +1 -1
  56. package/dist/ui/drawer.js +1 -1
  57. package/dist/ui/dropdown-menu.js +1 -1
  58. package/dist/ui/emoji-icon-picker.d.ts +13 -0
  59. package/dist/ui/emoji-icon-picker.js +50 -0
  60. package/dist/ui/emoji-picker.d.ts +14 -3
  61. package/dist/ui/emoji-picker.js +194 -15
  62. package/dist/ui/empty.js +1 -1
  63. package/dist/ui/hover-card.js +1 -1
  64. package/dist/ui/icon-picker.d.ts +35 -0
  65. package/dist/ui/icon-picker.js +140 -0
  66. package/dist/ui/input-group.js +1 -1
  67. package/dist/ui/item.js +1 -1
  68. package/dist/ui/markdown-elements.js +6 -10
  69. package/dist/ui/markdown.d.ts +6 -5
  70. package/dist/ui/markdown.js +12 -4
  71. package/dist/ui/menubar.js +1 -1
  72. package/dist/ui/morphing-panel.js +1 -1
  73. package/dist/ui/navigation-menu.js +1 -1
  74. package/dist/ui/phone-input.js +2 -2
  75. package/dist/ui/popover.d.ts +3 -0
  76. package/dist/ui/popover.js +37 -2
  77. package/dist/ui/rich-tooltip.js +1 -1
  78. package/dist/ui/scroll-area.d.ts +4 -1
  79. package/dist/ui/scroll-area.js +21 -6
  80. package/dist/ui/select.js +1 -1
  81. package/dist/ui/sheet.js +1 -1
  82. package/dist/ui/sidebar-menu.js +1 -1
  83. package/dist/ui/sidebar-provider.js +2 -2
  84. package/dist/ui/sidebar-resize-rail.js +1 -1
  85. package/dist/ui/sidebar.js +1 -1
  86. package/dist/ui/tabs.d.ts +4 -0
  87. package/dist/ui/tabs.js +69 -23
  88. package/dist/ui/timeline.js +1 -1
  89. package/dist/ui/toast.js +1 -1
  90. package/dist/ui/toggle.d.ts +1 -1
  91. package/dist/ui/toggle.js +2 -1
  92. package/dist/ui/toolbar.d.ts +1 -1
  93. package/dist/ui/toolbar.js +1 -1
  94. package/dist/ui/tooltip.js +1 -1
  95. package/dist/ui/tree.js +1 -1
  96. package/dist/ui/trigger-menu.js +1 -1
  97. package/dist/user-ask.js +2 -2
  98. package/package.json +1 -1
package/dist/ui/tabs.js CHANGED
@@ -1,14 +1,28 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
- import { Children, Fragment, createContext, isValidElement, useContext, useRef, useState } from "react";
3
+ import { Children, Fragment, createContext, isValidElement, useContext, useEffect, useRef, useState } from "react";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  import { Tabs as Tabs$1 } from "@base-ui/react/tabs";
6
6
  //#region src/ui/tabs.tsx
7
+ function TabsSurface({ className, ...props }) {
8
+ return /* @__PURE__ */ jsx("div", {
9
+ "data-control-ui": "tabs",
10
+ "data-control-family": "tabs",
11
+ "data-slot": "surface",
12
+ "data-surface": "panel",
13
+ className,
14
+ ...props
15
+ });
16
+ }
17
+ function refreshTabsPanelHeight(panel) {
18
+ if (panel.node.inert || panel.node.hidden) return;
19
+ panel.height = panel.node.getBoundingClientRect().height;
20
+ }
7
21
  const TabsPanelsContext = createContext(null);
8
- function useRegisterTabsPanel() {
9
- const registerPanel = useContext(TabsPanelsContext);
10
- if (!registerPanel) throw new Error("TabsPanel must be rendered inside <Tabs>.");
11
- return registerPanel;
22
+ function useTabsPanels() {
23
+ const context = useContext(TabsPanelsContext);
24
+ if (!context) throw new Error("TabsPanel must be rendered inside <Tabs>.");
25
+ return context;
12
26
  }
13
27
  function setRef(ref, value) {
14
28
  if (typeof ref === "function") return ref(value);
@@ -16,30 +30,61 @@ function setRef(ref, value) {
16
30
  }
17
31
  function Tabs({ className, onValueChange, children, ...props }) {
18
32
  const rootRef = useRef(null);
19
- const panelsRef = useRef(/* @__PURE__ */ new Map());
20
- const clearPrevHeight = useRef(0);
33
+ const activePanelRef = useRef(null);
34
+ const clearPreviousHeightFrame = useRef(0);
35
+ const [exitingValue, setExitingValue] = useState(null);
36
+ const [holdPreviousHeight] = useState(() => (height) => {
37
+ const root = rootRef.current;
38
+ if (!root) return;
39
+ root.style.setProperty("--aui-slide-prev-height", height);
40
+ cancelAnimationFrame(clearPreviousHeightFrame.current);
41
+ clearPreviousHeightFrame.current = requestAnimationFrame(() => {
42
+ clearPreviousHeightFrame.current = requestAnimationFrame(() => {
43
+ root.style.removeProperty("--aui-slide-prev-height");
44
+ root.removeAttribute("data-slide-starting");
45
+ });
46
+ });
47
+ });
48
+ useEffect(() => () => cancelAnimationFrame(clearPreviousHeightFrame.current), []);
21
49
  const [registerPanel] = useState(() => (value, node) => {
22
- if (!node) return;
23
- panelsRef.current.set(value, node);
50
+ if (!(node && !node.inert && !node.hidden)) return;
51
+ const previousPanel = activePanelRef.current;
52
+ const root = rootRef.current;
53
+ if (root && previousPanel && previousPanel.value !== value) {
54
+ root.setAttribute("data-slide-starting", "");
55
+ holdPreviousHeight(root.style.getPropertyValue("--aui-slide-prev-height") || `${previousPanel.height}px`);
56
+ setExitingValue(previousPanel.value);
57
+ }
58
+ activePanelRef.current = {
59
+ value,
60
+ node,
61
+ height: node.getBoundingClientRect().height
62
+ };
63
+ if (root) {
64
+ root.style.setProperty("--_tabs-panel-top", `${node.offsetTop}px`);
65
+ root.style.setProperty("--_tabs-panel-left", `${node.offsetLeft}px`);
66
+ root.style.setProperty("--_tabs-panel-width", `${node.offsetWidth}px`);
67
+ root.style.setProperty("--_tabs-panel-height", `${node.offsetHeight}px`);
68
+ }
24
69
  return () => {
25
- if (panelsRef.current.get(value) === node) panelsRef.current.delete(value);
70
+ const currentPanel = activePanelRef.current;
71
+ if (currentPanel && currentPanel.node === node) refreshTabsPanelHeight(currentPanel);
26
72
  };
27
73
  });
28
74
  const handleValueChange = (value) => {
29
- const root = rootRef.current;
30
- if (root) for (const panel of panelsRef.current.values()) {
31
- if (panel.inert || panel.hidden) continue;
32
- root.style.setProperty("--aui-slide-prev-height", `${panel.getBoundingClientRect().height}px`);
33
- cancelAnimationFrame(clearPrevHeight.current);
34
- clearPrevHeight.current = requestAnimationFrame(() => {
35
- clearPrevHeight.current = requestAnimationFrame(() => root.style.removeProperty("--aui-slide-prev-height"));
36
- });
37
- break;
75
+ const activePanel = activePanelRef.current;
76
+ if (activePanel) {
77
+ refreshTabsPanelHeight(activePanel);
78
+ holdPreviousHeight(`${activePanel.height}px`);
79
+ setExitingValue(activePanel.value);
38
80
  }
39
81
  onValueChange?.(value);
40
82
  };
41
83
  return /* @__PURE__ */ jsx(TabsPanelsContext.Provider, {
42
- value: registerPanel,
84
+ value: {
85
+ registerPanel,
86
+ exitingValue
87
+ },
43
88
  children: /* @__PURE__ */ jsx(Tabs$1.Root, {
44
89
  "data-control-ui": "tabs",
45
90
  "data-control-family": "tabs",
@@ -101,7 +146,7 @@ function TabsTab({ className, ...props }) {
101
146
  });
102
147
  }
103
148
  function TabsPanel({ className, value, ref, ...props }) {
104
- const registerPanel = useRegisterTabsPanel();
149
+ const { registerPanel, exitingValue } = useTabsPanels();
105
150
  const panelRef = (node) => {
106
151
  const unregister = registerPanel(value, node);
107
152
  const cleanup = setRef(ref, node);
@@ -119,9 +164,10 @@ function TabsPanel({ className, value, ref, ...props }) {
119
164
  "data-control-family": "tabs",
120
165
  "data-slot": "panel",
121
166
  "data-slide": "panel",
122
- className: cn("data-[hidden]:hidden [&[hidden]]:hidden", className),
167
+ "data-slide-exiting": exitingValue === value ? "" : void 0,
168
+ className: cn("data-[hidden]:hidden [&[hidden]]:hidden [&[inert]:not([data-slide=panel][data-slide-exiting][data-ending-style])]:hidden [&[inert][data-ending-style]]:m-0", "not-supports-[anchor-name:--aui-slide-panel]:[&[inert]]:hidden not-supports-[anchor-scope:--aui-slide-panel]:[&[inert]]:hidden", className),
123
169
  ...props
124
170
  });
125
171
  }
126
172
  //#endregion
127
- export { Tabs, TabsList, TabsPanel, TabsTab };
173
+ export { Tabs, TabsList, TabsPanel, TabsSurface, TabsTab };
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
- import { jsx } from "react/jsx-runtime";
4
3
  import { useRender } from "@base-ui/react/use-render";
4
+ import { jsx } from "react/jsx-runtime";
5
5
  //#region src/ui/timeline.tsx
6
6
  function Timeline({ className, ...props }) {
7
7
  return /* @__PURE__ */ jsx("ol", {
package/dist/ui/toast.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { controlEffectsAttribute } from "../skin.js";
3
2
  import { cn } from "../lib/cn.js";
3
+ 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";
@@ -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, iconOnly, showCheck, className, pressed, defaultPressed, onPressedChange, value, disabled, children, ...props }: ToggleProps): import("react").JSX.Element;
18
+ export declare function Toggle({ variant, size, tone, active, iconOnly, layout, 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, iconOnly = false, showCheck = false, className, pressed, defaultPressed, onPressedChange, value, disabled, children, ...props }) {
11
+ function Toggle({ variant = "surface", size = "sm", tone = "neutral", active, iconOnly = false, layout = "inline", 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,
@@ -31,6 +31,7 @@ function Toggle({ variant = "surface", size = "sm", tone = "neutral", active, ic
31
31
  "data-tone": tone,
32
32
  "data-size": size,
33
33
  "data-icon-only": iconOnly ? "true" : void 0,
34
+ "data-layout": layout,
34
35
  className: cn(buttonStructureClasses, renderProps.className, className),
35
36
  children: /* @__PURE__ */ jsxs("span", {
36
37
  "data-control-ui": "toggle",
@@ -1,6 +1,6 @@
1
1
  import { ToolbarKnobStyle } from "../knob-contracts/toolbar-knobs.js";
2
- import { CSSProperties, ComponentProps } from "react";
3
2
  import { Toolbar as Toolbar$1 } from "@base-ui/react/toolbar";
3
+ import { CSSProperties, ComponentProps } from "react";
4
4
  //#region src/ui/toolbar.d.ts
5
5
  export type ToolbarVariant = "default" | "inverse" | "floating";
6
6
  export type ToolbarLinkVariant = "default" | "track";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
- import { jsx, jsxs } from "react/jsx-runtime";
4
3
  import { Toolbar as Toolbar$1 } from "@base-ui/react/toolbar";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region src/ui/toolbar.tsx
6
6
  function Toolbar({ orientation = "horizontal", variant = "default", className, children, ...props }) {
7
7
  return /* @__PURE__ */ jsxs(Toolbar$1.Root, {
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { controlEffectsAttribute } from "../skin.js";
3
2
  import { cn } from "../lib/cn.js";
3
+ import { controlEffectsAttribute } from "../skin.js";
4
4
  import { useSkin } from "../skin-provider.js";
5
5
  import { PopupArrowShape } from "../popup-parts.js";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
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, useEffect, useId, useRef, useState } from "react";
6
+ import { useRender } from "@base-ui/react/use-render";
6
7
  import { jsx, jsxs } from "react/jsx-runtime";
7
8
  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,6 +1,6 @@
1
1
  "use client";
2
- import { controlEffectsAttribute } from "../skin.js";
3
2
  import { cn } from "../lib/cn.js";
3
+ import { controlEffectsAttribute } from "../skin.js";
4
4
  import { useSkin } from "../skin-provider.js";
5
5
  import { ScrollArea } from "./scroll-area.js";
6
6
  import { popupItemStructureClasses } from "../surface-variants.js";
package/dist/user-ask.js CHANGED
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  import { cn } from "./lib/cn.js";
3
- import { useUserAsk } from "./hooks/use-user-ask.js";
4
3
  import { Button } from "./ui/button.js";
5
- import { Kbd } from "./ui/kbd.js";
6
4
  import { LiveStatus } from "./ui/live-status.js";
5
+ import { useUserAsk } from "./hooks/use-user-ask.js";
6
+ import { Kbd } from "./ui/kbd.js";
7
7
  import { createContext, useContext, useEffect, useId, useRef, useState } from "react";
8
8
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
9
  import { Check, ChevronLeft, ChevronRight, PencilLine } from "lucide-react";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ctrl-ui/react",
3
- "version": "0.8.10",
3
+ "version": "0.8.12",
4
4
  "description": "Control UI components, blocks, and primitives with neutral defaults and consumer-owned themes.",
5
5
  "license": "MIT",
6
6
  "repository": {