@ctrl-ui/react 0.9.12 → 0.9.14
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.
- package/README.md +20 -7
- package/dist/blocks/design-canvas.js +16 -10
- package/dist/knob-contracts/field-knobs.d.ts +1 -1
- package/dist/knob-contracts/field-knobs.js +1 -0
- package/dist/knob-contracts/gradient-editor-knobs.d.ts +1 -1
- package/dist/knob-contracts/gradient-editor-knobs.js +1 -4
- package/dist/knob-contracts/popup-knobs.d.ts +1 -1
- package/dist/knob-contracts/popup-knobs.js +2 -0
- package/dist/lib/phone-input-format.js +1 -1
- package/dist/styles/recipes/card.css +8 -0
- package/dist/styles/recipes/color-picker-values.css +4 -18
- package/dist/styles/recipes/color-picker.css +3 -4
- package/dist/styles/recipes/field-parts.css +8 -1
- package/dist/styles/recipes/gradient-editor.css +3 -47
- package/dist/styles/recipes/markdown.css +5 -1
- package/dist/styles/recipes/popup-lists.css +17 -0
- package/dist/styles/recipes/popup.css +3 -0
- package/dist/styles/theme.css +4 -0
- package/dist/ui/autocomplete.d.ts +3 -0
- package/dist/ui/autocomplete.js +17 -2
- package/dist/ui/chart-cartesian.d.ts +60 -57
- package/dist/ui/chart-cartesian.js +7 -7
- package/dist/ui/chart-colors.d.ts +4 -2
- package/dist/ui/chart-colors.js +6 -2
- package/dist/ui/chart-marks.d.ts +4 -4
- package/dist/ui/chart-marks.js +14 -5
- package/dist/ui/chart-series.d.ts +9 -6
- package/dist/ui/chart-series.js +3 -2
- package/dist/ui/color-picker-swatches.d.ts +4 -3
- package/dist/ui/color-picker-swatches.js +7 -8
- package/dist/ui/command.d.ts +12 -0
- package/dist/ui/command.js +31 -1
- package/dist/ui/field.js +1 -1
- package/dist/ui/gradient-editor.d.ts +3 -2
- package/dist/ui/gradient-editor.js +7 -8
- package/dist/ui/markdown-components.d.ts +27 -0
- package/dist/ui/markdown-components.js +57 -0
- package/dist/ui/markdown-elements.d.ts +6 -25
- package/dist/ui/markdown-elements.js +19 -53
- package/dist/ui/markdown.d.ts +2 -7
- package/dist/ui/markdown.js +3 -20
- package/dist/ui/phone-input.js +2 -2
- package/lint/biome-preset.json +8 -1
- package/lint/class-policy.mjs +50 -1
- package/lint/eslint-plugin.mjs +98 -49
- package/lint/grit-rules.mjs +131 -42
- package/lint/no-component-part-css.grit +16 -0
- package/lint/no-component-style-classes.grit +66 -36
- package/lint/no-component-style-props.grit +51 -0
- package/lint/no-raw-type-classes.grit +1 -1
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -49,11 +49,15 @@ Controls size their own text: pick the control's `size`, or set its `--cui-*-fon
|
|
|
49
49
|
|
|
50
50
|
## Lint rules
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
These rules keep call sites honest. They come from one policy (`lint/class-policy.mjs`) and ship for Biome, ESLint, and oxlint, except the stylesheet rule, which is Biome only:
|
|
53
53
|
|
|
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, state styles such as `hover:` and `data-[…]:`, 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. Layout classes (`flex`, `gap-*`, widths, heights, margins, placement) stay allowed. Restyle through the component's props or its `--cui-*` knobs instead.
|
|
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
|
+
- `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
|
+
- `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`.
|
|
55
57
|
- `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.
|
|
56
58
|
|
|
59
|
+
The Biome rules need Biome 2.5.0 or later: the preset scopes the stylesheet rule with plugin `includes`.
|
|
60
|
+
|
|
57
61
|
Biome, extending the shipped preset so rules added later arrive with the package update:
|
|
58
62
|
|
|
59
63
|
```json
|
|
@@ -68,22 +72,31 @@ ESLint flat config:
|
|
|
68
72
|
```js
|
|
69
73
|
import controlUi from "@ctrl-ui/react/eslint-plugin";
|
|
70
74
|
|
|
71
|
-
export default [
|
|
75
|
+
export default [
|
|
76
|
+
{
|
|
77
|
+
plugins: { "control-ui": controlUi },
|
|
78
|
+
rules: { "control-ui/no-component-style-classes": "error", "control-ui/no-component-style-props": "error" },
|
|
79
|
+
},
|
|
80
|
+
];
|
|
72
81
|
```
|
|
73
82
|
|
|
74
83
|
oxlint, through its JS plugin support:
|
|
75
84
|
|
|
76
85
|
```json
|
|
77
|
-
{
|
|
86
|
+
{
|
|
87
|
+
"jsPlugins": ["@ctrl-ui/react/eslint-plugin"],
|
|
88
|
+
"rules": { "control-ui/no-component-style-classes": "error", "control-ui/no-component-style-props": "error" }
|
|
89
|
+
}
|
|
78
90
|
```
|
|
79
91
|
|
|
80
|
-
When your app imports components through its own wrapper package or folder, declare that path so the
|
|
92
|
+
When your app imports components through its own wrapper package or folder, declare that path so the rules follow those imports too:
|
|
81
93
|
|
|
82
94
|
```js
|
|
83
|
-
|
|
95
|
+
const options = { importSources: ["@acme/ui/components/"] };
|
|
96
|
+
rules: { "control-ui/no-component-style-classes": ["error", options], "control-ui/no-component-style-props": ["error", options] }
|
|
84
97
|
```
|
|
85
98
|
|
|
86
|
-
Biome's Grit plugins take no options, so the package ships `control-ui-grit` to write the rules with your paths. Run it on install so a package update regenerates them, gitignore `.control-ui`, and list
|
|
99
|
+
Biome's Grit plugins take no options, so the package ships `control-ui-grit` to write the rules with your paths. Run it on install so a package update regenerates them, gitignore `.control-ui`, and list the generated `no-component-style-classes.grit`, `no-component-style-props.grit`, and `no-component-part-css.grit` from `./.control-ui/` under `plugins` in place of the preset:
|
|
87
100
|
|
|
88
101
|
```json
|
|
89
102
|
{ "scripts": { "postinstall": "control-ui-grit --import-source=@acme/ui/components/ --out=.control-ui" } }
|
|
@@ -412,8 +412,7 @@ function DesignCanvasLayerNode({ layer, selected, onSelect, onKeyDown, onLayerCh
|
|
|
412
412
|
style: {
|
|
413
413
|
width: layer.width,
|
|
414
414
|
height: layer.height,
|
|
415
|
-
rotate: `${layer.rotation}deg
|
|
416
|
-
opacity: layer.opacity / 100
|
|
415
|
+
rotate: `${layer.rotation}deg`
|
|
417
416
|
},
|
|
418
417
|
onPointerDown: onSelect,
|
|
419
418
|
onKeyDown,
|
|
@@ -429,18 +428,25 @@ function DesignCanvasLayerNode({ layer, selected, onSelect, onKeyDown, onLayerCh
|
|
|
429
428
|
className: "absolute start-0 bottom-full mb-1 whitespace-nowrap",
|
|
430
429
|
children: layer.name
|
|
431
430
|
}) : null,
|
|
432
|
-
layer.kind === "text" ? /* @__PURE__ */ jsx(
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
children:
|
|
431
|
+
layer.kind === "text" ? /* @__PURE__ */ jsx("div", {
|
|
432
|
+
className: "size-full",
|
|
433
|
+
style: {
|
|
434
|
+
color: fillColor,
|
|
435
|
+
opacity: layer.opacity / 100
|
|
436
|
+
},
|
|
437
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
438
|
+
as: "p",
|
|
439
|
+
size: "heading-2",
|
|
440
|
+
weight: "normal",
|
|
441
|
+
className: "size-full overflow-hidden whitespace-nowrap",
|
|
442
|
+
children: layer.text
|
|
443
|
+
})
|
|
439
444
|
}) : /* @__PURE__ */ jsx("div", {
|
|
440
445
|
className: "size-full",
|
|
441
446
|
style: {
|
|
442
447
|
background: fillColor,
|
|
443
|
-
borderRadius: layer.kind === "ellipse" ? "50%" : layer.cornerRadius
|
|
448
|
+
borderRadius: layer.kind === "ellipse" ? "50%" : layer.cornerRadius,
|
|
449
|
+
opacity: layer.opacity / 100
|
|
444
450
|
}
|
|
445
451
|
}),
|
|
446
452
|
selected ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
//#region src/knob-contracts/field-knobs.d.ts
|
|
2
|
-
export declare const fieldKnobs: readonly ["--cui-field-label-radius", "--cui-field-label-background", "--cui-field-label-hover-background", "--cui-field-label-checked-background", "--cui-field-label-border-color", "--cui-field-label-checked-border-color", "--cui-field-label-border-width", "--cui-field-label-padding-block", "--cui-field-label-padding-inline", "--cui-field-legend-font-size", "--cui-field-legend-font-weight", "--cui-field-radius", "--cui-field-background", "--cui-field-hover-background", "--cui-field-affordance-background", "--cui-field-affordance-shadow", "--cui-field-affordance-foreground", "--cui-field-affordance-hover-background", "--cui-field-foreground", "--cui-field-border-color", "--cui-field-border-width", "--cui-field-shadow", "--cui-field-backdrop-filter", "--cui-field-height", "--cui-field-padding-inline", "--cui-field-font-size", "--cui-field-font-weight", "--cui-field-font-family", "--cui-field-group-radius", "--cui-field-group-background", "--cui-field-group-border-color", "--cui-field-group-border-width", "--cui-field-group-shadow", "--cui-field-group-padding-block", "--cui-field-group-padding-inline", "--cui-field-group-separator-color", "--cui-field-group-separator-inset", "--cui-field-label-font-size", "--cui-field-label-font-weight", "--cui-field-description-font-size"];
|
|
2
|
+
export declare const fieldKnobs: readonly ["--cui-field-label-radius", "--cui-field-label-background", "--cui-field-label-hover-background", "--cui-field-label-checked-background", "--cui-field-label-border-color", "--cui-field-label-checked-border-color", "--cui-field-label-border-width", "--cui-field-label-padding-block", "--cui-field-label-padding-inline", "--cui-field-legend-foreground", "--cui-field-legend-font-size", "--cui-field-legend-font-weight", "--cui-field-radius", "--cui-field-background", "--cui-field-hover-background", "--cui-field-affordance-background", "--cui-field-affordance-shadow", "--cui-field-affordance-foreground", "--cui-field-affordance-hover-background", "--cui-field-foreground", "--cui-field-border-color", "--cui-field-border-width", "--cui-field-shadow", "--cui-field-backdrop-filter", "--cui-field-height", "--cui-field-padding-inline", "--cui-field-font-size", "--cui-field-font-weight", "--cui-field-font-family", "--cui-field-group-radius", "--cui-field-group-background", "--cui-field-group-border-color", "--cui-field-group-border-width", "--cui-field-group-shadow", "--cui-field-group-padding-block", "--cui-field-group-padding-inline", "--cui-field-group-separator-color", "--cui-field-group-separator-inset", "--cui-field-label-font-size", "--cui-field-label-font-weight", "--cui-field-description-font-size"];
|
|
3
3
|
export type FieldKnobStyle = Partial<Record<(typeof fieldKnobs)[number], string>>;
|
|
4
4
|
//#endregion
|
|
@@ -9,6 +9,7 @@ const fieldKnobs = [
|
|
|
9
9
|
"--cui-field-label-border-width",
|
|
10
10
|
"--cui-field-label-padding-block",
|
|
11
11
|
"--cui-field-label-padding-inline",
|
|
12
|
+
"--cui-field-legend-foreground",
|
|
12
13
|
"--cui-field-legend-font-size",
|
|
13
14
|
"--cui-field-legend-font-weight",
|
|
14
15
|
"--cui-field-radius",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
//#region src/knob-contracts/gradient-editor-knobs.d.ts
|
|
2
|
-
export declare const gradientEditorKnobs: readonly ["--cui-gradient-editor-preview-radius", "--cui-gradient-editor-preview-ring-color", "--cui-gradient-editor-track-radius", "--cui-gradient-editor-stop-radius", "--cui-gradient-editor-stop-border-color", "--cui-gradient-editor-stop-border-width", "--cui-gradient-editor-stop-shadow"
|
|
2
|
+
export declare const gradientEditorKnobs: readonly ["--cui-gradient-editor-preview-radius", "--cui-gradient-editor-preview-ring-color", "--cui-gradient-editor-track-radius", "--cui-gradient-editor-stop-radius", "--cui-gradient-editor-stop-border-color", "--cui-gradient-editor-stop-border-width", "--cui-gradient-editor-stop-shadow"];
|
|
3
3
|
export type GradientEditorKnobStyle = Partial<Record<(typeof gradientEditorKnobs)[number], string>>;
|
|
4
4
|
//#endregion
|
|
@@ -6,10 +6,7 @@ const gradientEditorKnobs = [
|
|
|
6
6
|
"--cui-gradient-editor-stop-radius",
|
|
7
7
|
"--cui-gradient-editor-stop-border-color",
|
|
8
8
|
"--cui-gradient-editor-stop-border-width",
|
|
9
|
-
"--cui-gradient-editor-stop-shadow"
|
|
10
|
-
"--cui-gradient-editor-add-radius",
|
|
11
|
-
"--cui-gradient-editor-add-border-color",
|
|
12
|
-
"--cui-gradient-editor-add-border-width"
|
|
9
|
+
"--cui-gradient-editor-stop-shadow"
|
|
13
10
|
];
|
|
14
11
|
//#endregion
|
|
15
12
|
export { gradientEditorKnobs };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
//#region src/knob-contracts/popup-knobs.d.ts
|
|
2
|
-
export declare const popupKnobs: readonly ["--cui-popup-title-foreground", "--cui-popup-title-font-size", "--cui-popup-title-font-weight", "--cui-popup-title-line-height", "--cui-popup-title-letter-spacing", "--cui-popup-description-foreground", "--cui-popup-description-font-size", "--cui-popup-close-inset", "--cui-popup-item-inset", "--cui-popup-label-padding-block", "--cui-popup-label-padding-inline", "--cui-popup-label-font-size", "--cui-popup-label-font-weight", "--cui-popup-label-letter-spacing", "--cui-popup-label-text-transform", "--cui-popup-separator-inset", "--cui-popup-shortcut-font-size", "--cui-popup-shortcut-letter-spacing", "--cui-popup-separator-gap", "--cui-popup-submenu-indicator-foreground", "--cui-popup-command-heading-padding-block", "--cui-popup-command-heading-padding-inline", "--cui-popup-command-heading-font-size", "--cui-popup-command-heading-letter-spacing", "--cui-popup-command-heading-text-transform", "--cui-popup-dialog-max-inline-size", "--cui-popup-shortcut-foreground", "--cui-popup-tooltip-arrow-radius", "--cui-popup-status-success-foreground", "--cui-popup-status-warning-foreground", "--cui-popup-status-info-foreground", "--cui-popup-status-error-foreground", "--cui-popup-radius", "--cui-popup-background", "--cui-popup-foreground", "--cui-popup-border-color", "--cui-popup-border-width", "--cui-popup-shadow", "--cui-popup-backdrop-filter", "--cui-popup-backdrop-background", "--cui-popup-backdrop-blur", "--cui-popup-item-radius", "--cui-popup-item-font-size", "--cui-popup-item-icon-size", "--cui-popup-item-padding-block", "--cui-popup-item-padding-inline", "--cui-popup-item-min-height", "--cui-popup-item-highlight-shadow", "--cui-popup-item-foreground", "--cui-popup-item-highlight-background", "--cui-popup-item-highlight-foreground", "--cui-popup-item-highlight-muted-foreground", "--cui-popup-item-disabled-opacity", "--cui-popup-separator-color"];
|
|
2
|
+
export declare const popupKnobs: readonly ["--cui-popup-title-foreground", "--cui-popup-title-font-size", "--cui-popup-title-font-weight", "--cui-popup-title-line-height", "--cui-popup-title-letter-spacing", "--cui-popup-description-foreground", "--cui-popup-description-font-size", "--cui-popup-close-inset", "--cui-popup-item-inset", "--cui-popup-label-padding-block", "--cui-popup-label-padding-inline", "--cui-popup-label-font-size", "--cui-popup-label-font-weight", "--cui-popup-label-letter-spacing", "--cui-popup-label-text-transform", "--cui-popup-separator-inset", "--cui-popup-shortcut-font-size", "--cui-popup-shortcut-letter-spacing", "--cui-popup-separator-gap", "--cui-popup-submenu-indicator-foreground", "--cui-popup-command-heading-padding-block", "--cui-popup-command-heading-padding-inline", "--cui-popup-command-heading-font-size", "--cui-popup-command-heading-letter-spacing", "--cui-popup-command-heading-text-transform", "--cui-popup-dialog-max-inline-size", "--cui-popup-item-description-foreground", "--cui-popup-item-description-font-size", "--cui-popup-shortcut-foreground", "--cui-popup-tooltip-arrow-radius", "--cui-popup-status-success-foreground", "--cui-popup-status-warning-foreground", "--cui-popup-status-info-foreground", "--cui-popup-status-error-foreground", "--cui-popup-radius", "--cui-popup-background", "--cui-popup-foreground", "--cui-popup-border-color", "--cui-popup-border-width", "--cui-popup-shadow", "--cui-popup-backdrop-filter", "--cui-popup-backdrop-background", "--cui-popup-backdrop-blur", "--cui-popup-item-radius", "--cui-popup-item-font-size", "--cui-popup-item-icon-size", "--cui-popup-item-padding-block", "--cui-popup-item-padding-inline", "--cui-popup-item-min-height", "--cui-popup-item-highlight-shadow", "--cui-popup-item-foreground", "--cui-popup-item-highlight-background", "--cui-popup-item-highlight-foreground", "--cui-popup-item-highlight-muted-foreground", "--cui-popup-item-disabled-opacity", "--cui-popup-separator-color"];
|
|
3
3
|
export type PopupKnobStyle = Partial<Record<(typeof popupKnobs)[number], string>>;
|
|
4
4
|
//#endregion
|
|
@@ -26,6 +26,8 @@ const popupKnobs = [
|
|
|
26
26
|
"--cui-popup-command-heading-letter-spacing",
|
|
27
27
|
"--cui-popup-command-heading-text-transform",
|
|
28
28
|
"--cui-popup-dialog-max-inline-size",
|
|
29
|
+
"--cui-popup-item-description-foreground",
|
|
30
|
+
"--cui-popup-item-description-font-size",
|
|
29
31
|
"--cui-popup-shortcut-foreground",
|
|
30
32
|
"--cui-popup-tooltip-arrow-radius",
|
|
31
33
|
"--cui-popup-status-success-foreground",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getCountryCallingCode } from "react-phone-number-input/max";
|
|
2
1
|
import { AsYouType } from "libphonenumber-js/max";
|
|
2
|
+
import { getCountryCallingCode } from "react-phone-number-input/max";
|
|
3
3
|
//#region src/lib/phone-input-format.ts
|
|
4
4
|
function normalizePhoneInputText(value, country) {
|
|
5
5
|
if (!country) return value;
|
|
@@ -63,6 +63,14 @@
|
|
|
63
63
|
border-radius: var(--cui-card-radius);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
:where(
|
|
67
|
+
[data-control-family="card"][data-slot="root"]:has([data-control-family="card"][data-slot="link"])
|
|
68
|
+
:is(a[href], button, input, select, textarea, [role="checkbox"]):not([data-control-family="card"][data-slot="link"])
|
|
69
|
+
) {
|
|
70
|
+
position: relative;
|
|
71
|
+
z-index: 1;
|
|
72
|
+
}
|
|
73
|
+
|
|
66
74
|
:where([data-control-family="card"][data-slot="root"][data-size="sm"]) {
|
|
67
75
|
--cui-card-padding-block: calc(var(--spacing) * 3);
|
|
68
76
|
--cui-card-padding-inline: calc(var(--spacing) * 4);
|
|
@@ -53,23 +53,9 @@
|
|
|
53
53
|
font-size: var(--text-caption);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
:where([data-control-family="
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
border-style: dashed;
|
|
60
|
-
--_color-picker-swatch-add-border-color: var(--border);
|
|
61
|
-
border-color: var(--_color-picker-swatch-add-border-color);
|
|
62
|
-
--_color-picker-swatch-add-foreground: var(--muted-foreground);
|
|
63
|
-
color: var(--_color-picker-swatch-add-foreground);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
@media (hover: hover) {
|
|
67
|
-
:where([data-control-family="color-picker"][data-slot="swatch-add"]:hover:not(:disabled)) {
|
|
68
|
-
--_color-picker-swatch-add-border-color: oklch(from var(--foreground) l c h / 0.4);
|
|
69
|
-
border-color: var(--_color-picker-swatch-add-border-color);
|
|
70
|
-
--_color-picker-swatch-add-foreground: var(--foreground);
|
|
71
|
-
color: var(--_color-picker-swatch-add-foreground);
|
|
72
|
-
}
|
|
56
|
+
:where([data-control-family="button"][data-color-picker-swatch-add="true"]) {
|
|
57
|
+
--nest-radius: var(--radius-md);
|
|
58
|
+
--cui-button-height: calc(var(--spacing) * 6);
|
|
73
59
|
}
|
|
74
60
|
|
|
75
61
|
:where([data-control-family="color-picker"][data-slot="swatch"]) {
|
|
@@ -91,7 +77,7 @@
|
|
|
91
77
|
transition: box-shadow var(--duration-fast) var(--ease-standard);
|
|
92
78
|
}
|
|
93
79
|
|
|
94
|
-
:where([data-control-family="color-picker"]:is([data-slot="swatch"], [data-slot="
|
|
80
|
+
:where([data-control-family="color-picker"]:is([data-slot="swatch"], [data-slot="contrast-fix"]):disabled) {
|
|
95
81
|
opacity: var(--disabled-opacity);
|
|
96
82
|
}
|
|
97
83
|
|
|
@@ -59,8 +59,7 @@
|
|
|
59
59
|
border-radius: 9999px;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
:where([data-control-family="color-picker"][data-slot="swatch"])
|
|
63
|
-
:where([data-control-family="color-picker"][data-slot="swatch-add"]) {
|
|
62
|
+
:where([data-control-family="color-picker"][data-slot="swatch"]) {
|
|
64
63
|
inline-size: calc(var(--spacing) * 6);
|
|
65
64
|
block-size: calc(var(--spacing) * 6);
|
|
66
65
|
}
|
|
@@ -125,7 +124,7 @@
|
|
|
125
124
|
--_color-picker-thumb-elevation: var(--shadow-md);
|
|
126
125
|
}
|
|
127
126
|
|
|
128
|
-
:where([data-control-family="color-picker"]
|
|
127
|
+
:where([data-control-family="color-picker"][data-slot="slider-thumb"])::after {
|
|
129
128
|
content: "";
|
|
130
129
|
position: absolute;
|
|
131
130
|
inset: 50%;
|
|
@@ -135,7 +134,7 @@
|
|
|
135
134
|
}
|
|
136
135
|
|
|
137
136
|
@media (pointer: coarse) {
|
|
138
|
-
:where([data-control-family="color-picker"]
|
|
137
|
+
:where([data-control-family="color-picker"][data-slot="slider-thumb"])::after {
|
|
139
138
|
inline-size: max(100%, var(--touch-target));
|
|
140
139
|
block-size: max(100%, var(--touch-target));
|
|
141
140
|
}
|
|
@@ -240,6 +240,7 @@
|
|
|
240
240
|
}
|
|
241
241
|
|
|
242
242
|
:where([data-control-family="field"][data-field-kind="field"]) {
|
|
243
|
+
--cui-field-legend-foreground: var(--foreground);
|
|
243
244
|
--cui-field-legend-font-size: var(--text-label);
|
|
244
245
|
--cui-field-legend-font-weight: var(--font-weight-semibold);
|
|
245
246
|
--cui-field-label-radius: var(--radius-lg);
|
|
@@ -254,7 +255,7 @@
|
|
|
254
255
|
}
|
|
255
256
|
|
|
256
257
|
:where([data-control-family="field"][data-field-kind="field"][data-slot="legend"]) {
|
|
257
|
-
color: var(--foreground);
|
|
258
|
+
color: var(--cui-field-legend-foreground);
|
|
258
259
|
font-size: var(--cui-field-legend-font-size);
|
|
259
260
|
font-weight: var(--cui-field-legend-font-weight);
|
|
260
261
|
}
|
|
@@ -368,6 +369,12 @@
|
|
|
368
369
|
initial-value: 0px;
|
|
369
370
|
}
|
|
370
371
|
|
|
372
|
+
@property --cui-field-legend-foreground {
|
|
373
|
+
syntax: "<color>";
|
|
374
|
+
inherits: true;
|
|
375
|
+
initial-value: transparent;
|
|
376
|
+
}
|
|
377
|
+
|
|
371
378
|
@property --cui-field-legend-font-size {
|
|
372
379
|
syntax: "<length-percentage>";
|
|
373
380
|
inherits: true;
|
|
@@ -5,9 +5,6 @@
|
|
|
5
5
|
|
|
6
6
|
:where([data-control-family="gradient-editor"][data-slot="root"]) {
|
|
7
7
|
gap: calc(var(--spacing) * 3);
|
|
8
|
-
--cui-gradient-editor-add-border-color: var(--border);
|
|
9
|
-
--cui-gradient-editor-add-border-width: var(--control-rim-width);
|
|
10
|
-
--cui-gradient-editor-add-radius: 9999px;
|
|
11
8
|
--cui-gradient-editor-preview-radius: var(--radius-field);
|
|
12
9
|
--cui-gradient-editor-preview-ring-color: oklch(from var(--border) l c h / 0.6);
|
|
13
10
|
--cui-gradient-editor-stop-border-color: oklch(1 0 0);
|
|
@@ -48,19 +45,9 @@
|
|
|
48
45
|
transition: scale var(--duration-fast) var(--ease-standard);
|
|
49
46
|
}
|
|
50
47
|
|
|
51
|
-
:where([data-control-family="
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
border: var(--cui-gradient-editor-add-border-width) dashed var(--cui-gradient-editor-add-border-color);
|
|
55
|
-
border-radius: var(--cui-gradient-editor-add-radius);
|
|
56
|
-
color: var(--muted-foreground);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
@media (hover: hover) {
|
|
60
|
-
:where([data-control-family="gradient-editor"][data-slot="stop-add"]:hover:not(:disabled)) {
|
|
61
|
-
border-color: oklch(from var(--foreground) l c h / 0.4);
|
|
62
|
-
color: var(--foreground);
|
|
63
|
-
}
|
|
48
|
+
:where([data-control-family="button"][data-gradient-editor-stop-add="true"]) {
|
|
49
|
+
--nest-radius: 9999px;
|
|
50
|
+
--cui-button-height: calc(var(--spacing) * 7);
|
|
64
51
|
}
|
|
65
52
|
|
|
66
53
|
:where([data-control-family="gradient-editor"][data-slot="stop"][data-selected="true"]) {
|
|
@@ -77,19 +64,6 @@
|
|
|
77
64
|
}
|
|
78
65
|
|
|
79
66
|
@media (pointer: coarse) {
|
|
80
|
-
:where([data-control-family="gradient-editor"][data-slot="stop-add"]) {
|
|
81
|
-
position: relative;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
:where([data-control-family="gradient-editor"][data-slot="stop-add"])::after {
|
|
85
|
-
content: "";
|
|
86
|
-
position: absolute;
|
|
87
|
-
inset: 50%;
|
|
88
|
-
translate: -50% -50%;
|
|
89
|
-
inline-size: max(100%, var(--touch-target));
|
|
90
|
-
block-size: max(100%, var(--touch-target));
|
|
91
|
-
}
|
|
92
|
-
|
|
93
67
|
:where([data-control-family="gradient-editor"][data-slot="stop"])::after {
|
|
94
68
|
block-size: max(100%, var(--touch-target));
|
|
95
69
|
}
|
|
@@ -136,21 +110,3 @@
|
|
|
136
110
|
syntax: "*";
|
|
137
111
|
inherits: true;
|
|
138
112
|
}
|
|
139
|
-
|
|
140
|
-
@property --cui-gradient-editor-add-radius {
|
|
141
|
-
syntax: "<length-percentage>";
|
|
142
|
-
inherits: true;
|
|
143
|
-
initial-value: 0px;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
@property --cui-gradient-editor-add-border-color {
|
|
147
|
-
syntax: "<color>";
|
|
148
|
-
inherits: true;
|
|
149
|
-
initial-value: transparent;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
@property --cui-gradient-editor-add-border-width {
|
|
153
|
-
syntax: "<length>";
|
|
154
|
-
inherits: true;
|
|
155
|
-
initial-value: 0px;
|
|
156
|
-
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
@layer components {
|
|
2
|
-
:where([data-control-family="markdown"][data-slot="root"])
|
|
2
|
+
:where([data-control-family="markdown"][data-slot="root"]),
|
|
3
|
+
:where([data-control-family="markdown"]:not([data-control-family="markdown"][data-slot="root"] *)) {
|
|
3
4
|
--cui-markdown-foreground: oklch(from var(--foreground) l c h / 0.9);
|
|
4
5
|
--cui-markdown-blockquote-border-color: var(--border);
|
|
5
6
|
--cui-markdown-blockquote-foreground: var(--muted-foreground);
|
|
@@ -14,6 +15,9 @@
|
|
|
14
15
|
--cui-markdown-line-height: var(--leading-relaxed);
|
|
15
16
|
--cui-markdown-flow-gap: calc(var(--spacing) * 4);
|
|
16
17
|
--cui-markdown-heading-gap: calc(var(--spacing) * 6);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
:where([data-control-family="markdown"][data-slot="root"]) {
|
|
17
21
|
color: var(--cui-markdown-foreground);
|
|
18
22
|
font-size: var(--cui-markdown-font-size);
|
|
19
23
|
overflow-wrap: break-word;
|
|
@@ -169,6 +169,11 @@
|
|
|
169
169
|
letter-spacing: var(--cui-popup-shortcut-letter-spacing);
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
+
:where([data-control-family="popup"][data-slot="item-description"]) {
|
|
173
|
+
color: var(--cui-popup-item-description-foreground);
|
|
174
|
+
font-size: var(--cui-popup-item-description-font-size);
|
|
175
|
+
}
|
|
176
|
+
|
|
172
177
|
:where([data-control-family="popup"][data-popup-kind="command"][data-slot="shortcut"]) {
|
|
173
178
|
--cui-popup-shortcut-font-size: var(--text-label);
|
|
174
179
|
}
|
|
@@ -369,6 +374,18 @@
|
|
|
369
374
|
initial-value: 0px;
|
|
370
375
|
}
|
|
371
376
|
|
|
377
|
+
@property --cui-popup-item-description-foreground {
|
|
378
|
+
syntax: "<color>";
|
|
379
|
+
inherits: true;
|
|
380
|
+
initial-value: transparent;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
@property --cui-popup-item-description-font-size {
|
|
384
|
+
syntax: "<length-percentage>";
|
|
385
|
+
inherits: true;
|
|
386
|
+
initial-value: 0px;
|
|
387
|
+
}
|
|
388
|
+
|
|
372
389
|
@property --cui-popup-shortcut-foreground {
|
|
373
390
|
syntax: "<color>";
|
|
374
391
|
inherits: true;
|
|
@@ -28,6 +28,8 @@
|
|
|
28
28
|
--cui-popup-item-highlight-background: var(--hover-fill);
|
|
29
29
|
--cui-popup-item-highlight-foreground: var(--cui-popup-item-foreground);
|
|
30
30
|
--cui-popup-item-highlight-muted-foreground: var(--muted-foreground);
|
|
31
|
+
--cui-popup-item-description-foreground: var(--muted-foreground);
|
|
32
|
+
--cui-popup-item-description-font-size: var(--text-label);
|
|
31
33
|
--cui-popup-item-highlight-shadow: inset 0 0 0 1px oklch(from var(--foreground) l c h / 0.35);
|
|
32
34
|
--cui-popup-item-disabled-opacity: var(--disabled-opacity);
|
|
33
35
|
--cui-popup-label-padding-block: var(--cui-popup-item-padding-block);
|
|
@@ -209,6 +211,7 @@
|
|
|
209
211
|
) {
|
|
210
212
|
--cui-popup-shortcut-foreground: var(--cui-popup-item-highlight-foreground);
|
|
211
213
|
--cui-popup-submenu-indicator-foreground: var(--cui-popup-item-highlight-foreground);
|
|
214
|
+
--cui-popup-item-description-foreground: var(--cui-popup-item-highlight-muted-foreground);
|
|
212
215
|
--muted-foreground: var(--cui-popup-item-highlight-muted-foreground);
|
|
213
216
|
background-color: var(--cui-popup-item-highlight-background);
|
|
214
217
|
color: var(--cui-popup-item-highlight-foreground);
|
package/dist/styles/theme.css
CHANGED
|
@@ -710,6 +710,10 @@
|
|
|
710
710
|
outline-width: 0;
|
|
711
711
|
}
|
|
712
712
|
|
|
713
|
+
:where([data-control-family][data-focus-ring="none"]):focus-visible {
|
|
714
|
+
outline-style: none;
|
|
715
|
+
}
|
|
716
|
+
|
|
713
717
|
:where([data-control-family][data-highlighted]):focus-visible {
|
|
714
718
|
outline-offset: calc(var(--focus-ring-width) * -1);
|
|
715
719
|
}
|
|
@@ -2,6 +2,7 @@ import { OpenChangeEventDetails } from "../control-props.js";
|
|
|
2
2
|
import { ControlSize } from "../control-variants.js";
|
|
3
3
|
import { FieldKnobStyle } from "../knob-contracts/field-knobs.js";
|
|
4
4
|
import { PopupKnobStyle } from "../knob-contracts/popup-knobs.js";
|
|
5
|
+
import { InputGroupProps } from "./input-group.js";
|
|
5
6
|
import { CSSProperties, ComponentProps, ReactNode } from "react";
|
|
6
7
|
//#region src/ui/autocomplete.d.ts
|
|
7
8
|
export type AutocompleteProps<Value = string> = {
|
|
@@ -29,6 +30,7 @@ export type AutocompleteInputProps = Omit<Omit<ComponentProps<"input">, "size">,
|
|
|
29
30
|
} & {
|
|
30
31
|
size?: ControlSize;
|
|
31
32
|
};
|
|
33
|
+
export type AutocompleteInputGroupProps = Omit<InputGroupProps, "render">;
|
|
32
34
|
export type AutocompleteClearProps = ComponentProps<"button"> & {
|
|
33
35
|
style?: CSSProperties & FieldKnobStyle;
|
|
34
36
|
};
|
|
@@ -59,6 +61,7 @@ export type AutocompleteGroupLabelProps = Omit<ComponentProps<"div">, "style"> &
|
|
|
59
61
|
};
|
|
60
62
|
export declare function Autocomplete<Value = string>({ children, autoHighlight, ...props }: AutocompleteProps<Value>): import("react").JSX.Element;
|
|
61
63
|
export declare function AutocompleteClear({ className, children, ...props }: AutocompleteClearProps): import("react").JSX.Element;
|
|
64
|
+
export declare function AutocompleteInputGroup(props: AutocompleteInputGroupProps): import("react").JSX.Element;
|
|
62
65
|
export declare function AutocompleteInput({ size, className, ...props }: AutocompleteInputProps): import("react").JSX.Element;
|
|
63
66
|
export declare function AutocompleteContent({ className, children, sideOffset, ...props }: AutocompleteContentProps): import("react").JSX.Element;
|
|
64
67
|
export declare function AutocompleteList<Value = unknown>({ className, children, ...props }: AutocompleteListProps<Value>): import("react").JSX.Element;
|
package/dist/ui/autocomplete.js
CHANGED
|
@@ -4,7 +4,8 @@ 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 {
|
|
7
|
+
import { InputGroup, InputGroupAddon, useIsInsideInputGroup } from "./input-group.js";
|
|
8
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
9
|
import { Autocomplete as Autocomplete$1 } from "@base-ui/react/autocomplete";
|
|
9
10
|
//#region src/ui/autocomplete.tsx
|
|
10
11
|
function Autocomplete({ children, autoHighlight = true, ...props }) {
|
|
@@ -38,7 +39,21 @@ function AutocompleteClear({ className, children, ...props }) {
|
|
|
38
39
|
})
|
|
39
40
|
});
|
|
40
41
|
}
|
|
42
|
+
function AutocompleteInputGroup(props) {
|
|
43
|
+
return /* @__PURE__ */ jsx(InputGroup, {
|
|
44
|
+
...props,
|
|
45
|
+
render: /* @__PURE__ */ jsx(Autocomplete$1.InputGroup, {})
|
|
46
|
+
});
|
|
47
|
+
}
|
|
41
48
|
function AutocompleteInput({ size = "md", className, ...props }) {
|
|
49
|
+
if (useIsInsideInputGroup()) return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Autocomplete$1.Input, {
|
|
50
|
+
...props,
|
|
51
|
+
"data-control-ui": "input-group",
|
|
52
|
+
"data-control-family": "field",
|
|
53
|
+
"data-field-kind": "input-group",
|
|
54
|
+
"data-slot": "input",
|
|
55
|
+
className: cn("h-full min-w-0 flex-1", className)
|
|
56
|
+
}), /* @__PURE__ */ jsx(InputGroupAddon, { children: /* @__PURE__ */ jsx(AutocompleteClear, {}) })] });
|
|
42
57
|
return /* @__PURE__ */ jsxs(Autocomplete$1.InputGroup, {
|
|
43
58
|
"data-control-ui": "autocomplete",
|
|
44
59
|
"data-field-kind": "autocomplete",
|
|
@@ -155,4 +170,4 @@ function AutocompleteGroupLabel({ className, children, ...props }) {
|
|
|
155
170
|
});
|
|
156
171
|
}
|
|
157
172
|
//#endregion
|
|
158
|
-
export { Autocomplete, AutocompleteClear, AutocompleteContent, AutocompleteEmpty, AutocompleteGroup, AutocompleteGroupLabel, AutocompleteInput, AutocompleteItem, AutocompleteList };
|
|
173
|
+
export { Autocomplete, AutocompleteClear, AutocompleteContent, AutocompleteEmpty, AutocompleteGroup, AutocompleteGroupLabel, AutocompleteInput, AutocompleteInputGroup, AutocompleteItem, AutocompleteList };
|