@windwalker-io/unicorn-next 0.1.15 → 0.1.17

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/dist/unicorn.js CHANGED
@@ -1,4 +1,4 @@
1
- import { am, ai, an, ao, ap, aq, _, h, ar, as, at, b, J, I, au, d, e, aj, av, aw, ax, ae, D, C, ag, ay, t, T, S, af, x, y, A, az, U, B, f, ab, i, aA, l, N, z, aB, aC, p, a9, aD, aE, aF, aG, aH, c, r, w, v, M, G, F, s, al, Q, R, P, E, L, a7, K, aI, q, a0, $, a1, Y, V, ad, aJ, X, W, aK, aL, aM, aN, aO, aP, aQ, j, a4, a2, aR, aS, g, k, a5, a3, aT, u, aU, ac, aV, Z, aW, aX, aY, aZ, n, a_, a$, ak, b0, b1, m, o, b2, b3, O, b4, b5, a8, a, b6, b7, b8, b9, ba, aa } from "./chunks/unicorn.js";
1
+ import { am, ai, an, ao, ap, aq, _, h, ar, as, at, b, J, I, au, d, e, aj, av, aw, ax, ae, D, C, ag, ay, t, T, S, af, x, y, A, az, U, B, f, ab, i, aA, l, N, z, aB, aC, p, a9, aD, aE, aF, aG, aH, c, r, w, v, M, G, F, s, al, Q, R, P, E, L, a7, K, aI, q, a0, $, a1, aJ, Y, V, ad, aK, X, W, aL, aM, aN, aO, aP, aQ, aR, j, a4, a2, aS, aT, g, k, a5, a3, aU, u, aV, ac, aW, Z, aX, aY, aZ, a_, n, a$, b0, ak, b1, b2, m, o, b3, b4, O, b5, b6, a8, a, b7, b8, b9, ba, bb, aa } from "./chunks/unicorn.js";
2
2
  export {
3
3
  am as AttributeMutationObserver,
4
4
  ai as EventMixin,
@@ -73,58 +73,59 @@ export {
73
73
  a0 as useBs5ButtonRadio,
74
74
  $ as useBs5KeepTab,
75
75
  a1 as useBs5Tooltip,
76
+ aJ as useBsModalAlert,
76
77
  Y as useCheckboxesMultiSelect,
77
78
  V as useColorPicker,
78
79
  ad as useCssImport,
79
- aJ as useCssIncludes,
80
+ aK as useCssIncludes,
80
81
  X as useDisableIfStackNotEmpty,
81
82
  W as useDisableOnSubmit,
82
- aK as useFieldCascadeSelect,
83
- aL as useFieldFileDrag,
84
- aM as useFieldFlatpickr,
85
- aN as useFieldModalSelect,
86
- aO as useFieldModalTree,
87
- aP as useFieldRepeatable,
88
- aQ as useFieldSingleImageDrag,
83
+ aL as useFieldCascadeSelect,
84
+ aM as useFieldFileDrag,
85
+ aN as useFieldFlatpickr,
86
+ aO as useFieldModalSelect,
87
+ aP as useFieldModalTree,
88
+ aQ as useFieldRepeatable,
89
+ aR as useFieldSingleImageDrag,
89
90
  j as useFieldValidationInstance,
90
91
  a4 as useForm,
91
92
  a2 as useFormAsync,
92
- aR as useFormComponent,
93
- aS as useFormSubmit,
93
+ aS as useFormComponent,
94
+ aT as useFormSubmit,
94
95
  g as useFormValidation,
95
96
  k as useFormValidationInstance,
96
97
  a5 as useGrid,
97
98
  a3 as useGridAsync,
98
- aT as useGridComponent,
99
+ aU as useGridComponent,
99
100
  u as useHttpClient,
100
- aU as useIframeModal,
101
+ aV as useIframeModal,
101
102
  ac as useImport,
102
- aV as useInject,
103
+ aW as useInject,
103
104
  Z as useKeepAlive,
104
- aW as useLang,
105
- aX as useLegacy,
106
- aY as useListDependent,
107
- aZ as useMacro,
105
+ aX as useLang,
106
+ aY as useLegacy,
107
+ aZ as useListDependent,
108
+ a_ as useMacro,
108
109
  n as useQueue,
109
- a_ as useS3MultipartUploader,
110
- a$ as useS3Uploader,
110
+ a$ as useS3MultipartUploader,
111
+ b0 as useS3Uploader,
111
112
  ak as useScriptImport,
112
- b0 as useSeriesImport,
113
- b1 as useShowOn,
113
+ b1 as useSeriesImport,
114
+ b2 as useShowOn,
114
115
  m as useStack,
115
116
  o as useSystemUri,
116
- b2 as useTinymce,
117
- b3 as useTinymceHook,
117
+ b3 as useTinymce,
118
+ b4 as useTinymceHook,
118
119
  O as useTomSelect,
119
- b4 as useUI,
120
- b5 as useUIBootstrap5,
120
+ b5 as useUI,
121
+ b6 as useUIBootstrap5,
121
122
  a8 as useUITheme,
122
123
  a as useUniDirective,
123
- b6 as useUnicorn,
124
- b7 as useUnicornPhpAdapter,
125
- b8 as useVueComponentField,
126
- b9 as useWebDirective,
127
- ba as wait,
124
+ b7 as useUnicorn,
125
+ b8 as useUnicornPhpAdapter,
126
+ b9 as useVueComponentField,
127
+ ba as useWebDirective,
128
+ bb as wait,
128
129
  aa as watchAttributes
129
130
  };
130
131
  //# sourceMappingURL=unicorn.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windwalker-io/unicorn-next",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "Unicorn framework js library",
5
5
  "type": "module",
6
6
  "typings": "dist/index.d.ts",
@@ -1,3 +1,4 @@
1
+ export * from './useBsModalAlert';
1
2
  export * from './useCheckboxesMultiSelect';
2
3
  export * from './useFieldCascadeSelect';
3
4
  export * from './useFieldFileDrag';
@@ -0,0 +1,299 @@
1
+ import { Modal } from 'bootstrap';
2
+ import { html } from '../service';
3
+ import { useUIBootstrap5 } from './useUIBootstrap5';
4
+
5
+ export interface BsModalAlertOptions {
6
+ header?: string | HTMLElement | (() => HTMLElement | Promise<HTMLElement>);
7
+ title?: string;
8
+ text?: string;
9
+ icon?: string | HTMLElement | (() => HTMLElement | Promise<HTMLElement>);
10
+ content?: string | HTMLElement | (() => HTMLElement | Promise<HTMLElement>);
11
+ size?: 'sm' | 'lg' | 'xl' | 'xxl';
12
+ relatedTarget?: HTMLElement;
13
+ buttons?: BsModalButton[];
14
+ }
15
+
16
+ export type BsModalButton = {
17
+ text?: string | ((button: HTMLElement) => void);
18
+ class?: string;
19
+ attrs?: Record<string, string>;
20
+ styles?: Record<string, string>;
21
+ dismiss?: boolean;
22
+ value?: any;
23
+ href?: string;
24
+ target?: string;
25
+ onClick?: (value?: any, e?: MouseEvent) => any;
26
+ } | string | HTMLElement | (() => HTMLElement | Promise<HTMLElement>);
27
+
28
+ export interface BsModalAlertInstance {
29
+ show(title: BsModalAlertOptions): Promise<any>;
30
+
31
+ show(title: string, text?: string, icon?: string, options?: BsModalAlertOptions): Promise<any>;
32
+
33
+ show(title: BsModalAlertOptions | string, text?: string, icon?: string, options?: BsModalAlertOptions): Promise<any>;
34
+
35
+ hide: () => void;
36
+ toggle: (relatedTarget?: HTMLElement) => void;
37
+ dispose: () => void;
38
+ destroy: () => void;
39
+ instance: Modal;
40
+ el: HTMLElement;
41
+ }
42
+
43
+ const defaultOptions = {
44
+ buttons: [
45
+ 'OK'
46
+ ],
47
+ };
48
+
49
+ export async function useBsModalAlert(
50
+ options: Partial<Modal.Options>
51
+ ): Promise<BsModalAlertInstance>
52
+ export async function useBsModalAlert(
53
+ id?: string | HTMLElement,
54
+ options?: Partial<Modal.Options>
55
+ ): Promise<BsModalAlertInstance>;
56
+ export async function useBsModalAlert(
57
+ id?: string | HTMLElement | Partial<Modal.Options>,
58
+ options?: Partial<Modal.Options>
59
+ ): Promise<BsModalAlertInstance> {
60
+ await useUIBootstrap5();
61
+
62
+ let modalElement: HTMLElement | null | undefined = undefined;
63
+
64
+ if (typeof id !== 'string' && !(id instanceof HTMLElement)) {
65
+ options = id;
66
+ id = 'uni-modal-alert';
67
+ modalElement = document.getElementById(id);
68
+ } else {
69
+ modalElement = typeof id === 'string' ? document.getElementById(id) : id;
70
+ }
71
+
72
+ if (!modalElement) {
73
+ modalElement = html<HTMLDivElement>(`<div id="${id}" class="uni-modal-alert modal fade" tabindex="-1" role="dialog">
74
+ <div class="modal-dialog" role="document">
75
+ <div class="modal-content">
76
+ <div class="modal-body text-center p-4"></div>
77
+ <div class="modal-footer"></div>
78
+ </div>
79
+ </div>
80
+ </div>`);
81
+
82
+ document.body.appendChild(modalElement);
83
+ }
84
+
85
+ const modal = Modal.getOrCreateInstance(modalElement, options);
86
+
87
+ return {
88
+ show: (
89
+ title: BsModalAlertOptions | string,
90
+ text?: string,
91
+ icon?: string,
92
+ options?: BsModalAlertOptions
93
+ ): Promise<any> => {
94
+ if (typeof title === 'string') {
95
+ options = options || {};
96
+ options.title = title;
97
+ options.text = text;
98
+ options.icon = icon;
99
+ } else {
100
+ options = title;
101
+ }
102
+
103
+ return new Promise((resolve) => {
104
+ prepareModalElement(modalElement, resolve, options);
105
+
106
+ modal.show(options?.relatedTarget);
107
+ });
108
+ },
109
+ hide: () => {
110
+ modal.hide();
111
+ },
112
+ dispose: () => {
113
+ modal.dispose();
114
+ },
115
+ toggle: (relatedTarget?: HTMLElement) => {
116
+ modal.toggle(relatedTarget);
117
+ },
118
+ destroy: () => {
119
+ modal.dispose();
120
+ modalElement.remove();
121
+ },
122
+ instance: modal,
123
+ el: modalElement,
124
+ };
125
+ }
126
+
127
+ async function prepareModalElement(
128
+ modalElement: HTMLElement,
129
+ handler: (value?: any) => any,
130
+ options?: BsModalAlertOptions
131
+ ) {
132
+ options = Object.assign({}, defaultOptions, options || {});
133
+
134
+ let header = options.header;
135
+ const content = options.content;
136
+
137
+ modalElement.querySelector('.modal-header')?.remove();
138
+ modalElement.querySelector('.modal-body')!.innerHTML = '';
139
+ modalElement.querySelector('.modal-footer')!.innerHTML = '';
140
+
141
+ const dialog = modalElement.querySelector('.modal-dialog');
142
+
143
+ dialog?.classList.remove('modal-sm', 'modal-lg', 'modal-xl', 'modal-xxl');
144
+
145
+ if (header) {
146
+ if (typeof header === 'string') {
147
+ header = `<div class="modal-header">
148
+ <h5 class="modal-title">${header}</h5>
149
+ <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
150
+ </div>`;
151
+ }
152
+
153
+ header = await anyToElement(header);
154
+
155
+ modalElement.querySelector('.modal-content')!.insertAdjacentElement('afterbegin', header);
156
+ }
157
+
158
+ if (content) {
159
+ let contentElement = await anyToElement(content);
160
+
161
+ modalElement.querySelector('.modal-body')!.appendChild(contentElement);
162
+ } else {
163
+ const title = options.title;
164
+ const text = options.text;
165
+ let icon = options.icon;
166
+
167
+ if (icon) {
168
+ if (typeof icon === 'string') {
169
+ icon = `<div class="uni-modal-alert__icon text-center mb-4"><span class="${icon}" style="font-size: 48px;"></span></div>`;
170
+ }
171
+
172
+ icon = await anyToElement(icon);
173
+
174
+ modalElement.querySelector('.modal-body')!.appendChild(icon);
175
+ }
176
+
177
+ if (title) {
178
+ const titleEl = html(`<h4 class="uni-modal-alert__title">${title}</h4>`);
179
+
180
+ modalElement.querySelector('.modal-body')!.appendChild(titleEl);
181
+ }
182
+
183
+ if (text) {
184
+ const textEl = html(`<div class="uni-modal-alert__text">${text}</div>`);
185
+
186
+ modalElement.querySelector('.modal-body')!.appendChild(textEl);
187
+ }
188
+ }
189
+
190
+ const buttons = options.buttons!;
191
+
192
+ for (const i in buttons) {
193
+ const button = buttons[i];
194
+ const isConfirm = buttons.length === 1 || (buttons.length === 2 && Number(i) === 1);
195
+
196
+ const buttonElement = createButton(
197
+ button,
198
+ handler,
199
+ isConfirm
200
+ );
201
+
202
+ modalElement.querySelector('.modal-footer')!.appendChild(await buttonElement);
203
+ }
204
+
205
+ if (options.size) {
206
+ modalElement.querySelector('.modal-dialog')!.classList.add(`modal-${options.size}`);
207
+ }
208
+
209
+ return modalElement;
210
+ }
211
+
212
+ async function anyToElement(content: string | HTMLElement | (() => (HTMLElement | Promise<HTMLElement>))) {
213
+ if (typeof content === 'function') {
214
+ return content();
215
+ }
216
+
217
+ return typeof content === 'string' ? html(content) : content;
218
+ }
219
+
220
+ async function createButton(
221
+ buttonOption: BsModalButton,
222
+ handler: (value?: any) => any,
223
+ isConfirm?: boolean): Promise<HTMLElement> {
224
+ if (typeof buttonOption === 'function') {
225
+ return await buttonOption();
226
+ }
227
+
228
+ if (typeof buttonOption === 'string') {
229
+ buttonOption = {
230
+ text: buttonOption,
231
+ value: isConfirm ?? false,
232
+ class: isConfirm ? 'btn btn-primary is-confirm' : 'btn btn-outline-secondary',
233
+ styles: isConfirm ? { width: '150px' } : {},
234
+ dismiss: true,
235
+ };
236
+ }
237
+
238
+ // if not HTMLElement
239
+ let button: HTMLElement;
240
+
241
+ if (buttonOption instanceof HTMLElement) {
242
+ button = buttonOption;
243
+ } else {
244
+ const {
245
+ text,
246
+ class: className = 'btn btn-secondary',
247
+ attrs = {},
248
+ styles = {},
249
+ dismiss = true,
250
+ value,
251
+ href,
252
+ target,
253
+ onClick
254
+ } = buttonOption;
255
+
256
+ const tag = href ? 'a' : 'button';
257
+
258
+ const el = document.createElement(tag);
259
+
260
+ if (el instanceof HTMLAnchorElement) {
261
+ el.href = href!;
262
+ el.target = target || '_self';
263
+ }
264
+
265
+ if (el instanceof HTMLButtonElement) {
266
+ el.type = 'button';
267
+ }
268
+
269
+ el.setAttribute('class', className);
270
+
271
+ for (let attr in attrs) {
272
+ el.setAttribute(attr, attrs[attr]);
273
+ }
274
+
275
+ for (let style in styles) {
276
+ (el.style as any)[style] = styles[style];
277
+ }
278
+
279
+ if (dismiss) {
280
+ el.setAttribute('data-bs-dismiss', 'modal');
281
+ }
282
+
283
+ if (typeof text === 'string') {
284
+ el.textContent = text;
285
+ } else if (typeof text === 'function') {
286
+ text(el);
287
+ }
288
+
289
+ el.addEventListener('click', (e) => {
290
+ onClick?.(value, e as MouseEvent);
291
+ handler(value);
292
+ });
293
+
294
+ button = el;
295
+ }
296
+
297
+ return button;
298
+ }
299
+
@@ -1,19 +1,53 @@
1
1
  import type { UnicornFormElement } from '../module/form';
2
2
  import { module, selectOne } from '../service';
3
- import { Nullable } from '../types';
4
3
 
5
4
  let formElement: typeof UnicornFormElement;
6
5
 
7
- export async function useFormAsync(): Promise<UnicornFormElement>;
8
- export async function useFormAsync(ele?: string | Element,
9
- options?: Record<string, any>): Promise<UnicornFormElement | null>;
10
- export async function useFormAsync(ele?: string | Element,
11
- options: Record<string, any> = {}): Promise<UnicornFormElement | null> {
12
- const { UnicornFormElement } = await import('../module/form');
13
-
14
- formElement ??= UnicornFormElement;
15
-
16
- return useForm(ele, options);
6
+ type FormProxy = {
7
+ submit: (...args: Parameters<UnicornFormElement['submit']>) => Promise<ReturnType<UnicornFormElement['submit']> | undefined>;
8
+ get: (...args: Parameters<UnicornFormElement['get']>) => Promise<ReturnType<UnicornFormElement['get']> | undefined>;
9
+ post: (...args: Parameters<UnicornFormElement['post']>) => Promise<ReturnType<UnicornFormElement['post']> | undefined>;
10
+ put: (...args: Parameters<UnicornFormElement['put']>) => Promise<ReturnType<UnicornFormElement['put']> | undefined>;
11
+ patch: (...args: Parameters<UnicornFormElement['patch']>) => Promise<ReturnType<UnicornFormElement['patch']> | undefined>;
12
+ delete: (...args: Parameters<UnicornFormElement['delete']>) => Promise<ReturnType<UnicornFormElement['delete']> | undefined>;
13
+ };
14
+
15
+ export function useFormAsync(): FormProxy & Promise<UnicornFormElement>;
16
+ export function useFormAsync(
17
+ ele?: string | Element,
18
+ options?: Record<string, any>): FormProxy & Promise<UnicornFormElement | null>;
19
+ export function useFormAsync(
20
+ ele?: string | Element,
21
+ options: Record<string, any> = {}
22
+ ): FormProxy & Promise<UnicornFormElement | null> {
23
+ const promise = import('../module/form').then(({ UnicornFormElement }) => {
24
+ formElement ??= UnicornFormElement;
25
+
26
+ return useForm(ele, options);
27
+ });
28
+
29
+ const proxy = new Proxy({} as FormProxy, {
30
+ get(target, prop) {
31
+ return (...args: any[]) => {
32
+ return promise.then((form) => {
33
+ const func = (form as any)[prop];
34
+
35
+ if (typeof func === 'function') {
36
+ return func.apply(form, args);
37
+ }
38
+
39
+ throw new Error(`Method ${String(prop)} does not exist on form.`);
40
+ });
41
+ };
42
+ },
43
+ });
44
+
45
+ Object.assign(proxy, {
46
+ then: promise.then.bind(promise),
47
+ catch: promise.catch.bind(promise),
48
+ });
49
+
50
+ return proxy as FormProxy & Promise<UnicornFormElement | null>;
17
51
  }
18
52
 
19
53
  export function useForm(): UnicornFormElement;
@@ -2,8 +2,55 @@ import type { UnicornHttpClient } from '../module/http-client';
2
2
  import type { AxiosInstance, CreateAxiosDefaults } from 'axios';
3
3
  export type { ApiReturn, UnicornHttpClient } from '../module/http-client';
4
4
 
5
- export async function useHttpClient(config?: CreateAxiosDefaults | AxiosInstance): Promise<UnicornHttpClient> {
6
- const { createHttpClient } = await import('../module/http-client');
5
+ type UnicornHttpClientProxy = {
6
+ request: UnicornHttpClient['request'];
7
+ get: UnicornHttpClient['get'];
8
+ post: UnicornHttpClient['post'];
9
+ put: UnicornHttpClient['put'];
10
+ patch: UnicornHttpClient['patch'];
11
+ delete: UnicornHttpClient['delete'];
12
+ head: UnicornHttpClient['head'];
13
+ options: UnicornHttpClient['options'];
14
+ http: Promise<UnicornHttpClient>;
15
+ };
7
16
 
8
- return createHttpClient(config as CreateAxiosDefaults | undefined);
17
+ export function useHttpClient(config?: CreateAxiosDefaults | AxiosInstance): UnicornHttpClientProxy & Promise<UnicornHttpClient> {
18
+ const promise = import('../module/http-client').then(({ createHttpClient }) => {
19
+ return createHttpClient(config as CreateAxiosDefaults | undefined);
20
+ });
21
+
22
+ const data: UnicornHttpClientProxy = {
23
+ request: (options) => {
24
+ return promise.then((client) => client.request(options));
25
+ },
26
+ get: (url, options) => {
27
+ return promise.then((client) => client.get(url, options));
28
+ },
29
+ post: (url, data, options) => {
30
+ return promise.then((client) => client.post(url, data, options));
31
+ },
32
+ put: (url, data, options) => {
33
+ return promise.then((client) => client.put(url, data, options));
34
+ },
35
+ patch: (url, data, options) => {
36
+ return promise.then((client) => client.patch(url, data, options));
37
+ },
38
+ delete: (url, data, options) => {
39
+ return promise.then((client) => client.delete(url, data, options));
40
+ },
41
+ head: (url, options) => {
42
+ return promise.then((client) => client.head(url, options));
43
+ },
44
+ options: (url, options) => {
45
+ return promise.then((client) => client.options(url, options));
46
+ },
47
+ http: promise,
48
+ };
49
+
50
+ Object.assign(data, {
51
+ then: promise.then.bind(promise),
52
+ catch: promise.catch.bind(promise),
53
+ });
54
+
55
+ return data as UnicornHttpClientProxy & Promise<UnicornHttpClient>;
9
56
  }
@@ -46,3 +46,5 @@ export const useBs5ButtonRadio: typeof UIBootstrap5.prototype.buttonRadio = asyn
46
46
 
47
47
  return bs5.buttonRadio(selector, options);
48
48
  };
49
+
50
+