@threadlabs/looma 0.26.0 → 0.26.2
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 +42 -3
- package/components/ui-container/ui-container.html +11 -0
- package/components/ui-dialog/ui-dialog.html +6 -4
- package/components/ui-icon-button/ui-icon-button.html +58 -12
- package/components/ui-scroll-area/ui-scroll-area.html +12 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/styles/ui-badge.css +40 -0
- package/styles/ui-container.css +8 -0
- package/styles/ui-dialog.css +6 -4
- package/styles/ui-icon-button.css +62 -12
- package/styles/ui-scroll-area.css +11 -0
- package/vanilla/UiBadge.d.ts +1 -1
- package/vanilla/UiBadge.js +1 -1
- package/vanilla/UiContainer.d.ts +1 -0
- package/vanilla/UiContainer.js +5 -5
- package/vanilla/UiDialog.js +14 -8
- package/vanilla/UiIconButton.d.ts +1 -0
- package/vanilla/UiIconButton.js +4 -4
- package/vanilla/UiScrollArea.d.ts +1 -0
- package/vanilla/UiScrollArea.js +4 -4
- package/vue/UiBadge.d.ts +3 -3
- package/vue/UiBadge.vue +44 -6
- package/vue/UiContainer.d.ts +9 -0
- package/vue/UiContainer.vue +27 -1
- package/vue/UiDialog.vue +6 -4
- package/vue/UiIconButton.d.ts +9 -0
- package/vue/UiIconButton.vue +95 -12
- package/vue/UiScrollArea.d.ts +9 -0
- package/vue/UiScrollArea.vue +33 -1
- package/vue/chunks/UiBadge.js +5 -4
- package/vue/chunks/UiContainer.js +23 -1
- package/vue/chunks/UiDialog.js +4 -3
- package/vue/chunks/UiIconButton.js +25 -1
- package/vue/chunks/UiScrollArea.js +28 -5
- package/vue/components.css +254 -140
package/package.json
CHANGED
package/styles/ui-badge.css
CHANGED
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
syntax: "*";
|
|
8
8
|
inherits: false;
|
|
9
9
|
}
|
|
10
|
+
@property --ui-badge-circle-size {
|
|
11
|
+
syntax: "*";
|
|
12
|
+
inherits: false;
|
|
13
|
+
}
|
|
10
14
|
@property --ui-badge-dot-size {
|
|
11
15
|
syntax: "*";
|
|
12
16
|
inherits: false;
|
|
@@ -282,6 +286,36 @@
|
|
|
282
286
|
display: none;
|
|
283
287
|
}
|
|
284
288
|
|
|
289
|
+
/* A visible glyph needs fixed geometry, unlike a content-sized pill or a hidden-label dot. */
|
|
290
|
+
:scope[data-ui-badge-state~="shape=circle"] {
|
|
291
|
+
--_badge-circle-size: var(--ui-badge-circle-size, calc(var(--ui-space-3) * 2));
|
|
292
|
+
display: inline-flex;
|
|
293
|
+
flex: none;
|
|
294
|
+
inline-size: var(--_badge-circle-size);
|
|
295
|
+
block-size: var(--_badge-circle-size);
|
|
296
|
+
min-inline-size: var(--_badge-circle-size);
|
|
297
|
+
min-block-size: var(--_badge-circle-size);
|
|
298
|
+
padding: 0;
|
|
299
|
+
border-radius: var(--ui-radius-round);
|
|
300
|
+
text-box-trim: none;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
:scope[data-ui-badge-state~="shape=circle"][data-ui-badge-state~="size=xs"] {
|
|
304
|
+
--_badge-circle-size: var(--ui-badge-circle-size, var(--ui-space-4));
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
:scope[data-ui-badge-state~="shape=circle"] .label {
|
|
308
|
+
display: inline-flex;
|
|
309
|
+
align-items: center;
|
|
310
|
+
justify-content: center;
|
|
311
|
+
line-height: 1;
|
|
312
|
+
text-box-trim: none;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
:scope[data-ui-badge-state~="shape=circle"] .label:empty {
|
|
316
|
+
display: none;
|
|
317
|
+
}
|
|
318
|
+
|
|
285
319
|
/* A dot uses the badge's tone recipe; only its silhouette and visible label change. */
|
|
286
320
|
:scope[data-ui-badge-state~="shape=dot"] {
|
|
287
321
|
position: relative;
|
|
@@ -399,6 +433,12 @@
|
|
|
399
433
|
margin-inline-end: 0;
|
|
400
434
|
}
|
|
401
435
|
|
|
436
|
+
/* A visible glyph needs fixed geometry, unlike a content-sized pill or a hidden-label dot. */
|
|
437
|
+
|
|
438
|
+
:scope[data-ui-badge-state~="shape=circle"] .label :where([data-slotted], [data-slotted] *):is(svg) {
|
|
439
|
+
margin-inline-end: 0;
|
|
440
|
+
}
|
|
441
|
+
|
|
402
442
|
/* A dot uses the badge's tone recipe; only its silhouette and visible label change. */
|
|
403
443
|
|
|
404
444
|
/* The clipped point needs an inset surface over an outer border-colour shape: a native border
|
package/styles/ui-container.css
CHANGED
|
@@ -23,6 +23,14 @@
|
|
|
23
23
|
:scope[data-ui-container-state~="measure=narrow"] {
|
|
24
24
|
--_container-measure: 45ch;
|
|
25
25
|
}
|
|
26
|
+
:scope[data-ui-container-state~="fill"] {
|
|
27
|
+
box-sizing: border-box;
|
|
28
|
+
display: flex;
|
|
29
|
+
flex-direction: column;
|
|
30
|
+
flex: 1;
|
|
31
|
+
min-inline-size: 0;
|
|
32
|
+
min-block-size: 0;
|
|
33
|
+
}
|
|
26
34
|
:scope[data-ui-container-state~="measure=wide"] {
|
|
27
35
|
--_container-measure: 80ch;
|
|
28
36
|
}
|
package/styles/ui-dialog.css
CHANGED
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
display: none;
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
/*
|
|
107
|
+
/* Own the layout wrapper; nested component roots are outside these scoped rules. */
|
|
108
108
|
header {
|
|
109
109
|
display: flex;
|
|
110
110
|
align-items: center;
|
|
@@ -183,9 +183,11 @@
|
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
.body {
|
|
186
|
+
display: flex;
|
|
187
|
+
flex-direction: column;
|
|
186
188
|
flex: 1 1 auto;
|
|
187
189
|
min-block-size: 0;
|
|
188
|
-
padding: var(--ui-space-5);
|
|
190
|
+
padding: var(--ui-space-3) var(--ui-space-5) var(--ui-space-5);
|
|
189
191
|
}
|
|
190
192
|
|
|
191
193
|
footer {
|
|
@@ -194,7 +196,7 @@
|
|
|
194
196
|
flex-wrap: wrap;
|
|
195
197
|
justify-content: flex-end;
|
|
196
198
|
gap: var(--ui-space-2);
|
|
197
|
-
padding: var(--ui-space-
|
|
199
|
+
padding: 0 var(--ui-space-5) var(--ui-space-5);
|
|
198
200
|
}
|
|
199
201
|
|
|
200
202
|
footer:empty {
|
|
@@ -223,7 +225,7 @@
|
|
|
223
225
|
@scope ([data-component~="ui-dialog"]) to ([data-component]) {
|
|
224
226
|
/* This component's hooks style the element they are set on, and never a nested one. */
|
|
225
227
|
|
|
226
|
-
/*
|
|
228
|
+
/* Own the layout wrapper; nested component roots are outside these scoped rules. */
|
|
227
229
|
|
|
228
230
|
/* :host-qualified so page heading rules that reach in cannot outrank the dialog chrome. */
|
|
229
231
|
|
|
@@ -87,6 +87,21 @@
|
|
|
87
87
|
color: var(--ui-text-secondary);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
:scope[data-ui-icon-button-state~="tone=accent"] {
|
|
91
|
+
--_icon-button-border: var(--ui-accent-solid);
|
|
92
|
+
--_icon-button-hover-border: var(--ui-accent-hover);
|
|
93
|
+
--_icon-button-text: var(--ui-accent-subtle-text, var(--ui-accent-solid));
|
|
94
|
+
--_icon-button-outline-surface: color-mix(in srgb, var(--ui-accent-solid) 5%, var(--ui-surface-default));
|
|
95
|
+
color: var(--_icon-button-text);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* Omitted tone retains the existing accent solid; explicit neutral is additive. */
|
|
99
|
+
:scope[data-ui-icon-button-state~="tone=neutral"] {
|
|
100
|
+
--_icon-button-solid-surface: var(--ui-text-primary);
|
|
101
|
+
--_icon-button-solid-hover-surface: var(--ui-text-primary);
|
|
102
|
+
--_icon-button-solid-text: var(--ui-surface-default);
|
|
103
|
+
}
|
|
104
|
+
|
|
90
105
|
:scope[data-ui-icon-button-state~="anticipatory"] {
|
|
91
106
|
position: relative;
|
|
92
107
|
}
|
|
@@ -119,13 +134,13 @@
|
|
|
119
134
|
}
|
|
120
135
|
|
|
121
136
|
@media (hover: hover) and (pointer: fine) {
|
|
122
|
-
: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) {
|
|
137
|
+
: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, [aria-pressed="true"], [data-ui-proximity="near"], :hover, :focus-visible) {
|
|
123
138
|
border-color: transparent;
|
|
124
139
|
background-color: transparent;
|
|
125
140
|
box-shadow: none;
|
|
126
141
|
}
|
|
127
142
|
|
|
128
|
-
: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)
|
|
143
|
+
: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, [aria-pressed="true"], [data-ui-proximity="near"], :hover, :focus-visible)
|
|
129
144
|
.content {
|
|
130
145
|
opacity: 0;
|
|
131
146
|
transform: scale(0.65);
|
|
@@ -133,7 +148,7 @@
|
|
|
133
148
|
}
|
|
134
149
|
}
|
|
135
150
|
|
|
136
|
-
:scope[data-ui-icon-button-state~="anticipatory"]:is(:scope[data-ui-icon-button-state~="variant=solid"], [data-ui-proximity="near"], :hover, :focus-visible)::before {
|
|
151
|
+
:scope[data-ui-icon-button-state~="anticipatory"]:is(:scope[data-ui-icon-button-state~="variant=solid"], [aria-pressed="true"], [data-ui-proximity="near"], :hover, :focus-visible)::before {
|
|
137
152
|
opacity: 0;
|
|
138
153
|
}
|
|
139
154
|
|
|
@@ -243,17 +258,17 @@
|
|
|
243
258
|
}
|
|
244
259
|
|
|
245
260
|
:scope[data-ui-icon-button-state~="variant=outline"] {
|
|
246
|
-
border-color: var(--ui-icon-button-border, var(--ui-control-border, var(--ui-border-strong)));
|
|
247
|
-
background-color: var(--ui-icon-button-outline-surface, var(--ui-surface-default));
|
|
261
|
+
border-color: var(--ui-icon-button-border, var(--_icon-button-border, var(--ui-control-border, var(--ui-border-strong))));
|
|
262
|
+
background-color: var(--ui-icon-button-outline-surface, var(--_icon-button-outline-surface, var(--ui-surface-default)));
|
|
248
263
|
background-image: var(--ui-raised-highlight);
|
|
249
|
-
color: var(--ui-icon-button-outline-text, var(--ui-text-primary));
|
|
264
|
+
color: var(--ui-icon-button-outline-text, var(--_icon-button-text, var(--ui-text-primary)));
|
|
250
265
|
box-shadow: var(--ui-raised);
|
|
251
266
|
}
|
|
252
267
|
|
|
253
268
|
:scope[data-ui-icon-button-state~="variant=solid"] {
|
|
254
|
-
background-color: var(--ui-icon-button-solid-surface, var(--ui-accent-solid));
|
|
269
|
+
background-color: var(--ui-icon-button-solid-surface, var(--_icon-button-solid-surface, var(--ui-accent-solid)));
|
|
255
270
|
background-image: var(--ui-raised-highlight);
|
|
256
|
-
color: var(--ui-icon-button-solid-text, var(--ui-text-on-accent));
|
|
271
|
+
color: var(--ui-icon-button-solid-text, var(--_icon-button-solid-text, var(--ui-text-on-accent)));
|
|
257
272
|
box-shadow: var(
|
|
258
273
|
--ui-icon-button-solid-shadow,
|
|
259
274
|
0 1px 2px color-mix(in srgb, var(--ui-accent-solid) 18%, transparent)
|
|
@@ -263,20 +278,32 @@
|
|
|
263
278
|
:scope:hover:enabled:not([aria-disabled="true"]) {
|
|
264
279
|
/* Derived from the text colour so the ghost hover shows on any background. */
|
|
265
280
|
background-color: var(--ui-icon-button-hover-surface, color-mix(in srgb, currentColor 8%, transparent));
|
|
266
|
-
color: var(--ui-icon-button-hover-text, var(--ui-text-primary));
|
|
281
|
+
color: var(--ui-icon-button-hover-text, var(--_icon-button-text, var(--ui-text-primary)));
|
|
267
282
|
}
|
|
268
283
|
|
|
269
284
|
:scope[data-ui-icon-button-state~="variant=outline"]:hover:enabled:not([aria-disabled="true"]) {
|
|
270
|
-
border-color: var(--ui-icon-button-hover-border, var(--ui-control-border-hover, var(--ui-control-border)));
|
|
285
|
+
border-color: var(--ui-icon-button-hover-border, var(--_icon-button-hover-border, var(--ui-control-border-hover, var(--ui-control-border))));
|
|
271
286
|
}
|
|
272
287
|
|
|
273
288
|
:scope[data-ui-icon-button-state~="variant=solid"]:hover:enabled:not([aria-disabled="true"]) {
|
|
274
|
-
background-color: var(--ui-icon-button-solid-hover-surface, var(--ui-accent-hover));
|
|
289
|
+
background-color: var(--ui-icon-button-solid-hover-surface, var(--_icon-button-solid-hover-surface, var(--ui-accent-hover)));
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
:scope[data-ui-icon-button-state~="variant=solid"][data-ui-icon-button-state~="tone=accent"]:hover:enabled:not([aria-disabled="true"]),
|
|
293
|
+
:scope[data-ui-icon-button-state~="variant=solid"][data-ui-icon-button-state~="tone=neutral"]:hover:enabled:not([aria-disabled="true"]) {
|
|
294
|
+
color: var(--ui-icon-button-solid-text, var(--_icon-button-solid-text, var(--ui-text-on-accent)));
|
|
275
295
|
}
|
|
276
296
|
|
|
277
297
|
:scope[data-ui-icon-button-state~="variant=ghost"][aria-expanded="true"]:enabled:not([aria-disabled="true"]) {
|
|
278
298
|
background-color: var(--ui-icon-button-active-surface, color-mix(in srgb, currentColor 16%, transparent));
|
|
279
|
-
color: var(--ui-icon-button-hover-text, var(--ui-text-primary));
|
|
299
|
+
color: var(--ui-icon-button-hover-text, var(--_icon-button-text, var(--ui-text-primary)));
|
|
300
|
+
box-shadow: var(--ui-pressed);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/* Native toggle state persists after pointer release, including during loading. */
|
|
304
|
+
:scope[data-ui-icon-button-state~="variant=outline"][aria-pressed="true"]:enabled {
|
|
305
|
+
background-color: var(--ui-icon-button-active-surface, color-mix(in srgb, currentColor 12%, var(--ui-surface-default)));
|
|
306
|
+
background-image: none;
|
|
280
307
|
box-shadow: var(--ui-pressed);
|
|
281
308
|
}
|
|
282
309
|
|
|
@@ -309,6 +336,22 @@
|
|
|
309
336
|
box-shadow: var(--ui-focus-halo);
|
|
310
337
|
}
|
|
311
338
|
|
|
339
|
+
:scope[data-ui-icon-button-state~="variant=outline"][aria-pressed="true"]:enabled:focus-visible {
|
|
340
|
+
box-shadow:
|
|
341
|
+
var(--ui-pressed),
|
|
342
|
+
var(--ui-focus-halo);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
@media (forced-colors: active) {
|
|
346
|
+
:scope[data-ui-icon-button-state~="variant=outline"][aria-pressed="true"]:enabled {
|
|
347
|
+
outline: var(--ui-focus-width) solid Highlight;
|
|
348
|
+
outline-offset: calc(-2 * var(--ui-focus-width));
|
|
349
|
+
}
|
|
350
|
+
:scope[data-ui-icon-button-state~="variant=outline"][aria-pressed="true"]:enabled:focus-visible {
|
|
351
|
+
outline-offset: var(--ui-focus-width);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
312
355
|
/* Disabled is a flat neutral control, independent of the active variant's tone. */
|
|
313
356
|
:scope:disabled {
|
|
314
357
|
border-color: var(--ui-disabled-border);
|
|
@@ -349,6 +392,8 @@
|
|
|
349
392
|
@scope ([data-component~="ui-icon-button"]) to ([data-component]) {
|
|
350
393
|
/* This component's hooks style the element they are set on, and never a nested one. */
|
|
351
394
|
|
|
395
|
+
/* Omitted tone retains the existing accent solid; explicit neutral is additive. */
|
|
396
|
+
|
|
352
397
|
/* At rest an anticipatory button shows only its guide dot. The icon grows into place when
|
|
353
398
|
proximity, hover, or focus reveals it; the button's hit area and guide remain stable. */
|
|
354
399
|
|
|
@@ -368,9 +413,14 @@
|
|
|
368
413
|
@media (pointer: coarse) {
|
|
369
414
|
}
|
|
370
415
|
|
|
416
|
+
/* Native toggle state persists after pointer release, including during loading. */
|
|
417
|
+
|
|
371
418
|
@media (prefers-reduced-motion: reduce) {
|
|
372
419
|
}
|
|
373
420
|
|
|
421
|
+
@media (forced-colors: active) {
|
|
422
|
+
}
|
|
423
|
+
|
|
374
424
|
/* Disabled is a flat neutral control, independent of the active variant's tone. */
|
|
375
425
|
|
|
376
426
|
:where([data-slotted], [data-slotted] *):is(svg) {
|
|
@@ -31,6 +31,8 @@
|
|
|
31
31
|
display: flow-root;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
/* Trim projected edges without changing spacing inside an item. */
|
|
35
|
+
|
|
34
36
|
:scope[data-ui-scroll-area-state~="orientation=horizontal"] {
|
|
35
37
|
overflow-x: auto;
|
|
36
38
|
overflow-y: hidden;
|
|
@@ -61,5 +63,14 @@
|
|
|
61
63
|
into whatever is behind the area without needing to know its colour. Before upgrade, its
|
|
62
64
|
zero-length defaults leave the authored scroll area fully visible. */
|
|
63
65
|
|
|
66
|
+
/* Trim projected edges without changing spacing inside an item. */
|
|
67
|
+
:scope[data-ui-scroll-area-state~="trim"] .content > :where([data-slotted], [data-slotted] *):is(:first-child) {
|
|
68
|
+
margin-block-start: 0;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
:scope[data-ui-scroll-area-state~="trim"] .content > :where([data-slotted], [data-slotted] *):is(:last-child) {
|
|
72
|
+
margin-block-end: 0;
|
|
73
|
+
}
|
|
74
|
+
|
|
64
75
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
|
65
76
|
}
|
package/vanilla/UiBadge.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export interface UiBadgeElement extends HTMLSpanElement {
|
|
|
6
6
|
removeEventListener<K extends keyof UiBadgeEventMap>(type: K, listener: (this: UiBadgeElement, event: UiBadgeEventMap[K]) => unknown, options?: boolean | EventListenerOptions): void;
|
|
7
7
|
}
|
|
8
8
|
export interface UiBadgeProps {
|
|
9
|
-
shape?: "pill" | "tag" | "dot" | "square" | null;
|
|
9
|
+
shape?: "pill" | "tag" | "dot" | "square" | "circle" | null;
|
|
10
10
|
size?: "xs" | "md" | null;
|
|
11
11
|
tone?: "neutral" | "accent" | "info" | "success" | "warning" | "danger" | null;
|
|
12
12
|
variant?: "solid" | "subtle" | "outline" | null;
|
package/vanilla/UiBadge.js
CHANGED
|
@@ -7,7 +7,7 @@ const T1 = ["",[]];
|
|
|
7
7
|
const T2 = ["",[]];
|
|
8
8
|
let P0, P1, P2;
|
|
9
9
|
const S = { n: [], t: [], f: import.meta.url, g: "ui-badge" };
|
|
10
|
-
const D = { props: { "shape": { "required":false,"values":["pill","tag","dot","square"],"default":"pill", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "size": { "required":false,"values":["xs","md"],"default":"md", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "tone": { "required":false,"values":["neutral","accent","info","success","warning","danger"],"default":"neutral", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "variant": { "required":false,"values":["solid","subtle","outline"],"default":"subtle", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] } } };
|
|
10
|
+
const D = { props: { "shape": { "required":false,"values":["pill","tag","dot","square","circle"],"default":"pill", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "size": { "required":false,"values":["xs","md"],"default":"md", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "tone": { "required":false,"values":["neutral","accent","info","success","warning","danger"],"default":"neutral", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "variant": { "required":false,"values":["solid","subtle","outline"],"default":"subtle", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] } } };
|
|
11
11
|
|
|
12
12
|
export function createUiBadge(options = {}, html) {
|
|
13
13
|
const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
|
package/vanilla/UiContainer.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export interface UiContainerElement extends HTMLDivElement {
|
|
|
6
6
|
removeEventListener<K extends keyof UiContainerEventMap>(type: K, listener: (this: UiContainerElement, event: UiContainerEventMap[K]) => unknown, options?: boolean | EventListenerOptions): void;
|
|
7
7
|
}
|
|
8
8
|
export interface UiContainerProps {
|
|
9
|
+
fill?: boolean | null;
|
|
9
10
|
gutters?: "s" | "m" | "l" | null;
|
|
10
11
|
measure?: "narrow" | "wide" | null;
|
|
11
12
|
attributes?: Readonly<Record<string, string | number | boolean | null | undefined>>;
|
package/vanilla/UiContainer.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// Generated by HTML Next 1.0.0-alpha.35 for Vanilla DOM. Do not edit.
|
|
2
|
-
import { attachGeneratedController, buildTemplate, writeAttribute, dispose, formatOf, keywordFormat, hostState, acceptProps, manageProps, project, fillSlot, checkFormat } from "@nextwebwg/html-next/generated-runtime";
|
|
2
|
+
import { attachGeneratedController, buildTemplate, writeAttribute, dispose, formatOf, keywordFormat, hostState, acceptProps, manageProps, project, fillSlot, checkBoolean, checkFormat } from "@nextwebwg/html-next/generated-runtime";
|
|
3
3
|
import "../styles/ui-container.css";
|
|
4
4
|
|
|
5
5
|
const T0 = ["",[],4];
|
|
6
6
|
const T1 = ["",[]];
|
|
7
7
|
let P0, P1;
|
|
8
8
|
const S = { n: [], t: [], f: import.meta.url, g: "ui-container" };
|
|
9
|
-
const D = { props: { "gutters": { "required":false,"values":["s","m","l"], c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "measure": { "required":false,"values":["narrow","wide"], c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] } } };
|
|
9
|
+
const D = { props: { "fill": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "gutters": { "required":false,"values":["s","m","l"], c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "measure": { "required":false,"values":["narrow","wide"], c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] } } };
|
|
10
10
|
|
|
11
11
|
export function createUiContainer(options = {}, html) {
|
|
12
12
|
const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
|
|
@@ -17,7 +17,7 @@ export function createUiContainer(options = {}, html) {
|
|
|
17
17
|
}
|
|
18
18
|
element.setAttribute("data-component", "ui-container");
|
|
19
19
|
element.append((P0 ??= buildTemplate(T0)).cloneNode(true));
|
|
20
|
-
const v = [null, null];
|
|
20
|
+
const v = [null, null, null];
|
|
21
21
|
const B = acceptProps(element, D, S.n, v, componentProps, [], html);
|
|
22
22
|
const m1 = (d) => {
|
|
23
23
|
const n = (P1 ??= buildTemplate(T1)).cloneNode(true);
|
|
@@ -28,8 +28,8 @@ export function createUiContainer(options = {}, html) {
|
|
|
28
28
|
const p1 = (r, c, d) => {
|
|
29
29
|
};
|
|
30
30
|
const p0 = (r, c, d) => {
|
|
31
|
-
if (c &
|
|
32
|
-
const x0 = hostState(["measure","gutters"], [v[
|
|
31
|
+
if (c & 7) {
|
|
32
|
+
const x0 = hostState(["measure","fill","gutters"], [v[2], v[0], v[1]]);
|
|
33
33
|
const s0 = x0;
|
|
34
34
|
if (s0 !== r.v0) writeAttribute(r.n, "data-ui-container-state", (r.v0 = s0) === "" ? null : s0);
|
|
35
35
|
}
|
package/vanilla/UiDialog.js
CHANGED
|
@@ -3,7 +3,7 @@ import { attachGeneratedController, buildTemplate, clearRegion, toAttribute, toT
|
|
|
3
3
|
import * as controller from "../components/ui-dialog/ui-dialog.js";
|
|
4
4
|
import "../styles/ui-dialog.css";
|
|
5
5
|
|
|
6
|
-
const T0 = ["",[],["header",[],1,["button",["class","close","type","button","aria-label","Close"]]],["
|
|
6
|
+
const T0 = ["",[],["header",[],1,["button",["class","close","type","button","aria-label","Close"]]],["div",["class","body"],["ui-scroll-area",[],4]],["footer",[],4]];
|
|
7
7
|
const T1 = ["h2",["class","title"],0];
|
|
8
8
|
const T2 = ["",[]];
|
|
9
9
|
const T3 = ["",[]];
|
|
@@ -59,10 +59,15 @@ export function createUiDialog(options = {}, html) {
|
|
|
59
59
|
const s0 = toAttribute(x0, "aria-label");
|
|
60
60
|
if (s0 !== r.v0) writeAttribute(r.n, "aria-label", r.v0 = s0);
|
|
61
61
|
}
|
|
62
|
+
if (c === -1) {
|
|
63
|
+
const x1 = true;
|
|
64
|
+
const s1 = toAttribute(x1, "trim");
|
|
65
|
+
if (s1 !== r.v1) writeAttribute(r.a3, "trim", r.v1 = s1);
|
|
66
|
+
}
|
|
62
67
|
if (c & 516) {
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
if (
|
|
68
|
+
const x2 = hostState(["size","alert"], [v[9], v[2]]);
|
|
69
|
+
const s2 = x2;
|
|
70
|
+
if (s2 !== r.v2) writeAttribute(r.n, "data-ui-dialog-state", (r.v2 = s2) === "" ? null : s2);
|
|
66
71
|
}
|
|
67
72
|
if (c & 32) {
|
|
68
73
|
const t0 = truthy(v[5]);
|
|
@@ -74,10 +79,10 @@ export function createUiDialog(options = {}, html) {
|
|
|
74
79
|
}
|
|
75
80
|
} else if (r.b0 !== undefined) p1(r.b0, c, d);
|
|
76
81
|
} else if (r.b0 !== undefined) p1(r.b0, c, d);
|
|
77
|
-
if (r.f1 === undefined) { r.f1 = 1; const at = fillSlot(r.
|
|
82
|
+
if (r.f1 === undefined) { r.f1 = 1; const at = fillSlot(r.a4, r.e1, "", J, false, undefined, d);
|
|
78
83
|
if (Array.isArray(at)) (r.z ??= []).push(() => { at[0].l.delete(at[1]); dispose(at[1]); }); else if (at !== undefined) { r.b1 = m2(d); at.before(r.b1.n); } }
|
|
79
84
|
else if (r.b1 !== undefined) p2(r.b1, c, d);
|
|
80
|
-
if (r.f2 === undefined) { r.f2 = 1; const at = fillSlot(r.
|
|
85
|
+
if (r.f2 === undefined) { r.f2 = 1; const at = fillSlot(r.a5, r.e2, "actions", J, false, undefined, d);
|
|
81
86
|
if (Array.isArray(at)) (r.z ??= []).push(() => { at[0].l.delete(at[1]); dispose(at[1]); }); else if (at !== undefined) { r.b2 = m3(d); at.before(r.b2.n); } }
|
|
82
87
|
else if (r.b2 !== undefined) p3(r.b2, c, d);
|
|
83
88
|
};
|
|
@@ -86,8 +91,9 @@ export function createUiDialog(options = {}, html) {
|
|
|
86
91
|
const t2 = t1.nextSibling.nextSibling;
|
|
87
92
|
const t3 = t0.nextSibling;
|
|
88
93
|
const t4 = t3.firstChild;
|
|
89
|
-
const t5 =
|
|
90
|
-
const
|
|
94
|
+
const t5 = t4.firstChild;
|
|
95
|
+
const t6 = t3.nextSibling.firstChild;
|
|
96
|
+
const R = { n: element, a3: t4, v0: undefined, v1: null, v2: undefined, a1: t1, e0: t1.nextSibling, b0: undefined, a4: t5, e1: t5.nextSibling, b1: undefined, f1: undefined, a5: t6, e2: t6.nextSibling, b2: undefined, f2: undefined };
|
|
91
97
|
const I = { B };
|
|
92
98
|
const J = project(I, children, slots);
|
|
93
99
|
I.R = new Set();
|
|
@@ -14,6 +14,7 @@ export interface UiIconButtonProps {
|
|
|
14
14
|
pending?: boolean | null;
|
|
15
15
|
round?: boolean | null;
|
|
16
16
|
size?: "sm" | "md" | "lg" | null;
|
|
17
|
+
tone?: "accent" | "neutral" | null;
|
|
17
18
|
variant?: "ghost" | "outline" | "solid" | null;
|
|
18
19
|
attributes?: Readonly<Record<string, string | number | boolean | null | undefined>>;
|
|
19
20
|
children?: readonly (string | Node)[];
|
package/vanilla/UiIconButton.js
CHANGED
|
@@ -8,7 +8,7 @@ const T1 = ["ui-spinner",["size","sm"]];
|
|
|
8
8
|
const T2 = ["",[]];
|
|
9
9
|
let P0, P1, P2;
|
|
10
10
|
const S = { n: [], t: [], f: import.meta.url, g: "ui-icon-button" };
|
|
11
|
-
const D = { props: { "anticipatory": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "disabled": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "label": { "required":false, c: checkString, t: "string", j: 0, m: "s" }, "loading": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "matchButton": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "pending": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "round": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "size": { "required":false,"values":["sm","md","lg"],"default":"md", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "variant": { "required":false,"values":["ghost","outline","solid"],"default":"ghost", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] } } };
|
|
11
|
+
const D = { props: { "anticipatory": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "disabled": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "label": { "required":false, c: checkString, t: "string", j: 0, m: "s" }, "loading": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "matchButton": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "pending": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "round": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "size": { "required":false,"values":["sm","md","lg"],"default":"md", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "tone": { "required":false,"values":["accent","neutral"], c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "variant": { "required":false,"values":["ghost","outline","solid"],"default":"ghost", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] } } };
|
|
12
12
|
const C = (host) => controller.default(host);
|
|
13
13
|
|
|
14
14
|
export function createUiIconButton(options = {}, html) {
|
|
@@ -21,7 +21,7 @@ export function createUiIconButton(options = {}, html) {
|
|
|
21
21
|
if (!element.hasAttribute("type")) element.setAttribute("type", "button");
|
|
22
22
|
element.setAttribute("data-component", "ui-icon-button");
|
|
23
23
|
element.append((P0 ??= buildTemplate(T0)).cloneNode(true));
|
|
24
|
-
const v = [null, null, null, null, null, null, null, null, null];
|
|
24
|
+
const v = [null, null, null, null, null, null, null, null, null, null];
|
|
25
25
|
const B = acceptProps(element, D, S.n, v, componentProps, ["matchButton"], html);
|
|
26
26
|
const m1 = (d) => {
|
|
27
27
|
const n = (P1 ??= buildTemplate(T1)).cloneNode(true);
|
|
@@ -67,8 +67,8 @@ export function createUiIconButton(options = {}, html) {
|
|
|
67
67
|
const s4 = toAttribute(x4, "aria-busy");
|
|
68
68
|
if (s4 !== r.v4) writeAttribute(r.n, "aria-busy", r.v4 = s4);
|
|
69
69
|
}
|
|
70
|
-
if (c &
|
|
71
|
-
const x5 = hostState(["anticipatory","variant","loading","pending","size","matchButton","round"], [v[0], v[
|
|
70
|
+
if (c & 1017) {
|
|
71
|
+
const x5 = hostState(["tone","anticipatory","variant","loading","pending","size","matchButton","round"], [v[8], v[0], v[9], v[3], v[5], v[7], v[4], v[6]]);
|
|
72
72
|
const s5 = x5;
|
|
73
73
|
if (s5 !== r.v5) writeAttribute(r.n, "data-ui-icon-button-state", (r.v5 = s5) === "" ? null : s5);
|
|
74
74
|
}
|
|
@@ -9,6 +9,7 @@ export interface UiScrollAreaProps {
|
|
|
9
9
|
fill?: boolean | null;
|
|
10
10
|
orientation?: "vertical" | "horizontal" | null;
|
|
11
11
|
size?: "content" | "sm" | "md" | "lg" | null;
|
|
12
|
+
trim?: boolean | null;
|
|
12
13
|
attributes?: Readonly<Record<string, string | number | boolean | null | undefined>>;
|
|
13
14
|
children?: readonly (string | Node)[];
|
|
14
15
|
slots?: Readonly<Record<string, readonly (string | Node)[]>>;
|
package/vanilla/UiScrollArea.js
CHANGED
|
@@ -7,7 +7,7 @@ const T0 = ["",[],["div",["class","content"],4]];
|
|
|
7
7
|
const T1 = ["",[]];
|
|
8
8
|
let P0, P1;
|
|
9
9
|
const S = { n: [], t: [], f: import.meta.url, g: "ui-scroll-area" };
|
|
10
|
-
const D = { props: { "fill": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "orientation": { "required":false,"values":["vertical","horizontal"],"default":"vertical", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "size": { "required":false,"values":["content","sm","md","lg"],"default":"content", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] } } };
|
|
10
|
+
const D = { props: { "fill": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "orientation": { "required":false,"values":["vertical","horizontal"],"default":"vertical", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "size": { "required":false,"values":["content","sm","md","lg"],"default":"content", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "trim": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" } } };
|
|
11
11
|
const C = (host) => controller.default(host);
|
|
12
12
|
|
|
13
13
|
export function createUiScrollArea(options = {}, html) {
|
|
@@ -19,7 +19,7 @@ export function createUiScrollArea(options = {}, html) {
|
|
|
19
19
|
}
|
|
20
20
|
element.setAttribute("data-component", "ui-scroll-area");
|
|
21
21
|
element.append((P0 ??= buildTemplate(T0)).cloneNode(true));
|
|
22
|
-
const v = [null, null, null];
|
|
22
|
+
const v = [null, null, null, null];
|
|
23
23
|
const B = acceptProps(element, D, S.n, v, componentProps, [], html);
|
|
24
24
|
const m1 = (d) => {
|
|
25
25
|
const n = (P1 ??= buildTemplate(T1)).cloneNode(true);
|
|
@@ -30,8 +30,8 @@ export function createUiScrollArea(options = {}, html) {
|
|
|
30
30
|
const p1 = (r, c, d) => {
|
|
31
31
|
};
|
|
32
32
|
const p0 = (r, c, d) => {
|
|
33
|
-
if (c &
|
|
34
|
-
const x0 = hostState(["fill","orientation","size"], [v[0], v[1], v[2]]);
|
|
33
|
+
if (c & 15) {
|
|
34
|
+
const x0 = hostState(["fill","orientation","size","trim"], [v[0], v[1], v[2], v[3]]);
|
|
35
35
|
const s0 = x0;
|
|
36
36
|
if (s0 !== r.v0) writeAttribute(r.n, "data-ui-scroll-area-state", (r.v0 = s0) === "" ? null : s0);
|
|
37
37
|
}
|
package/vue/UiBadge.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ type __VLS_Slots = {} & {
|
|
|
7
7
|
};
|
|
8
8
|
declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
9
9
|
shape: {
|
|
10
|
-
type: PropType<"pill" | "tag" | "dot" | "square" | null>;
|
|
10
|
+
type: PropType<"pill" | "tag" | "dot" | "square" | "circle" | null>;
|
|
11
11
|
default: string;
|
|
12
12
|
};
|
|
13
13
|
size: {
|
|
@@ -24,7 +24,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
24
24
|
};
|
|
25
25
|
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
26
26
|
shape: {
|
|
27
|
-
type: PropType<"pill" | "tag" | "dot" | "square" | null>;
|
|
27
|
+
type: PropType<"pill" | "tag" | "dot" | "square" | "circle" | null>;
|
|
28
28
|
default: string;
|
|
29
29
|
};
|
|
30
30
|
size: {
|
|
@@ -40,7 +40,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
40
40
|
default: string;
|
|
41
41
|
};
|
|
42
42
|
}>> & Readonly<{}>, {
|
|
43
|
-
shape: "dot" | "tag" | "square" | "pill" | null;
|
|
43
|
+
shape: "circle" | "dot" | "tag" | "square" | "pill" | null;
|
|
44
44
|
size: "xs" | "md" | null;
|
|
45
45
|
tone: "info" | "neutral" | "accent" | "success" | "warning" | "danger" | null;
|
|
46
46
|
variant: "solid" | "subtle" | "outline" | null;
|
package/vue/UiBadge.vue
CHANGED
|
@@ -13,8 +13,8 @@ const propValidityContract = {
|
|
|
13
13
|
required: false,
|
|
14
14
|
target: { attribute: 'shape' },
|
|
15
15
|
description:
|
|
16
|
-
'Silhouette. pill is rounded at both ends; tag is a pointed label. dot is a compact circular signal with visually hidden text: include a state label, or set\n aria-hidden when the surrounding control already names that state. square is a fixed rounded square for an icon or single glyph beside a heading; hide a\n decorative icon when adjacent words name it.',
|
|
17
|
-
values: ['pill', 'tag', 'dot', 'square'],
|
|
16
|
+
'Silhouette. pill is rounded at both ends; tag is a pointed label. dot is a compact circular signal with visually hidden text: include a state label, or set\n aria-hidden when the surrounding control already names that state. square is a fixed rounded square for an icon or single glyph beside a heading; hide a\n decorative icon when adjacent words name it. circle frames a visible single glyph or icon in a fixed circle, centered in both directions.',
|
|
17
|
+
values: ['pill', 'tag', 'dot', 'square', 'circle'],
|
|
18
18
|
default: 'pill',
|
|
19
19
|
},
|
|
20
20
|
size: {
|
|
@@ -22,7 +22,7 @@ const propValidityContract = {
|
|
|
22
22
|
required: false,
|
|
23
23
|
target: { attribute: 'size' },
|
|
24
24
|
description:
|
|
25
|
-
'Scale. xs is a compact count beside small controls; md is the usual text badge. A square is 24px at xs and 32px at md with default spacing.',
|
|
25
|
+
'Scale. xs is a compact count beside small controls; md is the usual text badge. A square is 24px at xs and 32px at md with default spacing. A circle is\n 16px at xs and 24px at md.',
|
|
26
26
|
values: ['xs', 'md'],
|
|
27
27
|
default: 'md',
|
|
28
28
|
},
|
|
@@ -48,7 +48,7 @@ const propValidityContract = {
|
|
|
48
48
|
} as const
|
|
49
49
|
const props = defineProps({
|
|
50
50
|
shape: {
|
|
51
|
-
type: null as unknown as PropType<'pill' | 'tag' | 'dot' | 'square' | null>,
|
|
51
|
+
type: null as unknown as PropType<'pill' | 'tag' | 'dot' | 'square' | 'circle' | null>,
|
|
52
52
|
default: 'pill',
|
|
53
53
|
},
|
|
54
54
|
size: { type: null as unknown as PropType<'xs' | 'md' | null>, default: 'md' },
|
|
@@ -70,13 +70,13 @@ const acceptedProps: Record<string, unknown> = {
|
|
|
70
70
|
variant: 'subtle',
|
|
71
71
|
}
|
|
72
72
|
const checkedProps = computed(() => ({
|
|
73
|
-
shape: checkedProp<'pill' | 'tag' | 'dot' | 'square'>(
|
|
73
|
+
shape: checkedProp<'pill' | 'tag' | 'dot' | 'square' | 'circle'>(
|
|
74
74
|
props['shape'],
|
|
75
75
|
{ kind: 'terminal', name: 'keyword' },
|
|
76
76
|
false,
|
|
77
77
|
'shape',
|
|
78
78
|
acceptedProps,
|
|
79
|
-
) as 'pill' | 'tag' | 'dot' | 'square',
|
|
79
|
+
) as 'pill' | 'tag' | 'dot' | 'square' | 'circle',
|
|
80
80
|
size: checkedProp<'xs' | 'md'>(
|
|
81
81
|
props['size'],
|
|
82
82
|
{ kind: 'terminal', name: 'keyword' },
|
|
@@ -191,6 +191,10 @@ const hostState = computed(() =>
|
|
|
191
191
|
syntax: "*";
|
|
192
192
|
inherits: false;
|
|
193
193
|
}
|
|
194
|
+
@property --ui-badge-circle-size {
|
|
195
|
+
syntax: "*";
|
|
196
|
+
inherits: false;
|
|
197
|
+
}
|
|
194
198
|
@property --ui-badge-dot-size {
|
|
195
199
|
syntax: "*";
|
|
196
200
|
inherits: false;
|
|
@@ -490,6 +494,40 @@ const hostState = computed(() =>
|
|
|
490
494
|
display: none;
|
|
491
495
|
}
|
|
492
496
|
|
|
497
|
+
/* A visible glyph needs fixed geometry, unlike a content-sized pill or a hidden-label dot. */
|
|
498
|
+
[data-component~="ui-badge"][data-ui-badge-state~="shape=circle"] {
|
|
499
|
+
--_badge-circle-size: var(--ui-badge-circle-size, calc(var(--ui-space-3) * 2));
|
|
500
|
+
display: inline-flex;
|
|
501
|
+
flex: none;
|
|
502
|
+
inline-size: var(--_badge-circle-size);
|
|
503
|
+
block-size: var(--_badge-circle-size);
|
|
504
|
+
min-inline-size: var(--_badge-circle-size);
|
|
505
|
+
min-block-size: var(--_badge-circle-size);
|
|
506
|
+
padding: 0;
|
|
507
|
+
border-radius: var(--ui-radius-round);
|
|
508
|
+
text-box-trim: none;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
[data-component~="ui-badge"][data-ui-badge-state~="shape=circle"][data-ui-badge-state~="size=xs"] {
|
|
512
|
+
--_badge-circle-size: var(--ui-badge-circle-size, var(--ui-space-4));
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
[data-component~="ui-badge"][data-ui-badge-state~="shape=circle"] .label {
|
|
516
|
+
display: inline-flex;
|
|
517
|
+
align-items: center;
|
|
518
|
+
justify-content: center;
|
|
519
|
+
line-height: 1;
|
|
520
|
+
text-box-trim: none;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
[data-component~="ui-badge"][data-ui-badge-state~="shape=circle"] .label :slotted(svg) {
|
|
524
|
+
margin-inline-end: 0;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
[data-component~="ui-badge"][data-ui-badge-state~="shape=circle"] .label:empty {
|
|
528
|
+
display: none;
|
|
529
|
+
}
|
|
530
|
+
|
|
493
531
|
/* A dot uses the badge's tone recipe; only its silhouette and visible label change. */
|
|
494
532
|
[data-component~="ui-badge"][data-ui-badge-state~="shape=dot"] {
|
|
495
533
|
position: relative;
|