@threadlabs/looma 0.13.3 → 0.13.4

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/editor/icons.d.ts CHANGED
@@ -26,6 +26,7 @@ export declare const LOOMA_ICONS: {
26
26
  'heading-1': IconNode;
27
27
  'heading-2': IconNode;
28
28
  'heading-3': IconNode;
29
+ help: IconNode;
29
30
  highlighter: IconNode;
30
31
  image: IconNode;
31
32
  info: IconNode;
package/editor/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { n as TABLE_CELL_BACKGROUND_PRESETS, t as TABLE_CELL_BACKGROUND_OPTIONS } from "./chunks/table-backgrounds.js";
2
2
  import { n as resolveTableCellAt, t as measureTableOverlayGeometry } from "./chunks/ui.js";
3
3
  import { A as LOOMA_ACTIVE_BLOCK_CLASS, C as DEFAULT_MENTION_RESULT_LIMIT, D as LOOMA_CALLOUT_TONES, E as normalizeMentionResultLimit, M as LoomaActiveBlock, N as LoomaActiveBlockPluginKey, O as LoomaCallout, S as createLoomaMentionExtension, T as filterLoomaMentionItems, _ as getActiveTableCellBackground, a as handleTableAction, b as LoomaSmartPaste, c as normalizeActiveTableColumnWidths, d as getDefaultEditorExtensions, f as getLoomaTableExtensions, g as getActiveTableCellAlignment, h as LoomaTableHeader, i as getActiveTableUiState, j as LOOMA_ACTIVE_BLOCK_TYPING_IDLE_MS, k as LOOMA_ACTIVE_BLOCK_BLUR_GRACE_MS, l as shouldShowTextFormattingToolbar, m as LoomaTableCell, n as createLoomaSlashCommandExtension, o as handleTableOverlayAction, p as LoomaTable, r as getDefaultSlashCommands, s as insertTableAtRange, t as LoomaSlashCommand, u as LoomaTableKit, v as setActiveTableCellAlignment, w as MAX_MENTION_RESULT_LIMIT, x as LoomaMentionSuggestionPluginKey, y as setActiveTableCellBackground } from "./chunks/extensions.js";
4
- import { AlignCenter, AlignLeft, AlignRight, ArrowLeft, Bold, BookUser, Braces, Calculator, ChevronDown, ChevronLeft, ChevronRight, CircleCheck, CircleX, CodeXml, Columns3, CreditCard, Ellipsis, Eraser, FileText, Folder, GripHorizontal, GripVertical, Heading1, Heading2, Heading3, Highlighter, Image, Info, Italic, LayoutDashboard, List, ListOrdered, ListTodo, LoaderCircle, Merge, Minus, NotebookPen, PaintBucket, PanelBottom, PanelLeft, PanelRight, PanelTop, Pilcrow, Plus, Quote, Receipt, Redo2, Rows3, Settings, Split, Strikethrough, Table2, Trash2, TriangleAlert, Truck, Underline, Undo2, Users } from "lucide";
4
+ import { AlignCenter, AlignLeft, AlignRight, ArrowLeft, Bold, BookUser, Braces, Calculator, ChevronDown, ChevronLeft, ChevronRight, CircleCheck, CircleQuestionMark, CircleX, CodeXml, Columns3, CreditCard, Ellipsis, Eraser, FileText, Folder, GripHorizontal, GripVertical, Heading1, Heading2, Heading3, Highlighter, Image, Info, Italic, LayoutDashboard, List, ListOrdered, ListTodo, LoaderCircle, Merge, Minus, NotebookPen, PaintBucket, PanelBottom, PanelLeft, PanelRight, PanelTop, Pilcrow, Plus, Quote, Receipt, Redo2, Rows3, Settings, Split, Strikethrough, Table2, Trash2, TriangleAlert, Truck, Underline, Undo2, Users } from "lucide";
5
5
  //#region src/editor/icons.ts
6
6
  /** The opinionated Lucide set used by Looma's shipped interaction surfaces. */
7
7
  var LOOMA_ICONS = {
@@ -30,6 +30,7 @@ var LOOMA_ICONS = {
30
30
  "heading-1": Heading1,
31
31
  "heading-2": Heading2,
32
32
  "heading-3": Heading3,
33
+ help: CircleQuestionMark,
33
34
  highlighter: Highlighter,
34
35
  image: Image,
35
36
  info: Info,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@threadlabs/looma",
3
- "version": "0.13.3",
3
+ "version": "0.13.4",
4
4
  "type": "module",
5
5
  "description": "Looma components as HTML, Vue, and plain DOM, with design tokens.",
6
6
  "license": "MIT",
@@ -41,6 +41,15 @@
41
41
  :scope[data-ui-cluster-state~="align=stretch"] {
42
42
  align-items: stretch;
43
43
  }
44
+ :scope[data-ui-cluster-state~="justify=center"] {
45
+ justify-content: center;
46
+ }
47
+ :scope[data-ui-cluster-state~="justify=end"] {
48
+ justify-content: flex-end;
49
+ }
50
+ :scope[data-ui-cluster-state~="justify=between"] {
51
+ justify-content: space-between;
52
+ }
44
53
 
45
54
  /* A component that sets its display still honours the hidden attribute on its root. */
46
55
  :scope[hidden] {
@@ -249,6 +249,10 @@
249
249
 
250
250
  :scope {
251
251
  --_icon-button-icon-default: var(--ui-icon-size-md);
252
+ /* A slotted ui-icon is its own component, out of reach of the svg rule below; these are its
253
+ defaults, which its own --ui-icon-* hooks still override. */
254
+ --_ui-default-icon-size: var(--_ui-icon-button-icon-size, var(--_icon-button-icon-default));
255
+ --_ui-default-icon-stroke-width: var(--_ui-icon-button-icon-stroke-width, 1.75);
252
256
  }
253
257
 
254
258
  :scope[data-ui-icon-button-state~="size=sm"] {
@@ -8,6 +8,7 @@ export interface UiClusterElement extends HTMLDivElement {
8
8
  export interface UiClusterProps {
9
9
  align?: "start" | "center" | "end" | "stretch" | null;
10
10
  gap?: "xs" | "s" | "m" | "l" | "xl" | null;
11
+ justify?: "start" | "center" | "end" | "between" | null;
11
12
  attributes?: Readonly<Record<string, string | number | boolean | null | undefined>>;
12
13
  children?: readonly (string | Node)[];
13
14
  slots?: Readonly<Record<string, readonly (string | Node)[]>>;
@@ -7,6 +7,7 @@ export function createUiCluster(options = {}) {
7
7
  const projected = [];
8
8
  const prop0 = componentProps["align"] === undefined ? undefined : componentProps["align"];
9
9
  const prop1 = componentProps["gap"] === undefined ? undefined : componentProps["gap"];
10
+ const prop2 = componentProps["justify"] === undefined ? undefined : componentProps["justify"];
10
11
  const element = document.createElement("div");
11
12
  for (const [name, value] of Object.entries(attributes)) {
12
13
  if (value === null || value === undefined || value === false) continue;
@@ -24,6 +25,7 @@ export function createUiCluster(options = {}) {
24
25
  manageGeneratedProps(element, [
25
26
  { name: "align", attribute: "data-align", value: componentProps["align"], type: ["start","center","end","stretch"], required: false },
26
27
  { name: "gap", attribute: "data-gap", value: componentProps["gap"], type: ["xs","s","m","l","xl"], required: false },
28
+ { name: "justify", attribute: "data-justify", value: componentProps["justify"], type: ["start","center","end","between"], required: false },
27
29
  ]);
28
30
  return element;
29
31
  }
@@ -1,6 +1,7 @@
1
1
  type __VLS_Props = {
2
2
  align?: 'start' | 'center' | 'end' | 'stretch';
3
3
  gap?: 'xs' | 's' | 'm' | 'l' | 'xl';
4
+ justify?: 'start' | 'center' | 'end' | 'between';
4
5
  };
5
6
  declare var __VLS_1: {};
6
7
  type __VLS_Slots = {} & {
package/vue/UiCluster.vue CHANGED
@@ -7,6 +7,7 @@ defineOptions({ inheritAttrs: false })
7
7
  const props = defineProps<{
8
8
  align?: 'start' | 'center' | 'end' | 'stretch'
9
9
  gap?: 'xs' | 's' | 'm' | 'l' | 'xl'
10
+ justify?: 'start' | 'center' | 'end' | 'between'
10
11
  }>()
11
12
 
12
13
  /** The values the styles' :host-state() rules test. */
@@ -14,6 +15,7 @@ const hostState = computed(() =>
14
15
  [
15
16
  props.gap && `gap gap=${props.gap}`,
16
17
  props.align && `align align=${props.align}`,
18
+ props.justify && `justify justify=${props.justify}`,
17
19
  ].filter(Boolean).join(' ')
18
20
  )
19
21
  </script>
@@ -66,6 +68,15 @@ const hostState = computed(() =>
66
68
  [data-component~="ui-cluster"][data-ui-cluster-state~="align=stretch"] {
67
69
  align-items: stretch;
68
70
  }
71
+ [data-component~="ui-cluster"][data-ui-cluster-state~="justify=center"] {
72
+ justify-content: center;
73
+ }
74
+ [data-component~="ui-cluster"][data-ui-cluster-state~="justify=end"] {
75
+ justify-content: flex-end;
76
+ }
77
+ [data-component~="ui-cluster"][data-ui-cluster-state~="justify=between"] {
78
+ justify-content: space-between;
79
+ }
69
80
 
70
81
  /* A component that sets its display still honours the hidden attribute on its root. */
71
82
  [data-component~="ui-cluster"][hidden] {
@@ -309,6 +309,10 @@ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"]::after {
309
309
 
310
310
  [data-component~="ui-icon-button"] {
311
311
  --_icon-button-icon-default: var(--ui-icon-size-md);
312
+ /* A slotted ui-icon is its own component, out of reach of the svg rule below; these are its
313
+ defaults, which its own --ui-icon-* hooks still override. */
314
+ --_ui-default-icon-size: var(--_ui-icon-button-icon-size, var(--_icon-button-icon-default));
315
+ --_ui-default-icon-stroke-width: var(--_ui-icon-button-icon-stroke-width, 1.75);
312
316
  }
313
317
 
314
318
  [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=sm"] {
@@ -9,16 +9,21 @@ var UiCluster_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
9
9
  __name: "UiCluster",
10
10
  props: {
11
11
  align: {},
12
- gap: {}
12
+ gap: {},
13
+ justify: {}
13
14
  },
14
15
  setup(__props) {
15
16
  const props = __props;
16
17
  /** The values the styles' :host-state() rules test. */
17
- const hostState = computed(() => [props.gap && `gap gap=${props.gap}`, props.align && `align align=${props.align}`].filter(Boolean).join(" "));
18
+ const hostState = computed(() => [
19
+ props.gap && `gap gap=${props.gap}`,
20
+ props.align && `align align=${props.align}`,
21
+ props.justify && `justify justify=${props.justify}`
22
+ ].filter(Boolean).join(" "));
18
23
  return (_ctx, _cache) => {
19
24
  return openBlock(), createElementBlock("div", mergeProps({ "data-component": "ui-cluster" }, _ctx.$attrs, { "data-ui-cluster-state": hostState.value || void 0 }), [renderSlot(_ctx.$slots, "default", {}, void 0, true)], 16, _hoisted_1);
20
25
  };
21
26
  }
22
- }), [["__scopeId", "data-v-d749e74b"]]);
27
+ }), [["__scopeId", "data-v-81b18ffc"]]);
23
28
  //#endregion
24
29
  export { UiCluster_default as t };
@@ -59,6 +59,6 @@ var UiIconButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
59
59
  }), [renderSlot(_ctx.$slots, "default")], 16, _hoisted_1);
60
60
  };
61
61
  }
62
- }), [["__scopeId", "data-v-a20a82b7"]]);
62
+ }), [["__scopeId", "data-v-006fa1b2"]]);
63
63
  //#endregion
64
64
  export { UiIconButton_default as t };
@@ -1094,7 +1094,7 @@ input[data-v-e122df08]:focus-visible {
1094
1094
  syntax: "*";
1095
1095
  inherits: false;
1096
1096
  }
1097
- [data-component~="ui-cluster"][data-v-d749e74b] {
1097
+ [data-component~="ui-cluster"][data-v-81b18ffc] {
1098
1098
  --_layout-gap: var(--ui-space-3);
1099
1099
  display: flex;
1100
1100
  flex-wrap: wrap;
@@ -1104,33 +1104,42 @@ input[data-v-e122df08]:focus-visible {
1104
1104
  max-inline-size: 100%;
1105
1105
  margin: 0;
1106
1106
  }
1107
- [data-component~="ui-cluster"][data-ui-cluster-state~="gap=xs"][data-v-d749e74b] {
1107
+ [data-component~="ui-cluster"][data-ui-cluster-state~="gap=xs"][data-v-81b18ffc] {
1108
1108
  --_layout-gap: var(--ui-space-2);
1109
1109
  }
1110
- [data-component~="ui-cluster"][data-ui-cluster-state~="gap=s"][data-v-d749e74b] {
1110
+ [data-component~="ui-cluster"][data-ui-cluster-state~="gap=s"][data-v-81b18ffc] {
1111
1111
  --_layout-gap: var(--ui-space-3);
1112
1112
  }
1113
- [data-component~="ui-cluster"][data-ui-cluster-state~="gap=m"][data-v-d749e74b] {
1113
+ [data-component~="ui-cluster"][data-ui-cluster-state~="gap=m"][data-v-81b18ffc] {
1114
1114
  --_layout-gap: var(--ui-space-4);
1115
1115
  }
1116
- [data-component~="ui-cluster"][data-ui-cluster-state~="gap=l"][data-v-d749e74b] {
1116
+ [data-component~="ui-cluster"][data-ui-cluster-state~="gap=l"][data-v-81b18ffc] {
1117
1117
  --_layout-gap: var(--ui-space-5);
1118
1118
  }
1119
- [data-component~="ui-cluster"][data-ui-cluster-state~="gap=xl"][data-v-d749e74b] {
1119
+ [data-component~="ui-cluster"][data-ui-cluster-state~="gap=xl"][data-v-81b18ffc] {
1120
1120
  --_layout-gap: var(--ui-space-6);
1121
1121
  }
1122
- [data-component~="ui-cluster"][data-ui-cluster-state~="align=start"][data-v-d749e74b] {
1122
+ [data-component~="ui-cluster"][data-ui-cluster-state~="align=start"][data-v-81b18ffc] {
1123
1123
  align-items: flex-start;
1124
1124
  }
1125
- [data-component~="ui-cluster"][data-ui-cluster-state~="align=end"][data-v-d749e74b] {
1125
+ [data-component~="ui-cluster"][data-ui-cluster-state~="align=end"][data-v-81b18ffc] {
1126
1126
  align-items: flex-end;
1127
1127
  }
1128
- [data-component~="ui-cluster"][data-ui-cluster-state~="align=stretch"][data-v-d749e74b] {
1128
+ [data-component~="ui-cluster"][data-ui-cluster-state~="align=stretch"][data-v-81b18ffc] {
1129
1129
  align-items: stretch;
1130
1130
  }
1131
+ [data-component~="ui-cluster"][data-ui-cluster-state~="justify=center"][data-v-81b18ffc] {
1132
+ justify-content: center;
1133
+ }
1134
+ [data-component~="ui-cluster"][data-ui-cluster-state~="justify=end"][data-v-81b18ffc] {
1135
+ justify-content: flex-end;
1136
+ }
1137
+ [data-component~="ui-cluster"][data-ui-cluster-state~="justify=between"][data-v-81b18ffc] {
1138
+ justify-content: space-between;
1139
+ }
1131
1140
 
1132
1141
  /* A component that sets its display still honours the hidden attribute on its root. */
1133
- [data-component~="ui-cluster"][hidden][data-v-d749e74b] {
1142
+ [data-component~="ui-cluster"][hidden][data-v-81b18ffc] {
1134
1143
  display: none;
1135
1144
  }
1136
1145
 
@@ -3484,7 +3493,7 @@ svg[data-v-03a5b772-s] {
3484
3493
  syntax: "*";
3485
3494
  inherits: false;
3486
3495
  }
3487
- [data-component~="ui-icon-button"][data-v-a20a82b7] {
3496
+ [data-component~="ui-icon-button"][data-v-006fa1b2] {
3488
3497
  /* Hooks do not inherit, so the parts below read them from the root. */
3489
3498
  --_ui-icon-button-icon-size: var(--ui-icon-button-icon-size);
3490
3499
  --_ui-icon-button-icon-stroke-width: var(--ui-icon-button-icon-stroke-width);
@@ -3492,10 +3501,10 @@ svg[data-v-03a5b772-s] {
3492
3501
  display: inline-flex;
3493
3502
  color: var(--ui-text-secondary);
3494
3503
  }
3495
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-a20a82b7] {
3504
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-006fa1b2] {
3496
3505
  position: relative;
3497
3506
  }
3498
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-a20a82b7]::before {
3507
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-006fa1b2]::before {
3499
3508
  content: "";
3500
3509
  position: absolute;
3501
3510
  inset: 50% auto auto 50%;
@@ -3514,17 +3523,17 @@ svg[data-v-03a5b772-s] {
3514
3523
  * surface and icon. The root is the native button, so hiding it outright would hide the dot
3515
3524
  * too, and slotted icons sit outside this scope; `color: transparent` hides currentColor icons. */
3516
3525
  @media (hover: hover) and (pointer: fine) {
3517
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-a20a82b7]:not([data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"], [data-ui-proximity="near"], :hover, :focus-visible) {
3526
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-006fa1b2]:not([data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"], [data-ui-proximity="near"], :hover, :focus-visible) {
3518
3527
  border-color: transparent;
3519
3528
  background: transparent;
3520
3529
  box-shadow: none;
3521
3530
  color: transparent;
3522
3531
  }
3523
3532
  }
3524
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-a20a82b7]:is([data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"], [data-ui-proximity="near"], :hover, :focus-visible)::before {
3533
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-006fa1b2]:is([data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"], [data-ui-proximity="near"], :hover, :focus-visible)::before {
3525
3534
  opacity: 0;
3526
3535
  }
3527
- [data-component~="ui-icon-button"][data-v-a20a82b7] {
3536
+ [data-component~="ui-icon-button"][data-v-006fa1b2] {
3528
3537
  /* The size prop resolves here; --ui-icon-button-size overrides it on an element. */
3529
3538
  --_size: 2rem;
3530
3539
  appearance: none;
@@ -3550,7 +3559,7 @@ svg[data-v-03a5b772-s] {
3550
3559
  transform var(--ui-motion-fast) var(--ui-motion-ease);
3551
3560
  }
3552
3561
  @media (hover: none), (pointer: coarse) {
3553
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-a20a82b7]::before {
3562
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-006fa1b2]::before {
3554
3563
  opacity: 0;
3555
3564
  }
3556
3565
  }
@@ -3558,10 +3567,10 @@ svg[data-v-03a5b772-s] {
3558
3567
  /* A touch target without a bigger button: an invisible hit area, at least the control
3559
3568
  minimum, centred on the button (::before is the anticipatory guide). */
3560
3569
  @media (pointer: coarse) {
3561
- [data-component~="ui-icon-button"][data-v-a20a82b7] {
3570
+ [data-component~="ui-icon-button"][data-v-006fa1b2] {
3562
3571
  position: relative;
3563
3572
  }
3564
- [data-component~="ui-icon-button"][data-v-a20a82b7]::after {
3573
+ [data-component~="ui-icon-button"][data-v-006fa1b2]::after {
3565
3574
  content: "";
3566
3575
  position: absolute;
3567
3576
  inset: 50% auto auto 50%;
@@ -3570,10 +3579,10 @@ svg[data-v-03a5b772-s] {
3570
3579
  transform: translate(-50%, -50%);
3571
3580
  }
3572
3581
  }
3573
- html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"][data-v-a20a82b7] {
3582
+ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"][data-v-006fa1b2] {
3574
3583
  position: relative;
3575
3584
  }
3576
- html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"][data-v-a20a82b7]::after {
3585
+ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"][data-v-006fa1b2]::after {
3577
3586
  content: "";
3578
3587
  position: absolute;
3579
3588
  inset: 50% auto auto 50%;
@@ -3581,29 +3590,29 @@ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"][data-v-a
3581
3590
  block-size: max(100%, var(--ui-control-min-block-size));
3582
3591
  transform: translate(-50%, -50%);
3583
3592
  }
3584
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=sm"][data-v-a20a82b7] {
3593
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=sm"][data-v-006fa1b2] {
3585
3594
  --_size: 1.75rem;
3586
3595
  inline-size: var(--ui-icon-button-size, var(--_size));
3587
3596
  block-size: var(--ui-icon-button-size, var(--_size));
3588
3597
  min-inline-size: var(--ui-icon-button-size, var(--_size));
3589
3598
  min-block-size: var(--ui-icon-button-size, var(--_size));
3590
3599
  }
3591
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=lg"][data-v-a20a82b7] {
3600
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=lg"][data-v-006fa1b2] {
3592
3601
  --_size: 2.5rem;
3593
3602
  inline-size: var(--ui-icon-button-size, var(--_size));
3594
3603
  block-size: var(--ui-icon-button-size, var(--_size));
3595
3604
  min-inline-size: var(--ui-icon-button-size, var(--_size));
3596
3605
  min-block-size: var(--ui-icon-button-size, var(--_size));
3597
3606
  }
3598
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="round"][data-v-a20a82b7] {
3607
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="round"][data-v-006fa1b2] {
3599
3608
  border-radius: var(--ui-radius-round);
3600
3609
  }
3601
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"][data-v-a20a82b7] {
3610
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"][data-v-006fa1b2] {
3602
3611
  border-color: var(--ui-icon-button-border, var(--ui-border-default));
3603
3612
  background: var(--ui-icon-button-outline-surface, var(--ui-surface-default));
3604
3613
  color: var(--ui-icon-button-outline-text, var(--ui-text-primary));
3605
3614
  }
3606
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"][data-v-a20a82b7] {
3615
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"][data-v-006fa1b2] {
3607
3616
  background: var(--ui-icon-button-solid-surface, var(--ui-accent-solid));
3608
3617
  color: var(--ui-icon-button-solid-text, var(--ui-text-on-accent));
3609
3618
  box-shadow: var(
@@ -3611,43 +3620,47 @@ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"][data-v-a
3611
3620
  0 1px 2px color-mix(in srgb, var(--ui-accent-solid) 18%, transparent)
3612
3621
  );
3613
3622
  }
3614
- [data-component~="ui-icon-button"][data-v-a20a82b7]:hover:enabled {
3623
+ [data-component~="ui-icon-button"][data-v-006fa1b2]:hover:enabled {
3615
3624
  /* Derived from the text colour so the ghost hover shows on any background. */
3616
3625
  background: var(--ui-icon-button-hover-surface, color-mix(in srgb, currentColor 8%, transparent));
3617
3626
  color: var(--ui-icon-button-hover-text, var(--ui-text-primary));
3618
3627
  }
3619
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"][data-v-a20a82b7]:hover:enabled {
3628
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"][data-v-006fa1b2]:hover:enabled {
3620
3629
  border-color: var(--ui-icon-button-hover-border, var(--ui-border-strong));
3621
3630
  }
3622
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"][data-v-a20a82b7]:hover:enabled {
3631
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"][data-v-006fa1b2]:hover:enabled {
3623
3632
  background: var(--ui-icon-button-solid-hover-surface, var(--ui-accent-hover));
3624
3633
  }
3625
- [data-component~="ui-icon-button"][data-v-a20a82b7]:active:enabled {
3634
+ [data-component~="ui-icon-button"][data-v-006fa1b2]:active:enabled {
3626
3635
  transform: scale(var(--ui-icon-button-active-scale, 0.96));
3627
3636
  }
3628
- [data-component~="ui-icon-button"][data-v-a20a82b7]:focus-visible {
3637
+ [data-component~="ui-icon-button"][data-v-006fa1b2]:focus-visible {
3629
3638
  outline: none;
3630
3639
  box-shadow: var(--ui-focus-halo);
3631
3640
  }
3632
3641
 
3633
3642
  /* Disabled colours fall back to each variant's own; ghost takes only the icon colour. */
3634
3643
  /* Disabled washes the button out the way Button does: the same shape, one filter. */
3635
- [data-component~="ui-icon-button"][data-v-a20a82b7]:disabled {
3644
+ [data-component~="ui-icon-button"][data-v-006fa1b2]:disabled {
3636
3645
  filter: var(--ui-icon-button-disabled-filter, var(--ui-disabled-filter));
3637
3646
  opacity: var(--ui-icon-button-disabled-opacity, 1);
3638
3647
  cursor: not-allowed;
3639
3648
  box-shadow: none;
3640
3649
  }
3641
- [data-component~="ui-icon-button"][data-v-a20a82b7] {
3650
+ [data-component~="ui-icon-button"][data-v-006fa1b2] {
3642
3651
  --_icon-button-icon-default: var(--ui-icon-size-md);
3652
+ /* A slotted ui-icon is its own component, out of reach of the svg rule below; these are its
3653
+ defaults, which its own --ui-icon-* hooks still override. */
3654
+ --_ui-default-icon-size: var(--_ui-icon-button-icon-size, var(--_icon-button-icon-default));
3655
+ --_ui-default-icon-stroke-width: var(--_ui-icon-button-icon-stroke-width, 1.75);
3643
3656
  }
3644
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=sm"][data-v-a20a82b7] {
3657
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=sm"][data-v-006fa1b2] {
3645
3658
  --_icon-button-icon-default: var(--ui-icon-size-sm);
3646
3659
  }
3647
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=lg"][data-v-a20a82b7] {
3660
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=lg"][data-v-006fa1b2] {
3648
3661
  --_icon-button-icon-default: var(--ui-icon-size-lg);
3649
3662
  }
3650
- svg[data-v-a20a82b7-s] {
3663
+ svg[data-v-006fa1b2-s] {
3651
3664
  inline-size: var(--_ui-icon-button-icon-size, var(--_icon-button-icon-default));
3652
3665
  block-size: var(--_ui-icon-button-icon-size, var(--_icon-button-icon-default));
3653
3666
  flex-shrink: 0;
@@ -3655,7 +3668,7 @@ svg[data-v-a20a82b7-s] {
3655
3668
  }
3656
3669
 
3657
3670
  /* A component that sets its display still honours the hidden attribute on its root. */
3658
- [data-component~="ui-icon-button"][hidden][data-v-a20a82b7] {
3671
+ [data-component~="ui-icon-button"][hidden][data-v-006fa1b2] {
3659
3672
  display: none;
3660
3673
  }
3661
3674