@aerogel/core 0.1.0 → 0.1.1-next.095137d5f89c4b989d4961087f7a670de815e07f
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/aerogel-core.d.ts +534 -312
- package/dist/aerogel-core.js +1979 -1595
- package/dist/aerogel-core.js.map +1 -1
- package/package.json +4 -2
- package/src/bootstrap/index.ts +2 -1
- package/src/components/AppLayout.vue +1 -1
- package/src/components/AppOverlays.vue +3 -2
- package/src/components/contracts/AlertModal.ts +1 -1
- package/src/components/contracts/Button.ts +1 -1
- package/src/components/contracts/Combobox.ts +5 -0
- package/src/components/contracts/ConfirmModal.ts +5 -2
- package/src/components/contracts/Modal.ts +8 -3
- package/src/components/contracts/PromptModal.ts +6 -2
- package/src/components/contracts/Select.ts +98 -4
- package/src/components/contracts/Toast.ts +1 -1
- package/src/components/contracts/index.ts +1 -0
- package/src/components/headless/HeadlessInputInput.vue +13 -5
- package/src/components/headless/HeadlessModal.vue +6 -34
- package/src/components/headless/HeadlessModalContent.vue +5 -12
- package/src/components/headless/HeadlessSelect.vue +10 -91
- package/src/components/headless/HeadlessSelectOption.vue +1 -5
- package/src/components/index.ts +1 -1
- package/src/components/ui/AdvancedOptions.vue +4 -13
- package/src/components/ui/Button.vue +1 -0
- package/src/components/ui/Combobox.vue +94 -0
- package/src/components/ui/ComboboxLabel.vue +29 -0
- package/src/components/ui/ComboboxOption.vue +46 -0
- package/src/components/ui/ComboboxOptions.vue +71 -0
- package/src/components/ui/ComboboxTrigger.vue +67 -0
- package/src/components/ui/ConfirmModal.vue +7 -2
- package/src/components/ui/Details.vue +33 -0
- package/src/components/ui/Form.vue +1 -1
- package/src/components/ui/Input.vue +12 -4
- package/src/components/ui/LoadingModal.vue +1 -2
- package/src/components/ui/Modal.vue +53 -33
- package/src/components/ui/ProgressBar.vue +16 -2
- package/src/components/ui/PromptModal.vue +7 -2
- package/src/components/ui/Select.vue +2 -0
- package/src/components/ui/SelectTrigger.vue +13 -2
- package/src/components/ui/SettingsModal.vue +1 -1
- package/src/components/ui/Toast.vue +1 -0
- package/src/components/ui/index.ts +6 -1
- package/src/components/vue/Provide.vue +11 -0
- package/src/components/vue/index.ts +1 -0
- package/src/directives/index.ts +10 -8
- package/src/directives/safe-html.ts +10 -0
- package/src/errors/Errors.ts +4 -0
- package/src/forms/FormController.test.ts +4 -4
- package/src/forms/FormController.ts +7 -3
- package/src/forms/index.ts +11 -0
- package/src/forms/utils.ts +36 -17
- package/src/forms/validation.ts +5 -1
- package/src/index.css +10 -0
- package/src/jobs/Job.ts +1 -1
- package/src/services/App.state.ts +1 -0
- package/src/services/App.ts +4 -0
- package/src/services/index.ts +7 -0
- package/src/ui/UI.state.ts +0 -11
- package/src/ui/UI.ts +42 -125
- package/src/ui/index.ts +1 -0
- package/src/ui/modals.ts +36 -0
- package/src/utils/composition/reactiveSet.test.ts +32 -0
- package/src/utils/composition/reactiveSet.ts +53 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/time.ts +2 -0
- package/src/components/AppModals.vue +0 -14
- package/src/components/ui/ModalContext.vue +0 -31
package/src/ui/UI.ts
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
|
-
import { after, facade, fail, isDevelopment,
|
|
2
|
-
import { markRaw,
|
|
3
|
-
import type {
|
|
4
|
-
import type { Component } from 'vue';
|
|
5
|
-
import type { ClosureArgs } from '@noeldemartin/utils';
|
|
1
|
+
import { after, facade, fail, isDevelopment, uuid } from '@noeldemartin/utils';
|
|
2
|
+
import { markRaw, unref } from 'vue';
|
|
3
|
+
import type { Constructor } from '@noeldemartin/utils';
|
|
4
|
+
import type { Component, ComputedOptions, MethodOptions } from 'vue';
|
|
6
5
|
|
|
7
|
-
import App from '@aerogel/core/services/App';
|
|
8
6
|
import Events from '@aerogel/core/services/Events';
|
|
7
|
+
import { closeModal, createModal, modals, showModal } from '@aerogel/core/ui/modals';
|
|
8
|
+
import type { GetModalProps, GetModalResponse } from '@aerogel/core/ui/modals';
|
|
9
|
+
import type { AcceptRefs } from '@aerogel/core/utils';
|
|
10
|
+
import type { AlertModalExpose, AlertModalProps } from '@aerogel/core/components/contracts/AlertModal';
|
|
11
|
+
import type { ButtonVariant } from '@aerogel/core/components/contracts/Button';
|
|
12
|
+
import type { LoadingModalExpose, LoadingModalProps } from '@aerogel/core/components/contracts/LoadingModal';
|
|
13
|
+
import type { ToastAction, ToastExpose, ToastProps, ToastVariant } from '@aerogel/core/components/contracts/Toast';
|
|
9
14
|
import type {
|
|
10
15
|
ConfirmModalCheckboxes,
|
|
16
|
+
ConfirmModalEmits,
|
|
11
17
|
ConfirmModalExpose,
|
|
12
18
|
ConfirmModalProps,
|
|
13
19
|
} from '@aerogel/core/components/contracts/ConfirmModal';
|
|
@@ -15,42 +21,30 @@ import type {
|
|
|
15
21
|
ErrorReportModalExpose,
|
|
16
22
|
ErrorReportModalProps,
|
|
17
23
|
} from '@aerogel/core/components/contracts/ErrorReportModal';
|
|
18
|
-
import type {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
import type { ToastAction, ToastExpose, ToastProps, ToastVariant } from '@aerogel/core/components/contracts/Toast';
|
|
24
|
+
import type {
|
|
25
|
+
PromptModalEmits,
|
|
26
|
+
PromptModalExpose,
|
|
27
|
+
PromptModalProps,
|
|
28
|
+
} from '@aerogel/core/components/contracts/PromptModal';
|
|
24
29
|
|
|
25
30
|
import Service from './UI.state';
|
|
26
31
|
import { MOBILE_BREAKPOINT, getCurrentLayout } from './utils';
|
|
27
|
-
import type {
|
|
32
|
+
import type { UIToast } from './UI.state';
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
hasClosed(result: T | undefined): void;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export type ModalResult<T> = ModalExposeResult<ComponentExposed<T>>;
|
|
35
|
-
export type ModalExposeResult<T> = T extends { close(result?: infer Result): Promise<void> } ? Result : unknown;
|
|
36
|
-
export type UIComponent<Props = {}, Exposed = {}> = { new (...args: ClosureArgs): Exposed & { $props: Props } };
|
|
34
|
+
export type UIComponent<Props = {}, Exposed = {}, Emits = {}> = Constructor<{ $emit?: Emits } & Exposed> &
|
|
35
|
+
Component<Props, {}, {}, ComputedOptions, MethodOptions, {}, {}>;
|
|
37
36
|
|
|
38
37
|
export interface UIComponents {
|
|
39
38
|
'alert-modal': UIComponent<AlertModalProps, AlertModalExpose>;
|
|
40
|
-
'confirm-modal': UIComponent<ConfirmModalProps, ConfirmModalExpose>;
|
|
39
|
+
'confirm-modal': UIComponent<ConfirmModalProps, ConfirmModalExpose, ConfirmModalEmits>;
|
|
41
40
|
'error-report-modal': UIComponent<ErrorReportModalProps, ErrorReportModalExpose>;
|
|
42
41
|
'loading-modal': UIComponent<LoadingModalProps, LoadingModalExpose>;
|
|
43
|
-
'prompt-modal': UIComponent<PromptModalProps, PromptModalExpose>;
|
|
42
|
+
'prompt-modal': UIComponent<PromptModalProps, PromptModalExpose, PromptModalEmits>;
|
|
44
43
|
'router-link': UIComponent;
|
|
45
44
|
'startup-crash': UIComponent;
|
|
46
45
|
toast: UIComponent<ToastProps, ToastExpose>;
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
export interface UIModalContext {
|
|
50
|
-
modal: UIModal;
|
|
51
|
-
childIndex?: number;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
48
|
export type ConfirmOptions = AcceptRefs<{
|
|
55
49
|
acceptText?: string;
|
|
56
50
|
acceptVariant?: ButtonVariant;
|
|
@@ -91,7 +85,6 @@ export interface ToastOptions {
|
|
|
91
85
|
|
|
92
86
|
export class UIService extends Service {
|
|
93
87
|
|
|
94
|
-
private modalCallbacks: Record<string, Partial<ModalCallbacks>> = {};
|
|
95
88
|
private components: Partial<UIComponents> = {};
|
|
96
89
|
|
|
97
90
|
public registerComponent<T extends keyof UIComponents>(name: T, component: UIComponents[T]): void {
|
|
@@ -153,11 +146,11 @@ export class UIService extends Service {
|
|
|
153
146
|
};
|
|
154
147
|
|
|
155
148
|
const properties = getProperties();
|
|
156
|
-
const
|
|
157
|
-
const confirmed = typeof
|
|
149
|
+
const { response } = await this.modal(this.requireComponent('confirm-modal'), properties);
|
|
150
|
+
const confirmed = typeof response === 'object' ? response[0] : (response ?? false);
|
|
158
151
|
const checkboxes =
|
|
159
|
-
typeof
|
|
160
|
-
?
|
|
152
|
+
typeof response === 'object'
|
|
153
|
+
? response[1]
|
|
161
154
|
: Object.entries(properties.checkboxes ?? {}).reduce(
|
|
162
155
|
(values, [checkbox, { default: defaultValue }]) => ({
|
|
163
156
|
[checkbox]: defaultValue ?? false,
|
|
@@ -205,8 +198,8 @@ export class UIService extends Service {
|
|
|
205
198
|
} as PromptModalProps;
|
|
206
199
|
};
|
|
207
200
|
|
|
208
|
-
const
|
|
209
|
-
const result = trim && typeof
|
|
201
|
+
const { response } = await this.modal(this.requireComponent('prompt-modal'), getProperties());
|
|
202
|
+
const result = trim && typeof response === 'string' ? response?.trim() : response;
|
|
210
203
|
|
|
211
204
|
return result ?? null;
|
|
212
205
|
}
|
|
@@ -253,7 +246,9 @@ export class UIService extends Service {
|
|
|
253
246
|
return operationPromise;
|
|
254
247
|
}
|
|
255
248
|
|
|
256
|
-
const modal =
|
|
249
|
+
const modal = createModal(this.requireComponent('loading-modal'), props);
|
|
250
|
+
|
|
251
|
+
showModal(modal);
|
|
257
252
|
|
|
258
253
|
try {
|
|
259
254
|
const result = await operationPromise;
|
|
@@ -262,7 +257,7 @@ export class UIService extends Service {
|
|
|
262
257
|
|
|
263
258
|
return result;
|
|
264
259
|
} finally {
|
|
265
|
-
await
|
|
260
|
+
await closeModal(modal.id, { removeAfter: 1000 });
|
|
266
261
|
}
|
|
267
262
|
}
|
|
268
263
|
|
|
@@ -278,98 +273,28 @@ export class UIService extends Service {
|
|
|
278
273
|
}
|
|
279
274
|
|
|
280
275
|
public modal<T extends Component>(
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
): Promise<UIModal<ModalResult<T>>>;
|
|
285
|
-
|
|
286
|
-
public async modal<T extends Component>(component: T, props?: ComponentProps<T>): Promise<UIModal<ModalResult<T>>> {
|
|
287
|
-
const id = uuid();
|
|
288
|
-
const callbacks: Partial<ModalCallbacks<ModalResult<T>>> = {};
|
|
289
|
-
const modal: UIModal<ModalResult<T>> = {
|
|
290
|
-
id,
|
|
291
|
-
closing: false,
|
|
292
|
-
properties: props ?? {},
|
|
293
|
-
component: markRaw(component),
|
|
294
|
-
beforeClose: new Promise((resolve) => (callbacks.willClose = resolve)),
|
|
295
|
-
afterClose: new Promise((resolve) => (callbacks.hasClosed = resolve)),
|
|
296
|
-
};
|
|
297
|
-
const modals = this.modals.concat(modal);
|
|
298
|
-
|
|
299
|
-
this.modalCallbacks[modal.id] = callbacks;
|
|
300
|
-
|
|
301
|
-
this.setState({ modals });
|
|
302
|
-
|
|
303
|
-
await nextTick();
|
|
304
|
-
|
|
305
|
-
return modal;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
public modalForm<T extends Component>(
|
|
309
|
-
...args: {} extends ComponentProps<T>
|
|
310
|
-
? [component: T, props?: AcceptRefs<ComponentProps<T>>]
|
|
311
|
-
: [component: T, props: AcceptRefs<ComponentProps<T>>]
|
|
312
|
-
): Promise<ModalResult<T> | undefined>;
|
|
276
|
+
component: T & object extends GetModalProps<T> ? T : never,
|
|
277
|
+
props?: GetModalProps<T>
|
|
278
|
+
): Promise<GetModalResponse<T>>;
|
|
313
279
|
|
|
314
|
-
public
|
|
315
|
-
component: T,
|
|
316
|
-
props
|
|
317
|
-
): Promise<
|
|
318
|
-
const modal = await this.modal<T>(component, props as ComponentProps<T>);
|
|
319
|
-
const result = await modal.beforeClose;
|
|
320
|
-
|
|
321
|
-
return result;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
public async closeModal(id: string, result?: unknown): Promise<void> {
|
|
325
|
-
if (!App.isMounted()) {
|
|
326
|
-
await this.removeModal(id, result);
|
|
327
|
-
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
280
|
+
public modal<T extends Component>(
|
|
281
|
+
component: T & object extends GetModalProps<T> ? never : T,
|
|
282
|
+
props: GetModalProps<T>
|
|
283
|
+
): Promise<GetModalResponse<T>>;
|
|
330
284
|
|
|
331
|
-
|
|
285
|
+
public modal<T extends Component>(component: T, componentProps?: GetModalProps<T>): Promise<GetModalResponse<T>> {
|
|
286
|
+
return showModal(component, componentProps ?? {});
|
|
332
287
|
}
|
|
333
288
|
|
|
334
289
|
public async closeAllModals(): Promise<void> {
|
|
335
|
-
|
|
336
|
-
await this.closeModal(required(this.modals[this.modals.length - 1]).id);
|
|
337
|
-
}
|
|
290
|
+
await Promise.all(modals.value.map(({ id }) => closeModal(id, { removeAfter: 1000 })));
|
|
338
291
|
}
|
|
339
292
|
|
|
340
293
|
protected override async boot(): Promise<void> {
|
|
341
|
-
this.watchModalEvents();
|
|
342
294
|
this.watchMountedEvent();
|
|
343
295
|
this.watchViewportBreakpoints();
|
|
344
296
|
}
|
|
345
297
|
|
|
346
|
-
private async removeModal(id: string, result?: unknown): Promise<void> {
|
|
347
|
-
this.setState(
|
|
348
|
-
'modals',
|
|
349
|
-
this.modals.filter((m) => m.id !== id),
|
|
350
|
-
);
|
|
351
|
-
|
|
352
|
-
this.modalCallbacks[id]?.hasClosed?.(result);
|
|
353
|
-
|
|
354
|
-
delete this.modalCallbacks[id];
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
private watchModalEvents(): void {
|
|
358
|
-
Events.on('modal-will-close', ({ modal: { id }, result }) => {
|
|
359
|
-
const modal = this.modals.find((_modal) => id === _modal.id);
|
|
360
|
-
|
|
361
|
-
if (modal) {
|
|
362
|
-
modal.closing = true;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
this.modalCallbacks[id]?.willClose?.(result);
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
Events.on('modal-has-closed', async ({ modal: { id }, result }) => {
|
|
369
|
-
await this.removeModal(id, result);
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
|
|
373
298
|
private watchMountedEvent(): void {
|
|
374
299
|
Events.once('application-mounted', async () => {
|
|
375
300
|
if (!globalThis.document || !globalThis.getComputedStyle) {
|
|
@@ -405,11 +330,3 @@ export class UIService extends Service {
|
|
|
405
330
|
}
|
|
406
331
|
|
|
407
332
|
export default facade(UIService);
|
|
408
|
-
|
|
409
|
-
declare module '@aerogel/core/services/Events' {
|
|
410
|
-
export interface EventsPayload {
|
|
411
|
-
'close-modal': { id: string; result?: unknown };
|
|
412
|
-
'modal-will-close': { modal: UIModal; result?: unknown };
|
|
413
|
-
'modal-has-closed': { modal: UIModal; result?: unknown };
|
|
414
|
-
}
|
|
415
|
-
}
|
package/src/ui/index.ts
CHANGED
package/src/ui/modals.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { after } from '@noeldemartin/utils';
|
|
2
|
+
import { injectModal, useModal as useModalBase } from '@noeldemartin/vue-modals';
|
|
3
|
+
|
|
4
|
+
export {
|
|
5
|
+
createModal,
|
|
6
|
+
showModal,
|
|
7
|
+
injectModal,
|
|
8
|
+
closeModal,
|
|
9
|
+
modals,
|
|
10
|
+
ModalComponent,
|
|
11
|
+
ModalsPortal,
|
|
12
|
+
type GetModalProps,
|
|
13
|
+
type GetModalResponse,
|
|
14
|
+
type ModalController,
|
|
15
|
+
} from '@noeldemartin/vue-modals';
|
|
16
|
+
|
|
17
|
+
const instances = new WeakSet();
|
|
18
|
+
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
20
|
+
export function useModal<T = never>() {
|
|
21
|
+
const instance = injectModal<T>();
|
|
22
|
+
const { close, remove, ...modal } = useModalBase<T>(instances.has(instance) ? {} : { removeOnClose: false });
|
|
23
|
+
|
|
24
|
+
instances.add(instance);
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
...modal,
|
|
28
|
+
async close(result?: T) {
|
|
29
|
+
close(result);
|
|
30
|
+
|
|
31
|
+
await after(1000);
|
|
32
|
+
|
|
33
|
+
remove();
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { nextTick, watchEffect } from 'vue';
|
|
3
|
+
|
|
4
|
+
import { reactiveSet } from './reactiveSet';
|
|
5
|
+
|
|
6
|
+
describe('Vue reactiveSet', () => {
|
|
7
|
+
|
|
8
|
+
it('watches updates', async () => {
|
|
9
|
+
// Arrange
|
|
10
|
+
const set = reactiveSet();
|
|
11
|
+
let updates = 0;
|
|
12
|
+
|
|
13
|
+
watchEffect(() => (set.has('foo'), updates++));
|
|
14
|
+
|
|
15
|
+
// Act
|
|
16
|
+
set.add('foo');
|
|
17
|
+
await nextTick();
|
|
18
|
+
|
|
19
|
+
set.add('bar');
|
|
20
|
+
await nextTick();
|
|
21
|
+
|
|
22
|
+
set.add('baz');
|
|
23
|
+
await nextTick();
|
|
24
|
+
|
|
25
|
+
set.reset();
|
|
26
|
+
await nextTick();
|
|
27
|
+
|
|
28
|
+
// Assert
|
|
29
|
+
expect(updates).toEqual(5);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { fail } from '@noeldemartin/utils';
|
|
2
|
+
import { customRef } from 'vue';
|
|
3
|
+
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
5
|
+
export function reactiveSet<T>(initial?: T[] | Set<T>) {
|
|
6
|
+
let set: Set<T> = new Set(initial);
|
|
7
|
+
let trigger: () => void;
|
|
8
|
+
let track: () => void;
|
|
9
|
+
const ref = customRef((_track, _trigger) => {
|
|
10
|
+
track = _track;
|
|
11
|
+
trigger = _trigger;
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
get: () => set,
|
|
15
|
+
set: () => fail('Attempted to write read-only reactive set'),
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
values() {
|
|
21
|
+
track();
|
|
22
|
+
|
|
23
|
+
return Array.from(ref.value.values());
|
|
24
|
+
},
|
|
25
|
+
has(item: T) {
|
|
26
|
+
track();
|
|
27
|
+
|
|
28
|
+
return ref.value.has(item);
|
|
29
|
+
},
|
|
30
|
+
add(item: T) {
|
|
31
|
+
trigger();
|
|
32
|
+
|
|
33
|
+
ref.value.add(item);
|
|
34
|
+
},
|
|
35
|
+
delete(item: T) {
|
|
36
|
+
trigger();
|
|
37
|
+
|
|
38
|
+
ref.value.delete(item);
|
|
39
|
+
},
|
|
40
|
+
clear() {
|
|
41
|
+
trigger();
|
|
42
|
+
|
|
43
|
+
ref.value.clear();
|
|
44
|
+
},
|
|
45
|
+
reset(items?: T[] | Set<T>) {
|
|
46
|
+
trigger();
|
|
47
|
+
|
|
48
|
+
set = new Set(items);
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export type ReactiveSet<T = unknown> = ReturnType<typeof reactiveSet<T>>;
|
package/src/utils/index.ts
CHANGED
|
@@ -4,7 +4,9 @@ export * from './composition/events';
|
|
|
4
4
|
export * from './composition/forms';
|
|
5
5
|
export * from './composition/hooks';
|
|
6
6
|
export * from './composition/persistent';
|
|
7
|
+
export * from './composition/reactiveSet';
|
|
7
8
|
export * from './composition/state';
|
|
8
9
|
export * from './markdown';
|
|
10
|
+
export * from './time';
|
|
9
11
|
export * from './types';
|
|
10
12
|
export * from './vue';
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<aside v-if="modal">
|
|
3
|
-
<ModalContext :child-index="1" :modal />
|
|
4
|
-
</aside>
|
|
5
|
-
</template>
|
|
6
|
-
|
|
7
|
-
<script setup lang="ts">
|
|
8
|
-
import { computed } from 'vue';
|
|
9
|
-
|
|
10
|
-
import ModalContext from '@aerogel/core/components/ui/ModalContext.vue';
|
|
11
|
-
import UI from '@aerogel/core/ui/UI';
|
|
12
|
-
|
|
13
|
-
const modal = computed(() => UI.modals[0] ?? null);
|
|
14
|
-
</script>
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<component :is="modal.component" v-bind="modalProperties" />
|
|
3
|
-
</template>
|
|
4
|
-
|
|
5
|
-
<script setup lang="ts">
|
|
6
|
-
import { computed, provide, toRef, unref } from 'vue';
|
|
7
|
-
|
|
8
|
-
import type { UIModal } from '@aerogel/core/ui/UI.state';
|
|
9
|
-
import type { UIModalContext } from '@aerogel/core/ui/UI';
|
|
10
|
-
import type { AcceptRefs } from '@aerogel/core/utils/vue';
|
|
11
|
-
|
|
12
|
-
const props = defineProps<{
|
|
13
|
-
modal: UIModal;
|
|
14
|
-
childIndex?: number;
|
|
15
|
-
}>();
|
|
16
|
-
|
|
17
|
-
const modalProperties = computed(() => {
|
|
18
|
-
const properties = {} as typeof props.modal.properties;
|
|
19
|
-
|
|
20
|
-
for (const property in props.modal.properties) {
|
|
21
|
-
properties[property] = unref(props.modal.properties[property]);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return properties;
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
provide<AcceptRefs<UIModalContext>>('modal', {
|
|
28
|
-
modal: toRef(props, 'modal'),
|
|
29
|
-
childIndex: toRef(props, 'childIndex'),
|
|
30
|
-
});
|
|
31
|
-
</script>
|