srcdev-nuxt-forms 0.0.23 → 0.1.0
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/.prettierrc +2 -1
- package/assets/styles/forms/themes/_error.css +9 -0
- package/assets/styles/forms/themes/_ghost.css +11 -0
- package/assets/styles/forms/themes/_primary.css +9 -1
- package/assets/styles/forms/themes/_secondary.css +11 -0
- package/assets/styles/forms/themes/_success.css +12 -0
- package/assets/styles/forms/themes/_tertiary.css +11 -0
- package/assets/styles/forms/themes/_warning.css +11 -0
- package/assets/styles/forms/themes/index.css +5 -0
- package/assets/styles/forms/variables/_theme.css +60 -0
- package/assets/styles/variables/colors/_orange.css +1 -1
- package/assets/styles/variables/colors/_red.css +1 -1
- package/components/forms/c12/prop-validators/index.ts +25 -0
- package/components/forms/c12/validation-patterns/en.json +1 -1
- package/components/forms/input-button/InputButtonCore.vue +367 -0
- package/components/forms/input-button/variants/InputButtonConfirm.vue +78 -0
- package/components/forms/input-button/variants/InputButtonSubmit.vue +74 -0
- package/components/forms/input-text/InputTextCore.vue +72 -66
- package/components/forms/input-text/variants/material/InputEmailMaterial.vue +72 -0
- package/components/forms/input-text/variants/material/InputPasswordMaterial.vue +88 -0
- package/components/forms/input-text/variants/material/InputTextMaterial.vue +75 -0
- package/components/forms/input-text/variants/material/InputTextMaterialCore.vue +258 -0
- package/components/forms/ui/FormField.vue +7 -2
- package/components/forms/ui/FormWrapper.vue +2 -2
- package/composables/useErrorMessages.ts +4 -4
- package/composables/useFormControl.ts +36 -16
- package/layouts/default.vue +33 -2
- package/nuxt.config.ts +4 -3
- package/package.json +3 -1
- package/pages/forms/examples/buttons/index.vue +154 -0
- package/pages/forms/examples/material/text-fields-compact.vue +136 -0
- package/pages/forms/examples/material/text-fields.vue +136 -0
- package/pages/index.vue +2 -70
- package/types/types.forms.ts +6 -11
- package/components/forms/input-text/InputTextField.vue +0 -22
- package/components/forms/input-text/variants/InputTextMaterial.vue +0 -192
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<NuxtLayout name="default">
|
|
4
|
+
<template #layout-content>
|
|
5
|
+
<div>
|
|
6
|
+
<h1>Material UI text fields (compact)</h1>
|
|
7
|
+
<p>Example test fields in "compact" material UI</p>
|
|
8
|
+
|
|
9
|
+
<FormWrapper width="medium">
|
|
10
|
+
<template #default>
|
|
11
|
+
<form @submit.prevent="submitForm">
|
|
12
|
+
<FormField width="wide" :has-gutter="true">
|
|
13
|
+
<template #default>
|
|
14
|
+
<InputEmailMaterial
|
|
15
|
+
id="emailAddress"
|
|
16
|
+
name="emailAddress"
|
|
17
|
+
validation="emailaddress"
|
|
18
|
+
:required="true"
|
|
19
|
+
:c12="{
|
|
20
|
+
label: 'Your Email Address',
|
|
21
|
+
placeholder: 'eg. joe@example.com',
|
|
22
|
+
errorMessage: 'Please enter a valid email address',
|
|
23
|
+
}"
|
|
24
|
+
v-model="formData"
|
|
25
|
+
theme="secondary"
|
|
26
|
+
:compact
|
|
27
|
+
/>
|
|
28
|
+
</template>
|
|
29
|
+
</FormField>
|
|
30
|
+
|
|
31
|
+
<FormField width="wide" :has-gutter="true">
|
|
32
|
+
<template #default>
|
|
33
|
+
<InputTextMaterial
|
|
34
|
+
id="username"
|
|
35
|
+
name="username"
|
|
36
|
+
validation="username"
|
|
37
|
+
:required="true"
|
|
38
|
+
:c12="{
|
|
39
|
+
label: 'Your Username',
|
|
40
|
+
placeholder: 'eg. YourUserName',
|
|
41
|
+
errorMessage: 'Please enter a valid username',
|
|
42
|
+
}"
|
|
43
|
+
v-model="formData"
|
|
44
|
+
theme="secondary"
|
|
45
|
+
:compact
|
|
46
|
+
/>
|
|
47
|
+
</template>
|
|
48
|
+
</FormField>
|
|
49
|
+
|
|
50
|
+
<FormField width="wide" :has-gutter="true">
|
|
51
|
+
<template #default>
|
|
52
|
+
<InputPasswordMaterial
|
|
53
|
+
id="password"
|
|
54
|
+
name="password"
|
|
55
|
+
validation="password"
|
|
56
|
+
:required="true"
|
|
57
|
+
:c12="{
|
|
58
|
+
label: 'Password',
|
|
59
|
+
placeholder: 'eg. Your5illYPa55w0rd',
|
|
60
|
+
errorMessage: 'Please enter a valid password',
|
|
61
|
+
}"
|
|
62
|
+
v-model="formData"
|
|
63
|
+
theme="secondary"
|
|
64
|
+
:compact
|
|
65
|
+
/>
|
|
66
|
+
</template>
|
|
67
|
+
</FormField>
|
|
68
|
+
|
|
69
|
+
<FormField width="wide" :has-gutter="true">
|
|
70
|
+
<template #default>
|
|
71
|
+
<InputButtonSubmit @click.stop.prevent="submitForm" :is-pending="false" :readonly="submitDisabled" button-text="Submit" theme="secondary" size="medium" />
|
|
72
|
+
</template>
|
|
73
|
+
</FormField>
|
|
74
|
+
</form>
|
|
75
|
+
</template>
|
|
76
|
+
</FormWrapper>
|
|
77
|
+
</div>
|
|
78
|
+
<ClientOnly>
|
|
79
|
+
<p>Client only content</p>
|
|
80
|
+
<pre>
|
|
81
|
+
{{ formData }}
|
|
82
|
+
</pre>
|
|
83
|
+
</ClientOnly>
|
|
84
|
+
</template>
|
|
85
|
+
</NuxtLayout>
|
|
86
|
+
</div>
|
|
87
|
+
</template>
|
|
88
|
+
|
|
89
|
+
<script setup lang="ts">
|
|
90
|
+
import type { IFieldsInitialState, IOptionsConfig } from '@/types/types.forms';
|
|
91
|
+
|
|
92
|
+
definePageMeta({
|
|
93
|
+
layout: false,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
useHead({
|
|
97
|
+
title: 'Homepage',
|
|
98
|
+
meta: [{ name: 'description', content: 'Homepage' }],
|
|
99
|
+
bodyAttrs: {
|
|
100
|
+
class: '',
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const compact = ref(true);
|
|
105
|
+
|
|
106
|
+
/*
|
|
107
|
+
* Setup forms
|
|
108
|
+
*/
|
|
109
|
+
const fieldsInitialState = ref<IFieldsInitialState>({
|
|
110
|
+
emailAddress: '',
|
|
111
|
+
username: '',
|
|
112
|
+
password: '',
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Setup formData
|
|
116
|
+
const { formData, getErrorCount, updateCustomErrors, resetForm, formIsValid, submitDisabled } = useFormControl(fieldsInitialState);
|
|
117
|
+
|
|
118
|
+
const submitForm = async () => {
|
|
119
|
+
await getErrorCount(true);
|
|
120
|
+
|
|
121
|
+
if (formIsValid.value) {
|
|
122
|
+
formData.value.isPending = true;
|
|
123
|
+
console.log('Form is good - post it!');
|
|
124
|
+
// await useSleep(2000);
|
|
125
|
+
// formData.value.isPending = false;
|
|
126
|
+
} else {
|
|
127
|
+
console.warn('Form has errors');
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
</script>
|
|
131
|
+
|
|
132
|
+
<style lang="css">
|
|
133
|
+
p {
|
|
134
|
+
color: initial;
|
|
135
|
+
}
|
|
136
|
+
</style>
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<NuxtLayout name="default">
|
|
4
|
+
<template #layout-content>
|
|
5
|
+
<div>
|
|
6
|
+
<h1>Material UI text fields (default)</h1>
|
|
7
|
+
<p>Example test fields in default material UI</p>
|
|
8
|
+
|
|
9
|
+
<FormWrapper width="medium">
|
|
10
|
+
<template #default>
|
|
11
|
+
<form @submit.prevent="submitForm">
|
|
12
|
+
<FormField width="wide" :has-gutter="true">
|
|
13
|
+
<template #default>
|
|
14
|
+
<InputEmailMaterial
|
|
15
|
+
id="emailAddress"
|
|
16
|
+
name="emailAddress"
|
|
17
|
+
validation="emailaddress"
|
|
18
|
+
:required="true"
|
|
19
|
+
:c12="{
|
|
20
|
+
label: 'Your Email Address',
|
|
21
|
+
placeholder: 'eg. joe@example.com',
|
|
22
|
+
errorMessage: 'Please enter a valid email address',
|
|
23
|
+
}"
|
|
24
|
+
v-model="formData"
|
|
25
|
+
theme="secondary"
|
|
26
|
+
:compact
|
|
27
|
+
/>
|
|
28
|
+
</template>
|
|
29
|
+
</FormField>
|
|
30
|
+
|
|
31
|
+
<FormField width="wide" :has-gutter="true">
|
|
32
|
+
<template #default>
|
|
33
|
+
<InputTextMaterial
|
|
34
|
+
id="username"
|
|
35
|
+
name="username"
|
|
36
|
+
validation="username"
|
|
37
|
+
:required="true"
|
|
38
|
+
:c12="{
|
|
39
|
+
label: 'Your Username',
|
|
40
|
+
placeholder: 'eg. YourUserName',
|
|
41
|
+
errorMessage: 'Please enter a valid username',
|
|
42
|
+
}"
|
|
43
|
+
v-model="formData"
|
|
44
|
+
theme="secondary"
|
|
45
|
+
:compact
|
|
46
|
+
/>
|
|
47
|
+
</template>
|
|
48
|
+
</FormField>
|
|
49
|
+
|
|
50
|
+
<FormField width="wide" :has-gutter="true">
|
|
51
|
+
<template #default>
|
|
52
|
+
<InputPasswordMaterial
|
|
53
|
+
id="password"
|
|
54
|
+
name="password"
|
|
55
|
+
validation="password"
|
|
56
|
+
:required="true"
|
|
57
|
+
:c12="{
|
|
58
|
+
label: 'Password',
|
|
59
|
+
placeholder: 'eg. Your5illYPa55w0rd',
|
|
60
|
+
errorMessage: 'Please enter a valid password',
|
|
61
|
+
}"
|
|
62
|
+
v-model="formData"
|
|
63
|
+
theme="secondary"
|
|
64
|
+
:compact
|
|
65
|
+
/>
|
|
66
|
+
</template>
|
|
67
|
+
</FormField>
|
|
68
|
+
|
|
69
|
+
<FormField width="wide" :has-gutter="true">
|
|
70
|
+
<template #default>
|
|
71
|
+
<InputButtonSubmit @click.stop.prevent="submitForm" :is-pending="false" :readonly="submitDisabled" button-text="Submit" theme="secondary" size="medium" />
|
|
72
|
+
</template>
|
|
73
|
+
</FormField>
|
|
74
|
+
</form>
|
|
75
|
+
</template>
|
|
76
|
+
</FormWrapper>
|
|
77
|
+
</div>
|
|
78
|
+
<ClientOnly>
|
|
79
|
+
<p>Client only content</p>
|
|
80
|
+
<pre>
|
|
81
|
+
{{ formData }}
|
|
82
|
+
</pre>
|
|
83
|
+
</ClientOnly>
|
|
84
|
+
</template>
|
|
85
|
+
</NuxtLayout>
|
|
86
|
+
</div>
|
|
87
|
+
</template>
|
|
88
|
+
|
|
89
|
+
<script setup lang="ts">
|
|
90
|
+
import type { IFieldsInitialState, IOptionsConfig } from '@/types/types.forms';
|
|
91
|
+
|
|
92
|
+
definePageMeta({
|
|
93
|
+
layout: false,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
useHead({
|
|
97
|
+
title: 'Homepage',
|
|
98
|
+
meta: [{ name: 'description', content: 'Homepage' }],
|
|
99
|
+
bodyAttrs: {
|
|
100
|
+
class: '',
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const compact = ref(false);
|
|
105
|
+
|
|
106
|
+
/*
|
|
107
|
+
* Setup forms
|
|
108
|
+
*/
|
|
109
|
+
const fieldsInitialState = ref<IFieldsInitialState>({
|
|
110
|
+
emailAddress: '',
|
|
111
|
+
username: '',
|
|
112
|
+
password: '',
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Setup formData
|
|
116
|
+
const { formData, getErrorCount, updateCustomErrors, resetForm, formIsValid, submitDisabled } = useFormControl(fieldsInitialState);
|
|
117
|
+
|
|
118
|
+
const submitForm = async () => {
|
|
119
|
+
await getErrorCount(true);
|
|
120
|
+
|
|
121
|
+
if (formIsValid.value) {
|
|
122
|
+
formData.value.isPending = true;
|
|
123
|
+
console.log('Form is good - post it!');
|
|
124
|
+
// await useSleep(2000);
|
|
125
|
+
// formData.value.isPending = false;
|
|
126
|
+
} else {
|
|
127
|
+
console.warn('Form has errors');
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
</script>
|
|
131
|
+
|
|
132
|
+
<style lang="css">
|
|
133
|
+
p {
|
|
134
|
+
color: initial;
|
|
135
|
+
}
|
|
136
|
+
</style>
|
package/pages/index.vue
CHANGED
|
@@ -3,53 +3,16 @@
|
|
|
3
3
|
<NuxtLayout name="default">
|
|
4
4
|
<template #layout-content>
|
|
5
5
|
<div>
|
|
6
|
-
<h1>Sample form page</h1>
|
|
6
|
+
<h1>Sample form page pages</h1>
|
|
7
7
|
|
|
8
|
-
<
|
|
9
|
-
<template #default>
|
|
10
|
-
<form @submit.prevent="isPending">
|
|
11
|
-
<p>Form content</p>
|
|
12
|
-
<FormField width="wide" :has-gutter="true">
|
|
13
|
-
<template #default>
|
|
14
|
-
<p>Input text</p>
|
|
15
|
-
<InputTextMaterial
|
|
16
|
-
id="username"
|
|
17
|
-
name="username"
|
|
18
|
-
type="text"
|
|
19
|
-
validation="username"
|
|
20
|
-
:required="true"
|
|
21
|
-
:c12="{
|
|
22
|
-
label: 'Choose Username',
|
|
23
|
-
placeholder: 'eg. YourUserName',
|
|
24
|
-
errorMessage: 'Please enter a valid username',
|
|
25
|
-
}"
|
|
26
|
-
v-model="formData"
|
|
27
|
-
/>
|
|
28
|
-
</template>
|
|
29
|
-
</FormField>
|
|
30
|
-
<input
|
|
31
|
-
type="submit"
|
|
32
|
-
@click.prevent="isPending"
|
|
33
|
-
value="Submit"
|
|
34
|
-
/>
|
|
35
|
-
</form>
|
|
36
|
-
</template>
|
|
37
|
-
</FormWrapper>
|
|
8
|
+
<p>Example test fields in default material UI</p>
|
|
38
9
|
</div>
|
|
39
|
-
<ClientOnly>
|
|
40
|
-
<p>Client only content</p>
|
|
41
|
-
<pre>
|
|
42
|
-
{{ formData }}
|
|
43
|
-
</pre>
|
|
44
|
-
</ClientOnly>
|
|
45
10
|
</template>
|
|
46
11
|
</NuxtLayout>
|
|
47
12
|
</div>
|
|
48
13
|
</template>
|
|
49
14
|
|
|
50
15
|
<script setup lang="ts">
|
|
51
|
-
import type { IFieldsInitialState, IOptionsConfig } from '@/types/types.forms';
|
|
52
|
-
|
|
53
16
|
definePageMeta({
|
|
54
17
|
layout: false,
|
|
55
18
|
});
|
|
@@ -61,37 +24,6 @@ useHead({
|
|
|
61
24
|
class: '',
|
|
62
25
|
},
|
|
63
26
|
});
|
|
64
|
-
|
|
65
|
-
/*
|
|
66
|
-
* Setup forms
|
|
67
|
-
*/
|
|
68
|
-
const fieldsInitialState = ref<IFieldsInitialState>({
|
|
69
|
-
username: '',
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
// Setup formData
|
|
73
|
-
const {
|
|
74
|
-
formData,
|
|
75
|
-
initFormData,
|
|
76
|
-
getErrorCount,
|
|
77
|
-
updateCustomErrors,
|
|
78
|
-
resetForm,
|
|
79
|
-
formIsValid,
|
|
80
|
-
showErrors,
|
|
81
|
-
} = useFormControl(fieldsInitialState);
|
|
82
|
-
|
|
83
|
-
await initFormData();
|
|
84
|
-
|
|
85
|
-
const isPending = async () => {
|
|
86
|
-
formData.value.isPending = true;
|
|
87
|
-
await getErrorCount();
|
|
88
|
-
|
|
89
|
-
if (formIsValid.value) {
|
|
90
|
-
console.log('Form is good - post it!');
|
|
91
|
-
} else {
|
|
92
|
-
console.warn('Form has errors');
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
27
|
</script>
|
|
96
28
|
|
|
97
29
|
<style lang="css">
|
package/types/types.forms.ts
CHANGED
|
@@ -17,14 +17,7 @@ export interface IOptionsValueArr {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export interface IFieldsInitialState {
|
|
20
|
-
[key: string]:
|
|
21
|
-
| null
|
|
22
|
-
| string
|
|
23
|
-
| boolean
|
|
24
|
-
| number
|
|
25
|
-
| URL
|
|
26
|
-
| object
|
|
27
|
-
| IOptionsValueArr[];
|
|
20
|
+
[key: string]: null | string | boolean | number | URL | object | IOptionsValueArr[];
|
|
28
21
|
}
|
|
29
22
|
|
|
30
23
|
export interface IValidityState {
|
|
@@ -57,7 +50,7 @@ export interface IValidityStateArr {
|
|
|
57
50
|
};
|
|
58
51
|
}
|
|
59
52
|
|
|
60
|
-
export interface
|
|
53
|
+
export interface IFormFieldsState {
|
|
61
54
|
[key: string]: boolean;
|
|
62
55
|
}
|
|
63
56
|
|
|
@@ -79,11 +72,13 @@ export interface ICustomErrorMessagesArr {
|
|
|
79
72
|
export interface IFormData {
|
|
80
73
|
[x: string]: string | boolean | number | URL | object;
|
|
81
74
|
data: IFieldsInitialState;
|
|
82
|
-
validityState:
|
|
75
|
+
validityState: IFormFieldsState;
|
|
76
|
+
dirtyFields: IFormFieldsState;
|
|
77
|
+
focusedField: string;
|
|
83
78
|
isPending: boolean;
|
|
84
79
|
errorCount: number;
|
|
85
80
|
customErrorMessages: ICustomErrorMessagesArr;
|
|
86
81
|
formIsValid: boolean;
|
|
87
|
-
showErrors: boolean;
|
|
88
82
|
submitSuccess: boolean;
|
|
83
|
+
submitDisabled: boolean;
|
|
89
84
|
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<input type="text" class="input-text" v-model="formValue" />
|
|
4
|
-
</div>
|
|
5
|
-
</template>
|
|
6
|
-
<script setup lang="ts">
|
|
7
|
-
console.log('InputText component loaded')
|
|
8
|
-
|
|
9
|
-
const formValue = ref('')
|
|
10
|
-
|
|
11
|
-
watchEffect(() => {
|
|
12
|
-
console.log('Form value changed to: ', formValue.value)
|
|
13
|
-
})
|
|
14
|
-
</script>
|
|
15
|
-
|
|
16
|
-
<style lang="css">
|
|
17
|
-
.input-text {
|
|
18
|
-
border: var(--input-border-width-thin) solid var(--input-border);
|
|
19
|
-
border-radius: var(--input-border-radius);
|
|
20
|
-
padding: 10px;
|
|
21
|
-
}
|
|
22
|
-
</style>
|
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="input-text-material" :class="[{ error: fieldHasError }]">
|
|
3
|
-
<label
|
|
4
|
-
class="label"
|
|
5
|
-
:class="[{ active: isFocused }, { dirty: isDirty }]"
|
|
6
|
-
:for="id"
|
|
7
|
-
>{{ labelText }}</label
|
|
8
|
-
>
|
|
9
|
-
<div class="input-text-container">
|
|
10
|
-
<InputTextCore
|
|
11
|
-
:id
|
|
12
|
-
:name
|
|
13
|
-
:type
|
|
14
|
-
:validation
|
|
15
|
-
:required
|
|
16
|
-
v-model="modelValue"
|
|
17
|
-
v-model:isFocused="isFocused"
|
|
18
|
-
v-model:isDirty="isDirty"
|
|
19
|
-
:c12
|
|
20
|
-
:style-class-passthrough="styleClassPassthroughRef"
|
|
21
|
-
/>
|
|
22
|
-
</div>
|
|
23
|
-
</div>
|
|
24
|
-
</template>
|
|
25
|
-
|
|
26
|
-
<script setup lang="ts">
|
|
27
|
-
import type { InpuTextC12, IFormData } from '@/types/types.forms';
|
|
28
|
-
import { validationConfig } from '@/components/forms/c12/validation-patterns';
|
|
29
|
-
|
|
30
|
-
const props = defineProps({
|
|
31
|
-
type: {
|
|
32
|
-
// type: String as PropType<"text" | "password" | "tel" | "number" | "email" | "url">, // This breaks props setup in unit tests
|
|
33
|
-
type: String,
|
|
34
|
-
validator(value: string) {
|
|
35
|
-
return ['text', 'password', 'tel', 'number', 'email', 'url'].includes(
|
|
36
|
-
value
|
|
37
|
-
);
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
id: {
|
|
41
|
-
// type: String as PropType<string>,
|
|
42
|
-
type: String,
|
|
43
|
-
required: true,
|
|
44
|
-
},
|
|
45
|
-
name: {
|
|
46
|
-
type: String,
|
|
47
|
-
default: null,
|
|
48
|
-
},
|
|
49
|
-
validation: {
|
|
50
|
-
type: String,
|
|
51
|
-
default: '',
|
|
52
|
-
},
|
|
53
|
-
required: {
|
|
54
|
-
type: Boolean,
|
|
55
|
-
value: false,
|
|
56
|
-
},
|
|
57
|
-
isPending: {
|
|
58
|
-
type: Boolean,
|
|
59
|
-
value: false,
|
|
60
|
-
},
|
|
61
|
-
c12: {
|
|
62
|
-
type: Object as PropType<InpuTextC12>,
|
|
63
|
-
required: true,
|
|
64
|
-
},
|
|
65
|
-
styleClassPassthrough: {
|
|
66
|
-
type: String,
|
|
67
|
-
default: '',
|
|
68
|
-
},
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
const name = computed(() => {
|
|
72
|
-
return props.name !== null ? props.name : props.id;
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
const labelText = computed(() => {
|
|
76
|
-
return fieldHasError.value ? errorMessage.value : props.c12.label;
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
const { styleClassPassthroughRef, updateClasses } =
|
|
80
|
-
useUpdateStyleClassPassthrough(props.styleClassPassthrough);
|
|
81
|
-
|
|
82
|
-
const modelValue = defineModel() as Ref<IFormData>;
|
|
83
|
-
const isFocused = ref(false);
|
|
84
|
-
const isDirty = ref(false);
|
|
85
|
-
|
|
86
|
-
const { errorMessage, setDefaultError, fieldHasError } = useErrorMessage(
|
|
87
|
-
name.value,
|
|
88
|
-
modelValue
|
|
89
|
-
);
|
|
90
|
-
setDefaultError(props.c12.errorMessage);
|
|
91
|
-
</script>
|
|
92
|
-
|
|
93
|
-
<style lang="css">
|
|
94
|
-
.input-text-material {
|
|
95
|
-
input {
|
|
96
|
-
background-color: transparent;
|
|
97
|
-
line-height: var(--line-height);
|
|
98
|
-
|
|
99
|
-
&:focus {
|
|
100
|
-
outline: none;
|
|
101
|
-
box-shadow: none;
|
|
102
|
-
border: none;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
label {
|
|
107
|
-
margin: initial;
|
|
108
|
-
line-height: var(--line-height);
|
|
109
|
-
padding: initial;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
--_gutter: 12px;
|
|
113
|
-
--_form-theme: var(--theme-primary);
|
|
114
|
-
--_border-width: var(--input-border-width-default);
|
|
115
|
-
|
|
116
|
-
display: grid;
|
|
117
|
-
border-radius: 2px;
|
|
118
|
-
outline: var(--_border-width) solid var(--_form-theme);
|
|
119
|
-
|
|
120
|
-
margin-bottom: 20px;
|
|
121
|
-
overflow: hidden;
|
|
122
|
-
/* transition: all linear 0.2s; */
|
|
123
|
-
|
|
124
|
-
&:focus-within {
|
|
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
|
-
} */
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
.label {
|
|
139
|
-
grid-row: 1;
|
|
140
|
-
grid-column: 1;
|
|
141
|
-
|
|
142
|
-
font-family: var(--font-family);
|
|
143
|
-
font-size: 20px;
|
|
144
|
-
font-weight: 700;
|
|
145
|
-
padding: var(--_gutter);
|
|
146
|
-
transform: translateY(12px);
|
|
147
|
-
transition: all linear 0.2s;
|
|
148
|
-
background-color: transparent;
|
|
149
|
-
|
|
150
|
-
&.active,
|
|
151
|
-
&.dirty {
|
|
152
|
-
font-size: 14px;
|
|
153
|
-
transform: translateY(0);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
.input-text-container {
|
|
158
|
-
display: grid;
|
|
159
|
-
grid-row: 1;
|
|
160
|
-
grid-column: 1;
|
|
161
|
-
margin-top: 2rem;
|
|
162
|
-
background-color: transparent;
|
|
163
|
-
|
|
164
|
-
.input-text {
|
|
165
|
-
font-family: var(--font-family);
|
|
166
|
-
border: 0px solid green;
|
|
167
|
-
padding: calc(var(--_gutter) / 2) var(--_gutter);
|
|
168
|
-
font-size: var(--font-size);
|
|
169
|
-
margin: 0;
|
|
170
|
-
opacity: 0;
|
|
171
|
-
transition: opacity linear 0.2s;
|
|
172
|
-
|
|
173
|
-
&.active,
|
|
174
|
-
&.dirty {
|
|
175
|
-
opacity: 1;
|
|
176
|
-
}
|
|
177
|
-
/*
|
|
178
|
-
&::placeholder,
|
|
179
|
-
&:-ms-input-placeholder,
|
|
180
|
-
&::-moz-placeholder, */
|
|
181
|
-
&::-webkit-input-placeholder {
|
|
182
|
-
font-family: var(--font-family);
|
|
183
|
-
/* color: var(--gray-5); */
|
|
184
|
-
color: hsl(from var(--_form-theme) h s 50%);
|
|
185
|
-
font-size: var(--font-size);
|
|
186
|
-
font-style: italic;
|
|
187
|
-
font-weight: 500;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
</style>
|