@threadlabs/looma 0.23.14 → 0.23.16

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.23.14",
3
+ "version": "0.23.16",
4
4
  "type": "module",
5
5
  "description": "Looma components as HTML, Vue, and plain DOM, with design tokens.",
6
6
  "license": "MIT",
@@ -215,6 +215,29 @@
215
215
  min-block-size: var(--ui-icon-button-size, var(--_size));
216
216
  }
217
217
 
218
+ /* A text button's companion uses control geometry; compact icon buttons keep their own density. */
219
+ :scope[data-ui-icon-button-state~="matchButton"] {
220
+ --_size: var(--ui-control-size-md);
221
+ block-size: auto;
222
+ align-self: stretch;
223
+ }
224
+
225
+ :scope[data-ui-icon-button-state~="matchButton"][data-ui-icon-button-state~="size=sm"] {
226
+ --_size: var(--ui-control-size-sm);
227
+ }
228
+
229
+ :scope[data-ui-icon-button-state~="matchButton"][data-ui-icon-button-state~="size=lg"] {
230
+ --_size: var(--ui-control-size-lg);
231
+ }
232
+
233
+ @media (pointer: coarse) {
234
+ :scope[data-ui-icon-button-state~="matchButton"] {
235
+ inline-size: max(var(--ui-icon-button-size, var(--_size)), var(--ui-control-min-block-size));
236
+ min-inline-size: max(var(--ui-icon-button-size, var(--_size)), var(--ui-control-min-block-size));
237
+ min-block-size: max(var(--ui-icon-button-size, var(--_size)), var(--ui-control-min-block-size));
238
+ }
239
+ }
240
+
218
241
  :scope[data-ui-icon-button-state~="round"] {
219
242
  border-radius: var(--ui-radius-round);
220
243
  }
@@ -340,6 +363,11 @@
340
363
  @media (pointer: coarse) {
341
364
  }
342
365
 
366
+ /* A text button's companion uses control geometry; compact icon buttons keep their own density. */
367
+
368
+ @media (pointer: coarse) {
369
+ }
370
+
343
371
  @media (prefers-reduced-motion: reduce) {
344
372
  }
345
373
 
@@ -95,9 +95,14 @@
95
95
  /* Under touch a small field is still a touch-sized target, as a small button is, and keeps
96
96
  body-size text: below 16px, iOS zooms the page into the focused field. */
97
97
  @media (pointer: coarse) {
98
+ :scope,
99
+ :scope[data-ui-input-state~="size=sm"],
100
+ :scope[data-ui-input-state~="size=lg"] {
101
+ font-size: var(--ui-font-size-md);
102
+ }
103
+
98
104
  :scope[data-ui-input-state~="size=sm"] {
99
105
  min-block-size: var(--ui-input-min-block-size, var(--_ui-default-input-min-block-size, var(--ui-control-min-block-size)));
100
- font-size: inherit;
101
106
  }
102
107
  }
103
108
 
@@ -337,7 +337,7 @@
337
337
  }
338
338
 
339
339
  /* Without hover there is no reveal, so the controls keep their own column. */
340
- @media (hover: none) {
340
+ @media (hover: none), (pointer: coarse) {
341
341
  .row {
342
342
  grid-template-columns: var(--_tree-disclosure-size) auto minmax(0, 1fr) auto;
343
343
  }
@@ -351,6 +351,37 @@
351
351
  opacity: 1;
352
352
  pointer-events: auto;
353
353
  }
354
+
355
+ .row:is(:hover, :focus-within) > .label,
356
+ .row:is(:hover, :focus-within) > .label:dir(rtl),
357
+ :scope[data-move-source] > .row > .label,
358
+ :scope[data-move-source] > .row > .label:dir(rtl) {
359
+ mask-image: none;
360
+ }
361
+
362
+ .row[data-ui-marquee] > .label {
363
+ mask-image: linear-gradient(
364
+ to right,
365
+ transparent var(--_marquee-icon-width, 0px),
366
+ #000 calc(var(--_marquee-lead, 0px) + var(--_ui-tree-item-label-padding-inline, var(--ui-space-2)))
367
+ );
368
+ }
369
+
370
+ .row[data-ui-marquee] > .label:dir(rtl) {
371
+ mask-image: linear-gradient(
372
+ to left,
373
+ transparent var(--_marquee-icon-width, 0px),
374
+ #000 calc(var(--_marquee-lead, 0px) + var(--_ui-tree-item-label-padding-inline, var(--ui-space-2)))
375
+ );
376
+ }
377
+
378
+ :scope[data-selection-mode="multiple"] > .row {
379
+ grid-template-columns: var(--_tree-disclosure-size) 1.25rem auto minmax(0, 1fr) auto;
380
+ }
381
+
382
+ :scope[data-selection-mode="multiple"] > .row > .actions {
383
+ grid-column: 5;
384
+ }
354
385
  }
355
386
 
356
387
  /* The handle sits beside what it drags. A leaf row has no disclosure, so the handle takes that
@@ -492,6 +523,24 @@
492
523
  grid-column: 5;
493
524
  }
494
525
 
526
+ @media (hover: none), (pointer: coarse) {
527
+ html[data-ui-input-modality="touch"] :scope .row {
528
+ grid-template-columns: 44px var(--_tree-disclosure-size) auto minmax(0, 1fr) auto;
529
+ }
530
+
531
+ html[data-ui-input-modality="touch"] :scope .actions {
532
+ grid-column: 5;
533
+ }
534
+
535
+ html[data-ui-input-modality="touch"] :scope[data-selection-mode="multiple"] > .row {
536
+ grid-template-columns: 44px var(--_tree-disclosure-size) 44px auto minmax(0, 1fr) auto;
537
+ }
538
+
539
+ html[data-ui-input-modality="touch"] :scope[data-selection-mode="multiple"] > .row > .actions {
540
+ grid-column: 6;
541
+ }
542
+ }
543
+
495
544
  @media (prefers-reduced-motion: reduce) {
496
545
  .row,
497
546
  .disclosure-icon,
@@ -570,7 +619,7 @@
570
619
  }
571
620
 
572
621
  /* Without hover there is no reveal, so the controls keep their own column. */
573
- @media (hover: none) {
622
+ @media (hover: none), (pointer: coarse) {
574
623
  }
575
624
 
576
625
  /* The handle sits beside what it drags. A leaf row has no disclosure, so the handle takes that
@@ -578,6 +627,9 @@
578
627
  outside the row. It is bare until pointed at: a resting surface behind it read as a faint
579
628
  patch rather than as a control. */
580
629
 
630
+ @media (hover: none), (pointer: coarse) {
631
+ }
632
+
581
633
  @media (prefers-reduced-motion: reduce) {
582
634
  }
583
635
 
@@ -10,6 +10,7 @@ export interface UiIconButtonProps {
10
10
  disabled?: boolean | null;
11
11
  label?: string | null;
12
12
  loading?: boolean | null;
13
+ matchButton?: boolean | null;
13
14
  pending?: boolean | null;
14
15
  round?: boolean | null;
15
16
  size?: "sm" | "md" | "lg" | null;
@@ -3,7 +3,7 @@ import { manageComponentLifecycle } from "@nextwebwg/html-next/runtime";
3
3
  import * as controller from "../components/ui-icon-button/ui-icon-button.js";
4
4
  import "../styles/ui-icon-button.css";
5
5
 
6
- const definition = {...{"contract":{"tag":"ui-icon-button","props":{"anticipatory":{"type":"boolean","required":false,"target":{"attribute":"anticipatory"},"default":false},"disabled":{"type":"boolean","required":false,"target":{"attribute":"disabled"},"default":false},"label":{"type":"string","required":false,"target":{"attribute":"aria-label"}},"loading":{"type":"boolean","required":false,"target":{"attribute":"loading"},"default":false},"pending":{"type":"boolean","required":false,"target":{"attribute":"pending"},"default":false},"round":{"type":"boolean","required":false,"target":{"attribute":"round"},"default":false},"size":{"type":{"kind":"terminal","name":"keyword"},"values":["sm","md","lg"],"required":false,"target":{"attribute":"size"},"default":"md"},"variant":{"type":{"kind":"terminal","name":"keyword"},"values":["ghost","outline","solid"],"required":false,"target":{"attribute":"variant"},"default":"ghost"}}},"template":{"kind":"element","name":"button","attributes":[{"kind":"attribute","name":"disabled","expression":"disabled","expressionPlan":{"source":"disabled","ast":{"kind":"id","name":"disabled"},"dependencies":["disabled"]}},{"kind":"literal","name":"type","value":"button"},{"kind":"attribute","name":"aria-label","expression":"label","expressionPlan":{"source":"label","ast":{"kind":"id","name":"label"},"dependencies":["label"]}},{"kind":"attribute","name":"aria-disabled","expression":"{ true: 'true', false: null }[format('%s', loading or pending)]","expressionPlan":{"source":"{ true: 'true', false: null }[format('%s', loading or pending)]","ast":{"kind":"index","object":{"kind":"object","pairs":[{"key":"true","value":{"kind":"literal","value":"true"}},{"key":"false","value":{"kind":"literal","value":null}}]},"index":{"kind":"call","fn":"format","args":[{"kind":"literal","value":"%s"},{"kind":"binary","op":"or","left":{"kind":"id","name":"loading"},"right":{"kind":"id","name":"pending"}}]}},"dependencies":["loading","pending"]}},{"kind":"attribute","name":"aria-busy","expression":"loading or pending","expressionPlan":{"source":"loading or pending","ast":{"kind":"binary","op":"or","left":{"kind":"id","name":"loading"},"right":{"kind":"id","name":"pending"}},"dependencies":["loading","pending"]}}],"children":[{"kind":"element","name":"ui-spinner","attributes":[{"kind":"literal","name":"size","value":"sm"}],"children":[],"flow":{"kind":"if","test":"loading or pending","testPlan":{"source":"loading or pending","ast":{"kind":"binary","op":"or","left":{"kind":"id","name":"loading"},"right":{"kind":"id","name":"pending"}},"dependencies":["loading","pending"]}}},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"content"}],"children":[{"kind":"slot"}]}]},"declarations":[],"root":{"kind":"native","element":"button","choices":["button"]}},source:{file:import.meta.url},css:""};
6
+ const definition = {...{"contract":{"tag":"ui-icon-button","props":{"anticipatory":{"type":"boolean","required":false,"target":{"attribute":"anticipatory"},"default":false},"disabled":{"type":"boolean","required":false,"target":{"attribute":"disabled"},"default":false},"label":{"type":"string","required":false,"target":{"attribute":"aria-label"}},"loading":{"type":"boolean","required":false,"target":{"attribute":"loading"},"default":false},"matchButton":{"type":"boolean","required":false,"target":{"attribute":"data-match-button"},"default":false},"pending":{"type":"boolean","required":false,"target":{"attribute":"pending"},"default":false},"round":{"type":"boolean","required":false,"target":{"attribute":"round"},"default":false},"size":{"type":{"kind":"terminal","name":"keyword"},"values":["sm","md","lg"],"required":false,"target":{"attribute":"size"},"default":"md"},"variant":{"type":{"kind":"terminal","name":"keyword"},"values":["ghost","outline","solid"],"required":false,"target":{"attribute":"variant"},"default":"ghost"}}},"template":{"kind":"element","name":"button","attributes":[{"kind":"attribute","name":"disabled","expression":"disabled","expressionPlan":{"source":"disabled","ast":{"kind":"id","name":"disabled"},"dependencies":["disabled"]}},{"kind":"literal","name":"type","value":"button"},{"kind":"attribute","name":"aria-label","expression":"label","expressionPlan":{"source":"label","ast":{"kind":"id","name":"label"},"dependencies":["label"]}},{"kind":"attribute","name":"data-match-button","expression":"matchButton","expressionPlan":{"source":"matchButton","ast":{"kind":"id","name":"matchButton"},"dependencies":["matchButton"]}},{"kind":"attribute","name":"aria-disabled","expression":"{ true: 'true', false: null }[format('%s', loading or pending)]","expressionPlan":{"source":"{ true: 'true', false: null }[format('%s', loading or pending)]","ast":{"kind":"index","object":{"kind":"object","pairs":[{"key":"true","value":{"kind":"literal","value":"true"}},{"key":"false","value":{"kind":"literal","value":null}}]},"index":{"kind":"call","fn":"format","args":[{"kind":"literal","value":"%s"},{"kind":"binary","op":"or","left":{"kind":"id","name":"loading"},"right":{"kind":"id","name":"pending"}}]}},"dependencies":["loading","pending"]}},{"kind":"attribute","name":"aria-busy","expression":"loading or pending","expressionPlan":{"source":"loading or pending","ast":{"kind":"binary","op":"or","left":{"kind":"id","name":"loading"},"right":{"kind":"id","name":"pending"}},"dependencies":["loading","pending"]}}],"children":[{"kind":"element","name":"ui-spinner","attributes":[{"kind":"literal","name":"size","value":"sm"}],"children":[],"flow":{"kind":"if","test":"loading or pending","testPlan":{"source":"loading or pending","ast":{"kind":"binary","op":"or","left":{"kind":"id","name":"loading"},"right":{"kind":"id","name":"pending"}},"dependencies":["loading","pending"]}}},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"content"}],"children":[{"kind":"slot"}]}]},"declarations":[],"root":{"kind":"native","element":"button","choices":["button"]}},source:{file:import.meta.url},css:""};
7
7
 
8
8
  export function createUiIconButton(options = {}) {
9
9
  const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
@@ -20,6 +20,9 @@ export function createUiIconButton(options = {}) {
20
20
  const value1 = componentProps["label"] === undefined ? null : componentProps["label"];
21
21
  if (value1 === null || value1 === undefined) element.removeAttribute("aria-label");
22
22
  else element.setAttribute("aria-label", String(value1));
23
+ const value2 = componentProps["matchButton"] === undefined ? false : componentProps["matchButton"];
24
+ if (value2 === true) element.setAttribute("data-match-button", "");
25
+ else element.removeAttribute("data-match-button");
23
26
  element.setAttribute("data-component", "ui-icon-button");
24
27
  const element0 = document.createElement("ui-spinner");
25
28
  element0.setAttribute("size", "sm");
@@ -20,6 +20,10 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
20
20
  type: PropType<boolean | null>;
21
21
  default: boolean;
22
22
  };
23
+ matchButton: {
24
+ type: PropType<boolean | null>;
25
+ default: boolean;
26
+ };
23
27
  pending: {
24
28
  type: PropType<boolean | null>;
25
29
  default: boolean;
@@ -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
+ matchButton: {
61
+ type: PropType<boolean | null>;
62
+ default: boolean;
63
+ };
56
64
  pending: {
57
65
  type: PropType<boolean | null>;
58
66
  default: boolean;
@@ -78,6 +86,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
78
86
  loading: boolean | null;
79
87
  pending: boolean | null;
80
88
  anticipatory: boolean | null;
89
+ matchButton: boolean | null;
81
90
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
82
91
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
83
92
  declare const _default: typeof __VLS_export;
@@ -40,6 +40,14 @@ const propValidityContract = {
40
40
  'Keeps the button focusable and named while work is in progress. It shows a spinner, states aria-disabled and aria-busy, and prevents activation until\n cleared.',
41
41
  default: false,
42
42
  },
43
+ matchButton: {
44
+ type: { kind: 'terminal', name: 'boolean' },
45
+ required: false,
46
+ target: { attribute: 'data-match-button' },
47
+ description:
48
+ 'Matches a boxed Button of the same size when the two share a flex row. Uses the control-size theme tokens and stretches to the row\'s height, including\n touch-sized controls. Leave it off for compact toolbar and inline icon buttons.',
49
+ default: false,
50
+ },
43
51
  pending: {
44
52
  type: { kind: 'terminal', name: 'boolean' },
45
53
  required: false,
@@ -79,6 +87,7 @@ const props = defineProps({
79
87
  disabled: { type: null as unknown as PropType<boolean | null>, default: false },
80
88
  label: { type: null as unknown as PropType<string | null>, default: null },
81
89
  loading: { type: null as unknown as PropType<boolean | null>, default: false },
90
+ matchButton: { type: null as unknown as PropType<boolean | null>, default: false },
82
91
  pending: { type: null as unknown as PropType<boolean | null>, default: false },
83
92
  round: { type: null as unknown as PropType<boolean | null>, default: false },
84
93
  size: { type: null as unknown as PropType<'sm' | 'md' | 'lg' | null>, default: 'md' },
@@ -92,6 +101,7 @@ const acceptedProps: Record<string, unknown> = {
92
101
  disabled: false,
93
102
  label: null,
94
103
  loading: false,
104
+ matchButton: false,
95
105
  pending: false,
96
106
  round: false,
97
107
  size: 'md',
@@ -126,6 +136,13 @@ const checkedProps = computed(() => ({
126
136
  'loading',
127
137
  acceptedProps,
128
138
  ) as boolean,
139
+ matchButton: checkedProp<boolean>(
140
+ props['matchButton'],
141
+ { kind: 'terminal', name: 'boolean' },
142
+ false,
143
+ 'matchButton',
144
+ acceptedProps,
145
+ ) as boolean,
129
146
  pending: checkedProp<boolean>(
130
147
  props['pending'],
131
148
  { kind: 'terminal', name: 'boolean' },
@@ -222,6 +239,7 @@ const hostState = computed(() =>
222
239
  checkedProps.value.pending && 'pending',
223
240
  checkedProps.value.size && 'size',
224
241
  checkedProps.value.size != null && `size=${encodeURIComponent(checkedProps.value.size)}`,
242
+ checkedProps.value.matchButton && 'matchButton',
225
243
  checkedProps.value.round && 'round',
226
244
  ].filter(Boolean).join(' ')
227
245
  )
@@ -248,6 +266,7 @@ useComponentHost(() => import('../components/ui-icon-button/ui-icon-button.js'),
248
266
  'disabled',
249
267
  'label',
250
268
  'loading',
269
+ 'matchButton',
251
270
  'pending',
252
271
  'round',
253
272
  'size',
@@ -297,6 +316,7 @@ function attribute(value: unknown): any {
297
316
  :data-disabled="reflectedProp('disabled', 'disabled', checkedProps.disabled, undefined, false)"
298
317
  :data-label="reflectedProp('label', 'label', checkedProps.label, undefined, false)"
299
318
  :data-loading="reflectedProp('loading', 'loading', checkedProps.loading, undefined, false)"
319
+ :data-match-button="reflectedProp('matchButton', 'match-button', checkedProps.matchButton, undefined, true)"
300
320
  :data-pending="reflectedProp('pending', 'pending', checkedProps.pending, undefined, false)"
301
321
  :data-round="reflectedProp('round', 'round', checkedProps.round, undefined, false)"
302
322
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
@@ -527,6 +547,32 @@ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"]::after {
527
547
  min-block-size: var(--ui-icon-button-size, var(--_size));
528
548
  }
529
549
 
550
+ /* A text button's companion uses control geometry; compact icon buttons keep their own density. */
551
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="matchButton"] {
552
+ --_size: var(--ui-control-size-md);
553
+ block-size: auto;
554
+ align-self: stretch;
555
+ }
556
+
557
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="matchButton"][data-ui-icon-button-state~="size=sm"] {
558
+ --_size: var(--ui-control-size-sm);
559
+ }
560
+
561
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="matchButton"][data-ui-icon-button-state~="size=lg"] {
562
+ --_size: var(--ui-control-size-lg);
563
+ }
564
+
565
+ @media (pointer: coarse) {
566
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="matchButton"] {
567
+ inline-size: max(var(--ui-icon-button-size, var(--_size)), var(--ui-control-min-block-size));
568
+ min-inline-size: max(
569
+ var(--ui-icon-button-size, var(--_size)),
570
+ var(--ui-control-min-block-size)
571
+ );
572
+ min-block-size: max(var(--ui-icon-button-size, var(--_size)), var(--ui-control-min-block-size));
573
+ }
574
+ }
575
+
530
576
  [data-component~="ui-icon-button"][data-ui-icon-button-state~="round"] {
531
577
  border-radius: var(--ui-radius-round);
532
578
  }
package/vue/UiInput.vue CHANGED
@@ -602,12 +602,17 @@ useComponentHost(() => import('../components/ui-input/ui-input.js'), {
602
602
  /* Under touch a small field is still a touch-sized target, as a small button is, and keeps
603
603
  body-size text: below 16px, iOS zooms the page into the focused field. */
604
604
  @media (pointer: coarse) {
605
+ [data-component~="ui-input"],
606
+ [data-component~="ui-input"][data-ui-input-state~="size=sm"],
607
+ [data-component~="ui-input"][data-ui-input-state~="size=lg"] {
608
+ font-size: var(--ui-font-size-md);
609
+ }
610
+
605
611
  [data-component~="ui-input"][data-ui-input-state~="size=sm"] {
606
612
  min-block-size: var(
607
613
  --ui-input-min-block-size,
608
614
  var(--_ui-default-input-min-block-size, var(--ui-control-min-block-size))
609
615
  );
610
- font-size: inherit;
611
616
  }
612
617
  }
613
618
 
@@ -925,7 +925,7 @@ function attribute(value: unknown): any {
925
925
  }
926
926
 
927
927
  /* Without hover there is no reveal, so the controls keep their own column. */
928
- @media (hover: none) {
928
+ @media (hover: none), (pointer: coarse) {
929
929
  .row {
930
930
  grid-template-columns: var(--_tree-disclosure-size) auto minmax(0, 1fr) auto;
931
931
  }
@@ -939,6 +939,41 @@ function attribute(value: unknown): any {
939
939
  opacity: 1;
940
940
  pointer-events: auto;
941
941
  }
942
+
943
+ .row:is(:hover, :focus-within) > .label,
944
+ .row:is(:hover, :focus-within) > .label:dir(rtl),
945
+ [data-component~="ui-tree-item"][data-move-source] > .row > .label,
946
+ [data-component~="ui-tree-item"][data-move-source] > .row > .label:dir(rtl) {
947
+ mask-image: none;
948
+ }
949
+
950
+ .row[data-ui-marquee] > .label {
951
+ mask-image: linear-gradient(
952
+ to right,
953
+ transparent var(--_marquee-icon-width, 0px),
954
+ #000 calc(
955
+ var(--_marquee-lead, 0px) + var(--_ui-tree-item-label-padding-inline, var(--ui-space-2))
956
+ )
957
+ );
958
+ }
959
+
960
+ .row[data-ui-marquee] > .label:dir(rtl) {
961
+ mask-image: linear-gradient(
962
+ to left,
963
+ transparent var(--_marquee-icon-width, 0px),
964
+ #000 calc(
965
+ var(--_marquee-lead, 0px) + var(--_ui-tree-item-label-padding-inline, var(--ui-space-2))
966
+ )
967
+ );
968
+ }
969
+
970
+ [data-component~="ui-tree-item"][data-selection-mode="multiple"] > .row {
971
+ grid-template-columns: var(--_tree-disclosure-size) 1.25rem auto minmax(0, 1fr) auto;
972
+ }
973
+
974
+ [data-component~="ui-tree-item"][data-selection-mode="multiple"] > .row > .actions {
975
+ grid-column: 5;
976
+ }
942
977
  }
943
978
 
944
979
  /* The handle sits beside what it drags. A leaf row has no disclosure, so the handle takes that
@@ -1094,6 +1129,29 @@ html[data-ui-input-modality="touch"]
1094
1129
  grid-column: 5;
1095
1130
  }
1096
1131
 
1132
+ @media (hover: none), (pointer: coarse) {
1133
+ html[data-ui-input-modality="touch"] [data-component~="ui-tree-item"] .row {
1134
+ grid-template-columns: 44px var(--_tree-disclosure-size) auto minmax(0, 1fr) auto;
1135
+ }
1136
+
1137
+ html[data-ui-input-modality="touch"] [data-component~="ui-tree-item"] .actions {
1138
+ grid-column: 5;
1139
+ }
1140
+
1141
+ html[data-ui-input-modality="touch"]
1142
+ [data-component~="ui-tree-item"][data-selection-mode="multiple"]
1143
+ > .row {
1144
+ grid-template-columns: 44px var(--_tree-disclosure-size) 44px auto minmax(0, 1fr) auto;
1145
+ }
1146
+
1147
+ html[data-ui-input-modality="touch"]
1148
+ [data-component~="ui-tree-item"][data-selection-mode="multiple"]
1149
+ > .row
1150
+ > .actions {
1151
+ grid-column: 6;
1152
+ }
1153
+ }
1154
+
1097
1155
  @media (prefers-reduced-motion: reduce) {
1098
1156
  .row,
1099
1157
  .disclosure-icon,
@@ -13,6 +13,7 @@ var _hoisted_1 = [
13
13
  "data-disabled",
14
14
  "data-label",
15
15
  "data-loading",
16
+ "data-match-button",
16
17
  "data-pending",
17
18
  "data-round",
18
19
  "data-size",
@@ -42,6 +43,10 @@ var UiIconButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
42
43
  type: null,
43
44
  default: false
44
45
  },
46
+ matchButton: {
47
+ type: null,
48
+ default: false
49
+ },
45
50
  pending: {
46
51
  type: null,
47
52
  default: false
@@ -100,6 +105,16 @@ var UiIconButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
100
105
  description: "Keeps the button focusable and named while work is in progress. It shows a spinner, states aria-disabled and aria-busy, and prevents activation until\n cleared.",
101
106
  default: false
102
107
  },
108
+ matchButton: {
109
+ type: {
110
+ kind: "terminal",
111
+ name: "boolean"
112
+ },
113
+ required: false,
114
+ target: { attribute: "data-match-button" },
115
+ description: "Matches a boxed Button of the same size when the two share a flex row. Uses the control-size theme tokens and stretches to the row's height, including\n touch-sized controls. Leave it off for compact toolbar and inline icon buttons.",
116
+ default: false
117
+ },
103
118
  pending: {
104
119
  type: {
105
120
  kind: "terminal",
@@ -157,6 +172,7 @@ var UiIconButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
157
172
  disabled: false,
158
173
  label: null,
159
174
  loading: false,
175
+ matchButton: false,
160
176
  pending: false,
161
177
  round: false,
162
178
  size: "md",
@@ -179,6 +195,10 @@ var UiIconButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
179
195
  kind: "terminal",
180
196
  name: "boolean"
181
197
  }, false, "loading", acceptedProps),
198
+ matchButton: checkedProp(props["matchButton"], {
199
+ kind: "terminal",
200
+ name: "boolean"
201
+ }, false, "matchButton", acceptedProps),
182
202
  pending: checkedProp(props["pending"], {
183
203
  kind: "terminal",
184
204
  name: "boolean"
@@ -231,6 +251,7 @@ var UiIconButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
231
251
  checkedProps.value.pending && "pending",
232
252
  checkedProps.value.size && "size",
233
253
  checkedProps.value.size != null && `size=${encodeURIComponent(checkedProps.value.size)}`,
254
+ checkedProps.value.matchButton && "matchButton",
234
255
  checkedProps.value.round && "round"
235
256
  ].filter(Boolean).join(" "));
236
257
  const dispatch = createDispatch(root);
@@ -252,6 +273,7 @@ var UiIconButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
252
273
  "disabled",
253
274
  "label",
254
275
  "loading",
276
+ "matchButton",
255
277
  "pending",
256
278
  "round",
257
279
  "size",
@@ -292,6 +314,7 @@ var UiIconButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
292
314
  "data-disabled": reflectedProp("disabled", "disabled", checkedProps.value.disabled, void 0, false),
293
315
  "data-label": reflectedProp("label", "label", checkedProps.value.label, void 0, false),
294
316
  "data-loading": reflectedProp("loading", "loading", checkedProps.value.loading, void 0, false),
317
+ "data-match-button": reflectedProp("matchButton", "match-button", checkedProps.value.matchButton, void 0, true),
295
318
  "data-pending": reflectedProp("pending", "pending", checkedProps.value.pending, void 0, false),
296
319
  "data-round": reflectedProp("round", "round", checkedProps.value.round, void 0, false),
297
320
  "data-size": reflectedProp("size", "size", checkedProps.value.size, void 0, false),
@@ -308,6 +331,6 @@ var UiIconButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
308
331
  }]]);
309
332
  };
310
333
  }
311
- }), [["__scopeId", "data-v-7bb0fe2e"]]);
334
+ }), [["__scopeId", "data-v-1cd8b91b"]]);
312
335
  //#endregion
313
336
  export { UiIconButton_default as t };
@@ -690,6 +690,6 @@ var UiInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE
690
690
  }]]);
691
691
  };
692
692
  }
693
- }), [["__scopeId", "data-v-762209e1"]]);
693
+ }), [["__scopeId", "data-v-e45d8c3f"]]);
694
694
  //#endregion
695
695
  export { UiInput_default as t };
@@ -610,6 +610,6 @@ var UiTreeItem_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
610
610
  }]]);
611
611
  };
612
612
  }
613
- }), [["__scopeId", "data-v-d2b1bbe0"]]);
613
+ }), [["__scopeId", "data-v-fd74ff6c"]]);
614
614
  //#endregion
615
615
  export { UiTreeItem_default as t };