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.
@@ -0,0 +1,3 @@
1
+ :where(html) {
2
+ --theme-error: var(--red-7);
3
+ }
@@ -1,3 +1,3 @@
1
1
  :where(html) {
2
- --primary-border-default: var(--blue-8);
2
+ --theme-primary: var(--blue-8);
3
3
  }
@@ -1 +1,2 @@
1
1
  @import './_primary.css';
2
+ @import './_error.css';
@@ -1,4 +1,7 @@
1
- :root {
1
+ :where(html) {
2
+ --font-size: 16px;
3
+ --line-height: calc((var(--font-size) * 2) - 10px);
4
+
2
5
  --input-border-radius: 4px;
3
6
  --input-border-width-thin: 1px;
4
7
  --input-border-width-default: 2px;
@@ -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
- () => modelValue.value.data[name.value],
114
- () => {
115
- modelValue.value!.validityState[name.value] =
116
- inputField.value?.validity.valid ?? false;
117
- if (hasCustomError()) {
118
- removeCustomError(inputField.value?.validity.valid);
119
- }
120
- },
121
- { deep: true }
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
- >{{ c12.label }}</label
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="styleClassPassthrough"
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 styleClassPassthrough = computed(() => {
71
- return isFocused.value ? 'is-active' : '';
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 = computed(() => {
77
- return modelValue.value.data[name.value] !== '';
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
- --_border-default: var(--primary-border-default);
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(--_border-default);
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(--_border-default);
105
- background-color: hsl(from var(--_border-default) h s 95%);
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(10px);
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: 16px;
168
+ font-size: var(--font-size);
139
169
  margin: 0;
170
+ opacity: 0;
171
+ transition: opacity linear 0.2s;
140
172
 
141
- /* &::placeholder,
142
- &:-ms-input-placeholder,
143
- &::-moz-placeholder, */
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
- font-size: 14px;
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: 700;
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
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "srcdev-nuxt-forms",
3
3
  "type": "module",
4
- "version": "0.0.22",
4
+ "version": "0.0.23",
5
5
  "main": "./nuxt.config.ts",
6
6
  "scripts": {
7
7
  "reinstall": "rm -rf node_modules && npm install",