@quadrel-enterprise-ui/framework 20.21.0 → 20.21.1-beta.193.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.
package/index.d.ts CHANGED
@@ -3447,12 +3447,11 @@ declare class QdMockCheckboxComponent {
3447
3447
  value: string;
3448
3448
  disabled: boolean;
3449
3449
  testId: string;
3450
+ valueChange: EventEmitter<string>;
3450
3451
  get dataTestId(): string;
3451
- handleClick(value: any): {
3452
- value: any;
3453
- };
3452
+ handleClick(): void;
3454
3453
  static ɵfac: i0.ɵɵFactoryDeclaration<QdMockCheckboxComponent, never>;
3455
- static ɵcmp: i0.ɵɵComponentDeclaration<QdMockCheckboxComponent, "qd-checkbox", never, { "inputData": { "alias": "inputData"; "required": false; }; "value": { "alias": "value"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "testId": { "alias": "data-test-id"; "required": false; }; }, {}, never, never, false, never>;
3454
+ static ɵcmp: i0.ɵɵComponentDeclaration<QdMockCheckboxComponent, "qd-checkbox", never, { "inputData": { "alias": "inputData"; "required": false; }; "value": { "alias": "value"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "testId": { "alias": "data-test-id"; "required": false; }; }, { "valueChange": "valueChange"; }, never, never, false, never>;
3456
3455
  }
3457
3456
 
3458
3457
  declare class QdMockCheckboxesComponent {
@@ -5855,9 +5854,11 @@ declare class QdNotificationsSnackbarComponent {
5855
5854
  type ValidatorFnWithProps = {
5856
5855
  (control: AbstractControl): ValidationErrors | null;
5857
5856
  maxLength?: number;
5857
+ qdRevalidates?: string;
5858
5858
  };
5859
5859
  declare class QdFormControl<T> extends UntypedFormControl implements AbstractControl {
5860
5860
  private maxLength?;
5861
+ private revalidationPartners;
5861
5862
  private validatorList;
5862
5863
  constructor(formState?: T, validatorOrOpts?: ValidatorFnWithProps | ValidatorFnWithProps[] | FormControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null);
5863
5864
  private getValidatorList;
@@ -5868,6 +5869,7 @@ declare class QdFormControl<T> extends UntypedFormControl implements AbstractCon
5868
5869
  clearValidators(): void;
5869
5870
  hasMaxLength(): boolean;
5870
5871
  getMaxLengthOrUndefined(): number | undefined;
5872
+ getRevalidationPartners(): string[];
5871
5873
  }
5872
5874
 
5873
5875
  /**
@@ -7912,7 +7914,35 @@ declare class QdRadioButtonsComponent implements OnInit, OnChanges, OnDestroy, C
7912
7914
  static ɵcmp: i0.ɵɵComponentDeclaration<QdRadioButtonsComponent, "qd-radio-buttons", never, { "value": { "alias": "value"; "required": false; }; "config": { "alias": "config"; "required": false; }; "formControlName": { "alias": "formControlName"; "required": false; }; "testId": { "alias": "data-test-id"; "required": false; }; }, { "valueChange": "valueChange"; "clickHint": "clickHint"; "clickReadonly": "clickReadonly"; "clickViewonly": "clickViewonly"; }, never, never, false, never>;
7913
7915
  }
7914
7916
 
7917
+ /**
7918
+ * `UntypedFormGroup` that wires cross-field re-validation automatically.
7919
+ *
7920
+ * A validator can declare a sibling dependency via `qdRevalidates` (see `QdValidators.dateRange`).
7921
+ * The group then subscribes to that partner's `valueChanges` and re-validates the dependent control,
7922
+ * so a stale error never lingers when the partner value changes — without the consumer calling
7923
+ * `updateValueAndValidity`. The subscriptions are group-internal (sibling to sibling) and are torn
7924
+ * down and rebuilt whenever a control is added, replaced or removed.
7925
+ *
7926
+ * Re-wiring is triggered by control mutations (`add`/`set`/`removeControl`), not by validator
7927
+ * mutations on an existing control: calling `control.addValidators(...)` after construction updates
7928
+ * the control's partners but does not re-wire the group until the next control mutation.
7929
+ */
7915
7930
  declare class QdFormGroup extends UntypedFormGroup {
7931
+ private revalidationSubscription;
7932
+ constructor(controls: {
7933
+ [key: string]: AbstractControl;
7934
+ }, validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null);
7935
+ addControl(name: string, control: AbstractControl, options?: {
7936
+ emitEvent?: boolean;
7937
+ }): void;
7938
+ setControl(name: string, control: AbstractControl, options?: {
7939
+ emitEvent?: boolean;
7940
+ }): void;
7941
+ removeControl(name: string, options?: {
7942
+ emitEvent?: boolean;
7943
+ }): void;
7944
+ private rewireCrossFieldRevalidation;
7945
+ private wireCrossFieldRevalidation;
7916
7946
  }
7917
7947
 
7918
7948
  declare class QdFormBuilder extends UntypedFormBuilder {
@@ -8123,29 +8153,71 @@ declare class QdFilterFormItemsComponent implements OnInit {
8123
8153
  static ɵcmp: i0.ɵɵComponentDeclaration<QdFilterFormItemsComponent, "qd-filter-form-items", never, { "inputFilterValue": { "alias": "inputFilterValue"; "required": false; }; "testId": { "alias": "data-test-id"; "required": false; }; }, { "filterValueChange": "filterValueChange"; }, never, never, false, never>;
8124
8154
  }
8125
8155
 
8156
+ /**
8157
+ * Ready-to-use validators for Quadrel Reactive Forms.
8158
+ *
8159
+ * Use them like Angular's built-in `Validators`, but every validator returns a **translatable
8160
+ * error key** instead of a fixed message, and most accept a custom `errorKey` as the last
8161
+ * argument.
8162
+ *
8163
+ * Empty values pass for most validators — combine with `required()` when a value is mandatory.
8164
+ * The amount-aware validators (`min`, `max`, `minLength`, `maxLength`, `pattern`) also accept
8165
+ * `{ value, unit }` objects and validate the inner `value`.
8166
+ *
8167
+ * #### **Usage**
8168
+ * ```ts
8169
+ * form = new QdFormGroup({
8170
+ * email: new QdFormControl(null, [QdValidators.required(), QdValidators.email()]),
8171
+ * age: new QdFormControl(null, [QdValidators.required(), QdValidators.min(18)])
8172
+ * });
8173
+ * ```
8174
+ */
8126
8175
  declare class QdValidators {
8127
8176
  /**
8128
- * Validates that the value of the form field is at least the specified minimum.
8177
+ * Validates that a numeric value is greater than or equal to a minimum.
8178
+ *
8179
+ * Empty values (`null`/`undefined`) pass — combine with `required` when a value is mandatory.
8180
+ * Also accepts amount objects of the shape `{ value, unit }`; in that case the inner `value`
8181
+ * is validated.
8182
+ *
8183
+ * @param min - The smallest allowed value (inclusive).
8184
+ * @param errorKey - Translation key returned when the value is below the minimum.
8129
8185
  *
8130
8186
  * #### **Usage**
8131
8187
  * ```ts
8132
- * new QdFormControl('', QdValidators.min(3));
8133
- * new QdFormControl('', QdValidators.min(3, 'custom-error'));
8188
+ * new QdFormControl(null, QdValidators.min(3));
8189
+ * new QdFormControl(null, QdValidators.min(3, 'custom-error'));
8134
8190
  * ```
8135
8191
  */
8136
8192
  static min(min: number, errorKey?: string): ValidatorFn;
8137
8193
  /**
8138
- * Validates that the value of the form field does not exceed the specified maximum.
8194
+ * Validates that a numeric value is less than or equal to a maximum.
8195
+ *
8196
+ * Empty values (`null`/`undefined`) pass — combine with `required` when a value is mandatory.
8197
+ * Also accepts amount objects of the shape `{ value, unit }`; in that case the inner `value`
8198
+ * is validated.
8199
+ *
8200
+ * @param max - The largest allowed value (inclusive).
8201
+ * @param errorKey - Translation key returned when the value exceeds the maximum.
8139
8202
  *
8140
8203
  * #### **Usage**
8141
8204
  * ```ts
8142
- * new QdFormControl('', QdValidators.max(10));
8143
- * new QdFormControl('', QdValidators.max(10, 'custom-error'));
8205
+ * new QdFormControl(null, QdValidators.max(10));
8206
+ * new QdFormControl(null, QdValidators.max(10, 'custom-error'));
8144
8207
  * ```
8145
8208
  */
8146
8209
  static max(max: number, errorKey?: string): ValidatorFn;
8147
8210
  /**
8148
- * Ensures that the form field is not empty.
8211
+ * Validates that the field holds a non-empty value.
8212
+ *
8213
+ * Quadrel form components additionally render a required asterisk (`*`) on the field label
8214
+ * whenever this validator is present, so users see at a glance that the field is mandatory.
8215
+ *
8216
+ * Empty means: `null`, `undefined`, an empty string, an empty array, or an object whose
8217
+ * leaf values are all empty (checked recursively — useful for amount objects such as
8218
+ * `{ value, unit }`).
8219
+ *
8220
+ * @param errorKey - Translation key returned when the field is empty.
8149
8221
  *
8150
8222
  * #### **Usage**
8151
8223
  * ```ts
@@ -8156,7 +8228,12 @@ declare class QdValidators {
8156
8228
  static required(errorKey?: string): ValidatorFn;
8157
8229
  private static isEmptyInputValue;
8158
8230
  /**
8159
- * Validates that the form field contains a valid email address.
8231
+ * Validates that the field contains a single, well-formed email address.
8232
+ *
8233
+ * Empty values pass — combine with `required` when an address is mandatory. The whole value
8234
+ * must be the address; surrounding text makes it invalid.
8235
+ *
8236
+ * @param errorKey - Translation key returned when the address is malformed.
8160
8237
  *
8161
8238
  * #### **Usage**
8162
8239
  * ```ts
@@ -8166,7 +8243,14 @@ declare class QdValidators {
8166
8243
  */
8167
8244
  static email(errorKey?: string): ValidatorFn;
8168
8245
  /**
8169
- * Ensures that the form field contains at least the specified number of characters.
8246
+ * Validates that a text value is at least a given number of characters long.
8247
+ *
8248
+ * Empty values (`null`/`undefined`/`''`) pass — combine with `required` when input is
8249
+ * mandatory. Also accepts amount objects of the shape `{ value, unit }`; in that case the
8250
+ * inner `value` is measured.
8251
+ *
8252
+ * @param minLength - The minimum number of characters (inclusive).
8253
+ * @param errorKey - Translation key returned when the value is too short.
8170
8254
  *
8171
8255
  * #### **Usage**
8172
8256
  * ```ts
@@ -8176,7 +8260,15 @@ declare class QdValidators {
8176
8260
  */
8177
8261
  static minLength(minLength: number, errorKey?: string): ValidatorFn;
8178
8262
  /**
8179
- * Ensures that the form field contains no more than the specified number of characters.
8263
+ * Validates that a text value is no longer than a given number of characters.
8264
+ *
8265
+ * Empty values pass — combine with `required` when input is mandatory. Also accepts amount
8266
+ * objects of the shape `{ value, unit }`; in that case the inner `value` is measured. The
8267
+ * configured limit is exposed as `.maxLength` on the returned validator, which `qd-textarea`
8268
+ * reads to show a live character counter (`current / max`).
8269
+ *
8270
+ * @param maxLength - The maximum number of characters (inclusive).
8271
+ * @param errorKey - Translation key returned when the value is too long.
8180
8272
  *
8181
8273
  * #### **Usage**
8182
8274
  * ```ts
@@ -8186,7 +8278,13 @@ declare class QdValidators {
8186
8278
  */
8187
8279
  static maxLength(maxLength: number, errorKey?: string): ValidatorFn;
8188
8280
  /**
8189
- * Ensures that the form field matches a given regular expression pattern.
8281
+ * Validates that a text value matches a regular expression.
8282
+ *
8283
+ * Empty values pass — combine with `required` when input is mandatory. Also accepts amount
8284
+ * objects of the shape `{ value, unit }`; in that case the inner `value` is matched.
8285
+ *
8286
+ * @param pattern - The pattern to match, as a `RegExp` or a string regular expression.
8287
+ * @param errorKey - Translation key returned when the value does not match.
8190
8288
  *
8191
8289
  * #### **Usage**
8192
8290
  * ```ts
@@ -8197,37 +8295,102 @@ declare class QdValidators {
8197
8295
  */
8198
8296
  static pattern(pattern: string | RegExp, errorKey?: string): ValidatorFn;
8199
8297
  /**
8200
- * Ensures that the form field contains a valid date.
8298
+ * Validates that the value is a real, parseable `Date` object.
8299
+ *
8300
+ * Empty values pass — combine with `required` when a date is mandatory. Strings (including
8301
+ * `'Invalid Date'`), numbers and plain objects are rejected. The error carries the locale
8302
+ * date format (`DD.MM.YYYY`) as a `params.format` hint for the message.
8303
+ *
8304
+ * @param errorKey - Translation key returned when the value is not a valid date.
8201
8305
  *
8202
8306
  * #### **Usage**
8203
8307
  * ```ts
8204
- * new QdFormControl('', QdValidators.date());
8308
+ * new QdFormControl(null, QdValidators.date());
8205
8309
  * new QdFormControl(new Date(), QdValidators.date());
8206
8310
  * new QdFormControl(new Date(), QdValidators.date('date-error'));
8207
8311
  * ```
8208
8312
  */
8209
8313
  static date(errorKey?: string): ValidatorFn;
8210
8314
  /**
8211
- * Ensures that the selected date is not within a range of disabled dates.
8315
+ * Validates that a date does not fall inside any of the given disabled ranges.
8316
+ *
8317
+ * Each range may set `from`, `to`, or both; an open end reaches into the far past/future.
8318
+ * Boundaries are **exclusive** — a date exactly on `from` or `to` is still allowed; only
8319
+ * dates strictly between them are rejected. Comparison is day-granular. Empty or invalid
8320
+ * values pass.
8321
+ *
8322
+ * @param disabledDates - Ranges to block, e.g. `[{ from, to }]`.
8323
+ * @param errorKey - Translation key returned when the date lies inside a range.
8212
8324
  *
8213
8325
  * #### **Usage**
8214
8326
  * ```ts
8215
- * new QdFormControl('', QdValidators.disabledDates([{ from: new Date('2025-01-01') }]));
8327
+ * new QdFormControl(null, QdValidators.disabledDates([{ from: new Date('2025-01-01') }]));
8328
+ * new QdFormControl(null, QdValidators.disabledDates([{ from: new Date('2025-01-01'), to: new Date('2025-01-31') }]));
8216
8329
  * ```
8217
8330
  */
8218
8331
  static disabledDates(disabledDates: QdDisabledDates[], errorKey?: string): ValidatorFn;
8219
8332
  private static isDateDisabled;
8220
8333
  /**
8221
- * Ensures that the selected time is not within a range of disabled times.
8334
+ * Validates that a date stays on the correct side of a sibling "range partner" control.
8335
+ *
8336
+ * Put it on both ends of a from/to pair, each pointing at the other. A `'start'` control is
8337
+ * invalid when its date is after the partner; an `'end'` control is invalid when its date is
8338
+ * before the partner. Comparison is day-granular, so equal days are valid.
8339
+ *
8340
+ * The partner value is read live on every run, so the limit is never cached — it stays
8341
+ * correct across form rebuilds, saves and config changes. Empty or invalid own/partner
8342
+ * values, and a missing partner control, all pass.
8343
+ *
8344
+ * Inside a `QdFormGroup` the partner is re-validated automatically when this control changes
8345
+ * (and vice versa), so a stale error never lingers — no manual `updateValueAndValidity` needed.
8346
+ * The validator declares this dependency via `qdRevalidates`, which the group reads.
8347
+ *
8348
+ * The auto-revalidation only applies when both controls are `QdFormControl`s inside a
8349
+ * `QdFormGroup`, and only for validators present at construction or set via the group's
8350
+ * `add`/`set`/`removeControl`. On a native `FormGroup`/`FormControl`, or when the validator is
8351
+ * added later via `control.addValidators(...)`, re-validate the partner manually with
8352
+ * `partner.updateValueAndValidity({ emitEvent: false })` whenever this control changes.
8353
+ *
8354
+ * @param partnerControlName - Name of the sibling control holding the other end of the range.
8355
+ * @param position - `'start'` for the from-control, `'end'` for the to-control.
8356
+ * @param errorKey - Translation key returned when the order is violated.
8222
8357
  *
8223
8358
  * #### **Usage**
8224
8359
  * ```ts
8225
- * new QdFormControl('', QdValidators.disabledTimes([{ from: '15:00' }]));
8360
+ * new QdFormGroup({
8361
+ * from: new QdFormControl(null, QdValidators.dateRange('to', 'start')),
8362
+ * to: new QdFormControl(null, QdValidators.dateRange('from', 'end'))
8363
+ * });
8364
+ * ```
8365
+ */
8366
+ static dateRange(partnerControlName: string, position: 'start' | 'end', errorKey?: string): ValidatorFn;
8367
+ private static isValidDate;
8368
+ /**
8369
+ * Validates that the time of a date value does not fall inside any disabled time range.
8370
+ *
8371
+ * Each range may set `from`, `to`, or both, as `HH:mm` strings. Boundaries are **exclusive** —
8372
+ * a time exactly on `from` or `to` is allowed; only times strictly between them are rejected.
8373
+ * Only the time-of-day is considered, not the date. Empty or invalid values pass.
8374
+ *
8375
+ * @param disabledTimes - Ranges to block, e.g. `[{ from: '12:00', to: '13:00' }]`.
8376
+ * @param errorKey - Translation key returned when the time lies inside a range.
8377
+ *
8378
+ * #### **Usage**
8379
+ * ```ts
8380
+ * new QdFormControl(null, QdValidators.disabledTimes([{ from: '15:00' }]));
8381
+ * new QdFormControl(null, QdValidators.disabledTimes([{ from: '12:00', to: '13:00' }]));
8226
8382
  * ```
8227
8383
  */
8228
8384
  static disabledTimes(disabledTimes: QdDisabledTimes[], errorKey?: string): ValidatorFn;
8229
8385
  /**
8230
- * Ensures that the selected file does not exceed the given maximum size in megabytes.
8386
+ * Validates that a selected file does not exceed a maximum size.
8387
+ *
8388
+ * Operates on a `File` value (e.g. from a file input). Non-file values — including `null` —
8389
+ * pass, so combine with `required` when a file is mandatory. The error carries `params.maxMb`
8390
+ * for the message.
8391
+ *
8392
+ * @param maxMb - The maximum allowed size in megabytes.
8393
+ * @param errorKey - Translation key returned when the file is too large.
8231
8394
  *
8232
8395
  * #### **Usage**
8233
8396
  * ```ts
@@ -8237,7 +8400,15 @@ declare class QdValidators {
8237
8400
  */
8238
8401
  static fileSize(maxMb: number, errorKey?: string): ValidatorFn;
8239
8402
  /**
8240
- * Validates that the file type or file extension matches one of the accepted types.
8403
+ * Validates that a selected file matches one of the accepted types.
8404
+ *
8405
+ * Each accepted entry is either a MIME type (`'application/pdf'`), a MIME wildcard
8406
+ * (`'image/*'`), or a file extension (`'.pdf'`); matching is case-insensitive. Non-file
8407
+ * values — including `null` — pass, so combine with `required` when a file is mandatory. The
8408
+ * error carries `params.accepted` for the message.
8409
+ *
8410
+ * @param accepted - Allowed MIME types, MIME wildcards or extensions.
8411
+ * @param errorKey - Translation key returned when the file type is not accepted.
8241
8412
  *
8242
8413
  * #### **Usage**
8243
8414
  * ```ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quadrel-enterprise-ui/framework",
3
- "version": "20.21.0",
3
+ "version": "20.21.1-beta.193.1",
4
4
  "exports": {
5
5
  "./jest-preset": "./jest-preset.js",
6
6
  "./package.json": {
@@ -99,6 +99,7 @@
99
99
  "i18n.qd.form.error.pattern": "Entspricht nicht dem Muster",
100
100
  "i18n.qd.form.error.date": "Eingabe entspricht nicht DD.MM.JJJJ",
101
101
  "i18n.qd.form.error.disabledDates": "Datum ausserhalb des erlaubten Bereichs",
102
+ "i18n.qd.form.error.dateRange": "Das Datum liegt ausserhalb des gültigen Bereichs.",
102
103
  "i18n.qd.form.error.startDateNotAfterEndDate": "Das Startdatum darf nicht hinter dem Enddatum liegen.",
103
104
  "i18n.qd.form.error.endDateNotBeforeStartDate": "Das Enddatum darf nicht vor dem Startdatum liegen.",
104
105
  "i18n.qd.form.error.disabledTimes": "Zeit ausserhalb des erlaubten Bereichs",
@@ -101,6 +101,7 @@
101
101
  "i18n.qd.form.error.pattern": "Does not match pattern",
102
102
  "i18n.qd.form.error.date": "Input does not correspond to DD.MM.YYYY",
103
103
  "i18n.qd.form.error.disabledDates": "Date outside the permitted range",
104
+ "i18n.qd.form.error.dateRange": "The date is outside the valid range.",
104
105
  "i18n.qd.form.error.startDateNotAfterEndDate": "The start date cannot be later than the end date.",
105
106
  "i18n.qd.form.error.endDateNotBeforeStartDate": "The end date cannot be earlier than the start date.",
106
107
  "i18n.qd.form.error.disabledTimes": "Time outside the permitted range",
@@ -101,6 +101,7 @@
101
101
  "i18n.qd.form.error.pattern": "Ne correspond pas au schéma",
102
102
  "i18n.qd.form.error.date": "La saisie ne correspond pas à JJ.MM.AAAA",
103
103
  "i18n.qd.form.error.disabledDates": "Date en dehors de la plage autorisée",
104
+ "i18n.qd.form.error.dateRange": "La date est en dehors de la plage valide.",
104
105
  "i18n.qd.form.error.startDateNotAfterEndDate": "La date de début ne peut pas être postérieure à la date de fin.",
105
106
  "i18n.qd.form.error.endDateNotBeforeStartDate": "La date de fin ne peut pas être antérieure à la date de début.",
106
107
  "i18n.qd.form.error.disabledTimes": "Temps en dehors de la plage autorisée",
@@ -101,6 +101,7 @@
101
101
  "i18n.qd.form.error.pattern": "Non corrisponde allo schema",
102
102
  "i18n.qd.form.error.date": "L'input non corrisponde a GG.MM.AAAA",
103
103
  "i18n.qd.form.error.disabledDates": "Data fuori dall'intervallo consentito",
104
+ "i18n.qd.form.error.dateRange": "La data è al di fuori dell'intervallo valido.",
104
105
  "i18n.qd.form.error.startDateNotAfterEndDate": "La data di inizio non può essere successiva alla data di fine.",
105
106
  "i18n.qd.form.error.endDateNotBeforeStartDate": "La data di fine non può essere anteriore alla data di inizio.",
106
107
  "i18n.qd.form.error.disabledTimes": "Tempo fuori dall'intervallo consentito",