@ctrl-ui/react 0.9.14 → 0.9.16

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 (36) hide show
  1. package/README.md +1 -0
  2. package/dist/control-variants.d.ts +1 -1
  3. package/dist/control-variants.js +2 -1
  4. package/dist/knob-contracts/button-knobs.d.ts +1 -1
  5. package/dist/knob-contracts/button-knobs.js +11 -10
  6. package/dist/knob-contracts/item-knobs.d.ts +1 -1
  7. package/dist/knob-contracts/item-knobs.js +5 -0
  8. package/dist/knob-contracts/resize-handle-knobs.d.ts +1 -1
  9. package/dist/knob-contracts/resize-handle-knobs.js +2 -1
  10. package/dist/knob-contracts/reveal-knobs.d.ts +4 -0
  11. package/dist/knob-contracts/reveal-knobs.js +4 -0
  12. package/dist/knob-contracts/tabs-knobs.d.ts +1 -1
  13. package/dist/knob-contracts/tabs-knobs.js +2 -0
  14. package/dist/styles/index.css +1 -0
  15. package/dist/styles/recipes/badge.css +12 -0
  16. package/dist/styles/recipes/button-states.css +50 -0
  17. package/dist/styles/recipes/button.css +19 -52
  18. package/dist/styles/recipes/card.css +2 -2
  19. package/dist/styles/recipes/infinite-canvas.css +8 -0
  20. package/dist/styles/recipes/item.css +73 -6
  21. package/dist/styles/recipes/resize-handle.css +8 -0
  22. package/dist/styles/recipes/reveal.css +26 -0
  23. package/dist/styles/recipes/tabs.css +15 -1
  24. package/dist/ui/badge.d.ts +1 -1
  25. package/dist/ui/dropdown-menu.d.ts +6 -4
  26. package/dist/ui/dropdown-menu.js +2 -1
  27. package/dist/ui/reveal.d.ts +15 -0
  28. package/dist/ui/reveal.js +29 -0
  29. package/dist/ui/typography.d.ts +1 -0
  30. package/dist/ui/typography.js +2 -1
  31. package/lint/class-policy.mjs +2 -0
  32. package/lint/eslint-plugin.mjs +4 -1
  33. package/lint/grit-rules.mjs +4 -0
  34. package/lint/no-component-style-classes.grit +2 -0
  35. package/lint/no-component-style-props.grit +1 -0
  36. package/package.json +1 -1
package/README.md CHANGED
@@ -54,6 +54,7 @@ These rules keep call sites honest. They come from one policy (`lint/class-polic
54
54
  - `no-component-style-classes` errors when `className` on a component imported from `@ctrl-ui/react` (or a `components/control-ui` directory) sets what the component owns: colors, type, padding, borders, radius, shadows, filters, state styles such as `hover:` and `data-[…]:`, arbitrary properties that paint (`[background:…]`), or `!important`. Every `text-*` class counts except alignment and wrapping (`text-center`, `text-pretty`, `text-ellipsis`…). The rule also reads string constants the `className` references in the same file, and the `className` of the element passed to the component's `render` prop. On any other element, it errors on classes that reach into a component's parts, such as `[&_[data-slot=trigger]]:` or `*:data-[slot=icon]:`. Layout classes (`flex`, `gap-*`, widths, heights, margins, placement) stay allowed. Restyle through the component's props or its `--cui-*` knobs instead.
55
55
  - `no-component-style-props` applies the same boundary to `style`: `--cui-*` knobs and layout keys pass, while paint keys error (`color`, `background`, `font*`, `padding*`, `border*`, `boxShadow`, `opacity`, `filter`…). It also checks same-file constant objects and the element passed to `render`. When the paint is data, such as a user-picked fill, put it on a plain element of your own and let the component inherit it.
56
56
  - `no-component-part-css` errors when a stylesheet paints a component part: a rule whose subject is `[data-slot]`, `[data-control-family]`, or another `[data-control…]` attribute, including nested `&` rules and `@apply`. Setting the part's `--cui-*` knobs and layout there stays allowed. The preset skips installed Control UI source under `components/control-ui`.
57
+ - Paint-free components own no look, so both component rules treat them like plain elements: `RevealScope` can be the painted row or card itself, through `className`, `style`, or its `render` element. Part selectors on it still error, and `Reveal` keeps the full rule because its recipe owns opacity.
57
58
  - `no-raw-type-classes` errors on text sizes in any `className`: the type rungs, Tailwind's `text-xs`…`text-9xl`, and arbitrary `text-[13px]`. It reaches beyond Control UI, so adopt it folder by folder while you migrate.
58
59
 
59
60
  The Biome rules need Biome 2.5.0 or later: the preset scopes the stylesheet rule with plugin `includes`.
@@ -1,6 +1,6 @@
1
1
  //#region src/control-variants.d.ts
2
2
  export type ControlSize = "xs" | "sm" | "md" | "lg";
3
- export declare const buttonVariants: readonly ["solid", "surface", "ghost", "quiet", "dashed", "link"];
3
+ export declare const buttonVariants: readonly ["solid", "surface", "ghost", "quiet", "dashed", "link", "scrim"];
4
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];
@@ -5,7 +5,8 @@ const buttonVariants = [
5
5
  "ghost",
6
6
  "quiet",
7
7
  "dashed",
8
- "link"
8
+ "link",
9
+ "scrim"
9
10
  ];
10
11
  const controlTones = [
11
12
  "neutral",
@@ -1,4 +1,4 @@
1
1
  //#region src/knob-contracts/button-knobs.d.ts
2
- export declare const buttonKnobs: readonly ["--cui-button-press-background", "--cui-button-press-scale", "--cui-button-hover-border-color", "--cui-button-open-border-color", "--cui-button-open-background", "--cui-button-open-foreground", "--cui-button-open-shadow", "--cui-button-radius", "--cui-button-gap", "--cui-button-icon", "--cui-button-height", "--cui-button-padding-inline", "--cui-button-padding-block", "--cui-button-icon-padding-inline", "--cui-button-font-size", "--cui-button-font-weight", "--cui-button-background", "--cui-button-background-image", "--cui-button-hover-background-image", "--cui-button-foreground", "--cui-button-hover-background", "--cui-button-hover-foreground", "--cui-button-active-background", "--cui-button-active-foreground", "--cui-button-active-hover-background", "--cui-button-shadow", "--cui-button-hover-shadow", "--cui-button-press-shadow", "--cui-button-active-shadow", "--cui-button-border-width", "--cui-button-border-style", "--cui-button-border-color"];
2
+ export declare const buttonKnobs: readonly ["--cui-button-press-background", "--cui-button-press-scale", "--cui-button-hover-border-color", "--cui-button-open-border-color", "--cui-button-open-background", "--cui-button-open-foreground", "--cui-button-open-shadow", "--cui-button-hover-background-image", "--cui-button-hover-background", "--cui-button-hover-foreground", "--cui-button-active-background", "--cui-button-active-foreground", "--cui-button-active-hover-background", "--cui-button-hover-shadow", "--cui-button-press-shadow", "--cui-button-active-shadow", "--cui-button-radius", "--cui-button-gap", "--cui-button-icon", "--cui-button-height", "--cui-button-padding-inline", "--cui-button-padding-block", "--cui-button-icon-padding-inline", "--cui-button-font-size", "--cui-button-font-weight", "--cui-button-background", "--cui-button-background-image", "--cui-button-foreground", "--cui-button-shadow", "--cui-button-border-width", "--cui-button-border-style", "--cui-button-border-color", "--cui-button-backdrop-filter"];
3
3
  export type ButtonKnobStyle = Partial<Record<(typeof buttonKnobs)[number], string>>;
4
4
  //#endregion
@@ -7,6 +7,15 @@ const buttonKnobs = [
7
7
  "--cui-button-open-background",
8
8
  "--cui-button-open-foreground",
9
9
  "--cui-button-open-shadow",
10
+ "--cui-button-hover-background-image",
11
+ "--cui-button-hover-background",
12
+ "--cui-button-hover-foreground",
13
+ "--cui-button-active-background",
14
+ "--cui-button-active-foreground",
15
+ "--cui-button-active-hover-background",
16
+ "--cui-button-hover-shadow",
17
+ "--cui-button-press-shadow",
18
+ "--cui-button-active-shadow",
10
19
  "--cui-button-radius",
11
20
  "--cui-button-gap",
12
21
  "--cui-button-icon",
@@ -18,20 +27,12 @@ const buttonKnobs = [
18
27
  "--cui-button-font-weight",
19
28
  "--cui-button-background",
20
29
  "--cui-button-background-image",
21
- "--cui-button-hover-background-image",
22
30
  "--cui-button-foreground",
23
- "--cui-button-hover-background",
24
- "--cui-button-hover-foreground",
25
- "--cui-button-active-background",
26
- "--cui-button-active-foreground",
27
- "--cui-button-active-hover-background",
28
31
  "--cui-button-shadow",
29
- "--cui-button-hover-shadow",
30
- "--cui-button-press-shadow",
31
- "--cui-button-active-shadow",
32
32
  "--cui-button-border-width",
33
33
  "--cui-button-border-style",
34
- "--cui-button-border-color"
34
+ "--cui-button-border-color",
35
+ "--cui-button-backdrop-filter"
35
36
  ];
36
37
  //#endregion
37
38
  export { buttonKnobs };
@@ -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-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"];
2
+ export declare const itemKnobs: readonly ["--cui-item-radius", "--cui-item-hover-background", "--cui-item-current-background", "--cui-item-foreground", "--cui-item-selected-background", "--cui-item-selected-foreground", "--cui-item-dragging-opacity", "--cui-item-drop-target-shadow", "--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
@@ -3,6 +3,11 @@ const itemKnobs = [
3
3
  "--cui-item-radius",
4
4
  "--cui-item-hover-background",
5
5
  "--cui-item-current-background",
6
+ "--cui-item-foreground",
7
+ "--cui-item-selected-background",
8
+ "--cui-item-selected-foreground",
9
+ "--cui-item-dragging-opacity",
10
+ "--cui-item-drop-target-shadow",
6
11
  "--cui-item-hover-border-color",
7
12
  "--cui-item-border-width",
8
13
  "--cui-item-active-scale",
@@ -1,4 +1,4 @@
1
1
  //#region src/knob-contracts/resize-handle-knobs.d.ts
2
- export declare const resizeHandleKnobs: readonly ["--cui-resize-handle-size", "--cui-resize-handle-hit-size", "--cui-resize-handle-background", "--cui-resize-handle-hover-background", "--cui-resize-handle-border-color", "--cui-resize-handle-border-width", "--cui-resize-handle-radius"];
2
+ export declare const resizeHandleKnobs: readonly ["--cui-resize-handle-size", "--cui-resize-handle-hit-size", "--cui-resize-handle-background", "--cui-resize-handle-hover-background", "--cui-resize-handle-border-color", "--cui-resize-handle-border-width", "--cui-resize-handle-radius", "--cui-resize-handle-shadow"];
3
3
  export type ResizeHandleKnobStyle = Partial<Record<(typeof resizeHandleKnobs)[number], string>>;
4
4
  //#endregion
@@ -6,7 +6,8 @@ const resizeHandleKnobs = [
6
6
  "--cui-resize-handle-hover-background",
7
7
  "--cui-resize-handle-border-color",
8
8
  "--cui-resize-handle-border-width",
9
- "--cui-resize-handle-radius"
9
+ "--cui-resize-handle-radius",
10
+ "--cui-resize-handle-shadow"
10
11
  ];
11
12
  //#endregion
12
13
  export { resizeHandleKnobs };
@@ -0,0 +1,4 @@
1
+ //#region src/knob-contracts/reveal-knobs.d.ts
2
+ export declare const revealKnobs: readonly ["--cui-reveal-hidden-opacity"];
3
+ export type RevealKnobStyle = Partial<Record<(typeof revealKnobs)[number], string>>;
4
+ //#endregion
@@ -0,0 +1,4 @@
1
+ //#region src/knob-contracts/reveal-knobs.ts
2
+ const revealKnobs = ["--cui-reveal-hidden-opacity"];
3
+ //#endregion
4
+ export { revealKnobs };
@@ -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-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"];
2
+ export declare const tabsKnobs: readonly ["--cui-tabs-surface-background", "--cui-tabs-surface-radius", "--cui-tabs-trigger-padding-inline", "--cui-tabs-trigger-padding-inline-start", "--cui-tabs-trigger-padding-inline-end", "--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
@@ -3,6 +3,8 @@ const tabsKnobs = [
3
3
  "--cui-tabs-surface-background",
4
4
  "--cui-tabs-surface-radius",
5
5
  "--cui-tabs-trigger-padding-inline",
6
+ "--cui-tabs-trigger-padding-inline-start",
7
+ "--cui-tabs-trigger-padding-inline-end",
6
8
  "--cui-tabs-trigger-radius",
7
9
  "--cui-tabs-trigger-height",
8
10
  "--cui-tabs-list-padding",
@@ -84,6 +84,7 @@
84
84
  @import "./recipes/pagination.css";
85
85
  @import "./recipes/phone-input.css";
86
86
  @import "./recipes/resize-handle.css";
87
+ @import "./recipes/reveal.css";
87
88
  @import "./recipes/rich-tooltip.css";
88
89
  @import "./recipes/skeleton.css";
89
90
  @import "./recipes/stepper.css";
@@ -46,6 +46,18 @@
46
46
  }
47
47
  }
48
48
 
49
+ :where([data-control-family="badge"][data-slot="root"][data-color="primary"]) {
50
+ --_badge-color-background: var(--primary);
51
+ --_badge-color-foreground: var(--primary-foreground);
52
+ --_badge-color-border: var(--primary);
53
+ --_badge-color-background-hover: oklch(from var(--primary) calc(l - 0.05) c h);
54
+ }
55
+
56
+ :where([data-control-family="badge"][data-slot="root"][data-color="primary"][data-variant="outline"]) {
57
+ --_badge-color-background: oklch(from var(--primary) l c h / var(--badge-fill-alpha));
58
+ --_badge-color-foreground: var(--primary-text);
59
+ }
60
+
49
61
  :where([data-control-family="badge"][data-slot="root"][data-color="red"]) {
50
62
  --_badge-color-background: var(--badge-red);
51
63
  --_badge-color-foreground: var(--badge-red-foreground);
@@ -125,3 +125,53 @@
125
125
  syntax: "*";
126
126
  inherits: true;
127
127
  }
128
+
129
+ @property --cui-button-hover-background-image {
130
+ syntax: "*";
131
+ inherits: true;
132
+ }
133
+
134
+ @property --cui-button-hover-background {
135
+ syntax: "<color>";
136
+ inherits: true;
137
+ initial-value: transparent;
138
+ }
139
+
140
+ @property --cui-button-hover-foreground {
141
+ syntax: "<color>";
142
+ inherits: true;
143
+ initial-value: transparent;
144
+ }
145
+
146
+ @property --cui-button-active-background {
147
+ syntax: "<color>";
148
+ inherits: true;
149
+ initial-value: transparent;
150
+ }
151
+
152
+ @property --cui-button-active-foreground {
153
+ syntax: "<color>";
154
+ inherits: true;
155
+ initial-value: transparent;
156
+ }
157
+
158
+ @property --cui-button-active-hover-background {
159
+ syntax: "<color>";
160
+ inherits: true;
161
+ initial-value: transparent;
162
+ }
163
+
164
+ @property --cui-button-hover-shadow {
165
+ syntax: "*";
166
+ inherits: true;
167
+ }
168
+
169
+ @property --cui-button-press-shadow {
170
+ syntax: "*";
171
+ inherits: true;
172
+ }
173
+
174
+ @property --cui-button-active-shadow {
175
+ syntax: "*";
176
+ inherits: true;
177
+ }
@@ -56,10 +56,12 @@
56
56
  --cui-button-border-color: var(--control-rim);
57
57
  --cui-button-hover-border-color: var(--cui-button-border-color);
58
58
  --cui-button-open-border-color: var(--cui-button-hover-border-color);
59
+ --cui-button-backdrop-filter: none;
59
60
  border: var(--cui-button-border-width) var(--cui-button-border-style) var(--cui-button-border-color);
60
61
  border-radius: var(--cui-button-radius);
61
62
  background-color: var(--cui-button-background);
62
63
  background-image: var(--cui-button-background-image);
64
+ backdrop-filter: var(--cui-button-backdrop-filter);
63
65
  box-shadow: var(--cui-button-shadow);
64
66
  color: var(--cui-button-foreground);
65
67
  cursor: pointer;
@@ -193,6 +195,16 @@
193
195
  --cui-button-hover-background: transparent;
194
196
  }
195
197
 
198
+ :where([data-control-family="button"][data-variant="scrim"]) {
199
+ --cui-button-background: oklch(0 0 0 / 0.6);
200
+ --cui-button-foreground: oklch(1 0 0);
201
+ --cui-button-hover-background: oklch(0 0 0 / 0.8);
202
+ --cui-button-hover-foreground: var(--cui-button-foreground);
203
+ --cui-button-active-background: var(--cui-button-foreground);
204
+ --cui-button-active-foreground: oklch(0 0 0);
205
+ --cui-button-backdrop-filter: blur(8px);
206
+ }
207
+
196
208
  :where([data-control-family="button"]:is([data-variant="surface"], [data-variant="ghost"], [data-variant="quiet"])) {
197
209
  --cui-button-open-background: oklch(from var(--foreground) l c h / 0.07);
198
210
  }
@@ -210,7 +222,7 @@
210
222
  }
211
223
  }
212
224
 
213
- :where([data-control-family="button"][data-tone="primary"]:not([data-variant="solid"])) {
225
+ :where([data-control-family="button"][data-tone="primary"]:not([data-variant="solid"], [data-variant="scrim"])) {
214
226
  --cui-button-foreground: var(--primary-text);
215
227
  --cui-button-hover-foreground: var(--primary-text);
216
228
  --cui-button-active-foreground: var(--primary-text);
@@ -226,7 +238,7 @@
226
238
  --cui-button-active-hover-background: var(--cui-button-hover-background);
227
239
  }
228
240
 
229
- :where([data-control-family="button"][data-tone="danger"]:not([data-variant="solid"])) {
241
+ :where([data-control-family="button"][data-tone="danger"]:not([data-variant="solid"], [data-variant="scrim"])) {
230
242
  --cui-button-foreground: var(--destructive-text);
231
243
  --cui-button-hover-foreground: var(--destructive-text);
232
244
  --cui-button-active-foreground: var(--destructive-text);
@@ -316,67 +328,17 @@
316
328
  inherits: true;
317
329
  }
318
330
 
319
- @property --cui-button-hover-background-image {
320
- syntax: "*";
321
- inherits: true;
322
- }
323
-
324
331
  @property --cui-button-foreground {
325
332
  syntax: "<color>";
326
333
  inherits: true;
327
334
  initial-value: transparent;
328
335
  }
329
336
 
330
- @property --cui-button-hover-background {
331
- syntax: "<color>";
332
- inherits: true;
333
- initial-value: transparent;
334
- }
335
-
336
- @property --cui-button-hover-foreground {
337
- syntax: "<color>";
338
- inherits: true;
339
- initial-value: transparent;
340
- }
341
-
342
- @property --cui-button-active-background {
343
- syntax: "<color>";
344
- inherits: true;
345
- initial-value: transparent;
346
- }
347
-
348
- @property --cui-button-active-foreground {
349
- syntax: "<color>";
350
- inherits: true;
351
- initial-value: transparent;
352
- }
353
-
354
- @property --cui-button-active-hover-background {
355
- syntax: "<color>";
356
- inherits: true;
357
- initial-value: transparent;
358
- }
359
-
360
337
  @property --cui-button-shadow {
361
338
  syntax: "*";
362
339
  inherits: true;
363
340
  }
364
341
 
365
- @property --cui-button-hover-shadow {
366
- syntax: "*";
367
- inherits: true;
368
- }
369
-
370
- @property --cui-button-press-shadow {
371
- syntax: "*";
372
- inherits: true;
373
- }
374
-
375
- @property --cui-button-active-shadow {
376
- syntax: "*";
377
- inherits: true;
378
- }
379
-
380
342
  @property --cui-button-border-width {
381
343
  syntax: "<length>";
382
344
  inherits: true;
@@ -393,3 +355,8 @@
393
355
  inherits: true;
394
356
  initial-value: transparent;
395
357
  }
358
+
359
+ @property --cui-button-backdrop-filter {
360
+ syntax: "*";
361
+ inherits: true;
362
+ }
@@ -84,11 +84,11 @@
84
84
  }
85
85
 
86
86
  :where([data-control-family="card"][data-slot="root"][data-variant="sectioned"] > [data-slot="content"]) {
87
- padding-block: calc(var(--spacing) * 6);
87
+ padding-block: var(--cui-card-padding-block);
88
88
  }
89
89
 
90
90
  :where([data-control-family="card"][data-slot="root"][data-variant="sectioned"] > [data-slot="header"]) {
91
- padding-block: calc(var(--spacing) * 5);
91
+ padding-block: calc(var(--cui-card-padding-block) - var(--spacing));
92
92
  border-block-end: 1px solid oklch(from var(--border) l c h / 0.7);
93
93
  }
94
94
 
@@ -26,6 +26,14 @@
26
26
  --focus-ring-offset: calc(var(--focus-ring-width) * -1);
27
27
  }
28
28
 
29
+ :where([data-control-family="infinite-canvas"][data-slot="root"][data-pan-ready]:not([data-panning])) {
30
+ cursor: grab;
31
+ }
32
+
33
+ :where([data-control-family="infinite-canvas"][data-slot="root"][data-panning]) {
34
+ cursor: grabbing;
35
+ }
36
+
29
37
  :where([data-control-family="infinite-canvas"][data-slot="root"][data-easing]) {
30
38
  transition-property: background-position, background-size;
31
39
  transition-duration: var(--duration-base);
@@ -1,8 +1,13 @@
1
1
  @layer components {
2
2
  :where([data-control-family="item"][data-slot="root"]) {
3
3
  --cui-item-radius: var(--radius-lg);
4
+ --cui-item-foreground: var(--foreground);
4
5
  --cui-item-hover-background: var(--hover-fill);
5
6
  --cui-item-current-background: var(--active-fill);
7
+ --cui-item-selected-background: var(--cui-item-current-background);
8
+ --cui-item-selected-foreground: var(--cui-item-foreground);
9
+ --cui-item-dragging-opacity: 0.5;
10
+ --cui-item-drop-target-shadow: inset 0 0 0 var(--focus-ring-width) var(--primary);
6
11
  --cui-item-hover-border-color: var(--_item-border-color);
7
12
  --cui-item-border-width: 0px;
8
13
  --cui-item-active-scale: 0.99;
@@ -20,7 +25,7 @@
20
25
  border-radius: var(--cui-item-radius);
21
26
  background: var(--_item-background);
22
27
  box-shadow: none;
23
- color: var(--foreground);
28
+ color: var(--cui-item-foreground);
24
29
  transition-property: scale;
25
30
  transition-duration: var(--duration-fast);
26
31
  transition-timing-function: var(--ease-standard);
@@ -72,11 +77,16 @@
72
77
 
73
78
  @media (hover: hover) {
74
79
  :where(
75
- [data-control-family="item"][data-slot="root"]:is(a, button, [href], [role="button"]):not(
76
- :disabled,
77
- [data-disabled],
78
- [aria-disabled="true"]
79
- ):hover
80
+ [data-control-family="item"][data-slot="root"]:is(
81
+ a,
82
+ button,
83
+ [href],
84
+ [role="button"],
85
+ [role="treeitem"],
86
+ [role="option"],
87
+ [role="row"],
88
+ [role="menuitem"]
89
+ ):not(:disabled, [data-disabled], [aria-disabled="true"]):hover
80
90
  ) {
81
91
  outline-color: var(--cui-item-hover-border-color);
82
92
  background: var(--cui-item-hover-background);
@@ -84,6 +94,34 @@
84
94
  }
85
95
  }
86
96
 
97
+ :where([data-control-family="item"][data-slot="root"][aria-selected="true"]) {
98
+ background: var(--cui-item-selected-background);
99
+ color: var(--cui-item-selected-foreground);
100
+ }
101
+
102
+ :where([data-control-family="item"][data-slot="root"][data-dragging]) {
103
+ opacity: var(--cui-item-dragging-opacity);
104
+ }
105
+
106
+ :where([data-control-family="item"][data-slot="root"][data-drop-target]) {
107
+ box-shadow: var(--cui-item-drop-target-shadow);
108
+ }
109
+
110
+ @media (forced-colors: active) {
111
+ :where([data-control-family="item"][data-slot="root"][aria-selected="true"]) {
112
+ --cui-item-description-foreground: HighlightText;
113
+ --cui-item-media-foreground: HighlightText;
114
+ forced-color-adjust: none;
115
+ background: Highlight;
116
+ color: HighlightText;
117
+ }
118
+
119
+ :where([data-control-family="item"][data-slot="root"][data-drop-target]) {
120
+ outline: var(--focus-ring-width) solid Highlight;
121
+ outline-offset: calc(var(--focus-ring-width) * -1);
122
+ }
123
+ }
124
+
87
125
  :where(
88
126
  [data-control-family="item"][data-slot="root"]:is(a, button, [href], [role="button"]):not(
89
127
  :disabled,
@@ -138,6 +176,35 @@
138
176
  initial-value: transparent;
139
177
  }
140
178
 
179
+ @property --cui-item-foreground {
180
+ syntax: "<color>";
181
+ inherits: true;
182
+ initial-value: transparent;
183
+ }
184
+
185
+ @property --cui-item-selected-background {
186
+ syntax: "<color>";
187
+ inherits: true;
188
+ initial-value: transparent;
189
+ }
190
+
191
+ @property --cui-item-selected-foreground {
192
+ syntax: "<color>";
193
+ inherits: true;
194
+ initial-value: transparent;
195
+ }
196
+
197
+ @property --cui-item-dragging-opacity {
198
+ syntax: "<number>";
199
+ inherits: true;
200
+ initial-value: 1;
201
+ }
202
+
203
+ @property --cui-item-drop-target-shadow {
204
+ syntax: "*";
205
+ inherits: true;
206
+ }
207
+
141
208
  @property --cui-item-hover-border-color {
142
209
  syntax: "<color>";
143
210
  inherits: true;
@@ -7,11 +7,13 @@
7
7
  --cui-resize-handle-border-color: var(--primary);
8
8
  --cui-resize-handle-border-width: var(--control-rim-width);
9
9
  --cui-resize-handle-radius: 0px;
10
+ --cui-resize-handle-shadow: none;
10
11
  inline-size: var(--cui-resize-handle-hit-size);
11
12
  block-size: var(--cui-resize-handle-hit-size);
12
13
  translate: -50% -50%;
13
14
  padding: 0;
14
15
  border: 0;
16
+ border-radius: var(--cui-resize-handle-radius);
15
17
  background: transparent;
16
18
  }
17
19
 
@@ -25,6 +27,7 @@
25
27
  border: var(--cui-resize-handle-border-width) solid var(--cui-resize-handle-border-color);
26
28
  border-radius: var(--cui-resize-handle-radius);
27
29
  background: var(--cui-resize-handle-background);
30
+ box-shadow: var(--cui-resize-handle-shadow);
28
31
  transition: background-color var(--duration-fast) var(--ease-standard);
29
32
  }
30
33
 
@@ -124,3 +127,8 @@
124
127
  inherits: true;
125
128
  initial-value: 0px;
126
129
  }
130
+
131
+ @property --cui-resize-handle-shadow {
132
+ syntax: "*";
133
+ inherits: true;
134
+ }
@@ -0,0 +1,26 @@
1
+ @layer components {
2
+ :where([data-control-family="reveal"][data-slot="scope"]) {
3
+ --cui-reveal-hidden-opacity: 0;
4
+ }
5
+
6
+ :where([data-control-family="reveal"][data-slot="content"]) {
7
+ transition-property: opacity;
8
+ transition-duration: var(--duration-fast);
9
+ transition-timing-function: var(--ease-standard);
10
+ }
11
+
12
+ @media (hover: hover) and (pointer: fine) {
13
+ :where(
14
+ [data-control-family="reveal"][data-slot="scope"]:not(:hover, :focus-within, :has([data-popup-open]))
15
+ [data-control-family="reveal"][data-slot="content"]
16
+ ) {
17
+ opacity: var(--cui-reveal-hidden-opacity);
18
+ }
19
+ }
20
+ }
21
+
22
+ @property --cui-reveal-hidden-opacity {
23
+ syntax: "<number>";
24
+ inherits: true;
25
+ initial-value: 1;
26
+ }
@@ -34,6 +34,8 @@
34
34
 
35
35
  :where([data-control-family="tabs"][data-slot="list"]) {
36
36
  --cui-tabs-trigger-height: var(--control-h-sm);
37
+ --cui-tabs-trigger-padding-inline-start: var(--cui-tabs-trigger-padding-inline);
38
+ --cui-tabs-trigger-padding-inline-end: var(--cui-tabs-trigger-padding-inline);
37
39
  --_tabs-trigger-radius-fit: min(var(--cui-tabs-trigger-radius), calc(var(--cui-tabs-trigger-height) / 2));
38
40
  position: relative;
39
41
  display: flex;
@@ -105,7 +107,7 @@
105
107
  gap: calc(var(--spacing) * 1.5);
106
108
  white-space: nowrap;
107
109
  border-radius: var(--_tabs-trigger-radius-fit);
108
- padding-inline: var(--cui-tabs-trigger-padding-inline);
110
+ padding-inline: var(--cui-tabs-trigger-padding-inline-start) var(--cui-tabs-trigger-padding-inline-end);
109
111
  color: var(--cui-tabs-foreground);
110
112
  font-size: var(--cui-tabs-font-size);
111
113
  font-weight: var(--cui-tabs-font-weight);
@@ -285,6 +287,18 @@
285
287
  initial-value: 0px;
286
288
  }
287
289
 
290
+ @property --cui-tabs-trigger-padding-inline-start {
291
+ syntax: "<length-percentage>";
292
+ inherits: true;
293
+ initial-value: 0px;
294
+ }
295
+
296
+ @property --cui-tabs-trigger-padding-inline-end {
297
+ syntax: "<length-percentage>";
298
+ inherits: true;
299
+ initial-value: 0px;
300
+ }
301
+
288
302
  @property --cui-tabs-trigger-radius {
289
303
  syntax: "<length-percentage>";
290
304
  inherits: true;
@@ -7,7 +7,7 @@ export type BadgeVariant = (typeof badgeVariants)[number];
7
7
  export declare const badgeSizes: readonly ["sm", "md"];
8
8
  export type BadgeSize = (typeof badgeSizes)[number];
9
9
  export declare const BADGE_COLORS: readonly ["neutral", "red", "orange", "yellow", "green", "blue", "purple", "pink"];
10
- export type BadgeColor = (typeof BADGE_COLORS)[number];
10
+ export type BadgeColor = (typeof BADGE_COLORS)[number] | "primary";
11
11
  export type BadgeProps = Omit<ComponentProps<"span">, "style"> & {
12
12
  variant?: BadgeVariant;
13
13
  size?: BadgeSize;
@@ -9,10 +9,12 @@ type DropdownMenuStyledProps<PrimitiveProps> = Omit<PrimitiveProps, "className"
9
9
  className?: string;
10
10
  style?: CSSProperties & PopupKnobStyle;
11
11
  };
12
- export type DropdownMenuProps = Menu.Root.Props;
12
+ export type DropdownMenuProps<Payload = unknown> = Menu.Root.Props<Payload>;
13
+ export type DropdownMenuHandle<Payload = unknown> = Menu.Handle<Payload>;
14
+ export declare const createDropdownMenuHandle: typeof Menu.createHandle;
13
15
  export declare const dropdownMenuTriggerVariants: readonly ["surface", "ghost"];
14
16
  export type DropdownMenuTriggerVariant = (typeof dropdownMenuTriggerVariants)[number];
15
- export type DropdownMenuTriggerProps = Omit<ComponentProps<"button">, "style"> & Pick<ComponentProps<typeof Menu.Trigger>, "nativeButton" | "render"> & {
17
+ export type DropdownMenuTriggerProps<Payload = unknown> = Omit<ComponentProps<"button">, "style"> & Pick<Menu.Trigger.Props<Payload>, "nativeButton" | "render" | "handle" | "payload"> & {
16
18
  style?: CSSProperties & ButtonKnobStyle;
17
19
  } & {
18
20
  size?: ControlSize;
@@ -37,8 +39,8 @@ export type DropdownMenuSeparatorProps = Omit<ComponentProps<"div">, "style"> &
37
39
  export type DropdownMenuLabelProps = Omit<ComponentProps<"div">, "style"> & {
38
40
  style?: CSSProperties & PopupKnobStyle;
39
41
  };
40
- export declare function DropdownMenu({ children, ...props }: DropdownMenuProps): import("react").JSX.Element;
41
- export declare function DropdownMenuTrigger({ size, iconOnly, variant, className, ...props }: DropdownMenuTriggerProps): import("react").JSX.Element;
42
+ export declare function DropdownMenu<Payload>({ children, ...props }: DropdownMenuProps<Payload>): import("react").JSX.Element;
43
+ export declare function DropdownMenuTrigger<Payload>({ size, iconOnly, variant, className, ...props }: DropdownMenuTriggerProps<Payload>): import("react").JSX.Element;
42
44
  export declare function DropdownMenuContent({ className, children, side, sideOffset, align, alignOffset, collisionBoundary, collisionPadding, collisionAvoidance, ...props }: DropdownMenuContentProps): import("react").JSX.Element;
43
45
  export declare function DropdownMenuItem({ tone, className, ...props }: DropdownMenuItemProps): import("react").JSX.Element;
44
46
  export declare function DropdownMenuSeparator({ className, ...props }: DropdownMenuSeparatorProps): import("react").JSX.Element;
@@ -9,6 +9,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
9
9
  import { mergeProps } from "@base-ui/react/merge-props";
10
10
  import { Menu } from "@base-ui/react/menu";
11
11
  //#region src/ui/dropdown-menu.tsx
12
+ const createDropdownMenuHandle = Menu.createHandle;
12
13
  const dropdownMenuTriggerVariants = ["surface", "ghost"];
13
14
  function DropdownMenu({ children, ...props }) {
14
15
  return /* @__PURE__ */ jsx(Menu.Root, {
@@ -209,4 +210,4 @@ function DropdownMenuShortcut(props) {
209
210
  });
210
211
  }
211
212
  //#endregion
212
- export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, dropdownMenuTriggerVariants };
213
+ export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, createDropdownMenuHandle, dropdownMenuTriggerVariants };
@@ -0,0 +1,15 @@
1
+ import { RenderProp } from "../control-props.js";
2
+ import { RevealKnobStyle } from "../knob-contracts/reveal-knobs.js";
3
+ import { CSSProperties, ComponentProps } from "react";
4
+ //#region src/ui/reveal.d.ts
5
+ export type RevealScopeProps = Omit<ComponentProps<"div">, "style"> & {
6
+ render?: RenderProp<ComponentProps<"div">>;
7
+ style?: CSSProperties & RevealKnobStyle;
8
+ };
9
+ export type RevealProps = Omit<ComponentProps<"span">, "style"> & {
10
+ render?: RenderProp<ComponentProps<"span">>;
11
+ style?: CSSProperties & RevealKnobStyle;
12
+ };
13
+ export declare function RevealScope({ render, ...props }: RevealScopeProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
14
+ export declare function Reveal({ render, ...props }: RevealProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
15
+ //#endregion
@@ -0,0 +1,29 @@
1
+ "use client";
2
+ import { useRender } from "@base-ui/react/use-render";
3
+ //#region src/ui/reveal.tsx
4
+ function RevealScope({ render, ...props }) {
5
+ return useRender({
6
+ defaultTagName: "div",
7
+ render,
8
+ props: {
9
+ ...props,
10
+ "data-control-ui": "reveal",
11
+ "data-control-family": "reveal",
12
+ "data-slot": "scope"
13
+ }
14
+ });
15
+ }
16
+ function Reveal({ render, ...props }) {
17
+ return useRender({
18
+ defaultTagName: "span",
19
+ render,
20
+ props: {
21
+ ...props,
22
+ "data-control-ui": "reveal",
23
+ "data-control-family": "reveal",
24
+ "data-slot": "content"
25
+ }
26
+ });
27
+ }
28
+ //#endregion
29
+ export { Reveal, RevealScope };
@@ -25,6 +25,7 @@ declare const weightClassNames: {
25
25
  readonly normal: "font-normal";
26
26
  readonly medium: "font-medium";
27
27
  readonly semibold: "font-semibold";
28
+ readonly bold: "font-bold";
28
29
  };
29
30
  export type TypeSize = keyof typeof sizeClassNames;
30
31
  export type TypeTone = keyof typeof toneClassNames;
@@ -25,7 +25,8 @@ const toneClassNames = {
25
25
  const weightClassNames = {
26
26
  normal: "font-normal",
27
27
  medium: "font-medium",
28
- semibold: "font-semibold"
28
+ semibold: "font-semibold",
29
+ bold: "font-bold"
29
30
  };
30
31
  const headingSizeByLevel = {
31
32
  1: "heading-1",
@@ -1,5 +1,7 @@
1
1
  const controlUiImportPath = `(?:@ctrl-ui/react|[^'"]*components/control-ui)/`;
2
2
 
3
+ export const paintFreeComponents = ["RevealScope"];
4
+
3
5
  const escapeRegExp = (text) => text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4
6
 
5
7
  export function controlUiImportPattern(importSources = []) {
@@ -6,6 +6,7 @@ import {
6
6
  componentStyleMessage,
7
7
  componentStylePropMessage,
8
8
  controlUiImportPattern,
9
+ paintFreeComponents,
9
10
  rawTypeClass,
10
11
  rawTypeMessage,
11
12
  } from "./class-policy.mjs";
@@ -77,7 +78,9 @@ function controlUiLocalNames(program, controlUiImport) {
77
78
  for (const statement of program.body) {
78
79
  if (statement.type !== "ImportDeclaration" || statement.importKind === "type") continue;
79
80
  if (!controlUiImport.test(statement.source.value)) continue;
80
- for (const specifier of statement.specifiers) names.add(specifier.local.name);
81
+ for (const specifier of statement.specifiers) {
82
+ if (!paintFreeComponents.includes(specifier.imported?.name)) names.add(specifier.local.name);
83
+ }
81
84
  }
82
85
  return names;
83
86
  }
@@ -8,6 +8,7 @@ import {
8
8
  componentStyleMessage,
9
9
  componentStylePropMessage,
10
10
  controlUiImportPattern,
11
+ paintFreeComponents,
11
12
  paintProperty,
12
13
  rawTypeClass,
13
14
  rawTypeMessage,
@@ -30,6 +31,7 @@ const stringTexts = (name) =>
30
31
  const classLiterals = "or { JsStringLiteralExpression(), JsTemplateExpression(), JsObjectExpression() }";
31
32
  const renderedTag = "or { JsxTagExpression(tag=$tag), JsParenthesizedExpression(expression=JsxTagExpression(tag=$tag)) }";
32
33
  const componentName = `r"([A-Z]\\w*)(?:\\.[\\w.]+)?"`;
34
+ const paintFreeComponent = gritExactRegex(`(?:${paintFreeComponents.join("|")})`);
33
35
 
34
36
  function constantMatches(reference, literals, offends) {
35
37
  return `contains JsReferenceIdentifier() as $${reference} where {
@@ -97,6 +99,7 @@ function componentAttributePattern({ attribute, offends, message, importSources
97
99
  }
98
100
  } where {
99
101
  $name <: ${componentName}($component),
102
+ not $component <: ${paintFreeComponent},
100
103
  $attr <: within JsModule() as $module,
101
104
  ${offends("$attr")},
102
105
  ${importedFromControlUi("$component", importSources)},
@@ -115,6 +118,7 @@ function partClassPattern(importSources) {
115
118
  ${classNameMatches("$plainAttr", componentPartClass)},
116
119
  not and {
117
120
  $plainName <: ${componentName}($plainComponent),
121
+ not $plainComponent <: ${paintFreeComponent},
118
122
  ${importedFromControlUi("$plainComponent", importSources, "Plain")}
119
123
  },
120
124
  register_diagnostic(span=$plainAttr, message=${gritString(componentPartMessage)}, severity="error")
@@ -31,6 +31,7 @@ or {
31
31
  }
32
32
  } where {
33
33
  $name <: r"([A-Z]\w*)(?:\.[\w.]+)?"($component),
34
+ not $component <: r"(?:RevealScope)",
34
35
  $attr <: within JsModule() as $module,
35
36
  $attr <: or {
36
37
  contains or { JsxString(), JsStringLiteralExpression(), JsTemplateChunkElement(), JsLiteralMemberName() as $attrMember where { $attrMember <: r"(?s)[\"'].*" } } as $attrText where { $attrText <: r"(?s).*(?:[^\s\"'\x60]!(?:[\s\"'\x60]|$)|(?:^|[\s\"'\x60])![\w\[-]|(?:^|[^\w-])(?:p[xytrblse]?-|bg-[\w\[]|text-(?:(?:[\s\"'\x60]|$)|[^lcrjsewnbp\s\"'\x60]|l(?:(?:[\s\"'\x60]|$)|[^e\s\"'\x60]|e(?:(?:[\s\"'\x60]|$)|[^f\s\"'\x60]|f(?:(?:[\s\"'\x60]|$)|[^t\s\"'\x60]|t(?:[^\s\"'\x60]))))|c(?:(?:[\s\"'\x60]|$)|[^el\s\"'\x60]|e(?:(?:[\s\"'\x60]|$)|[^n\s\"'\x60]|n(?:(?:[\s\"'\x60]|$)|[^t\s\"'\x60]|t(?:(?:[\s\"'\x60]|$)|[^e\s\"'\x60]|e(?:(?:[\s\"'\x60]|$)|[^r\s\"'\x60]|r(?:[^\s\"'\x60])))))|l(?:(?:[\s\"'\x60]|$)|[^i\s\"'\x60]|i(?:(?:[\s\"'\x60]|$)|[^p\s\"'\x60]|p(?:[^\s\"'\x60]))))|r(?:(?:[\s\"'\x60]|$)|[^i\s\"'\x60]|i(?:(?:[\s\"'\x60]|$)|[^g\s\"'\x60]|g(?:(?:[\s\"'\x60]|$)|[^h\s\"'\x60]|h(?:(?:[\s\"'\x60]|$)|[^t\s\"'\x60]|t(?:[^\s\"'\x60])))))|j(?:(?:[\s\"'\x60]|$)|[^u\s\"'\x60]|u(?:(?:[\s\"'\x60]|$)|[^s\s\"'\x60]|s(?:(?:[\s\"'\x60]|$)|[^t\s\"'\x60]|t(?:(?:[\s\"'\x60]|$)|[^i\s\"'\x60]|i(?:(?:[\s\"'\x60]|$)|[^f\s\"'\x60]|f(?:(?:[\s\"'\x60]|$)|[^y\s\"'\x60]|y(?:[^\s\"'\x60])))))))|s(?:(?:[\s\"'\x60]|$)|[^t\s\"'\x60]|t(?:(?:[\s\"'\x60]|$)|[^a\s\"'\x60]|a(?:(?:[\s\"'\x60]|$)|[^r\s\"'\x60]|r(?:(?:[\s\"'\x60]|$)|[^t\s\"'\x60]|t(?:[^\s\"'\x60])))))|e(?:(?:[\s\"'\x60]|$)|[^nl\s\"'\x60]|n(?:(?:[\s\"'\x60]|$)|[^d\s\"'\x60]|d(?:[^\s\"'\x60]))|l(?:(?:[\s\"'\x60]|$)|[^l\s\"'\x60]|l(?:(?:[\s\"'\x60]|$)|[^i\s\"'\x60]|i(?:(?:[\s\"'\x60]|$)|[^p\s\"'\x60]|p(?:(?:[\s\"'\x60]|$)|[^s\s\"'\x60]|s(?:(?:[\s\"'\x60]|$)|[^i\s\"'\x60]|i(?:(?:[\s\"'\x60]|$)|[^s\s\"'\x60]|s(?:[^\s\"'\x60]))))))))|w(?:(?:[\s\"'\x60]|$)|[^r\s\"'\x60]|r(?:(?:[\s\"'\x60]|$)|[^a\s\"'\x60]|a(?:(?:[\s\"'\x60]|$)|[^p\s\"'\x60]|p(?:[^\s\"'\x60]))))|n(?:(?:[\s\"'\x60]|$)|[^o\s\"'\x60]|o(?:(?:[\s\"'\x60]|$)|[^w\s\"'\x60]|w(?:(?:[\s\"'\x60]|$)|[^r\s\"'\x60]|r(?:(?:[\s\"'\x60]|$)|[^a\s\"'\x60]|a(?:(?:[\s\"'\x60]|$)|[^p\s\"'\x60]|p(?:[^\s\"'\x60]))))))|b(?:(?:[\s\"'\x60]|$)|[^a\s\"'\x60]|a(?:(?:[\s\"'\x60]|$)|[^l\s\"'\x60]|l(?:(?:[\s\"'\x60]|$)|[^a\s\"'\x60]|a(?:(?:[\s\"'\x60]|$)|[^n\s\"'\x60]|n(?:(?:[\s\"'\x60]|$)|[^c\s\"'\x60]|c(?:(?:[\s\"'\x60]|$)|[^e\s\"'\x60]|e(?:[^\s\"'\x60])))))))|p(?:(?:[\s\"'\x60]|$)|[^r\s\"'\x60]|r(?:(?:[\s\"'\x60]|$)|[^e\s\"'\x60]|e(?:(?:[\s\"'\x60]|$)|[^t\s\"'\x60]|t(?:(?:[\s\"'\x60]|$)|[^t\s\"'\x60]|t(?:(?:[\s\"'\x60]|$)|[^y\s\"'\x60]|y(?:[^\s\"'\x60])))))))|font-|leading-|tracking-|border|divide-|rounded|shadow|inset-shadow|drop-shadow|ring\b|ring-|inset-ring|outline|opacity-|backdrop-|fill-|stroke-|caret-|accent-|scheme-|mask-|decoration-|underline|no-underline|overline|line-through|italic|not-italic|uppercase|lowercase|capitalize|normal-case|antialiased|subpixel-antialiased|ordinal|slashed-zero|(?:normal|lining|oldstyle|proportional|tabular)-nums|(?:diagonal|stacked)-fractions|blur(?:-|(?:[\s\"'\x60]|$))|brightness-|contrast-[\d\[]|grayscale|hue-rotate-|invert|saturate-|sepia|(?:hover|focus|focus-visible|focus-within|active|disabled|enabled|open|checked|indeterminate|visited|target|invalid|valid|user-invalid|user-valid|required|optional|read-only|autofill|placeholder-shown|in-range|out-of-range|inert|starting|dark|placeholder|selection|marker|file|first-letter|first-line|backdrop|details-content|aria-[^:\s]*|data-[^:\s]*|group-[^:\s]*|peer-[^:\s]*|has-[^:\s]*|\*|\[&[^\s]*?\]):)|(?:^|[^\w-])\[(?:padding|background|color|font|line-height|letter-spacing|border|outline|box-shadow|text-shadow|text-decoration|text-underline|text-transform|opacity|filter|backdrop-filter|fill|stroke|caret-color|accent-color|mask|-webkit-mask|-webkit-font-smoothing|-moz-osx-font-smoothing)(?:-[\w-]*)?:).*" },
@@ -71,6 +72,7 @@ or {
71
72
  },
72
73
  not and {
73
74
  $plainName <: r"([A-Z]\w*)(?:\.[\w.]+)?"($plainComponent),
75
+ not $plainComponent <: r"(?:RevealScope)",
74
76
  $module <: contains JsImport() as $importPlain where {
75
77
  $importPlain <: r"(?s).*(?:from\s+['\"](?:(?:@ctrl-ui/react|[^'\"]*components/control-ui)/)).*",
76
78
  $importPlain <: contains JsIdentifierBinding() as $bindingPlain where { $bindingPlain <: $plainComponent }
@@ -30,6 +30,7 @@ or {
30
30
  }
31
31
  } where {
32
32
  $name <: r"([A-Z]\w*)(?:\.[\w.]+)?"($component),
33
+ not $component <: r"(?:RevealScope)",
33
34
  $attr <: within JsModule() as $module,
34
35
  $attr <: or {
35
36
  contains or { JsPropertyObjectMember(name=$attrKey), JsShorthandPropertyObjectMember(name=$attrKey) } where { $attrKey <: r"[\"']?(?:(?:padding|background|color|font|lineHeight|letterSpacing|border|outline|boxShadow|textShadow|textDecoration|textUnderline|textTransform|opacity|filter|backdropFilter|fill|stroke|caretColor|accentColor|mask|WebkitMask|WebkitFontSmoothing|MozOsxFontSmoothing)(?:[A-Z]\w*)?|(?:padding|background|color|font|line-height|letter-spacing|border|outline|box-shadow|text-shadow|text-decoration|text-underline|text-transform|opacity|filter|backdrop-filter|fill|stroke|caret-color|accent-color|mask|-webkit-mask|-webkit-font-smoothing|-moz-osx-font-smoothing)(?:-[\w-]*)?)[\"']?" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ctrl-ui/react",
3
- "version": "0.9.14",
3
+ "version": "0.9.16",
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",