@threadlabs/looma 0.25.3 → 0.25.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-badge/ui-badge.html +59 -3
- package/components/ui-button/ui-button.html +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/styles/ui-badge.css +61 -4
- package/styles/ui-button.css +1 -1
- package/vanilla/UiBadge.js +16 -3
- package/vue/UiBadge.d.ts +4 -2
- package/vue/UiBadge.vue +57 -3
- package/vue/UiButton.vue +1 -1
- package/vue/UiEditorSlashMenuItem.d.ts +1 -1
- package/vue/chunks/UiBadge.js +7 -3
- package/vue/chunks/UiButton.js +1 -1
- package/vue/components.css +133 -86
package/package.json
CHANGED
package/styles/ui-badge.css
CHANGED
|
@@ -73,6 +73,7 @@
|
|
|
73
73
|
display: inline-flex;
|
|
74
74
|
align-items: center;
|
|
75
75
|
justify-content: center;
|
|
76
|
+
gap: var(--ui-space-1);
|
|
76
77
|
box-sizing: border-box;
|
|
77
78
|
min-inline-size: 0;
|
|
78
79
|
max-inline-size: 100%;
|
|
@@ -97,8 +98,30 @@
|
|
|
97
98
|
text-overflow: ellipsis;
|
|
98
99
|
}
|
|
99
100
|
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
.label:empty {
|
|
102
|
+
display: none;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* Icon content has its own flex item so label ellipsis never clips its strokes. */
|
|
106
|
+
.icon {
|
|
107
|
+
display: inline-flex;
|
|
108
|
+
align-items: center;
|
|
109
|
+
justify-content: center;
|
|
110
|
+
flex: none;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.icon:empty {
|
|
114
|
+
display: none;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/* Ordinary icon-plus-text children keep inline ellipsis, with explicit glyph spacing. */
|
|
118
|
+
|
|
119
|
+
.label:has(svg) {
|
|
120
|
+
text-box-trim: none;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* Text-only badges retain their trimmed inline baseline. Icon content needs a flex row;
|
|
124
|
+
trimming its label separately keeps the glyph centered without changing adjacent lines. */
|
|
102
125
|
@supports (text-box-trim: trim-both) {
|
|
103
126
|
:scope {
|
|
104
127
|
display: inline-block;
|
|
@@ -108,6 +131,15 @@
|
|
|
108
131
|
text-box-trim: trim-both;
|
|
109
132
|
text-box-edge: text;
|
|
110
133
|
}
|
|
134
|
+
:scope:has(.icon:not(:empty)),
|
|
135
|
+
:scope:has(.label svg) {
|
|
136
|
+
display: inline-flex;
|
|
137
|
+
text-box-trim: none;
|
|
138
|
+
}
|
|
139
|
+
:scope:has(.icon:not(:empty)) .label {
|
|
140
|
+
text-box-trim: trim-both;
|
|
141
|
+
text-box-edge: text;
|
|
142
|
+
}
|
|
111
143
|
}
|
|
112
144
|
|
|
113
145
|
:scope[data-ui-badge-state~="size=xs"] {
|
|
@@ -246,6 +278,10 @@
|
|
|
246
278
|
justify-content: center;
|
|
247
279
|
}
|
|
248
280
|
|
|
281
|
+
:scope[data-ui-badge-state~="shape=square"] .label:empty {
|
|
282
|
+
display: none;
|
|
283
|
+
}
|
|
284
|
+
|
|
249
285
|
/* A dot uses the badge's tone recipe; only its silhouette and visible label change. */
|
|
250
286
|
:scope[data-ui-badge-state~="shape=dot"] {
|
|
251
287
|
position: relative;
|
|
@@ -332,8 +368,25 @@
|
|
|
332
368
|
/* A constrained badge keeps its surface intact and ellipsizes only its label. The full
|
|
333
369
|
text stays in the DOM for accessible names and consumers' selected values. */
|
|
334
370
|
|
|
335
|
-
/*
|
|
336
|
-
|
|
371
|
+
/* Icon content has its own flex item so label ellipsis never clips its strokes. */
|
|
372
|
+
|
|
373
|
+
.icon :where([data-slotted], [data-slotted] *):is(svg) {
|
|
374
|
+
display: block;
|
|
375
|
+
inline-size: 1em;
|
|
376
|
+
block-size: 1em;
|
|
377
|
+
flex: none;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/* Ordinary icon-plus-text children keep inline ellipsis, with explicit glyph spacing. */
|
|
381
|
+
.label :where([data-slotted], [data-slotted] *):is(svg) {
|
|
382
|
+
inline-size: 1em;
|
|
383
|
+
block-size: 1em;
|
|
384
|
+
vertical-align: middle;
|
|
385
|
+
margin-inline-end: var(--ui-space-1);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/* Text-only badges retain their trimmed inline baseline. Icon content needs a flex row;
|
|
389
|
+
trimming its label separately keeps the glyph centered without changing adjacent lines. */
|
|
337
390
|
@supports (text-box-trim: trim-both) {
|
|
338
391
|
}
|
|
339
392
|
|
|
@@ -342,6 +395,10 @@
|
|
|
342
395
|
|
|
343
396
|
/* An icon mark keeps the existing tone recipe and follows the global spacing and radius. */
|
|
344
397
|
|
|
398
|
+
:scope[data-ui-badge-state~="shape=square"] .label :where([data-slotted], [data-slotted] *):is(svg) {
|
|
399
|
+
margin-inline-end: 0;
|
|
400
|
+
}
|
|
401
|
+
|
|
345
402
|
/* A dot uses the badge's tone recipe; only its silhouette and visible label change. */
|
|
346
403
|
|
|
347
404
|
/* The clipped point needs an inset surface over an outer border-colour shape: a native border
|
package/styles/ui-button.css
CHANGED
|
@@ -90,6 +90,7 @@
|
|
|
90
90
|
display: inline-flex;
|
|
91
91
|
align-items: center;
|
|
92
92
|
justify-content: center;
|
|
93
|
+
column-gap: var(--ui-space-2);
|
|
93
94
|
vertical-align: middle;
|
|
94
95
|
color: var(--_tone-text);
|
|
95
96
|
}
|
|
@@ -139,7 +140,6 @@
|
|
|
139
140
|
.spinner-wrap {
|
|
140
141
|
display: inline-flex;
|
|
141
142
|
flex: none;
|
|
142
|
-
margin-inline-end: var(--ui-space-2);
|
|
143
143
|
vertical-align: middle;
|
|
144
144
|
}
|
|
145
145
|
|
package/vanilla/UiBadge.js
CHANGED
|
@@ -16,17 +16,30 @@ export function createUiBadge(options = {}) {
|
|
|
16
16
|
}
|
|
17
17
|
element.setAttribute("data-component", "ui-badge");
|
|
18
18
|
const element0 = document.createElement("span");
|
|
19
|
-
element0.setAttribute("class", "
|
|
19
|
+
element0.setAttribute("class", "icon");
|
|
20
|
+
element0.setAttribute("aria-hidden", "true");
|
|
21
|
+
if (slots["icon"] ?? [].length > 0) {
|
|
22
|
+
for (const child of slots["icon"] ?? []) {
|
|
23
|
+
const node = typeof child === "string" ? document.createTextNode(child) : child;
|
|
24
|
+
if (node.nodeType === 1) node.setAttribute("data-slotted", "");
|
|
25
|
+
projected.push([node, "icon"]);
|
|
26
|
+
element0.append(node);
|
|
27
|
+
}
|
|
28
|
+
} else {
|
|
29
|
+
}
|
|
30
|
+
element.append(element0);
|
|
31
|
+
const element1 = document.createElement("span");
|
|
32
|
+
element1.setAttribute("class", "label");
|
|
20
33
|
if (children.length > 0) {
|
|
21
34
|
for (const child of children) {
|
|
22
35
|
const node = typeof child === "string" ? document.createTextNode(child) : child;
|
|
23
36
|
if (node.nodeType === 1) node.setAttribute("data-slotted", "");
|
|
24
37
|
projected.push([node, ""]);
|
|
25
|
-
|
|
38
|
+
element1.append(node);
|
|
26
39
|
}
|
|
27
40
|
} else {
|
|
28
41
|
}
|
|
29
|
-
element.append(
|
|
42
|
+
element.append(element1);
|
|
30
43
|
manageGeneratedProps(element, [
|
|
31
44
|
{ name: "shape", attribute: "data-shape", value: componentProps["shape"], default: "pill", type: ["pill","tag","dot","square"], required: false },
|
|
32
45
|
{ name: "size", attribute: "data-size", value: componentProps["size"], default: "md", type: ["xs","md"], required: false },
|
package/vue/UiBadge.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { PropType } from 'vue';
|
|
2
|
-
declare var __VLS_1: {};
|
|
2
|
+
declare var __VLS_1: {}, __VLS_3: {};
|
|
3
3
|
type __VLS_Slots = {} & {
|
|
4
|
-
|
|
4
|
+
icon?: (props: typeof __VLS_1) => any;
|
|
5
|
+
} & {
|
|
6
|
+
default?: (props: typeof __VLS_3) => any;
|
|
5
7
|
};
|
|
6
8
|
declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
7
9
|
shape: {
|
package/vue/UiBadge.vue
CHANGED
|
@@ -177,7 +177,8 @@ const hostState = computed(() =>
|
|
|
177
177
|
:data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
|
|
178
178
|
:data-variant="reflectedProp('variant', 'variant', checkedProps.variant, undefined, false)"
|
|
179
179
|
:data-ui-badge-state="hostState || undefined"
|
|
180
|
-
><span class="
|
|
180
|
+
><span class="icon" aria-hidden="true"><slot name="icon" /></span>
|
|
181
|
+
<span class="label"><slot /></span></span>
|
|
181
182
|
</template>
|
|
182
183
|
|
|
183
184
|
<style scoped>
|
|
@@ -261,6 +262,7 @@ const hostState = computed(() =>
|
|
|
261
262
|
display: inline-flex;
|
|
262
263
|
align-items: center;
|
|
263
264
|
justify-content: center;
|
|
265
|
+
gap: var(--ui-space-1);
|
|
264
266
|
box-sizing: border-box;
|
|
265
267
|
min-inline-size: 0;
|
|
266
268
|
max-inline-size: 100%;
|
|
@@ -287,8 +289,43 @@ const hostState = computed(() =>
|
|
|
287
289
|
text-overflow: ellipsis;
|
|
288
290
|
}
|
|
289
291
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
+
.label:empty {
|
|
293
|
+
display: none;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/* Icon content has its own flex item so label ellipsis never clips its strokes. */
|
|
297
|
+
.icon {
|
|
298
|
+
display: inline-flex;
|
|
299
|
+
align-items: center;
|
|
300
|
+
justify-content: center;
|
|
301
|
+
flex: none;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.icon:empty {
|
|
305
|
+
display: none;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.icon :slotted(svg) {
|
|
309
|
+
display: block;
|
|
310
|
+
inline-size: 1em;
|
|
311
|
+
block-size: 1em;
|
|
312
|
+
flex: none;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/* Ordinary icon-plus-text children keep inline ellipsis, with explicit glyph spacing. */
|
|
316
|
+
.label :slotted(svg) {
|
|
317
|
+
inline-size: 1em;
|
|
318
|
+
block-size: 1em;
|
|
319
|
+
vertical-align: middle;
|
|
320
|
+
margin-inline-end: var(--ui-space-1);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
.label:has(svg) {
|
|
324
|
+
text-box-trim: none;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/* Text-only badges retain their trimmed inline baseline. Icon content needs a flex row;
|
|
328
|
+
trimming its label separately keeps the glyph centered without changing adjacent lines. */
|
|
292
329
|
@supports (text-box-trim: trim-both) {
|
|
293
330
|
[data-component~="ui-badge"] {
|
|
294
331
|
display: inline-block;
|
|
@@ -298,6 +335,15 @@ const hostState = computed(() =>
|
|
|
298
335
|
text-box-trim: trim-both;
|
|
299
336
|
text-box-edge: text;
|
|
300
337
|
}
|
|
338
|
+
[data-component~="ui-badge"]:has(.icon:not(:empty)),
|
|
339
|
+
[data-component~="ui-badge"]:has(.label svg) {
|
|
340
|
+
display: inline-flex;
|
|
341
|
+
text-box-trim: none;
|
|
342
|
+
}
|
|
343
|
+
[data-component~="ui-badge"]:has(.icon:not(:empty)) .label {
|
|
344
|
+
text-box-trim: trim-both;
|
|
345
|
+
text-box-edge: text;
|
|
346
|
+
}
|
|
301
347
|
}
|
|
302
348
|
|
|
303
349
|
[data-component~="ui-badge"][data-ui-badge-state~="size=xs"] {
|
|
@@ -436,6 +482,14 @@ const hostState = computed(() =>
|
|
|
436
482
|
justify-content: center;
|
|
437
483
|
}
|
|
438
484
|
|
|
485
|
+
[data-component~="ui-badge"][data-ui-badge-state~="shape=square"] .label :slotted(svg) {
|
|
486
|
+
margin-inline-end: 0;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
[data-component~="ui-badge"][data-ui-badge-state~="shape=square"] .label:empty {
|
|
490
|
+
display: none;
|
|
491
|
+
}
|
|
492
|
+
|
|
439
493
|
/* A dot uses the badge's tone recipe; only its silhouette and visible label change. */
|
|
440
494
|
[data-component~="ui-badge"][data-ui-badge-state~="shape=dot"] {
|
|
441
495
|
position: relative;
|
package/vue/UiButton.vue
CHANGED
|
@@ -933,6 +933,7 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
|
|
|
933
933
|
display: inline-flex;
|
|
934
934
|
align-items: center;
|
|
935
935
|
justify-content: center;
|
|
936
|
+
column-gap: var(--ui-space-2);
|
|
936
937
|
vertical-align: middle;
|
|
937
938
|
color: var(--_tone-text);
|
|
938
939
|
}
|
|
@@ -982,7 +983,6 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
|
|
|
982
983
|
.spinner-wrap {
|
|
983
984
|
display: inline-flex;
|
|
984
985
|
flex: none;
|
|
985
|
-
margin-inline-end: var(--ui-space-2);
|
|
986
986
|
vertical-align: middle;
|
|
987
987
|
}
|
|
988
988
|
|
|
@@ -47,8 +47,8 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
47
47
|
};
|
|
48
48
|
}>> & Readonly<{}>, {
|
|
49
49
|
value: string | null;
|
|
50
|
-
disabled: boolean | null;
|
|
51
50
|
icon: string | null;
|
|
51
|
+
disabled: boolean | null;
|
|
52
52
|
description: string | null;
|
|
53
53
|
keywords: string | null;
|
|
54
54
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
package/vue/chunks/UiBadge.js
CHANGED
|
@@ -9,7 +9,11 @@ var _hoisted_1 = [
|
|
|
9
9
|
"data-variant",
|
|
10
10
|
"data-ui-badge-state"
|
|
11
11
|
];
|
|
12
|
-
var _hoisted_2 = {
|
|
12
|
+
var _hoisted_2 = {
|
|
13
|
+
class: "icon",
|
|
14
|
+
"aria-hidden": "true"
|
|
15
|
+
};
|
|
16
|
+
var _hoisted_3 = { class: "label" };
|
|
13
17
|
//#endregion
|
|
14
18
|
//#region .build/vue/UiBadge.vue
|
|
15
19
|
var UiBadge_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
|
|
@@ -163,12 +167,12 @@ var UiBadge_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE
|
|
|
163
167
|
"data-tone": reflectedProp("tone", "tone", checkedProps.value.tone, void 0, false),
|
|
164
168
|
"data-variant": reflectedProp("variant", "variant", checkedProps.value.variant, void 0, false),
|
|
165
169
|
"data-ui-badge-state": hostState.value || void 0
|
|
166
|
-
}), [createElementVNode("span", _hoisted_2, [renderSlot(_ctx.$slots, "
|
|
170
|
+
}), [createElementVNode("span", _hoisted_2, [renderSlot(_ctx.$slots, "icon")]), createElementVNode("span", _hoisted_3, [renderSlot(_ctx.$slots, "default")])], 16, _hoisted_1)), [[unref(vPropValidity), {
|
|
167
171
|
contract: propValidityContract,
|
|
168
172
|
values: { ...props }
|
|
169
173
|
}]]);
|
|
170
174
|
};
|
|
171
175
|
}
|
|
172
|
-
}), [["__scopeId", "data-v-
|
|
176
|
+
}), [["__scopeId", "data-v-5065fda2"]]);
|
|
173
177
|
//#endregion
|
|
174
178
|
export { UiBadge_default as t };
|
package/vue/chunks/UiButton.js
CHANGED