@aerogel/core 0.1.1-next.b342b522bd4e8a154c68962bb545cd8ae66010c3 → 0.1.1-next.bf5c51083c0817e96fa4f38273c32d388441f514
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 +14 -14
- package/dist/aerogel-core.js +993 -971
- package/dist/aerogel-core.js.map +1 -1
- package/package.json +3 -3
- package/src/components/headless/HeadlessInputInput.vue +19 -5
- package/src/components/ui/Combobox.vue +17 -3
- package/src/errors/index.ts +5 -0
- package/src/forms/FormController.ts +16 -10
- package/src/plugins/index.ts +1 -3
- package/src/testing/index.ts +1 -2
- package/src/ui/UI.ts +2 -1
- package/src/utils/classes.ts +2 -3
- package/src/utils/composition/reactiveSet.ts +10 -2
- package/src/utils/time.ts +6 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aerogel/core",
|
|
3
|
-
"version": "0.1.1-next.
|
|
3
|
+
"version": "0.1.1-next.bf5c51083c0817e96fa4f38273c32d388441f514",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"exports": {
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"vue": "^3.5.0"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@noeldemartin/utils": "0.7.
|
|
33
|
-
"@noeldemartin/vue-modals": "0.
|
|
32
|
+
"@noeldemartin/utils": "0.7.3",
|
|
33
|
+
"@noeldemartin/vue-modals": "0.1.1",
|
|
34
34
|
"class-variance-authority": "^0.7.1",
|
|
35
35
|
"clsx": "^2.1.1",
|
|
36
36
|
"dompurify": "^3.2.4",
|
|
@@ -19,7 +19,7 @@ import { computed, inject, useTemplateRef, watchEffect } from 'vue';
|
|
|
19
19
|
|
|
20
20
|
import { injectReactiveOrFail } from '@aerogel/core/utils/vue';
|
|
21
21
|
import { onFormFocus } from '@aerogel/core/utils/composition/forms';
|
|
22
|
-
import {
|
|
22
|
+
import { getLocalTimezoneOffset } from '@aerogel/core/utils';
|
|
23
23
|
import type FormController from '@aerogel/core/forms/FormController';
|
|
24
24
|
import type { FormFieldValue } from '@aerogel/core/forms/FormController';
|
|
25
25
|
import type { InputExpose } from '@aerogel/core/components/contracts/Input';
|
|
@@ -65,8 +65,19 @@ function getValue(): FormFieldValue | null {
|
|
|
65
65
|
return $input.value.checked;
|
|
66
66
|
case 'date':
|
|
67
67
|
case 'time':
|
|
68
|
-
case 'datetime-local':
|
|
69
|
-
|
|
68
|
+
case 'datetime-local': {
|
|
69
|
+
const date = new Date(
|
|
70
|
+
Math.round($input.value.valueAsNumber / 60000) * 60000 +
|
|
71
|
+
getLocalTimezoneOffset($input.value.valueAsDate ?? new Date($input.value.valueAsNumber)),
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
if (isNaN(date.getTime())) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return date;
|
|
79
|
+
}
|
|
80
|
+
|
|
70
81
|
case 'number':
|
|
71
82
|
return $input.value.valueAsNumber;
|
|
72
83
|
default:
|
|
@@ -83,8 +94,11 @@ watchEffect(() => {
|
|
|
83
94
|
if (['date', 'time', 'datetime-local'].includes(renderedType.value) && value.value instanceof Date) {
|
|
84
95
|
const roundedValue = Math.round(value.value.getTime() / 60000) * 60000;
|
|
85
96
|
|
|
86
|
-
$input.value.valueAsNumber = roundedValue -
|
|
87
|
-
|
|
97
|
+
$input.value.valueAsNumber = roundedValue - getLocalTimezoneOffset(value.value);
|
|
98
|
+
|
|
99
|
+
if (value.value.getTime() !== roundedValue) {
|
|
100
|
+
input.update(new Date(roundedValue));
|
|
101
|
+
}
|
|
88
102
|
|
|
89
103
|
return;
|
|
90
104
|
}
|
|
@@ -52,6 +52,8 @@ const {
|
|
|
52
52
|
emit,
|
|
53
53
|
);
|
|
54
54
|
const open = ref(false);
|
|
55
|
+
const optionsByLabel = computed(() =>
|
|
56
|
+
Object.fromEntries(expose.options.value?.map((option) => [option.label, option.value]) ?? []));
|
|
55
57
|
const combobox = {
|
|
56
58
|
input: ref(acceptableValue.value ? renderOption(acceptableValue.value as T) : ''),
|
|
57
59
|
preventChange: ref(false),
|
|
@@ -64,12 +66,24 @@ function update(value: AcceptableValue) {
|
|
|
64
66
|
baseUpdate(value);
|
|
65
67
|
}
|
|
66
68
|
|
|
69
|
+
watch(expose.value, (value) => {
|
|
70
|
+
const newOptionLabel = renderOption(value as T);
|
|
71
|
+
|
|
72
|
+
if (combobox.input.value === newOptionLabel) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
combobox.preventChange.value = true;
|
|
77
|
+
combobox.input.value = newOptionLabel;
|
|
78
|
+
});
|
|
79
|
+
|
|
67
80
|
watch(combobox.input, (value) => {
|
|
68
81
|
const newInputOption = newInputValue ? (newInputValue(value) as AcceptableValue) : value;
|
|
69
|
-
const
|
|
70
|
-
|
|
82
|
+
const newInputOptionLabel = renderOption(newInputOption as T);
|
|
83
|
+
|
|
84
|
+
if (newInputOptionLabel in optionsByLabel.value) {
|
|
85
|
+
update(optionsByLabel.value[newInputOptionLabel] as AcceptableValue);
|
|
71
86
|
|
|
72
|
-
if (renderedValue === renderedNewInputOption) {
|
|
73
87
|
return;
|
|
74
88
|
}
|
|
75
89
|
|
package/src/errors/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { App as AppInstance } from 'vue';
|
|
|
3
3
|
import App from '@aerogel/core/services/App';
|
|
4
4
|
import { bootServices } from '@aerogel/core/services';
|
|
5
5
|
import { definePlugin } from '@aerogel/core/plugins';
|
|
6
|
+
import { getErrorMessage } from '@aerogel/core/errors/utils';
|
|
6
7
|
|
|
7
8
|
import Errors from './Errors';
|
|
8
9
|
import settings from './settings';
|
|
@@ -16,6 +17,10 @@ export type { ErrorSource, ErrorReport, ErrorReportLog };
|
|
|
16
17
|
|
|
17
18
|
const services = { $errors: Errors };
|
|
18
19
|
const frameworkHandler: ErrorHandler = (error) => {
|
|
20
|
+
if (getErrorMessage(error).includes('ResizeObserver loop completed with undelivered notifications.')) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
|
|
19
24
|
Errors.report(error);
|
|
20
25
|
|
|
21
26
|
return true;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { computed, nextTick, reactive, readonly, ref } from 'vue';
|
|
2
|
-
import { MagicObject, arrayRemove, fail
|
|
2
|
+
import { MagicObject, arrayRemove, fail } from '@noeldemartin/utils';
|
|
3
3
|
import type { ComputedRef, DeepReadonly, Ref, UnwrapNestedRefs } from 'vue';
|
|
4
4
|
|
|
5
5
|
import { validate, validateType } from './validation';
|
|
@@ -91,17 +91,13 @@ export default class FormController<Fields extends FormFieldDefinitions = FormFi
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
public setFieldValue<T extends keyof Fields>(field: T, value: FormData<Fields>[T]): void {
|
|
94
|
-
|
|
95
|
-
this._fields[field] ?? fail<FormFieldDefinition>(`Trying to set undefined '${toString(field)}' field`);
|
|
94
|
+
this._data[field] = value;
|
|
96
95
|
|
|
97
|
-
this.
|
|
98
|
-
|
|
99
|
-
? (toString(value).trim() as FormData<Fields>[T])
|
|
100
|
-
: value;
|
|
101
|
-
|
|
102
|
-
if (this._submitted.value) {
|
|
103
|
-
this.validate();
|
|
96
|
+
if (!this._submitted.value) {
|
|
97
|
+
return;
|
|
104
98
|
}
|
|
99
|
+
|
|
100
|
+
this.validate();
|
|
105
101
|
}
|
|
106
102
|
|
|
107
103
|
public getFieldValue<T extends keyof Fields>(field: T): GetFormFieldValue<Fields[T]['type']> {
|
|
@@ -149,6 +145,16 @@ export default class FormController<Fields extends FormFieldDefinitions = FormFi
|
|
|
149
145
|
public submit(): boolean {
|
|
150
146
|
this._submitted.value = true;
|
|
151
147
|
|
|
148
|
+
for (const [field, value] of Object.entries(this._data)) {
|
|
149
|
+
const definition = this._fields[field] ?? fail<FormFieldDefinition>();
|
|
150
|
+
|
|
151
|
+
if (typeof value !== 'string' || !(definition.trim ?? true)) {
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
this._data[field as keyof Fields] = value.trim() as FormData<Fields>[string];
|
|
156
|
+
}
|
|
157
|
+
|
|
152
158
|
const valid = this.validate();
|
|
153
159
|
|
|
154
160
|
valid && this._listeners['submit']?.forEach((listener) => listener());
|
package/src/plugins/index.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import type { GetClosureArgs } from '@noeldemartin/utils';
|
|
2
|
-
|
|
3
1
|
import App from '@aerogel/core/services/App';
|
|
4
2
|
|
|
5
3
|
import type { Plugin } from './Plugin';
|
|
@@ -10,7 +8,7 @@ export function definePlugin<T extends Plugin>(plugin: T): T {
|
|
|
10
8
|
return plugin;
|
|
11
9
|
}
|
|
12
10
|
|
|
13
|
-
export async function installPlugins(plugins: Plugin[], ...args:
|
|
11
|
+
export async function installPlugins(plugins: Plugin[], ...args: Parameters<Plugin['install']>): Promise<void> {
|
|
14
12
|
App.setState(
|
|
15
13
|
'plugins',
|
|
16
14
|
plugins.reduce(
|
package/src/testing/index.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { isTesting } from '@noeldemartin/utils';
|
|
2
|
-
import type { GetClosureArgs } from '@noeldemartin/utils';
|
|
3
2
|
|
|
4
3
|
import Events from '@aerogel/core/services/Events';
|
|
5
4
|
import { App } from '@aerogel/core/services';
|
|
@@ -18,7 +17,7 @@ export default definePlugin({
|
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
globalThis.testingRuntime = {
|
|
21
|
-
on: ((...args:
|
|
20
|
+
on: ((...args: Parameters<(typeof Events)['on']>) => Events.on(...args)) as (typeof Events)['on'],
|
|
22
21
|
service: (name) => App.service(name),
|
|
23
22
|
};
|
|
24
23
|
},
|
package/src/ui/UI.ts
CHANGED
|
@@ -283,7 +283,8 @@ export class UIService extends Service {
|
|
|
283
283
|
): Promise<GetModalResponse<T>>;
|
|
284
284
|
|
|
285
285
|
public modal<T extends Component>(component: T, componentProps?: GetModalProps<T>): Promise<GetModalResponse<T>> {
|
|
286
|
-
|
|
286
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
287
|
+
return showModal(component as any, componentProps ?? {}) as Promise<GetModalResponse<T>>;
|
|
287
288
|
}
|
|
288
289
|
|
|
289
290
|
public async closeAllModals(): Promise<void> {
|
package/src/utils/classes.ts
CHANGED
|
@@ -4,10 +4,9 @@ import { cva } from 'class-variance-authority';
|
|
|
4
4
|
import { twMerge } from 'tailwind-merge';
|
|
5
5
|
import type { ClassValue } from 'clsx';
|
|
6
6
|
import type { PropType } from 'vue';
|
|
7
|
-
import type { GetClosureArgs, GetClosureResult } from '@noeldemartin/utils';
|
|
8
7
|
|
|
9
|
-
export type CVAConfig<T> = NonNullable<
|
|
10
|
-
export type CVAProps<T> = NonNullable<
|
|
8
|
+
export type CVAConfig<T> = NonNullable<Parameters<typeof cva<T>>[1]>;
|
|
9
|
+
export type CVAProps<T> = NonNullable<Parameters<ReturnType<typeof cva<T>>>[0]>;
|
|
11
10
|
export type Variants<T extends Record<string, string | boolean>> = Required<{
|
|
12
11
|
[K in keyof T]: Exclude<T[K], undefined> extends string
|
|
13
12
|
? { [key in Exclude<T[K], undefined>]: string | null }
|
|
@@ -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/time.ts
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
|
+
import type { Nullable } from '@noeldemartin/utils';
|
|
2
|
+
|
|
1
3
|
export const MINUTE_MILLISECONDS = 60000;
|
|
2
|
-
|
|
4
|
+
|
|
5
|
+
export function getLocalTimezoneOffset(date?: Nullable<Date>): number {
|
|
6
|
+
return -(date ?? new Date()).getTimezoneOffset() * -MINUTE_MILLISECONDS;
|
|
7
|
+
}
|