@threadlabs/looma 0.11.6 → 0.12.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/shared/describe.js +9 -0
- package/components/ui-button/ui-button.html +6 -19
- package/components/ui-checkbox/ui-checkbox.html +22 -1
- package/components/ui-checkbox/ui-checkbox.js +2 -0
- package/components/ui-icon-button/ui-icon-button.html +4 -14
- package/components/ui-radio/ui-radio.html +22 -1
- package/components/ui-radio/ui-radio.js +2 -0
- package/components/ui-sidebar/ui-sidebar.js +3 -1
- package/components/ui-switch/ui-switch.html +22 -1
- package/components/ui-switch/ui-switch.js +2 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/styles/ui-button.css +11 -25
- package/styles/ui-checkbox.css +21 -1
- package/styles/ui-icon-button.css +4 -13
- package/styles/ui-radio.css +21 -1
- package/styles/ui-switch.css +21 -1
- package/theme-dark.css +2 -0
- package/theme-high-contrast.css +3 -0
- package/tokens.css +3 -0
- package/vanilla/UiCheckbox.js +18 -3
- package/vanilla/UiRadio.js +18 -3
- package/vanilla/UiSwitch.js +18 -3
- package/vue/UiButton.vue +6 -19
- package/vue/UiCheckbox.d.ts +3 -1
- package/vue/UiCheckbox.vue +24 -2
- package/vue/UiIconButton.vue +3 -13
- package/vue/UiRadio.d.ts +3 -1
- package/vue/UiRadio.vue +24 -2
- package/vue/UiSwitch.d.ts +3 -1
- package/vue/UiSwitch.vue +24 -2
- package/vue/chunks/UiButton.js +1 -1
- package/vue/chunks/UiCheckbox.js +14 -4
- package/vue/chunks/UiIconButton.js +1 -1
- package/vue/chunks/UiRadio.js +14 -4
- package/vue/chunks/UiSwitch.js +14 -4
- package/vue/components.css +150 -123
package/package.json
CHANGED
package/styles/ui-button.css
CHANGED
|
@@ -182,31 +182,19 @@
|
|
|
182
182
|
var(--ui-focus-halo);
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
/* Disabled
|
|
186
|
-
disabled outline is still an outline and a disabled ghost still has no edge.
|
|
187
|
-
|
|
188
|
-
highlight and shadow, because nothing that cannot be pressed should
|
|
185
|
+
/* Disabled keeps the shape and washes out the rest: every variant keeps its own structure, so a
|
|
186
|
+
disabled outline is still an outline and a disabled ghost still has no edge. One filter fades
|
|
187
|
+
fill, border, and text together (--ui-disabled-filter), and the theme decides which way is
|
|
188
|
+
toward the page. The highlight and shadow go, because nothing that cannot be pressed should
|
|
189
|
+
look raised. */
|
|
189
190
|
:scope:is(:disabled, [aria-disabled="true"]) {
|
|
190
|
-
|
|
191
|
-
page, which desaturates it at the same time. Toward the page rather than toward white,
|
|
192
|
-
so a dark theme dims where a light one lightens — the same rule, both schemes. */
|
|
193
|
-
--_tone: color-mix(in oklab, var(--_hue) 58%, var(--ui-surface));
|
|
194
|
-
--_tone-hover: var(--_tone);
|
|
195
|
-
--_tone-active: var(--_tone);
|
|
196
|
-
--_tone-text: color-mix(in oklab, var(--_hue-text) 72%, var(--ui-surface));
|
|
197
|
-
--_on-tone: var(--_tone-text);
|
|
198
|
-
|
|
191
|
+
filter: var(--ui-button-disabled-filter, var(--ui-disabled-filter));
|
|
199
192
|
opacity: var(--ui-button-disabled-opacity, 1);
|
|
200
193
|
cursor: not-allowed;
|
|
201
194
|
background-image: none;
|
|
202
195
|
box-shadow: none;
|
|
203
196
|
}
|
|
204
197
|
|
|
205
|
-
/* A filled button keeps its fill, faded further so its text stays legible on it. */
|
|
206
|
-
:is(:scope[data-ui-button-state~="variant=solid"], :scope[data-ui-button-state~="variant=danger"]):is(:disabled, [aria-disabled="true"]) {
|
|
207
|
-
--_tone: color-mix(in oklab, var(--_hue) 34%, var(--ui-surface));
|
|
208
|
-
}
|
|
209
|
-
|
|
210
198
|
/* Ghost has no hover to fall back on, so disabled is the one state it has to state outright:
|
|
211
199
|
it takes a surface rather than reading as plain text. The surface is a wash of the faded tone,
|
|
212
200
|
the way hover washes the live one, so it stays light in every tone. An opaque mix toward the
|
|
@@ -273,7 +261,6 @@
|
|
|
273
261
|
:scope[data-ui-button-state~="variant=link"]:is(:disabled, [aria-disabled="true"]) {
|
|
274
262
|
background: none;
|
|
275
263
|
border-color: transparent;
|
|
276
|
-
color: var(--ui-button-disabled-text, var(--ui-disabled-text));
|
|
277
264
|
}
|
|
278
265
|
|
|
279
266
|
:scope[data-ui-button-state~="variant=link"]:focus-visible {
|
|
@@ -304,12 +291,11 @@
|
|
|
304
291
|
|
|
305
292
|
/* A soft halo that transitions in with the other box-shadow changes, layered on the raised shadow. */
|
|
306
293
|
|
|
307
|
-
/* Disabled
|
|
308
|
-
disabled outline is still an outline and a disabled ghost still has no edge.
|
|
309
|
-
|
|
310
|
-
highlight and shadow, because nothing that cannot be pressed should
|
|
311
|
-
|
|
312
|
-
/* A filled button keeps its fill, faded further so its text stays legible on it. */
|
|
294
|
+
/* Disabled keeps the shape and washes out the rest: every variant keeps its own structure, so a
|
|
295
|
+
disabled outline is still an outline and a disabled ghost still has no edge. One filter fades
|
|
296
|
+
fill, border, and text together (--ui-disabled-filter), and the theme decides which way is
|
|
297
|
+
toward the page. The highlight and shadow go, because nothing that cannot be pressed should
|
|
298
|
+
look raised. */
|
|
313
299
|
|
|
314
300
|
/* Ghost has no hover to fall back on, so disabled is the one state it has to state outright:
|
|
315
301
|
it takes a surface rather than reading as plain text. The surface is a wash of the faded tone,
|
package/styles/ui-checkbox.css
CHANGED
|
@@ -9,11 +9,29 @@
|
|
|
9
9
|
cursor: pointer;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
/* The label, and under it an optional line saying what the choice means. */
|
|
13
|
+
.text {
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
gap: var(--ui-space-1);
|
|
17
|
+
min-inline-size: 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
12
20
|
.label {
|
|
13
21
|
min-inline-size: 0;
|
|
14
22
|
line-height: var(--ui-line-height-md);
|
|
15
23
|
}
|
|
16
24
|
|
|
25
|
+
.description {
|
|
26
|
+
color: var(--ui-text-secondary);
|
|
27
|
+
font-size: var(--ui-font-size-sm);
|
|
28
|
+
line-height: var(--ui-line-height);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.description:empty {
|
|
32
|
+
display: none;
|
|
33
|
+
}
|
|
34
|
+
|
|
17
35
|
input {
|
|
18
36
|
appearance: none;
|
|
19
37
|
-webkit-appearance: none;
|
|
@@ -95,7 +113,9 @@
|
|
|
95
113
|
}
|
|
96
114
|
}
|
|
97
115
|
@scope ([data-component~="ui-checkbox"]) to ([data-component]) {
|
|
98
|
-
/*
|
|
116
|
+
/* The label, and under it an optional line saying what the choice means. */
|
|
117
|
+
|
|
118
|
+
/* Centre the tick's box, then lift it: a rotated L's ink sits ~0.11rem below its box centre. */
|
|
99
119
|
|
|
100
120
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
|
101
121
|
}
|
|
@@ -161,22 +161,12 @@
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
/* Disabled colours fall back to each variant's own; ghost takes only the icon colour. */
|
|
164
|
+
/* Disabled washes the button out the way Button does: the same shape, one filter. */
|
|
164
165
|
:scope:disabled {
|
|
166
|
+
filter: var(--ui-icon-button-disabled-filter, var(--ui-disabled-filter));
|
|
165
167
|
opacity: var(--ui-icon-button-disabled-opacity, 1);
|
|
166
|
-
color: var(--ui-icon-button-disabled-text, var(--ui-disabled-text));
|
|
167
168
|
cursor: not-allowed;
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
:scope[data-ui-icon-button-state~="variant=outline"]:disabled {
|
|
171
|
-
border-color: var(--ui-icon-button-disabled-border, var(--ui-border));
|
|
172
|
-
background-color: var(--ui-icon-button-disabled-surface, var(--ui-disabled-surface));
|
|
173
|
-
color: var(--ui-icon-button-disabled-text, var(--ui-disabled-text));
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
:scope[data-ui-icon-button-state~="variant=solid"]:disabled {
|
|
177
|
-
border-color: var(--ui-icon-button-disabled-border, var(--ui-border));
|
|
178
|
-
background-color: var(--ui-icon-button-disabled-surface, var(--ui-disabled-surface));
|
|
179
|
-
color: var(--ui-icon-button-disabled-text, var(--ui-disabled-text));
|
|
169
|
+
box-shadow: none;
|
|
180
170
|
}
|
|
181
171
|
|
|
182
172
|
:scope {
|
|
@@ -212,6 +202,7 @@
|
|
|
212
202
|
}
|
|
213
203
|
|
|
214
204
|
/* Disabled colours fall back to each variant's own; ghost takes only the icon colour. */
|
|
205
|
+
/* Disabled washes the button out the way Button does: the same shape, one filter. */
|
|
215
206
|
|
|
216
207
|
:where([data-slotted], [data-slotted] *):is(svg) {
|
|
217
208
|
inline-size: var(--ui-icon-button-icon-size, var(--_icon-button-icon-default));
|
package/styles/ui-radio.css
CHANGED
|
@@ -9,11 +9,29 @@
|
|
|
9
9
|
cursor: pointer;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
/* The label, and under it an optional line saying what the choice means. */
|
|
13
|
+
.text {
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
gap: var(--ui-space-1);
|
|
17
|
+
min-inline-size: 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
12
20
|
.label {
|
|
13
21
|
min-inline-size: 0;
|
|
14
22
|
line-height: var(--ui-line-height-md);
|
|
15
23
|
}
|
|
16
24
|
|
|
25
|
+
.description {
|
|
26
|
+
color: var(--ui-text-secondary);
|
|
27
|
+
font-size: var(--ui-font-size-sm);
|
|
28
|
+
line-height: var(--ui-line-height);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.description:empty {
|
|
32
|
+
display: none;
|
|
33
|
+
}
|
|
34
|
+
|
|
17
35
|
input {
|
|
18
36
|
flex: 0 0 auto;
|
|
19
37
|
inline-size: var(--ui-radio-size, 1.125rem);
|
|
@@ -42,5 +60,7 @@
|
|
|
42
60
|
}
|
|
43
61
|
}
|
|
44
62
|
@scope ([data-component~="ui-radio"]) to ([data-component]) {
|
|
45
|
-
/*
|
|
63
|
+
/* The label, and under it an optional line saying what the choice means. */
|
|
64
|
+
|
|
65
|
+
/* A component that sets its display still honours the hidden attribute on its root. */
|
|
46
66
|
}
|
package/styles/ui-switch.css
CHANGED
|
@@ -9,11 +9,29 @@
|
|
|
9
9
|
cursor: pointer;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
/* The label, and under it an optional line saying what the choice means. */
|
|
13
|
+
.text {
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
gap: var(--ui-space-1);
|
|
17
|
+
min-inline-size: 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
12
20
|
.label {
|
|
13
21
|
min-inline-size: 0;
|
|
14
22
|
line-height: var(--ui-line-height-md);
|
|
15
23
|
}
|
|
16
24
|
|
|
25
|
+
.description {
|
|
26
|
+
color: var(--ui-text-secondary);
|
|
27
|
+
font-size: var(--ui-font-size-sm);
|
|
28
|
+
line-height: var(--ui-line-height);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.description:empty {
|
|
32
|
+
display: none;
|
|
33
|
+
}
|
|
34
|
+
|
|
17
35
|
input {
|
|
18
36
|
appearance: none;
|
|
19
37
|
-webkit-appearance: none;
|
|
@@ -81,7 +99,9 @@
|
|
|
81
99
|
}
|
|
82
100
|
}
|
|
83
101
|
@scope ([data-component~="ui-switch"]) to ([data-component]) {
|
|
84
|
-
|
|
102
|
+
/* The label, and under it an optional line saying what the choice means. */
|
|
103
|
+
|
|
104
|
+
@media (prefers-reduced-motion: reduce) {
|
|
85
105
|
}
|
|
86
106
|
|
|
87
107
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
package/theme-dark.css
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
--ui-shadow-lg: 0 10px 28px rgb(0 0 0 / 0.55), 0 4px 10px rgb(0 0 0 / 0.35);
|
|
24
24
|
--ui-control-inset: inset 0 1px 2px rgb(0 0 0 / 0.35);
|
|
25
25
|
--ui-raised: 0 1px 2px rgb(0 0 0 / 0.4), inset 0 1px 0 rgb(255 255 255 / 0.06);
|
|
26
|
+
--ui-disabled-filter: saturate(0.2) contrast(0.75) brightness(0.8);
|
|
26
27
|
--ui-raised-highlight: linear-gradient(rgb(255 255 255 / 0.04), rgb(255 255 255 / 0));
|
|
27
28
|
--ui-select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a0a09c' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
|
|
28
29
|
}
|
|
@@ -51,6 +52,7 @@
|
|
|
51
52
|
--ui-shadow-lg: 0 10px 28px rgb(0 0 0 / 0.55), 0 4px 10px rgb(0 0 0 / 0.35);
|
|
52
53
|
--ui-control-inset: inset 0 1px 2px rgb(0 0 0 / 0.35);
|
|
53
54
|
--ui-raised: 0 1px 2px rgb(0 0 0 / 0.4), inset 0 1px 0 rgb(255 255 255 / 0.06);
|
|
55
|
+
--ui-disabled-filter: saturate(0.2) contrast(0.75) brightness(0.8);
|
|
54
56
|
--ui-raised-highlight: linear-gradient(rgb(255 255 255 / 0.04), rgb(255 255 255 / 0));
|
|
55
57
|
--ui-select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a0a09c' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
|
|
56
58
|
}
|
package/theme-high-contrast.css
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
--ui-text-secondary: #111111;
|
|
25
25
|
--ui-text-muted: #222222;
|
|
26
26
|
--ui-disabled-text: #333333;
|
|
27
|
+
--ui-disabled-filter: saturate(0);
|
|
27
28
|
--ui-focus-ring: #0000ff;
|
|
28
29
|
}
|
|
29
30
|
}
|
|
@@ -52,6 +53,8 @@
|
|
|
52
53
|
--ui-text-secondary: #111111;
|
|
53
54
|
--ui-text-muted: #222222;
|
|
54
55
|
--ui-disabled-text: #333333;
|
|
56
|
+
/* Disabled loses its colour, never its contrast. */
|
|
57
|
+
--ui-disabled-filter: saturate(0);
|
|
55
58
|
--ui-focus-ring: #0000ff;
|
|
56
59
|
}
|
|
57
60
|
}
|
package/tokens.css
CHANGED
|
@@ -141,6 +141,9 @@
|
|
|
141
141
|
full opacity, so a disabled control reads as unavailable rather than as a faded variant. */
|
|
142
142
|
--ui-disabled-surface: var(--ui-surface-sunken);
|
|
143
143
|
--ui-disabled-text: var(--ui-text-muted);
|
|
144
|
+
/* A disabled button keeps its own look, washed out: less colour, less contrast, toward the page.
|
|
145
|
+
A filter rather than a second palette, so every variant and tone fades the same way. */
|
|
146
|
+
--ui-disabled-filter: saturate(0.2) contrast(0.75) brightness(1.25);
|
|
144
147
|
|
|
145
148
|
--ui-focus-ring: var(--ui-accent);
|
|
146
149
|
|
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":"label"}],"children":[{"kind":"slot"}]}]},"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},"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 = {}, as, ...componentProps } = options;
|
|
@@ -32,15 +32,30 @@ export function createUiCheckbox(options = {}) {
|
|
|
32
32
|
else element0.setAttribute("value", String(value4));
|
|
33
33
|
element.append(element0);
|
|
34
34
|
const element1 = document.createElement("span");
|
|
35
|
-
element1.setAttribute("class", "
|
|
35
|
+
element1.setAttribute("class", "text");
|
|
36
|
+
const element2 = document.createElement("span");
|
|
37
|
+
element2.setAttribute("class", "label");
|
|
36
38
|
if (children.length > 0) {
|
|
37
39
|
for (const child of children) {
|
|
38
40
|
const node = typeof child === "string" ? document.createTextNode(child) : child;
|
|
39
41
|
projected.push([node, ""]);
|
|
40
|
-
|
|
42
|
+
element2.append(node);
|
|
41
43
|
}
|
|
42
44
|
} else {
|
|
43
45
|
}
|
|
46
|
+
element1.append(element2);
|
|
47
|
+
const element3 = document.createElement("span");
|
|
48
|
+
element3.setAttribute("class", "description");
|
|
49
|
+
element3.setAttribute("aria-hidden", "true");
|
|
50
|
+
if (slots["description"] ?? [].length > 0) {
|
|
51
|
+
for (const child of slots["description"] ?? []) {
|
|
52
|
+
const node = typeof child === "string" ? document.createTextNode(child) : child;
|
|
53
|
+
projected.push([node, "description"]);
|
|
54
|
+
element3.append(node);
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
}
|
|
58
|
+
element1.append(element3);
|
|
44
59
|
element.append(element1);
|
|
45
60
|
manageComponentLifecycle(element, definition, { props: componentProps, projected,
|
|
46
61
|
controller,
|
package/vanilla/UiRadio.js
CHANGED
|
@@ -3,7 +3,7 @@ import { manageComponentLifecycle } from "@nextwebwg/html-next/runtime";
|
|
|
3
3
|
import * as controller from "../components/ui-radio/ui-radio.js";
|
|
4
4
|
import "../styles/ui-radio.css";
|
|
5
5
|
|
|
6
|
-
const definition = {...{"contract":{"tag":"ui-radio","props":{"checked":{"type":"boolean","required":false,"target":{"attribute":"checked"},"default":false},"disabled":{"type":"boolean","required":false,"target":{"attribute":"disabled"},"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":"radio"},{"kind":"property","key":"checked","name":"checked","expression":"internalChecked","expressionPlan":{"source":"internalChecked","ast":{"kind":"id","name":"internalChecked"},"dependencies":["internalChecked"]}},{"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":"value","expression":"value","expressionPlan":{"source":"value","ast":{"kind":"id","name":"value"},"dependencies":["value"]}},{"kind":"attribute","name":"name","expression":"name","expressionPlan":{"source":"name","ast":{"kind":"id","name":"name"},"dependencies":["name"]}}],"children":[],"ref":"input"},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"label"}],"children":[{"kind":"slot"}]}]},"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-radio","props":{"checked":{"type":"boolean","required":false,"target":{"attribute":"checked"},"default":false},"disabled":{"type":"boolean","required":false,"target":{"attribute":"disabled"},"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":"radio"},{"kind":"property","key":"checked","name":"checked","expression":"internalChecked","expressionPlan":{"source":"internalChecked","ast":{"kind":"id","name":"internalChecked"},"dependencies":["internalChecked"]}},{"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":"value","expression":"value","expressionPlan":{"source":"value","ast":{"kind":"id","name":"value"},"dependencies":["value"]}},{"kind":"attribute","name":"name","expression":"name","expressionPlan":{"source":"name","ast":{"kind":"id","name":"name"},"dependencies":["name"]}}],"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 createUiRadio(options = {}) {
|
|
9
9
|
const { attributes = {}, children = [], slots = {}, as, ...componentProps } = options;
|
|
@@ -30,15 +30,30 @@ export function createUiRadio(options = {}) {
|
|
|
30
30
|
else element0.setAttribute("name", String(value3));
|
|
31
31
|
element.append(element0);
|
|
32
32
|
const element1 = document.createElement("span");
|
|
33
|
-
element1.setAttribute("class", "
|
|
33
|
+
element1.setAttribute("class", "text");
|
|
34
|
+
const element2 = document.createElement("span");
|
|
35
|
+
element2.setAttribute("class", "label");
|
|
34
36
|
if (children.length > 0) {
|
|
35
37
|
for (const child of children) {
|
|
36
38
|
const node = typeof child === "string" ? document.createTextNode(child) : child;
|
|
37
39
|
projected.push([node, ""]);
|
|
38
|
-
|
|
40
|
+
element2.append(node);
|
|
39
41
|
}
|
|
40
42
|
} else {
|
|
41
43
|
}
|
|
44
|
+
element1.append(element2);
|
|
45
|
+
const element3 = document.createElement("span");
|
|
46
|
+
element3.setAttribute("class", "description");
|
|
47
|
+
element3.setAttribute("aria-hidden", "true");
|
|
48
|
+
if (slots["description"] ?? [].length > 0) {
|
|
49
|
+
for (const child of slots["description"] ?? []) {
|
|
50
|
+
const node = typeof child === "string" ? document.createTextNode(child) : child;
|
|
51
|
+
projected.push([node, "description"]);
|
|
52
|
+
element3.append(node);
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
}
|
|
56
|
+
element1.append(element3);
|
|
42
57
|
element.append(element1);
|
|
43
58
|
manageComponentLifecycle(element, definition, { props: componentProps, projected,
|
|
44
59
|
controller,
|
package/vanilla/UiSwitch.js
CHANGED
|
@@ -3,7 +3,7 @@ import { manageComponentLifecycle } from "@nextwebwg/html-next/runtime";
|
|
|
3
3
|
import * as controller from "../components/ui-switch/ui-switch.js";
|
|
4
4
|
import "../styles/ui-switch.css";
|
|
5
5
|
|
|
6
|
-
const definition = {...{"contract":{"tag":"ui-switch","props":{"checked":{"type":"boolean","required":false,"target":{"attribute":"checked"},"default":false},"disabled":{"type":"boolean","required":false,"target":{"attribute":"disabled"},"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":"literal","name":"role","value":"switch"},{"kind":"property","key":"checked","name":"checked","expression":"internalChecked","expressionPlan":{"source":"internalChecked","ast":{"kind":"id","name":"internalChecked"},"dependencies":["internalChecked"]}},{"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":"label"}],"children":[{"kind":"slot"}]}]},"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-switch","props":{"checked":{"type":"boolean","required":false,"target":{"attribute":"checked"},"default":false},"disabled":{"type":"boolean","required":false,"target":{"attribute":"disabled"},"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":"literal","name":"role","value":"switch"},{"kind":"property","key":"checked","name":"checked","expression":"internalChecked","expressionPlan":{"source":"internalChecked","ast":{"kind":"id","name":"internalChecked"},"dependencies":["internalChecked"]}},{"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 createUiSwitch(options = {}) {
|
|
9
9
|
const { attributes = {}, children = [], slots = {}, as, ...componentProps } = options;
|
|
@@ -31,15 +31,30 @@ export function createUiSwitch(options = {}) {
|
|
|
31
31
|
else element0.setAttribute("value", String(value3));
|
|
32
32
|
element.append(element0);
|
|
33
33
|
const element1 = document.createElement("span");
|
|
34
|
-
element1.setAttribute("class", "
|
|
34
|
+
element1.setAttribute("class", "text");
|
|
35
|
+
const element2 = document.createElement("span");
|
|
36
|
+
element2.setAttribute("class", "label");
|
|
35
37
|
if (children.length > 0) {
|
|
36
38
|
for (const child of children) {
|
|
37
39
|
const node = typeof child === "string" ? document.createTextNode(child) : child;
|
|
38
40
|
projected.push([node, ""]);
|
|
39
|
-
|
|
41
|
+
element2.append(node);
|
|
40
42
|
}
|
|
41
43
|
} else {
|
|
42
44
|
}
|
|
45
|
+
element1.append(element2);
|
|
46
|
+
const element3 = document.createElement("span");
|
|
47
|
+
element3.setAttribute("class", "description");
|
|
48
|
+
element3.setAttribute("aria-hidden", "true");
|
|
49
|
+
if (slots["description"] ?? [].length > 0) {
|
|
50
|
+
for (const child of slots["description"] ?? []) {
|
|
51
|
+
const node = typeof child === "string" ? document.createTextNode(child) : child;
|
|
52
|
+
projected.push([node, "description"]);
|
|
53
|
+
element3.append(node);
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
}
|
|
57
|
+
element1.append(element3);
|
|
43
58
|
element.append(element1);
|
|
44
59
|
manageComponentLifecycle(element, definition, { props: componentProps, projected,
|
|
45
60
|
controller,
|
package/vue/UiButton.vue
CHANGED
|
@@ -259,31 +259,19 @@ function attribute(value: unknown): any {
|
|
|
259
259
|
var(--ui-focus-halo);
|
|
260
260
|
}
|
|
261
261
|
|
|
262
|
-
/* Disabled
|
|
263
|
-
disabled outline is still an outline and a disabled ghost still has no edge.
|
|
264
|
-
|
|
265
|
-
highlight and shadow, because nothing that cannot be pressed should
|
|
262
|
+
/* Disabled keeps the shape and washes out the rest: every variant keeps its own structure, so a
|
|
263
|
+
disabled outline is still an outline and a disabled ghost still has no edge. One filter fades
|
|
264
|
+
fill, border, and text together (--ui-disabled-filter), and the theme decides which way is
|
|
265
|
+
toward the page. The highlight and shadow go, because nothing that cannot be pressed should
|
|
266
|
+
look raised. */
|
|
266
267
|
[data-component~="ui-button"]:is(:disabled, [aria-disabled="true"]) {
|
|
267
|
-
|
|
268
|
-
page, which desaturates it at the same time. Toward the page rather than toward white,
|
|
269
|
-
so a dark theme dims where a light one lightens — the same rule, both schemes. */
|
|
270
|
-
--_tone: color-mix(in oklab, var(--_hue) 58%, var(--ui-surface));
|
|
271
|
-
--_tone-hover: var(--_tone);
|
|
272
|
-
--_tone-active: var(--_tone);
|
|
273
|
-
--_tone-text: color-mix(in oklab, var(--_hue-text) 72%, var(--ui-surface));
|
|
274
|
-
--_on-tone: var(--_tone-text);
|
|
275
|
-
|
|
268
|
+
filter: var(--ui-button-disabled-filter, var(--ui-disabled-filter));
|
|
276
269
|
opacity: var(--ui-button-disabled-opacity, 1);
|
|
277
270
|
cursor: not-allowed;
|
|
278
271
|
background-image: none;
|
|
279
272
|
box-shadow: none;
|
|
280
273
|
}
|
|
281
274
|
|
|
282
|
-
/* A filled button keeps its fill, faded further so its text stays legible on it. */
|
|
283
|
-
:is([data-component~="ui-button"][data-ui-button-state~="variant=solid"], [data-component~="ui-button"][data-ui-button-state~="variant=danger"]):is(:disabled, [aria-disabled="true"]) {
|
|
284
|
-
--_tone: color-mix(in oklab, var(--_hue) 34%, var(--ui-surface));
|
|
285
|
-
}
|
|
286
|
-
|
|
287
275
|
/* Ghost has no hover to fall back on, so disabled is the one state it has to state outright:
|
|
288
276
|
it takes a surface rather than reading as plain text. The surface is a wash of the faded tone,
|
|
289
277
|
the way hover washes the live one, so it stays light in every tone. An opaque mix toward the
|
|
@@ -354,7 +342,6 @@ html[data-ui-input-modality="touch"]
|
|
|
354
342
|
[data-component~="ui-button"][data-ui-button-state~="variant=link"]:is(:disabled, [aria-disabled="true"]) {
|
|
355
343
|
background: none;
|
|
356
344
|
border-color: transparent;
|
|
357
|
-
color: var(--ui-button-disabled-text, var(--ui-disabled-text));
|
|
358
345
|
}
|
|
359
346
|
|
|
360
347
|
[data-component~="ui-button"][data-ui-button-state~="variant=link"]:focus-visible {
|
package/vue/UiCheckbox.d.ts
CHANGED
|
@@ -6,9 +6,11 @@ type __VLS_Props = {
|
|
|
6
6
|
required?: boolean;
|
|
7
7
|
value?: string;
|
|
8
8
|
};
|
|
9
|
-
declare var __VLS_1: {};
|
|
9
|
+
declare var __VLS_1: {}, __VLS_3: {};
|
|
10
10
|
type __VLS_Slots = {} & {
|
|
11
11
|
default?: (props: typeof __VLS_1) => any;
|
|
12
|
+
} & {
|
|
13
|
+
description?: (props: typeof __VLS_3) => any;
|
|
12
14
|
};
|
|
13
15
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
14
16
|
change: (detail: {
|
package/vue/UiCheckbox.vue
CHANGED
|
@@ -38,6 +38,7 @@ const emit = defineEmits<{
|
|
|
38
38
|
|
|
39
39
|
const root = ref<HTMLElement | null>(null)
|
|
40
40
|
const inputElement = useTemplateRef<HTMLElement>('input')
|
|
41
|
+
const descriptionElement = useTemplateRef<HTMLElement>('description')
|
|
41
42
|
const internalChecked = ref(false)
|
|
42
43
|
|
|
43
44
|
/** The values the styles' :host-state() rules test. */
|
|
@@ -66,7 +67,7 @@ useComponentHost(controllerModule.default, {
|
|
|
66
67
|
root,
|
|
67
68
|
dispatch,
|
|
68
69
|
props,
|
|
69
|
-
refs: { input: inputElement },
|
|
70
|
+
refs: { input: inputElement, description: descriptionElement },
|
|
70
71
|
state: { internalChecked },
|
|
71
72
|
})
|
|
72
73
|
</script>
|
|
@@ -87,7 +88,10 @@ useComponentHost(controllerModule.default, {
|
|
|
87
88
|
:value="value"
|
|
88
89
|
ref="input"
|
|
89
90
|
>
|
|
90
|
-
<span class="label"><slot /></span
|
|
91
|
+
<span class="text"><span class="label"><slot /></span>
|
|
92
|
+
<span class="description" aria-hidden="true" ref="description"><slot
|
|
93
|
+
name="description"
|
|
94
|
+
/></span></span></label>
|
|
91
95
|
</template>
|
|
92
96
|
|
|
93
97
|
<style scoped>
|
|
@@ -100,11 +104,29 @@ useComponentHost(controllerModule.default, {
|
|
|
100
104
|
cursor: pointer;
|
|
101
105
|
}
|
|
102
106
|
|
|
107
|
+
/* The label, and under it an optional line saying what the choice means. */
|
|
108
|
+
.text {
|
|
109
|
+
display: flex;
|
|
110
|
+
flex-direction: column;
|
|
111
|
+
gap: var(--ui-space-1);
|
|
112
|
+
min-inline-size: 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
103
115
|
.label {
|
|
104
116
|
min-inline-size: 0;
|
|
105
117
|
line-height: var(--ui-line-height-md);
|
|
106
118
|
}
|
|
107
119
|
|
|
120
|
+
.description {
|
|
121
|
+
color: var(--ui-text-secondary);
|
|
122
|
+
font-size: var(--ui-font-size-sm);
|
|
123
|
+
line-height: var(--ui-line-height);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.description:empty {
|
|
127
|
+
display: none;
|
|
128
|
+
}
|
|
129
|
+
|
|
108
130
|
input {
|
|
109
131
|
appearance: none;
|
|
110
132
|
-webkit-appearance: none;
|
package/vue/UiIconButton.vue
CHANGED
|
@@ -221,22 +221,12 @@ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"]::after {
|
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
/* Disabled colours fall back to each variant's own; ghost takes only the icon colour. */
|
|
224
|
+
/* Disabled washes the button out the way Button does: the same shape, one filter. */
|
|
224
225
|
[data-component~="ui-icon-button"]:disabled {
|
|
226
|
+
filter: var(--ui-icon-button-disabled-filter, var(--ui-disabled-filter));
|
|
225
227
|
opacity: var(--ui-icon-button-disabled-opacity, 1);
|
|
226
|
-
color: var(--ui-icon-button-disabled-text, var(--ui-disabled-text));
|
|
227
228
|
cursor: not-allowed;
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
[data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"]:disabled {
|
|
231
|
-
border-color: var(--ui-icon-button-disabled-border, var(--ui-border));
|
|
232
|
-
background-color: var(--ui-icon-button-disabled-surface, var(--ui-disabled-surface));
|
|
233
|
-
color: var(--ui-icon-button-disabled-text, var(--ui-disabled-text));
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
[data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"]:disabled {
|
|
237
|
-
border-color: var(--ui-icon-button-disabled-border, var(--ui-border));
|
|
238
|
-
background-color: var(--ui-icon-button-disabled-surface, var(--ui-disabled-surface));
|
|
239
|
-
color: var(--ui-icon-button-disabled-text, var(--ui-disabled-text));
|
|
229
|
+
box-shadow: none;
|
|
240
230
|
}
|
|
241
231
|
|
|
242
232
|
[data-component~="ui-icon-button"] {
|
package/vue/UiRadio.d.ts
CHANGED
|
@@ -5,9 +5,11 @@ type __VLS_Props = {
|
|
|
5
5
|
required?: boolean;
|
|
6
6
|
value?: string;
|
|
7
7
|
};
|
|
8
|
-
declare var __VLS_1: {};
|
|
8
|
+
declare var __VLS_1: {}, __VLS_3: {};
|
|
9
9
|
type __VLS_Slots = {} & {
|
|
10
10
|
default?: (props: typeof __VLS_1) => any;
|
|
11
|
+
} & {
|
|
12
|
+
description?: (props: typeof __VLS_3) => any;
|
|
11
13
|
};
|
|
12
14
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
13
15
|
change: (detail: {
|