@josercl/form-maker 1.1.0-beta01 → 1.1.0-beta04

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/index.js CHANGED
@@ -2,13 +2,13 @@ import FormMakerComponent from './lib/components/FormMaker.vue';
2
2
  import FormMakerInput from './lib/components/FormMakerInput.vue';
3
3
  import CheckboxInput from './lib/components/inputs/CheckboxInput.vue';
4
4
  import FileInput from './lib/components/inputs/FileInput.vue';
5
- import FormMakerInputError from './lib/components/inputs/FormMakerInputError.vue';
6
- import FormMakerInputHelp from './lib/components/inputs/FormMakerInputHelp.vue';
7
- import FormMakerInputLabel from './lib/components/inputs/FormMakerInputLabel.vue';
5
+ import FormMakerInputError from './lib/components/texts/FormMakerInputError.vue';
6
+ import FormMakerInputHelp from './lib/components/texts/FormMakerInputHelp.vue';
7
+ import FormMakerInputLabel from './lib/components/texts/FormMakerInputLabel.vue';
8
8
  import RadioInput from './lib/components/inputs/RadioInput.vue';
9
9
  import SelectInput from './lib/components/inputs/SelectInput.vue';
10
10
  import TextAreaInput from './lib/components/inputs/TextAreaInput.vue';
11
- import TextInput from './lib/components/inputs/TextInput.vue';
11
+ import BasicInput from './lib/components/inputs/BasicInput.vue';
12
12
 
13
13
  const defaultOptions = {
14
14
  classes: {
@@ -26,19 +26,19 @@ const defaultOptions = {
26
26
  'submit-button': 'form-maker-submit',
27
27
  },
28
28
  components: {
29
- 'form-maker-input-color': TextInput,
30
- 'form-maker-input-date': TextInput,
31
- 'form-maker-input-email': TextInput,
32
- 'form-maker-input-month': TextInput,
33
- 'form-maker-input-number': TextInput,
34
- 'form-maker-input-password': TextInput,
35
- 'form-maker-input-search': TextInput,
36
- 'form-maker-input-tel': TextInput,
37
- 'form-maker-input-time': TextInput,
38
- 'form-maker-input-text': TextInput,
39
- 'form-maker-input-url': TextInput,
40
- 'form-maker-input-week': TextInput,
41
- 'form-maker-input-range': TextInput,
29
+ 'form-maker-input-color': BasicInput,
30
+ 'form-maker-input-date': BasicInput,
31
+ 'form-maker-input-email': BasicInput,
32
+ 'form-maker-input-month': BasicInput,
33
+ 'form-maker-input-number': BasicInput,
34
+ 'form-maker-input-password': BasicInput,
35
+ 'form-maker-input-search': BasicInput,
36
+ 'form-maker-input-tel': BasicInput,
37
+ 'form-maker-input-time': BasicInput,
38
+ 'form-maker-input-text': BasicInput,
39
+ 'form-maker-input-url': BasicInput,
40
+ 'form-maker-input-week': BasicInput,
41
+ 'form-maker-input-range': BasicInput,
42
42
  'form-maker-input-file': FileInput,
43
43
  'form-maker-input-textarea': TextAreaInput,
44
44
  'form-maker-input-select': SelectInput,
@@ -63,13 +63,15 @@ const FormMaker = {
63
63
  app.component('FormMaker', FormMakerComponent);
64
64
  app.component('FormMakerInput', FormMakerInput);
65
65
 
66
- Object.keys(options.classes).forEach(key => {
67
- app.provide(key, options.classes[key]);
68
- });
66
+ Object.keys(options.classes)
67
+ .forEach(key => {
68
+ app.provide(key, options.classes[key]);
69
+ });
69
70
 
70
- Object.keys(options.components).forEach(key => {
71
- app.component(key, options.components[key]);
72
- });
71
+ Object.keys(options.components)
72
+ .forEach(key => {
73
+ app.component(key, options.components[key]);
74
+ });
73
75
  },
74
76
  };
75
77
  export default FormMaker;
@@ -1,3 +1,153 @@
1
+ <script setup>
2
+ import {
3
+ computed, inject, provide, toRefs
4
+ } from 'vue';
5
+
6
+ const props = defineProps({
7
+ loading: {
8
+ type: Boolean,
9
+ default: false,
10
+ },
11
+ hasActions: {
12
+ type: Boolean,
13
+ default: true,
14
+ },
15
+ modelValue: {
16
+ type: Object,
17
+ default: () => ({}),
18
+ },
19
+ fields: {
20
+ type: Array,
21
+ default: () => [],
22
+ },
23
+ hideDivider: {
24
+ type: Boolean,
25
+ default: false,
26
+ },
27
+ rowClass: {
28
+ type: String,
29
+ default: null,
30
+ },
31
+ columnClass: {
32
+ type: String,
33
+ default: null,
34
+ },
35
+ labelClass: {
36
+ type: String,
37
+ default: null,
38
+ },
39
+ inputGroupClass: {
40
+ type: String,
41
+ default: null,
42
+ },
43
+ inputWrapperClass: {
44
+ type: String,
45
+ default: null,
46
+ },
47
+ inputErrorClass: {
48
+ type: String,
49
+ default: null,
50
+ },
51
+ inputClass: {
52
+ type: String,
53
+ default: null,
54
+ },
55
+ errorClass: {
56
+ type: String,
57
+ default: null,
58
+ },
59
+ helpTextClass: {
60
+ type: String,
61
+ default: null,
62
+ },
63
+ submitButtonClass: {
64
+ type: String,
65
+ default: null,
66
+ },
67
+ submitButtonText: {
68
+ type: String,
69
+ default: 'Submit',
70
+ },
71
+ });
72
+
73
+ const emit = defineEmits([ 'submit', 'update:modelValue' ]);
74
+
75
+ const handleSubmit = () => emit('submit');
76
+
77
+ const formFields = computed(() => {
78
+ if (props.fields.length > 0) {
79
+ return props.fields.map(row => {
80
+ let newRow = row;
81
+ if (!Array.isArray(row)) {
82
+ newRow = [ row ];
83
+ }
84
+ return newRow.map(fieldSpec => {
85
+ if (!fieldSpec.id) {
86
+ return {
87
+ ...fieldSpec,
88
+ id: `formMaker_${new Date().getTime()}_${fieldSpec.name}`,
89
+ };
90
+ }
91
+ return fieldSpec;
92
+ });
93
+ });
94
+ }
95
+
96
+ return Object.keys(props.modelValue).map(key => [
97
+ {
98
+ name: key,
99
+ label: key,
100
+ id: `formMaker_${key}`,
101
+ },
102
+ ]);
103
+ });
104
+
105
+ const {
106
+ rowClass,
107
+ columnClass,
108
+ labelClass,
109
+ inputGroupClass,
110
+ inputWrapperClass,
111
+ inputErrorClass,
112
+ inputClass,
113
+ errorClass,
114
+ helpTextClass,
115
+ submitButtonClass,
116
+ modelValue,
117
+ } = toRefs(props);
118
+
119
+ provide('labelClass', labelClass.value || inject('form-label'));
120
+ provide('inputGroupClass', inputGroupClass.value || inject('input-group'));
121
+ provide('inputWrapperClass', inputWrapperClass.value || inject('input-wrapper'));
122
+ provide('inputErrorClass', inputErrorClass.value || inject('input-error'));
123
+ provide('inputClass', inputClass.value || inject('input'));
124
+ provide('errorClass', errorClass.value || inject('error'));
125
+ provide('helpTextClass', helpTextClass.value || inject('help-text'));
126
+
127
+ const realRowClass = rowClass.value || inject('form-row');
128
+ const realColumnClass = columnClass.value || inject('form-column');
129
+ const realSubmitButtonClass = submitButtonClass.value || inject('submit-button');
130
+
131
+ const getObject = fieldName => {
132
+ const fields = fieldName.split('.');
133
+ let result = modelValue.value;
134
+ for (let i = 0; i < fields.length - 1; i += 1) {
135
+ const candidate = result[fields[i]];
136
+ if (!candidate) {
137
+ break;
138
+ }
139
+ result = candidate;
140
+ }
141
+ return result;
142
+ };
143
+
144
+ const getProp = fieldName => {
145
+ const fields = fieldName.split('.');
146
+ return fields[fields.length - 1];
147
+ };
148
+
149
+ </script>
150
+
1
151
  <template>
2
152
  <form
3
153
  class="form-maker"
@@ -16,7 +166,7 @@
16
166
  :key="`fieldRow_${i}`"
17
167
  >
18
168
  <div
19
- v-for="(field,j) in fieldRow"
169
+ v-for="(field, j) in fieldRow"
20
170
  :class="[realColumnClass, field.columnClass]"
21
171
  :key="`field_${i}_${j}`"
22
172
  >
@@ -25,14 +175,13 @@
25
175
  :name="`${field.name}`"
26
176
  >
27
177
  <form-maker-input
28
- v-model="value[field.name]"
178
+ v-model="getObject(field.name)[getProp(field.name)]"
29
179
  v-bind="field"
30
180
  />
31
181
  </slot>
32
182
  </div>
33
183
  </div>
34
184
  </slot>
35
-
36
185
  <slot name="extra" />
37
186
  <slot name="divider">
38
187
  <hr v-if="hasActions && !hideDivider">
@@ -54,148 +203,3 @@
54
203
  </slot>
55
204
  </form>
56
205
  </template>
57
-
58
- <script>
59
- import {
60
- computed, inject, provide, toRefs
61
- } from 'vue';
62
- // import setupVModel from '../utils';
63
-
64
- export default {
65
- name: 'FormMaker',
66
- emits: [ 'submit', 'update:modelValue' ],
67
- props: {
68
- loading: {
69
- type: Boolean,
70
- default: false,
71
- },
72
- hasActions: {
73
- type: Boolean,
74
- default: true,
75
- },
76
- modelValue: {
77
- type: Object,
78
- default: () => ({}),
79
- },
80
- fields: {
81
- type: Array,
82
- default: () => [],
83
- },
84
- hideDivider: {
85
- type: Boolean,
86
- default: false,
87
- },
88
- rowClass: {
89
- type: String,
90
- default: null,
91
- },
92
- columnClass: {
93
- type: String,
94
- default: null,
95
- },
96
- labelClass: {
97
- type: String,
98
- default: null,
99
- },
100
- inputGroupClass: {
101
- type: String,
102
- default: null,
103
- },
104
- inputWrapperClass: {
105
- type: String,
106
- default: null,
107
- },
108
- inputErrorClass: {
109
- type: String,
110
- default: null,
111
- },
112
- inputClass: {
113
- type: String,
114
- default: null,
115
- },
116
- errorClass: {
117
- type: String,
118
- default: null,
119
- },
120
- helpTextClass: {
121
- type: String,
122
- default: null,
123
- },
124
- submitButtonClass: {
125
- type: String,
126
- default: null,
127
- },
128
- submitButtonText: {
129
- type: String,
130
- default: 'Submit',
131
- },
132
- },
133
- setup(props, { emit }) {
134
- const handleSubmit = () => emit('submit');
135
-
136
- const formFields = computed(() => {
137
- if (props.fields.length > 0) {
138
- return props.fields.map(row => {
139
- let newRow = row;
140
- if (!Array.isArray(row)) {
141
- newRow = [ row ];
142
- }
143
- return newRow.map(fieldSpec => {
144
- if (!fieldSpec.id) {
145
- return {
146
- ...fieldSpec,
147
- id: `formMaker_${new Date().getTime()}_${fieldSpec.name}`,
148
- };
149
- }
150
- return fieldSpec;
151
- });
152
- });
153
- }
154
-
155
- return Object.keys(props.modelValue)
156
- .map(key => [
157
- {
158
- name: key,
159
- label: key,
160
- id: `formMaker_${key}`,
161
- },
162
- ]);
163
- });
164
-
165
- const {
166
- rowClass,
167
- columnClass,
168
- labelClass,
169
- inputGroupClass,
170
- inputWrapperClass,
171
- inputErrorClass,
172
- inputClass,
173
- errorClass,
174
- helpTextClass,
175
- submitButtonClass,
176
- modelValue,
177
- } = toRefs(props);
178
-
179
- provide('labelClass', labelClass.value || inject('form-label'));
180
- provide('inputGroupClass', inputGroupClass.value || inject('input-group'));
181
- provide('inputWrapperClass', inputWrapperClass.value || inject('input-wrapper'));
182
- provide('inputErrorClass', inputErrorClass.value || inject('input-error'));
183
- provide('inputClass', inputClass.value || inject('input'));
184
- provide('errorClass', errorClass.value || inject('error'));
185
- provide('helpTextClass', helpTextClass.value || inject('help-text'));
186
-
187
- const realRowClass = rowClass.value || inject('form-row');
188
- const realColumnClass = columnClass.value || inject('form-column');
189
- const realSubmitButtonClass = submitButtonClass.value || inject('submit-button');
190
-
191
- return {
192
- value: modelValue,
193
- formFields,
194
- realColumnClass,
195
- realRowClass,
196
- realSubmitButtonClass,
197
- handleSubmit,
198
- };
199
- },
200
- };
201
- </script>
@@ -1,5 +1,57 @@
1
+ <script setup>
2
+ import { ref, computed } from 'vue';
3
+ import setupVModel from '../utils';
4
+ import RuleEvaluator from './RuleEvaluator.vue';
5
+
6
+ import {
7
+ FormInputMixin,
8
+ injectFormClasses
9
+ } from './inputs/FormInputMixin';
10
+
11
+ const props = defineProps({
12
+ ...FormInputMixin.props,
13
+ rules: {
14
+ type: Array,
15
+ default: () => ([]),
16
+ },
17
+ });
18
+ const emit = defineEmits(FormInputMixin.emits);
19
+
20
+ const value = setupVModel(props, emit);
21
+
22
+ const {
23
+ labelClass,
24
+ inputClass,
25
+ inputWrapperClass,
26
+ inputGroupClass,
27
+ inputErrorClass,
28
+ errorClass,
29
+ helpTextClass,
30
+ } = injectFormClasses();
31
+
32
+ const hasLabel = computed(() => Boolean(props.label));
33
+ const hasHelpText = computed(() => Boolean(props.helpText));
34
+
35
+ const validationError = ref(null);
36
+
37
+ const hasErrors = computed(() => Boolean(props.error) || Boolean(validationError.value));
38
+
39
+ const realError = computed(() => {
40
+ if (props.error) {
41
+ return props.error;
42
+ }
43
+ return validationError.value;
44
+ });
45
+
46
+ </script>
47
+ <script>
48
+ export default {
49
+ inheritAttrs: false,
50
+ };
51
+ </script>
52
+
1
53
  <template>
2
- <div :class="[ hasErrors && inputErrorClass ]">
54
+ <div :class="[ hasErrors && inputErrorClass, inputWrapperClass ]">
3
55
  <slot
4
56
  v-if="type !== 'checkbox'"
5
57
  name="label"
@@ -8,8 +60,9 @@
8
60
  v-if="hasLabel"
9
61
  :id="id"
10
62
  :class="labelClass"
11
- :text="label"
12
- />
63
+ >
64
+ {{ label }}
65
+ </form-maker-label>
13
66
  </slot>
14
67
  <slot>
15
68
  <div :class="[inputGroupClass, hasErrors && inputErrorClass]">
@@ -28,55 +81,23 @@
28
81
  <form-maker-help
29
82
  v-if="hasHelpText"
30
83
  :class="helpTextClass"
31
- :text="helpText"
32
- />
84
+ >
85
+ {{ helpText }}
86
+ </form-maker-help>
33
87
  </slot>
34
88
  <slot name="errors">
35
89
  <form-maker-error
36
90
  v-if="hasErrors"
37
91
  :class="errorClass"
38
- :text="error"
92
+ >
93
+ {{ realError }}
94
+ </form-maker-error>
95
+ <rule-evaluator
96
+ v-if="rules.length"
97
+ :rules="rules"
98
+ :value="modelValue"
99
+ v-model="validationError"
39
100
  />
40
101
  </slot>
41
102
  </div>
42
103
  </template>
43
-
44
- <script>
45
- import setupVModel from '../utils';
46
- import { FormInputMixin, injectFormClasses, getFormInputComputeds } from './inputs/FormInputMixin';
47
-
48
- export default {
49
- name: 'FormMakerInput',
50
- mixins: [ FormInputMixin ],
51
- inheritAttrs: false,
52
- setup(props, { emit }) {
53
- const value = setupVModel(props, emit);
54
-
55
- const {
56
- labelClass,
57
- inputClass,
58
- inputWrapperClass,
59
- inputGroupClass,
60
- inputErrorClass,
61
- errorClass,
62
- helpTextClass,
63
- } = injectFormClasses();
64
-
65
- const { hasErrors, hasLabel, hasHelpText } = getFormInputComputeds(props);
66
-
67
- return {
68
- value,
69
- labelClass,
70
- inputClass,
71
- inputErrorClass,
72
- inputGroupClass,
73
- inputWrapperClass,
74
- errorClass,
75
- helpTextClass,
76
- hasErrors,
77
- hasLabel,
78
- hasHelpText,
79
- };
80
- },
81
- };
82
- </script>
@@ -0,0 +1,37 @@
1
+ <script>
2
+ import { watch } from 'vue';
3
+
4
+ export default {
5
+ emits: [ 'update:modelValue' ],
6
+ props: {
7
+ rules: {
8
+ type: Array,
9
+ default: () => ([]),
10
+ },
11
+ value: {
12
+ type: String,
13
+ required: true,
14
+ },
15
+ modelValue: {
16
+ type: String,
17
+ default: null,
18
+ },
19
+ },
20
+ setup(props, ctx) {
21
+ watch(props, newVal => {
22
+ let error = null;
23
+ for (let i = 0; i < props.rules.length; i += 1) {
24
+ const rule = props.rules[i];
25
+ const validator = rule.validator(newVal.value);
26
+ if (!validator) {
27
+ error = rule.message;
28
+ break;
29
+ }
30
+ }
31
+ ctx.emit('update:modelValue', error);
32
+ }, { immediate: true });
33
+
34
+ return {};
35
+ },
36
+ };
37
+ </script>
@@ -1,3 +1,13 @@
1
+ <script setup>
2
+ import setupVModel from '../../utils';
3
+ import { FormInputMixin } from './FormInputMixin';
4
+
5
+ const props = defineProps(FormInputMixin.props);
6
+ const emit = defineEmits(FormInputMixin.emits);
7
+
8
+ const value = setupVModel(props, emit);
9
+ </script>
10
+
1
11
  <template>
2
12
  <input
3
13
  v-model="value"
@@ -5,20 +15,3 @@
5
15
  v-bind="$props"
6
16
  >
7
17
  </template>
8
-
9
- <script>
10
- import setupVModel from '../../utils';
11
- import { FormInputMixin } from './FormInputMixin';
12
-
13
- export default {
14
- name: 'TextInput',
15
- mixins: [ FormInputMixin ],
16
- setup(props, { emit }) {
17
- const value = setupVModel(props, emit);
18
-
19
- return {
20
- value,
21
- };
22
- },
23
- };
24
- </script>
@@ -1,3 +1,52 @@
1
+ <script setup>
2
+ import { computed, toRefs } from 'vue';
3
+ import { FormInputMixin } from './FormInputMixin';
4
+
5
+ const props = defineProps({
6
+ ...FormInputMixin.props,
7
+ options: { type: Array, default: () => [] },
8
+ });
9
+ const emit = defineEmits(FormInputMixin.emits);
10
+
11
+ const { options, label } = toRefs(props);
12
+
13
+ const isBinary = computed(() => options.value.length === 0);
14
+
15
+ const val = computed(() => props.modelValue);
16
+
17
+ const selectedOptions = computed(() => {
18
+ const arr = Array.isArray(val.value) ? val.value : [ val.value ];
19
+ return arr.filter(x => !!x);
20
+ });
21
+
22
+ const fieldOptions = computed(() => {
23
+ if (!isBinary.value) {
24
+ return options.value;
25
+ }
26
+ return [
27
+ {
28
+ label: label.value,
29
+ value: true,
30
+ },
31
+ ];
32
+ });
33
+
34
+ const handleClick = clickVal => {
35
+ let selOptions = [ ...selectedOptions.value ];
36
+ if (selOptions.indexOf(clickVal) === -1) {
37
+ selOptions.push(clickVal);
38
+ } else {
39
+ selOptions = selOptions.filter(x => x !== clickVal);
40
+ }
41
+
42
+ if (isBinary.value) {
43
+ emit('update:modelValue', selOptions.length > 0);
44
+ } else {
45
+ emit('update:modelValue', selOptions);
46
+ }
47
+ };
48
+ </script>
49
+
1
50
  <template>
2
51
  <div
3
52
  v-for="(option,i) in fieldOptions"
@@ -15,66 +64,3 @@
15
64
  </label>
16
65
  </div>
17
66
  </template>
18
-
19
- <script>
20
- import { computed, toRefs } from 'vue';
21
- import { FormInputMixin } from './FormInputMixin';
22
-
23
- export default {
24
- name: 'CheckInput',
25
- mixins: [ FormInputMixin ],
26
- emits: [ 'update:modelValue' ],
27
- props: {
28
- label: {
29
- type: String,
30
- default: null,
31
- },
32
- },
33
- setup(props, { emit }) {
34
- const { options, label } = toRefs(props);
35
-
36
- const isBinary = computed(() => options.value.length === 0);
37
-
38
- const val = computed(() => props.modelValue);
39
-
40
- const selectedOptions = computed(() => {
41
- const arr = Array.isArray(val.value) ? val.value : [ val.value ];
42
- return arr.filter(x => !!x);
43
- });
44
-
45
- const fieldOptions = computed(() => {
46
- if (!isBinary.value) {
47
- return options.value;
48
- }
49
- return [
50
- {
51
- label: label.value,
52
- value: true,
53
- },
54
- ];
55
- });
56
-
57
- const handleClick = clickVal => {
58
- let selOptions = [ ...selectedOptions.value ];
59
- if (selOptions.indexOf(clickVal) === -1) {
60
- selOptions.push(clickVal);
61
- } else {
62
- selOptions = selOptions.filter(x => x !== clickVal);
63
- }
64
-
65
- if (isBinary.value) {
66
- emit('update:modelValue', selOptions.length > 0);
67
- } else {
68
- emit('update:modelValue', selOptions);
69
- }
70
- };
71
-
72
- return {
73
- fieldOptions,
74
- isBinary,
75
- selectedOptions,
76
- handleClick,
77
- };
78
- },
79
- };
80
- </script>
@@ -1,3 +1,17 @@
1
+ <script setup>
2
+ import { FormInputMixin } from './FormInputMixin';
3
+
4
+ defineProps(FormInputMixin.props);
5
+ const emit = defineEmits(FormInputMixin.emits);
6
+
7
+ const handleFileSelect = event => {
8
+ if (event.target.files.length) {
9
+ const file = event.target.files[0];
10
+ emit('update:modelValue', file);
11
+ }
12
+ };
13
+ </script>
14
+
1
15
  <template>
2
16
  <input
3
17
  v-bind="$props"
@@ -5,25 +19,3 @@
5
19
  @change="handleFileSelect"
6
20
  >
7
21
  </template>
8
-
9
- <script>
10
- import { FormInputMixin } from './FormInputMixin';
11
-
12
- export default {
13
- name: 'FileInput',
14
- mixins: [ FormInputMixin ],
15
- emits: [ 'update:modelValue' ],
16
- setup(props, { emit }) {
17
- const handleFileSelect = event => {
18
- if (event.target.files.length) {
19
- const file = event.target.files[0];
20
- emit('update:modelValue', file);
21
- }
22
- };
23
-
24
- return {
25
- handleFileSelect,
26
- };
27
- },
28
- };
29
- </script>
@@ -1,4 +1,4 @@
1
- import { computed, toRefs, inject } from 'vue';
1
+ import { inject } from 'vue';
2
2
 
3
3
  export const injectFormClasses = () => {
4
4
  const labelClass = inject('labelClass', null);
@@ -20,20 +20,6 @@ export const injectFormClasses = () => {
20
20
  };
21
21
  };
22
22
 
23
- export const getFormInputComputeds = props => {
24
- const { label, error, helpText } = toRefs(props);
25
-
26
- const hasErrors = computed(() => !!error.value);
27
- const hasLabel = computed(() => !!label.value);
28
- const hasHelpText = computed(() => !!helpText.value);
29
-
30
- return {
31
- hasErrors,
32
- hasLabel,
33
- hasHelpText,
34
- };
35
- };
36
-
37
23
  export const FormInputMixin = {
38
24
  emits: [ 'update:modelValue' ],
39
25
  props: {
@@ -47,7 +33,5 @@ export const FormInputMixin = {
47
33
  name: { type: String, default: null },
48
34
  placeholder: { type: String, default: null },
49
35
  type: { type: String, default: 'text' },
50
- options: { type: Array, default: () => [] },
51
- optionGroups: { type: Object, default: () => ({}) },
52
36
  },
53
37
  };
@@ -1,3 +1,19 @@
1
+ <script setup>
2
+ import { FormInputMixin } from './FormInputMixin';
3
+
4
+ defineProps({
5
+ ...FormInputMixin.props,
6
+ options: {
7
+ type: Array,
8
+ default: () => [],
9
+ },
10
+ });
11
+
12
+ const emit = defineEmits(FormInputMixin.emits);
13
+
14
+ const handleClick = e => emit('update:modelValue', e.target.value);
15
+ </script>
16
+
1
17
  <template>
2
18
  <div
3
19
  v-for="(option, i) in options"
@@ -15,26 +31,3 @@
15
31
  </label>
16
32
  </div>
17
33
  </template>
18
-
19
- <script>
20
- import { FormInputMixin } from './FormInputMixin';
21
-
22
- export default {
23
- name: 'RadioInput',
24
- emits: [ 'update:modelValue' ],
25
- mixins: [ FormInputMixin ],
26
- props: {
27
- label: {
28
- type: String,
29
- default: null,
30
- },
31
- },
32
- setup(props, { emit }) {
33
- const handleClick = e => emit('update:modelValue', e.target.value);
34
-
35
- return {
36
- handleClick,
37
- };
38
- },
39
- };
40
- </script>
@@ -1,3 +1,37 @@
1
+ <script setup>
2
+ import { computed } from 'vue';
3
+ import { FormInputMixin } from './FormInputMixin';
4
+ import setupVModel from '../../utils';
5
+
6
+ const props = defineProps({
7
+ ...FormInputMixin.props,
8
+ options: {
9
+ type: Array,
10
+ default: () => [],
11
+ },
12
+ optionGroups: {
13
+ type: Object,
14
+ default: () => ({}),
15
+ },
16
+ });
17
+
18
+ const emit = defineEmits(FormInputMixin.emits);
19
+
20
+ const value = setupVModel(props, emit);
21
+
22
+ const hasGroups = Object.keys(props.optionGroups).length > 0;
23
+
24
+ const fixedOptions = computed(() => props.options.map(o => {
25
+ if (typeof o === 'object') {
26
+ return o;
27
+ }
28
+ return {
29
+ label: o,
30
+ value: o,
31
+ };
32
+ }));
33
+ </script>
34
+
1
35
  <template>
2
36
  <select
3
37
  :id="id"
@@ -22,7 +56,7 @@
22
56
  </optgroup>
23
57
  </template>
24
58
  <option
25
- v-for="(option,i) in options"
59
+ v-for="(option,i) in fixedOptions"
26
60
  v-else
27
61
  :key="`option_${i}`"
28
62
  :value="option.value"
@@ -31,23 +65,3 @@
31
65
  </option>
32
66
  </select>
33
67
  </template>
34
-
35
- <script>
36
- import setupVModel from '../../utils';
37
- import { FormInputMixin } from './FormInputMixin';
38
-
39
- export default {
40
- name: 'SelectInput',
41
- mixins: [ FormInputMixin ],
42
- setup(props, { emit }) {
43
- const value = setupVModel(props, emit);
44
-
45
- const hasGroups = Object.keys(props.optionGroups).length > 0;
46
-
47
- return {
48
- value,
49
- hasGroups,
50
- };
51
- },
52
- };
53
- </script>
@@ -1,3 +1,13 @@
1
+ <script setup>
2
+ import setupVModel from '../../utils';
3
+ import { FormInputMixin } from './FormInputMixin';
4
+
5
+ const props = defineProps(FormInputMixin.props);
6
+ const emit = defineEmits(FormInputMixin.emits);
7
+
8
+ const value = setupVModel(props, emit);
9
+ </script>
10
+
1
11
  <template>
2
12
  <textarea
3
13
  :id="id"
@@ -7,20 +17,3 @@
7
17
  :placeholder="placeholder"
8
18
  />
9
19
  </template>
10
-
11
- <script>
12
- import setupVModel from '../../utils';
13
- import { FormInputMixin } from './FormInputMixin';
14
-
15
- export default {
16
- name: 'TextAreaInput',
17
- mixins: [ FormInputMixin ],
18
- setup(props, { emit }) {
19
- const value = setupVModel(props, emit);
20
-
21
- return {
22
- value,
23
- };
24
- },
25
- };
26
- </script>
@@ -0,0 +1,5 @@
1
+ <script>
2
+ import { simpleComponent } from '../../utils';
3
+
4
+ export default simpleComponent();
5
+ </script>
@@ -0,0 +1,5 @@
1
+ <script>
2
+ import { simpleComponent } from '../../utils';
3
+
4
+ export default simpleComponent();
5
+ </script>
@@ -0,0 +1,15 @@
1
+ <script>
2
+ import { h } from 'vue';
3
+
4
+ export default {
5
+ props: {
6
+ id: {
7
+ type: String,
8
+ default: null,
9
+ },
10
+ },
11
+ setup(props, { slots, attrs }) {
12
+ return () => h('label', { ...attrs, for: props.id }, slots.default());
13
+ },
14
+ };
15
+ </script>
package/lib/utils.js CHANGED
@@ -1,4 +1,4 @@
1
- import { computed } from 'vue';
1
+ import { computed, h } from 'vue';
2
2
 
3
3
  const setupVModel = (props, emit, propName = 'modelValue') => computed({
4
4
  get: () => props[propName],
@@ -6,3 +6,9 @@ const setupVModel = (props, emit, propName = 'modelValue') => computed({
6
6
  });
7
7
 
8
8
  export default setupVModel;
9
+
10
+ export const simpleComponent = () => ({
11
+ setup(props, { slots, attrs }) {
12
+ return () => h('div', attrs, slots.default());
13
+ },
14
+ });
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "@josercl/form-maker",
3
- "version": "1.1.0-beta01",
3
+ "version": "1.1.0-beta04",
4
4
  "description": "Form generator using vue 3",
5
5
  "author": "Jose Carrero <josercl@gmail.com>",
6
6
  "scripts": {
7
- "dev": "vite -c docs.config.js dev",
7
+ "docs": "vite -c docs.config.js dev --port 9090",
8
+ "dev": "vite -c dev.config.js dev",
8
9
  "build": "vite build",
9
10
  "build-docs": "vite -c docs.config.js build",
10
11
  "preview": "vite -c docs.config.js preview --port 5050",
11
- "lint": "eslint --ext .vue,.js lib/ docs/ index.js"
12
+ "lint": "eslint --ext .vue,.js lib/ docs/ dev/ index.js --fix"
12
13
  },
13
14
  "files": [
14
15
  "index.js",
@@ -26,13 +27,16 @@
26
27
  "@fortawesome/free-brands-svg-icons": "^5.15.1",
27
28
  "@fortawesome/free-regular-svg-icons": "^5.15.1",
28
29
  "@fortawesome/vue-fontawesome": "^3.0.0-2",
29
- "@tailwindcss/typography": "^0.2.0",
30
+ "@tailwindcss/forms": "^0.4.0",
31
+ "@tailwindcss/typography": "^0.5.2",
30
32
  "@vitejs/plugin-vue": "^2.2.2",
31
33
  "@vue/eslint-config-airbnb": "^6.0.0",
34
+ "autoprefixer": "^10.4.2",
32
35
  "eslint": "^8.10.0",
33
36
  "eslint-plugin-vue": "^8.5.0",
34
37
  "highlight.js": "^10.2.1",
35
- "tailwindcss": "^1.9.6",
38
+ "postcss": "^8.4.7",
39
+ "tailwindcss": "^3.0.23",
36
40
  "vite": "^2.8.4",
37
41
  "vue-router": "^4.0.12"
38
42
  },
package/umd/index.umd.js CHANGED
@@ -1 +1 @@
1
- var $e=Object.defineProperty,Se=Object.defineProperties;var Ee=Object.getOwnPropertyDescriptors;var S=Object.getOwnPropertySymbols;var Ve=Object.prototype.hasOwnProperty,Fe=Object.prototype.propertyIsEnumerable;var E=(e,a,f)=>a in e?$e(e,a,{enumerable:!0,configurable:!0,writable:!0,value:f}):e[a]=f,k=(e,a)=>{for(var f in a||(a={}))Ve.call(a,f)&&E(e,f,a[f]);if(S)for(var f of S(a))Fe.call(a,f)&&E(e,f,a[f]);return e},V=(e,a)=>Se(e,Ee(a));(function(e,a){typeof exports=="object"&&typeof module!="undefined"?module.exports=a(require("vue")):typeof define=="function"&&define.amd?define(["vue"],a):(e=typeof globalThis!="undefined"?globalThis:e||self,e.FormMaker=a(e.Vue))})(this,function(e){"use strict";var a=(t,r)=>{const n=t.__vccOpts||t;for(const[l,s]of r)n[l]=s;return n};const f={name:"FormMaker",emits:["submit","update:modelValue"],props:{loading:{type:Boolean,default:!1},hasActions:{type:Boolean,default:!0},modelValue:{type:Object,default:()=>({})},fields:{type:Array,default:()=>[]},hideDivider:{type:Boolean,default:!1},rowClass:{type:String,default:null},columnClass:{type:String,default:null},labelClass:{type:String,default:null},inputGroupClass:{type:String,default:null},inputWrapperClass:{type:String,default:null},inputErrorClass:{type:String,default:null},inputClass:{type:String,default:null},errorClass:{type:String,default:null},helpTextClass:{type:String,default:null},submitButtonClass:{type:String,default:null},submitButtonText:{type:String,default:"Submit"}},setup(t,{emit:r}){const n=()=>r("submit"),l=e.computed(()=>t.fields.length>0?t.fields.map(b=>{let $=b;return Array.isArray(b)||($=[b]),$.map(g=>g.id?g:V(k({},g),{id:`formMaker_${new Date().getTime()}_${g.name}`}))}):Object.keys(t.modelValue).map(b=>[{name:b,label:b,id:`formMaker_${b}`}])),{rowClass:s,columnClass:i,labelClass:o,inputGroupClass:m,inputWrapperClass:u,inputErrorClass:p,inputClass:c,errorClass:h,helpTextClass:B,submitButtonClass:be,modelValue:ye}=e.toRefs(t);e.provide("labelClass",o.value||e.inject("form-label")),e.provide("inputGroupClass",m.value||e.inject("input-group")),e.provide("inputWrapperClass",u.value||e.inject("input-wrapper")),e.provide("inputErrorClass",p.value||e.inject("input-error")),e.provide("inputClass",c.value||e.inject("input")),e.provide("errorClass",h.value||e.inject("error")),e.provide("helpTextClass",B.value||e.inject("help-text"));const ge=s.value||e.inject("form-row"),Be=i.value||e.inject("form-column"),_e=be.value||e.inject("submit-button");return{value:ye,formFields:l,realColumnClass:Be,realRowClass:ge,realSubmitButtonClass:_e,handleSubmit:n}}},F=e.createTextVNode(" Loading... "),x={key:0},T=["disabled"];function j(t,r,n,l,s,i){const o=e.resolveComponent("form-maker-input");return e.openBlock(),e.createElementBlock("form",{class:"form-maker",onSubmit:r[0]||(r[0]=e.withModifiers((...m)=>l.handleSubmit&&l.handleSubmit(...m),["prevent"]))},[n.loading?e.renderSlot(t.$slots,"loading",{key:0},()=>[F]):e.createCommentVNode("",!0),e.renderSlot(t.$slots,"default",{},()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(l.formFields,(m,u)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(l.realRowClass),key:`fieldRow_${u}`},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(m,(p,c)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass([l.realColumnClass,p.columnClass]),key:`field_${u}_${c}`},[e.renderSlot(t.$slots,`${p.name}`,{field:p},()=>[e.createVNode(o,e.mergeProps({modelValue:l.value[p.name],"onUpdate:modelValue":h=>l.value[p.name]=h},p),null,16,["modelValue","onUpdate:modelValue"])])],2))),128))],2))),128))]),e.renderSlot(t.$slots,"extra"),e.renderSlot(t.$slots,"divider",{},()=>[n.hasActions&&!n.hideDivider?(e.openBlock(),e.createElementBlock("hr",x)):e.createCommentVNode("",!0)]),n.hasActions?e.renderSlot(t.$slots,"actions",{key:1},()=>[e.renderSlot(t.$slots,"submit-button",{},()=>[e.createElementVNode("button",{class:e.normalizeClass(l.realSubmitButtonClass),disabled:n.loading,type:"submit"},e.toDisplayString(n.submitButtonText),11,T)]),e.renderSlot(t.$slots,"extra-buttons")]):e.createCommentVNode("",!0)],32)}var I=a(f,[["render",j]]);const y=(t,r,n="modelValue")=>e.computed({get:()=>t[n],set:l=>r(`update:${n}`,l)}),M=()=>{const t=e.inject("labelClass",null),r=e.inject("inputClass",null),n=e.inject("inputWrapperClass",null),l=e.inject("inputGroupClass",null),s=e.inject("inputErrorClass",null),i=e.inject("errorClass",null),o=e.inject("helpTextClass",null);return{labelClass:t,inputClass:r,inputWrapperClass:n,inputGroupClass:l,inputErrorClass:s,errorClass:i,helpTextClass:o}},w=t=>{const{label:r,error:n,helpText:l}=e.toRefs(t),s=e.computed(()=>!!n.value),i=e.computed(()=>!!r.value),o=e.computed(()=>!!l.value);return{hasErrors:s,hasLabel:i,hasHelpText:o}},C={emits:["update:modelValue"],props:{loading:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},modelValue:{default:null},error:{type:String,default:null},helpText:{type:String,default:null},id:{type:String,default:null},label:{type:String,default:null},name:{type:String,default:null},placeholder:{type:String,default:null},type:{type:String,default:"text"},options:{type:Array,default:()=>[]},optionGroups:{type:Object,default:()=>({})}}},D={name:"FormMakerInput",mixins:[C],inheritAttrs:!1,setup(t,{emit:r}){const n=y(t,r),{labelClass:l,inputClass:s,inputWrapperClass:i,inputGroupClass:o,inputErrorClass:m,errorClass:u,helpTextClass:p}=M(),{hasErrors:c,hasLabel:h,hasHelpText:B}=w(t);return{value:n,labelClass:l,inputClass:s,inputErrorClass:m,inputGroupClass:o,inputWrapperClass:i,errorClass:u,helpTextClass:p,hasErrors:c,hasLabel:h,hasHelpText:B}}};function N(t,r,n,l,s,i){const o=e.resolveComponent("form-maker-label"),m=e.resolveComponent("form-maker-help"),u=e.resolveComponent("form-maker-error");return e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass([l.hasErrors&&l.inputErrorClass])},[t.type!=="checkbox"?e.renderSlot(t.$slots,"label",{key:0},()=>[l.hasLabel?(e.openBlock(),e.createBlock(o,{key:0,id:t.id,class:e.normalizeClass(l.labelClass),text:t.label},null,8,["id","class","text"])):e.createCommentVNode("",!0)]):e.createCommentVNode("",!0),e.renderSlot(t.$slots,"default",{},()=>[e.createElementVNode("div",{class:e.normalizeClass([l.inputGroupClass,l.hasErrors&&l.inputErrorClass])},[e.renderSlot(t.$slots,"before"),(e.openBlock(),e.createBlock(e.resolveDynamicComponent(`form-maker-input-${t.type}`),e.mergeProps({modelValue:l.value,"onUpdate:modelValue":r[0]||(r[0]=p=>l.value=p)},k(k({},t.$props),t.$attrs),{class:[t.type!=="checkbox"&&l.inputClass,l.hasErrors&&l.inputErrorClass],label:t.label}),null,16,["modelValue","class","label"])),e.renderSlot(t.$slots,"after")],2)]),e.renderSlot(t.$slots,"help",{},()=>[l.hasHelpText?(e.openBlock(),e.createBlock(m,{key:0,class:e.normalizeClass(l.helpTextClass),text:t.helpText},null,8,["class","text"])):e.createCommentVNode("",!0)]),e.renderSlot(t.$slots,"errors",{},()=>[l.hasErrors?(e.openBlock(),e.createBlock(u,{key:0,class:e.normalizeClass(l.errorClass),text:t.error},null,8,["class","text"])):e.createCommentVNode("",!0)])],2)}var O=a(D,[["render",N]]);const G={name:"CheckInput",mixins:[C],emits:["update:modelValue"],props:{label:{type:String,default:null}},setup(t,{emit:r}){const{options:n,label:l}=e.toRefs(t),s=e.computed(()=>n.value.length===0),i=e.computed(()=>t.modelValue),o=e.computed(()=>(Array.isArray(i.value)?i.value:[i.value]).filter(c=>!!c));return{fieldOptions:e.computed(()=>s.value?[{label:l.value,value:!0}]:n.value),isBinary:s,selectedOptions:o,handleClick:p=>{let c=[...o.value];c.indexOf(p)===-1?c.push(p):c=c.filter(h=>h!==p),s.value?r("update:modelValue",c.length>0):r("update:modelValue",c)}}}},L=["checked","value","onClick"];function A(t,r,n,l,s,i){return e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(l.fieldOptions,(o,m)=>(e.openBlock(),e.createElementBlock("div",{key:`option_${m}`},[e.createElementVNode("label",null,[e.createElementVNode("input",e.mergeProps(t.$props,{checked:l.selectedOptions.indexOf(o.value)!==-1,value:o.value,type:"checkbox",onClick:()=>l.handleClick(o.value)}),null,16,L),e.createTextVNode(" "+e.toDisplayString(o.label),1)])]))),128)}var R=a(G,[["render",A]]);const z={name:"FileInput",mixins:[C],emits:["update:modelValue"],setup(t,{emit:r}){return{handleFileSelect:l=>{if(l.target.files.length){const s=l.target.files[0];r("update:modelValue",s)}}}}};function P(t,r,n,l,s,i){return e.openBlock(),e.createElementBlock("input",e.mergeProps(t.$props,{type:"file",onChange:r[0]||(r[0]=(...o)=>l.handleFileSelect&&l.handleFileSelect(...o))}),null,16)}var U=a(z,[["render",P]]);const W={name:"FormMakerInputError",props:{text:{type:String,default:null}}};function H(t,r,n,l,s,i){return e.openBlock(),e.createElementBlock("div",null,e.toDisplayString(n.text),1)}var q=a(W,[["render",H]]);const J={name:"FormMakerInputHelp",props:{text:{type:String,default:null}}};function K(t,r,n,l,s,i){return e.openBlock(),e.createElementBlock("div",null,e.toDisplayString(n.text),1)}var Q=a(J,[["render",K]]);const X={name:"FormMakerInputLabel",props:{text:{type:String,default:null},id:{type:String,default:null}}},Y=["for"];function Z(t,r,n,l,s,i){return e.openBlock(),e.createElementBlock("label",{for:n.id},e.toDisplayString(n.text),9,Y)}var v=a(X,[["render",Z]]);const ee={name:"RadioInput",emits:["update:modelValue"],mixins:[C],props:{label:{type:String,default:null}},setup(t,{emit:r}){return{handleClick:l=>r("update:modelValue",l.target.value)}}},te=["checked","value"];function le(t,r,n,l,s,i){return e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.options,(o,m)=>(e.openBlock(),e.createElementBlock("div",{key:`option_${m}`},[e.createElementVNode("label",null,[e.createElementVNode("input",e.mergeProps(t.$props,{checked:o.value===t.modelValue,value:o.value,type:"radio",onChange:r[0]||(r[0]=(...u)=>l.handleClick&&l.handleClick(...u))}),null,16,te),e.createTextVNode(" "+e.toDisplayString(o.label),1)])]))),128)}var re=a(ee,[["render",le]]);const ne={name:"SelectInput",mixins:[C],setup(t,{emit:r}){const n=y(t,r),l=Object.keys(t.optionGroups).length>0;return{value:n,hasGroups:l}}},oe=["id","disabled","name","placeholder"],ae=["label"],se=["value"],ie=["value"];function pe(t,r,n,l,s,i){return e.withDirectives((e.openBlock(),e.createElementBlock("select",{id:t.id,"onUpdate:modelValue":r[0]||(r[0]=o=>l.value=o),disabled:t.disabled,name:t.name,placeholder:t.placeholder},[l.hasGroups?(e.openBlock(!0),e.createElementBlock(e.Fragment,{key:0},e.renderList(t.optionGroups,(o,m)=>(e.openBlock(),e.createElementBlock("optgroup",{key:`optGroup_${m}`,label:m},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(o,(u,p)=>(e.openBlock(),e.createElementBlock("option",{key:`option_${p}`,value:p},e.toDisplayString(u),9,se))),128))],8,ae))),128)):(e.openBlock(!0),e.createElementBlock(e.Fragment,{key:1},e.renderList(t.options,(o,m)=>(e.openBlock(),e.createElementBlock("option",{key:`option_${m}`,value:o.value},e.toDisplayString(o.label),9,ie))),128))],8,oe)),[[e.vModelSelect,l.value]])}var me=a(ne,[["render",pe]]);const ce={name:"TextAreaInput",mixins:[C],setup(t,{emit:r}){return{value:y(t,r)}}},de=["id","disabled","name","placeholder"];function ue(t,r,n,l,s,i){return e.withDirectives((e.openBlock(),e.createElementBlock("textarea",{id:t.id,"onUpdate:modelValue":r[0]||(r[0]=o=>l.value=o),disabled:t.disabled,name:t.name,placeholder:t.placeholder},null,8,de)),[[e.vModelText,l.value]])}var fe=a(ce,[["render",ue]]);const ke={name:"TextInput",mixins:[C],setup(t,{emit:r}){return{value:y(t,r)}}},Ce=["type"];function he(t,r,n,l,s,i){return e.withDirectives((e.openBlock(),e.createElementBlock("input",e.mergeProps({"onUpdate:modelValue":r[0]||(r[0]=o=>l.value=o),type:t.type},t.$props),null,16,Ce)),[[e.vModelDynamic,l.value]])}var d=a(ke,[["render",he]]);const _={classes:{"form-row":"form-maker-row","form-column":"form-maker-column","form-label":"form-maker-label","input-group":"form-maker-input-group","input-wrapper":"form-maker-input-wrapper","input-error":"form-maker-input-error",input:"form-maker-input",error:"form-maker-error","help-text":"form-maker-help-text","submit-button":"form-maker-submit"},components:{"form-maker-input-color":d,"form-maker-input-date":d,"form-maker-input-email":d,"form-maker-input-month":d,"form-maker-input-number":d,"form-maker-input-password":d,"form-maker-input-search":d,"form-maker-input-tel":d,"form-maker-input-time":d,"form-maker-input-text":d,"form-maker-input-url":d,"form-maker-input-week":d,"form-maker-input-range":d,"form-maker-input-file":U,"form-maker-input-textarea":fe,"form-maker-input-select":me,"form-maker-input-checkbox":R,"form-maker-input-radio":re,"form-maker-label":v,"form-maker-help":Q,"form-maker-error":q}};return{install:(t,r={})=>{const n={classes:k(k({},_.classes),r.classes),components:k(k({},_.components),r.components)};t.component("FormMaker",I),t.component("FormMakerInput",O),Object.keys(n.classes).forEach(l=>{t.provide(l,n.classes[l])}),Object.keys(n.components).forEach(l=>{t.component(l,n.components[l])})}}});
1
+ var pe=Object.defineProperty,me=Object.defineProperties;var ce=Object.getOwnPropertyDescriptors;var x=Object.getOwnPropertySymbols;var de=Object.prototype.hasOwnProperty,ue=Object.prototype.propertyIsEnumerable;var L=(e,p,h)=>p in e?pe(e,p,{enumerable:!0,configurable:!0,writable:!0,value:h}):e[p]=h,k=(e,p)=>{for(var h in p||(p={}))de.call(p,h)&&L(e,h,p[h]);if(x)for(var h of x(p))ue.call(p,h)&&L(e,h,p[h]);return e},E=(e,p)=>me(e,ce(p));(function(e,p){typeof exports=="object"&&typeof module!="undefined"?module.exports=p(require("vue")):typeof define=="function"&&define.amd?define(["vue"],p):(e=typeof globalThis!="undefined"?globalThis:e||self,e.FormMaker=p(e.Vue))})(this,function(e){"use strict";const p=["onSubmit"],h=e.createTextVNode(" Loading... "),R={key:0},z=["disabled"],P={props:{loading:{type:Boolean,default:!1},hasActions:{type:Boolean,default:!0},modelValue:{type:Object,default:()=>({})},fields:{type:Array,default:()=>[]},hideDivider:{type:Boolean,default:!1},rowClass:{type:String,default:null},columnClass:{type:String,default:null},labelClass:{type:String,default:null},inputGroupClass:{type:String,default:null},inputWrapperClass:{type:String,default:null},inputErrorClass:{type:String,default:null},inputClass:{type:String,default:null},errorClass:{type:String,default:null},helpTextClass:{type:String,default:null},submitButtonClass:{type:String,default:null},submitButtonText:{type:String,default:"Submit"}},emits:["submit","update:modelValue"],setup(r,{emit:o}){const l=r,t=()=>o("submit"),a=e.computed(()=>l.fields.length>0?l.fields.map(s=>{let $=s;return Array.isArray(s)||($=[s]),$.map(g=>g.id?g:E(k({},g),{id:`formMaker_${new Date().getTime()}_${g.name}`}))}):Object.keys(l.modelValue).map(s=>[{name:s,label:s,id:`formMaker_${s}`}])),{rowClass:i,columnClass:n,labelClass:B,inputGroupClass:u,inputWrapperClass:C,inputErrorClass:y,inputClass:c,errorClass:b,helpTextClass:V,submitButtonClass:_,modelValue:A}=e.toRefs(l);e.provide("labelClass",B.value||e.inject("form-label")),e.provide("inputGroupClass",u.value||e.inject("input-group")),e.provide("inputWrapperClass",C.value||e.inject("input-wrapper")),e.provide("inputErrorClass",y.value||e.inject("input-error")),e.provide("inputClass",c.value||e.inject("input")),e.provide("errorClass",b.value||e.inject("error")),e.provide("helpTextClass",V.value||e.inject("help-text"));const m=i.value||e.inject("form-row"),j=n.value||e.inject("form-column"),O=_.value||e.inject("submit-button"),D=s=>{const $=s.split(".");let g=A.value;for(let T=0;T<$.length-1;T+=1){const w=g[$[T]];if(!w)break;g=w}return g},F=s=>{const $=s.split(".");return $[$.length-1]};return(s,$)=>{const g=e.resolveComponent("form-maker-input");return e.openBlock(),e.createElementBlock("form",{class:"form-maker",onSubmit:e.withModifiers(t,["prevent"])},[r.loading?e.renderSlot(s.$slots,"loading",{key:0},()=>[h]):e.createCommentVNode("",!0),e.renderSlot(s.$slots,"default",{},()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(a),(T,w)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(e.unref(m)),key:`fieldRow_${w}`},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(T,(S,se)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass([e.unref(j),S.columnClass]),key:`field_${w}_${se}`},[e.renderSlot(s.$slots,`${S.name}`,{field:S},()=>[e.createVNode(g,e.mergeProps({modelValue:D(S.name)[F(S.name)],"onUpdate:modelValue":ie=>D(S.name)[F(S.name)]=ie},S),null,16,["modelValue","onUpdate:modelValue"])])],2))),128))],2))),128))]),e.renderSlot(s.$slots,"extra"),e.renderSlot(s.$slots,"divider",{},()=>[r.hasActions&&!r.hideDivider?(e.openBlock(),e.createElementBlock("hr",R)):e.createCommentVNode("",!0)]),r.hasActions?e.renderSlot(s.$slots,"actions",{key:1},()=>[e.renderSlot(s.$slots,"submit-button",{},()=>[e.createElementVNode("button",{class:e.normalizeClass(e.unref(O)),disabled:r.loading,type:"submit"},e.toDisplayString(r.submitButtonText),11,z)]),e.renderSlot(s.$slots,"extra-buttons")]):e.createCommentVNode("",!0)],40,p)}}},N=(r,o,l="modelValue")=>e.computed({get:()=>r[l],set:t=>o(`update:${l}`,t)}),M=()=>({setup(r,{slots:o,attrs:l}){return()=>e.h("div",l,o.default())}}),U={emits:["update:modelValue"],props:{rules:{type:Array,default:()=>[]},value:{type:String,required:!0},modelValue:{type:String,default:null}},setup(r,o){return e.watch(r,l=>{let t=null;for(let a=0;a<r.rules.length;a+=1){const i=r.rules[a];if(!i.validator(l.value)){t=i.message;break}}o.emit("update:modelValue",t)},{immediate:!0}),{}}},W=()=>{const r=e.inject("labelClass",null),o=e.inject("inputClass",null),l=e.inject("inputWrapperClass",null),t=e.inject("inputGroupClass",null),a=e.inject("inputErrorClass",null),i=e.inject("errorClass",null),n=e.inject("helpTextClass",null);return{labelClass:r,inputClass:o,inputWrapperClass:l,inputGroupClass:t,inputErrorClass:a,errorClass:i,helpTextClass:n}},d={emits:["update:modelValue"],props:{loading:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},modelValue:{default:null},error:{type:String,default:null},helpText:{type:String,default:null},id:{type:String,default:null},label:{type:String,default:null},name:{type:String,default:null},placeholder:{type:String,default:null},type:{type:String,default:"text"}}},q=Object.assign({inheritAttrs:!1},{props:E(k({},d.props),{rules:{type:Array,default:()=>[]}}),emits:d.emits,setup(r,{emit:o}){const l=r,t=N(l,o),{labelClass:a,inputClass:i,inputWrapperClass:n,inputGroupClass:B,inputErrorClass:u,errorClass:C,helpTextClass:y}=W(),c=e.computed(()=>Boolean(l.label)),b=e.computed(()=>Boolean(l.helpText)),V=e.ref(null),_=e.computed(()=>Boolean(l.error)||Boolean(V.value)),A=e.computed(()=>l.error?l.error:V.value);return(m,j)=>{const O=e.resolveComponent("form-maker-label"),D=e.resolveComponent("form-maker-help"),F=e.resolveComponent("form-maker-error");return e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass([e.unref(_)&&e.unref(u),e.unref(n)])},[m.type!=="checkbox"?e.renderSlot(m.$slots,"label",{key:0},()=>[e.unref(c)?(e.openBlock(),e.createBlock(O,{key:0,id:m.id,class:e.normalizeClass(e.unref(a))},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(m.label),1)]),_:1},8,["id","class"])):e.createCommentVNode("",!0)]):e.createCommentVNode("",!0),e.renderSlot(m.$slots,"default",{},()=>[e.createElementVNode("div",{class:e.normalizeClass([e.unref(B),e.unref(_)&&e.unref(u)])},[e.renderSlot(m.$slots,"before"),(e.openBlock(),e.createBlock(e.resolveDynamicComponent(`form-maker-input-${m.type}`),e.mergeProps({modelValue:e.unref(t),"onUpdate:modelValue":j[0]||(j[0]=s=>e.isRef(t)?t.value=s:null)},k(k({},m.$props),m.$attrs),{class:[m.type!=="checkbox"&&e.unref(i),e.unref(_)&&e.unref(u)],label:m.label}),null,16,["modelValue","class","label"])),e.renderSlot(m.$slots,"after")],2)]),e.renderSlot(m.$slots,"help",{},()=>[e.unref(b)?(e.openBlock(),e.createBlock(D,{key:0,class:e.normalizeClass(e.unref(y))},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(m.helpText),1)]),_:1},8,["class"])):e.createCommentVNode("",!0)]),e.renderSlot(m.$slots,"errors",{},()=>[e.unref(_)?(e.openBlock(),e.createBlock(F,{key:0,class:e.normalizeClass(e.unref(C))},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(e.unref(A)),1)]),_:1},8,["class"])):e.createCommentVNode("",!0),r.rules.length?(e.openBlock(),e.createBlock(U,{key:1,rules:r.rules,value:m.modelValue,modelValue:V.value,"onUpdate:modelValue":j[1]||(j[1]=s=>V.value=s)},null,8,["rules","value","modelValue"])):e.createCommentVNode("",!0)])],2)}}}),I=["checked","value","onClick"],H={props:E(k({},d.props),{options:{type:Array,default:()=>[]}}),emits:d.emits,setup(r,{emit:o}){const l=r,{options:t,label:a}=e.toRefs(l),i=e.computed(()=>t.value.length===0),n=e.computed(()=>l.modelValue),B=e.computed(()=>(Array.isArray(n.value)?n.value:[n.value]).filter(c=>!!c)),u=e.computed(()=>i.value?[{label:a.value,value:!0}]:t.value),C=y=>{let c=[...B.value];c.indexOf(y)===-1?c.push(y):c=c.filter(b=>b!==y),i.value?o("update:modelValue",c.length>0):o("update:modelValue",c)};return(y,c)=>(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(u),(b,V)=>(e.openBlock(),e.createElementBlock("div",{key:`option_${V}`},[e.createElementVNode("label",null,[e.createElementVNode("input",e.mergeProps(y.$props,{checked:e.unref(B).indexOf(b.value)!==-1,value:b.value,type:"checkbox",onClick:()=>C(b.value)}),null,16,I),e.createTextVNode(" "+e.toDisplayString(b.label),1)])]))),128))}},J={props:d.props,emits:d.emits,setup(r,{emit:o}){const l=t=>{if(t.target.files.length){const a=t.target.files[0];o("update:modelValue",a)}};return(t,a)=>(e.openBlock(),e.createElementBlock("input",e.mergeProps(t.$props,{type:"file",onChange:l}),null,16))}},K=M(),Q=M(),X={props:{id:{type:String,default:null}},setup(r,{slots:o,attrs:l}){return()=>e.h("label",E(k({},l),{for:r.id}),o.default())}},Y=["checked","value"],Z={props:E(k({},d.props),{options:{type:Array,default:()=>[]}}),emits:d.emits,setup(r,{emit:o}){const l=t=>o("update:modelValue",t.target.value);return(t,a)=>(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(r.options,(i,n)=>(e.openBlock(),e.createElementBlock("div",{key:`option_${n}`},[e.createElementVNode("label",null,[e.createElementVNode("input",e.mergeProps(t.$props,{checked:i.value===t.modelValue,value:i.value,type:"radio",onChange:l}),null,16,Y),e.createTextVNode(" "+e.toDisplayString(i.label),1)])]))),128))}},v=["id","disabled","name","placeholder"],ee=["label"],te=["value"],le=["value"],re={props:E(k({},d.props),{options:{type:Array,default:()=>[]},optionGroups:{type:Object,default:()=>({})}}),emits:d.emits,setup(r,{emit:o}){const l=r,t=N(l,o),a=Object.keys(l.optionGroups).length>0,i=e.computed(()=>l.options.map(n=>typeof n=="object"?n:{label:n,value:n}));return(n,B)=>e.withDirectives((e.openBlock(),e.createElementBlock("select",{id:n.id,"onUpdate:modelValue":B[0]||(B[0]=u=>e.isRef(t)?t.value=u:null),disabled:n.disabled,name:n.name,placeholder:n.placeholder},[a?(e.openBlock(!0),e.createElementBlock(e.Fragment,{key:0},e.renderList(r.optionGroups,(u,C)=>(e.openBlock(),e.createElementBlock("optgroup",{key:`optGroup_${C}`,label:C},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(u,(y,c)=>(e.openBlock(),e.createElementBlock("option",{key:`option_${c}`,value:c},e.toDisplayString(y),9,te))),128))],8,ee))),128)):(e.openBlock(!0),e.createElementBlock(e.Fragment,{key:1},e.renderList(e.unref(i),(u,C)=>(e.openBlock(),e.createElementBlock("option",{key:`option_${C}`,value:u.value},e.toDisplayString(u.label),9,le))),128))],8,v)),[[e.vModelSelect,e.unref(t)]])}},oe=["id","disabled","name","placeholder"],ne={props:d.props,emits:d.emits,setup(r,{emit:o}){const t=N(r,o);return(a,i)=>e.withDirectives((e.openBlock(),e.createElementBlock("textarea",{id:a.id,"onUpdate:modelValue":i[0]||(i[0]=n=>e.isRef(t)?t.value=n:null),disabled:a.disabled,name:a.name,placeholder:a.placeholder},null,8,oe)),[[e.vModelText,e.unref(t)]])}},ae=["type"],f={props:d.props,emits:d.emits,setup(r,{emit:o}){const t=N(r,o);return(a,i)=>e.withDirectives((e.openBlock(),e.createElementBlock("input",e.mergeProps({"onUpdate:modelValue":i[0]||(i[0]=n=>e.isRef(t)?t.value=n:null),type:a.type},a.$props),null,16,ae)),[[e.vModelDynamic,e.unref(t)]])}},G={classes:{"form-row":"form-maker-row","form-column":"form-maker-column","form-label":"form-maker-label","input-group":"form-maker-input-group","input-wrapper":"form-maker-input-wrapper","input-error":"form-maker-input-error",input:"form-maker-input",error:"form-maker-error","help-text":"form-maker-help-text","submit-button":"form-maker-submit"},components:{"form-maker-input-color":f,"form-maker-input-date":f,"form-maker-input-email":f,"form-maker-input-month":f,"form-maker-input-number":f,"form-maker-input-password":f,"form-maker-input-search":f,"form-maker-input-tel":f,"form-maker-input-time":f,"form-maker-input-text":f,"form-maker-input-url":f,"form-maker-input-week":f,"form-maker-input-range":f,"form-maker-input-file":J,"form-maker-input-textarea":ne,"form-maker-input-select":re,"form-maker-input-checkbox":H,"form-maker-input-radio":Z,"form-maker-label":X,"form-maker-help":Q,"form-maker-error":K}};return{install:(r,o={})=>{const l={classes:k(k({},G.classes),o.classes),components:k(k({},G.components),o.components)};r.component("FormMaker",P),r.component("FormMakerInput",q),Object.keys(l.classes).forEach(t=>{r.provide(t,l.classes[t])}),Object.keys(l.components).forEach(t=>{r.component(t,l.components[t])})}}});
@@ -1,15 +0,0 @@
1
- <template>
2
- <div>{{ text }}</div>
3
- </template>
4
-
5
- <script>
6
- export default {
7
- name: 'FormMakerInputError',
8
- props: {
9
- text: {
10
- type: String,
11
- default: null,
12
- },
13
- },
14
- };
15
- </script>
@@ -1,15 +0,0 @@
1
- <template>
2
- <div>{{ text }}</div>
3
- </template>
4
-
5
- <script>
6
- export default {
7
- name: 'FormMakerInputHelp',
8
- props: {
9
- text: {
10
- type: String,
11
- default: null,
12
- },
13
- },
14
- };
15
- </script>
@@ -1,19 +0,0 @@
1
- <template>
2
- <label :for="id">{{ text }}</label>
3
- </template>
4
-
5
- <script>
6
- export default {
7
- name: 'FormMakerInputLabel',
8
- props: {
9
- text: {
10
- type: String,
11
- default: null,
12
- },
13
- id: {
14
- type: String,
15
- default: null,
16
- },
17
- },
18
- };
19
- </script>