@dynamicforms/vue-forms 0.16.0 → 0.17.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/dist/index.d.ts CHANGED
@@ -12,7 +12,7 @@ import { Ref } from 'vue';
12
12
  export declare class AbortEventHandlingException extends Error {
13
13
  }
14
14
 
15
- export declare class Action<T extends ActionValue = ActionValue, X extends object = {}> extends Field<T, X> {
15
+ export declare class Action<T extends ActionValue = ActionValue, X extends object = Omit<Extras, keyof ActionValue>> extends Field<T, X> {
16
16
  get [Symbol.toStringTag](): string;
17
17
  protected init(params?: IFieldParams<T, X>): void;
18
18
  /**
@@ -22,9 +22,9 @@ export declare class Action<T extends ActionValue = ActionValue, X extends objec
22
22
  * against a baseline that never carried the key.
23
23
  */
24
24
  private valueWith;
25
- get icon(): string | undefined;
26
- set icon(newValue: string | undefined);
27
- get label(): string | undefined;
25
+ get icon(): T['icon'];
26
+ set icon(newValue: T['icon']);
27
+ get label(): T['label'];
28
28
  /**
29
29
  * The two setters hand the value setter a new object rather than writing into the one the action holds, so each
30
30
  * is an ordinary value change: the handlers fire, isChanged answers over it, and a disabled action refuses it.
@@ -32,7 +32,7 @@ export declare class Action<T extends ActionValue = ActionValue, X extends objec
32
32
  * identity and every copy is a new object, so without the comparison here a write of the value already held
33
33
  * would announce a change and invalidate the value cache of every container above.
34
34
  */
35
- set label(newValue: string | undefined);
35
+ set label(newValue: T['label']);
36
36
  /** the counter behind `busy`, allocated for this action the first time it is asked for */
37
37
  private get busyRuns();
38
38
  /** true from the moment execute() is called until the handler it ran has settled, however it settles */
@@ -117,9 +117,19 @@ export declare class ActionsMap {
117
117
  private walk;
118
118
  }
119
119
 
120
+ /**
121
+ * The value an `Action` holds. Both members are `unknown` because `Action` states the concept and a UI library
122
+ * states what it renders: a subclass declares its value type with `label` and `icon` in whatever shape it renders
123
+ * them - `string | MdString`, a per-breakpoint object - and the accessors below answer at that type, because they
124
+ * read it off `T` rather than fixing one of their own.
125
+ *
126
+ * The consequence for an `Action` built without a type argument is that reading either member answers `unknown`
127
+ * and the reader states what it expects. That is the shape the class is for; an application that renders actions
128
+ * uses the subclass its UI library ships.
129
+ */
120
130
  export declare interface ActionValue {
121
- label?: string;
122
- icon?: string;
131
+ label?: unknown;
132
+ icon?: unknown;
123
133
  }
124
134
 
125
135
  /**
@@ -363,7 +373,31 @@ export declare class ExecuteAction extends FieldActionBase {
363
373
  execute(field: FieldBase, supr: FieldActionExecute, params: any): any;
364
374
  }
365
375
 
366
- export declare class Field<T = any, X extends object = {}> extends FieldBase<T, X> {
376
+ /**
377
+ * The extended properties an element carries when nothing states otherwise. It is empty as declared and exists
378
+ * to be augmented: the layer that renders the elements declares what it renders them with, and every element in
379
+ * the application then carries those properties without a type argument at any construction site.
380
+ *
381
+ * ```ts
382
+ * declare module '@dynamicforms/vue-forms' {
383
+ * interface Extras {
384
+ * label?: string;
385
+ * hint?: string;
386
+ * cssClass?: string;
387
+ * }
388
+ * }
389
+ * ```
390
+ *
391
+ * The interface is one per application, so two packages that both declare a property of the same name must give
392
+ * it the same type; declaration merging refuses a second declaration that differs.
393
+ *
394
+ * An element that states an X of its own replaces this rather than adding to it, so an element that carries both
395
+ * is `Field<string, Extras & Local>`.
396
+ */
397
+ export declare interface Extras {
398
+ }
399
+
400
+ export declare class Field<T = any, X extends object = Extras> extends FieldBase<T, X> {
367
401
  get [Symbol.toStringTag](): string;
368
402
  protected get state(): FieldSlots<T>;
369
403
  protected get raw(): FieldSlots<T>;
@@ -431,7 +465,7 @@ export declare abstract class FieldActionBase {
431
465
 
432
466
  export declare type FieldActionExecute<T = any> = (field: FieldBase<T>, ...params: any[]) => any;
433
467
 
434
- export declare abstract class FieldBase<T = any, X extends object = {}> {
468
+ export declare abstract class FieldBase<T = any, X extends object = Extras> {
435
469
  #private;
436
470
  /**
437
471
  * Vue's getTargetType answers INVALID for an object that carries __v_skip, so reactive() hands an element back
@@ -710,6 +744,25 @@ export declare abstract class FieldBase<T = any, X extends object = {}> {
710
744
  * different list whatever the items compare as - so the commit announces it without composing a comparison.
711
745
  */
712
746
  protected propagateValueChanged(force?: boolean): void;
747
+ /**
748
+ * The last step of a construction: it runs inside the transaction the construction is, with the parameters
749
+ * applied and the value in place, before the element records what it was built as.
750
+ *
751
+ * A subclass overrides it to complete what the element was built with. What it writes here is part of the
752
+ * construction rather than a change of it: the element announces no ValueChangedAction, and what the hook
753
+ * leaves is what its eager actions and its validators run over, once. An element whose parameters named no
754
+ * `originalValue` is baselined on the value the hook left and so starts unchanged; one that named a baseline is
755
+ * measured against it, as any element is. A `Field` writes
756
+ * `_value`, which reaches the slot on an element built `enabled: false` as well - the value setter, which a
757
+ * disabled field refuses, states a change, and this is not one.
758
+ *
759
+ * A container completes itself through its members, and a member carries a construction of its own: the write
760
+ * reaches it as any later one would, so the member announces it and reports itself changed. A member that is to
761
+ * start unchanged is baselined here as well - `this.fields.x.originalValue = this.fields.x.value`.
762
+ *
763
+ * `params` is the parameter object the constructor received, where it received one.
764
+ */
765
+ protected constructed(params?: object): void;
713
766
  /**
714
767
  * Re-reads the value that the next ValueChangedAction will report as the one it replaces. A leaf records what
715
768
  * it announced at every announcement, so its copy is always current and there is nothing to re-read; a
@@ -766,6 +819,22 @@ export declare abstract class FieldBase<T = any, X extends object = {}> {
766
819
  set visibility(newValue: DisplayMode);
767
820
  get enabled(): boolean;
768
821
  set enabled(newValue: boolean);
822
+ /**
823
+ * Whether this element and every container above it are enabled. A rendering layer binds one read instead of
824
+ * walking the parent chain: a disabled `Group` states that its section cannot be edited, and the inputs
825
+ * rendered from the members inside it read that here.
826
+ *
827
+ * It is a read and nothing else. `enabled` on each element stays exactly what was written to it, a write to a
828
+ * member of a disabled container is accepted the way it always was, and what a container serializes is decided
829
+ * by the members' own `enabled`. Where a whole subtree is to stop serializing, the members are disabled.
830
+ *
831
+ * `enabled` is the only member with a reading of this kind, and it is not a scheme the other members follow.
832
+ * `visibility` has none because `SUPPRESS` states that an element is absent from the value as well, so folding
833
+ * it down the tree would decide serialization rather than report it; `value` has none because a container
834
+ * composes its own from its members rather than passing one down. A rendering layer that needs a third thing
835
+ * folded down the tree has `provide`/`inject`, which is where the render tree's own context belongs.
836
+ */
837
+ get effectiveEnabled(): boolean;
769
838
  /**
770
839
  * True for an element whose value is composed of its members'. The commit builds such a value only where
771
840
  * something receives it, compares it by content rather than by identity, and runs the element's own validators
@@ -897,6 +966,7 @@ declare namespace Form {
897
966
  NullableField,
898
967
  IFieldConstructorActionsList,
899
968
  IFieldConstructorParams,
969
+ Extras,
900
970
  IFieldParams,
901
971
  IBindParams,
902
972
  AbortEventHandlingException,
@@ -952,7 +1022,7 @@ export declare type GenericFieldsInterface = Record<string, FieldBase>;
952
1022
  /** The current configuration. The object is the module's own record, and reading it again reports later writes. */
953
1023
  export declare function getConfig(): FormsConfig;
954
1024
 
955
- export declare class Group<T extends GenericFieldsInterface = GenericFieldsInterface, X extends object = {}> extends FieldBase<GroupValue<T>, X> {
1025
+ export declare class Group<T extends GenericFieldsInterface = GenericFieldsInterface, X extends object = Extras> extends FieldBase<GroupValue<T>, X> {
956
1026
  get [Symbol.toStringTag](): string;
957
1027
  protected get state(): GroupSlots<GroupValue<T>>;
958
1028
  protected get raw(): GroupSlots<GroupValue<T>>;
@@ -1086,7 +1156,7 @@ export declare type GroupValueInput<T extends GenericFieldsInterface> = Partial<
1086
1156
  * `validators` and `actions` are carried from the declaration rather than supplied, and `touched` and `errors`
1087
1157
  * are what the binding establishes for itself as it validates.
1088
1158
  */
1089
- export declare type IBindParams<T = any, X extends object = {}> = Partial<Pick<IFieldConstructorParams<T>, 'originalValue' | 'enabled' | 'visibility'>> & Partial<NoInfer<X>>;
1159
+ export declare type IBindParams<T = any, X extends object = Extras> = Partial<Pick<IFieldConstructorParams<T>, 'originalValue' | 'enabled' | 'visibility'>> & Partial<NoInfer<X>>;
1090
1160
 
1091
1161
  export declare interface IFieldConstructorActionsList {
1092
1162
  actions?: FieldActionBase[];
@@ -1113,15 +1183,14 @@ export declare type IFieldConstructorParams<T = any> = {
1113
1183
  * What an element's constructor accepts: the parameters the element answers for itself, together with the
1114
1184
  * extended properties its X parameter declares.
1115
1185
  *
1116
- * X is left out of inference, so an element built without a type argument carries no extended properties and a
1117
- * parameter object naming one is rejected as an excess property. A caller that wants them states them:
1118
- * `new Field<string, { label: string }>({ value: 'a', label: 'Name' })`.
1186
+ * X is left out of inference, so an element carries what its X states - `Extras` where no type argument replaces
1187
+ * it - and a parameter object naming anything else is rejected as an excess property.
1119
1188
  *
1120
1189
  * The two halves are made partial separately. `Partial<A & X>` is a mapped type over an intersection, which is
1121
1190
  * what T is inferred through, and inference through it answers with one constituent of a union rather than the
1122
1191
  * union: `new Field({ value: someStringOrNumber })` would be a Field<string>.
1123
1192
  */
1124
- export declare type IFieldParams<T = any, X extends object = {}> = Partial<IFieldConstructorParams<T>> & Partial<NoInfer<X>>;
1193
+ export declare type IFieldParams<T = any, X extends object = Extras> = Partial<IFieldConstructorParams<T>> & Partial<NoInfer<X>>;
1125
1194
 
1126
1195
  declare class InAllowedValues<T = any> extends Validator {
1127
1196
  constructor(allowedValues: AllowedValues<T>, message?: RenderContentRef);
@@ -1140,7 +1209,7 @@ declare class LengthInRange extends Validator {
1140
1209
  constructor(minLength: number, maxLength: number, message?: RenderContentRef);
1141
1210
  }
1142
1211
 
1143
- export declare class List<T extends GenericFieldsInterface = GenericFieldsInterface, X extends object = {}> extends FieldBase<ListValue, X> {
1212
+ export declare class List<T extends GenericFieldsInterface = GenericFieldsInterface, X extends object = Extras> extends FieldBase<ListValue, X> {
1144
1213
  get [Symbol.toStringTag](): string;
1145
1214
  protected get state(): ListSlots<T>;
1146
1215
  protected get raw(): ListSlots<T>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dynamicforms/vue-forms",
3
3
  "private": false,
4
- "version": "0.16.0",
4
+ "version": "0.17.0",
5
5
  "type": "module",
6
6
  "description": "A lightweight Vue.js library for form state management with built-in validation, conditional logic, nested structures, and a rich event system. UI-agnostic and TypeScript-first.",
7
7
  "author": "Jure Erzno\u017enik",