@threadlabs/looma 0.37.5 → 0.38.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-button/ui-button.html +20 -5
- package/components/ui-combobox/ui-combobox.html +24 -3
- package/components/ui-combobox/ui-combobox.js +18 -3
- package/components/ui-icon-button/ui-icon-button.html +17 -8
- package/components/ui-menu-item/ui-menu-item.html +6 -1
- package/components/ui-select/ui-select.html +12 -0
- package/components/ui-skeleton/ui-skeleton.html +91 -0
- package/dist/index.js +1 -1
- package/docs/README.md +23 -10
- package/docs/catalog.json +246 -31
- package/docs/customizer-render.mjs +36 -20
- package/docs/customizer.js +76 -25
- package/docs/documentation.css +2 -0
- package/docs/palette.mjs +3 -3
- package/docs/site.mjs +1 -1
- package/docs/theme-session.mjs +1 -0
- package/docs/theme.mjs +11 -10
- package/package.json +2 -2
- package/styles/ui-button.css +19 -9
- package/styles/ui-combobox.css +40 -2
- package/styles/ui-icon-button.css +12 -2
- package/styles/ui-menu-item.css +6 -1
- package/styles/ui-select.css +9 -0
- package/styles/ui-skeleton.css +91 -0
- package/theme-system.css +7 -2
- package/vanilla/UiButton.js +1 -1
- package/vanilla/UiCombobox.d.ts +1 -0
- package/vanilla/UiCombobox.js +38 -37
- package/vanilla/UiIconButton.d.ts +1 -1
- package/vanilla/UiIconButton.js +1 -1
- package/vanilla/UiSelect.d.ts +1 -0
- package/vanilla/UiSelect.js +7 -7
- package/vanilla/UiSkeleton.d.ts +26 -0
- package/vanilla/UiSkeleton.js +42 -0
- package/vanilla/index.js +1 -0
- package/vue/UiButton.vue +30 -12
- package/vue/UiCombobox.d.ts +6 -0
- package/vue/UiCombobox.vue +70 -6
- package/vue/UiIconButton.d.ts +2 -2
- package/vue/UiIconButton.vue +23 -18
- package/vue/UiMenuItem.vue +6 -1
- package/vue/UiSelect.d.ts +6 -0
- package/vue/UiSelect.vue +30 -1
- package/vue/UiSkeleton.d.ts +37 -0
- package/vue/UiSkeleton.js +2 -0
- package/vue/UiSkeleton.vue +235 -0
- package/vue/chunks/UiButton.js +4 -4
- package/vue/chunks/UiCombobox.js +72 -46
- package/vue/chunks/UiIconButton.js +6 -7
- package/vue/chunks/UiMenuItem.js +1 -1
- package/vue/chunks/UiSelect.js +27 -2
- package/vue/chunks/UiSkeleton.js +151 -0
- package/vue/components.css +197 -25
- package/vue/editor/index.js +2 -3
- package/vue/index.d.ts +1 -0
- package/vue/index.js +2 -1
package/vue/UiCombobox.vue
CHANGED
|
@@ -192,6 +192,14 @@ const propValidityContract = {
|
|
|
192
192
|
'Lets the user choose several options. Each choice becomes a removable badge before the input, the list stays open between picks, and choosing a checked\n option removes it. items-change then reports the whole list of items, and selected-values-change the list of their values; use selectedValues or items,\n not value, in this mode.',
|
|
193
193
|
default: false,
|
|
194
194
|
},
|
|
195
|
+
muted: {
|
|
196
|
+
type: { kind: 'terminal', name: 'boolean' },
|
|
197
|
+
required: false,
|
|
198
|
+
target: { attribute: 'muted' },
|
|
199
|
+
description:
|
|
200
|
+
'Shows the selected field value with supporting-text emphasis, for an inherited or default choice. Suggestions keep normal emphasis and the field stays interactive.',
|
|
201
|
+
default: false,
|
|
202
|
+
},
|
|
195
203
|
name: {
|
|
196
204
|
type: { kind: 'terminal', name: 'string' },
|
|
197
205
|
required: false,
|
|
@@ -204,7 +212,8 @@ const propValidityContract = {
|
|
|
204
212
|
type: { kind: 'terminal', name: 'boolean' },
|
|
205
213
|
required: false,
|
|
206
214
|
target: { attribute: 'openonfocus' },
|
|
207
|
-
description:
|
|
215
|
+
description:
|
|
216
|
+
'Opens suggestions when the input receives focus or is clicked. A committed selection shows all choices until typing filters them; an explicitly supplied query keeps its filtering.',
|
|
208
217
|
default: false,
|
|
209
218
|
},
|
|
210
219
|
placeholder: {
|
|
@@ -310,6 +319,7 @@ const props = defineProps({
|
|
|
310
319
|
labelVisibility: { type: null as unknown as PropType<'visible' | 'sr-only' | null> },
|
|
311
320
|
loading: { type: null as unknown as PropType<boolean | null> },
|
|
312
321
|
multiple: { type: null as unknown as PropType<boolean | null> },
|
|
322
|
+
muted: { type: null as unknown as PropType<boolean | null> },
|
|
313
323
|
name: { type: null as unknown as PropType<string | null> },
|
|
314
324
|
openOnFocus: { type: null as unknown as PropType<boolean | null> },
|
|
315
325
|
placeholder: { type: null as unknown as PropType<string | null> },
|
|
@@ -339,6 +349,7 @@ const acceptedProps: Record<string, unknown> = {
|
|
|
339
349
|
labelVisibility: 'visible',
|
|
340
350
|
loading: false,
|
|
341
351
|
multiple: false,
|
|
352
|
+
muted: false,
|
|
342
353
|
name: '',
|
|
343
354
|
openOnFocus: false,
|
|
344
355
|
placeholder: '',
|
|
@@ -366,6 +377,7 @@ const inputTracking = vuePropInputs(acceptedProps, {
|
|
|
366
377
|
labelVisibility: 'visible',
|
|
367
378
|
loading: false,
|
|
368
379
|
multiple: false,
|
|
380
|
+
muted: false,
|
|
369
381
|
name: '',
|
|
370
382
|
openOnFocus: false,
|
|
371
383
|
placeholder: '',
|
|
@@ -445,6 +457,8 @@ const inputTracking = vuePropInputs(acceptedProps, {
|
|
|
445
457
|
return checkPropInput(value, { kind: 'terminal', name: 'boolean' }, true, true)
|
|
446
458
|
case 'multiple':
|
|
447
459
|
return checkPropInput(value, { kind: 'terminal', name: 'boolean' }, true, true)
|
|
460
|
+
case 'muted':
|
|
461
|
+
return checkPropInput(value, { kind: 'terminal', name: 'boolean' }, true, true)
|
|
448
462
|
case 'name':
|
|
449
463
|
return checkPropInput(value, { kind: 'terminal', name: 'string' }, true, true)
|
|
450
464
|
case 'openOnFocus':
|
|
@@ -572,6 +586,11 @@ const checkedProps = computed(() => {
|
|
|
572
586
|
props['multiple'],
|
|
573
587
|
props[BINDING_INPUTS_PROP],
|
|
574
588
|
) as boolean,
|
|
589
|
+
muted: propInputs.value<boolean | null>(
|
|
590
|
+
'muted',
|
|
591
|
+
props['muted'],
|
|
592
|
+
props[BINDING_INPUTS_PROP],
|
|
593
|
+
) as boolean,
|
|
575
594
|
name: propInputs.value<string | null>(
|
|
576
595
|
'name',
|
|
577
596
|
props['name'],
|
|
@@ -1085,6 +1104,7 @@ const hostState = computed(() =>
|
|
|
1085
1104
|
[
|
|
1086
1105
|
checkedProps.value.size && 'size',
|
|
1087
1106
|
checkedProps.value.size != null && `size=${encodeURIComponent(checkedProps.value.size)}`,
|
|
1107
|
+
checkedProps.value.muted && 'muted',
|
|
1088
1108
|
validationStatus.value && 'validationStatus',
|
|
1089
1109
|
`validationStatus=${encodeURIComponent(validationStatus.value)}`,
|
|
1090
1110
|
checkedProps.value.invalid && 'invalid',
|
|
@@ -1711,6 +1731,7 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
|
|
|
1711
1731
|
'labelVisibility',
|
|
1712
1732
|
'loading',
|
|
1713
1733
|
'multiple',
|
|
1734
|
+
'muted',
|
|
1714
1735
|
'name',
|
|
1715
1736
|
'openOnFocus',
|
|
1716
1737
|
'placeholder',
|
|
@@ -1783,6 +1804,7 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
|
|
|
1783
1804
|
:data-ui-combobox-prop-label-visibility="reflectedProp('labelVisibility', 'label-visibility', checkedProps.labelVisibility, undefined, false)"
|
|
1784
1805
|
:data-ui-combobox-prop-loading="reflectedProp('loading', 'loading', checkedProps.loading, undefined, false)"
|
|
1785
1806
|
:data-ui-combobox-prop-multiple="reflectedProp('multiple', 'multiple', checkedProps.multiple, undefined, false)"
|
|
1807
|
+
:data-ui-combobox-prop-muted="reflectedProp('muted', 'muted', checkedProps.muted, undefined, false)"
|
|
1786
1808
|
:data-ui-combobox-prop-name="reflectedProp('name', 'name', checkedProps.name, undefined, false)"
|
|
1787
1809
|
:data-ui-combobox-prop-open-on-focus="reflectedProp('openOnFocus', 'open-on-focus', checkedProps.openOnFocus, undefined, false)"
|
|
1788
1810
|
:data-ui-combobox-prop-placeholder="reflectedProp('placeholder', 'placeholder', checkedProps.placeholder, undefined, false)"
|
|
@@ -1806,9 +1828,9 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
|
|
|
1806
1828
|
<div class="control" data-hn-ui-combobox>
|
|
1807
1829
|
<div class="field" data-hn-ui-combobox ref="fieldElement">
|
|
1808
1830
|
<div class="entry" data-hn-ui-combobox>
|
|
1809
|
-
<slot name="start"
|
|
1810
|
-
|
|
1811
|
-
|
|
1831
|
+
<span class="start" data-hn-ui-combobox><slot name="start" /></span>{{ ' ' }}<template
|
|
1832
|
+
v-if="checkedProps.multiple"
|
|
1833
|
+
>{{ ' ' }}<KeyedBoundary><button
|
|
1812
1834
|
v-for="(item, index) in uniqueKeys(internalItems, (item, index, loop) => item.id)"
|
|
1813
1835
|
:key="item.id"
|
|
1814
1836
|
class="item"
|
|
@@ -2190,6 +2212,21 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
|
|
|
2190
2212
|
flex: 1 1 auto;
|
|
2191
2213
|
min-inline-size: 0;
|
|
2192
2214
|
}
|
|
2215
|
+
:global(.start:where([data-hn-ui-combobox])) {
|
|
2216
|
+
display: flex !important;
|
|
2217
|
+
align-items: center !important;
|
|
2218
|
+
flex: none;
|
|
2219
|
+
padding-inline-start: var(--ui-space-3) !important;
|
|
2220
|
+
}
|
|
2221
|
+
:global(.start:empty:where([data-hn-ui-combobox])) {
|
|
2222
|
+
display: none !important;
|
|
2223
|
+
}
|
|
2224
|
+
:global(:scope[data-ui-combobox-state~="size=sm"] .start:where([data-hn-ui-combobox])) {
|
|
2225
|
+
padding-inline-start: var(--ui-space-2) !important;
|
|
2226
|
+
}
|
|
2227
|
+
:global(:scope[data-ui-combobox-state~="size=lg"] .start:where([data-hn-ui-combobox])) {
|
|
2228
|
+
padding-inline-start: var(--ui-space-4) !important;
|
|
2229
|
+
}
|
|
2193
2230
|
:global(.help:where([data-hn-ui-combobox])) {
|
|
2194
2231
|
flex: none;
|
|
2195
2232
|
display: inline-flex !important;
|
|
@@ -2229,6 +2266,11 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
|
|
|
2229
2266
|
block-size: var(--ui-icon-size-sm);
|
|
2230
2267
|
}
|
|
2231
2268
|
|
|
2269
|
+
:global(:scope[data-ui-combobox-state~="muted"]
|
|
2270
|
+
input:not(:disabled):where([data-hn-ui-combobox])) {
|
|
2271
|
+
color: var(--ui-text-secondary);
|
|
2272
|
+
}
|
|
2273
|
+
|
|
2232
2274
|
:global(input:where([data-hn-ui-combobox])::selection) {
|
|
2233
2275
|
background: color-mix(in srgb, var(--ui-accent-solid) 20%, transparent);
|
|
2234
2276
|
color: inherit;
|
|
@@ -2322,7 +2364,7 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
|
|
|
2322
2364
|
border-radius: var(--_ui-combobox-popup-radius, var(--ui-overlay-radius, var(--ui-radius-md)));
|
|
2323
2365
|
background: var(
|
|
2324
2366
|
--_ui-combobox-popup-surface,
|
|
2325
|
-
var(--ui-
|
|
2367
|
+
var(--ui-material-content, var(--ui-surface-elevated))
|
|
2326
2368
|
);
|
|
2327
2369
|
color: var(--ui-text-primary);
|
|
2328
2370
|
box-shadow: var(
|
|
@@ -2522,6 +2564,23 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
|
|
|
2522
2564
|
flex: 1 1 auto;
|
|
2523
2565
|
min-inline-size: 0;
|
|
2524
2566
|
}
|
|
2567
|
+
:global(.start:where(:scope, :scope *):where([data-hn-ui-combobox])) {
|
|
2568
|
+
display: flex !important;
|
|
2569
|
+
align-items: center !important;
|
|
2570
|
+
flex: none;
|
|
2571
|
+
padding-inline-start: var(--ui-space-3) !important;
|
|
2572
|
+
}
|
|
2573
|
+
:global(.start:empty:where(:scope, :scope *):where([data-hn-ui-combobox])) {
|
|
2574
|
+
display: none !important;
|
|
2575
|
+
}
|
|
2576
|
+
:global(:where(.ui-combobox)[data-ui-combobox-state~="size=sm"]
|
|
2577
|
+
.start:where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-combobox"]))):where([data-hn-ui-combobox])) {
|
|
2578
|
+
padding-inline-start: var(--ui-space-2) !important;
|
|
2579
|
+
}
|
|
2580
|
+
:global(:where(.ui-combobox)[data-ui-combobox-state~="size=lg"]
|
|
2581
|
+
.start:where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-combobox"]))):where([data-hn-ui-combobox])) {
|
|
2582
|
+
padding-inline-start: var(--ui-space-4) !important;
|
|
2583
|
+
}
|
|
2525
2584
|
:global(.help:where(:scope, :scope *):where([data-hn-ui-combobox])) {
|
|
2526
2585
|
flex: none;
|
|
2527
2586
|
display: inline-flex !important;
|
|
@@ -2561,6 +2620,11 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
|
|
|
2561
2620
|
block-size: var(--ui-icon-size-sm);
|
|
2562
2621
|
}
|
|
2563
2622
|
|
|
2623
|
+
:global(:where(.ui-combobox)[data-ui-combobox-state~="muted"]
|
|
2624
|
+
input:not(:disabled):where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-combobox"]))):where([data-hn-ui-combobox])) {
|
|
2625
|
+
color: var(--ui-text-secondary);
|
|
2626
|
+
}
|
|
2627
|
+
|
|
2564
2628
|
:global(input:where(:not([data-hn], [data-slotted]:not([data-slotted~="ui-combobox"]))):where(:scope, :scope
|
|
2565
2629
|
*):where([data-hn-ui-combobox])::selection) {
|
|
2566
2630
|
background: color-mix(in srgb, var(--ui-accent-solid) 20%, transparent);
|
|
@@ -2658,7 +2722,7 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
|
|
|
2658
2722
|
border-radius: var(--_ui-combobox-popup-radius, var(--ui-overlay-radius, var(--ui-radius-md)));
|
|
2659
2723
|
background: var(
|
|
2660
2724
|
--_ui-combobox-popup-surface,
|
|
2661
|
-
var(--ui-
|
|
2725
|
+
var(--ui-material-content, var(--ui-surface-elevated))
|
|
2662
2726
|
);
|
|
2663
2727
|
color: var(--ui-text-primary);
|
|
2664
2728
|
box-shadow: var(
|
package/vue/UiIconButton.d.ts
CHANGED
|
@@ -39,7 +39,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
39
39
|
type: PropType<"sm" | "md" | "lg" | null>;
|
|
40
40
|
};
|
|
41
41
|
tone: {
|
|
42
|
-
type: PropType<"
|
|
42
|
+
type: PropType<"accent" | "neutral" | "danger" | "success" | "warning" | "info" | null>;
|
|
43
43
|
};
|
|
44
44
|
variant: {
|
|
45
45
|
type: PropType<"ghost" | "outline" | "solid" | null>;
|
|
@@ -82,7 +82,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
82
82
|
type: PropType<"sm" | "md" | "lg" | null>;
|
|
83
83
|
};
|
|
84
84
|
tone: {
|
|
85
|
-
type: PropType<"
|
|
85
|
+
type: PropType<"accent" | "neutral" | "danger" | "success" | "warning" | "info" | null>;
|
|
86
86
|
};
|
|
87
87
|
variant: {
|
|
88
88
|
type: PropType<"ghost" | "outline" | "solid" | null>;
|
package/vue/UiIconButton.vue
CHANGED
|
@@ -125,16 +125,16 @@ const propValidityContract = {
|
|
|
125
125
|
required: false,
|
|
126
126
|
target: { attribute: 'tone' },
|
|
127
127
|
description:
|
|
128
|
-
'Colour for every variant.
|
|
129
|
-
values: ['
|
|
130
|
-
default: '
|
|
128
|
+
'Colour for every variant. The default neutral shares the quiet control family with fields and text buttons. Choose accent explicitly for a coloured action,\n or primary for solid accent. danger, success, warning and info share Button\'s intent colors. Native aria-pressed="true" keeps an outline toggle visibly\n pressed; the consumer owns that state.',
|
|
129
|
+
values: ['accent', 'neutral', 'danger', 'success', 'warning', 'info'],
|
|
130
|
+
default: 'neutral',
|
|
131
131
|
},
|
|
132
132
|
variant: {
|
|
133
133
|
type: { kind: 'terminal', name: 'keyword' },
|
|
134
134
|
required: false,
|
|
135
135
|
target: { attribute: 'variant' },
|
|
136
136
|
description:
|
|
137
|
-
'Emphasis. ghost shows only the icon until it is hovered, for toolbars and dense rows; outline adds a border on the default surface; solid fills with
|
|
137
|
+
'Emphasis. ghost shows only the icon until it is hovered, for toolbars and dense rows; outline adds a border on the default surface; solid fills with its\n chosen tone.',
|
|
138
138
|
values: ['ghost', 'outline', 'solid'],
|
|
139
139
|
default: 'ghost',
|
|
140
140
|
},
|
|
@@ -158,7 +158,7 @@ const props = defineProps({
|
|
|
158
158
|
size: { type: null as unknown as PropType<'sm' | 'md' | 'lg' | null> },
|
|
159
159
|
tone: {
|
|
160
160
|
type: null as unknown as PropType<
|
|
161
|
-
'
|
|
161
|
+
'accent' | 'neutral' | 'danger' | 'success' | 'warning' | 'info' | null
|
|
162
162
|
>,
|
|
163
163
|
},
|
|
164
164
|
variant: { type: null as unknown as PropType<'ghost' | 'outline' | 'solid' | null> },
|
|
@@ -176,7 +176,7 @@ const acceptedProps: Record<string, unknown> = {
|
|
|
176
176
|
revealed: false,
|
|
177
177
|
round: false,
|
|
178
178
|
size: 'md',
|
|
179
|
-
tone: '
|
|
179
|
+
tone: 'neutral',
|
|
180
180
|
variant: 'ghost',
|
|
181
181
|
}
|
|
182
182
|
const inputTracking = vuePropInputs(acceptedProps, {
|
|
@@ -190,7 +190,7 @@ const inputTracking = vuePropInputs(acceptedProps, {
|
|
|
190
190
|
revealed: false,
|
|
191
191
|
round: false,
|
|
192
192
|
size: 'md',
|
|
193
|
-
tone: '
|
|
193
|
+
tone: 'neutral',
|
|
194
194
|
variant: 'ghost',
|
|
195
195
|
}, (name, value, source, values) => {
|
|
196
196
|
switch (name) {
|
|
@@ -281,16 +281,11 @@ const checkedProps = computed(() => {
|
|
|
281
281
|
props['size'],
|
|
282
282
|
props[BINDING_INPUTS_PROP],
|
|
283
283
|
) as 'sm' | 'md' | 'lg',
|
|
284
|
-
tone: propInputs.value<
|
|
285
|
-
'
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
| 'neutral'
|
|
290
|
-
| 'danger'
|
|
291
|
-
| 'success'
|
|
292
|
-
| 'warning'
|
|
293
|
-
| 'info',
|
|
284
|
+
tone: propInputs.value<'accent' | 'neutral' | 'danger' | 'success' | 'warning' | 'info' | null>(
|
|
285
|
+
'tone',
|
|
286
|
+
props['tone'],
|
|
287
|
+
props[BINDING_INPUTS_PROP],
|
|
288
|
+
) as 'accent' | 'neutral' | 'danger' | 'success' | 'warning' | 'info',
|
|
294
289
|
variant: propInputs.value<'ghost' | 'outline' | 'solid' | null>(
|
|
295
290
|
'variant',
|
|
296
291
|
props['variant'],
|
|
@@ -557,7 +552,7 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
|
|
|
557
552
|
inherits: false;
|
|
558
553
|
}
|
|
559
554
|
|
|
560
|
-
/*
|
|
555
|
+
/* Neutral actions share the same quiet surface and border roles as fields. */
|
|
561
556
|
|
|
562
557
|
/* At rest an anticipatory button shows only its guide dot. The icon grows into place when
|
|
563
558
|
proximity, hover, or focus reveals it; the button's hit area and guide remain stable. */
|
|
@@ -691,6 +686,10 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
|
|
|
691
686
|
:global(:scope[data-tone="neutral"]:where([data-hn-ui-icon-button])) {
|
|
692
687
|
--_tone-highlight: var(--ui-neutral-highlight, none);
|
|
693
688
|
--_tone-glow: var(--ui-neutral-glow, 0 0 transparent);
|
|
689
|
+
--_icon-button-outline-surface: transparent;
|
|
690
|
+
--_icon-button-border: var(--ui-control-border);
|
|
691
|
+
--_icon-button-hover-border: var(--ui-control-border-hover, var(--ui-control-border));
|
|
692
|
+
--_icon-button-text: var(--ui-text);
|
|
694
693
|
--_icon-button-solid-surface: var(--ui-neutral-surface);
|
|
695
694
|
--_icon-button-solid-hover-surface: var(--ui-neutral-hover);
|
|
696
695
|
--_icon-button-solid-text: var(--ui-text);
|
|
@@ -891,6 +890,12 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
|
|
|
891
890
|
var(--_icon-button-hover-border, var(--ui-control-border-hover, var(--ui-control-border)))
|
|
892
891
|
);
|
|
893
892
|
}
|
|
893
|
+
:global(:scope[data-tone="neutral"][data-appearance="outline"]:hover:enabled:not([aria-disabled="true"]):where([data-hn-ui-icon-button])) {
|
|
894
|
+
background-color: var(--ui-icon-button-hover-surface, var(--ui-neutral-hover));
|
|
895
|
+
}
|
|
896
|
+
:global(:scope[data-tone="neutral"][data-appearance="outline"]:active:enabled:not([aria-disabled="true"]):where([data-hn-ui-icon-button])) {
|
|
897
|
+
background-color: var(--ui-icon-button-active-surface, var(--ui-neutral-active));
|
|
898
|
+
}
|
|
894
899
|
|
|
895
900
|
:global(:scope[data-appearance="solid"]:hover:enabled:not([aria-disabled="true"]):where([data-hn-ui-icon-button])) {
|
|
896
901
|
background-color: var(
|
package/vue/UiMenuItem.vue
CHANGED
|
@@ -517,7 +517,12 @@ useComponentHost(() => import('../components/ui-menu-item/ui-menu-item.js'), {
|
|
|
517
517
|
}
|
|
518
518
|
|
|
519
519
|
:global(:scope:is(:hover, :focus-visible):not([aria-disabled="true"]):where([data-hn-ui-menu-item])) {
|
|
520
|
-
background: var(--ui-menu-item-hover-surface, var(--ui-
|
|
520
|
+
background: var(--ui-menu-item-hover-surface, var(--ui-accent-subtle));
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
:global(:scope[aria-checked="true"]:not([aria-disabled="true"]):where([data-hn-ui-menu-item])) {
|
|
524
|
+
background: var(--ui-selection-surface);
|
|
525
|
+
color: var(--ui-selection-text);
|
|
521
526
|
}
|
|
522
527
|
|
|
523
528
|
:global(:scope:focus-visible:where([data-hn-ui-menu-item])) {
|
package/vue/UiSelect.d.ts
CHANGED
|
@@ -11,6 +11,9 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
11
11
|
invalid: {
|
|
12
12
|
type: PropType<boolean | null>;
|
|
13
13
|
};
|
|
14
|
+
muted: {
|
|
15
|
+
type: PropType<boolean | null>;
|
|
16
|
+
};
|
|
14
17
|
required: {
|
|
15
18
|
type: PropType<boolean | null>;
|
|
16
19
|
};
|
|
@@ -35,6 +38,9 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
35
38
|
invalid: {
|
|
36
39
|
type: PropType<boolean | null>;
|
|
37
40
|
};
|
|
41
|
+
muted: {
|
|
42
|
+
type: PropType<boolean | null>;
|
|
43
|
+
};
|
|
38
44
|
required: {
|
|
39
45
|
type: PropType<boolean | null>;
|
|
40
46
|
};
|
package/vue/UiSelect.vue
CHANGED
|
@@ -41,6 +41,14 @@ const propValidityContract = {
|
|
|
41
41
|
description: 'Exposes invalid state to assistive technology and styling.',
|
|
42
42
|
default: false,
|
|
43
43
|
},
|
|
44
|
+
muted: {
|
|
45
|
+
type: { kind: 'terminal', name: 'boolean' },
|
|
46
|
+
required: false,
|
|
47
|
+
target: { attribute: 'muted' },
|
|
48
|
+
description:
|
|
49
|
+
'Shows the selected value with supporting-text emphasis, for an inherited or default choice. The select remains interactive and its options retain normal\n emphasis.',
|
|
50
|
+
default: false,
|
|
51
|
+
},
|
|
44
52
|
required: {
|
|
45
53
|
type: { kind: 'terminal', name: 'boolean' },
|
|
46
54
|
required: false,
|
|
@@ -69,6 +77,7 @@ const propValidityContract = {
|
|
|
69
77
|
const props = defineProps({
|
|
70
78
|
disabled: { type: null as unknown as PropType<boolean | null> },
|
|
71
79
|
invalid: { type: null as unknown as PropType<boolean | null> },
|
|
80
|
+
muted: { type: null as unknown as PropType<boolean | null> },
|
|
72
81
|
required: { type: null as unknown as PropType<boolean | null> },
|
|
73
82
|
size: { type: null as unknown as PropType<'sm' | 'md' | 'lg' | null> },
|
|
74
83
|
value: { type: null as unknown as PropType<string | null> },
|
|
@@ -78,6 +87,7 @@ const props = defineProps({
|
|
|
78
87
|
const acceptedProps: Record<string, unknown> = {
|
|
79
88
|
disabled: false,
|
|
80
89
|
invalid: false,
|
|
90
|
+
muted: false,
|
|
81
91
|
required: false,
|
|
82
92
|
size: 'md',
|
|
83
93
|
value: null,
|
|
@@ -85,6 +95,7 @@ const acceptedProps: Record<string, unknown> = {
|
|
|
85
95
|
const inputTracking = vuePropInputs(acceptedProps, {
|
|
86
96
|
disabled: false,
|
|
87
97
|
invalid: false,
|
|
98
|
+
muted: false,
|
|
88
99
|
required: false,
|
|
89
100
|
size: 'md',
|
|
90
101
|
}, (name, value, source, values) => {
|
|
@@ -93,6 +104,8 @@ const inputTracking = vuePropInputs(acceptedProps, {
|
|
|
93
104
|
return checkPropInput(value, { kind: 'terminal', name: 'boolean' }, true, true)
|
|
94
105
|
case 'invalid':
|
|
95
106
|
return checkPropInput(value, { kind: 'terminal', name: 'boolean' }, true, true)
|
|
107
|
+
case 'muted':
|
|
108
|
+
return checkPropInput(value, { kind: 'terminal', name: 'boolean' }, true, true)
|
|
96
109
|
case 'required':
|
|
97
110
|
return checkPropInput(value, { kind: 'terminal', name: 'boolean' }, true, true)
|
|
98
111
|
case 'size':
|
|
@@ -119,6 +132,11 @@ const checkedProps = computed(() => {
|
|
|
119
132
|
props['invalid'],
|
|
120
133
|
props[BINDING_INPUTS_PROP],
|
|
121
134
|
) as boolean,
|
|
135
|
+
muted: propInputs.value<boolean | null>(
|
|
136
|
+
'muted',
|
|
137
|
+
props['muted'],
|
|
138
|
+
props[BINDING_INPUTS_PROP],
|
|
139
|
+
) as boolean,
|
|
122
140
|
required: propInputs.value<boolean | null>(
|
|
123
141
|
'required',
|
|
124
142
|
props['required'],
|
|
@@ -164,6 +182,7 @@ checkHydratedRoot('select', 'ui-select')
|
|
|
164
182
|
/** The values the styles' :host() and :state() rules test. */
|
|
165
183
|
const hostState = computed(() =>
|
|
166
184
|
[
|
|
185
|
+
checkedProps.value.muted && 'muted',
|
|
167
186
|
checkedProps.value.size && 'size',
|
|
168
187
|
checkedProps.value.size != null && `size=${encodeURIComponent(checkedProps.value.size)}`,
|
|
169
188
|
].filter(Boolean).join(' ')
|
|
@@ -189,7 +208,7 @@ useComponentHost(() => import('../components/ui-select/ui-select.js'), {
|
|
|
189
208
|
? (incoming[name] ?? incoming[kebab] ?? null)
|
|
190
209
|
: null
|
|
191
210
|
},
|
|
192
|
-
propNames: ['disabled', 'invalid', 'required', 'size', 'value'],
|
|
211
|
+
propNames: ['disabled', 'invalid', 'muted', 'required', 'size', 'value'],
|
|
193
212
|
propValidity: (name: string) =>
|
|
194
213
|
propValidityState({ contract: propValidityContract, values: { ...props } }, name),
|
|
195
214
|
})
|
|
@@ -207,6 +226,7 @@ useComponentHost(() => import('../components/ui-select/ui-select.js'), {
|
|
|
207
226
|
v-prop-validity="{ contract: propValidityContract, values: { ...props } }"
|
|
208
227
|
:data-ui-select-prop-disabled="reflectedProp('disabled', 'disabled', checkedProps.disabled, undefined, false)"
|
|
209
228
|
:data-ui-select-prop-invalid="reflectedProp('invalid', 'invalid', checkedProps.invalid, undefined, false)"
|
|
229
|
+
:data-ui-select-prop-muted="reflectedProp('muted', 'muted', checkedProps.muted, undefined, false)"
|
|
210
230
|
:data-ui-select-prop-required="reflectedProp('required', 'required', checkedProps.required, undefined, false)"
|
|
211
231
|
:data-ui-select-prop-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
|
|
212
232
|
:data-ui-select-prop-value="reflectedProp('value', 'value', checkedProps.value, undefined, false)"
|
|
@@ -319,6 +339,15 @@ useComponentHost(() => import('../components/ui-select/ui-select.js'), {
|
|
|
319
339
|
background-size: 1.125rem 1.125rem, 100% 100%;
|
|
320
340
|
}
|
|
321
341
|
|
|
342
|
+
:global(:scope[data-ui-select-state~="muted"]:where([data-hn-ui-select])) {
|
|
343
|
+
color: var(--ui-text-secondary);
|
|
344
|
+
}
|
|
345
|
+
:global(:scope[data-ui-select-state~="muted"] :where(:not([data-hn-ui-select])):is(option)),
|
|
346
|
+
:global(:scope[data-ui-select-state~="muted"] :where(:not([data-hn-ui-select])):is(optgroup)) {
|
|
347
|
+
color: var(--ui-text-primary);
|
|
348
|
+
background-color: var(--ui-control-surface);
|
|
349
|
+
}
|
|
350
|
+
|
|
322
351
|
:global(:scope:hover:not(:focus):not(:disabled):not([aria-invalid="true"]):not(:is(:user-invalid, [data-user-invalid])):where([data-hn-ui-select])) {
|
|
323
352
|
border-color: var(
|
|
324
353
|
--ui-select-border-hover,
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { PropType } from 'vue';
|
|
2
|
+
import { type InputBindings } from './props.js';
|
|
3
|
+
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
4
|
+
animated: {
|
|
5
|
+
type: PropType<boolean | null>;
|
|
6
|
+
};
|
|
7
|
+
height: {
|
|
8
|
+
type: PropType<string | null>;
|
|
9
|
+
};
|
|
10
|
+
shape: {
|
|
11
|
+
type: PropType<"text" | "circle" | "rectangle" | null>;
|
|
12
|
+
};
|
|
13
|
+
width: {
|
|
14
|
+
type: PropType<string | null>;
|
|
15
|
+
};
|
|
16
|
+
"\0htmlNextInputStatus": {
|
|
17
|
+
type: PropType<InputBindings>;
|
|
18
|
+
};
|
|
19
|
+
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
20
|
+
animated: {
|
|
21
|
+
type: PropType<boolean | null>;
|
|
22
|
+
};
|
|
23
|
+
height: {
|
|
24
|
+
type: PropType<string | null>;
|
|
25
|
+
};
|
|
26
|
+
shape: {
|
|
27
|
+
type: PropType<"text" | "circle" | "rectangle" | null>;
|
|
28
|
+
};
|
|
29
|
+
width: {
|
|
30
|
+
type: PropType<string | null>;
|
|
31
|
+
};
|
|
32
|
+
"\0htmlNextInputStatus": {
|
|
33
|
+
type: PropType<InputBindings>;
|
|
34
|
+
};
|
|
35
|
+
}>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
36
|
+
declare const _default: typeof __VLS_export;
|
|
37
|
+
export default _default;
|