srcdev-nuxt-forms 2.4.10 → 2.4.12
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/forms/input-text/InputTextCore.vue +24 -1
- package/components/forms/input-text/variants/InputPasswordWithLabel.vue +22 -3
- package/components/forms/input-text/variants/InputTextAsNumberWithLabel.vue +5 -0
- package/components/forms/input-text/variants/InputTextWithLabel.vue +97 -32
- package/composables/useColourScheme.ts +0 -33
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
class="input-text-wrapper"
|
|
4
4
|
:data-form-theme="formTheme"
|
|
5
5
|
:data-size="size"
|
|
6
|
-
:class="[{ dirty: isDirty }, { active: isActive }, { error: fieldHasError }, { 'has-left-slot': hasLeftSlot }, { 'has-right-slot': hasRightSlot }]"
|
|
6
|
+
:class="[{ isMaterial: isMaterial }, { dirty: isDirty }, { active: isActive }, { error: fieldHasError }, { 'has-left-slot': hasLeftSlot }, { 'has-right-slot': hasRightSlot }]"
|
|
7
7
|
>
|
|
8
8
|
<span v-if="hasLeftSlot" class="slot left-slot">
|
|
9
9
|
<slot name="left"></slot>
|
|
@@ -98,8 +98,14 @@ const props = defineProps({
|
|
|
98
98
|
return propValidators.size.includes(value);
|
|
99
99
|
},
|
|
100
100
|
},
|
|
101
|
+
isMaterial: {
|
|
102
|
+
type: Boolean,
|
|
103
|
+
default: false,
|
|
104
|
+
},
|
|
101
105
|
});
|
|
102
106
|
|
|
107
|
+
console.log('isMaterial: ', props.isMaterial);
|
|
108
|
+
|
|
103
109
|
const slots = useSlots();
|
|
104
110
|
const hasLeftSlot = computed(() => slots.left !== undefined);
|
|
105
111
|
const hasRightSlot = computed(() => slots.right !== undefined);
|
|
@@ -250,6 +256,23 @@ onMounted(() => {
|
|
|
250
256
|
border-left: 2px solid var(--theme-btn-bg-hover);
|
|
251
257
|
}
|
|
252
258
|
}
|
|
259
|
+
|
|
260
|
+
/* Material Design Styles */
|
|
261
|
+
|
|
262
|
+
&.isMaterial {
|
|
263
|
+
background-color: transparent;
|
|
264
|
+
border-radius: initial;
|
|
265
|
+
border: none;
|
|
266
|
+
outline: none;
|
|
267
|
+
box-shadow: none;
|
|
268
|
+
opacity: 0;
|
|
269
|
+
transition: opacity 0.2s ease-in-out;
|
|
270
|
+
|
|
271
|
+
&.active,
|
|
272
|
+
&.dirty {
|
|
273
|
+
opacity: 1;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
253
276
|
}
|
|
254
277
|
|
|
255
278
|
input:autofill,
|
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<InputTextWithLabel
|
|
2
|
+
<InputTextWithLabel
|
|
3
|
+
v-model="modelValue"
|
|
4
|
+
:data-form-theme="formTheme"
|
|
5
|
+
:type="inputType"
|
|
6
|
+
:maxlength
|
|
7
|
+
:name
|
|
8
|
+
:placeholder
|
|
9
|
+
:label
|
|
10
|
+
:errorMessage
|
|
11
|
+
:fieldHasError
|
|
12
|
+
:required
|
|
13
|
+
:styleClassPassthrough
|
|
14
|
+
:theme
|
|
15
|
+
:size
|
|
16
|
+
:isMaterial
|
|
17
|
+
>
|
|
3
18
|
<template #right>
|
|
4
19
|
<InputButtonCore
|
|
5
20
|
type="button"
|
|
@@ -25,7 +40,7 @@ import propValidators from '../../c12/prop-validators';
|
|
|
25
40
|
|
|
26
41
|
const props = defineProps({
|
|
27
42
|
type: {
|
|
28
|
-
type: String
|
|
43
|
+
type: String as PropType<'text' | 'password'>,
|
|
29
44
|
default: 'password',
|
|
30
45
|
},
|
|
31
46
|
maxlength: {
|
|
@@ -74,6 +89,10 @@ const props = defineProps({
|
|
|
74
89
|
return propValidators.size.includes(value);
|
|
75
90
|
},
|
|
76
91
|
},
|
|
92
|
+
isMaterial: {
|
|
93
|
+
type: Boolean,
|
|
94
|
+
default: false,
|
|
95
|
+
},
|
|
77
96
|
});
|
|
78
97
|
|
|
79
98
|
const formTheme = computed(() => {
|
|
@@ -89,7 +108,7 @@ const updateFocus = (name: string, isFocused: boolean) => {
|
|
|
89
108
|
// modelValue.value.focusedField = isFocused ? name : '';
|
|
90
109
|
};
|
|
91
110
|
|
|
92
|
-
const inputType = ref(props.type);
|
|
111
|
+
const inputType = ref<'text' | 'password'>(props.type);
|
|
93
112
|
|
|
94
113
|
const displayPassword = ref(false);
|
|
95
114
|
const buttonText = computed(() => {
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
inputmode="numeric"
|
|
25
25
|
:ariaDescribedby
|
|
26
26
|
:size
|
|
27
|
+
:isMaterial
|
|
27
28
|
>
|
|
28
29
|
<template v-if="hasLeftSlot" #left>
|
|
29
30
|
<InputButtonCore
|
|
@@ -121,6 +122,10 @@ const props = defineProps({
|
|
|
121
122
|
return propValidators.size.includes(value);
|
|
122
123
|
},
|
|
123
124
|
},
|
|
125
|
+
isMaterial: {
|
|
126
|
+
type: Boolean,
|
|
127
|
+
default: false,
|
|
128
|
+
},
|
|
124
129
|
});
|
|
125
130
|
|
|
126
131
|
const slots = useSlots();
|
|
@@ -1,38 +1,46 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
<
|
|
2
|
+
<div>
|
|
3
|
+
<div class="input-text-with-label" :data-form-theme="formTheme" :class="[elementClasses, { isMaterial: isMaterial }, { dirty: isDirty }, { active: isActive }]">
|
|
4
|
+
<label :for="id" class="input-text-label">{{ label }}</label>
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
<div v-if="!isMaterial && hasDescriptionSlot" :id="`${id}-description`">
|
|
7
|
+
<slot name="description"></slot>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<InputTextCore
|
|
11
|
+
v-model="modelValue"
|
|
12
|
+
v-model:isDirty="isDirty"
|
|
13
|
+
v-model:isActive="isActive"
|
|
14
|
+
:type
|
|
15
|
+
:inputmode
|
|
16
|
+
:maxlength
|
|
17
|
+
:id
|
|
18
|
+
:name
|
|
19
|
+
:placeholder
|
|
20
|
+
:label
|
|
21
|
+
:errorMessage
|
|
22
|
+
:fieldHasError
|
|
23
|
+
:required
|
|
24
|
+
:styleClassPassthrough
|
|
25
|
+
:theme
|
|
26
|
+
:ariaDescribedby
|
|
27
|
+
:size
|
|
28
|
+
:isMaterial
|
|
29
|
+
>
|
|
30
|
+
<template v-if="hasLeftSlot" #left>
|
|
31
|
+
<slot name="left"></slot>
|
|
32
|
+
</template>
|
|
33
|
+
<template v-if="hasRightSlot" #right>
|
|
34
|
+
<slot name="right"></slot>
|
|
35
|
+
</template>
|
|
36
|
+
</InputTextCore>
|
|
37
|
+
|
|
38
|
+
<InputError :errorMessage="errorMessage" :showError="fieldHasError" :id="errorId" :isDetached="false" />
|
|
7
39
|
</div>
|
|
8
40
|
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
v-model:isActive="isActive"
|
|
13
|
-
:type
|
|
14
|
-
:inputmode
|
|
15
|
-
:maxlength
|
|
16
|
-
:id
|
|
17
|
-
:name
|
|
18
|
-
:placeholder
|
|
19
|
-
:label
|
|
20
|
-
:errorMessage
|
|
21
|
-
:fieldHasError
|
|
22
|
-
:required
|
|
23
|
-
:styleClassPassthrough
|
|
24
|
-
:theme
|
|
25
|
-
:ariaDescribedby
|
|
26
|
-
:size
|
|
27
|
-
>
|
|
28
|
-
<template v-if="hasLeftSlot" #left>
|
|
29
|
-
<slot name="left"></slot>
|
|
30
|
-
</template>
|
|
31
|
-
<template v-if="hasRightSlot" #right>
|
|
32
|
-
<slot name="right"></slot>
|
|
33
|
-
</template>
|
|
34
|
-
</InputTextCore>
|
|
35
|
-
<InputError :errorMessage="errorMessage" :showError="fieldHasError" :id="errorId" :isDetached="false" />
|
|
41
|
+
<div v-if="isMaterial && hasDescriptionSlot" :id="`${id}-description`">
|
|
42
|
+
<slot name="description"></slot>
|
|
43
|
+
</div>
|
|
36
44
|
</div>
|
|
37
45
|
</template>
|
|
38
46
|
|
|
@@ -44,7 +52,7 @@ const props = defineProps({
|
|
|
44
52
|
default: 255,
|
|
45
53
|
},
|
|
46
54
|
type: {
|
|
47
|
-
type: String
|
|
55
|
+
type: String as PropType<'text' | 'email' | 'password' | 'number' | 'tel' | 'url'>,
|
|
48
56
|
required: true,
|
|
49
57
|
},
|
|
50
58
|
inputmode: {
|
|
@@ -96,6 +104,10 @@ const props = defineProps({
|
|
|
96
104
|
return propValidators.size.includes(value);
|
|
97
105
|
},
|
|
98
106
|
},
|
|
107
|
+
isMaterial: {
|
|
108
|
+
type: Boolean,
|
|
109
|
+
default: false,
|
|
110
|
+
},
|
|
99
111
|
});
|
|
100
112
|
|
|
101
113
|
const slots = useSlots();
|
|
@@ -142,9 +154,62 @@ watch(
|
|
|
142
154
|
|
|
143
155
|
<style lang="css">
|
|
144
156
|
.input-text-with-label {
|
|
157
|
+
--_focus-box-shadow: var(--box-shadow-off);
|
|
158
|
+
|
|
145
159
|
.input-text-label {
|
|
146
160
|
display: block;
|
|
147
161
|
margin-block: 0.8rem;
|
|
162
|
+
font-size: var(--step-1);
|
|
163
|
+
font-weight: normal;
|
|
164
|
+
line-height: 1.5;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/* Material Design Styles */
|
|
168
|
+
|
|
169
|
+
&.isMaterial {
|
|
170
|
+
--_label-offset: 0 0;
|
|
171
|
+
|
|
172
|
+
display: grid;
|
|
173
|
+
grid-template-columns: 1fr;
|
|
174
|
+
grid-template-rows: 1fr;
|
|
175
|
+
grid-template-areas: 'material-text-stack';
|
|
176
|
+
|
|
177
|
+
background-color: var(--theme-form-input-bg);
|
|
178
|
+
border-radius: var(--form-element-border-width);
|
|
179
|
+
border: var(--form-element-border-width) solid var(--theme-form-input-border);
|
|
180
|
+
outline: var(--form-element-outline-width) solid var(--theme-form-input-outline);
|
|
181
|
+
box-shadow: var(--_focus-box-shadow);
|
|
182
|
+
|
|
183
|
+
padding: 0 0.8rem;
|
|
184
|
+
|
|
185
|
+
.input-text-label {
|
|
186
|
+
grid-area: material-text-stack;
|
|
187
|
+
|
|
188
|
+
display: inline-block;
|
|
189
|
+
width: fit-content;
|
|
190
|
+
padding: 0.2rem 1.2rem;
|
|
191
|
+
background-color: var(--theme-form-input-bg);
|
|
192
|
+
border-radius: 0.4em;
|
|
193
|
+
color: var(--theme-form-input-text);
|
|
194
|
+
translate: var(--_label-offset);
|
|
195
|
+
|
|
196
|
+
font-size: var(--step-2);
|
|
197
|
+
font-weight: normal;
|
|
198
|
+
line-height: 1.5;
|
|
199
|
+
|
|
200
|
+
transition: font-size 0.2s ease-in-out, translate 0.2s ease-in-out;
|
|
201
|
+
|
|
202
|
+
&:has(+ .input-text-wrapper.active),
|
|
203
|
+
&:has(+ .input-text-wrapper.dirty) {
|
|
204
|
+
--_label-offset: 0 -3rem;
|
|
205
|
+
/* font-size: var(--step-2); */
|
|
206
|
+
/* padding: 0.2rem 1.2rem; */
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.input-text-wrapper {
|
|
211
|
+
grid-area: material-text-stack;
|
|
212
|
+
}
|
|
148
213
|
}
|
|
149
214
|
}
|
|
150
215
|
</style>
|
|
@@ -1,24 +1,6 @@
|
|
|
1
1
|
export const useColourScheme = () => {
|
|
2
|
-
// const currentColourScheme = computed(() => {
|
|
3
|
-
// return colourScheme.value;
|
|
4
|
-
// });
|
|
5
|
-
|
|
6
2
|
const currentColourScheme = ref<'auto' | 'dark' | 'light' | null>(null);
|
|
7
3
|
|
|
8
|
-
// const updateColourScheme = (newColourScheme: 'auto' | 'dark' | 'light') => {
|
|
9
|
-
// colourScheme.value = newColourScheme;
|
|
10
|
-
// };
|
|
11
|
-
|
|
12
|
-
// const getSetPrefereredColourScheme = () => {
|
|
13
|
-
// if (import.meta.client) {
|
|
14
|
-
// if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches && !document.documentElement.dataset.colorScheme) {
|
|
15
|
-
// colourScheme.value = 'dark';
|
|
16
|
-
// } else {
|
|
17
|
-
// colourScheme.value = 'light';
|
|
18
|
-
// }
|
|
19
|
-
// }
|
|
20
|
-
// };
|
|
21
|
-
|
|
22
4
|
const returnSavedColourPreferenceFromLocalStorage = () => {
|
|
23
5
|
if (import.meta.client) {
|
|
24
6
|
return localStorage.getItem('colourScheme') as 'auto' | 'dark' | 'light' | null;
|
|
@@ -27,18 +9,6 @@ export const useColourScheme = () => {
|
|
|
27
9
|
|
|
28
10
|
onMounted(() => {
|
|
29
11
|
currentColourScheme.value = returnSavedColourPreferenceFromLocalStorage() || 'auto';
|
|
30
|
-
// colourScheme.value = currentColourScheme.value;
|
|
31
|
-
//
|
|
32
|
-
// if (import.meta.client) {
|
|
33
|
-
// const savedColourScheme = localStorage.getItem('colourScheme');
|
|
34
|
-
// if (savedColourScheme) {
|
|
35
|
-
// colourScheme.value = savedColourScheme as 'dark' | 'light';
|
|
36
|
-
// } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
37
|
-
// colourScheme.value = 'dark';
|
|
38
|
-
// } else {
|
|
39
|
-
// colourScheme.value = 'light';
|
|
40
|
-
// }
|
|
41
|
-
// }
|
|
42
12
|
});
|
|
43
13
|
|
|
44
14
|
watch(currentColourScheme, (newVal) => {
|
|
@@ -51,8 +21,5 @@ export const useColourScheme = () => {
|
|
|
51
21
|
|
|
52
22
|
return {
|
|
53
23
|
currentColourScheme,
|
|
54
|
-
// colourScheme,
|
|
55
|
-
// updateColourScheme,
|
|
56
|
-
// getSetPrefereredColourScheme,
|
|
57
24
|
};
|
|
58
25
|
};
|
package/package.json
CHANGED