@ctrl-ui/react 0.9.8 → 0.9.10

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 (54) hide show
  1. package/dist/blocks/design-canvas-inspector.js +1 -1
  2. package/dist/blocks/file-explorer.js +1 -1
  3. package/dist/blocks/settings.js +1 -1
  4. package/dist/control-variants.d.ts +2 -2
  5. package/dist/control-variants.js +4 -3
  6. package/dist/knob-contracts/badge-knobs.d.ts +1 -1
  7. package/dist/knob-contracts/badge-knobs.js +1 -0
  8. package/dist/knob-contracts/card-knobs.d.ts +1 -1
  9. package/dist/knob-contracts/card-knobs.js +1 -0
  10. package/dist/knob-contracts/collapsible-knobs.d.ts +1 -1
  11. package/dist/knob-contracts/collapsible-knobs.js +4 -1
  12. package/dist/knob-contracts/flow-knobs.d.ts +1 -1
  13. package/dist/knob-contracts/flow-knobs.js +4 -0
  14. package/dist/knob-contracts/item-knobs.d.ts +1 -1
  15. package/dist/knob-contracts/item-knobs.js +1 -0
  16. package/dist/knob-contracts/tabs-knobs.d.ts +1 -1
  17. package/dist/knob-contracts/tabs-knobs.js +1 -0
  18. package/dist/skin.d.ts +2 -2
  19. package/dist/styles/recipes/alert.css +12 -0
  20. package/dist/styles/recipes/badge.css +7 -0
  21. package/dist/styles/recipes/button-states.css +6 -0
  22. package/dist/styles/recipes/button.css +21 -0
  23. package/dist/styles/recipes/card.css +35 -0
  24. package/dist/styles/recipes/collapsible.css +25 -1
  25. package/dist/styles/recipes/empty.css +5 -0
  26. package/dist/styles/recipes/flow.css +33 -2
  27. package/dist/styles/recipes/item.css +11 -0
  28. package/dist/styles/recipes/popup-controls.css +44 -0
  29. package/dist/styles/recipes/skeleton.css +8 -0
  30. package/dist/styles/recipes/tabs.css +8 -1
  31. package/dist/surface-variants.d.ts +2 -0
  32. package/dist/surface-variants.js +2 -1
  33. package/dist/ui/alert.d.ts +4 -0
  34. package/dist/ui/alert.js +10 -1
  35. package/dist/ui/button.d.ts +3 -3
  36. package/dist/ui/card.d.ts +5 -0
  37. package/dist/ui/card.js +15 -1
  38. package/dist/ui/combobox.d.ts +3 -0
  39. package/dist/ui/combobox.js +17 -2
  40. package/dist/ui/context-menu.d.ts +3 -1
  41. package/dist/ui/context-menu.js +2 -1
  42. package/dist/ui/dropdown-menu.d.ts +5 -2
  43. package/dist/ui/dropdown-menu.js +2 -1
  44. package/dist/ui/empty.d.ts +4 -1
  45. package/dist/ui/empty.js +4 -2
  46. package/dist/ui/menubar.d.ts +3 -1
  47. package/dist/ui/menubar.js +2 -1
  48. package/dist/ui/popover.d.ts +1 -1
  49. package/dist/ui/popover.js +5 -1
  50. package/dist/ui/sheet.d.ts +9 -0
  51. package/dist/ui/sheet.js +23 -1
  52. package/dist/ui/skeleton.d.ts +4 -1
  53. package/dist/ui/skeleton.js +8 -2
  54. package/package.json +1 -1
@@ -1,11 +1,11 @@
1
1
  "use client";
2
2
  import { Button } from "../ui/button.js";
3
3
  import { Heading } from "../ui/typography.js";
4
+ import { InputGroup, InputGroupAddon } from "../ui/input-group.js";
4
5
  import { Separator } from "../ui/separator.js";
5
6
  import { resizeDesignCanvasLayer } from "./design-canvas-data.js";
6
7
  import { ColorPickerArea } from "../ui/color-picker-area.js";
7
8
  import { ColorPickerHue } from "../ui/color-picker-sliders.js";
8
- import { InputGroup, InputGroupAddon } from "../ui/input-group.js";
9
9
  import { NumberField, NumberFieldGroup, NumberFieldInput, NumberFieldScrubArea } from "../ui/number-field.js";
10
10
  import { ColorPickerEyeDropper, ColorPickerInput } from "../ui/color-picker-values.js";
11
11
  import { ColorPicker, ColorPickerContent, ColorPickerTrigger } from "../ui/color-picker.js";
@@ -4,11 +4,11 @@ import { Button } from "../ui/button.js";
4
4
  import { LiveStatus } from "../ui/live-status.js";
5
5
  import { ScrollArea } from "../ui/scroll-area.js";
6
6
  import { Heading, Text } from "../ui/typography.js";
7
+ import { InputGroup, InputGroupAddon } from "../ui/input-group.js";
7
8
  import { Drawer, DrawerBody, DrawerContent, DrawerTitle, DrawerTrigger } from "../ui/drawer.js";
8
9
  import { SidebarProvider, useSidebar } from "../ui/sidebar-provider.js";
9
10
  import { SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem } from "../ui/sidebar-menu.js";
10
11
  import { Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarInset, SidebarRail, SidebarTrigger } from "../ui/sidebar.js";
11
- import { InputGroup, InputGroupAddon } from "../ui/input-group.js";
12
12
  import { Input } from "../ui/input.js";
13
13
  import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "../ui/empty.js";
14
14
  import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "../ui/resizable.js";
@@ -5,10 +5,10 @@ import { LiveStatus } from "../ui/live-status.js";
5
5
  import { ScrollArea } from "../ui/scroll-area.js";
6
6
  import { Heading, Text } from "../ui/typography.js";
7
7
  import { prefersReducedMotion } from "../lib/motion.js";
8
+ import { InputGroup, InputGroupAddon } from "../ui/input-group.js";
8
9
  import { SidebarProvider, useSidebar } from "../ui/sidebar-provider.js";
9
10
  import { SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem } from "../ui/sidebar-menu.js";
10
11
  import { Sidebar, SidebarContent, SidebarHeader, SidebarInset, SidebarTrigger } from "../ui/sidebar.js";
11
- import { InputGroup, InputGroupAddon } from "../ui/input-group.js";
12
12
  import { Input } from "../ui/input.js";
13
13
  import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "../ui/empty.js";
14
14
  import { searchSettings } from "./settings-data.js";
@@ -1,7 +1,7 @@
1
1
  //#region src/control-variants.d.ts
2
2
  export type ControlSize = "xs" | "sm" | "md" | "lg";
3
- export declare const controlVariants: readonly ["solid", "surface", "ghost", "quiet"];
4
- export type ControlVariant = (typeof controlVariants)[number];
3
+ export declare const buttonVariants: readonly ["solid", "surface", "ghost", "quiet", "link"];
4
+ export type ButtonVariant = (typeof buttonVariants)[number];
5
5
  export declare const controlTones: readonly ["neutral", "primary", "danger"];
6
6
  export type ControlTone = (typeof controlTones)[number];
7
7
  //#endregion
@@ -1,9 +1,10 @@
1
1
  //#region src/control-variants.ts
2
- const controlVariants = [
2
+ const buttonVariants = [
3
3
  "solid",
4
4
  "surface",
5
5
  "ghost",
6
- "quiet"
6
+ "quiet",
7
+ "link"
7
8
  ];
8
9
  const controlTones = [
9
10
  "neutral",
@@ -11,4 +12,4 @@ const controlTones = [
11
12
  "danger"
12
13
  ];
13
14
  //#endregion
14
- export { controlTones, controlVariants };
15
+ export { buttonVariants, controlTones };
@@ -1,4 +1,4 @@
1
1
  //#region src/knob-contracts/badge-knobs.d.ts
2
- export declare const badgeKnobs: readonly ["--cui-badge-radius", "--cui-badge-background", "--cui-badge-foreground", "--cui-badge-border-color", "--cui-badge-border-width", "--cui-badge-font-size", "--cui-badge-font-weight"];
2
+ export declare const badgeKnobs: readonly ["--cui-badge-radius", "--cui-badge-background", "--cui-badge-foreground", "--cui-badge-border-color", "--cui-badge-border-width", "--cui-badge-font-family", "--cui-badge-font-size", "--cui-badge-font-weight"];
3
3
  export type BadgeKnobStyle = Partial<Record<(typeof badgeKnobs)[number], string>>;
4
4
  //#endregion
@@ -5,6 +5,7 @@ const badgeKnobs = [
5
5
  "--cui-badge-foreground",
6
6
  "--cui-badge-border-color",
7
7
  "--cui-badge-border-width",
8
+ "--cui-badge-font-family",
8
9
  "--cui-badge-font-size",
9
10
  "--cui-badge-font-weight"
10
11
  ];
@@ -1,4 +1,4 @@
1
1
  //#region src/knob-contracts/card-knobs.d.ts
2
- export declare const cardKnobs: readonly ["--cui-card-radius", "--cui-card-background", "--cui-card-border-color", "--cui-card-border-width", "--cui-card-shadow", "--cui-card-backdrop-filter", "--cui-card-padding-block", "--cui-card-padding-inline", "--cui-card-gap", "--cui-card-title-font-size"];
2
+ export declare const cardKnobs: readonly ["--cui-card-radius", "--cui-card-background", "--cui-card-hover-background", "--cui-card-border-color", "--cui-card-border-width", "--cui-card-shadow", "--cui-card-backdrop-filter", "--cui-card-padding-block", "--cui-card-padding-inline", "--cui-card-gap", "--cui-card-title-font-size"];
3
3
  export type CardKnobStyle = Partial<Record<(typeof cardKnobs)[number], string>>;
4
4
  //#endregion
@@ -2,6 +2,7 @@
2
2
  const cardKnobs = [
3
3
  "--cui-card-radius",
4
4
  "--cui-card-background",
5
+ "--cui-card-hover-background",
5
6
  "--cui-card-border-color",
6
7
  "--cui-card-border-width",
7
8
  "--cui-card-shadow",
@@ -1,4 +1,4 @@
1
1
  //#region src/knob-contracts/collapsible-knobs.d.ts
2
- export declare const collapsibleKnobs: readonly ["--cui-collapsible-trigger-radius", "--cui-collapsible-trigger-hover-background", "--cui-collapsible-trigger-padding-inline"];
2
+ export declare const collapsibleKnobs: readonly ["--cui-collapsible-trigger-radius", "--cui-collapsible-trigger-hover-background", "--cui-collapsible-trigger-padding-inline", "--cui-collapsible-trigger-padding-block", "--cui-collapsible-trigger-foreground", "--cui-collapsible-trigger-hover-foreground"];
3
3
  export type CollapsibleKnobStyle = Partial<Record<(typeof collapsibleKnobs)[number], string>>;
4
4
  //#endregion
@@ -2,7 +2,10 @@
2
2
  const collapsibleKnobs = [
3
3
  "--cui-collapsible-trigger-radius",
4
4
  "--cui-collapsible-trigger-hover-background",
5
- "--cui-collapsible-trigger-padding-inline"
5
+ "--cui-collapsible-trigger-padding-inline",
6
+ "--cui-collapsible-trigger-padding-block",
7
+ "--cui-collapsible-trigger-foreground",
8
+ "--cui-collapsible-trigger-hover-foreground"
6
9
  ];
7
10
  //#endregion
8
11
  export { collapsibleKnobs };
@@ -1,4 +1,4 @@
1
1
  //#region src/knob-contracts/flow-knobs.d.ts
2
- export declare const flowKnobs: readonly ["--cui-flow-background", "--cui-flow-grid-dot-color", "--cui-flow-edge-stroke", "--cui-flow-selected-edge-stroke", "--cui-flow-edge-size", "--cui-flow-node-background", "--cui-flow-node-foreground", "--cui-flow-node-border-color", "--cui-flow-node-hover-border-color", "--cui-flow-node-selected-border-color", "--cui-flow-node-border-width", "--cui-flow-node-radius", "--cui-flow-node-shadow", "--cui-flow-handle-size", "--cui-flow-handle-background", "--cui-flow-handle-border-color", "--cui-flow-handle-border-width", "--cui-flow-edge-label-background", "--cui-flow-edge-label-foreground", "--cui-flow-edge-label-border-color", "--cui-flow-edge-label-border-width", "--cui-flow-controls-item-radius", "--cui-flow-controls-padding", "--cui-flow-controls-radius", "--cui-flow-controls-background", "--cui-flow-controls-border-color", "--cui-flow-controls-shadow"];
2
+ export declare const flowKnobs: readonly ["--cui-flow-background", "--cui-flow-grid-dot-color", "--cui-flow-edge-stroke", "--cui-flow-selected-edge-stroke", "--cui-flow-edge-size", "--cui-flow-node-background", "--cui-flow-node-foreground", "--cui-flow-node-border-color", "--cui-flow-node-hover-border-color", "--cui-flow-node-selected-border-color", "--cui-flow-node-border-width", "--cui-flow-node-body-background", "--cui-flow-node-body-radius", "--cui-flow-node-body-padding-inline", "--cui-flow-node-body-padding-block", "--cui-flow-node-radius", "--cui-flow-node-shadow", "--cui-flow-handle-size", "--cui-flow-handle-background", "--cui-flow-handle-border-color", "--cui-flow-handle-border-width", "--cui-flow-edge-label-background", "--cui-flow-edge-label-foreground", "--cui-flow-edge-label-border-color", "--cui-flow-edge-label-border-width", "--cui-flow-controls-item-radius", "--cui-flow-controls-padding", "--cui-flow-controls-radius", "--cui-flow-controls-background", "--cui-flow-controls-border-color", "--cui-flow-controls-shadow"];
3
3
  export type FlowKnobStyle = Partial<Record<(typeof flowKnobs)[number], string>>;
4
4
  //#endregion
@@ -11,6 +11,10 @@ const flowKnobs = [
11
11
  "--cui-flow-node-hover-border-color",
12
12
  "--cui-flow-node-selected-border-color",
13
13
  "--cui-flow-node-border-width",
14
+ "--cui-flow-node-body-background",
15
+ "--cui-flow-node-body-radius",
16
+ "--cui-flow-node-body-padding-inline",
17
+ "--cui-flow-node-body-padding-block",
14
18
  "--cui-flow-node-radius",
15
19
  "--cui-flow-node-shadow",
16
20
  "--cui-flow-handle-size",
@@ -1,4 +1,4 @@
1
1
  //#region src/knob-contracts/item-knobs.d.ts
2
- export declare const itemKnobs: readonly ["--cui-item-radius", "--cui-item-hover-background", "--cui-item-hover-border-color", "--cui-item-border-width", "--cui-item-active-scale", "--cui-item-gap", "--cui-item-padding-block", "--cui-item-padding-inline", "--cui-item-description-font-size", "--cui-item-description-line-height", "--cui-item-description-foreground", "--cui-item-media-foreground"];
2
+ export declare const itemKnobs: readonly ["--cui-item-radius", "--cui-item-hover-background", "--cui-item-current-background", "--cui-item-hover-border-color", "--cui-item-border-width", "--cui-item-active-scale", "--cui-item-gap", "--cui-item-padding-block", "--cui-item-padding-inline", "--cui-item-description-font-size", "--cui-item-description-line-height", "--cui-item-description-foreground", "--cui-item-media-foreground"];
3
3
  export type ItemKnobStyle = Partial<Record<(typeof itemKnobs)[number], string>>;
4
4
  //#endregion
@@ -2,6 +2,7 @@
2
2
  const itemKnobs = [
3
3
  "--cui-item-radius",
4
4
  "--cui-item-hover-background",
5
+ "--cui-item-current-background",
5
6
  "--cui-item-hover-border-color",
6
7
  "--cui-item-border-width",
7
8
  "--cui-item-active-scale",
@@ -1,4 +1,4 @@
1
1
  //#region src/knob-contracts/tabs-knobs.d.ts
2
- export declare const tabsKnobs: readonly ["--cui-tabs-surface-background", "--cui-tabs-surface-radius", "--cui-tabs-trigger-radius", "--cui-tabs-trigger-height", "--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-font-size", "--cui-tabs-font-weight", "--cui-tabs-active-foreground", "--cui-tabs-hover-foreground", "--cui-tabs-indicator-shadow", "--cui-tabs-list-shadow", "--cui-tabs-border-color", "--cui-tabs-border-width", "--cui-tabs-indicator-background-image"];
2
+ export declare const tabsKnobs: readonly ["--cui-tabs-surface-background", "--cui-tabs-surface-radius", "--cui-tabs-trigger-padding-inline", "--cui-tabs-trigger-radius", "--cui-tabs-trigger-height", "--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-font-size", "--cui-tabs-font-weight", "--cui-tabs-active-foreground", "--cui-tabs-hover-foreground", "--cui-tabs-indicator-shadow", "--cui-tabs-list-shadow", "--cui-tabs-border-color", "--cui-tabs-border-width", "--cui-tabs-indicator-background-image"];
3
3
  export type TabsKnobStyle = Partial<Record<(typeof tabsKnobs)[number], string>>;
4
4
  //#endregion
@@ -2,6 +2,7 @@
2
2
  const tabsKnobs = [
3
3
  "--cui-tabs-surface-background",
4
4
  "--cui-tabs-surface-radius",
5
+ "--cui-tabs-trigger-padding-inline",
5
6
  "--cui-tabs-trigger-radius",
6
7
  "--cui-tabs-trigger-height",
7
8
  "--cui-tabs-list-padding",
package/dist/skin.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import { HoverIndicator, SelectionIndicator } from "./control-props.js";
2
- import { ControlTone, ControlVariant } from "./control-variants.js";
2
+ import { ButtonVariant, ControlTone } from "./control-variants.js";
3
3
  import { ReactNode } from "react";
4
4
  //#region src/skin.d.ts
5
5
  type StatelessPart = Record<never, never>;
6
6
  export type SkinAdornmentContexts = {
7
7
  button: {
8
8
  layer: {
9
- variant: ControlVariant;
9
+ variant: ButtonVariant;
10
10
  tone: ControlTone;
11
11
  };
12
12
  };
@@ -39,6 +39,18 @@
39
39
  column-gap: var(--cui-alert-icon-gap);
40
40
  }
41
41
 
42
+ :where([data-control-family="alert"][data-slot="root"]:has(> [data-slot="action"])) {
43
+ grid-template-columns: 0 minmax(0, 1fr) auto;
44
+ }
45
+
46
+ :where([data-control-family="alert"][data-slot="root"]:has(> svg):has(> [data-slot="action"])) {
47
+ grid-template-columns: var(--cui-alert-icon-size) minmax(0, 1fr) auto;
48
+ }
49
+
50
+ :where([data-control-family="alert"][data-slot="root"]:not(:has(> svg)) > [data-slot="action"]) {
51
+ margin-inline-start: var(--cui-alert-icon-gap);
52
+ }
53
+
42
54
  :where([data-control-family="alert"][data-slot="description"]) {
43
55
  gap: var(--cui-alert-description-gap);
44
56
  color: var(--cui-alert-description-foreground);
@@ -9,6 +9,7 @@
9
9
  --cui-badge-border-width: 1px;
10
10
  --cui-badge-font-size: var(--text-caption);
11
11
  --cui-badge-font-weight: var(--font-weight-medium);
12
+ --cui-badge-font-family: var(--font-body);
12
13
  --_badge-color-background: var(--badge-neutral);
13
14
  --_badge-color-foreground: var(--badge-neutral-foreground);
14
15
  --_badge-color-border: var(--badge-neutral-border);
@@ -20,6 +21,7 @@
20
21
  border-radius: var(--cui-badge-radius);
21
22
  background: var(--cui-badge-background);
22
23
  color: var(--cui-badge-foreground);
24
+ font-family: var(--cui-badge-font-family);
23
25
  font-size: var(--cui-badge-font-size);
24
26
  font-weight: var(--cui-badge-font-weight);
25
27
  font-variant-numeric: tabular-nums;
@@ -124,6 +126,11 @@
124
126
  initial-value: 0px;
125
127
  }
126
128
 
129
+ @property --cui-badge-font-family {
130
+ syntax: "*";
131
+ inherits: true;
132
+ }
133
+
127
134
  @property --cui-badge-font-size {
128
135
  syntax: "<length-percentage>";
129
136
  inherits: true;
@@ -59,6 +59,12 @@
59
59
  scale: var(--cui-button-press-scale);
60
60
  }
61
61
 
62
+ :where([data-control-family="button"][data-variant="link"]) {
63
+ background: none;
64
+ box-shadow: none;
65
+ scale: none;
66
+ }
67
+
62
68
  :where([data-control-family="button"]:is(:disabled, [data-disabled], [aria-disabled="true"])) {
63
69
  cursor: not-allowed;
64
70
  opacity: var(--disabled-opacity);
@@ -183,9 +183,23 @@
183
183
  --cui-button-open-background: oklch(from var(--foreground) l c h / 0.07);
184
184
  }
185
185
 
186
+ :where([data-control-family="button"][data-variant="link"]) {
187
+ --cui-button-active-foreground: var(--cui-button-hover-foreground);
188
+ block-size: auto;
189
+ padding-inline: 0;
190
+ text-underline-offset: 0.2em;
191
+ }
192
+
193
+ @media (hover: hover) {
194
+ :where([data-control-family="button"][data-variant="link"]:not(:disabled, [data-disabled]):hover) {
195
+ text-decoration-line: underline;
196
+ }
197
+ }
198
+
186
199
  :where([data-control-family="button"][data-tone="primary"]:not([data-variant="solid"])) {
187
200
  --cui-button-foreground: var(--primary-text);
188
201
  --cui-button-hover-foreground: var(--primary-text);
202
+ --cui-button-active-foreground: var(--primary-text);
189
203
  }
190
204
 
191
205
  :where([data-control-family="button"][data-tone="danger"][data-variant="solid"]) {
@@ -201,6 +215,13 @@
201
215
  :where([data-control-family="button"][data-tone="danger"]:not([data-variant="solid"])) {
202
216
  --cui-button-foreground: var(--destructive-text);
203
217
  --cui-button-hover-foreground: var(--destructive-text);
218
+ --cui-button-active-foreground: var(--destructive-text);
219
+ }
220
+
221
+ :where([data-control-family="button"][data-tone="danger"][data-variant="surface"]) {
222
+ --cui-button-active-background: oklch(from var(--destructive) l c h / 0.08);
223
+ --cui-button-active-hover-background: oklch(from var(--destructive) l c h / 0.1);
224
+ --cui-button-active-shadow: inset 0 0 0 var(--control-rim-width) oklch(from var(--destructive) l c h / 0.6), var(--shadow-sm);
204
225
  }
205
226
 
206
227
  :where([data-control-family="button"][data-shape="circle"]) {
@@ -2,6 +2,7 @@
2
2
  :where([data-control-family="card"][data-slot="root"]) {
3
3
  --cui-card-radius: var(--radius-lg);
4
4
  --cui-card-background: var(--card);
5
+ --cui-card-hover-background: var(--accent);
5
6
  --cui-card-border-color: var(--border);
6
7
  --cui-card-border-width: var(--control-rim-width);
7
8
  --cui-card-shadow: var(--shadow-sm);
@@ -34,6 +35,34 @@
34
35
  padding-inline: var(--cui-card-padding-inline);
35
36
  }
36
37
 
38
+ :where([data-control-family="card"][data-slot="root"]:has([data-control-family="card"][data-slot="link"])) {
39
+ position: relative;
40
+ }
41
+
42
+ @media (hover: hover) {
43
+ :where([data-control-family="card"][data-slot="root"]:has([data-control-family="card"][data-slot="link"]:hover)) {
44
+ background: var(--cui-card-hover-background);
45
+ }
46
+ }
47
+
48
+ :where([data-control-family="card"][data-slot="root"]:has([data-control-family="card"][data-slot="link"]:focus-visible)) {
49
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring);
50
+ outline-offset: var(--focus-ring-offset);
51
+ }
52
+
53
+ :where([data-control-family="card"][data-slot="link"]) {
54
+ text-align: start;
55
+ cursor: pointer;
56
+ outline: none;
57
+ }
58
+
59
+ :where([data-control-family="card"][data-slot="link"])::after {
60
+ content: "";
61
+ position: absolute;
62
+ inset: 0;
63
+ border-radius: var(--cui-card-radius);
64
+ }
65
+
37
66
  :where([data-control-family="card"][data-slot="root"][data-size="sm"]) {
38
67
  --cui-card-padding-block: calc(var(--spacing) * 3);
39
68
  --cui-card-padding-inline: calc(var(--spacing) * 4);
@@ -81,6 +110,12 @@
81
110
  initial-value: transparent;
82
111
  }
83
112
 
113
+ @property --cui-card-hover-background {
114
+ syntax: "<color>";
115
+ inherits: true;
116
+ initial-value: transparent;
117
+ }
118
+
84
119
  @property --cui-card-border-color {
85
120
  syntax: "<color>";
86
121
  inherits: true;
@@ -3,6 +3,9 @@
3
3
  --cui-collapsible-trigger-radius: var(--radius-control);
4
4
  --cui-collapsible-trigger-hover-background: var(--hover-fill);
5
5
  --cui-collapsible-trigger-padding-inline: calc(var(--spacing) * 2);
6
+ --cui-collapsible-trigger-padding-block: 0px;
7
+ --cui-collapsible-trigger-foreground: var(--foreground);
8
+ --cui-collapsible-trigger-hover-foreground: var(--foreground);
6
9
  }
7
10
 
8
11
  :where([data-control-family="collapsible"][data-slot="trigger"]) {
@@ -12,8 +15,9 @@
12
15
  align-items: center;
13
16
  gap: calc(var(--spacing) * 2);
14
17
  border-radius: var(--cui-collapsible-trigger-radius);
18
+ padding-block: var(--cui-collapsible-trigger-padding-block);
15
19
  padding-inline: var(--cui-collapsible-trigger-padding-inline);
16
- color: var(--foreground);
20
+ color: var(--cui-collapsible-trigger-foreground);
17
21
  font-size: var(--text-label);
18
22
  font-weight: var(--font-weight-medium);
19
23
  text-align: start;
@@ -22,11 +26,13 @@
22
26
 
23
27
  :where([data-control-family="collapsible"][data-slot="trigger"]:focus-visible) {
24
28
  background: var(--cui-collapsible-trigger-hover-background);
29
+ color: var(--cui-collapsible-trigger-hover-foreground);
25
30
  }
26
31
 
27
32
  @media (hover: hover) {
28
33
  :where([data-control-family="collapsible"][data-slot="trigger"]:not(:disabled, [data-disabled]):hover) {
29
34
  background: var(--cui-collapsible-trigger-hover-background);
35
+ color: var(--cui-collapsible-trigger-hover-foreground);
30
36
  }
31
37
  }
32
38
 
@@ -86,3 +92,21 @@
86
92
  inherits: true;
87
93
  initial-value: 0px;
88
94
  }
95
+
96
+ @property --cui-collapsible-trigger-padding-block {
97
+ syntax: "<length-percentage>";
98
+ inherits: true;
99
+ initial-value: 0px;
100
+ }
101
+
102
+ @property --cui-collapsible-trigger-foreground {
103
+ syntax: "<color>";
104
+ inherits: true;
105
+ initial-value: transparent;
106
+ }
107
+
108
+ @property --cui-collapsible-trigger-hover-foreground {
109
+ syntax: "<color>";
110
+ inherits: true;
111
+ initial-value: transparent;
112
+ }
@@ -33,6 +33,11 @@
33
33
  overflow-wrap: anywhere;
34
34
  }
35
35
 
36
+ :where([data-control-family="empty"][data-slot="root"][data-variant="outline"]) {
37
+ --cui-empty-border-color: var(--border);
38
+ --cui-empty-border-style: dashed;
39
+ }
40
+
36
41
  :where([data-control-family="empty"][data-slot="media"]) {
37
42
  inline-size: var(--cui-empty-media-size);
38
43
  block-size: var(--cui-empty-media-size);
@@ -13,6 +13,10 @@
13
13
  --cui-flow-node-border-width: var(--control-rim-width);
14
14
  --cui-flow-node-radius: var(--radius-lg);
15
15
  --cui-flow-node-shadow: var(--shadow-sm);
16
+ --cui-flow-node-body-background: transparent;
17
+ --cui-flow-node-body-radius: 0px;
18
+ --cui-flow-node-body-padding-inline: calc(var(--spacing) * 3);
19
+ --cui-flow-node-body-padding-block: 0px;
16
20
  --cui-flow-handle-size: calc(var(--spacing) * 2);
17
21
  --cui-flow-handle-background: var(--background);
18
22
  --cui-flow-handle-border-color: var(--muted-foreground);
@@ -101,8 +105,11 @@
101
105
 
102
106
  :where([data-control-family="flow"][data-slot="node-body"]) {
103
107
  gap: calc(var(--spacing) * 1.5);
104
- padding-inline: calc(var(--spacing) * 3);
105
- padding-block-end: calc(var(--spacing) * 3);
108
+ margin-block-end: calc(var(--spacing) * 3);
109
+ border-radius: var(--cui-flow-node-body-radius);
110
+ background-color: var(--cui-flow-node-body-background);
111
+ padding-block: var(--cui-flow-node-body-padding-block);
112
+ padding-inline: var(--cui-flow-node-body-padding-inline);
106
113
  font-size: var(--text-caption);
107
114
  }
108
115
 
@@ -211,6 +218,30 @@
211
218
  initial-value: 0px;
212
219
  }
213
220
 
221
+ @property --cui-flow-node-body-background {
222
+ syntax: "<color>";
223
+ inherits: true;
224
+ initial-value: transparent;
225
+ }
226
+
227
+ @property --cui-flow-node-body-radius {
228
+ syntax: "<length-percentage>";
229
+ inherits: true;
230
+ initial-value: 0px;
231
+ }
232
+
233
+ @property --cui-flow-node-body-padding-inline {
234
+ syntax: "<length-percentage>";
235
+ inherits: true;
236
+ initial-value: 0px;
237
+ }
238
+
239
+ @property --cui-flow-node-body-padding-block {
240
+ syntax: "<length-percentage>";
241
+ inherits: true;
242
+ initial-value: 0px;
243
+ }
244
+
214
245
  @property --cui-flow-node-radius {
215
246
  syntax: "<length-percentage>";
216
247
  inherits: true;
@@ -2,6 +2,7 @@
2
2
  :where([data-control-family="item"][data-slot="root"]) {
3
3
  --cui-item-radius: var(--radius-lg);
4
4
  --cui-item-hover-background: var(--hover-fill);
5
+ --cui-item-current-background: var(--active-fill);
5
6
  --cui-item-hover-border-color: var(--_item-border-color);
6
7
  --cui-item-border-width: 0px;
7
8
  --cui-item-active-scale: 0.99;
@@ -65,6 +66,10 @@
65
66
  --_item-background: oklch(from var(--muted) l c h / 0.5);
66
67
  }
67
68
 
69
+ :where([data-control-family="item"][data-slot="root"][aria-current]:not([aria-current="false"])) {
70
+ --_item-background: var(--cui-item-current-background);
71
+ }
72
+
68
73
  @media (hover: hover) {
69
74
  :where(
70
75
  [data-control-family="item"][data-slot="root"]:is(a, button, [href], [role="button"]):not(
@@ -127,6 +132,12 @@
127
132
  initial-value: transparent;
128
133
  }
129
134
 
135
+ @property --cui-item-current-background {
136
+ syntax: "<color>";
137
+ inherits: true;
138
+ initial-value: transparent;
139
+ }
140
+
130
141
  @property --cui-item-hover-border-color {
131
142
  syntax: "<color>";
132
143
  inherits: true;
@@ -1,4 +1,10 @@
1
1
  @layer components {
2
+ :where([data-control-family="popup"][data-popup-part="item"][data-tone="danger"]) {
3
+ --cui-popup-item-foreground: var(--destructive-text);
4
+ --cui-popup-item-highlight-background: oklch(from var(--destructive-text) l c h / 0.12);
5
+ --cui-popup-item-highlight-foreground: var(--destructive-text);
6
+ }
7
+
2
8
  :where([data-control-family="popup"][data-popup-kind="dialog"][data-slot="title"]),
3
9
  :where([data-control-family="popup"][data-popup-kind="alert-dialog"][data-slot="title"]),
4
10
  :where([data-control-family="popup"][data-popup-kind="sheet"][data-slot="title"]),
@@ -112,6 +118,32 @@
112
118
  padding: calc(var(--spacing) * 4);
113
119
  }
114
120
 
121
+ :where([data-control-family="popup"][data-popup-kind="sheet"][data-slot="content"]:has(> [data-slot="body"])) {
122
+ gap: 0;
123
+ }
124
+
125
+ :where([data-control-family="popup"][data-popup-kind="sheet"][data-slot="body"]) {
126
+ gap: calc(var(--spacing) * 4);
127
+ overscroll-behavior: contain;
128
+ }
129
+
130
+ :where([data-control-family="popup"][data-popup-kind="sheet"][data-slot="body"][data-padding="default"]) {
131
+ padding: calc(var(--spacing) * 4);
132
+ }
133
+
134
+ :where([data-control-family="popup"][data-popup-kind="sheet"][data-slot="footer"]) {
135
+ gap: calc(var(--spacing) * 2);
136
+ padding: calc(var(--spacing) * 4);
137
+ }
138
+
139
+ :where([data-control-family="popup"][data-popup-kind="sheet"][data-slot="header"]:has(+ [data-slot="body"])) {
140
+ border-block-end: 1px solid var(--cui-popup-separator-color);
141
+ }
142
+
143
+ :where([data-control-family="popup"][data-popup-kind="sheet"][data-slot="body"] + [data-slot="footer"]) {
144
+ border-block-start: 1px solid var(--cui-popup-separator-color);
145
+ }
146
+
115
147
  :where([data-control-family="popup"][data-popup-kind="popover"][data-slot="header"]) {
116
148
  gap: calc(var(--spacing) * 1.5);
117
149
  padding-block-end: calc(var(--spacing) * 3);
@@ -122,6 +154,18 @@
122
154
  padding: calc(var(--spacing) * 4);
123
155
  }
124
156
 
157
+ :where([data-control-family="popup"][data-popup-kind="popover"][data-popup-part="surface"][data-padding="sm"]) {
158
+ padding: calc(var(--spacing) * 2);
159
+ }
160
+
161
+ :where([data-control-family="popup"][data-popup-kind="popover"][data-padding="none"] > [data-slot="header"]) {
162
+ padding: calc(var(--spacing) * 3) calc(var(--spacing) * 4);
163
+ }
164
+
165
+ :where([data-control-family="popup"][data-popup-kind="popover"][data-padding="none"] > [data-slot="header"]:not(:last-child)) {
166
+ border-block-end: 1px solid var(--cui-popup-separator-color);
167
+ }
168
+
125
169
  :where([data-control-family="popup"][data-popup-kind="hover-card"][data-slot="trigger"]:is(a)) {
126
170
  border-radius: var(--radius-sm);
127
171
  color: var(--foreground);
@@ -15,6 +15,14 @@
15
15
  background-image: var(--cui-skeleton-background-image);
16
16
  }
17
17
 
18
+ :where([data-control-family="skeleton"][data-slot="root"][data-shape="circle"]) {
19
+ --cui-skeleton-radius: 9999px;
20
+ }
21
+
22
+ :where([data-control-family="skeleton"][data-slot="root"][data-shape="panel"]) {
23
+ --cui-skeleton-radius: var(--radius-panel);
24
+ }
25
+
18
26
  :where([data-control-family="skeleton"][data-slot="root"][data-variant="shimmer"]) {
19
27
  --cui-skeleton-easing: linear;
20
28
  }
@@ -4,6 +4,7 @@
4
4
  display: flex;
5
5
  flex-direction: column;
6
6
  --cui-tabs-trigger-radius: var(--radius-control);
7
+ --cui-tabs-trigger-padding-inline: calc(var(--spacing) * 3.5);
7
8
  --cui-tabs-list-padding: calc(var(--spacing) * 1);
8
9
  --cui-tabs-list-radius: calc(
9
10
  var(--cui-tabs-trigger-radius) +
@@ -104,7 +105,7 @@
104
105
  gap: calc(var(--spacing) * 1.5);
105
106
  white-space: nowrap;
106
107
  border-radius: var(--_tabs-trigger-radius-fit);
107
- padding-inline: calc(var(--spacing) * 3.5);
108
+ padding-inline: var(--cui-tabs-trigger-padding-inline);
108
109
  color: var(--cui-tabs-foreground);
109
110
  font-size: var(--cui-tabs-font-size);
110
111
  font-weight: var(--cui-tabs-font-weight);
@@ -278,6 +279,12 @@
278
279
  initial-value: 0px;
279
280
  }
280
281
 
282
+ @property --cui-tabs-trigger-padding-inline {
283
+ syntax: "<length-percentage>";
284
+ inherits: true;
285
+ initial-value: 0px;
286
+ }
287
+
281
288
  @property --cui-tabs-trigger-radius {
282
289
  syntax: "<length-percentage>";
283
290
  inherits: true;
@@ -1,5 +1,7 @@
1
1
  //#region src/surface-variants.d.ts
2
2
  export declare const popupItemStructureClasses = "flex select-none items-center";
3
+ export declare const popupItemTones: readonly ["neutral", "danger"];
4
+ export type PopupItemTone = (typeof popupItemTones)[number];
3
5
  export declare const popupParts: readonly ["backdrop", "surface", "list-surface", "list-content", "bar", "item", "navigation-link", "label", "separator", "shortcut"];
4
6
  export type PopupPart = (typeof popupParts)[number];
5
7
  //#endregion
@@ -1,5 +1,6 @@
1
1
  //#region src/surface-variants.ts
2
2
  const popupItemStructureClasses = "flex select-none items-center";
3
+ const popupItemTones = ["neutral", "danger"];
3
4
  const popupParts = [
4
5
  "backdrop",
5
6
  "surface",
@@ -13,4 +14,4 @@ const popupParts = [
13
14
  "shortcut"
14
15
  ];
15
16
  //#endregion
16
- export { popupItemStructureClasses, popupParts };
17
+ export { popupItemStructureClasses, popupItemTones, popupParts };
@@ -16,7 +16,11 @@ export type AlertTitleProps = Omit<ComponentProps<"div">, "style"> & {
16
16
  export type AlertDescriptionProps = Omit<ComponentProps<"div">, "style"> & {
17
17
  style?: CSSProperties & AlertKnobStyle;
18
18
  };
19
+ export type AlertActionProps = Omit<ComponentProps<"div">, "style"> & {
20
+ style?: CSSProperties & AlertKnobStyle;
21
+ };
19
22
  export declare function Alert({ variant, className, ...props }: AlertProps): import("react").JSX.Element;
20
23
  export declare function AlertTitle({ render, className, ...props }: AlertTitleProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
21
24
  export declare function AlertDescription({ className, ...props }: AlertDescriptionProps): import("react").JSX.Element;
25
+ export declare function AlertAction({ className, ...props }: AlertActionProps): import("react").JSX.Element;
22
26
  //#endregion
package/dist/ui/alert.js CHANGED
@@ -38,5 +38,14 @@ function AlertDescription({ className, ...props }) {
38
38
  ...props
39
39
  });
40
40
  }
41
+ function AlertAction({ className, ...props }) {
42
+ return /* @__PURE__ */ jsx("div", {
43
+ "data-control-ui": "alert",
44
+ "data-control-family": "alert",
45
+ "data-slot": "action",
46
+ className: cn("col-start-3 row-span-2 row-start-1 flex items-center gap-1 self-start", className),
47
+ ...props
48
+ });
49
+ }
41
50
  //#endregion
42
- export { Alert, AlertDescription, AlertTitle, alertVariants };
51
+ export { Alert, AlertAction, AlertDescription, AlertTitle, alertVariants };
@@ -1,9 +1,8 @@
1
1
  import { RenderProp } from "../control-props.js";
2
- import { ControlSize, ControlTone, ControlVariant } from "../control-variants.js";
2
+ import { ButtonVariant, ControlSize, ControlTone } from "../control-variants.js";
3
3
  import { ButtonKnobStyle } from "../knob-contracts/button-knobs.js";
4
4
  import { CSSProperties, ComponentProps } from "react";
5
5
  //#region src/ui/button.d.ts
6
- export type ButtonVariant = ControlVariant;
7
6
  export type ButtonSize = ControlSize;
8
7
  export type ButtonTone = ControlTone;
9
8
  export declare const ButtonTrackContext: import("react").Context<boolean>;
@@ -38,4 +37,5 @@ export declare const buttonContentClasses = "relative z-[1] inline-flex min-w-0
38
37
  export declare function Button({ variant, size, tone, active, iconOnly, shape, layout, type, disabled, render, nativeButton, className, children, ...props }: ButtonProps): import("react").JSX.Element;
39
38
  export declare function ButtonLink({ variant, size, tone, active, iconOnly, shape, layout, render, className, children, ...props }: ButtonLinkProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
40
39
  export declare function ButtonLabel({ variant, size, tone, active, iconOnly, shape, layout, className, children, ...props }: ButtonLabelProps): import("react").JSX.Element;
41
- //#endregion
40
+ //#endregion
41
+ export type { ButtonVariant };
package/dist/ui/card.d.ts CHANGED
@@ -29,6 +29,10 @@ export type CardContentProps = ComponentProps<"div"> & {
29
29
  export type CardFooterProps = ComponentProps<"div"> & {
30
30
  style?: CSSProperties & CardKnobStyle;
31
31
  };
32
+ export type CardLinkProps = Omit<ComponentProps<"button">, "style"> & {
33
+ render?: RenderProp<ComponentProps<"button">>;
34
+ style?: CSSProperties & CardKnobStyle;
35
+ };
32
36
  export declare function Card({ variant, size, className, ...props }: CardProps): import("react").JSX.Element;
33
37
  export declare function CardHeader({ className, ...props }: CardHeaderProps): import("react").JSX.Element;
34
38
  export declare function CardTitle({ render, ...props }: CardTitleProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
@@ -36,4 +40,5 @@ export declare function CardDescription({ className, ...props }: CardDescription
36
40
  export declare function CardAction({ className, ...props }: CardActionProps): import("react").JSX.Element;
37
41
  export declare function CardContent({ className, ...props }: CardContentProps): import("react").JSX.Element;
38
42
  export declare function CardFooter({ className, ...props }: CardFooterProps): import("react").JSX.Element;
43
+ export declare function CardLink({ render, ...props }: CardLinkProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
39
44
  //#endregion
package/dist/ui/card.js CHANGED
@@ -72,5 +72,19 @@ function CardFooter({ className, ...props }) {
72
72
  ...props
73
73
  });
74
74
  }
75
+ function CardLink({ render, ...props }) {
76
+ return useRender({
77
+ defaultTagName: "button",
78
+ render,
79
+ props: {
80
+ type: render ? void 0 : "button",
81
+ ...props,
82
+ "data-control-ui": "card",
83
+ "data-control-family": "card",
84
+ "data-slot": "link",
85
+ "data-focus-ring": "none"
86
+ }
87
+ });
88
+ }
75
89
  //#endregion
76
- export { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };
90
+ export { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardLink, CardTitle };
@@ -1,6 +1,7 @@
1
1
  import { ControlSize } from "../control-variants.js";
2
2
  import { FieldKnobStyle } from "../knob-contracts/field-knobs.js";
3
3
  import { PopupKnobStyle } from "../knob-contracts/popup-knobs.js";
4
+ import { InputGroupProps } from "./input-group.js";
4
5
  import { CSSProperties, ComponentProps, ReactNode } from "react";
5
6
  import { Combobox as Combobox$1 } from "@base-ui/react/combobox";
6
7
  //#region src/ui/combobox.d.ts
@@ -12,6 +13,7 @@ export type ComboboxInputProps = Omit<Omit<ComponentProps<"input">, "size">, "st
12
13
  } & {
13
14
  size?: ControlSize;
14
15
  };
16
+ export type ComboboxInputGroupProps = Omit<InputGroupProps, "render">;
15
17
  export type ComboboxTriggerProps = ComponentProps<"button"> & {
16
18
  style?: CSSProperties & FieldKnobStyle;
17
19
  };
@@ -43,6 +45,7 @@ export type ComboboxGroupLabelProps = Omit<ComponentProps<"div">, "style"> & {
43
45
  };
44
46
  export declare function Combobox<Value = string, Multiple extends boolean | undefined = false>({ children, onValueChange, autoHighlight, ...props }: ComboboxProps<Value, Multiple>): import("react").JSX.Element;
45
47
  export declare function ComboboxTrigger({ className, children, ...props }: ComboboxTriggerProps): import("react").JSX.Element;
48
+ export declare function ComboboxInputGroup(props: ComboboxInputGroupProps): import("react").JSX.Element;
46
49
  export declare function ComboboxInput({ size, className, ...props }: ComboboxInputProps): import("react").JSX.Element;
47
50
  export declare function ComboboxContent({ className, children, sideOffset, anchor, ...props }: ComboboxContentProps): import("react").JSX.Element;
48
51
  export declare function ComboboxList<Value = unknown>({ className, children, ...props }: ComboboxListProps<Value>): import("react").JSX.Element;
@@ -4,9 +4,10 @@ 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";
7
+ import { InputGroup, InputGroupAddon, useIsInsideInputGroup } from "./input-group.js";
7
8
  import { shouldAcceptComboboxValueChange } from "./combobox-disabled-selection.js";
8
9
  import { createContext, use, useEffect, useState } from "react";
9
- import { jsx, jsxs } from "react/jsx-runtime";
10
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
10
11
  import { Combobox as Combobox$1 } from "@base-ui/react/combobox";
11
12
  //#region src/ui/combobox.tsx
12
13
  const ComboboxDisabledValueContext = createContext(null);
@@ -66,7 +67,21 @@ function ComboboxTrigger({ className, children, ...props }) {
66
67
  })
67
68
  });
68
69
  }
70
+ function ComboboxInputGroup(props) {
71
+ return /* @__PURE__ */ jsx(InputGroup, {
72
+ ...props,
73
+ render: /* @__PURE__ */ jsx(Combobox$1.InputGroup, {})
74
+ });
75
+ }
69
76
  function ComboboxInput({ size = "md", className, ...props }) {
77
+ if (useIsInsideInputGroup()) return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Combobox$1.Input, {
78
+ ...props,
79
+ "data-control-ui": "input-group",
80
+ "data-control-family": "field",
81
+ "data-field-kind": "input-group",
82
+ "data-slot": "input",
83
+ className: cn("h-full min-w-0 flex-1", className)
84
+ }), /* @__PURE__ */ jsx(InputGroupAddon, { children: /* @__PURE__ */ jsx(ComboboxTrigger, {}) })] });
70
85
  return /* @__PURE__ */ jsxs(Combobox$1.InputGroup, {
71
86
  "data-control-ui": "combobox",
72
87
  "data-control-family": "field",
@@ -213,4 +228,4 @@ function ComboboxGroupLabel({ className, children, ...props }) {
213
228
  });
214
229
  }
215
230
  //#endregion
216
- export { Combobox, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxGroupLabel, ComboboxInput, ComboboxItem, ComboboxList, ComboboxTrigger };
231
+ export { Combobox, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxGroupLabel, ComboboxInput, ComboboxInputGroup, ComboboxItem, ComboboxList, ComboboxTrigger };
@@ -1,5 +1,6 @@
1
1
  import { ControlledChoice, OpenChangeEventDetails } from "../control-props.js";
2
2
  import { PopupKnobStyle } from "../knob-contracts/popup-knobs.js";
3
+ import { PopupItemTone } from "../surface-variants.js";
3
4
  import { CSSProperties, ComponentProps, MouseEvent, ReactNode } from "react";
4
5
  import { ContextMenu as ContextMenu$1 } from "@base-ui/react/context-menu";
5
6
  //#region src/ui/context-menu.d.ts
@@ -23,6 +24,7 @@ export type ContextMenuItemProps = Omit<Omit<ComponentProps<"div">, "onClick">,
23
24
  } & {
24
25
  disabled?: boolean;
25
26
  inset?: boolean;
27
+ tone?: PopupItemTone;
26
28
  onClick?: (event: MouseEvent) => void;
27
29
  };
28
30
  export type ContextMenuCheckboxItemProps = Omit<Omit<ComponentProps<"div">, "onClick">, "style"> & {
@@ -72,7 +74,7 @@ export declare function ContextMenuTrigger({ className, ...props }: ContextMenuT
72
74
  export declare function ContextMenuPortal(props: ComponentProps<typeof ContextMenu$1.Portal>): import("react").JSX.Element;
73
75
  export declare function ContextMenuGroup({ className, ...props }: ContextMenuGroupProps): import("react").JSX.Element;
74
76
  export declare function ContextMenuContent({ className, children, ...props }: ContextMenuContentProps): import("react").JSX.Element;
75
- export declare function ContextMenuItem({ className, inset, ...props }: ContextMenuItemProps): import("react").JSX.Element;
77
+ export declare function ContextMenuItem({ className, inset, tone, ...props }: ContextMenuItemProps): import("react").JSX.Element;
76
78
  export declare function ContextMenuCheckboxItem({ className, children, ...props }: ContextMenuCheckboxItemProps): import("react").JSX.Element;
77
79
  export declare function ContextMenuRadioGroup<TValue extends string = string>({ className, ...props }: ContextMenuRadioGroupProps<TValue>): import("react").JSX.Element;
78
80
  export declare function ContextMenuRadioItem({ className, children, value, ...props }: ContextMenuRadioItemProps): import("react").JSX.Element;
@@ -56,13 +56,14 @@ function ContextMenuContent({ className, children, ...props }) {
56
56
  })
57
57
  }) });
58
58
  }
59
- function ContextMenuItem({ className, inset = false, ...props }) {
59
+ function ContextMenuItem({ className, inset = false, tone = "neutral", ...props }) {
60
60
  return /* @__PURE__ */ jsx(ContextMenu$1.Item, {
61
61
  "data-control-ui": "context-menu",
62
62
  "data-popup-kind": "context-menu",
63
63
  "data-slot": "item",
64
64
  "data-control-family": "popup",
65
65
  "data-popup-part": "item",
66
+ "data-tone": tone,
66
67
  "data-inset": inset || void 0,
67
68
  className: cn(itemClasses, className),
68
69
  ...mergeProps(popupItemFocusProps, props)
@@ -1,6 +1,7 @@
1
1
  import { ControlSize } from "../control-variants.js";
2
2
  import { ButtonKnobStyle } from "../knob-contracts/button-knobs.js";
3
3
  import { PopupKnobStyle } from "../knob-contracts/popup-knobs.js";
4
+ import { PopupItemTone } from "../surface-variants.js";
4
5
  import { CSSProperties, ComponentProps } from "react";
5
6
  import { Menu } from "@base-ui/react/menu";
6
7
  //#region src/ui/dropdown-menu.d.ts
@@ -19,7 +20,9 @@ export type DropdownMenuTriggerProps = Omit<ComponentProps<"button">, "style"> &
19
20
  variant?: DropdownMenuTriggerVariant;
20
21
  };
21
22
  export type DropdownMenuContentProps = DropdownMenuStyledProps<Menu.Popup.Props> & Pick<Menu.Positioner.Props, "side" | "sideOffset" | "align" | "alignOffset" | "collisionBoundary" | "collisionPadding" | "collisionAvoidance">;
22
- export type DropdownMenuItemProps = DropdownMenuStyledProps<Menu.Item.Props>;
23
+ export type DropdownMenuItemProps = DropdownMenuStyledProps<Menu.Item.Props> & {
24
+ tone?: PopupItemTone;
25
+ };
23
26
  export type DropdownMenuGroupProps = DropdownMenuStyledProps<Menu.Group.Props>;
24
27
  export type DropdownMenuCheckboxItemProps = DropdownMenuStyledProps<Menu.CheckboxItem.Props>;
25
28
  export type DropdownMenuRadioGroupProps = DropdownMenuStyledProps<Menu.RadioGroup.Props>;
@@ -37,7 +40,7 @@ export type DropdownMenuLabelProps = Omit<ComponentProps<"div">, "style"> & {
37
40
  export declare function DropdownMenu({ children, ...props }: DropdownMenuProps): import("react").JSX.Element;
38
41
  export declare function DropdownMenuTrigger({ size, iconOnly, variant, className, ...props }: DropdownMenuTriggerProps): import("react").JSX.Element;
39
42
  export declare function DropdownMenuContent({ className, children, side, sideOffset, align, alignOffset, collisionBoundary, collisionPadding, collisionAvoidance, ...props }: DropdownMenuContentProps): import("react").JSX.Element;
40
- export declare function DropdownMenuItem({ className, ...props }: DropdownMenuItemProps): import("react").JSX.Element;
43
+ export declare function DropdownMenuItem({ tone, className, ...props }: DropdownMenuItemProps): import("react").JSX.Element;
41
44
  export declare function DropdownMenuSeparator({ className, ...props }: DropdownMenuSeparatorProps): import("react").JSX.Element;
42
45
  export declare function DropdownMenuLabel({ className, ...props }: DropdownMenuLabelProps): import("react").JSX.Element;
43
46
  export declare function DropdownMenuPortal(props: Menu.Portal.Props): import("react").JSX.Element;
@@ -74,12 +74,13 @@ function DropdownMenuContent({ className, children, side, sideOffset = 6, align
74
74
  })
75
75
  }) });
76
76
  }
77
- function DropdownMenuItem({ className, ...props }) {
77
+ function DropdownMenuItem({ tone = "neutral", className, ...props }) {
78
78
  return /* @__PURE__ */ jsx(Menu.Item, {
79
79
  "data-control-ui": "dropdown-menu",
80
80
  "data-slot": "item",
81
81
  "data-control-family": "popup",
82
82
  "data-popup-part": "item",
83
+ "data-tone": tone,
83
84
  className: cn(popupItemStructureClasses, className),
84
85
  ...mergeProps(popupItemFocusProps, props)
85
86
  });
@@ -2,8 +2,11 @@ import { RenderProp } from "../control-props.js";
2
2
  import { EmptyKnobStyle } from "../knob-contracts/empty-knobs.js";
3
3
  import { CSSProperties, ComponentProps } from "react";
4
4
  //#region src/ui/empty.d.ts
5
+ export declare const emptyVariants: readonly ["default", "outline"];
6
+ export type EmptyVariant = (typeof emptyVariants)[number];
5
7
  export type EmptyProps = Omit<ComponentProps<"div">, "style"> & {
6
8
  style?: CSSProperties & EmptyKnobStyle;
9
+ variant?: EmptyVariant;
7
10
  };
8
11
  export type EmptyHeaderProps = Omit<ComponentProps<"div">, "style"> & {
9
12
  style?: CSSProperties & EmptyKnobStyle;
@@ -21,7 +24,7 @@ export type EmptyTitleProps = Omit<ComponentProps<"div">, "style"> & {
21
24
  render?: RenderProp<ComponentProps<"div">>;
22
25
  style?: CSSProperties & EmptyKnobStyle;
23
26
  };
24
- export declare function Empty({ className, ...props }: EmptyProps): import("react").JSX.Element;
27
+ export declare function Empty({ variant, className, ...props }: EmptyProps): import("react").JSX.Element;
25
28
  export declare function EmptyHeader({ className, ...props }: EmptyHeaderProps): import("react").JSX.Element;
26
29
  export declare function EmptyMedia({ className, ...props }: EmptyMediaProps): import("react").JSX.Element;
27
30
  export declare function EmptyTitle({ render, ...props }: EmptyTitleProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
package/dist/ui/empty.js CHANGED
@@ -3,11 +3,13 @@ import { cn } from "../lib/cn.js";
3
3
  import { useRender } from "@base-ui/react/use-render";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  //#region src/ui/empty.tsx
6
- function Empty({ className, ...props }) {
6
+ const emptyVariants = ["default", "outline"];
7
+ function Empty({ variant = "default", className, ...props }) {
7
8
  return /* @__PURE__ */ jsx("div", {
8
9
  "data-control-ui": "empty",
9
10
  "data-control-family": "empty",
10
11
  "data-slot": "root",
12
+ "data-variant": variant,
11
13
  className: cn("flex min-w-0 flex-1 flex-col items-center justify-center", className),
12
14
  ...props
13
15
  });
@@ -61,4 +63,4 @@ function EmptyContent({ className, ...props }) {
61
63
  });
62
64
  }
63
65
  //#endregion
64
- export { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle };
66
+ export { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, emptyVariants };
@@ -1,6 +1,7 @@
1
1
  import { OpenChangeEventDetails } from "../control-props.js";
2
2
  import { ButtonKnobStyle } from "../knob-contracts/button-knobs.js";
3
3
  import { PopupKnobStyle } from "../knob-contracts/popup-knobs.js";
4
+ import { PopupItemTone } from "../surface-variants.js";
4
5
  import { CSSProperties, ComponentProps, MouseEvent, ReactNode } from "react";
5
6
  //#region src/ui/menubar.d.ts
6
7
  export type MenubarProps = Omit<ComponentProps<"div">, "style"> & {
@@ -30,6 +31,7 @@ export type MenubarItemProps = Omit<Omit<ComponentProps<"div">, "onClick">, "sty
30
31
  style?: CSSProperties & PopupKnobStyle;
31
32
  } & {
32
33
  disabled?: boolean;
34
+ tone?: PopupItemTone;
33
35
  onClick?: (event: MouseEvent) => void;
34
36
  };
35
37
  export type MenubarSeparatorProps = Omit<ComponentProps<"div">, "style"> & {
@@ -63,7 +65,7 @@ export declare function MenubarMenu(props: MenubarMenuProps): import("react").JS
63
65
  export declare function MenubarTrigger({ className, ...props }: MenubarTriggerProps): import("react").JSX.Element;
64
66
  export declare function MenubarContent({ className, children, ...props }: MenubarContentProps): import("react").JSX.Element;
65
67
  export declare function MenubarGroup({ className, ...props }: MenubarGroupProps): import("react").JSX.Element;
66
- export declare function MenubarItem({ className, ...props }: MenubarItemProps): import("react").JSX.Element;
68
+ export declare function MenubarItem({ tone, className, ...props }: MenubarItemProps): import("react").JSX.Element;
67
69
  export declare function MenubarLabel({ className, inset, ...props }: MenubarLabelProps): import("react").JSX.Element;
68
70
  export declare function MenubarSeparator({ className, ...props }: MenubarSeparatorProps): import("react").JSX.Element;
69
71
  export declare function MenubarShortcut({ className, ...props }: MenubarShortcutProps): import("react").JSX.Element;
@@ -69,13 +69,14 @@ function MenubarGroup({ className, ...props }) {
69
69
  ...props
70
70
  });
71
71
  }
72
- function MenubarItem({ className, ...props }) {
72
+ function MenubarItem({ tone = "neutral", className, ...props }) {
73
73
  return /* @__PURE__ */ jsx(Menu.Item, {
74
74
  "data-control-ui": "menubar",
75
75
  "data-popup-kind": "menubar",
76
76
  "data-slot": "item",
77
77
  "data-control-family": "popup",
78
78
  "data-popup-part": "item",
79
+ "data-tone": tone,
79
80
  className: cn(itemClasses, className),
80
81
  ...props
81
82
  });
@@ -2,7 +2,7 @@ import { PopupKnobStyle } from "../knob-contracts/popup-knobs.js";
2
2
  import { CSSProperties, ComponentProps } from "react";
3
3
  import { Popover as Popover$1 } from "@base-ui/react/popover";
4
4
  //#region src/ui/popover.d.ts
5
- export declare const popoverContentPaddings: readonly ["default", "none"];
5
+ export declare const popoverContentPaddings: readonly ["default", "sm", "none"];
6
6
  export type PopoverContentPadding = (typeof popoverContentPaddings)[number];
7
7
  type PopoverPopupProps = Omit<ComponentProps<typeof Popover$1.Popup>, "style"> & {
8
8
  side?: ComponentProps<typeof Popover$1.Positioner>["side"];
@@ -6,7 +6,11 @@ import { useImperativeHandle, useLayoutEffect, useRef } from "react";
6
6
  import { jsx } from "react/jsx-runtime";
7
7
  import { Popover as Popover$1 } from "@base-ui/react/popover";
8
8
  //#region src/ui/popover.tsx
9
- const popoverContentPaddings = ["default", "none"];
9
+ const popoverContentPaddings = [
10
+ "default",
11
+ "sm",
12
+ "none"
13
+ ];
10
14
  function Popover(props) {
11
15
  return /* @__PURE__ */ jsx(Popover$1.Root, { ...props });
12
16
  }
@@ -2,6 +2,8 @@ import { PopupKnobStyle } from "../knob-contracts/popup-knobs.js";
2
2
  import { CSSProperties, ComponentProps } from "react";
3
3
  import { Dialog } from "@base-ui/react/dialog";
4
4
  //#region src/ui/sheet.d.ts
5
+ export declare const sheetBodyPaddings: readonly ["default", "none"];
6
+ export type SheetBodyPadding = (typeof sheetBodyPaddings)[number];
5
7
  export declare function Sheet(props: ComponentProps<typeof Dialog.Root>): import("react").JSX.Element;
6
8
  export declare function SheetClose({ className, ...props }: ComponentProps<typeof Dialog.Close> & {
7
9
  style?: CSSProperties & PopupKnobStyle;
@@ -15,6 +17,13 @@ export declare function SheetContent({ className, children, side, ...props }: Sh
15
17
  export declare function SheetHeader({ className, ...props }: ComponentProps<"div"> & {
16
18
  style?: CSSProperties & PopupKnobStyle;
17
19
  }): import("react").JSX.Element;
20
+ export declare function SheetBody({ padding, className, ...props }: ComponentProps<"div"> & {
21
+ padding?: SheetBodyPadding;
22
+ style?: CSSProperties & PopupKnobStyle;
23
+ }): import("react").JSX.Element;
24
+ export declare function SheetFooter({ className, ...props }: ComponentProps<"div"> & {
25
+ style?: CSSProperties & PopupKnobStyle;
26
+ }): import("react").JSX.Element;
18
27
  export declare function SheetTitle({ className, ...props }: ComponentProps<typeof Dialog.Title> & {
19
28
  style?: CSSProperties & PopupKnobStyle;
20
29
  }): import("react").JSX.Element;
package/dist/ui/sheet.js CHANGED
@@ -5,6 +5,7 @@ import { useSkin } from "../skin-provider.js";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
6
  import { Dialog } from "@base-ui/react/dialog";
7
7
  //#region src/ui/sheet.tsx
8
+ const sheetBodyPaddings = ["default", "none"];
8
9
  function Sheet(props) {
9
10
  return /* @__PURE__ */ jsx(Dialog.Root, { ...props });
10
11
  }
@@ -54,6 +55,27 @@ function SheetHeader({ className, ...props }) {
54
55
  ...props
55
56
  });
56
57
  }
58
+ function SheetBody({ padding = "default", className, ...props }) {
59
+ return /* @__PURE__ */ jsx("div", {
60
+ "data-control-ui": "sheet",
61
+ "data-control-family": "popup",
62
+ "data-popup-kind": "sheet",
63
+ "data-slot": "body",
64
+ "data-padding": padding,
65
+ className: cn("flex min-h-0 flex-1 flex-col overflow-y-auto", className),
66
+ ...props
67
+ });
68
+ }
69
+ function SheetFooter({ className, ...props }) {
70
+ return /* @__PURE__ */ jsx("div", {
71
+ "data-control-ui": "sheet",
72
+ "data-control-family": "popup",
73
+ "data-popup-kind": "sheet",
74
+ "data-slot": "footer",
75
+ className: cn("mt-auto flex shrink-0 flex-col sm:flex-row sm:justify-end", className),
76
+ ...props
77
+ });
78
+ }
57
79
  function SheetTitle({ className, ...props }) {
58
80
  return /* @__PURE__ */ jsx(Dialog.Title, {
59
81
  "data-control-ui": "sheet",
@@ -75,4 +97,4 @@ function SheetDescription({ className, ...props }) {
75
97
  });
76
98
  }
77
99
  //#endregion
78
- export { Sheet, SheetClose, SheetContent, SheetDescription, SheetHeader, SheetTitle };
100
+ export { Sheet, SheetBody, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, sheetBodyPaddings };
@@ -3,9 +3,12 @@ import { CSSProperties, ComponentProps } from "react";
3
3
  //#region src/ui/skeleton.d.ts
4
4
  export declare const skeletonVariants: readonly ["shimmer", "pulse", "none"];
5
5
  export type SkeletonVariant = (typeof skeletonVariants)[number];
6
+ export declare const skeletonShapes: readonly ["default", "circle", "panel"];
7
+ export type SkeletonShape = (typeof skeletonShapes)[number];
6
8
  export type SkeletonProps = Omit<ComponentProps<"div">, "style"> & {
7
9
  style?: CSSProperties & SkeletonKnobStyle;
8
10
  variant?: SkeletonVariant;
11
+ shape?: SkeletonShape;
9
12
  };
10
- export declare function Skeleton({ variant, className, ...props }: SkeletonProps): import("react").JSX.Element;
13
+ export declare function Skeleton({ variant, shape, className, ...props }: SkeletonProps): import("react").JSX.Element;
11
14
  //#endregion
@@ -5,16 +5,22 @@ const skeletonVariants = [
5
5
  "pulse",
6
6
  "none"
7
7
  ];
8
- function Skeleton({ variant = "shimmer", className, ...props }) {
8
+ const skeletonShapes = [
9
+ "default",
10
+ "circle",
11
+ "panel"
12
+ ];
13
+ function Skeleton({ variant = "shimmer", shape = "default", className, ...props }) {
9
14
  return /* @__PURE__ */ jsx("div", {
10
15
  "aria-hidden": "true",
11
16
  "data-control-ui": "skeleton",
12
17
  "data-control-family": "skeleton",
13
18
  "data-slot": "root",
14
19
  "data-variant": variant,
20
+ "data-shape": shape,
15
21
  className,
16
22
  ...props
17
23
  });
18
24
  }
19
25
  //#endregion
20
- export { Skeleton, skeletonVariants };
26
+ export { Skeleton, skeletonShapes, skeletonVariants };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ctrl-ui/react",
3
- "version": "0.9.8",
3
+ "version": "0.9.10",
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",