@neeloong/form 0.26.0 → 0.28.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.
- package/index.d.mts +37 -8
- package/index.full.js +186 -76
- package/index.full.min.js +6 -6
- package/index.full.min.mjs +4 -4
- package/index.min.mjs +2 -2
- package/index.mjs +186 -76
- package/package.json +1 -1
package/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @neeloong/form v0.
|
|
2
|
+
* @neeloong/form v0.28.0
|
|
3
3
|
* (c) 2024-2026 Fierflame
|
|
4
4
|
* @license Apache-2.0
|
|
5
5
|
*/
|
|
@@ -129,9 +129,10 @@ declare namespace StoreLayout {
|
|
|
129
129
|
relate?: ((store: Store, el: Element | StoreLayout.Relatedness) => () => void) | undefined;
|
|
130
130
|
editable?: boolean | undefined;
|
|
131
131
|
signal?: AbortSignal | undefined;
|
|
132
|
+
sanitizeHtml?: ((arg0: string) => string) | undefined;
|
|
132
133
|
call?: ((name: string, event: Event, store: Store<any, any, any>, options?: StoreLayout.Options | null) => void) | undefined;
|
|
133
134
|
};
|
|
134
|
-
type Renderer<T_1 = unknown> = (store: Store<any, any, any>, renderer?: T_1, options?: StoreLayout.Options | null) => HTMLElement | null;
|
|
135
|
+
type Renderer<T_1 = unknown> = (store: Store<any, any, any>, renderer?: T_1 | string, options?: StoreLayout.Options | null) => HTMLElement | null;
|
|
135
136
|
}
|
|
136
137
|
|
|
137
138
|
type Schema<M = any, S extends {
|
|
@@ -409,6 +410,31 @@ type Ref = {
|
|
|
409
410
|
[k: string]: Ref | undefined;
|
|
410
411
|
};
|
|
411
412
|
|
|
413
|
+
/** @import { Schema } from '../Schema.types.mjs' */
|
|
414
|
+
/**
|
|
415
|
+
* @template [T=any]
|
|
416
|
+
* @template [M=any]
|
|
417
|
+
* @template {Object.<string, Schema.State>} [S=Object.<string, Schema.State>]
|
|
418
|
+
* @extends {Store<T, M, S>}
|
|
419
|
+
*/
|
|
420
|
+
declare class BindObjectStore<T = any, M = any, S extends {
|
|
421
|
+
[x: string]: Schema.State;
|
|
422
|
+
} = {
|
|
423
|
+
[x: string]: Schema.State;
|
|
424
|
+
}> extends Store<T, M, S> {
|
|
425
|
+
/**
|
|
426
|
+
* @param {Schema<any, Object.<string, Schema.State>>} schema 数据结构模式
|
|
427
|
+
* @param {Store<T, M, S>} store
|
|
428
|
+
*/
|
|
429
|
+
constructor(schema: Schema<any, {
|
|
430
|
+
[x: string]: Schema.State;
|
|
431
|
+
}>, store: Store<T, M, S>);
|
|
432
|
+
[Symbol.iterator](): Generator<[string, Store<any, any, {
|
|
433
|
+
[x: string]: Schema.State;
|
|
434
|
+
}>], void, unknown>;
|
|
435
|
+
#private;
|
|
436
|
+
}
|
|
437
|
+
|
|
412
438
|
/** @import { Ref } from './ref.mjs' */
|
|
413
439
|
/** @import { Schema } from '../Schema.types.mjs' */
|
|
414
440
|
/** @import { StoreLayout } from '../StoreLayout.types.mjs' */
|
|
@@ -449,7 +475,7 @@ declare class Store<T = any, M = any, S extends {
|
|
|
449
475
|
new (...p: ConstructorParameters<typeof Store>): Store;
|
|
450
476
|
}): void;
|
|
451
477
|
/**
|
|
452
|
-
* @param {Schema.Field<M, S>} schema 字段的 Schema 定义
|
|
478
|
+
* @param {Schema.Field<M, S> | Store<T,M,S>} schema 字段的 Schema 定义
|
|
453
479
|
* @param {object} [options] 可选配置
|
|
454
480
|
* @param {Store?} [options.parent]
|
|
455
481
|
* @param {Partial<S>?} [options.states]
|
|
@@ -485,7 +511,7 @@ declare class Store<T = any, M = any, S extends {
|
|
|
485
511
|
*
|
|
486
512
|
* @param {((value: T?, index: any, store: Store) => void)?} [options.onUpdate]
|
|
487
513
|
*/
|
|
488
|
-
constructor(schema: Schema.Field<M, S>, { null: isNull, ref, default: defaultValue, setValue, convert, onUpdate, states, validator, validators, index, size, new: isNew, parent: parentNode, hidden, clearable, required, disabled, readonly, removable, label, description, placeholder, min, max, step, minLength, maxLength, pattern, values }?: {
|
|
514
|
+
constructor(schema: Schema.Field<M, S> | Store<T, M, S>, { null: isNull, ref, default: defaultValue, setValue, convert, onUpdate, states, validator, validators, index, size, new: isNew, parent: parentNode, hidden, clearable, required, disabled, readonly, removable, label, description, placeholder, min, max, step, minLength, maxLength, pattern, values }?: {
|
|
489
515
|
parent?: Store<any, any, {
|
|
490
516
|
[x: string]: Schema.State;
|
|
491
517
|
}> | null | undefined;
|
|
@@ -539,11 +565,13 @@ declare class Store<T = any, M = any, S extends {
|
|
|
539
565
|
convert?: ((value: any) => any) | null | undefined;
|
|
540
566
|
onUpdate?: ((value: T | null, index: any, store: Store) => void) | null | undefined;
|
|
541
567
|
});
|
|
568
|
+
get schema(): Schema.Field<M, S>;
|
|
542
569
|
/**
|
|
543
570
|
* 触发事件并通知监听器
|
|
544
571
|
* @template {keyof Schema.Events} K
|
|
545
572
|
* @param {K} event
|
|
546
573
|
* @param {Schema.Events[K]} value
|
|
574
|
+
* @returns {boolean}
|
|
547
575
|
*/
|
|
548
576
|
emit<K extends keyof Schema.Events>(event: K, value: Schema.Events[K]): boolean;
|
|
549
577
|
/**
|
|
@@ -559,7 +587,6 @@ declare class Store<T = any, M = any, S extends {
|
|
|
559
587
|
/** 存储类类别,继承的自定义类需要设置自定义的此只读属性 */
|
|
560
588
|
get kind(): string;
|
|
561
589
|
get ref(): Ref;
|
|
562
|
-
schema: Schema.Field<M, S>;
|
|
563
590
|
get states(): S | null;
|
|
564
591
|
get layout(): StoreLayout.Field<any>;
|
|
565
592
|
/** @param {any} [value] @returns {any} */
|
|
@@ -699,17 +726,19 @@ declare class Store<T = any, M = any, S extends {
|
|
|
699
726
|
* @template [M=any]
|
|
700
727
|
* @template {Object.<string, Schema.State>} [S=Object.<string, Schema.State>]
|
|
701
728
|
* @param {Schema<M, S>} schema 数据结构模式
|
|
729
|
+
* @param {AbortSignal} [signal]
|
|
730
|
+
* @returns {BindObjectStore}
|
|
702
731
|
*/
|
|
703
732
|
bindObject<M_1 = any, S_1 extends {
|
|
704
733
|
[x: string]: Schema.State;
|
|
705
734
|
} = {
|
|
706
735
|
[x: string]: Schema.State;
|
|
707
|
-
}>(schema: Schema<M_1, S_1
|
|
736
|
+
}>(schema: Schema<M_1, S_1>, signal?: AbortSignal): BindObjectStore;
|
|
737
|
+
/** 内容是否已改变 */
|
|
738
|
+
get changed(): boolean;
|
|
708
739
|
set value(v: T | null);
|
|
709
740
|
/** 字段当前值 */
|
|
710
741
|
get value(): T | null;
|
|
711
|
-
/** 内容是否已改变 */
|
|
712
|
-
get changed(): boolean;
|
|
713
742
|
/** 重置数据 */
|
|
714
743
|
reset(value?: unknown, isNew?: boolean): void;
|
|
715
744
|
/**
|
package/index.full.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @neeloong/form v0.
|
|
2
|
+
* @neeloong/form v0.28.0
|
|
3
3
|
* (c) 2024-2026 Fierflame
|
|
4
4
|
* @license Apache-2.0
|
|
5
5
|
*/
|
|
@@ -716,7 +716,7 @@
|
|
|
716
716
|
|
|
717
717
|
|
|
718
718
|
/** @type {{new(...p: ConstructorParameters<typeof Store>): Store}?} */
|
|
719
|
-
let ObjectStore$
|
|
719
|
+
let ObjectStore$2 = null;
|
|
720
720
|
/** @type {{new(...p: ConstructorParameters<typeof Store>): ArrayStore}?} */
|
|
721
721
|
let ArrayStoreClass = null;
|
|
722
722
|
/** @type {Record<string, {new(...p: ConstructorParameters<typeof Store>): Store}?>} */
|
|
@@ -741,14 +741,14 @@
|
|
|
741
741
|
const C = TypeStores[type];
|
|
742
742
|
if (C) { Class = C; }
|
|
743
743
|
} else if (type && typeof type === 'object') {
|
|
744
|
-
if (ObjectStore$
|
|
744
|
+
if (ObjectStore$2) { Class = ObjectStore$2; }
|
|
745
745
|
}
|
|
746
746
|
return new Class(schema, options);
|
|
747
747
|
}
|
|
748
748
|
|
|
749
749
|
/** @param {{new(...p: ConstructorParameters<typeof Store>): Store}} Class */
|
|
750
750
|
function setObjectStore(Class) {
|
|
751
|
-
ObjectStore$
|
|
751
|
+
ObjectStore$2 = Class;
|
|
752
752
|
}
|
|
753
753
|
|
|
754
754
|
/** @param {{new(...p: ConstructorParameters<typeof Store>): ArrayStore}} Class */
|
|
@@ -870,6 +870,52 @@
|
|
|
870
870
|
return (value) => structuredClone(def(store, value));
|
|
871
871
|
}
|
|
872
872
|
|
|
873
|
+
/** @import { Schema } from '../Schema.types.mjs' */
|
|
874
|
+
|
|
875
|
+
/**
|
|
876
|
+
* @template [T=any]
|
|
877
|
+
* @template [M=any]
|
|
878
|
+
* @template {Object.<string, Schema.State>} [S=Object.<string, Schema.State>]
|
|
879
|
+
* @extends {Store<T, M, S>}
|
|
880
|
+
*/
|
|
881
|
+
class BindObjectStore extends Store {
|
|
882
|
+
|
|
883
|
+
get kind() { return 'object'; }
|
|
884
|
+
/** @type {Record<string, Store>} */
|
|
885
|
+
#children = Object.create(null);
|
|
886
|
+
*[Symbol.iterator]() { yield* Object.entries(this.#children); }
|
|
887
|
+
/**
|
|
888
|
+
*
|
|
889
|
+
* @param {string | number} key
|
|
890
|
+
* @returns {Store?}
|
|
891
|
+
*/
|
|
892
|
+
child(key) { return this.#children[key] || null; }
|
|
893
|
+
/**
|
|
894
|
+
* @param {Schema<any, Object.<string, Schema.State>>} schema 数据结构模式
|
|
895
|
+
* @param {Store<T, M, S>} store
|
|
896
|
+
*/
|
|
897
|
+
constructor(schema, store) {
|
|
898
|
+
super(store);
|
|
899
|
+
const children = this.#children;
|
|
900
|
+
for (const [index, field] of Object.entries(schema)) {
|
|
901
|
+
const bindStore = create(field, {
|
|
902
|
+
index, parent: this,
|
|
903
|
+
/** @param {*} value @param {*} index @param {Store} store */
|
|
904
|
+
onUpdate: (value, index, store) => {
|
|
905
|
+
if (store !== children[index]) { return; }
|
|
906
|
+
const val = this.value ?? null;
|
|
907
|
+
if (typeof val !== 'object' || Array.isArray(val)) { return; }
|
|
908
|
+
// @ts-ignore
|
|
909
|
+
this.value = { ...val, [index]: value };
|
|
910
|
+
},
|
|
911
|
+
});
|
|
912
|
+
children[index] = bindStore;
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
// @ts-ignore
|
|
917
|
+
setObjectStore(ObjectStore);
|
|
918
|
+
|
|
873
919
|
/** @import { Ref } from './ref.mjs' */
|
|
874
920
|
/** @import { Schema } from '../Schema.types.mjs' */
|
|
875
921
|
/** @import { StoreLayout } from '../StoreLayout.types.mjs' */
|
|
@@ -881,6 +927,12 @@
|
|
|
881
927
|
* @template {Object.<string, Schema.State>} [S=Object.<string, Schema.State>]
|
|
882
928
|
*/
|
|
883
929
|
class Store {
|
|
930
|
+
/** @type {Store<T, M, S>?} */
|
|
931
|
+
#originStore = null;
|
|
932
|
+
|
|
933
|
+
/** @type {Schema.Field<M, S>} 字段的 Schema 定义 */
|
|
934
|
+
#schema;
|
|
935
|
+
get schema() { return this.#schema; }
|
|
884
936
|
/** @type {Map<string, Set<(value: any, store: any) => void | boolean | null>>} */
|
|
885
937
|
#events = new Map();
|
|
886
938
|
/**
|
|
@@ -888,8 +940,11 @@
|
|
|
888
940
|
* @template {keyof Schema.Events} K
|
|
889
941
|
* @param {K} event
|
|
890
942
|
* @param {Schema.Events[K]} value
|
|
943
|
+
* @returns {boolean}
|
|
891
944
|
*/
|
|
892
945
|
emit(event, value) {
|
|
946
|
+
const originStore = this.#originStore;
|
|
947
|
+
if (originStore) { return originStore.emit(event, value); }
|
|
893
948
|
const key = typeof event === 'number' ? String(event) : event;
|
|
894
949
|
const events = this.#events;
|
|
895
950
|
let canceled = false;
|
|
@@ -906,6 +961,8 @@
|
|
|
906
961
|
* @returns {() => void}
|
|
907
962
|
*/
|
|
908
963
|
listen(event, listener) {
|
|
964
|
+
const originStore = this.#originStore;
|
|
965
|
+
if (originStore) { return originStore.listen(event, p => listener.call(this, p, this)); }
|
|
909
966
|
const fn = listener.bind(this);
|
|
910
967
|
const events = this.#events;
|
|
911
968
|
const key = typeof event === 'number' ? String(event) : event;
|
|
@@ -946,7 +1003,7 @@
|
|
|
946
1003
|
#ref = null;
|
|
947
1004
|
get ref() { return this.#ref || createRef(this); }
|
|
948
1005
|
/**
|
|
949
|
-
* @param {Schema.Field<M, S>} schema 字段的 Schema 定义
|
|
1006
|
+
* @param {Schema.Field<M, S> | Store<T,M,S>} schema 字段的 Schema 定义
|
|
950
1007
|
* @param {object} [options] 可选配置
|
|
951
1008
|
* @param {Store?} [options.parent]
|
|
952
1009
|
* @param {Partial<S>?} [options.states]
|
|
@@ -990,7 +1047,74 @@
|
|
|
990
1047
|
hidden, clearable, required, disabled, readonly, removable,
|
|
991
1048
|
label, description, placeholder, min, max, step, minLength, maxLength, pattern, values: values$1
|
|
992
1049
|
} = {}) {
|
|
993
|
-
|
|
1050
|
+
if (schema instanceof Store) {
|
|
1051
|
+
this.#originStore = schema;
|
|
1052
|
+
this.#schema = schema.#schema;
|
|
1053
|
+
this.#null = schema.#null;
|
|
1054
|
+
this.#ref = schema.#ref;
|
|
1055
|
+
this.#states = schema.#states;
|
|
1056
|
+
this.#layout = schema.#layout;
|
|
1057
|
+
this.#createDefault = schema.#createDefault;
|
|
1058
|
+
this.#setValue = schema.#setValue;
|
|
1059
|
+
this.#convert = schema.#convert;
|
|
1060
|
+
this.#onUpdate = schema.#onUpdate;
|
|
1061
|
+
this.#parent = schema.#parent;
|
|
1062
|
+
this.#root = schema.#root;
|
|
1063
|
+
this.#type = schema.#type;
|
|
1064
|
+
this.#meta = schema.#meta;
|
|
1065
|
+
this.#component = schema.#component;
|
|
1066
|
+
this.#selfLoading = schema.#selfLoading;
|
|
1067
|
+
this.#loading = schema.#loading;
|
|
1068
|
+
this.#size = schema.#size;
|
|
1069
|
+
this.#index = schema.#index;
|
|
1070
|
+
this.#creatable = schema.#creatable;
|
|
1071
|
+
this.#immutable = schema.#immutable;
|
|
1072
|
+
this.#new = schema.#new;
|
|
1073
|
+
this.#selfNew = schema.#selfNew;
|
|
1074
|
+
this.#selfHidden = schema.#selfHidden;
|
|
1075
|
+
this.#hidden = schema.#hidden;
|
|
1076
|
+
this.#selfClearable = schema.#selfClearable;
|
|
1077
|
+
this.#clearable = schema.#clearable;
|
|
1078
|
+
this.#selfRequired = schema.#selfRequired;
|
|
1079
|
+
this.#required = schema.#required;
|
|
1080
|
+
this.#selfDisabled = schema.#selfDisabled;
|
|
1081
|
+
this.#disabled = schema.#disabled;
|
|
1082
|
+
this.#selfReadonly = schema.#selfReadonly;
|
|
1083
|
+
this.#readonly = schema.#readonly;
|
|
1084
|
+
this.#selfRemovable = schema.#selfRemovable;
|
|
1085
|
+
this.#removable = schema.#removable;
|
|
1086
|
+
this.#selfLabel = schema.#selfLabel;
|
|
1087
|
+
this.#label = schema.#label;
|
|
1088
|
+
this.#selfDescription = schema.#selfDescription;
|
|
1089
|
+
this.#description = schema.#description;
|
|
1090
|
+
this.#selfPlaceholder = schema.#selfPlaceholder;
|
|
1091
|
+
this.#placeholder = schema.#placeholder;
|
|
1092
|
+
this.#selfMin = schema.#selfMin;
|
|
1093
|
+
this.#min = schema.#min;
|
|
1094
|
+
this.#selfMax = schema.#selfMax;
|
|
1095
|
+
this.#max = schema.#max;
|
|
1096
|
+
this.#selfStep = schema.#selfStep;
|
|
1097
|
+
this.#step = schema.#step;
|
|
1098
|
+
this.#selfMinLength = schema.#selfMinLength;
|
|
1099
|
+
this.#minLength = schema.#minLength;
|
|
1100
|
+
this.#selfMaxLength = schema.#selfMaxLength;
|
|
1101
|
+
this.#maxLength = schema.#maxLength;
|
|
1102
|
+
this.#selfPattern = schema.#selfPattern;
|
|
1103
|
+
this.#pattern = schema.#pattern;
|
|
1104
|
+
this.#selfValues = schema.#selfValues;
|
|
1105
|
+
this.#values = schema.#values;
|
|
1106
|
+
this.#errors = schema.#errors;
|
|
1107
|
+
this.#validatorResult = schema.#validatorResult;
|
|
1108
|
+
this.#changed = schema.#changed;
|
|
1109
|
+
this.#blurred = schema.#blurred;
|
|
1110
|
+
this.#cancelChange = schema.#cancelChange;
|
|
1111
|
+
this.#cancelBlur = schema.#cancelBlur;
|
|
1112
|
+
this.#set = schema.#set;
|
|
1113
|
+
this.#initValue = schema.#initValue;
|
|
1114
|
+
this.#value = schema.#value;
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1117
|
+
this.#schema = schema;
|
|
994
1118
|
const parent = parentNode instanceof Store ? parentNode : null;
|
|
995
1119
|
if (parent) {
|
|
996
1120
|
this.#parent = parent;
|
|
@@ -1118,6 +1242,7 @@
|
|
|
1118
1242
|
/** @type {StoreLayout.Field<any>} */
|
|
1119
1243
|
#layout;
|
|
1120
1244
|
get layout() { return this.#layout; }
|
|
1245
|
+
/** @type {(value?: any) => unknown} */
|
|
1121
1246
|
#createDefault;
|
|
1122
1247
|
/** @param {any} [value] @returns {any} */
|
|
1123
1248
|
createDefault(value) { return this.#createDefault(value); }
|
|
@@ -1399,40 +1524,26 @@
|
|
|
1399
1524
|
#initValue = new exports.Signal.State(/** @type {T?} */(null));
|
|
1400
1525
|
#value = new exports.Signal.State(this.#initValue.get());
|
|
1401
1526
|
|
|
1527
|
+
/** @type {Set<Store>} */
|
|
1528
|
+
#subBindStores = new Set();
|
|
1402
1529
|
/**
|
|
1403
1530
|
* @template [M=any]
|
|
1404
1531
|
* @template {Object.<string, Schema.State>} [S=Object.<string, Schema.State>]
|
|
1405
1532
|
* @param {Schema<M, S>} schema 数据结构模式
|
|
1533
|
+
* @param {AbortSignal} [signal]
|
|
1534
|
+
* @returns {BindObjectStore}
|
|
1406
1535
|
*/
|
|
1407
|
-
bindObject(schema) {
|
|
1408
|
-
const
|
|
1409
|
-
|
|
1410
|
-
const
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
onUpdate: (value, currentIndex, store) => {
|
|
1416
|
-
if (index !== currentIndex) { return; }
|
|
1417
|
-
if (bindStores.has(store)) { return; }
|
|
1418
|
-
const val = this.#value ?? null;
|
|
1419
|
-
if (typeof val !== 'object' || Array.isArray(val)) { return }
|
|
1420
|
-
// @ts-ignore
|
|
1421
|
-
this.value = { ...val, [currentIndex]: value };
|
|
1422
|
-
},
|
|
1423
|
-
});
|
|
1424
|
-
list.push(bindStore);
|
|
1425
|
-
bindStores.set(bindStore, index);
|
|
1426
|
-
}
|
|
1536
|
+
bindObject(schema, signal) {
|
|
1537
|
+
const originStore = this.#originStore;
|
|
1538
|
+
if (originStore) { return originStore.bindObject(schema, signal); }
|
|
1539
|
+
const store = new BindObjectStore(schema, this);
|
|
1540
|
+
if (signal?.aborted) { return store; }
|
|
1541
|
+
const subBindStores = this.#subBindStores;
|
|
1542
|
+
subBindStores.add(store);
|
|
1543
|
+
signal?.addEventListener('abort', () => subBindStores.delete(store));
|
|
1427
1544
|
this.#requestUpdate();
|
|
1428
|
-
return
|
|
1429
|
-
for (const bindStore of list) {
|
|
1430
|
-
bindStores.delete(bindStore);
|
|
1431
|
-
}
|
|
1432
|
-
};
|
|
1545
|
+
return store;
|
|
1433
1546
|
}
|
|
1434
|
-
/** @type {Map<Store, string>} */
|
|
1435
|
-
#bindStores = new Map();
|
|
1436
1547
|
|
|
1437
1548
|
/** 内容是否已改变 */
|
|
1438
1549
|
get changed() { return !Object.is(this.#value.get(), this.#initValue.get()); }
|
|
@@ -1440,6 +1551,8 @@
|
|
|
1440
1551
|
/** 字段当前值 */
|
|
1441
1552
|
get value() { return this.#value.get(); }
|
|
1442
1553
|
set value(v) {
|
|
1554
|
+
const originStore = this.#originStore;
|
|
1555
|
+
if (originStore) { originStore.value = v; return; }
|
|
1443
1556
|
const newValue = this.#setValue?.(v);
|
|
1444
1557
|
const val = newValue === undefined ? v : newValue;
|
|
1445
1558
|
this.#value.set(val);
|
|
@@ -1460,6 +1573,8 @@
|
|
|
1460
1573
|
}
|
|
1461
1574
|
/** 重置数据 */
|
|
1462
1575
|
reset(value = this.#set ? this.#initValue.get() : this.#createDefault(), isNew = this.#selfNew.get()) {
|
|
1576
|
+
const originStore = this.#originStore;
|
|
1577
|
+
if (originStore) { originStore.reset(value, isNew); return; }
|
|
1463
1578
|
this.#reset(value, Boolean(isNew));
|
|
1464
1579
|
}
|
|
1465
1580
|
/**
|
|
@@ -1476,11 +1591,10 @@
|
|
|
1476
1591
|
this.#cancelBlur();
|
|
1477
1592
|
this.#set = true;
|
|
1478
1593
|
if (!value || typeof value !== 'object') {
|
|
1479
|
-
for (const [,
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
field.#reset(null, false);
|
|
1594
|
+
for (const bind of [this, ...this.#subBindStores]) {
|
|
1595
|
+
for (const [, field] of bind) {
|
|
1596
|
+
field.#reset(null, false);
|
|
1597
|
+
}
|
|
1484
1598
|
}
|
|
1485
1599
|
this.#value.set(value);
|
|
1486
1600
|
this.#initValue.set(value);
|
|
@@ -1489,11 +1603,10 @@
|
|
|
1489
1603
|
}
|
|
1490
1604
|
/** @type {*} */
|
|
1491
1605
|
const newValues = Array.isArray(value) ? [...value] : { ...value };
|
|
1492
|
-
for (const [
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
newValues[key] = field.#reset(Object.hasOwn(newValues, key) ? newValues[key] : undefined, false);
|
|
1606
|
+
for (const bind of [this, ...this.#subBindStores]) {
|
|
1607
|
+
for (const [key, field] of bind) {
|
|
1608
|
+
newValues[key] = field.#reset(Object.hasOwn(newValues, key) ? newValues[key] : undefined, false);
|
|
1609
|
+
}
|
|
1497
1610
|
}
|
|
1498
1611
|
this.#value.set(newValues);
|
|
1499
1612
|
this.#initValue.set(newValues);
|
|
@@ -1527,23 +1640,16 @@
|
|
|
1527
1640
|
// @ts-ignore
|
|
1528
1641
|
let newValues = Array.isArray(val) ? [...val] : { ...val };
|
|
1529
1642
|
let updated = false;
|
|
1530
|
-
for (const
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
// @ts-ignore
|
|
1541
|
-
const data = Object.hasOwn(val, key) ? val[key] : undefined;
|
|
1542
|
-
const newData = field.#toUpdate(data);
|
|
1543
|
-
if (Object.is(data, newData)) { continue; }
|
|
1544
|
-
// @ts-ignore
|
|
1545
|
-
newValues[key] = newData;
|
|
1546
|
-
updated = true;
|
|
1643
|
+
for (const bind of [this,...this.#subBindStores]) {
|
|
1644
|
+
for (const [key, field] of bind) {
|
|
1645
|
+
// @ts-ignore
|
|
1646
|
+
const data = Object.hasOwn(val, key) ? val[key] : undefined;
|
|
1647
|
+
const newData = field.#toUpdate(data);
|
|
1648
|
+
if (Object.is(data, newData)) { continue; }
|
|
1649
|
+
// @ts-ignore
|
|
1650
|
+
newValues[key] = newData;
|
|
1651
|
+
updated = true;
|
|
1652
|
+
}
|
|
1547
1653
|
}
|
|
1548
1654
|
if (updated) {
|
|
1549
1655
|
val = newValues;
|
|
@@ -1577,6 +1683,7 @@
|
|
|
1577
1683
|
*/
|
|
1578
1684
|
validate(path) {
|
|
1579
1685
|
if (path === true) {
|
|
1686
|
+
if (this.#originStore) { return Promise.resolve(null); }
|
|
1580
1687
|
return Promise.all([this.#validatorResult.get(), this.#changed(), this.#blurred()])
|
|
1581
1688
|
.then(v => {
|
|
1582
1689
|
const errors = v.flat();
|
|
@@ -1584,7 +1691,7 @@
|
|
|
1584
1691
|
});
|
|
1585
1692
|
}
|
|
1586
1693
|
const selfPath = Array.isArray(path) ? path : [];
|
|
1587
|
-
if (this.#hidden.get()) { return Promise.resolve([]); }
|
|
1694
|
+
if (!this.#originStore && this.#hidden.get()) { return Promise.resolve([]); }
|
|
1588
1695
|
const list = [this.validate(true).then(errors => {
|
|
1589
1696
|
if (!errors?.length) { return []; }
|
|
1590
1697
|
return [{ path: [...selfPath], store: /** @type {Store} */(this), errors }];
|
|
@@ -1592,8 +1699,8 @@
|
|
|
1592
1699
|
for (const [key, field] of this) {
|
|
1593
1700
|
list.push(field.validate([...selfPath, key]));
|
|
1594
1701
|
}
|
|
1595
|
-
for (const
|
|
1596
|
-
list.push(
|
|
1702
|
+
for (const sub of this.#subBindStores) {
|
|
1703
|
+
list.push(sub.validate(selfPath));
|
|
1597
1704
|
}
|
|
1598
1705
|
return Promise.all(list).then(v => v.flat());
|
|
1599
1706
|
}
|
|
@@ -1607,7 +1714,7 @@
|
|
|
1607
1714
|
* @template {Object.<string, Schema.State>} [S=Object.<string, Schema.State>]
|
|
1608
1715
|
* @extends {Store<T, M, S>}
|
|
1609
1716
|
*/
|
|
1610
|
-
class ObjectStore extends Store {
|
|
1717
|
+
let ObjectStore$1 = class ObjectStore extends Store {
|
|
1611
1718
|
get kind() { return 'object'; }
|
|
1612
1719
|
/** @type {Record<string, Store>} */
|
|
1613
1720
|
#children;
|
|
@@ -1660,9 +1767,9 @@
|
|
|
1660
1767
|
}
|
|
1661
1768
|
this.#children = children;
|
|
1662
1769
|
}
|
|
1663
|
-
}
|
|
1770
|
+
};
|
|
1664
1771
|
// @ts-ignore
|
|
1665
|
-
setObjectStore(ObjectStore);
|
|
1772
|
+
setObjectStore(ObjectStore$1);
|
|
1666
1773
|
|
|
1667
1774
|
/** @import { Schema } from '../Schema.types.mjs' */
|
|
1668
1775
|
|
|
@@ -5332,7 +5439,7 @@
|
|
|
5332
5439
|
if (list instanceof ArrayStore) {
|
|
5333
5440
|
return renderArray(parent, next, list, env, r, layout.sort);
|
|
5334
5441
|
}
|
|
5335
|
-
if (list instanceof ObjectStore) {
|
|
5442
|
+
if (list instanceof ObjectStore$1) {
|
|
5336
5443
|
return renderObject(parent, next, list, env, r, layout.sort);
|
|
5337
5444
|
}
|
|
5338
5445
|
if (typeof list === 'function') {
|
|
@@ -5441,6 +5548,8 @@
|
|
|
5441
5548
|
if (tagName === 'nl-form-field') {
|
|
5442
5549
|
const field = node.getAttribute('name') || '';
|
|
5443
5550
|
const mode = node.getAttribute('mode') || '';
|
|
5551
|
+
const renderer = node.getAttribute('renderer') || '';
|
|
5552
|
+
const editable = options?.editable && !node.hasAttribute('non-editable');
|
|
5444
5553
|
const fieldStore = field ? store.child(field) : store;
|
|
5445
5554
|
if (!fieldStore) { return; }
|
|
5446
5555
|
/** @type {HTMLElement?} */
|
|
@@ -5450,11 +5559,11 @@
|
|
|
5450
5559
|
const fieldLayout = field
|
|
5451
5560
|
? layout?.fields?.find(createFieldFilter(field)) || fieldStore.layout
|
|
5452
5561
|
: { ...layout, html: '' };
|
|
5453
|
-
el = Form(fieldStore, fieldRenderer, fieldLayout, options);
|
|
5562
|
+
el = Form(fieldStore, fieldRenderer, fieldLayout, {...options, editable});
|
|
5454
5563
|
break;
|
|
5455
5564
|
}
|
|
5456
5565
|
default: {
|
|
5457
|
-
el = fieldRenderer(fieldStore, layout.renderer, options);
|
|
5566
|
+
el = fieldRenderer(fieldStore, renderer || layout.renderer, {...options, editable});
|
|
5458
5567
|
break;
|
|
5459
5568
|
}
|
|
5460
5569
|
}
|
|
@@ -5656,9 +5765,10 @@
|
|
|
5656
5765
|
/**
|
|
5657
5766
|
*
|
|
5658
5767
|
* @param {string | ParentNode | null} [html]
|
|
5768
|
+
* @param {function(string): string} [sanitize]
|
|
5659
5769
|
* @returns {ParentNode}
|
|
5660
5770
|
*/
|
|
5661
|
-
function getHtmlContent(html) {
|
|
5771
|
+
function getHtmlContent(html, sanitize) {
|
|
5662
5772
|
if (!html) {
|
|
5663
5773
|
return document.createElement('template').content;
|
|
5664
5774
|
}
|
|
@@ -5666,7 +5776,7 @@
|
|
|
5666
5776
|
return /** @type {ParentNode} */(html.cloneNode(true));
|
|
5667
5777
|
}
|
|
5668
5778
|
const template = document.createElement('template');
|
|
5669
|
-
template.innerHTML = html;
|
|
5779
|
+
template.innerHTML = sanitize ? sanitize(html) : html;
|
|
5670
5780
|
return template.content;
|
|
5671
5781
|
}
|
|
5672
5782
|
|
|
@@ -5683,7 +5793,7 @@
|
|
|
5683
5793
|
if (options?.signal?.aborted) { return null; }
|
|
5684
5794
|
const html = layout.html;
|
|
5685
5795
|
if (html) {
|
|
5686
|
-
const content = getHtmlContent(html);
|
|
5796
|
+
const content = getHtmlContent(html, options?.sanitizeHtml);
|
|
5687
5797
|
renderHtml(store, fieldRenderer, content, options, layout);
|
|
5688
5798
|
return content;
|
|
5689
5799
|
}
|
|
@@ -6860,7 +6970,7 @@
|
|
|
6860
6970
|
* @returns {ParentNode}
|
|
6861
6971
|
*/
|
|
6862
6972
|
function Html(html, store, fieldRenderer, options, layout) {
|
|
6863
|
-
const htmlContent = getHtmlContent(html);
|
|
6973
|
+
const htmlContent = getHtmlContent(html, options?.sanitizeHtml);
|
|
6864
6974
|
renderHtml(store, fieldRenderer, htmlContent, options, layout);
|
|
6865
6975
|
return htmlContent;
|
|
6866
6976
|
}
|
|
@@ -6967,7 +7077,7 @@
|
|
|
6967
7077
|
const html = layout.html;
|
|
6968
7078
|
if (!html) { return null; }
|
|
6969
7079
|
const [root, content] = createCell(options?.signal, layout, store);
|
|
6970
|
-
const htmlContent = getHtmlContent(html);
|
|
7080
|
+
const htmlContent = getHtmlContent(html, options?.sanitizeHtml);
|
|
6971
7081
|
renderHtml(store, fieldRenderer, htmlContent, options, layout);
|
|
6972
7082
|
content.appendChild(htmlContent);
|
|
6973
7083
|
return root;
|
|
@@ -7053,7 +7163,7 @@
|
|
|
7053
7163
|
Form(store, fieldRenderer, storeLayout, options || null, root);
|
|
7054
7164
|
return;
|
|
7055
7165
|
}
|
|
7056
|
-
const content = getHtmlContent(html);
|
|
7166
|
+
const content = getHtmlContent(html, options?.sanitizeHtml);
|
|
7057
7167
|
renderHtml(store, fieldRenderer, content, options || null, storeLayout);
|
|
7058
7168
|
root.appendChild(content);
|
|
7059
7169
|
options?.signal?.addEventListener('abort', () => {
|
|
@@ -7063,7 +7173,7 @@
|
|
|
7063
7173
|
|
|
7064
7174
|
exports.ArrayStore = ArrayStore;
|
|
7065
7175
|
exports.Layout = index;
|
|
7066
|
-
exports.ObjectStore = ObjectStore;
|
|
7176
|
+
exports.ObjectStore = ObjectStore$1;
|
|
7067
7177
|
exports.Store = Store;
|
|
7068
7178
|
exports.effect = effect;
|
|
7069
7179
|
exports.render = render;
|