@threadlabs/looma 0.35.0 → 0.36.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.
Files changed (66) hide show
  1. package/components/ui-button/ui-button.html +11 -4
  2. package/components/ui-color-picker/ui-color-picker.html +1 -1
  3. package/components/ui-combobox/ui-combobox.html +1 -1
  4. package/components/ui-curve-editor/ui-curve-editor.html +1 -0
  5. package/components/ui-curve-editor/ui-curve-editor.js +15 -6
  6. package/components/ui-input/ui-input.html +4 -1
  7. package/components/ui-light-editor/ui-light-editor.html +143 -19
  8. package/components/ui-light-editor/ui-light-editor.js +26 -9
  9. package/components/ui-reel/ui-reel.html +2 -1
  10. package/components/ui-select/ui-select.html +10 -6
  11. package/components/ui-tabs/ui-tabs.html +2 -3
  12. package/components/ui-tabs/ui-tabs.js +0 -9
  13. package/components/ui-tooltip/ui-tooltip.html +2 -1
  14. package/dist/index.js +1 -1
  15. package/docs/README.md +36 -8
  16. package/docs/card.html +7 -6
  17. package/docs/card.js +1 -0
  18. package/docs/catalog-view.mjs +2 -1
  19. package/docs/catalog.json +46 -12
  20. package/docs/customizer-render.mjs +38 -18
  21. package/docs/customizer.js +128 -21
  22. package/docs/fonts.mjs +45 -0
  23. package/docs/index.d.ts +2 -2
  24. package/docs/palette.mjs +67 -0
  25. package/docs/site.mjs +5 -4
  26. package/docs/theme-session.mjs +28 -9
  27. package/docs/theme.mjs +69 -27
  28. package/docs/value-editors.mjs +6 -4
  29. package/package.json +2 -2
  30. package/styles/ui-button.css +11 -4
  31. package/styles/ui-color-picker.css +1 -1
  32. package/styles/ui-combobox.css +2 -2
  33. package/styles/ui-input.css +4 -1
  34. package/styles/ui-light-editor.css +111 -16
  35. package/styles/ui-select.css +10 -6
  36. package/styles/ui-tabs.css +2 -3
  37. package/styles/ui-tooltip.css +2 -1
  38. package/theme-system.css +14 -2
  39. package/tokens.css +11 -1
  40. package/vanilla/UiCurveEditor.d.ts +1 -0
  41. package/vanilla/UiCurveEditor.js +1 -1
  42. package/vanilla/UiLightEditor.d.ts +1 -0
  43. package/vanilla/UiLightEditor.js +2 -2
  44. package/vue/UiButton.vue +4 -2
  45. package/vue/UiColorPicker.vue +1 -1
  46. package/vue/UiCombobox.vue +2 -2
  47. package/vue/UiCurveEditor.d.ts +6 -0
  48. package/vue/UiCurveEditor.vue +2 -0
  49. package/vue/UiInput.vue +4 -1
  50. package/vue/UiLightEditor.d.ts +8 -0
  51. package/vue/UiLightEditor.vue +22 -3
  52. package/vue/UiReel.vue +1 -1
  53. package/vue/UiSelect.vue +1 -1
  54. package/vue/UiTabs.vue +2 -3
  55. package/vue/UiTooltip.vue +2 -1
  56. package/vue/chunks/UiButton.js +1 -1
  57. package/vue/chunks/UiColorPicker.js +1 -1
  58. package/vue/chunks/UiCombobox.js +1 -1
  59. package/vue/chunks/UiCurveEditor.js +5 -3
  60. package/vue/chunks/UiInput.js +1 -1
  61. package/vue/chunks/UiLightEditor.js +16 -6
  62. package/vue/chunks/UiReel.js +2 -2
  63. package/vue/chunks/UiSelect.js +1 -1
  64. package/vue/chunks/UiTabs.js +1 -1
  65. package/vue/chunks/UiTooltip.js +1 -1
  66. package/vue/components.css +47 -19
@@ -2,6 +2,7 @@
2
2
  export interface UiCurveEditorEventMap {
3
3
  input: CustomEvent<{ readonly value: string }>;
4
4
  change: CustomEvent<{ readonly value: string }>;
5
+ cancel: CustomEvent<{ readonly value: string }>;
5
6
  }
6
7
  export interface UiCurveEditorElement extends HTMLSpanElement {
7
8
  addEventListener<K extends keyof UiCurveEditorEventMap>(type: K, listener: (this: UiCurveEditorElement, event: UiCurveEditorEventMap[K]) => unknown, options?: boolean | AddEventListenerOptions): void;
@@ -5,7 +5,7 @@ import "../styles/ui-curve-editor.css";
5
5
 
6
6
  const T0 = ["",[],"\n ",["span",["class","plot-frame","role","group"],["span",["class","plot"],"\n ",["svg",["viewBox","0 0 100 100","preserveAspectRatio","none","aria-hidden","true"],["path",["class","guide","d","M0 66.667 H100 M0 33.333 H100"]],["path",["class","guide","d","M0 66.667 L25 63.333"]],["path",["class","guide","d","M100 33.333 L25 33.333"]],["path",["d","M0 66.667 C25 63.333 25 33.333 100 33.333"]]],"\n ",["button",["class","handle","type","button","aria-label","First curve handle. Arrow keys adjust; Shift moves faster."],"\n "],"\n ",["button",["class","handle second","type","button","aria-label","Second curve handle. Arrow keys adjust; Shift moves faster."],"\n "],"\n "]],"\n ",["span",["class","coordinates"],"\n ",["span",["class","coordinate"],["span",[],"X1"],["ui-number-input",["data-curve-coordinate","0","min","0","max","1","step","0.01","label","First handle X"]]],"\n ",["span",["class","coordinate"],["span",[],"Y1"],["ui-number-input",["data-curve-coordinate","1","min","-1","max","2","step","0.01","label","First handle Y"]]],"\n ",["span",["class","coordinate"],["span",[],"X2"],["ui-number-input",["data-curve-coordinate","2","min","0","max","1","step","0.01","label","Second handle X"]]],"\n ",["span",["class","coordinate"],["span",[],"Y2"],["ui-number-input",["data-curve-coordinate","3","min","-1","max","2","step","0.01","label","Second handle Y"]]],"\n "],"\n ",["output",[],0],"\n "];
7
7
  let P0;
8
- const S = { n: ["point0","point1","point2","point3"], t: ["s","s","s","s"], f: import.meta.url, g: "ui-curve-editor", d: { "input": [detailCheck(checkObject([["value", checkString, false]], false)), true, true, false], "change": [detailCheck(checkObject([["value", checkString, false]], false)), true, true, false] }, x: dispatchDeclared, a: (host, I) => C(host, I), b: generatedInputs, i: ["0.25", "0.1", "0.25", "1"] };
8
+ const S = { n: ["point0","point1","point2","point3"], t: ["s","s","s","s"], f: import.meta.url, g: "ui-curve-editor", d: { "input": [detailCheck(checkObject([["value", checkString, false]], false)), true, true, false], "change": [detailCheck(checkObject([["value", checkString, false]], false)), true, true, false], "cancel": [detailCheck(checkObject([["value", checkString, false]], false)), true, true, false] }, x: dispatchDeclared, a: (host, I) => C(host, I), b: generatedInputs, i: ["0.25", "0.1", "0.25", "1"] };
9
9
  const D = { g: "ui-curve-editor", props: { "disabled": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "label": { "required":false,"default":"Value", c: checkString, t: "string", j: 0, m: "s" }, "size": { "required":false,"values":["sm","md","lg"],"default":"md", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat)] }, "value": { "required":false,"default":"cubic-bezier(0.25, 0.1, 0.25, 1)", c: checkString, t: "string", j: 0, m: "s" } } };
10
10
  const C = (host) => activateModule(controller, host);
11
11
 
@@ -2,6 +2,7 @@
2
2
  export interface UiLightEditorEventMap {
3
3
  input: CustomEvent<{ readonly x: number; readonly y: number }>;
4
4
  change: CustomEvent<{ readonly x: number; readonly y: number }>;
5
+ cancel: CustomEvent<{ readonly x: number; readonly y: number }>;
5
6
  }
6
7
  export interface UiLightEditorElement extends HTMLSpanElement {
7
8
  addEventListener<K extends keyof UiLightEditorEventMap>(type: K, listener: (this: UiLightEditorElement, event: UiLightEditorEventMap[K]) => unknown, options?: boolean | AddEventListenerOptions): void;
@@ -3,10 +3,10 @@ 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 "],"\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, use arrow keys, or enter its position. 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","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 "];
7
7
  const T1 = ["",[]];
8
8
  let P0, P1;
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] }, x: dispatchDeclared, a: (host, I) => C(host, I), b: generatedInputs, i: ["50", "0"] };
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"] };
10
10
  const D = { g: "ui-light-editor", props: { "disabled": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "label": { "required":false,"default":"Light position", c: checkString, t: "string", j: 0, m: "s" }, "size": { "required":false,"values":["sm","md","lg"],"default":"md", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat)] }, "x": { "required":false,"default":0.5, c: checkNumber, t: "number", j: 0, m: "n" }, "y": { "required":false,"default":0, c: checkNumber, t: "number", j: 0, m: "n" } } };
11
11
  const C = (host) => activateModule(controller, host);
12
12
 
package/vue/UiButton.vue CHANGED
@@ -1412,9 +1412,11 @@ useComponentHost(() => import('../components/ui-button/ui-button.js'), {
1412
1412
  border-color: transparent;
1413
1413
  }
1414
1414
  @media (pointer: coarse) {
1415
- :global(:scope:where([data-hn-ui-button])),
1415
+ :global(:scope:where([data-hn-ui-button])) {
1416
+ min-block-size: max(var(--ui-control-size-md), var(--ui-control-min-block-size));
1417
+ }
1416
1418
  :global(:scope[data-ui-button-state~="size=sm"]:where([data-hn-ui-button])) {
1417
- min-block-size: var(--ui-control-min-block-size);
1419
+ min-block-size: max(var(--ui-control-size-sm), var(--ui-control-min-block-size));
1418
1420
  }
1419
1421
  }
1420
1422
  :global(html[data-ui-input-modality="touch"]
@@ -414,7 +414,7 @@ useComponentHost(() => import('../components/ui-color-picker/ui-color-picker.js'
414
414
  --_size: max(var(--ui-control-size-md), var(--ui-control-min-block-size));
415
415
  }
416
416
  :global(:scope[data-ui-color-picker-state~="size=sm"]) {
417
- --_size: var(--ui-control-min-block-size);
417
+ --_size: max(var(--ui-control-size-sm), var(--ui-control-min-block-size));
418
418
  --_font: var(--ui-font-size-md);
419
419
  }
420
420
  }
@@ -2388,7 +2388,7 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
2388
2388
  /* Under touch a small field is still a touch-sized target, as a small button is, and keeps
2389
2389
  body-size text: below 16px, iOS zooms the page into the focused field. */
2390
2390
  :global(:scope[data-ui-combobox-state~="size=sm"]:where([data-hn-ui-combobox])) {
2391
- --_row: var(--ui-control-min-block-size);
2391
+ --_row: max(var(--ui-control-size-sm), var(--ui-control-min-block-size));
2392
2392
  }
2393
2393
  :global(:scope[data-ui-combobox-state~="size=sm"] input:where([data-hn-ui-combobox])) {
2394
2394
  font-size: inherit;
@@ -2739,7 +2739,7 @@ useComponentHost(() => import('../components/ui-combobox/ui-combobox.js'), {
2739
2739
  /* Under touch a small field is still a touch-sized target, as a small button is, and keeps
2740
2740
  body-size text: below 16px, iOS zooms the page into the focused field. */
2741
2741
  :global(:where(.ui-combobox)[data-ui-combobox-state~="size=sm"]:where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-combobox"]))):where([data-hn-ui-combobox])) {
2742
- --_row: var(--ui-control-min-block-size);
2742
+ --_row: max(var(--ui-control-size-sm), var(--ui-control-min-block-size));
2743
2743
  }
2744
2744
  :global(:where(.ui-combobox)[data-ui-combobox-state~="size=sm"]
2745
2745
  input:where(:scope, :not([data-hn], [data-slotted]:not([data-slotted~="ui-combobox"]))):where([data-hn-ui-combobox])) {
@@ -20,6 +20,9 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
20
20
  input: (event: CustomEvent<{
21
21
  readonly value: string;
22
22
  }>) => any;
23
+ cancel: (event: CustomEvent<{
24
+ readonly value: string;
25
+ }>) => any;
23
26
  change: (event: CustomEvent<{
24
27
  readonly value: string;
25
28
  }>) => any;
@@ -44,6 +47,9 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
44
47
  onInput?: ((event: CustomEvent<{
45
48
  readonly value: string;
46
49
  }>) => any) | undefined;
50
+ onCancel?: ((event: CustomEvent<{
51
+ readonly value: string;
52
+ }>) => any) | undefined;
47
53
  onChange?: ((event: CustomEvent<{
48
54
  readonly value: string;
49
55
  }>) => any) | undefined;
@@ -136,6 +136,7 @@ const emit = defineEmits<{
136
136
  'update:value': [value: string]
137
137
  input: [event: CustomEvent<{ readonly value: string }>]
138
138
  change: [event: CustomEvent<{ readonly value: string }>]
139
+ cancel: [event: CustomEvent<{ readonly value: string }>]
139
140
  }>()
140
141
 
141
142
  const root = ref<HTMLElement | null>(null)
@@ -165,6 +166,7 @@ const dispatch = createDispatch(root, emit as (name: string, detail: unknown) =>
165
166
  checks: {
166
167
  input: isInputDetail,
167
168
  change: isInputDetail,
169
+ cancel: isInputDetail,
168
170
  },
169
171
  modeled: ['value'],
170
172
  })
package/vue/UiInput.vue CHANGED
@@ -632,7 +632,10 @@ useComponentHost(() => import('../components/ui-input/ui-input.js'), {
632
632
  :global(:scope[data-ui-input-state~="size=sm"]) {
633
633
  min-block-size: var(
634
634
  --ui-input-min-block-size,
635
- var(--_ui-default-input-min-block-size, var(--ui-control-min-block-size))
635
+ var(
636
+ --_ui-default-input-min-block-size,
637
+ max(var(--ui-control-size-sm), var(--ui-control-min-block-size))
638
+ )
636
639
  );
637
640
  }
638
641
  }
@@ -28,6 +28,10 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
28
28
  readonly x: number;
29
29
  readonly y: number;
30
30
  }>) => any;
31
+ cancel: (event: CustomEvent<{
32
+ readonly x: number;
33
+ readonly y: number;
34
+ }>) => any;
31
35
  change: (event: CustomEvent<{
32
36
  readonly x: number;
33
37
  readonly y: number;
@@ -58,6 +62,10 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
58
62
  readonly x: number;
59
63
  readonly y: number;
60
64
  }>) => any) | undefined;
65
+ onCancel?: ((event: CustomEvent<{
66
+ readonly x: number;
67
+ readonly y: number;
68
+ }>) => any) | undefined;
61
69
  onChange?: ((event: CustomEvent<{
62
70
  readonly x: number;
63
71
  readonly y: number;
@@ -23,6 +23,7 @@ import {
23
23
  vPropValidity,
24
24
  vuePropInputs,
25
25
  } from './props'
26
+ import UiIcon from './UiIcon.vue'
26
27
  import UiNumberInput from './UiNumberInput.vue'
27
28
 
28
29
  defineOptions({ inheritAttrs: false })
@@ -148,6 +149,7 @@ const emit = defineEmits<{
148
149
  'update:y': [value: number]
149
150
  input: [event: CustomEvent<{ readonly x: number; readonly y: number }>]
150
151
  change: [event: CustomEvent<{ readonly x: number; readonly y: number }>]
152
+ cancel: [event: CustomEvent<{ readonly x: number; readonly y: number }>]
151
153
  }>()
152
154
 
153
155
  const root = ref<HTMLElement | null>(null)
@@ -180,6 +182,7 @@ const dispatch = createDispatch(root, emit as (name: string, detail: unknown) =>
180
182
  checks: {
181
183
  input: isInputDetail,
182
184
  change: isInputDetail,
185
+ cancel: isInputDetail,
183
186
  },
184
187
  modeled: ['x', 'y'],
185
188
  })
@@ -255,6 +258,10 @@ useComponentHost(() => import('../components/ui-light-editor/ui-light-editor.js'
255
258
  :aria-label="guarded"
256
259
  ref="sourceElement"
257
260
  >
261
+ <span class="source-glyph" data-hn-ui-light-editor><UiIcon
262
+ class="ui-icon"
263
+ name="lightbulb"
264
+ /></span>
258
265
  </button></span></span>{{ ' ' }}<span
259
266
  class="coordinates"
260
267
  data-hn-ui-light-editor
@@ -293,7 +300,8 @@ useComponentHost(() => import('../components/ui-light-editor/ui-light-editor.js'
293
300
  },
294
301
  }"
295
302
  /></span>{{ ' ' }}<span class="hint" data-hn-ui-light-editor
296
- >Drag the light, use arrow keys, or enter its position. Top centre is 50%, 0%.</span></span>
303
+ >Drag the light, tap the background, use arrow keys, or enter its position. Escape cancels a
304
+ drag. Top centre is 50%, 0%.</span></span>
297
305
  </template>
298
306
 
299
307
  <style scoped>
@@ -354,10 +362,18 @@ useComponentHost(() => import('../components/ui-light-editor/ui-light-editor.js'
354
362
  cursor: grab;
355
363
  touch-action: none;
356
364
  }
365
+ :global(.source-glyph:where([data-hn-ui-light-editor])) {
366
+ position: relative;
367
+ z-index: 1;
368
+ display: inline-flex !important;
369
+ color: var(--ui-accent);
370
+ font-size: var(--ui-font-size-lg);
371
+ }
357
372
  :global(.source:where([data-hn-ui-light-editor])::after) {
358
373
  content: "";
359
- inline-size: 1rem;
360
- block-size: 1rem;
374
+ position: absolute;
375
+ inline-size: 2rem;
376
+ block-size: 2rem;
361
377
  border: var(--ui-border-width) solid var(--ui-accent);
362
378
  border-radius: 50%;
363
379
  background: var(--ui-surface-raised);
@@ -390,6 +406,9 @@ useComponentHost(() => import('../components/ui-light-editor/ui-light-editor.js'
390
406
  color: var(--ui-text-secondary);
391
407
  }
392
408
  @media (forced-colors: active) {
409
+ :global(.source-glyph:where([data-hn-ui-light-editor])) {
410
+ color: CanvasText;
411
+ }
393
412
  :global(.source:where([data-hn-ui-light-editor])::after) {
394
413
  background: Canvas;
395
414
  border-color: CanvasText;
package/vue/UiReel.vue CHANGED
@@ -40,7 +40,7 @@ const propValidityContract = {
40
40
  required: false,
41
41
  target: { attribute: 'snap' },
42
42
  description:
43
- 'Snaps scrolling to items: start comes to rest with an item\'s start edge at the reel\'s start, and center with an item centred in the reel. Unset, the reel\n scrolls freely.',
43
+ 'Snaps scrolling to items: start comes to rest with an item\'s start edge at the reel\'s start, and center with an item centred in the reel. Unset, the reel\n scrolls freely. Wrap a component item in a plain element when snapping: the wrapper receives snap alignment while the component keeps ownership of its\n root styles.',
44
44
  values: ['start', 'center'],
45
45
  },
46
46
  },
package/vue/UiSelect.vue CHANGED
@@ -386,7 +386,7 @@ useComponentHost(() => import('../components/ui-select/ui-select.js'), {
386
386
  }
387
387
 
388
388
  :global(:scope[data-ui-select-state~="size=sm"]:where([data-hn-ui-select])) {
389
- min-block-size: var(--ui-control-min-block-size);
389
+ min-block-size: max(var(--ui-control-size-sm), var(--ui-control-min-block-size));
390
390
  font-size: inherit;
391
391
  }
392
392
  }
package/vue/UiTabs.vue CHANGED
@@ -395,10 +395,9 @@ useComponentHost(() => import('../components/ui-tabs/ui-tabs.js'), {
395
395
  max-inline-size: 100%;
396
396
  /* Tabs that do not fit scroll sideways rather than wrapping or squeezing. */
397
397
  overflow-x: auto;
398
- /* overflow-x: auto would make the block axis scrollable too; a sideways swipe must not scroll the
399
- strip or the page vertically. */
398
+ /* Contain sideways overscroll without trapping vertical page scrolling. */
400
399
  overflow-y: hidden;
401
- overscroll-behavior: contain;
400
+ overscroll-behavior-inline: contain;
402
401
  scrollbar-width: thin;
403
402
  border-block-end: var(--ui-border-width) solid var(--ui-border-divider);
404
403
  }
package/vue/UiTooltip.vue CHANGED
@@ -580,7 +580,8 @@ useComponentHost(() => import('../components/ui-tooltip/ui-tooltip.js'), {
580
580
  border-inline-end-width: var(--ui-border-width);
581
581
  border-block-end-width: var(--ui-border-width);
582
582
  border-end-end-radius: var(--ui-border-width);
583
- transform: rotate(45deg) scaleX(1.25) scaleY(0.85);
583
+ /* Stretch in screen axes after rotation so both arrow shoulders stay level. */
584
+ transform: scale(1.25, 0.85) rotate(45deg);
584
585
  }
585
586
 
586
587
  :global(:scope[data-ui-actual-placement="bottom"] .surface:where([data-hn-ui-tooltip])::after) {
@@ -866,6 +866,6 @@ var UiButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
866
866
  }]]);
867
867
  };
868
868
  }
869
- }), [["__scopeId", "data-v-bb40b79e"]]);
869
+ }), [["__scopeId", "data-v-bf2aad19"]]);
870
870
  //#endregion
871
871
  export { UiButton_default as t };
@@ -321,6 +321,6 @@ var UiColorPicker_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @
321
321
  }]]);
322
322
  };
323
323
  }
324
- }), [["__scopeId", "data-v-908b48a2"]]);
324
+ }), [["__scopeId", "data-v-b2a9e21e"]]);
325
325
  //#endregion
326
326
  export { UiColorPicker_default as t };
@@ -2134,6 +2134,6 @@ var UiCombobox_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
2134
2134
  }]]);
2135
2135
  };
2136
2136
  }
2137
- }), [["__scopeId", "data-v-ee406b40"]]);
2137
+ }), [["__scopeId", "data-v-85d2ac14"]]);
2138
2138
  //#endregion
2139
2139
  export { UiCombobox_default as t };
@@ -37,7 +37,8 @@ var UiCurveEditor_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @
37
37
  emits: [
38
38
  "update:value",
39
39
  "input",
40
- "change"
40
+ "change",
41
+ "cancel"
41
42
  ],
42
43
  setup(__props, { emit: __emit }) {
43
44
  const propValidityContract = { props: {
@@ -164,7 +165,8 @@ var UiCurveEditor_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @
164
165
  const dispatch = createDispatch(root, emit, {
165
166
  checks: {
166
167
  input: isInputDetail,
167
- change: isInputDetail
168
+ change: isInputDetail,
169
+ cancel: isInputDetail
168
170
  },
169
171
  modeled: ["value"]
170
172
  });
@@ -408,6 +410,6 @@ var UiCurveEditor_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @
408
410
  }]]);
409
411
  };
410
412
  }
411
- }), [["__scopeId", "data-v-b4dfbbee"]]);
413
+ }), [["__scopeId", "data-v-0eaa205c"]]);
412
414
  //#endregion
413
415
  export { UiCurveEditor_default as t };
@@ -704,6 +704,6 @@ var UiInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE
704
704
  }]]);
705
705
  };
706
706
  }
707
- }), [["__scopeId", "data-v-c67ac937"]]);
707
+ }), [["__scopeId", "data-v-881962d1"]]);
708
708
  //#endregion
709
709
  export { UiInput_default as t };
@@ -1,5 +1,6 @@
1
1
  import { a as concat, b as useReflectedProp, i as checkHydratedRoot, m as nativeAttrs, o as createDispatch, t as _plugin_vue_export_helper_default, y as useComponentHost } from "./_plugin-vue_export-helper.js";
2
2
  import { d as requireInputStatus, i as checkPropInput, m as vuePropInputs, p as vPropValidity, r as acceptsControllerWrite, t as BINDING_INPUTS_PROP, u as propValidityState } from "./props.js";
3
+ import { t as UiIcon_default } from "./UiIcon.js";
3
4
  import { t as UiNumberInput_default } from "./UiNumberInput.js";
4
5
  import { computed, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, getCurrentInstance, mergeProps, openBlock, provide, ref, renderSlot, toDisplayString, unref, useTemplateRef, watchSyncEffect, withDirectives } from "vue";
5
6
  //#region .build/vue/UiLightEditor.vue?vue&type=script&setup=true&lang.ts
@@ -17,6 +18,10 @@ var _hoisted_3 = {
17
18
  };
18
19
  var _hoisted_4 = ["disabled", "aria-label"];
19
20
  var _hoisted_5 = {
21
+ class: "source-glyph",
22
+ "data-hn-ui-light-editor": ""
23
+ };
24
+ var _hoisted_6 = {
20
25
  class: "coordinates",
21
26
  "data-hn-ui-light-editor": ""
22
27
  };
@@ -37,7 +42,8 @@ var UiLightEditor_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @
37
42
  "update:x",
38
43
  "update:y",
39
44
  "input",
40
- "change"
45
+ "change",
46
+ "cancel"
41
47
  ],
42
48
  setup(__props, { emit: __emit }) {
43
49
  const propValidityContract = { props: {
@@ -178,7 +184,8 @@ var UiLightEditor_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @
178
184
  const dispatch = createDispatch(root, emit, {
179
185
  checks: {
180
186
  input: isInputDetail,
181
- change: isInputDetail
187
+ change: isInputDetail,
188
+ cancel: isInputDetail
182
189
  },
183
190
  modeled: ["x", "y"]
184
191
  });
@@ -275,10 +282,13 @@ var UiLightEditor_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @
275
282
  "aria-label": guarded.value,
276
283
  ref_key: "sourceElement",
277
284
  ref: sourceElement
278
- }, null, 8, _hoisted_4)
285
+ }, [createElementVNode("span", _hoisted_5, [createVNode(UiIcon_default, {
286
+ class: "ui-icon",
287
+ name: "lightbulb"
288
+ })])], 8, _hoisted_4)
279
289
  ], 512)], 8, _hoisted_2),
280
290
  _cache[4] || (_cache[4] = createTextVNode(toDisplayString(" "), -1)),
281
- createElementVNode("span", _hoisted_5, [
291
+ createElementVNode("span", _hoisted_6, [
282
292
  createVNode(UiNumberInput_default, mergeProps({
283
293
  class: "ui-number-input",
284
294
  "data-coordinate": "x",
@@ -335,13 +345,13 @@ var UiLightEditor_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @
335
345
  _cache[6] || (_cache[6] = createElementVNode("span", {
336
346
  class: "hint",
337
347
  "data-hn-ui-light-editor": ""
338
- }, "Drag the light, use arrow keys, or enter its position. Top centre is 50%, 0%.", -1))
348
+ }, "Drag the light, tap the background, use arrow keys, or enter its position. Escape cancels a drag. Top centre is 50%, 0%.", -1))
339
349
  ], 16, _hoisted_1)), [[unref(vPropValidity), {
340
350
  contract: propValidityContract,
341
351
  values: { ...props }
342
352
  }]]);
343
353
  };
344
354
  }
345
- }), [["__scopeId", "data-v-1cd5c26a"]]);
355
+ }), [["__scopeId", "data-v-dc22fbcf"]]);
346
356
  //#endregion
347
357
  export { UiLightEditor_default as t };
@@ -58,7 +58,7 @@ var UiReel_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
58
58
  },
59
59
  required: false,
60
60
  target: { attribute: "snap" },
61
- description: "Snaps scrolling to items: start comes to rest with an item's start edge at the reel's start, and center with an item centred in the reel. Unset, the reel\n scrolls freely.",
61
+ description: "Snaps scrolling to items: start comes to rest with an item's start edge at the reel's start, and center with an item centred in the reel. Unset, the reel\n scrolls freely. Wrap a component item in a plain element when snapping: the wrapper receives snap alignment while the component keeps ownership of its\n root styles.",
62
62
  values: ["start", "center"]
63
63
  }
64
64
  } };
@@ -128,6 +128,6 @@ var UiReel_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
128
128
  }]]);
129
129
  };
130
130
  }
131
- }), [["__scopeId", "data-v-ace220e1"]]);
131
+ }), [["__scopeId", "data-v-fbdba47c"]]);
132
132
  //#endregion
133
133
  export { UiReel_default as t };
@@ -221,6 +221,6 @@ var UiSelect_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
221
221
  }]]);
222
222
  };
223
223
  }
224
- }), [["__scopeId", "data-v-4348aae0"]]);
224
+ }), [["__scopeId", "data-v-1d116383"]]);
225
225
  //#endregion
226
226
  export { UiSelect_default as t };
@@ -329,6 +329,6 @@ var UiTabs_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
329
329
  }]]);
330
330
  };
331
331
  }
332
- }), [["__scopeId", "data-v-f1705832"]]);
332
+ }), [["__scopeId", "data-v-502b66c9"]]);
333
333
  //#endregion
334
334
  export { UiTabs_default as t };
@@ -292,6 +292,6 @@ var UiTooltip_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
292
292
  }]]);
293
293
  };
294
294
  }
295
- }), [["__scopeId", "data-v-4cc4aab6"]]);
295
+ }), [["__scopeId", "data-v-21fb192b"]]);
296
296
  //#endregion
297
297
  export { UiTooltip_default as t };