@tstdl/base 0.91.41 → 0.91.42

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.
Files changed (79) hide show
  1. package/examples/orm/user.model.d.ts +1 -3
  2. package/examples/orm/user.model.js +0 -10
  3. package/orm/types.d.ts +2 -2
  4. package/orm/types.js +2 -2
  5. package/package.json +1 -1
  6. package/form/abstract-control.d.ts +0 -72
  7. package/form/abstract-control.js +0 -82
  8. package/form/controls/checkbox.control.d.ts +0 -10
  9. package/form/controls/checkbox.control.js +0 -19
  10. package/form/controls/chip-select.control.d.ts +0 -36
  11. package/form/controls/chip-select.control.js +0 -56
  12. package/form/controls/date.control.d.ts +0 -26
  13. package/form/controls/date.control.js +0 -64
  14. package/form/controls/hidden.control.d.ts +0 -11
  15. package/form/controls/hidden.control.js +0 -22
  16. package/form/controls/index.d.ts +0 -10
  17. package/form/controls/index.js +0 -10
  18. package/form/controls/items.control.d.ts +0 -38
  19. package/form/controls/items.control.js +0 -41
  20. package/form/controls/number.control.d.ts +0 -33
  21. package/form/controls/number.control.js +0 -73
  22. package/form/controls/radio-group.control.d.ts +0 -22
  23. package/form/controls/radio-group.control.js +0 -28
  24. package/form/controls/select.control.d.ts +0 -17
  25. package/form/controls/select.control.js +0 -26
  26. package/form/controls/text.control.d.ts +0 -47
  27. package/form/controls/text.control.js +0 -94
  28. package/form/controls/time.control.d.ts +0 -24
  29. package/form/controls/time.control.js +0 -44
  30. package/form/form-array.d.ts +0 -71
  31. package/form/form-array.js +0 -188
  32. package/form/form-button.d.ts +0 -41
  33. package/form/form-button.js +0 -49
  34. package/form/form-container.d.ts +0 -24
  35. package/form/form-container.js +0 -33
  36. package/form/form-control.d.ts +0 -45
  37. package/form/form-control.js +0 -92
  38. package/form/form-dialog.d.ts +0 -22
  39. package/form/form-dialog.js +0 -24
  40. package/form/form-element.d.ts +0 -7
  41. package/form/form-element.js +0 -6
  42. package/form/form-group.d.ts +0 -70
  43. package/form/form-group.js +0 -134
  44. package/form/form-header-footer-element.d.ts +0 -14
  45. package/form/form-header-footer-element.js +0 -20
  46. package/form/form-portal.d.ts +0 -10
  47. package/form/form-portal.js +0 -13
  48. package/form/form-text.d.ts +0 -13
  49. package/form/form-text.js +0 -15
  50. package/form/form-wrapper.d.ts +0 -40
  51. package/form/form-wrapper.js +0 -64
  52. package/form/index.d.ts +0 -15
  53. package/form/index.js +0 -15
  54. package/form/localization.d.ts +0 -49
  55. package/form/localization.js +0 -56
  56. package/form/types.d.ts +0 -11
  57. package/form/types.js +0 -1
  58. package/form/utils.d.ts +0 -38
  59. package/form/utils.js +0 -47
  60. package/form/validators/boolean.validator.d.ts +0 -3
  61. package/form/validators/boolean.validator.js +0 -15
  62. package/form/validators/date.validator.d.ts +0 -4
  63. package/form/validators/date.validator.js +0 -26
  64. package/form/validators/form.validator.d.ts +0 -10
  65. package/form/validators/form.validator.js +0 -3
  66. package/form/validators/index.d.ts +0 -9
  67. package/form/validators/index.js +0 -9
  68. package/form/validators/max-length.validator.d.ts +0 -3
  69. package/form/validators/max-length.validator.js +0 -17
  70. package/form/validators/number.validator.d.ts +0 -4
  71. package/form/validators/number.validator.js +0 -22
  72. package/form/validators/pattern.validator.d.ts +0 -3
  73. package/form/validators/pattern.validator.js +0 -16
  74. package/form/validators/required.validator.d.ts +0 -3
  75. package/form/validators/required.validator.js +0 -16
  76. package/form/validators/time.validator.d.ts +0 -4
  77. package/form/validators/time.validator.js +0 -22
  78. package/form/validators/unique.validator.d.ts +0 -5
  79. package/form/validators/unique.validator.js +0 -22
@@ -1,73 +0,0 @@
1
- import { decimalFormat, formatNumber, integerFormat, yearFormat } from '../../formats.js';
2
- import { getNumberParser } from '../../intl/number-parser.js';
3
- import { isDefined, isNull, isNumber } from '../../utils/type-guards.js';
4
- import { computedInternalValidators } from '../abstract-control.js';
5
- import { FormControl } from '../form-control.js';
6
- import { reactiveOptionToSignal } from '../utils.js';
7
- import { numberValidator } from '../validators/number.validator.js';
8
- const numberParser = getNumberParser('de');
9
- export class NumberFormControl extends FormControl {
10
- internalValidators = computedInternalValidators(() => {
11
- const minimum = this.minimum();
12
- const maximum = this.maximum();
13
- return [(isDefined(minimum) || isDefined(maximum)) ? numberValidator(minimum, maximum) : undefined];
14
- });
15
- autocomplete;
16
- placeholder;
17
- integer;
18
- format;
19
- minimum;
20
- maximum;
21
- step;
22
- constructor(initialValue, options = {}) {
23
- super(initialValue, options);
24
- this.autocomplete = reactiveOptionToSignal(options.autocomplete ?? 'off', { initialValue: 'off' });
25
- this.placeholder = reactiveOptionToSignal(options.placeholder ?? null, { initialValue: null });
26
- this.integer = reactiveOptionToSignal(options.integer ?? false, { initialValue: false });
27
- this.format = reactiveOptionToSignal(options.format ?? decimalFormat, { initialValue: decimalFormat });
28
- this.minimum = reactiveOptionToSignal(options.minimum ?? null, { initialValue: null });
29
- this.maximum = reactiveOptionToSignal(options.maximum ?? null, { initialValue: null });
30
- this.step = reactiveOptionToSignal(options.step ?? null, { initialValue: null });
31
- }
32
- parseRawValue(value) {
33
- if (isNumber(value) && this.integer()) {
34
- return Math.floor(value);
35
- }
36
- return value;
37
- }
38
- parseInputValue(value) {
39
- if (isNull(value) || (value.trim().length == 0)) {
40
- return null;
41
- }
42
- const parsed = numberParser.parse(value, true);
43
- return this.integer() ? Math.floor(parsed) : parsed;
44
- }
45
- formatRawValue(value) {
46
- if (isNull(value)) {
47
- return '';
48
- }
49
- const valueToFormat = this.integer() ? Math.floor(value) : value;
50
- return formatNumber(valueToFormat, this.format());
51
- }
52
- }
53
- export function numberFormControl(options) {
54
- return new NumberFormControl(null, options);
55
- }
56
- export function integerNumberControl(options) {
57
- return numberFormControl({
58
- integer: true,
59
- format: integerFormat,
60
- ...options
61
- });
62
- }
63
- export function yearNumberControl(options) {
64
- return integerNumberControl({
65
- format: yearFormat,
66
- minimum: 1600,
67
- maximum: 2200,
68
- ...options,
69
- });
70
- }
71
- export function isNumberFormControl(value) {
72
- return (value instanceof NumberFormControl);
73
- }
@@ -1,22 +0,0 @@
1
- import type { Signal } from '../../signals/api.js';
2
- import type { EnumerationObject, FilledReadonlyArray, TypedOmit } from '../../types.js';
3
- import type { InitialValue, InitialValueOption } from '../form-control.js';
4
- import { ItemsFormControl, type ItemsFormControlOptions } from './items.control.js';
5
- export type RadioGroupFormControlDirection = 'row' | 'column';
6
- export type RadioGroupFormControlOptions<T, I extends InitialValue<T>> = ItemsFormControlOptions<T, I> & {
7
- direction?: RadioGroupFormControlDirection;
8
- };
9
- export declare class RadioGroupFormControl<T, I extends InitialValue<T> = T | null> extends ItemsFormControl<T, I> {
10
- readonly direction: Signal<RadioGroupFormControlDirection>;
11
- constructor(initialValue: I, options: RadioGroupFormControlOptions<T, I>);
12
- }
13
- export declare function radioGroupFormControl<T, I extends InitialValue<T>>(options: RadioGroupFormControlOptions<T, I> & InitialValueOption<I>): RadioGroupFormControl<T, I>;
14
- export declare function radioGroupFormControl<T, I extends InitialValue<T>>(options: RadioGroupFormControlOptions<T, I>): RadioGroupFormControl<T, T | null>;
15
- export declare function booleanRadioGroupFormControl<I extends InitialValue<boolean>>(options: TypedOmit<RadioGroupFormControlOptions<boolean, I>, 'items'> & InitialValueOption<I>): RadioGroupFormControl<boolean, I>;
16
- export declare function booleanRadioGroupFormControl<I extends InitialValue<boolean>>(options?: TypedOmit<RadioGroupFormControlOptions<boolean, I>, 'items'>): RadioGroupFormControl<boolean>;
17
- export type EnumRadioGroupFormControlOptions<T extends EnumerationObject, I extends InitialValue<T[keyof T]>> = TypedOmit<RadioGroupFormControlOptions<T[keyof T], I>, 'items'> & {
18
- allowedValues?: FilledReadonlyArray<T[keyof T]>;
19
- };
20
- export declare function enumRadioGroupFormControl<T extends EnumerationObject, I extends InitialValue<T[keyof T]>>(enumeration: T, options: EnumRadioGroupFormControlOptions<T, I> & InitialValueOption<I>): RadioGroupFormControl<T[keyof T], I>;
21
- export declare function enumRadioGroupFormControl<T extends EnumerationObject, I extends InitialValue<T[keyof T]>>(enumeration: T, options?: EnumRadioGroupFormControlOptions<T, I>): RadioGroupFormControl<T[keyof T]>;
22
- export declare function isRadioGroupFormControl(value: any): value is RadioGroupFormControl<any, any>;
@@ -1,28 +0,0 @@
1
- import { tstdlCommonLocalizationKeys } from '../../text/common-localization.js';
2
- import { enumAsItems, reactiveOptionToSignal } from '../utils.js';
3
- import { ItemsFormControl } from './items.control.js';
4
- export class RadioGroupFormControl extends ItemsFormControl {
5
- direction;
6
- constructor(initialValue, options) {
7
- super(initialValue, options);
8
- this.direction = reactiveOptionToSignal(options.direction ?? 'column', { initialValue: 'column' });
9
- }
10
- }
11
- export function radioGroupFormControl(options) {
12
- return new RadioGroupFormControl(null, options);
13
- }
14
- export function booleanRadioGroupFormControl(options = {}) {
15
- return radioGroupFormControl({
16
- ...options,
17
- items: [{ label: tstdlCommonLocalizationKeys.yes, value: true }, { label: tstdlCommonLocalizationKeys.no, value: false }]
18
- });
19
- }
20
- export function enumRadioGroupFormControl(enumeration, options = {}) {
21
- return radioGroupFormControl({
22
- ...options,
23
- items: enumAsItems(enumeration, options.allowedValues)
24
- });
25
- }
26
- export function isRadioGroupFormControl(value) {
27
- return (value instanceof RadioGroupFormControl);
28
- }
@@ -1,17 +0,0 @@
1
- import type { EnumerationObject, FilledReadonlyArray, TypedOmit } from '../../types.js';
2
- import type { InitialValue, InitialValueOption } from '../form-control.js';
3
- import { ItemsFormControl, type ItemsFormControlOptions } from './items.control.js';
4
- export type SelectFormControlOptions<T, I extends InitialValue<T>> = ItemsFormControlOptions<T, I>;
5
- export declare class SelectFormControl<T, I extends InitialValue<T> = T | null> extends ItemsFormControl<T, I> {
6
- constructor(initialValue: I, options: SelectFormControlOptions<T, I>);
7
- }
8
- export declare function selectFormControl<T, I extends InitialValue<T>>(options: SelectFormControlOptions<T, I> & InitialValueOption<I>): SelectFormControl<T, I>;
9
- export declare function selectFormControl<T, I extends InitialValue<T>>(options: SelectFormControlOptions<T, I>): SelectFormControl<T, T | null>;
10
- export declare function booleanSelectFormControl<I extends InitialValue<boolean>>(options: TypedOmit<SelectFormControlOptions<boolean, I>, 'items'> & InitialValueOption<I>): SelectFormControl<boolean, I>;
11
- export declare function booleanSelectFormControl<I extends InitialValue<boolean>>(options?: TypedOmit<SelectFormControlOptions<boolean, I>, 'items'>): SelectFormControl<boolean>;
12
- export type EnumSelectFormControlOptions<T extends EnumerationObject, I extends InitialValue<T[keyof T]>> = TypedOmit<SelectFormControlOptions<T[keyof T], I>, 'items'> & {
13
- allowedValues?: FilledReadonlyArray<T[keyof T]>;
14
- };
15
- export declare function enumSelectFormControl<T extends EnumerationObject, I extends InitialValue<T[keyof T]>>(enumeration: T, options: EnumSelectFormControlOptions<T, I> & InitialValueOption<I>): SelectFormControl<T[keyof T], I>;
16
- export declare function enumSelectFormControl<T extends EnumerationObject, I extends InitialValue<T[keyof T]>>(enumeration: T, options?: EnumSelectFormControlOptions<T, I>): SelectFormControl<T[keyof T]>;
17
- export declare function isSelectFormControl(value: any): value is SelectFormControl<any, any>;
@@ -1,26 +0,0 @@
1
- import { tstdlCommonLocalizationKeys } from '../../text/common-localization.js';
2
- import { enumAsItems } from '../utils.js';
3
- import { ItemsFormControl } from './items.control.js';
4
- export class SelectFormControl extends ItemsFormControl {
5
- constructor(initialValue, options) {
6
- super(initialValue, options);
7
- }
8
- }
9
- export function selectFormControl(options) {
10
- return new SelectFormControl(null, options);
11
- }
12
- export function booleanSelectFormControl(options = {}) {
13
- return selectFormControl({
14
- ...options,
15
- items: [{ label: tstdlCommonLocalizationKeys.yes, value: true }, { label: tstdlCommonLocalizationKeys.no, value: false }]
16
- });
17
- }
18
- export function enumSelectFormControl(enumeration, options = {}) {
19
- return selectFormControl({
20
- ...options,
21
- items: enumAsItems(enumeration, options.allowedValues)
22
- });
23
- }
24
- export function isSelectFormControl(value) {
25
- return (value instanceof SelectFormControl);
26
- }
@@ -1,47 +0,0 @@
1
- import { type Signal } from '../../signals/index.js';
2
- import type { ReactiveValue, TypedOmit } from '../../types.js';
3
- import type { InputAutocomplete } from '../../web-types.js';
4
- import { FormControl, type FormControlOptions, type InitialValue, type InitialValueOption } from '../form-control.js';
5
- import type { DynamicTextOption } from '../types.js';
6
- export type TextFormControlType = 'text' | 'password' | 'email';
7
- export type AutoFillSuggestionSelectHandler<T = any> = (suggestion: AutoFillSuggestion<T>) => any;
8
- export type AutoFillSuggestion<T = any> = {
9
- display: ReactiveValue<string>;
10
- selectValue?: string;
11
- data?: T;
12
- onSelect?: AutoFillSuggestionSelectHandler<T>;
13
- };
14
- export type NormalizedAutoFillSuggestion<T = any> = TypedOmit<AutoFillSuggestion<T>, 'display'> & {
15
- display: Signal<string>;
16
- searchText: Signal<string>;
17
- };
18
- export type TextFormControlOptions<I extends InitialValue<string> = InitialValue<string>> = FormControlOptions<string | I> & {
19
- type?: ReactiveValue<TextFormControlType>;
20
- autocomplete?: ReactiveValue<InputAutocomplete>;
21
- placeholder?: ReactiveValue<DynamicTextOption>;
22
- pattern?: ReactiveValue<RegExp | null>;
23
- inputPattern?: ReactiveValue<RegExp | null>;
24
- trim?: ReactiveValue<boolean>;
25
- maxLength?: ReactiveValue<number>;
26
- autoFillSuggestions?: ReactiveValue<(string | AutoFillSuggestion)[] | undefined>;
27
- filterAutoFillSuggestions?: ReactiveValue<boolean>;
28
- };
29
- export declare class TextFormControl<I extends InitialValue<string> = string | null> extends FormControl<string | I, string> {
30
- protected readonly internalValidators: Signal<readonly import("../validators/form.validator.js").FormValidator<any>[]>;
31
- readonly type: Signal<TextFormControlType>;
32
- readonly autocomplete: Signal<InputAutocomplete>;
33
- readonly placeholder: Signal<DynamicTextOption>;
34
- readonly pattern: Signal<RegExp | null>;
35
- readonly inputPattern: Signal<RegExp | null>;
36
- readonly trim: Signal<boolean>;
37
- readonly maxLength: Signal<number | null>;
38
- readonly autoFillSuggestions: Signal<readonly NormalizedAutoFillSuggestion[] | null>;
39
- readonly filterAutoFillSuggestions: Signal<boolean>;
40
- readonly filteredAutoFillSuggestions: Signal<readonly NormalizedAutoFillSuggestion[] | null>;
41
- constructor(initialValue: I, options?: TextFormControlOptions<I>);
42
- parseInputValue(value: string | null): string | I | null;
43
- formatRawValue(value: string | null): string;
44
- }
45
- export declare function textFormControl<I extends InitialValue<string>>(options: TextFormControlOptions<I> & InitialValueOption<I>): TextFormControl<I>;
46
- export declare function textFormControl<I extends InitialValue<string>>(options?: TextFormControlOptions<I>): TextFormControl;
47
- export declare function isTextFormControl(value: any): value is TextFormControl<any>;
@@ -1,94 +0,0 @@
1
- import { computed, getCurrentSignalsInjector, runInSignalsInjectionContext } from '../../signals/index.js';
2
- import { normalizeText } from '../../utils/helpers.js';
3
- import { mailPattern } from '../../utils/patterns.js';
4
- import { isNotNull, isNull, isNumber, isString } from '../../utils/type-guards.js';
5
- import { computedInternalValidators } from '../abstract-control.js';
6
- import { FormControl } from '../form-control.js';
7
- import { reactiveOptionToSignal } from '../utils.js';
8
- import { maxLengthValidator, patternValidator } from '../validators/index.js';
9
- export class TextFormControl extends FormControl {
10
- internalValidators = computedInternalValidators(() => {
11
- const pattern = this.pattern();
12
- const maxLength = this.maxLength();
13
- const type = this.type();
14
- return [
15
- isNumber(maxLength) ? maxLengthValidator(maxLength) : null,
16
- (type == 'email') ? patternValidator(mailPattern) : null,
17
- isNotNull(pattern) ? patternValidator(pattern) : null
18
- ];
19
- });
20
- type;
21
- autocomplete;
22
- placeholder;
23
- pattern;
24
- inputPattern;
25
- trim;
26
- maxLength;
27
- autoFillSuggestions;
28
- filterAutoFillSuggestions;
29
- filteredAutoFillSuggestions;
30
- constructor(initialValue, options = {}) {
31
- super(initialValue, options);
32
- this.type = reactiveOptionToSignal(options.type ?? 'text', { initialValue: 'text' });
33
- this.autocomplete = reactiveOptionToSignal(options.autocomplete ?? 'off', { initialValue: 'off' });
34
- this.placeholder = reactiveOptionToSignal(options.placeholder ?? null, { initialValue: null });
35
- this.pattern = reactiveOptionToSignal(options.pattern ?? null, { initialValue: null });
36
- this.inputPattern = reactiveOptionToSignal(options.inputPattern ?? null, { initialValue: null });
37
- this.trim = reactiveOptionToSignal(options.trim ?? true, { initialValue: true });
38
- this.maxLength = reactiveOptionToSignal(options.maxLength ?? null, { initialValue: null });
39
- const rawAutoFillSuggestions = reactiveOptionToSignal(options.autoFillSuggestions);
40
- const signalsInjector = getCurrentSignalsInjector();
41
- this.autoFillSuggestions = computed(() => runInSignalsInjectionContext(signalsInjector, () => normalizeAutoFillSuggestions(rawAutoFillSuggestions() ?? null)));
42
- this.filterAutoFillSuggestions = reactiveOptionToSignal(options.filterAutoFillSuggestions ?? true, { initialValue: true });
43
- this.filteredAutoFillSuggestions = computed(() => {
44
- const searchValue = normalizeText(this.value() ?? '');
45
- const autoFillSuggestions = this.autoFillSuggestions();
46
- if (isNull(autoFillSuggestions)) {
47
- return null;
48
- }
49
- if (!this.filterAutoFillSuggestions() || (searchValue.length == 0)) {
50
- return autoFillSuggestions;
51
- }
52
- return autoFillSuggestions.filter((suggestion) => suggestion.searchText().includes(searchValue));
53
- });
54
- }
55
- parseInputValue(value) {
56
- if (isNull(value)) {
57
- return null;
58
- }
59
- const normalized = this.trim() ? value.trim() : value;
60
- if (normalized.length == 0) {
61
- return null;
62
- }
63
- return normalized;
64
- }
65
- formatRawValue(value) {
66
- return value ?? '';
67
- }
68
- }
69
- export function textFormControl(options) {
70
- return new TextFormControl(null, options);
71
- }
72
- export function isTextFormControl(value) {
73
- return (value instanceof TextFormControl);
74
- }
75
- function normalizeAutoFillSuggestions(suggestions) {
76
- if (isNull(suggestions)) {
77
- return null;
78
- }
79
- return suggestions.map((suggestion) => {
80
- if (isString(suggestion)) {
81
- return {
82
- display: computed(() => suggestion),
83
- searchText: computed(() => normalizeText(suggestion)),
84
- data: suggestion
85
- };
86
- }
87
- const displaySignal = reactiveOptionToSignal(suggestion.display, { requireSync: true });
88
- return {
89
- ...suggestion,
90
- display: displaySignal,
91
- searchText: computed(() => normalizeText(displaySignal()))
92
- };
93
- });
94
- }
@@ -1,24 +0,0 @@
1
- import type { Signal } from '../../signals/api.js';
2
- import type { ReactiveValue } from '../../types.js';
3
- import type { InputAutocomplete } from '../../web-types.js';
4
- import { FormControl, type FormControlOptions, type InitialValue, type InitialValueOption } from '../form-control.js';
5
- import type { DynamicTextOption } from '../types.js';
6
- export type TimeFormControlOptions<I extends InitialValue<number> = InitialValue<number>> = FormControlOptions<number | I> & {
7
- autocomplete?: InputAutocomplete;
8
- placeholder?: ReactiveValue<DynamicTextOption>;
9
- minimum?: ReactiveValue<number | null>;
10
- maximum?: ReactiveValue<number | null>;
11
- };
12
- export declare class TimeFormControl<I extends InitialValue<number> = number | null> extends FormControl<number | I, string> {
13
- protected readonly internalValidators: Signal<readonly import("../index.js").FormValidator<any>[]>;
14
- readonly autocomplete: Signal<InputAutocomplete>;
15
- readonly placeholder: Signal<DynamicTextOption>;
16
- readonly minimum: Signal<number | null>;
17
- readonly maximum: Signal<number | null>;
18
- constructor(initialValue: I, options?: TimeFormControlOptions<I>);
19
- parseInputValue(value: string | null): number | null;
20
- formatRawValue(value: number | null): string;
21
- }
22
- export declare function timeFormControl<I extends InitialValue<number>>(options: TimeFormControlOptions<I> & InitialValueOption<I>): TimeFormControl<I>;
23
- export declare function timeFormControl<I extends InitialValue<number>>(options?: TimeFormControlOptions<I>): TimeFormControl;
24
- export declare function isTimeFormControl(value: any): value is TimeFormControl<any>;
@@ -1,44 +0,0 @@
1
- import { Duration } from 'luxon';
2
- import { isDefined, isNull } from '../../utils/type-guards.js';
3
- import { millisecondsPerHour, millisecondsPerMinute, millisecondsPerSecond } from '../../utils/units.js';
4
- import { computedInternalValidators } from '../abstract-control.js';
5
- import { FormControl } from '../form-control.js';
6
- import { reactiveOptionToSignal } from '../utils.js';
7
- import { timeValidator } from '../validators/time.validator.js';
8
- export class TimeFormControl extends FormControl {
9
- internalValidators = computedInternalValidators(() => {
10
- const minimum = this.minimum();
11
- const maximum = this.maximum();
12
- return [(isDefined(minimum) || isDefined(maximum)) ? timeValidator(minimum, maximum) : undefined];
13
- });
14
- autocomplete;
15
- placeholder;
16
- minimum;
17
- maximum;
18
- constructor(initialValue, options = {}) {
19
- super(initialValue, options);
20
- this.autocomplete = reactiveOptionToSignal(options.autocomplete ?? 'off', { initialValue: 'off' });
21
- this.placeholder = reactiveOptionToSignal(options.placeholder ?? null, { initialValue: null });
22
- this.minimum = reactiveOptionToSignal(options.minimum ?? null, { initialValue: null });
23
- this.maximum = reactiveOptionToSignal(options.maximum ?? null, { initialValue: null });
24
- }
25
- parseInputValue(value) {
26
- if (isNull(value)) {
27
- return null;
28
- }
29
- const [hours, minutes, seconds] = value.split(':').map((part) => Number(part));
30
- return ((hours ?? 0) * millisecondsPerHour) + ((minutes ?? 0) * millisecondsPerMinute) + ((seconds ?? 0) * millisecondsPerSecond);
31
- }
32
- formatRawValue(value) {
33
- if (isNull(value) || Number.isNaN(value)) {
34
- return '';
35
- }
36
- return Duration.fromMillis(value).toFormat('hh:mm');
37
- }
38
- }
39
- export function timeFormControl(options) {
40
- return new TimeFormControl(null, options);
41
- }
42
- export function isTimeFormControl(value) {
43
- return (value instanceof TimeFormControl);
44
- }
@@ -1,71 +0,0 @@
1
- import type { JsonPath } from '../json-path/json-path.js';
2
- import { type Signal } from '../signals/api.js';
3
- import type { ReactiveValue } from '../types.js';
4
- import { type AbstractControl, type AbstractControlParent, type AbstractControlRawValueType, type AbstractControlValueType, type MarkOptions } from './abstract-control.js';
5
- import { FormContainer, type FormContainerOptions } from './form-container.js';
6
- import type { FormControlRemoveHandler } from './types.js';
7
- import type { FormValidatorError } from './validators/form.validator.js';
8
- export type FormArrayDisplayType = 'simple' | 'tabs';
9
- export type FormArrayChildBuilder<T = unknown, TRaw = unknown, C extends AbstractControl<T, TRaw> = AbstractControl<T, TRaw>> = (value: T) => C;
10
- export type FormArrayOptions<T, TRaw, C extends AbstractControl<T, TRaw>> = FormContainerOptions<T[]> & {
11
- children?: C[];
12
- displayType?: FormArrayDisplayType;
13
- allowRemove?: ReactiveValue<boolean>;
14
- allowRemoveAll?: ReactiveValue<boolean>;
15
- removeHandler?: FormControlRemoveHandler<C & {}>;
16
- builder?: FormArrayChildBuilder<T, TRaw, C>;
17
- };
18
- export type FormArrayByControl<C extends AbstractControl = AbstractControl> = FormArray<AbstractControlValueType<C>, AbstractControlRawValueType<C>, C>;
19
- export type FormArrayChild<T extends FormArray> = ReturnType<T['children']>[number];
20
- export declare class FormArray<T = any, TRaw = any, C extends AbstractControl<T, TRaw> = AbstractControl<T, TRaw>> extends FormContainer<T[], TRaw[]> implements Iterable<C> {
21
- #private;
22
- protected readonly internalValidators: null;
23
- readonly children: Signal<readonly C[]>;
24
- readonly enabledChildren: Signal<readonly C[]>;
25
- readonly size: Signal<number>;
26
- readonly displayType: Signal<FormArrayDisplayType>;
27
- readonly allowRemove: Signal<boolean>;
28
- readonly allowRemoveAll: Signal<boolean>;
29
- readonly removedChildren: Signal<C[]>;
30
- readonly removeHandler: FormControlRemoveHandler<any>;
31
- readonly builder: FormArrayChildBuilder<T, TRaw, C>;
32
- /** Raw values of all children whether disabled or not */
33
- readonly rawValue: Signal<TRaw[]>;
34
- /** Values of all enabled children */
35
- readonly value: Signal<T[]>;
36
- readonly dirty: Signal<boolean>;
37
- readonly touched: Signal<boolean>;
38
- readonly localErrors: Signal<readonly FormValidatorError[]>;
39
- readonly childrenErrors: Signal<FormValidatorError[]>;
40
- readonly errors: Signal<FormValidatorError[]>;
41
- readonly errorDebug: Signal<{
42
- _self: readonly FormValidatorError[];
43
- } | null>;
44
- constructor(options?: FormArrayOptions<T, TRaw, C>);
45
- get(index: number): C | undefined;
46
- getValue(index: number): T | undefined;
47
- getRawValue(index: number): TRaw | undefined;
48
- reset(): void;
49
- indexOf(child: C): number | null;
50
- add(...children: C[]): void;
51
- addValue(...values: T[]): void;
52
- removeAll(): void;
53
- remove(child: C): void;
54
- removeAt(index: number, count?: number): void;
55
- setValue(values: T[]): void;
56
- markAsDirty({ onlySelf }?: MarkOptions): void;
57
- markAsTouched({ onlySelf }?: MarkOptions): void;
58
- setParent(parent: AbstractControlParent, force?: boolean): void;
59
- setParent(parent: null): void;
60
- [Symbol.iterator](): Iterator<C>;
61
- getChildPath(child: C): Signal<JsonPath>;
62
- private updateParents;
63
- }
64
- export declare function formArray<C extends AbstractControl>(options: FormArrayOptions<AbstractControlValueType<C>, AbstractControlRawValueType<C>, C> & {
65
- builder: FormArrayChildBuilder<AbstractControlValueType<C>, AbstractControlRawValueType<C>, C>;
66
- }): FormArray<AbstractControlValueType<C>, AbstractControlRawValueType<C>, C>;
67
- export declare function formArray<C extends AbstractControl>(options: FormArrayOptions<AbstractControlValueType<C>, AbstractControlRawValueType<C>, C> & {
68
- children: C[];
69
- }): FormArray<AbstractControlValueType<C>, AbstractControlRawValueType<C>, C>;
70
- export declare function formArray<T, TRaw, C extends AbstractControl>(options: FormArrayOptions<T, TRaw, C>): FormArray<T, TRaw, C>;
71
- export declare function isFormArray(value: any): value is FormArray;
@@ -1,188 +0,0 @@
1
- import { computed, signal, untracked } from '../signals/api.js';
2
- import { switchAll } from '../signals/index.js';
3
- import { createArray } from '../utils/array/array.js';
4
- import { fromEntries } from '../utils/object/object.js';
5
- import { deferThrow } from '../utils/throw.js';
6
- import { isDefined, isNotNull } from '../utils/type-guards.js';
7
- import { ignoreFormValue } from './abstract-control.js';
8
- import { FormContainer } from './form-container.js';
9
- import { bindReactiveOption } from './utils.js';
10
- export class FormArray extends FormContainer {
11
- #children = signal([]);
12
- #selfTouched = signal(false);
13
- #selfDirty = signal(false);
14
- #displayType = signal('tabs');
15
- #allowRemove = signal(true);
16
- #allowRemoveAll = signal(true);
17
- #removedChildren = signal(new Set());
18
- internalValidators = null;
19
- children = this.#children.asReadonly();
20
- enabledChildren = computed(() => this.#children().filter((child) => child.enabled()));
21
- size = computed(() => this.children().length);
22
- displayType = this.#displayType.asReadonly();
23
- allowRemove = this.#allowRemove.asReadonly();
24
- allowRemoveAll = this.#allowRemoveAll.asReadonly();
25
- removedChildren = computed(() => [...this.#removedChildren()]);
26
- removeHandler;
27
- builder;
28
- /** Raw values of all children whether disabled or not */
29
- rawValue = computed(() => this.#children().map((child) => child.rawValue()));
30
- /** Values of all enabled children */
31
- value = computed(() => this.enabledChildren().map((child) => child.value()));
32
- dirty = computed(() => this.#selfDirty() || this.children().some((child) => child.dirty()));
33
- touched = computed(() => this.#selfTouched() || this.children().some((child) => child.touched()));
34
- localErrors = switchAll(() => {
35
- const validations = this.validators().map((validator) => validator(this));
36
- return computed(() => validations.map((validation) => validation()).filter(isNotNull));
37
- });
38
- childrenErrors = computed(() => this.children().flatMap((child) => child.errors()));
39
- errors = computed(() => [
40
- ...this.localErrors(),
41
- ...this.childrenErrors()
42
- ]);
43
- errorDebug = computed(() => this.valid()
44
- ? null
45
- : ({
46
- _self: this.localErrors(),
47
- ...fromEntries(this.children().map((child, index) => [index, child.errorDebug()]).filter(([, errorDebug]) => isNotNull(errorDebug)))
48
- }));
49
- constructor(options = {}) {
50
- super(options);
51
- this.builder = options.builder ?? deferThrow(() => new Error('Builder required to add children by value'));
52
- this.removeHandler = options.removeHandler ?? (() => true);
53
- if (isDefined(options.children)) {
54
- this.add(...options.children);
55
- }
56
- bindReactiveOption(options.displayType, this.#displayType);
57
- bindReactiveOption(options.allowRemove, this.#allowRemove);
58
- bindReactiveOption(options.allowRemoveAll, this.#allowRemoveAll);
59
- }
60
- get(index) {
61
- return this.children()[index];
62
- }
63
- getValue(index) {
64
- return this.get(index)?.value();
65
- }
66
- getRawValue(index) {
67
- return this.get(index)?.rawValue();
68
- }
69
- reset() {
70
- for (const child of untracked(this.#children)) {
71
- child.reset();
72
- }
73
- this.#removedChildren.set(new Set());
74
- }
75
- indexOf(child) {
76
- const index = untracked(this.children).indexOf(child);
77
- return (index == -1) ? null : index;
78
- }
79
- add(...children) {
80
- this.#children.set([...untracked(this.children), ...children]);
81
- for (const child of children) {
82
- child.setParent(this);
83
- }
84
- }
85
- addValue(...values) {
86
- const children = values.map((value) => this.builder(value));
87
- this.add(...children);
88
- }
89
- removeAll() {
90
- const newlyRemovedChildren = [];
91
- for (const child of untracked(this.children)) {
92
- if (untracked(child.parent) == this) {
93
- child.setParent(null);
94
- }
95
- newlyRemovedChildren.push(child);
96
- }
97
- this.#removedChildren.update((removedChildren) => new Set([...removedChildren, ...newlyRemovedChildren]));
98
- this.#children.set([]);
99
- }
100
- remove(child) {
101
- const index = this.indexOf(child);
102
- if (isNotNull(index)) {
103
- this.removeAt(index);
104
- }
105
- }
106
- removeAt(index, count = 1) {
107
- const children = untracked(this.children);
108
- const newlyRemovedChildren = [];
109
- const end = Math.min(index + count, children.length);
110
- if (end <= index) {
111
- return;
112
- }
113
- for (let i = index; i < end; i++) {
114
- const child = children[i];
115
- child.setParent(null);
116
- newlyRemovedChildren.push(child);
117
- }
118
- const spliced = children.toSpliced(index, 1);
119
- this.#removedChildren.update((removedChildren) => new Set([...removedChildren, ...newlyRemovedChildren]));
120
- this.#children.set(spliced);
121
- }
122
- setValue(values) {
123
- if (values == ignoreFormValue) {
124
- return;
125
- }
126
- let children = untracked(this.#children);
127
- const newlyRemovedChildren = [];
128
- if (values.length < children.length) {
129
- for (let i = values.length; i < children.length - 1; i++) {
130
- const child = children[i];
131
- child.setParent(null);
132
- newlyRemovedChildren.push(child);
133
- }
134
- children = children.slice(0, values.length);
135
- }
136
- else if (values.length > children.length) {
137
- const newChildren = createArray(values.length - children.length, (index) => this.builder(values[children.length + index]));
138
- children = [...children, ...newChildren];
139
- }
140
- for (let i = 0; i < values.length; i++) {
141
- children[i].setValue(values[i]);
142
- }
143
- this.#removedChildren.update((removedChildren) => new Set([...removedChildren, ...newlyRemovedChildren]));
144
- this.#children.set(children);
145
- }
146
- markAsDirty({ onlySelf = false } = {}) {
147
- this.#selfDirty.set(true);
148
- if (onlySelf) {
149
- return;
150
- }
151
- for (const child of untracked(this.children)) {
152
- child.markAsDirty();
153
- }
154
- }
155
- markAsTouched({ onlySelf = false } = {}) {
156
- this.#selfTouched.set(true);
157
- if (onlySelf) {
158
- return;
159
- }
160
- for (const child of untracked(this.children)) {
161
- child.markAsTouched();
162
- }
163
- }
164
- setParent(parent, force) {
165
- super.setParent(parent, force);
166
- this.updateParents(true);
167
- }
168
- *[Symbol.iterator]() {
169
- yield* untracked(this.children);
170
- }
171
- getChildPath(child) {
172
- return computed(() => {
173
- const key = this.#children().indexOf(child);
174
- return this.path().add((key >= 0) ? key : 'CHILD_NOT_FOUND');
175
- });
176
- }
177
- updateParents(force) {
178
- for (const child of untracked(this.#children)) {
179
- child.setParent(this, force);
180
- }
181
- }
182
- }
183
- export function formArray(options) {
184
- return new FormArray(options); // eslint-disable-line @typescript-eslint/no-unsafe-return
185
- }
186
- export function isFormArray(value) {
187
- return (value instanceof FormArray);
188
- }