@xyo-network/react-form-group 7.4.2 → 7.5.1

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.
@@ -1,4 +1,4 @@
1
- import type { EmptyObject } from '@xylabs/object';
1
+ import type { EmptyObject } from '@xylabs/sdk-js';
2
2
  import type { AbstractControl } from './AbstractControl.ts';
3
3
  export type CursorPosition = {
4
4
  current: number | undefined;
@@ -1,4 +1,4 @@
1
- import type { EmptyObject } from '@xylabs/object';
1
+ import type { EmptyObject } from '@xylabs/sdk-js';
2
2
  import { AbstractControl } from './AbstractControl.ts';
3
3
  import type { SetOptions } from './accessor/index.ts';
4
4
  import type { CursorPosition, FormControl } from './FormControl.ts';
@@ -1,9 +1,12 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
1
4
  // src/context/Context.ts
2
5
  import { createContextEx } from "@xylabs/react-shared";
3
6
  var FormGroupBaseContext = createContextEx();
4
7
 
5
8
  // src/context/Provider.tsx
6
- import { useMemo } from "react";
9
+ import React, { useMemo } from "react";
7
10
 
8
11
  // src/FormGroup.ts
9
12
  import { forget as forget3 } from "@xylabs/forget";
@@ -14,11 +17,19 @@ import { forget as forget2 } from "@xylabs/forget";
14
17
  // src/control/accessor/ControlValueAccessorBase.ts
15
18
  import { forget } from "@xylabs/forget";
16
19
  import { ModuleBaseEmitter } from "@xyo-network/module-event-emitter";
17
- var DefaultSetOptions = { disableEmit: false };
20
+ var DefaultSetOptions = {
21
+ disableEmit: false
22
+ };
18
23
  var ControlValueAccessorBase = class extends ModuleBaseEmitter {
24
+ static {
25
+ __name(this, "ControlValueAccessorBase");
26
+ }
19
27
  _error = "";
20
28
  _previousValue = void 0;
21
- _serializeSettings = { sensitive: false, serializable: false };
29
+ _serializeSettings = {
30
+ sensitive: false,
31
+ serializable: false
32
+ };
22
33
  _touched = false;
23
34
  _value = void 0;
24
35
  config;
@@ -27,92 +38,94 @@ var ControlValueAccessorBase = class extends ModuleBaseEmitter {
27
38
  this.config = config;
28
39
  }
29
40
  /**
30
- * The error message for the control.
31
- */
41
+ * The error message for the control.
42
+ */
32
43
  get error() {
33
44
  return this._error;
34
45
  }
35
46
  /**
36
- * The "previous value" of the input element.
37
- */
47
+ * The "previous value" of the input element.
48
+ */
38
49
  get previousValue() {
39
50
  return this._previousValue;
40
51
  }
41
52
  /**
42
- * The serialize settings of the input element.
43
- */
53
+ * The serialize settings of the input element.
54
+ */
44
55
  get serializeSettings() {
45
56
  return this._serializeSettings;
46
57
  }
47
58
  /**
48
- * The "touched" state of the input element.
49
- */
59
+ * The "touched" state of the input element.
60
+ */
50
61
  get touched() {
51
62
  return this._touched;
52
63
  }
53
64
  /**
54
- * The current value of the input element.
55
- */
65
+ * The current value of the input element.
66
+ */
56
67
  get value() {
57
68
  return this._value;
58
69
  }
59
70
  /**
60
- * The registered callback function called when a change or input event occurs on the input
61
- * element.
62
- */
63
- onChange = (_) => {
64
- };
71
+ * The registered callback function called when a change or input event occurs on the input
72
+ * element.
73
+ */
74
+ onChange = /* @__PURE__ */ __name((_) => {
75
+ }, "onChange");
65
76
  /**
66
- * Registers a function called when the control error changes.
67
- */
68
- onErrorChange = () => {
69
- };
77
+ * Registers a function called when the control error changes.
78
+ */
79
+ onErrorChange = /* @__PURE__ */ __name(() => {
80
+ }, "onErrorChange");
70
81
  /**
71
- * The registered callback function called when a blur event occurs on the input element.
72
- */
73
- onTouched = (_isTouched) => {
74
- };
82
+ * The registered callback function called when a blur event occurs on the input element.
83
+ */
84
+ onTouched = /* @__PURE__ */ __name((_isTouched) => {
85
+ }, "onTouched");
75
86
  /**
76
- * Registers a function called when the control value changes.
77
- * @param {(_value:ValidControlValue)=>void} fn
78
- * @returns void
79
- */
87
+ * Registers a function called when the control value changes.
88
+ * @param {(_value:ValidControlValue)=>void} fn
89
+ * @returns void
90
+ */
80
91
  registerOnChange(fn) {
81
92
  this.onChange = fn;
82
93
  }
83
94
  /**
84
- * Registers a function called when the control error changes.
85
- * @param {(error:string)=>void} fn
86
- */
95
+ * Registers a function called when the control error changes.
96
+ * @param {(error:string)=>void} fn
97
+ */
87
98
  registerOnErrorChange(fn) {
88
99
  this.onErrorChange = fn;
89
100
  }
90
101
  /**
91
- * Registers a function called when the control is touched.
92
- * @param {(isTouched:boolean)=>void} fn
93
- * @returns void
94
- */
102
+ * Registers a function called when the control is touched.
103
+ * @param {(isTouched:boolean)=>void} fn
104
+ * @returns void
105
+ */
95
106
  registerOnTouched(fn) {
96
107
  this.onTouched = fn;
97
108
  }
98
109
  /**
99
- * Sets the "touched" state of the input element.
100
- * @param {boolean} isTouched
101
- */
110
+ * Sets the "touched" state of the input element.
111
+ * @param {boolean} isTouched
112
+ */
102
113
  setTouched(isTouched) {
103
114
  if (this.touched !== isTouched) {
104
115
  this._touched = isTouched;
105
116
  this.onTouched(isTouched);
106
117
  if (this.config.disableEvents) return;
107
- const emit = async () => await this.emit("touchChanged", { touched: isTouched });
118
+ const emit = /* @__PURE__ */ __name(async () => await this.emit("touchChanged", {
119
+ touched: isTouched
120
+ }), "emit");
108
121
  forget(emit());
109
122
  }
110
123
  }
111
124
  /**
112
- * Sets the "value" property on the input element.
113
- * @param {ValidControlValue} value
114
- * @returns void
115
- */
125
+ * Sets the "value" property on the input element.
126
+ * @param {ValidControlValue} value
127
+ * @returns void
128
+ */
116
129
  setValue(value, options = DefaultSetOptions) {
117
130
  this._previousValue = this._value;
118
131
  const normalizedValue = value == null ? "" : value;
@@ -120,35 +133,39 @@ var ControlValueAccessorBase = class extends ModuleBaseEmitter {
120
133
  this._value = normalizedValue;
121
134
  this.onChange(normalizedValue);
122
135
  if (this.config.disableEvents || options.disableEmit) return;
123
- const emit = async () => await this.emit("valueChanged", { value: normalizedValue });
136
+ const emit = /* @__PURE__ */ __name(async () => await this.emit("valueChanged", {
137
+ value: normalizedValue
138
+ }), "emit");
124
139
  forget(emit());
125
140
  }
126
141
  }
127
142
  /**
128
- * Set the error message for the control.
129
- * @param {string} error
130
- */
143
+ * Set the error message for the control.
144
+ * @param {string} error
145
+ */
131
146
  setError(error) {
132
147
  if (this.error !== error) {
133
148
  this._error = error;
134
149
  this.onErrorChange(error);
135
150
  if (this.config.disableEvents) return;
136
- const emit = async () => await this.emit("errorChanged", { error });
151
+ const emit = /* @__PURE__ */ __name(async () => await this.emit("errorChanged", {
152
+ error
153
+ }), "emit");
137
154
  forget(emit());
138
155
  }
139
156
  }
140
157
  /**
141
- * Sets the "previous value" of the input element.
142
- * @param {ValidControlValue} value
143
- * @returns void
144
- */
158
+ * Sets the "previous value" of the input element.
159
+ * @param {ValidControlValue} value
160
+ * @returns void
161
+ */
145
162
  setPreviousValue(value) {
146
163
  this._previousValue = value;
147
164
  }
148
165
  /**
149
- * Sets the serialize settings of the input element.
150
- * @param {ControlSerializeSettings} settings
151
- */
166
+ * Sets the serialize settings of the input element.
167
+ * @param {ControlSerializeSettings} settings
168
+ */
152
169
  setSerializeSettings(settings) {
153
170
  this._serializeSettings = settings;
154
171
  }
@@ -162,29 +179,32 @@ var DISABLED = "DISABLED";
162
179
 
163
180
  // src/control/AbstractControl.ts
164
181
  var AbstractControl = class extends ControlValueAccessorBase {
182
+ static {
183
+ __name(this, "AbstractControl");
184
+ }
165
185
  _status = void 0;
166
186
  constructor() {
167
187
  super({});
168
188
  }
169
189
  /**
170
- * A control is `disabled` when its `status` is `DISABLED`.
171
- *
172
- * Disabled controls are exempt from validation checks and
173
- * are not included in the aggregate value of their ancestor
174
- * controls.
175
- *
176
- * @returns True if the control is disabled, false otherwise.
177
- */
190
+ * A control is `disabled` when its `status` is `DISABLED`.
191
+ *
192
+ * Disabled controls are exempt from validation checks and
193
+ * are not included in the aggregate value of their ancestor
194
+ * controls.
195
+ *
196
+ * @returns True if the control is disabled, false otherwise.
197
+ */
178
198
  /** @deprecated - disabled functionality not implemented */
179
199
  get disabled() {
180
200
  return this.status === DISABLED;
181
201
  }
182
202
  /**
183
- * A control is `enabled` as long as its `status` is not `DISABLED`.
184
- *
185
- * @returns True if the control has any status other than 'DISABLED',
186
- * false if the status is 'DISABLED'.
187
- */
203
+ * A control is `enabled` as long as its `status` is not `DISABLED`.
204
+ *
205
+ * @returns True if the control has any status other than 'DISABLED',
206
+ * false if the status is 'DISABLED'.
207
+ */
188
208
  get enabled() {
189
209
  return this.status !== DISABLED;
190
210
  }
@@ -199,32 +219,32 @@ var AbstractControl = class extends ControlValueAccessorBase {
199
219
  return this.status === INVALID;
200
220
  }
201
221
  /**
202
- * A control is `pending` when its `status` is `PENDING`.
203
- *
204
- * @returns True if this control is in the process of conducting a validation check,
205
- * false otherwise.
206
- */
222
+ * A control is `pending` when its `status` is `PENDING`.
223
+ *
224
+ * @returns True if this control is in the process of conducting a validation check,
225
+ * false otherwise.
226
+ */
207
227
  get pending() {
208
228
  return this.status == PENDING;
209
229
  }
210
230
  /**
211
- * The raw value of the control.
212
- */
231
+ * The raw value of the control.
232
+ */
213
233
  get rawValue() {
214
234
  return this.value;
215
235
  }
216
236
  /**
217
- * The current status of the control.
218
- */
237
+ * The current status of the control.
238
+ */
219
239
  get status() {
220
240
  return this._status;
221
241
  }
222
242
  /**
223
- * A control is `valid` when its `status` is `VALID`.
224
- *
225
- * @returns True if the control has passed all of its validation tests,
226
- * false otherwise.
227
- */
243
+ * A control is `valid` when its `status` is `VALID`.
244
+ *
245
+ * @returns True if the control has passed all of its validation tests,
246
+ * false otherwise.
247
+ */
228
248
  get valid() {
229
249
  return this.status === VALID;
230
250
  }
@@ -235,7 +255,9 @@ var AbstractControl = class extends ControlValueAccessorBase {
235
255
  setStatus(status) {
236
256
  if (this._status === status) return;
237
257
  this._status = status;
238
- const emit = async () => await this.emit("statusChanged", { status });
258
+ const emit = /* @__PURE__ */ __name(async () => await this.emit("statusChanged", {
259
+ status
260
+ }), "emit");
239
261
  forget2(emit());
240
262
  }
241
263
  validate() {
@@ -246,10 +268,16 @@ var AbstractControl = class extends ControlValueAccessorBase {
246
268
  // src/control/FormControlBase.ts
247
269
  var AllowAllRegex = /^.*$/s;
248
270
  var FormControlBase = class extends AbstractControl {
271
+ static {
272
+ __name(this, "FormControlBase");
273
+ }
249
274
  /**
250
- * The current and previous cursor position of the input element.
251
- */
252
- cursorPosition = { current: void 0, previous: void 0 };
275
+ * The current and previous cursor position of the input element.
276
+ */
277
+ cursorPosition = {
278
+ current: void 0,
279
+ previous: void 0
280
+ };
253
281
  invalidMessage = "Invalid input";
254
282
  pattern = AllowAllRegex;
255
283
  patternStrict = AllowAllRegex;
@@ -265,8 +293,8 @@ var FormControlBase = class extends AbstractControl {
265
293
  get rawValue() {
266
294
  return this.unmask && this.value ? this.unmask(this.value) : this.value;
267
295
  }
268
- onCursorChange = () => {
269
- };
296
+ onCursorChange = /* @__PURE__ */ __name(() => {
297
+ }, "onCursorChange");
270
298
  setValue(value = "", setOptions) {
271
299
  if (this.unmask && this.pattern) {
272
300
  const unmasked = this.unmask(value);
@@ -299,6 +327,9 @@ var FormControlBase = class extends AbstractControl {
299
327
 
300
328
  // src/FormGroup.ts
301
329
  var FormGroup = class extends AbstractControl {
330
+ static {
331
+ __name(this, "FormGroup");
332
+ }
302
333
  _controls = {};
303
334
  fgParams;
304
335
  serializeListeners = {};
@@ -411,7 +442,7 @@ var FormGroup = class extends AbstractControl {
411
442
  if (!shouldSerialize && (storage || sensitiveStorage)) console.warn("storage medium set but serialize is not enabled");
412
443
  if (shouldSerialize && control.serializeSettings.serializable) {
413
444
  this.setStateValueFromStorage(name, control);
414
- const listener = ({ value }) => {
445
+ const listener = /* @__PURE__ */ __name(({ value }) => {
415
446
  if (control.serializeSettings.serializable) {
416
447
  const targetStorage = control.serializeSettings.sensitive ? sensitiveStorage : storage;
417
448
  const targetState = control.serializeSettings.sensitive ? this.serializedSensitiveState : this.serializedState;
@@ -420,60 +451,63 @@ var FormGroup = class extends AbstractControl {
420
451
  payloadWithTimestamp.timestamp = Date.now();
421
452
  this.serializeValues(targetStorage, targetState);
422
453
  }
423
- };
454
+ }, "listener");
424
455
  control.on("valueChanged", listener);
425
456
  this.serializeListeners[name] = listener;
426
457
  }
427
458
  }
428
459
  serializeValues(storage, values) {
429
460
  if (storage && values) {
430
- const write = async () => await storage.insert(values);
431
- const clear = async () => await storage.clear();
461
+ const write = /* @__PURE__ */ __name(async () => await storage.insert(values), "write");
462
+ const clear = /* @__PURE__ */ __name(async () => await storage.clear(), "clear");
432
463
  forget3(clear());
433
464
  forget3(write());
434
465
  }
435
466
  }
436
467
  setStateValueFromStorage(name, control) {
437
- const read = async () => {
468
+ const read = /* @__PURE__ */ __name(async () => {
438
469
  const savedValue = await this.getSerializedValue(name, control.serializeSettings.sensitive);
439
470
  if (savedValue) {
440
471
  const targetState = control.serializeSettings.sensitive ? this.serializedSensitiveState : this.serializedState;
441
472
  targetState[name] = savedValue;
442
- control.setValue(savedValue, { disableEmit: true });
473
+ control.setValue(savedValue, {
474
+ disableEmit: true
475
+ });
443
476
  }
444
- };
477
+ }, "read");
445
478
  forget3(read());
446
479
  }
447
480
  };
448
481
 
449
482
  // src/context/Provider.tsx
450
- import { jsx } from "react/jsx-runtime";
451
- var FormGroupPayloadProvider = ({
452
- children,
453
- params,
454
- ...props
455
- }) => {
483
+ var FormGroupPayloadProvider = /* @__PURE__ */ __name(({ children, params, ...props }) => {
456
484
  const formGroup = useMemo(() => {
457
485
  const formGroup2 = new FormGroup(params);
458
486
  return formGroup2;
459
- }, [params]);
460
- const value = useMemo(() => ({ formGroup, provided: true }), [formGroup]);
461
- return /* @__PURE__ */ jsx(
462
- FormGroupBaseContext,
463
- {
464
- value,
465
- ...props,
466
- children
467
- }
468
- );
469
- };
487
+ }, [
488
+ params
489
+ ]);
490
+ const value = useMemo(() => ({
491
+ formGroup,
492
+ provided: true
493
+ }), [
494
+ formGroup
495
+ ]);
496
+ return /* @__PURE__ */ React.createElement(FormGroupBaseContext, {
497
+ value,
498
+ ...props
499
+ }, children);
500
+ }, "FormGroupPayloadProvider");
470
501
 
471
502
  // src/context/use.ts
472
503
  import { useContextEx } from "@xylabs/react-shared";
473
- var useFormGroup = (required = false) => useContextEx(FormGroupBaseContext, "FormGroup", required);
504
+ var useFormGroup = /* @__PURE__ */ __name((required = false) => useContextEx(FormGroupBaseContext, "FormGroup", required), "useFormGroup");
474
505
 
475
506
  // src/storage/ArchivistFormGroupStorage.ts
476
507
  var ArchivistFormGroupStorage = class {
508
+ static {
509
+ __name(this, "ArchivistFormGroupStorage");
510
+ }
477
511
  archivist;
478
512
  constructor(archivist) {
479
513
  this.archivist = archivist;
@@ -486,7 +520,9 @@ var ArchivistFormGroupStorage = class {
486
520
  return all.at(-1);
487
521
  }
488
522
  async insert(value) {
489
- await this.archivist.insert?.([value]);
523
+ await this.archivist.insert?.([
524
+ value
525
+ ]);
490
526
  }
491
527
  };
492
528
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/context/Context.ts","../../src/context/Provider.tsx","../../src/FormGroup.ts","../../src/control/AbstractControl.ts","../../src/control/accessor/ControlValueAccessorBase.ts","../../src/control/accessor/FormControlStatus.ts","../../src/control/FormControlBase.ts","../../src/context/use.ts","../../src/storage/ArchivistFormGroupStorage.ts"],"sourcesContent":["import { createContextEx } from '@xylabs/react-shared'\n\nimport type { FormGroupContextWithPayloadState } from './State.ts'\n\nexport const FormGroupBaseContext = createContextEx<FormGroupContextWithPayloadState>()\n","import type { Payload } from '@xyo-network/payload-model'\nimport type { PropsWithChildren } from 'react'\nimport React, { useMemo } from 'react'\n\nimport type { FormGroupParams } from '../FormGroup.ts'\nimport { FormGroup } from '../FormGroup.ts'\nimport { FormGroupBaseContext } from './Context.ts'\nimport type { FormGroupContextWithPayloadState } from './State.ts'\n\nexport interface FormGroupPayloadProviderProps<TStorage extends Payload = Payload> extends PropsWithChildren {\n params?: FormGroupParams<TStorage>\n}\n\n/**\n * Provides a FormGroup to child components.\n */\nexport const FormGroupPayloadProvider = ({\n children, params, ...props\n}: FormGroupPayloadProviderProps) => {\n const formGroup = useMemo(() => {\n const formGroup = new FormGroup<Payload, Payload>(params)\n return formGroup\n }, [params])\n\n const value: FormGroupContextWithPayloadState = useMemo(() => ({ formGroup, provided: true }), [formGroup])\n\n return (\n\n <FormGroupBaseContext\n value={value}\n {...props}\n >\n {children}\n </FormGroupBaseContext>\n )\n}\n","import type { EventListener } from '@xylabs/events'\nimport { forget } from '@xylabs/forget'\nimport type { Payload } from '@xyo-network/payload-model'\n\nimport type { ControlValueAccessorBaseEvents } from './control/index.ts'\nimport { AbstractControl } from './control/index.ts'\nimport type { ErrorSummary } from './InputError.ts'\nimport type { FormGroupStorage } from './storage/index.ts'\n\nexport type PayloadWithTimestamp = Payload<{ timestamp?: number }>\n\nexport type KeyOfString<T> = keyof T extends string ? keyof T : never\n\ntype FormGroupErrors<TValue> = Record<KeyOfString<TValue>, string>\n\nexport type FormGroupParams<TStorageValue extends Payload = Payload> = {\n serialize?: boolean\n storage?: {\n sensitive?: FormGroupStorage<TStorageValue>\n storage?: FormGroupStorage<TStorageValue>\n }\n ttlStorage?: number\n}\n\ntype ValueChangeEventListener = EventListener<ControlValueAccessorBaseEvents['valueChanged']>\n\n/**\n * Organize form controls in a group.\n *\n * NOTE: This is a work in progress and only supports top level controls. Nested controls are not supported.\n */\nexport class FormGroup<\n TValue extends PayloadWithTimestamp = PayloadWithTimestamp,\n TStorageValue extends PayloadWithTimestamp = PayloadWithTimestamp,\n> extends AbstractControl {\n private _controls = {} as Record<KeyOfString<TValue>, AbstractControl>\n\n private fgParams?: FormGroupParams<TStorageValue>\n\n private serializeListeners: Record<string, ValueChangeEventListener> = {}\n\n private serializedSensitiveState = {} as Record<KeyOfString<TStorageValue>, string>\n private serializedState = {} as Record<KeyOfString<TStorageValue>, string>\n\n constructor(fgParams?: FormGroupParams<TStorageValue>) {\n super()\n this.fgParams = fgParams\n }\n\n get errorSummary() {\n const errorSummary: ErrorSummary = {\n errorMessage: '',\n invalidFields: [],\n }\n for (const [key, value] of Object.entries(this.errors)) {\n if (value) {\n errorSummary.errorMessage = `${errorSummary.errorMessage}, ${value}`\n errorSummary.invalidFields.push(key)\n }\n }\n\n return errorSummary\n }\n\n get errors(): FormGroupErrors<TValue> {\n const value = {} as FormGroupErrors<TValue>\n for (const key in this._controls) {\n const castKey = key as KeyOfString<TValue>\n value[castKey] = this._controls[castKey].error\n }\n return value\n }\n\n get nonSensitiveStorage() {\n return this.fgParams?.storage?.storage\n }\n\n get sensitiveStorage() {\n return this.fgParams?.storage?.sensitive\n }\n\n override get touched() {\n return Object.values<AbstractControl>(this._controls).some(control => control.touched)\n }\n\n override get valid() {\n return Object.values<AbstractControl>(this._controls).every(control => control.valid)\n }\n\n get values(): TValue {\n const value = {} as TValue\n for (const key in this._controls) {\n const castKey = key as KeyOfString<TValue>\n value[castKey] = this._controls[castKey].rawValue as TValue[KeyOfString<TValue>]\n }\n return value\n }\n\n getControl(name: string) {\n return this._controls[name as KeyOfString<TValue>]\n }\n\n async getSerializedValue(name: string, sensitive = false): Promise<string | undefined> {\n const storage = sensitive ? this.sensitiveStorage : this.nonSensitiveStorage\n if (storage) {\n const savedState = await storage.get()\n if (savedState && name in savedState) {\n const savedValue = savedState[name as keyof typeof savedState] as string\n\n // casting to PayloadWithTimestamp to check for timestamp\n const savedStateWithTimestamp = savedState as unknown as PayloadWithTimestamp\n if (savedStateWithTimestamp.timestamp && this.fgParams?.ttlStorage) {\n const expirationDate = savedStateWithTimestamp.timestamp + (this.fgParams?.ttlStorage ?? 0)\n const now = Date.now()\n return now > expirationDate ? undefined : savedValue\n }\n return savedValue\n }\n } else {\n console.warn(`Cannot return value for ${name}. No storage set`)\n }\n }\n\n registerControl(name: string, control: AbstractControl) {\n if (this._controls[name as KeyOfString<TValue>]) console.error(`Replacing Control with name ${name} since it already exists!`)\n this._controls[name as KeyOfString<TValue>] = control\n this.serializeControlValue(name, control)\n }\n\n resetControls() {\n for (const key in this._controls) {\n this.unregisterControl(key)\n }\n }\n\n resetValues() {\n for (const control of Object.values<AbstractControl>(this._controls)) {\n control.setValue('')\n }\n }\n\n unregisterControl(name: string) {\n const control = this._controls[name as KeyOfString<TValue>]\n\n if (control) {\n const listener = this.serializeListeners[name]\n control.on('valueChanged', listener)\n delete this.serializeListeners[name]\n delete this._controls[name as KeyOfString<TValue>]\n }\n }\n\n validateFields(requiredFields?: string[] | undefined) {\n const castRequiredFields = requiredFields as KeyOfString<TValue>[]\n for (const key in this._controls) {\n const castKey = key as KeyOfString<TValue>\n if (castRequiredFields === undefined || castRequiredFields.includes(castKey)) {\n const control = this._controls[castKey]\n control.validate()\n }\n }\n }\n\n private serializeControlValue(name: string, control: AbstractControl) {\n const shouldSerialize = this.fgParams?.serialize\n const sensitiveStorage = this.sensitiveStorage\n const storage = this.nonSensitiveStorage\n\n if (!shouldSerialize && (storage || sensitiveStorage)) console.warn('storage medium set but serialize is not enabled')\n\n if (shouldSerialize && control.serializeSettings.serializable) {\n this.setStateValueFromStorage(name, control)\n\n const listener: ValueChangeEventListener = ({ value }) => {\n // detect if control wants to be serialized\n if (control.serializeSettings.serializable) {\n // detect control's preferred storage\n const targetStorage = control.serializeSettings.sensitive ? sensitiveStorage : storage\n\n // detect control's preferred state\n const targetState = control.serializeSettings.sensitive ? this.serializedSensitiveState : this.serializedState\n\n // set the value\n targetState[name as KeyOfString<TStorageValue>] = value ?? ''\n\n // add a timestamp\n const payloadWithTimestamp = targetState as PayloadWithTimestamp\n payloadWithTimestamp.timestamp = Date.now()\n\n // serialize the value\n this.serializeValues(targetStorage, targetState as TStorageValue)\n }\n }\n\n // listen for value changes\n control.on('valueChanged', listener)\n\n // store the listener for later removal\n this.serializeListeners[name] = listener\n }\n }\n\n private serializeValues(storage?: FormGroupStorage<TStorageValue>, values?: TStorageValue) {\n if (storage && values) {\n const write = async () => await storage.insert(values)\n const clear = async () => await storage.clear()\n\n forget(clear())\n forget(write())\n }\n }\n\n private setStateValueFromStorage(name: string, control: AbstractControl) {\n const read = async () => {\n const savedValue = await this.getSerializedValue(name, control.serializeSettings.sensitive)\n\n if (savedValue) {\n const targetState = control.serializeSettings.sensitive ? this.serializedSensitiveState : this.serializedState\n targetState[name as KeyOfString<TStorageValue>] = savedValue\n\n control.setValue(savedValue, { disableEmit: true })\n }\n }\n\n forget(read())\n }\n}\n","import { forget } from '@xylabs/forget'\n\nimport type {\n ControlValueAccessorBaseEvents,\n FormControlStatus,\n ValidControlValue,\n} from './accessor/index.ts'\nimport {\n ControlValueAccessorBase,\n DISABLED,\n INVALID,\n PENDING,\n VALID,\n} from './accessor/index.ts'\n\nexport type AbstractControlEvents<TValue> = ControlValueAccessorBaseEvents<TValue> & {\n statusChanged: { status: FormControlStatus }\n}\n\n/**\n * This is the base class for `Control` classes (i.e. FormControl),\n *\n * It provides some of the shared behavior that all controls and groups of controls have, like\n * running validators, calculating status, and resetting state. It also defines the properties\n * that are shared between all sub-classes, like `value`, `valid`, and `dirty`. It shouldn't be\n * instantiated directly.\n *\n * NOTE: Heavily borrowed from Angular's AbstractControl:\n * https://github.com/angular/angular/blob/5dcdbfcba934a930468aec140a7183b034466bdf/packages/forms/src/model/abstract_model.ts\n */\nexport class AbstractControl<TValue extends ValidControlValue = ValidControlValue> extends ControlValueAccessorBase<\n TValue,\n AbstractControlEvents<TValue>\n> {\n private _status: FormControlStatus | undefined = undefined\n\n constructor() {\n super({})\n }\n\n /**\n * A control is `disabled` when its `status` is `DISABLED`.\n *\n * Disabled controls are exempt from validation checks and\n * are not included in the aggregate value of their ancestor\n * controls.\n *\n * @returns True if the control is disabled, false otherwise.\n */\n /** @deprecated - disabled functionality not implemented */\n get disabled(): boolean {\n return this.status === DISABLED\n }\n\n /**\n * A control is `enabled` as long as its `status` is not `DISABLED`.\n *\n * @returns True if the control has any status other than 'DISABLED',\n * false if the status is 'DISABLED'.\n */\n get enabled(): boolean {\n return this.status !== DISABLED\n }\n\n /**\n * A control is `invalid` when its `status` is `INVALID`.\n\n *\n * @returns True if this control has failed one or more of its validation checks,\n * false otherwise.\n */\n get invalid(): boolean {\n return this.status === INVALID\n }\n\n /**\n * A control is `pending` when its `status` is `PENDING`.\n *\n * @returns True if this control is in the process of conducting a validation check,\n * false otherwise.\n */\n get pending(): boolean {\n return this.status == PENDING\n }\n\n /**\n * The raw value of the control.\n */\n get rawValue(): TValue {\n return this.value\n }\n\n /**\n * The current status of the control.\n */\n get status() {\n return this._status\n }\n\n /**\n * A control is `valid` when its `status` is `VALID`.\n *\n * @returns True if the control has passed all of its validation tests,\n * false otherwise.\n */\n get valid(): boolean {\n return this.status === VALID\n }\n\n setErrorAndValidity(error: string, status: FormControlStatus) {\n this.setError(error)\n this.setStatus(status)\n }\n\n setStatus(status: FormControlStatus) {\n if (this._status === status) return\n\n this._status = status\n\n const emit = async () => await this.emit('statusChanged', { status })\n forget(emit())\n }\n\n validate(): boolean {\n return true\n }\n}\n","import type { BaseParams } from '@xylabs/base'\nimport { forget } from '@xylabs/forget'\nimport { ModuleBaseEmitter } from '@xyo-network/module-event-emitter'\n\nimport type {\n ControlSerializeSettings, ControlValueAccessor, SetOptions,\n} from './ControlValueAccessor.ts'\nimport type { ValidControlValue } from './ValidControlValue.ts'\n\nexport type ControlValueAccessorBaseConfig = {\n disableEvents?: boolean\n}\n\nexport const DefaultSetOptions: SetOptions = { disableEmit: false }\n\nexport type ControlValueAccessorBaseEvents<TValue = ValidControlValue> = {\n errorChanged: { error: string }\n touchChanged: { touched: boolean }\n valueChanged: { value: TValue }\n}\n\n/**\n * The base class for control value accessors interface\n */\nexport class ControlValueAccessorBase<\n TValue = ValidControlValue,\n TEventData extends ControlValueAccessorBaseEvents<TValue> = ControlValueAccessorBaseEvents<TValue>,\n>\n extends ModuleBaseEmitter<BaseParams, TEventData>\n implements ControlValueAccessor<TValue> {\n private _error: string = ''\n\n private _previousValue = undefined as TValue\n\n private _serializeSettings: ControlSerializeSettings = { sensitive: false, serializable: false }\n\n private _touched: boolean = false\n\n private _value = undefined as TValue\n\n private config: ControlValueAccessorBaseConfig\n\n constructor(config: ControlValueAccessorBaseConfig) {\n super({})\n this.config = config\n }\n\n /**\n * The error message for the control.\n */\n get error() {\n return this._error\n }\n\n /**\n * The \"previous value\" of the input element.\n */\n get previousValue() {\n return this._previousValue\n }\n\n /**\n * The serialize settings of the input element.\n */\n get serializeSettings() {\n return this._serializeSettings\n }\n\n /**\n * The \"touched\" state of the input element.\n */\n get touched() {\n return this._touched\n }\n\n /**\n * The current value of the input element.\n */\n get value() {\n return this._value\n }\n\n /**\n * The registered callback function called when a change or input event occurs on the input\n * element.\n */\n onChange = (_: TValue) => {}\n\n /**\n * Registers a function called when the control error changes.\n */\n onErrorChange: (error: string) => void = () => {}\n\n /**\n * The registered callback function called when a blur event occurs on the input element.\n */\n onTouched = (_isTouched: boolean) => {}\n\n /**\n * Registers a function called when the control value changes.\n * @param {(_value:ValidControlValue)=>void} fn\n * @returns void\n */\n registerOnChange(fn: (_value: TValue) => void): void {\n this.onChange = fn\n }\n\n /**\n * Registers a function called when the control error changes.\n * @param {(error:string)=>void} fn\n */\n registerOnErrorChange(fn: (error: string) => void) {\n this.onErrorChange = fn\n }\n\n /**\n * Registers a function called when the control is touched.\n * @param {(isTouched:boolean)=>void} fn\n * @returns void\n */\n registerOnTouched(fn: (isTouched: boolean) => void): void {\n this.onTouched = fn\n }\n\n /**\n * Sets the \"touched\" state of the input element.\n * @param {boolean} isTouched\n */\n setTouched(isTouched: boolean) {\n if (this.touched !== isTouched) {\n this._touched = isTouched\n this.onTouched(isTouched)\n\n if (this.config.disableEvents) return\n const emit = async () => await this.emit('touchChanged', { touched: isTouched })\n forget(emit())\n }\n }\n\n /**\n * Sets the \"value\" property on the input element.\n * @param {ValidControlValue} value\n * @returns void\n */\n setValue(value: TValue, options = DefaultSetOptions): void {\n this._previousValue = this._value\n\n const normalizedValue = value == null ? ('' as TValue) : value\n\n if (this.value !== normalizedValue) {\n this._value = normalizedValue\n this.onChange(normalizedValue)\n\n if (this.config.disableEvents || options.disableEmit) return\n const emit = async () => await this.emit('valueChanged', { value: normalizedValue })\n forget(emit())\n }\n }\n\n /**\n * Set the error message for the control.\n * @param {string} error\n */\n protected setError(error: string) {\n if (this.error !== error) {\n this._error = error\n this.onErrorChange(error)\n\n if (this.config.disableEvents) return\n const emit = async () => await this.emit('errorChanged', { error })\n forget(emit())\n }\n }\n\n /**\n * Sets the \"previous value\" of the input element.\n * @param {ValidControlValue} value\n * @returns void\n */\n protected setPreviousValue(value: TValue): void {\n this._previousValue = value\n }\n\n /**\n * Sets the serialize settings of the input element.\n * @param {ControlSerializeSettings} settings\n */\n protected setSerializeSettings(settings: ControlSerializeSettings) {\n this._serializeSettings = settings\n }\n}\n","/**\n * Reports that a control is valid, meaning that no errors exist in the input value.\n */\nexport const VALID = 'VALID' as const\n\n/**\n * Reports that a control is invalid, meaning that an error exists in the input value.\n */\nexport const INVALID = 'INVALID' as const\n\n/**\n * Reports that a control is pending, meaning that async validation is occurring and\n * errors are not yet available for the input value.\n */\nexport const PENDING = 'PENDING' as const\n\n/**\n * Reports that a control is disabled, meaning that the control is exempt from ancestor\n * calculations of validity or value.\n */\nexport const DISABLED = 'DISABLED' as const\n\n/**\n * A control can have several different statuses. Each\n * possible status is returned as a string literal.\n *\n * * **VALID**: Reports that a control is valid, meaning that no errors exist in the input\n * value.\n * * **INVALID**: Reports that a control is invalid, meaning that an error exists in the input\n * value.\n * * **PENDING**: Reports that a control is pending, meaning that async validation is\n * occurring and errors are not yet available for the input value.\n * * **DISABLED**: Reports that a control is\n * disabled, meaning that the control is exempt from ancestor calculations of validity or value.\n */\nexport type FormControlStatus = typeof VALID | typeof INVALID | typeof PENDING | typeof DISABLED\n","import type { EmptyObject } from '@xylabs/object'\n\nimport { AbstractControl } from './AbstractControl.ts'\nimport type { SetOptions } from './accessor/index.ts'\nimport type { CursorPosition, FormControl } from './FormControl.ts'\n\nconst AllowAllRegex = /^.*$/s\n\n/**\n * A base class for form controls and their validation.\n */\nexport abstract class FormControlBase<TProps extends EmptyObject = EmptyObject> extends AbstractControl implements FormControl {\n /**\n * The current and previous cursor position of the input element.\n */\n cursorPosition: CursorPosition = { current: undefined, previous: undefined }\n\n invalidMessage = 'Invalid input'\n pattern = AllowAllRegex\n patternStrict = AllowAllRegex\n props = {} as TProps\n required = false\n\n private _name: string | undefined = undefined\n\n constructor() {\n super()\n }\n\n get name() {\n return this._name\n }\n\n override get rawValue() {\n return this.unmask && this.value ? this.unmask(this.value) : this.value\n }\n\n blurError?(value: string): void | undefined\n changeError?(value: string): void\n getCursorPosition?(): number | undefined\n mask?(value: string): string\n onCursorChange: (cursor: number | undefined) => void = () => {}\n\n override setValue(value: string = '', setOptions: SetOptions) {\n // check for pattern validation\n if (this.unmask && this.pattern) {\n const unmasked = this.unmask(value)\n const match = RegExp(this.pattern).exec(unmasked)\n // set the new value before checking for errors\n super.setValue(this.mask ? this.mask(unmasked) : unmasked, setOptions)\n if (match) {\n // if the value matches the pattern, update the cursor position\n if (this.getCursorPosition) {\n const newCursor = this.getCursorPosition()\n this.onCursorChange(newCursor)\n }\n } else {\n // if no match, set the error and return to the previous value\n this.setValue(this.previousValue, setOptions)\n this.onCursorChange?.(this.cursorPosition.previous)\n }\n } else {\n // if no mask or pattern, just set the value\n super.setValue(value, setOptions)\n }\n // check for changeError validation after pattern validation\n this.changeError?.(value)\n }\n\n unmask?(value: string): string\n\n // For FormControls, validate is the same as running one of the error checking functions\n override validate(): boolean {\n const normalizedValue = this.value ?? ''\n // prefer the blurError function since validation assumes the user is done typing\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n this.blurError ? this.blurError(normalizedValue) : this.changeError?.(normalizedValue)\n return !this.error\n }\n\n protected setName(name: string | undefined) {\n this._name = name\n }\n}\n","import { useContextEx } from '@xylabs/react-shared'\n\nimport { FormGroupBaseContext } from './Context.ts'\n\nexport const useFormGroup = (required = false) => useContextEx(FormGroupBaseContext, 'FormGroup', required)\n","import type { ArchivistInstance } from '@xyo-network/archivist-model'\nimport type { Payload } from '@xyo-network/payload-model'\n\nimport type { FormGroupStorage } from './FormGroupStorage.ts'\n\nexport class ArchivistFormGroupStorage implements FormGroupStorage {\n private archivist: ArchivistInstance\n\n constructor(archivist: ArchivistInstance) {\n this.archivist = archivist\n }\n\n async clear() {\n await this.archivist.clear?.()\n }\n\n async get() {\n const all = await this.archivist.all?.()\n return all.at(-1)\n }\n\n async insert(value: Payload) {\n await this.archivist.insert?.([value])\n }\n}\n"],"mappings":"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","names":["forget","forget","forget","forget","formGroup"]}
1
+ {"version":3,"sources":["../../src/context/Context.ts","../../src/context/Provider.tsx","../../src/FormGroup.ts","../../src/control/AbstractControl.ts","../../src/control/accessor/ControlValueAccessorBase.ts","../../src/control/accessor/FormControlStatus.ts","../../src/control/FormControlBase.ts","../../src/context/use.ts","../../src/storage/ArchivistFormGroupStorage.ts"],"sourcesContent":["import { createContextEx } from '@xylabs/react-shared'\n\nimport type { FormGroupContextWithPayloadState } from './State.ts'\n\nexport const FormGroupBaseContext = createContextEx<FormGroupContextWithPayloadState>()\n","import type { Payload } from '@xyo-network/payload-model'\nimport type { PropsWithChildren } from 'react'\nimport React, { useMemo } from 'react'\n\nimport type { FormGroupParams } from '../FormGroup.ts'\nimport { FormGroup } from '../FormGroup.ts'\nimport { FormGroupBaseContext } from './Context.ts'\nimport type { FormGroupContextWithPayloadState } from './State.ts'\n\nexport interface FormGroupPayloadProviderProps<TStorage extends Payload = Payload> extends PropsWithChildren {\n params?: FormGroupParams<TStorage>\n}\n\n/**\n * Provides a FormGroup to child components.\n */\nexport const FormGroupPayloadProvider = ({\n children, params, ...props\n}: FormGroupPayloadProviderProps) => {\n const formGroup = useMemo(() => {\n const formGroup = new FormGroup<Payload, Payload>(params)\n return formGroup\n }, [params])\n\n const value: FormGroupContextWithPayloadState = useMemo(() => ({ formGroup, provided: true }), [formGroup])\n\n return (\n\n <FormGroupBaseContext\n value={value}\n {...props}\n >\n {children}\n </FormGroupBaseContext>\n )\n}\n","import type { EventListener } from '@xylabs/events'\nimport { forget } from '@xylabs/forget'\nimport type { Payload } from '@xyo-network/payload-model'\n\nimport type { ControlValueAccessorBaseEvents } from './control/index.ts'\nimport { AbstractControl } from './control/index.ts'\nimport type { ErrorSummary } from './InputError.ts'\nimport type { FormGroupStorage } from './storage/index.ts'\n\nexport type PayloadWithTimestamp = Payload<{ timestamp?: number }>\n\nexport type KeyOfString<T> = keyof T extends string ? keyof T : never\n\ntype FormGroupErrors<TValue> = Record<KeyOfString<TValue>, string>\n\nexport type FormGroupParams<TStorageValue extends Payload = Payload> = {\n serialize?: boolean\n storage?: {\n sensitive?: FormGroupStorage<TStorageValue>\n storage?: FormGroupStorage<TStorageValue>\n }\n ttlStorage?: number\n}\n\ntype ValueChangeEventListener = EventListener<ControlValueAccessorBaseEvents['valueChanged']>\n\n/**\n * Organize form controls in a group.\n *\n * NOTE: This is a work in progress and only supports top level controls. Nested controls are not supported.\n */\nexport class FormGroup<\n TValue extends PayloadWithTimestamp = PayloadWithTimestamp,\n TStorageValue extends PayloadWithTimestamp = PayloadWithTimestamp,\n> extends AbstractControl {\n private _controls = {} as Record<KeyOfString<TValue>, AbstractControl>\n\n private fgParams?: FormGroupParams<TStorageValue>\n\n private serializeListeners: Record<string, ValueChangeEventListener> = {}\n\n private serializedSensitiveState = {} as Record<KeyOfString<TStorageValue>, string>\n private serializedState = {} as Record<KeyOfString<TStorageValue>, string>\n\n constructor(fgParams?: FormGroupParams<TStorageValue>) {\n super()\n this.fgParams = fgParams\n }\n\n get errorSummary() {\n const errorSummary: ErrorSummary = {\n errorMessage: '',\n invalidFields: [],\n }\n for (const [key, value] of Object.entries(this.errors)) {\n if (value) {\n errorSummary.errorMessage = `${errorSummary.errorMessage}, ${value}`\n errorSummary.invalidFields.push(key)\n }\n }\n\n return errorSummary\n }\n\n get errors(): FormGroupErrors<TValue> {\n const value = {} as FormGroupErrors<TValue>\n for (const key in this._controls) {\n const castKey = key as KeyOfString<TValue>\n value[castKey] = this._controls[castKey].error\n }\n return value\n }\n\n get nonSensitiveStorage() {\n return this.fgParams?.storage?.storage\n }\n\n get sensitiveStorage() {\n return this.fgParams?.storage?.sensitive\n }\n\n override get touched() {\n return Object.values<AbstractControl>(this._controls).some(control => control.touched)\n }\n\n override get valid() {\n return Object.values<AbstractControl>(this._controls).every(control => control.valid)\n }\n\n get values(): TValue {\n const value = {} as TValue\n for (const key in this._controls) {\n const castKey = key as KeyOfString<TValue>\n value[castKey] = this._controls[castKey].rawValue as TValue[KeyOfString<TValue>]\n }\n return value\n }\n\n getControl(name: string) {\n return this._controls[name as KeyOfString<TValue>]\n }\n\n async getSerializedValue(name: string, sensitive = false): Promise<string | undefined> {\n const storage = sensitive ? this.sensitiveStorage : this.nonSensitiveStorage\n if (storage) {\n const savedState = await storage.get()\n if (savedState && name in savedState) {\n const savedValue = savedState[name as keyof typeof savedState] as string\n\n // casting to PayloadWithTimestamp to check for timestamp\n const savedStateWithTimestamp = savedState as unknown as PayloadWithTimestamp\n if (savedStateWithTimestamp.timestamp && this.fgParams?.ttlStorage) {\n const expirationDate = savedStateWithTimestamp.timestamp + (this.fgParams?.ttlStorage ?? 0)\n const now = Date.now()\n return now > expirationDate ? undefined : savedValue\n }\n return savedValue\n }\n } else {\n console.warn(`Cannot return value for ${name}. No storage set`)\n }\n }\n\n registerControl(name: string, control: AbstractControl) {\n if (this._controls[name as KeyOfString<TValue>]) console.error(`Replacing Control with name ${name} since it already exists!`)\n this._controls[name as KeyOfString<TValue>] = control\n this.serializeControlValue(name, control)\n }\n\n resetControls() {\n for (const key in this._controls) {\n this.unregisterControl(key)\n }\n }\n\n resetValues() {\n for (const control of Object.values<AbstractControl>(this._controls)) {\n control.setValue('')\n }\n }\n\n unregisterControl(name: string) {\n const control = this._controls[name as KeyOfString<TValue>]\n\n if (control) {\n const listener = this.serializeListeners[name]\n control.on('valueChanged', listener)\n delete this.serializeListeners[name]\n delete this._controls[name as KeyOfString<TValue>]\n }\n }\n\n validateFields(requiredFields?: string[] | undefined) {\n const castRequiredFields = requiredFields as KeyOfString<TValue>[]\n for (const key in this._controls) {\n const castKey = key as KeyOfString<TValue>\n if (castRequiredFields === undefined || castRequiredFields.includes(castKey)) {\n const control = this._controls[castKey]\n control.validate()\n }\n }\n }\n\n private serializeControlValue(name: string, control: AbstractControl) {\n const shouldSerialize = this.fgParams?.serialize\n const sensitiveStorage = this.sensitiveStorage\n const storage = this.nonSensitiveStorage\n\n if (!shouldSerialize && (storage || sensitiveStorage)) console.warn('storage medium set but serialize is not enabled')\n\n if (shouldSerialize && control.serializeSettings.serializable) {\n this.setStateValueFromStorage(name, control)\n\n const listener: ValueChangeEventListener = ({ value }) => {\n // detect if control wants to be serialized\n if (control.serializeSettings.serializable) {\n // detect control's preferred storage\n const targetStorage = control.serializeSettings.sensitive ? sensitiveStorage : storage\n\n // detect control's preferred state\n const targetState = control.serializeSettings.sensitive ? this.serializedSensitiveState : this.serializedState\n\n // set the value\n targetState[name as KeyOfString<TStorageValue>] = value ?? ''\n\n // add a timestamp\n const payloadWithTimestamp = targetState as PayloadWithTimestamp\n payloadWithTimestamp.timestamp = Date.now()\n\n // serialize the value\n this.serializeValues(targetStorage, targetState as TStorageValue)\n }\n }\n\n // listen for value changes\n control.on('valueChanged', listener)\n\n // store the listener for later removal\n this.serializeListeners[name] = listener\n }\n }\n\n private serializeValues(storage?: FormGroupStorage<TStorageValue>, values?: TStorageValue) {\n if (storage && values) {\n const write = async () => await storage.insert(values)\n const clear = async () => await storage.clear()\n\n forget(clear())\n forget(write())\n }\n }\n\n private setStateValueFromStorage(name: string, control: AbstractControl) {\n const read = async () => {\n const savedValue = await this.getSerializedValue(name, control.serializeSettings.sensitive)\n\n if (savedValue) {\n const targetState = control.serializeSettings.sensitive ? this.serializedSensitiveState : this.serializedState\n targetState[name as KeyOfString<TStorageValue>] = savedValue\n\n control.setValue(savedValue, { disableEmit: true })\n }\n }\n\n forget(read())\n }\n}\n","import { forget } from '@xylabs/forget'\n\nimport type {\n ControlValueAccessorBaseEvents,\n FormControlStatus,\n ValidControlValue,\n} from './accessor/index.ts'\nimport {\n ControlValueAccessorBase,\n DISABLED,\n INVALID,\n PENDING,\n VALID,\n} from './accessor/index.ts'\n\nexport type AbstractControlEvents<TValue> = ControlValueAccessorBaseEvents<TValue> & {\n statusChanged: { status: FormControlStatus }\n}\n\n/**\n * This is the base class for `Control` classes (i.e. FormControl),\n *\n * It provides some of the shared behavior that all controls and groups of controls have, like\n * running validators, calculating status, and resetting state. It also defines the properties\n * that are shared between all sub-classes, like `value`, `valid`, and `dirty`. It shouldn't be\n * instantiated directly.\n *\n * NOTE: Heavily borrowed from Angular's AbstractControl:\n * https://github.com/angular/angular/blob/5dcdbfcba934a930468aec140a7183b034466bdf/packages/forms/src/model/abstract_model.ts\n */\nexport class AbstractControl<TValue extends ValidControlValue = ValidControlValue> extends ControlValueAccessorBase<\n TValue,\n AbstractControlEvents<TValue>\n> {\n private _status: FormControlStatus | undefined = undefined\n\n constructor() {\n super({})\n }\n\n /**\n * A control is `disabled` when its `status` is `DISABLED`.\n *\n * Disabled controls are exempt from validation checks and\n * are not included in the aggregate value of their ancestor\n * controls.\n *\n * @returns True if the control is disabled, false otherwise.\n */\n /** @deprecated - disabled functionality not implemented */\n get disabled(): boolean {\n return this.status === DISABLED\n }\n\n /**\n * A control is `enabled` as long as its `status` is not `DISABLED`.\n *\n * @returns True if the control has any status other than 'DISABLED',\n * false if the status is 'DISABLED'.\n */\n get enabled(): boolean {\n return this.status !== DISABLED\n }\n\n /**\n * A control is `invalid` when its `status` is `INVALID`.\n\n *\n * @returns True if this control has failed one or more of its validation checks,\n * false otherwise.\n */\n get invalid(): boolean {\n return this.status === INVALID\n }\n\n /**\n * A control is `pending` when its `status` is `PENDING`.\n *\n * @returns True if this control is in the process of conducting a validation check,\n * false otherwise.\n */\n get pending(): boolean {\n return this.status == PENDING\n }\n\n /**\n * The raw value of the control.\n */\n get rawValue(): TValue {\n return this.value\n }\n\n /**\n * The current status of the control.\n */\n get status() {\n return this._status\n }\n\n /**\n * A control is `valid` when its `status` is `VALID`.\n *\n * @returns True if the control has passed all of its validation tests,\n * false otherwise.\n */\n get valid(): boolean {\n return this.status === VALID\n }\n\n setErrorAndValidity(error: string, status: FormControlStatus) {\n this.setError(error)\n this.setStatus(status)\n }\n\n setStatus(status: FormControlStatus) {\n if (this._status === status) return\n\n this._status = status\n\n const emit = async () => await this.emit('statusChanged', { status })\n forget(emit())\n }\n\n validate(): boolean {\n return true\n }\n}\n","import type { BaseParams } from '@xylabs/base'\nimport { forget } from '@xylabs/forget'\nimport { ModuleBaseEmitter } from '@xyo-network/module-event-emitter'\n\nimport type {\n ControlSerializeSettings, ControlValueAccessor, SetOptions,\n} from './ControlValueAccessor.ts'\nimport type { ValidControlValue } from './ValidControlValue.ts'\n\nexport type ControlValueAccessorBaseConfig = {\n disableEvents?: boolean\n}\n\nexport const DefaultSetOptions: SetOptions = { disableEmit: false }\n\nexport type ControlValueAccessorBaseEvents<TValue = ValidControlValue> = {\n errorChanged: { error: string }\n touchChanged: { touched: boolean }\n valueChanged: { value: TValue }\n}\n\n/**\n * The base class for control value accessors interface\n */\nexport class ControlValueAccessorBase<\n TValue = ValidControlValue,\n TEventData extends ControlValueAccessorBaseEvents<TValue> = ControlValueAccessorBaseEvents<TValue>,\n>\n extends ModuleBaseEmitter<BaseParams, TEventData>\n implements ControlValueAccessor<TValue> {\n private _error: string = ''\n\n private _previousValue = undefined as TValue\n\n private _serializeSettings: ControlSerializeSettings = { sensitive: false, serializable: false }\n\n private _touched: boolean = false\n\n private _value = undefined as TValue\n\n private config: ControlValueAccessorBaseConfig\n\n constructor(config: ControlValueAccessorBaseConfig) {\n super({})\n this.config = config\n }\n\n /**\n * The error message for the control.\n */\n get error() {\n return this._error\n }\n\n /**\n * The \"previous value\" of the input element.\n */\n get previousValue() {\n return this._previousValue\n }\n\n /**\n * The serialize settings of the input element.\n */\n get serializeSettings() {\n return this._serializeSettings\n }\n\n /**\n * The \"touched\" state of the input element.\n */\n get touched() {\n return this._touched\n }\n\n /**\n * The current value of the input element.\n */\n get value() {\n return this._value\n }\n\n /**\n * The registered callback function called when a change or input event occurs on the input\n * element.\n */\n onChange = (_: TValue) => {}\n\n /**\n * Registers a function called when the control error changes.\n */\n onErrorChange: (error: string) => void = () => {}\n\n /**\n * The registered callback function called when a blur event occurs on the input element.\n */\n onTouched = (_isTouched: boolean) => {}\n\n /**\n * Registers a function called when the control value changes.\n * @param {(_value:ValidControlValue)=>void} fn\n * @returns void\n */\n registerOnChange(fn: (_value: TValue) => void): void {\n this.onChange = fn\n }\n\n /**\n * Registers a function called when the control error changes.\n * @param {(error:string)=>void} fn\n */\n registerOnErrorChange(fn: (error: string) => void) {\n this.onErrorChange = fn\n }\n\n /**\n * Registers a function called when the control is touched.\n * @param {(isTouched:boolean)=>void} fn\n * @returns void\n */\n registerOnTouched(fn: (isTouched: boolean) => void): void {\n this.onTouched = fn\n }\n\n /**\n * Sets the \"touched\" state of the input element.\n * @param {boolean} isTouched\n */\n setTouched(isTouched: boolean) {\n if (this.touched !== isTouched) {\n this._touched = isTouched\n this.onTouched(isTouched)\n\n if (this.config.disableEvents) return\n const emit = async () => await this.emit('touchChanged', { touched: isTouched })\n forget(emit())\n }\n }\n\n /**\n * Sets the \"value\" property on the input element.\n * @param {ValidControlValue} value\n * @returns void\n */\n setValue(value: TValue, options = DefaultSetOptions): void {\n this._previousValue = this._value\n\n const normalizedValue = value == null ? ('' as TValue) : value\n\n if (this.value !== normalizedValue) {\n this._value = normalizedValue\n this.onChange(normalizedValue)\n\n if (this.config.disableEvents || options.disableEmit) return\n const emit = async () => await this.emit('valueChanged', { value: normalizedValue })\n forget(emit())\n }\n }\n\n /**\n * Set the error message for the control.\n * @param {string} error\n */\n protected setError(error: string) {\n if (this.error !== error) {\n this._error = error\n this.onErrorChange(error)\n\n if (this.config.disableEvents) return\n const emit = async () => await this.emit('errorChanged', { error })\n forget(emit())\n }\n }\n\n /**\n * Sets the \"previous value\" of the input element.\n * @param {ValidControlValue} value\n * @returns void\n */\n protected setPreviousValue(value: TValue): void {\n this._previousValue = value\n }\n\n /**\n * Sets the serialize settings of the input element.\n * @param {ControlSerializeSettings} settings\n */\n protected setSerializeSettings(settings: ControlSerializeSettings) {\n this._serializeSettings = settings\n }\n}\n","/**\n * Reports that a control is valid, meaning that no errors exist in the input value.\n */\nexport const VALID = 'VALID' as const\n\n/**\n * Reports that a control is invalid, meaning that an error exists in the input value.\n */\nexport const INVALID = 'INVALID' as const\n\n/**\n * Reports that a control is pending, meaning that async validation is occurring and\n * errors are not yet available for the input value.\n */\nexport const PENDING = 'PENDING' as const\n\n/**\n * Reports that a control is disabled, meaning that the control is exempt from ancestor\n * calculations of validity or value.\n */\nexport const DISABLED = 'DISABLED' as const\n\n/**\n * A control can have several different statuses. Each\n * possible status is returned as a string literal.\n *\n * * **VALID**: Reports that a control is valid, meaning that no errors exist in the input\n * value.\n * * **INVALID**: Reports that a control is invalid, meaning that an error exists in the input\n * value.\n * * **PENDING**: Reports that a control is pending, meaning that async validation is\n * occurring and errors are not yet available for the input value.\n * * **DISABLED**: Reports that a control is\n * disabled, meaning that the control is exempt from ancestor calculations of validity or value.\n */\nexport type FormControlStatus = typeof VALID | typeof INVALID | typeof PENDING | typeof DISABLED\n","import type { EmptyObject } from '@xylabs/sdk-js'\n\nimport { AbstractControl } from './AbstractControl.ts'\nimport type { SetOptions } from './accessor/index.ts'\nimport type { CursorPosition, FormControl } from './FormControl.ts'\n\nconst AllowAllRegex = /^.*$/s\n\n/**\n * A base class for form controls and their validation.\n */\nexport abstract class FormControlBase<TProps extends EmptyObject = EmptyObject> extends AbstractControl implements FormControl {\n /**\n * The current and previous cursor position of the input element.\n */\n cursorPosition: CursorPosition = { current: undefined, previous: undefined }\n\n invalidMessage = 'Invalid input'\n pattern = AllowAllRegex\n patternStrict = AllowAllRegex\n props = {} as TProps\n required = false\n\n private _name: string | undefined = undefined\n\n constructor() {\n super()\n }\n\n get name() {\n return this._name\n }\n\n override get rawValue() {\n return this.unmask && this.value ? this.unmask(this.value) : this.value\n }\n\n blurError?(value: string): void | undefined\n changeError?(value: string): void\n getCursorPosition?(): number | undefined\n mask?(value: string): string\n onCursorChange: (cursor: number | undefined) => void = () => {}\n\n override setValue(value: string = '', setOptions: SetOptions) {\n // check for pattern validation\n if (this.unmask && this.pattern) {\n const unmasked = this.unmask(value)\n const match = RegExp(this.pattern).exec(unmasked)\n // set the new value before checking for errors\n super.setValue(this.mask ? this.mask(unmasked) : unmasked, setOptions)\n if (match) {\n // if the value matches the pattern, update the cursor position\n if (this.getCursorPosition) {\n const newCursor = this.getCursorPosition()\n this.onCursorChange(newCursor)\n }\n } else {\n // if no match, set the error and return to the previous value\n this.setValue(this.previousValue, setOptions)\n this.onCursorChange?.(this.cursorPosition.previous)\n }\n } else {\n // if no mask or pattern, just set the value\n super.setValue(value, setOptions)\n }\n // check for changeError validation after pattern validation\n this.changeError?.(value)\n }\n\n unmask?(value: string): string\n\n // For FormControls, validate is the same as running one of the error checking functions\n override validate(): boolean {\n const normalizedValue = this.value ?? ''\n // prefer the blurError function since validation assumes the user is done typing\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n this.blurError ? this.blurError(normalizedValue) : this.changeError?.(normalizedValue)\n return !this.error\n }\n\n protected setName(name: string | undefined) {\n this._name = name\n }\n}\n","import { useContextEx } from '@xylabs/react-shared'\n\nimport { FormGroupBaseContext } from './Context.ts'\n\nexport const useFormGroup = (required = false) => useContextEx(FormGroupBaseContext, 'FormGroup', required)\n","import type { ArchivistInstance } from '@xyo-network/archivist-model'\nimport type { Payload } from '@xyo-network/payload-model'\n\nimport type { FormGroupStorage } from './FormGroupStorage.ts'\n\nexport class ArchivistFormGroupStorage implements FormGroupStorage {\n private archivist: ArchivistInstance\n\n constructor(archivist: ArchivistInstance) {\n this.archivist = archivist\n }\n\n async clear() {\n await this.archivist.clear?.()\n }\n\n async get() {\n const all = await this.archivist.all?.()\n return all.at(-1)\n }\n\n async insert(value: Payload) {\n await this.archivist.insert?.([value])\n }\n}\n"],"mappings":"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","names":["createContextEx","FormGroupBaseContext","React","useMemo","forget","forget","forget","ModuleBaseEmitter","DefaultSetOptions","disableEmit","ControlValueAccessorBase","ModuleBaseEmitter","_error","_previousValue","undefined","_serializeSettings","sensitive","serializable","_touched","_value","config","error","previousValue","serializeSettings","touched","value","onChange","_","onErrorChange","onTouched","_isTouched","registerOnChange","fn","registerOnErrorChange","registerOnTouched","setTouched","isTouched","disableEvents","emit","forget","setValue","options","normalizedValue","setError","setPreviousValue","setSerializeSettings","settings","VALID","INVALID","PENDING","DISABLED","AbstractControl","ControlValueAccessorBase","_status","undefined","disabled","status","DISABLED","enabled","invalid","INVALID","pending","PENDING","rawValue","value","valid","VALID","setErrorAndValidity","error","setError","setStatus","emit","forget","validate","AllowAllRegex","FormControlBase","AbstractControl","cursorPosition","current","undefined","previous","invalidMessage","pattern","patternStrict","props","required","_name","name","rawValue","unmask","value","onCursorChange","setValue","setOptions","unmasked","match","RegExp","exec","mask","getCursorPosition","newCursor","previousValue","changeError","validate","normalizedValue","blurError","error","setName","FormGroup","AbstractControl","_controls","fgParams","serializeListeners","serializedSensitiveState","serializedState","errorSummary","errorMessage","invalidFields","key","value","Object","entries","errors","push","castKey","error","nonSensitiveStorage","storage","sensitiveStorage","sensitive","touched","values","some","control","valid","every","rawValue","getControl","name","getSerializedValue","savedState","get","savedValue","savedStateWithTimestamp","timestamp","ttlStorage","expirationDate","now","Date","undefined","console","warn","registerControl","serializeControlValue","resetControls","unregisterControl","resetValues","setValue","listener","on","validateFields","requiredFields","castRequiredFields","includes","validate","shouldSerialize","serialize","serializeSettings","serializable","setStateValueFromStorage","targetStorage","targetState","payloadWithTimestamp","serializeValues","write","insert","clear","forget","read","disableEmit","FormGroupPayloadProvider","children","params","props","formGroup","useMemo","FormGroup","value","provided","FormGroupBaseContext","useContextEx","useFormGroup","required","useContextEx","FormGroupBaseContext","ArchivistFormGroupStorage","archivist","clear","get","all","at","insert","value"]}
@@ -1,4 +1,4 @@
1
- import type { Promisable } from '@xylabs/promise';
1
+ import type { Promisable } from '@xylabs/sdk-js';
2
2
  import type { Payload } from '@xyo-network/payload-model';
3
3
  export interface FormGroupStorage<TValue extends Payload = Payload> {
4
4
  clear: () => Promisable<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"FormGroupStorage.d.ts","sourceRoot":"","sources":["../../../src/storage/FormGroupStorage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AAEzD,MAAM,WAAW,gBAAgB,CAAC,MAAM,SAAS,OAAO,GAAG,OAAO;IAChE,KAAK,EAAE,MAAM,UAAU,CAAC,IAAI,CAAC,CAAA;IAC7B,GAAG,EAAE,MAAM,UAAU,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IACzC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,UAAU,CAAC,IAAI,CAAC,CAAA;CAC5C"}
1
+ {"version":3,"file":"FormGroupStorage.d.ts","sourceRoot":"","sources":["../../../src/storage/FormGroupStorage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AAEzD,MAAM,WAAW,gBAAgB,CAAC,MAAM,SAAS,OAAO,GAAG,OAAO;IAChE,KAAK,EAAE,MAAM,UAAU,CAAC,IAAI,CAAC,CAAA;IAC7B,GAAG,EAAE,MAAM,UAAU,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IACzC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,UAAU,CAAC,IAAI,CAAC,CAAA;CAC5C"}
@@ -4,6 +4,6 @@
4
4
  import type { Meta } from '@storybook/react-vite';
5
5
  declare const _default: Meta;
6
6
  export default _default;
7
- declare const Default: import(".store/storybook-virtual-a067dd1507/package/internal/csf").AnnotatedStoryFn<import("@storybook/react-vite").ReactRenderer, {}>;
7
+ declare const Default: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, {}>;
8
8
  export { Default };
9
9
  //# sourceMappingURL=test.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"test.stories.d.ts","sourceRoot":"","sources":["../../../src/stories/test.stories.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAW,MAAM,uBAAuB,CAAA;wBAGT,IAAI;AAArD,wBAAqD;AAMrD,QAAA,MAAM,OAAO,wIAAoB,CAAA;AAGjC,OAAO,EAAE,OAAO,EAAE,CAAA"}
1
+ {"version":3,"file":"test.stories.d.ts","sourceRoot":"","sources":["../../../src/stories/test.stories.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAW,MAAM,uBAAuB,CAAA;wBAGT,IAAI;AAArD,wBAAqD;AAMrD,QAAA,MAAM,OAAO,iGAAoB,CAAA;AAGjC,OAAO,EAAE,OAAO,EAAE,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xyo-network/react-form-group",
3
- "version": "7.4.2",
3
+ "version": "7.5.1",
4
4
  "description": "Common React library for all XYO projects that use React",
5
5
  "keywords": [
6
6
  "xyo",
@@ -43,39 +43,39 @@
43
43
  "src"
44
44
  ],
45
45
  "dependencies": {
46
- "@xylabs/base": "~5.0.50",
47
- "@xylabs/forget": "~5.0.50",
48
- "@xylabs/object": "~5.0.50",
49
- "@xylabs/promise": "~5.0.50",
50
- "@xylabs/react-shared": "~7.1.8",
51
- "@xyo-network/archivist-model": "~5.2.17",
52
- "@xyo-network/module-event-emitter": "~5.2.17",
53
- "@xyo-network/payload-model": "~5.2.17"
46
+ "@xylabs/base": "~5.0.64",
47
+ "@xylabs/react-shared": "~7.1.12",
48
+ "@xylabs/sdk-js": "~5.0.64",
49
+ "@xyo-network/archivist-model": "~5.3.2",
50
+ "@xyo-network/module-event-emitter": "~5.3.2",
51
+ "@xyo-network/payload-model": "~5.3.2"
54
52
  },
55
53
  "devDependencies": {
56
- "@mui/icons-material": "~7.3.6",
57
- "@mui/material": "~7.3.6",
58
- "@storybook/react-vite": "~10.1.4",
59
- "@types/react": "^19.2.7",
60
- "@xylabs/events": "~5.0.50",
61
- "@xylabs/ts-scripts-yarn3": "~7.2.8",
62
- "@xylabs/tsconfig": "~7.2.8",
63
- "@xylabs/tsconfig-dom": "~7.2.8",
64
- "@xylabs/tsconfig-react": "~7.2.8",
65
- "react": "^19.2.1",
66
- "react-dom": "^19.2.1",
67
- "storybook": "~10.1.4",
54
+ "@mui/icons-material": "~7.3.7",
55
+ "@mui/material": "~7.3.7",
56
+ "@storybook/react-vite": "~10.2.1",
57
+ "@types/react": "^19.2.10",
58
+ "@xylabs/events": "~5.0.64",
59
+ "@xylabs/ts-scripts-yarn3": "~7.3.2",
60
+ "@xylabs/tsconfig": "~7.3.2",
61
+ "@xylabs/tsconfig-dom": "~7.3.2",
62
+ "@xylabs/tsconfig-react": "~7.3.2",
63
+ "react": "^19.2.4",
64
+ "react-dom": "^19.2.4",
65
+ "storybook": "~10.2.1",
68
66
  "typescript": "^5.9.3",
69
- "vite": "~7.2.6"
67
+ "vite": "~7.3.1",
68
+ "zod": "^4.3.6"
70
69
  },
71
70
  "peerDependencies": {
72
71
  "@mui/icons-material": ">=6 <8",
73
72
  "@mui/material": ">=6 <8",
74
73
  "react": "^19",
75
- "react-dom": "^19"
74
+ "react-dom": "^19",
75
+ "zod": "^4"
76
76
  },
77
77
  "publishConfig": {
78
78
  "access": "public"
79
79
  },
80
80
  "docs": "dist/docs.json"
81
- }
81
+ }
@@ -1,4 +1,4 @@
1
- import type { EmptyObject } from '@xylabs/object'
1
+ import type { EmptyObject } from '@xylabs/sdk-js'
2
2
 
3
3
  import type { AbstractControl } from './AbstractControl.ts'
4
4
 
@@ -1,4 +1,4 @@
1
- import type { EmptyObject } from '@xylabs/object'
1
+ import type { EmptyObject } from '@xylabs/sdk-js'
2
2
 
3
3
  import { AbstractControl } from './AbstractControl.ts'
4
4
  import type { SetOptions } from './accessor/index.ts'
@@ -1,4 +1,4 @@
1
- import type { Promisable } from '@xylabs/promise'
1
+ import type { Promisable } from '@xylabs/sdk-js'
2
2
  import type { Payload } from '@xyo-network/payload-model'
3
3
 
4
4
  export interface FormGroupStorage<TValue extends Payload = Payload> {