@threadlabs/looma 0.26.3 → 0.26.5
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-badge/ui-badge.html +41 -4
- package/components/ui-button/ui-button.html +50 -5
- package/components/ui-callout/ui-callout.html +2 -1
- package/components/ui-icon-button/ui-icon-button.html +35 -7
- package/components/ui-input-group/ui-input-group.html +9 -0
- package/components/ui-toast/ui-toast.html +13 -7
- package/components/ui-toast-region/ui-toast-region.html +18 -7
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/styles/ui-badge.css +40 -1
- package/styles/ui-button.css +53 -5
- package/styles/ui-callout.css +2 -1
- package/styles/ui-icon-button.css +35 -7
- package/styles/ui-input-group.css +6 -0
- package/styles/ui-toast-region.css +18 -7
- package/styles/ui-toast.css +13 -7
- package/vanilla/UiBadge.d.ts +1 -1
- package/vanilla/UiBadge.js +1 -1
- package/vanilla/UiButton.js +47 -21
- package/vanilla/UiInputGroup.d.ts +1 -0
- package/vanilla/UiInputGroup.js +4 -4
- package/vue/UiBadge.d.ts +3 -3
- package/vue/UiBadge.vue +79 -6
- package/vue/UiButton.d.ts +6 -2
- package/vue/UiButton.vue +56 -6
- package/vue/UiCallout.vue +4 -2
- package/vue/UiIconButton.vue +40 -7
- package/vue/UiInputGroup.d.ts +9 -0
- package/vue/UiInputGroup.vue +29 -1
- package/vue/UiToast.vue +16 -8
- package/vue/UiToastRegion.vue +18 -7
- package/vue/chunks/UiBadge.js +3 -2
- package/vue/chunks/UiButton.js +15 -5
- package/vue/chunks/UiCallout.js +1 -1
- package/vue/chunks/UiIconButton.js +1 -1
- package/vue/chunks/UiInputGroup.js +29 -4
- package/vue/chunks/UiToast.js +1 -1
- package/vue/chunks/UiToastRegion.js +1 -1
- package/vue/components.css +435 -263
package/vue/UiBadge.vue
CHANGED
|
@@ -22,8 +22,8 @@ const propValidityContract = {
|
|
|
22
22
|
required: false,
|
|
23
23
|
target: { attribute: 'size' },
|
|
24
24
|
description:
|
|
25
|
-
'Scale. xs is compact; md is the usual text
|
|
26
|
-
values: ['xs', 'md', 'lg'],
|
|
25
|
+
'Scale. xs is compact; sm keeps the usual badge geometry with compact text, fitting short counts such as 99+ inside a 24px circle. md is the usual text\n badge; lg adds room to fixed marks while retaining the usual text size. A square is 24px at xs, 32px at sm and md, and 40px at lg. A circle is 16px at xs,\n 24px at sm and md, and 32px at lg.',
|
|
26
|
+
values: ['xs', 'sm', 'md', 'lg'],
|
|
27
27
|
default: 'md',
|
|
28
28
|
},
|
|
29
29
|
tone: {
|
|
@@ -51,7 +51,7 @@ const props = defineProps({
|
|
|
51
51
|
type: null as unknown as PropType<'pill' | 'tag' | 'dot' | 'square' | 'circle' | null>,
|
|
52
52
|
default: 'pill',
|
|
53
53
|
},
|
|
54
|
-
size: { type: null as unknown as PropType<'xs' | 'md' | 'lg' | null>, default: 'md' },
|
|
54
|
+
size: { type: null as unknown as PropType<'xs' | 'sm' | 'md' | 'lg' | null>, default: 'md' },
|
|
55
55
|
tone: {
|
|
56
56
|
type: null as unknown as PropType<
|
|
57
57
|
'neutral' | 'accent' | 'info' | 'success' | 'warning' | 'danger' | null
|
|
@@ -77,13 +77,13 @@ const checkedProps = computed(() => ({
|
|
|
77
77
|
'shape',
|
|
78
78
|
acceptedProps,
|
|
79
79
|
) as 'pill' | 'tag' | 'dot' | 'square' | 'circle',
|
|
80
|
-
size: checkedProp<'xs' | 'md' | 'lg'>(
|
|
80
|
+
size: checkedProp<'xs' | 'sm' | 'md' | 'lg'>(
|
|
81
81
|
props['size'],
|
|
82
82
|
{ kind: 'terminal', name: 'keyword' },
|
|
83
83
|
false,
|
|
84
84
|
'size',
|
|
85
85
|
acceptedProps,
|
|
86
|
-
) as 'xs' | 'md' | 'lg',
|
|
86
|
+
) as 'xs' | 'sm' | 'md' | 'lg',
|
|
87
87
|
tone: checkedProp<'neutral' | 'accent' | 'info' | 'success' | 'warning' | 'danger'>(
|
|
88
88
|
props['tone'],
|
|
89
89
|
{ kind: 'terminal', name: 'keyword' },
|
|
@@ -195,6 +195,10 @@ const hostState = computed(() =>
|
|
|
195
195
|
syntax: "*";
|
|
196
196
|
inherits: false;
|
|
197
197
|
}
|
|
198
|
+
@property --ui-badge-circle-opacity {
|
|
199
|
+
syntax: "*";
|
|
200
|
+
inherits: false;
|
|
201
|
+
}
|
|
198
202
|
@property --ui-badge-dot-size {
|
|
199
203
|
syntax: "*";
|
|
200
204
|
inherits: false;
|
|
@@ -360,6 +364,11 @@ const hostState = computed(() =>
|
|
|
360
364
|
line-height: var(--ui-badge-line-height, 1);
|
|
361
365
|
}
|
|
362
366
|
|
|
367
|
+
[data-component~="ui-badge"][data-ui-badge-state~="size=sm"] {
|
|
368
|
+
font-size: var(--ui-badge-font-size, var(--ui-font-size-2xs));
|
|
369
|
+
line-height: var(--ui-badge-line-height, 1);
|
|
370
|
+
}
|
|
371
|
+
|
|
363
372
|
[data-component~="ui-badge"][data-ui-badge-state~="tone=accent"] {
|
|
364
373
|
--_badge-surface: var(--ui-accent-strong-surface, var(--ui-accent-solid));
|
|
365
374
|
--_badge-border: var(--ui-accent-strong-surface, var(--ui-accent-solid));
|
|
@@ -454,8 +463,72 @@ const hostState = computed(() =>
|
|
|
454
463
|
background-clip: padding-box;
|
|
455
464
|
}
|
|
456
465
|
|
|
466
|
+
/* A circular count has a tone-tinted surface, a separate lighter rim and readable tone ink.
|
|
467
|
+
Dark controls retain a shaded surface and theme ink with a quieter rim. */
|
|
457
468
|
[data-component~="ui-badge"][data-ui-badge-state~="variant=inverse"][data-ui-badge-state~="shape=circle"] {
|
|
458
|
-
|
|
469
|
+
--_badge-color-surface: light-dark(
|
|
470
|
+
color-mix(
|
|
471
|
+
in srgb,
|
|
472
|
+
color-mix(in oklab, var(--_ui-badge-color) 0%, var(--ui-surface-default)) var(
|
|
473
|
+
--ui-badge-circle-opacity,
|
|
474
|
+
66%
|
|
475
|
+
),
|
|
476
|
+
transparent
|
|
477
|
+
),
|
|
478
|
+
color-mix(
|
|
479
|
+
in srgb,
|
|
480
|
+
color-mix(in oklab, var(--_ui-badge-color) 0%, var(--ui-surface-default)) var(
|
|
481
|
+
--ui-badge-circle-opacity,
|
|
482
|
+
56%
|
|
483
|
+
),
|
|
484
|
+
transparent
|
|
485
|
+
)
|
|
486
|
+
);
|
|
487
|
+
--_badge-color-border: light-dark(
|
|
488
|
+
color-mix(
|
|
489
|
+
in srgb,
|
|
490
|
+
color-mix(in oklab, var(--_ui-badge-color) 0%, var(--ui-surface-default)) 88%,
|
|
491
|
+
transparent
|
|
492
|
+
),
|
|
493
|
+
color-mix(
|
|
494
|
+
in srgb,
|
|
495
|
+
color-mix(in oklab, var(--_ui-badge-color) 0%, var(--ui-surface-default)) 44%,
|
|
496
|
+
transparent
|
|
497
|
+
)
|
|
498
|
+
);
|
|
499
|
+
--_badge-color-text: light-dark(
|
|
500
|
+
color-mix(in srgb, var(--_badge-color-ink) 65%, var(--ui-text-primary)),
|
|
501
|
+
color-mix(in oklab, var(--_ui-badge-color) 0%, var(--ui-text-primary))
|
|
502
|
+
);
|
|
503
|
+
--_badge-count-surface: light-dark(
|
|
504
|
+
color-mix(in srgb, var(--_badge-text) var(--ui-badge-circle-opacity, 66%), transparent),
|
|
505
|
+
color-mix(in srgb, var(--_badge-text) var(--ui-badge-circle-opacity, 56%), transparent)
|
|
506
|
+
);
|
|
507
|
+
--_badge-outline-surface: var(
|
|
508
|
+
--ui-badge-surface,
|
|
509
|
+
var(--_badge-color-surface, var(--_badge-count-surface))
|
|
510
|
+
);
|
|
511
|
+
border-color: var(
|
|
512
|
+
--ui-badge-border,
|
|
513
|
+
var(
|
|
514
|
+
--_badge-color-border,
|
|
515
|
+
light-dark(
|
|
516
|
+
color-mix(in srgb, var(--_badge-text) 88%, transparent),
|
|
517
|
+
color-mix(in srgb, var(--_badge-text) 44%, transparent)
|
|
518
|
+
)
|
|
519
|
+
)
|
|
520
|
+
);
|
|
521
|
+
color: var(
|
|
522
|
+
--ui-badge-text,
|
|
523
|
+
var(
|
|
524
|
+
--_badge-color-text,
|
|
525
|
+
light-dark(
|
|
526
|
+
color-mix(in srgb, var(--_badge-surface) 65%, var(--ui-text-primary)),
|
|
527
|
+
var(--ui-text-primary)
|
|
528
|
+
)
|
|
529
|
+
)
|
|
530
|
+
);
|
|
531
|
+
box-shadow: 0 1px 1px light-dark(rgb(0 0 0 / 0.08), rgb(0 0 0 / 0.12));
|
|
459
532
|
}
|
|
460
533
|
|
|
461
534
|
/* Neutral reverses a subtle surface/ink pair rather than a strong tone. Keep its original
|
package/vue/UiButton.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PropType } from 'vue';
|
|
2
|
-
declare var __VLS_6: {}, __VLS_8: {}, __VLS_10: {}, __VLS_22: {}, __VLS_24: {}, __VLS_26: {}, __VLS_38: {},
|
|
2
|
+
declare var __VLS_6: {}, __VLS_8: {}, __VLS_10: {}, __VLS_22: {}, __VLS_24: {}, __VLS_26: {}, __VLS_38: {}, __VLS_40: {}, __VLS_47: {}, __VLS_49: {};
|
|
3
3
|
type __VLS_Slots = {} & {
|
|
4
4
|
icon?: (props: typeof __VLS_6) => any;
|
|
5
5
|
} & {
|
|
@@ -15,7 +15,11 @@ type __VLS_Slots = {} & {
|
|
|
15
15
|
} & {
|
|
16
16
|
default?: (props: typeof __VLS_38) => any;
|
|
17
17
|
} & {
|
|
18
|
-
|
|
18
|
+
badge?: (props: typeof __VLS_40) => any;
|
|
19
|
+
} & {
|
|
20
|
+
default?: (props: typeof __VLS_47) => any;
|
|
21
|
+
} & {
|
|
22
|
+
badge?: (props: typeof __VLS_49) => any;
|
|
19
23
|
};
|
|
20
24
|
declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
21
25
|
align: {
|
package/vue/UiButton.vue
CHANGED
|
@@ -808,7 +808,8 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
|
|
|
808
808
|
><span v-if="checkedProps.loading || checkedProps.pending" class="spinner-wrap"><UiSpinner
|
|
809
809
|
size="sm"
|
|
810
810
|
/></span>
|
|
811
|
-
<slot
|
|
811
|
+
<slot />
|
|
812
|
+
<span class="badge"><slot name="badge" /></span></a>
|
|
812
813
|
<button
|
|
813
814
|
v-else
|
|
814
815
|
data-component="ui-button"
|
|
@@ -839,6 +840,7 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
|
|
|
839
840
|
size="sm"
|
|
840
841
|
/></span>
|
|
841
842
|
<slot />
|
|
843
|
+
<span class="badge"><slot name="badge" /></span>
|
|
842
844
|
</button>
|
|
843
845
|
</template>
|
|
844
846
|
|
|
@@ -918,6 +920,21 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
|
|
|
918
920
|
}
|
|
919
921
|
|
|
920
922
|
[data-component~="ui-button"] {
|
|
923
|
+
/* Optional inherited action-group values keep text and icon actions under the same light.
|
|
924
|
+
One fine top/start highlight follows the bottom/end lowlight at a joined action seam.
|
|
925
|
+
A single ambient lift avoids stacking a face gradient or another inset bevel. */
|
|
926
|
+
--_ui-action-start: 1px;
|
|
927
|
+
--_ui-action-edge: var(
|
|
928
|
+
--ui-action-edge,
|
|
929
|
+
inset var(--_ui-action-start) 1px 0 light-dark(
|
|
930
|
+
rgb(255 255 255 / 0.08),
|
|
931
|
+
rgb(255 255 255 / 0.06)
|
|
932
|
+
),
|
|
933
|
+
inset calc(-1 * var(--_ui-action-start)) -1px 0 light-dark(rgb(0 0 0 / 0.08), rgb(0 0 0 / 0.08))
|
|
934
|
+
);
|
|
935
|
+
--_ui-action-shadow:
|
|
936
|
+
var(--_ui-action-edge),
|
|
937
|
+
0 1px 2px light-dark(rgb(0 0 0 / 0.10), rgb(0 0 0 / 0.20));
|
|
921
938
|
--_hue: var(--ui-accent);
|
|
922
939
|
--_hue-hover: var(--ui-accent-hover);
|
|
923
940
|
--_hue-active: var(--ui-accent-active);
|
|
@@ -938,6 +955,10 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
|
|
|
938
955
|
color: var(--_tone-text);
|
|
939
956
|
}
|
|
940
957
|
|
|
958
|
+
[data-component~="ui-button"]:dir(rtl) {
|
|
959
|
+
--_ui-action-start: -1px;
|
|
960
|
+
}
|
|
961
|
+
|
|
941
962
|
[data-component~="ui-button"][data-ui-button-state~="align=start"] {
|
|
942
963
|
justify-content: flex-start;
|
|
943
964
|
text-align: start;
|
|
@@ -964,8 +985,8 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
|
|
|
964
985
|
white-space: var(--ui-button-white-space, inherit);
|
|
965
986
|
line-height: var(--ui-line-height-tight);
|
|
966
987
|
padding: var(--ui-space-2) var(--ui-space-3);
|
|
967
|
-
background-image:
|
|
968
|
-
box-shadow: var(--ui-button-shadow, var(--ui-
|
|
988
|
+
background-image: none;
|
|
989
|
+
box-shadow: var(--ui-button-shadow, var(--ui-action-shadow, var(--_ui-action-shadow)));
|
|
969
990
|
cursor: pointer;
|
|
970
991
|
transition:
|
|
971
992
|
background-color var(--ui-motion-fast) var(--ui-motion-ease),
|
|
@@ -986,6 +1007,22 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
|
|
|
986
1007
|
vertical-align: middle;
|
|
987
1008
|
}
|
|
988
1009
|
|
|
1010
|
+
/* A count is an adornment, not another line of label text. Keep the standard control height
|
|
1011
|
+
with enough inset for a 24px mark; large content can still grow the button naturally. */
|
|
1012
|
+
[data-component~="ui-button"]:not([variant="link"]):has(.badge:not(:empty)) {
|
|
1013
|
+
padding-block: var(--ui-space-0-5);
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
.badge {
|
|
1017
|
+
display: inline-flex;
|
|
1018
|
+
align-items: center;
|
|
1019
|
+
flex: none;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
.badge:empty {
|
|
1023
|
+
display: none;
|
|
1024
|
+
}
|
|
1025
|
+
|
|
989
1026
|
@supports (text-box-trim: trim-both) {
|
|
990
1027
|
[data-component~="ui-button"] {
|
|
991
1028
|
text-box-trim: trim-both;
|
|
@@ -1059,6 +1096,15 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
|
|
|
1059
1096
|
background-color: var(--ui-button-hover-surface, oklch(from var(--_tone) l c h / 12%));
|
|
1060
1097
|
}
|
|
1061
1098
|
|
|
1099
|
+
/* A neutral card encloses content quietly; ordinary outlines keep their action-tone edge. */
|
|
1100
|
+
[data-component~="ui-button"][data-ui-button-state~="variant=card"][data-ui-button-state~="tone=neutral"] {
|
|
1101
|
+
border-color: var(--ui-button-border, var(--ui-border));
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
[data-component~="ui-button"][data-ui-button-state~="variant=card"][data-ui-button-state~="tone=neutral"]:hover:not(:disabled, [aria-disabled="true"]) {
|
|
1105
|
+
border-color: var(--ui-button-hover-border, var(--ui-border-strong));
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1062
1108
|
/* Pressed reads as pressed in: the highlight goes, and the shadow moves inside. */
|
|
1063
1109
|
[data-component~="ui-button"]:active:not(:disabled, [aria-disabled="true"]) {
|
|
1064
1110
|
background-color: var(--ui-button-active-surface, oklch(from var(--_tone) l c h / 18%));
|
|
@@ -1071,7 +1117,7 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
|
|
|
1071
1117
|
border-color: var(--_tone);
|
|
1072
1118
|
background-color: var(--_tone);
|
|
1073
1119
|
color: var(--_on-tone);
|
|
1074
|
-
box-shadow: var(--ui-button-solid-shadow, var(--ui-
|
|
1120
|
+
box-shadow: var(--ui-button-solid-shadow, var(--ui-action-shadow, var(--_ui-action-shadow)));
|
|
1075
1121
|
}
|
|
1076
1122
|
|
|
1077
1123
|
:is([data-component~="ui-button"][data-ui-button-state~="variant=solid"], [data-component~="ui-button"][data-ui-button-state~="variant=danger"]):hover:not(:disabled, [aria-disabled="true"]) {
|
|
@@ -1159,16 +1205,20 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
|
|
|
1159
1205
|
[data-component~="ui-button"]:focus-visible {
|
|
1160
1206
|
outline: none;
|
|
1161
1207
|
box-shadow:
|
|
1162
|
-
var(--ui-button-shadow, var(--ui-
|
|
1208
|
+
var(--ui-button-shadow, var(--ui-action-shadow, var(--_ui-action-shadow))),
|
|
1163
1209
|
var(--ui-focus-halo);
|
|
1164
1210
|
}
|
|
1165
1211
|
|
|
1166
1212
|
[data-component~="ui-button"][data-ui-button-state~="variant=solid"]:focus-visible {
|
|
1167
1213
|
box-shadow:
|
|
1168
|
-
var(--ui-button-solid-shadow, var(--ui-
|
|
1214
|
+
var(--ui-button-solid-shadow, var(--ui-action-shadow, var(--_ui-action-shadow))),
|
|
1169
1215
|
var(--ui-focus-halo);
|
|
1170
1216
|
}
|
|
1171
1217
|
|
|
1218
|
+
:is([data-component~="ui-button"][data-ui-button-state~="variant=ghost"], [data-component~="ui-button"][data-ui-button-state~="variant=link"], [data-component~="ui-button"][data-ui-button-state~="variant=card"]):focus-visible {
|
|
1219
|
+
box-shadow: var(--ui-focus-halo);
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1172
1222
|
/* A loading action stays visually active; only an explicitly disabled action takes the
|
|
1173
1223
|
neutral disabled palette. Its flat surface and muted ink make the state unambiguous. */
|
|
1174
1224
|
[data-component~="ui-button"]:is(:disabled, [aria-disabled="true"]:not([aria-busy="true"])) {
|
package/vue/UiCallout.vue
CHANGED
|
@@ -245,8 +245,10 @@ const hostState = computed(() =>
|
|
|
245
245
|
padding-inline-end: var(--ui-callout-padding-inline, var(--ui-space-3));
|
|
246
246
|
border: var(--ui-callout-border-width, var(--ui-border-width)) solid
|
|
247
247
|
color-mix(in srgb, var(--ui-callout-border, var(--_callout-border)) 35%, transparent);
|
|
248
|
-
border-inline-start: var(
|
|
249
|
-
|
|
248
|
+
border-inline-start: var(
|
|
249
|
+
--ui-callout-leading-border-width,
|
|
250
|
+
var(--ui-callout-border-width, var(--ui-border-width))
|
|
251
|
+
) solid color-mix(in srgb, var(--ui-callout-border, var(--_callout-border)) 35%, transparent);
|
|
250
252
|
border-radius: var(--ui-radius-md);
|
|
251
253
|
background: var(--ui-callout-surface, var(--_callout-surface));
|
|
252
254
|
color: var(--ui-callout-text, var(--ui-text-primary));
|
package/vue/UiIconButton.vue
CHANGED
|
@@ -474,6 +474,21 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
|
|
|
474
474
|
}
|
|
475
475
|
|
|
476
476
|
[data-component~="ui-icon-button"] {
|
|
477
|
+
/* Optional inherited action-group values keep text and icon actions under the same light.
|
|
478
|
+
One fine top/start highlight follows the bottom/end lowlight at a joined action seam.
|
|
479
|
+
A single ambient lift avoids stacking a face gradient or another inset bevel. */
|
|
480
|
+
--_ui-action-start: 1px;
|
|
481
|
+
--_ui-action-edge: var(
|
|
482
|
+
--ui-action-edge,
|
|
483
|
+
inset var(--_ui-action-start) 1px 0 light-dark(
|
|
484
|
+
rgb(255 255 255 / 0.08),
|
|
485
|
+
rgb(255 255 255 / 0.06)
|
|
486
|
+
),
|
|
487
|
+
inset calc(-1 * var(--_ui-action-start)) -1px 0 light-dark(rgb(0 0 0 / 0.08), rgb(0 0 0 / 0.08))
|
|
488
|
+
);
|
|
489
|
+
--_ui-action-shadow:
|
|
490
|
+
var(--_ui-action-edge),
|
|
491
|
+
0 1px 2px light-dark(rgb(0 0 0 / 0.10), rgb(0 0 0 / 0.20));
|
|
477
492
|
/* Hooks do not inherit, so the parts below read them from the root. */
|
|
478
493
|
--_ui-icon-button-icon-size: var(--ui-icon-button-icon-size);
|
|
479
494
|
--_ui-icon-button-icon-stroke-width: var(--ui-icon-button-icon-stroke-width);
|
|
@@ -482,6 +497,10 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
|
|
|
482
497
|
color: var(--ui-text-secondary);
|
|
483
498
|
}
|
|
484
499
|
|
|
500
|
+
[data-component~="ui-icon-button"]:dir(rtl) {
|
|
501
|
+
--_ui-action-start: -1px;
|
|
502
|
+
}
|
|
503
|
+
|
|
485
504
|
[data-component~="ui-icon-button"][data-ui-icon-button-state~="tone=accent"] {
|
|
486
505
|
--_icon-button-border: var(--ui-accent-solid);
|
|
487
506
|
--_icon-button-hover-border: var(--ui-accent-hover);
|
|
@@ -670,9 +689,9 @@ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"]::after {
|
|
|
670
689
|
--ui-icon-button-outline-surface,
|
|
671
690
|
var(--_icon-button-outline-surface, var(--ui-surface-default))
|
|
672
691
|
);
|
|
673
|
-
background-image:
|
|
692
|
+
background-image: none;
|
|
674
693
|
color: var(--ui-icon-button-outline-text, var(--_icon-button-text, var(--ui-text-primary)));
|
|
675
|
-
box-shadow: var(--ui-
|
|
694
|
+
box-shadow: var(--ui-action-shadow, var(--_ui-action-shadow));
|
|
676
695
|
}
|
|
677
696
|
|
|
678
697
|
[data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"] {
|
|
@@ -680,12 +699,9 @@ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"]::after {
|
|
|
680
699
|
--ui-icon-button-solid-surface,
|
|
681
700
|
var(--_icon-button-solid-surface, var(--ui-accent-solid))
|
|
682
701
|
);
|
|
683
|
-
background-image:
|
|
702
|
+
background-image: none;
|
|
684
703
|
color: var(--ui-icon-button-solid-text, var(--_icon-button-solid-text, var(--ui-text-on-accent)));
|
|
685
|
-
box-shadow: var(
|
|
686
|
-
--ui-icon-button-solid-shadow,
|
|
687
|
-
0 1px 2px color-mix(in srgb, var(--ui-accent-solid) 18%, transparent)
|
|
688
|
-
);
|
|
704
|
+
box-shadow: var(--ui-icon-button-solid-shadow, var(--ui-action-shadow, var(--_ui-action-shadow)));
|
|
689
705
|
}
|
|
690
706
|
|
|
691
707
|
[data-component~="ui-icon-button"]:hover:enabled:not([aria-disabled="true"]) {
|
|
@@ -765,6 +781,23 @@ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"]::after {
|
|
|
765
781
|
box-shadow: var(--ui-focus-halo);
|
|
766
782
|
}
|
|
767
783
|
|
|
784
|
+
[data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"]:focus-visible {
|
|
785
|
+
box-shadow:
|
|
786
|
+
var(--ui-action-shadow, var(--_ui-action-shadow)),
|
|
787
|
+
var(--ui-focus-halo);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
[data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"]:focus-visible {
|
|
791
|
+
box-shadow:
|
|
792
|
+
var(--ui-icon-button-solid-shadow, var(--ui-action-shadow, var(--_ui-action-shadow))),
|
|
793
|
+
var(--ui-focus-halo);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
[data-component~="ui-icon-button"]:is([data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"], [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"]):active:enabled:not([aria-disabled="true"]) {
|
|
797
|
+
background-image: none;
|
|
798
|
+
box-shadow: var(--ui-pressed);
|
|
799
|
+
}
|
|
800
|
+
|
|
768
801
|
[data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"][aria-pressed="true"]:enabled:focus-visible {
|
|
769
802
|
box-shadow:
|
|
770
803
|
var(--ui-pressed),
|
package/vue/UiInputGroup.d.ts
CHANGED
|
@@ -26,6 +26,10 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
26
26
|
type: PropType<"text" | "icon" | null>;
|
|
27
27
|
default: string;
|
|
28
28
|
};
|
|
29
|
+
variant: {
|
|
30
|
+
type: PropType<"outline" | "subtle" | null>;
|
|
31
|
+
default: string;
|
|
32
|
+
};
|
|
29
33
|
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
30
34
|
actionPosition: {
|
|
31
35
|
type: PropType<"below" | "top-end" | null>;
|
|
@@ -43,7 +47,12 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
43
47
|
type: PropType<"text" | "icon" | null>;
|
|
44
48
|
default: string;
|
|
45
49
|
};
|
|
50
|
+
variant: {
|
|
51
|
+
type: PropType<"outline" | "subtle" | null>;
|
|
52
|
+
default: string;
|
|
53
|
+
};
|
|
46
54
|
}>> & Readonly<{}>, {
|
|
55
|
+
variant: "subtle" | "outline" | null;
|
|
47
56
|
disabled: boolean | null;
|
|
48
57
|
multiline: boolean | null;
|
|
49
58
|
actionPosition: "top-end" | "below" | null;
|
package/vue/UiInputGroup.vue
CHANGED
|
@@ -42,6 +42,15 @@ const propValidityContract = {
|
|
|
42
42
|
values: ['text', 'icon'],
|
|
43
43
|
default: 'text',
|
|
44
44
|
},
|
|
45
|
+
variant: {
|
|
46
|
+
type: { kind: 'terminal', name: 'keyword' },
|
|
47
|
+
required: false,
|
|
48
|
+
target: { attribute: 'variant' },
|
|
49
|
+
description:
|
|
50
|
+
'outline uses the standard field edge and surface. subtle uses a quiet decorative edge and muted surface for a multiline composer. Both retain the same\n focus, invalid and disabled states, and the field inside shares the group\'s one frame.',
|
|
51
|
+
values: ['outline', 'subtle'],
|
|
52
|
+
default: 'outline',
|
|
53
|
+
},
|
|
45
54
|
},
|
|
46
55
|
} as const
|
|
47
56
|
const props = defineProps({
|
|
@@ -52,12 +61,14 @@ const props = defineProps({
|
|
|
52
61
|
disabled: { type: null as unknown as PropType<boolean | null>, default: false },
|
|
53
62
|
multiline: { type: null as unknown as PropType<boolean | null>, default: false },
|
|
54
63
|
prefixKind: { type: null as unknown as PropType<'text' | 'icon' | null>, default: 'text' },
|
|
64
|
+
variant: { type: null as unknown as PropType<'outline' | 'subtle' | null>, default: 'outline' },
|
|
55
65
|
})
|
|
56
66
|
const acceptedProps: Record<string, unknown> = {
|
|
57
67
|
actionPosition: 'below',
|
|
58
68
|
disabled: false,
|
|
59
69
|
multiline: false,
|
|
60
70
|
prefixKind: 'text',
|
|
71
|
+
variant: 'outline',
|
|
61
72
|
}
|
|
62
73
|
const checkedProps = computed(() => ({
|
|
63
74
|
actionPosition: checkedProp<'below' | 'top-end'>(
|
|
@@ -88,6 +99,13 @@ const checkedProps = computed(() => ({
|
|
|
88
99
|
'prefixKind',
|
|
89
100
|
acceptedProps,
|
|
90
101
|
) as 'text' | 'icon',
|
|
102
|
+
variant: checkedProp<'outline' | 'subtle'>(
|
|
103
|
+
props['variant'],
|
|
104
|
+
{ kind: 'terminal', name: 'keyword' },
|
|
105
|
+
false,
|
|
106
|
+
'variant',
|
|
107
|
+
acceptedProps,
|
|
108
|
+
) as 'outline' | 'subtle',
|
|
91
109
|
}))
|
|
92
110
|
void checkedProps.value
|
|
93
111
|
watchSyncEffect(() => {
|
|
@@ -148,6 +166,9 @@ if (
|
|
|
148
166
|
/** The values the styles' :host-state() rules test. */
|
|
149
167
|
const hostState = computed(() =>
|
|
150
168
|
[
|
|
169
|
+
checkedProps.value.variant && 'variant',
|
|
170
|
+
checkedProps.value.variant != null
|
|
171
|
+
&& `variant=${encodeURIComponent(checkedProps.value.variant)}`,
|
|
151
172
|
checkedProps.value.disabled && 'disabled',
|
|
152
173
|
checkedProps.value.prefixKind && 'prefixKind',
|
|
153
174
|
checkedProps.value.prefixKind != null
|
|
@@ -176,7 +197,7 @@ useComponentHost(() => import('../components/ui-input-group/ui-input-group.js'),
|
|
|
176
197
|
? (incoming[name] ?? incoming[kebab] ?? null)
|
|
177
198
|
: null
|
|
178
199
|
},
|
|
179
|
-
propNames: ['actionPosition', 'disabled', 'multiline', 'prefixKind'],
|
|
200
|
+
propNames: ['actionPosition', 'disabled', 'multiline', 'prefixKind', 'variant'],
|
|
180
201
|
propValidity: (name: string) =>
|
|
181
202
|
propValidityState({ contract: propValidityContract, values: { ...props } }, name),
|
|
182
203
|
})
|
|
@@ -191,6 +212,7 @@ useComponentHost(() => import('../components/ui-input-group/ui-input-group.js'),
|
|
|
191
212
|
:data-disabled="reflectedProp('disabled', 'disabled', checkedProps.disabled, undefined, false)"
|
|
192
213
|
:data-multiline="reflectedProp('multiline', 'multiline', checkedProps.multiline, undefined, false)"
|
|
193
214
|
:data-prefix-kind="reflectedProp('prefixKind', 'prefix-kind', checkedProps.prefixKind, undefined, false)"
|
|
215
|
+
:data-variant="reflectedProp('variant', 'variant', checkedProps.variant, undefined, false)"
|
|
194
216
|
:data-ui-input-group-state="hostState || undefined"
|
|
195
217
|
ref="root"
|
|
196
218
|
>
|
|
@@ -268,6 +290,12 @@ useComponentHost(() => import('../components/ui-input-group/ui-input-group.js'),
|
|
|
268
290
|
box-shadow var(--ui-motion-fast) var(--ui-motion-ease);
|
|
269
291
|
}
|
|
270
292
|
|
|
293
|
+
[data-component~="ui-input-group"][data-ui-input-group-state~="variant=subtle"] {
|
|
294
|
+
border-color: var(--ui-border);
|
|
295
|
+
background: var(--ui-surface-muted);
|
|
296
|
+
box-shadow: none;
|
|
297
|
+
}
|
|
298
|
+
|
|
271
299
|
/* The frame takes its input's size, so a small group lines up with small buttons and fields. */
|
|
272
300
|
[data-component~="ui-input-group"]:has(.field [data-ui-input-state~="size=sm"]) {
|
|
273
301
|
min-block-size: var(--ui-control-size-sm);
|
package/vue/UiToast.vue
CHANGED
|
@@ -234,6 +234,7 @@ function attribute(value: unknown): any {
|
|
|
234
234
|
|
|
235
235
|
[data-component~="ui-toast"] {
|
|
236
236
|
--_ui-toast-accent: var(--ui-border-strong);
|
|
237
|
+
--_ui-toast-surface: var(--ui-surface-muted);
|
|
237
238
|
|
|
238
239
|
display: flex;
|
|
239
240
|
align-items: center;
|
|
@@ -242,13 +243,20 @@ function attribute(value: unknown): any {
|
|
|
242
243
|
inline-size: 100%;
|
|
243
244
|
margin: 0;
|
|
244
245
|
padding: var(--ui-space-3) var(--ui-space-4);
|
|
246
|
+
/* The close button's internal space supplies the rest of the trailing inset. */
|
|
247
|
+
padding-inline-end: var(--ui-space-2);
|
|
245
248
|
border: var(--ui-border-width) solid
|
|
246
|
-
var(
|
|
247
|
-
|
|
248
|
-
|
|
249
|
+
var(
|
|
250
|
+
--ui-toast-border,
|
|
251
|
+
var(--ui-overlay-border, var(--ui-toast-accent, var(--_ui-toast-accent)))
|
|
252
|
+
);
|
|
249
253
|
border-radius: var(--ui-toast-radius, var(--ui-overlay-radius, var(--ui-radius-lg)));
|
|
250
|
-
background: var(--ui-toast-surface, var(--ui-overlay-surface, var(--
|
|
254
|
+
background: var(--ui-toast-surface, var(--ui-overlay-surface, var(--_ui-toast-surface)));
|
|
251
255
|
color: var(--ui-text-primary);
|
|
256
|
+
font-family: var(--ui-font-family-sans);
|
|
257
|
+
font-size: var(--ui-font-size-sm);
|
|
258
|
+
font-weight: var(--ui-font-normal);
|
|
259
|
+
line-height: var(--ui-line-height-md);
|
|
252
260
|
box-shadow: var(
|
|
253
261
|
--ui-toast-shadow,
|
|
254
262
|
var(--ui-overlay-shadow, var(--ui-elevation-overlay, var(--ui-shadow-lg)))
|
|
@@ -258,15 +266,19 @@ function attribute(value: unknown): any {
|
|
|
258
266
|
|
|
259
267
|
[data-component~="ui-toast"][data-ui-toast-state~="tone=info"] {
|
|
260
268
|
--_ui-toast-accent: var(--ui-info-solid);
|
|
269
|
+
--_ui-toast-surface: var(--ui-info-soft);
|
|
261
270
|
}
|
|
262
271
|
[data-component~="ui-toast"][data-ui-toast-state~="tone=success"] {
|
|
263
272
|
--_ui-toast-accent: var(--ui-success-solid);
|
|
273
|
+
--_ui-toast-surface: var(--ui-success-soft);
|
|
264
274
|
}
|
|
265
275
|
[data-component~="ui-toast"][data-ui-toast-state~="tone=warning"] {
|
|
266
276
|
--_ui-toast-accent: var(--ui-warning-solid);
|
|
277
|
+
--_ui-toast-surface: var(--ui-warning-soft);
|
|
267
278
|
}
|
|
268
279
|
[data-component~="ui-toast"][data-ui-toast-state~="tone=danger"] {
|
|
269
280
|
--_ui-toast-accent: var(--ui-danger-solid);
|
|
281
|
+
--_ui-toast-surface: var(--ui-danger-soft);
|
|
270
282
|
}
|
|
271
283
|
|
|
272
284
|
.message {
|
|
@@ -276,10 +288,6 @@ function attribute(value: unknown): any {
|
|
|
276
288
|
.action:not(:has(> *)) {
|
|
277
289
|
display: none;
|
|
278
290
|
}
|
|
279
|
-
.dismiss {
|
|
280
|
-
margin-inline-end: calc(var(--ui-space-2) * -1);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
291
|
[data-component~="ui-toast"][hidden] {
|
|
284
292
|
display: none;
|
|
285
293
|
}
|
package/vue/UiToastRegion.vue
CHANGED
|
@@ -460,19 +460,27 @@ function uniqueKeys<T>(
|
|
|
460
460
|
}
|
|
461
461
|
|
|
462
462
|
.toast {
|
|
463
|
+
--_ui-toast-region-accent: var(--ui-border-strong);
|
|
464
|
+
--_ui-toast-region-tone-surface: var(--ui-surface-muted);
|
|
463
465
|
display: grid;
|
|
464
466
|
grid-template-columns: 1fr auto;
|
|
465
467
|
gap: var(--ui-space-2);
|
|
466
468
|
align-items: start;
|
|
467
469
|
border: var(--ui-border-width) solid
|
|
468
|
-
var(--_ui-toast-region-border, var(--ui-overlay-border, var(--
|
|
470
|
+
var(--_ui-toast-region-border, var(--ui-overlay-border, var(--_ui-toast-region-accent)));
|
|
469
471
|
border-radius: var(--_ui-toast-region-radius, var(--ui-overlay-radius, var(--ui-radius-lg)));
|
|
470
472
|
padding: var(--ui-space-3) var(--ui-space-4);
|
|
473
|
+
/* The close button's internal space supplies the rest of the trailing inset. */
|
|
474
|
+
padding-inline-end: var(--ui-space-2);
|
|
471
475
|
background: var(
|
|
472
476
|
--_ui-toast-region-surface,
|
|
473
|
-
var(--ui-overlay-surface, var(--
|
|
477
|
+
var(--ui-overlay-surface, var(--_ui-toast-region-tone-surface))
|
|
474
478
|
);
|
|
475
479
|
color: var(--ui-text-primary);
|
|
480
|
+
font-family: var(--ui-font-family-sans);
|
|
481
|
+
font-size: var(--ui-font-size-sm);
|
|
482
|
+
font-weight: var(--ui-font-normal);
|
|
483
|
+
line-height: var(--ui-line-height-md);
|
|
476
484
|
box-shadow: var(
|
|
477
485
|
--_ui-toast-region-shadow,
|
|
478
486
|
var(--ui-overlay-shadow, var(--ui-elevation-overlay, var(--ui-shadow-lg)))
|
|
@@ -482,16 +490,20 @@ function uniqueKeys<T>(
|
|
|
482
490
|
}
|
|
483
491
|
|
|
484
492
|
.toast[data-tone="info"] {
|
|
485
|
-
|
|
493
|
+
--_ui-toast-region-accent: var(--ui-info-solid);
|
|
494
|
+
--_ui-toast-region-tone-surface: var(--ui-info-soft);
|
|
486
495
|
}
|
|
487
496
|
.toast[data-tone="success"] {
|
|
488
|
-
|
|
497
|
+
--_ui-toast-region-accent: var(--ui-success-solid);
|
|
498
|
+
--_ui-toast-region-tone-surface: var(--ui-success-soft);
|
|
489
499
|
}
|
|
490
500
|
.toast[data-tone="warning"] {
|
|
491
|
-
|
|
501
|
+
--_ui-toast-region-accent: var(--ui-warning-solid);
|
|
502
|
+
--_ui-toast-region-tone-surface: var(--ui-warning-soft);
|
|
492
503
|
}
|
|
493
504
|
.toast[data-tone="danger"] {
|
|
494
|
-
|
|
505
|
+
--_ui-toast-region-accent: var(--ui-danger-solid);
|
|
506
|
+
--_ui-toast-region-tone-surface: var(--ui-danger-soft);
|
|
495
507
|
}
|
|
496
508
|
|
|
497
509
|
/* Leaving slides on down and fades; the controller removes the toast when this ends. */
|
|
@@ -567,7 +579,6 @@ function uniqueKeys<T>(
|
|
|
567
579
|
|
|
568
580
|
.dismiss {
|
|
569
581
|
align-self: center;
|
|
570
|
-
margin-inline-end: calc(var(--ui-space-2) * -1);
|
|
571
582
|
}
|
|
572
583
|
|
|
573
584
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
package/vue/chunks/UiBadge.js
CHANGED
|
@@ -63,9 +63,10 @@ var UiBadge_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE
|
|
|
63
63
|
},
|
|
64
64
|
required: false,
|
|
65
65
|
target: { attribute: "size" },
|
|
66
|
-
description: "Scale. xs is compact; md is the usual text
|
|
66
|
+
description: "Scale. xs is compact; sm keeps the usual badge geometry with compact text, fitting short counts such as 99+ inside a 24px circle. md is the usual text\n badge; lg adds room to fixed marks while retaining the usual text size. A square is 24px at xs, 32px at sm and md, and 40px at lg. A circle is 16px at xs,\n 24px at sm and md, and 32px at lg.",
|
|
67
67
|
values: [
|
|
68
68
|
"xs",
|
|
69
|
+
"sm",
|
|
69
70
|
"md",
|
|
70
71
|
"lg"
|
|
71
72
|
],
|
|
@@ -179,6 +180,6 @@ var UiBadge_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE
|
|
|
179
180
|
}]]);
|
|
180
181
|
};
|
|
181
182
|
}
|
|
182
|
-
}), [["__scopeId", "data-v-
|
|
183
|
+
}), [["__scopeId", "data-v-57826cf9"]]);
|
|
183
184
|
//#endregion
|
|
184
185
|
export { UiBadge_default as t };
|