@threadlabs/looma 0.12.0 → 0.12.2
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/components/ui-form-field/ui-form-field.js +3 -2
- package/components/ui-input/ui-input.html +10 -2
- package/components/ui-input-group/ui-input-group.html +49 -11
- package/components/ui-input-group/ui-input-group.js +60 -0
- package/dist/index.js +17 -16
- package/package.json +1 -1
- package/styles/ui-input-group.css +60 -11
- package/styles/ui-input.css +14 -2
- package/vanilla/UiInputGroup.js +18 -5
- package/vue/UiInput.vue +11 -2
- package/vue/UiInputGroup.d.ts +3 -1
- package/vue/UiInputGroup.vue +62 -11
- package/vue/chunks/UiInput.js +1 -1
- package/vue/chunks/UiInputGroup.js +19 -4
- package/vue/components.css +73 -27
package/vue/components.css
CHANGED
|
@@ -3146,16 +3146,17 @@ svg[data-v-c322b7ed-s] {
|
|
|
3146
3146
|
display: none;
|
|
3147
3147
|
}
|
|
3148
3148
|
|
|
3149
|
-
[data-component~="ui-input"][data-v-
|
|
3149
|
+
[data-component~="ui-input"][data-v-e7c851a2] {
|
|
3150
3150
|
box-sizing: border-box;
|
|
3151
3151
|
display: inline-block;
|
|
3152
3152
|
inline-size: 100%;
|
|
3153
3153
|
min-inline-size: 0;
|
|
3154
|
-
min-block-size: var(--ui-control-size-md);
|
|
3154
|
+
min-block-size: var(--ui-input-min-block-size, var(--ui-control-size-md));
|
|
3155
3155
|
margin: 0;
|
|
3156
3156
|
padding: var(--ui-space-2) var(--ui-space-3);
|
|
3157
3157
|
appearance: none;
|
|
3158
|
-
border:
|
|
3158
|
+
border: var(--ui-input-border-width, 1px) solid
|
|
3159
|
+
var(--ui-input-border, var(--ui-control-border, var(--ui-border-strong)));
|
|
3159
3160
|
border-radius: var(--ui-input-radius, var(--ui-radius-md));
|
|
3160
3161
|
background: var(--ui-input-surface, var(--ui-control-surface, var(--ui-surface-elevated)));
|
|
3161
3162
|
color: var(--ui-text-primary);
|
|
@@ -3169,21 +3170,21 @@ svg[data-v-c322b7ed-s] {
|
|
|
3169
3170
|
}
|
|
3170
3171
|
|
|
3171
3172
|
/* Tabbing into a field selects its text; tint that selection softly instead of the page highlight. */
|
|
3172
|
-
[data-component~="ui-input"][data-v-
|
|
3173
|
+
[data-component~="ui-input"][data-v-e7c851a2]::selection {
|
|
3173
3174
|
background: color-mix(in srgb, var(--ui-accent-solid) 20%, transparent);
|
|
3174
3175
|
color: inherit;
|
|
3175
3176
|
}
|
|
3176
|
-
[data-component~="ui-input"][data-v-
|
|
3177
|
+
[data-component~="ui-input"][data-v-e7c851a2]::placeholder {
|
|
3177
3178
|
color: var(--ui-control-placeholder, var(--ui-text-secondary));
|
|
3178
3179
|
opacity: 1;
|
|
3179
3180
|
}
|
|
3180
|
-
[data-component~="ui-input"][data-v-
|
|
3181
|
+
[data-component~="ui-input"][data-v-e7c851a2]:hover:not(:focus):not(:disabled) {
|
|
3181
3182
|
border-color: var(
|
|
3182
3183
|
--ui-input-border-hover,
|
|
3183
3184
|
var(--ui-control-border-hover, var(--ui-text-secondary))
|
|
3184
3185
|
);
|
|
3185
3186
|
}
|
|
3186
|
-
[data-component~="ui-input"][data-v-
|
|
3187
|
+
[data-component~="ui-input"][data-v-e7c851a2]:focus-visible {
|
|
3187
3188
|
border-color: var(--ui-input-focus-border, var(--ui-control-focus, var(--ui-accent-solid)));
|
|
3188
3189
|
outline: none;
|
|
3189
3190
|
box-shadow: var(
|
|
@@ -3194,29 +3195,37 @@ svg[data-v-c322b7ed-s] {
|
|
|
3194
3195
|
}
|
|
3195
3196
|
|
|
3196
3197
|
/* 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-
|
|
3198
|
-
[data-component~="ui-input"][data-v-
|
|
3198
|
+
[data-component~="ui-input"][aria-invalid="true"][data-v-e7c851a2],
|
|
3199
|
+
[data-component~="ui-input"][data-v-e7c851a2]:is(:user-invalid, [data-user-invalid]) {
|
|
3199
3200
|
border-color: var(--ui-input-invalid-border, var(--ui-danger-solid));
|
|
3200
3201
|
}
|
|
3201
|
-
[data-component~="ui-input"][data-v-
|
|
3202
|
+
[data-component~="ui-input"][data-v-e7c851a2]:is([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])):focus-visible {
|
|
3202
3203
|
box-shadow: var(
|
|
3203
3204
|
--ui-input-invalid-focus-shadow,
|
|
3204
3205
|
var(--ui-control-inset),
|
|
3205
3206
|
0 0 0 3px color-mix(in srgb, var(--ui-danger-solid) 22%, transparent)
|
|
3206
3207
|
);
|
|
3207
3208
|
}
|
|
3208
|
-
[data-component~="ui-input"][data-v-
|
|
3209
|
+
[data-component~="ui-input"][data-v-e7c851a2]:disabled {
|
|
3209
3210
|
background: var(--ui-control-surface-disabled, var(--ui-surface-muted));
|
|
3210
3211
|
color: var(--ui-text-muted);
|
|
3211
3212
|
box-shadow: none;
|
|
3212
3213
|
cursor: not-allowed;
|
|
3213
3214
|
}
|
|
3214
3215
|
|
|
3216
|
+
/* Forced colors drop box shadows, so the focus ring becomes an outline. */
|
|
3217
|
+
@media (forced-colors: active) {
|
|
3218
|
+
[data-component~="ui-input"][data-v-e7c851a2]:focus-visible {
|
|
3219
|
+
outline: var(--ui-input-focus-outline, 2px solid Highlight);
|
|
3220
|
+
outline-offset: 1px;
|
|
3221
|
+
}
|
|
3222
|
+
}
|
|
3223
|
+
|
|
3215
3224
|
/* No text-box-trim here: trimming a native input's line box below its line height lets the text
|
|
3216
3225
|
* scroll vertically inside the field. Native inputs already center their single line. */
|
|
3217
3226
|
|
|
3218
3227
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
|
3219
|
-
[data-component~="ui-input"][hidden][data-v-
|
|
3228
|
+
[data-component~="ui-input"][hidden][data-v-e7c851a2] {
|
|
3220
3229
|
display: none;
|
|
3221
3230
|
}
|
|
3222
3231
|
|
|
@@ -3225,8 +3234,13 @@ svg[data-v-c322b7ed-s] {
|
|
|
3225
3234
|
focus ring around the input and its affixes together; the input inside drops its own through
|
|
3226
3235
|
its custom properties, so it is still the one ui-input, with its form behaviour intact. The
|
|
3227
3236
|
affixes are plain text beside the input, so name the input with a label that says what the
|
|
3228
|
-
whole value is.
|
|
3229
|
-
|
|
3237
|
+
whole value is. The action slot takes one button at the end, inside the border, for the one
|
|
3238
|
+
thing the field is for ("Continue" after a site's address), so it reads as the field's action
|
|
3239
|
+
and not the form's. */
|
|
3240
|
+
[data-component~="ui-input-group"][data-v-027c11f5] {
|
|
3241
|
+
/* The group's own border and height stand for the input's, so the group is a lone Input's height. */
|
|
3242
|
+
--ui-input-border-width: 0;
|
|
3243
|
+
--ui-input-min-block-size: 0;
|
|
3230
3244
|
--ui-input-border: transparent;
|
|
3231
3245
|
--ui-input-border-hover: transparent;
|
|
3232
3246
|
--ui-input-focus-border: transparent;
|
|
@@ -3234,6 +3248,7 @@ svg[data-v-c322b7ed-s] {
|
|
|
3234
3248
|
--ui-input-invalid-focus-shadow: none;
|
|
3235
3249
|
--ui-input-shadow: none;
|
|
3236
3250
|
--ui-input-focus-shadow: none;
|
|
3251
|
+
--ui-input-focus-outline: none;
|
|
3237
3252
|
--ui-input-radius: 0;
|
|
3238
3253
|
--ui-input-surface: transparent;
|
|
3239
3254
|
|
|
@@ -3243,37 +3258,58 @@ svg[data-v-c322b7ed-s] {
|
|
|
3243
3258
|
inline-size: 100%;
|
|
3244
3259
|
min-inline-size: 0;
|
|
3245
3260
|
min-block-size: var(--ui-control-size-md);
|
|
3246
|
-
|
|
3261
|
+
/* The frame reads the shared control tokens with a lone Input's fallbacks, so the two match. */
|
|
3262
|
+
border: 1px solid var(--ui-control-border, var(--ui-border-strong));
|
|
3247
3263
|
border-radius: var(--ui-radius-md);
|
|
3248
|
-
background: var(--ui-surface-elevated);
|
|
3264
|
+
background: var(--ui-control-surface, var(--ui-surface-elevated));
|
|
3249
3265
|
box-shadow: var(--ui-control-inset);
|
|
3250
3266
|
overflow: hidden;
|
|
3267
|
+
/* A press anywhere in the frame focuses the input. */
|
|
3268
|
+
cursor: text;
|
|
3251
3269
|
transition:
|
|
3252
3270
|
border-color var(--ui-motion-fast) var(--ui-motion-ease),
|
|
3253
3271
|
box-shadow var(--ui-motion-fast) var(--ui-motion-ease);
|
|
3254
3272
|
}
|
|
3255
|
-
[data-component~="ui-input-group"][data-v-
|
|
3256
|
-
border-color: var(--ui-text-secondary);
|
|
3273
|
+
[data-component~="ui-input-group"][data-v-027c11f5]:hover:not(:has(input:focus, input:disabled)) {
|
|
3274
|
+
border-color: var(--ui-control-border-hover, var(--ui-text-secondary));
|
|
3257
3275
|
}
|
|
3258
|
-
|
|
3259
|
-
|
|
3276
|
+
|
|
3277
|
+
/* The ring shows when the field's input would show its own: when it is focus-visible, which a
|
|
3278
|
+
text input is for a pointer as well as a keyboard. A focused action button draws its own. */
|
|
3279
|
+
[data-component~="ui-input-group"][data-v-027c11f5]:has(.field input:focus-visible) {
|
|
3280
|
+
border-color: var(--ui-control-focus, var(--ui-accent-solid));
|
|
3260
3281
|
box-shadow:
|
|
3261
3282
|
var(--ui-control-inset),
|
|
3262
3283
|
var(--ui-control-focus-halo-shadow);
|
|
3263
3284
|
}
|
|
3264
|
-
[data-component~="ui-input-group"][data-v-
|
|
3285
|
+
[data-component~="ui-input-group"][data-v-027c11f5]:has([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])) {
|
|
3265
3286
|
border-color: var(--ui-danger-solid);
|
|
3266
3287
|
}
|
|
3267
|
-
[data-component~="ui-input-group"][data-
|
|
3268
|
-
|
|
3288
|
+
[data-component~="ui-input-group"][data-v-027c11f5]:has(input:is([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])):focus-visible) {
|
|
3289
|
+
box-shadow:
|
|
3290
|
+
var(--ui-control-inset),
|
|
3291
|
+
0 0 0 3px color-mix(in srgb, var(--ui-danger-solid) 22%, transparent);
|
|
3292
|
+
}
|
|
3293
|
+
|
|
3294
|
+
/* Forced colors drop box shadows, so the focus ring becomes an outline. */
|
|
3295
|
+
@media (forced-colors: active) {
|
|
3296
|
+
[data-component~="ui-input-group"][data-v-027c11f5]:has(input:focus-visible) {
|
|
3297
|
+
outline: 2px solid Highlight;
|
|
3298
|
+
outline-offset: 1px;
|
|
3299
|
+
}
|
|
3300
|
+
}
|
|
3301
|
+
[data-component~="ui-input-group"][data-ui-input-group-state~="disabled"][data-v-027c11f5],
|
|
3302
|
+
[data-component~="ui-input-group"][data-v-027c11f5]:has(input:disabled) {
|
|
3303
|
+
background: var(--ui-control-surface-disabled, var(--ui-surface-muted));
|
|
3269
3304
|
box-shadow: none;
|
|
3305
|
+
cursor: not-allowed;
|
|
3270
3306
|
}
|
|
3271
|
-
.field[data-v-
|
|
3307
|
+
.field[data-v-027c11f5] {
|
|
3272
3308
|
display: flex;
|
|
3273
3309
|
flex: 1;
|
|
3274
3310
|
min-inline-size: 0;
|
|
3275
3311
|
}
|
|
3276
|
-
.affix[data-v-
|
|
3312
|
+
.affix[data-v-027c11f5] {
|
|
3277
3313
|
display: inline-flex;
|
|
3278
3314
|
flex: none;
|
|
3279
3315
|
align-items: center;
|
|
@@ -3283,12 +3319,22 @@ svg[data-v-c322b7ed-s] {
|
|
|
3283
3319
|
font-size: var(--ui-font-size-sm);
|
|
3284
3320
|
white-space: nowrap;
|
|
3285
3321
|
}
|
|
3286
|
-
|
|
3322
|
+
|
|
3323
|
+
/* Centred rather than padded above and below: the group is exactly a lone Input's height, so a
|
|
3324
|
+
small button sits inside it with the difference split evenly, and the field keeps its height. */
|
|
3325
|
+
.action[data-v-027c11f5] {
|
|
3326
|
+
display: flex;
|
|
3327
|
+
flex: none;
|
|
3328
|
+
align-items: center;
|
|
3329
|
+
padding-inline: var(--ui-space-1);
|
|
3330
|
+
}
|
|
3331
|
+
.affix[data-v-027c11f5]:empty,
|
|
3332
|
+
.action[data-v-027c11f5]:empty {
|
|
3287
3333
|
display: none;
|
|
3288
3334
|
}
|
|
3289
3335
|
|
|
3290
3336
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
|
3291
|
-
[data-component~="ui-input-group"][hidden][data-v-
|
|
3337
|
+
[data-component~="ui-input-group"][hidden][data-v-027c11f5] {
|
|
3292
3338
|
display: none;
|
|
3293
3339
|
}
|
|
3294
3340
|
|