@threadlabs/looma 0.17.3 → 0.18.0
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/components/ui-avatar/ui-avatar.html +8 -4
- package/components/ui-badge/ui-badge.html +28 -34
- package/components/ui-button/ui-button.html +5 -0
- package/components/ui-checkbox/ui-checkbox.html +5 -5
- package/components/ui-combobox/ui-combobox.html +4 -48
- package/components/ui-icon-button/ui-icon-button.html +7 -7
- package/components/ui-input/ui-input.html +1 -1
- package/components/ui-input-group/ui-input-group.html +2 -2
- package/components/ui-listbox/ui-listbox.html +88 -12
- package/components/ui-listbox/ui-listbox.js +162 -18
- package/components/ui-search-result-row/ui-search-result-row.html +2 -6
- package/components/ui-search-shell/ui-search-shell.html +2 -11
- package/components/ui-select/ui-select.html +1 -1
- package/components/ui-spinner/ui-spinner.html +45 -18
- package/components/ui-textarea/ui-textarea.html +1 -1
- package/components/ui-tooltip/ui-tooltip.html +2 -2
- package/dist/index.js +1 -1
- package/editor/chunks/extensions.js +5 -0
- package/package.json +1 -1
- package/styles/ui-avatar.css +6 -2
- package/styles/ui-badge.css +30 -40
- package/styles/ui-button.css +7 -0
- package/styles/ui-checkbox.css +6 -6
- package/styles/ui-combobox.css +0 -52
- package/styles/ui-icon-button.css +7 -7
- package/styles/ui-input-group.css +2 -2
- package/styles/ui-input.css +1 -1
- package/styles/ui-listbox.css +33 -8
- package/styles/ui-search-result-row.css +2 -6
- package/styles/ui-search-shell.css +2 -13
- package/styles/ui-select.css +1 -1
- package/styles/ui-spinner.css +38 -19
- package/styles/ui-textarea.css +1 -1
- package/styles/ui-tooltip.css +2 -2
- package/tokens.css +67 -2
- package/vanilla/UiCombobox.js +9 -1
- package/vanilla/UiListbox.d.ts +3 -1
- package/vanilla/UiListbox.js +65 -18
- package/vanilla/UiSpinner.js +19 -1
- package/vue/UiAvatar.vue +11 -2
- package/vue/UiBadge.vue +30 -36
- package/vue/UiButton.vue +5 -0
- package/vue/UiCheckbox.vue +5 -5
- package/vue/UiCombobox.vue +4 -49
- package/vue/UiIconButton.vue +10 -7
- package/vue/UiInput.vue +1 -1
- package/vue/UiInputGroup.vue +2 -2
- package/vue/UiListbox.d.ts +18 -5
- package/vue/UiListbox.vue +142 -25
- package/vue/UiSearchResultRow.vue +2 -6
- package/vue/UiSearchShell.vue +2 -13
- package/vue/UiSelect.vue +1 -1
- package/vue/UiSpinner.vue +45 -18
- package/vue/UiTextarea.vue +1 -1
- package/vue/UiTooltip.vue +2 -2
- package/vue/chunks/UiAvatar.js +2 -1
- package/vue/chunks/UiBadge.js +1 -1
- package/vue/chunks/UiButton.js +1 -1
- package/vue/chunks/UiCheckbox.js +1 -1
- package/vue/chunks/UiCombobox.js +11 -2
- package/vue/chunks/UiIconButton.js +1 -1
- package/vue/chunks/UiInput.js +1 -1
- package/vue/chunks/UiInputGroup.js +1 -1
- package/vue/chunks/UiListbox.js +134 -20
- package/vue/chunks/UiSearchResultRow.js +1 -1
- package/vue/chunks/UiSearchShell.js +1 -1
- package/vue/chunks/UiSelect.js +1 -1
- package/vue/chunks/UiSpinner.js +29 -3
- package/vue/chunks/UiTextarea.js +1 -1
- package/vue/chunks/UiTooltip.js +1 -1
- package/vue/components.css +426 -440
|
@@ -8638,6 +8638,11 @@ function parseHtmlSlice(schema, value) {
|
|
|
8638
8638
|
if (/\s$/.test(child.textContent) || /^\s/.test(next.textContent)) continue;
|
|
8639
8639
|
wrapper.insertBefore(parsed.createTextNode(" "), next);
|
|
8640
8640
|
}
|
|
8641
|
+
for (const pre of parsed.body.querySelectorAll("pre")) {
|
|
8642
|
+
let last = pre;
|
|
8643
|
+
while (last.lastChild) last = last.lastChild;
|
|
8644
|
+
if (last.nodeType === Node.TEXT_NODE) last.textContent = last.textContent?.replace(/\r?\n$/, "") ?? "";
|
|
8645
|
+
}
|
|
8641
8646
|
const container = document.createElement("div");
|
|
8642
8647
|
container.append(purify.sanitize(parsed.body.innerHTML, {
|
|
8643
8648
|
USE_PROFILES: { html: true },
|
package/package.json
CHANGED
package/styles/ui-avatar.css
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
inline-size: 2.5rem;
|
|
31
31
|
block-size: 2.5rem;
|
|
32
32
|
border-radius: var(--ui-avatar-radius, var(--ui-radius-round));
|
|
33
|
-
border: 1px solid var(--ui-avatar-border, var(--ui-
|
|
33
|
+
border: 1px solid var(--ui-avatar-border, color-mix(in srgb, var(--ui-accent-solid) 35%, var(--ui-surface-default)));
|
|
34
34
|
background: var(--ui-avatar-surface, var(--ui-accent-soft));
|
|
35
35
|
color: var(--ui-avatar-text, var(--ui-accent-subtle-text, var(--ui-accent-solid)));
|
|
36
36
|
font: inherit;
|
|
@@ -46,6 +46,10 @@
|
|
|
46
46
|
font-size: var(--ui-font-size-xs);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
:scope[data-ui-avatar-state~="hasImage"] {
|
|
50
|
+
border-color: var(--ui-avatar-border, var(--ui-border-strong));
|
|
51
|
+
}
|
|
52
|
+
|
|
49
53
|
:scope[data-ui-avatar-state~="shape=square"] {
|
|
50
54
|
border-radius: var(--ui-avatar-radius, var(--ui-radius-md));
|
|
51
55
|
}
|
|
@@ -53,7 +57,7 @@
|
|
|
53
57
|
/* An outline, not a dot: the avatar clips its content to the circle, and an outline is drawn
|
|
54
58
|
outside the box, so the ring survives the clip and the overlap in an Avatar Group. */
|
|
55
59
|
:scope[data-ui-avatar-state~="active"] {
|
|
56
|
-
outline:
|
|
60
|
+
outline: 1px solid var(--ui-avatar-active-ring, var(--ui-accent-solid));
|
|
57
61
|
outline-offset: 1px;
|
|
58
62
|
}
|
|
59
63
|
|
package/styles/ui-badge.css
CHANGED
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
/* This component's hooks style the element they are set on, and never a nested one. */
|
|
48
48
|
|
|
49
49
|
:scope {
|
|
50
|
-
--_badge-surface: var(--ui-surface-subtle);
|
|
50
|
+
--_badge-surface: color-mix(in srgb, var(--ui-surface-subtle) 80%, var(--ui-surface-default));
|
|
51
51
|
--_badge-text: var(--ui-text-secondary);
|
|
52
52
|
/* Sit between the soft fill and its stronger theme ink. */
|
|
53
53
|
--_badge-border: color-mix(in srgb, var(--_badge-surface) 75%, var(--_badge-text) 25%);
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
surface, text, and border hooks. Each value is invalid, so the tone shows, while it is unset. The
|
|
56
56
|
mixes keep 4.5:1 text contrast for any colour, in a light theme or a dark one. */
|
|
57
57
|
--_ui-badge-color: var(--ui-badge-color);
|
|
58
|
-
--_badge-color-wash: color-mix(in oklab, var(--_ui-badge-color)
|
|
58
|
+
--_badge-color-wash: color-mix(in oklab, var(--_ui-badge-color) 13%, var(--ui-surface-default));
|
|
59
59
|
--_badge-color-ink: color-mix(in oklab, var(--_ui-badge-color) 35%, var(--ui-text-primary));
|
|
60
60
|
--_badge-color-surface: var(--_badge-color-wash);
|
|
61
61
|
--_badge-color-border: color-mix(in srgb, var(--_badge-color-wash) 75%, var(--_badge-color-ink) 25%);
|
|
@@ -123,32 +123,32 @@
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
:scope[data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=accent"] {
|
|
126
|
-
--_badge-surface: color-mix(in srgb, var(--ui-accent-solid)
|
|
127
|
-
--_badge-border: color-mix(in srgb, var(--ui-accent-solid)
|
|
126
|
+
--_badge-surface: color-mix(in srgb, var(--ui-accent-solid) 19%, var(--ui-surface-default));
|
|
127
|
+
--_badge-border: color-mix(in srgb, var(--ui-accent-solid) 25%, var(--ui-surface-default));
|
|
128
128
|
--_badge-text: var(--ui-accent-subtle-text, var(--ui-accent-solid));
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
:scope[data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=danger"] {
|
|
132
|
-
--_badge-surface: color-mix(in srgb, var(--ui-danger-solid)
|
|
133
|
-
--_badge-border: color-mix(in srgb, var(--ui-danger-solid)
|
|
132
|
+
--_badge-surface: color-mix(in srgb, var(--ui-danger-solid) 19%, var(--ui-surface-default));
|
|
133
|
+
--_badge-border: color-mix(in srgb, var(--ui-danger-solid) 25%, var(--ui-surface-default));
|
|
134
134
|
--_badge-text: var(--ui-danger-subtle-text, var(--ui-danger-solid));
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
:scope[data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=success"] {
|
|
138
|
-
--_badge-surface: color-mix(in srgb, var(--ui-success-solid)
|
|
139
|
-
--_badge-border: color-mix(in srgb, var(--ui-success-solid)
|
|
138
|
+
--_badge-surface: color-mix(in srgb, var(--ui-success-solid) 19%, var(--ui-surface-default));
|
|
139
|
+
--_badge-border: color-mix(in srgb, var(--ui-success-solid) 25%, var(--ui-surface-default));
|
|
140
140
|
--_badge-text: var(--ui-success-subtle-text, var(--ui-success-solid));
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
:scope[data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=warning"] {
|
|
144
|
-
--_badge-surface: color-mix(in srgb, var(--ui-warning-solid)
|
|
145
|
-
--_badge-border: color-mix(in srgb, var(--ui-warning-solid)
|
|
144
|
+
--_badge-surface: color-mix(in srgb, var(--ui-warning-solid) 19%, var(--ui-surface-default));
|
|
145
|
+
--_badge-border: color-mix(in srgb, var(--ui-warning-solid) 25%, var(--ui-surface-default));
|
|
146
146
|
--_badge-text: var(--ui-warning-subtle-text, var(--ui-warning-solid));
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
:scope[data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=info"] {
|
|
150
|
-
--_badge-surface: color-mix(in srgb, var(--ui-info-solid)
|
|
151
|
-
--_badge-border: color-mix(in srgb, var(--ui-info-solid)
|
|
150
|
+
--_badge-surface: color-mix(in srgb, var(--ui-info-solid) 19%, var(--ui-surface-default));
|
|
151
|
+
--_badge-border: color-mix(in srgb, var(--ui-info-solid) 25%, var(--ui-surface-default));
|
|
152
152
|
--_badge-text: var(--ui-info-subtle-text, var(--ui-info-solid));
|
|
153
153
|
}
|
|
154
154
|
|
|
@@ -194,54 +194,48 @@
|
|
|
194
194
|
--_badge-text: var(--ui-info-subtle-text, var(--ui-info-solid));
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
/*
|
|
198
|
-
|
|
199
|
-
label never runs into it. */
|
|
197
|
+
/* The clipped point needs an inset surface over an outer border-colour shape: a native border
|
|
198
|
+
has no diagonal edge to follow. Keep this edge for every tag variant. */
|
|
200
199
|
:scope[data-ui-badge-state~="shape=tag"] {
|
|
201
200
|
--_badge-point: var(--ui-badge-point, var(--ui-space-2));
|
|
202
201
|
|
|
202
|
+
position: relative;
|
|
203
|
+
isolation: isolate;
|
|
203
204
|
border-color: transparent;
|
|
204
205
|
border-radius: 0;
|
|
206
|
+
background: var(--ui-badge-border, var(--_badge-color-border, var(--_badge-border)));
|
|
205
207
|
padding-inline-end: calc(var(--ui-badge-padding-inline, var(--ui-space-2)) + var(--_badge-point));
|
|
206
208
|
clip-path: polygon(0 0, calc(100% - var(--_badge-point)) 0, 100% 50%, calc(100% - var(--_badge-point)) 100%, 0 100%);
|
|
207
209
|
}
|
|
208
210
|
|
|
209
|
-
:scope[data-ui-badge-state~="shape=tag"]
|
|
210
|
-
padding-inline-end: var(--ui-badge-padding-inline, var(--ui-space-2));
|
|
211
|
-
padding-inline-start: calc(var(--ui-badge-padding-inline, var(--ui-space-2)) + var(--_badge-point));
|
|
212
|
-
clip-path: polygon(var(--_badge-point) 0, 100% 0, 100% 100%, var(--_badge-point) 100%, 0 50%);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/* The tag clips its point, including the native border. Draw the outer shape in the border
|
|
216
|
-
colour and an inset inner shape in the surface colour to keep a visible diagonal edge. */
|
|
217
|
-
:scope[data-ui-badge-state~="variant=outline"][data-ui-badge-state~="shape=tag"] {
|
|
218
|
-
position: relative;
|
|
219
|
-
isolation: isolate;
|
|
220
|
-
background: var(--ui-badge-border, var(--_badge-color-border, var(--_badge-border)));
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
:scope[data-ui-badge-state~="variant=outline"][data-ui-badge-state~="shape=tag"]::before {
|
|
211
|
+
:scope[data-ui-badge-state~="shape=tag"]::before {
|
|
224
212
|
content: "";
|
|
225
213
|
position: absolute;
|
|
226
|
-
inset:
|
|
214
|
+
inset: 0;
|
|
227
215
|
z-index: -1;
|
|
228
216
|
background: var(--_badge-outline-surface);
|
|
229
217
|
clip-path: polygon(0 0, calc(100% - var(--_badge-point)) 0, 100% 50%, calc(100% - var(--_badge-point)) 100%, 0 100%);
|
|
230
218
|
pointer-events: none;
|
|
231
219
|
}
|
|
232
220
|
|
|
233
|
-
:scope[data-ui-badge-state~="
|
|
221
|
+
:scope[data-ui-badge-state~="shape=tag"]:dir(rtl) {
|
|
222
|
+
padding-inline-end: var(--ui-badge-padding-inline, var(--ui-space-2));
|
|
223
|
+
padding-inline-start: calc(var(--ui-badge-padding-inline, var(--ui-space-2)) + var(--_badge-point));
|
|
224
|
+
clip-path: polygon(var(--_badge-point) 0, 100% 0, 100% 100%, var(--_badge-point) 100%, 0 50%);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
:scope[data-ui-badge-state~="shape=tag"]:dir(rtl)::before {
|
|
234
228
|
clip-path: polygon(var(--_badge-point) 0, 100% 0, 100% 100%, var(--_badge-point) 100%, 0 50%);
|
|
235
229
|
}
|
|
236
230
|
|
|
237
231
|
@media (forced-colors: active) {
|
|
238
|
-
:scope[data-ui-badge-state~="
|
|
232
|
+
:scope[data-ui-badge-state~="shape=tag"] {
|
|
239
233
|
forced-color-adjust: none;
|
|
240
234
|
background: CanvasText;
|
|
241
235
|
color: CanvasText;
|
|
242
236
|
}
|
|
243
237
|
|
|
244
|
-
:scope[data-ui-badge-state~="
|
|
238
|
+
:scope[data-ui-badge-state~="shape=tag"]::before {
|
|
245
239
|
background: Canvas;
|
|
246
240
|
}
|
|
247
241
|
}
|
|
@@ -263,12 +257,8 @@
|
|
|
263
257
|
/* A solid colour fills with the ink. Its text is the page surface, mixed at 0% only so that it too is
|
|
264
258
|
invalid while the hook is unset. */
|
|
265
259
|
|
|
266
|
-
/*
|
|
267
|
-
|
|
268
|
-
label never runs into it. */
|
|
269
|
-
|
|
270
|
-
/* The tag clips its point, including the native border. Draw the outer shape in the border
|
|
271
|
-
colour and an inset inner shape in the surface colour to keep a visible diagonal edge. */
|
|
260
|
+
/* The clipped point needs an inset surface over an outer border-colour shape: a native border
|
|
261
|
+
has no diagonal edge to follow. Keep this edge for every tag variant. */
|
|
272
262
|
|
|
273
263
|
@media (forced-colors: active) {
|
|
274
264
|
}
|
package/styles/ui-button.css
CHANGED
|
@@ -131,6 +131,11 @@
|
|
|
131
131
|
margin: 0;
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
+
/* An anchor keeps the boxed button look even when an app styles ordinary links. */
|
|
135
|
+
:scope:is(a) {
|
|
136
|
+
text-decoration: none;
|
|
137
|
+
}
|
|
138
|
+
|
|
134
139
|
.spinner-wrap {
|
|
135
140
|
display: inline-flex;
|
|
136
141
|
flex: none;
|
|
@@ -363,6 +368,8 @@
|
|
|
363
368
|
@scope ([data-component~="ui-button"]) to ([data-component]) {
|
|
364
369
|
/* This component's hooks style the element they are set on, and never a nested one. */
|
|
365
370
|
|
|
371
|
+
/* An anchor keeps the boxed button look even when an app styles ordinary links. */
|
|
372
|
+
|
|
366
373
|
@supports (text-box-trim: trim-both) {
|
|
367
374
|
}
|
|
368
375
|
|
package/styles/ui-checkbox.css
CHANGED
|
@@ -14,15 +14,15 @@
|
|
|
14
14
|
@keyframes ui-checkbox-check {
|
|
15
15
|
from {
|
|
16
16
|
opacity: 0;
|
|
17
|
-
transform:
|
|
17
|
+
transform: translateY(-0.09rem) rotate(45deg) scale(0.55);
|
|
18
18
|
}
|
|
19
19
|
65% {
|
|
20
20
|
opacity: 1;
|
|
21
|
-
transform:
|
|
21
|
+
transform: translateY(-0.09rem) rotate(45deg) scale(1.12);
|
|
22
22
|
}
|
|
23
23
|
to {
|
|
24
24
|
opacity: 1;
|
|
25
|
-
transform:
|
|
25
|
+
transform: translateY(-0.09rem) rotate(45deg) scale(1);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
@scope ([data-component~="ui-checkbox"]) to ([data-component], [data-slotted]) {
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
box-shadow: var(--ui-control-inset);
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
/* Centre the tick's box
|
|
100
|
+
/* Centre the tick's box and lift it slightly for the rotated check shape. */
|
|
101
101
|
input:checked::after {
|
|
102
102
|
inset: 0;
|
|
103
103
|
margin: auto;
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
border-color: var(--ui-text-on-accent);
|
|
110
110
|
border-width: 0 0.125rem 0.125rem 0;
|
|
111
111
|
opacity: 1;
|
|
112
|
-
transform:
|
|
112
|
+
transform: translateY(-0.09rem) rotate(45deg);
|
|
113
113
|
animation: ui-checkbox-check 180ms var(--ui-motion-ease-out, cubic-bezier(0.16, 1, 0.3, 1)) both;
|
|
114
114
|
}
|
|
115
115
|
|
|
@@ -197,7 +197,7 @@
|
|
|
197
197
|
|
|
198
198
|
/* The label, and under it an optional line saying what the choice means. */
|
|
199
199
|
|
|
200
|
-
/* Centre the tick's box
|
|
200
|
+
/* Centre the tick's box and lift it slightly for the rotated check shape. */
|
|
201
201
|
|
|
202
202
|
@media (prefers-reduced-motion: reduce) {
|
|
203
203
|
}
|
package/styles/ui-combobox.css
CHANGED
|
@@ -254,21 +254,6 @@
|
|
|
254
254
|
[hidden] {
|
|
255
255
|
display: none;
|
|
256
256
|
}
|
|
257
|
-
.option {
|
|
258
|
-
padding: var(--ui-space-2) var(--ui-space-3);
|
|
259
|
-
border-radius: var(--ui-radius-sm);
|
|
260
|
-
cursor: pointer;
|
|
261
|
-
overflow-wrap: anywhere;
|
|
262
|
-
}
|
|
263
|
-
.option:hover, .option.active {
|
|
264
|
-
background: var(--ui-surface-muted);
|
|
265
|
-
outline: 1px solid var(--ui-focus-ring);
|
|
266
|
-
outline-offset: -1px;
|
|
267
|
-
}
|
|
268
|
-
.option[aria-disabled="true"] {
|
|
269
|
-
color: var(--ui-disabled-text);
|
|
270
|
-
cursor: not-allowed;
|
|
271
|
-
}
|
|
272
257
|
.option[aria-disabled="true"] .primary,
|
|
273
258
|
.option[aria-disabled="true"] .secondary {
|
|
274
259
|
color: var(--ui-disabled-text);
|
|
@@ -336,39 +321,6 @@
|
|
|
336
321
|
}
|
|
337
322
|
}
|
|
338
323
|
|
|
339
|
-
/* Multiple mode: every option carries a checkbox, so a list that takes several answers says so
|
|
340
|
-
before anything is picked. aria-selected is the state; this draws it.
|
|
341
|
-
Longhands, not shorthands: lowering drops a shorthand that omits a component. */
|
|
342
|
-
:scope[data-ui-combobox-state~="multiple"] .option {
|
|
343
|
-
display: flex;
|
|
344
|
-
gap: var(--ui-space-2);
|
|
345
|
-
align-items: center;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
:scope[data-ui-combobox-state~="multiple"] .option::before {
|
|
349
|
-
content: "";
|
|
350
|
-
flex: none;
|
|
351
|
-
inline-size: 1.125rem;
|
|
352
|
-
block-size: 1.125rem;
|
|
353
|
-
border-style: solid;
|
|
354
|
-
border-width: 1px;
|
|
355
|
-
border-color: var(--ui-control-border-hover, var(--ui-border-strong));
|
|
356
|
-
border-radius: var(--ui-radius-sm);
|
|
357
|
-
background-color: var(--ui-control-surface, var(--ui-surface-default));
|
|
358
|
-
background-repeat: no-repeat;
|
|
359
|
-
background-position: center;
|
|
360
|
-
background-size: 0.7rem;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
:scope[data-ui-combobox-state~="multiple"] .option[aria-selected="true"]::before {
|
|
364
|
-
border-color: var(--ui-accent-solid);
|
|
365
|
-
background-color: var(--ui-accent-solid);
|
|
366
|
-
background-image: var(
|
|
367
|
-
--_ui-combobox-option-check,
|
|
368
|
-
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12 5 5 9-9'/%3E%3C/svg%3E")
|
|
369
|
-
);
|
|
370
|
-
}
|
|
371
|
-
|
|
372
324
|
/* Multiple mode keeps one control height. Chips and the input scroll within the entry,
|
|
373
325
|
while the clear and disclosure controls remain fixed at the end of the field. */
|
|
374
326
|
:scope[data-ui-combobox-state~="multiple"] .field {
|
|
@@ -448,10 +400,6 @@
|
|
|
448
400
|
@media (forced-colors: active) {
|
|
449
401
|
}
|
|
450
402
|
|
|
451
|
-
/* Multiple mode: every option carries a checkbox, so a list that takes several answers says so
|
|
452
|
-
before anything is picked. aria-selected is the state; this draws it.
|
|
453
|
-
Longhands, not shorthands: lowering drops a shorthand that omits a component. */
|
|
454
|
-
|
|
455
403
|
/* Multiple mode keeps one control height. Chips and the input scroll within the entry,
|
|
456
404
|
while the clear and disclosure controls remain fixed at the end of the field. */
|
|
457
405
|
/* Size variants keep their control height as selections are added. */
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
@media (hover: hover) and (pointer: fine) {
|
|
118
118
|
:scope[data-ui-icon-button-state~="anticipatory"]:not(:scope[data-ui-icon-button-state~="variant=solid"], :scope[data-ui-icon-button-state~="loading"], :scope[data-ui-icon-button-state~="pending"], :disabled, [data-ui-proximity="near"], :hover, :focus-visible) {
|
|
119
119
|
border-color: transparent;
|
|
120
|
-
background: transparent;
|
|
120
|
+
background-color: transparent;
|
|
121
121
|
box-shadow: none;
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
margin: 0;
|
|
146
146
|
border: 1px solid transparent;
|
|
147
147
|
border-radius: var(--ui-icon-button-radius, var(--ui-action-radius, var(--ui-radius-md)));
|
|
148
|
-
background: var(--ui-icon-button-surface, transparent);
|
|
148
|
+
background-color: var(--ui-icon-button-surface, transparent);
|
|
149
149
|
color: inherit;
|
|
150
150
|
display: inline-flex;
|
|
151
151
|
align-items: center;
|
|
@@ -217,14 +217,14 @@
|
|
|
217
217
|
|
|
218
218
|
:scope[data-ui-icon-button-state~="variant=outline"] {
|
|
219
219
|
border-color: var(--ui-icon-button-border, var(--ui-control-border, var(--ui-border-strong)));
|
|
220
|
-
background: var(--ui-icon-button-outline-surface, var(--ui-surface-default));
|
|
220
|
+
background-color: var(--ui-icon-button-outline-surface, var(--ui-surface-default));
|
|
221
221
|
background-image: var(--ui-raised-highlight);
|
|
222
222
|
color: var(--ui-icon-button-outline-text, var(--ui-text-primary));
|
|
223
223
|
box-shadow: var(--ui-raised);
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
:scope[data-ui-icon-button-state~="variant=solid"] {
|
|
227
|
-
background: var(--ui-icon-button-solid-surface, var(--ui-accent-solid));
|
|
227
|
+
background-color: var(--ui-icon-button-solid-surface, var(--ui-accent-solid));
|
|
228
228
|
background-image: var(--ui-raised-highlight);
|
|
229
229
|
color: var(--ui-icon-button-solid-text, var(--ui-text-on-accent));
|
|
230
230
|
box-shadow: var(
|
|
@@ -235,7 +235,7 @@
|
|
|
235
235
|
|
|
236
236
|
:scope:hover:enabled:not([aria-disabled="true"]) {
|
|
237
237
|
/* Derived from the text colour so the ghost hover shows on any background. */
|
|
238
|
-
background: var(--ui-icon-button-hover-surface, color-mix(in srgb, currentColor 8%, transparent));
|
|
238
|
+
background-color: var(--ui-icon-button-hover-surface, color-mix(in srgb, currentColor 8%, transparent));
|
|
239
239
|
color: var(--ui-icon-button-hover-text, var(--ui-text-primary));
|
|
240
240
|
}
|
|
241
241
|
|
|
@@ -244,7 +244,7 @@
|
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
:scope[data-ui-icon-button-state~="variant=solid"]:hover:enabled:not([aria-disabled="true"]) {
|
|
247
|
-
background: var(--ui-icon-button-solid-hover-surface, var(--ui-accent-hover));
|
|
247
|
+
background-color: var(--ui-icon-button-solid-hover-surface, var(--ui-accent-hover));
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
:scope:active:enabled:not([aria-disabled="true"]) {
|
|
@@ -279,7 +279,7 @@
|
|
|
279
279
|
/* Disabled is a flat neutral control, independent of the active variant's tone. */
|
|
280
280
|
:scope:disabled {
|
|
281
281
|
border-color: var(--ui-disabled-border);
|
|
282
|
-
background: var(--ui-disabled-surface);
|
|
282
|
+
background-color: var(--ui-disabled-surface);
|
|
283
283
|
color: var(--ui-disabled-text);
|
|
284
284
|
filter: var(--ui-icon-button-disabled-filter, var(--ui-disabled-filter));
|
|
285
285
|
opacity: var(--ui-icon-button-disabled-opacity, 1);
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
:scope:hover:not(:has(input:focus, input:disabled)) {
|
|
71
|
+
:scope:hover:not(:has(input:focus, input:disabled, input:read-only, [aria-invalid="true"], :is(:user-invalid, [data-user-invalid]))) {
|
|
72
72
|
border-color: var(--ui-control-border-hover, var(--ui-text-secondary));
|
|
73
73
|
}
|
|
74
74
|
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
flex: none;
|
|
120
120
|
align-items: center;
|
|
121
121
|
padding-inline: var(--ui-space-2);
|
|
122
|
-
color: var(--ui-text-
|
|
122
|
+
color: var(--ui-text-muted);
|
|
123
123
|
font-family: var(--ui-font-family-mono);
|
|
124
124
|
font-size: var(--ui-font-size-sm);
|
|
125
125
|
white-space: nowrap;
|
package/styles/ui-input.css
CHANGED
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
opacity: 1;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
:scope:hover:not(:focus):not(:disabled) {
|
|
114
|
+
:scope:hover:not(:focus):not(:disabled):not(:read-only):not([aria-invalid="true"]):not(:is(:user-invalid, [data-user-invalid])) {
|
|
115
115
|
border-color: var(--ui-input-border-hover, var(--_ui-default-input-border-hover, var(--ui-control-border-hover, var(--ui-text-secondary))));
|
|
116
116
|
}
|
|
117
117
|
|
package/styles/ui-listbox.css
CHANGED
|
@@ -21,29 +21,55 @@
|
|
|
21
21
|
}
|
|
22
22
|
@scope ([data-component~="ui-listbox"]) to ([data-component], [data-slotted]) {
|
|
23
23
|
:scope {
|
|
24
|
+
position: relative;
|
|
24
25
|
box-sizing: border-box;
|
|
25
26
|
display: block;
|
|
26
27
|
inline-size: 100%;
|
|
27
28
|
min-inline-size: 0;
|
|
28
|
-
min-block-size: var(--ui-control-min-block-size);
|
|
29
29
|
margin: 0;
|
|
30
30
|
padding: var(--ui-space-1);
|
|
31
31
|
border: 1px solid var(--ui-listbox-border, var(--ui-control-border));
|
|
32
32
|
border-radius: var(--ui-listbox-radius, var(--ui-field-radius, var(--ui-radius-md)));
|
|
33
33
|
background: var(--ui-listbox-surface, var(--ui-control-surface));
|
|
34
34
|
color: var(--ui-text-primary);
|
|
35
|
-
color-scheme: light dark;
|
|
36
35
|
font: inherit;
|
|
37
36
|
line-height: var(--ui-line-height-md);
|
|
38
37
|
box-shadow: var(--ui-control-inset);
|
|
38
|
+
outline: none;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
.choices {
|
|
42
|
+
max-block-size: calc(max(2, var(--_rows, 5)) * var(--ui-control-size-md));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
:scope:not([data-enhanced]) {
|
|
46
|
+
padding: 0;
|
|
47
|
+
border: 0;
|
|
48
|
+
background: transparent;
|
|
49
|
+
box-shadow: none;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
:scope:not([data-enhanced]) .choices,
|
|
53
|
+
:scope[data-enhanced] .fallback {
|
|
54
|
+
display: none;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.fallback {
|
|
58
|
+
box-sizing: border-box;
|
|
59
|
+
inline-size: 100%;
|
|
44
60
|
font: inherit;
|
|
45
61
|
}
|
|
46
62
|
|
|
63
|
+
.validity {
|
|
64
|
+
position: absolute;
|
|
65
|
+
inline-size: 1px;
|
|
66
|
+
block-size: 1px;
|
|
67
|
+
overflow: hidden;
|
|
68
|
+
clip-path: inset(50%);
|
|
69
|
+
opacity: 0;
|
|
70
|
+
pointer-events: none;
|
|
71
|
+
}
|
|
72
|
+
|
|
47
73
|
:scope:focus-visible {
|
|
48
74
|
border-color: var(--ui-control-focus);
|
|
49
75
|
outline: 2px solid var(--ui-focus-ring);
|
|
@@ -51,12 +77,11 @@
|
|
|
51
77
|
box-shadow: var(--ui-listbox-focus-shadow, var(--ui-focus-halo));
|
|
52
78
|
}
|
|
53
79
|
|
|
54
|
-
:scope[aria-invalid="true"]
|
|
55
|
-
:scope:is(:user-invalid, [data-user-invalid]) {
|
|
80
|
+
:scope[aria-invalid="true"] {
|
|
56
81
|
border-color: var(--ui-listbox-invalid-border, var(--ui-field-danger, var(--ui-danger)));
|
|
57
82
|
}
|
|
58
83
|
|
|
59
|
-
:scope
|
|
84
|
+
:scope[aria-disabled="true"] {
|
|
60
85
|
background: var(--ui-control-surface-disabled);
|
|
61
86
|
color: var(--ui-disabled-text);
|
|
62
87
|
box-shadow: none;
|
|
@@ -45,18 +45,14 @@
|
|
|
45
45
|
align-items: flex-start;
|
|
46
46
|
gap: var(--ui-search-result-row-gap, var(--ui-space-3));
|
|
47
47
|
background: var(--ui-search-result-row-surface, transparent);
|
|
48
|
-
border:
|
|
49
|
-
border-
|
|
48
|
+
border: 1px solid var(--ui-search-result-row-border, transparent);
|
|
49
|
+
border-radius: var(--ui-radius-md);
|
|
50
50
|
color: inherit;
|
|
51
51
|
cursor: pointer;
|
|
52
52
|
text-align: left;
|
|
53
53
|
transition: background-color var(--ui-motion-fast) var(--ui-motion-ease);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
:scope:last-child {
|
|
57
|
-
border-block-end: none;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
56
|
:scope:hover:enabled {
|
|
61
57
|
background: var(--ui-search-result-row-hover-surface, color-mix(in srgb, var(--ui-surface) 85%, black 3%));
|
|
62
58
|
}
|
|
@@ -96,14 +96,6 @@
|
|
|
96
96
|
|
|
97
97
|
.search {
|
|
98
98
|
padding: var(--ui-space-3);
|
|
99
|
-
border-block-end: 1px solid var(--ui-border-divider);
|
|
100
|
-
transition: border-color var(--ui-motion-fast) var(--ui-motion-ease), box-shadow var(--ui-motion-fast) var(--ui-motion-ease);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/* The search region shows where typing goes, whatever the author put in it. */
|
|
104
|
-
.search:focus-within {
|
|
105
|
-
border-block-end-color: var(--_ui-search-shell-focus-color, var(--ui-control-focus));
|
|
106
|
-
box-shadow: inset 0 -1px 0 var(--_ui-search-shell-focus-color, var(--ui-control-focus));
|
|
107
99
|
}
|
|
108
100
|
|
|
109
101
|
.status,
|
|
@@ -115,7 +107,7 @@
|
|
|
115
107
|
}
|
|
116
108
|
|
|
117
109
|
.status {
|
|
118
|
-
|
|
110
|
+
padding-block-start: 0;
|
|
119
111
|
}
|
|
120
112
|
|
|
121
113
|
/* Laid out like the dialog's action row: actions right-aligned, spaced as buttons, no fill. */
|
|
@@ -126,7 +118,6 @@
|
|
|
126
118
|
justify-content: flex-end;
|
|
127
119
|
gap: var(--ui-space-2);
|
|
128
120
|
padding: var(--ui-space-3) var(--ui-space-4);
|
|
129
|
-
border-block-start: 1px solid var(--ui-border-divider);
|
|
130
121
|
}
|
|
131
122
|
|
|
132
123
|
.status:empty,
|
|
@@ -180,8 +171,6 @@
|
|
|
180
171
|
@scope ([data-component~="ui-search-shell"]) to ([data-component]) {
|
|
181
172
|
/* This component's hooks style the element they are set on, and never a nested one. */
|
|
182
173
|
|
|
183
|
-
/* The search region shows where typing goes, whatever the author put in it. */
|
|
184
|
-
|
|
185
174
|
:where([data-slotted], [data-slotted] *):is(input[slot="search"]) {
|
|
186
175
|
box-sizing: border-box;
|
|
187
176
|
inline-size: 100%;
|
|
@@ -196,7 +185,7 @@
|
|
|
196
185
|
}
|
|
197
186
|
|
|
198
187
|
:where([data-slotted], [data-slotted] *):is(input[slot="search"]:focus-visible) {
|
|
199
|
-
border-color: var(--ui-control-focus);
|
|
188
|
+
border-color: var(--_ui-search-shell-focus-color, var(--ui-control-focus));
|
|
200
189
|
outline: 2px solid var(--ui-focus-ring);
|
|
201
190
|
outline-offset: 2px;
|
|
202
191
|
}
|
package/styles/ui-select.css
CHANGED
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
background-size: 1.125rem 1.125rem;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
:scope:hover:not(:focus):not(:disabled) {
|
|
81
|
+
:scope:hover:not(:focus):not(:disabled):not([aria-invalid="true"]):not(:is(:user-invalid, [data-user-invalid])) {
|
|
82
82
|
border-color: var(--ui-select-border-hover, var(--ui-control-border-hover, var(--ui-text-secondary)));
|
|
83
83
|
}
|
|
84
84
|
|