@threadlabs/looma 0.26.2 → 0.26.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/ui-avatar/ui-avatar.html +6 -1
- package/components/ui-badge/ui-badge.html +62 -12
- package/components/ui-callout/ui-callout.html +2 -1
- package/components/ui-list-item/ui-list-item.html +13 -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-avatar.css +4 -0
- package/styles/ui-badge.css +67 -8
- package/styles/ui-callout.css +2 -1
- package/styles/ui-list-item.css +12 -0
- package/styles/ui-toast-region.css +18 -7
- package/styles/ui-toast.css +13 -7
- package/vanilla/UiBadge.d.ts +2 -2
- package/vanilla/UiBadge.js +1 -1
- package/vanilla/UiListItem.d.ts +1 -0
- package/vanilla/UiListItem.js +6 -6
- package/vue/UiAvatar.vue +6 -1
- package/vue/UiBadge.d.ts +6 -6
- package/vue/UiBadge.vue +81 -17
- package/vue/UiCallout.vue +4 -2
- package/vue/UiCard.d.ts +1 -1
- package/vue/UiListItem.d.ts +9 -0
- package/vue/UiListItem.vue +31 -0
- package/vue/UiPopover.d.ts +1 -1
- package/vue/UiScrollArea.d.ts +1 -1
- package/vue/UiToast.vue +16 -8
- package/vue/UiToastRegion.vue +18 -7
- package/vue/UiTooltip.d.ts +1 -1
- package/vue/chunks/UiAvatar.js +2 -2
- package/vue/chunks/UiBadge.js +11 -6
- package/vue/chunks/UiCallout.js +1 -1
- package/vue/chunks/UiListItem.js +26 -2
- package/vue/chunks/UiToast.js +1 -1
- package/vue/chunks/UiToastRegion.js +1 -1
- package/vue/components.css +255 -161
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
<prop name="size" type="keyword" values="xs, sm, md" default="md"
|
|
17
17
|
>md is 2.5rem, for a person on their own (a profile, a comment); sm is 1.75rem with smaller initials, for a row of people in a toolbar or header; xs is
|
|
18
18
|
1.25rem with small initials, for a person named inline in a line of small text.</prop>
|
|
19
|
-
<prop name="shape" type="keyword" values="circle, square" default="circle"
|
|
19
|
+
<prop name="shape" type="keyword" values="circle, square" default="circle"
|
|
20
|
+
>Circle by default, with a shallow shadow; square uses the theme's medium radius.</prop>
|
|
20
21
|
<prop name="decorative" type="boolean" default="false">Hides the avatar from assistive technology when adjacent text already identifies the person.</prop>
|
|
21
22
|
<prop name="active" type="boolean" default="false"
|
|
22
23
|
>Marks the person as active now, such as editing the same page: a fine accent ring around the avatar. The ring is not announced, so say what it means in alt
|
|
@@ -96,6 +97,10 @@
|
|
|
96
97
|
border-color: var(--ui-avatar-border, var(--ui-border-strong));
|
|
97
98
|
}
|
|
98
99
|
|
|
100
|
+
:host([shape="circle"]) {
|
|
101
|
+
box-shadow: var(--ui-shadow-sm);
|
|
102
|
+
}
|
|
103
|
+
|
|
99
104
|
:host([shape="square"]) {
|
|
100
105
|
border-radius: var(--ui-avatar-radius, var(--ui-radius-md));
|
|
101
106
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<template component="ui-badge">
|
|
2
2
|
<defs>
|
|
3
|
-
<prop name="variant" type="keyword" values="solid, subtle, outline" default="subtle"
|
|
3
|
+
<prop name="variant" type="keyword" values="solid, subtle, outline, inverse" default="subtle"
|
|
4
4
|
>Emphasis. subtle sets toned text over a soft wash; solid fills with the tone and uses contrasting text; outline keeps the surface with a toned edge.
|
|
5
|
-
|
|
5
|
+
inverse uses a translucent contrasting surface and toned ink for a count or label on a filled control of that tone. Neutral looks the same in solid and
|
|
6
|
+
subtle. When space is constrained, the label truncates with an ellipsis while its full text remains available.</prop>
|
|
6
7
|
<prop name="tone" type="keyword" values="neutral, accent, info, success, warning, danger" default="neutral"
|
|
7
8
|
>Which colour the badge speaks in. neutral is a quiet grey for plain labels; accent draws the eye in the accent colour; info, success, warning, and danger
|
|
8
9
|
mark a status, so match the tone to what the badge says. For a category rather than a status, set the --ui-badge-color hook on the badge instead: any CSS
|
|
@@ -10,10 +11,11 @@
|
|
|
10
11
|
<prop name="shape" type="keyword" values="pill, tag, dot, square, circle" default="pill"
|
|
11
12
|
>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
|
|
12
13
|
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
|
|
13
|
-
decorative icon when adjacent words name it. circle frames a visible
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
decorative icon when adjacent words name it. circle frames a visible glyph, icon or short bounded count in a fixed circle, centered in both
|
|
15
|
+
directions.</prop>
|
|
16
|
+
<prop name="size" type="keyword" values="xs, md, lg" default="md"
|
|
17
|
+
>Scale. xs is compact; md is the usual text badge; lg adds room to fixed marks while retaining the usual text size. A square is 24px at xs, 32px at md and
|
|
18
|
+
40px at lg. A circle is 16px at xs, 24px at md and 32px at lg; use lg for short counts such as 30 or 99+.</prop>
|
|
17
19
|
</defs>
|
|
18
20
|
<span>
|
|
19
21
|
<span class="icon" aria-hidden="true"><slot name="icon"></slot></span>
|
|
@@ -157,25 +159,26 @@
|
|
|
157
159
|
text-box-trim: none;
|
|
158
160
|
}
|
|
159
161
|
|
|
160
|
-
/*
|
|
161
|
-
|
|
162
|
+
/* Center the capital/baseline text box, while clipping only inline overflow for ellipsis.
|
|
163
|
+
Vertical ink remains visible so trimming never cuts off ascenders or descenders. */
|
|
162
164
|
@supports (text-box-trim: trim-both) {
|
|
163
165
|
:host {
|
|
164
166
|
display: inline-block;
|
|
165
167
|
min-block-size: var(--ui-badge-min-block-size, 1.5rem);
|
|
166
168
|
text-align: center;
|
|
167
169
|
align-content: center;
|
|
168
|
-
text-box-trim:
|
|
169
|
-
text-box-edge: text;
|
|
170
|
+
text-box-trim: none;
|
|
170
171
|
}
|
|
171
172
|
:host:has(.icon:not(:empty)),
|
|
172
173
|
:host:has(.label svg) {
|
|
173
174
|
display: inline-flex;
|
|
174
175
|
text-box-trim: none;
|
|
175
176
|
}
|
|
176
|
-
|
|
177
|
+
.label:not(:has(svg)) {
|
|
177
178
|
text-box-trim: trim-both;
|
|
178
|
-
text-box-edge:
|
|
179
|
+
text-box-edge: cap alphabetic;
|
|
180
|
+
overflow-x: clip;
|
|
181
|
+
overflow-y: visible;
|
|
179
182
|
}
|
|
180
183
|
}
|
|
181
184
|
|
|
@@ -256,6 +259,29 @@
|
|
|
256
259
|
--_badge-color-text: color-mix(in oklab, var(--_ui-badge-color) 0%, var(--ui-surface-default));
|
|
257
260
|
}
|
|
258
261
|
|
|
262
|
+
/* A translucent inverse surface picks up its filled control's tone. Deepen the tone ink
|
|
263
|
+
toward the theme text to retain contrast against that composed surface. */
|
|
264
|
+
:host([variant="inverse"]) {
|
|
265
|
+
--_badge-color-surface: color-mix(in srgb, color-mix(in oklab, var(--_ui-badge-color) 0%, var(--ui-surface-default)) 88%, transparent);
|
|
266
|
+
--_badge-color-border: var(--_badge-color-surface);
|
|
267
|
+
--_badge-color-text: color-mix(in srgb, var(--_badge-color-ink) 85%, var(--ui-text-primary));
|
|
268
|
+
--_badge-outline-surface: var(--ui-badge-surface, var(--_badge-color-surface, color-mix(in srgb, var(--_badge-text) 88%, transparent)));
|
|
269
|
+
border-color: var(--ui-badge-border, var(--_badge-color-border, color-mix(in srgb, var(--_badge-text) 88%, transparent)));
|
|
270
|
+
color: var(--ui-badge-text, var(--_badge-color-text, color-mix(in srgb, var(--_badge-surface) 85%, var(--ui-text-primary))));
|
|
271
|
+
/* Paint each translucent layer once, including the border, without a bright double-painted ring. */
|
|
272
|
+
background-clip: padding-box;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
:host([variant="inverse"][shape="circle"]) {
|
|
276
|
+
box-shadow: var(--ui-shadow-sm);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/* Neutral reverses a subtle surface/ink pair rather than a strong tone. Keep its original
|
|
280
|
+
surface ink: moving it toward dark-theme primary text would reduce overlay contrast. */
|
|
281
|
+
:host([variant="inverse"][tone="neutral"]) {
|
|
282
|
+
color: var(--ui-badge-text, var(--_badge-color-text, var(--_badge-surface)));
|
|
283
|
+
}
|
|
284
|
+
|
|
259
285
|
:host([variant="outline"]) {
|
|
260
286
|
--_badge-surface: var(--ui-surface-default);
|
|
261
287
|
--_badge-border: var(--ui-border-strong);
|
|
@@ -309,6 +335,10 @@
|
|
|
309
335
|
--_badge-square-size: var(--ui-badge-square-size, calc(var(--ui-space-3) * 2));
|
|
310
336
|
}
|
|
311
337
|
|
|
338
|
+
:host([shape="square"][size="lg"]) {
|
|
339
|
+
--_badge-square-size: var(--ui-badge-square-size, calc(var(--ui-space-4) * 2 + var(--ui-space-2)));
|
|
340
|
+
}
|
|
341
|
+
|
|
312
342
|
:host([shape="square"]) .label {
|
|
313
343
|
display: inline-flex;
|
|
314
344
|
align-items: center;
|
|
@@ -341,6 +371,10 @@
|
|
|
341
371
|
--_badge-circle-size: var(--ui-badge-circle-size, var(--ui-space-4));
|
|
342
372
|
}
|
|
343
373
|
|
|
374
|
+
:host([shape="circle"][size="lg"]) {
|
|
375
|
+
--_badge-circle-size: var(--ui-badge-circle-size, calc(var(--ui-space-4) * 2));
|
|
376
|
+
}
|
|
377
|
+
|
|
344
378
|
:host([shape="circle"]) .label {
|
|
345
379
|
display: inline-flex;
|
|
346
380
|
align-items: center;
|
|
@@ -357,6 +391,18 @@
|
|
|
357
391
|
display: none;
|
|
358
392
|
}
|
|
359
393
|
|
|
394
|
+
/* Center capital and numeral ink, rather than the font's ascent/descent line box.
|
|
395
|
+
Icon labels retain flex geometry; untrimmed browsers keep that fallback too. */
|
|
396
|
+
@supports (text-box-trim: trim-both) {
|
|
397
|
+
:host([shape="circle"]) .label:not(:has(svg)),
|
|
398
|
+
:host([shape="square"]) .label:not(:has(svg)) {
|
|
399
|
+
display: block;
|
|
400
|
+
text-box-trim: trim-both;
|
|
401
|
+
text-box-edge: cap alphabetic;
|
|
402
|
+
overflow: visible;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
360
406
|
/* A dot uses the badge's tone recipe; only its silhouette and visible label change. */
|
|
361
407
|
:host([shape="dot"]) {
|
|
362
408
|
position: relative;
|
|
@@ -404,6 +450,10 @@
|
|
|
404
450
|
pointer-events: none;
|
|
405
451
|
}
|
|
406
452
|
|
|
453
|
+
:host([shape="tag"][variant="inverse"]) {
|
|
454
|
+
background: var(--ui-badge-border, var(--_badge-color-border, var(--_badge-text)));
|
|
455
|
+
}
|
|
456
|
+
|
|
407
457
|
:host([shape="tag"]):dir(rtl) {
|
|
408
458
|
padding-inline-end: var(--ui-badge-padding-inline, var(--ui-space-2));
|
|
409
459
|
padding-inline-start: calc(var(--ui-badge-padding-inline, var(--ui-space-2)) + var(--_badge-point));
|
|
@@ -108,7 +108,8 @@
|
|
|
108
108
|
padding-inline-end: var(--ui-callout-padding-inline, var(--ui-space-3));
|
|
109
109
|
border: var(--ui-callout-border-width, var(--ui-border-width)) solid
|
|
110
110
|
color-mix(in srgb, var(--ui-callout-border, var(--_callout-border)) 35%, transparent);
|
|
111
|
-
border-inline-start: var(--ui-callout-leading-border-width, var(--ui-
|
|
111
|
+
border-inline-start: var(--ui-callout-leading-border-width, var(--ui-callout-border-width, var(--ui-border-width))) solid
|
|
112
|
+
color-mix(in srgb, var(--ui-callout-border, var(--_callout-border)) 35%, transparent);
|
|
112
113
|
border-radius: var(--ui-radius-md);
|
|
113
114
|
background: var(--ui-callout-surface, var(--_callout-surface));
|
|
114
115
|
color: var(--ui-callout-text, var(--ui-text-primary));
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
combining them with a leading control.</prop>
|
|
9
9
|
<prop name="wrap" type="boolean" default="false"
|
|
10
10
|
>Lets the title and description wrap so explanatory text stays readable on narrow screens. Omit it for the default equal-height, one-line rows.</prop>
|
|
11
|
+
<prop name="align" type="keyword" values="center, title" default="center"
|
|
12
|
+
>Where the leading and trailing regions sit vertically. center aligns them with the whole row. title aligns them with the first title line, keeping an
|
|
13
|
+
identifying icon beside its name when the title or description wraps. Taller controls retain their natural height.</prop>
|
|
11
14
|
<prop name="current" type="boolean" default="false"
|
|
12
15
|
>Marks the item as the current one, such as the site you are in: it takes the selected surface and aria-current="true", which assistive technology
|
|
13
16
|
announces. Set it on one item at a time.</prop>
|
|
@@ -158,6 +161,16 @@
|
|
|
158
161
|
line-height: var(--ui-line-height-tight);
|
|
159
162
|
}
|
|
160
163
|
|
|
164
|
+
/* Keep identity and disclosure marks beside the first line, even with a long description. */
|
|
165
|
+
:host([align="title"]) {
|
|
166
|
+
align-items: flex-start;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
:host([align="title"]) .leading,
|
|
170
|
+
:host([align="title"]) .trailing {
|
|
171
|
+
min-block-size: calc(var(--ui-font-size-md) * var(--ui-line-height-tight));
|
|
172
|
+
}
|
|
173
|
+
|
|
161
174
|
.description {
|
|
162
175
|
color: var(--ui-text-muted);
|
|
163
176
|
font-size: var(--ui-font-size-sm);
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
|
|
45
45
|
:host {
|
|
46
46
|
--_ui-toast-accent: var(--ui-border-strong);
|
|
47
|
+
--_ui-toast-surface: var(--ui-surface-muted);
|
|
47
48
|
|
|
48
49
|
display: flex;
|
|
49
50
|
align-items: center;
|
|
@@ -52,26 +53,35 @@
|
|
|
52
53
|
inline-size: 100%;
|
|
53
54
|
margin: 0;
|
|
54
55
|
padding: var(--ui-space-3) var(--ui-space-4);
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
/* The close button's internal space supplies the rest of the trailing inset. */
|
|
57
|
+
padding-inline-end: var(--ui-space-2);
|
|
58
|
+
border: var(--ui-border-width) solid var(--ui-toast-border, var(--ui-overlay-border, var(--ui-toast-accent, var(--_ui-toast-accent))));
|
|
57
59
|
border-radius: var(--ui-toast-radius, var(--ui-overlay-radius, var(--ui-radius-lg)));
|
|
58
|
-
background: var(--ui-toast-surface, var(--ui-overlay-surface, var(--
|
|
60
|
+
background: var(--ui-toast-surface, var(--ui-overlay-surface, var(--_ui-toast-surface)));
|
|
59
61
|
color: var(--ui-text-primary);
|
|
62
|
+
font-family: var(--ui-font-family-sans);
|
|
63
|
+
font-size: var(--ui-font-size-sm);
|
|
64
|
+
font-weight: var(--ui-font-normal);
|
|
65
|
+
line-height: var(--ui-line-height-md);
|
|
60
66
|
box-shadow: var(--ui-toast-shadow, var(--ui-overlay-shadow, var(--ui-elevation-overlay, var(--ui-shadow-lg))));
|
|
61
67
|
pointer-events: auto;
|
|
62
68
|
}
|
|
63
69
|
|
|
64
70
|
:host([tone="info"]) {
|
|
65
71
|
--_ui-toast-accent: var(--ui-info-solid);
|
|
72
|
+
--_ui-toast-surface: var(--ui-info-soft);
|
|
66
73
|
}
|
|
67
74
|
:host([tone="success"]) {
|
|
68
75
|
--_ui-toast-accent: var(--ui-success-solid);
|
|
76
|
+
--_ui-toast-surface: var(--ui-success-soft);
|
|
69
77
|
}
|
|
70
78
|
:host([tone="warning"]) {
|
|
71
79
|
--_ui-toast-accent: var(--ui-warning-solid);
|
|
80
|
+
--_ui-toast-surface: var(--ui-warning-soft);
|
|
72
81
|
}
|
|
73
82
|
:host([tone="danger"]) {
|
|
74
83
|
--_ui-toast-accent: var(--ui-danger-solid);
|
|
84
|
+
--_ui-toast-surface: var(--ui-danger-soft);
|
|
75
85
|
}
|
|
76
86
|
|
|
77
87
|
.message {
|
|
@@ -81,10 +91,6 @@
|
|
|
81
91
|
.action:not(:has(> *)) {
|
|
82
92
|
display: none;
|
|
83
93
|
}
|
|
84
|
-
.dismiss {
|
|
85
|
-
margin-inline-end: calc(var(--ui-space-2) * -1);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
94
|
:host[hidden] {
|
|
89
95
|
display: none;
|
|
90
96
|
}
|
|
@@ -141,30 +141,42 @@
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
.toast {
|
|
144
|
+
--_ui-toast-region-accent: var(--ui-border-strong);
|
|
145
|
+
--_ui-toast-region-tone-surface: var(--ui-surface-muted);
|
|
144
146
|
display: grid;
|
|
145
147
|
grid-template-columns: 1fr auto;
|
|
146
148
|
gap: var(--ui-space-2);
|
|
147
149
|
align-items: start;
|
|
148
|
-
border: var(--ui-border-width) solid var(--_ui-toast-region-border, var(--ui-overlay-border, var(--
|
|
150
|
+
border: var(--ui-border-width) solid var(--_ui-toast-region-border, var(--ui-overlay-border, var(--_ui-toast-region-accent)));
|
|
149
151
|
border-radius: var(--_ui-toast-region-radius, var(--ui-overlay-radius, var(--ui-radius-lg)));
|
|
150
152
|
padding: var(--ui-space-3) var(--ui-space-4);
|
|
151
|
-
|
|
153
|
+
/* The close button's internal space supplies the rest of the trailing inset. */
|
|
154
|
+
padding-inline-end: var(--ui-space-2);
|
|
155
|
+
background: var(--_ui-toast-region-surface, var(--ui-overlay-surface, var(--_ui-toast-region-tone-surface)));
|
|
152
156
|
color: var(--ui-text-primary);
|
|
157
|
+
font-family: var(--ui-font-family-sans);
|
|
158
|
+
font-size: var(--ui-font-size-sm);
|
|
159
|
+
font-weight: var(--ui-font-normal);
|
|
160
|
+
line-height: var(--ui-line-height-md);
|
|
153
161
|
box-shadow: var(--_ui-toast-region-shadow, var(--ui-overlay-shadow, var(--ui-elevation-overlay, var(--ui-shadow-lg))));
|
|
154
162
|
animation: ui-toast-enter var(--_ui-toast-region-enter-duration, 0.32s) var(--ui-motion-ease-out, cubic-bezier(0.16, 1, 0.3, 1)) both;
|
|
155
163
|
}
|
|
156
164
|
|
|
157
165
|
.toast[data-tone="info"] {
|
|
158
|
-
|
|
166
|
+
--_ui-toast-region-accent: var(--ui-info-solid);
|
|
167
|
+
--_ui-toast-region-tone-surface: var(--ui-info-soft);
|
|
159
168
|
}
|
|
160
169
|
.toast[data-tone="success"] {
|
|
161
|
-
|
|
170
|
+
--_ui-toast-region-accent: var(--ui-success-solid);
|
|
171
|
+
--_ui-toast-region-tone-surface: var(--ui-success-soft);
|
|
162
172
|
}
|
|
163
173
|
.toast[data-tone="warning"] {
|
|
164
|
-
|
|
174
|
+
--_ui-toast-region-accent: var(--ui-warning-solid);
|
|
175
|
+
--_ui-toast-region-tone-surface: var(--ui-warning-soft);
|
|
165
176
|
}
|
|
166
177
|
.toast[data-tone="danger"] {
|
|
167
|
-
|
|
178
|
+
--_ui-toast-region-accent: var(--ui-danger-solid);
|
|
179
|
+
--_ui-toast-region-tone-surface: var(--ui-danger-soft);
|
|
168
180
|
}
|
|
169
181
|
|
|
170
182
|
/* Leaving slides on down and fades; the controller removes the toast when this ends. */
|
|
@@ -238,7 +250,6 @@
|
|
|
238
250
|
|
|
239
251
|
.dismiss {
|
|
240
252
|
align-self: center;
|
|
241
|
-
margin-inline-end: calc(var(--ui-space-2) * -1);
|
|
242
253
|
}
|
|
243
254
|
|
|
244
255
|
/* A component that sets its display still honours the hidden attribute on its root. */
|