srcdev-nuxt-forms 0.0.22 → 0.0.23
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/assets/styles/forms/themes/_error.css +3 -0
- package/assets/styles/forms/themes/_primary.css +1 -1
- package/assets/styles/forms/themes/index.css +1 -0
- package/assets/styles/forms/variables/_theme.css +4 -1
- package/components/forms/input-text/InputTextCore.vue +23 -11
- package/components/forms/input-text/variants/InputTextMaterial.vue +58 -25
- package/composables/useUpdateStyleClassPassthrough.ts +29 -0
- package/package.json +1 -1
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
'input-text',
|
|
12
12
|
'text-normal',
|
|
13
13
|
styleClassPassthrough,
|
|
14
|
+
{ active: isFocused },
|
|
15
|
+
{ dirty: isDirty },
|
|
14
16
|
{ error: fieldHasError() },
|
|
15
17
|
]"
|
|
16
18
|
v-model="modelValue.data[name]"
|
|
@@ -67,10 +69,12 @@ const props = defineProps({
|
|
|
67
69
|
|
|
68
70
|
const modelValue = defineModel() as Ref<IFormData>;
|
|
69
71
|
const isFocused = defineModel('isFocused') as Ref<boolean>;
|
|
72
|
+
const isDirty = defineModel('isDirty') as Ref<boolean>;
|
|
70
73
|
|
|
71
74
|
const name = computed(() => {
|
|
72
75
|
return props.name !== null ? props.name : props.id;
|
|
73
76
|
});
|
|
77
|
+
|
|
74
78
|
const validatorLocale = toRef(useRuntimeConfig().public.validatorLocale);
|
|
75
79
|
|
|
76
80
|
const componentValidation =
|
|
@@ -99,6 +103,14 @@ watchEffect(() => {
|
|
|
99
103
|
'InputTextCore >> Form value changed to: ',
|
|
100
104
|
modelValue.value.data[name.value]
|
|
101
105
|
);
|
|
106
|
+
|
|
107
|
+
isDirty.value = modelValue.value.data[name.value] !== '';
|
|
108
|
+
|
|
109
|
+
modelValue.value!.validityState[name.value] =
|
|
110
|
+
inputField.value?.validity.valid ?? false;
|
|
111
|
+
if (hasCustomError()) {
|
|
112
|
+
removeCustomError(inputField.value?.validity.valid);
|
|
113
|
+
}
|
|
102
114
|
});
|
|
103
115
|
|
|
104
116
|
const isValid = () => {
|
|
@@ -109,17 +121,17 @@ const isValid = () => {
|
|
|
109
121
|
};
|
|
110
122
|
|
|
111
123
|
// Keep an eye on this for performance issue
|
|
112
|
-
watch(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
);
|
|
124
|
+
// watch(
|
|
125
|
+
// () => modelValue.value.data[name.value],
|
|
126
|
+
// () => {
|
|
127
|
+
// modelValue.value!.validityState[name.value] =
|
|
128
|
+
// inputField.value?.validity.valid ?? false;
|
|
129
|
+
// if (hasCustomError()) {
|
|
130
|
+
// removeCustomError(inputField.value?.validity.valid);
|
|
131
|
+
// }
|
|
132
|
+
// },
|
|
133
|
+
// { deep: true }
|
|
134
|
+
// );
|
|
123
135
|
|
|
124
136
|
onMounted(() => {
|
|
125
137
|
isValid();
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="input-text-material">
|
|
2
|
+
<div class="input-text-material" :class="[{ error: fieldHasError }]">
|
|
3
3
|
<label
|
|
4
4
|
class="label"
|
|
5
5
|
:class="[{ active: isFocused }, { dirty: isDirty }]"
|
|
6
6
|
:for="id"
|
|
7
|
-
>{{
|
|
7
|
+
>{{ labelText }}</label
|
|
8
8
|
>
|
|
9
9
|
<div class="input-text-container">
|
|
10
10
|
<InputTextCore
|
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
:required
|
|
16
16
|
v-model="modelValue"
|
|
17
17
|
v-model:isFocused="isFocused"
|
|
18
|
+
v-model:isDirty="isDirty"
|
|
18
19
|
:c12
|
|
19
|
-
:style-class-passthrough="
|
|
20
|
+
:style-class-passthrough="styleClassPassthroughRef"
|
|
20
21
|
/>
|
|
21
22
|
</div>
|
|
22
23
|
</div>
|
|
@@ -61,27 +62,40 @@ const props = defineProps({
|
|
|
61
62
|
type: Object as PropType<InpuTextC12>,
|
|
62
63
|
required: true,
|
|
63
64
|
},
|
|
65
|
+
styleClassPassthrough: {
|
|
66
|
+
type: String,
|
|
67
|
+
default: '',
|
|
68
|
+
},
|
|
64
69
|
});
|
|
65
70
|
|
|
66
71
|
const name = computed(() => {
|
|
67
72
|
return props.name !== null ? props.name : props.id;
|
|
68
73
|
});
|
|
69
74
|
|
|
70
|
-
const
|
|
71
|
-
return
|
|
75
|
+
const labelText = computed(() => {
|
|
76
|
+
return fieldHasError.value ? errorMessage.value : props.c12.label;
|
|
72
77
|
});
|
|
73
78
|
|
|
79
|
+
const { styleClassPassthroughRef, updateClasses } =
|
|
80
|
+
useUpdateStyleClassPassthrough(props.styleClassPassthrough);
|
|
81
|
+
|
|
74
82
|
const modelValue = defineModel() as Ref<IFormData>;
|
|
75
83
|
const isFocused = ref(false);
|
|
76
|
-
const isDirty =
|
|
77
|
-
|
|
78
|
-
}
|
|
84
|
+
const isDirty = ref(false);
|
|
85
|
+
|
|
86
|
+
const { errorMessage, setDefaultError, fieldHasError } = useErrorMessage(
|
|
87
|
+
name.value,
|
|
88
|
+
modelValue
|
|
89
|
+
);
|
|
90
|
+
setDefaultError(props.c12.errorMessage);
|
|
79
91
|
</script>
|
|
80
92
|
|
|
81
93
|
<style lang="css">
|
|
82
94
|
.input-text-material {
|
|
83
95
|
input {
|
|
84
96
|
background-color: transparent;
|
|
97
|
+
line-height: var(--line-height);
|
|
98
|
+
|
|
85
99
|
&:focus {
|
|
86
100
|
outline: none;
|
|
87
101
|
box-shadow: none;
|
|
@@ -89,20 +103,36 @@ const isDirty = computed(() => {
|
|
|
89
103
|
}
|
|
90
104
|
}
|
|
91
105
|
|
|
106
|
+
label {
|
|
107
|
+
margin: initial;
|
|
108
|
+
line-height: var(--line-height);
|
|
109
|
+
padding: initial;
|
|
110
|
+
}
|
|
111
|
+
|
|
92
112
|
--_gutter: 12px;
|
|
93
|
-
--
|
|
113
|
+
--_form-theme: var(--theme-primary);
|
|
94
114
|
--_border-width: var(--input-border-width-default);
|
|
95
115
|
|
|
96
116
|
display: grid;
|
|
97
117
|
border-radius: 2px;
|
|
98
|
-
outline: var(--_border-width) solid var(--
|
|
118
|
+
outline: var(--_border-width) solid var(--_form-theme);
|
|
99
119
|
|
|
100
120
|
margin-bottom: 20px;
|
|
101
121
|
overflow: hidden;
|
|
122
|
+
/* transition: all linear 0.2s; */
|
|
102
123
|
|
|
103
124
|
&:focus-within {
|
|
104
|
-
outline: calc(var(--_border-width) * 2) solid var(--
|
|
105
|
-
background-color: hsl(from var(--
|
|
125
|
+
outline: calc(var(--_border-width) * 2) solid var(--_form-theme);
|
|
126
|
+
background-color: hsl(from var(--_form-theme) h s 95%);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
&.error {
|
|
130
|
+
outline: calc(var(--_border-width) * 2) solid var(--theme-error);
|
|
131
|
+
background-color: hsl(from var(--theme-error) h s 95%);
|
|
132
|
+
|
|
133
|
+
/* .label {
|
|
134
|
+
color: var(--theme-error);
|
|
135
|
+
} */
|
|
106
136
|
}
|
|
107
137
|
|
|
108
138
|
.label {
|
|
@@ -113,7 +143,7 @@ const isDirty = computed(() => {
|
|
|
113
143
|
font-size: 20px;
|
|
114
144
|
font-weight: 700;
|
|
115
145
|
padding: var(--_gutter);
|
|
116
|
-
transform: translateY(
|
|
146
|
+
transform: translateY(12px);
|
|
117
147
|
transition: all linear 0.2s;
|
|
118
148
|
background-color: transparent;
|
|
119
149
|
|
|
@@ -135,23 +165,26 @@ const isDirty = computed(() => {
|
|
|
135
165
|
font-family: var(--font-family);
|
|
136
166
|
border: 0px solid green;
|
|
137
167
|
padding: calc(var(--_gutter) / 2) var(--_gutter);
|
|
138
|
-
font-size:
|
|
168
|
+
font-size: var(--font-size);
|
|
139
169
|
margin: 0;
|
|
170
|
+
opacity: 0;
|
|
171
|
+
transition: opacity linear 0.2s;
|
|
140
172
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
173
|
+
&.active,
|
|
174
|
+
&.dirty {
|
|
175
|
+
opacity: 1;
|
|
176
|
+
}
|
|
177
|
+
/*
|
|
178
|
+
&::placeholder,
|
|
179
|
+
&:-ms-input-placeholder,
|
|
180
|
+
&::-moz-placeholder, */
|
|
144
181
|
&::-webkit-input-placeholder {
|
|
145
182
|
font-family: var(--font-family);
|
|
146
|
-
color: var(--gray-5);
|
|
147
|
-
|
|
183
|
+
/* color: var(--gray-5); */
|
|
184
|
+
color: hsl(from var(--_form-theme) h s 50%);
|
|
185
|
+
font-size: var(--font-size);
|
|
148
186
|
font-style: italic;
|
|
149
|
-
font-weight:
|
|
150
|
-
opacity: 0;
|
|
151
|
-
|
|
152
|
-
&.is-active {
|
|
153
|
-
opacity: 1;
|
|
154
|
-
}
|
|
187
|
+
font-weight: 500;
|
|
155
188
|
}
|
|
156
189
|
}
|
|
157
190
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const useUpdateStyleClassPassthrough = (classes: string) => {
|
|
2
|
+
const styleClassPassthroughRef = ref(classes);
|
|
3
|
+
|
|
4
|
+
function updateClasses(add: boolean, cssClass: string) {
|
|
5
|
+
let classesArray = classes.split(' ');
|
|
6
|
+
|
|
7
|
+
if (add && !classesArray.includes(cssClass)) {
|
|
8
|
+
classesArray.push(cssClass);
|
|
9
|
+
} else if (!add && classesArray.includes(cssClass)) {
|
|
10
|
+
classesArray = classesArray.filter((className) => className !== cssClass);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// if (classesArray.includes(cssClass)) {
|
|
14
|
+
// // Remove the value if it's already in the array
|
|
15
|
+
// classesArray = classesArray.filter(className => className !== cssClass);
|
|
16
|
+
// } else {
|
|
17
|
+
// // Add the value if it's not in the array
|
|
18
|
+
// classesArray.push(cssClass);
|
|
19
|
+
// }
|
|
20
|
+
|
|
21
|
+
// Join the array back into a string and assign it back
|
|
22
|
+
styleClassPassthroughRef.value = classesArray.join(' ');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
styleClassPassthroughRef,
|
|
27
|
+
updateClasses,
|
|
28
|
+
};
|
|
29
|
+
};
|