@xyo-network/react-form-group 2.81.2
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/LICENSE +165 -0
- package/README.md +13 -0
- package/dist/browser/FormGroup.d.cts +44 -0
- package/dist/browser/FormGroup.d.cts.map +1 -0
- package/dist/browser/FormGroup.d.mts +44 -0
- package/dist/browser/FormGroup.d.mts.map +1 -0
- package/dist/browser/FormGroup.d.ts +44 -0
- package/dist/browser/FormGroup.d.ts.map +1 -0
- package/dist/browser/InputError.d.cts +5 -0
- package/dist/browser/InputError.d.cts.map +1 -0
- package/dist/browser/InputError.d.mts +5 -0
- package/dist/browser/InputError.d.mts.map +1 -0
- package/dist/browser/InputError.d.ts +5 -0
- package/dist/browser/InputError.d.ts.map +1 -0
- package/dist/browser/context/Context.d.cts +7 -0
- package/dist/browser/context/Context.d.cts.map +1 -0
- package/dist/browser/context/Context.d.mts +7 -0
- package/dist/browser/context/Context.d.mts.map +1 -0
- package/dist/browser/context/Context.d.ts +7 -0
- package/dist/browser/context/Context.d.ts.map +1 -0
- package/dist/browser/context/Provider.d.cts +8 -0
- package/dist/browser/context/Provider.d.cts.map +1 -0
- package/dist/browser/context/Provider.d.mts +8 -0
- package/dist/browser/context/Provider.d.mts.map +1 -0
- package/dist/browser/context/Provider.d.ts +8 -0
- package/dist/browser/context/Provider.d.ts.map +1 -0
- package/dist/browser/context/State.d.cts +7 -0
- package/dist/browser/context/State.d.cts.map +1 -0
- package/dist/browser/context/State.d.mts +7 -0
- package/dist/browser/context/State.d.mts.map +1 -0
- package/dist/browser/context/State.d.ts +7 -0
- package/dist/browser/context/State.d.ts.map +1 -0
- package/dist/browser/context/index.d.cts +5 -0
- package/dist/browser/context/index.d.cts.map +1 -0
- package/dist/browser/context/index.d.mts +5 -0
- package/dist/browser/context/index.d.mts.map +1 -0
- package/dist/browser/context/index.d.ts +5 -0
- package/dist/browser/context/index.d.ts.map +1 -0
- package/dist/browser/context/use.d.cts +6 -0
- package/dist/browser/context/use.d.cts.map +1 -0
- package/dist/browser/context/use.d.mts +6 -0
- package/dist/browser/context/use.d.mts.map +1 -0
- package/dist/browser/context/use.d.ts +6 -0
- package/dist/browser/context/use.d.ts.map +1 -0
- package/dist/browser/control/AbstractControl.d.cts +21 -0
- package/dist/browser/control/AbstractControl.d.cts.map +1 -0
- package/dist/browser/control/AbstractControl.d.mts +21 -0
- package/dist/browser/control/AbstractControl.d.mts.map +1 -0
- package/dist/browser/control/AbstractControl.d.ts +21 -0
- package/dist/browser/control/AbstractControl.d.ts.map +1 -0
- package/dist/browser/control/FormControl.d.cts +25 -0
- package/dist/browser/control/FormControl.d.cts.map +1 -0
- package/dist/browser/control/FormControl.d.mts +25 -0
- package/dist/browser/control/FormControl.d.mts.map +1 -0
- package/dist/browser/control/FormControl.d.ts +25 -0
- package/dist/browser/control/FormControl.d.ts.map +1 -0
- package/dist/browser/control/FormControlBase.d.cts +26 -0
- package/dist/browser/control/FormControlBase.d.cts.map +1 -0
- package/dist/browser/control/FormControlBase.d.mts +26 -0
- package/dist/browser/control/FormControlBase.d.mts.map +1 -0
- package/dist/browser/control/FormControlBase.d.ts +26 -0
- package/dist/browser/control/FormControlBase.d.ts.map +1 -0
- package/dist/browser/control/accessor/ControlValueAccessor.d.cts +21 -0
- package/dist/browser/control/accessor/ControlValueAccessor.d.cts.map +1 -0
- package/dist/browser/control/accessor/ControlValueAccessor.d.mts +21 -0
- package/dist/browser/control/accessor/ControlValueAccessor.d.mts.map +1 -0
- package/dist/browser/control/accessor/ControlValueAccessor.d.ts +21 -0
- package/dist/browser/control/accessor/ControlValueAccessor.d.ts.map +1 -0
- package/dist/browser/control/accessor/ControlValueAccessorBase.d.cts +45 -0
- package/dist/browser/control/accessor/ControlValueAccessorBase.d.cts.map +1 -0
- package/dist/browser/control/accessor/ControlValueAccessorBase.d.mts +45 -0
- package/dist/browser/control/accessor/ControlValueAccessorBase.d.mts.map +1 -0
- package/dist/browser/control/accessor/ControlValueAccessorBase.d.ts +45 -0
- package/dist/browser/control/accessor/ControlValueAccessorBase.d.ts.map +1 -0
- package/dist/browser/control/accessor/FormControlStatus.d.cts +6 -0
- package/dist/browser/control/accessor/FormControlStatus.d.cts.map +1 -0
- package/dist/browser/control/accessor/FormControlStatus.d.mts +6 -0
- package/dist/browser/control/accessor/FormControlStatus.d.mts.map +1 -0
- package/dist/browser/control/accessor/FormControlStatus.d.ts +6 -0
- package/dist/browser/control/accessor/FormControlStatus.d.ts.map +1 -0
- package/dist/browser/control/accessor/ValidControlValue.d.cts +2 -0
- package/dist/browser/control/accessor/ValidControlValue.d.cts.map +1 -0
- package/dist/browser/control/accessor/ValidControlValue.d.mts +2 -0
- package/dist/browser/control/accessor/ValidControlValue.d.mts.map +1 -0
- package/dist/browser/control/accessor/ValidControlValue.d.ts +2 -0
- package/dist/browser/control/accessor/ValidControlValue.d.ts.map +1 -0
- package/dist/browser/control/accessor/index.d.cts +5 -0
- package/dist/browser/control/accessor/index.d.cts.map +1 -0
- package/dist/browser/control/accessor/index.d.mts +5 -0
- package/dist/browser/control/accessor/index.d.mts.map +1 -0
- package/dist/browser/control/accessor/index.d.ts +5 -0
- package/dist/browser/control/accessor/index.d.ts.map +1 -0
- package/dist/browser/control/index.d.cts +5 -0
- package/dist/browser/control/index.d.cts.map +1 -0
- package/dist/browser/control/index.d.mts +5 -0
- package/dist/browser/control/index.d.mts.map +1 -0
- package/dist/browser/control/index.d.ts +5 -0
- package/dist/browser/control/index.d.ts.map +1 -0
- package/dist/browser/index.cjs +517 -0
- package/dist/browser/index.cjs.map +1 -0
- package/dist/browser/index.d.cts +6 -0
- package/dist/browser/index.d.cts.map +1 -0
- package/dist/browser/index.d.mts +6 -0
- package/dist/browser/index.d.mts.map +1 -0
- package/dist/browser/index.d.ts +6 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +494 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/storage/ArchivistFormGroupStorage.d.cts +13 -0
- package/dist/browser/storage/ArchivistFormGroupStorage.d.cts.map +1 -0
- package/dist/browser/storage/ArchivistFormGroupStorage.d.mts +13 -0
- package/dist/browser/storage/ArchivistFormGroupStorage.d.mts.map +1 -0
- package/dist/browser/storage/ArchivistFormGroupStorage.d.ts +13 -0
- package/dist/browser/storage/ArchivistFormGroupStorage.d.ts.map +1 -0
- package/dist/browser/storage/FormGroupStorage.d.cts +8 -0
- package/dist/browser/storage/FormGroupStorage.d.cts.map +1 -0
- package/dist/browser/storage/FormGroupStorage.d.mts +8 -0
- package/dist/browser/storage/FormGroupStorage.d.mts.map +1 -0
- package/dist/browser/storage/FormGroupStorage.d.ts +8 -0
- package/dist/browser/storage/FormGroupStorage.d.ts.map +1 -0
- package/dist/browser/storage/index.d.cts +3 -0
- package/dist/browser/storage/index.d.cts.map +1 -0
- package/dist/browser/storage/index.d.mts +3 -0
- package/dist/browser/storage/index.d.mts.map +1 -0
- package/dist/browser/storage/index.d.ts +3 -0
- package/dist/browser/storage/index.d.ts.map +1 -0
- package/dist/neutral/FormGroup.d.cts +44 -0
- package/dist/neutral/FormGroup.d.cts.map +1 -0
- package/dist/neutral/FormGroup.d.mts +44 -0
- package/dist/neutral/FormGroup.d.mts.map +1 -0
- package/dist/neutral/FormGroup.d.ts +44 -0
- package/dist/neutral/FormGroup.d.ts.map +1 -0
- package/dist/neutral/InputError.d.cts +5 -0
- package/dist/neutral/InputError.d.cts.map +1 -0
- package/dist/neutral/InputError.d.mts +5 -0
- package/dist/neutral/InputError.d.mts.map +1 -0
- package/dist/neutral/InputError.d.ts +5 -0
- package/dist/neutral/InputError.d.ts.map +1 -0
- package/dist/neutral/context/Context.d.cts +7 -0
- package/dist/neutral/context/Context.d.cts.map +1 -0
- package/dist/neutral/context/Context.d.mts +7 -0
- package/dist/neutral/context/Context.d.mts.map +1 -0
- package/dist/neutral/context/Context.d.ts +7 -0
- package/dist/neutral/context/Context.d.ts.map +1 -0
- package/dist/neutral/context/Provider.d.cts +8 -0
- package/dist/neutral/context/Provider.d.cts.map +1 -0
- package/dist/neutral/context/Provider.d.mts +8 -0
- package/dist/neutral/context/Provider.d.mts.map +1 -0
- package/dist/neutral/context/Provider.d.ts +8 -0
- package/dist/neutral/context/Provider.d.ts.map +1 -0
- package/dist/neutral/context/State.d.cts +7 -0
- package/dist/neutral/context/State.d.cts.map +1 -0
- package/dist/neutral/context/State.d.mts +7 -0
- package/dist/neutral/context/State.d.mts.map +1 -0
- package/dist/neutral/context/State.d.ts +7 -0
- package/dist/neutral/context/State.d.ts.map +1 -0
- package/dist/neutral/context/index.d.cts +5 -0
- package/dist/neutral/context/index.d.cts.map +1 -0
- package/dist/neutral/context/index.d.mts +5 -0
- package/dist/neutral/context/index.d.mts.map +1 -0
- package/dist/neutral/context/index.d.ts +5 -0
- package/dist/neutral/context/index.d.ts.map +1 -0
- package/dist/neutral/context/use.d.cts +6 -0
- package/dist/neutral/context/use.d.cts.map +1 -0
- package/dist/neutral/context/use.d.mts +6 -0
- package/dist/neutral/context/use.d.mts.map +1 -0
- package/dist/neutral/context/use.d.ts +6 -0
- package/dist/neutral/context/use.d.ts.map +1 -0
- package/dist/neutral/control/AbstractControl.d.cts +21 -0
- package/dist/neutral/control/AbstractControl.d.cts.map +1 -0
- package/dist/neutral/control/AbstractControl.d.mts +21 -0
- package/dist/neutral/control/AbstractControl.d.mts.map +1 -0
- package/dist/neutral/control/AbstractControl.d.ts +21 -0
- package/dist/neutral/control/AbstractControl.d.ts.map +1 -0
- package/dist/neutral/control/FormControl.d.cts +25 -0
- package/dist/neutral/control/FormControl.d.cts.map +1 -0
- package/dist/neutral/control/FormControl.d.mts +25 -0
- package/dist/neutral/control/FormControl.d.mts.map +1 -0
- package/dist/neutral/control/FormControl.d.ts +25 -0
- package/dist/neutral/control/FormControl.d.ts.map +1 -0
- package/dist/neutral/control/FormControlBase.d.cts +26 -0
- package/dist/neutral/control/FormControlBase.d.cts.map +1 -0
- package/dist/neutral/control/FormControlBase.d.mts +26 -0
- package/dist/neutral/control/FormControlBase.d.mts.map +1 -0
- package/dist/neutral/control/FormControlBase.d.ts +26 -0
- package/dist/neutral/control/FormControlBase.d.ts.map +1 -0
- package/dist/neutral/control/accessor/ControlValueAccessor.d.cts +21 -0
- package/dist/neutral/control/accessor/ControlValueAccessor.d.cts.map +1 -0
- package/dist/neutral/control/accessor/ControlValueAccessor.d.mts +21 -0
- package/dist/neutral/control/accessor/ControlValueAccessor.d.mts.map +1 -0
- package/dist/neutral/control/accessor/ControlValueAccessor.d.ts +21 -0
- package/dist/neutral/control/accessor/ControlValueAccessor.d.ts.map +1 -0
- package/dist/neutral/control/accessor/ControlValueAccessorBase.d.cts +45 -0
- package/dist/neutral/control/accessor/ControlValueAccessorBase.d.cts.map +1 -0
- package/dist/neutral/control/accessor/ControlValueAccessorBase.d.mts +45 -0
- package/dist/neutral/control/accessor/ControlValueAccessorBase.d.mts.map +1 -0
- package/dist/neutral/control/accessor/ControlValueAccessorBase.d.ts +45 -0
- package/dist/neutral/control/accessor/ControlValueAccessorBase.d.ts.map +1 -0
- package/dist/neutral/control/accessor/FormControlStatus.d.cts +6 -0
- package/dist/neutral/control/accessor/FormControlStatus.d.cts.map +1 -0
- package/dist/neutral/control/accessor/FormControlStatus.d.mts +6 -0
- package/dist/neutral/control/accessor/FormControlStatus.d.mts.map +1 -0
- package/dist/neutral/control/accessor/FormControlStatus.d.ts +6 -0
- package/dist/neutral/control/accessor/FormControlStatus.d.ts.map +1 -0
- package/dist/neutral/control/accessor/ValidControlValue.d.cts +2 -0
- package/dist/neutral/control/accessor/ValidControlValue.d.cts.map +1 -0
- package/dist/neutral/control/accessor/ValidControlValue.d.mts +2 -0
- package/dist/neutral/control/accessor/ValidControlValue.d.mts.map +1 -0
- package/dist/neutral/control/accessor/ValidControlValue.d.ts +2 -0
- package/dist/neutral/control/accessor/ValidControlValue.d.ts.map +1 -0
- package/dist/neutral/control/accessor/index.d.cts +5 -0
- package/dist/neutral/control/accessor/index.d.cts.map +1 -0
- package/dist/neutral/control/accessor/index.d.mts +5 -0
- package/dist/neutral/control/accessor/index.d.mts.map +1 -0
- package/dist/neutral/control/accessor/index.d.ts +5 -0
- package/dist/neutral/control/accessor/index.d.ts.map +1 -0
- package/dist/neutral/control/index.d.cts +5 -0
- package/dist/neutral/control/index.d.cts.map +1 -0
- package/dist/neutral/control/index.d.mts +5 -0
- package/dist/neutral/control/index.d.mts.map +1 -0
- package/dist/neutral/control/index.d.ts +5 -0
- package/dist/neutral/control/index.d.ts.map +1 -0
- package/dist/neutral/index.cjs +517 -0
- package/dist/neutral/index.cjs.map +1 -0
- package/dist/neutral/index.d.cts +6 -0
- package/dist/neutral/index.d.cts.map +1 -0
- package/dist/neutral/index.d.mts +6 -0
- package/dist/neutral/index.d.mts.map +1 -0
- package/dist/neutral/index.d.ts +6 -0
- package/dist/neutral/index.d.ts.map +1 -0
- package/dist/neutral/index.js +494 -0
- package/dist/neutral/index.js.map +1 -0
- package/dist/neutral/storage/ArchivistFormGroupStorage.d.cts +13 -0
- package/dist/neutral/storage/ArchivistFormGroupStorage.d.cts.map +1 -0
- package/dist/neutral/storage/ArchivistFormGroupStorage.d.mts +13 -0
- package/dist/neutral/storage/ArchivistFormGroupStorage.d.mts.map +1 -0
- package/dist/neutral/storage/ArchivistFormGroupStorage.d.ts +13 -0
- package/dist/neutral/storage/ArchivistFormGroupStorage.d.ts.map +1 -0
- package/dist/neutral/storage/FormGroupStorage.d.cts +8 -0
- package/dist/neutral/storage/FormGroupStorage.d.cts.map +1 -0
- package/dist/neutral/storage/FormGroupStorage.d.mts +8 -0
- package/dist/neutral/storage/FormGroupStorage.d.mts.map +1 -0
- package/dist/neutral/storage/FormGroupStorage.d.ts +8 -0
- package/dist/neutral/storage/FormGroupStorage.d.ts.map +1 -0
- package/dist/neutral/storage/index.d.cts +3 -0
- package/dist/neutral/storage/index.d.cts.map +1 -0
- package/dist/neutral/storage/index.d.mts +3 -0
- package/dist/neutral/storage/index.d.mts.map +1 -0
- package/dist/neutral/storage/index.d.ts +3 -0
- package/dist/neutral/storage/index.d.ts.map +1 -0
- package/dist/node/FormGroup.d.cts +44 -0
- package/dist/node/FormGroup.d.cts.map +1 -0
- package/dist/node/FormGroup.d.mts +44 -0
- package/dist/node/FormGroup.d.mts.map +1 -0
- package/dist/node/FormGroup.d.ts +44 -0
- package/dist/node/FormGroup.d.ts.map +1 -0
- package/dist/node/InputError.d.cts +5 -0
- package/dist/node/InputError.d.cts.map +1 -0
- package/dist/node/InputError.d.mts +5 -0
- package/dist/node/InputError.d.mts.map +1 -0
- package/dist/node/InputError.d.ts +5 -0
- package/dist/node/InputError.d.ts.map +1 -0
- package/dist/node/context/Context.d.cts +7 -0
- package/dist/node/context/Context.d.cts.map +1 -0
- package/dist/node/context/Context.d.mts +7 -0
- package/dist/node/context/Context.d.mts.map +1 -0
- package/dist/node/context/Context.d.ts +7 -0
- package/dist/node/context/Context.d.ts.map +1 -0
- package/dist/node/context/Provider.d.cts +8 -0
- package/dist/node/context/Provider.d.cts.map +1 -0
- package/dist/node/context/Provider.d.mts +8 -0
- package/dist/node/context/Provider.d.mts.map +1 -0
- package/dist/node/context/Provider.d.ts +8 -0
- package/dist/node/context/Provider.d.ts.map +1 -0
- package/dist/node/context/State.d.cts +7 -0
- package/dist/node/context/State.d.cts.map +1 -0
- package/dist/node/context/State.d.mts +7 -0
- package/dist/node/context/State.d.mts.map +1 -0
- package/dist/node/context/State.d.ts +7 -0
- package/dist/node/context/State.d.ts.map +1 -0
- package/dist/node/context/index.d.cts +5 -0
- package/dist/node/context/index.d.cts.map +1 -0
- package/dist/node/context/index.d.mts +5 -0
- package/dist/node/context/index.d.mts.map +1 -0
- package/dist/node/context/index.d.ts +5 -0
- package/dist/node/context/index.d.ts.map +1 -0
- package/dist/node/context/use.d.cts +6 -0
- package/dist/node/context/use.d.cts.map +1 -0
- package/dist/node/context/use.d.mts +6 -0
- package/dist/node/context/use.d.mts.map +1 -0
- package/dist/node/context/use.d.ts +6 -0
- package/dist/node/context/use.d.ts.map +1 -0
- package/dist/node/control/AbstractControl.d.cts +21 -0
- package/dist/node/control/AbstractControl.d.cts.map +1 -0
- package/dist/node/control/AbstractControl.d.mts +21 -0
- package/dist/node/control/AbstractControl.d.mts.map +1 -0
- package/dist/node/control/AbstractControl.d.ts +21 -0
- package/dist/node/control/AbstractControl.d.ts.map +1 -0
- package/dist/node/control/FormControl.d.cts +25 -0
- package/dist/node/control/FormControl.d.cts.map +1 -0
- package/dist/node/control/FormControl.d.mts +25 -0
- package/dist/node/control/FormControl.d.mts.map +1 -0
- package/dist/node/control/FormControl.d.ts +25 -0
- package/dist/node/control/FormControl.d.ts.map +1 -0
- package/dist/node/control/FormControlBase.d.cts +26 -0
- package/dist/node/control/FormControlBase.d.cts.map +1 -0
- package/dist/node/control/FormControlBase.d.mts +26 -0
- package/dist/node/control/FormControlBase.d.mts.map +1 -0
- package/dist/node/control/FormControlBase.d.ts +26 -0
- package/dist/node/control/FormControlBase.d.ts.map +1 -0
- package/dist/node/control/accessor/ControlValueAccessor.d.cts +21 -0
- package/dist/node/control/accessor/ControlValueAccessor.d.cts.map +1 -0
- package/dist/node/control/accessor/ControlValueAccessor.d.mts +21 -0
- package/dist/node/control/accessor/ControlValueAccessor.d.mts.map +1 -0
- package/dist/node/control/accessor/ControlValueAccessor.d.ts +21 -0
- package/dist/node/control/accessor/ControlValueAccessor.d.ts.map +1 -0
- package/dist/node/control/accessor/ControlValueAccessorBase.d.cts +45 -0
- package/dist/node/control/accessor/ControlValueAccessorBase.d.cts.map +1 -0
- package/dist/node/control/accessor/ControlValueAccessorBase.d.mts +45 -0
- package/dist/node/control/accessor/ControlValueAccessorBase.d.mts.map +1 -0
- package/dist/node/control/accessor/ControlValueAccessorBase.d.ts +45 -0
- package/dist/node/control/accessor/ControlValueAccessorBase.d.ts.map +1 -0
- package/dist/node/control/accessor/FormControlStatus.d.cts +6 -0
- package/dist/node/control/accessor/FormControlStatus.d.cts.map +1 -0
- package/dist/node/control/accessor/FormControlStatus.d.mts +6 -0
- package/dist/node/control/accessor/FormControlStatus.d.mts.map +1 -0
- package/dist/node/control/accessor/FormControlStatus.d.ts +6 -0
- package/dist/node/control/accessor/FormControlStatus.d.ts.map +1 -0
- package/dist/node/control/accessor/ValidControlValue.d.cts +2 -0
- package/dist/node/control/accessor/ValidControlValue.d.cts.map +1 -0
- package/dist/node/control/accessor/ValidControlValue.d.mts +2 -0
- package/dist/node/control/accessor/ValidControlValue.d.mts.map +1 -0
- package/dist/node/control/accessor/ValidControlValue.d.ts +2 -0
- package/dist/node/control/accessor/ValidControlValue.d.ts.map +1 -0
- package/dist/node/control/accessor/index.d.cts +5 -0
- package/dist/node/control/accessor/index.d.cts.map +1 -0
- package/dist/node/control/accessor/index.d.mts +5 -0
- package/dist/node/control/accessor/index.d.mts.map +1 -0
- package/dist/node/control/accessor/index.d.ts +5 -0
- package/dist/node/control/accessor/index.d.ts.map +1 -0
- package/dist/node/control/index.d.cts +5 -0
- package/dist/node/control/index.d.cts.map +1 -0
- package/dist/node/control/index.d.mts +5 -0
- package/dist/node/control/index.d.mts.map +1 -0
- package/dist/node/control/index.d.ts +5 -0
- package/dist/node/control/index.d.ts.map +1 -0
- package/dist/node/index.cjs +542 -0
- package/dist/node/index.cjs.map +1 -0
- package/dist/node/index.d.cts +6 -0
- package/dist/node/index.d.cts.map +1 -0
- package/dist/node/index.d.mts +6 -0
- package/dist/node/index.d.mts.map +1 -0
- package/dist/node/index.d.ts +6 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +503 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/storage/ArchivistFormGroupStorage.d.cts +13 -0
- package/dist/node/storage/ArchivistFormGroupStorage.d.cts.map +1 -0
- package/dist/node/storage/ArchivistFormGroupStorage.d.mts +13 -0
- package/dist/node/storage/ArchivistFormGroupStorage.d.mts.map +1 -0
- package/dist/node/storage/ArchivistFormGroupStorage.d.ts +13 -0
- package/dist/node/storage/ArchivistFormGroupStorage.d.ts.map +1 -0
- package/dist/node/storage/FormGroupStorage.d.cts +8 -0
- package/dist/node/storage/FormGroupStorage.d.cts.map +1 -0
- package/dist/node/storage/FormGroupStorage.d.mts +8 -0
- package/dist/node/storage/FormGroupStorage.d.mts.map +1 -0
- package/dist/node/storage/FormGroupStorage.d.ts +8 -0
- package/dist/node/storage/FormGroupStorage.d.ts.map +1 -0
- package/dist/node/storage/index.d.cts +3 -0
- package/dist/node/storage/index.d.cts.map +1 -0
- package/dist/node/storage/index.d.mts +3 -0
- package/dist/node/storage/index.d.mts.map +1 -0
- package/dist/node/storage/index.d.ts +3 -0
- package/dist/node/storage/index.d.ts.map +1 -0
- package/package.json +88 -0
- package/src/FormGroup.ts +226 -0
- package/src/InputError.ts +4 -0
- package/src/context/Context.ts +5 -0
- package/src/context/Provider.tsx +25 -0
- package/src/context/State.ts +8 -0
- package/src/context/index.ts +4 -0
- package/src/context/use.tsx +5 -0
- package/src/control/AbstractControl.ts +125 -0
- package/src/control/FormControl.ts +31 -0
- package/src/control/FormControlBase.ts +82 -0
- package/src/control/accessor/ControlValueAccessor.ts +23 -0
- package/src/control/accessor/ControlValueAccessorBase.ts +187 -0
- package/src/control/accessor/FormControlStatus.ts +36 -0
- package/src/control/accessor/ValidControlValue.ts +1 -0
- package/src/control/accessor/index.ts +4 -0
- package/src/control/index.ts +4 -0
- package/src/index.ts +5 -0
- package/src/storage/ArchivistFormGroupStorage.ts +21 -0
- package/src/storage/FormGroupStorage.ts +8 -0
- package/src/storage/index.ts +2 -0
- package/src/stories/test.stories.tsx +20 -0
- package/src/types/images.d.ts +5 -0
- package/typedoc.json +5 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAA;AAC9C,cAAc,uBAAuB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAA;AAC9C,cAAc,uBAAuB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAA;AAC9C,cAAc,uBAAuB,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@xyo-network/react-form-group",
|
|
3
|
+
"author": {
|
|
4
|
+
"email": "support@xyo.network",
|
|
5
|
+
"name": "XYO Development Team",
|
|
6
|
+
"url": "https://xyo.network"
|
|
7
|
+
},
|
|
8
|
+
"bugs": {
|
|
9
|
+
"email": "support@xyo.network",
|
|
10
|
+
"url": "https://github.com/XYOracleNetwork/sdk-xyo-react-js/issues"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@mui/icons-material": "^5.16.1",
|
|
14
|
+
"@xylabs/forget": "^3.5.9",
|
|
15
|
+
"@xylabs/object": "^3.5.9",
|
|
16
|
+
"@xylabs/promise": "^3.5.9",
|
|
17
|
+
"@xyo-network/archivist-model": "^2.110.5",
|
|
18
|
+
"@xyo-network/module-abstract": "^2.110.5",
|
|
19
|
+
"@xyo-network/module-events": "^2.110.5",
|
|
20
|
+
"@xyo-network/payload-model": "^2.110.5",
|
|
21
|
+
"@xyo-network/react-shared": "^2.81.2"
|
|
22
|
+
},
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"@mui/material": "^5",
|
|
25
|
+
"@mui/styles": "^5",
|
|
26
|
+
"react": "^18",
|
|
27
|
+
"react-dom": "^18"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@storybook/react": "^7.6.20",
|
|
31
|
+
"@xylabs/ts-scripts-yarn3": "^3.12.1",
|
|
32
|
+
"@xylabs/tsconfig-react": "^3.12.1",
|
|
33
|
+
"typescript": "^5.5.3"
|
|
34
|
+
},
|
|
35
|
+
"description": "Common React library for all XYO projects that use React",
|
|
36
|
+
"docs": "dist/docs.json",
|
|
37
|
+
"exports": {
|
|
38
|
+
".": {
|
|
39
|
+
"node": {
|
|
40
|
+
"import": {
|
|
41
|
+
"types": "./dist/node/index.d.mts",
|
|
42
|
+
"default": "./dist/node/index.js"
|
|
43
|
+
},
|
|
44
|
+
"require": {
|
|
45
|
+
"types": "./dist/node/index.d.cts",
|
|
46
|
+
"default": "./dist/node/index.cjs"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"browser": {
|
|
50
|
+
"import": {
|
|
51
|
+
"types": "./dist/browser/index.d.mts",
|
|
52
|
+
"default": "./dist/browser/index.js"
|
|
53
|
+
},
|
|
54
|
+
"require": {
|
|
55
|
+
"types": "./dist/browser/index.d.cts",
|
|
56
|
+
"default": "./dist/browser/index.cjs"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"default": "./dist/browser/index.js"
|
|
60
|
+
},
|
|
61
|
+
"./package.json": "./package.json"
|
|
62
|
+
},
|
|
63
|
+
"main": "dist/browser/index.cjs",
|
|
64
|
+
"module": "dist/browser/index.js",
|
|
65
|
+
"homepage": "https://xyo.network",
|
|
66
|
+
"keywords": [
|
|
67
|
+
"xyo",
|
|
68
|
+
"utility",
|
|
69
|
+
"typescript",
|
|
70
|
+
"react"
|
|
71
|
+
],
|
|
72
|
+
"license": "LGPL-3.0-only",
|
|
73
|
+
"publishConfig": {
|
|
74
|
+
"access": "public"
|
|
75
|
+
},
|
|
76
|
+
"repository": {
|
|
77
|
+
"type": "git",
|
|
78
|
+
"url": "https://github.com/XYOracleNetwork/sdk-xyo-react-js.git"
|
|
79
|
+
},
|
|
80
|
+
"scripts": {
|
|
81
|
+
"lint-pkg": "npmPkgJsonLint .",
|
|
82
|
+
"license": "yarn license-checker --exclude \"MIT, ISC, Apache-2.0, BSD, BSD-2-Clause, CC-BY-4.0, Unlicense, CC-BY-3.0, CC0-1.0\""
|
|
83
|
+
},
|
|
84
|
+
"sideEffects": false,
|
|
85
|
+
"types": "dist/browser/index.d.ts",
|
|
86
|
+
"version": "2.81.2",
|
|
87
|
+
"type": "module"
|
|
88
|
+
}
|
package/src/FormGroup.ts
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { forget } from '@xylabs/forget'
|
|
2
|
+
import { EventListener } from '@xyo-network/module-events'
|
|
3
|
+
import { Payload } from '@xyo-network/payload-model'
|
|
4
|
+
|
|
5
|
+
import { AbstractControl, ControlValueAccessorBaseEvents } from './control/index.js'
|
|
6
|
+
import { ErrorSummary } from './InputError.js'
|
|
7
|
+
import { FormGroupStorage } from './storage/index.js'
|
|
8
|
+
|
|
9
|
+
export type PayloadWithTimestamp = Payload<{ timestamp?: number }>
|
|
10
|
+
|
|
11
|
+
export type KeyOfString<T> = keyof T extends string ? keyof T : never
|
|
12
|
+
|
|
13
|
+
type FormGroupErrors<TValue> = Record<KeyOfString<TValue>, string>
|
|
14
|
+
|
|
15
|
+
export type FormGroupParams<TStorageValue extends Payload = Payload> = {
|
|
16
|
+
serialize?: boolean
|
|
17
|
+
storage?: {
|
|
18
|
+
sensitive?: FormGroupStorage<TStorageValue>
|
|
19
|
+
storage?: FormGroupStorage<TStorageValue>
|
|
20
|
+
}
|
|
21
|
+
ttlStorage?: number
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type ValueChangeEventListener = EventListener<ControlValueAccessorBaseEvents['valueChanged']>
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Organize form controls in a group.
|
|
28
|
+
*
|
|
29
|
+
* NOTE: This is a work in progress and only supports top level controls. Nested controls are not supported.
|
|
30
|
+
*/
|
|
31
|
+
export class FormGroup<
|
|
32
|
+
TValue extends PayloadWithTimestamp = PayloadWithTimestamp,
|
|
33
|
+
TStorageValue extends PayloadWithTimestamp = PayloadWithTimestamp,
|
|
34
|
+
> extends AbstractControl {
|
|
35
|
+
private _controls = {} as Record<KeyOfString<TValue>, AbstractControl>
|
|
36
|
+
|
|
37
|
+
private serializeListeners: Record<string, ValueChangeEventListener> = {}
|
|
38
|
+
|
|
39
|
+
private serializedSensitiveState = {} as Record<KeyOfString<TStorageValue>, string>
|
|
40
|
+
private serializedState = {} as Record<KeyOfString<TStorageValue>, string>
|
|
41
|
+
|
|
42
|
+
constructor(private fgParams?: FormGroupParams<TStorageValue>) {
|
|
43
|
+
super()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
get errorSummary() {
|
|
47
|
+
const errorSummary: ErrorSummary = {
|
|
48
|
+
errorMessage: '',
|
|
49
|
+
invalidFields: [],
|
|
50
|
+
}
|
|
51
|
+
for (const [key, value] of Object.entries(this.errors)) {
|
|
52
|
+
if (value) {
|
|
53
|
+
errorSummary.errorMessage = `${errorSummary.errorMessage}, ${value}`
|
|
54
|
+
errorSummary.invalidFields.push(key)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return errorSummary
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
get errors(): FormGroupErrors<TValue> {
|
|
62
|
+
const value = {} as FormGroupErrors<TValue>
|
|
63
|
+
for (const key in this._controls) {
|
|
64
|
+
const castKey = key as KeyOfString<TValue>
|
|
65
|
+
value[castKey] = this._controls[castKey].error
|
|
66
|
+
}
|
|
67
|
+
return value
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
get nonSensitiveStorage() {
|
|
71
|
+
return this.fgParams?.storage?.storage
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
get sensitiveStorage() {
|
|
75
|
+
return this.fgParams?.storage?.sensitive
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
override get touched() {
|
|
79
|
+
return Object.values<AbstractControl>(this._controls).some((control) => control.touched)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
override get valid() {
|
|
83
|
+
return Object.values<AbstractControl>(this._controls).every((control) => control.valid)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
get values(): TValue {
|
|
87
|
+
const value = {} as TValue
|
|
88
|
+
for (const key in this._controls) {
|
|
89
|
+
const castKey = key as KeyOfString<TValue>
|
|
90
|
+
value[castKey] = this._controls[castKey].rawValue as TValue[KeyOfString<TValue>]
|
|
91
|
+
}
|
|
92
|
+
return value
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
getControl(name: string) {
|
|
96
|
+
return this._controls[name as KeyOfString<TValue>]
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async getSerializedValue(name: string, sensitive = false): Promise<string | undefined> {
|
|
100
|
+
const storage = sensitive ? this.sensitiveStorage : this.nonSensitiveStorage
|
|
101
|
+
if (storage) {
|
|
102
|
+
if (!storage) {
|
|
103
|
+
console.warn(`Cannot return value for ${name}. No storage set`)
|
|
104
|
+
return
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const savedState = await storage.get()
|
|
108
|
+
if (savedState && name in savedState) {
|
|
109
|
+
const savedValue = savedState[name as keyof typeof savedState] as string
|
|
110
|
+
|
|
111
|
+
// casting to PayloadWithTimestamp to check for timestamp
|
|
112
|
+
const savedStateWithTimestamp = savedState as unknown as PayloadWithTimestamp
|
|
113
|
+
if (savedStateWithTimestamp.timestamp && this.fgParams?.ttlStorage) {
|
|
114
|
+
const expirationDate = savedStateWithTimestamp.timestamp + (this.fgParams?.ttlStorage ?? 0)
|
|
115
|
+
const now = Date.now()
|
|
116
|
+
return now > expirationDate ? undefined : savedValue
|
|
117
|
+
}
|
|
118
|
+
return savedValue
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
registerControl(name: string, control: AbstractControl) {
|
|
124
|
+
if (this._controls[name as KeyOfString<TValue>]) console.error(`Replacing Control with name ${name} since it already exists!`)
|
|
125
|
+
this._controls[name as KeyOfString<TValue>] = control
|
|
126
|
+
this.serializeControlValue(name, control)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
resetControls() {
|
|
130
|
+
for (const key in this._controls) {
|
|
131
|
+
this.unregisterControl(key)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
resetValues() {
|
|
136
|
+
for (const control of Object.values<AbstractControl>(this._controls)) {
|
|
137
|
+
control.setValue('')
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
unregisterControl(name: string) {
|
|
142
|
+
const control = this._controls[name as KeyOfString<TValue>]
|
|
143
|
+
|
|
144
|
+
if (control) {
|
|
145
|
+
const listener = this.serializeListeners[name]
|
|
146
|
+
control.off('valueChanged', listener)
|
|
147
|
+
delete this.serializeListeners[name]
|
|
148
|
+
delete this._controls[name as KeyOfString<TValue>]
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
validateFields(requiredFields?: string[] | undefined) {
|
|
153
|
+
const castRequiredFields = requiredFields as KeyOfString<TValue>[]
|
|
154
|
+
for (const key in this._controls) {
|
|
155
|
+
const castKey = key as KeyOfString<TValue>
|
|
156
|
+
if (castRequiredFields === undefined || castRequiredFields.includes(castKey)) {
|
|
157
|
+
const control = this._controls[castKey]
|
|
158
|
+
control.validate()
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private serializeControlValue(name: string, control: AbstractControl) {
|
|
164
|
+
const shouldSerialize = this.fgParams?.serialize
|
|
165
|
+
const sensitiveStorage = this.sensitiveStorage
|
|
166
|
+
const storage = this.nonSensitiveStorage
|
|
167
|
+
|
|
168
|
+
if (!shouldSerialize && (storage || sensitiveStorage)) console.warn('storage medium set but serialize is not enabled')
|
|
169
|
+
|
|
170
|
+
if (shouldSerialize && control.serializeSettings.serializable) {
|
|
171
|
+
this.setStateValueFromStorage(name, control)
|
|
172
|
+
|
|
173
|
+
const listener: ValueChangeEventListener = ({ value }) => {
|
|
174
|
+
// detect if control wants to be serialized
|
|
175
|
+
if (control.serializeSettings.serializable) {
|
|
176
|
+
// detect control's preferred storage
|
|
177
|
+
const targetStorage = control.serializeSettings.sensitive ? sensitiveStorage : storage
|
|
178
|
+
|
|
179
|
+
// detect control's preferred state
|
|
180
|
+
const targetState = control.serializeSettings.sensitive ? this.serializedSensitiveState : this.serializedState
|
|
181
|
+
|
|
182
|
+
// set the value
|
|
183
|
+
targetState[name as KeyOfString<TStorageValue>] = value ?? ''
|
|
184
|
+
|
|
185
|
+
// add a timestamp
|
|
186
|
+
const payloadWithTimestamp = targetState as PayloadWithTimestamp
|
|
187
|
+
payloadWithTimestamp.timestamp = Date.now()
|
|
188
|
+
|
|
189
|
+
// serialize the value
|
|
190
|
+
this.serializeValues(targetStorage, targetState as TStorageValue)
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// listen for value changes
|
|
195
|
+
control.on('valueChanged', listener)
|
|
196
|
+
|
|
197
|
+
// store the listener for later removal
|
|
198
|
+
this.serializeListeners[name] = listener
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
private serializeValues(storage?: FormGroupStorage<TStorageValue>, values?: TStorageValue) {
|
|
203
|
+
if (storage && values) {
|
|
204
|
+
const write = async () => await storage.insert(values)
|
|
205
|
+
const clear = async () => await storage.clear()
|
|
206
|
+
|
|
207
|
+
forget(clear())
|
|
208
|
+
forget(write())
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
private setStateValueFromStorage(name: string, control: AbstractControl) {
|
|
213
|
+
const read = async () => {
|
|
214
|
+
const savedValue = await this.getSerializedValue(name, control.serializeSettings.sensitive)
|
|
215
|
+
|
|
216
|
+
if (savedValue) {
|
|
217
|
+
const targetState = control.serializeSettings.sensitive ? this.serializedSensitiveState : this.serializedState
|
|
218
|
+
targetState[name as KeyOfString<TStorageValue>] = savedValue
|
|
219
|
+
|
|
220
|
+
control.setValue(savedValue, { disableEmit: true })
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
forget(read())
|
|
225
|
+
}
|
|
226
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Payload } from '@xyo-network/payload-model'
|
|
2
|
+
import { PropsWithChildren, useMemo } from 'react'
|
|
3
|
+
|
|
4
|
+
import { FormGroup, FormGroupParams } from '../FormGroup.js'
|
|
5
|
+
import { FormGroupBaseContext } from './Context.js'
|
|
6
|
+
|
|
7
|
+
export interface FormGroupPayloadProviderProps<TStorage extends Payload = Payload> extends PropsWithChildren {
|
|
8
|
+
params?: FormGroupParams<TStorage>
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Provides a FormGroup to child components.
|
|
13
|
+
*/
|
|
14
|
+
export const FormGroupPayloadProvider = ({ children, params, ...props }: FormGroupPayloadProviderProps) => {
|
|
15
|
+
const formGroup = useMemo(() => {
|
|
16
|
+
const formGroup = new FormGroup<Payload, Payload>(params)
|
|
17
|
+
return formGroup
|
|
18
|
+
}, [params])
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<FormGroupBaseContext.Provider value={{ formGroup, provided: true }} {...props}>
|
|
22
|
+
{children}
|
|
23
|
+
</FormGroupBaseContext.Provider>
|
|
24
|
+
)
|
|
25
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Payload } from '@xyo-network/payload-model'
|
|
2
|
+
import { ContextExState } from '@xyo-network/react-shared'
|
|
3
|
+
|
|
4
|
+
import { FormGroup } from '../FormGroup.js'
|
|
5
|
+
|
|
6
|
+
export interface FormGroupContextWithPayloadState<TValue extends Payload = Payload, TStorageValue extends Payload = Payload> extends ContextExState {
|
|
7
|
+
formGroup?: FormGroup<TValue, TStorageValue>
|
|
8
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { forget } from '@xylabs/forget'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
ControlValueAccessorBase,
|
|
5
|
+
ControlValueAccessorBaseEvents,
|
|
6
|
+
DISABLED,
|
|
7
|
+
FormControlStatus,
|
|
8
|
+
INVALID,
|
|
9
|
+
PENDING,
|
|
10
|
+
VALID,
|
|
11
|
+
ValidControlValue,
|
|
12
|
+
} from './accessor/index.js'
|
|
13
|
+
|
|
14
|
+
export type AbstractControlEvents<TValue> = ControlValueAccessorBaseEvents<TValue> & {
|
|
15
|
+
statusChanged: { status: FormControlStatus }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* This is the base class for `Control` classes (i.e. FormControl),
|
|
20
|
+
*
|
|
21
|
+
* It provides some of the shared behavior that all controls and groups of controls have, like
|
|
22
|
+
* running validators, calculating status, and resetting state. It also defines the properties
|
|
23
|
+
* that are shared between all sub-classes, like `value`, `valid`, and `dirty`. It shouldn't be
|
|
24
|
+
* instantiated directly.
|
|
25
|
+
*
|
|
26
|
+
* NOTE: Heavily borrowed from Angular's AbstractControl:
|
|
27
|
+
* https://github.com/angular/angular/blob/5dcdbfcba934a930468aec140a7183b034466bdf/packages/forms/src/model/abstract_model.ts
|
|
28
|
+
*/
|
|
29
|
+
export class AbstractControl<TValue extends ValidControlValue = ValidControlValue> extends ControlValueAccessorBase<
|
|
30
|
+
TValue,
|
|
31
|
+
AbstractControlEvents<TValue>
|
|
32
|
+
> {
|
|
33
|
+
private _status: FormControlStatus | undefined = undefined
|
|
34
|
+
|
|
35
|
+
constructor() {
|
|
36
|
+
super({})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* A control is `disabled` when its `status` is `DISABLED`.
|
|
41
|
+
*
|
|
42
|
+
* Disabled controls are exempt from validation checks and
|
|
43
|
+
* are not included in the aggregate value of their ancestor
|
|
44
|
+
* controls.
|
|
45
|
+
*
|
|
46
|
+
* @returns True if the control is disabled, false otherwise.
|
|
47
|
+
*/
|
|
48
|
+
/** @deprecated - disabled functionality not implemented */
|
|
49
|
+
get disabled(): boolean {
|
|
50
|
+
return this.status === DISABLED
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* A control is `enabled` as long as its `status` is not `DISABLED`.
|
|
55
|
+
*
|
|
56
|
+
* @returns True if the control has any status other than 'DISABLED',
|
|
57
|
+
* false if the status is 'DISABLED'.
|
|
58
|
+
*/
|
|
59
|
+
get enabled(): boolean {
|
|
60
|
+
return this.status !== DISABLED
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* A control is `invalid` when its `status` is `INVALID`.
|
|
65
|
+
|
|
66
|
+
*
|
|
67
|
+
* @returns True if this control has failed one or more of its validation checks,
|
|
68
|
+
* false otherwise.
|
|
69
|
+
*/
|
|
70
|
+
get invalid(): boolean {
|
|
71
|
+
return this.status === INVALID
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* A control is `pending` when its `status` is `PENDING`.
|
|
76
|
+
*
|
|
77
|
+
* @returns True if this control is in the process of conducting a validation check,
|
|
78
|
+
* false otherwise.
|
|
79
|
+
*/
|
|
80
|
+
get pending(): boolean {
|
|
81
|
+
return this.status == PENDING
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* The raw value of the control.
|
|
86
|
+
*/
|
|
87
|
+
get rawValue(): TValue {
|
|
88
|
+
return this.value
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The current status of the control.
|
|
93
|
+
*/
|
|
94
|
+
get status() {
|
|
95
|
+
return this._status
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* A control is `valid` when its `status` is `VALID`.
|
|
100
|
+
*
|
|
101
|
+
* @returns True if the control has passed all of its validation tests,
|
|
102
|
+
* false otherwise.
|
|
103
|
+
*/
|
|
104
|
+
get valid(): boolean {
|
|
105
|
+
return this.status === VALID
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
setErrorAndValidity(error: string, status: FormControlStatus) {
|
|
109
|
+
this.setError(error)
|
|
110
|
+
this.setStatus(status)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
setStatus(status: FormControlStatus) {
|
|
114
|
+
if (this._status === status) return
|
|
115
|
+
|
|
116
|
+
this._status = status
|
|
117
|
+
|
|
118
|
+
const emit = async () => await this.emit('statusChanged', { status })
|
|
119
|
+
forget(emit())
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
validate(): boolean {
|
|
123
|
+
return true
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { EmptyObject } from '@xylabs/object'
|
|
2
|
+
|
|
3
|
+
import { AbstractControl } from './AbstractControl.js'
|
|
4
|
+
|
|
5
|
+
export type CursorPosition = {
|
|
6
|
+
current: number | undefined
|
|
7
|
+
previous: number | undefined
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface FormControlValidator {
|
|
11
|
+
blurError?: (value: string) => void
|
|
12
|
+
changeError?: (value: string) => void
|
|
13
|
+
// filter that supports an empty value
|
|
14
|
+
pattern?: RegExp
|
|
15
|
+
// filter that does not support an empty value
|
|
16
|
+
patternStrict?: RegExp
|
|
17
|
+
required?: boolean
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface FormControlMask {
|
|
21
|
+
cursorPosition: CursorPosition
|
|
22
|
+
getCursorPosition?: () => number | undefined
|
|
23
|
+
mask?: (value: string) => string
|
|
24
|
+
onCursorChange?: (cursor: number | undefined) => void
|
|
25
|
+
unmask?: (value: string) => string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface FormControl<TProps extends EmptyObject = EmptyObject> extends FormControlValidator, FormControlMask, AbstractControl {
|
|
29
|
+
readonly name?: string
|
|
30
|
+
props: TProps
|
|
31
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { EmptyObject } from '@xylabs/object'
|
|
2
|
+
|
|
3
|
+
import { AbstractControl } from './AbstractControl.js'
|
|
4
|
+
import { SetOptions } from './accessor/index.js'
|
|
5
|
+
import { CursorPosition, FormControl } from './FormControl.js'
|
|
6
|
+
|
|
7
|
+
const AllowAllRegex = /^.*$/s
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A base class for form controls and their validation.
|
|
11
|
+
*/
|
|
12
|
+
export abstract class FormControlBase<TProps extends EmptyObject = EmptyObject> extends AbstractControl implements FormControl {
|
|
13
|
+
/**
|
|
14
|
+
* The current and previous cursor position of the input element.
|
|
15
|
+
*/
|
|
16
|
+
cursorPosition: CursorPosition = { current: undefined, previous: undefined }
|
|
17
|
+
invalidMessage = 'Invalid input'
|
|
18
|
+
pattern = AllowAllRegex
|
|
19
|
+
patternStrict = AllowAllRegex
|
|
20
|
+
props = {} as TProps
|
|
21
|
+
required = false
|
|
22
|
+
|
|
23
|
+
private _name: string | undefined = undefined
|
|
24
|
+
|
|
25
|
+
constructor() {
|
|
26
|
+
super()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
get name() {
|
|
30
|
+
return this._name
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
override get rawValue() {
|
|
34
|
+
return this.unmask && this.value ? this.unmask(this.value) : this.value
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
blurError?(value: string): void | undefined
|
|
38
|
+
changeError?(value: string): void
|
|
39
|
+
getCursorPosition?(): number | undefined
|
|
40
|
+
mask?(value: string): string
|
|
41
|
+
onCursorChange: (cursor: number | undefined) => void = () => {}
|
|
42
|
+
|
|
43
|
+
override setValue(value: string = '', setOptions: SetOptions) {
|
|
44
|
+
// check for pattern validation
|
|
45
|
+
if (this.unmask && this.pattern) {
|
|
46
|
+
const unmasked = this.unmask(value)
|
|
47
|
+
const match = unmasked.match(this.pattern)
|
|
48
|
+
// set the new value before checking for errors
|
|
49
|
+
super.setValue(this.mask ? this.mask(unmasked) : unmasked, setOptions)
|
|
50
|
+
if (match) {
|
|
51
|
+
// if the value matches the pattern, update the cursor position
|
|
52
|
+
if (this.getCursorPosition) {
|
|
53
|
+
const newCursor = this.getCursorPosition()
|
|
54
|
+
this.onCursorChange(newCursor)
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
// if no match, set the error and return to the previous value
|
|
58
|
+
this.setValue(this.previousValue, setOptions)
|
|
59
|
+
this.onCursorChange?.(this.cursorPosition.previous)
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
// if no mask or pattern, just set the value
|
|
63
|
+
super.setValue(value, setOptions)
|
|
64
|
+
}
|
|
65
|
+
// check for changeError validation after pattern validation
|
|
66
|
+
this.changeError?.(value)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
unmask?(value: string): string
|
|
70
|
+
|
|
71
|
+
// For FormControls, validate is the same as running one of the error checking functions
|
|
72
|
+
override validate(): boolean {
|
|
73
|
+
const normalizedValue = this.value ?? ''
|
|
74
|
+
// prefer the blurError function since validation assumes the user is done typing
|
|
75
|
+
this.blurError ? this.blurError(normalizedValue) : this.changeError?.(normalizedValue)
|
|
76
|
+
return !this.error
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
protected setName(name: string | undefined) {
|
|
80
|
+
this._name = name
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ValidControlValue } from './ValidControlValue.js'
|
|
2
|
+
|
|
3
|
+
export interface SetOptions {
|
|
4
|
+
disableEmit?: boolean
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface ControlSerializeSettings {
|
|
8
|
+
sensitive?: boolean
|
|
9
|
+
serializable?: boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ControlValueAccessor<T = ValidControlValue> {
|
|
13
|
+
readonly error: string
|
|
14
|
+
readonly previousValue: T
|
|
15
|
+
readonly serializeSettings: ControlSerializeSettings
|
|
16
|
+
readonly touched: boolean
|
|
17
|
+
readonly value: T
|
|
18
|
+
registerOnChange(fn: (value: T) => void): void
|
|
19
|
+
registerOnErrorChange(fn: (error: string) => void): void
|
|
20
|
+
registerOnTouched(fn: (isTouched: boolean) => void): void
|
|
21
|
+
setTouched(isTouched: boolean): void
|
|
22
|
+
setValue(fieldValue: T, options?: SetOptions): void
|
|
23
|
+
}
|