@mk-kit/ui 0.45.0 → 0.46.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.
- package/README.md +10 -7
- package/fesm2022/mk-kit-ui-forms.mjs +21 -75
- package/fesm2022/mk-kit-ui-forms.mjs.map +1 -1
- package/package.json +2 -1
- package/types/mk-kit-ui-forms.d.ts +13 -10
package/README.md
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
**Themable, accessible Angular component library for admin dashboards, back-offices and internal tools.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
185+ components (225+ selectors with directives and pipes) and 16 services — data tables, charts,
|
|
6
6
|
date & time pickers, editors, kanban, overlays, an app shell — written for
|
|
7
7
|
Angular 22 with signals and `OnPush` from day one. Every visual value is a
|
|
8
8
|
`--mk-*` CSS custom property; light and dark ship out of the box; WCAG 2.1 AA
|
|
9
|
-
is the target, not the marketing. MIT licensed.
|
|
10
|
-
|
|
9
|
+
is the target, not the marketing. MIT licensed. No third-party runtime
|
|
10
|
+
dependencies — only Angular and the sibling `@mk-kit/validators` (the
|
|
11
|
+
identifier checks, 14 kB, tree-shakeable).
|
|
11
12
|
|
|
12
13
|
- **Docs & live demos:** <https://mk-kit.dev>
|
|
13
14
|
- **API reference:** <https://mk-kit.dev/api> — also as [api.json](https://mk-kit.dev/api.json), [llms.txt](https://mk-kit.dev/llms.txt) and [llms-full.txt](https://mk-kit.dev/llms-full.txt) for tools and AI assistants
|
|
@@ -103,10 +104,12 @@ import { MkDatePicker } from '@mk-kit/ui/datetime';
|
|
|
103
104
|
```
|
|
104
105
|
|
|
105
106
|
Available: `core`, `forms`, `datetime`, `table`, `data`, `navigation`,
|
|
106
|
-
`feedback`, `directives`, `dnd`, `media`, `icon`, `
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
107
|
+
`feedback`, `directives`, `dnd`, `media`, `icon`, `icon/extended` (the opt-in
|
|
108
|
+
305-icon set), `button`, `checkbox`, `chip`, `context-menu`, `layout`, `chat`,
|
|
109
|
+
`query-builder`, `dynamic-form`, `rich-text`, `block-editor`, plus `testing`
|
|
110
|
+
(component harnesses for specs) and `locales/pl` (the Polish string pack) —
|
|
111
|
+
the last two are never re-exported from the umbrella. `sideEffects: false`
|
|
112
|
+
throughout.
|
|
110
113
|
|
|
111
114
|
## Theming
|
|
112
115
|
|
|
@@ -12,6 +12,7 @@ import { NgTemplateOutlet, isPlatformBrowser } from '@angular/common';
|
|
|
12
12
|
import { mkMoveItemInArray, MkDropList, MkDrag, MkDragHandle } from '@mk-kit/ui/dnd';
|
|
13
13
|
import { MkTree } from '@mk-kit/ui/navigation';
|
|
14
14
|
import { mkApplyMask, MkMask, mkMaskCaret } from '@mk-kit/ui/directives';
|
|
15
|
+
import { detectCardBrand, isLuhn, IBAN_LENGTHS, ibanMod97, isIban, isNip } from '@mk-kit/validators';
|
|
15
16
|
export * from '@mk-kit/ui/checkbox';
|
|
16
17
|
|
|
17
18
|
/**
|
|
@@ -7983,41 +7984,13 @@ const MK_CARD_BRAND_NAMES = {
|
|
|
7983
7984
|
diners: 'Diners Club',
|
|
7984
7985
|
jcb: 'JCB',
|
|
7985
7986
|
};
|
|
7986
|
-
/** Detect the card network from the leading digits
|
|
7987
|
+
/** Detect the card network from the leading digits — `detectCardBrand` from `@mk-kit/validators`. */
|
|
7987
7988
|
function mkDetectCardBrand(digits) {
|
|
7988
|
-
|
|
7989
|
-
return null;
|
|
7990
|
-
if (/^3[47]/.test(digits))
|
|
7991
|
-
return 'amex';
|
|
7992
|
-
if (/^(30[0-5]|36|38)/.test(digits))
|
|
7993
|
-
return 'diners';
|
|
7994
|
-
if (/^35/.test(digits))
|
|
7995
|
-
return 'jcb';
|
|
7996
|
-
if (/^(6011|64[4-9]|65)/.test(digits))
|
|
7997
|
-
return 'discover';
|
|
7998
|
-
if (/^(5[1-5]|22[2-9]|2[3-6]|27[0-2])/.test(digits))
|
|
7999
|
-
return 'mastercard';
|
|
8000
|
-
if (/^4/.test(digits))
|
|
8001
|
-
return 'visa';
|
|
8002
|
-
return null;
|
|
7989
|
+
return detectCardBrand(digits);
|
|
8003
7990
|
}
|
|
8004
|
-
/** Luhn (mod 10) checksum over a digit string
|
|
7991
|
+
/** Luhn (mod 10) checksum over a digit string — `isLuhn` from `@mk-kit/validators`. */
|
|
8005
7992
|
function mkLuhnCheck(digits) {
|
|
8006
|
-
|
|
8007
|
-
return false;
|
|
8008
|
-
let sum = 0;
|
|
8009
|
-
let double = false;
|
|
8010
|
-
for (let i = digits.length - 1; i >= 0; i--) {
|
|
8011
|
-
let d = digits.charCodeAt(i) - 48;
|
|
8012
|
-
if (double) {
|
|
8013
|
-
d *= 2;
|
|
8014
|
-
if (d > 9)
|
|
8015
|
-
d -= 9;
|
|
8016
|
-
}
|
|
8017
|
-
sum += d;
|
|
8018
|
-
double = !double;
|
|
8019
|
-
}
|
|
8020
|
-
return sum % 10 === 0;
|
|
7993
|
+
return /^\d+$/.test(digits) && isLuhn(digits);
|
|
8021
7994
|
}
|
|
8022
7995
|
/** Grouping masks per brand (digit counts differ). */
|
|
8023
7996
|
const BRAND_MASKS = {
|
|
@@ -8201,42 +8174,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
8201
8174
|
], template: "<input\n type=\"text\"\n class=\"mk-card-number-input__field\"\n [id]=\"inputId\"\n autocomplete=\"cc-number\"\n spellcheck=\"false\"\n [mkMask]=\"mask()\"\n [value]=\"masked()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-labelledby]=\"labelledBy()\"\n [attr.aria-label]=\"labelledBy() ? null : i18n.cardNumber\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-invalid]=\"isInvalid() || null\"\n [attr.aria-required]=\"isRequired() || null\"\n (unmaskedChange)=\"onDigitsChange($event)\"\n (blur)=\"onBlur()\"\n/>\n\n@if (showBrand() && brandName()) {\n <span class=\"mk-card-number-input__brand\">\n {{ brandName() }}\n <span class=\"mk-visually-hidden\">{{ i18n.cardBrand(brandName()) }}</span>\n </span>\n}\n", styles: ["@charset \"UTF-8\";:host{display:inline-flex;align-items:center;gap:var(--mk-space-2);width:100%;height:var(--mk-control-height-md);padding-inline-end:var(--mk-space-2);background-color:var(--mk-surface);border:var(--mk-border-width) solid var(--mk-border);border-radius:var(--mk-radius-md);font-family:var(--mk-font-sans);overflow:hidden;transition:border-color var(--mk-duration-fast) var(--mk-ease-standard),box-shadow var(--mk-duration-fast) var(--mk-ease-standard)}:host(.mk-card-number-input--sm){height:var(--mk-control-height-sm);border-radius:var(--mk-radius-sm)}:host(.mk-card-number-input--lg){height:var(--mk-control-height-lg)}:host(:hover:not(.mk-card-number-input--disabled)){border-color:var(--mk-border-strong)}:host(:focus-within){outline:var(--mk-focus-ring-width) solid var(--mk-focus-ring);outline-offset:var(--mk-focus-ring-offset);border-color:var(--mk-primary)}:host(.mk-card-number-input--invalid){border-color:var(--mk-danger)}:host(.mk-card-number-input--invalid:focus-within){outline-color:var(--mk-danger)}:host(.mk-card-number-input--disabled){background-color:var(--mk-surface-2);opacity:.7}.mk-card-number-input__field{flex:1 1 auto;min-width:0;padding:0 var(--mk-space-3);font-family:inherit;font-size:var(--mk-font-size-md);font-variant-numeric:tabular-nums;color:var(--mk-text);background:transparent;border:none;outline:none}.mk-card-number-input__field::placeholder{color:var(--mk-text-subtle)}.mk-card-number-input__field:disabled{color:var(--mk-text-disabled);cursor:not-allowed}.mk-card-number-input__brand{flex:none;padding:2px var(--mk-space-2);font-size:var(--mk-font-size-xs);font-weight:var(--mk-font-weight-medium);color:var(--mk-neutral-subtle-text);background-color:var(--mk-neutral-subtle);border-radius:var(--mk-radius-pill);white-space:nowrap;-webkit-user-select:none;user-select:none}:host(.mk-card-number-input--sm) .mk-card-number-input__field{font-size:var(--mk-font-size-sm)}:host(.mk-card-number-input--lg) .mk-card-number-input__field{font-size:var(--mk-font-size-lg)}@media(prefers-reduced-motion:reduce){:host{transition:none}}@media(pointer:coarse){.mk-card-number-input__field{font-size:max(var(--mk-font-size-md),16px)}:host(.mk-card-number-input--sm) .mk-card-number-input__field{font-size:max(var(--mk-font-size-sm),16px)}}\n"] }]
|
|
8202
8175
|
}], propDecorators: { showBrand: [{ type: i0.Input, args: [{ isSignal: true, alias: "showBrand", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], brandChange: [{ type: i0.Output, args: ["brandChange"] }] } });
|
|
8203
8176
|
|
|
8204
|
-
/** IBAN length per ISO 13616 country code (SEPA + common others). */
|
|
8205
|
-
const MK_IBAN_LENGTHS = {
|
|
8206
|
-
AD: 24, AE: 23, AL: 28, AT: 20, AZ: 28, BA: 20, BE: 16, BG: 22, BH: 22,
|
|
8207
|
-
BR: 29, CH: 21, CR: 22, CY: 28, CZ: 24, DE: 22, DK: 18, DO: 28, EE: 20,
|
|
8208
|
-
EG: 29, ES: 24, FI: 18, FO: 18, FR: 27, GB: 22, GE: 22, GI: 23, GL: 18,
|
|
8209
|
-
GR: 27, HR: 21, HU: 28, IE: 22, IL: 23, IS: 26, IT: 27, JO: 30, KW: 30,
|
|
8210
|
-
KZ: 20, LB: 28, LI: 21, LT: 20, LU: 20, LV: 21, MC: 27, MD: 24, ME: 22,
|
|
8211
|
-
MK: 19, MT: 31, NL: 18, NO: 15, PK: 24, PL: 28, PT: 25, QA: 29, RO: 24,
|
|
8212
|
-
RS: 22, SA: 24, SE: 24, SI: 19, SK: 24, SM: 27, TN: 24, TR: 26, UA: 29,
|
|
8213
|
-
VA: 22, XK: 20,
|
|
8214
|
-
};
|
|
8215
|
-
/** The maximum IBAN length the standard allows. */
|
|
8216
|
-
const IBAN_MAX = 34;
|
|
8217
8177
|
/**
|
|
8218
|
-
*
|
|
8219
|
-
*
|
|
8178
|
+
* IBAN lengths per country — re-exported from `@mk-kit/validators`
|
|
8179
|
+
* (`IBAN_LENGTHS`, the SWIFT registry).
|
|
8220
8180
|
*/
|
|
8181
|
+
const MK_IBAN_LENGTHS = IBAN_LENGTHS;
|
|
8182
|
+
/** Longest IBAN in the registry (Malta, 31) rounded up to the ISO 13616 maximum. */
|
|
8183
|
+
const IBAN_MAX = 34;
|
|
8184
|
+
/** ISO 7064 MOD 97-10 over a compact (uppercase, no separators) IBAN. */
|
|
8221
8185
|
function mkIbanChecksum(compact) {
|
|
8222
|
-
|
|
8223
|
-
return false;
|
|
8224
|
-
const rearranged = compact.slice(4) + compact.slice(0, 4);
|
|
8225
|
-
let rem = 0;
|
|
8226
|
-
for (const ch of rearranged) {
|
|
8227
|
-
const code = ch.charCodeAt(0);
|
|
8228
|
-
// A→10 … Z→35 contribute two digits; plain digits contribute one.
|
|
8229
|
-
if (code >= 65)
|
|
8230
|
-
rem = (rem * 100 + (code - 55)) % 97;
|
|
8231
|
-
else
|
|
8232
|
-
rem = (rem * 10 + (code - 48)) % 97;
|
|
8233
|
-
}
|
|
8234
|
-
return rem === 1;
|
|
8186
|
+
return /^[A-Z]{2}\d{2}[A-Z0-9]+$/.test(compact) && ibanMod97(compact) === 1;
|
|
8235
8187
|
}
|
|
8236
|
-
/**
|
|
8188
|
+
/**
|
|
8189
|
+
* Shape, the registry length for the country and the checksum — delegates
|
|
8190
|
+
* to `isIban` from `@mk-kit/validators`. Unlike that function this one keeps
|
|
8191
|
+
* the input kit's stricter rule that the country must be in the table.
|
|
8192
|
+
*/
|
|
8237
8193
|
function mkIbanIsValid(compact) {
|
|
8238
|
-
|
|
8239
|
-
return (length !== undefined && compact.length === length && mkIbanChecksum(compact));
|
|
8194
|
+
return MK_IBAN_LENGTHS[compact.slice(0, 2)] !== undefined && isIban(compact);
|
|
8240
8195
|
}
|
|
8241
8196
|
/**
|
|
8242
8197
|
* Reactive-forms validator for an IBAN (any supported country). Empty values
|
|
@@ -8429,21 +8384,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
8429
8384
|
], template: "<input\n type=\"text\"\n class=\"mk-iban-input__field\"\n [id]=\"inputId\"\n autocomplete=\"off\"\n autocapitalize=\"characters\"\n spellcheck=\"false\"\n [value]=\"grouped()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-labelledby]=\"labelledBy()\"\n [attr.aria-label]=\"labelledBy() ? null : i18n.iban\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-invalid]=\"isInvalid() || null\"\n [attr.aria-required]=\"isRequired() || null\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n/>\n", styles: ["@charset \"UTF-8\";:host{display:inline-flex;width:100%;font-family:var(--mk-font-sans)}.mk-iban-input__field{width:100%;min-width:0;height:var(--mk-control-height-md);padding:0 var(--mk-space-3);font-family:var(--mk-font-mono);font-size:var(--mk-font-size-md);color:var(--mk-text);background-color:var(--mk-surface);border:var(--mk-border-width) solid var(--mk-border);border-radius:var(--mk-radius-md);outline:none;transition:border-color var(--mk-duration-fast) var(--mk-ease-standard),box-shadow var(--mk-duration-fast) var(--mk-ease-standard)}:host(.mk-iban-input--sm) .mk-iban-input__field{height:var(--mk-control-height-sm);padding:0 var(--mk-space-2);font-size:var(--mk-font-size-sm);border-radius:var(--mk-radius-sm)}:host(.mk-iban-input--lg) .mk-iban-input__field{height:var(--mk-control-height-lg);padding:0 var(--mk-space-4);font-size:var(--mk-font-size-lg)}.mk-iban-input__field::placeholder{color:var(--mk-text-subtle);font-family:var(--mk-font-sans)}.mk-iban-input__field:hover:not(:disabled){border-color:var(--mk-border-strong)}.mk-iban-input__field:focus-visible{outline:var(--mk-focus-ring-width) solid var(--mk-focus-ring);outline-offset:var(--mk-focus-ring-offset);border-color:var(--mk-primary)}:host(.mk-iban-input--invalid) .mk-iban-input__field{border-color:var(--mk-danger)}:host(.mk-iban-input--invalid) .mk-iban-input__field:focus-visible{outline-color:var(--mk-danger)}.mk-iban-input__field:disabled{background-color:var(--mk-surface-2);color:var(--mk-text-disabled);border-color:var(--mk-border-subtle);cursor:not-allowed;opacity:.7}@media(prefers-reduced-motion:reduce){.mk-iban-input__field{transition:none}}@media(pointer:coarse){.mk-iban-input__field{font-size:max(var(--mk-font-size-md),16px)}:host(.mk-iban-input--sm) .mk-iban-input__field{font-size:max(var(--mk-font-size-sm),16px)}}\n"] }]
|
|
8430
8385
|
}], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
|
|
8431
8386
|
|
|
8432
|
-
/** NIP weights, applied to the first nine digits (PL). */
|
|
8433
|
-
const NIP_WEIGHTS = [6, 5, 7, 2, 3, 4, 5, 6, 7];
|
|
8434
8387
|
/**
|
|
8435
|
-
* Polish NIP checksum
|
|
8436
|
-
*
|
|
8437
|
-
* number is invalid whatever its last digit.
|
|
8388
|
+
* Polish NIP checksum — delegates to `isNip` from `@mk-kit/validators`
|
|
8389
|
+
* (weights 6-5-7-2-3-4-5-6-7 mod 11; a remainder of 10 is invalid).
|
|
8438
8390
|
*/
|
|
8439
8391
|
function mkNipChecksum(compact) {
|
|
8440
|
-
|
|
8441
|
-
return false;
|
|
8442
|
-
let sum = 0;
|
|
8443
|
-
for (let i = 0; i < 9; i++)
|
|
8444
|
-
sum += NIP_WEIGHTS[i] * Number(compact[i]);
|
|
8445
|
-
const check = sum % 11;
|
|
8446
|
-
return check < 10 && check === Number(compact[9]);
|
|
8392
|
+
return /^\d{10}$/.test(compact) && isNip(compact);
|
|
8447
8393
|
}
|
|
8448
8394
|
/**
|
|
8449
8395
|
* The built-in tax-identifier formats (alphabetical by ISO code). Only Poland
|