@windwalker-io/unicorn-next 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 (175) hide show
  1. package/.editorconfig +18 -0
  2. package/.gulp.json +7 -0
  3. package/bin/release.mjs +47 -0
  4. package/dist/chunks/_arrayPush.js +168 -0
  5. package/dist/chunks/_arrayPush.js.map +1 -0
  6. package/dist/chunks/_baseRest.js +73 -0
  7. package/dist/chunks/_baseRest.js.map +1 -0
  8. package/dist/chunks/_commonjsHelpers.js +7 -0
  9. package/dist/chunks/_commonjsHelpers.js.map +1 -0
  10. package/dist/chunks/_getPrototype.js +130 -0
  11. package/dist/chunks/_getPrototype.js.map +1 -0
  12. package/dist/chunks/button-radio.js +147 -0
  13. package/dist/chunks/button-radio.js.map +1 -0
  14. package/dist/chunks/checkboxes-multi-select.js +44 -0
  15. package/dist/chunks/checkboxes-multi-select.js.map +1 -0
  16. package/dist/chunks/cloneDeep.js +287 -0
  17. package/dist/chunks/cloneDeep.js.map +1 -0
  18. package/dist/chunks/cropper.min.js +5 -0
  19. package/dist/chunks/cropper.min.js.map +1 -0
  20. package/dist/chunks/field-cascade-select.js +256 -0
  21. package/dist/chunks/field-cascade-select.js.map +1 -0
  22. package/dist/chunks/field-file-drag.js +218 -0
  23. package/dist/chunks/field-file-drag.js.map +1 -0
  24. package/dist/chunks/field-flatpickr.js +893 -0
  25. package/dist/chunks/field-flatpickr.js.map +1 -0
  26. package/dist/chunks/field-modal-select.js +403 -0
  27. package/dist/chunks/field-modal-select.js.map +1 -0
  28. package/dist/chunks/field-modal-tree.js +790 -0
  29. package/dist/chunks/field-modal-tree.js.map +1 -0
  30. package/dist/chunks/field-multi-uploader.js +256 -0
  31. package/dist/chunks/field-multi-uploader.js.map +1 -0
  32. package/dist/chunks/field-repeatable.js +132 -0
  33. package/dist/chunks/field-repeatable.js.map +1 -0
  34. package/dist/chunks/field-single-image-drag.js +338 -0
  35. package/dist/chunks/field-single-image-drag.js.map +1 -0
  36. package/dist/chunks/form.js +154 -0
  37. package/dist/chunks/form.js.map +1 -0
  38. package/dist/chunks/grid.js +345 -0
  39. package/dist/chunks/grid.js.map +1 -0
  40. package/dist/chunks/http-client.js +229 -0
  41. package/dist/chunks/http-client.js.map +1 -0
  42. package/dist/chunks/iframe-modal.js +124 -0
  43. package/dist/chunks/iframe-modal.js.map +1 -0
  44. package/dist/chunks/index.js +309 -0
  45. package/dist/chunks/index.js.map +1 -0
  46. package/dist/chunks/isArguments.js +146 -0
  47. package/dist/chunks/isArguments.js.map +1 -0
  48. package/dist/chunks/keep-tab.js +101 -0
  49. package/dist/chunks/keep-tab.js.map +1 -0
  50. package/dist/chunks/legacy.js +210 -0
  51. package/dist/chunks/legacy.js.map +1 -0
  52. package/dist/chunks/list-dependent.js +231 -0
  53. package/dist/chunks/list-dependent.js.map +1 -0
  54. package/dist/chunks/s3-multipart-uploader.js +172 -0
  55. package/dist/chunks/s3-multipart-uploader.js.map +1 -0
  56. package/dist/chunks/s3-uploader.js +136 -0
  57. package/dist/chunks/s3-uploader.js.map +1 -0
  58. package/dist/chunks/show-on.js +237 -0
  59. package/dist/chunks/show-on.js.map +1 -0
  60. package/dist/chunks/tinymce.js +196 -0
  61. package/dist/chunks/tinymce.js.map +1 -0
  62. package/dist/chunks/ui-bootstrap5.js +71 -0
  63. package/dist/chunks/ui-bootstrap5.js.map +1 -0
  64. package/dist/chunks/unicorn.js +2202 -0
  65. package/dist/chunks/unicorn.js.map +1 -0
  66. package/dist/chunks/validation.js +854 -0
  67. package/dist/chunks/validation.js.map +1 -0
  68. package/dist/editor.css +1 -0
  69. package/dist/index.d.ts +1427 -0
  70. package/dist/multi-level-menu.css +1 -0
  71. package/dist/switcher.css +1 -0
  72. package/dist/unicorn-next.css +12 -0
  73. package/dist/unicorn.js +125 -0
  74. package/dist/unicorn.js.map +1 -0
  75. package/fusionfile.mjs +155 -0
  76. package/images/ajax-loader.gif +0 -0
  77. package/images/placeholder/avatar.png +0 -0
  78. package/images/placeholder/image-16x10.png +0 -0
  79. package/images/placeholder/image-16x9.png +0 -0
  80. package/images/placeholder/image-1x1.png +0 -0
  81. package/images/placeholder/image-4x3.png +0 -0
  82. package/package.json +102 -0
  83. package/scss/bootstrap/multi-level-menu.scss +121 -0
  84. package/scss/editor.scss +116 -0
  85. package/scss/field/file-drag.scss +102 -0
  86. package/scss/field/single-image-drag.scss +88 -0
  87. package/scss/field/vue-drag-uploader.scss +160 -0
  88. package/scss/switcher.scss +156 -0
  89. package/src/app.ts +128 -0
  90. package/src/bootstrap/button-radio.ts +208 -0
  91. package/src/bootstrap/keep-tab.ts +155 -0
  92. package/src/composable/index.ts +21 -0
  93. package/src/composable/useCheckboxesMultiSelect.ts +22 -0
  94. package/src/composable/useFieldCascadeSelect.ts +9 -0
  95. package/src/composable/useFieldFileDrag.ts +9 -0
  96. package/src/composable/useFieldFlatpickr.ts +3 -0
  97. package/src/composable/useFieldModalSelect.ts +6 -0
  98. package/src/composable/useFieldModalTree.ts +3 -0
  99. package/src/composable/useFieldMultiUploader.ts +3 -0
  100. package/src/composable/useFieldRepeatable.ts +9 -0
  101. package/src/composable/useFieldSingleImageDrag.ts +5 -0
  102. package/src/composable/useForm.ts +43 -0
  103. package/src/composable/useGrid.ts +57 -0
  104. package/src/composable/useHttp.ts +8 -0
  105. package/src/composable/useIframeModal.ts +9 -0
  106. package/src/composable/useListDependent.ts +26 -0
  107. package/src/composable/useQueue.ts +13 -0
  108. package/src/composable/useS3Uploader.ts +32 -0
  109. package/src/composable/useShowOn.ts +9 -0
  110. package/src/composable/useStack.ts +13 -0
  111. package/src/composable/useTinymce.ts +29 -0
  112. package/src/composable/useTomSelect.ts +72 -0
  113. package/src/composable/useUIBootstrap5.ts +48 -0
  114. package/src/composable/useUniDirective.ts +32 -0
  115. package/src/composable/useValidation.ts +39 -0
  116. package/src/data.ts +36 -0
  117. package/src/events.ts +73 -0
  118. package/src/legacy/legacy.ts +186 -0
  119. package/src/legacy/loader.ts +125 -0
  120. package/src/module/checkboxes-multi-select.ts +54 -0
  121. package/src/module/field-cascade-select.ts +292 -0
  122. package/src/module/field-file-drag.ts +292 -0
  123. package/src/module/field-flatpickr.ts +127 -0
  124. package/src/module/field-modal-select.ts +174 -0
  125. package/src/module/field-modal-tree.ts +27 -0
  126. package/src/module/field-multi-uploader.ts +361 -0
  127. package/src/module/field-repeatable.ts +202 -0
  128. package/src/module/field-single-image-drag.ts +468 -0
  129. package/src/module/form.ts +223 -0
  130. package/src/module/grid.ts +465 -0
  131. package/src/module/http-client.ts +243 -0
  132. package/src/module/iframe-modal.ts +167 -0
  133. package/src/module/list-dependent.ts +321 -0
  134. package/src/module/s3-multipart-uploader.ts +300 -0
  135. package/src/module/s3-uploader.ts +234 -0
  136. package/src/module/show-on.ts +173 -0
  137. package/src/module/tinymce.ts +263 -0
  138. package/src/module/ui-bootstrap5.ts +107 -0
  139. package/src/module/validation.ts +1019 -0
  140. package/src/plugin/index.ts +1 -0
  141. package/src/plugin/php-adapter.ts +65 -0
  142. package/src/polyfill/form-request-submit.ts +31 -0
  143. package/src/polyfill/index.ts +9 -0
  144. package/src/service/animate.ts +58 -0
  145. package/src/service/crypto.ts +27 -0
  146. package/src/service/dom-watcher.ts +62 -0
  147. package/src/service/dom.ts +265 -0
  148. package/src/service/helper.ts +48 -0
  149. package/src/service/index.ts +10 -0
  150. package/src/service/lang.ts +122 -0
  151. package/src/service/loader.ts +152 -0
  152. package/src/service/router.ts +118 -0
  153. package/src/service/ui.ts +497 -0
  154. package/src/service/uri.ts +106 -0
  155. package/src/types/base.ts +9 -0
  156. package/src/types/index.ts +4 -0
  157. package/src/types/modal-tree.ts +12 -0
  158. package/src/types/plugin.ts +6 -0
  159. package/src/types/shims.d.ts +18 -0
  160. package/src/types/ui.ts +6 -0
  161. package/src/unicorn.ts +63 -0
  162. package/src/utilities/arr.ts +25 -0
  163. package/src/utilities/base.ts +9 -0
  164. package/src/utilities/data.ts +48 -0
  165. package/src/utilities/index.ts +5 -0
  166. package/src/utilities/tree.ts +20 -0
  167. package/src/vue/components/ModalTree/ModalTreeApp.vue +175 -0
  168. package/src/vue/components/ModalTree/TreeItem.vue +262 -0
  169. package/src/vue/components/ModalTree/TreeModal.vue +225 -0
  170. package/tests/test.js +4 -0
  171. package/tsconfig.js.json +25 -0
  172. package/tsconfig.json +17 -0
  173. package/vite.assets.config.ts +61 -0
  174. package/vite.config.test.ts +36 -0
  175. package/vite.config.ts +112 -0
@@ -0,0 +1,208 @@
1
+ import { useUniDirective } from '../composable';
2
+ import { data } from '../data';
3
+ import { getBoundedInstance, h, selectAll, selectOne } from '../service';
4
+ import { mergeDeep } from '../utilities';
5
+
6
+ export interface ButtonRadioOptions {
7
+ selector?: string;
8
+ buttonClass?: string;
9
+ activeClass?: string;
10
+ color?: {
11
+ 'default'?: string;
12
+ green?: string;
13
+ red?: string;
14
+ blue?: string;
15
+ };
16
+ }
17
+
18
+ const defaultOptions = {
19
+ selector: '.btn-group .radio',
20
+ buttonClass: 'btn',
21
+ activeClass: 'active',
22
+ color: {
23
+ 'default': 'btn-default btn-outline-secondary',
24
+ green: 'btn-success',
25
+ red: 'btn-danger',
26
+ blue: 'btn-primary'
27
+ }
28
+ };
29
+
30
+ export class ButtonRadio {
31
+ wrapper: HTMLElement;
32
+ element: HTMLElement;
33
+ radios: HTMLInputElement[] = [];
34
+ inputs: HTMLInputElement[] = [];
35
+ buttons: HTMLButtonElement[] = [];
36
+ colors: string[] = [];
37
+ options: Required<ButtonRadioOptions>;
38
+
39
+ static handle(el: HTMLElement | string, options: ButtonRadioOptions = {}) {
40
+ return getBoundedInstance(el, 'button-radio', (el: HTMLElement) => {
41
+ return new this(el, options);
42
+ });
43
+ }
44
+
45
+ constructor(selector: HTMLElement | string, options: ButtonRadioOptions = {}) {
46
+ this.element = selectOne<HTMLElement>(selector)!;
47
+ this.options = mergeDeep({}, defaultOptions, options);
48
+ let wrapper: HTMLElement;
49
+
50
+ // Turn radios into btn-group
51
+
52
+ if (this.element.dataset.fieldInput != null) {
53
+ wrapper = this.element;
54
+ } else {
55
+ wrapper = this.element.querySelector('[data-field-input]')!;
56
+ }
57
+
58
+ this.wrapper = wrapper;
59
+ let inputGroup = wrapper.querySelector<HTMLElement>('.btn-group')!;
60
+ const exists = inputGroup != null;
61
+
62
+ if (!inputGroup) {
63
+ inputGroup = h('div', { class: 'btn-group' })
64
+ }
65
+
66
+ this.radios = selectAll(wrapper.querySelectorAll<HTMLInputElement>('.radio'));
67
+
68
+ this.radios.forEach(radio => {
69
+ const button = this.prepareButton(radio, exists);
70
+
71
+ if (!exists) {
72
+ inputGroup.appendChild(button);
73
+ }
74
+ });
75
+
76
+ this.syncState();
77
+
78
+ wrapper.insertBefore(inputGroup, wrapper.firstChild);
79
+
80
+ wrapper.dispatchEvent(new Event('button-radio.loaded'));
81
+
82
+ // Make color elements unique
83
+ this.colors = [...new Set(this.colors)];
84
+ }
85
+
86
+ prepareButton(radio: HTMLInputElement, exists = false) {
87
+ const options = this.options;
88
+
89
+ const input = radio.querySelector('input')!;
90
+ const label = radio.querySelector('label')!;
91
+
92
+ let button: HTMLButtonElement;
93
+
94
+ if (exists) {
95
+ button = this.wrapper.querySelector(`[data-for="${input.id}"]`)!;
96
+ button.classList.add(...this.parseClasses(`${options.buttonClass} ${options.color['default']}`));
97
+ } else {
98
+ button = h(
99
+ 'button',
100
+ {
101
+ type: 'button',
102
+ class: `${options.buttonClass} ${options.color['default']}`,
103
+ 'data-value': input.value,
104
+ },
105
+ `<span>${label.innerHTML}</span>`
106
+ );
107
+ }
108
+
109
+ data(button, 'input', input);
110
+ this.inputs.push(input);
111
+ this.buttons.push(button);
112
+
113
+ radio.style.display = 'none';
114
+
115
+ // Prepare color schema
116
+ let color = input.dataset.colorClass || '';
117
+
118
+ if (!color) {
119
+ switch (input.value) {
120
+ case '':
121
+ color = options.color.blue || '';
122
+ break;
123
+
124
+ case '0':
125
+ color = options.color.red || '';
126
+ break;
127
+
128
+ default:
129
+ color = options.color.green || '';
130
+ break;
131
+ }
132
+
133
+ input.dataset.colorClass = color;
134
+ }
135
+
136
+ this.colors.push(color);
137
+
138
+ if (input.disabled || input.getAttribute('readonly') != null) {
139
+ button.classList.add('disabled');
140
+ button.disabled = true;
141
+ }
142
+
143
+ if (input.getAttribute('readonly') != null) {
144
+ button.classList.add('readonly');
145
+ }
146
+
147
+ // Bind event
148
+ button.addEventListener('click', () => {
149
+ if (input.getAttribute('disabled') || input.getAttribute('readonly')) {
150
+ return;
151
+ }
152
+
153
+ const changed = !input.checked;
154
+
155
+ if (changed) {
156
+ this.inputs.forEach((ele) => {
157
+ ele.checked = false;
158
+ });
159
+
160
+ input.checked = true;
161
+
162
+ input.dispatchEvent(new Event('change'));
163
+ input.dispatchEvent(new Event('input'));
164
+ }
165
+ });
166
+
167
+ input.addEventListener('change', () => {
168
+ this.syncState();
169
+ });
170
+
171
+ return button;
172
+ }
173
+
174
+ syncState() {
175
+ const options = this.options;
176
+
177
+ this.buttons.forEach((button) => {
178
+ const input: HTMLInputElement = data(button, 'input');
179
+
180
+ button.classList.add(...this.parseClasses(options.color.default || ''));
181
+ button.classList.remove(...this.parseClasses(options.activeClass));
182
+ button.classList.remove(...this.parseClasses(...this.colors));
183
+
184
+ if (input.checked) {
185
+ button.classList.add(...this.parseClasses(options.activeClass));
186
+ button.classList.add(...this.parseClasses(input.dataset.colorClass || ''));
187
+ button.classList.remove(...this.parseClasses(options.color.default || ''));
188
+ }
189
+ });
190
+ }
191
+
192
+ parseClasses(...className: string[]) {
193
+ const classNameStr = className.join(' ');
194
+ return classNameStr.split(' ').filter(t => t !== '');
195
+ }
196
+ }
197
+
198
+ export const ready = useUniDirective('button-radio', {
199
+ mounted(el, { value }) {
200
+ const options: ButtonRadioOptions = JSON.parse(value || '{}');
201
+ ButtonRadio.handle(el, value || {});
202
+ }
203
+ });
204
+
205
+ export interface ButtonRadioModule {
206
+ ButtonRadio: typeof ButtonRadio;
207
+ ready: typeof ready;
208
+ }
@@ -0,0 +1,155 @@
1
+ import { useUniDirective } from '../composable';
2
+ import { module, selectAll, selectOne, sleep } from '../service';
3
+ import { Tab } from 'bootstrap';
4
+ import { mergeDeep } from '../utilities';
5
+
6
+ export interface KeepTabOptions {
7
+ uid?: string;
8
+ delay?: number;
9
+ tabItemSelector?: string;
10
+ }
11
+
12
+ const defaultOptions = {
13
+ tabItemSelector: '[data-toggle=tab],[data-bs-toggle=tab],[data-toggle=pill],[data-bs-toggle=pill]',
14
+ delay: 0,
15
+ };
16
+
17
+ export class KeepTab {
18
+ $element: HTMLElement;
19
+ tabButtons!: NodeListOf<HTMLElement>;
20
+ storageKey: string = '';
21
+ options: any;
22
+
23
+ constructor(selector: HTMLElement | string, options: KeepTabOptions = {}) {
24
+ options = mergeDeep({}, defaultOptions, options);
25
+ let uid: string;
26
+
27
+ if (typeof selector === 'object') {
28
+ uid = options.uid || selector.id;
29
+ } else {
30
+ uid = selector;
31
+ }
32
+
33
+ const $element = this.$element = selectOne<HTMLElement>(selector)!;
34
+
35
+ if (!$element) {
36
+ console.warn(`[KeepTab] Element ${selector} not found.`);
37
+ return;
38
+ }
39
+
40
+ this.options = options;
41
+
42
+ this.$element = $element;
43
+ this.tabButtons = $element.querySelectorAll(this.options.tabItemSelector);
44
+
45
+ this.init(uid);
46
+ }
47
+
48
+ protected async init(uid: string) {
49
+ this.storageKey = 'tab-href-' + await this.hashCode(location.href + ':' + uid);
50
+
51
+ this.bindEvents();
52
+
53
+ await sleep(this.options.delay || 0);
54
+
55
+ this.switchTab();
56
+ }
57
+
58
+ bindEvents() {
59
+ [].forEach.call(this.tabButtons, (button: HTMLAnchorElement) => {
60
+ button.addEventListener('click', () => {
61
+ // Store the selected tab href in localstorage
62
+ window.localStorage.setItem(this.storageKey, this.getButtonHref(button));
63
+ });
64
+ });
65
+ }
66
+
67
+ getButtonHref(button: HTMLAnchorElement) {
68
+ return button.dataset.bsTarget || button.dataset.target || button.href;
69
+ }
70
+
71
+ findTabButtonByHref(href: string) {
72
+ return selectAll<HTMLAnchorElement>(this.options.tabItemSelector)
73
+ .filter((button: HTMLAnchorElement) => {
74
+ if (button.href === href) {
75
+ return true;
76
+ }
77
+
78
+ if (button.dataset.bsTarget === href) {
79
+ return true;
80
+ }
81
+
82
+ return button.dataset.target === href;
83
+ })
84
+ .shift();
85
+ }
86
+
87
+ activateTab(href: string) {
88
+ const tabTrigger = this.findTabButtonByHref(href);
89
+
90
+ if (tabTrigger) {
91
+ Tab.getOrCreateInstance(tabTrigger).show();
92
+ }
93
+ }
94
+
95
+ hasTab(href: string) {
96
+ return this.findTabButtonByHref(href) != null;
97
+ }
98
+
99
+ /**
100
+ * Switch tab.
101
+ *
102
+ * @returns {boolean}
103
+ */
104
+ switchTab() {
105
+ if (localStorage.getItem(this.storageKey)) {
106
+ // When moving from tab area to a different view
107
+ if (!this.hasTab(localStorage.getItem(this.storageKey) || '')) {
108
+ localStorage.removeItem(this.storageKey);
109
+ return true;
110
+ }
111
+
112
+ // Clean default tabs
113
+ // selectOne(this.$element, '[data-toggle="tab"], [data-bs-toggle=tab]')
114
+ // this.$element.querySelector('a[data-toggle="tab"]').parent().removeClass('active');
115
+
116
+ const tabhref = localStorage.getItem(this.storageKey) || '';
117
+
118
+ // Add active attribute for selected tab indicated by url
119
+ this.activateTab(tabhref);
120
+
121
+ // Check whether internal tab is selected (in format <tabname>-<id>)
122
+ // const seperatorIndex = tabhref.indexOf('-');
123
+ //
124
+ // if (seperatorIndex !== -1) {
125
+ // const singular = tabhref.substring(0, seperatorIndex);
126
+ // const plural = singular + 's';
127
+ //
128
+ // this.activateTab(plural);
129
+ // }
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Hash code.
135
+ */
136
+ async hashCode(text: string): Promise<string> {
137
+ const msgBuffer = new TextEncoder().encode(text);
138
+ const hashBuffer = await globalThis.crypto.subtle.digest("SHA-256", msgBuffer);
139
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
140
+ return hashArray.map(b => b.toString(16).padStart(2, "0")).join("");
141
+ }
142
+ }
143
+
144
+ export const ready = useUniDirective('keeptab', {
145
+ mounted(el, { value }) {
146
+ const options: KeepTabOptions = JSON.parse(value || '{}');
147
+
148
+ module(el, 'uni.keeptab', () => new KeepTab(el, options));
149
+ }
150
+ });
151
+
152
+ export interface KeepTabModule {
153
+ KeepTab: typeof KeepTab;
154
+ ready: typeof ready;
155
+ }
@@ -0,0 +1,21 @@
1
+ export * from './useCheckboxesMultiSelect';
2
+ export * from './useFieldCascadeSelect';
3
+ export * from './useFieldFileDrag';
4
+ export * from './useFieldFlatpickr';
5
+ export * from './useFieldModalSelect';
6
+ export * from './useFieldModalTree';
7
+ export * from './useFieldRepeatable';
8
+ export * from './useFieldSingleImageDrag';
9
+ export * from './useForm';
10
+ export * from './useGrid';
11
+ export * from './useHttp';
12
+ export * from './useIframeModal';
13
+ export * from './useListDependent';
14
+ export * from './useQueue';
15
+ export * from './useS3Uploader';
16
+ export * from './useShowOn';
17
+ export * from './useStack';
18
+ export * from './useTomSelect';
19
+ export * from './useUIBootstrap5';
20
+ export * from './useUniDirective';
21
+ export * from './useValidation';
@@ -0,0 +1,22 @@
1
+ import type { CheckboxesMultiSelect } from '../module/checkboxes-multi-select';
2
+ import type { Nullable } from '../types';
3
+
4
+ export async function useCheckboxesMultiSelect(): Promise<any>;
5
+
6
+ export async function useCheckboxesMultiSelect(
7
+ selector?: Nullable<string | HTMLElement>,
8
+ options?: Record<string, any>
9
+ ): Promise<CheckboxesMultiSelect>;
10
+
11
+ export async function useCheckboxesMultiSelect(
12
+ selector?: Nullable<string | HTMLElement>,
13
+ options: Record<string, any> = {}
14
+ ): Promise<any> {
15
+ const m = await import('../module/checkboxes-multi-select');
16
+
17
+ if (selector) {
18
+ m.CheckboxesMultiSelect.handle(selector, options);
19
+ }
20
+
21
+ return m;
22
+ }
@@ -0,0 +1,9 @@
1
+ import { CascadeSelectModule } from '../module/field-cascade-select';
2
+
3
+ export async function useFieldCascadeSelect(): Promise<CascadeSelectModule> {
4
+ const module = await import('../module/field-cascade-select');
5
+
6
+ await module.ready;
7
+
8
+ return module;
9
+ }
@@ -0,0 +1,9 @@
1
+ import { FileDragModule } from '../module/field-file-drag';
2
+
3
+ export async function useFieldFileDrag(): Promise<FileDragModule> {
4
+ const module = await import('../module/field-file-drag');
5
+
6
+ await module.ready;
7
+
8
+ return module;
9
+ }
@@ -0,0 +1,3 @@
1
+ export function useFieldFlatpickr(): Promise<any> {
2
+ return import('../module/field-flatpickr');
3
+ }
@@ -0,0 +1,6 @@
1
+ import type { ModalSelectModule } from '../module/field-modal-select';
2
+
3
+ export function useFieldModalSelect(): Promise<ModalSelectModule> {
4
+ // Modal select has no exports now
5
+ return import('../module/field-modal-select');
6
+ }
@@ -0,0 +1,3 @@
1
+ export function useFieldModalTree() {
2
+ import('../module/field-modal-tree');
3
+ }
@@ -0,0 +1,3 @@
1
+ export async function useFieldMultiUploader() {
2
+ await import('../module/field-multi-uploader');
3
+ }
@@ -0,0 +1,9 @@
1
+ import { RepeatableModule } from '../module/field-repeatable';
2
+
3
+ export async function useFieldRepeatable(): Promise<RepeatableModule> {
4
+ const module = await import('../module/field-repeatable');
5
+
6
+ await module.ready;
7
+
8
+ return module;
9
+ }
@@ -0,0 +1,5 @@
1
+ import { SingleImageDragModule } from '../module/field-single-image-drag';
2
+
3
+ export function useFieldSingleImageDrag(): Promise<SingleImageDragModule> {
4
+ return import('../module/field-single-image-drag');
5
+ }
@@ -0,0 +1,43 @@
1
+ import type { UnicornFormElement } from '../module/form';
2
+ import { selectOne, module } from '../service';
3
+
4
+ let formElement: typeof UnicornFormElement;
5
+
6
+ export async function useFormAsync(): Promise<UnicornFormElement>;
7
+ export async function useFormAsync(ele?: string | Element, options?: Record<string, any>): Promise<UnicornFormElement | null>;
8
+ export async function useFormAsync(ele?: string | Element, options: Record<string, any> = {}): Promise<UnicornFormElement | null> {
9
+ const { UnicornFormElement } = await import('../module/form');
10
+
11
+ formElement ??= UnicornFormElement;
12
+
13
+ return useForm(ele, options);
14
+ }
15
+
16
+ export function useForm(): UnicornFormElement;
17
+ export function useForm(ele?: string | Element, options?: Record<string, any>): UnicornFormElement | null;
18
+ export function useForm(ele?: string | Element, options: Record<string, any> = {}): UnicornFormElement | null {
19
+ if (ele == null) {
20
+ return new formElement(undefined, undefined, options);
21
+ }
22
+
23
+ const selector = typeof ele === 'string' ? ele : undefined;
24
+ const el = selectOne<HTMLFormElement>(ele as string);
25
+
26
+ if (!el) {
27
+ throw new Error(`Form element of: ${selector} not found.`);
28
+ }
29
+
30
+ return module(
31
+ el,
32
+ 'unicorn.form',
33
+ () => new formElement(selector, el, options)
34
+ );
35
+ }
36
+
37
+ export async function useFormComponent(ele?: string | Element, options: Record<string, any> = {}) {
38
+ const form = await useFormAsync(ele, options);
39
+
40
+ await form?.initComponent();
41
+
42
+ return form;
43
+ }
@@ -0,0 +1,57 @@
1
+ import type { UnicornGridElement } from '../module/grid';
2
+ import { useForm, useFormAsync } from './useForm';
3
+ import { selectOne, module } from '../service';
4
+
5
+ let gridElement: typeof UnicornGridElement;
6
+
7
+ export async function useGridAsync(
8
+ ele?: string | HTMLElement,
9
+ options: Record<string, any> | undefined = {}
10
+ ): Promise<UnicornGridElement | null> {
11
+ await useFormAsync();
12
+
13
+ const { UnicornGridElement } = await import('../module/grid');
14
+
15
+ gridElement ??= UnicornGridElement;
16
+
17
+ if (!ele) {
18
+ return null;
19
+ }
20
+
21
+ return useGrid(ele, options);
22
+ }
23
+
24
+ export function useGrid(
25
+ ele: string | HTMLElement,
26
+ options: Record<string, any> | undefined = {}
27
+ ): UnicornGridElement | null {
28
+ const selector = typeof ele === 'string' ? ele : '';
29
+ const element = selectOne(ele);
30
+
31
+ if (!element) {
32
+ throw new Error('Element is empty');
33
+ }
34
+
35
+ const form = useForm(selector || element);
36
+
37
+ if (!form) {
38
+ throw new Error('UnicornGrid is depends on UnicornForm');
39
+ }
40
+
41
+ return module(
42
+ element,
43
+ 'grid.plugin',
44
+ () => new gridElement(selector, element, form, options)
45
+ );
46
+ }
47
+
48
+ export async function useGridComponent(
49
+ ele: string | HTMLElement,
50
+ options: Record<string, any> | undefined = {}
51
+ ): Promise<UnicornGridElement | null> {
52
+ const grid = await useGridAsync(ele, options);
53
+
54
+ await grid?.initComponent();
55
+
56
+ return grid;
57
+ }
@@ -0,0 +1,8 @@
1
+ import type { UnicornHttpClient } from '../module/http-client';
2
+ import type { AxiosInstance, CreateAxiosDefaults } from 'axios';
3
+
4
+ export async function useHttpClient(config?: CreateAxiosDefaults | AxiosInstance): Promise<UnicornHttpClient> {
5
+ const { createHttpClient } = await import('../module/http-client');
6
+
7
+ return createHttpClient(config as CreateAxiosDefaults | undefined);
8
+ }
@@ -0,0 +1,9 @@
1
+ import { IframeModalModule } from '../module/iframe-modal';
2
+
3
+ export async function useIframeModal(): Promise<IframeModalModule> {
4
+ const module = await import('../module/iframe-modal');
5
+
6
+ await module.ready;
7
+
8
+ return module;
9
+ }
@@ -0,0 +1,26 @@
1
+ import type { ListDependent, ListDependentModule, ListDependentOptions } from '../module/list-dependent';
2
+ import { Nullable } from '../types';
3
+
4
+ export async function useListDependent(): Promise<ListDependentModule>;
5
+ export async function useListDependent(
6
+ element: string | HTMLSelectElement,
7
+ dependent?: Nullable<string | HTMLSelectElement>,
8
+ options?: Partial<ListDependentOptions>
9
+ ): Promise<ListDependent>;
10
+ export async function useListDependent(
11
+ element?: Nullable<string | HTMLSelectElement>,
12
+ dependent?: Nullable<string | HTMLSelectElement>,
13
+ options: Partial<ListDependentOptions> = {}
14
+ ): Promise<any> {
15
+ const module = await import('../module/list-dependent');
16
+
17
+ await module.ready;
18
+
19
+ if (element) {
20
+ const { ListDependent } = module;
21
+
22
+ return ListDependent.handle(element, dependent ?? undefined, options);
23
+ }
24
+
25
+ return module;
26
+ }
@@ -0,0 +1,13 @@
1
+ import { Dictionary } from '../types';
2
+ import { TaskQueue, queue } from '@lyrasoft/ts-toolkit/generic';
3
+
4
+ const queues: Dictionary<TaskQueue> = {};
5
+
6
+ export function useQueue(name: string = 'default', maxRunning = 1): TaskQueue {
7
+ return queues[name] ??= createQueue(maxRunning);
8
+ }
9
+
10
+ export function createQueue(maxRunning = 1): TaskQueue {
11
+ return queue(maxRunning);
12
+ }
13
+
@@ -0,0 +1,32 @@
1
+ import {
2
+ S3MultipartUploader,
3
+ S3MultipartUploaderModule,
4
+ S3MultipartUploaderOptions
5
+ } from '../module/s3-multipart-uploader';
6
+ import type { S3Uploader, S3UploaderGlobalOptions, S3UploaderModule } from '../module/s3-uploader';
7
+
8
+ export async function useS3Uploader(): Promise<S3UploaderModule>;
9
+ export async function useS3Uploader(name: string, options?: Partial<S3UploaderGlobalOptions>): Promise<S3Uploader>;
10
+ export async function useS3Uploader(name?: string, options: Partial<S3UploaderGlobalOptions> = {}): Promise<any> {
11
+ const module = await import('../module/s3-uploader');
12
+
13
+ if (!name) {
14
+ return module;
15
+ }
16
+
17
+ const { get } = module;
18
+
19
+ return get(name, options);
20
+ }
21
+
22
+ export async function useS3MultipartUploader(): Promise<S3MultipartUploaderModule>;
23
+ export async function useS3MultipartUploader(options: Partial<S3MultipartUploaderOptions>): Promise<S3MultipartUploader>;
24
+ export async function useS3MultipartUploader(options?: Partial<S3MultipartUploaderOptions>): Promise<any> {
25
+ const module = await import('../module/s3-multipart-uploader');
26
+
27
+ if (options != null) {
28
+ return new module.S3MultipartUploader(options);
29
+ }
30
+
31
+ return module;
32
+ }
@@ -0,0 +1,9 @@
1
+ import { ShowOnModule } from '../module/show-on';
2
+
3
+ export async function useShowOn(): Promise<ShowOnModule> {
4
+ const module = await import('../module/show-on');
5
+
6
+ await module.ready;
7
+
8
+ return module;
9
+ }