@threadlabs/looma 0.26.16 → 0.26.18
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-menu/ui-menu.html +6 -0
- package/components/ui-menu-item/ui-menu-item.html +26 -0
- package/components/ui-meter/ui-meter.html +59 -8
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/styles/ui-menu-item.css +25 -0
- package/styles/ui-menu.css +5 -0
- package/styles/ui-meter.css +34 -0
- package/vanilla/UiMenu.d.ts +1 -0
- package/vanilla/UiMenu.js +4 -4
- package/vanilla/UiMenuItem.d.ts +1 -0
- package/vanilla/UiMenuItem.js +77 -49
- package/vanilla/UiMeter.d.ts +2 -0
- package/vanilla/UiMeter.js +136 -38
- package/vue/UiMenu.d.ts +9 -0
- package/vue/UiMenu.vue +25 -1
- package/vue/UiMenuItem.d.ts +13 -0
- package/vue/UiMenuItem.vue +48 -2
- package/vue/UiMeter.d.ts +27 -0
- package/vue/UiMeter.vue +514 -77
- package/vue/chunks/UiMenu.js +24 -1
- package/vue/chunks/UiMenuItem.js +55 -12
- package/vue/chunks/UiMeter.js +271 -57
- package/vue/components.css +101 -52
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
<defs>
|
|
3
3
|
<prop name="density" type="keyword" values="comfortable, compact" default="comfortable"
|
|
4
4
|
>Compact trades padding and type size for rows that fit more on screen.</prop>
|
|
5
|
+
<prop name="icons" type="boolean" default="false">Reserves a fixed icon column in every item, including items without an icon. Supply item icons through their icon slot.</prop>
|
|
5
6
|
<prop name="size" type="keyword" values="sm, md" default="md"
|
|
6
7
|
>sm sizes the menu to a small trigger, such as an xs or sm button: smallest text, short rows, a small check, and a narrower minimum width. md is the
|
|
7
8
|
standard size.</prop>
|
|
@@ -77,6 +78,10 @@
|
|
|
77
78
|
gap: 0;
|
|
78
79
|
}
|
|
79
80
|
|
|
81
|
+
:host([icons]) {
|
|
82
|
+
--_ui-default-menu-icon-display: inline-flex;
|
|
83
|
+
}
|
|
84
|
+
|
|
80
85
|
:host {
|
|
81
86
|
--_ui-menu-surface: var(--ui-menu-surface);
|
|
82
87
|
--_ui-menu-border: var(--ui-menu-border);
|
|
@@ -89,6 +94,7 @@
|
|
|
89
94
|
--_ui-default-menu-item-radius: initial;
|
|
90
95
|
--_ui-default-menu-item-min-block-size: initial;
|
|
91
96
|
--_ui-default-menu-indicator-size: initial;
|
|
97
|
+
--_ui-default-menu-icon-display: none;
|
|
92
98
|
display: flex;
|
|
93
99
|
flex-direction: column;
|
|
94
100
|
box-sizing: border-box;
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
<prop name="type" type="keyword" values="action, checkbox, radio" default="action"
|
|
11
11
|
>An action closes its menu; a checkbox toggles, and a radio chooses one item within its nearest Menu Group. Checkable items keep the menu open.</prop>
|
|
12
12
|
<prop name="checked" type="boolean" default="false">Initial or externally controlled checked state of a checkbox or radio item.</prop>
|
|
13
|
+
<prop name="tone" type="keyword" values="neutral, danger" default="neutral">Danger identifies a destructive action without changing its behavior.</prop>
|
|
13
14
|
<state type="boolean" name="internalChecked" value="false"></state>
|
|
14
15
|
<event name="change" type="object">
|
|
15
16
|
<prop name="checked" required type="boolean"></prop>
|
|
@@ -27,6 +28,7 @@
|
|
|
27
28
|
from:data-value="$value"
|
|
28
29
|
from:href="{ true: null, false: $href }[concat($disabled)]"
|
|
29
30
|
>
|
|
31
|
+
<span class="icon" aria-hidden="true"><slot name="icon"></slot></span>
|
|
30
32
|
<span class="label"><slot></slot></span>
|
|
31
33
|
<span class="shortcut" aria-hidden="true"><slot name="shortcut"></slot></span>
|
|
32
34
|
</a>
|
|
@@ -41,6 +43,7 @@
|
|
|
41
43
|
<span class="indicator" aria-hidden="true">
|
|
42
44
|
<ui-icon $if="($type = 'checkbox' or $type = 'radio') and $internalChecked" name="check"></ui-icon>
|
|
43
45
|
</span>
|
|
46
|
+
<span class="icon" aria-hidden="true"><slot name="icon"></slot></span>
|
|
44
47
|
<span class="label"><slot></slot></span>
|
|
45
48
|
<span class="shortcut" aria-hidden="true"><slot name="shortcut"></slot></span>
|
|
46
49
|
</div>
|
|
@@ -91,6 +94,29 @@
|
|
|
91
94
|
transition: background-color var(--ui-motion-fast) var(--ui-motion-ease), color var(--ui-motion-fast) var(--ui-motion-ease);
|
|
92
95
|
}
|
|
93
96
|
|
|
97
|
+
/* A named icon has a fixed column; an icon-enabled menu reserves it on every row. */
|
|
98
|
+
.icon {
|
|
99
|
+
display: var(--_ui-default-menu-icon-display, none);
|
|
100
|
+
align-items: center;
|
|
101
|
+
justify-content: center;
|
|
102
|
+
flex: none;
|
|
103
|
+
inline-size: var(--ui-icon-size-sm);
|
|
104
|
+
block-size: var(--ui-icon-size-sm);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.icon:not(:empty) {
|
|
108
|
+
display: inline-flex;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.icon :slotted(svg) {
|
|
112
|
+
inline-size: 100%;
|
|
113
|
+
block-size: 100%;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
:host([tone="danger"]) {
|
|
117
|
+
color: var(--ui-danger);
|
|
118
|
+
}
|
|
119
|
+
|
|
94
120
|
.label {
|
|
95
121
|
display: flex;
|
|
96
122
|
align-items: center;
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
<template component="ui-meter">
|
|
2
2
|
<defs>
|
|
3
|
+
<prop name="variant" type="keyword" values="progress, distribution" default="progress"
|
|
4
|
+
>progress measures one value against max. distribution shows mutually exclusive parts of a whole as a full-width proportional bar; it uses parts rather than
|
|
5
|
+
value/max and is an image, not a progress reading.</prop>
|
|
6
|
+
<prop name="parts" type="list" default="[]">Categories in display order for distribution. Positive finite values determine each share without rounding; zero
|
|
7
|
+
and negative values draw nothing. Supply label and valueText to describe every category, and a visible text legend so colour is never the only
|
|
8
|
+
explanation.
|
|
9
|
+
<prop type="object">
|
|
10
|
+
<prop name="value" required type="number"></prop>
|
|
11
|
+
<prop name="color" required type="string"
|
|
12
|
+
>A CSS category colour, including a theme variable. This names category identity independently of status tones.</prop>
|
|
13
|
+
</prop>
|
|
14
|
+
</prop>
|
|
3
15
|
<prop name="value" type="number" default="0"
|
|
4
16
|
>How far along, from 0 to max. A value outside that range draws at the nearer end: below 0 is an empty track, above max a full bar.</prop>
|
|
5
17
|
<prop name="max" type="number" default="1"
|
|
@@ -25,15 +37,26 @@
|
|
|
25
37
|
<computed name="percent" from="{ true: $amount / $max * 100, false: 0 }[concat($max > 0)]"></computed>
|
|
26
38
|
</defs>
|
|
27
39
|
<span
|
|
28
|
-
role="meter"
|
|
29
|
-
aria-valuemin="0"
|
|
30
|
-
from:aria-valuemax="$max"
|
|
31
|
-
from:aria-valuenow="$amount"
|
|
32
|
-
from:aria-valuetext="{ true: $valueText, false: format($percent / 100, 'percent', { maximumFractionDigits: 0 }) }[concat($valueText != '')]"
|
|
33
|
-
from:aria-label="{ true: $label, false: null }[concat($label != '')]"
|
|
34
|
-
from:data-ui-meter-segments="{ true: $segments, false: null }[concat($segments > 1)]"
|
|
40
|
+
from:role="{ true: 'img', false: 'meter' }[concat($variant = 'distribution')]"
|
|
41
|
+
from:aria-valuemin="{ true: null, false: 0 }[concat($variant = 'distribution')]"
|
|
42
|
+
from:aria-valuemax="{ true: null, false: $max }[concat($variant = 'distribution')]"
|
|
43
|
+
from:aria-valuenow="{ true: null, false: $amount }[concat($variant = 'distribution')]"
|
|
44
|
+
from:aria-valuetext="{ true: null, false: { true: $valueText, false: format($percent / 100, 'percent', { maximumFractionDigits: 0 }) }[concat($valueText != '')] }[concat($variant = 'distribution')]"
|
|
45
|
+
from:aria-label="{ true: { true: concat($label, ': ', $valueText), false: $label }[concat($variant = 'distribution' and $valueText != '')], false: null }[concat($label != '')]"
|
|
46
|
+
from:data-ui-meter-segments="{ true: $segments, false: null }[concat($variant = 'progress' and $segments > 1)]"
|
|
35
47
|
>
|
|
36
|
-
<span class="fill" style:inline-size="concat($percent, '%')"></span>
|
|
48
|
+
<span $if="$variant = 'progress'" class="fill" style:inline-size="concat($percent, '%')"></span>
|
|
49
|
+
<template $if="$variant = 'distribution'">
|
|
50
|
+
<template $each="part of $parts">
|
|
51
|
+
<span
|
|
52
|
+
$if="$part.value > 0 and $part.value - $part.value = 0"
|
|
53
|
+
class="part"
|
|
54
|
+
aria-hidden="true"
|
|
55
|
+
style:flex-grow="$part.value"
|
|
56
|
+
style:background-color="$part.color"
|
|
57
|
+
></span>
|
|
58
|
+
</template>
|
|
59
|
+
</template>
|
|
37
60
|
</span>
|
|
38
61
|
<style>
|
|
39
62
|
/* How far along something is: a track, filled from the start in the tone's colour. The track is a
|
|
@@ -158,6 +181,34 @@
|
|
|
158
181
|
--_meter-gap: var(--ui-space-0-5);
|
|
159
182
|
}
|
|
160
183
|
|
|
184
|
+
/* A categorical distribution uses flex ratios, avoiding rounded percentages and retaining
|
|
185
|
+
identical geometry before hydration. It has no progress mask or growing-value animation. */
|
|
186
|
+
:host([variant="distribution"]) {
|
|
187
|
+
display: flex;
|
|
188
|
+
inline-size: 100%;
|
|
189
|
+
block-size: var(--ui-space-4);
|
|
190
|
+
gap: var(--ui-space-0-5);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
:host([variant="distribution"])[size="sm"] {
|
|
194
|
+
block-size: var(--ui-space-2);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.part {
|
|
198
|
+
flex-basis: 0;
|
|
199
|
+
min-inline-size: 0;
|
|
200
|
+
block-size: 100%;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
@media (forced-colors: active) {
|
|
204
|
+
.part {
|
|
205
|
+
forced-color-adjust: none;
|
|
206
|
+
background: CanvasText !important;
|
|
207
|
+
outline: var(--ui-border-width) solid Canvas;
|
|
208
|
+
outline-offset: calc(-1 * var(--ui-border-width));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
161
212
|
/* Forced colours drop backgrounds: draw the fill in the text colour inside the outlined track. */
|
|
162
213
|
@media (forced-colors: active) {
|
|
163
214
|
.fill {
|