@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
@@ -1,11 +1,11 @@
1
1
  "use client";
2
+ import { useCopyToClipboard } from "./hooks/use-copy-to-clipboard.js";
2
3
  import { cn } from "./lib/cn.js";
3
4
  import { Button } from "./ui/button.js";
4
5
  import { LiveStatus } from "./ui/live-status.js";
5
- import { useCopyToClipboard } from "./hooks/use-copy-to-clipboard.js";
6
+ import { Toolbar } from "@base-ui/react/toolbar";
6
7
  import { createContext, useContext } from "react";
7
8
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
- import { Toolbar } from "@base-ui/react/toolbar";
9
9
  //#region src/action-bar.tsx
10
10
  const ActionBarContext = createContext({});
11
11
  async function resolveCopyValue(value) {
package/dist/activity.js CHANGED
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import { cn } from "./lib/cn.js";
3
3
  import { LiveStatus } from "./ui/live-status.js";
4
- import { ScrollArea } from "./ui/scroll-area.js";
5
4
  import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "./ui/collapsible.js";
5
+ import { ScrollArea } from "./ui/scroll-area.js";
6
6
  import { createContext, useContext } from "react";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
8
  import { Check, ChevronRight, CircleAlert, CircleDashed, LoaderCircle } from "lucide-react";
@@ -1,11 +1,11 @@
1
1
  "use client";
2
2
  import { Button } from "../ui/button.js";
3
3
  import { InputGroup, InputGroupAddon } from "../ui/input-group.js";
4
- import { Empty, EmptyDescription, EmptyHeader, EmptyTitle } from "../ui/empty.js";
5
- import { Separator } from "../ui/separator.js";
6
4
  import { resizeDesignCanvasLayer } from "./design-canvas-data.js";
7
5
  import { NumberField, NumberFieldGroup, NumberFieldInput, NumberFieldScrubArea } from "../ui/number-field.js";
8
6
  import { ColorPicker, ColorPickerArea, ColorPickerContent, ColorPickerEyeDropper, ColorPickerHue, ColorPickerInput, ColorPickerTrigger } from "../ui/color-picker.js";
7
+ import { Empty, EmptyDescription, EmptyHeader, EmptyTitle } from "../ui/empty.js";
8
+ import { Separator } from "../ui/separator.js";
9
9
  import { Toggle } from "../ui/toggle.js";
10
10
  import { useState } from "react";
11
11
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
@@ -3,12 +3,12 @@ import { cn } from "../lib/cn.js";
3
3
  import { Button } from "../ui/button.js";
4
4
  import { ScrollArea } from "../ui/scroll-area.js";
5
5
  import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../ui/tooltip.js";
6
+ import { createDesignCanvasLayer, designCanvasFillColor, drawnDesignCanvasBounds } from "./design-canvas-data.js";
7
+ import { DesignCanvasInspector } from "./design-canvas-inspector.js";
6
8
  import { Drawer, DrawerContent, DrawerTitle } from "../ui/drawer.js";
7
9
  import { InfiniteCanvas, InfiniteCanvasContent, InfiniteCanvasControls, InfiniteCanvasItem } from "../ui/infinite-canvas.js";
8
10
  import { ResizableFloatingPanel } from "../ui/resizable.js";
9
11
  import { Toolbar, ToolbarButton, ToolbarGroup, ToolbarSeparator } from "../ui/toolbar.js";
10
- import { createDesignCanvasLayer, designCanvasFillColor, drawnDesignCanvasBounds } from "./design-canvas-data.js";
11
- import { DesignCanvasInspector } from "./design-canvas-inspector.js";
12
12
  import { useRef, useState } from "react";
13
13
  import { jsx, jsxs } from "react/jsx-runtime";
14
14
  import { CircleIcon, FrameIcon, LayersIcon, MousePointer2Icon, SlidersHorizontalIcon, SquareIcon, TypeIcon } from "lucide-react";
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  import { Button } from "../ui/button.js";
3
- import { Kbd, KbdGroup } from "../ui/kbd.js";
4
3
  import { ChatComposer, ChatComposerShell, ChatComposerSubmit, ChatComposerTextarea, ChatComposerToolbar } from "../chat-composer.js";
5
4
  import { ChatMessageReplies } from "../chat-message/social.js";
6
5
  import { ChatMessage, ChatMessageActions, ChatMessageAuthor, ChatMessageAvatar, ChatMessageBody, ChatMessageContent, ChatMessageFooter, ChatMessageHeader, ChatMessageRow, ChatMessageTime } from "../chat-message.js";
6
+ import { Kbd, KbdGroup } from "../ui/kbd.js";
7
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
8
  import { CornerDownRightIcon } from "lucide-react";
9
9
  //#region src/blocks/discussion.tsx
@@ -5,15 +5,15 @@ import { LiveStatus } from "../ui/live-status.js";
5
5
  import { ScrollArea } from "../ui/scroll-area.js";
6
6
  import { InputGroup, InputGroupAddon } from "../ui/input-group.js";
7
7
  import { Input } from "../ui/input.js";
8
- import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "../ui/empty.js";
9
8
  import { SidebarProvider, useSidebar } from "../ui/sidebar-provider.js";
10
9
  import { SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem } from "../ui/sidebar-menu.js";
11
10
  import { Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarInset, SidebarRail, SidebarTrigger } from "../ui/sidebar.js";
11
+ import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "../ui/empty.js";
12
12
  import { Drawer, DrawerBody, DrawerContent, DrawerTitle, DrawerTrigger } from "../ui/drawer.js";
13
13
  import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "../ui/resizable.js";
14
14
  import { groupFileExplorerItems, orderFileExplorerEntries, resolveFileExplorer, searchFileExplorer } from "./file-explorer-data.js";
15
- import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from "../ui/dropdown-menu.js";
16
15
  import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from "../ui/breadcrumb.js";
16
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from "../ui/dropdown-menu.js";
17
17
  import { Fragment, useEffect, useId, useRef, useState } from "react";
18
18
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
19
19
  import { ChevronLeftIcon, ChevronRightIcon, FileIcon, FolderIcon, MoreHorizontalIcon, SearchIcon, XIcon } from "lucide-react";
@@ -2,16 +2,16 @@
2
2
  import { cn } from "../lib/cn.js";
3
3
  import { Button } from "../ui/button.js";
4
4
  import { LiveStatus } from "../ui/live-status.js";
5
- import { prefersReducedMotion } from "../lib/motion.js";
6
5
  import { ScrollArea } from "../ui/scroll-area.js";
6
+ import { prefersReducedMotion } from "../lib/motion.js";
7
7
  import { InputGroup, InputGroupAddon } from "../ui/input-group.js";
8
8
  import { Input } from "../ui/input.js";
9
- import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "../ui/empty.js";
10
- import { Field, FieldContent, FieldDescription, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet } from "../ui/field.js";
11
9
  import { SidebarProvider, useSidebar } from "../ui/sidebar-provider.js";
12
10
  import { SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem } from "../ui/sidebar-menu.js";
13
11
  import { Sidebar, SidebarContent, SidebarHeader, SidebarInset, SidebarTrigger } from "../ui/sidebar.js";
12
+ import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "../ui/empty.js";
14
13
  import { searchSettings } from "./settings-data.js";
14
+ import { Field, FieldContent, FieldDescription, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet } from "../ui/field.js";
15
15
  import { useEffect, useId, useState } from "react";
16
16
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
17
17
  import { ArrowLeftIcon, SearchIcon, XIcon } from "lucide-react";
@@ -2,8 +2,8 @@
2
2
  import { LiveStatus } from "../../ui/live-status.js";
3
3
  import { isComposingKey, useTriggerMenu } from "../../hooks/use-trigger-menu.js";
4
4
  import { spawnExitGhost } from "../ghost.js";
5
- import { TriggerMenu, TriggerMenuEmpty, TriggerMenuIcon, TriggerMenuItem, TriggerMenuList } from "../../ui/trigger-menu.js";
6
5
  import { detectTrigger } from "../../lib/trigger-detect.js";
6
+ import { TriggerMenu, TriggerMenuEmpty, TriggerMenuIcon, TriggerMenuItem, TriggerMenuList } from "../../ui/trigger-menu.js";
7
7
  import { useEffect } from "react";
8
8
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
9
  //#region src/chat-composer-editor/extensions/mention.tsx
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { hasSkinAdornment, skinAdornment } from "./skin.js";
3
2
  import { cn } from "./lib/cn.js";
3
+ import { hasSkinAdornment, skinAdornment } from "./skin.js";
4
4
  import { useSkin } from "./skin-provider.js";
5
5
  import { Button } from "./ui/button.js";
6
6
  import { Spinner } from "./ui/spinner.js";
@@ -7,9 +7,9 @@ import { ScrollArea } from "./ui/scroll-area.js";
7
7
  import { ChatThreadAnnounceContext } from "./hooks/use-chat-message.js";
8
8
  import { useChatThreadScroll } from "./hooks/use-chat-thread-scroll.js";
9
9
  import { createContext, useContext, useState } from "react";
10
+ import { useRender } from "@base-ui/react/use-render";
10
11
  import { jsx, jsxs } from "react/jsx-runtime";
11
12
  import { ArrowDown } from "lucide-react";
12
- import { useRender } from "@base-ui/react/use-render";
13
13
  //#region src/chat-layout.tsx
14
14
  const chromeSizing = {
15
15
  panel: "mx-auto min-h-[640px] max-w-3xl",
package/dist/context.js CHANGED
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  import { cn } from "./lib/cn.js";
3
3
  import { Button } from "./ui/button.js";
4
- import { Popover, PopoverClose, PopoverContent, PopoverDescription, PopoverTitle, PopoverTrigger } from "./ui/popover.js";
5
4
  import { ScrollArea } from "./ui/scroll-area.js";
6
5
  import { deriveContextModel } from "./context-model.js";
6
+ import { Popover, PopoverClose, PopoverContent, PopoverDescription, PopoverTitle, PopoverTrigger } from "./ui/popover.js";
7
7
  import { createContext, useContext, useId, useMemo } from "react";
8
8
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
9
  import { X } from "lucide-react";
@@ -2,8 +2,8 @@
2
2
  import { cn } from "./lib/cn.js";
3
3
  import { Button } from "./ui/button.js";
4
4
  import { LiveStatus } from "./ui/live-status.js";
5
- import { createDynamicNotificationLiquid } from "./dynamic-notification-liquid.js";
6
5
  import { createDynamicNotificationGlass } from "./dynamic-notification-glass.js";
6
+ import { createDynamicNotificationLiquid } from "./dynamic-notification-liquid.js";
7
7
  import { useDynamicNotification } from "./hooks/use-dynamic-notification.js";
8
8
  import { createContext, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
9
9
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1,5 +1,5 @@
1
- import { composite, resolveColor, tokenMaps } from "../scripts/contrast-eval.js";
2
1
  import { emailLengthPixels } from "./length.js";
2
+ import { composite, resolveColor, tokenMaps } from "../scripts/contrast-eval.js";
3
3
  //#region src/email/theme.ts
4
4
  function resolveVariables(value, tokens, chain = []) {
5
5
  if (chain.length > 16) throw new Error(`Email theme: token chain exceeds 16 references (${chain.join(" → ")}).`);
@@ -5,9 +5,9 @@ import { useFilterBarContext } from "./context.js";
5
5
  import { describeFilter, formatFilterValue } from "./model.js";
6
6
  import { FilterBarEditor, FilterBarInlineInput } from "./editor.js";
7
7
  import { useEffect, useId, useRef } from "react";
8
+ import { useRender } from "@base-ui/react/use-render";
8
9
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
10
  import { PlusIcon, XIcon } from "lucide-react";
10
- import { useRender } from "@base-ui/react/use-render";
11
11
  //#region src/filter-bar/parts.tsx
12
12
  function chipSegments(item, field, operator, draft) {
13
13
  const segments = [{
@@ -6,8 +6,8 @@ import { describeFilter, fieldOperators, filterNavigationKeys } from "./filter-b
6
6
  import { filterMotionEnabled, useFilterBarMotion } from "./filter-bar/motion.js";
7
7
  import { FilterBarAddButton, FilterBarChip, FilterBarChips, FilterBarClear, FilterBarInput } from "./filter-bar/parts.js";
8
8
  import { useState } from "react";
9
- import { jsx, jsxs } from "react/jsx-runtime";
10
9
  import { useRender } from "@base-ui/react/use-render";
10
+ import { jsx, jsxs } from "react/jsx-runtime";
11
11
  //#region src/filter-bar.tsx
12
12
  function valueStatusMessage(field) {
13
13
  if (field?.error) return typeof field.error === "string" ? field.error : "Couldn’t load values.";
@@ -2,8 +2,8 @@
2
2
  import { cn } from "./lib/cn.js";
3
3
  import { Button } from "./ui/button.js";
4
4
  import { LiveStatus } from "./ui/live-status.js";
5
- import { SourceFavicon, sourceHostname } from "./source-badge.js";
6
5
  import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover.js";
6
+ import { SourceFavicon, sourceHostname } from "./source-badge.js";
7
7
  import { createContext, useContext, useRef, useState } from "react";
8
8
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
9
  import { ArrowLeft, ArrowRight, ExternalLink } from "lucide-react";
@@ -1,4 +1,4 @@
1
1
  //#region src/knob-contracts/emoji-picker-knobs.d.ts
2
- export declare const emojiPickerKnobs: readonly ["--cui-emoji-picker-cell-size", "--cui-emoji-picker-cell-radius", "--cui-emoji-picker-active-background", "--cui-emoji-picker-header-background", "--cui-emoji-picker-header-foreground"];
2
+ export declare const emojiPickerKnobs: readonly ["--cui-emoji-picker-cell-size", "--cui-emoji-picker-height", "--cui-emoji-picker-cell-radius", "--cui-emoji-picker-active-background", "--cui-emoji-picker-header-background", "--cui-emoji-picker-header-foreground"];
3
3
  export type EmojiPickerKnobStyle = Partial<Record<(typeof emojiPickerKnobs)[number], string>>;
4
4
  //#endregion
@@ -1,6 +1,7 @@
1
1
  //#region src/knob-contracts/emoji-picker-knobs.ts
2
2
  const emojiPickerKnobs = [
3
3
  "--cui-emoji-picker-cell-size",
4
+ "--cui-emoji-picker-height",
4
5
  "--cui-emoji-picker-cell-radius",
5
6
  "--cui-emoji-picker-active-background",
6
7
  "--cui-emoji-picker-header-background",
@@ -0,0 +1,4 @@
1
+ //#region src/knob-contracts/icon-picker-knobs.d.ts
2
+ export declare const iconPickerKnobs: readonly ["--cui-icon-picker-cell-size", "--cui-icon-picker-cell-radius", "--cui-icon-picker-foreground", "--cui-icon-picker-active-background"];
3
+ export type IconPickerKnobStyle = Partial<Record<(typeof iconPickerKnobs)[number], string>>;
4
+ //#endregion
@@ -0,0 +1,9 @@
1
+ //#region src/knob-contracts/icon-picker-knobs.ts
2
+ const iconPickerKnobs = [
3
+ "--cui-icon-picker-cell-size",
4
+ "--cui-icon-picker-cell-radius",
5
+ "--cui-icon-picker-foreground",
6
+ "--cui-icon-picker-active-background"
7
+ ];
8
+ //#endregion
9
+ export { iconPickerKnobs };
@@ -1,4 +1,4 @@
1
1
  //#region src/knob-contracts/markdown-knobs.d.ts
2
- export declare const markdownKnobs: readonly ["--cui-markdown-foreground", "--cui-markdown-blockquote-border-color", "--cui-markdown-blockquote-foreground", "--cui-markdown-inline-code-background", "--cui-markdown-inline-code-foreground", "--cui-markdown-inline-code-radius", "--cui-markdown-link-foreground", "--cui-markdown-image-outline-color", "--cui-markdown-table-cell-border-color", "--cui-markdown-table-header-background", "--cui-markdown-font-size", "--cui-markdown-line-height"];
2
+ export declare const markdownKnobs: readonly ["--cui-markdown-foreground", "--cui-markdown-blockquote-border-color", "--cui-markdown-blockquote-foreground", "--cui-markdown-inline-code-background", "--cui-markdown-inline-code-foreground", "--cui-markdown-inline-code-radius", "--cui-markdown-link-foreground", "--cui-markdown-image-outline-color", "--cui-markdown-table-cell-border-color", "--cui-markdown-table-header-background", "--cui-markdown-font-size", "--cui-markdown-line-height", "--cui-markdown-flow-gap", "--cui-markdown-heading-gap"];
3
3
  export type MarkdownKnobStyle = Partial<Record<(typeof markdownKnobs)[number], string>>;
4
4
  //#endregion
@@ -11,7 +11,9 @@ const markdownKnobs = [
11
11
  "--cui-markdown-table-cell-border-color",
12
12
  "--cui-markdown-table-header-background",
13
13
  "--cui-markdown-font-size",
14
- "--cui-markdown-line-height"
14
+ "--cui-markdown-line-height",
15
+ "--cui-markdown-flow-gap",
16
+ "--cui-markdown-heading-gap"
15
17
  ];
16
18
  //#endregion
17
19
  export { markdownKnobs };
@@ -1,4 +1,4 @@
1
1
  //#region src/knob-contracts/tabs-knobs.d.ts
2
- export declare const tabsKnobs: readonly ["--cui-tabs-trigger-radius", "--cui-tabs-list-padding", "--cui-tabs-list-radius", "--cui-tabs-list-background", "--cui-tabs-list-backdrop-filter", "--cui-tabs-indicator-background", "--cui-tabs-foreground", "--cui-tabs-active-foreground", "--cui-tabs-hover-foreground", "--cui-tabs-indicator-shadow", "--cui-tabs-list-shadow", "--cui-tabs-border-color", "--cui-tabs-border-width"];
2
+ export declare const tabsKnobs: readonly ["--cui-tabs-surface-background", "--cui-tabs-surface-radius", "--cui-tabs-trigger-radius", "--cui-tabs-list-padding", "--cui-tabs-list-radius", "--cui-tabs-list-background", "--cui-tabs-list-backdrop-filter", "--cui-tabs-indicator-background", "--cui-tabs-foreground", "--cui-tabs-active-foreground", "--cui-tabs-hover-foreground", "--cui-tabs-indicator-shadow", "--cui-tabs-list-shadow", "--cui-tabs-border-color", "--cui-tabs-border-width"];
3
3
  export type TabsKnobStyle = Partial<Record<(typeof tabsKnobs)[number], string>>;
4
4
  //#endregion
@@ -1,5 +1,7 @@
1
1
  //#region src/knob-contracts/tabs-knobs.ts
2
2
  const tabsKnobs = [
3
+ "--cui-tabs-surface-background",
4
+ "--cui-tabs-surface-radius",
3
5
  "--cui-tabs-trigger-radius",
4
6
  "--cui-tabs-list-padding",
5
7
  "--cui-tabs-list-radius",
@@ -1,5 +1,5 @@
1
- import { getCountryCallingCode } from "react-phone-number-input/max";
2
1
  import { AsYouType } from "libphonenumber-js/max";
2
+ import { getCountryCallingCode } from "react-phone-number-input/max";
3
3
  //#region src/lib/phone-input-format.ts
4
4
  function normalizePhoneInputText(value, country) {
5
5
  if (!country) return value;
package/dist/skin.d.ts CHANGED
@@ -38,6 +38,8 @@ export type ControlUiSkin = {
38
38
  colorScheme?: "light" | "dark";
39
39
  sidebarLayout?: SidebarLayout;
40
40
  scrollAreaBlur?: boolean;
41
+ scrollAreaScrollbarVisibility?: "scroll" | "hover" | "always";
42
+ scrollAreaScrollbarGutter?: "auto" | "stable";
41
43
  indicators?: SkinIndicators;
42
44
  sidebarWidth?: string;
43
45
  effects?: ControlEffect[];
@@ -58,6 +58,9 @@
58
58
  @import "./recipes/dynamic-notification-input.css";
59
59
  @import "./recipes/dynamic-notification-motion.css";
60
60
  @import "./recipes/emoji-picker.css";
61
+ @import "./recipes/icon-picker.css";
62
+ @import "./recipes/tabs.css";
63
+ @import "./recipes/tabs-motion.css";
61
64
  @import "./recipes/environment-variables.css";
62
65
  @import "./recipes/filter-bar.css";
63
66
  @import "./recipes/gradient-editor.css";
@@ -76,7 +79,6 @@
76
79
  @import "./recipes/switch.css";
77
80
  @import "./recipes/table.css";
78
81
  @import "./recipes/table-of-contents.css";
79
- @import "./recipes/tabs.css";
80
82
  @import "./recipes/task-list.css";
81
83
  @import "./recipes/thread-rail.css";
82
84
  @import "./recipes/timeline.css";
@@ -55,13 +55,25 @@
55
55
  font-size: var(--text-body);
56
56
  text-wrap: pretty;
57
57
  height: var(--accordion-panel-height);
58
- overflow: hidden;
59
58
  transition: height var(--duration-base) var(--ease-emphasized);
60
59
  }
61
60
 
62
61
  :where([data-control-family="accordion"][data-slot="panel"][data-starting-style]),
63
62
  :where([data-control-family="accordion"][data-slot="panel"][data-ending-style]) {
64
63
  height: 0;
64
+ overflow: clip;
65
+ }
66
+
67
+ @supports (transition-behavior: allow-discrete) {
68
+ :where([data-control-family="accordion"][data-slot="panel"]) {
69
+ transition-property: height, overflow;
70
+ transition-timing-function: var(--ease-emphasized), step-end;
71
+ transition-behavior: normal, allow-discrete;
72
+ }
73
+
74
+ :where([data-control-family="accordion"][data-slot="panel"][data-ending-style]) {
75
+ transition-timing-function: var(--ease-emphasized), step-start;
76
+ }
65
77
  }
66
78
  }
67
79
 
@@ -17,6 +17,7 @@
17
17
  background: var(--cui-badge-background);
18
18
  color: var(--cui-badge-foreground);
19
19
  font-size: var(--cui-badge-font-size);
20
+ font-variant-numeric: tabular-nums;
20
21
  }
21
22
 
22
23
  :where([data-control-family="badge"][data-slot="root"][data-size="sm"]) {
@@ -9,17 +9,22 @@
9
9
  }
10
10
 
11
11
  @media (pointer: coarse) {
12
- :where([data-control-family="button"][data-size="xs"])::after {
12
+ :where([data-control-family="button"][data-size])::after {
13
+ content: "";
14
+ position: absolute;
15
+ inset: 50%;
16
+ translate: -50% -50%;
17
+ inline-size: 100%;
13
18
  block-size: max(100%, var(--touch-target));
14
19
  }
15
20
 
16
- :where([data-control-family="button"][data-size="xs"][data-icon-only="true"])::after {
21
+ :where([data-control-family="button"][data-size][data-icon-only="true"])::after {
17
22
  inline-size: max(100%, var(--touch-target));
18
23
  }
19
24
  }
20
25
 
21
26
  :where([data-control-family="button"][data-control="true"]) {
22
- --cui-button-radius: var(--radius-control);
27
+ --cui-button-radius: var(--nest-radius, var(--radius-control));
23
28
  --cui-button-gap: calc(var(--spacing) * 1.5);
24
29
  --cui-button-icon: 1rem;
25
30
  --cui-button-height: var(--control-h-md);
@@ -44,7 +49,7 @@
44
49
  --cui-button-open-background: var(--cui-button-hover-background);
45
50
  --cui-button-open-foreground: var(--cui-button-hover-foreground);
46
51
  --cui-button-open-shadow: var(--cui-button-shadow);
47
- border-radius: var(--nest-radius, var(--cui-button-radius));
52
+ border-radius: var(--cui-button-radius);
48
53
  background-color: var(--cui-button-background);
49
54
  background-image: var(--cui-button-background-image);
50
55
  box-shadow: var(--cui-button-shadow);
@@ -110,6 +115,17 @@
110
115
  padding-inline: 0;
111
116
  }
112
117
 
118
+ :where([data-control-family="button"][data-layout="stacked"]) {
119
+ flex-direction: column;
120
+ block-size: auto;
121
+ padding-block: calc(var(--spacing) * 1.5);
122
+ padding-inline: var(--cui-button-padding-inline);
123
+ }
124
+
125
+ :where([data-control-family="button"][data-layout="stacked"] > [data-slot="content"]) {
126
+ flex-direction: column;
127
+ }
128
+
113
129
  :where([data-control-family="button"][data-control="true"] svg) {
114
130
  pointer-events: none;
115
131
  flex-shrink: 0;
@@ -137,21 +137,6 @@
137
137
  :where(:is([data-control-family="code"], [data-control-family="code-diff"])[data-slot="header"]) {
138
138
  min-block-size: var(--touch-target);
139
139
  }
140
-
141
- :where(:is([data-control-family="code"], [data-control-family="code-diff"])[data-slot="actions"] [data-control-family="button"]),
142
- :where([data-control-family="button"][data-code-copy="true"]) {
143
- position: relative;
144
- }
145
-
146
- :where(:is([data-control-family="code"], [data-control-family="code-diff"])[data-slot="actions"] [data-control-family="button"])::after,
147
- :where([data-control-family="button"][data-code-copy="true"])::after {
148
- content: "";
149
- position: absolute;
150
- inset: 50% 50%;
151
- translate: -50% -50%;
152
- inline-size: 100%;
153
- block-size: max(100%, var(--touch-target));
154
- }
155
140
  }
156
141
  }
157
142
 
@@ -38,6 +38,7 @@
38
38
  }
39
39
 
40
40
  :where([data-control-family="collapsible"][data-slot="content"]) {
41
+ height: var(--collapsible-panel-height);
41
42
  transition-property: height, opacity;
42
43
  transition-duration: var(--duration-slow);
43
44
  transition-timing-function: var(--ease-standard);
@@ -45,9 +46,23 @@
45
46
 
46
47
  :where([data-control-family="collapsible"][data-slot="content"][data-starting-style]),
47
48
  :where([data-control-family="collapsible"][data-slot="content"][data-ending-style]) {
49
+ height: 0;
50
+ overflow: clip;
48
51
  opacity: 0;
49
52
  }
50
53
 
54
+ @supports (transition-behavior: allow-discrete) {
55
+ :where([data-control-family="collapsible"][data-slot="content"]) {
56
+ transition-property: height, opacity, overflow;
57
+ transition-timing-function: var(--ease-standard), var(--ease-standard), step-end;
58
+ transition-behavior: normal, normal, allow-discrete;
59
+ }
60
+
61
+ :where([data-control-family="collapsible"][data-slot="content"][data-ending-style]) {
62
+ transition-timing-function: var(--ease-standard), var(--ease-standard), step-start;
63
+ }
64
+ }
65
+
51
66
  :where([data-control-family="collapsible"][data-slot="trigger"][data-state="open"] > svg) {
52
67
  rotate: 90deg;
53
68
  }
@@ -1,14 +1,78 @@
1
1
  @layer components {
2
2
  :where([data-control-family="emoji-picker"][data-slot="root"]) {
3
- --cui-emoji-picker-cell-size: calc(var(--spacing) * 8);
3
+ --cui-emoji-picker-cell-size: calc(var(--spacing) * 10);
4
4
  --cui-emoji-picker-cell-radius: var(--radius-control);
5
5
  --cui-emoji-picker-active-background: var(--accent);
6
6
  --cui-emoji-picker-header-background: var(--popover);
7
7
  --cui-emoji-picker-header-foreground: var(--muted-foreground);
8
+ --cui-emoji-picker-height: 22rem;
9
+ }
10
+ :where([data-control-family="emoji-picker"][data-slot="root"]:not([data-variant="reactions"])) {
11
+ inline-size: calc(var(--_emoji-picker-columns) * var(--cui-emoji-picker-cell-size) + var(--spacing) * 4);
12
+ max-inline-size: 100%;
13
+ block-size: var(--cui-emoji-picker-height);
8
14
  color: var(--foreground);
9
15
  font-family: var(--font-sans);
10
16
  }
11
17
 
18
+ :where([data-control-family="emoji-picker"][data-slot="categories"]) {
19
+ display: flex;
20
+ justify-content: space-between;
21
+ flex-shrink: 0;
22
+ overflow-x: auto;
23
+ padding-inline: calc(var(--spacing) * 1.5);
24
+ }
25
+ :where([data-control-family="emoji-picker"][data-slot="category"]) {
26
+ display: grid;
27
+ place-items: center;
28
+ flex: 0 0 calc(var(--spacing) * 9);
29
+ block-size: calc(var(--spacing) * 9);
30
+ border-radius: var(--cui-emoji-picker-cell-radius);
31
+ color: var(--muted-foreground);
32
+ cursor: pointer;
33
+ }
34
+ :where([data-control-family="emoji-picker"][data-slot="category"]:hover) {
35
+ color: var(--foreground);
36
+ background: var(--cui-emoji-picker-active-background);
37
+ }
38
+ :where([data-control-family="emoji-picker"][data-slot="category"] svg) {
39
+ inline-size: calc(var(--spacing) * 4);
40
+ block-size: calc(var(--spacing) * 4);
41
+ }
42
+ :where([data-control-family="emoji-picker"][data-slot="recent"]) {
43
+ padding-inline: calc(var(--spacing) * 2);
44
+ padding-block: calc(var(--spacing) * 1);
45
+ }
46
+ :where([data-control-family="emoji-picker"][data-slot="recent-label"]) {
47
+ color: var(--muted-foreground);
48
+ font-size: var(--text-caption);
49
+ padding-inline: calc(var(--spacing) * 1);
50
+ }
51
+ :where([data-control-family="emoji-picker"]:is([data-slot="recent-grid"], [data-variant="reactions"])) {
52
+ display: flex;
53
+ }
54
+ :where(
55
+ [data-control-family="emoji-picker"][data-slot="root"]:has(input:not(:placeholder-shown))
56
+ :is([data-slot="categories"], [data-slot="recent"])
57
+ ) {
58
+ display: none;
59
+ }
60
+ :where([data-control-family="emoji-picker"][data-slot="error"]) {
61
+ display: flex;
62
+ flex-direction: column;
63
+ align-items: center;
64
+ justify-content: center;
65
+ gap: calc(var(--spacing) * 2);
66
+ block-size: 100%;
67
+ color: var(--muted-foreground);
68
+ font-size: var(--text-label);
69
+ }
70
+ :where([data-control-family="emoji-picker"][data-slot="error"] button) {
71
+ color: var(--foreground);
72
+ text-decoration: underline;
73
+ min-block-size: 44px;
74
+ cursor: pointer;
75
+ }
12
76
  :where([data-control-family="emoji-picker"][data-slot="search"]) {
13
77
  position: relative;
14
78
  margin: calc(var(--spacing) * 2);
@@ -99,6 +163,19 @@
99
163
  :where([data-control-family="emoji-picker"][data-slot="footer-label"]) {
100
164
  color: var(--foreground);
101
165
  }
166
+
167
+ @media (pointer: coarse) {
168
+ :where([data-control-family="emoji-picker"][data-slot="root"]) {
169
+ --cui-emoji-picker-cell-size: 44px;
170
+ }
171
+ :where([data-control-family="emoji-picker"][data-slot="category"]) {
172
+ flex-basis: 44px;
173
+ block-size: 44px;
174
+ }
175
+ :where([data-control-family="emoji-picker"][data-slot="search-input"]) {
176
+ font-size: 16px;
177
+ }
178
+ }
102
179
  }
103
180
 
104
181
  @property --cui-emoji-picker-cell-size {
@@ -107,6 +184,12 @@
107
184
  initial-value: 0px;
108
185
  }
109
186
 
187
+ @property --cui-emoji-picker-height {
188
+ syntax: "<length>";
189
+ inherits: true;
190
+ initial-value: 0px;
191
+ }
192
+
110
193
  @property --cui-emoji-picker-cell-radius {
111
194
  syntax: "<length-percentage>";
112
195
  inherits: true;
@@ -1,7 +1,7 @@
1
1
  @layer components {
2
2
  :where([data-control-family="field"][data-control="true"]) {
3
3
  gap: calc(var(--spacing) * 1.5);
4
- --cui-field-radius: var(--radius-control);
4
+ --cui-field-radius: var(--nest-radius, var(--radius-control));
5
5
  --cui-field-background: var(--control-fill);
6
6
  --cui-field-hover-background: var(--hover-fill);
7
7
  --cui-field-affordance-background: transparent;
@@ -18,7 +18,7 @@
18
18
  --cui-field-padding-inline: var(--padding-x);
19
19
  --cui-field-font-size: var(--text-body);
20
20
  border: var(--cui-field-border-width) solid var(--cui-field-border-color);
21
- border-radius: var(--nest-radius, var(--cui-field-radius));
21
+ border-radius: var(--cui-field-radius);
22
22
  background: var(--cui-field-background);
23
23
  box-shadow: var(--cui-field-shadow);
24
24
  color: var(--cui-field-foreground);
@@ -58,6 +58,19 @@
58
58
  font-size: var(--cui-field-font-size);
59
59
  }
60
60
 
61
+ :where(
62
+ input[data-control-family="field"]:is(
63
+ [type="number"],
64
+ [type="date"],
65
+ [type="time"],
66
+ [type="datetime-local"],
67
+ [inputmode="numeric"],
68
+ [inputmode="decimal"]
69
+ )
70
+ ) {
71
+ font-variant-numeric: tabular-nums;
72
+ }
73
+
61
74
  :where([data-control-family="field"][data-control="true"])::placeholder {
62
75
  color: var(--muted-foreground);
63
76
  }