@aerogel/core 0.1.1-next.7fce7b4ce55cfb9c329a7746f571015aedc8e3bd → 0.1.1-next.9089cf50b6e252df5d7c6f134d3d287dae86fc73
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 +443 -122
- package/dist/aerogel-core.js +1772 -1342
- package/dist/aerogel-core.js.map +1 -1
- package/package.json +2 -1
- package/src/bootstrap/index.ts +2 -1
- package/src/components/AppLayout.vue +1 -1
- package/src/components/AppOverlays.vue +1 -1
- package/src/components/contracts/Button.ts +1 -1
- package/src/components/contracts/Combobox.ts +5 -0
- package/src/components/contracts/Modal.ts +2 -0
- 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 +16 -5
- package/src/components/headless/HeadlessModal.vue +3 -12
- package/src/components/headless/HeadlessModalContent.vue +1 -1
- package/src/components/headless/HeadlessSelect.vue +10 -91
- package/src/components/headless/HeadlessSelectOption.vue +1 -5
- package/src/components/index.ts +1 -0
- 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/Details.vue +33 -0
- package/src/components/ui/Input.vue +12 -4
- package/src/components/ui/LoadingModal.vue +1 -2
- package/src/components/ui/Modal.vue +32 -13
- package/src/components/ui/ProgressBar.vue +16 -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 -0
- package/src/components/vue/Provide.vue +11 -0
- package/src/components/vue/index.ts +1 -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.ts +2 -2
- package/src/ui/index.ts +1 -1
- package/src/ui/modals.ts +36 -0
- package/src/utils/composition/reactiveSet.ts +10 -2
- package/src/utils/index.ts +1 -0
- package/src/utils/time.ts +7 -0
package/src/forms/utils.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { FormFieldDefinition } from './FormController';
|
|
2
2
|
|
|
3
|
-
export function booleanInput(
|
|
3
|
+
export function booleanInput(
|
|
4
|
+
defaultValue?: boolean,
|
|
5
|
+
options: { rules?: string[] } = {},
|
|
6
|
+
): FormFieldDefinition<'boolean'> {
|
|
4
7
|
return {
|
|
5
8
|
default: defaultValue,
|
|
6
9
|
type: 'boolean',
|
|
@@ -8,7 +11,7 @@ export function booleanInput(defaultValue?: boolean, options: { rules?: string }
|
|
|
8
11
|
};
|
|
9
12
|
}
|
|
10
13
|
|
|
11
|
-
export function dateInput(defaultValue?: Date, options: { rules?: string } = {}): FormFieldDefinition<'date'> {
|
|
14
|
+
export function dateInput(defaultValue?: Date, options: { rules?: string[] } = {}): FormFieldDefinition<'date'> {
|
|
12
15
|
return {
|
|
13
16
|
default: defaultValue,
|
|
14
17
|
type: 'date',
|
|
@@ -19,7 +22,7 @@ export function dateInput(defaultValue?: Date, options: { rules?: string } = {})
|
|
|
19
22
|
export function enumInput<const T extends string>(
|
|
20
23
|
values: readonly T[],
|
|
21
24
|
defaultValue?: T,
|
|
22
|
-
options: { rules?: string } = {},
|
|
25
|
+
options: { rules?: string[] } = {},
|
|
23
26
|
): FormFieldDefinition<'enum', string, T> {
|
|
24
27
|
return {
|
|
25
28
|
default: defaultValue,
|
|
@@ -29,59 +32,75 @@ export function enumInput<const T extends string>(
|
|
|
29
32
|
};
|
|
30
33
|
}
|
|
31
34
|
|
|
32
|
-
export function requiredBooleanInput(
|
|
35
|
+
export function requiredBooleanInput(
|
|
36
|
+
defaultValue?: boolean,
|
|
37
|
+
options: { rules?: string[] } = {},
|
|
38
|
+
): FormFieldDefinition<'boolean', 'required'> {
|
|
33
39
|
return {
|
|
34
40
|
default: defaultValue,
|
|
35
41
|
type: 'boolean',
|
|
36
|
-
rules: 'required',
|
|
42
|
+
rules: ['required', ...((options.rules as 'required'[]) ?? [])],
|
|
37
43
|
};
|
|
38
44
|
}
|
|
39
45
|
|
|
40
|
-
export function requiredDateInput(
|
|
46
|
+
export function requiredDateInput(
|
|
47
|
+
defaultValue?: Date,
|
|
48
|
+
options: { rules?: string[] } = {},
|
|
49
|
+
): FormFieldDefinition<'date', 'required'> {
|
|
41
50
|
return {
|
|
42
51
|
default: defaultValue,
|
|
43
52
|
type: 'date',
|
|
44
|
-
rules: 'required',
|
|
53
|
+
rules: ['required', ...((options.rules as 'required'[]) ?? [])],
|
|
45
54
|
};
|
|
46
55
|
}
|
|
47
56
|
|
|
48
57
|
export function requiredEnumInput<const T extends string>(
|
|
49
58
|
values: readonly T[],
|
|
50
59
|
defaultValue?: T,
|
|
60
|
+
options: { rules?: string[] } = {},
|
|
51
61
|
): FormFieldDefinition<'enum', 'required', T> {
|
|
52
62
|
return {
|
|
53
63
|
default: defaultValue,
|
|
54
64
|
type: 'enum',
|
|
55
|
-
rules: 'required',
|
|
65
|
+
rules: ['required', ...((options.rules as 'required'[]) ?? [])],
|
|
56
66
|
values,
|
|
57
67
|
};
|
|
58
68
|
}
|
|
59
69
|
|
|
60
|
-
export function requiredNumberInput(
|
|
70
|
+
export function requiredNumberInput(
|
|
71
|
+
defaultValue?: number,
|
|
72
|
+
options: { rules?: string[] } = {},
|
|
73
|
+
): FormFieldDefinition<'number', 'required'> {
|
|
61
74
|
return {
|
|
62
75
|
default: defaultValue,
|
|
63
76
|
type: 'number',
|
|
64
|
-
rules: 'required',
|
|
77
|
+
rules: ['required', ...((options.rules as 'required'[]) ?? [])],
|
|
65
78
|
};
|
|
66
79
|
}
|
|
67
80
|
|
|
68
|
-
export function requiredObjectInput<T extends object>(
|
|
81
|
+
export function requiredObjectInput<T extends object>(
|
|
82
|
+
defaultValue?: T,
|
|
83
|
+
options: { rules?: string[] } = {},
|
|
84
|
+
): FormFieldDefinition<'object', 'required', T> {
|
|
69
85
|
return {
|
|
70
86
|
default: defaultValue,
|
|
71
87
|
type: 'object',
|
|
72
|
-
rules: 'required',
|
|
88
|
+
rules: ['required', ...((options.rules as 'required'[]) ?? [])],
|
|
73
89
|
};
|
|
74
90
|
}
|
|
75
91
|
|
|
76
|
-
export function requiredStringInput(
|
|
92
|
+
export function requiredStringInput(
|
|
93
|
+
defaultValue?: string,
|
|
94
|
+
options: { rules?: string[] } = {},
|
|
95
|
+
): FormFieldDefinition<'string', 'required'> {
|
|
77
96
|
return {
|
|
78
97
|
default: defaultValue,
|
|
79
98
|
type: 'string',
|
|
80
|
-
rules: 'required',
|
|
99
|
+
rules: ['required', ...((options.rules as 'required'[]) ?? [])],
|
|
81
100
|
};
|
|
82
101
|
}
|
|
83
102
|
|
|
84
|
-
export function numberInput(defaultValue?: number, options: { rules?: string } = {}): FormFieldDefinition<'number'> {
|
|
103
|
+
export function numberInput(defaultValue?: number, options: { rules?: string[] } = {}): FormFieldDefinition<'number'> {
|
|
85
104
|
return {
|
|
86
105
|
default: defaultValue,
|
|
87
106
|
type: 'number',
|
|
@@ -91,7 +110,7 @@ export function numberInput(defaultValue?: number, options: { rules?: string } =
|
|
|
91
110
|
|
|
92
111
|
export function objectInput<T extends object>(
|
|
93
112
|
defaultValue?: T,
|
|
94
|
-
options: { rules?: string } = {},
|
|
113
|
+
options: { rules?: string[] } = {},
|
|
95
114
|
): FormFieldDefinition<'object', string, T> {
|
|
96
115
|
return {
|
|
97
116
|
default: defaultValue,
|
|
@@ -100,7 +119,7 @@ export function objectInput<T extends object>(
|
|
|
100
119
|
};
|
|
101
120
|
}
|
|
102
121
|
|
|
103
|
-
export function stringInput(defaultValue?: string, options: { rules?: string } = {}): FormFieldDefinition<'string'> {
|
|
122
|
+
export function stringInput(defaultValue?: string, options: { rules?: string[] } = {}): FormFieldDefinition<'string'> {
|
|
104
123
|
return {
|
|
105
124
|
default: defaultValue,
|
|
106
125
|
type: 'string',
|
package/src/forms/validation.ts
CHANGED
|
@@ -31,10 +31,14 @@ export type FormFieldValidator<T = unknown> = (value: T) => string | string[] |
|
|
|
31
31
|
|
|
32
32
|
export const validators: Record<string, FormFieldValidator> = { ...builtInRules };
|
|
33
33
|
|
|
34
|
-
export function
|
|
34
|
+
export function registerFormValidationRule<T>(rule: string, validator: FormFieldValidator<T>): void {
|
|
35
35
|
validators[rule] = validator as FormFieldValidator;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
export function defineFormValidationRules<T extends Record<string, FormFieldValidator>>(rules: T): T {
|
|
39
|
+
return rules;
|
|
40
|
+
}
|
|
41
|
+
|
|
38
42
|
export function validateType(value: unknown, definition: FormFieldDefinition): string[] {
|
|
39
43
|
if (isValidType(value, definition)) {
|
|
40
44
|
return [];
|
package/src/index.css
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
--color-primary-950: color-mix(in oklab, var(--color-primary-600) 50%, black);
|
|
21
21
|
|
|
22
22
|
--color-background: oklch(1 0 0);
|
|
23
|
+
--color-primary-text: var(--color-gray-900);
|
|
23
24
|
--color-links: var(--color-primary);
|
|
24
25
|
|
|
25
26
|
--breakpoint-content: var(--breakpoint-md);
|
|
@@ -66,6 +67,15 @@ button[data-markdown-action] {
|
|
|
66
67
|
}
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
@keyframes slide-in {
|
|
71
|
+
0% {
|
|
72
|
+
transform: translateY(100%);
|
|
73
|
+
}
|
|
74
|
+
100% {
|
|
75
|
+
transform: translateY(0);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
69
79
|
@keyframes grow {
|
|
70
80
|
0% {
|
|
71
81
|
scale: 0;
|
package/src/jobs/Job.ts
CHANGED
package/src/services/App.ts
CHANGED
|
@@ -30,6 +30,10 @@ export class AppService extends Service {
|
|
|
30
30
|
this.settings.push(markRaw(setting));
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
public setSettingsFullscreenOnMobile(fullscreenOnMobile: boolean): void {
|
|
34
|
+
this.settingsFullscreenOnMobile = fullscreenOnMobile;
|
|
35
|
+
}
|
|
36
|
+
|
|
33
37
|
public async whenReady<T>(callback: () => T): Promise<T> {
|
|
34
38
|
const result = await this.ready.then(callback);
|
|
35
39
|
|
package/src/services/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ import Service from './Service';
|
|
|
10
10
|
import Storage from './Storage';
|
|
11
11
|
import { getPiniaStore } from './store';
|
|
12
12
|
import type { AppSetting } from './App.state';
|
|
13
|
+
import type { FormFieldValidator } from '@aerogel/core/forms';
|
|
13
14
|
|
|
14
15
|
export * from './App';
|
|
15
16
|
export * from './Cache';
|
|
@@ -56,6 +57,10 @@ export default definePlugin({
|
|
|
56
57
|
app.use(getPiniaStore());
|
|
57
58
|
options.settings?.forEach((setting) => App.addSetting(setting));
|
|
58
59
|
|
|
60
|
+
if (options.settingsFullscreenOnMobile !== undefined) {
|
|
61
|
+
App.setSettingsFullscreenOnMobile(options.settingsFullscreenOnMobile);
|
|
62
|
+
}
|
|
63
|
+
|
|
59
64
|
await bootServices(app, services);
|
|
60
65
|
},
|
|
61
66
|
});
|
|
@@ -64,6 +69,8 @@ declare module '@aerogel/core/bootstrap/options' {
|
|
|
64
69
|
export interface AerogelOptions {
|
|
65
70
|
services?: Record<string, Service>;
|
|
66
71
|
settings?: AppSetting[];
|
|
72
|
+
formValidationRules?: Record<string, FormFieldValidator>;
|
|
73
|
+
settingsFullscreenOnMobile?: boolean;
|
|
67
74
|
}
|
|
68
75
|
}
|
|
69
76
|
|
package/src/ui/UI.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { after, facade, fail, isDevelopment, uuid } from '@noeldemartin/utils';
|
|
2
2
|
import { markRaw, unref } from 'vue';
|
|
3
|
-
import { closeModal, createModal, modals, showModal } from '@noeldemartin/vue-modals';
|
|
4
3
|
import type { Constructor } from '@noeldemartin/utils';
|
|
5
4
|
import type { Component, ComputedOptions, MethodOptions } from 'vue';
|
|
6
|
-
import type { GetModalProps, GetModalResponse } from '@noeldemartin/vue-modals';
|
|
7
5
|
|
|
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
9
|
import type { AcceptRefs } from '@aerogel/core/utils';
|
|
10
10
|
import type { AlertModalExpose, AlertModalProps } from '@aerogel/core/components/contracts/AlertModal';
|
|
11
11
|
import type { ButtonVariant } from '@aerogel/core/components/contracts/Button';
|
package/src/ui/index.ts
CHANGED
|
@@ -14,10 +14,10 @@ import type { Component } from 'vue';
|
|
|
14
14
|
|
|
15
15
|
const services = { $ui: UI };
|
|
16
16
|
|
|
17
|
+
export * from './modals';
|
|
17
18
|
export * from './UI';
|
|
18
19
|
export * from './utils';
|
|
19
20
|
export { default as UI } from './UI';
|
|
20
|
-
export { useModal } from '@noeldemartin/vue-modals';
|
|
21
21
|
|
|
22
22
|
export type UIServices = typeof services;
|
|
23
23
|
|
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
|
+
}
|
|
@@ -2,10 +2,14 @@ import { fail } from '@noeldemartin/utils';
|
|
|
2
2
|
import { customRef } from 'vue';
|
|
3
3
|
|
|
4
4
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
5
|
-
export function reactiveSet<T>(initial?: T[] | Set<T
|
|
5
|
+
export function reactiveSet<T>(initial?: T[] | Set<T>, options: { equals?: (a: T, b: T) => boolean } = {}) {
|
|
6
6
|
let set: Set<T> = new Set(initial);
|
|
7
7
|
let trigger: () => void;
|
|
8
8
|
let track: () => void;
|
|
9
|
+
const equals = options?.equals;
|
|
10
|
+
const hasEqual = equals
|
|
11
|
+
? (item: T) => ref.value.values().some((existingItem) => equals(item, existingItem))
|
|
12
|
+
: () => false;
|
|
9
13
|
const ref = customRef((_track, _trigger) => {
|
|
10
14
|
track = _track;
|
|
11
15
|
trigger = _trigger;
|
|
@@ -25,11 +29,15 @@ export function reactiveSet<T>(initial?: T[] | Set<T>) {
|
|
|
25
29
|
has(item: T) {
|
|
26
30
|
track();
|
|
27
31
|
|
|
28
|
-
return ref.value.has(item);
|
|
32
|
+
return ref.value.has(item) || hasEqual(item);
|
|
29
33
|
},
|
|
30
34
|
add(item: T) {
|
|
31
35
|
trigger();
|
|
32
36
|
|
|
37
|
+
if (hasEqual(item)) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
33
41
|
ref.value.add(item);
|
|
34
42
|
},
|
|
35
43
|
delete(item: T) {
|
package/src/utils/index.ts
CHANGED