@threadlabs/looma 0.29.17 → 0.29.18

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.29.17",
3
+ "version": "0.29.18",
4
4
  "type": "module",
5
5
  "description": "Looma components as HTML, Vue, and plain DOM, with design tokens.",
6
6
  "license": "MIT",
@@ -28,6 +28,14 @@
28
28
  block-size: var(--ui-icon-size, var(--_ui-default-icon-size, 1em));
29
29
  }
30
30
 
31
+ :scope:where([data-component~="ui-icon"])[data-ui-icon-state~="tone=secondary"] {
32
+ color: var(--ui-text-secondary);
33
+ }
34
+
35
+ :scope:where([data-component~="ui-icon"])[data-ui-icon-state~="tone=muted"] {
36
+ color: var(--ui-text-muted);
37
+ }
38
+
31
39
  svg {
32
40
  inline-size: 100%;
33
41
  block-size: 100%;
@@ -3,9 +3,9 @@ import { attachGeneratedController, buildTemplate, clearRegion, NONCONFORMING, r
3
3
  import * as controller from "../components/ui-editor-link-card/ui-editor-link-card.js";
4
4
  import "../styles/ui-editor-link-card.css";
5
5
 
6
- const T0 = ["",[],"\n ",["ui-card",["variant","elevated","padding","xs","size","content"],["ui-cluster",["gap","xs","wrap","nowrap","role","group","aria-label","Link actions"],["ui-icon",[]],"\n ",["ui-stack",["gap","none"],["ui-text",["as","strong","size","sm","weight","medium","font","sans","wrap","anywhere"],0],"\n ",1],"\n ",1,"\n ",["ui-icon-button",["label","Edit link","variant","ghost","size","sm","data-link-action","edit"],["ui-icon",["name","pencil"]]],"\n ",["ui-tooltip",[],"Edit link"],"\n ",["ui-icon-button",["label","Remove link","variant","ghost","size","sm","data-link-action","remove"],["ui-icon",["name","unlink"]]],"\n ",["ui-tooltip",[],"Remove link"]]],"\n "];
7
- const T1 = ["ui-text",["as","small","size","xs","tone","secondary","font","sans"],0];
8
- const T2 = ["",[],"\n ",["ui-button",["as","a","variant","ghost","tone","neutral","size","sm","target","_blank","rel","noopener noreferrer","aria-label","Open link"],["ui-cluster",["gap","xs","wrap","nowrap"],["ui-icon",["name","external-link"]],"Open link"]],"\n ",["ui-tooltip",[],"Open link"],"\n "];
6
+ const T0 = ["",[],"\n ",["ui-card",["variant","elevated","padding","xs","size","sm"],["ui-cluster",["gap","xs","wrap","nowrap","role","group","aria-label","Link actions"],["ui-icon",[]],"\n ",["ui-stack",["gap","none","fill",""],["ui-text",["as","strong","size","sm","weight","medium","font","sans","truncate",""],0],"\n ",1],"\n ",1,"\n ",["ui-icon-button",["label","Edit link","variant","ghost","size","sm","data-link-action","edit"],["ui-icon",["name","pencil"]]],"\n ",["ui-tooltip",[],"Edit link"],"\n ",["ui-icon-button",["label","Remove link","variant","ghost","size","sm","data-link-action","remove"],["ui-icon",["name","unlink"]]],"\n ",["ui-tooltip",[],"Remove link"]]],"\n "];
7
+ const T1 = ["ui-text",["as","small","size","xs","tone","secondary","font","sans","truncate",""],0];
8
+ const T2 = ["",[],"\n ",["ui-button",["as","a","variant","ghost","tone","neutral","size","sm","target","_blank","rel","noopener noreferrer","aria-label","Open link"],["ui-icon",["name","external-link"]]],"\n ",["ui-tooltip",[],"Open link"],"\n "];
9
9
  let P0, P1, P2;
10
10
  const S = { n: ["base","resolved","shown"], t: ["s","?","?"], f: import.meta.url, g: "ui-editor-link-card", k: 1, d: { "edit": [detailCheck(checkRecord(checkUnknown)), true, true, false], "remove": [detailCheck(checkRecord(checkUnknown)), true, true, false] }, x: dispatchDeclared, r: readonlyView };
11
11
  const D = { g: "ui-editor-link-card", props: { "detail": { "required":false,"default":"", c: checkString, t: "string", j: 0, m: "s" }, "href": { "required":false,"default":"", c: checkString, t: "string", j: 0, m: "s" }, "label": { "required":false,"default":"", c: checkString, t: "string", j: 0, m: "s" }, "openHref": { "required":false,"default":"", c: checkString, t: "string", j: 0, m: "s" }, "targetLabel": { "required":false,"default":"Item", c: checkString, t: "string", j: 0, m: "s" } } };
@@ -7,6 +7,7 @@ export interface UiIconElement extends HTMLSpanElement {
7
7
  }
8
8
  export interface UiIconProps {
9
9
  name?: string | null;
10
+ tone?: "inherit" | "secondary" | "muted" | null;
10
11
  attributes?: Readonly<Record<string, string | number | boolean | null | undefined>>;
11
12
  children?: readonly (string | Node)[];
12
13
  slots?: Readonly<Record<string, readonly (string | Node)[]>>;
package/vanilla/UiIcon.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // Generated by HTML Next 1.0.0-alpha.57 for Vanilla DOM. Do not edit.
2
- import { attachGeneratedController, buildTemplate, clearRegion, readIndex, readMember, toAttribute, trackContainer, writeAttribute, computedCycle, IndexedList, acceptProps, manageProps, readonlyView, checkString } from "@nextwebwg/html-next/generated-runtime";
2
+ import { attachGeneratedController, buildTemplate, clearRegion, readIndex, readMember, toAttribute, trackContainer, writeAttribute, computedCycle, IndexedList, formatOf, keywordFormat, hostState, acceptProps, manageProps, readonlyView, checkFormat, checkString } from "@nextwebwg/html-next/generated-runtime";
3
3
  import "../styles/ui-icon.css";
4
4
 
5
5
  const T0 = ["",[],"\n ",["svg",["viewBox","0 0 24 24","fill","none","stroke","currentColor","stroke-width","2","stroke-linecap","round","stroke-linejoin","round","focusable","false"],2],"\n "];
@@ -11,7 +11,7 @@ const T5 = ["line",[]];
11
11
  let P0, P1, P2, P3, P4, P5;
12
12
  const E = new Map();
13
13
  const S = { n: ["shapes"], t: ["?"], f: import.meta.url, g: "ui-icon", k: 0, r: readonlyView };
14
- const D = { g: "ui-icon", props: { "name": { "required":false,"default":"", c: checkString, t: "string", j: 0, m: "s" } } };
14
+ const D = { g: "ui-icon", props: { "name": { "required":false,"default":"", c: checkString, t: "string", j: 0, m: "s" }, "tone": { "required":false,"values":["inherit","secondary","muted"],"default":"inherit", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] } } };
15
15
 
16
16
  export function createUiIcon(options = {}, html) {
17
17
  const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
@@ -23,7 +23,7 @@ export function createUiIcon(options = {}, html) {
23
23
  if (!element.hasAttribute("aria-hidden")) element.setAttribute("aria-hidden", "true");
24
24
  element.setAttribute("data-component", "ui-icon");
25
25
  element.append((P0 ??= buildTemplate(T0)).cloneNode(true));
26
- const v = [undefined, null];
26
+ const v = [undefined, null, null];
27
27
  const B = acceptProps(element, D, S.n, v, componentProps, [], html);
28
28
  const X = { e: 0, g: (j) => g(j), w: new Set() };
29
29
  const ke = [];
@@ -156,10 +156,15 @@ export function createUiIcon(options = {}, html) {
156
156
  }
157
157
  };
158
158
  const p0 = (r, c, d) => {
159
+ if (c & 4) {
160
+ const x0 = hostState(["tone"], [v[2]]);
161
+ const s0 = x0;
162
+ if (s0 !== r.v0) writeAttribute(r.n, "data-ui-icon-state", (r.v0 = s0) === "" ? null : s0);
163
+ }
159
164
  if (c & 1073741826) r.L0.update(g(0), d, c);
160
165
  };
161
166
  const t0 = element.firstChild.nextSibling.firstChild;
162
- const R = { L0: new IndexedList(t0, t0.nextSibling, m1, p1, undefined, "shape") };
167
+ const R = { n: element, v0: undefined, L0: new IndexedList(t0, t0.nextSibling, m1, p1, undefined, "shape") };
163
168
  const I = { B };
164
169
  attachGeneratedController(element, S, v, ((c, d) => p0(R, c, d)), undefined, X, I);
165
170
  manageProps(I);
package/vue/UiBadge.d.ts CHANGED
@@ -41,8 +41,8 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
41
41
  };
42
42
  }>> & Readonly<{}>, {
43
43
  size: "xs" | "sm" | "md" | "lg" | null;
44
- shape: "circle" | "dot" | "tag" | "square" | "pill" | null;
45
44
  tone: "info" | "neutral" | "accent" | "success" | "warning" | "danger" | null;
45
+ shape: "circle" | "dot" | "tag" | "square" | "pill" | null;
46
46
  variant: "solid" | "subtle" | "outline" | "inverse" | "overlay" | null;
47
47
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
48
48
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
package/vue/UiButton.d.ts CHANGED
@@ -138,8 +138,8 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
138
138
  }>> & Readonly<{}>, {
139
139
  type: "button" | "reset" | "submit" | null;
140
140
  size: "xs" | "sm" | "md" | "lg" | null;
141
- shape: "pill" | "rounded" | null;
142
141
  tone: "info" | "neutral" | "accent" | "success" | "warning" | "danger" | null;
142
+ shape: "pill" | "rounded" | null;
143
143
  variant: "link" | "field" | "danger" | "solid" | "outline" | "ghost" | "card" | null;
144
144
  align: "center" | "start" | null;
145
145
  as: "a" | "button" | null;
@@ -267,16 +267,17 @@ useComponentHost(() => import('../components/ui-editor-link-card/ui-editor-link-
267
267
  :data-ui-editor-link-card-prop-target-label="reflectedProp('targetLabel', 'target-label', checkedProps.targetLabel, undefined, false)"
268
268
  ref="root"
269
269
  >
270
- <UiCard variant="elevated" padding="xs" size="content"><UiCluster
270
+ <UiCard variant="elevated" padding="xs" size="sm"><UiCluster
271
271
  gap="xs"
272
272
  wrap="nowrap"
273
273
  role="group"
274
274
  aria-label="Link actions"
275
275
  ><UiIcon :name="guarded" />{{ ' ' }}<UiStack
276
276
  gap="none"
277
+ :fill="true"
277
278
  :title="checkedProps.href"
278
279
  :aria-label="guardedBinding"
279
- ><UiText as="strong" size="sm" weight="medium" font="sans" wrap="anywhere">{{
280
+ ><UiText as="strong" size="sm" weight="medium" font="sans" :truncate="true">{{
280
281
  text(shown)
281
282
  }}</UiText>{{ ' ' }}<UiText
282
283
  v-if="checkedProps.detail !== ''"
@@ -284,6 +285,7 @@ useComponentHost(() => import('../components/ui-editor-link-card/ui-editor-link-
284
285
  size="xs"
285
286
  tone="secondary"
286
287
  font="sans"
288
+ :truncate="true"
287
289
  >{{ checkedProps.detail }}</UiText></UiStack>{{ ' ' }}<template
288
290
  v-if="checkedProps.openHref !== ''"
289
291
  >{{ ' ' }}<UiButton
@@ -296,8 +298,7 @@ useComponentHost(() => import('../components/ui-editor-link-card/ui-editor-link-
296
298
  aria-label="Open link"
297
299
  :id="guardedBinding2"
298
300
  :href="checkedProps.openHref"
299
- ><UiCluster gap="xs" wrap="nowrap"><UiIcon name="external-link" />Open
300
- link</UiCluster></UiButton>{{ ' ' }}<UiTooltip :for="guardedBinding3"
301
+ ><UiIcon name="external-link" /></UiButton>{{ ' ' }}<UiTooltip :for="guardedBinding3"
301
302
  >Open link</UiTooltip>{{ ' ' }}</template>{{ ' ' }}<UiIconButton
302
303
  label="Edit link"
303
304
  variant="ghost"
package/vue/UiIcon.d.ts CHANGED
@@ -4,13 +4,22 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
4
4
  type: PropType<string | null>;
5
5
  default: string;
6
6
  };
7
+ tone: {
8
+ type: PropType<"inherit" | "secondary" | "muted" | null>;
9
+ default: string;
10
+ };
7
11
  }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
8
12
  name: {
9
13
  type: PropType<string | null>;
10
14
  default: string;
11
15
  };
16
+ tone: {
17
+ type: PropType<"inherit" | "secondary" | "muted" | null>;
18
+ default: string;
19
+ };
12
20
  }>> & Readonly<{}>, {
13
21
  name: string | null;
22
+ tone: "secondary" | "inherit" | "muted" | null;
14
23
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
15
24
  declare const _default: typeof __VLS_export;
16
25
  export default _default;
package/vue/UiIcon.vue CHANGED
@@ -24,12 +24,25 @@ const propValidityContract = {
24
24
  'Which icon to draw, by its name in Looma\'s icon set (LOOMA_ICONS), such as "align-left". An unknown or empty name draws nothing. The icon is hidden from\n assistive technology, so name the control it sits in.',
25
25
  default: '',
26
26
  },
27
+ tone: {
28
+ type: { kind: 'terminal', name: 'keyword' },
29
+ required: false,
30
+ target: { attribute: 'tone' },
31
+ description:
32
+ 'Icon colour. inherit follows its control; secondary and muted keep a supporting icon quiet without a text wrapper.',
33
+ values: ['inherit', 'secondary', 'muted'],
34
+ default: 'inherit',
35
+ },
27
36
  },
28
37
  } as const
29
38
  const props = defineProps({
30
39
  name: { type: null as unknown as PropType<string | null>, default: '' },
40
+ tone: {
41
+ type: null as unknown as PropType<'inherit' | 'secondary' | 'muted' | null>,
42
+ default: 'inherit',
43
+ },
31
44
  })
32
- const acceptedProps: Record<string, unknown> = { name: '' }
45
+ const acceptedProps: Record<string, unknown> = { name: '', tone: 'inherit' }
33
46
  const checkedProps = computed(() => ({
34
47
  name: checkedProp<string>(
35
48
  props['name'],
@@ -38,6 +51,13 @@ const checkedProps = computed(() => ({
38
51
  'name',
39
52
  acceptedProps,
40
53
  ) as string,
54
+ tone: checkedProp<'inherit' | 'secondary' | 'muted'>(
55
+ props['tone'],
56
+ { kind: 'terminal', name: 'keyword' },
57
+ false,
58
+ 'tone',
59
+ acceptedProps,
60
+ ) as 'inherit' | 'secondary' | 'muted',
41
61
  }))
42
62
  void checkedProps.value
43
63
  watchSyncEffect(() => {
@@ -418,6 +438,14 @@ const shapes = cycleCheckedComputed(() =>
418
438
  }) as Record<string, any>)[checkedProps.value.name]
419
439
  )
420
440
  checkHydratedRoot('span', 'ui-icon')
441
+
442
+ /** The values the styles' :host() prop and state rules test. */
443
+ const hostState = computed(() =>
444
+ [
445
+ checkedProps.value.tone && 'tone',
446
+ checkedProps.value.tone != null && `tone=${encodeURIComponent(checkedProps.value.tone)}`,
447
+ ].filter(Boolean).join(' ')
448
+ )
421
449
  </script>
422
450
 
423
451
  <template>
@@ -428,6 +456,8 @@ checkHydratedRoot('span', 'ui-icon')
428
456
  data-hn
429
457
  v-prop-validity="{ contract: propValidityContract, values: { ...props } }"
430
458
  :data-ui-icon-prop-name="reflectedProp('name', 'name', checkedProps.name, undefined, false)"
459
+ :data-ui-icon-prop-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
460
+ :data-ui-icon-state="hostState || undefined"
431
461
  ><svg
432
462
  viewBox="0 0 24 24"
433
463
  fill="none"
@@ -493,6 +523,14 @@ checkHydratedRoot('span', 'ui-icon')
493
523
  block-size: var(--ui-icon-size, var(--_ui-default-icon-size, 1em));
494
524
  }
495
525
 
526
+ :global(:scope[data-ui-icon-state~="tone=secondary"]) {
527
+ color: var(--ui-text-secondary);
528
+ }
529
+
530
+ :global(:scope[data-ui-icon-state~="tone=muted"]) {
531
+ color: var(--ui-text-muted);
532
+ }
533
+
496
534
  :global(svg) {
497
535
  inline-size: 100%;
498
536
  block-size: 100%;
package/vue/UiText.d.ts CHANGED
@@ -117,7 +117,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
117
117
  size: "inherit" | "xs" | "sm" | "md" | "lg" | null;
118
118
  trim: boolean | null;
119
119
  font: "inherit" | "sans" | null;
120
- tone: "default" | "secondary" | "info" | "accent" | "success" | "warning" | "danger" | "muted" | null;
120
+ tone: "default" | "secondary" | "muted" | "info" | "accent" | "success" | "warning" | "danger" | null;
121
121
  variant: "code" | "body" | "eyebrow" | null;
122
122
  align: "center" | "start" | null;
123
123
  as: "div" | "h2" | "h3" | "h4" | "h5" | "h6" | "label" | "p" | "small" | "span" | "strong" | null;
@@ -255,7 +255,7 @@ var UiEditorLinkCard_default = /* @__PURE__ */ defineComponent({
255
255
  }), [createVNode(UiCard_default, {
256
256
  variant: "elevated",
257
257
  padding: "xs",
258
- size: "content"
258
+ size: "sm"
259
259
  }, {
260
260
  default: withCtx(() => [createVNode(UiCluster_default, {
261
261
  gap: "xs",
@@ -265,9 +265,10 @@ var UiEditorLinkCard_default = /* @__PURE__ */ defineComponent({
265
265
  }, {
266
266
  default: withCtx(() => [
267
267
  createVNode(UiIcon_default, { name: guarded.value }, null, 8, ["name"]),
268
- _cache[8] || (_cache[8] = createTextVNode(toDisplayString(" "), -1)),
268
+ _cache[7] || (_cache[7] = createTextVNode(toDisplayString(" "), -1)),
269
269
  createVNode(UiStack_default, {
270
270
  gap: "none",
271
+ fill: true,
271
272
  title: checkedProps.value.href,
272
273
  "aria-label": guardedBinding.value
273
274
  }, {
@@ -277,7 +278,7 @@ var UiEditorLinkCard_default = /* @__PURE__ */ defineComponent({
277
278
  size: "sm",
278
279
  weight: "medium",
279
280
  font: "sans",
280
- wrap: "anywhere"
281
+ truncate: true
281
282
  }, {
282
283
  default: withCtx(() => [createTextVNode(toDisplayString(unref(text)(unref(shown))), 1)]),
283
284
  _: 1
@@ -288,7 +289,8 @@ var UiEditorLinkCard_default = /* @__PURE__ */ defineComponent({
288
289
  as: "small",
289
290
  size: "xs",
290
291
  tone: "secondary",
291
- font: "sans"
292
+ font: "sans",
293
+ truncate: true
292
294
  }, {
293
295
  default: withCtx(() => [createTextVNode(toDisplayString(checkedProps.value.detail), 1)]),
294
296
  _: 1
@@ -296,9 +298,9 @@ var UiEditorLinkCard_default = /* @__PURE__ */ defineComponent({
296
298
  ]),
297
299
  _: 1
298
300
  }, 8, ["title", "aria-label"]),
299
- _cache[9] || (_cache[9] = createTextVNode(toDisplayString(" "), -1)),
301
+ _cache[8] || (_cache[8] = createTextVNode(toDisplayString(" "), -1)),
300
302
  checkedProps.value.openHref !== "" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
301
- _cache[3] || (_cache[3] = createTextVNode(toDisplayString(" "), -1)),
303
+ _cache[2] || (_cache[2] = createTextVNode(toDisplayString(" "), -1)),
302
304
  createVNode(UiButton_default, {
303
305
  as: "a",
304
306
  variant: "ghost",
@@ -310,23 +312,17 @@ var UiEditorLinkCard_default = /* @__PURE__ */ defineComponent({
310
312
  id: guardedBinding2.value,
311
313
  href: checkedProps.value.openHref
312
314
  }, {
313
- default: withCtx(() => [createVNode(UiCluster_default, {
314
- gap: "xs",
315
- wrap: "nowrap"
316
- }, {
317
- default: withCtx(() => [createVNode(UiIcon_default, { name: "external-link" }), _cache[1] || (_cache[1] = createTextVNode("Open link", -1))]),
318
- _: 1
319
- })]),
315
+ default: withCtx(() => [createVNode(UiIcon_default, { name: "external-link" })]),
320
316
  _: 1
321
317
  }, 8, ["id", "href"]),
322
- _cache[4] || (_cache[4] = createTextVNode(toDisplayString(" "), -1)),
318
+ _cache[3] || (_cache[3] = createTextVNode(toDisplayString(" "), -1)),
323
319
  createVNode(UiTooltip_default, { for: guardedBinding3.value }, {
324
- default: withCtx(() => [..._cache[2] || (_cache[2] = [createTextVNode("Open link", -1)])]),
320
+ default: withCtx(() => [..._cache[1] || (_cache[1] = [createTextVNode("Open link", -1)])]),
325
321
  _: 1
326
322
  }, 8, ["for"]),
327
- _cache[5] || (_cache[5] = createTextVNode(toDisplayString(" "), -1))
323
+ _cache[4] || (_cache[4] = createTextVNode(toDisplayString(" "), -1))
328
324
  ], 64)) : createCommentVNode("v-if", true),
329
- _cache[10] || (_cache[10] = createTextVNode(toDisplayString(" "), -1)),
325
+ _cache[9] || (_cache[9] = createTextVNode(toDisplayString(" "), -1)),
330
326
  createVNode(UiIconButton_default, {
331
327
  label: "Edit link",
332
328
  variant: "ghost",
@@ -337,12 +333,12 @@ var UiEditorLinkCard_default = /* @__PURE__ */ defineComponent({
337
333
  default: withCtx(() => [createVNode(UiIcon_default, { name: "pencil" })]),
338
334
  _: 1
339
335
  }, 8, ["id"]),
340
- _cache[11] || (_cache[11] = createTextVNode(toDisplayString(" "), -1)),
336
+ _cache[10] || (_cache[10] = createTextVNode(toDisplayString(" "), -1)),
341
337
  createVNode(UiTooltip_default, { for: guardedBinding5.value }, {
342
- default: withCtx(() => [..._cache[6] || (_cache[6] = [createTextVNode("Edit link", -1)])]),
338
+ default: withCtx(() => [..._cache[5] || (_cache[5] = [createTextVNode("Edit link", -1)])]),
343
339
  _: 1
344
340
  }, 8, ["for"]),
345
- _cache[12] || (_cache[12] = createTextVNode(toDisplayString(" "), -1)),
341
+ _cache[11] || (_cache[11] = createTextVNode(toDisplayString(" "), -1)),
346
342
  createVNode(UiIconButton_default, {
347
343
  label: "Remove link",
348
344
  variant: "ghost",
@@ -353,9 +349,9 @@ var UiEditorLinkCard_default = /* @__PURE__ */ defineComponent({
353
349
  default: withCtx(() => [createVNode(UiIcon_default, { name: "unlink" })]),
354
350
  _: 1
355
351
  }, 8, ["id"]),
356
- _cache[13] || (_cache[13] = createTextVNode(toDisplayString(" "), -1)),
352
+ _cache[12] || (_cache[12] = createTextVNode(toDisplayString(" "), -1)),
357
353
  createVNode(UiTooltip_default, { for: guardedBinding7.value }, {
358
- default: withCtx(() => [..._cache[7] || (_cache[7] = [createTextVNode("Remove link", -1)])]),
354
+ default: withCtx(() => [..._cache[6] || (_cache[6] = [createTextVNode("Remove link", -1)])]),
359
355
  _: 1
360
356
  }, 8, ["for"])
361
357
  ]),
@@ -2,7 +2,11 @@ import { d as list, i as checkHydratedRoot, p as nativeAttrs, r as attribute, s
2
2
  import { a as vPropValidity, n as checkedProp } from "./props.js";
3
3
  import { Fragment, computed, createCommentVNode, createElementBlock, defineComponent, mergeProps, openBlock, renderList, unref, watchSyncEffect, withDirectives } from "vue";
4
4
  //#region .build/vue/UiIcon.vue?vue&type=script&setup=true&lang.ts
5
- var _hoisted_1 = ["data-ui-icon-prop-name"];
5
+ var _hoisted_1 = [
6
+ "data-ui-icon-prop-name",
7
+ "data-ui-icon-prop-tone",
8
+ "data-ui-icon-state"
9
+ ];
6
10
  var _hoisted_2 = {
7
11
  viewBox: "0 0 24 24",
8
12
  fill: "none",
@@ -37,27 +41,59 @@ var _hoisted_6 = [
37
41
  var UiIcon_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
38
42
  inheritAttrs: false,
39
43
  __name: "UiIcon",
40
- props: { name: {
41
- type: null,
42
- default: ""
43
- } },
44
+ props: {
45
+ name: {
46
+ type: null,
47
+ default: ""
48
+ },
49
+ tone: {
50
+ type: null,
51
+ default: "inherit"
52
+ }
53
+ },
44
54
  setup(__props) {
45
- const propValidityContract = { props: { name: {
46
- type: {
47
- kind: "terminal",
48
- name: "string"
55
+ const propValidityContract = { props: {
56
+ name: {
57
+ type: {
58
+ kind: "terminal",
59
+ name: "string"
60
+ },
61
+ required: false,
62
+ target: { attribute: "name" },
63
+ description: "Which icon to draw, by its name in Looma's icon set (LOOMA_ICONS), such as \"align-left\". An unknown or empty name draws nothing. The icon is hidden from\n assistive technology, so name the control it sits in.",
64
+ default: ""
49
65
  },
50
- required: false,
51
- target: { attribute: "name" },
52
- description: "Which icon to draw, by its name in Looma's icon set (LOOMA_ICONS), such as \"align-left\". An unknown or empty name draws nothing. The icon is hidden from\n assistive technology, so name the control it sits in.",
53
- default: ""
54
- } } };
66
+ tone: {
67
+ type: {
68
+ kind: "terminal",
69
+ name: "keyword"
70
+ },
71
+ required: false,
72
+ target: { attribute: "tone" },
73
+ description: "Icon colour. inherit follows its control; secondary and muted keep a supporting icon quiet without a text wrapper.",
74
+ values: [
75
+ "inherit",
76
+ "secondary",
77
+ "muted"
78
+ ],
79
+ default: "inherit"
80
+ }
81
+ } };
55
82
  const props = __props;
56
- const acceptedProps = { name: "" };
57
- const checkedProps = computed(() => ({ name: checkedProp(props["name"], {
58
- kind: "terminal",
59
- name: "string"
60
- }, false, "name", acceptedProps) }));
83
+ const acceptedProps = {
84
+ name: "",
85
+ tone: "inherit"
86
+ };
87
+ const checkedProps = computed(() => ({
88
+ name: checkedProp(props["name"], {
89
+ kind: "terminal",
90
+ name: "string"
91
+ }, false, "name", acceptedProps),
92
+ tone: checkedProp(props["tone"], {
93
+ kind: "terminal",
94
+ name: "keyword"
95
+ }, false, "tone", acceptedProps)
96
+ }));
61
97
  checkedProps.value;
62
98
  watchSyncEffect(() => {
63
99
  checkedProps.value;
@@ -1157,13 +1193,17 @@ var UiIcon_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
1157
1193
  }]
1158
1194
  })[checkedProps.value.name]);
1159
1195
  checkHydratedRoot("span", "ui-icon");
1196
+ /** The values the styles' :host() prop and state rules test. */
1197
+ const hostState = computed(() => [checkedProps.value.tone && "tone", checkedProps.value.tone != null && `tone=${encodeURIComponent(checkedProps.value.tone)}`].filter(Boolean).join(" "));
1160
1198
  return (_ctx, _cache) => {
1161
1199
  return withDirectives((openBlock(), createElementBlock("span", mergeProps({
1162
1200
  class: "ui-icon",
1163
1201
  "aria-hidden": "true"
1164
1202
  }, unref(nativeAttrs)(_ctx.$attrs), {
1165
1203
  "data-hn": "",
1166
- "data-ui-icon-prop-name": unref(reflectedProp)("name", "name", checkedProps.value.name, void 0, false)
1204
+ "data-ui-icon-prop-name": unref(reflectedProp)("name", "name", checkedProps.value.name, void 0, false),
1205
+ "data-ui-icon-prop-tone": unref(reflectedProp)("tone", "tone", checkedProps.value.tone, void 0, false),
1206
+ "data-ui-icon-state": hostState.value || void 0
1167
1207
  }), [(openBlock(), createElementBlock("svg", _hoisted_2, [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(list)(unref(shapes)), (shape, index) => {
1168
1208
  return openBlock(), createElementBlock("g", { key: index }, [
1169
1209
  shape.tag === "path" ? (openBlock(), createElementBlock("path", {
@@ -1199,6 +1239,6 @@ var UiIcon_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
1199
1239
  }]]);
1200
1240
  };
1201
1241
  }
1202
- }), [["__scopeId", "data-v-effc7962"]]);
1242
+ }), [["__scopeId", "data-v-39bdd7d1"]]);
1203
1243
  //#endregion
1204
1244
  export { UiIcon_default as t };
@@ -100,6 +100,12 @@
100
100
  inline-size: var(--ui-icon-size, var(--_ui-default-icon-size, 1em));
101
101
  block-size: var(--ui-icon-size, var(--_ui-default-icon-size, 1em));
102
102
  }
103
+ :scope[data-ui-icon-state~="tone=secondary"] {
104
+ color: var(--ui-text-secondary);
105
+ }
106
+ :scope[data-ui-icon-state~="tone=muted"] {
107
+ color: var(--ui-text-muted);
108
+ }
103
109
  svg {
104
110
  inline-size: 100%;
105
111
  block-size: 100%;
@@ -11829,6 +11835,14 @@ html[data-ui-input-modality="touch"]
11829
11835
  block-size: var(--ui-icon-size, var(--_ui-default-icon-size, 1em));
11830
11836
  }
11831
11837
 
11838
+ :scope:where([data-component~="ui-icon"])[data-ui-icon-state~="tone=secondary"] {
11839
+ color: var(--ui-text-secondary);
11840
+ }
11841
+
11842
+ :scope:where([data-component~="ui-icon"])[data-ui-icon-state~="tone=muted"] {
11843
+ color: var(--ui-text-muted);
11844
+ }
11845
+
11832
11846
  svg {
11833
11847
  inline-size: 100%;
11834
11848
  block-size: 100%;
@@ -5242,14 +5242,33 @@ var S$14 = {
5242
5242
  };
5243
5243
  var D$14 = {
5244
5244
  g: "ui-icon",
5245
- props: { "name": {
5246
- "required": false,
5247
- "default": "",
5248
- c: checkString,
5249
- t: "string",
5250
- j: 0,
5251
- m: "s"
5252
- } }
5245
+ props: {
5246
+ "name": {
5247
+ "required": false,
5248
+ "default": "",
5249
+ c: checkString,
5250
+ t: "string",
5251
+ j: 0,
5252
+ m: "s"
5253
+ },
5254
+ "tone": {
5255
+ "required": false,
5256
+ "values": [
5257
+ "inherit",
5258
+ "secondary",
5259
+ "muted"
5260
+ ],
5261
+ "default": "inherit",
5262
+ c: checkFormat("keyword", keywordFormat),
5263
+ t: "keyword",
5264
+ j: 0,
5265
+ m: [
5266
+ "p",
5267
+ formatOf(keywordFormat),
5268
+ false
5269
+ ]
5270
+ }
5271
+ }
5253
5272
  };
5254
5273
  function createUiIcon(options = {}, html) {
5255
5274
  const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
@@ -5261,7 +5280,11 @@ function createUiIcon(options = {}, html) {
5261
5280
  if (!element.hasAttribute("aria-hidden")) element.setAttribute("aria-hidden", "true");
5262
5281
  element.setAttribute("data-component", "ui-icon");
5263
5282
  element.append((P0$12 ??= buildTemplate(T0$12)).cloneNode(true));
5264
- const v = [void 0, null];
5283
+ const v = [
5284
+ void 0,
5285
+ null,
5286
+ null
5287
+ ];
5265
5288
  const B = acceptProps(element, D$14, S$14.n, v, componentProps, [], html);
5266
5289
  const X = {
5267
5290
  e: 0,
@@ -6562,10 +6585,18 @@ function createUiIcon(options = {}, html) {
6562
6585
  }
6563
6586
  };
6564
6587
  const p0 = (r, c, d) => {
6588
+ if (c & 4) {
6589
+ const s0 = hostState(["tone"], [v[2]]);
6590
+ if (s0 !== r.v0) writeAttribute(r.n, "data-ui-icon-state", (r.v0 = s0) === "" ? null : s0);
6591
+ }
6565
6592
  if (c & 1073741826) r.L0.update(g(0), d, c);
6566
6593
  };
6567
6594
  const t0 = element.firstChild.nextSibling.firstChild;
6568
- const R = { L0: new IndexedList(t0, t0.nextSibling, m1, p1, void 0, "shape") };
6595
+ const R = {
6596
+ n: element,
6597
+ v0: void 0,
6598
+ L0: new IndexedList(t0, t0.nextSibling, m1, p1, void 0, "shape")
6599
+ };
6569
6600
  const I = { B };
6570
6601
  attachGeneratedController(element, S$14, v, ((c, d) => p0(R, c, d)), void 0, X, I);
6571
6602
  manageProps(I);
@@ -11161,10 +11192,9 @@ var tableOfContentsNodeView = ({ editor, node, getPos }) => {
11161
11192
  size: "sm",
11162
11193
  anticipatory: true,
11163
11194
  attributes: { id },
11164
- children: [element(createUiText({
11165
- as: "span",
11166
- tone: "secondary",
11167
- children: [element(createUiIcon({ name: "settings" }))]
11195
+ children: [element(createUiIcon({
11196
+ name: "settings",
11197
+ tone: "secondary"
11168
11198
  }))]
11169
11199
  }));
11170
11200
  const revealSettings = () => updateComponentProps(settingsButton, { revealed: selected || hovered || settingsOpen });
@@ -14920,7 +14950,6 @@ var LoomaEditor = defineComponent({
14920
14950
  element,
14921
14951
  pluginKey: "looma-link-context-menu",
14922
14952
  shouldShow: ({ editor: menuEditor, from, to }) => (from === to || Boolean(selectedLinkReference(menuEditor))) && isLinkActive(menuEditor) && linkState.value.surface !== "popover" && !formatting?.dismissed(menuEditor.state.selection) && Boolean(menuEditor.isFocused || linkState.value.surface === "context" || linkPopup?.element.contains(document.activeElement)) && !(props.toolbarMode === "contextual" && floatingFormattingMode() && formattingActive()),
14923
- maxWidth: () => Math.min(480, window.innerWidth - 24),
14924
14953
  related: editorRoot,
14925
14954
  onDismiss: (reason) => reason === "escape" ? dismissFormatting() : linkPopup?.hide()
14926
14955
  }));