@threadlabs/looma 0.5.0 → 0.5.1

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.5.0",
3
+ "version": "0.5.1",
4
4
  "type": "module",
5
5
  "description": "Looma components as HTML, Vue, and plain DOM, with design tokens.",
6
6
  "license": "MIT",
@@ -107,6 +107,7 @@
107
107
  border-color: transparent;
108
108
  background: transparent;
109
109
  box-shadow: none;
110
+ color: var(--ui-button-ghost-text, var(--ui-action-secondary-text, var(--ui-text-primary)));
110
111
  }
111
112
 
112
113
  /* Tints derive from the text colour, not a surface token, so hover and press show on any background. */
@@ -134,9 +135,31 @@
134
135
  var(--ui-focus-halo);
135
136
  }
136
137
 
138
+ /* Disabled colours fall back to each variant's own; ghost and link take only the text colour. */
137
139
  :scope:disabled {
138
- opacity: 0.6;
140
+ opacity: var(--ui-button-disabled-opacity, 0.6);
139
141
  cursor: not-allowed;
142
+ border-color: var(--ui-button-disabled-border, var(--ui-button-border, var(--ui-border-strong)));
143
+ background-color: var(--ui-button-disabled-surface, var(--ui-button-surface, var(--ui-surface-elevated)));
144
+ color: var(--ui-button-disabled-text, var(--ui-button-text, var(--ui-action-secondary-text, var(--ui-text-primary))));
145
+ }
146
+
147
+ :scope[data-ui-button-state~="variant=solid"]:disabled {
148
+ border-color: var(--ui-button-disabled-border, var(--ui-action-primary-surface, var(--ui-accent-solid)));
149
+ background-color: var(--ui-button-disabled-surface, var(--ui-action-primary-surface, var(--ui-accent-solid)));
150
+ color: var(--ui-button-disabled-text, var(--ui-action-primary-text, var(--ui-text-on-accent)));
151
+ }
152
+
153
+ :scope[data-ui-button-state~="variant=danger"]:disabled {
154
+ border-color: var(--ui-button-disabled-border, var(--ui-danger-solid));
155
+ background-color: var(--ui-button-disabled-surface, var(--ui-danger-solid));
156
+ color: var(--ui-button-disabled-text, var(--ui-text-on-accent));
157
+ }
158
+
159
+ :scope[data-ui-button-state~="variant=ghost"]:disabled {
160
+ border-color: transparent;
161
+ background-color: transparent;
162
+ color: var(--ui-button-disabled-text, var(--ui-button-ghost-text, var(--ui-action-secondary-text, var(--ui-text-primary))));
140
163
  }
141
164
 
142
165
  @media (pointer: coarse) {
@@ -176,6 +199,11 @@
176
199
  transform: none;
177
200
  }
178
201
 
202
+ :scope[data-ui-button-state~="variant=link"]:disabled {
203
+ background: none;
204
+ color: var(--ui-button-disabled-text, var(--ui-button-link-color, var(--ui-text-secondary)));
205
+ }
206
+
179
207
  :scope[data-ui-button-state~="variant=link"]:focus-visible {
180
208
  box-shadow: none;
181
209
  /* Fallback keeps the ring if the token is missing: an unresolved var() would void the outline. */
@@ -196,6 +224,8 @@
196
224
 
197
225
  /* A soft halo that transitions in with the other box-shadow changes, layered on the raised shadow. */
198
226
 
227
+ /* Disabled colours fall back to each variant's own; ghost and link take only the text colour. */
228
+
199
229
  @media (pointer: coarse) {
200
230
  }
201
231
 
@@ -126,11 +126,24 @@
126
126
  box-shadow: var(--ui-focus-halo);
127
127
  }
128
128
 
129
+ /* Disabled colours fall back to each variant's own; ghost takes only the icon colour. */
129
130
  :scope:disabled {
130
- opacity: 0.6;
131
+ opacity: var(--ui-icon-button-disabled-opacity, 0.6);
132
+ color: var(--ui-icon-button-disabled-color, inherit);
131
133
  cursor: not-allowed;
132
134
  }
133
135
 
136
+ :scope[data-ui-icon-button-state~="variant=outline"]:disabled {
137
+ border-color: var(--ui-icon-button-disabled-border, var(--ui-icon-button-border, var(--ui-border-default)));
138
+ background-color: var(--ui-icon-button-disabled-bg, var(--ui-icon-button-outline-bg, var(--ui-surface-default)));
139
+ color: var(--ui-icon-button-disabled-color, var(--ui-icon-button-outline-color, var(--ui-text-primary)));
140
+ }
141
+
142
+ :scope[data-ui-icon-button-state~="variant=solid"]:disabled {
143
+ background-color: var(--ui-icon-button-disabled-bg, var(--ui-icon-button-solid-bg, var(--ui-accent-solid)));
144
+ color: var(--ui-icon-button-disabled-color, var(--ui-icon-button-solid-color, var(--ui-text-on-accent)));
145
+ }
146
+
134
147
  :scope {
135
148
  --_icon-button-icon-default: var(--ui-icon-size-md, 1.25rem);
136
149
  }
@@ -158,6 +171,8 @@
158
171
  @media (hover: none), (pointer: coarse) {
159
172
  }
160
173
 
174
+ /* Disabled colours fall back to each variant's own; ghost takes only the icon colour. */
175
+
161
176
  :where([data-slotted], [data-slotted] *):is(svg) {
162
177
  inline-size: var(--ui-icon-button-icon-size, var(--_icon-button-icon-default));
163
178
  block-size: var(--ui-icon-button-icon-size, var(--_icon-button-icon-default));
package/vue/UiButton.vue CHANGED
@@ -146,6 +146,7 @@ function read(name: string): unknown {
146
146
  border-color: transparent;
147
147
  background: transparent;
148
148
  box-shadow: none;
149
+ color: var(--ui-button-ghost-text, var(--ui-action-secondary-text, var(--ui-text-primary)));
149
150
  }
150
151
 
151
152
  /* Tints derive from the text colour, not a surface token, so hover and press show on any background. */
@@ -173,9 +174,31 @@ function read(name: string): unknown {
173
174
  var(--ui-focus-halo);
174
175
  }
175
176
 
177
+ /* Disabled colours fall back to each variant's own; ghost and link take only the text colour. */
176
178
  [data-component~="ui-button"]:disabled {
177
- opacity: 0.6;
179
+ opacity: var(--ui-button-disabled-opacity, 0.6);
178
180
  cursor: not-allowed;
181
+ border-color: var(--ui-button-disabled-border, var(--ui-button-border, var(--ui-border-strong)));
182
+ background-color: var(--ui-button-disabled-surface, var(--ui-button-surface, var(--ui-surface-elevated)));
183
+ color: var(--ui-button-disabled-text, var(--ui-button-text, var(--ui-action-secondary-text, var(--ui-text-primary))));
184
+ }
185
+
186
+ [data-component~="ui-button"][data-ui-button-state~="variant=solid"]:disabled {
187
+ border-color: var(--ui-button-disabled-border, var(--ui-action-primary-surface, var(--ui-accent-solid)));
188
+ background-color: var(--ui-button-disabled-surface, var(--ui-action-primary-surface, var(--ui-accent-solid)));
189
+ color: var(--ui-button-disabled-text, var(--ui-action-primary-text, var(--ui-text-on-accent)));
190
+ }
191
+
192
+ [data-component~="ui-button"][data-ui-button-state~="variant=danger"]:disabled {
193
+ border-color: var(--ui-button-disabled-border, var(--ui-danger-solid));
194
+ background-color: var(--ui-button-disabled-surface, var(--ui-danger-solid));
195
+ color: var(--ui-button-disabled-text, var(--ui-text-on-accent));
196
+ }
197
+
198
+ [data-component~="ui-button"][data-ui-button-state~="variant=ghost"]:disabled {
199
+ border-color: transparent;
200
+ background-color: transparent;
201
+ color: var(--ui-button-disabled-text, var(--ui-button-ghost-text, var(--ui-action-secondary-text, var(--ui-text-primary))));
179
202
  }
180
203
 
181
204
  @media (pointer: coarse) {
@@ -215,6 +238,11 @@ function read(name: string): unknown {
215
238
  transform: none;
216
239
  }
217
240
 
241
+ [data-component~="ui-button"][data-ui-button-state~="variant=link"]:disabled {
242
+ background: none;
243
+ color: var(--ui-button-disabled-text, var(--ui-button-link-color, var(--ui-text-secondary)));
244
+ }
245
+
218
246
  [data-component~="ui-button"][data-ui-button-state~="variant=link"]:focus-visible {
219
247
  box-shadow: none;
220
248
  /* Fallback keeps the ring if the token is missing: an unresolved var() would void the outline. */
@@ -237,11 +237,24 @@ onBeforeUnmount(() => {
237
237
  box-shadow: var(--ui-focus-halo);
238
238
  }
239
239
 
240
+ /* Disabled colours fall back to each variant's own; ghost takes only the icon colour. */
240
241
  [data-component~="ui-icon-button"]:disabled {
241
- opacity: 0.6;
242
+ opacity: var(--ui-icon-button-disabled-opacity, 0.6);
243
+ color: var(--ui-icon-button-disabled-color, inherit);
242
244
  cursor: not-allowed;
243
245
  }
244
246
 
247
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"]:disabled {
248
+ border-color: var(--ui-icon-button-disabled-border, var(--ui-icon-button-border, var(--ui-border-default)));
249
+ background-color: var(--ui-icon-button-disabled-bg, var(--ui-icon-button-outline-bg, var(--ui-surface-default)));
250
+ color: var(--ui-icon-button-disabled-color, var(--ui-icon-button-outline-color, var(--ui-text-primary)));
251
+ }
252
+
253
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"]:disabled {
254
+ background-color: var(--ui-icon-button-disabled-bg, var(--ui-icon-button-solid-bg, var(--ui-accent-solid)));
255
+ color: var(--ui-icon-button-disabled-color, var(--ui-icon-button-solid-color, var(--ui-text-on-accent)));
256
+ }
257
+
245
258
  [data-component~="ui-icon-button"] {
246
259
  --_icon-button-icon-default: var(--ui-icon-size-md, 1.25rem);
247
260
  }
@@ -42,6 +42,6 @@ var UiButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
42
42
  }), [renderSlot(_ctx.$slots, "default", {}, void 0, true)], 16, _hoisted_1);
43
43
  };
44
44
  }
45
- }), [["__scopeId", "data-v-c8f3a3fb"]]);
45
+ }), [["__scopeId", "data-v-d75759c7"]]);
46
46
  //#endregion
47
47
  export { UiButton_default as t };
@@ -136,6 +136,6 @@ var UiIconButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
136
136
  }), [renderSlot(_ctx.$slots, "default")], 16, _hoisted_1);
137
137
  };
138
138
  }
139
- }), [["__scopeId", "data-v-370603ec"]]);
139
+ }), [["__scopeId", "data-v-1326805b"]]);
140
140
  //#endregion
141
141
  export { UiIconButton_default as t };
@@ -171,17 +171,17 @@
171
171
  display: none;
172
172
  }
173
173
 
174
- [data-component~="ui-button"][data-v-c8f3a3fb] {
174
+ [data-component~="ui-button"][data-v-d75759c7] {
175
175
  display: inline-flex;
176
176
  align-items: center;
177
177
  justify-content: center;
178
178
  vertical-align: middle;
179
179
  color: var(--ui-action-secondary-text, var(--ui-text-primary));
180
180
  }
181
- [data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-c8f3a3fb] {
181
+ [data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-d75759c7] {
182
182
  color: var(--ui-action-primary-text, var(--ui-text-on-accent));
183
183
  }
184
- [data-component~="ui-button"][data-v-c8f3a3fb] {
184
+ [data-component~="ui-button"][data-v-d75759c7] {
185
185
  appearance: none;
186
186
  min-block-size: var(--ui-button-min-block-size, var(--ui-control-size-md, 2.5rem));
187
187
  border: 1px solid var(--ui-button-border, var(--ui-border-strong));
@@ -204,103 +204,124 @@
204
204
  margin: 0;
205
205
  }
206
206
  @supports (text-box-trim: trim-both) {
207
- [data-component~="ui-button"][data-v-c8f3a3fb] {
207
+ [data-component~="ui-button"][data-v-d75759c7] {
208
208
  text-box-trim: trim-both;
209
209
  text-box-edge: cap alphabetic;
210
210
  }
211
211
  }
212
- [data-component~="ui-button"][data-ui-button-state~="size=sm"][data-v-c8f3a3fb] {
212
+ [data-component~="ui-button"][data-ui-button-state~="size=sm"][data-v-d75759c7] {
213
213
  min-block-size: var(--ui-control-size-sm, 2rem);
214
214
  padding: var(--ui-space-1) var(--ui-space-2);
215
215
  font-size: 0.875rem;
216
216
  }
217
- [data-component~="ui-button"][data-ui-button-state~="size=lg"][data-v-c8f3a3fb] {
217
+ [data-component~="ui-button"][data-ui-button-state~="size=lg"][data-v-d75759c7] {
218
218
  min-block-size: var(--ui-control-size-lg, 3rem);
219
219
  padding: var(--ui-space-3) var(--ui-space-4);
220
220
  font-size: 1rem;
221
221
  }
222
- [data-component~="ui-button"][data-v-c8f3a3fb]:hover:enabled {
222
+ [data-component~="ui-button"][data-v-d75759c7]:hover:enabled {
223
223
  background: var(--ui-action-secondary-surface-hover, var(--ui-surface-muted));
224
224
  border-color: var(--ui-control-border-hover, var(--ui-border-strong));
225
225
  }
226
- [data-component~="ui-button"][data-v-c8f3a3fb]:active:enabled {
226
+ [data-component~="ui-button"][data-v-d75759c7]:active:enabled {
227
227
  background: var(--ui-surface-subtle);
228
228
  }
229
- [data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-c8f3a3fb] {
229
+ [data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-d75759c7] {
230
230
  border-color: var(--ui-action-primary-surface, var(--ui-accent-solid));
231
231
  background: var(--ui-action-primary-surface, var(--ui-accent-solid));
232
232
  color: var(--ui-action-primary-text, var(--ui-text-on-accent));
233
233
  box-shadow: var(--ui-button-solid-shadow, inset 0 1px rgb(255 255 255 / 0.16), var(--ui-shadow-xs));
234
234
  }
235
- [data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-c8f3a3fb]:hover:enabled {
235
+ [data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-d75759c7]:hover:enabled {
236
236
  background: var(--ui-action-primary-surface-hover, var(--ui-accent-hover));
237
237
  border-color: var(--ui-action-primary-surface-hover, var(--ui-accent-hover));
238
238
  box-shadow: var(--ui-shadow-sm);
239
239
  transform: translateY(-1px);
240
240
  }
241
- [data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-c8f3a3fb]:active:enabled {
241
+ [data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-d75759c7]:active:enabled {
242
242
  background: var(--ui-action-primary-surface-active, var(--ui-accent-active));
243
243
  border-color: var(--ui-action-primary-surface-active, var(--ui-accent-active));
244
244
  box-shadow: none;
245
245
  transform: translateY(0);
246
246
  }
247
- [data-component~="ui-button"][data-ui-button-state~="variant=danger"][data-v-c8f3a3fb] {
247
+ [data-component~="ui-button"][data-ui-button-state~="variant=danger"][data-v-d75759c7] {
248
248
  border-color: var(--ui-danger-solid);
249
249
  background: var(--ui-danger-solid);
250
250
  color: var(--ui-text-on-accent);
251
251
  box-shadow: var(--ui-button-danger-shadow, inset 0 1px rgb(255 255 255 / 0.14), var(--ui-shadow-xs));
252
252
  }
253
- [data-component~="ui-button"][data-ui-button-state~="variant=danger"][data-v-c8f3a3fb]:hover:enabled {
253
+ [data-component~="ui-button"][data-ui-button-state~="variant=danger"][data-v-d75759c7]:hover:enabled {
254
254
  background: var(--ui-danger-hover);
255
255
  border-color: var(--ui-danger-hover);
256
256
  box-shadow: var(--ui-shadow-sm);
257
257
  transform: translateY(-1px);
258
258
  }
259
- [data-component~="ui-button"][data-ui-button-state~="variant=danger"][data-v-c8f3a3fb]:active:enabled {
259
+ [data-component~="ui-button"][data-ui-button-state~="variant=danger"][data-v-d75759c7]:active:enabled {
260
260
  box-shadow: none;
261
261
  transform: translateY(0);
262
262
  }
263
- [data-component~="ui-button"][data-ui-button-state~="variant=ghost"][data-v-c8f3a3fb] {
263
+ [data-component~="ui-button"][data-ui-button-state~="variant=ghost"][data-v-d75759c7] {
264
264
  border-color: transparent;
265
265
  background: transparent;
266
266
  box-shadow: none;
267
+ color: var(--ui-button-ghost-text, var(--ui-action-secondary-text, var(--ui-text-primary)));
267
268
  }
268
269
 
269
270
  /* Tints derive from the text colour, not a surface token, so hover and press show on any background. */
270
- [data-component~="ui-button"][data-ui-button-state~="variant=ghost"][data-v-c8f3a3fb]:hover:enabled {
271
+ [data-component~="ui-button"][data-ui-button-state~="variant=ghost"][data-v-d75759c7]:hover:enabled {
271
272
  background: var(--ui-button-ghost-hover, color-mix(in srgb, currentColor 8%, transparent));
272
273
  border-color: transparent;
273
274
  }
274
- [data-component~="ui-button"][data-ui-button-state~="variant=ghost"][data-v-c8f3a3fb]:active:enabled {
275
+ [data-component~="ui-button"][data-ui-button-state~="variant=ghost"][data-v-d75759c7]:active:enabled {
275
276
  background: var(--ui-button-ghost-active, color-mix(in srgb, currentColor 14%, transparent));
276
277
  border-color: transparent;
277
278
  }
278
279
 
279
280
  /* A soft halo that transitions in with the other box-shadow changes, layered on the raised shadow. */
280
- [data-component~="ui-button"][data-v-c8f3a3fb]:focus-visible {
281
+ [data-component~="ui-button"][data-v-d75759c7]:focus-visible {
281
282
  outline: none;
282
283
  box-shadow:
283
284
  var(--ui-button-shadow, var(--ui-raised, var(--ui-shadow-xs))),
284
285
  var(--ui-focus-halo);
285
286
  }
286
- [data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-c8f3a3fb]:focus-visible {
287
+ [data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-d75759c7]:focus-visible {
287
288
  box-shadow:
288
289
  var(--ui-button-solid-shadow, inset 0 1px rgb(255 255 255 / 0.16), var(--ui-shadow-xs)),
289
290
  var(--ui-focus-halo);
290
291
  }
291
- [data-component~="ui-button"][data-v-c8f3a3fb]:disabled {
292
- opacity: 0.6;
292
+
293
+ /* Disabled colours fall back to each variant's own; ghost and link take only the text colour. */
294
+ [data-component~="ui-button"][data-v-d75759c7]:disabled {
295
+ opacity: var(--ui-button-disabled-opacity, 0.6);
293
296
  cursor: not-allowed;
297
+ border-color: var(--ui-button-disabled-border, var(--ui-button-border, var(--ui-border-strong)));
298
+ background-color: var(--ui-button-disabled-surface, var(--ui-button-surface, var(--ui-surface-elevated)));
299
+ color: var(--ui-button-disabled-text, var(--ui-button-text, var(--ui-action-secondary-text, var(--ui-text-primary))));
300
+ }
301
+ [data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-d75759c7]:disabled {
302
+ border-color: var(--ui-button-disabled-border, var(--ui-action-primary-surface, var(--ui-accent-solid)));
303
+ background-color: var(--ui-button-disabled-surface, var(--ui-action-primary-surface, var(--ui-accent-solid)));
304
+ color: var(--ui-button-disabled-text, var(--ui-action-primary-text, var(--ui-text-on-accent)));
305
+ }
306
+ [data-component~="ui-button"][data-ui-button-state~="variant=danger"][data-v-d75759c7]:disabled {
307
+ border-color: var(--ui-button-disabled-border, var(--ui-danger-solid));
308
+ background-color: var(--ui-button-disabled-surface, var(--ui-danger-solid));
309
+ color: var(--ui-button-disabled-text, var(--ui-text-on-accent));
310
+ }
311
+ [data-component~="ui-button"][data-ui-button-state~="variant=ghost"][data-v-d75759c7]:disabled {
312
+ border-color: transparent;
313
+ background-color: transparent;
314
+ color: var(--ui-button-disabled-text, var(--ui-button-ghost-text, var(--ui-action-secondary-text, var(--ui-text-primary))));
294
315
  }
295
316
  @media (pointer: coarse) {
296
- [data-component~="ui-button"][data-v-c8f3a3fb] {
317
+ [data-component~="ui-button"][data-v-d75759c7] {
297
318
  min-block-size: var(--ui-control-min-block-size, 2.75rem);
298
319
  }
299
320
  }
300
321
 
301
322
  /* Link: an inline text action. No box, padding, or minimum height (inline targets are exempt under
302
323
  WCAG 2.5.8); the inherited font; an underline that strengthens on hover; a visible focus ring. */
303
- [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-c8f3a3fb] {
324
+ [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-d75759c7] {
304
325
  display: inline;
305
326
  min-block-size: 0;
306
327
  padding: 0;
@@ -316,17 +337,21 @@
316
337
  text-underline-offset: 0.2em;
317
338
  transition: color var(--ui-motion-fast) var(--ui-motion-ease), text-decoration-color var(--ui-motion-fast) var(--ui-motion-ease);
318
339
  }
319
- [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-c8f3a3fb]:hover:enabled {
340
+ [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-d75759c7]:hover:enabled {
320
341
  color: var(--ui-button-link-hover-color, var(--ui-text-primary));
321
342
  text-decoration-color: currentColor;
322
343
  background: none;
323
344
  transform: none;
324
345
  }
325
- [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-c8f3a3fb]:active:enabled {
346
+ [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-d75759c7]:active:enabled {
326
347
  background: none;
327
348
  transform: none;
328
349
  }
329
- [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-c8f3a3fb]:focus-visible {
350
+ [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-d75759c7]:disabled {
351
+ background: none;
352
+ color: var(--ui-button-disabled-text, var(--ui-button-link-color, var(--ui-text-secondary)));
353
+ }
354
+ [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-d75759c7]:focus-visible {
330
355
  box-shadow: none;
331
356
  /* Fallback keeps the ring if the token is missing: an unresolved var() would void the outline. */
332
357
  outline: 2px solid var(--ui-focus-ring, currentColor);
@@ -334,7 +359,7 @@
334
359
  }
335
360
 
336
361
  /* A component that sets its display still honours the hidden attribute on its root. */
337
- [data-component~="ui-button"][hidden][data-v-c8f3a3fb] {
362
+ [data-component~="ui-button"][hidden][data-v-d75759c7] {
338
363
  display: none;
339
364
  }
340
365
 
@@ -2315,14 +2340,14 @@ svg[data-v-b94e6e26-s] {
2315
2340
  display: none;
2316
2341
  }
2317
2342
 
2318
- [data-component~="ui-icon-button"][data-v-370603ec] {
2343
+ [data-component~="ui-icon-button"][data-v-1326805b] {
2319
2344
  display: inline-flex;
2320
2345
  color: var(--ui-text-secondary);
2321
2346
  }
2322
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-370603ec] {
2347
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-1326805b] {
2323
2348
  position: relative;
2324
2349
  }
2325
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-370603ec]::before {
2350
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-1326805b]::before {
2326
2351
  content: "";
2327
2352
  position: absolute;
2328
2353
  inset: 50% auto auto 50%;
@@ -2341,17 +2366,17 @@ svg[data-v-b94e6e26-s] {
2341
2366
  * surface and icon. The root is the native button, so hiding it outright would hide the dot
2342
2367
  * too, and slotted icons sit outside this scope; `color: transparent` hides currentColor icons. */
2343
2368
  @media (hover: hover) and (pointer: fine) {
2344
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-370603ec]:not([data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"], [data-ui-proximity="near"], :hover, :focus-visible) {
2369
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-1326805b]:not([data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"], [data-ui-proximity="near"], :hover, :focus-visible) {
2345
2370
  border-color: transparent;
2346
2371
  background: transparent;
2347
2372
  box-shadow: none;
2348
2373
  color: transparent;
2349
2374
  }
2350
2375
  }
2351
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-370603ec]:is([data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"], [data-ui-proximity="near"], :hover, :focus-visible)::before {
2376
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-1326805b]:is([data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"], [data-ui-proximity="near"], :hover, :focus-visible)::before {
2352
2377
  opacity: 0;
2353
2378
  }
2354
- [data-component~="ui-icon-button"][data-v-370603ec] {
2379
+ [data-component~="ui-icon-button"][data-v-1326805b] {
2355
2380
  appearance: none;
2356
2381
  inline-size: var(--ui-icon-button-size, 2rem);
2357
2382
  block-size: var(--ui-icon-button-size, 2rem);
@@ -2375,31 +2400,31 @@ svg[data-v-b94e6e26-s] {
2375
2400
  transform var(--ui-motion-fast) var(--ui-motion-ease);
2376
2401
  }
2377
2402
  @media (hover: none), (pointer: coarse) {
2378
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-370603ec]::before {
2403
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-1326805b]::before {
2379
2404
  opacity: 0;
2380
2405
  }
2381
2406
  }
2382
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=sm"][data-v-370603ec] {
2407
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=sm"][data-v-1326805b] {
2383
2408
  inline-size: var(--ui-icon-button-size-sm, 1.75rem);
2384
2409
  block-size: var(--ui-icon-button-size-sm, 1.75rem);
2385
2410
  min-inline-size: var(--ui-icon-button-size-sm, 1.75rem);
2386
2411
  min-block-size: var(--ui-icon-button-size-sm, 1.75rem);
2387
2412
  }
2388
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=lg"][data-v-370603ec] {
2413
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=lg"][data-v-1326805b] {
2389
2414
  inline-size: var(--ui-icon-button-size-lg, 2.5rem);
2390
2415
  block-size: var(--ui-icon-button-size-lg, 2.5rem);
2391
2416
  min-inline-size: var(--ui-icon-button-size-lg, 2.5rem);
2392
2417
  min-block-size: var(--ui-icon-button-size-lg, 2.5rem);
2393
2418
  }
2394
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="round"][data-v-370603ec] {
2419
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="round"][data-v-1326805b] {
2395
2420
  border-radius: var(--ui-radius-round, 999px);
2396
2421
  }
2397
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"][data-v-370603ec] {
2422
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"][data-v-1326805b] {
2398
2423
  border-color: var(--ui-icon-button-border, var(--ui-border-default));
2399
2424
  background: var(--ui-icon-button-outline-bg, var(--ui-surface-default));
2400
2425
  color: var(--ui-icon-button-outline-color, var(--ui-text-primary));
2401
2426
  }
2402
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"][data-v-370603ec] {
2427
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"][data-v-1326805b] {
2403
2428
  background: var(--ui-icon-button-solid-bg, var(--ui-accent-solid));
2404
2429
  color: var(--ui-icon-button-solid-color, var(--ui-text-on-accent));
2405
2430
  box-shadow: var(
@@ -2407,38 +2432,50 @@ svg[data-v-b94e6e26-s] {
2407
2432
  0 1px 2px color-mix(in srgb, var(--ui-accent-solid) 18%, transparent)
2408
2433
  );
2409
2434
  }
2410
- [data-component~="ui-icon-button"][data-v-370603ec]:hover:enabled {
2435
+ [data-component~="ui-icon-button"][data-v-1326805b]:hover:enabled {
2411
2436
  /* Derived from the text colour so the ghost hover shows on any background. */
2412
2437
  background: var(--ui-icon-button-hover-bg, color-mix(in srgb, currentColor 8%, transparent));
2413
2438
  color: var(--ui-icon-button-hover-color, var(--ui-text-primary));
2414
2439
  }
2415
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"][data-v-370603ec]:hover:enabled {
2440
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"][data-v-1326805b]:hover:enabled {
2416
2441
  border-color: var(--ui-icon-button-hover-border, var(--ui-border-strong));
2417
2442
  }
2418
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"][data-v-370603ec]:hover:enabled {
2443
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"][data-v-1326805b]:hover:enabled {
2419
2444
  background: var(--ui-icon-button-solid-hover-bg, var(--ui-accent-hover));
2420
2445
  }
2421
- [data-component~="ui-icon-button"][data-v-370603ec]:active:enabled {
2446
+ [data-component~="ui-icon-button"][data-v-1326805b]:active:enabled {
2422
2447
  transform: scale(var(--ui-icon-button-active-scale, 0.96));
2423
2448
  }
2424
- [data-component~="ui-icon-button"][data-v-370603ec]:focus-visible {
2449
+ [data-component~="ui-icon-button"][data-v-1326805b]:focus-visible {
2425
2450
  outline: none;
2426
2451
  box-shadow: var(--ui-focus-halo);
2427
2452
  }
2428
- [data-component~="ui-icon-button"][data-v-370603ec]:disabled {
2429
- opacity: 0.6;
2453
+
2454
+ /* Disabled colours fall back to each variant's own; ghost takes only the icon colour. */
2455
+ [data-component~="ui-icon-button"][data-v-1326805b]:disabled {
2456
+ opacity: var(--ui-icon-button-disabled-opacity, 0.6);
2457
+ color: var(--ui-icon-button-disabled-color, inherit);
2430
2458
  cursor: not-allowed;
2431
2459
  }
2432
- [data-component~="ui-icon-button"][data-v-370603ec] {
2460
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"][data-v-1326805b]:disabled {
2461
+ border-color: var(--ui-icon-button-disabled-border, var(--ui-icon-button-border, var(--ui-border-default)));
2462
+ background-color: var(--ui-icon-button-disabled-bg, var(--ui-icon-button-outline-bg, var(--ui-surface-default)));
2463
+ color: var(--ui-icon-button-disabled-color, var(--ui-icon-button-outline-color, var(--ui-text-primary)));
2464
+ }
2465
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"][data-v-1326805b]:disabled {
2466
+ background-color: var(--ui-icon-button-disabled-bg, var(--ui-icon-button-solid-bg, var(--ui-accent-solid)));
2467
+ color: var(--ui-icon-button-disabled-color, var(--ui-icon-button-solid-color, var(--ui-text-on-accent)));
2468
+ }
2469
+ [data-component~="ui-icon-button"][data-v-1326805b] {
2433
2470
  --_icon-button-icon-default: var(--ui-icon-size-md, 1.25rem);
2434
2471
  }
2435
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=sm"][data-v-370603ec] {
2472
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=sm"][data-v-1326805b] {
2436
2473
  --_icon-button-icon-default: var(--ui-icon-size-sm, 1rem);
2437
2474
  }
2438
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=lg"][data-v-370603ec] {
2475
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=lg"][data-v-1326805b] {
2439
2476
  --_icon-button-icon-default: var(--ui-icon-size-lg, 1.5rem);
2440
2477
  }
2441
- svg[data-v-370603ec-s] {
2478
+ svg[data-v-1326805b-s] {
2442
2479
  inline-size: var(--ui-icon-button-icon-size, var(--_icon-button-icon-default));
2443
2480
  block-size: var(--ui-icon-button-icon-size, var(--_icon-button-icon-default));
2444
2481
  flex-shrink: 0;
@@ -2446,7 +2483,7 @@ svg[data-v-370603ec-s] {
2446
2483
  }
2447
2484
 
2448
2485
  /* A component that sets its display still honours the hidden attribute on its root. */
2449
- [data-component~="ui-icon-button"][hidden][data-v-370603ec] {
2486
+ [data-component~="ui-icon-button"][hidden][data-v-1326805b] {
2450
2487
  display: none;
2451
2488
  }
2452
2489
 
package/vue/index.d.ts CHANGED
@@ -46,3 +46,4 @@ export { default as Tooltip } from "./UiTooltip.js";
46
46
  export { default as TopBar } from "./UiTopBar.js";
47
47
  export { default as Tree } from "./UiTree.js";
48
48
  export { default as TreeItem } from "./UiTreeItem.js";
49
+ export { trackInputModality } from "../components/shared/input-modality.js";
package/vue/index.js CHANGED
@@ -46,4 +46,5 @@ import { t as UiToastRegion_default } from "./chunks/UiToastRegion.js";
46
46
  import { t as UiTopBar_default } from "./chunks/UiTopBar.js";
47
47
  import { t as UiTree_default } from "./chunks/UiTree.js";
48
48
  import { t as UiTreeItem_default } from "./chunks/UiTreeItem.js";
49
- export { UiAffordanceScope_default as AffordanceScope, UiAvatar_default as Avatar, UiAvatarGroup_default as AvatarGroup, UiBadge_default as Badge, UiButton_default as Button, UiCallout_default as Callout, UiCheckbox_default as Checkbox, UiCluster_default as Cluster, UiCombobox_default as Combobox, UiContainer_default as Container, UiContextMenu_default as ContextMenu, UiDialog_default as Dialog, UiDisclosure_default as Disclosure, UiEditable_default as Editable, UiEditorInsertTableGrid_default as EditorInsertTableGrid, UiEditorMentionMenu_default as EditorMentionMenu, UiEditorSlashMenu_default as EditorSlashMenu, UiEditorTableContextMenu_default as EditorTableContextMenu, UiEditorTableOverlay_default as EditorTableOverlay, UiEditorTableToolbar_default as EditorTableToolbar, UiEditorToolbar_default as EditorToolbar, UiFloatingActionButton_default as FloatingActionButton, UiFormField_default as FormField, UiGrid_default as Grid, UiIcon_default as Icon, UiIconButton_default as IconButton, UiInput_default as Input, UiMenu_default as Menu, UiMenuItem_default as MenuItem, UiPopover_default as Popover, UiRadio_default as Radio, UiRadioGroup_default as RadioGroup, UiReel_default as Reel, UiSearchResultRow_default as SearchResultRow, UiSearchShell_default as SearchShell, UiSelect_default as Select, UiSeparator_default as Separator, UiSidebar_default as Sidebar, UiStack_default as Stack, UiSwitch_default as Switch, UiSwitcher_default as Switcher, UiTabs_default as Tabs, UiTextarea_default as Textarea, UiToastRegion_default as ToastRegion, UiTooltip_default as Tooltip, UiTopBar_default as TopBar, UiTree_default as Tree, UiTreeItem_default as TreeItem };
49
+ import { trackInputModality } from "@threadlabs/looma/components/shared/input-modality.js";
50
+ export { UiAffordanceScope_default as AffordanceScope, UiAvatar_default as Avatar, UiAvatarGroup_default as AvatarGroup, UiBadge_default as Badge, UiButton_default as Button, UiCallout_default as Callout, UiCheckbox_default as Checkbox, UiCluster_default as Cluster, UiCombobox_default as Combobox, UiContainer_default as Container, UiContextMenu_default as ContextMenu, UiDialog_default as Dialog, UiDisclosure_default as Disclosure, UiEditable_default as Editable, UiEditorInsertTableGrid_default as EditorInsertTableGrid, UiEditorMentionMenu_default as EditorMentionMenu, UiEditorSlashMenu_default as EditorSlashMenu, UiEditorTableContextMenu_default as EditorTableContextMenu, UiEditorTableOverlay_default as EditorTableOverlay, UiEditorTableToolbar_default as EditorTableToolbar, UiEditorToolbar_default as EditorToolbar, UiFloatingActionButton_default as FloatingActionButton, UiFormField_default as FormField, UiGrid_default as Grid, UiIcon_default as Icon, UiIconButton_default as IconButton, UiInput_default as Input, UiMenu_default as Menu, UiMenuItem_default as MenuItem, UiPopover_default as Popover, UiRadio_default as Radio, UiRadioGroup_default as RadioGroup, UiReel_default as Reel, UiSearchResultRow_default as SearchResultRow, UiSearchShell_default as SearchShell, UiSelect_default as Select, UiSeparator_default as Separator, UiSidebar_default as Sidebar, UiStack_default as Stack, UiSwitch_default as Switch, UiSwitcher_default as Switcher, UiTabs_default as Tabs, UiTextarea_default as Textarea, UiToastRegion_default as ToastRegion, UiTooltip_default as Tooltip, UiTopBar_default as TopBar, UiTree_default as Tree, UiTreeItem_default as TreeItem, trackInputModality };