@threadlabs/looma 0.39.1 → 0.39.3

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.
Files changed (50) hide show
  1. package/components/ui-button/ui-button.html +24 -3
  2. package/components/ui-checkbox/ui-checkbox.html +34 -18
  3. package/components/ui-combobox/ui-combobox.html +8 -3
  4. package/components/ui-combobox/ui-combobox.js +3 -2
  5. package/components/ui-dialog/ui-dialog.html +6 -52
  6. package/components/ui-input/ui-input.html +21 -3
  7. package/components/ui-input-group/ui-input-group.html +1 -0
  8. package/components/ui-light-editor/ui-light-editor.html +26 -25
  9. package/components/ui-select/ui-select.html +10 -3
  10. package/dist/index.js +1 -1
  11. package/docs/README.md +18 -7
  12. package/docs/catalog.json +2 -26
  13. package/docs/customizer-render.mjs +37 -33
  14. package/docs/customizer.js +82 -47
  15. package/docs/site.mjs +10 -6
  16. package/docs/theme-session.mjs +7 -8
  17. package/docs/theme.mjs +10 -22
  18. package/package.json +1 -1
  19. package/styles/ui-button.css +24 -1
  20. package/styles/ui-checkbox.css +39 -19
  21. package/styles/ui-combobox.css +16 -6
  22. package/styles/ui-dialog.css +6 -107
  23. package/styles/ui-input-group.css +1 -0
  24. package/styles/ui-input.css +24 -3
  25. package/styles/ui-light-editor.css +111 -0
  26. package/styles/ui-select.css +10 -3
  27. package/theme-system.css +4 -1
  28. package/tokens.css +9 -2
  29. package/vanilla/UiButton.js +14 -12
  30. package/vanilla/UiDialog.js +2 -2
  31. package/vanilla/UiLightEditor.js +2 -2
  32. package/vue/UiButton.vue +28 -7
  33. package/vue/UiCheckbox.vue +34 -19
  34. package/vue/UiCombobox.vue +22 -6
  35. package/vue/UiDialog.d.ts +3 -3
  36. package/vue/UiDialog.vue +18 -111
  37. package/vue/UiInput.vue +30 -3
  38. package/vue/UiInputGroup.vue +1 -0
  39. package/vue/UiLightEditor.vue +156 -40
  40. package/vue/UiSelect.vue +16 -3
  41. package/vue/chunks/UiButton.js +18 -10
  42. package/vue/chunks/UiCheckbox.js +1 -1
  43. package/vue/chunks/UiCombobox.js +1 -1
  44. package/vue/chunks/UiDialog.js +22 -14
  45. package/vue/chunks/UiInput.js +1 -1
  46. package/vue/chunks/UiInputGroup.js +1 -1
  47. package/vue/chunks/UiLightEditor.js +66 -58
  48. package/vue/chunks/UiSelect.js +1 -1
  49. package/vue/components.css +337 -160
  50. package/vue/editor/index.js +46 -36
@@ -121,3 +121,114 @@
121
121
  @media (forced-colors: active) {
122
122
  }
123
123
  }
124
+ @scope ([data-slotted~="ui-light-editor"]:not([data-component])) to ([data-component], [data-slotted]) {
125
+ :where([data-component~="ui-light-editor"]):where(:scope, :not([data-component], [data-slotted]:not([data-slotted~="ui-light-editor"]))) {
126
+ display: grid !important;
127
+ gap: var(--ui-space-3) !important;
128
+ min-inline-size: 0;
129
+ padding: 0 !important;
130
+ margin: 0 !important;
131
+ }
132
+ .stage:where(:scope, :scope *) {
133
+ box-sizing: border-box !important;
134
+ display: block !important;
135
+ block-size: 13rem;
136
+ padding: calc(var(--ui-control-min-block-size) / 2) !important;
137
+ border: var(--ui-border-width) solid var(--ui-control-border);
138
+ border-radius: var(--ui-field-radius, var(--ui-radius-md));
139
+ background: var(--ui-neutral-surface, var(--ui-surface));
140
+ }
141
+ .plane:where(:scope, :scope *) {
142
+ position: relative;
143
+ display: block !important;
144
+ inline-size: 100%;
145
+ block-size: 100%;
146
+ }
147
+ svg:where(:scope, :scope *) {
148
+ inline-size: 100%;
149
+ block-size: 100%;
150
+ overflow: visible;
151
+ }
152
+ path:where(:scope, :scope *) {
153
+ fill: none;
154
+ stroke: var(--ui-border);
155
+ stroke-width: 1;
156
+ vector-effect: non-scaling-stroke;
157
+ }
158
+ .specimen:where(:scope, :scope *) {
159
+ position: absolute;
160
+ inset: 0;
161
+ display: grid !important;
162
+ place-items: center !important;
163
+ }
164
+ .source:where(:scope, :scope *) {
165
+ position: absolute;
166
+ left: 50%;
167
+ top: 0;
168
+ translate: -50% -50%;
169
+ display: grid !important;
170
+ place-items: center !important;
171
+ inline-size: max(2rem, var(--ui-control-min-block-size));
172
+ block-size: max(2rem, var(--ui-control-min-block-size));
173
+ padding: 0 !important;
174
+ margin: 0 !important;
175
+ border: 0;
176
+ border-radius: 50%;
177
+ background: transparent;
178
+ cursor: grab;
179
+ touch-action: none;
180
+ }
181
+ .source-glyph:where(:scope, :scope *) {
182
+ position: relative;
183
+ z-index: 1;
184
+ display: inline-flex !important;
185
+ color: var(--ui-accent);
186
+ font-size: var(--ui-font-size-lg);
187
+ }
188
+ .source:where(:not([data-component], [data-slotted]:not([data-slotted~="ui-light-editor"]))):where(:scope, :scope *)::after {
189
+ content: "";
190
+ position: absolute;
191
+ inline-size: 2rem;
192
+ block-size: 2rem;
193
+ border: var(--ui-border-width) solid var(--ui-accent);
194
+ border-radius: 50%;
195
+ background: var(--ui-surface-raised);
196
+ box-shadow: 0 0 0 var(--ui-space-2) color-mix(in srgb, var(--ui-accent) 12%, transparent), var(--ui-shadow-sm);
197
+ }
198
+ .source:active:where(:scope, :scope *) {
199
+ cursor: grabbing;
200
+ }
201
+ .source:focus-visible:where(:scope, :scope *) {
202
+ outline: var(--ui-focus-width) solid var(--ui-focus-ring);
203
+ outline-offset: var(--ui-space-1);
204
+ }
205
+ .source:disabled:where(:scope, :scope *) {
206
+ cursor: not-allowed;
207
+ }
208
+ .source:disabled:where(:not([data-component], [data-slotted]:not([data-slotted~="ui-light-editor"]))):where(:scope, :scope *)::after {
209
+ background: var(--ui-disabled-surface);
210
+ border-color: var(--ui-disabled-border);
211
+ box-shadow: none;
212
+ }
213
+ .coordinates:where(:scope, :scope *) {
214
+ display: grid !important;
215
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
216
+ gap: var(--ui-space-2) !important;
217
+ }
218
+ .hint:where(:scope, :scope *) {
219
+ font-size: var(--ui-font-size-sm);
220
+ color: var(--ui-text-secondary);
221
+ }
222
+ @media (forced-colors: active) {
223
+ .source-glyph:where(:scope, :scope *) {
224
+ color: CanvasText;
225
+ }
226
+ .source:where(:not([data-component], [data-slotted]:not([data-slotted~="ui-light-editor"]))):where(:scope, :scope *)::after {
227
+ background: Canvas;
228
+ border-color: CanvasText;
229
+ }
230
+ .source:focus-visible:where(:scope, :scope *) {
231
+ outline-color: Highlight;
232
+ }
233
+ }
234
+ }
@@ -50,13 +50,16 @@
50
50
  }
51
51
 
52
52
  :scope:where([data-component~="ui-select"]) {
53
+ --_ui-select-size: var(--ui-control-size-md);
54
+ --_ui-select-inset-block: var(--ui-control-inset-block-md, var(--ui-space-2));
53
55
  box-sizing: border-box !important;
54
56
  display: inline-block !important;
55
57
  inline-size: var(--ui-select-inline-size, 100%);
56
58
  min-inline-size: 0;
59
+ max-block-size: max(var(--_ui-select-size), calc(1em * var(--ui-line-height-tight) + 2 * var(--_ui-select-inset-block) + 2 * var(--ui-border-width)));
57
60
  min-block-size: var(--ui-control-size-md);
58
61
  margin: 0 !important;
59
- padding: var(--ui-control-inset-block-md, var(--ui-space-2)) var(--ui-space-3) !important;
62
+ padding: var(--_ui-select-inset-block) var(--ui-space-3) !important;
60
63
  border: var(--ui-border-width) solid var(--ui-select-border, var(--ui-control-border, var(--ui-border-strong)));
61
64
  border-radius: var(--ui-select-radius, var(--ui-field-radius, var(--ui-radius-md)));
62
65
  background-color: var(--ui-select-surface, var(--ui-control-surface, var(--ui-surface-elevated)));
@@ -129,8 +132,10 @@
129
132
  }
130
133
 
131
134
  :scope:where([data-component~="ui-select"])[data-ui-select-state~="size=sm"] {
135
+ --_ui-select-size: var(--ui-control-size-sm);
136
+ --_ui-select-inset-block: var(--ui-control-inset-block-sm, var(--ui-space-1));
132
137
  min-block-size: var(--ui-control-size-sm);
133
- padding: var(--ui-control-inset-block-sm, var(--ui-space-1)) var(--ui-space-2) !important;
138
+ padding: var(--_ui-select-inset-block) var(--ui-space-2) !important;
134
139
  padding-inline-end: calc(var(--ui-space-2) + var(--ui-icon-size-sm) + var(--ui-space-1)) !important;
135
140
  background-position: right var(--ui-space-2) center, center;
136
141
  background-size:
@@ -140,8 +145,10 @@
140
145
  }
141
146
 
142
147
  :scope:where([data-component~="ui-select"])[data-ui-select-state~="size=lg"] {
148
+ --_ui-select-size: var(--ui-control-size-lg);
149
+ --_ui-select-inset-block: var(--ui-control-inset-block-lg, var(--ui-space-3));
143
150
  min-block-size: var(--ui-control-size-lg);
144
- padding: var(--ui-control-inset-block-lg, var(--ui-space-3)) var(--ui-space-4) !important;
151
+ padding: var(--_ui-select-inset-block) var(--ui-space-4) !important;
145
152
  padding-inline-end: calc(var(--ui-space-4) + 1.5rem) !important;
146
153
  background-position: right var(--ui-space-4) center, center;
147
154
  font-size: var(--ui-font-size-md);
package/theme-system.css CHANGED
@@ -8,11 +8,14 @@
8
8
  /* Keep the root font seed unregistered: a registered rem length used by root
9
9
  font-size creates a dependency cycle (CSS Properties and Values API 2.7.2). */
10
10
  @property --ui-control-size { syntax: "<length>"; inherits: true; initial-value: 40px; }
11
+ @property --_ui-root-font-unit { syntax: "<length>"; inherits: true; initial-value: 16px; }
11
12
  @property --ui-radius-md { syntax: "<length>"; inherits: true; initial-value: 8px; }
12
13
  @property --ui-border-width { syntax: "<length>"; inherits: true; initial-value: 1px; }
13
14
 
14
15
  @layer theme {
15
16
  :root {
17
+ /* Resolve once on the root: WebKit can resolve registered rem lengths against the initial font size. */
18
+ --_ui-root-font-unit: 1em;
16
19
  --ui-spacing: 1;
17
20
  --ui-rhythm: 1;
18
21
  --ui-control-roominess: 2.5;
@@ -35,7 +38,7 @@
35
38
  :where(:root, [data-theme], [data-contrast]) {
36
39
  /* Controls use a ratio. Spacing uses an independent curve, so increasing the size
37
40
  contrast cannot unexpectedly turn linear spacing into quadratic spacing. */
38
- --ui-control-size: calc(1rem * var(--ui-control-roominess));
41
+ --ui-control-size: calc(var(--_ui-root-font-unit) * var(--ui-control-roominess));
39
42
  --_ui-theme-ratio: max(1, var(--ui-scale-ratio));
40
43
  --_ui-theme-unit: calc(1rem * 0.25 * max(0, var(--ui-spacing)) * clamp(0.75, var(--ui-rhythm), 1.5));
41
44
  --ui-line-height-tight: clamp(1.1, calc(1.2 + (var(--ui-rhythm) - 1) * 0.2), 1.3);
package/tokens.css CHANGED
@@ -353,9 +353,12 @@
353
353
  }
354
354
 
355
355
  [data-ui-choice-option]:is(:hover, .active) {
356
- background: var(--ui-surface-muted);
356
+ background: var(--ui-accent-subtle);
357
+ }
358
+
359
+ [data-ui-choice-option]:focus-visible {
357
360
  outline: var(--ui-focus-width) solid var(--ui-focus-ring);
358
- outline-offset: calc(-1 * var(--ui-border-width));
361
+ outline-offset: calc(-1 * var(--ui-focus-width));
359
362
  }
360
363
 
361
364
  [data-ui-choice-option][aria-disabled="true"],
@@ -403,6 +406,10 @@
403
406
  }
404
407
 
405
408
  @media (forced-colors: active) {
409
+ [data-ui-choice-option].active {
410
+ outline: var(--ui-focus-width) solid Highlight;
411
+ outline-offset: calc(-1 * var(--ui-focus-width));
412
+ }
406
413
  [data-ui-choice-option][aria-selected="true"]:not([aria-disabled="true"]):not(.active) {
407
414
  outline: var(--ui-focus-width) solid Highlight;
408
415
  outline-offset: calc(-1 * var(--ui-border-width));
@@ -15,11 +15,11 @@ const T8 = ["",[],4];
15
15
  const T9 = ["",[]];
16
16
  const T10 = ["",[]];
17
17
  const T11 = ["",[],["ui-icon",["name","chevron-right","aria-hidden","true"]]];
18
- const T12 = ["",[],"\n ",1,"\n ",4,"\n ",["span",["class","badge"],4],"\n "];
18
+ const T12 = ["",[],"\n ",1,"\n ",["span",["class","label"],4],"\n ",["span",["class","badge"],4],"\n "];
19
19
  const T13 = ["span",["class","spinner-wrap"],["ui-spinner",["size","sm"]]];
20
20
  const T14 = ["",[]];
21
21
  const T15 = ["",[]];
22
- const T16 = ["",[],"\n ",1,"\n ",4,"\n ",["span",["class","badge"],4],"\n "];
22
+ const T16 = ["",[],"\n ",1,"\n ",["span",["class","label"],4],"\n ",["span",["class","badge"],4],"\n "];
23
23
  const T17 = ["span",["class","spinner-wrap"],["ui-spinner",["size","sm"]]];
24
24
  const T18 = ["",[]];
25
25
  const T19 = ["",[]];
@@ -373,8 +373,9 @@ export function createUiButton(options = {}, html) {
373
373
  n.append((P12 ??= buildTemplate(T12)).cloneNode(true));
374
374
  const t0 = n.firstChild.nextSibling;
375
375
  const t1 = t0.nextSibling.nextSibling.nextSibling;
376
- const t2 = t1.nextSibling.nextSibling.nextSibling.firstChild;
377
- const r = { n, v0: undefined, v1: undefined, v2: undefined, v3: undefined, v4: undefined, v5: undefined, v6: undefined, v7: undefined, v8: undefined, a1: t0, e0: t0.nextSibling, b0: undefined, a2: t1, e1: t1.nextSibling, b1: undefined, f1: undefined, a3: t2, e2: t2.nextSibling, b2: undefined, f2: undefined };
376
+ const t2 = t1.firstChild;
377
+ const t3 = t1.nextSibling.nextSibling.firstChild;
378
+ const r = { n, v0: undefined, v1: undefined, v2: undefined, v3: undefined, v4: undefined, v5: undefined, v6: undefined, v7: undefined, v8: undefined, a1: t0, e0: t0.nextSibling, b0: undefined, a2: t2, e1: t2.nextSibling, b1: undefined, f1: undefined, a3: t3, e2: t3.nextSibling, b2: undefined, f2: undefined };
378
379
  p12(r, -1, d);
379
380
  return r;
380
381
  };
@@ -436,19 +437,20 @@ export function createUiButton(options = {}, html) {
436
437
  if (r.b0) { r.b0 = undefined; clearRegion(r.a1, r.e0); }
437
438
  else { r.b0 = m13(d); r.e0.before(r.b0.n); }
438
439
  } else if (r.b0 !== undefined) p13(r.b0, c, d);
439
- if (r.f2 === undefined) { r.f2 = 1; const at = fillSlot(r.a3, r.e2, "badge", J, false, undefined, d);
440
- if (Array.isArray(at)) (r.z ??= []).push(() => { at[0].l.delete(at[1]); dispose(at[1]); }); else if (at !== undefined) { r.b2 = m15(d); at.before(r.b2.n); } }
441
- else if (r.b2 !== undefined) p15(r.b2, c, d);
442
440
  if (r.f1 === undefined) { r.f1 = 1; const at = fillSlot(r.a2, r.e1, "", J, false, undefined, d);
443
441
  if (Array.isArray(at)) (r.z ??= []).push(() => { at[0].l.delete(at[1]); dispose(at[1]); }); else if (at !== undefined) { r.b1 = m14(d); at.before(r.b1.n); } }
444
442
  else if (r.b1 !== undefined) p14(r.b1, c, d);
443
+ if (r.f2 === undefined) { r.f2 = 1; const at = fillSlot(r.a3, r.e2, "badge", J, false, undefined, d);
444
+ if (Array.isArray(at)) (r.z ??= []).push(() => { at[0].l.delete(at[1]); dispose(at[1]); }); else if (at !== undefined) { r.b2 = m15(d); at.before(r.b2.n); } }
445
+ else if (r.b2 !== undefined) p15(r.b2, c, d);
445
446
  };
446
447
  const m16 = (n, d) => {
447
448
  n.append((P16 ??= buildTemplate(T16)).cloneNode(true));
448
449
  const t0 = n.firstChild.nextSibling;
449
450
  const t1 = t0.nextSibling.nextSibling.nextSibling;
450
- const t2 = t1.nextSibling.nextSibling.nextSibling.firstChild;
451
- const r = { n, v0: undefined, v1: undefined, v2: undefined, v3: undefined, v4: undefined, v5: undefined, v6: undefined, a1: t0, e0: t0.nextSibling, b0: undefined, a2: t1, e1: t1.nextSibling, b1: undefined, f1: undefined, a3: t2, e2: t2.nextSibling, b2: undefined, f2: undefined };
451
+ const t2 = t1.firstChild;
452
+ const t3 = t1.nextSibling.nextSibling.firstChild;
453
+ const r = { n, v0: undefined, v1: undefined, v2: undefined, v3: undefined, v4: undefined, v5: undefined, v6: undefined, a1: t0, e0: t0.nextSibling, b0: undefined, a2: t2, e1: t2.nextSibling, b1: undefined, f1: undefined, a3: t3, e2: t3.nextSibling, b2: undefined, f2: undefined };
452
454
  p16(r, -1, d);
453
455
  return r;
454
456
  };
@@ -496,12 +498,12 @@ export function createUiButton(options = {}, html) {
496
498
  if (r.b0) { r.b0 = undefined; clearRegion(r.a1, r.e0); }
497
499
  else { r.b0 = m17(d); r.e0.before(r.b0.n); }
498
500
  } else if (r.b0 !== undefined) p17(r.b0, c, d);
499
- if (r.f2 === undefined) { r.f2 = 1; const at = fillSlot(r.a3, r.e2, "badge", J, false, undefined, d);
500
- if (Array.isArray(at)) (r.z ??= []).push(() => { at[0].l.delete(at[1]); dispose(at[1]); }); else if (at !== undefined) { r.b2 = m19(d); at.before(r.b2.n); } }
501
- else if (r.b2 !== undefined) p19(r.b2, c, d);
502
501
  if (r.f1 === undefined) { r.f1 = 1; const at = fillSlot(r.a2, r.e1, "", J, false, undefined, d);
503
502
  if (Array.isArray(at)) (r.z ??= []).push(() => { at[0].l.delete(at[1]); dispose(at[1]); }); else if (at !== undefined) { r.b1 = m18(d); at.before(r.b1.n); } }
504
503
  else if (r.b1 !== undefined) p18(r.b1, c, d);
504
+ if (r.f2 === undefined) { r.f2 = 1; const at = fillSlot(r.a3, r.e2, "badge", J, false, undefined, d);
505
+ if (Array.isArray(at)) (r.z ??= []).push(() => { at[0].l.delete(at[1]); dispose(at[1]); }); else if (at !== undefined) { r.b2 = m19(d); at.before(r.b2.n); } }
506
+ else if (r.b2 !== undefined) p19(r.b2, c, d);
505
507
  };
506
508
  const M = [m0, m6, m12, m16], N = [p0, p6, p12, p16];
507
509
  let R;
@@ -3,7 +3,7 @@ import { attachGeneratedController, buildTemplate, clearRegion, toAttribute, toT
3
3
  import * as controller from "../components/ui-dialog/ui-dialog.js";
4
4
  import "../styles/ui-dialog.css";
5
5
 
6
- const T0 = ["",[],"\n ",["header",[],"\n ",1,"\n ",["button",["class","close","type","button","aria-label","Close"]],"\n "],"\n ",["div",["class","body"],["ui-scroll-area",[],4]],"\n ",["footer",[],4],"\n "];
6
+ const T0 = ["",[],"\n ",["header",[],"\n ",1,"\n ",["div",["class","close"],["ui-icon-button",["size","sm","round","","label","Close"],["ui-icon",["name","x"]]]],"\n "],"\n ",["div",["class","body"],["ui-scroll-area",[],4]],"\n ",["footer",[],4],"\n "];
7
7
  const T1 = ["h2",["class","title"],0];
8
8
  const T2 = ["",[]];
9
9
  const T3 = ["",[]];
@@ -82,7 +82,7 @@ export function createUiDialog(options = {}, html) {
82
82
  };
83
83
  const t0 = element.firstChild.nextSibling;
84
84
  const t1 = t0.firstChild.nextSibling;
85
- const t2 = t1.nextSibling.nextSibling.nextSibling;
85
+ const t2 = t1.nextSibling.nextSibling.nextSibling.firstChild;
86
86
  const t3 = t0.nextSibling.nextSibling;
87
87
  const t4 = t3.firstChild;
88
88
  const t5 = t4.firstChild;
@@ -3,7 +3,7 @@ import { attachGeneratedController, buildTemplate, NONCONFORMING, textCall, toAt
3
3
  import * as controller from "../components/ui-light-editor/ui-light-editor.js";
4
4
  import "../styles/ui-light-editor.css";
5
5
 
6
- const T0 = ["",[],"\n ",["span",["class","stage","role","group"],"\n ",["span",["class","plane"],"\n ",["svg",["viewBox","0 0 100 60","preserveAspectRatio","none","aria-hidden","true"],["path",["d","M0 30 H100 M50 0 V60"]]],"\n ",["span",["class","specimen"],4],"\n ",["button",["type","button","class","source"],"\n ",["span",["class","source-glyph"],["ui-icon",["name","lightbulb"]]],"\n "],"\n "],"\n "],"\n ",["span",["class","coordinates"],"\n ",["ui-number-input",["data-coordinate","x","min","0","max","100","step","1","unit","%","label","Light horizontal position"]],"\n ",["ui-number-input",["data-coordinate","y","min","0","max","100","step","1","unit","%","label","Light vertical position"]],"\n "],"\n ",["span",["class","hint"],"Drag the light, tap the background, use arrow keys, or enter its position. Escape cancels a drag. Top centre is 50%, 0%."],"\n "];
6
+ const T0 = ["",[],"\n ",["span",["class","stage","role","group"],"\n ",["span",["class","plane"],"\n ",["svg",["viewBox","0 0 100 60","preserveAspectRatio","none","aria-hidden","true"],["path",["d","M0 30 H100 M50 0 V60"]]],"\n ",["span",["class","specimen"],4],"\n ",["button",["type","button","class","source"],"\n ",["span",["class","source-glyph"],["ui-icon",["name","lightbulb"]]],"\n "],"\n "],"\n "],"\n ",["span",["class","hint"],"Drag or tap to move the light. Arrow keys adjust; Escape cancels."],"\n ",["ui-disclosure",["summary","Exact position"],["span",["class","coordinates","data-slotted","ui-light-editor"],"\n ",["ui-number-input",["data-coordinate","x","min","0","max","100","step","1","unit","%","label","Light horizontal position"]],"\n ",["ui-number-input",["data-coordinate","y","min","0","max","100","step","1","unit","%","label","Light vertical position"]],"\n "]],"\n "];
7
7
  const T1 = ["",[]];
8
8
  let P0, P1;
9
9
  const S = { n: ["horizontal","vertical"], t: ["s","s"], f: import.meta.url, g: "ui-light-editor", d: { "input": [detailCheck(checkObject([["x", checkNumber, false], ["y", checkNumber, false]], false)), true, true, false], "change": [detailCheck(checkObject([["x", checkNumber, false], ["y", checkNumber, false]], false)), true, true, false], "cancel": [detailCheck(checkObject([["x", checkNumber, false], ["y", checkNumber, false]], false)), true, true, false] }, x: dispatchDeclared, a: (host, I) => C(host, I), b: generatedInputs, i: ["50", "0"] };
@@ -86,7 +86,7 @@ export function createUiLightEditor(options = {}, html) {
86
86
  const t2 = t1.firstChild.nextSibling.nextSibling.nextSibling;
87
87
  const t3 = t2.firstChild;
88
88
  const t4 = t2.nextSibling.nextSibling;
89
- const t5 = t0.nextSibling.nextSibling;
89
+ const t5 = t0.nextSibling.nextSibling.nextSibling.nextSibling.firstChild;
90
90
  const t6 = t5.firstChild.nextSibling;
91
91
  const t7 = t6.nextSibling.nextSibling;
92
92
  const R = { a0: t0, a3: t4, a4: t6, a5: t7, v0: null, v1: null, v2: null, v3: null, v4: null, v5: null, v6: null, v7: null, v8: null, a2: t3, e0: t3.nextSibling, b0: undefined, f0: undefined };
package/vue/UiButton.vue CHANGED
@@ -904,10 +904,10 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
904
904
  v-if="checkedProps.loading || checkedProps.pending"
905
905
  class="spinner-wrap"
906
906
  data-hn-ui-button
907
- ><UiSpinner class="ui-spinner" size="sm" /></span>{{ ' ' }}<slot />{{ ' ' }}<span
908
- class="badge"
907
+ ><UiSpinner class="ui-spinner" size="sm" /></span>{{ ' ' }}<span
908
+ class="label"
909
909
  data-hn-ui-button
910
- ><slot name="badge" /></span></a>
910
+ ><slot /></span>{{ ' ' }}<span class="badge" data-hn-ui-button><slot name="badge" /></span></a>
911
911
  <button
912
912
  v-else
913
913
  class="ui-button"
@@ -944,10 +944,10 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
944
944
  v-if="checkedProps.loading || checkedProps.pending"
945
945
  class="spinner-wrap"
946
946
  data-hn-ui-button
947
- ><UiSpinner class="ui-spinner" size="sm" /></span>{{ ' ' }}<slot />{{ ' ' }}<span
948
- class="badge"
947
+ ><UiSpinner class="ui-spinner" size="sm" /></span>{{ ' ' }}<span
948
+ class="label"
949
949
  data-hn-ui-button
950
- ><slot name="badge" /></span>
950
+ ><slot /></span>{{ ' ' }}<span class="badge" data-hn-ui-button><slot name="badge" /></span>
951
951
  </button>
952
952
  </template>
953
953
 
@@ -1031,6 +1031,8 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1031
1031
  /* A count is an adornment, not another line of label text. Keep the standard control height
1032
1032
  with enough inset for a 24px mark; large content can still grow the button naturally. */
1033
1033
 
1034
+ /* Trim the text line itself: an anonymous flex item retains font-metric space in some fonts. */
1035
+
1034
1036
  /* Short numeric and icon actions share a minimum box; large values remain readable. */
1035
1037
 
1036
1038
  /* Card actions inherit Button's palette and behavior; only their shared layout changes.
@@ -1125,6 +1127,7 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1125
1127
 
1126
1128
  :global(:scope:where([data-hn-ui-button])) {
1127
1129
  --_button-square-size: var(--ui-button-min-block-size, var(--ui-control-size-md));
1130
+ box-sizing: border-box !important;
1128
1131
  appearance: none;
1129
1132
  min-block-size: var(--ui-button-min-block-size, var(--ui-control-size-md));
1130
1133
  border-style: solid;
@@ -1166,6 +1169,19 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1166
1169
  :global(:scope:not([data-appearance="link"]):has(.badge:not(:empty)):where([data-hn-ui-button])) {
1167
1170
  padding-block: var(--ui-space-0-5) !important;
1168
1171
  }
1172
+ :global(.label:where([data-hn-ui-button])) {
1173
+ display: block !important;
1174
+ align-content: center !important;
1175
+ min-inline-size: 0 !important;
1176
+ min-block-size: 1lh !important;
1177
+ }
1178
+
1179
+ :global(.label:has(svg):where([data-hn-ui-button])) {
1180
+ display: inline-flex !important;
1181
+ align-items: center !important;
1182
+ gap: var(--ui-space-2) !important;
1183
+ text-box-trim: none;
1184
+ }
1169
1185
 
1170
1186
  :global(.badge:where([data-hn-ui-button])) {
1171
1187
  display: inline-flex !important;
@@ -1178,7 +1194,7 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1178
1194
  }
1179
1195
 
1180
1196
  @supports (text-box-trim: trim-both) {
1181
- :global(:scope:where([data-hn-ui-button])) {
1197
+ :global(.label:not(:has(svg)):where([data-hn-ui-button])) {
1182
1198
  text-box-trim: trim-both;
1183
1199
  text-box-edge: cap alphabetic;
1184
1200
  }
@@ -1499,6 +1515,11 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1499
1515
  text-decoration-color var(--ui-motion-fast) var(--ui-motion-ease);
1500
1516
  }
1501
1517
 
1518
+ :global(:scope[data-appearance="link"] .label:where([data-hn-ui-button])) {
1519
+ display: inline !important;
1520
+ text-box-trim: none;
1521
+ }
1522
+
1502
1523
  :global(:scope[data-appearance="link"]:hover:not(:disabled, [aria-disabled="true"]):where([data-hn-ui-button])) {
1503
1524
  color: var(--ui-button-link-hover-text, var(--ui-text-primary));
1504
1525
  text-decoration-color: currentColor;
@@ -377,20 +377,21 @@ useComponentHost(() => import('../components/ui-checkbox/ui-checkbox.js'), {
377
377
 
378
378
  /* The label, and under it an optional line saying what the choice means. */
379
379
 
380
- /* Centre the tick's box and lift it slightly for the rotated check shape. */
380
+ /* The SVG's painted bounds are centred in its viewBox, including its round stroke.
381
+ Centre that box directly; rotated border boxes do not centre the visible check. */
381
382
 
382
383
  @keyframes ui-checkbox-check {
383
384
  from {
384
385
  opacity: 0;
385
- transform: translateY(calc(var(--_ui-checkbox-size) * -0.09 / 1.125)) rotate(45deg) scale(0.55);
386
+ scale: 0.55;
386
387
  }
387
388
  65% {
388
389
  opacity: 1;
389
- transform: translateY(calc(var(--_ui-checkbox-size) * -0.09 / 1.125)) rotate(45deg) scale(1.12);
390
+ scale: 1.12;
390
391
  }
391
392
  to {
392
393
  opacity: 1;
393
- transform: translateY(calc(var(--_ui-checkbox-size) * -0.09 / 1.125)) rotate(45deg) scale(1);
394
+ scale: 1;
394
395
  }
395
396
  }
396
397
 
@@ -484,7 +485,8 @@ useComponentHost(() => import('../components/ui-checkbox/ui-checkbox.js'), {
484
485
 
485
486
  :global(input:where([data-hn-ui-checkbox])::after) {
486
487
  content: "";
487
- position: absolute;
488
+ position: absolute !important;
489
+ transform: none !important;
488
490
  opacity: 0;
489
491
  transition: opacity var(--ui-motion-fast) var(--ui-motion-ease);
490
492
  }
@@ -497,29 +499,28 @@ useComponentHost(() => import('../components/ui-checkbox/ui-checkbox.js'), {
497
499
  box-shadow: var(--ui-control-inset);
498
500
  }
499
501
  :global(input:checked:where([data-hn-ui-checkbox])::after) {
500
- inset: 0;
501
- margin: auto !important;
502
- inline-size: calc(var(--_ui-checkbox-size) * 0.28 / 1.125);
503
- block-size: calc(var(--_ui-checkbox-size) * 0.5 / 1.125);
504
- /* Longhands, not `border: solid var(...)`: lowering drops a shorthand that omits a
505
- component, which left the tick with no style and no colour. */
506
- border-style: solid;
507
- border-color: var(--ui-text-on-accent);
508
- border-width: 0 calc(var(--_ui-checkbox-size) * 0.125 / 1.125)
509
- calc(var(--_ui-checkbox-size) * 0.125 / 1.125) 0;
502
+ inset: 50% auto auto 50% !important;
503
+ inline-size: calc(var(--_ui-checkbox-size) * 0.7) !important;
504
+ block-size: calc(var(--_ui-checkbox-size) * 0.7) !important;
505
+ background: var(--ui-text-on-accent);
506
+ mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 11.5 5 5 9-9'/%3E%3C/svg%3E")
507
+ center / contain no-repeat;
510
508
  opacity: 1;
511
- transform: translateY(calc(var(--_ui-checkbox-size) * -0.09 / 1.125)) rotate(45deg);
509
+ translate: -50% -50% !important;
512
510
  animation: ui-checkbox-check var(--ui-motion-base)
513
511
  var(--ui-motion-ease-out, cubic-bezier(0.16, 1, 0.3, 1)) both;
514
512
  }
515
513
 
516
514
  :global(input:indeterminate:where([data-hn-ui-checkbox])::after) {
517
- inset: 50% calc(var(--_ui-checkbox-size) * 0.23 / 1.125) auto;
518
- block-size: calc(var(--_ui-checkbox-size) * 0.125 / 1.125);
515
+ mask: none;
516
+ animation: none;
517
+ inset: 50% calc(var(--_ui-checkbox-size) * 0.23 / 1.125) auto !important;
518
+ inline-size: auto !important;
519
+ block-size: calc(var(--_ui-checkbox-size) * 0.125 / 1.125) !important;
519
520
  border-radius: var(--ui-radius-round);
520
521
  background: var(--ui-text-on-accent);
521
522
  opacity: 1;
522
- transform: translateY(-50%);
523
+ translate: 0 -50% !important;
523
524
  }
524
525
 
525
526
  @media (prefers-reduced-motion: reduce) {
@@ -529,6 +530,20 @@ useComponentHost(() => import('../components/ui-checkbox/ui-checkbox.js'), {
529
530
  }
530
531
  }
531
532
 
533
+ @media (forced-colors: active) {
534
+ :global(input:checked:where([data-hn-ui-checkbox])),
535
+ :global(input:indeterminate:where([data-hn-ui-checkbox])) {
536
+ forced-color-adjust: none;
537
+ background: Highlight;
538
+ border-color: Highlight;
539
+ }
540
+ :global(input:checked:where([data-hn-ui-checkbox])::after),
541
+ :global(input:indeterminate:where([data-hn-ui-checkbox])::after) {
542
+ forced-color-adjust: none;
543
+ background: HighlightText;
544
+ }
545
+ }
546
+
532
547
  :global(input:hover:enabled:where([data-hn-ui-checkbox])) {
533
548
  border-color: var(--ui-accent-solid);
534
549
  }
@@ -2276,10 +2276,15 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
2276
2276
  color: inherit;
2277
2277
  }
2278
2278
  :global(input:where([data-hn-ui-combobox])) {
2279
+ --_ui-combobox-inset-block: var(--ui-control-inset-block-md, var(--ui-space-2));
2279
2280
  appearance: none;
2280
2281
  width: 100%;
2281
2282
  min-inline-size: 0;
2282
2283
  min-block-size: calc(var(--_row) - 2 * var(--ui-border-width));
2284
+ max-block-size: max(
2285
+ calc(var(--_row) - 2 * var(--ui-border-width)),
2286
+ calc(1em * var(--ui-line-height-tight) + 2 * var(--_ui-combobox-inset-block))
2287
+ );
2283
2288
  box-sizing: border-box !important;
2284
2289
  border: 0;
2285
2290
  border-radius: inherit;
@@ -2287,7 +2292,7 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
2287
2292
  color: inherit;
2288
2293
  font: inherit;
2289
2294
  line-height: var(--ui-line-height-tight);
2290
- padding: var(--ui-control-inset-block-md, var(--ui-space-2)) var(--ui-space-3) !important;
2295
+ padding: var(--_ui-combobox-inset-block) var(--ui-space-3) !important;
2291
2296
  margin: 0 !important;
2292
2297
  outline: none;
2293
2298
  }
@@ -2295,14 +2300,16 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
2295
2300
  --_row: var(--ui-control-size-sm);
2296
2301
  }
2297
2302
  :global(:scope[data-ui-combobox-state~="size=sm"] input:where([data-hn-ui-combobox])) {
2298
- padding: var(--ui-control-inset-block-sm, var(--ui-space-1)) var(--ui-space-2) !important;
2303
+ --_ui-combobox-inset-block: var(--ui-control-inset-block-sm, var(--ui-space-1));
2304
+ padding: var(--_ui-combobox-inset-block) var(--ui-space-2) !important;
2299
2305
  font-size: var(--ui-font-size-sm);
2300
2306
  }
2301
2307
  :global(:scope[data-ui-combobox-state~="size=lg"]:where([data-hn-ui-combobox])) {
2302
2308
  --_row: var(--ui-control-size-lg);
2303
2309
  }
2304
2310
  :global(:scope[data-ui-combobox-state~="size=lg"] input:where([data-hn-ui-combobox])) {
2305
- padding: var(--ui-control-inset-block-lg, var(--ui-space-3)) var(--ui-space-4) !important;
2311
+ --_ui-combobox-inset-block: var(--ui-control-inset-block-lg, var(--ui-space-3));
2312
+ padding: var(--_ui-combobox-inset-block) var(--ui-space-4) !important;
2306
2313
  font-size: var(--ui-font-size-md);
2307
2314
  }
2308
2315
  :global(button:where([data-hn-ui-combobox])) {
@@ -2448,6 +2455,7 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
2448
2455
  display: none !important;
2449
2456
  }
2450
2457
  :global(:scope[data-ui-combobox-state~="multiple"] input:where([data-hn-ui-combobox])) {
2458
+ max-block-size: none;
2451
2459
  flex: 1 0 var(--_ui-combobox-item-input-min-inline-size, 5rem);
2452
2460
  width: auto;
2453
2461
  min-block-size: 1.75rem;
@@ -2631,10 +2639,15 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
2631
2639
  color: inherit;
2632
2640
  }
2633
2641
  :global(input:where(:scope, :scope *):where([data-hn-ui-combobox])) {
2642
+ --_ui-combobox-inset-block: var(--ui-control-inset-block-md, var(--ui-space-2));
2634
2643
  appearance: none;
2635
2644
  width: 100%;
2636
2645
  min-inline-size: 0;
2637
2646
  min-block-size: calc(var(--_row) - 2 * var(--ui-border-width));
2647
+ max-block-size: max(
2648
+ calc(var(--_row) - 2 * var(--ui-border-width)),
2649
+ calc(1em * var(--ui-line-height-tight) + 2 * var(--_ui-combobox-inset-block))
2650
+ );
2638
2651
  box-sizing: border-box !important;
2639
2652
  border: 0;
2640
2653
  border-radius: inherit;
@@ -2642,7 +2655,7 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
2642
2655
  color: inherit;
2643
2656
  font: inherit;
2644
2657
  line-height: var(--ui-line-height-tight);
2645
- padding: var(--ui-control-inset-block-md, var(--ui-space-2)) var(--ui-space-3) !important;
2658
+ padding: var(--_ui-combobox-inset-block) var(--ui-space-3) !important;
2646
2659
  margin: 0 !important;
2647
2660
  outline: none;
2648
2661
  }
@@ -2651,7 +2664,8 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
2651
2664
  }
2652
2665
  :global(:where(.ui-combobox)[data-ui-combobox-state~="size=sm"]
2653
2666
  input:where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-combobox"]))):where([data-hn-ui-combobox])) {
2654
- padding: var(--ui-control-inset-block-sm, var(--ui-space-1)) var(--ui-space-2) !important;
2667
+ --_ui-combobox-inset-block: var(--ui-control-inset-block-sm, var(--ui-space-1));
2668
+ padding: var(--_ui-combobox-inset-block) var(--ui-space-2) !important;
2655
2669
  font-size: var(--ui-font-size-sm);
2656
2670
  }
2657
2671
  :global(:where(.ui-combobox)[data-ui-combobox-state~="size=lg"]:where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-combobox"]))):where([data-hn-ui-combobox])) {
@@ -2659,7 +2673,8 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
2659
2673
  }
2660
2674
  :global(:where(.ui-combobox)[data-ui-combobox-state~="size=lg"]
2661
2675
  input:where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-combobox"]))):where([data-hn-ui-combobox])) {
2662
- padding: var(--ui-control-inset-block-lg, var(--ui-space-3)) var(--ui-space-4) !important;
2676
+ --_ui-combobox-inset-block: var(--ui-control-inset-block-lg, var(--ui-space-3));
2677
+ padding: var(--_ui-combobox-inset-block) var(--ui-space-4) !important;
2663
2678
  font-size: var(--ui-font-size-md);
2664
2679
  }
2665
2680
  :global(button:where(:scope, :scope *):where([data-hn-ui-combobox])) {
@@ -2814,6 +2829,7 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
2814
2829
  }
2815
2830
  :global(:where(.ui-combobox)[data-ui-combobox-state~="multiple"]
2816
2831
  input:where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-combobox"]))):where([data-hn-ui-combobox])) {
2832
+ max-block-size: none;
2817
2833
  flex: 1 0 var(--_ui-combobox-item-input-min-inline-size, 5rem);
2818
2834
  width: auto;
2819
2835
  min-block-size: 1.75rem;
package/vue/UiDialog.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import type { PropType } from 'vue';
2
2
  import { type InputBindings } from './props.js';
3
- declare var __VLS_7: {}, __VLS_9: {};
3
+ declare var __VLS_20: {}, __VLS_22: {};
4
4
  type __VLS_Slots = {} & {
5
- default?: (props: typeof __VLS_7) => any;
5
+ default?: (props: typeof __VLS_20) => any;
6
6
  } & {
7
- actions?: (props: typeof __VLS_9) => any;
7
+ actions?: (props: typeof __VLS_22) => any;
8
8
  };
9
9
  declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
10
10
  alert: {