srcdev-nuxt-forms 0.0.22 → 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.
Files changed (37) hide show
  1. package/.prettierrc +2 -1
  2. package/assets/styles/forms/themes/_error.css +12 -0
  3. package/assets/styles/forms/themes/_ghost.css +11 -0
  4. package/assets/styles/forms/themes/_primary.css +9 -1
  5. package/assets/styles/forms/themes/_secondary.css +11 -0
  6. package/assets/styles/forms/themes/_success.css +12 -0
  7. package/assets/styles/forms/themes/_tertiary.css +11 -0
  8. package/assets/styles/forms/themes/_warning.css +11 -0
  9. package/assets/styles/forms/themes/index.css +6 -0
  10. package/assets/styles/forms/variables/_theme.css +64 -1
  11. package/assets/styles/variables/colors/_orange.css +1 -1
  12. package/assets/styles/variables/colors/_red.css +1 -1
  13. package/components/forms/c12/prop-validators/index.ts +25 -0
  14. package/components/forms/c12/validation-patterns/en.json +1 -1
  15. package/components/forms/input-button/InputButtonCore.vue +367 -0
  16. package/components/forms/input-button/variants/InputButtonConfirm.vue +78 -0
  17. package/components/forms/input-button/variants/InputButtonSubmit.vue +74 -0
  18. package/components/forms/input-text/InputTextCore.vue +77 -59
  19. package/components/forms/input-text/variants/material/InputEmailMaterial.vue +72 -0
  20. package/components/forms/input-text/variants/material/InputPasswordMaterial.vue +88 -0
  21. package/components/forms/input-text/variants/material/InputTextMaterial.vue +75 -0
  22. package/components/forms/input-text/variants/material/InputTextMaterialCore.vue +258 -0
  23. package/components/forms/ui/FormField.vue +7 -2
  24. package/components/forms/ui/FormWrapper.vue +2 -2
  25. package/composables/useErrorMessages.ts +4 -4
  26. package/composables/useFormControl.ts +36 -16
  27. package/composables/useUpdateStyleClassPassthrough.ts +29 -0
  28. package/layouts/default.vue +33 -2
  29. package/nuxt.config.ts +4 -3
  30. package/package.json +3 -1
  31. package/pages/forms/examples/buttons/index.vue +154 -0
  32. package/pages/forms/examples/material/text-fields-compact.vue +136 -0
  33. package/pages/forms/examples/material/text-fields.vue +136 -0
  34. package/pages/index.vue +2 -70
  35. package/types/types.forms.ts +6 -11
  36. package/components/forms/input-text/InputTextField.vue +0 -22
  37. package/components/forms/input-text/variants/InputTextMaterial.vue +0 -159
@@ -0,0 +1,154 @@
1
+ <template>
2
+ <div>
3
+ <NuxtLayout name="default">
4
+ <template #layout-content>
5
+ <div>
6
+ <h1>Example buttons</h1>
7
+ <p>Primary submit</p>
8
+
9
+ <p>Themes switcher</p>
10
+ <ul class="flex-group">
11
+ <li>
12
+ <InputButtonSubmit @click.stop.prevent="swapTheme('primary')" :is-pending="false" button-text="Primary" theme="primary" size="normal" />
13
+ </li>
14
+ <li>
15
+ <InputButtonSubmit @click.stop.prevent="swapTheme('secondary')" :is-pending="false" button-text="Secondary" theme="secondary" size="normal" />
16
+ </li>
17
+ <li>
18
+ <InputButtonSubmit @click.stop.prevent="swapTheme('tertiary')" :is-pending="false" button-text="Tertiary" theme="tertiary" size="normal" />
19
+ </li>
20
+ <li>
21
+ <InputButtonSubmit @click.stop.prevent="swapTheme('warning')" :is-pending="false" button-text="Warning" theme="warning" size="normal" />
22
+ </li>
23
+ <li>
24
+ <InputButtonSubmit @click.stop.prevent="swapTheme('success')" :is-pending="false" button-text="Success" theme="success" size="normal" />
25
+ </li>
26
+ <li>
27
+ <InputButtonSubmit @click.stop.prevent="swapTheme('error')" :is-pending="false" button-text="Error" theme="error" size="normal" />
28
+ </li>
29
+ <li>
30
+ <InputButtonSubmit @click.stop.prevent="swapTheme('ghost')" :is-pending="false" button-text="Ghost" theme="ghost" size="normal" />
31
+ </li>
32
+ </ul>
33
+
34
+ <FormWrapper width="medium">
35
+ <template #default>
36
+ <form @submit.prevent="submitForm">
37
+ <div class="flex-group">
38
+ <InputButtonSubmit @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="x-small" />
39
+
40
+ <InputButtonSubmit @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="small" />
41
+
42
+ <InputButtonSubmit @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="normal" />
43
+ <InputButtonSubmit @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="medium" />
44
+ <InputButtonSubmit @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="large" />
45
+ </div>
46
+
47
+ <div class="flex-group">
48
+ <InputButtonConfirm @click.stop.prevent="submitForm" :is-pending="false" button-text="Confirm" :theme size="x-small" />
49
+ <InputButtonConfirm @click.stop.prevent="submitForm" :is-pending="false" button-text="Confirm" :theme size="small" />
50
+ <InputButtonConfirm @click.stop.prevent="submitForm" :is-pending="false" button-text="Confirm" :theme size="normal" />
51
+ <InputButtonConfirm @click.stop.prevent="submitForm" :is-pending="false" button-text="Confirm" :theme size="medium" />
52
+ <InputButtonConfirm @click.stop.prevent="submitForm" :is-pending="false" button-text="Confirm" :theme size="large" />
53
+ </div>
54
+ <div class="flex-group">
55
+ <InputButtonCore @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="x-small">
56
+ <template #iconOnly>
57
+ <Icon name="radix-icons:eye-none" class="icon" />
58
+ </template>
59
+ </InputButtonCore>
60
+
61
+ <InputButtonCore @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="small">
62
+ <template #iconOnly>
63
+ <Icon name="radix-icons:eye-none" class="icon" />
64
+ </template>
65
+ </InputButtonCore>
66
+
67
+ <InputButtonCore @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="normal">
68
+ <template #iconOnly>
69
+ <Icon name="radix-icons:eye-none" class="icon" />
70
+ </template>
71
+ </InputButtonCore>
72
+
73
+ <InputButtonCore @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="medium">
74
+ <template #iconOnly>
75
+ <Icon name="radix-icons:eye-none" class="icon" />
76
+ </template>
77
+ </InputButtonCore>
78
+
79
+ <InputButtonCore @click.stop.prevent="submitForm" :is-pending="false" button-text="Submit" :theme size="large">
80
+ <template #iconOnly>
81
+ <Icon name="radix-icons:eye-none" class="icon" />
82
+ </template>
83
+ </InputButtonCore>
84
+ </div>
85
+ </form>
86
+ </template>
87
+ </FormWrapper>
88
+ </div>
89
+ </template>
90
+ </NuxtLayout>
91
+ </div>
92
+ </template>
93
+
94
+ <script setup lang="ts">
95
+ import type { IFieldsInitialState, IOptionsConfig } from '@/types/types.forms';
96
+
97
+ definePageMeta({
98
+ layout: false,
99
+ });
100
+
101
+ useHead({
102
+ title: 'Homepage',
103
+ meta: [{ name: 'description', content: 'Homepage' }],
104
+ bodyAttrs: {
105
+ class: '',
106
+ },
107
+ });
108
+
109
+ const theme = ref('primary');
110
+
111
+ const swapTheme = (newTheme: string) => {
112
+ theme.value = newTheme;
113
+ };
114
+
115
+ /*
116
+ * Setup forms
117
+ */
118
+ const fieldsInitialState = ref<IFieldsInitialState>({
119
+ emailAddress: '',
120
+ username: '',
121
+ password: '',
122
+ });
123
+
124
+ // Setup formData
125
+ const { formData, getErrorCount, updateCustomErrors, resetForm, formIsValid, submitDisabled } = useFormControl(fieldsInitialState);
126
+
127
+ const submitForm = async () => {
128
+ await getErrorCount(true);
129
+
130
+ if (formIsValid.value) {
131
+ formData.value.isPending = true;
132
+ console.log('Form is good - post it!');
133
+ // await useSleep(2000);
134
+ // formData.value.isPending = false;
135
+ } else {
136
+ console.warn('Form has errors');
137
+ }
138
+ };
139
+ </script>
140
+
141
+ <style lang="css">
142
+ .flex-group {
143
+ align-items: flex-start;
144
+ display: flex;
145
+ flex-wrap: wrap;
146
+ gap: 24px;
147
+ margin-bottom: 32px;
148
+ }
149
+
150
+ ul.flex-group {
151
+ list-style-type: none;
152
+ padding: 0;
153
+ }
154
+ </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 (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
- <FormWrapper width="medium">
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">
@@ -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 IValidityStateArrShort {
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: IValidityStateArrShort;
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>