srcdev-nuxt-forms 6.0.0 → 6.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.
Files changed (29) hide show
  1. package/README.md +45 -5
  2. package/app/assets/styles/extends-layer/srcdev-forms/components/_form-fieldset.css +1 -1
  3. package/app/assets/styles/extends-layer/srcdev-forms/components/_input-button.css +1 -1
  4. package/app/assets/styles/extends-layer/srcdev-forms/components/_input-checkbox-radio-core.css +1 -1
  5. package/app/assets/styles/extends-layer/srcdev-forms/components/_input-checkbox-radio-options-button.css +1 -1
  6. package/app/assets/styles/extends-layer/srcdev-forms/components/_input-error.css +1 -1
  7. package/app/assets/styles/extends-layer/srcdev-forms/components/_input-label.css +1 -1
  8. package/app/assets/styles/extends-layer/srcdev-forms/components/_input-select.css +1 -1
  9. package/app/assets/styles/extends-layer/srcdev-forms/components/_input-text.css +1 -1
  10. package/app/assets/styles/extends-layer/srcdev-forms/components/_input-textarea.css +1 -1
  11. package/app/assets/styles/setup/_head.css +1 -1
  12. package/app/assets/styles/setup/typography/vars/_reponsive-font-sizes.css +10 -10
  13. package/app/assets/styles/setup/typography/vars/index.css +0 -1
  14. package/app/components/forms/c12/utils.ts +1 -1
  15. package/app/components/forms/input-checkbox/MultipleCheckboxes.vue +1 -1
  16. package/app/components/forms/input-checkbox/SingleCheckbox.vue +1 -1
  17. package/app/components/forms/input-radio/MultipleRadiobuttons.vue +1 -1
  18. package/app/components/forms/input-select/InputSelectCore.vue +1 -1
  19. package/app/components/forms/input-select/variants/InputSelectWithLabel.vue +1 -1
  20. package/app/components/forms/input-text/InputTextCore.vue +56 -50
  21. package/app/composables/useErrorMessages.ts +2 -2
  22. package/app/composables/useFormControl.ts +15 -9
  23. package/app/composables/useZodValidation.ts +1 -1
  24. package/nuxt.config.ts +16 -13
  25. package/package.json +3 -2
  26. package/{app/types/types.zodFormControl.ts → shared/types/types.zodFormControl.d.ts} +1 -1
  27. package/app/assets/styles/setup/typography/vars/_colors.css +0 -14
  28. package/app/assets/styles/setup/variables/index.css +0 -1
  29. /package/{app/types/types.forms.ts → shared/types/types.forms.d.ts} +0 -0
package/README.md CHANGED
@@ -83,18 +83,58 @@ Styles exist for multiple themes/variants, primary, secondary, tertiary, error e
83
83
 
84
84
  Colour scheme can be updated by modifying the css colour variables
85
85
 
86
- ## Thing to note
86
+ ## Styles Architecture
87
87
 
88
- Must add modifier class within nuxt config to enable local css overrides:
88
+ The `/app/assets/styles` folder contains the CSS architecture for this Nuxt layer, organized into two main directories:
89
89
 
90
- ```bash
90
+ ### `/app/assets/styles/setup/`
91
+
92
+ This directory contains the foundational styles that will be mirrored in any app that extends this layer. It includes:
93
+
94
+ - **`index.css`** - Main setup file that imports all setup modules
95
+ - **`_head.css`** - Head-level styles and document setup
96
+ - **`a11y/`** - Accessibility utilities and variables
97
+ - **`theming/`** - Theme definitions, color schemes, and theme variants
98
+ - **`typography/`** - Typography setup, font definitions, and text utility classes
99
+ - **`utility-classes/`** - General utility classes including fluid spacing and animations
100
+
101
+ These styles form the base layer and will be automatically available in any app that extends this layer.
102
+
103
+ ### `/app/assets/styles/extends-layer/srcdev-forms/`
104
+
105
+ This directory contains override styles specifically for apps that extend this layer. It includes:
106
+
107
+ - **`index.css`** - Main override file
108
+ - **`components/`** - Component-specific overrides
109
+ - **`setup/`** - Setup overrides for extended apps
110
+
111
+ This folder structure will also be present in the extending app's assets directory, allowing for easy customization and theming.
112
+
113
+ ### Layer Override Namespace
114
+
115
+ To enable proper CSS override functionality, the extending app must include the `srcdev-forms-extended` class namespace:
116
+
117
+ ```ts
118
+ // nuxt.config.ts in the extending app
119
+ export default defineNuxtConfig({
120
+ extends: 'srcdev-nuxt-forms',
91
121
  app: {
92
122
  head: {
93
123
  htmlAttrs: {
94
- class: 'your-site-class',
124
+ class: 'srcdev-forms-extended',
95
125
  },
96
126
  },
97
127
  },
128
+ });
98
129
  ```
99
130
 
100
- This class must be added to css files located at `~/assets/styles/extends-layer/srcdev-forms/components`
131
+ **Important:** All override CSS files in the extending app's `~/assets/styles/extends-layer/srcdev-forms/` directory must use the `.srcdev-forms-extended` class as a namespace prefix to ensure proper specificity and override behavior.
132
+
133
+ Example override structure in the extending app:
134
+
135
+ ```css
136
+ /* ~/assets/styles/extends-layer/srcdev-forms/components/button.css */
137
+ .srcdev-forms-extended .btn-primary {
138
+ /* Your custom button styles */
139
+ }
140
+ ```
@@ -1,4 +1,4 @@
1
- .your-site-class {
1
+ .srcdev-forms-extended {
2
2
  .form-fieldset {
3
3
  margin: 0;
4
4
  padding: 0;
@@ -1,4 +1,4 @@
1
- .your-site-class {
1
+ .srcdev-forms-extended {
2
2
  .input-button-core {
3
3
  gap: var(--form-button-icon-gap);
4
4
  border-radius: var(--form-input-border-radius);
@@ -1,4 +1,4 @@
1
- .your-site-class {
1
+ .srcdev-forms-extended {
2
2
  .input-checkbox-radio-wrapper {
3
3
  background-color: var(--theme-checkbox-symbol-surface);
4
4
  border: var(--form-element-border-width) solid var(--theme-input-border);
@@ -1,4 +1,4 @@
1
- .your-site-class {
1
+ .srcdev-forms-extended {
2
2
  .input-checkbox-radio-options-button {
3
3
  gap: 1rem;
4
4
  border-radius: 1lh;
@@ -1,4 +1,4 @@
1
- .your-site-class {
1
+ .srcdev-forms-extended {
2
2
  .input-error-message {
3
3
  color: var(--input-error-color);
4
4
  background-color: var(--theme-error-surface);
@@ -1,4 +1,4 @@
1
- .your-site-class {
1
+ .srcdev-forms-extended {
2
2
  .input-label {
3
3
  &.normal {
4
4
  color: var(--form-label-color);
@@ -1,4 +1,4 @@
1
- .your-site-class {
1
+ .srcdev-forms-extended {
2
2
  .input-select-wrapper {
3
3
  background-color: var(--theme-input-surface);
4
4
 
@@ -1,4 +1,4 @@
1
- .your-site-class {
1
+ .srcdev-forms-extended {
2
2
  .input-text-wrapper {
3
3
  display: flex;
4
4
  align-items: center;
@@ -1,4 +1,4 @@
1
- .your-site-class {
1
+ .srcdev-forms-extended {
2
2
  .input-textarea-wrapper {
3
3
  /* Custom placeholder styles */
4
4
  background-color: var(--theme-input-surface);
@@ -26,7 +26,7 @@ html {
26
26
  overflow-x: hidden;
27
27
  }
28
28
  body {
29
- color: var(--grayscale-text-body);
29
+ color: light-dark(var(--gray-12), var(--gray-3));
30
30
  font-family: var(--font-family);
31
31
  font-size: var(--step-4);
32
32
  min-height: 100vh;
@@ -1,12 +1,12 @@
1
1
  :root {
2
- --step-10: clamp(4.0311rem, 3.36rem + 3.3555vw, 5.9605rem); /* 10 */
3
- --step-9: clamp(3.3592rem, 2.8691rem + 2.4507vw, 4.7684rem); /* 9 */
4
- --step-8: clamp(2.7994rem, 2.4462rem + 1.7658vw, 3.8147rem); /* 8 */
5
- --step-7: clamp(2.3328rem, 2.0827rem + 1.2504vw, 3.0518rem); /* 7 */
6
- --step-6: clamp(1.944rem, 1.771rem + 0.8651vw, 2.4414rem); /* 6 */
7
- --step-5: clamp(1.62rem, 1.5041rem + 0.5793vw, 1.9531rem); /* 5 */
8
- --step-4: clamp(1.35rem, 1.2761rem + 0.3696vw, 1.5625rem); /* 4 */
9
- --step-3: clamp(1.125rem, 1.0815rem + 0.2174vw, 1.25rem); /* 3 */
10
- --step-2: clamp(0.9375rem, 0.9158rem + 0.1087vw, 1rem); /* 2 */
11
- --step-1: clamp(0.7813rem, 0.7747rem + 0.0326vw, 0.8rem); /* 1 */
2
+ --step-10: clamp(4.0311rem, 3.36rem + 3.3555vw, 5.9605rem);
3
+ --step-9: clamp(3.3592rem, 2.8691rem + 2.4507vw, 4.7684rem);
4
+ --step-8: clamp(2.7994rem, 2.4462rem + 1.7658vw, 3.8147rem);
5
+ --step-7: clamp(2.3328rem, 2.0827rem + 1.2504vw, 3.0518rem);
6
+ --step-6: clamp(1.944rem, 1.771rem + 0.8651vw, 2.4414rem);
7
+ --step-5: clamp(1.62rem, 1.5041rem + 0.5793vw, 1.9531rem);
8
+ --step-4: clamp(1.35rem, 1.2761rem + 0.3696vw, 1.5625rem);
9
+ --step-3: clamp(1.125rem, 1.0815rem + 0.2174vw, 1.25rem);
10
+ --step-2: clamp(0.9375rem, 0.9158rem + 0.1087vw, 1rem);
11
+ --step-1: clamp(0.7813rem, 0.7747rem + 0.0326vw, 0.8rem);
12
12
  }
@@ -1,2 +1 @@
1
1
  @import './_reponsive-font-sizes.css';
2
- @import './_colors.css';
@@ -1,4 +1,4 @@
1
- import type { InpuTextC12, IFormFieldC12, IFormData } from '@/types/types.forms';
1
+ import type { InpuTextC12, IFormFieldC12, IFormData } from '../../../../shared/types/types.forms';
2
2
 
3
3
  const formFieldC12 = <IFormFieldC12>{
4
4
  label: '',
@@ -62,7 +62,7 @@
62
62
 
63
63
  <script setup lang="ts">
64
64
  import propValidators from '../c12/prop-validators';
65
- import type { IOptionsConfig, IFormMultipleOptions } from '@/types/types.forms';
65
+ import type { IOptionsConfig, IFormMultipleOptions } from '../../../../shared/types/types.forms';
66
66
 
67
67
  const { dataTestid, name, legend, label, required, fieldHasError, placeholder, isButton, errorMessage, size, optionsLayout, equalCols, styleClassPassthrough, theme, direction } = defineProps({
68
68
  dataTestid: {
@@ -22,7 +22,7 @@
22
22
 
23
23
  <script setup lang="ts">
24
24
  import propValidators from '../c12/prop-validators';
25
- import type { IFormMultipleOptions } from '@/types/types.forms';
25
+ import type { IFormMultipleOptions } from '../../../../shared/types/types.forms';
26
26
 
27
27
  const props = defineProps({
28
28
  dataTestid: {
@@ -60,7 +60,7 @@
60
60
 
61
61
  <script setup lang="ts">
62
62
  import propValidators from '../c12/prop-validators';
63
- import type { IFormMultipleOptions } from '@/types/types.forms';
63
+ import type { IFormMultipleOptions } from '../../../../shared/types/types.forms';
64
64
 
65
65
  const props = defineProps({
66
66
  dataTestid: {
@@ -12,7 +12,7 @@
12
12
 
13
13
  <script setup lang="ts">
14
14
  import propValidators from '../c12/prop-validators';
15
- import type { IFormMultipleOptions } from '@/types/types.forms';
15
+ import type { IFormMultipleOptions } from '../../../../shared/types/types.forms';
16
16
 
17
17
  const props = defineProps({
18
18
  id: {
@@ -36,7 +36,7 @@
36
36
 
37
37
  <script setup lang="ts">
38
38
  import propValidators from '../../c12/prop-validators';
39
- import type { IFormMultipleOptions } from '@/types/types.forms';
39
+ import type { IFormMultipleOptions } from '../../../../../shared/types/types.forms';
40
40
 
41
41
  const props = defineProps({
42
42
  dataTestid: {
@@ -4,7 +4,14 @@
4
4
  :data-theme="formTheme"
5
5
  :data-size="size"
6
6
  :data-inputmode="inputmode"
7
- :class="[inputVariant, { dirty: isDirty }, { active: isActive }, { error: fieldHasError }, { 'has-left-slot': hasLeftSlot }, { 'has-right-slot': hasRightSlot }]"
7
+ :class="[
8
+ inputVariant,
9
+ { dirty: isDirty },
10
+ { active: isActive },
11
+ { error: fieldHasError },
12
+ { 'has-left-slot': hasLeftSlot },
13
+ { 'has-right-slot': hasRightSlot },
14
+ ]"
8
15
  >
9
16
  <span v-if="hasLeftSlot" class="slot left-slot">
10
17
  <slot name="left"></slot>
@@ -35,22 +42,21 @@
35
42
  </template>
36
43
 
37
44
  <script setup lang="ts">
38
- import propValidators from '../c12/prop-validators';
45
+ import propValidators from "../c12/prop-validators"
39
46
 
40
47
  const props = defineProps({
41
48
  type: {
42
- type: String as PropType<'text' | 'email' | 'password' | 'number' | 'tel' | 'url'>,
43
- // type: String,
44
- default: 'text',
49
+ type: String as PropType<"text" | "email" | "password" | "number" | "tel" | "url">,
50
+ default: "text",
45
51
  validator(value: string) {
46
- return propValidators.inputTypesText.includes(value);
52
+ return propValidators.inputTypesText.includes(value)
47
53
  },
48
54
  },
49
55
  inputmode: {
50
- type: String as PropType<'text' | 'email' | 'tel' | 'url' | 'search' | 'numeric' | 'none' | 'decimal'>,
51
- default: 'text',
56
+ type: String as PropType<"text" | "email" | "tel" | "url" | "search" | "numeric" | "none" | "decimal">,
57
+ default: "text",
52
58
  validator(value: string) {
53
- return propValidators.inputMode.includes(value);
59
+ return propValidators.inputMode.includes(value)
54
60
  },
55
61
  },
56
62
  maxlength: {
@@ -71,7 +77,7 @@ const props = defineProps({
71
77
  },
72
78
  placeholder: {
73
79
  type: String,
74
- default: '',
80
+ default: "",
75
81
  },
76
82
  fieldHasError: {
77
83
  type: Boolean,
@@ -83,9 +89,9 @@ const props = defineProps({
83
89
  },
84
90
  theme: {
85
91
  type: String as PropType<string>,
86
- default: 'primary',
92
+ default: "primary",
87
93
  validator(value: string) {
88
- return propValidators.theme.includes(value);
94
+ return propValidators.theme.includes(value)
89
95
  },
90
96
  },
91
97
  ariaDescribedby: {
@@ -94,66 +100,66 @@ const props = defineProps({
94
100
  },
95
101
  size: {
96
102
  type: String as PropType<string>,
97
- default: 'default',
103
+ default: "default",
98
104
  validator(value: string) {
99
- return propValidators.size.includes(value);
105
+ return propValidators.size.includes(value)
100
106
  },
101
107
  },
102
108
  inputVariant: {
103
109
  type: String as PropType<string>,
104
- default: 'normal',
110
+ default: "normal",
105
111
  validator(value: string) {
106
- return propValidators.inputVariant.includes(value);
112
+ return propValidators.inputVariant.includes(value)
107
113
  },
108
114
  },
109
- });
115
+ })
110
116
 
111
- const slots = useSlots();
112
- const hasLeftSlot = computed(() => slots.left !== undefined);
113
- const hasRightSlot = computed(() => slots.right !== undefined);
117
+ const slots = useSlots()
118
+ const hasLeftSlot = computed(() => slots.left !== undefined)
119
+ const hasRightSlot = computed(() => slots.right !== undefined)
114
120
 
115
121
  const formTheme = computed(() => {
116
- return props.fieldHasError ? 'error' : props.theme;
117
- });
122
+ return props.fieldHasError ? "error" : props.theme
123
+ })
118
124
 
119
- const modelValue = defineModel();
120
- const isDirty = defineModel('isDirty');
121
- const isActive = defineModel('isActive');
125
+ const modelValue = defineModel()
126
+ const isDirty = defineModel("isDirty")
127
+ const isActive = defineModel("isActive")
122
128
 
123
129
  const inputPattern = computed(() => {
124
- return props.inputmode === 'numeric' ? '[0-9]+' : undefined;
125
- });
130
+ return props.inputmode === "numeric" ? "[0-9]+" : undefined
131
+ })
126
132
 
127
133
  const updateFocus = (isFocused: boolean) => {
128
- isActive.value = isFocused;
129
- };
134
+ isActive.value = isFocused
135
+ }
130
136
 
131
- const inputField = ref<HTMLInputElement | null>(null);
137
+ const inputField = ref<HTMLInputElement | null>(null)
132
138
 
133
- const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
139
+ const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
134
140
 
135
141
  // TODO: Move this to a utility function to allow removeEventListener on unmounted
136
142
  // Leaving like this could lead to memory leaks
137
143
  const validateInput = () => {
138
144
  if (inputField.value !== null) {
139
- inputField.value.addEventListener('beforeinput', (event: any) => {
140
- let beforeValue = modelValue.value;
145
+ inputField.value.addEventListener("beforeinput", (event: any) => {
146
+ let beforeValue = modelValue.value
141
147
  event.target.addEventListener(
142
- 'input',
148
+ "input",
143
149
  () => {
144
150
  if (inputField.value !== null && inputField.value.validity.patternMismatch) {
145
- inputField.value.value = beforeValue as string;
151
+ inputField.value.value = beforeValue as string
146
152
  }
147
153
  },
148
154
  { once: true }
149
- );
150
- });
155
+ )
156
+ })
151
157
  }
152
- };
158
+ }
153
159
 
154
160
  onMounted(() => {
155
- if (props.inputmode === 'numeric') validateInput();
156
- });
161
+ if (props.inputmode === "numeric") validateInput()
162
+ })
157
163
  </script>
158
164
 
159
165
  <style lang="css">
@@ -197,13 +203,13 @@ onMounted(() => {
197
203
  place-items: center;
198
204
  background-clip: padding-box;
199
205
 
200
- &.left-slot:not([data-theme='input-action']) {
206
+ &.left-slot:not([data-theme="input-action"]) {
201
207
  .icon {
202
208
  width: 2.2rem;
203
209
  height: 2.2rem;
204
210
  }
205
211
 
206
- [data-theme='input-action'] {
212
+ [data-theme="input-action"] {
207
213
  width: initial;
208
214
  height: initial;
209
215
  padding: 0.5rem;
@@ -214,13 +220,13 @@ onMounted(() => {
214
220
  }
215
221
  }
216
222
  }
217
- &.right-slot:not([data-theme='input-action']) {
223
+ &.right-slot:not([data-theme="input-action"]) {
218
224
  .icon {
219
225
  width: 2.2rem;
220
226
  height: 2.2rem;
221
227
  }
222
228
 
223
- [data-theme='input-action'] {
229
+ [data-theme="input-action"] {
224
230
  width: initial;
225
231
  height: initial;
226
232
  padding: 0.5rem;
@@ -233,12 +239,12 @@ onMounted(() => {
233
239
  }
234
240
  }
235
241
 
236
- &[data-inputmode='numeric'] {
242
+ &[data-inputmode="numeric"] {
237
243
  padding-block: 0rem;
238
244
  padding-inline: 0.75rem;
239
245
 
240
246
  .slot {
241
- [data-theme='input-action'] {
247
+ [data-theme="input-action"] {
242
248
  width: initial;
243
249
  height: initial;
244
250
  padding: 0.5rem;
@@ -281,13 +287,13 @@ onMounted(() => {
281
287
  place-items: center;
282
288
  background-clip: padding-box;
283
289
 
284
- &.left-slot:not([data-theme='input-action-underlined']) {
290
+ &.left-slot:not([data-theme="input-action-underlined"]) {
285
291
  .icon {
286
292
  width: 2.2rem;
287
293
  height: 2.2rem;
288
294
  }
289
295
 
290
- [data-theme='input-action-underlined'] {
296
+ [data-theme="input-action-underlined"] {
291
297
  width: initial;
292
298
  height: initial;
293
299
  padding: 0.5rem;
@@ -298,13 +304,13 @@ onMounted(() => {
298
304
  }
299
305
  }
300
306
  }
301
- &.right-slot:not([data-theme='input-action-underlined']) {
307
+ &.right-slot:not([data-theme="input-action-underlined"]) {
302
308
  .icon {
303
309
  width: 2.2rem;
304
310
  height: 2.2rem;
305
311
  }
306
312
 
307
- [data-theme='input-action-underlined'] {
313
+ [data-theme="input-action-underlined"] {
308
314
  width: initial;
309
315
  height: initial;
310
316
  padding: 0.5rem;
@@ -1,4 +1,4 @@
1
- import type { IFormData } from '@/types/types.forms';
1
+ import type { IFormData } from '../../shared/types/types.forms';
2
2
 
3
3
  export function useErrorMessage(name: string, formData: Ref<IFormData>) {
4
4
  const defaultError = ref('');
@@ -12,7 +12,7 @@ export function useErrorMessage(name: string, formData: Ref<IFormData>) {
12
12
  console.log(`errorMessage()`);
13
13
  if (hasCustomError()) {
14
14
  console.log(`errorMessage() | IF`);
15
- return errorMessages.value[name].message;
15
+ return errorMessages.value[name]?.message;
16
16
  } else {
17
17
  return defaultError.value;
18
18
  }
@@ -1,5 +1,5 @@
1
- import type { IFormData, IFieldsInitialState, IFormFieldC12, IApiErrorMessages, ICustomErrorMessage, IErrorMessagesArr } from '@/types/types.forms';
2
- import { formFieldC12 } from '@/components/forms/c12/utils';
1
+ import type { IFormData, IFieldsInitialState, IFormFieldC12, IApiErrorMessages, ICustomErrorMessage, IErrorMessagesArr } from '../../shared/types/types.forms';
2
+ // import { formFieldC12 } from '@/components/forms/c12/utils';
3
3
 
4
4
  // export function useFormControl(name: string = '') {
5
5
  export function useFormControl(name: string = '') {
@@ -50,7 +50,13 @@ export function useFormControl(name: string = '') {
50
50
  console.log(`useFormControl | updatePreviousValues`);
51
51
 
52
52
  Object.keys(formData.value.data).forEach((key) => {
53
- formData.value.formFieldsC12[key].previousValue = formData.value.data[key];
53
+ if (formData.value.formFieldsC12[key]) {
54
+ const currentValue = formData.value.data[key];
55
+ // Filter out undefined values and IOptionsValueArr[] which are not supported by previousValue
56
+ if (currentValue !== undefined && !Array.isArray(currentValue)) {
57
+ formData.value.formFieldsC12[key].previousValue = currentValue;
58
+ }
59
+ }
54
60
  });
55
61
  };
56
62
 
@@ -86,7 +92,7 @@ export function useFormControl(name: string = '') {
86
92
  let count = 0;
87
93
 
88
94
  for (const key in obj) {
89
- if (obj.hasOwnProperty(key) && obj[key].useCustomError === true) {
95
+ if (obj.hasOwnProperty(key) && obj[key]?.useCustomError === true) {
90
96
  count++;
91
97
  }
92
98
  }
@@ -108,11 +114,11 @@ export function useFormControl(name: string = '') {
108
114
  */
109
115
  const updateErrorMessages = async (name: string, message: string = '', valid: boolean = false) => {
110
116
  if (!valid) {
111
- // formData.value.validityState[name] = valid;
112
- // formData.value.errorMessages[name] = {
113
- // useCustomError: true,
114
- // message,
115
- // };
117
+ // Ensure the form field exists before updating it
118
+ if (!formData.value.formFieldsC12[name]) {
119
+ console.warn(`Form field "${name}" not found in formFieldsC12`);
120
+ return;
121
+ }
116
122
 
117
123
  formData.value.formFieldsC12[name].useCustomError = true;
118
124
 
@@ -1,6 +1,6 @@
1
1
  import { ref, reactive, toRaw, type Ref } from 'vue';
2
2
  import { z, ZodError } from 'zod';
3
- import type { ApiErrorResponse } from '../types/types.forms';
3
+ import type { ApiErrorResponse } from '../../shared/types/types.forms';
4
4
 
5
5
  const useZodValidation = (formSchema: any, formRef: Ref<HTMLFormElement | null>) => {
6
6
  const zodFormControl = reactive({
package/nuxt.config.ts CHANGED
@@ -2,36 +2,39 @@
2
2
 
3
3
  export default defineNuxtConfig({
4
4
  devtools: { enabled: true },
5
- css: ['modern-normalize', './app/assets/styles/main.css'],
6
- modules: ['@nuxt/icon', '@nuxt/test-utils/module'],
5
+ css: ["modern-normalize", "./app/assets/styles/main.css"],
6
+ modules: ["@nuxt/eslint", "@nuxt/icon", "@nuxt/test-utils/module"],
7
+ alias: {
8
+ "#shared": "./shared",
9
+ },
7
10
  typescript: {
8
11
  tsConfig: {
9
12
  compilerOptions: {
10
- types: ['vitest/globals'], // TypeScript support for globals
13
+ types: ["vitest/globals"], // TypeScript support for globals
11
14
  },
12
15
  },
13
16
  },
14
17
  app: {
15
18
  head: {
16
19
  htmlAttrs: {
17
- lang: 'en',
18
- 'data-color-scheme': 'auto',
20
+ lang: "en",
21
+ "data-color-scheme": "auto",
19
22
  },
20
- titleTemplate: '%s - Website name',
21
- meta: [{ charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }],
23
+ titleTemplate: "%s - Website name",
24
+ meta: [{ charset: "utf-8" }, { name: "viewport", content: "width=device-width, initial-scale=1" }],
22
25
  },
23
26
  },
24
27
  components: [
25
28
  {
26
- path: './components',
29
+ path: "./components",
27
30
  pathPrefix: false,
28
31
  },
29
32
  ],
30
33
  vue: {
31
34
  runtimeCompiler: true,
32
35
  },
33
- compatibilityDate: '2024-12-01',
34
- // future: {
35
- // compatibilityVersion: 4,
36
- // },
37
- });
36
+ compatibilityDate: "2024-12-01",
37
+ future: {
38
+ compatibilityVersion: 4,
39
+ },
40
+ })
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "srcdev-nuxt-forms",
3
3
  "type": "module",
4
- "version": "6.0.0",
4
+ "version": "6.1.0",
5
5
  "main": "nuxt.config.ts",
6
6
  "scripts": {
7
7
  "clean": "rm -rf .nuxt && rm -rf .output && rm -rf .playground/.nuxt && rm -rf .playground/.output",
@@ -19,13 +19,14 @@
19
19
  },
20
20
  "files": [
21
21
  "app/",
22
+ "shared/",
22
23
  "nuxt.config.ts"
23
24
  ],
24
25
  "devDependencies": {
25
26
  "@iconify-json/carbon": "1.2.10",
26
27
  "@iconify-json/material-symbols": "1.2.29",
27
28
  "@iconify-json/material-symbols-light": "1.2.29",
28
- "@nuxt/eslint-config": "1.8.0",
29
+ "@nuxt/eslint": "1.8.0",
29
30
  "@nuxt/icon": "1.15.0",
30
31
  "@nuxt/test-utils": "3.19.2",
31
32
  "@vue/test-utils": "2.4.6",
@@ -1,4 +1,4 @@
1
- import type { IFieldsInitialState, IFormFieldsState, IFormFieldsC12, IFormFieldC12, IApiErrorMessages, ICustomErrorMessage, IErrorMessagesArr } from '@/types/types.forms';
1
+ import type { IFieldsInitialState, IFormFieldsState, IFormFieldsC12, IFormFieldC12, IApiErrorMessages, ICustomErrorMessage, IErrorMessagesArr } from './types.forms';
2
2
 
3
3
  export interface IZodeFormControl {
4
4
  [x: string]: string | boolean | number | URL | object;
@@ -1,14 +0,0 @@
1
- :root {
2
- --theme-link-default: light-dark(var(--blue-12), var(--blue-4));
3
-
4
- --page-bg: light-dark(var(--gray-0), var(--gray-9));
5
-
6
- --surface-subtle: light-dark(var(--gray-1), var(--gray-8));
7
-
8
- --grayscale-text-title: light-dark(var(--gray-12), var(--gray-2));
9
- --grayscale-text-body: light-dark(var(--gray-12), var(--gray-3));
10
- --grayscale-text-subtitle: light-dark(var(--gray-12), var(--gray-2));
11
- --grayscale-text-caption: light-dark(var(--gray-12), var(--gray-2));
12
- --grayscale-text-negative: light-dark(var(--gray-12), var(--gray-2));
13
- --grayscale-text-disabled: light-dark(var(--gray-12), var(--gray-2));
14
- }
@@ -1 +0,0 @@
1
- @import './colors';