@threadlabs/looma 0.12.1 → 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 +38 -12
- 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 +46 -12
- package/styles/ui-input.css +14 -2
- package/vanilla/UiInputGroup.js +7 -5
- package/vue/UiInput.vue +11 -2
- package/vue/UiInputGroup.vue +51 -12
- package/vue/chunks/UiInput.js +1 -1
- package/vue/chunks/UiInputGroup.js +16 -3
- package/vue/components.css +66 -31
package/package.json
CHANGED
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
thing the field is for ("Continue" after a site's address), so it reads as the field's action
|
|
10
10
|
and not the form's. */
|
|
11
11
|
:scope {
|
|
12
|
+
/* The group's own border and height stand for the input's, so the group is a lone Input's height. */
|
|
13
|
+
--ui-input-border-width: 0;
|
|
14
|
+
--ui-input-min-block-size: 0;
|
|
12
15
|
--ui-input-border: transparent;
|
|
13
16
|
--ui-input-border-hover: transparent;
|
|
14
17
|
--ui-input-focus-border: transparent;
|
|
@@ -16,6 +19,7 @@
|
|
|
16
19
|
--ui-input-invalid-focus-shadow: none;
|
|
17
20
|
--ui-input-shadow: none;
|
|
18
21
|
--ui-input-focus-shadow: none;
|
|
22
|
+
--ui-input-focus-outline: none;
|
|
19
23
|
--ui-input-radius: 0;
|
|
20
24
|
--ui-input-surface: transparent;
|
|
21
25
|
|
|
@@ -25,21 +29,25 @@
|
|
|
25
29
|
inline-size: 100%;
|
|
26
30
|
min-inline-size: 0;
|
|
27
31
|
min-block-size: var(--ui-control-size-md);
|
|
28
|
-
|
|
32
|
+
/* The frame reads the shared control tokens with a lone Input's fallbacks, so the two match. */
|
|
33
|
+
border: 1px solid var(--ui-control-border, var(--ui-border-strong));
|
|
29
34
|
border-radius: var(--ui-radius-md);
|
|
30
|
-
background: var(--ui-surface-elevated);
|
|
35
|
+
background: var(--ui-control-surface, var(--ui-surface-elevated));
|
|
31
36
|
box-shadow: var(--ui-control-inset);
|
|
32
37
|
overflow: hidden;
|
|
38
|
+
/* A press anywhere in the frame focuses the input. */
|
|
39
|
+
cursor: text;
|
|
33
40
|
transition: border-color var(--ui-motion-fast) var(--ui-motion-ease), box-shadow var(--ui-motion-fast) var(--ui-motion-ease);
|
|
34
41
|
}
|
|
35
42
|
|
|
36
|
-
:scope:hover:not(:focus
|
|
37
|
-
border-color: var(--ui-text-secondary);
|
|
43
|
+
:scope:hover:not(:has(input:focus, input:disabled)) {
|
|
44
|
+
border-color: var(--ui-control-border-hover, var(--ui-text-secondary));
|
|
38
45
|
}
|
|
39
46
|
|
|
40
|
-
/* The
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
/* The ring shows when the field's input would show its own: when it is focus-visible, which a
|
|
48
|
+
text input is for a pointer as well as a keyboard. A focused action button draws its own. */
|
|
49
|
+
:scope:has(.field input:focus-visible) {
|
|
50
|
+
border-color: var(--ui-control-focus, var(--ui-accent-solid));
|
|
43
51
|
box-shadow:
|
|
44
52
|
var(--ui-control-inset),
|
|
45
53
|
var(--ui-control-focus-halo-shadow);
|
|
@@ -49,9 +57,25 @@
|
|
|
49
57
|
border-color: var(--ui-danger-solid);
|
|
50
58
|
}
|
|
51
59
|
|
|
52
|
-
:scope[
|
|
53
|
-
|
|
60
|
+
:scope:has(input:is([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])):focus-visible) {
|
|
61
|
+
box-shadow:
|
|
62
|
+
var(--ui-control-inset),
|
|
63
|
+
0 0 0 3px color-mix(in srgb, var(--ui-danger-solid) 22%, transparent);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* Forced colors drop box shadows, so the focus ring becomes an outline. */
|
|
67
|
+
@media (forced-colors: active) {
|
|
68
|
+
:scope:has(input:focus-visible) {
|
|
69
|
+
outline: 2px solid Highlight;
|
|
70
|
+
outline-offset: 1px;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
:scope[data-ui-input-group-state~="disabled"],
|
|
75
|
+
:scope:has(input:disabled) {
|
|
76
|
+
background: var(--ui-control-surface-disabled, var(--ui-surface-muted));
|
|
54
77
|
box-shadow: none;
|
|
78
|
+
cursor: not-allowed;
|
|
55
79
|
}
|
|
56
80
|
|
|
57
81
|
.field {
|
|
@@ -71,11 +95,13 @@
|
|
|
71
95
|
white-space: nowrap;
|
|
72
96
|
}
|
|
73
97
|
|
|
98
|
+
/* Centred rather than padded above and below: the group is exactly a lone Input's height, so a
|
|
99
|
+
small button sits inside it with the difference split evenly, and the field keeps its height. */
|
|
74
100
|
.action {
|
|
75
101
|
display: flex;
|
|
76
102
|
flex: none;
|
|
77
|
-
align-items:
|
|
78
|
-
padding: var(--ui-space-1);
|
|
103
|
+
align-items: center;
|
|
104
|
+
padding-inline: var(--ui-space-1);
|
|
79
105
|
}
|
|
80
106
|
|
|
81
107
|
.affix:empty,
|
|
@@ -98,7 +124,15 @@
|
|
|
98
124
|
thing the field is for ("Continue" after a site's address), so it reads as the field's action
|
|
99
125
|
and not the form's. */
|
|
100
126
|
|
|
101
|
-
/* The
|
|
127
|
+
/* The ring shows when the field's input would show its own: when it is focus-visible, which a
|
|
128
|
+
text input is for a pointer as well as a keyboard. A focused action button draws its own. */
|
|
129
|
+
|
|
130
|
+
/* Forced colors drop box shadows, so the focus ring becomes an outline. */
|
|
131
|
+
@media (forced-colors: active) {
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* Centred rather than padded above and below: the group is exactly a lone Input's height, so a
|
|
135
|
+
small button sits inside it with the difference split evenly, and the field keeps its height. */
|
|
102
136
|
|
|
103
137
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
|
104
138
|
}
|
package/styles/ui-input.css
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
display: inline-block;
|
|
6
6
|
inline-size: 100%;
|
|
7
7
|
min-inline-size: 0;
|
|
8
|
-
min-block-size: var(--ui-control-size-md);
|
|
8
|
+
min-block-size: var(--ui-input-min-block-size, var(--ui-control-size-md));
|
|
9
9
|
margin: 0;
|
|
10
10
|
padding: var(--ui-space-2) var(--ui-space-3);
|
|
11
11
|
appearance: none;
|
|
12
|
-
border: 1px solid var(--ui-input-border, var(--ui-control-border, var(--ui-border-strong)));
|
|
12
|
+
border: var(--ui-input-border-width, 1px) solid var(--ui-input-border, var(--ui-control-border, var(--ui-border-strong)));
|
|
13
13
|
border-radius: var(--ui-input-radius, var(--ui-radius-md));
|
|
14
14
|
background: var(--ui-input-surface, var(--ui-control-surface, var(--ui-surface-elevated)));
|
|
15
15
|
color: var(--ui-text-primary);
|
|
@@ -64,6 +64,14 @@
|
|
|
64
64
|
cursor: not-allowed;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
/* Forced colors drop box shadows, so the focus ring becomes an outline. */
|
|
68
|
+
@media (forced-colors: active) {
|
|
69
|
+
:scope:focus-visible {
|
|
70
|
+
outline: var(--ui-input-focus-outline, 2px solid Highlight);
|
|
71
|
+
outline-offset: 1px;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
67
75
|
/* No text-box-trim here: trimming a native input's line box below its line height lets the text
|
|
68
76
|
* scroll vertically inside the field. Native inputs already center their single line. */
|
|
69
77
|
|
|
@@ -77,6 +85,10 @@
|
|
|
77
85
|
|
|
78
86
|
/* The app's invalid flag, or the browser's own verdict once the user has left an invalid field. */
|
|
79
87
|
|
|
88
|
+
/* Forced colors drop box shadows, so the focus ring becomes an outline. */
|
|
89
|
+
@media (forced-colors: active) {
|
|
90
|
+
}
|
|
91
|
+
|
|
80
92
|
/* No text-box-trim here: trimming a native input's line box below its line height lets the text
|
|
81
93
|
* scroll vertically inside the field. Native inputs already center their single line. */
|
|
82
94
|
|
package/vanilla/UiInputGroup.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
// Generated by HTML Next 1.0.0-alpha.5 for Vanilla DOM. Do not edit.
|
|
2
|
-
import {
|
|
2
|
+
import { manageComponentLifecycle } from "@nextwebwg/html-next/runtime";
|
|
3
|
+
import * as controller from "../components/ui-input-group/ui-input-group.js";
|
|
3
4
|
import "../styles/ui-input-group.css";
|
|
4
5
|
|
|
6
|
+
const definition = {...{"contract":{"tag":"ui-input-group","props":{"disabled":{"type":"boolean","required":false,"target":{"attribute":"disabled"},"default":false}}},"template":{"kind":"element","name":"div","attributes":[],"children":[{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"affix"}],"children":[{"kind":"slot","fallback":[],"name":"prefix"}]},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"field"}],"children":[{"kind":"slot"}]},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"affix"}],"children":[{"kind":"slot","fallback":[],"name":"suffix"}]},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"action"}],"children":[{"kind":"slot","fallback":[],"name":"action"}]}]},"declarations":[],"root":{"kind":"native","element":"div","choices":["div"]}},source:{file:import.meta.url},css:""};
|
|
7
|
+
|
|
5
8
|
export function createUiInputGroup(options = {}) {
|
|
6
9
|
const { attributes = {}, children = [], slots = {}, as, ...componentProps } = options;
|
|
7
10
|
const projected = [];
|
|
8
|
-
const prop0 = componentProps["disabled"] === undefined ? false : componentProps["disabled"];
|
|
9
11
|
const element = document.createElement("div");
|
|
10
12
|
for (const [name, value] of Object.entries(attributes)) {
|
|
11
13
|
if (value === null || value === undefined || value === false) continue;
|
|
@@ -56,9 +58,9 @@ export function createUiInputGroup(options = {}) {
|
|
|
56
58
|
} else {
|
|
57
59
|
}
|
|
58
60
|
element.append(element3);
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
manageComponentLifecycle(element, definition, { props: componentProps, projected,
|
|
62
|
+
controller,
|
|
63
|
+
});
|
|
62
64
|
return element;
|
|
63
65
|
}
|
|
64
66
|
|
package/vue/UiInput.vue
CHANGED
|
@@ -60,11 +60,12 @@ useComponentHost(controllerModule.default, {
|
|
|
60
60
|
display: inline-block;
|
|
61
61
|
inline-size: 100%;
|
|
62
62
|
min-inline-size: 0;
|
|
63
|
-
min-block-size: var(--ui-control-size-md);
|
|
63
|
+
min-block-size: var(--ui-input-min-block-size, var(--ui-control-size-md));
|
|
64
64
|
margin: 0;
|
|
65
65
|
padding: var(--ui-space-2) var(--ui-space-3);
|
|
66
66
|
appearance: none;
|
|
67
|
-
border:
|
|
67
|
+
border: var(--ui-input-border-width, 1px) solid
|
|
68
|
+
var(--ui-input-border, var(--ui-control-border, var(--ui-border-strong)));
|
|
68
69
|
border-radius: var(--ui-input-radius, var(--ui-radius-md));
|
|
69
70
|
background: var(--ui-input-surface, var(--ui-control-surface, var(--ui-surface-elevated)));
|
|
70
71
|
color: var(--ui-text-primary);
|
|
@@ -126,6 +127,14 @@ useComponentHost(controllerModule.default, {
|
|
|
126
127
|
cursor: not-allowed;
|
|
127
128
|
}
|
|
128
129
|
|
|
130
|
+
/* Forced colors drop box shadows, so the focus ring becomes an outline. */
|
|
131
|
+
@media (forced-colors: active) {
|
|
132
|
+
[data-component~="ui-input"]:focus-visible {
|
|
133
|
+
outline: var(--ui-input-focus-outline, 2px solid Highlight);
|
|
134
|
+
outline-offset: 1px;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
129
138
|
/* No text-box-trim here: trimming a native input's line box below its line height lets the text
|
|
130
139
|
* scroll vertically inside the field. Native inputs already center their single line. */
|
|
131
140
|
|
package/vue/UiInputGroup.vue
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<!-- Generated by HTML Next 1.0.0-alpha.5 for Vue 3.5. Do not edit. -->
|
|
2
2
|
<script setup lang="ts">
|
|
3
|
-
import { computed } from 'vue'
|
|
3
|
+
import { computed, ref } from 'vue'
|
|
4
|
+
import * as controllerModule from '../components/ui-input-group/ui-input-group.js'
|
|
5
|
+
import { createDispatch, useComponentHost } from './host'
|
|
4
6
|
|
|
5
7
|
defineOptions({ inheritAttrs: false })
|
|
6
8
|
|
|
@@ -13,12 +15,22 @@ const props = withDefaults(
|
|
|
13
15
|
},
|
|
14
16
|
)
|
|
15
17
|
|
|
18
|
+
const root = ref<HTMLElement | null>(null)
|
|
19
|
+
|
|
16
20
|
/** The values the styles' :host-state() rules test. */
|
|
17
21
|
const hostState = computed(() =>
|
|
18
22
|
[
|
|
19
23
|
props.disabled && 'disabled',
|
|
20
24
|
].filter(Boolean).join(' ')
|
|
21
25
|
)
|
|
26
|
+
|
|
27
|
+
const dispatch = createDispatch(root)
|
|
28
|
+
|
|
29
|
+
useComponentHost(controllerModule.default, {
|
|
30
|
+
root,
|
|
31
|
+
dispatch,
|
|
32
|
+
props,
|
|
33
|
+
})
|
|
22
34
|
</script>
|
|
23
35
|
|
|
24
36
|
<template>
|
|
@@ -26,6 +38,7 @@ const hostState = computed(() =>
|
|
|
26
38
|
data-component="ui-input-group"
|
|
27
39
|
v-bind="$attrs"
|
|
28
40
|
:data-ui-input-group-state="hostState || undefined"
|
|
41
|
+
ref="root"
|
|
29
42
|
>
|
|
30
43
|
<span class="affix"><slot name="prefix" /></span>
|
|
31
44
|
<span class="field"><slot /></span>
|
|
@@ -44,6 +57,9 @@ const hostState = computed(() =>
|
|
|
44
57
|
thing the field is for ("Continue" after a site's address), so it reads as the field's action
|
|
45
58
|
and not the form's. */
|
|
46
59
|
[data-component~="ui-input-group"] {
|
|
60
|
+
/* The group's own border and height stand for the input's, so the group is a lone Input's height. */
|
|
61
|
+
--ui-input-border-width: 0;
|
|
62
|
+
--ui-input-min-block-size: 0;
|
|
47
63
|
--ui-input-border: transparent;
|
|
48
64
|
--ui-input-border-hover: transparent;
|
|
49
65
|
--ui-input-focus-border: transparent;
|
|
@@ -51,6 +67,7 @@ const hostState = computed(() =>
|
|
|
51
67
|
--ui-input-invalid-focus-shadow: none;
|
|
52
68
|
--ui-input-shadow: none;
|
|
53
69
|
--ui-input-focus-shadow: none;
|
|
70
|
+
--ui-input-focus-outline: none;
|
|
54
71
|
--ui-input-radius: 0;
|
|
55
72
|
--ui-input-surface: transparent;
|
|
56
73
|
|
|
@@ -60,23 +77,27 @@ const hostState = computed(() =>
|
|
|
60
77
|
inline-size: 100%;
|
|
61
78
|
min-inline-size: 0;
|
|
62
79
|
min-block-size: var(--ui-control-size-md);
|
|
63
|
-
|
|
80
|
+
/* The frame reads the shared control tokens with a lone Input's fallbacks, so the two match. */
|
|
81
|
+
border: 1px solid var(--ui-control-border, var(--ui-border-strong));
|
|
64
82
|
border-radius: var(--ui-radius-md);
|
|
65
|
-
background: var(--ui-surface-elevated);
|
|
83
|
+
background: var(--ui-control-surface, var(--ui-surface-elevated));
|
|
66
84
|
box-shadow: var(--ui-control-inset);
|
|
67
85
|
overflow: hidden;
|
|
86
|
+
/* A press anywhere in the frame focuses the input. */
|
|
87
|
+
cursor: text;
|
|
68
88
|
transition:
|
|
69
89
|
border-color var(--ui-motion-fast) var(--ui-motion-ease),
|
|
70
90
|
box-shadow var(--ui-motion-fast) var(--ui-motion-ease);
|
|
71
91
|
}
|
|
72
92
|
|
|
73
|
-
[data-component~="ui-input-group"]:hover:not(:focus
|
|
74
|
-
border-color: var(--ui-text-secondary);
|
|
93
|
+
[data-component~="ui-input-group"]:hover:not(:has(input:focus, input:disabled)) {
|
|
94
|
+
border-color: var(--ui-control-border-hover, var(--ui-text-secondary));
|
|
75
95
|
}
|
|
76
96
|
|
|
77
|
-
/* The
|
|
78
|
-
|
|
79
|
-
|
|
97
|
+
/* The ring shows when the field's input would show its own: when it is focus-visible, which a
|
|
98
|
+
text input is for a pointer as well as a keyboard. A focused action button draws its own. */
|
|
99
|
+
[data-component~="ui-input-group"]:has(.field input:focus-visible) {
|
|
100
|
+
border-color: var(--ui-control-focus, var(--ui-accent-solid));
|
|
80
101
|
box-shadow:
|
|
81
102
|
var(--ui-control-inset),
|
|
82
103
|
var(--ui-control-focus-halo-shadow);
|
|
@@ -86,9 +107,25 @@ const hostState = computed(() =>
|
|
|
86
107
|
border-color: var(--ui-danger-solid);
|
|
87
108
|
}
|
|
88
109
|
|
|
89
|
-
[data-component~="ui-input-group"][
|
|
90
|
-
|
|
110
|
+
[data-component~="ui-input-group"]:has(input:is([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])):focus-visible) {
|
|
111
|
+
box-shadow:
|
|
112
|
+
var(--ui-control-inset),
|
|
113
|
+
0 0 0 3px color-mix(in srgb, var(--ui-danger-solid) 22%, transparent);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* Forced colors drop box shadows, so the focus ring becomes an outline. */
|
|
117
|
+
@media (forced-colors: active) {
|
|
118
|
+
[data-component~="ui-input-group"]:has(input:focus-visible) {
|
|
119
|
+
outline: 2px solid Highlight;
|
|
120
|
+
outline-offset: 1px;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
[data-component~="ui-input-group"][data-ui-input-group-state~="disabled"],
|
|
125
|
+
[data-component~="ui-input-group"]:has(input:disabled) {
|
|
126
|
+
background: var(--ui-control-surface-disabled, var(--ui-surface-muted));
|
|
91
127
|
box-shadow: none;
|
|
128
|
+
cursor: not-allowed;
|
|
92
129
|
}
|
|
93
130
|
|
|
94
131
|
.field {
|
|
@@ -108,11 +145,13 @@ const hostState = computed(() =>
|
|
|
108
145
|
white-space: nowrap;
|
|
109
146
|
}
|
|
110
147
|
|
|
148
|
+
/* Centred rather than padded above and below: the group is exactly a lone Input's height, so a
|
|
149
|
+
small button sits inside it with the difference split evenly, and the field keeps its height. */
|
|
111
150
|
.action {
|
|
112
151
|
display: flex;
|
|
113
152
|
flex: none;
|
|
114
|
-
align-items:
|
|
115
|
-
padding: var(--ui-space-1);
|
|
153
|
+
align-items: center;
|
|
154
|
+
padding-inline: var(--ui-space-1);
|
|
116
155
|
}
|
|
117
156
|
|
|
118
157
|
.affix:empty,
|
package/vue/chunks/UiInput.js
CHANGED
|
@@ -61,6 +61,6 @@ var UiInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE
|
|
|
61
61
|
}), null, 16, _hoisted_1)), [[vModelDynamic, model.value]]);
|
|
62
62
|
};
|
|
63
63
|
}
|
|
64
|
-
}), [["__scopeId", "data-v-
|
|
64
|
+
}), [["__scopeId", "data-v-e7c851a2"]]);
|
|
65
65
|
//#endregion
|
|
66
66
|
export { UiInput_default as t };
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { t as _plugin_vue_export_helper_default } from "./_plugin-vue_export-helper.js";
|
|
2
|
-
import {
|
|
2
|
+
import { n as useComponentHost, t as createDispatch } from "./host.js";
|
|
3
|
+
import { computed, createElementBlock, createElementVNode, defineComponent, mergeProps, openBlock, ref, renderSlot } from "vue";
|
|
4
|
+
import * as controllerModule from "@threadlabs/looma/components/ui-input-group/ui-input-group.js";
|
|
3
5
|
//#region .build/vue/UiInputGroup.vue?vue&type=script&setup=true&lang.ts
|
|
4
6
|
var _hoisted_1 = ["data-ui-input-group-state"];
|
|
5
7
|
var _hoisted_2 = { class: "affix" };
|
|
@@ -17,10 +19,21 @@ var UiInputGroup_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
|
|
|
17
19
|
} },
|
|
18
20
|
setup(__props) {
|
|
19
21
|
const props = __props;
|
|
22
|
+
const root = ref(null);
|
|
20
23
|
/** The values the styles' :host-state() rules test. */
|
|
21
24
|
const hostState = computed(() => [props.disabled && "disabled"].filter(Boolean).join(" "));
|
|
25
|
+
const dispatch = createDispatch(root);
|
|
26
|
+
useComponentHost(controllerModule.default, {
|
|
27
|
+
root,
|
|
28
|
+
dispatch,
|
|
29
|
+
props
|
|
30
|
+
});
|
|
22
31
|
return (_ctx, _cache) => {
|
|
23
|
-
return openBlock(), createElementBlock("div", mergeProps({ "data-component": "ui-input-group" }, _ctx.$attrs, {
|
|
32
|
+
return openBlock(), createElementBlock("div", mergeProps({ "data-component": "ui-input-group" }, _ctx.$attrs, {
|
|
33
|
+
"data-ui-input-group-state": hostState.value || void 0,
|
|
34
|
+
ref_key: "root",
|
|
35
|
+
ref: root
|
|
36
|
+
}), [
|
|
24
37
|
createElementVNode("span", _hoisted_2, [renderSlot(_ctx.$slots, "prefix", {}, void 0, true)]),
|
|
25
38
|
createElementVNode("span", _hoisted_3, [renderSlot(_ctx.$slots, "default", {}, void 0, true)]),
|
|
26
39
|
createElementVNode("span", _hoisted_4, [renderSlot(_ctx.$slots, "suffix", {}, void 0, true)]),
|
|
@@ -28,6 +41,6 @@ var UiInputGroup_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
|
|
|
28
41
|
], 16, _hoisted_1);
|
|
29
42
|
};
|
|
30
43
|
}
|
|
31
|
-
}), [["__scopeId", "data-v-
|
|
44
|
+
}), [["__scopeId", "data-v-027c11f5"]]);
|
|
32
45
|
//#endregion
|
|
33
46
|
export { UiInputGroup_default as t };
|
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
|
|
|
@@ -3228,7 +3237,10 @@ svg[data-v-c322b7ed-s] {
|
|
|
3228
3237
|
whole value is. The action slot takes one button at the end, inside the border, for the one
|
|
3229
3238
|
thing the field is for ("Continue" after a site's address), so it reads as the field's action
|
|
3230
3239
|
and not the form's. */
|
|
3231
|
-
[data-component~="ui-input-group"][data-v-
|
|
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;
|
|
3232
3244
|
--ui-input-border: transparent;
|
|
3233
3245
|
--ui-input-border-hover: transparent;
|
|
3234
3246
|
--ui-input-focus-border: transparent;
|
|
@@ -3236,6 +3248,7 @@ svg[data-v-c322b7ed-s] {
|
|
|
3236
3248
|
--ui-input-invalid-focus-shadow: none;
|
|
3237
3249
|
--ui-input-shadow: none;
|
|
3238
3250
|
--ui-input-focus-shadow: none;
|
|
3251
|
+
--ui-input-focus-outline: none;
|
|
3239
3252
|
--ui-input-radius: 0;
|
|
3240
3253
|
--ui-input-surface: transparent;
|
|
3241
3254
|
|
|
@@ -3245,39 +3258,58 @@ svg[data-v-c322b7ed-s] {
|
|
|
3245
3258
|
inline-size: 100%;
|
|
3246
3259
|
min-inline-size: 0;
|
|
3247
3260
|
min-block-size: var(--ui-control-size-md);
|
|
3248
|
-
|
|
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));
|
|
3249
3263
|
border-radius: var(--ui-radius-md);
|
|
3250
|
-
background: var(--ui-surface-elevated);
|
|
3264
|
+
background: var(--ui-control-surface, var(--ui-surface-elevated));
|
|
3251
3265
|
box-shadow: var(--ui-control-inset);
|
|
3252
3266
|
overflow: hidden;
|
|
3267
|
+
/* A press anywhere in the frame focuses the input. */
|
|
3268
|
+
cursor: text;
|
|
3253
3269
|
transition:
|
|
3254
3270
|
border-color var(--ui-motion-fast) var(--ui-motion-ease),
|
|
3255
3271
|
box-shadow var(--ui-motion-fast) var(--ui-motion-ease);
|
|
3256
3272
|
}
|
|
3257
|
-
[data-component~="ui-input-group"][data-v-
|
|
3258
|
-
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));
|
|
3259
3275
|
}
|
|
3260
3276
|
|
|
3261
|
-
/* The
|
|
3262
|
-
|
|
3263
|
-
|
|
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));
|
|
3264
3281
|
box-shadow:
|
|
3265
3282
|
var(--ui-control-inset),
|
|
3266
3283
|
var(--ui-control-focus-halo-shadow);
|
|
3267
3284
|
}
|
|
3268
|
-
[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])) {
|
|
3269
3286
|
border-color: var(--ui-danger-solid);
|
|
3270
3287
|
}
|
|
3271
|
-
[data-component~="ui-input-group"][data-
|
|
3272
|
-
|
|
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));
|
|
3273
3304
|
box-shadow: none;
|
|
3305
|
+
cursor: not-allowed;
|
|
3274
3306
|
}
|
|
3275
|
-
.field[data-v-
|
|
3307
|
+
.field[data-v-027c11f5] {
|
|
3276
3308
|
display: flex;
|
|
3277
3309
|
flex: 1;
|
|
3278
3310
|
min-inline-size: 0;
|
|
3279
3311
|
}
|
|
3280
|
-
.affix[data-v-
|
|
3312
|
+
.affix[data-v-027c11f5] {
|
|
3281
3313
|
display: inline-flex;
|
|
3282
3314
|
flex: none;
|
|
3283
3315
|
align-items: center;
|
|
@@ -3287,19 +3319,22 @@ svg[data-v-c322b7ed-s] {
|
|
|
3287
3319
|
font-size: var(--ui-font-size-sm);
|
|
3288
3320
|
white-space: nowrap;
|
|
3289
3321
|
}
|
|
3290
|
-
|
|
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] {
|
|
3291
3326
|
display: flex;
|
|
3292
3327
|
flex: none;
|
|
3293
|
-
align-items:
|
|
3294
|
-
padding: var(--ui-space-1);
|
|
3328
|
+
align-items: center;
|
|
3329
|
+
padding-inline: var(--ui-space-1);
|
|
3295
3330
|
}
|
|
3296
|
-
.affix[data-v-
|
|
3297
|
-
.action[data-v-
|
|
3331
|
+
.affix[data-v-027c11f5]:empty,
|
|
3332
|
+
.action[data-v-027c11f5]:empty {
|
|
3298
3333
|
display: none;
|
|
3299
3334
|
}
|
|
3300
3335
|
|
|
3301
3336
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
|
3302
|
-
[data-component~="ui-input-group"][hidden][data-v-
|
|
3337
|
+
[data-component~="ui-input-group"][hidden][data-v-027c11f5] {
|
|
3303
3338
|
display: none;
|
|
3304
3339
|
}
|
|
3305
3340
|
|