@threadlabs/looma 0.12.1 → 0.12.3

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.
@@ -169,10 +169,11 @@
169
169
  display: none;
170
170
  }
171
171
 
172
- [data-component~="ui-badge"][data-v-0dbc98f0] {
172
+ [data-component~="ui-badge"][data-v-4fe703f2] {
173
173
  --_badge-surface: var(--ui-surface-subtle);
174
174
  --_badge-text: var(--ui-text-secondary);
175
- --_badge-border: color-mix(in srgb, var(--ui-text-secondary) 30%, transparent);
175
+ /* Every tone's edge is its fill, so it is unseen until forced colors draw it. */
176
+ --_badge-border: var(--ui-surface-subtle);
176
177
 
177
178
  display: inline-flex;
178
179
  align-items: center;
@@ -191,12 +192,12 @@
191
192
  white-space: nowrap;
192
193
  }
193
194
 
194
- /* Centre the glyphs, not the line box: a label without descenders otherwise reads high. */
195
195
  /* Centre the glyphs, not the line box: a label without descenders otherwise reads high.
196
- * Trimming applies to block containers, so the box is a block with centred content. */
196
+ * Trimming applies to block containers; an inline-block is one and, like the inline-flex it
197
+ * replaces, still sizes to its label rather than filling its container. */
197
198
  @supports (text-box-trim: trim-both) {
198
- [data-component~="ui-badge"][data-v-0dbc98f0] {
199
- display: block;
199
+ [data-component~="ui-badge"][data-v-4fe703f2] {
200
+ display: inline-block;
200
201
  min-block-size: var(--ui-badge-min-block-size, 1.5rem);
201
202
  text-align: center;
202
203
  align-content: center;
@@ -204,52 +205,52 @@
204
205
  text-box-edge: cap alphabetic;
205
206
  }
206
207
  }
207
- [data-component~="ui-badge"][data-ui-badge-state~="tone=accent"][data-v-0dbc98f0] {
208
+ [data-component~="ui-badge"][data-ui-badge-state~="tone=accent"][data-v-4fe703f2] {
208
209
  --_badge-surface: var(--ui-accent-strong-surface, var(--ui-accent-solid));
209
210
  --_badge-border: var(--ui-accent-strong-surface, var(--ui-accent-solid));
210
211
  --_badge-text: var(--ui-accent-on-strong, var(--ui-text-on-accent));
211
212
  }
212
- [data-component~="ui-badge"][data-ui-badge-state~="tone=danger"][data-v-0dbc98f0] {
213
+ [data-component~="ui-badge"][data-ui-badge-state~="tone=danger"][data-v-4fe703f2] {
213
214
  --_badge-surface: var(--ui-danger-strong-surface, var(--ui-danger-solid));
214
215
  --_badge-border: var(--ui-danger-strong-surface, var(--ui-danger-solid));
215
216
  --_badge-text: var(--ui-danger-on-strong, var(--ui-text-on-accent));
216
217
  }
217
- [data-component~="ui-badge"][data-ui-badge-state~="tone=success"][data-v-0dbc98f0] {
218
+ [data-component~="ui-badge"][data-ui-badge-state~="tone=success"][data-v-4fe703f2] {
218
219
  --_badge-surface: var(--ui-success-strong-surface, var(--ui-success-solid));
219
220
  --_badge-border: var(--ui-success-strong-surface, var(--ui-success-solid));
220
221
  --_badge-text: var(--ui-success-on-strong, var(--ui-text-on-accent));
221
222
  }
222
- [data-component~="ui-badge"][data-ui-badge-state~="tone=warning"][data-v-0dbc98f0] {
223
+ [data-component~="ui-badge"][data-ui-badge-state~="tone=warning"][data-v-4fe703f2] {
223
224
  --_badge-surface: var(--ui-warning-strong-surface, var(--ui-warning-solid));
224
225
  --_badge-border: var(--ui-warning-strong-surface, var(--ui-warning-solid));
225
226
  --_badge-text: var(--ui-warning-on-strong, var(--ui-text-on-accent));
226
227
  }
227
- [data-component~="ui-badge"][data-ui-badge-state~="tone=info"][data-v-0dbc98f0] {
228
+ [data-component~="ui-badge"][data-ui-badge-state~="tone=info"][data-v-4fe703f2] {
228
229
  --_badge-surface: var(--ui-info-strong-surface, var(--ui-info-solid));
229
230
  --_badge-border: var(--ui-info-strong-surface, var(--ui-info-solid));
230
231
  --_badge-text: var(--ui-info-on-strong, var(--ui-text-on-accent));
231
232
  }
232
- [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=accent"][data-v-0dbc98f0] {
233
+ [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=accent"][data-v-4fe703f2] {
233
234
  --_badge-surface: var(--ui-accent-soft);
234
235
  --_badge-border: var(--ui-accent-soft);
235
236
  --_badge-text: var(--ui-accent-subtle-text, var(--ui-accent-solid));
236
237
  }
237
- [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=danger"][data-v-0dbc98f0] {
238
+ [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=danger"][data-v-4fe703f2] {
238
239
  --_badge-surface: var(--ui-danger-soft);
239
240
  --_badge-border: var(--ui-danger-soft);
240
241
  --_badge-text: var(--ui-danger-subtle-text, var(--ui-danger-solid));
241
242
  }
242
- [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=success"][data-v-0dbc98f0] {
243
+ [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=success"][data-v-4fe703f2] {
243
244
  --_badge-surface: var(--ui-success-soft);
244
245
  --_badge-border: var(--ui-success-soft);
245
246
  --_badge-text: var(--ui-success-subtle-text, var(--ui-success-solid));
246
247
  }
247
- [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=warning"][data-v-0dbc98f0] {
248
+ [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=warning"][data-v-4fe703f2] {
248
249
  --_badge-surface: var(--ui-warning-soft);
249
250
  --_badge-border: var(--ui-warning-soft);
250
251
  --_badge-text: var(--ui-warning-subtle-text, var(--ui-warning-solid));
251
252
  }
252
- [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=info"][data-v-0dbc98f0] {
253
+ [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=info"][data-v-4fe703f2] {
253
254
  --_badge-surface: var(--ui-info-soft);
254
255
  --_badge-border: var(--ui-info-soft);
255
256
  --_badge-text: var(--ui-info-subtle-text, var(--ui-info-solid));
@@ -258,7 +259,7 @@
258
259
  /* A tag is flat at the start and points at the end. The point is cut from the box, so it has no
259
260
  outline to follow: the edge is the fill. The end padding grows by the point's depth so the
260
261
  label never runs into it. */
261
- [data-component~="ui-badge"][data-ui-badge-state~="shape=tag"][data-v-0dbc98f0] {
262
+ [data-component~="ui-badge"][data-ui-badge-state~="shape=tag"][data-v-4fe703f2] {
262
263
  --_badge-point: var(--ui-badge-point, var(--ui-space-2));
263
264
 
264
265
  border-color: transparent;
@@ -272,7 +273,7 @@
272
273
  0 100%
273
274
  );
274
275
  }
275
- [data-component~="ui-badge"][data-ui-badge-state~="shape=tag"][data-v-0dbc98f0]:dir(rtl) {
276
+ [data-component~="ui-badge"][data-ui-badge-state~="shape=tag"][data-v-4fe703f2]:dir(rtl) {
276
277
  padding-inline-end: var(--ui-badge-padding-inline, var(--ui-space-2));
277
278
  padding-inline-start: calc(
278
279
  var(--ui-badge-padding-inline, var(--ui-space-2)) + var(--_badge-point)
@@ -281,7 +282,7 @@
281
282
  }
282
283
 
283
284
  /* A component that sets its display still honours the hidden attribute on its root. */
284
- [data-component~="ui-badge"][hidden][data-v-0dbc98f0] {
285
+ [data-component~="ui-badge"][hidden][data-v-4fe703f2] {
285
286
  display: none;
286
287
  }
287
288
 
@@ -3146,16 +3147,17 @@ svg[data-v-c322b7ed-s] {
3146
3147
  display: none;
3147
3148
  }
3148
3149
 
3149
- [data-component~="ui-input"][data-v-c19f8322] {
3150
+ [data-component~="ui-input"][data-v-e7c851a2] {
3150
3151
  box-sizing: border-box;
3151
3152
  display: inline-block;
3152
3153
  inline-size: 100%;
3153
3154
  min-inline-size: 0;
3154
- min-block-size: var(--ui-control-size-md);
3155
+ min-block-size: var(--ui-input-min-block-size, var(--ui-control-size-md));
3155
3156
  margin: 0;
3156
3157
  padding: var(--ui-space-2) var(--ui-space-3);
3157
3158
  appearance: none;
3158
- border: 1px solid var(--ui-input-border, var(--ui-control-border, var(--ui-border-strong)));
3159
+ border: var(--ui-input-border-width, 1px) solid
3160
+ var(--ui-input-border, var(--ui-control-border, var(--ui-border-strong)));
3159
3161
  border-radius: var(--ui-input-radius, var(--ui-radius-md));
3160
3162
  background: var(--ui-input-surface, var(--ui-control-surface, var(--ui-surface-elevated)));
3161
3163
  color: var(--ui-text-primary);
@@ -3169,21 +3171,21 @@ svg[data-v-c322b7ed-s] {
3169
3171
  }
3170
3172
 
3171
3173
  /* Tabbing into a field selects its text; tint that selection softly instead of the page highlight. */
3172
- [data-component~="ui-input"][data-v-c19f8322]::selection {
3174
+ [data-component~="ui-input"][data-v-e7c851a2]::selection {
3173
3175
  background: color-mix(in srgb, var(--ui-accent-solid) 20%, transparent);
3174
3176
  color: inherit;
3175
3177
  }
3176
- [data-component~="ui-input"][data-v-c19f8322]::placeholder {
3178
+ [data-component~="ui-input"][data-v-e7c851a2]::placeholder {
3177
3179
  color: var(--ui-control-placeholder, var(--ui-text-secondary));
3178
3180
  opacity: 1;
3179
3181
  }
3180
- [data-component~="ui-input"][data-v-c19f8322]:hover:not(:focus):not(:disabled) {
3182
+ [data-component~="ui-input"][data-v-e7c851a2]:hover:not(:focus):not(:disabled) {
3181
3183
  border-color: var(
3182
3184
  --ui-input-border-hover,
3183
3185
  var(--ui-control-border-hover, var(--ui-text-secondary))
3184
3186
  );
3185
3187
  }
3186
- [data-component~="ui-input"][data-v-c19f8322]:focus-visible {
3188
+ [data-component~="ui-input"][data-v-e7c851a2]:focus-visible {
3187
3189
  border-color: var(--ui-input-focus-border, var(--ui-control-focus, var(--ui-accent-solid)));
3188
3190
  outline: none;
3189
3191
  box-shadow: var(
@@ -3194,29 +3196,37 @@ svg[data-v-c322b7ed-s] {
3194
3196
  }
3195
3197
 
3196
3198
  /* The app's invalid flag, or the browser's own verdict once the user has left an invalid field. */
3197
- [data-component~="ui-input"][aria-invalid="true"][data-v-c19f8322],
3198
- [data-component~="ui-input"][data-v-c19f8322]:is(:user-invalid, [data-user-invalid]) {
3199
+ [data-component~="ui-input"][aria-invalid="true"][data-v-e7c851a2],
3200
+ [data-component~="ui-input"][data-v-e7c851a2]:is(:user-invalid, [data-user-invalid]) {
3199
3201
  border-color: var(--ui-input-invalid-border, var(--ui-danger-solid));
3200
3202
  }
3201
- [data-component~="ui-input"][data-v-c19f8322]:is([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])):focus-visible {
3203
+ [data-component~="ui-input"][data-v-e7c851a2]:is([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])):focus-visible {
3202
3204
  box-shadow: var(
3203
3205
  --ui-input-invalid-focus-shadow,
3204
3206
  var(--ui-control-inset),
3205
3207
  0 0 0 3px color-mix(in srgb, var(--ui-danger-solid) 22%, transparent)
3206
3208
  );
3207
3209
  }
3208
- [data-component~="ui-input"][data-v-c19f8322]:disabled {
3210
+ [data-component~="ui-input"][data-v-e7c851a2]:disabled {
3209
3211
  background: var(--ui-control-surface-disabled, var(--ui-surface-muted));
3210
3212
  color: var(--ui-text-muted);
3211
3213
  box-shadow: none;
3212
3214
  cursor: not-allowed;
3213
3215
  }
3214
3216
 
3217
+ /* Forced colors drop box shadows, so the focus ring becomes an outline. */
3218
+ @media (forced-colors: active) {
3219
+ [data-component~="ui-input"][data-v-e7c851a2]:focus-visible {
3220
+ outline: var(--ui-input-focus-outline, 2px solid Highlight);
3221
+ outline-offset: 1px;
3222
+ }
3223
+ }
3224
+
3215
3225
  /* No text-box-trim here: trimming a native input's line box below its line height lets the text
3216
3226
  * scroll vertically inside the field. Native inputs already center their single line. */
3217
3227
 
3218
3228
  /* A component that sets its display still honours the hidden attribute on its root. */
3219
- [data-component~="ui-input"][hidden][data-v-c19f8322] {
3229
+ [data-component~="ui-input"][hidden][data-v-e7c851a2] {
3220
3230
  display: none;
3221
3231
  }
3222
3232
 
@@ -3228,7 +3238,10 @@ svg[data-v-c322b7ed-s] {
3228
3238
  whole value is. The action slot takes one button at the end, inside the border, for the one
3229
3239
  thing the field is for ("Continue" after a site's address), so it reads as the field's action
3230
3240
  and not the form's. */
3231
- [data-component~="ui-input-group"][data-v-ac7159ba] {
3241
+ [data-component~="ui-input-group"][data-v-027c11f5] {
3242
+ /* The group's own border and height stand for the input's, so the group is a lone Input's height. */
3243
+ --ui-input-border-width: 0;
3244
+ --ui-input-min-block-size: 0;
3232
3245
  --ui-input-border: transparent;
3233
3246
  --ui-input-border-hover: transparent;
3234
3247
  --ui-input-focus-border: transparent;
@@ -3236,6 +3249,7 @@ svg[data-v-c322b7ed-s] {
3236
3249
  --ui-input-invalid-focus-shadow: none;
3237
3250
  --ui-input-shadow: none;
3238
3251
  --ui-input-focus-shadow: none;
3252
+ --ui-input-focus-outline: none;
3239
3253
  --ui-input-radius: 0;
3240
3254
  --ui-input-surface: transparent;
3241
3255
 
@@ -3245,39 +3259,58 @@ svg[data-v-c322b7ed-s] {
3245
3259
  inline-size: 100%;
3246
3260
  min-inline-size: 0;
3247
3261
  min-block-size: var(--ui-control-size-md);
3248
- border: 1px solid var(--ui-border-strong);
3262
+ /* The frame reads the shared control tokens with a lone Input's fallbacks, so the two match. */
3263
+ border: 1px solid var(--ui-control-border, var(--ui-border-strong));
3249
3264
  border-radius: var(--ui-radius-md);
3250
- background: var(--ui-surface-elevated);
3265
+ background: var(--ui-control-surface, var(--ui-surface-elevated));
3251
3266
  box-shadow: var(--ui-control-inset);
3252
3267
  overflow: hidden;
3268
+ /* A press anywhere in the frame focuses the input. */
3269
+ cursor: text;
3253
3270
  transition:
3254
3271
  border-color var(--ui-motion-fast) var(--ui-motion-ease),
3255
3272
  box-shadow var(--ui-motion-fast) var(--ui-motion-ease);
3256
3273
  }
3257
- [data-component~="ui-input-group"][data-v-ac7159ba]:hover:not(:focus-within) {
3258
- border-color: var(--ui-text-secondary);
3274
+ [data-component~="ui-input-group"][data-v-027c11f5]:hover:not(:has(input:focus, input:disabled)) {
3275
+ border-color: var(--ui-control-border-hover, var(--ui-text-secondary));
3259
3276
  }
3260
3277
 
3261
- /* The field's focus, not the action's: a focused button draws its own ring. */
3262
- [data-component~="ui-input-group"][data-v-ac7159ba]:has(.field :focus) {
3263
- border-color: var(--ui-accent-solid);
3278
+ /* The ring shows when the field's input would show its own: when it is focus-visible, which a
3279
+ text input is for a pointer as well as a keyboard. A focused action button draws its own. */
3280
+ [data-component~="ui-input-group"][data-v-027c11f5]:has(.field input:focus-visible) {
3281
+ border-color: var(--ui-control-focus, var(--ui-accent-solid));
3264
3282
  box-shadow:
3265
3283
  var(--ui-control-inset),
3266
3284
  var(--ui-control-focus-halo-shadow);
3267
3285
  }
3268
- [data-component~="ui-input-group"][data-v-ac7159ba]:has([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])) {
3286
+ [data-component~="ui-input-group"][data-v-027c11f5]:has([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])) {
3269
3287
  border-color: var(--ui-danger-solid);
3270
3288
  }
3271
- [data-component~="ui-input-group"][data-ui-input-group-state~="disabled"][data-v-ac7159ba] {
3272
- background: var(--ui-surface-muted);
3289
+ [data-component~="ui-input-group"][data-v-027c11f5]:has(input:is([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])):focus-visible) {
3290
+ box-shadow:
3291
+ var(--ui-control-inset),
3292
+ 0 0 0 3px color-mix(in srgb, var(--ui-danger-solid) 22%, transparent);
3293
+ }
3294
+
3295
+ /* Forced colors drop box shadows, so the focus ring becomes an outline. */
3296
+ @media (forced-colors: active) {
3297
+ [data-component~="ui-input-group"][data-v-027c11f5]:has(input:focus-visible) {
3298
+ outline: 2px solid Highlight;
3299
+ outline-offset: 1px;
3300
+ }
3301
+ }
3302
+ [data-component~="ui-input-group"][data-ui-input-group-state~="disabled"][data-v-027c11f5],
3303
+ [data-component~="ui-input-group"][data-v-027c11f5]:has(input:disabled) {
3304
+ background: var(--ui-control-surface-disabled, var(--ui-surface-muted));
3273
3305
  box-shadow: none;
3306
+ cursor: not-allowed;
3274
3307
  }
3275
- .field[data-v-ac7159ba] {
3308
+ .field[data-v-027c11f5] {
3276
3309
  display: flex;
3277
3310
  flex: 1;
3278
3311
  min-inline-size: 0;
3279
3312
  }
3280
- .affix[data-v-ac7159ba] {
3313
+ .affix[data-v-027c11f5] {
3281
3314
  display: inline-flex;
3282
3315
  flex: none;
3283
3316
  align-items: center;
@@ -3287,19 +3320,22 @@ svg[data-v-c322b7ed-s] {
3287
3320
  font-size: var(--ui-font-size-sm);
3288
3321
  white-space: nowrap;
3289
3322
  }
3290
- .action[data-v-ac7159ba] {
3323
+
3324
+ /* Centred rather than padded above and below: the group is exactly a lone Input's height, so a
3325
+ small button sits inside it with the difference split evenly, and the field keeps its height. */
3326
+ .action[data-v-027c11f5] {
3291
3327
  display: flex;
3292
3328
  flex: none;
3293
- align-items: stretch;
3294
- padding: var(--ui-space-1);
3329
+ align-items: center;
3330
+ padding-inline: var(--ui-space-1);
3295
3331
  }
3296
- .affix[data-v-ac7159ba]:empty,
3297
- .action[data-v-ac7159ba]:empty {
3332
+ .affix[data-v-027c11f5]:empty,
3333
+ .action[data-v-027c11f5]:empty {
3298
3334
  display: none;
3299
3335
  }
3300
3336
 
3301
3337
  /* A component that sets its display still honours the hidden attribute on its root. */
3302
- [data-component~="ui-input-group"][hidden][data-v-ac7159ba] {
3338
+ [data-component~="ui-input-group"][hidden][data-v-027c11f5] {
3303
3339
  display: none;
3304
3340
  }
3305
3341