@threadlabs/looma 0.26.24 → 0.26.26

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@threadlabs/looma",
3
- "version": "0.26.24",
3
+ "version": "0.26.26",
4
4
  "type": "module",
5
5
  "description": "Looma components as HTML, Vue, and plain DOM, with design tokens.",
6
6
  "license": "MIT",
@@ -135,6 +135,13 @@
135
135
  pointer-events: none;
136
136
  }
137
137
 
138
+ :scope[data-ui-icon-button-state~="anticipatory"][data-ui-icon-button-state~="guide=bar"]::before {
139
+ inline-size: 2px;
140
+ block-size: 20px;
141
+ background: var(--ui-border-strong);
142
+ opacity: 1;
143
+ }
144
+
138
145
  :scope[data-ui-icon-button-state~="anticipatory"]:disabled::before {
139
146
  opacity: 0;
140
147
  }
@@ -189,7 +196,7 @@
189
196
  border-color var(--ui-motion-fast) var(--ui-motion-ease),
190
197
  color var(--ui-motion-fast) var(--ui-motion-ease),
191
198
  box-shadow var(--ui-motion-base) var(--ui-motion-ease),
192
- transform var(--ui-motion-fast) var(--ui-motion-ease);
199
+ scale var(--ui-motion-fast) var(--ui-motion-ease);
193
200
  }
194
201
 
195
202
  @media (hover: none), (pointer: coarse) {
@@ -319,7 +326,7 @@
319
326
  }
320
327
 
321
328
  :scope:active:enabled:not([aria-disabled="true"]) {
322
- transform: scale(var(--ui-icon-button-active-scale, 0.96));
329
+ scale: var(--ui-icon-button-active-scale, 0.96);
323
330
  }
324
331
 
325
332
  :is(:scope[data-ui-icon-button-state~="loading"], :scope[data-ui-icon-button-state~="pending"]) {
@@ -8,6 +8,7 @@ export interface UiIconButtonElement extends HTMLButtonElement {
8
8
  export interface UiIconButtonProps {
9
9
  anticipatory?: boolean | null;
10
10
  disabled?: boolean | null;
11
+ guide?: "dot" | "bar" | null;
11
12
  label?: string | null;
12
13
  loading?: boolean | null;
13
14
  matchButton?: boolean | null;
@@ -8,7 +8,7 @@ const T1 = ["ui-spinner",["size","sm"]];
8
8
  const T2 = ["",[]];
9
9
  let P0, P1, P2;
10
10
  const S = { n: [], t: [], f: import.meta.url, g: "ui-icon-button" };
11
- const D = { props: { "anticipatory": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "disabled": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "label": { "required":false, c: checkString, t: "string", j: 0, m: "s" }, "loading": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "matchButton": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "pending": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "round": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "size": { "required":false,"values":["sm","md","lg"],"default":"md", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "tone": { "required":false,"values":["accent","neutral"], c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "variant": { "required":false,"values":["ghost","outline","solid"],"default":"ghost", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] } } };
11
+ const D = { props: { "anticipatory": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "disabled": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "guide": { "required":false,"values":["dot","bar"],"default":"dot", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "label": { "required":false, c: checkString, t: "string", j: 0, m: "s" }, "loading": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "matchButton": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "pending": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "round": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "size": { "required":false,"values":["sm","md","lg"],"default":"md", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "tone": { "required":false,"values":["accent","neutral"], c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "variant": { "required":false,"values":["ghost","outline","solid"],"default":"ghost", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] } } };
12
12
  const C = (host) => controller.default(host);
13
13
 
14
14
  export function createUiIconButton(options = {}, html) {
@@ -21,7 +21,7 @@ export function createUiIconButton(options = {}, html) {
21
21
  if (!element.hasAttribute("type")) element.setAttribute("type", "button");
22
22
  element.setAttribute("data-component", "ui-icon-button");
23
23
  element.append((P0 ??= buildTemplate(T0)).cloneNode(true));
24
- const v = [null, null, null, null, null, null, null, null, null, null];
24
+ const v = [null, null, null, null, null, null, null, null, null, null, null];
25
25
  const B = acceptProps(element, D, S.n, v, componentProps, ["matchButton"], html);
26
26
  const m1 = (d) => {
27
27
  const n = (P1 ??= buildTemplate(T1)).cloneNode(true);
@@ -45,35 +45,35 @@ export function createUiIconButton(options = {}, html) {
45
45
  const s0 = toAttribute(x0, "disabled");
46
46
  if (s0 !== r.v0) writeAttribute(r.n, "disabled", r.v0 = s0);
47
47
  }
48
- if (c & 4) {
49
- const x1 = v[2];
48
+ if (c & 8) {
49
+ const x1 = v[3];
50
50
  const s1 = toAttribute(x1, "aria-label");
51
51
  if (s1 !== r.v1) writeAttribute(r.n, "aria-label", r.v1 = s1);
52
52
  }
53
- if (c & 16) {
54
- const x2 = v[4];
53
+ if (c & 32) {
54
+ const x2 = v[5];
55
55
  const s2 = toAttribute(x2, "data-match-button");
56
56
  if (s2 !== r.v2) writeAttribute(r.n, "data-match-button", r.v2 = s2);
57
57
  }
58
- if (c & 1073741864) {
59
- const x3 = readIndex({ "true": "true", "false": null }, textCall("concat", [(truthy(v[3]) || truthy(v[5]))]));
58
+ if (c & 1073741904) {
59
+ const x3 = readIndex({ "true": "true", "false": null }, textCall("concat", [(truthy(v[4]) || truthy(v[6]))]));
60
60
  if (x3 !== NONCONFORMING) {
61
61
  const s3 = toAttribute(x3, "aria-disabled");
62
62
  if (s3 !== r.v3) writeAttribute(r.n, "aria-disabled", r.v3 = s3);
63
63
  }
64
64
  }
65
- if (c & 40) {
66
- const x4 = (truthy(v[3]) || truthy(v[5]));
65
+ if (c & 80) {
66
+ const x4 = (truthy(v[4]) || truthy(v[6]));
67
67
  const s4 = toAttribute(x4, "aria-busy");
68
68
  if (s4 !== r.v4) writeAttribute(r.n, "aria-busy", r.v4 = s4);
69
69
  }
70
- if (c & 1017) {
71
- const x5 = hostState(["tone","anticipatory","variant","loading","pending","size","matchButton","round"], [v[8], v[0], v[9], v[3], v[5], v[7], v[4], v[6]]);
70
+ if (c & 2037) {
71
+ const x5 = hostState(["tone","anticipatory","guide","variant","loading","pending","size","matchButton","round"], [v[9], v[0], v[2], v[10], v[4], v[6], v[8], v[5], v[7]]);
72
72
  const s5 = x5;
73
73
  if (s5 !== r.v5) writeAttribute(r.n, "data-ui-icon-button-state", (r.v5 = s5) === "" ? null : s5);
74
74
  }
75
- if (c & 40) {
76
- const t0 = (truthy(v[3]) || truthy(v[5]));
75
+ if (c & 80) {
76
+ const t0 = (truthy(v[4]) || truthy(v[6]));
77
77
  if (true) {
78
78
  {
79
79
  r.b0 = undefined;
@@ -12,6 +12,10 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
12
12
  type: PropType<boolean | null>;
13
13
  default: boolean;
14
14
  };
15
+ guide: {
16
+ type: PropType<"dot" | "bar" | null>;
17
+ default: string;
18
+ };
15
19
  label: {
16
20
  type: PropType<string | null>;
17
21
  default: null;
@@ -53,6 +57,10 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
53
57
  type: PropType<boolean | null>;
54
58
  default: boolean;
55
59
  };
60
+ guide: {
61
+ type: PropType<"dot" | "bar" | null>;
62
+ default: string;
63
+ };
56
64
  label: {
57
65
  type: PropType<string | null>;
58
66
  default: null;
@@ -87,6 +95,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
87
95
  };
88
96
  }>> & Readonly<{}>, {
89
97
  label: string | null;
98
+ guide: "bar" | "dot" | null;
90
99
  round: boolean | null;
91
100
  size: "sm" | "md" | "lg" | null;
92
101
  tone: "neutral" | "accent" | null;
@@ -26,6 +26,15 @@ const propValidityContract = {
26
26
  'Disables the button, so it cannot be pressed or focused, and gives it a flat neutral surface and muted icon.',
27
27
  default: false,
28
28
  },
29
+ guide: {
30
+ type: { kind: 'terminal', name: 'keyword' },
31
+ required: false,
32
+ target: { attribute: 'guide' },
33
+ description:
34
+ 'The idle marker of an anticipatory button: dot for contextual actions, or a slim neutral rounded bar for a panel-edge control. The icon appears on hover or\n keyboard focus; touch always shows the icon.',
35
+ values: ['dot', 'bar'],
36
+ default: 'dot',
37
+ },
29
38
  label: {
30
39
  type: { kind: 'terminal', name: 'string' },
31
40
  required: false,
@@ -93,6 +102,7 @@ const propValidityContract = {
93
102
  const props = defineProps({
94
103
  anticipatory: { type: null as unknown as PropType<boolean | null>, default: false },
95
104
  disabled: { type: null as unknown as PropType<boolean | null>, default: false },
105
+ guide: { type: null as unknown as PropType<'dot' | 'bar' | null>, default: 'dot' },
96
106
  label: { type: null as unknown as PropType<string | null>, default: null },
97
107
  loading: { type: null as unknown as PropType<boolean | null>, default: false },
98
108
  matchButton: { type: null as unknown as PropType<boolean | null>, default: false },
@@ -108,6 +118,7 @@ const props = defineProps({
108
118
  const acceptedProps: Record<string, unknown> = {
109
119
  anticipatory: false,
110
120
  disabled: false,
121
+ guide: 'dot',
111
122
  label: null,
112
123
  loading: false,
113
124
  matchButton: false,
@@ -132,6 +143,13 @@ const checkedProps = computed(() => ({
132
143
  'disabled',
133
144
  acceptedProps,
134
145
  ) as boolean,
146
+ guide: checkedProp<'dot' | 'bar'>(
147
+ props['guide'],
148
+ { kind: 'terminal', name: 'keyword' },
149
+ false,
150
+ 'guide',
151
+ acceptedProps,
152
+ ) as 'dot' | 'bar',
135
153
  label: checkedProp<string>(
136
154
  props['label'],
137
155
  { kind: 'terminal', name: 'string' },
@@ -289,6 +307,8 @@ const hostState = computed(() =>
289
307
  checkedProps.value.tone && 'tone',
290
308
  checkedProps.value.tone != null && `tone=${encodeURIComponent(checkedProps.value.tone)}`,
291
309
  checkedProps.value.anticipatory && 'anticipatory',
310
+ checkedProps.value.guide && 'guide',
311
+ checkedProps.value.guide != null && `guide=${encodeURIComponent(checkedProps.value.guide)}`,
292
312
  checkedProps.value.variant && 'variant',
293
313
  checkedProps.value.variant != null
294
314
  && `variant=${encodeURIComponent(checkedProps.value.variant)}`,
@@ -321,6 +341,7 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
321
341
  propNames: [
322
342
  'anticipatory',
323
343
  'disabled',
344
+ 'guide',
324
345
  'label',
325
346
  'loading',
326
347
  'matchButton',
@@ -378,6 +399,7 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
378
399
  v-prop-validity="{ contract: propValidityContract, values: { ...props } }"
379
400
  :data-anticipatory="reflectedProp('anticipatory', 'anticipatory', checkedProps.anticipatory, undefined, false)"
380
401
  :data-disabled="reflectedProp('disabled', 'disabled', checkedProps.disabled, undefined, false)"
402
+ :data-guide="reflectedProp('guide', 'guide', checkedProps.guide, undefined, false)"
381
403
  :data-label="reflectedProp('label', 'label', checkedProps.label, undefined, false)"
382
404
  :data-loading="reflectedProp('loading', 'loading', checkedProps.loading, undefined, false)"
383
405
  :data-match-button="reflectedProp('matchButton', 'match-button', checkedProps.matchButton, undefined, true)"
@@ -539,6 +561,13 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
539
561
  pointer-events: none;
540
562
  }
541
563
 
564
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-ui-icon-button-state~="guide=bar"]::before {
565
+ inline-size: 2px;
566
+ block-size: 20px;
567
+ background: var(--ui-border-strong);
568
+ opacity: 1;
569
+ }
570
+
542
571
  [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"]:disabled::before {
543
572
  opacity: 0;
544
573
  }
@@ -595,7 +624,7 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
595
624
  border-color var(--ui-motion-fast) var(--ui-motion-ease),
596
625
  color var(--ui-motion-fast) var(--ui-motion-ease),
597
626
  box-shadow var(--ui-motion-base) var(--ui-motion-ease),
598
- transform var(--ui-motion-fast) var(--ui-motion-ease);
627
+ scale var(--ui-motion-fast) var(--ui-motion-ease);
599
628
  }
600
629
 
601
630
  @media (hover: none), (pointer: coarse) {
@@ -752,7 +781,7 @@ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"]::after {
752
781
  }
753
782
 
754
783
  [data-component~="ui-icon-button"]:active:enabled:not([aria-disabled="true"]) {
755
- transform: scale(var(--ui-icon-button-active-scale, 0.96));
784
+ scale: var(--ui-icon-button-active-scale, 0.96);
756
785
  }
757
786
 
758
787
  :is([data-component~="ui-icon-button"][data-ui-icon-button-state~="loading"], [data-component~="ui-icon-button"][data-ui-icon-button-state~="pending"]) {
package/vue/UiTooltip.vue CHANGED
@@ -84,7 +84,7 @@ const propValidityContract = {
84
84
  required: false,
85
85
  target: { attribute: 'trigger' },
86
86
  description:
87
- 'How the trigger opens it. hover also opens on keyboard focus; click toggles it and suits a help button, where hovering a question mark says nothing; focus\n opens only while the trigger holds focus.',
87
+ 'How the trigger opens it. hover also opens on keyboard focus; click toggles it and suits a help button, where hovering a question mark says nothing; focus\n opens only on keyboard-visible focus. Action activation dismisses hover/focus hints without removing focus; a fresh hover or keyboard focus can open them\n again.',
88
88
  values: ['hover', 'click', 'focus'],
89
89
  default: 'hover',
90
90
  },
@@ -11,6 +11,7 @@ var _hoisted_1 = [
11
11
  "aria-busy",
12
12
  "data-anticipatory",
13
13
  "data-disabled",
14
+ "data-guide",
14
15
  "data-label",
15
16
  "data-loading",
16
17
  "data-match-button",
@@ -36,6 +37,10 @@ var UiIconButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
36
37
  type: null,
37
38
  default: false
38
39
  },
40
+ guide: {
41
+ type: null,
42
+ default: "dot"
43
+ },
39
44
  label: {
40
45
  type: null,
41
46
  default: null
@@ -91,6 +96,17 @@ var UiIconButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
91
96
  description: "Disables the button, so it cannot be pressed or focused, and gives it a flat neutral surface and muted icon.",
92
97
  default: false
93
98
  },
99
+ guide: {
100
+ type: {
101
+ kind: "terminal",
102
+ name: "keyword"
103
+ },
104
+ required: false,
105
+ target: { attribute: "guide" },
106
+ description: "The idle marker of an anticipatory button: dot for contextual actions, or a slim neutral rounded bar for a panel-edge control. The icon appears on hover or\n keyboard focus; touch always shows the icon.",
107
+ values: ["dot", "bar"],
108
+ default: "dot"
109
+ },
94
110
  label: {
95
111
  type: {
96
112
  kind: "terminal",
@@ -185,6 +201,7 @@ var UiIconButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
185
201
  const acceptedProps = {
186
202
  anticipatory: false,
187
203
  disabled: false,
204
+ guide: "dot",
188
205
  label: null,
189
206
  loading: false,
190
207
  matchButton: false,
@@ -203,6 +220,10 @@ var UiIconButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
203
220
  kind: "terminal",
204
221
  name: "boolean"
205
222
  }, false, "disabled", acceptedProps),
223
+ guide: checkedProp(props["guide"], {
224
+ kind: "terminal",
225
+ name: "keyword"
226
+ }, false, "guide", acceptedProps),
206
227
  label: checkedProp(props["label"], {
207
228
  kind: "terminal",
208
229
  name: "string"
@@ -284,6 +305,8 @@ var UiIconButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
284
305
  checkedProps.value.tone && "tone",
285
306
  checkedProps.value.tone != null && `tone=${encodeURIComponent(checkedProps.value.tone)}`,
286
307
  checkedProps.value.anticipatory && "anticipatory",
308
+ checkedProps.value.guide && "guide",
309
+ checkedProps.value.guide != null && `guide=${encodeURIComponent(checkedProps.value.guide)}`,
287
310
  checkedProps.value.variant && "variant",
288
311
  checkedProps.value.variant != null && `variant=${encodeURIComponent(checkedProps.value.variant)}`,
289
312
  checkedProps.value.loading && "loading",
@@ -310,6 +333,7 @@ var UiIconButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
310
333
  propNames: [
311
334
  "anticipatory",
312
335
  "disabled",
336
+ "guide",
313
337
  "label",
314
338
  "loading",
315
339
  "matchButton",
@@ -349,6 +373,7 @@ var UiIconButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
349
373
  "aria-busy": checkedProps.value.loading || checkedProps.value.pending,
350
374
  "data-anticipatory": reflectedProp("anticipatory", "anticipatory", checkedProps.value.anticipatory, void 0, false),
351
375
  "data-disabled": reflectedProp("disabled", "disabled", checkedProps.value.disabled, void 0, false),
376
+ "data-guide": reflectedProp("guide", "guide", checkedProps.value.guide, void 0, false),
352
377
  "data-label": reflectedProp("label", "label", checkedProps.value.label, void 0, false),
353
378
  "data-loading": reflectedProp("loading", "loading", checkedProps.value.loading, void 0, false),
354
379
  "data-match-button": reflectedProp("matchButton", "match-button", checkedProps.value.matchButton, void 0, true),
@@ -369,6 +394,6 @@ var UiIconButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
369
394
  }]]);
370
395
  };
371
396
  }
372
- }), [["__scopeId", "data-v-219fa683"]]);
397
+ }), [["__scopeId", "data-v-ea2a5496"]]);
373
398
  //#endregion
374
399
  export { UiIconButton_default as t };
@@ -148,7 +148,7 @@ var UiTooltip_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
148
148
  },
149
149
  required: false,
150
150
  target: { attribute: "trigger" },
151
- description: "How the trigger opens it. hover also opens on keyboard focus; click toggles it and suits a help button, where hovering a question mark says nothing; focus\n opens only while the trigger holds focus.",
151
+ description: "How the trigger opens it. hover also opens on keyboard focus; click toggles it and suits a help button, where hovering a question mark says nothing; focus\n opens only on keyboard-visible focus. Action activation dismisses hover/focus hints without removing focus; a fresh hover or keyboard focus can open them\n again.",
152
152
  values: [
153
153
  "hover",
154
154
  "click",
@@ -299,6 +299,6 @@ var UiTooltip_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
299
299
  }]]);
300
300
  };
301
301
  }
302
- }), [["__scopeId", "data-v-a876d863"]]);
302
+ }), [["__scopeId", "data-v-4a6fb61a"]]);
303
303
  //#endregion
304
304
  export { UiTooltip_default as t };