@windwalker-io/unicorn-next 0.1.0 → 0.1.2
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/.editorconfig +18 -18
- package/.gulp.json +7 -7
- package/bin/release.mjs +47 -47
- package/dist/chunks/button-radio.js +1 -1
- package/dist/chunks/button-radio.js.map +1 -1
- package/dist/chunks/checkboxes-multi-select.js.map +1 -1
- package/dist/chunks/field-cascade-select.js +1 -1
- package/dist/chunks/field-cascade-select.js.map +1 -1
- package/dist/chunks/field-file-drag.js +1 -1
- package/dist/chunks/field-file-drag.js.map +1 -1
- package/dist/chunks/field-flatpickr.js +2 -2
- package/dist/chunks/field-flatpickr.js.map +1 -1
- package/dist/chunks/field-modal-select.js +1 -1
- package/dist/chunks/field-modal-select.js.map +1 -1
- package/dist/chunks/field-modal-tree.js +3 -3
- package/dist/chunks/field-modal-tree.js.map +1 -1
- package/dist/chunks/field-multi-uploader.js +1 -1
- package/dist/chunks/field-multi-uploader.js.map +1 -1
- package/dist/chunks/field-repeatable.js +1 -1
- package/dist/chunks/field-repeatable.js.map +1 -1
- package/dist/chunks/field-single-image-drag.js +1 -1
- package/dist/chunks/field-single-image-drag.js.map +1 -1
- package/dist/chunks/form.js +1 -1
- package/dist/chunks/form.js.map +1 -1
- package/dist/chunks/grid.js +1 -1
- package/dist/chunks/grid.js.map +1 -1
- package/dist/chunks/http-client.js +1 -1
- package/dist/chunks/http-client.js.map +1 -1
- package/dist/chunks/iframe-modal.js +1 -1
- package/dist/chunks/iframe-modal.js.map +1 -1
- package/dist/chunks/keep-tab.js +1 -1
- package/dist/chunks/keep-tab.js.map +1 -1
- package/dist/chunks/legacy.js +7 -5
- package/dist/chunks/legacy.js.map +1 -1
- package/dist/chunks/list-dependent.js +1 -1
- package/dist/chunks/list-dependent.js.map +1 -1
- package/dist/chunks/s3-multipart-uploader.js +1 -1
- package/dist/chunks/s3-multipart-uploader.js.map +1 -1
- package/dist/chunks/s3-uploader.js +1 -1
- package/dist/chunks/s3-uploader.js.map +1 -1
- package/dist/chunks/show-on.js +3 -2
- package/dist/chunks/show-on.js.map +1 -1
- package/dist/chunks/tinymce.js +25 -15
- package/dist/chunks/tinymce.js.map +1 -1
- package/dist/chunks/ui-bootstrap5.js +9 -2
- package/dist/chunks/ui-bootstrap5.js.map +1 -1
- package/dist/chunks/unicorn.js +154 -101
- package/dist/chunks/unicorn.js.map +1 -1
- package/dist/chunks/validation.js +10 -8
- package/dist/chunks/validation.js.map +1 -1
- package/dist/editor.css +1 -1
- package/dist/index.d.ts +72 -42
- package/dist/multi-level-menu.css +1 -1
- package/dist/switcher.css +1 -1
- package/dist/unicorn.js +72 -72
- package/fusionfile.mjs +155 -155
- package/package.json +103 -102
- package/scss/bootstrap/multi-level-menu.scss +121 -121
- package/scss/editor.scss +116 -116
- package/scss/field/file-drag.scss +102 -102
- package/scss/field/single-image-drag.scss +88 -88
- package/scss/field/vue-drag-uploader.scss +160 -160
- package/scss/switcher.scss +156 -156
- package/src/app.ts +128 -128
- package/src/bootstrap/button-radio.ts +208 -208
- package/src/bootstrap/keep-tab.ts +155 -155
- package/src/composable/index.ts +21 -21
- package/src/composable/useCheckboxesMultiSelect.ts +22 -22
- package/src/composable/useFieldCascadeSelect.ts +9 -9
- package/src/composable/useFieldFileDrag.ts +9 -9
- package/src/composable/useFieldFlatpickr.ts +3 -3
- package/src/composable/useFieldModalSelect.ts +6 -6
- package/src/composable/useFieldModalTree.ts +3 -3
- package/src/composable/useFieldMultiUploader.ts +3 -3
- package/src/composable/useFieldRepeatable.ts +9 -9
- package/src/composable/useFieldSingleImageDrag.ts +5 -5
- package/src/composable/useForm.ts +43 -43
- package/src/composable/useGrid.ts +57 -57
- package/src/composable/useHttp.ts +9 -8
- package/src/composable/useIframeModal.ts +10 -9
- package/src/composable/useListDependent.ts +26 -26
- package/src/composable/useQueue.ts +13 -13
- package/src/composable/useS3Uploader.ts +32 -32
- package/src/composable/useShowOn.ts +9 -9
- package/src/composable/useStack.ts +13 -13
- package/src/composable/useTinymce.ts +29 -29
- package/src/composable/useTomSelect.ts +72 -72
- package/src/composable/useUIBootstrap5.ts +48 -48
- package/src/composable/useUniDirective.ts +32 -32
- package/src/composable/useValidation.ts +39 -39
- package/src/data.ts +34 -36
- package/src/events.ts +82 -73
- package/src/legacy/legacy.ts +190 -186
- package/src/legacy/loader.ts +125 -125
- package/src/module/checkboxes-multi-select.ts +54 -54
- package/src/module/field-cascade-select.ts +292 -292
- package/src/module/field-file-drag.ts +292 -292
- package/src/module/field-flatpickr.ts +127 -127
- package/src/module/field-modal-select.ts +174 -174
- package/src/module/field-modal-tree.ts +27 -27
- package/src/module/field-multi-uploader.ts +361 -361
- package/src/module/field-repeatable.ts +202 -202
- package/src/module/field-single-image-drag.ts +468 -468
- package/src/module/form.ts +223 -223
- package/src/module/grid.ts +465 -465
- package/src/module/http-client.ts +248 -243
- package/src/module/iframe-modal.ts +167 -167
- package/src/module/list-dependent.ts +321 -321
- package/src/module/s3-multipart-uploader.ts +300 -300
- package/src/module/s3-uploader.ts +234 -234
- package/src/module/show-on.ts +175 -173
- package/src/module/tinymce.ts +276 -263
- package/src/module/ui-bootstrap5.ts +116 -107
- package/src/module/validation.ts +1026 -1019
- package/src/plugin/index.ts +1 -1
- package/src/plugin/php-adapter.ts +72 -65
- package/src/polyfill/form-request-submit.ts +31 -31
- package/src/polyfill/index.ts +9 -9
- package/src/service/animate.ts +58 -58
- package/src/service/crypto.ts +27 -27
- package/src/service/dom-watcher.ts +62 -62
- package/src/service/dom.ts +265 -265
- package/src/service/helper.ts +48 -48
- package/src/service/index.ts +10 -10
- package/src/service/lang.ts +122 -122
- package/src/service/loader.ts +152 -152
- package/src/service/router.ts +118 -118
- package/src/service/ui.ts +525 -497
- package/src/service/uri.ts +106 -106
- package/src/types/base.ts +9 -9
- package/src/types/index.ts +4 -4
- package/src/types/modal-tree.ts +12 -12
- package/src/types/plugin.ts +6 -6
- package/src/types/shims.d.ts +18 -18
- package/src/types/ui.ts +6 -6
- package/src/unicorn.ts +79 -63
- package/src/utilities/arr.ts +25 -25
- package/src/utilities/base.ts +9 -9
- package/src/utilities/data.ts +48 -48
- package/src/utilities/index.ts +5 -5
- package/src/utilities/tree.ts +20 -20
- package/src/vue/components/ModalTree/ModalTreeApp.vue +175 -175
- package/src/vue/components/ModalTree/TreeItem.vue +262 -262
- package/src/vue/components/ModalTree/TreeModal.vue +225 -225
- package/tests/test.js +4 -4
- package/tsconfig.js.json +25 -25
- package/tsconfig.json +17 -17
- package/vite.assets.config.ts +61 -61
- package/vite.config.test.ts +36 -36
- package/vite.config.ts +112 -112
- package/dist/unicorn-next.css +0 -12
|
@@ -1,202 +1,202 @@
|
|
|
1
|
-
import { cloneDeep } from 'lodash-es';
|
|
2
|
-
import { initAlpineComponent, prepareAlpineDefer, uid, useCssImport } from '../service';
|
|
3
|
-
import { mergeDeep } from '../utilities';
|
|
4
|
-
|
|
5
|
-
export interface RepeatableOptions {
|
|
6
|
-
id?: string;
|
|
7
|
-
fieldName?: string;
|
|
8
|
-
sortable?: boolean;
|
|
9
|
-
hasKey?: boolean;
|
|
10
|
-
singleArray?: boolean;
|
|
11
|
-
ensureFirstRow?: boolean;
|
|
12
|
-
max?: number | null;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const defaultOptions: RepeatableOptions = {
|
|
16
|
-
id: '',
|
|
17
|
-
fieldName: '',
|
|
18
|
-
sortable: false,
|
|
19
|
-
hasKey: false,
|
|
20
|
-
singleArray: false,
|
|
21
|
-
ensureFirstRow: false,
|
|
22
|
-
max: null,
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
function prepareItem(item: any) {
|
|
26
|
-
if (item.uid == null) {
|
|
27
|
-
item.uid = uid();
|
|
28
|
-
}
|
|
29
|
-
return item;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
type RepeatableParams = {
|
|
33
|
-
items: Record<string, any>[];
|
|
34
|
-
defaultValues: any;
|
|
35
|
-
attrs: Record<string, any>;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
async function init() {
|
|
39
|
-
await prepareAlpineDefer(async (Alpine) => {
|
|
40
|
-
useCssImport('@vue-animate');
|
|
41
|
-
|
|
42
|
-
Alpine.data('RepeatableField', ({ items, defaultValues, attrs }: RepeatableParams, options: RepeatableOptions) => ({
|
|
43
|
-
items,
|
|
44
|
-
defaultValues,
|
|
45
|
-
attrs,
|
|
46
|
-
options: mergeDeep<RepeatableOptions>(defaultOptions, options),
|
|
47
|
-
init() {
|
|
48
|
-
// this.items = this.items.filter((item) => item !== '__EMPTY_ARRAY__');
|
|
49
|
-
|
|
50
|
-
if (this.options.sortable) {
|
|
51
|
-
// @see https://github.com/alpinejs/alpine/discussions/1635
|
|
52
|
-
import('sortablejs').then(({ default: Sortable }) => {
|
|
53
|
-
Sortable.create(this.$refs.tbody, {
|
|
54
|
-
handle: '.h-handle',
|
|
55
|
-
animation: 300,
|
|
56
|
-
onEnd: (event: any) => {
|
|
57
|
-
// V3 helper to unwrap the proxy
|
|
58
|
-
const items = Alpine.raw(this.items);
|
|
59
|
-
|
|
60
|
-
// splice mutates the original object, which
|
|
61
|
-
// you want to avoid. In this case it works because we
|
|
62
|
-
// created a temporary object that we can control
|
|
63
|
-
// That way we know there are no side effects
|
|
64
|
-
const droppedAtItem = items.splice(event.oldIndex, 1)[0];
|
|
65
|
-
items.splice(event.newIndex, 0, droppedAtItem);
|
|
66
|
-
//
|
|
67
|
-
// // Alpine will update when you modify the state,
|
|
68
|
-
// // so we need to set it back to our new state
|
|
69
|
-
this.items = items;
|
|
70
|
-
|
|
71
|
-
// HACK update prevKeys to new sort order
|
|
72
|
-
let keys = [];
|
|
73
|
-
for (let item of items) {
|
|
74
|
-
keys.push(item.uid);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// HACK update index of dataStack
|
|
78
|
-
// @ts-ignore
|
|
79
|
-
this.$refs.steps_template._x_prevKeys = keys;
|
|
80
|
-
// @ts-ignore
|
|
81
|
-
const elements = this.$refs.steps_template
|
|
82
|
-
.parentElement
|
|
83
|
-
.querySelectorAll('tr');
|
|
84
|
-
|
|
85
|
-
[].slice.call(elements).forEach((ele, i) => {
|
|
86
|
-
// @ts-ignore
|
|
87
|
-
if (ele?._x_dataStack[0]?.i != null) {
|
|
88
|
-
// @ts-ignore
|
|
89
|
-
ele._x_dataStack[0].i = i;
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
this.items.forEach(prepareItem);
|
|
98
|
-
|
|
99
|
-
if (this.options.ensureFirstRow) {
|
|
100
|
-
this.ensureFirstRow();
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
|
|
104
|
-
addItem(i: number) {
|
|
105
|
-
const item = prepareItem(this.getEmptyItem());
|
|
106
|
-
|
|
107
|
-
this.items.splice(i + 1, 0, item);
|
|
108
|
-
},
|
|
109
|
-
|
|
110
|
-
delItem(i: number) {
|
|
111
|
-
const el = this.getItemElementByUID(this.items[i].uid);
|
|
112
|
-
let hasAnimate = false;
|
|
113
|
-
|
|
114
|
-
el?.addEventListener('animationstart', () => {
|
|
115
|
-
hasAnimate = true;
|
|
116
|
-
}, { once: true });
|
|
117
|
-
|
|
118
|
-
el?.classList.add('animate__fadeOut');
|
|
119
|
-
|
|
120
|
-
setTimeout(() => {
|
|
121
|
-
if (!hasAnimate) {
|
|
122
|
-
this._removeItem(i);
|
|
123
|
-
}
|
|
124
|
-
}, 100);
|
|
125
|
-
|
|
126
|
-
el?.addEventListener('animationend', () => {
|
|
127
|
-
this._removeItem(i);
|
|
128
|
-
}, { once: true });
|
|
129
|
-
},
|
|
130
|
-
|
|
131
|
-
_removeItem(i: number) {
|
|
132
|
-
this.items.splice(i, 1);
|
|
133
|
-
|
|
134
|
-
if (this.options.ensureFirstRow) {
|
|
135
|
-
this.ensureFirstRow();
|
|
136
|
-
}
|
|
137
|
-
},
|
|
138
|
-
|
|
139
|
-
ensureFirstRow() {
|
|
140
|
-
if (this.items.length === 0) {
|
|
141
|
-
this.items.push(prepareItem(this.getEmptyItem()));
|
|
142
|
-
}
|
|
143
|
-
},
|
|
144
|
-
|
|
145
|
-
getItemElementByUID(uid: string) {
|
|
146
|
-
return this.$root.querySelector(`[data-item="${uid}"]`);
|
|
147
|
-
},
|
|
148
|
-
|
|
149
|
-
getId(i: number, item: any, field: string) {
|
|
150
|
-
return `${this.id}-${item.uid}-${field}`;
|
|
151
|
-
},
|
|
152
|
-
|
|
153
|
-
getName(i: number, item: any, field: string) {
|
|
154
|
-
if (this.options.singleArray) {
|
|
155
|
-
if (this.options.hasKey) {
|
|
156
|
-
if (field === 'key') {
|
|
157
|
-
return '';
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
return `${this.fieldName}[${item.key}]`;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return `${this.fieldName}[]`;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return `${this.fieldName}[${i}][${field}]`;
|
|
167
|
-
},
|
|
168
|
-
|
|
169
|
-
getEmptyItem() {
|
|
170
|
-
return cloneDeep(this.defaultValues);
|
|
171
|
-
},
|
|
172
|
-
|
|
173
|
-
get canAdd() {
|
|
174
|
-
if (!this.options.max) {
|
|
175
|
-
return true;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
return this.options.max > this.items.length;
|
|
179
|
-
},
|
|
180
|
-
|
|
181
|
-
get canModify() {
|
|
182
|
-
return this.attrs.disabled == null && this.attrs.readonly == null;
|
|
183
|
-
},
|
|
184
|
-
|
|
185
|
-
get fieldName() {
|
|
186
|
-
return this.options.fieldName;
|
|
187
|
-
},
|
|
188
|
-
|
|
189
|
-
get id() {
|
|
190
|
-
return this.options.id;
|
|
191
|
-
}
|
|
192
|
-
}));
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
await initAlpineComponent('data-repeatable');
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
export const ready = init();
|
|
199
|
-
|
|
200
|
-
export interface RepeatableModule {
|
|
201
|
-
ready: typeof ready;
|
|
202
|
-
}
|
|
1
|
+
import { cloneDeep } from 'lodash-es';
|
|
2
|
+
import { initAlpineComponent, prepareAlpineDefer, uid, useCssImport } from '../service';
|
|
3
|
+
import { mergeDeep } from '../utilities';
|
|
4
|
+
|
|
5
|
+
export interface RepeatableOptions {
|
|
6
|
+
id?: string;
|
|
7
|
+
fieldName?: string;
|
|
8
|
+
sortable?: boolean;
|
|
9
|
+
hasKey?: boolean;
|
|
10
|
+
singleArray?: boolean;
|
|
11
|
+
ensureFirstRow?: boolean;
|
|
12
|
+
max?: number | null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const defaultOptions: RepeatableOptions = {
|
|
16
|
+
id: '',
|
|
17
|
+
fieldName: '',
|
|
18
|
+
sortable: false,
|
|
19
|
+
hasKey: false,
|
|
20
|
+
singleArray: false,
|
|
21
|
+
ensureFirstRow: false,
|
|
22
|
+
max: null,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function prepareItem(item: any) {
|
|
26
|
+
if (item.uid == null) {
|
|
27
|
+
item.uid = uid();
|
|
28
|
+
}
|
|
29
|
+
return item;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type RepeatableParams = {
|
|
33
|
+
items: Record<string, any>[];
|
|
34
|
+
defaultValues: any;
|
|
35
|
+
attrs: Record<string, any>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
async function init() {
|
|
39
|
+
await prepareAlpineDefer(async (Alpine) => {
|
|
40
|
+
useCssImport('@vue-animate');
|
|
41
|
+
|
|
42
|
+
Alpine.data('RepeatableField', ({ items, defaultValues, attrs }: RepeatableParams, options: RepeatableOptions) => ({
|
|
43
|
+
items,
|
|
44
|
+
defaultValues,
|
|
45
|
+
attrs,
|
|
46
|
+
options: mergeDeep<RepeatableOptions>(defaultOptions, options),
|
|
47
|
+
init() {
|
|
48
|
+
// this.items = this.items.filter((item) => item !== '__EMPTY_ARRAY__');
|
|
49
|
+
|
|
50
|
+
if (this.options.sortable) {
|
|
51
|
+
// @see https://github.com/alpinejs/alpine/discussions/1635
|
|
52
|
+
import('sortablejs').then(({ default: Sortable }) => {
|
|
53
|
+
Sortable.create(this.$refs.tbody, {
|
|
54
|
+
handle: '.h-handle',
|
|
55
|
+
animation: 300,
|
|
56
|
+
onEnd: (event: any) => {
|
|
57
|
+
// V3 helper to unwrap the proxy
|
|
58
|
+
const items = Alpine.raw(this.items);
|
|
59
|
+
|
|
60
|
+
// splice mutates the original object, which
|
|
61
|
+
// you want to avoid. In this case it works because we
|
|
62
|
+
// created a temporary object that we can control
|
|
63
|
+
// That way we know there are no side effects
|
|
64
|
+
const droppedAtItem = items.splice(event.oldIndex, 1)[0];
|
|
65
|
+
items.splice(event.newIndex, 0, droppedAtItem);
|
|
66
|
+
//
|
|
67
|
+
// // Alpine will update when you modify the state,
|
|
68
|
+
// // so we need to set it back to our new state
|
|
69
|
+
this.items = items;
|
|
70
|
+
|
|
71
|
+
// HACK update prevKeys to new sort order
|
|
72
|
+
let keys = [];
|
|
73
|
+
for (let item of items) {
|
|
74
|
+
keys.push(item.uid);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// HACK update index of dataStack
|
|
78
|
+
// @ts-ignore
|
|
79
|
+
this.$refs.steps_template._x_prevKeys = keys;
|
|
80
|
+
// @ts-ignore
|
|
81
|
+
const elements = this.$refs.steps_template
|
|
82
|
+
.parentElement
|
|
83
|
+
.querySelectorAll('tr');
|
|
84
|
+
|
|
85
|
+
[].slice.call(elements).forEach((ele, i) => {
|
|
86
|
+
// @ts-ignore
|
|
87
|
+
if (ele?._x_dataStack[0]?.i != null) {
|
|
88
|
+
// @ts-ignore
|
|
89
|
+
ele._x_dataStack[0].i = i;
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
this.items.forEach(prepareItem);
|
|
98
|
+
|
|
99
|
+
if (this.options.ensureFirstRow) {
|
|
100
|
+
this.ensureFirstRow();
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
addItem(i: number) {
|
|
105
|
+
const item = prepareItem(this.getEmptyItem());
|
|
106
|
+
|
|
107
|
+
this.items.splice(i + 1, 0, item);
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
delItem(i: number) {
|
|
111
|
+
const el = this.getItemElementByUID(this.items[i].uid);
|
|
112
|
+
let hasAnimate = false;
|
|
113
|
+
|
|
114
|
+
el?.addEventListener('animationstart', () => {
|
|
115
|
+
hasAnimate = true;
|
|
116
|
+
}, { once: true });
|
|
117
|
+
|
|
118
|
+
el?.classList.add('animate__fadeOut');
|
|
119
|
+
|
|
120
|
+
setTimeout(() => {
|
|
121
|
+
if (!hasAnimate) {
|
|
122
|
+
this._removeItem(i);
|
|
123
|
+
}
|
|
124
|
+
}, 100);
|
|
125
|
+
|
|
126
|
+
el?.addEventListener('animationend', () => {
|
|
127
|
+
this._removeItem(i);
|
|
128
|
+
}, { once: true });
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
_removeItem(i: number) {
|
|
132
|
+
this.items.splice(i, 1);
|
|
133
|
+
|
|
134
|
+
if (this.options.ensureFirstRow) {
|
|
135
|
+
this.ensureFirstRow();
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
ensureFirstRow() {
|
|
140
|
+
if (this.items.length === 0) {
|
|
141
|
+
this.items.push(prepareItem(this.getEmptyItem()));
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
|
|
145
|
+
getItemElementByUID(uid: string) {
|
|
146
|
+
return this.$root.querySelector(`[data-item="${uid}"]`);
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
getId(i: number, item: any, field: string) {
|
|
150
|
+
return `${this.id}-${item.uid}-${field}`;
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
getName(i: number, item: any, field: string) {
|
|
154
|
+
if (this.options.singleArray) {
|
|
155
|
+
if (this.options.hasKey) {
|
|
156
|
+
if (field === 'key') {
|
|
157
|
+
return '';
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return `${this.fieldName}[${item.key}]`;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return `${this.fieldName}[]`;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return `${this.fieldName}[${i}][${field}]`;
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
getEmptyItem() {
|
|
170
|
+
return cloneDeep(this.defaultValues);
|
|
171
|
+
},
|
|
172
|
+
|
|
173
|
+
get canAdd() {
|
|
174
|
+
if (!this.options.max) {
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return this.options.max > this.items.length;
|
|
179
|
+
},
|
|
180
|
+
|
|
181
|
+
get canModify() {
|
|
182
|
+
return this.attrs.disabled == null && this.attrs.readonly == null;
|
|
183
|
+
},
|
|
184
|
+
|
|
185
|
+
get fieldName() {
|
|
186
|
+
return this.options.fieldName;
|
|
187
|
+
},
|
|
188
|
+
|
|
189
|
+
get id() {
|
|
190
|
+
return this.options.id;
|
|
191
|
+
}
|
|
192
|
+
}));
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
await initAlpineComponent('data-repeatable');
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export const ready = init();
|
|
199
|
+
|
|
200
|
+
export interface RepeatableModule {
|
|
201
|
+
ready: typeof ready;
|
|
202
|
+
}
|