@mk-kit/ui 0.42.0 → 0.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +5 -3
  2. package/THIRD_PARTY_NOTICES.md +4 -2
  3. package/fesm2022/mk-kit-ui-block-editor.mjs +4 -2
  4. package/fesm2022/mk-kit-ui-block-editor.mjs.map +1 -1
  5. package/fesm2022/mk-kit-ui-checkbox.mjs +4 -2
  6. package/fesm2022/mk-kit-ui-checkbox.mjs.map +1 -1
  7. package/fesm2022/mk-kit-ui-core.mjs +136 -1
  8. package/fesm2022/mk-kit-ui-core.mjs.map +1 -1
  9. package/fesm2022/mk-kit-ui-data.mjs +438 -8
  10. package/fesm2022/mk-kit-ui-data.mjs.map +1 -1
  11. package/fesm2022/mk-kit-ui-datetime.mjs +88 -50
  12. package/fesm2022/mk-kit-ui-datetime.mjs.map +1 -1
  13. package/fesm2022/mk-kit-ui-directives.mjs +27 -8
  14. package/fesm2022/mk-kit-ui-directives.mjs.map +1 -1
  15. package/fesm2022/mk-kit-ui-dnd.mjs +43 -8
  16. package/fesm2022/mk-kit-ui-dnd.mjs.map +1 -1
  17. package/fesm2022/mk-kit-ui-dynamic-form.mjs +149 -2
  18. package/fesm2022/mk-kit-ui-dynamic-form.mjs.map +1 -1
  19. package/fesm2022/mk-kit-ui-feedback.mjs +1 -1
  20. package/fesm2022/mk-kit-ui-feedback.mjs.map +1 -1
  21. package/fesm2022/mk-kit-ui-forms.mjs +326 -78
  22. package/fesm2022/mk-kit-ui-forms.mjs.map +1 -1
  23. package/fesm2022/mk-kit-ui-icon-extended.mjs +425 -0
  24. package/fesm2022/mk-kit-ui-icon-extended.mjs.map +1 -0
  25. package/fesm2022/mk-kit-ui-icon.mjs +296 -459
  26. package/fesm2022/mk-kit-ui-icon.mjs.map +1 -1
  27. package/fesm2022/mk-kit-ui-media.mjs +1 -1
  28. package/fesm2022/mk-kit-ui-media.mjs.map +1 -1
  29. package/fesm2022/mk-kit-ui-query-builder.mjs +1 -1
  30. package/fesm2022/mk-kit-ui-query-builder.mjs.map +1 -1
  31. package/fesm2022/mk-kit-ui-rich-text.mjs +4 -2
  32. package/fesm2022/mk-kit-ui-rich-text.mjs.map +1 -1
  33. package/fesm2022/mk-kit-ui-table.mjs +668 -24
  34. package/fesm2022/mk-kit-ui-table.mjs.map +1 -1
  35. package/fesm2022/mk-kit-ui-testing.mjs +54 -0
  36. package/fesm2022/mk-kit-ui-testing.mjs.map +1 -1
  37. package/fesm2022/mk-kit-ui.mjs +1 -0
  38. package/fesm2022/mk-kit-ui.mjs.map +1 -1
  39. package/package.json +5 -1
  40. package/schematics/migrate-primeng/transform.js +4 -1
  41. package/schematics/ng-add/index.js +30 -2
  42. package/schematics/ng-add/schema.json +6 -0
  43. package/types/mk-kit-ui-block-editor.d.ts +2 -0
  44. package/types/mk-kit-ui-checkbox.d.ts +2 -0
  45. package/types/mk-kit-ui-core.d.ts +82 -2
  46. package/types/mk-kit-ui-data.d.ts +203 -2
  47. package/types/mk-kit-ui-datetime.d.ts +41 -19
  48. package/types/mk-kit-ui-directives.d.ts +12 -6
  49. package/types/mk-kit-ui-dnd.d.ts +32 -4
  50. package/types/mk-kit-ui-dynamic-form.d.ts +44 -1
  51. package/types/mk-kit-ui-forms.d.ts +154 -16
  52. package/types/mk-kit-ui-icon-extended.d.ts +83 -0
  53. package/types/mk-kit-ui-icon.d.ts +100 -17
  54. package/types/mk-kit-ui-rich-text.d.ts +2 -0
  55. package/types/mk-kit-ui-table.d.ts +234 -25
  56. package/types/mk-kit-ui-testing.d.ts +16 -0
  57. package/types/mk-kit-ui.d.ts +1 -0
@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { inject, model, input, booleanAttribute, signal, computed, forwardRef, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
  import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
4
- import { MkFieldContext, mkUniqueId, mkValidatorChange } from '@mk-kit/ui/core';
4
+ import { MkFieldContext, mkInjectFieldTouched, mkUniqueId, mkValidatorChange } from '@mk-kit/ui/core';
5
5
 
6
6
  /**
7
7
  * Checkbox — a themed checkbox built on a visually-hidden native
@@ -20,6 +20,8 @@ import { MkFieldContext, mkUniqueId, mkValidatorChange } from '@mk-kit/ui/core';
20
20
  */
21
21
  class MkCheckbox {
22
22
  field = inject(MkFieldContext, { optional: true });
23
+ /** Signal Forms: gates `invalid` until the bound field is touched or dirty. */
24
+ fieldTouched = mkInjectFieldTouched();
23
25
  /** Two-way checked state. */
24
26
  checked = model(false, /* @ts-ignore */
25
27
  ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
@@ -49,7 +51,7 @@ class MkCheckbox {
49
51
  ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
50
52
  isRequired = computed(() => this.required() || (this.field?.isRequired() ?? false), /* @ts-ignore */
51
53
  ...(ngDevMode ? [{ debugName: "isRequired" }] : /* istanbul ignore next */ []));
52
- isInvalid = computed(() => this.invalid() || (this.field?.hasError() ?? false), /* @ts-ignore */
54
+ isInvalid = computed(() => (this.invalid() && this.fieldTouched()) || (this.field?.hasError() ?? false), /* @ts-ignore */
53
55
  ...(ngDevMode ? [{ debugName: "isInvalid" }] : /* istanbul ignore next */ []));
54
56
  describedBy = computed(() => this.field?.describedBy() ?? null, /* @ts-ignore */
55
57
  ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
@@ -1 +1 @@
1
- {"version":3,"file":"mk-kit-ui-checkbox.mjs","sources":["../../../projects/mk-kit/checkbox/checkbox.ts","../../../projects/mk-kit/checkbox/checkbox.html","../../../projects/mk-kit/checkbox/mk-kit-ui-checkbox.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n booleanAttribute,\n computed,\n forwardRef,\n inject,\n input,\n model,\n signal,\n} from '@angular/core';\nimport {\n ControlValueAccessor,\n NG_VALIDATORS,\n NG_VALUE_ACCESSOR,\n type AbstractControl,\n type ValidationErrors,\n type Validator,\n} from '@angular/forms';\nimport type { MkSize, MkTone } from '@mk-kit/ui/core';\nimport { MkFieldContext } from '@mk-kit/ui/core';\nimport { mkUniqueId } from '@mk-kit/ui/core';\nimport { mkValidatorChange } from '@mk-kit/ui/core';\n\n/**\n * Checkbox — a themed checkbox built on a visually-hidden native\n * `input[type=checkbox]` (so keyboard + form semantics are native) with a\n * custom box. Supports an `indeterminate` state and projects its label.\n *\n * Implements `ControlValueAccessor` with a two-way `checked` model, so it works\n * with `[(ngModel)]`, reactive forms and `[(checked)]`.\n *\n * ```html\n * <mk-checkbox [(ngModel)]=\"accepted\">Accept terms</mk-checkbox>\n * <mk-checkbox [(checked)]=\"all\" [indeterminate]=\"some()\" tone=\"success\">\n * Select all\n * </mk-checkbox>\n * ```\n */\n@Component({\n selector: 'mk-checkbox',\n templateUrl: './checkbox.html',\n styleUrl: './checkbox.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'mk-checkbox',\n '[class.mk-checkbox--sm]': \"size() === 'sm'\",\n '[class.mk-checkbox--md]': \"size() === 'md'\",\n '[class.mk-checkbox--lg]': \"size() === 'lg'\",\n '[class.mk-checkbox--checked]': 'checked()',\n '[class.mk-checkbox--indeterminate]': 'indeterminate()',\n '[class.mk-checkbox--disabled]': 'isDisabled()',\n '[class.mk-checkbox--invalid]': 'isInvalid()',\n '[attr.data-tone]': 'tone()',\n },\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => MkCheckbox),\n multi: true,\n },\n {\n provide: NG_VALIDATORS,\n useExisting: forwardRef(() => MkCheckbox),\n multi: true,\n },\n ],\n})\nexport class MkCheckbox implements ControlValueAccessor, Validator {\n private readonly field = inject(MkFieldContext, { optional: true });\n\n /** Two-way checked state. */\n readonly checked = model(false);\n /** Two-way indeterminate (\"mixed\") state; cleared when the user toggles. */\n readonly indeterminate = model(false);\n /** Disable the control. */\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Force the invalid visual + `aria-invalid` when used standalone. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Mark required (adds `aria-required`). */\n readonly required = input(false, { transform: booleanAttribute });\n /** Control size. */\n readonly size = input<MkSize>('md');\n /** Semantic color tone for the checked box. */\n readonly tone = input<MkTone>('primary');\n /** Accessible label when no text content is projected. */\n readonly ariaLabel = input<string>('', { alias: 'aria-label' });\n\n private readonly cvaDisabled = signal(false);\n private onChange: (value: boolean) => void = () => {};\n protected onTouched: () => void = () => {};\n\n readonly inputId = this.field?.controlId ?? mkUniqueId('mk-checkbox');\n\n protected readonly isDisabled = computed(\n () => this.disabled() || this.cvaDisabled(),\n );\n protected readonly isRequired = computed(\n () => this.required() || (this.field?.isRequired() ?? false),\n );\n protected readonly isInvalid = computed(\n () => this.invalid() || (this.field?.hasError() ?? false),\n );\n protected readonly describedBy = computed(\n () => this.field?.describedBy() ?? null,\n );\n\n protected onNativeChange(event: Event): void {\n const target = event.target as HTMLInputElement;\n this.indeterminate.set(false);\n this.checked.set(target.checked);\n this.onChange(target.checked);\n }\n\n // --- ControlValueAccessor -------------------------------------------------\n writeValue(value: unknown): void {\n this.checked.set(!!value);\n }\n registerOnChange(fn: (value: boolean) => void): void {\n this.onChange = fn;\n }\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n setDisabledState(isDisabled: boolean): void {\n this.cvaDisabled.set(isDisabled);\n }\n\n // --- Validator ------------------------------------------------------------\n private readonly validatorChange = mkValidatorChange(() => {\n this.required();\n });\n\n /**\n * Reports `required` for an unchecked box when `[required]` is set, so\n * `required` on the element behaves like `Validators.requiredTrue`.\n */\n validate(control: AbstractControl): ValidationErrors | null {\n if (!this.required()) return null;\n return control.value === true ? null : { required: true };\n }\n\n registerOnValidatorChange(fn: () => void): void {\n this.validatorChange.register(fn);\n }\n}\n","<label class=\"mk-checkbox__root\">\n <span class=\"mk-checkbox__control\">\n <input\n class=\"mk-checkbox__native\"\n type=\"checkbox\"\n [id]=\"inputId\"\n [checked]=\"checked()\"\n [indeterminate]=\"indeterminate()\"\n [disabled]=\"isDisabled()\"\n [required]=\"isRequired()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-required]=\"isRequired() || null\"\n [attr.aria-invalid]=\"isInvalid() || null\"\n [attr.aria-describedby]=\"describedBy()\"\n (change)=\"onNativeChange($event)\"\n (blur)=\"onTouched()\"\n />\n <span class=\"mk-checkbox__box\" aria-hidden=\"true\">\n <span class=\"mk-checkbox__check\"></span>\n <span class=\"mk-checkbox__dash\"></span>\n </span>\n </span>\n <span class=\"mk-checkbox__text\"><ng-content /></span>\n</label>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mk-kit-ui-checkbox.mjs","sources":["../../../projects/mk-kit/checkbox/checkbox.ts","../../../projects/mk-kit/checkbox/checkbox.html","../../../projects/mk-kit/checkbox/mk-kit-ui-checkbox.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n booleanAttribute,\n computed,\n forwardRef,\n inject,\n input,\n model,\n signal,\n} from '@angular/core';\nimport {\n ControlValueAccessor,\n NG_VALIDATORS,\n NG_VALUE_ACCESSOR,\n type AbstractControl,\n type ValidationErrors,\n type Validator,\n} from '@angular/forms';\nimport type { MkSize, MkTone } from '@mk-kit/ui/core';\nimport { MkFieldContext } from '@mk-kit/ui/core';\nimport { mkUniqueId } from '@mk-kit/ui/core';\nimport { mkValidatorChange } from '@mk-kit/ui/core';\nimport { mkInjectFieldTouched } from '@mk-kit/ui/core';\n\n/**\n * Checkbox — a themed checkbox built on a visually-hidden native\n * `input[type=checkbox]` (so keyboard + form semantics are native) with a\n * custom box. Supports an `indeterminate` state and projects its label.\n *\n * Implements `ControlValueAccessor` with a two-way `checked` model, so it works\n * with `[(ngModel)]`, reactive forms and `[(checked)]`.\n *\n * ```html\n * <mk-checkbox [(ngModel)]=\"accepted\">Accept terms</mk-checkbox>\n * <mk-checkbox [(checked)]=\"all\" [indeterminate]=\"some()\" tone=\"success\">\n * Select all\n * </mk-checkbox>\n * ```\n */\n@Component({\n selector: 'mk-checkbox',\n templateUrl: './checkbox.html',\n styleUrl: './checkbox.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'mk-checkbox',\n '[class.mk-checkbox--sm]': \"size() === 'sm'\",\n '[class.mk-checkbox--md]': \"size() === 'md'\",\n '[class.mk-checkbox--lg]': \"size() === 'lg'\",\n '[class.mk-checkbox--checked]': 'checked()',\n '[class.mk-checkbox--indeterminate]': 'indeterminate()',\n '[class.mk-checkbox--disabled]': 'isDisabled()',\n '[class.mk-checkbox--invalid]': 'isInvalid()',\n '[attr.data-tone]': 'tone()',\n },\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => MkCheckbox),\n multi: true,\n },\n {\n provide: NG_VALIDATORS,\n useExisting: forwardRef(() => MkCheckbox),\n multi: true,\n },\n ],\n})\nexport class MkCheckbox implements ControlValueAccessor, Validator {\n private readonly field = inject(MkFieldContext, { optional: true });\n /** Signal Forms: gates `invalid` until the bound field is touched or dirty. */\n private readonly fieldTouched = mkInjectFieldTouched();\n\n /** Two-way checked state. */\n readonly checked = model(false);\n /** Two-way indeterminate (\"mixed\") state; cleared when the user toggles. */\n readonly indeterminate = model(false);\n /** Disable the control. */\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Force the invalid visual + `aria-invalid` when used standalone. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Mark required (adds `aria-required`). */\n readonly required = input(false, { transform: booleanAttribute });\n /** Control size. */\n readonly size = input<MkSize>('md');\n /** Semantic color tone for the checked box. */\n readonly tone = input<MkTone>('primary');\n /** Accessible label when no text content is projected. */\n readonly ariaLabel = input<string>('', { alias: 'aria-label' });\n\n private readonly cvaDisabled = signal(false);\n private onChange: (value: boolean) => void = () => {};\n protected onTouched: () => void = () => {};\n\n readonly inputId = this.field?.controlId ?? mkUniqueId('mk-checkbox');\n\n protected readonly isDisabled = computed(\n () => this.disabled() || this.cvaDisabled(),\n );\n protected readonly isRequired = computed(\n () => this.required() || (this.field?.isRequired() ?? false),\n );\n protected readonly isInvalid = computed(\n () => (this.invalid() && this.fieldTouched()) || (this.field?.hasError() ?? false),\n );\n protected readonly describedBy = computed(\n () => this.field?.describedBy() ?? null,\n );\n\n protected onNativeChange(event: Event): void {\n const target = event.target as HTMLInputElement;\n this.indeterminate.set(false);\n this.checked.set(target.checked);\n this.onChange(target.checked);\n }\n\n // --- ControlValueAccessor -------------------------------------------------\n writeValue(value: unknown): void {\n this.checked.set(!!value);\n }\n registerOnChange(fn: (value: boolean) => void): void {\n this.onChange = fn;\n }\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n setDisabledState(isDisabled: boolean): void {\n this.cvaDisabled.set(isDisabled);\n }\n\n // --- Validator ------------------------------------------------------------\n private readonly validatorChange = mkValidatorChange(() => {\n this.required();\n });\n\n /**\n * Reports `required` for an unchecked box when `[required]` is set, so\n * `required` on the element behaves like `Validators.requiredTrue`.\n */\n validate(control: AbstractControl): ValidationErrors | null {\n if (!this.required()) return null;\n return control.value === true ? null : { required: true };\n }\n\n registerOnValidatorChange(fn: () => void): void {\n this.validatorChange.register(fn);\n }\n}\n","<label class=\"mk-checkbox__root\">\n <span class=\"mk-checkbox__control\">\n <input\n class=\"mk-checkbox__native\"\n type=\"checkbox\"\n [id]=\"inputId\"\n [checked]=\"checked()\"\n [indeterminate]=\"indeterminate()\"\n [disabled]=\"isDisabled()\"\n [required]=\"isRequired()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-required]=\"isRequired() || null\"\n [attr.aria-invalid]=\"isInvalid() || null\"\n [attr.aria-describedby]=\"describedBy()\"\n (change)=\"onNativeChange($event)\"\n (blur)=\"onTouched()\"\n />\n <span class=\"mk-checkbox__box\" aria-hidden=\"true\">\n <span class=\"mk-checkbox__check\"></span>\n <span class=\"mk-checkbox__dash\"></span>\n </span>\n </span>\n <span class=\"mk-checkbox__text\"><ng-content /></span>\n</label>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import * as i0 from '@angular/core';
2
2
  import { inject, DOCUMENT, DestroyRef, PLATFORM_ID, signal, computed, effect, Injectable, InjectionToken, ApplicationRef, EnvironmentInjector, createComponent, Injector, ElementRef, input, output, Directive, untracked } from '@angular/core';
3
3
  import { isPlatformBrowser } from '@angular/common';
4
4
  import { Observable } from 'rxjs';
5
+ import { FORM_FIELD } from '@angular/forms/signals';
5
6
 
6
7
  /** Shared primitive types used across mk-kit components. */
7
8
 
@@ -1446,6 +1447,9 @@ const MK_DEFAULT_I18N = {
1446
1447
  logFollow: 'Follow',
1447
1448
  logCopyAll: 'Copy log',
1448
1449
  logWrapLines: 'Wrap lines',
1450
+ orgChartLabel: 'Organisation chart',
1451
+ orgChartExpand: 'Expand {label}',
1452
+ orgChartCollapse: 'Collapse {label}',
1449
1453
  chatLabel: 'Conversation',
1450
1454
  chatComposerLabel: 'Message',
1451
1455
  chatPlaceholder: 'Type a message…',
@@ -1581,6 +1585,11 @@ const MK_DEFAULT_I18N = {
1581
1585
  chartShare: 'Share',
1582
1586
  chartLabel: 'Label',
1583
1587
  qrCodeLabel: (text) => `QR code: ${text}`,
1588
+ sortableListLabel: 'Sortable list',
1589
+ filterColumn: (column) => `Filter ${column}`,
1590
+ clearFilter: (column) => `Clear filter for ${column}`,
1591
+ filterAny: 'All',
1592
+ filterMin: 'Min',
1584
1593
  blockEditor: {
1585
1594
  addBlock: 'Add block',
1586
1595
  addFirstBlock: 'Add your first block',
@@ -1872,6 +1881,132 @@ function mkFirstErrorMessage(errors, strings, overrides) {
1872
1881
  return errors ? strings.unknown : null;
1873
1882
  }
1874
1883
 
1884
+ /**
1885
+ * Converts Signal Forms errors to the reactive-forms `ValidationErrors` shape
1886
+ * the `validation` i18n table is keyed by, so both form systems render the
1887
+ * same messages. The built-in kinds map to Angular's classic keys and payloads
1888
+ * (`minLength` → `minlength: { requiredLength }`, `minDate` → `mkMinDate`,
1889
+ * …); any other kind is kept as-is with its payload spread into the value.
1890
+ *
1891
+ * @returns The error map in the order the errors were reported, or `null`
1892
+ * when the list is empty.
1893
+ */
1894
+ function mkSignalErrorsToValidationErrors(errors) {
1895
+ if (!errors || errors.length === 0)
1896
+ return null;
1897
+ const out = {};
1898
+ for (const err of errors) {
1899
+ const [key, payload] = toReactiveError(err);
1900
+ if (!(key in out))
1901
+ out[key] = payload;
1902
+ }
1903
+ return out;
1904
+ }
1905
+ function toReactiveError(error) {
1906
+ const err = error;
1907
+ const message = err.message;
1908
+ switch (err.kind) {
1909
+ case 'required':
1910
+ return ['required', message ? { message } : true];
1911
+ case 'email':
1912
+ return ['email', message ? { message } : true];
1913
+ case 'min':
1914
+ return ['min', { min: err['min'], actual: err['actual'], message }];
1915
+ case 'max':
1916
+ return ['max', { max: err['max'], actual: err['actual'], message }];
1917
+ case 'minLength':
1918
+ return ['minlength', { requiredLength: err['minLength'], actualLength: err['actualLength'], message }];
1919
+ case 'maxLength':
1920
+ return ['maxlength', { requiredLength: err['maxLength'], actualLength: err['actualLength'], message }];
1921
+ case 'pattern':
1922
+ return ['pattern', { requiredPattern: String(err['pattern'] ?? ''), message }];
1923
+ case 'minDate':
1924
+ return ['mkMinDate', { min: err['minDate'], actual: err['actual'], message }];
1925
+ case 'maxDate':
1926
+ return ['mkMaxDate', { max: err['maxDate'], actual: err['actual'], message }];
1927
+ default: {
1928
+ // Custom / server / compat errors: keep the kind as the key and expose the
1929
+ // payload (a `CompatValidationError` carries the reactive payload in
1930
+ // `context`) so per-key `errorMessages` functions receive it.
1931
+ const rest = {};
1932
+ for (const key of Object.keys(err)) {
1933
+ if (key !== 'kind' && key !== 'fieldTree' && key !== 'formField')
1934
+ rest[key] = err[key];
1935
+ }
1936
+ const context = rest['context'];
1937
+ if (context && typeof context === 'object') {
1938
+ return [err.kind, { ...context, message: message ?? context.message }];
1939
+ }
1940
+ return [err.kind, Object.keys(rest).length ? rest : message ? { message } : true];
1941
+ }
1942
+ }
1943
+ }
1944
+ /**
1945
+ * Resolves the message for the first Signal Forms error on a field, the way
1946
+ * `mkFirstErrorMessage` does for reactive forms.
1947
+ *
1948
+ * Lookup order: the field's `overrides` for that kind, then the `message` the
1949
+ * schema attached to the error (`required(p.email, { message: '…' })`), then
1950
+ * the i18n `validation` table, then the generic fallback.
1951
+ *
1952
+ * @returns The message, or `null` when there are no errors.
1953
+ */
1954
+ function mkSignalErrorMessage(errors, strings, overrides) {
1955
+ if (!errors || errors.length === 0)
1956
+ return null;
1957
+ const first = errors[0];
1958
+ const [key, payload] = toReactiveError(first);
1959
+ const override = overrides?.[key];
1960
+ if (typeof override === 'string')
1961
+ return override;
1962
+ if (typeof override === 'function')
1963
+ return override(payload);
1964
+ if (typeof first.message === 'string' && first.message)
1965
+ return first.message;
1966
+ return mkFirstErrorMessage({ [key]: payload }, strings);
1967
+ }
1968
+
1969
+ /**
1970
+ * Touched-gate for a control's `invalid` input under Signal Forms.
1971
+ *
1972
+ * When a control is bound with the `[formField]` directive, Angular writes the
1973
+ * field's `invalid()` state straight into the control's `invalid` input — from
1974
+ * the first render, before the user has reached the field. mk-kit controls
1975
+ * pass that input through this gate so the invalid visual (and `aria-invalid`)
1976
+ * only shows once the field is touched or dirty, matching how `mk-form-field`
1977
+ * reveals its message and how `submit()` (which marks every field touched)
1978
+ * surfaces the remaining problems.
1979
+ *
1980
+ * Returns a signal that is always `true` for a control that is not bound with
1981
+ * `[formField]`, so a standalone `[invalid]="true"` keeps working as before.
1982
+ * Call it in a field initializer (an injection context):
1983
+ *
1984
+ * ```ts
1985
+ * private readonly fieldTouched = mkInjectFieldTouched();
1986
+ * protected readonly isInvalid = computed(
1987
+ * () => (this.invalid() && this.fieldTouched()) || (this.field?.hasError() ?? false),
1988
+ * );
1989
+ * ```
1990
+ *
1991
+ * The binding is looked up lazily, on first read: the `FormField` directive
1992
+ * itself injects the element's `NG_VALUE_ACCESSOR` (the control) while it is
1993
+ * created, so resolving it from the control's constructor would be circular.
1994
+ */
1995
+ function mkInjectFieldTouched() {
1996
+ const injector = inject(Injector);
1997
+ let formField;
1998
+ const resolve = () => formField === undefined
1999
+ ? (formField = injector.get(FORM_FIELD, null, { self: true, optional: true }))
2000
+ : formField;
2001
+ return computed(() => {
2002
+ const field = resolve();
2003
+ if (!field)
2004
+ return true;
2005
+ const state = field.state();
2006
+ return state.touched() || state.dirty();
2007
+ });
2008
+ }
2009
+
1875
2010
  /** Operators offered per field type, in menu order. */
1876
2011
  const MK_QUERY_OPERATORS = {
1877
2012
  string: ['contains', 'notContains', 'eq', 'neq', 'startsWith', 'endsWith', 'empty', 'notEmpty'],
@@ -2126,5 +2261,5 @@ function mkQueryToText(group, fields = [], i18n = MK_DEFAULT_I18N) {
2126
2261
  * Generated bundle index. Do not edit.
2127
2262
  */
2128
2263
 
2129
- export { MK_BREAKPOINTS, MK_DEFAULT_BREAKPOINTS, MK_DEFAULT_DATE_NAMES, MK_DEFAULT_I18N, MK_DEFAULT_VALIDATION, MK_I18N, MK_OVERLAY_DATA, MK_QUERY_OPERATORS, MK_QUERY_UNARY, MkAnchoredPanel, MkBreakpointService, MkFieldContext, MkFocusTrap, MkLiveAnnouncer, MkOverlayRef, MkOverlayService, MkThemeService, mkComputeAnchoredPosition, mkCreateQueryGroup, mkCreateQueryRule, mkFirstErrorMessage, mkGetFocusable, mkHighlight, mkHighlightJson, mkIsQueryGroup, mkIsResponsive, mkQueryCompact, mkQueryIsEmpty, mkQueryOperatorLabel, mkQueryOperatorsFor, mkQueryRuleCount, mkQueryRuleIsComplete, mkQueryRuleMatches, mkQueryToPredicate, mkQueryToText, mkUniqueId, mkValidatorChange, provideMkI18n };
2264
+ export { MK_BREAKPOINTS, MK_DEFAULT_BREAKPOINTS, MK_DEFAULT_DATE_NAMES, MK_DEFAULT_I18N, MK_DEFAULT_VALIDATION, MK_I18N, MK_OVERLAY_DATA, MK_QUERY_OPERATORS, MK_QUERY_UNARY, MkAnchoredPanel, MkBreakpointService, MkFieldContext, MkFocusTrap, MkLiveAnnouncer, MkOverlayRef, MkOverlayService, MkThemeService, mkComputeAnchoredPosition, mkCreateQueryGroup, mkCreateQueryRule, mkFirstErrorMessage, mkGetFocusable, mkHighlight, mkHighlightJson, mkInjectFieldTouched, mkIsQueryGroup, mkIsResponsive, mkQueryCompact, mkQueryIsEmpty, mkQueryOperatorLabel, mkQueryOperatorsFor, mkQueryRuleCount, mkQueryRuleIsComplete, mkQueryRuleMatches, mkQueryToPredicate, mkQueryToText, mkSignalErrorMessage, mkSignalErrorsToValidationErrors, mkUniqueId, mkValidatorChange, provideMkI18n };
2130
2265
  //# sourceMappingURL=mk-kit-ui-core.mjs.map