@ctrl-ui/react 0.9.9 → 0.9.11

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 (35) 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 +5 -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/tabs-knobs.d.ts +1 -1
  15. package/dist/knob-contracts/tabs-knobs.js +1 -0
  16. package/dist/skin.d.ts +2 -2
  17. package/dist/styles/recipes/alert.css +12 -0
  18. package/dist/styles/recipes/badge.css +7 -0
  19. package/dist/styles/recipes/button-states.css +6 -0
  20. package/dist/styles/recipes/button.css +21 -0
  21. package/dist/styles/recipes/card.css +35 -0
  22. package/dist/styles/recipes/collapsible.css +33 -2
  23. package/dist/styles/recipes/flow.css +33 -2
  24. package/dist/styles/recipes/popup-controls.css +12 -0
  25. package/dist/styles/recipes/tabs.css +8 -1
  26. package/dist/ui/alert.d.ts +4 -0
  27. package/dist/ui/alert.js +10 -1
  28. package/dist/ui/button.d.ts +3 -3
  29. package/dist/ui/card.d.ts +5 -0
  30. package/dist/ui/card.js +15 -1
  31. package/dist/ui/combobox.d.ts +3 -0
  32. package/dist/ui/combobox.js +17 -2
  33. package/dist/ui/popover.d.ts +1 -1
  34. package/dist/ui/popover.js +5 -1
  35. 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-font-size", "--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,11 @@
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-font-size",
8
+ "--cui-collapsible-trigger-foreground",
9
+ "--cui-collapsible-trigger-hover-foreground"
6
10
  ];
7
11
  //#endregion
8
12
  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/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,10 @@
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);
9
+ --cui-collapsible-trigger-font-size: var(--text-label);
6
10
  }
7
11
 
8
12
  :where([data-control-family="collapsible"][data-slot="trigger"]) {
@@ -12,9 +16,10 @@
12
16
  align-items: center;
13
17
  gap: calc(var(--spacing) * 2);
14
18
  border-radius: var(--cui-collapsible-trigger-radius);
19
+ padding-block: var(--cui-collapsible-trigger-padding-block);
15
20
  padding-inline: var(--cui-collapsible-trigger-padding-inline);
16
- color: var(--foreground);
17
- font-size: var(--text-label);
21
+ color: var(--cui-collapsible-trigger-foreground);
22
+ font-size: var(--cui-collapsible-trigger-font-size);
18
23
  font-weight: var(--font-weight-medium);
19
24
  text-align: start;
20
25
  transition: background-color var(--duration-fast) var(--ease-standard);
@@ -22,11 +27,13 @@
22
27
 
23
28
  :where([data-control-family="collapsible"][data-slot="trigger"]:focus-visible) {
24
29
  background: var(--cui-collapsible-trigger-hover-background);
30
+ color: var(--cui-collapsible-trigger-hover-foreground);
25
31
  }
26
32
 
27
33
  @media (hover: hover) {
28
34
  :where([data-control-family="collapsible"][data-slot="trigger"]:not(:disabled, [data-disabled]):hover) {
29
35
  background: var(--cui-collapsible-trigger-hover-background);
36
+ color: var(--cui-collapsible-trigger-hover-foreground);
30
37
  }
31
38
  }
32
39
 
@@ -86,3 +93,27 @@
86
93
  inherits: true;
87
94
  initial-value: 0px;
88
95
  }
96
+
97
+ @property --cui-collapsible-trigger-padding-block {
98
+ syntax: "<length-percentage>";
99
+ inherits: true;
100
+ initial-value: 0px;
101
+ }
102
+
103
+ @property --cui-collapsible-trigger-font-size {
104
+ syntax: "<length-percentage>";
105
+ inherits: true;
106
+ initial-value: 0px;
107
+ }
108
+
109
+ @property --cui-collapsible-trigger-foreground {
110
+ syntax: "<color>";
111
+ inherits: true;
112
+ initial-value: transparent;
113
+ }
114
+
115
+ @property --cui-collapsible-trigger-hover-foreground {
116
+ syntax: "<color>";
117
+ inherits: true;
118
+ initial-value: transparent;
119
+ }
@@ -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;
@@ -154,6 +154,18 @@
154
154
  padding: calc(var(--spacing) * 4);
155
155
  }
156
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
+
157
169
  :where([data-control-family="popup"][data-popup-kind="hover-card"][data-slot="trigger"]:is(a)) {
158
170
  border-radius: var(--radius-sm);
159
171
  color: var(--foreground);
@@ -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;
@@ -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 };
@@ -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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ctrl-ui/react",
3
- "version": "0.9.9",
3
+ "version": "0.9.11",
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",