@threadlabs/looma 0.13.5 → 0.14.0
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-button/ui-button.html +2 -1
- package/components/ui-checkbox/ui-checkbox.html +35 -0
- package/components/ui-combobox/ui-combobox.html +38 -3
- package/components/ui-icon/ui-icon.html +67 -7
- package/components/ui-input/ui-input.html +27 -0
- package/components/ui-input-group/ui-input-group.html +15 -0
- package/components/ui-radio/ui-radio.html +35 -0
- package/components/ui-select/ui-select.html +29 -3
- package/components/ui-switch/ui-switch.html +36 -0
- package/components/ui-textarea/ui-textarea.html +20 -0
- package/dist/index.js +17 -18
- package/package.json +1 -1
- package/styles/ui-button.css +3 -1
- package/styles/ui-checkbox.css +38 -0
- package/styles/ui-combobox.css +38 -1
- package/styles/ui-input-group.css +20 -0
- package/styles/ui-input.css +29 -0
- package/styles/ui-radio.css +38 -0
- package/styles/ui-select.css +29 -3
- package/styles/ui-switch.css +41 -0
- package/styles/ui-textarea.css +21 -0
- package/vanilla/UiCheckbox.d.ts +1 -0
- package/vanilla/UiCheckbox.js +1 -1
- package/vanilla/UiCombobox.d.ts +1 -1
- package/vanilla/UiCombobox.js +1 -1
- package/vanilla/UiIcon.js +1 -3
- package/vanilla/UiInput.d.ts +1 -0
- package/vanilla/UiInput.js +1 -1
- package/vanilla/UiRadio.d.ts +1 -0
- package/vanilla/UiRadio.js +1 -1
- package/vanilla/UiSelect.d.ts +1 -0
- package/vanilla/UiSelect.js +1 -1
- package/vanilla/UiSwitch.d.ts +1 -0
- package/vanilla/UiSwitch.js +1 -1
- package/vanilla/UiTextarea.d.ts +1 -0
- package/vanilla/UiTextarea.js +1 -1
- package/vue/UiButton.vue +2 -1
- package/vue/UiCheckbox.d.ts +2 -0
- package/vue/UiCheckbox.vue +34 -0
- package/vue/UiCombobox.d.ts +2 -2
- package/vue/UiCombobox.vue +39 -2
- package/vue/UiIcon.vue +337 -42
- package/vue/UiInput.d.ts +2 -0
- package/vue/UiInput.vue +41 -0
- package/vue/UiInputGroup.vue +15 -0
- package/vue/UiRadio.d.ts +2 -0
- package/vue/UiRadio.vue +34 -0
- package/vue/UiSelect.d.ts +2 -0
- package/vue/UiSelect.vue +34 -3
- package/vue/UiSwitch.d.ts +2 -0
- package/vue/UiSwitch.vue +35 -0
- package/vue/UiTextarea.d.ts +2 -0
- package/vue/UiTextarea.vue +27 -0
- package/vue/chunks/UiButton.js +1 -1
- package/vue/chunks/UiCheckbox.js +3 -2
- package/vue/chunks/UiCombobox.js +1 -1
- package/vue/chunks/UiIcon.js +950 -32
- package/vue/chunks/UiInput.js +7 -2
- package/vue/chunks/UiInputGroup.js +1 -1
- package/vue/chunks/UiRadio.js +3 -2
- package/vue/chunks/UiSelect.js +7 -2
- package/vue/chunks/UiSwitch.js +3 -2
- package/vue/chunks/UiTextarea.js +7 -2
- package/vue/components.css +368 -168
- package/components/ui-icon/ui-icon.js +0 -8
package/package.json
CHANGED
package/styles/ui-button.css
CHANGED
|
@@ -274,8 +274,9 @@
|
|
|
274
274
|
border-color: transparent;
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
+
/* The size states outrank :host, so sm is named too, or a small button would stay small. */
|
|
277
278
|
@media (pointer: coarse) {
|
|
278
|
-
:scope {
|
|
279
|
+
:scope, :scope[data-ui-button-state~="size=sm"] {
|
|
279
280
|
min-block-size: var(--ui-control-min-block-size);
|
|
280
281
|
}
|
|
281
282
|
}
|
|
@@ -374,6 +375,7 @@
|
|
|
374
375
|
the way hover washes the live one, so it stays light in every tone. An opaque mix toward the
|
|
375
376
|
hue came out a mid-grey slab for neutral, whose hue is the ink: louder than the enabled button. */
|
|
376
377
|
|
|
378
|
+
/* The size states outrank :host, so sm is named too, or a small button would stay small. */
|
|
377
379
|
@media (pointer: coarse) {
|
|
378
380
|
}
|
|
379
381
|
|
package/styles/ui-checkbox.css
CHANGED
|
@@ -120,6 +120,37 @@
|
|
|
120
120
|
cursor: not-allowed;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
/* A sized choice keeps its box and aligns instead: the label takes that size's field type size,
|
|
124
|
+
and the first line centres in that control height, so the label shares a row's baseline.
|
|
125
|
+
Multi-line labels and descriptions still grow downward from that first line. */
|
|
126
|
+
:scope[data-ui-checkbox-state~="size=sm"] {
|
|
127
|
+
--_font: var(--ui-font-size-sm);
|
|
128
|
+
--_row: var(--ui-control-size-sm);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
:scope[data-ui-checkbox-state~="size=lg"] {
|
|
132
|
+
--_font: var(--ui-font-size-md);
|
|
133
|
+
--_row: var(--ui-control-size-lg);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
:scope[data-ui-checkbox-state~="size=sm"],
|
|
137
|
+
:scope[data-ui-checkbox-state~="size=lg"] {
|
|
138
|
+
--_line: calc(var(--_font) * var(--ui-line-height-md));
|
|
139
|
+
font-size: var(--_font);
|
|
140
|
+
padding-block: calc((var(--_row) - var(--_line)) / 2);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
:scope[data-ui-checkbox-state~="size=sm"] input,
|
|
144
|
+
:scope[data-ui-checkbox-state~="size=lg"] input {
|
|
145
|
+
margin-top: calc((var(--_line) - var(--_ui-checkbox-size, 1.125rem)) / 2);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@media (pointer: coarse) {
|
|
149
|
+
:scope[data-ui-checkbox-state~="size=sm"] {
|
|
150
|
+
--_row: var(--ui-control-min-block-size);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
123
154
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
|
124
155
|
:scope[hidden] {
|
|
125
156
|
display: none;
|
|
@@ -132,5 +163,12 @@
|
|
|
132
163
|
|
|
133
164
|
/* Centre the tick's box, then lift it: a rotated L's ink sits ~0.11rem below its box centre. */
|
|
134
165
|
|
|
166
|
+
/* A sized choice keeps its box and aligns instead: the label takes that size's field type size,
|
|
167
|
+
and the first line centres in that control height, so the label shares a row's baseline.
|
|
168
|
+
Multi-line labels and descriptions still grow downward from that first line. */
|
|
169
|
+
|
|
170
|
+
@media (pointer: coarse) {
|
|
171
|
+
}
|
|
172
|
+
|
|
135
173
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
|
136
174
|
}
|
package/styles/ui-combobox.css
CHANGED
|
@@ -149,9 +149,18 @@
|
|
|
149
149
|
margin: 0;
|
|
150
150
|
outline: none;
|
|
151
151
|
}
|
|
152
|
+
:scope[data-ui-combobox-state~="size=sm"] {
|
|
153
|
+
--_row: var(--ui-control-size-sm);
|
|
154
|
+
}
|
|
152
155
|
:scope[data-ui-combobox-state~="size=sm"] input {
|
|
153
|
-
min-block-size: calc(var(--
|
|
156
|
+
min-block-size: calc(var(--_row) - 2px);
|
|
154
157
|
padding: var(--ui-space-1) var(--ui-space-2);
|
|
158
|
+
font-size: var(--ui-font-size-sm);
|
|
159
|
+
}
|
|
160
|
+
:scope[data-ui-combobox-state~="size=lg"] input {
|
|
161
|
+
min-block-size: calc(var(--ui-control-size-lg) - 2px);
|
|
162
|
+
padding: var(--ui-space-3) var(--ui-space-4);
|
|
163
|
+
font-size: var(--ui-font-size-md);
|
|
155
164
|
}
|
|
156
165
|
button {
|
|
157
166
|
appearance: none;
|
|
@@ -252,6 +261,14 @@
|
|
|
252
261
|
min-inline-size: 2.75rem;
|
|
253
262
|
min-block-size: 2.75rem;
|
|
254
263
|
}
|
|
264
|
+
/* Under touch a small field is still a touch-sized target, as a small button is, and keeps
|
|
265
|
+
body-size text: below 16px, iOS zooms the page into the focused field. */
|
|
266
|
+
:scope[data-ui-combobox-state~="size=sm"] {
|
|
267
|
+
--_row: var(--ui-control-min-block-size);
|
|
268
|
+
}
|
|
269
|
+
:scope[data-ui-combobox-state~="size=sm"] input {
|
|
270
|
+
font-size: inherit;
|
|
271
|
+
}
|
|
255
272
|
}
|
|
256
273
|
@media (forced-colors: active) {
|
|
257
274
|
.field, .popup {
|
|
@@ -309,6 +326,22 @@
|
|
|
309
326
|
min-block-size: 1.75rem;
|
|
310
327
|
padding: var(--ui-space-0-5) var(--ui-space-1);
|
|
311
328
|
}
|
|
329
|
+
/* A small multiple field starts at the small control height; chosen items still wrap it taller. */
|
|
330
|
+
:scope[data-ui-combobox-state~="multiple"]:scope[data-ui-combobox-state~="size=sm"] .field {
|
|
331
|
+
min-block-size: 0;
|
|
332
|
+
padding: var(--ui-space-0-5);
|
|
333
|
+
}
|
|
334
|
+
:scope[data-ui-combobox-state~="multiple"]:scope[data-ui-combobox-state~="size=sm"] input {
|
|
335
|
+
min-block-size: calc(var(--_row) - 2px - 2 * var(--ui-space-0-5));
|
|
336
|
+
padding: 0 var(--ui-space-1);
|
|
337
|
+
}
|
|
338
|
+
/* A large multiple field starts at the large control height, as sm starts at the small one. */
|
|
339
|
+
:scope[data-ui-combobox-state~="multiple"]:scope[data-ui-combobox-state~="size=lg"] .field {
|
|
340
|
+
min-block-size: 0;
|
|
341
|
+
}
|
|
342
|
+
:scope[data-ui-combobox-state~="multiple"]:scope[data-ui-combobox-state~="size=lg"] input {
|
|
343
|
+
min-block-size: calc(var(--ui-control-size-lg) - 2px - 2 * var(--ui-space-1));
|
|
344
|
+
}
|
|
312
345
|
.item {
|
|
313
346
|
appearance: none;
|
|
314
347
|
display: inline-flex;
|
|
@@ -342,6 +375,8 @@
|
|
|
342
375
|
not inside it, because a control's box holds its value. */
|
|
343
376
|
/* A ghost icon button: the affordance is the mark, not a box around it. */
|
|
344
377
|
@media (pointer: coarse) {
|
|
378
|
+
/* Under touch a small field is still a touch-sized target, as a small button is, and keeps
|
|
379
|
+
body-size text: below 16px, iOS zooms the page into the focused field. */
|
|
345
380
|
}
|
|
346
381
|
@media (forced-colors: active) {
|
|
347
382
|
}
|
|
@@ -351,6 +386,8 @@
|
|
|
351
386
|
Longhands, not shorthands: lowering drops a shorthand that omits a component. */
|
|
352
387
|
|
|
353
388
|
/* Multiple mode: chips wrap before the cursor on one flexible field line. */
|
|
389
|
+
/* A small multiple field starts at the small control height; chosen items still wrap it taller. */
|
|
390
|
+
/* A large multiple field starts at the large control height, as sm starts at the small one. */
|
|
354
391
|
|
|
355
392
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
|
356
393
|
}
|
|
@@ -41,6 +41,21 @@
|
|
|
41
41
|
transition: border-color var(--ui-motion-fast) var(--ui-motion-ease), box-shadow var(--ui-motion-fast) var(--ui-motion-ease);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
/* The frame takes its input's size, so a small group lines up with small buttons and fields. */
|
|
45
|
+
:scope:has(.field [data-ui-input-state~="size=sm"]) {
|
|
46
|
+
min-block-size: var(--ui-control-size-sm);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
:scope:has(.field [data-ui-input-state~="size=lg"]) {
|
|
50
|
+
min-block-size: var(--ui-control-size-lg);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@media (pointer: coarse) {
|
|
54
|
+
:scope:has(.field [data-ui-input-state~="size=sm"]) {
|
|
55
|
+
min-block-size: var(--ui-control-min-block-size);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
44
59
|
:scope:hover:not(:has(input:focus, input:disabled)) {
|
|
45
60
|
border-color: var(--ui-control-border-hover, var(--ui-text-secondary));
|
|
46
61
|
}
|
|
@@ -125,6 +140,11 @@
|
|
|
125
140
|
thing the field is for ("Continue" after a site's address), so it reads as the field's action
|
|
126
141
|
and not the form's. */
|
|
127
142
|
|
|
143
|
+
/* The frame takes its input's size, so a small group lines up with small buttons and fields. */
|
|
144
|
+
|
|
145
|
+
@media (pointer: coarse) {
|
|
146
|
+
}
|
|
147
|
+
|
|
128
148
|
/* The ring shows when the field's input would show its own: when it is focus-visible, which a
|
|
129
149
|
text input is for a pointer as well as a keyboard. A focused action button draws its own. */
|
|
130
150
|
|
package/styles/ui-input.css
CHANGED
|
@@ -74,6 +74,28 @@
|
|
|
74
74
|
background-color var(--ui-motion-fast) var(--ui-motion-ease);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
/* Each size reads the hook and then an Input Group's default first, so a group, which draws the frame, can zero it. */
|
|
78
|
+
:scope[data-ui-input-state~="size=sm"] {
|
|
79
|
+
min-block-size: var(--ui-input-min-block-size, var(--_ui-default-input-min-block-size, var(--ui-control-size-sm)));
|
|
80
|
+
padding: var(--ui-space-1) var(--ui-space-2);
|
|
81
|
+
font-size: var(--ui-font-size-sm);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
:scope[data-ui-input-state~="size=lg"] {
|
|
85
|
+
min-block-size: var(--ui-input-min-block-size, var(--_ui-default-input-min-block-size, var(--ui-control-size-lg)));
|
|
86
|
+
padding: var(--ui-space-3) var(--ui-space-4);
|
|
87
|
+
font-size: var(--ui-font-size-md);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* Under touch a small field is still a touch-sized target, as a small button is, and keeps
|
|
91
|
+
body-size text: below 16px, iOS zooms the page into the focused field. */
|
|
92
|
+
@media (pointer: coarse) {
|
|
93
|
+
:scope[data-ui-input-state~="size=sm"] {
|
|
94
|
+
min-block-size: var(--ui-input-min-block-size, var(--_ui-default-input-min-block-size, var(--ui-control-min-block-size)));
|
|
95
|
+
font-size: inherit;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
77
99
|
/* Tabbing into a field selects its text; tint that selection softly instead of the page highlight. */
|
|
78
100
|
:scope::selection {
|
|
79
101
|
background: color-mix(in srgb, var(--ui-accent-solid) 20%, transparent);
|
|
@@ -139,6 +161,13 @@
|
|
|
139
161
|
/* This component's hooks style the element they are set on, and never a nested one. An Input
|
|
140
162
|
Group sets --_ui-default-input-* for the input inside it, below the input's own hooks. */
|
|
141
163
|
|
|
164
|
+
/* Each size reads the hook and then an Input Group's default first, so a group, which draws the frame, can zero it. */
|
|
165
|
+
|
|
166
|
+
/* Under touch a small field is still a touch-sized target, as a small button is, and keeps
|
|
167
|
+
body-size text: below 16px, iOS zooms the page into the focused field. */
|
|
168
|
+
@media (pointer: coarse) {
|
|
169
|
+
}
|
|
170
|
+
|
|
142
171
|
/* Tabbing into a field selects its text; tint that selection softly instead of the page highlight. */
|
|
143
172
|
|
|
144
173
|
/* The app's invalid flag, or the browser's own verdict once the user has left an invalid field. */
|
package/styles/ui-radio.css
CHANGED
|
@@ -67,6 +67,37 @@
|
|
|
67
67
|
cursor: not-allowed;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
/* A sized choice keeps its box and aligns instead: the label takes that size's field type size,
|
|
71
|
+
and the first line centres in that control height, so the label shares a row's baseline.
|
|
72
|
+
Multi-line labels and descriptions still grow downward from that first line. */
|
|
73
|
+
:scope[data-ui-radio-state~="size=sm"] {
|
|
74
|
+
--_font: var(--ui-font-size-sm);
|
|
75
|
+
--_row: var(--ui-control-size-sm);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
:scope[data-ui-radio-state~="size=lg"] {
|
|
79
|
+
--_font: var(--ui-font-size-md);
|
|
80
|
+
--_row: var(--ui-control-size-lg);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
:scope[data-ui-radio-state~="size=sm"],
|
|
84
|
+
:scope[data-ui-radio-state~="size=lg"] {
|
|
85
|
+
--_line: calc(var(--_font) * var(--ui-line-height-md));
|
|
86
|
+
font-size: var(--_font);
|
|
87
|
+
padding-block: calc((var(--_row) - var(--_line)) / 2);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
:scope[data-ui-radio-state~="size=sm"] input,
|
|
91
|
+
:scope[data-ui-radio-state~="size=lg"] input {
|
|
92
|
+
margin-top: calc((var(--_line) - var(--_ui-radio-size, 1.125rem)) / 2);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@media (pointer: coarse) {
|
|
96
|
+
:scope[data-ui-radio-state~="size=sm"] {
|
|
97
|
+
--_row: var(--ui-control-min-block-size);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
70
101
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
|
71
102
|
:scope[hidden] {
|
|
72
103
|
display: none;
|
|
@@ -77,5 +108,12 @@
|
|
|
77
108
|
|
|
78
109
|
/* The label, and under it an optional line saying what the choice means. */
|
|
79
110
|
|
|
111
|
+
/* A sized choice keeps its box and aligns instead: the label takes that size's field type size,
|
|
112
|
+
and the first line centres in that control height, so the label shares a row's baseline.
|
|
113
|
+
Multi-line labels and descriptions still grow downward from that first line. */
|
|
114
|
+
|
|
115
|
+
@media (pointer: coarse) {
|
|
116
|
+
}
|
|
117
|
+
|
|
80
118
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
|
81
119
|
}
|
package/styles/ui-select.css
CHANGED
|
@@ -79,9 +79,30 @@
|
|
|
79
79
|
cursor: not-allowed;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
:scope[size
|
|
83
|
-
min-block-size:
|
|
84
|
-
padding: var(--ui-space-2);
|
|
82
|
+
:scope[data-ui-select-state~="size=sm"] {
|
|
83
|
+
min-block-size: var(--ui-control-size-sm);
|
|
84
|
+
padding: var(--ui-space-1) var(--ui-space-2);
|
|
85
|
+
padding-inline-end: calc(var(--ui-space-2) + var(--ui-icon-size-sm) + var(--ui-space-1));
|
|
86
|
+
background-position: right var(--ui-space-2) center;
|
|
87
|
+
background-size: var(--ui-icon-size-sm) var(--ui-icon-size-sm);
|
|
88
|
+
font-size: var(--ui-font-size-sm);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
:scope[data-ui-select-state~="size=lg"] {
|
|
92
|
+
min-block-size: var(--ui-control-size-lg);
|
|
93
|
+
padding: var(--ui-space-3) var(--ui-space-4);
|
|
94
|
+
padding-inline-end: calc(var(--ui-space-4) + 1.5rem);
|
|
95
|
+
background-position: right var(--ui-space-4) center;
|
|
96
|
+
font-size: var(--ui-font-size-md);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Under touch a small field is still a touch-sized target, as a small button is, and keeps
|
|
100
|
+
body-size text: below 16px, iOS zooms the page into the focused field. */
|
|
101
|
+
@media (pointer: coarse) {
|
|
102
|
+
:scope[data-ui-select-state~="size=sm"] {
|
|
103
|
+
min-block-size: var(--ui-control-min-block-size);
|
|
104
|
+
font-size: inherit;
|
|
105
|
+
}
|
|
85
106
|
}
|
|
86
107
|
|
|
87
108
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
|
@@ -97,5 +118,10 @@
|
|
|
97
118
|
|
|
98
119
|
/* The app's invalid flag, or the browser's own verdict once the user has left an invalid field. */
|
|
99
120
|
|
|
121
|
+
/* Under touch a small field is still a touch-sized target, as a small button is, and keeps
|
|
122
|
+
body-size text: below 16px, iOS zooms the page into the focused field. */
|
|
123
|
+
@media (pointer: coarse) {
|
|
124
|
+
}
|
|
125
|
+
|
|
100
126
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
|
101
127
|
}
|
package/styles/ui-switch.css
CHANGED
|
@@ -111,6 +111,38 @@
|
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
/* A sized switch keeps its track and aligns instead: the label takes that size's field type size,
|
|
115
|
+
and the first line centres in that control height, so the label shares a row's baseline.
|
|
116
|
+
Multi-line labels and descriptions still grow downward from that first line. */
|
|
117
|
+
:scope[data-ui-switch-state~="size=sm"] {
|
|
118
|
+
--_font: var(--ui-font-size-sm);
|
|
119
|
+
--_row: var(--ui-control-size-sm);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
:scope[data-ui-switch-state~="size=lg"] {
|
|
123
|
+
--_font: var(--ui-font-size-md);
|
|
124
|
+
--_row: var(--ui-control-size-lg);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
:scope[data-ui-switch-state~="size=sm"],
|
|
128
|
+
:scope[data-ui-switch-state~="size=lg"] {
|
|
129
|
+
--_line: calc(var(--_font) * var(--ui-line-height-md));
|
|
130
|
+
font-size: var(--_font);
|
|
131
|
+
padding-block: calc((var(--_row) - var(--ui-switch-track-height, 1.5rem)) / 2);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* The label centres on the track. */
|
|
135
|
+
:scope[data-ui-switch-state~="size=sm"] .text,
|
|
136
|
+
:scope[data-ui-switch-state~="size=lg"] .text {
|
|
137
|
+
margin-top: calc((var(--_ui-switch-track-height, 1.5rem) - var(--_line)) / 2);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@media (pointer: coarse) {
|
|
141
|
+
:scope[data-ui-switch-state~="size=sm"] {
|
|
142
|
+
--_row: var(--ui-control-min-block-size);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
114
146
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
|
115
147
|
:scope[hidden] {
|
|
116
148
|
display: none;
|
|
@@ -124,5 +156,14 @@
|
|
|
124
156
|
@media (prefers-reduced-motion: reduce) {
|
|
125
157
|
}
|
|
126
158
|
|
|
159
|
+
/* A sized switch keeps its track and aligns instead: the label takes that size's field type size,
|
|
160
|
+
and the first line centres in that control height, so the label shares a row's baseline.
|
|
161
|
+
Multi-line labels and descriptions still grow downward from that first line. */
|
|
162
|
+
|
|
163
|
+
/* The label centres on the track. */
|
|
164
|
+
|
|
165
|
+
@media (pointer: coarse) {
|
|
166
|
+
}
|
|
167
|
+
|
|
127
168
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
|
128
169
|
}
|
package/styles/ui-textarea.css
CHANGED
|
@@ -77,6 +77,23 @@
|
|
|
77
77
|
cursor: not-allowed;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
:scope[data-ui-textarea-state~="size=sm"] {
|
|
81
|
+
padding: var(--ui-space-1) var(--ui-space-2);
|
|
82
|
+
font-size: var(--ui-font-size-sm);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
:scope[data-ui-textarea-state~="size=lg"] {
|
|
86
|
+
padding: var(--ui-space-3) var(--ui-space-4);
|
|
87
|
+
font-size: var(--ui-font-size-md);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* Below 16px, iOS zooms the page into the focused field, so touch keeps body-size text. */
|
|
91
|
+
@media (pointer: coarse) {
|
|
92
|
+
:scope[data-ui-textarea-state~="size=sm"] {
|
|
93
|
+
font-size: inherit;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
80
97
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
|
81
98
|
:scope[hidden] {
|
|
82
99
|
display: none;
|
|
@@ -89,5 +106,9 @@
|
|
|
89
106
|
|
|
90
107
|
/* The app's invalid flag, or the browser's own verdict once the user has left an invalid field. */
|
|
91
108
|
|
|
109
|
+
/* Below 16px, iOS zooms the page into the focused field, so touch keeps body-size text. */
|
|
110
|
+
@media (pointer: coarse) {
|
|
111
|
+
}
|
|
112
|
+
|
|
92
113
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
|
93
114
|
}
|
package/vanilla/UiCheckbox.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export interface UiCheckboxProps {
|
|
|
12
12
|
indeterminate?: boolean | null;
|
|
13
13
|
name?: string | null;
|
|
14
14
|
required?: boolean | null;
|
|
15
|
+
size?: "sm" | "md" | "lg" | null;
|
|
15
16
|
value?: string | null;
|
|
16
17
|
attributes?: Readonly<Record<string, string | number | boolean | null | undefined>>;
|
|
17
18
|
children?: readonly (string | Node)[];
|
package/vanilla/UiCheckbox.js
CHANGED
|
@@ -3,7 +3,7 @@ import { manageComponentLifecycle } from "@nextwebwg/html-next/runtime";
|
|
|
3
3
|
import * as controller from "../components/ui-checkbox/ui-checkbox.js";
|
|
4
4
|
import "../styles/ui-checkbox.css";
|
|
5
5
|
|
|
6
|
-
const definition = {...{"contract":{"tag":"ui-checkbox","props":{"checked":{"type":"boolean","required":false,"target":{"attribute":"checked"},"default":false},"disabled":{"type":"boolean","required":false,"target":{"attribute":"disabled"},"default":false},"indeterminate":{"type":"boolean","required":false,"target":{"property":"indeterminate"},"default":false},"name":{"type":"string","required":false,"target":{"attribute":"name"},"default":""},"required":{"type":"boolean","required":false,"target":{"attribute":"required"},"default":false},"value":{"type":"string","required":false,"target":{"attribute":"value"},"default":"on"}}},"template":{"kind":"element","name":"label","attributes":[],"children":[{"kind":"element","name":"input","attributes":[{"kind":"literal","name":"type","value":"checkbox"},{"kind":"property","key":"checked","name":"checked","expression":"internalChecked","expressionPlan":{"source":"internalChecked","ast":{"kind":"id","name":"internalChecked"},"dependencies":["internalChecked"]}},{"kind":"property","key":"indeterminate","name":"indeterminate","expression":"indeterminate","expressionPlan":{"source":"indeterminate","ast":{"kind":"id","name":"indeterminate"},"dependencies":["indeterminate"]}},{"kind":"attribute","name":"disabled","expression":"disabled","expressionPlan":{"source":"disabled","ast":{"kind":"id","name":"disabled"},"dependencies":["disabled"]}},{"kind":"attribute","name":"required","expression":"required","expressionPlan":{"source":"required","ast":{"kind":"id","name":"required"},"dependencies":["required"]}},{"kind":"attribute","name":"name","expression":"name","expressionPlan":{"source":"name","ast":{"kind":"id","name":"name"},"dependencies":["name"]}},{"kind":"attribute","name":"value","expression":"value","expressionPlan":{"source":"value","ast":{"kind":"id","name":"value"},"dependencies":["value"]}}],"children":[],"ref":"input"},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"text"}],"children":[{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"label"}],"children":[{"kind":"slot"}]},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"description"},{"kind":"literal","name":"aria-hidden","value":"true"}],"children":[{"kind":"slot","fallback":[],"name":"description"}],"ref":"description"}]}]},"declarations":[{"kind":"state","name":"internalChecked","expression":{"source":"false","ast":{"kind":"literal","value":false},"dependencies":[]}},{"kind":"event","name":"change","type":"object({ checked: boolean, value: string, trigger: keyboard | pointer | programmatic })","bubbles":true,"composed":true,"cancelable":false}],"root":{"kind":"native","element":"label","choices":["label"]}},source:{file:import.meta.url},css:""};
|
|
6
|
+
const definition = {...{"contract":{"tag":"ui-checkbox","props":{"checked":{"type":"boolean","required":false,"target":{"attribute":"checked"},"default":false},"disabled":{"type":"boolean","required":false,"target":{"attribute":"disabled"},"default":false},"indeterminate":{"type":"boolean","required":false,"target":{"property":"indeterminate"},"default":false},"name":{"type":"string","required":false,"target":{"attribute":"name"},"default":""},"required":{"type":"boolean","required":false,"target":{"attribute":"required"},"default":false},"size":{"type":{"enum":["sm","md","lg"]},"required":false,"target":{"attribute":"size"},"default":"md"},"value":{"type":"string","required":false,"target":{"attribute":"value"},"default":"on"}}},"template":{"kind":"element","name":"label","attributes":[],"children":[{"kind":"element","name":"input","attributes":[{"kind":"literal","name":"type","value":"checkbox"},{"kind":"property","key":"checked","name":"checked","expression":"internalChecked","expressionPlan":{"source":"internalChecked","ast":{"kind":"id","name":"internalChecked"},"dependencies":["internalChecked"]}},{"kind":"property","key":"indeterminate","name":"indeterminate","expression":"indeterminate","expressionPlan":{"source":"indeterminate","ast":{"kind":"id","name":"indeterminate"},"dependencies":["indeterminate"]}},{"kind":"attribute","name":"disabled","expression":"disabled","expressionPlan":{"source":"disabled","ast":{"kind":"id","name":"disabled"},"dependencies":["disabled"]}},{"kind":"attribute","name":"required","expression":"required","expressionPlan":{"source":"required","ast":{"kind":"id","name":"required"},"dependencies":["required"]}},{"kind":"attribute","name":"name","expression":"name","expressionPlan":{"source":"name","ast":{"kind":"id","name":"name"},"dependencies":["name"]}},{"kind":"attribute","name":"value","expression":"value","expressionPlan":{"source":"value","ast":{"kind":"id","name":"value"},"dependencies":["value"]}}],"children":[],"ref":"input"},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"text"}],"children":[{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"label"}],"children":[{"kind":"slot"}]},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"description"},{"kind":"literal","name":"aria-hidden","value":"true"}],"children":[{"kind":"slot","fallback":[],"name":"description"}],"ref":"description"}]}]},"declarations":[{"kind":"state","name":"internalChecked","expression":{"source":"false","ast":{"kind":"literal","value":false},"dependencies":[]}},{"kind":"event","name":"change","type":"object({ checked: boolean, value: string, trigger: keyboard | pointer | programmatic })","bubbles":true,"composed":true,"cancelable":false}],"root":{"kind":"native","element":"label","choices":["label"]}},source:{file:import.meta.url},css:""};
|
|
7
7
|
|
|
8
8
|
export function createUiCheckbox(options = {}) {
|
|
9
9
|
const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
|
package/vanilla/UiCombobox.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export interface UiComboboxProps {
|
|
|
34
34
|
readonly?: boolean | null;
|
|
35
35
|
required?: boolean | null;
|
|
36
36
|
selectedValues?: readonly (string)[] | null;
|
|
37
|
-
size?: "sm" | "md" | null;
|
|
37
|
+
size?: "sm" | "md" | "lg" | null;
|
|
38
38
|
tokenSeparators?: readonly (string)[] | null;
|
|
39
39
|
value?: string | null;
|
|
40
40
|
attributes?: Readonly<Record<string, string | number | boolean | null | undefined>>;
|