# @mk-kit/ui 0.60.2 — full API reference Generated from the library sources. Browsable version: https://mk-kit.dev/api · JSON: https://mk-kit.dev/api.json · Guides: https://mk-kit.dev/llms.txt ## Usage ```bash ng add @mk-kit/ui ``` Every component and directive below is standalone — import the class from its entry point and list it in `imports`. Attribute selectors like `button[mkButton]` enhance native elements; element selectors render their own template. Inputs marked two-way are `model()` signals and accept `[(name)]`. Inputs are signal inputs: read them as `comp.name()` in TypeScript. ## @mk-kit/ui/core 87 exports. `import { … } from '@mk-kit/ui/core';` ### MkAnchoredPanel (directive) Selector: `[mkAnchoredPanel]` · exportAs: `mkAnchoredPanel` Docs: https://mk-kit.dev/core-services Import: `import { MkAnchoredPanel } from '@mk-kit/ui/core';` Anchored-overlay directive. Apply it to a floating panel element (a dropdown list, calendar, menu, …) that is rendered inside its component's own template — typically inside an `@if (open()) { … }` block. On init the directive **teleports the panel to `document.body` and into the browser top layer** via the native Popover API (`popover="manual"` + `showPopover()`), then positions it against the anchor with `position: fixed`. Because the element stays part of the component's Angular view, all bindings, `@for` content, events and projected content keep working after the move. The top layer is immune to ancestor `overflow`, `transform` and `z-index` stacking contexts, so the panel can never be clipped by a container or hidden behind sibling content. Where the Popover API is unavailable the panel still renders in a `document.body` portal with a `z-index` fallback. ```html ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `mkAnchoredPanelFor` | `HTMLElement \| ElementRef \| undefined` | `undefined` | The trigger element to position against. | | `anchorRect` | `{ x: number; y: number; } \| undefined` | `undefined` | Viewport-point anchor (e.g. a right-click position) — takes precedence. | | `placement` | `MkPlacement` | `'bottom-start'` | Preferred placement relative to the anchor. | | `gap` | `number` | `4` | Distance in px between the anchor and the panel. | | `matchWidth` | `boolean` | `false` | Set the panel's `min-width` to the anchor's width (dropdowns). | | `flip` | `boolean` | `true` | Flip to the opposite side when the preferred side would overflow. | | `clamp` | `boolean` | `true` | Clamp the panel inside the viewport. | | `keepOpenWhen` | `((target: Node) => boolean) \| null` | `null` | Predicate consulted before an outside pointerdown dismisses the panel. Return `true` for targets that must keep it open — e.g. a nested panel (a submenu) that lives in the top layer outside this element. | Outputs: | Name | Type | Description | | --- | --- | --- | | `dismiss` | `void` | Emitted on an outside pointerdown or when the window loses focus. | Methods: | Signature | Description | | --- | --- | | `position(track?: boolean): void` | Recompute and apply the panel position. Safe to call at any time. With `track` (scroll-driven), the panel follows the anchor unclamped and dismisses once the anchor leaves the viewport (matching the CDK's reposition-with-auto-close scroll behaviour). | ### MkAccentService (service) Import: `import { MkAccentService } from '@mk-kit/ui/core';` Runtime accent — the user picks one of `MK_ACCENTS` and every kit control recolours: the service writes the `--mk-primary` family (`primary`, `-hover`, `-active`, `-subtle`, `-subtle-hover`, `-subtle-text`), `--mk-focus-ring`, `--mk-selected-bg` / `-text` and three accent tokens of its own — `--mk-accent`, `--mk-accent-ink`, `--mk-accent-glow` — onto ``, and mirrors the key as `data-mk-accent`. Hover / active are a touch darker in light and a touch lighter in dark (it follows `MkThemeService`). The choice persists in `localStorage` (`mk-kit-accent`); nothing is written until `set()` is called, so an app that never picks keeps the preset's own primary. ```ts readonly accent = inject(MkAccentService); accent.set('coral'); // every button, ring and chip turns coral accent.key(); // 'coral' mkAccentSwatch(accent.key()); // for the picker ``` Methods: | Signature | Description | | --- | --- | | `set(key: MkAccentKey): void` | Pick an accent; persisted. | | `reset(): void` | Back to the preset's own primary; the stored choice is cleared. | Properties: | Name | Type | Description | | --- | --- | --- | | `key` | `Signal` | The chosen accent, or `null` while the preset's own primary is in use. | | `accent` | `Signal` | The chosen accent's definition (indigo when none is chosen). | ### MkBreakpointService (service) Docs: https://mk-kit.dev/core-services Import: `import { MkBreakpointService } from '@mk-kit/ui/core';` Reactive viewport breakpoints, one `matchMedia` listener per step. ```ts private readonly bp = inject(MkBreakpointService); readonly compact = this.bp.down('md'); // Signal readonly columns = computed(() => this.bp.resolve({ xs: 1, md: 2, xl: 4 })); ``` On the server (no `window`) everything reports `xs`. Methods: | Signature | Description | | --- | --- | | `up(bp: MkBreakpoint): Signal` | True while the viewport is at least `bp` wide (`up('md')` = md, lg, xl, 2xl). | | `down(bp: MkBreakpoint): Signal` | True while the viewport is narrower than `bp` (`down('md')` = xs, sm). | | `between(from: MkBreakpoint, to: MkBreakpoint): Signal` | True while the viewport is at least `from` and narrower than `to`. | | `observe(query: string): Signal` | Any media query as a signal, e.g. `observe('(orientation: portrait)')`. | | `resolve(value: MkResponsive): T \| undefined` | Pick the entry of a responsive value for the current viewport — mobile-first, so `{ xs: 1, md: 2 }` gives 1 on `sm` and 2 on `xl`. A plain value is returned as is. Read inside a `computed` to track it. | Properties: | Name | Type | Description | | --- | --- | --- | | `breakpoints` | `MkBreakpoints` | The breakpoint scale in effect (see `MK_BREAKPOINTS`). | | `current` | `Signal` | The widest breakpoint the viewport currently satisfies. | ### MkLiveAnnouncer (service) Docs: https://mk-kit.dev/core-services Import: `import { MkLiveAnnouncer } from '@mk-kit/ui/core';` Announces messages to assistive technology via a visually-hidden `aria-live` region. Used by toasts, form validation, sort changes, etc. so state changes are perceivable without sight. WCAG 4.1.3 (Status Messages). Methods: | Signature | Description | | --- | --- | | `announce(message: string, politeness?: MkAriaLivePoliteness): void` | Announce `message`. `politeness` controls interruption behavior. | ### MkOverlayService (service) Docs: https://mk-kit.dev/core-services Import: `import { MkOverlayService } from '@mk-kit/ui/core';` Lightweight, dependency-free overlay renderer. Instantiates a standalone component into a body-level host, manages the backdrop, focus trapping, Escape handling, and scroll locking. Powers Dialog, Menu, and others. Methods: | Signature | Description | | --- | --- | | `closeAll(): void` | Close every open overlay, newest first. Each is closed with no result, so `afterClosed` resolves undefined exactly as a backdrop click or Escape would. Safe to call when nothing is open. | | `open(component: Type, config?: MkOverlayConfig): MkOverlayRef` | | Properties: | Name | Type | Description | | --- | --- | --- | | `openCount` | `number` | How many overlays are currently open. | ### MkThemeService (service) Docs: https://mk-kit.dev/core-services Import: `import { MkThemeService } from '@mk-kit/ui/core';` Reactive theme controller for mk-kit. - `preference()` is the user's choice: `light`, `dark`, or `system`. - `resolvedTheme()` is the concrete theme currently applied. - Writes `data-mk-theme` on `` and persists the choice to `localStorage`. When set to `system`, it live-tracks the OS setting and removes the attribute so pure-CSS `prefers-color-scheme` takes over. Provided in root — inject it anywhere and bind to the signals. Methods: | Signature | Description | | --- | --- | | `setDensity(density: MkDensity): void` | Set the global density mode. | | `toggleDensity(): void` | Toggle between comfortable and compact — the two modes a density switch in a UI offers. `touch` is a deliberate choice for a specific screen, not something to land on by toggling, so from `touch` this returns to comfortable rather than cycling. | | `setContrast(contrast: MkContrastPreference): void` | Set the contrast preference explicitly. | | `toggleContrast(): void` | Toggle between normal and high contrast (resolving `system` first). | | `setTheme(preference: MkThemePreference): void` | Set the theme preference explicitly. | | `toggle(): void` | Toggle between light and dark (resolving `system` first). | Properties: | Name | Type | Description | | --- | --- | --- | | `preference` | `Signal` | The user's theme preference. | | `resolvedTheme` | `Signal` | The concrete theme in effect (`light` or `dark`). | | `isDark` | `Signal` | Convenience boolean for template bindings. | | `density` | `Signal` | The global density mode. `compact` tightens control heights and the core spacing steps via the `data-mk-density` attribute, `touch` enlarges them — every component follows automatically because they read the same tokens. This signal is the GLOBAL mode only. To make one screen or dialog touch- sized inside an otherwise comfortable app, put `data-mk-density="touch"` on that element instead; the tokens inherit and this service stays out of it. | | `contrast` | `Signal` | The user's contrast preference: `normal`, `high` or `system` (follow the OS `prefers-contrast` setting — the default). Written as `data-mk-contrast` on `` and persisted; `system` removes the attribute so the pure-CSS `prefers-contrast: more` mapping takes over. Like density, the attribute also works per subtree: put `data-mk-contrast="high"` on any element to raise contrast there only. | | `resolvedContrast` | `Signal` | The concrete contrast in effect (`normal` or `high`). | | `isHighContrast` | `Signal` | Convenience boolean for template bindings. | ### MkFieldContext (class) Import: `import { MkFieldContext } from '@mk-kit/ui/core';` Field context — the contract a field wrapper (`mk-form-field`) exposes to the control nested inside it. Controls inject it optionally (`inject(MkFieldContext, { optional: true })`) to adopt the wrapper's control id and to reflect its required/error state and `aria-describedby` wiring — without depending on the `@mk-kit/ui/forms` entry point. `MkFormField` provides itself under this token; standalone usage (no wrapper) simply yields `null`. Properties: | Name | Type | Description | | --- | --- | --- | | `controlId` | `string` | Id for the nested interactive control — adopt on your control element. | | `labelId` | `string` | Id of the field's label element, for `aria-labelledby`. | | `size` | `Signal` | The field's visual size, mirrored onto the nested control. | | `isRequired` | `Signal` | Whether the field is required (explicitly or via the bound control). | | `hasError` | `Signal` | Whether the field currently shows an error. | | `describedBy` | `Signal` | Space-separated id list for the nested control's `aria-describedby`, or `null` when there is nothing to describe. | ### MkFocusTrap (class) Docs: https://mk-kit.dev/core-services Import: `import { MkFocusTrap } from '@mk-kit/ui/core';` Traps keyboard focus within `root` (wrapping Tab / Shift+Tab), moves focus inside on activation, and restores focus to the previously-focused element on release. Essential for accessible modals/menus (WCAG 2.4.3, 2.1.2). Methods: | Signature | Description | | --- | --- | | `activate(initialFocus?: HTMLElement): void` | Activate the trap and move focus to the first focusable element (or root). | | `release(): void` | Deactivate and restore focus to the trigger element. | ### MkOverlayRef (class) Import: `import { MkOverlayRef } from '@mk-kit/ui/core';` Handle to an open overlay. Injected into the rendered component and returned from `MkOverlayService.open`. Resolve the overlay by calling `close`. The close result is exposed three ways so the handle fits whatever style the calling code already uses — they all settle together: - `result` — a signal, for template binding and signal-based components. - `closed$` — an Observable that emits once and completes, for RxJS pipelines. A service that hands a dialog result back to its callers can return this directly instead of wrapping the promise in `from(...)`. - `afterClosed` — a Promise, for `await` / `.then()`. Methods: | Signature | Description | | --- | --- | | `close(result?: TResult): void` | Close the overlay, optionally returning a result. | Properties: | Name | Type | Description | | --- | --- | --- | | `componentRef` | `ComponentRef \| undefined` | The rendered component instance (set by the service after creation). | | `closed` | `Signal` | Becomes `true` once the overlay has been dismissed. | | `result` | `Signal` | The value passed to `close`, or `undefined` while open and for a dismissal (Escape / backdrop). Read `closed()` to tell "closed with no result" apart from "still open". | | `afterClosed` | `Promise` | Resolves with the close result when the overlay is dismissed. | | `closed$` | `Observable` | Emits the close result once, then completes. Subscribing after the overlay has already closed replays the result immediately, so a late subscriber never hangs. | ### mkAccentSwatch (function) Import: `import { mkAccentSwatch } from '@mk-kit/ui/core';` The swatch a picker shows for an accent (bumblebee is the black / yellow split). ```ts function mkAccentSwatch(key: MkAccentKey): string ``` ### mkBodyLevelAncestor (function) Import: `import { mkBodyLevelAncestor } from '@mk-kit/ui/core';` The direct child of `document.body` an overlay-root descendant lives under, crossing shadow boundaries on the way up — `null` when the node is not under `body` at all. The overlay service uses it to keep the overlay's own host out of the elements it makes `inert` behind a modal. ```ts function mkBodyLevelAncestor(node: Node, body: HTMLElement): Element | null ``` ### mkComputeAnchoredPosition (function) Import: `import { mkComputeAnchoredPosition } from '@mk-kit/ui/core';` Pure viewport-positioning maths shared by every anchored overlay (`MkAnchoredPanel` and the tooltip). Given the anchor rect, the panel size and the viewport size, returns the top/left for a `position: fixed` panel — flipping to the opposite side when it would overflow and clamping back inside the viewport. ```ts function mkComputeAnchoredPosition(anchor: MkRectLike, panel: MkDimensions, viewport: MkDimensions, opts: MkAnchoredPositionOptions): MkAnchoredPosition ``` ### mkCreateQueryGroup (function) Import: `import { mkCreateQueryGroup } from '@mk-kit/ui/core';` A fresh empty group. ```ts function mkCreateQueryGroup(init?: Partial>): MkQueryGroup ``` ### mkCreateQueryRule (function) Import: `import { mkCreateQueryRule } from '@mk-kit/ui/core';` A fresh rule on `field`, using its first operator. ```ts function mkCreateQueryRule(field: MkQueryField): MkQueryRule ``` ### mkFirstErrorMessage (function) Import: `import { mkFirstErrorMessage } from '@mk-kit/ui/core';` Resolves the message for the first error on a control, mirroring how `mat-error` shows one message at a time. Lookup order per key: the field's `overrides`, then the i18n `validation` table, then the error payload's own `message` string (so a custom validator can carry its text), then the generic fallback. Keys are visited in the order the validators put them on the control, so composing `[Validators.required, Validators.email]` surfaces "required" while empty. ```ts function mkFirstErrorMessage(errors: ValidationErrors | null | undefined, strings: MkValidationStrings, overrides?: MkErrorMessages): string | null ``` ### mkGetFocusable (function) Import: `import { mkGetFocusable } from '@mk-kit/ui/core';` Returns the tabbable elements inside `root`, in DOM order. ```ts function mkGetFocusable(root: HTMLElement): HTMLElement[] ``` ### mkHexAlpha (function) Import: `import { mkHexAlpha } from '@mk-kit/ui/core';` `#rrggbb` → `rgba(r,g,b,a)`. ```ts function mkHexAlpha(hex: string, alpha: number): string ``` ### mkHighlight (function) Import: `import { mkHighlight } from '@mk-kit/ui/core';` Highlight `src` for `language`, falling back to escaped plain text. ```ts function mkHighlight(src: string, language: string): string ``` ### mkHighlightJson (function) Import: `import { mkHighlightJson } from '@mk-kit/ui/core';` Highlight a JSON document. Recognises object keys, strings, numbers, the `true`/`false`/`null` literals and structural punctuation. Invalid JSON is still highlighted token-by-token (the editor validates separately). ```ts function mkHighlightJson(src: string): string ``` ### mkIsQueryGroup (function) Import: `import { mkIsQueryGroup } from '@mk-kit/ui/core';` True for a group node (as opposed to a rule). ```ts function mkIsQueryGroup(node: MkQueryNode): node is MkQueryGroup ``` ### mkIsResponsive (function) Import: `import { mkIsResponsive } from '@mk-kit/ui/core';` True when `value` is a per-breakpoint map rather than a plain value. ```ts function mkIsResponsive(value: MkResponsive): value is Partial> ``` ### mkMergeI18n (function) Import: `import { mkMergeI18n } from '@mk-kit/ui/core';` Merges `overrides` over a complete string map — shallow for the top level, deep for the `dateNames`, `blockEditor` and `validation` groups. Exported so locale packs and tests can build a map without providing it. ```ts function mkMergeI18n(base: MkI18nStrings, overrides: MkI18nOverrides): MkI18nStrings ``` ### mkQueryCompact (function) Import: `import { mkQueryCompact } from '@mk-kit/ui/core';` Drop empty groups and rules that still need a value, so the API gets only complete conditions. ```ts function mkQueryCompact(group: MkQueryGroup): MkQueryGroup ``` ### mkQueryIsEmpty (function) Import: `import { mkQueryIsEmpty } from '@mk-kit/ui/core';` True when the tree holds no rule at all (empty groups only). ```ts function mkQueryIsEmpty(group: MkQueryGroup): boolean ``` ### mkQueryOperatorLabel (function) Import: `import { mkQueryOperatorLabel } from '@mk-kit/ui/core';` Localised label of an operator. ```ts function mkQueryOperatorLabel(op: MkQueryOperator, i18n?: MkQueryTextStrings): string ``` ### mkQueryOperatorsFor (function) Import: `import { mkQueryOperatorsFor } from '@mk-kit/ui/core';` Operators a field offers (its own list, else the defaults for its type). ```ts function mkQueryOperatorsFor(field: MkQueryField | undefined): readonly MkQueryOperator[] ``` ### mkQueryRuleCount (function) Import: `import { mkQueryRuleCount } from '@mk-kit/ui/core';` Number of rules in the tree. ```ts function mkQueryRuleCount(group: MkQueryGroup): number ``` ### mkQueryRuleIsComplete (function) Import: `import { mkQueryRuleIsComplete } from '@mk-kit/ui/core';` A rule is complete when its operator needs no value or has one. ```ts function mkQueryRuleIsComplete(rule: MkQueryRule): boolean ``` ### mkQueryRuleMatches (function) Import: `import { mkQueryRuleMatches } from '@mk-kit/ui/core';` Evaluate one rule against a row. ```ts function mkQueryRuleMatches(rule: MkQueryRule, row: Record, field?: MkQueryField): boolean ``` ### mkQueryToPredicate (function) Import: `import { mkQueryToPredicate } from '@mk-kit/ui/core';` Compile a query into a row predicate for client-side filtering (`rows.filter(mkQueryToPredicate(query, fields))`). Unfinished rules are ignored, so a half-edited query never blanks the table. ```ts function mkQueryToPredicate>(group: MkQueryGroup, fields?: readonly MkQueryField[]): (row: T) => boolean ``` ### mkQueryToText (function) Import: `import { mkQueryToText } from '@mk-kit/ui/core';` Human-readable sentence for a query, e.g. `(Name contains "ada" and Orders at least 10) or Status is any of Active, Invited`. ```ts function mkQueryToText(group: MkQueryGroup, fields?: readonly MkQueryField[], i18n?: MkQueryTextStrings): string ``` ### mkSignalErrorMessage (function) Import: `import { mkSignalErrorMessage } from '@mk-kit/ui/core';` Resolves the message for the first Signal Forms error on a field, the way `mkFirstErrorMessage` does for reactive forms. Lookup order: the field's `overrides` for that kind, then the `message` the schema attached to the error (`required(p.email, { message: '…' })`), then the i18n `validation` table, then the generic fallback. ```ts function mkSignalErrorMessage(errors: readonly MkSignalValidationError[] | null | undefined, strings: MkValidationStrings, overrides?: MkErrorMessages): string | null ``` ### mkSignalErrorsToValidationErrors (function) Import: `import { mkSignalErrorsToValidationErrors } from '@mk-kit/ui/core';` Converts Signal Forms errors to the reactive-forms `ValidationErrors` shape the `validation` i18n table is keyed by, so both form systems render the same messages. The built-in kinds map to Angular's classic keys and payloads (`minLength` → `minlength: { requiredLength }`, `minDate` → `mkMinDate`, …); any other kind is kept as-is with its payload spread into the value. ```ts function mkSignalErrorsToValidationErrors(errors: readonly MkSignalValidationError[] | null | undefined): ValidationErrors | null ``` ### mkUniqueId (function) Import: `import { mkUniqueId } from '@mk-kit/ui/core';` Generates a stable, unique DOM id for wiring `aria-*` relationships (labels, descriptions, controls). Prefer this over `Math.random()` so ids are deterministic within a render and SSR-safe. ```ts function mkUniqueId(prefix?: string): string ``` ### mkValidatorChange (function) Import: `import { mkValidatorChange } from '@mk-kit/ui/core';` Re-validates the bound form control whenever a validator's inputs change. A `Validator` whose constraints come from component inputs (`[min]`, `[max]`, `[required]`, …) must tell Angular when those inputs change, otherwise the control keeps the verdict computed under the old constraints. `NgModel`/`FormControlName` pass a callback to `registerOnValidatorChange` for exactly this; call it from an effect over the constraint signals. Must be called from an injection context (i.e. as a field initialiser). ```ts private readonly validatorChange = mkValidatorChange(() => { this.min(); this.max(); }); registerOnValidatorChange(fn: () => void): void { this.validatorChange.register(fn); } ``` ```ts function mkValidatorChange(deps: () => void): MkValidatorChangeRef ``` ### provideMkI18n (function) Docs: https://mk-kit.dev/core-services Import: `import { provideMkI18n } from '@mk-kit/ui/core';` Provide localised strings — pass any subset, merged over `base` (the English defaults unless given). The nested `dateNames`, `blockEditor` and `validation` groups are merged deeply, so partial overrides of those work too. ```ts bootstrapApplication(App, { providers: [provideMkI18n({ noResults: 'Brak wyników', close: 'Zamknij' })], }); ``` A locale pack is a complete map that serves as the base — either through its own helper (`provideMkI18nPl(overrides)` from `@mk-kit/ui/locales/pl`) or explicitly: `provideMkI18n(overrides, MK_PL_I18N)`. ```ts function provideMkI18n(overrides: MkI18nOverrides, base?: MkI18nStrings): Provider ``` ### MK_BREAKPOINTS (token) Import: `import { MK_BREAKPOINTS } from '@mk-kit/ui/core';` Override the breakpoint scale app-wide: `{ provide: MK_BREAKPOINTS, useValue: { …, lg: 1100 } }`. ```ts const MK_BREAKPOINTS: InjectionToken; ``` ### MK_I18N (token) Import: `import { MK_I18N } from '@mk-kit/ui/core';` The active string map. Defaults to `MK_DEFAULT_I18N`; override with `provideMkI18n`. Inject it (`inject(MK_I18N)`) wherever a built-in string is rendered. ```ts const MK_I18N: InjectionToken; ``` ### MK_OVERLAY_DATA (token) Import: `import { MK_OVERLAY_DATA } from '@mk-kit/ui/core';` Injection token exposing the data passed to an overlay component. ```ts const MK_OVERLAY_DATA: InjectionToken; ``` ### MK_OVERLAY_ROOT (token) Import: `import { MK_OVERLAY_ROOT } from '@mk-kit/ui/core';` Where mk-kit mounts everything that leaves the component tree: overlay containers (dialogs), anchored panels (selects, menus, tooltips), toast / snackbar containers and the tour surfaces. Defaults to `document.body`. Override it to confine those surfaces to another element — `@mk-kit/ui/embed` points it at a themed shadow-DOM host so overlays opened by embedded custom elements stay isolated from the host page's stylesheet: ```ts { provide: MK_OVERLAY_ROOT, useValue: () => myOverlayHost } ``` ```ts const MK_OVERLAY_ROOT: InjectionToken; ``` ### MK_ACCENT_ORDER (const) Import: `import { MK_ACCENT_ORDER } from '@mk-kit/ui/core';` Picker order. ```ts const MK_ACCENT_ORDER: readonly MkAccentKey[]; ``` ### MK_ACCENTS (const) Import: `import { MK_ACCENTS } from '@mk-kit/ui/core';` High-saturation, distinct, energising accents — the set the `momentum` preset was designed around. ```ts const MK_ACCENTS: Record; ``` ### MK_DEFAULT_BREAKPOINTS (const) Import: `import { MK_DEFAULT_BREAKPOINTS } from '@mk-kit/ui/core';` The default scale (same numbers as Tailwind, so mental models transfer). ```ts const MK_DEFAULT_BREAKPOINTS: MkBreakpoints; ``` ### MK_DEFAULT_DATE_NAMES (const) Import: `import { MK_DEFAULT_DATE_NAMES } from '@mk-kit/ui/core';` The built-in English date names. ```ts const MK_DEFAULT_DATE_NAMES: MkDateNames; ``` ### MK_DEFAULT_I18N (const) Import: `import { MK_DEFAULT_I18N } from '@mk-kit/ui/core';` The built-in English strings. ```ts const MK_DEFAULT_I18N: MkI18nStrings; ``` ### MK_DEFAULT_VALIDATION (const) Import: `import { MK_DEFAULT_VALIDATION } from '@mk-kit/ui/core';` The built-in English validation messages. ```ts const MK_DEFAULT_VALIDATION: MkValidationStrings; ``` ### MK_QUERY_OPERATORS (const) Import: `import { MK_QUERY_OPERATORS } from '@mk-kit/ui/core';` Operators offered per field type, in menu order. ```ts const MK_QUERY_OPERATORS: Readonly>; ``` ### MK_QUERY_TEXT_EN (const) Import: `import { MK_QUERY_TEXT_EN } from '@mk-kit/ui/core';` English defaults for `MkQueryTextStrings`. ```ts const MK_QUERY_TEXT_EN: MkQueryTextStrings; ``` ### MK_QUERY_UNARY (const) Import: `import { MK_QUERY_UNARY } from '@mk-kit/ui/core';` Operators that take no value. ```ts const MK_QUERY_UNARY: ReadonlySet; ``` ### MkAccent (interface) Import: `import { MkAccent } from '@mk-kit/ui/core';` `fill` = bars, rings and buttons · `ink` = small accent text on a light ground. Members: | Name | Type | Description | | --- | --- | --- | | `fill` | `string` | | | `ink` | `string` | | | `name` | `string` | | ### MkAnchoredPosition (interface) Import: `import { MkAnchoredPosition } from '@mk-kit/ui/core';` Resolved coordinates (viewport-relative, for `position: fixed`). Members: | Name | Type | Description | | --- | --- | --- | | `top` | `number` | | | `left` | `number` | | | `placement` | `MkPlacement` | The placement actually used after any flip. | ### MkAnchoredPositionOptions (interface) Import: `import { MkAnchoredPositionOptions } from '@mk-kit/ui/core';` Options controlling `mkComputeAnchoredPosition`. Members: | Name | Type | Description | | --- | --- | --- | | `placement` | `MkPlacement` | | | `gap` | `number` | | | `flip` | `boolean` | | | `clamp` | `boolean` | | | `rtl`? | `boolean \| undefined` | Resolve `-start`/`-end` alignment against a right-to-left anchor. | ### MkBlockEditorStrings (interface) Import: `import { MkBlockEditorStrings } from '@mk-kit/ui/core';` Strings used by the block editor's chrome. Members: | Name | Type | Description | | --- | --- | --- | | `addBlock` | `string` | | | `addFirstBlock` | `string` | | | `insertBlockHere` | `string` | | | `blockInserter` | `string` | | | `searchBlocks` | `string` | | | `blocks` | `string` | | | `moveBlockUp` | `string` | | | `moveBlockDown` | `string` | | | `blockOptions` | `string` | | | `duplicate` | `string` | | | `remove` | `string` | | | `textFormatting` | `string` | | | `altText` | `string` | | | `caption` | `string` | | | `alignment` | `string` | | | `replaceImage` | `string` | | | `imageUrl` | `string` | | | `externalContent` | `string` | | | `embedUrl` | `string` | | | `columnSettings` | `string` | | | `columns` | `string` | | | `ratio` | `string` | | | `gap` | `string` | | | `align` | `string` | | | `justify` | `string` | | | `headingLevel` | `(level: number) => string` | | | `editorLabel` | `string` | Editor region label + empty-block placeholder defaults. | | `emptyBlockPlaceholder` | `string` | | | `dragHandle` | `string` | Drag handle tooltip. | | `turnInto` | `(label: string) => string` | "Turn into …" transform menu item; receives the target block's label. | | `unknownBlock` | `(type: string) => string` | Shown for a block whose type has no registered definition. | | `blockAdded` | `(label: string) => string` | Structural-change screen-reader announcements. | | `blockDuplicated` | `string` | | | `blockDeleted` | `(label: string) => string` | | | `blockMovedUp` | `string` | | | `blockMovedDown` | `string` | | | `turnedInto` | `(label: string) => string` | | | `noBlocksMatch` | `(query: string) => string` | Inserter empty state; receives the search query. | | `groupText` | `string` | Built-in palette group headings. | | `groupMedia` | `string` | | | `groupLayout` | `string` | | | `blockParagraph` | `string` | Built-in block labels + inserter descriptions. | | `blockParagraphDesc` | `string` | | | `blockHeading` | `string` | | | `blockHeadingDesc` | `string` | | | `blockList` | `string` | | | `blockListDesc` | `string` | | | `blockQuote` | `string` | | | `blockQuoteDesc` | `string` | | | `blockCode` | `string` | | | `blockCodeDesc` | `string` | | | `blockImage` | `string` | | | `blockImageDesc` | `string` | | | `blockEmbed` | `string` | | | `blockEmbedDesc` | `string` | | | `blockButton` | `string` | | | `blockButtonDesc` | `string` | | | `blockDivider` | `string` | | | `blockDividerDesc` | `string` | | | `blockColumns` | `string` | | | `blockColumnsDesc` | `string` | | | `bold` | `string` | Rich-text inline toolbar. | | `italic` | `string` | | | `underline` | `string` | | | `strikethrough` | `string` | | | `inlineCode` | `string` | | | `link` | `string` | | | `clearFormatting` | `string` | | | `linkUrlPrompt` | `string` | Prompt asking for a link URL. | | `editableText` | `string` | Default label of the editable rich-text region. | | `headingPlaceholder` | `(level: number) => string` | Heading block. | | `headingLevelGroup` | `string` | | | `listStyle` | `string` | List block. | | `bulleted` | `string` | | | `numbered` | `string` | | | `listItem` | `string` | | | `quoteText` | `string` | Quote block. | | `citation` | `string` | | | `addCitation` | `string` | | | `codeLanguage` | `string` | Code block. | | `codeLanguagePlaceholder` | `string` | | | `enterCode` | `string` | | | `imageWidth` | `(percent: number) => string` | Image block. | | `uploading` | `string` | | | `dropImagePrompt` | `string` | | | `chooseFile` | `string` | | | `pasteImageUrl` | `string` | | | `notAnImage` | `string` | | | `uploadFailed` | `string` | | | `imageAdded` | `string` | | | `pasteEmbedUrl` | `string` | Embed block. | | `embedFallbackNote` | `string` | | | `embedTitle` | `(provider: string) => string` | | | `embedAdded` | `(provider: string) => string` | | | `embeddedContent` | `string` | | | `buttonLabel` | `string` | Button block settings. | | `buttonLink` | `string` | | | `buttonTone` | `string` | | | `buttonVariant` | `string` | | | `buttonDefaultLabel` | `string` | Label a freshly inserted Button block starts with. | | `alignLeft` | `string` | Alignment option captions (image + button blocks). | | `alignCenter` | `string` | | | `alignRight` | `string` | | | `tonePrimary` | `string` | Tone option captions (button block swatches). | | `toneNeutral` | `string` | | | `toneSuccess` | `string` | | | `toneWarning` | `string` | | | `toneDanger` | `string` | | | `toneInfo` | `string` | | | `variantSolid` | `string` | Variant option captions (button block). | | `variantSoft` | `string` | | | `variantOutline` | `string` | | | `ratioEqual` | `string` | Columns settings option captions. | | `alignStretch` | `string` | | | `alignTop` | `string` | | | `alignMiddle` | `string` | | | `alignBottom` | `string` | | | `justifyStart` | `string` | | | `justifyCenter` | `string` | | | `justifyEnd` | `string` | | | `justifyBetween` | `string` | | ### MkDateNames (interface) Import: `import { MkDateNames } from '@mk-kit/ui/core';` Localised month and weekday name tables (the shape `MK_I18N` carries). Members: | Name | Type | Description | | --- | --- | --- | | `months` | `readonly string[]` | Full month names, January-first (12). | | `monthsShort` | `readonly string[]` | Abbreviated month names (12). | | `weekdays` | `readonly string[]` | Full weekday names, Sunday-first (7). | | `weekdaysShort` | `readonly string[]` | Abbreviated weekday names (7). | | `weekdaysNarrow` | `readonly string[]` | One/two-letter weekday names for calendar headers (7). | ### MkI18nStrings (interface) Import: `import { MkI18nStrings } from '@mk-kit/ui/core';` All user-facing strings the library renders itself (aria-labels, empty-state text, control captions and screen-reader announcements). Consumers localise the library by overriding any subset via `provideMkI18n`. Interpolated strings are functions so translators control word order. Members: | Name | Type | Description | | --- | --- | --- | | `locale`? | `string \| undefined` | BCP 47 locale tag (`'pl-PL'`, `'de'`) used by the formatting pipes (`mkCurrency`, `mkRelativeTime`, `mkFileSize`, `mkPluralize`) and any other `Intl`-based formatting that has no explicit locale of its own. Unset → the runtime (browser / Node) default locale. | | `currency`? | `string \| undefined` | ISO 4217 currency code the `mkCurrency` pipe falls back to when the template passes none. Unset → `'USD'`. | | `validation` | `MkValidationStrings` | Validation messages (deep-merged by provideMkI18n). | | `close` | `string` | Generic "Close" control (dialog, drawer, bottom-sheet). | | `dismiss` | `string` | Generic "Dismiss" control (alert, banner, toast, snackbar). | | `clear` | `string` | Clear-input control (autocomplete, pickers, tag inputs). | | `confirm` | `string` | Generic confirm action (confirm dialog, popconfirm). | | `cancel` | `string` | Generic cancel action (dialogs, inline edit). | | `ok` | `string` | Generic acknowledge action (alert/prompt dialogs). | | `save` | `string` | Generic save action (inline edit). | | `submit` | `string` | Default action-button caption (submit input). | | `edit` | `string` | Generic edit affordance (inline edit trigger). | | `remove` | `string` | Generic remove control (chip). | | `removeItem` | `(name: string) => string` | Remove a named item (tag input chips, file upload rows). | | `empty` | `string` | Placeholder shown for an empty editable value (inline edit, mini date). | | `optional` | `string` | "Optional" marker (stepper). | | `filter` | `string` | Filter/search field placeholder (transfer list). | | `confirmMessage` | `string` | Default confirmation question (popconfirm). | | `decrease` | `string` | Decrease control (number input). | | `increase` | `string` | Increase control (number input). | | `loading` | `string` | Async loading row (autocomplete, multi-select). | | `noOptions` | `string` | Empty listbox with no options (select, time picker). | | `noResults` | `string` | Empty async/filtered results (autocomplete, multi-select, command palette). | | `noData` | `string` | Empty data table / list. | | `translationEditorSearch` | `string` | Translation editor (`@mk-kit/ui/translate/editor`). | | `translationEditorAll` | `string` | | | `translationEditorOverridden` | `string` | | | `translationEditorMissing` | `string` | | | `translationEditorKey` | `string` | | | `translationEditorReset` | `string` | | | `translationEditorExport` | `string` | | | `translationEditorKeys` | `string` | | | `sessionExpiryTitle` | `string` | Session-expiry dialog (`@mk-kit/ui/attention`). | | `sessionExpiryExtend` | `string` | | | `sessionExpiryExtending` | `string` | | | `sessionExpiryLogout` | `string` | | | `sessionExpiryBody` | `(countdown: string) => string` | | | `scannerTitle` | `string` | Barcode scanner (`@mk-kit/ui/media/scanner`). | | `scannerHint` | `string` | | | `scannerCameraError` | `string` | | | `resultsCount` | `(count: number) => string` | Announced when a filterable list updates (autocomplete, multi-select, command palette). | | `previousPage` | `string` | Pagination: previous page control. | | `nextPage` | `string` | Pagination: next page control. | | `goToPage` | `(page: number) => string` | Pagination: jump to a page. | | `paginationLabel` | `string` | Pagination landmark label. | | `previousSlide` | `string` | Carousel: previous slide control. | | `nextSlide` | `string` | Carousel: next slide control. | | `goToSlide` | `(slide: number) => string` | Carousel: jump to a slide. | | `carouselLabel` | `string` | Carousel region label. | | `pauseSlideshow` | `string` | Carousel: pause / resume automatic rotation. | | `playSlideshow` | `string` | | | `slideOf` | `(slide: number, total: number) => string` | Carousel: slide position (slide labels + live announcements). | | `dateNames` | `MkDateNames` | Localised month/weekday name tables (deep-merged by provideMkI18n). | | `previousMonth` | `string` | Calendar: previous month control. | | `nextMonth` | `string` | Calendar: next month control. | | `previousYear` | `string` | Month picker: previous/next year (month mode). | | `nextYear` | `string` | | | `previousYears` | `string` | Month picker: previous/next decade page (year mode). | | `nextYears` | `string` | | | `selectDate` | `string` | Field placeholders. | | `selectRange` | `string` | | | `selectTime` | `string` | | | `selectMonth` | `string` | | | `selectYear` | `string` | | | `selectWeek` | `string` | | | `selectPlaceholder` | `string` | | | `chooseDate` | `string` | Popover dialog labels. | | `chooseDateRange` | `string` | | | `chooseMonth` | `string` | | | `chooseYear` | `string` | | | `chooseWeek` | `string` | | | `openCalendar` | `string` | | | `openTimeList` | `string` | | | `moreActions` | `string` | Accessible name of the chevron segment of `mk-split-button`. | | `selectDateTime` | `string` | Placeholder of `mk-datetime-picker`. | | `chooseDateTime` | `string` | Dialog label of the `mk-datetime-picker` panel. | | `chooseTime` | `string` | Listbox label of the time list inside `mk-datetime-picker`. | | `openDateTimePicker` | `string` | Toggle-button label of `mk-datetime-picker`. | | `daySegment` | `string` | Mini-date segment names. | | `monthSegment` | `string` | | | `yearSegment` | `string` | | | `countdownDays` | `string` | Countdown unit captions. | | `countdownHours` | `string` | | | `countdownMinutes` | `string` | | | `countdownSeconds` | `string` | | | `countdownFinished` | `string` | Announced when a countdown reaches zero. | | `dayEvents` | `(count: number, titles: string) => string` | Event-calendar day label suffix, e.g. `2 events: Standup, Demo`. | | `moreEvents` | `(count: number) => string` | Event-calendar overflow pill for events beyond `maxPerDay`, e.g. `+2 more`. | | `selectAllRows` | `string` | Select-all header checkbox. | | `selectRow` | `(row: string) => string` | Per-row checkbox; receives the row's leading cell text. | | `expandHeader` | `string` | Hidden expander column header. | | `expandRow` | `string` | Row expander toggle labels. | | `collapseRow` | `string` | | | `expandTreeRow` | `string` | Tree-row toggle labels (`childrenKey`). | | `collapseTreeRow` | `string` | | | `expandGroup` | `string` | aria-label of a group header's toggle when the group is collapsed. | | `collapseGroup` | `string` | aria-label of a group header's toggle when the group is expanded. | | `groupCount` | `(count: number) => string` | Row count shown on a group header, e.g. "4 items". | | `resizeColumn` | `string` | Column resize separator label. | | `columnWidth` | `(column: string, width: number) => string` | Announced while a column is resized by keyboard. | | `columnMoved` | `(column: string, position: number, total: number) => string` | Announced when a column is reordered. | | `editCell` | `string` | Hint suffix + announcement for editable cells. | | `cellSaved` | `(value: string) => string` | | | `sortedBy` | `(column: string, direction: MkSortAnnounceDirection) => string` | Announced when a column is sorted. | | `sortingCleared` | `(column: string) => string` | Announced when sorting is removed from a column. | | `showPassword` | `string` | Password reveal toggle. | | `hidePassword` | `string` | | | `passwordRuleMinLength` | `(length: number) => string` | Password rule captions. | | `passwordRuleUppercase` | `string` | | | `passwordRuleNumber` | `string` | | | `passwordRuleSymbol` | `string` | | | `passwordStrength` | `(score: number) => string` | Password strength label for a 0–4 score. | | `passwordStrengthLabel` | `string` | Visible prefix before the strength label. | | `ruleMet` | `string` | Rule-state prefixes announced to screen readers. | | `ruleNotMet` | `string` | | | `oneTimeCode` | `string` | OTP field labels. | | `otpDigit` | `(position: number) => string` | | | `numericKeypadLabel` | `string` | Numeric keypad labels + masked-PIN progress announcement. | | `keypadClear` | `string` | | | `keypadBackspace` | `string` | | | `keypadDigitsEntered` | `(count: number, length: number) => string` | | | `onScreenKeyboardLabel` | `string` | On-screen keyboard label + action-key labels. | | `keyboardShift` | `string` | | | `keyboardSpace` | `string` | | | `keyboardEnter` | `string` | | | `keyboardAltLayer` | `string` | | | `keyboardBaseLayer` | `string` | | | `ratingLabel` | `string` | Rating slider label + value text. | | `ratingValueText` | `(value: number, max: number) => string` | | | `minimum` | `string` | Range slider thumb labels. | | `maximum` | `string` | | | `chooseColor` | `string` | Color picker labels. | | `hexValue` | `string` | | | `presetColors` | `string` | | | `chooseCountry` | `string` | Phone input: country-prefix trigger label. | | `searchCountries` | `string` | Phone input: search field placeholder inside the country list. | | `phoneNumber` | `string` | Phone input: default accessible label of the national-number field. | | `postalCode` | `string` | Postal-code input: default accessible label. | | `amount` | `string` | Currency input: default accessible label. | | `cardNumber` | `string` | Card-number input: default accessible label. | | `cardBrand` | `(brand: string) => string` | Card-number input: announced/badge text for a detected brand. | | `iban` | `string` | IBAN input: default accessible label. | | `taxId` | `string` | Tax-ID input: default accessible label. | | `signature` | `string` | Signature pad: default accessible label of the drawing surface. | | `jsonLabel` | `string` | JSON viewer: default accessible label of the tree. | | `logViewerLabel` | `string` | Log viewer: default accessible label of the log region. | | `logFollow` | `string` | Log viewer: re-attach-to-tail button. | | `logCopyAll` | `string` | Log viewer: copy-the-whole-buffer toolbar button. | | `logWrapLines` | `string` | Log viewer: soft-wrap toolbar toggle. | | `orgChartLabel` | `string` | Org chart: default accessible label of the tree. | | `orgChartExpand` | `string` | Org chart: aria-label of a collapsed node's toggle (`{label}` = node label). | | `orgChartCollapse` | `string` | Org chart: aria-label of an expanded node's toggle (`{label}` = node label). | | `chatLabel` | `string` | Chat: accessible name of the message log. | | `chatComposerLabel` | `string` | Chat: accessible name of the composer textarea. | | `chatPlaceholder` | `string` | Chat: composer placeholder. | | `chatSend` | `string` | Chat: send button. | | `chatStop` | `string` | Chat: stop-generating button (replaces send while busy). | | `chatAttach` | `string` | Chat: attach-files button. | | `chatRemoveAttachment` | `string` | Chat: remove one pending attachment. | | `chatAttachments` | `string` | Chat: group label of pending / shown attachments. | | `chatSuggestions` | `string` | Chat: group label of quick-reply suggestions. | | `chatCopy` | `string` | Chat: copy-message button. | | `chatRetry` | `string` | Chat: retry a failed message. | | `chatTyping` | `string` | Chat: typing indicator. | | `chatStreaming` | `string` | Chat: screen-reader text while a reply streams in. | | `chatJumpToLatest` | `string` | Chat: scroll-to-newest button. | | `chatEmpty` | `string` | Chat: empty-state text. | | `chatYou` | `string` | Chat: author fallback for the user's own messages. | | `chatAssistant` | `string` | Chat: author fallback for assistant messages. | | `chatToolRunning` | `string` | Chat: tool call in progress. | | `chatToolDone` | `string` | Chat: tool call finished. | | `chatToolError` | `string` | Chat: tool call failed. | | `dynamicFormAdd` | `string` | Dynamic form: add an item to an array field. | | `dynamicFormRemove` | `(index: number) => string` | Dynamic form: remove one item of an array field (index is 1-based). | | `queryBuilderLabel` | `string` | Query builder: accessible name of the whole builder. | | `queryAddRule` | `string` | | | `queryAddGroup` | `string` | | | `queryRemoveRule` | `string` | | | `queryRemoveGroup` | `string` | | | `queryAnd` | `string` | Combinator labels — also used by `mkQueryToText`. | | `queryOr` | `string` | | | `queryNot` | `string` | | | `queryField` | `string` | | | `queryOperator` | `string` | | | `queryValue` | `string` | | | `queryValueFrom` | `string` | | | `queryValueTo` | `string` | | | `queryEmptyGroup` | `string` | | | `queryTrue` | `string` | | | `queryFalse` | `string` | | | `queryOpEq` | `string` | | | `queryOpNeq` | `string` | | | `queryOpContains` | `string` | | | `queryOpNotContains` | `string` | | | `queryOpStartsWith` | `string` | | | `queryOpEndsWith` | `string` | | | `queryOpGt` | `string` | | | `queryOpGte` | `string` | | | `queryOpLt` | `string` | | | `queryOpLte` | `string` | | | `queryOpBetween` | `string` | | | `queryOpIn` | `string` | | | `queryOpNotIn` | `string` | | | `queryOpBefore` | `string` | | | `queryOpAfter` | `string` | | | `queryOpEmpty` | `string` | | | `queryOpNotEmpty` | `string` | | | `dialogMove` | `string` | Dialog: label of the move grip (arrow keys move, Home resets). | | `dialogResize` | `string` | Dialog: label of the resize grip (arrow keys resize, Home resets). | | `listboxFilter` | `string` | Listbox: filter box placeholder / label. | | `listboxEmpty` | `string` | Listbox: shown when the filter matches nothing. | | `eventCalendarGrabbed` | `(title: string, from: string, to: string) => string` | Announced when an event is picked up in keyboard move mode. | | `eventCalendarPosition` | `(title: string, day: string, from: string, to: string) => string` | Announced after each keyboard step: current day + time range. | | `eventCalendarMoved` | `(title: string, day: string, from: string, to: string) => string` | Announced when a move commits. | | `eventCalendarResized` | `(title: string, to: string) => string` | Announced when a resize commits. | | `eventCalendarEditCancelled` | `string` | Announced when an edit is aborted. | | `eventCalendarMovableEvent` | `string` | `aria-roledescription` of an editable event pill. | | `previousImage` | `string` | Lightbox / gallery: previous-image control. | | `nextImage` | `string` | Lightbox / gallery: next-image control. | | `imageOf` | `(index: number, total: number) => string` | Lightbox counter + per-image aria label, e.g. `Image 2 of 8`. | | `viewImage` | `(alt: string) => string` | Gallery tile label; receives the image's alt text. | | `imageFailed` | `string` | Shown in an image block whose source failed to load. | | `zoom` | `string` | Cropper zoom controls. | | `zoomIn` | `string` | | | `zoomOut` | `string` | | | `mediaLibrary` | `string` | Media gallery region label. | | `dropzoneLabel` | `string` | File upload dropzone + states. | | `uploadFailed` | `string` | | | `retryUpload` | `string` | | | `errorSummaryTitle` | `string` | Form error summary heading. | | `available` | `string` | Default column titles. | | `selected` | `string` | | | `transferSelected` | `(target: string) => string` | Move-button labels; receive the target list's title. | | `transferAll` | `(target: string) => string` | | | `itemsMoved` | `(count: number, target: string) => string` | Announced after a move. | | `notificationsTitle` | `string` | | | `allCaughtUp` | `string` | | | `markAllRead` | `string` | | | `notificationsUnread` | `(count: number) => string` | | | `unread` | `string` | Unread state announced per row. | | `tourStepOf` | `(step: number, total: number) => string` | | | `tourSkip` | `string` | | | `tourPrevious` | `string` | | | `tourNext` | `string` | | | `tourDone` | `string` | | | `commandPalettePlaceholder` | `string` | Command palette input placeholder. | | `commandPaletteLabel` | `string` | Command palette dialog label. | | `stepCompleted` | `string` | Stepper: step state, appended to the step's accessible name. | | `stepError` | `string` | | | `diffAddedLine` | `string` | Diff: screen-reader prefix for changed lines. | | `diffRemovedLine` | `string` | | | `itemAdded` | `(name: string) => string` | Chip collections (tag input, multi-select): announced on add/remove. | | `itemRemoved` | `(name: string) => string` | | | `resizePanes` | `string` | Splitter separator label. | | `backToTop` | `string` | Back-to-top button label. | | `breadcrumbLabel` | `string` | Breadcrumb nav landmark label. | | `fabLabel` | `string` | FAB default label. | | `appSwitcherLabel` | `string` | App switcher: trigger / panel label, and the note when the registry cannot be fetched. | | `appSwitcherError` | `string` | | | `diffBefore` | `string` | Diff view labels. | | `diffAfter` | `string` | | | `diffChanges` | `string` | | | `skipToContent` | `string` | App shell. | | `primaryNav` | `string` | | | `dndPickedUp` | `(position: number, total: number) => string` | Announced when an item is lifted for keyboard dragging. | | `dndMoved` | `(position: number, total: number) => string` | Announced as the item moves within its list. | | `dndMovedToList` | `(list: string, position: number, total: number) => string` | Announced as the item moves into another list. | | `dndDropped` | `(position: number) => string` | Announced when the item is dropped. | | `dndMovedToZone` | `(zone: string) => string` | Announced as a lifted item reaches a drop zone (a target that is not a list). | | `dndDroppedInZone` | `(zone: string) => string` | Announced when the item is dropped on a zone. | | `dndCancelled` | `string` | Announced when the drag is cancelled. | | `repeaterAddRow` | `string` | Repeater add-row button caption (default when no `addLabel` is given). | | `repeaterRemoveRow` | `(index: number) => string` | Repeater per-row remove button label (1-based row number). | | `repeaterReorderRow` | `(index: number) => string` | Repeater per-row drag-handle label (1-based row number). | | `repeaterRowMoved` | `(from: number, to: number) => string` | Announced after a repeater row is reordered (1-based positions). | | `fileRejectedType` | `(name: string) => string` | | | `fileRejectedSize` | `(name: string, limit: string) => string` | | | `fileRejectedCount` | `(name: string, max: number) => string` | | | `chartCategory` | `string` | | | `chartValue` | `string` | | | `chartSeries` | `string` | | | `chartSlice` | `string` | | | `chartStage` | `string` | | | `chartConversion` | `string` | | | `chartAxis` | `string` | | | `chartShare` | `string` | | | `chartLabel` | `string` | | | `qrCodeLabel` | `(text: string) => string` | Default accessible label of a QR code, carrying its encoded content. | | `sortableListLabel` | `string` | Default accessible name of `mk-sortable-list` when no `label` is given. | | `filterColumn` | `(column: string) => string` | Table filter row: accessible name of a column's filter control. | | `clearFilter` | `(column: string) => string` | Table filter row: the per-control clear (×) button. | | `filterAny` | `string` | Table filter row: the "no filter" option of a select filter. | | `filterMin` | `string` | Table filter row: placeholder of a number / date filter (matches values ≥ the entry). | | `blockEditor` | `MkBlockEditorStrings` | Block editor chrome (deep-merged by provideMkI18n). | ### MkOverlayConfig (interface) Import: `import { MkOverlayConfig } from '@mk-kit/ui/core';` Members: | Name | Type | Description | | --- | --- | --- | | `data`? | `TData \| undefined` | Arbitrary data injected via `MK_OVERLAY_DATA`. | | `hasBackdrop`? | `boolean \| undefined` | Render a dimmed scrim behind the panel. Default `true`. | | `closeOnBackdropClick`? | `boolean \| undefined` | Close when the backdrop is clicked. Default `true`. | | `closeOnEscape`? | `boolean \| undefined` | Close when Escape is pressed. Default `true`. | | `trapFocus`? | `boolean \| undefined` | Trap focus within the panel and restore it on close. Default `true`. | | `autoFocus`? | `boolean \| undefined` | Move focus to the panel's first focusable element on open. Default `true`. Set `false` to focus the panel itself instead — for content-led surfaces (a product sheet, a preview) where focusing the close button first reads as "dismiss me". Tab containment and focus restore are unaffected; turn `trapFocus` off only if you want neither. | | `panelClass`? | `string \| string[] \| undefined` | Extra class(es) applied to the panel host element. | | `role`? | `"dialog" \| "alertdialog" \| "menu" \| "listbox" \| undefined` | Accessible role for the panel. Default `dialog`. | | `ariaLabel`? | `string \| undefined` | `aria-label` for the panel when no visible title is wired up. | | `injector`? | `Injector \| undefined` | A custom injector to use as the parent for the rendered component. | ### MkQueryField (interface) Import: `import { MkQueryField } from '@mk-kit/ui/core';` A field the user can filter on. Members: | Name | Type | Description | | --- | --- | --- | | `key` | `string` | Property key on the row objects / the API's filter name. | | `label` | `string` | Label shown in the field picker. | | `type`? | `MkQueryValueType \| undefined` | Default `string`. | | `options`? | `readonly MkQueryFieldOption[] \| undefined` | Choices for `select` fields. | | `operators`? | `readonly MkQueryOperator[] \| undefined` | Restrict / reorder the operators offered (default: all for the type). | | `placeholder`? | `string \| undefined` | Placeholder of the value editor. | ### MkQueryFieldOption (interface) Import: `import { MkQueryFieldOption } from '@mk-kit/ui/core';` A choice for `select` fields. Members: | Name | Type | Description | | --- | --- | --- | | `label` | `string` | | | `value` | `unknown` | | ### MkQueryGroup (interface) Import: `import { MkQueryGroup } from '@mk-kit/ui/core';` A group of rules and nested groups joined by one combinator, optionally negated. Members: | Name | Type | Description | | --- | --- | --- | | `id` | `string` | | | `combinator` | `MkQueryCombinator` | | | `not`? | `boolean \| undefined` | Negate the whole group. | | `rules` | `MkQueryNode[]` | | ### MkQueryRule (interface) Import: `import { MkQueryRule } from '@mk-kit/ui/core';` A leaf condition. `value` is `[from, to]` for `between`, an array for `in` / `notIn`, absent for `empty` / `notEmpty`. Dates are ISO strings. Members: | Name | Type | Description | | --- | --- | --- | | `id` | `string` | | | `field` | `string` | | | `operator` | `MkQueryOperator` | | | `value`? | `unknown` | | ### MkQueryTextStrings (interface) Import: `import { MkQueryTextStrings } from '@mk-kit/ui/core';` The strings `mkQueryToText` and `mkQueryOperatorLabel` render with. A structural subset of mk-kit's `MkI18nStrings`, so the UI's full i18n map can be passed directly; defaults to `MK_QUERY_TEXT_EN`. Members: | Name | Type | Description | | --- | --- | --- | | `queryTrue` | `string` | | | `queryFalse` | `string` | | | `queryAnd` | `string` | | | `queryOr` | `string` | | | `queryNot` | `string` | | | `queryOpEq` | `string` | | | `queryOpNeq` | `string` | | | `queryOpContains` | `string` | | | `queryOpNotContains` | `string` | | | `queryOpStartsWith` | `string` | | | `queryOpEndsWith` | `string` | | | `queryOpGt` | `string` | | | `queryOpGte` | `string` | | | `queryOpLt` | `string` | | | `queryOpLte` | `string` | | | `queryOpBetween` | `string` | | | `queryOpIn` | `string` | | | `queryOpNotIn` | `string` | | | `queryOpBefore` | `string` | | | `queryOpAfter` | `string` | | | `queryOpEmpty` | `string` | | | `queryOpNotEmpty` | `string` | | ### MkSignalValidationError (interface) Import: `import { MkSignalValidationError } from '@mk-kit/ui/core';` The shape of a Signal Forms validation error as `mk-kit` reads it — the `{ kind, message? }` contract of `ValidationError` from `@angular/forms/signals`, plus whatever payload the error class carries (`min`, `maxLength`, `pattern`, …). Declared structurally so `@mk-kit/ui/core` stays free of a runtime dependency on the signals entry point. Members: | Name | Type | Description | | --- | --- | --- | | `kind` | `string` | Identifies the kind of error (`'required'`, `'minLength'`, …). | | `message`? | `string \| undefined` | Human-readable message, when the schema supplied one. | ### MkValidationStrings (interface) Import: `import { MkValidationStrings } from '@mk-kit/ui/core';` Messages rendered by `mk-form-field` for the validation errors the library's own controls produce, plus the standard Angular `Validators` keys, so a field wrapping any control shows something sensible without per-form wiring. Keys match the `ValidationErrors` keys exactly and each entry receives that key's error payload. Override any subset through `provideMkI18n({ validation: … })`, or a whole map per field via `mk-form-field`'s `errorMessages` input. Members: | Name | Type | Description | | --- | --- | --- | | `required` | `string` | `Validators.required` — also emitted by checkbox and radio-group. | | `email` | `string` | `Validators.email`. | | `min` | `(err: { min: number; actual: number; }) => string` | `Validators.min`, and the numeric controls' `[min]`. | | `max` | `(err: { max: number; actual: number; }) => string` | `Validators.max`, and the numeric controls' `[max]`. | | `minlength` | `(err: { requiredLength: number; actualLength: number; }) => string` | `Validators.minLength` — also emitted by password-input and OTP. | | `maxlength` | `(err: { requiredLength: number; actualLength: number; }) => string` | `Validators.maxLength`. | | `pattern` | `string` | `Validators.pattern`. | | `mkMinDate` | `(err: { min: Date; actual: Date; }) => string` | A date/month/week picker's `[min]`. | | `mkMaxDate` | `(err: { max: Date; actual: Date; }) => string` | A date/month/week picker's `[max]`. | | `mkDateFilter` | `string` | A date rejected by a calendar's `[disabledDate]` predicate. | | `mkDateRangeIncomplete` | `string` | A range picker with only one end filled in. | | `mkMinTime` | `(err: { min: string; actual: string; }) => string` | The time-picker's `[min]`. | | `mkMaxTime` | `(err: { max: string; actual: string; }) => string` | The time-picker's `[max]`. | | `mkMaxItems` | `(err: { max: number; actual: number; }) => string` | More items than a multi-select's, tag-input's or upload's `[max*]` allows. | | `mkFileSize` | `(err: { max: number; maxLabel: string; name: string; }) => string` | A file larger than a file-upload's `[maxSize]`. | | `mkFileType` | `(err: { accept: string; name: string; }) => string` | A file not matching a file-upload's `[accept]` filter. | | `cardNumber` | `string` | A card number failing the Luhn checksum. | | `iban` | `(err: { country: string; expectedLength: number \| null; }) => string` | An IBAN failing the mod-97 checksum. | | `postalCode` | `(err: { country: string; example: string; }) => string` | A postal code not matching the country's format. | | `taxId` | `(err: { country: string; label: string; example: string; }) => string` | A tax identifier not matching the country's format or checksum. | | `unknown` | `string` | Fallback for an error key with no message of its own. | ### MkValidatorChangeRef (interface) Import: `import { MkValidatorChangeRef } from '@mk-kit/ui/core';` Handle returned by `mkValidatorChange`, wiring a component's `registerOnValidatorChange` callback to a set of reactive dependencies. Members: | Name | Type | Description | | --- | --- | --- | | `register` | `(fn: () => void): void` | Store the callback Angular hands to `registerOnValidatorChange`. | | `notify` | `(): void` | Ask the bound control to re-run `validate()` now. | ### MkAccentKey (type) Import: `import { MkAccentKey } from '@mk-kit/ui/core';` One of the eight kit accents (the Momentum palette). ```ts type MkAccentKey = 'indigo' | 'blue' | 'teal' | 'violet' | 'coral' | 'lime' | 'pink' | 'bumblebee'; ``` ### MkAriaLivePoliteness (type) Import: `import { MkAriaLivePoliteness } from '@mk-kit/ui/core';` ```ts type MkAriaLivePoliteness = 'polite' | 'assertive'; ``` ### MkBreakpoint (type) Import: `import { MkBreakpoint } from '@mk-kit/ui/core';` Named viewport ranges, mobile-first: each starts at its min-width. ```ts type MkBreakpoint = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'; ``` ### MkBreakpoints (type) Import: `import { MkBreakpoints } from '@mk-kit/ui/core';` Min-widths (px) at which each named breakpoint begins; `xs` is everything below `sm`. ```ts type MkBreakpoints = Record, number>; ``` ### MkCodeLanguage (type) Import: `import { MkCodeLanguage } from '@mk-kit/ui/core';` Languages with built-in highlighting. Unknown values render plain text. ```ts type MkCodeLanguage = 'json' | 'plaintext'; ``` ### MkContrastPreference (type) Import: `import { MkContrastPreference } from '@mk-kit/ui/core';` Contrast preference. `high` applies the high-contrast token preset (`data-mk-contrast="high"`): pure text colours, line-like borders, opaque interaction washes, a thicker focus ring. `system` (the default) writes no attribute and lets the stylesheet follow the OS `prefers-contrast: more` setting; `normal` opts out of that even when the OS asks for more contrast. ```ts type MkContrastPreference = 'normal' | 'high' | 'system'; ``` ### MkDensity (type) Import: `import { MkDensity } from '@mk-kit/ui/core';` Global control-density mode. `touch` sizes controls for fingers (48px default) rather than a cursor — tablets, kiosks, order screens. It is usually applied per-subtree with the `data-mk-density` attribute rather than globally, since one app often has both a mouse-driven admin and a touch-driven screen. ```ts type MkDensity = 'comfortable' | 'compact' | 'touch'; ``` ### MkErrorMessages (type) Import: `import { MkErrorMessages } from '@mk-kit/ui/core';` A per-field override map: an error key mapped either to a fixed message or to a function receiving that key's error payload. ```html ``` ```ts type MkErrorMessages = Readonly string)>>; ``` ### MkI18nOverrides (type) Import: `import { MkI18nOverrides } from '@mk-kit/ui/core';` Any subset of `MkI18nStrings`; the nested `dateNames`, `blockEditor` and `validation` groups may be partial too (they are merged deeply). ```ts type MkI18nOverrides = Partial< Omit > & { dateNames?: Partial; blockEditor?: Partial; validation?: Partial; }; ``` ### MkOverlayRootFn (type) Import: `import { MkOverlayRootFn } from '@mk-kit/ui/core';` Resolves the element overlay surfaces are appended to. A function (not an element) because the root may be created lazily, after DI is set up. ```ts type MkOverlayRootFn = () => HTMLElement; ``` ### MkPlacement (type) Import: `import { MkPlacement } from '@mk-kit/ui/core';` Common placement values for anchored overlays (menus, tooltips, popovers). ```ts type MkPlacement = | 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end'; ``` ### MkQueryCombinator (type) Import: `import { MkQueryCombinator } from '@mk-kit/ui/core';` ```ts type MkQueryCombinator = 'and' | 'or'; ``` ### MkQueryNode (type) Import: `import { MkQueryNode } from '@mk-kit/ui/core';` ```ts type MkQueryNode = MkQueryRule | MkQueryGroup; ``` ### MkQueryOperator (type) Import: `import { MkQueryOperator } from '@mk-kit/ui/core';` Comparison operators. Which apply depends on the field type. ```ts type MkQueryOperator = | 'eq' | 'neq' | 'contains' | 'notContains' | 'startsWith' | 'endsWith' | 'gt' | 'gte' | 'lt' | 'lte' | 'between' | 'in' | 'notIn' | 'before' | 'after' | 'empty' | 'notEmpty'; ``` ### MkQueryValueType (type) Import: `import { MkQueryValueType } from '@mk-kit/ui/core';` Value kind of a filterable field; decides the editor and the operators offered. ```ts type MkQueryValueType = 'string' | 'number' | 'boolean' | 'date' | 'select'; ``` ### MkResolvedContrast (type) Import: `import { MkResolvedContrast } from '@mk-kit/ui/core';` Concrete resolved contrast (never `system`). ```ts type MkResolvedContrast = 'normal' | 'high'; ``` ### MkResolvedTheme (type) Import: `import { MkResolvedTheme } from '@mk-kit/ui/core';` Concrete resolved theme (never `system`). ```ts type MkResolvedTheme = 'light' | 'dark'; ``` ### MkResponsive (type) Import: `import { MkResponsive } from '@mk-kit/ui/core';` A value that may differ per breakpoint: either the plain value or a mobile-first map, `{ xs: 1, md: 2, xl: 4 }`, where each key applies from that breakpoint up until the next key given. ```ts type MkResponsive = T | Partial>; ``` ### MkSize (type) Import: `import { MkSize } from '@mk-kit/ui/core';` Control size scale. Maps to `--mk-control-height-*` tokens. ```ts type MkSize = 'sm' | 'md' | 'lg'; ``` ### MkSortAnnounceDirection (type) Import: `import { MkSortAnnounceDirection } from '@mk-kit/ui/core';` Direction passed to the sort announcer. ```ts type MkSortAnnounceDirection = 'asc' | 'desc'; ``` ### MkThemePreference (type) Import: `import { MkThemePreference } from '@mk-kit/ui/core';` Theme selection. `system` follows the OS `prefers-color-scheme`. ```ts type MkThemePreference = 'light' | 'dark' | 'system'; ``` ### MkTone (type) Import: `import { MkTone } from '@mk-kit/ui/core';` Semantic color tone. Each maps to a `--mk-*` token family. ```ts type MkTone = | 'primary' | 'neutral' | 'success' | 'warning' | 'danger' | 'info'; ``` ### MkVariant (type) Import: `import { MkVariant } from '@mk-kit/ui/core';` Visual treatment for tinted/interactive surfaces. ```ts type MkVariant = 'solid' | 'soft' | 'outline' | 'ghost' | 'link'; ``` ## @mk-kit/ui/core/signal-forms 1 exports. `import { … } from '@mk-kit/ui/core/signal-forms';` ### mkInjectFieldTouched (function) Import: `import { mkInjectFieldTouched } from '@mk-kit/ui/core/signal-forms';` Touched-gate for a control's `invalid` input under Signal Forms. When a control is bound with the `[formField]` directive, Angular writes the field's `invalid()` state straight into the control's `invalid` input — from the first render, before the user has reached the field. mk-kit controls pass that input through this gate so the invalid visual (and `aria-invalid`) only shows once the field is touched or dirty, matching how `mk-form-field` reveals its message and how `submit()` (which marks every field touched) surfaces the remaining problems. Returns a signal that is always `true` for a control that is not bound with `[formField]`, so a standalone `[invalid]="true"` keeps working as before. Call it in a field initializer (an injection context): ```ts private readonly fieldTouched = mkInjectFieldTouched(); protected readonly isInvalid = computed( () => (this.invalid() && this.fieldTouched()) || (this.field?.hasError() ?? false), ); ``` The binding is looked up lazily, on first read: the `FormField` directive itself injects the element's `NG_VALUE_ACCESSOR` (the control) while it is created, so resolving it from the control's constructor would be circular. ```ts function mkInjectFieldTouched(): Signal ``` ## @mk-kit/ui/icon 8 exports. `import { … } from '@mk-kit/ui/icon';` ### MkIcon (component) Selector: `mk-icon` Docs: https://mk-kit.dev/components/icon Import: `import { MkIcon } from '@mk-kit/ui/icon';` Icon — renders a registered SVG by `name`, or your own projected ``. The glyph inherits the current text colour (`currentColor`) and scales to the `size` box, so it composes cleanly inside buttons, inputs and menus. Decorative by default (`aria-hidden`); pass `label` to expose it as an image to assistive tech. ```html …custom… ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `name` | `string` | `''` | Name of a registered icon (see `MkIconRegistry`). | | `size` | `number \| MkSize` | `'md'` | Size: `sm`/`md`/`lg`, or a pixel number for a custom dimension. | | `label` | `string` | `''` | Accessible name. When set the icon becomes `role="img"`; otherwise hidden. | ### MkIconRegistry (service) Docs: https://mk-kit.dev/components/icon Import: `import { MkIconRegistry } from '@mk-kit/ui/icon';` IconRegistry — the name → SVG store behind ``. The hand-made `MK_DEFAULT_ICONS` are registered on construction and ship with every app. Everything else is opt-in and tree-shakeable: the Lucide-derived extended set via `provideMkExtendedIcons()` (from `@mk-kit/ui/icon/extended`), a themed subset or your own SVGs (from a sprite, a design export, anything) via `provideMkIcons()`, or at runtime with `register` / `registerIcons` / `load`. SVG markup is trusted verbatim (bypassed through `DomSanitizer`), so only register icons from sources you control — never user input. ```ts const reg = inject(MkIconRegistry); reg.register('logo', '…'); reg.registerIcons({ save: '', share: '' }); reg.load(() => import('@mk-kit/ui/icon/extended').then((m) => m.MK_EXTENDED_ICONS_FILES)); ``` Methods: | Signature | Description | | --- | --- | | `register(name: string, svg: string): this` | Register (or overwrite) a single named icon from raw SVG markup. | | `registerIcons(icons: MkIconMap): this` | Register many icons at once from a `{ name: svg }` map — a whole set, a themed subset (`MK_EXTENDED_ICONS_FILES`) or a hand-picked few. Later registrations overwrite earlier ones on a shared name. | | `registerAliases(aliases: Readonly>): this` | Register alternative names that resolve to existing icons — e.g. map Material Symbols ligature names onto the built-in set (`{ delete: 'trash', expand_more: 'chevron-down' }`). A real icon registered under an alias name always wins over the alias; an alias whose target is not registered resolves to nothing (and, in dev mode, warns once naming the missing target). | | `load(loader: MkIconLoader): Promise` | Load an icon map asynchronously and register it once it arrives. Icons already on screen fill in when the map lands (see `changes`); the missing-icon warning stays quiet while a load is pending. Server-side rendering waits for it (Angular's `PendingTasks`), so the HTML ships with the icons in place. ```ts registry.load(() => import('@mk-kit/ui/icon/extended').then((m) => m.MK_EXTENDED_ICONS)); ``` | | `get(name: string): SafeHtml \| null` | Sanitized SVG for a name (aliases resolved), or `null` when unknown. | | `has(name: string): boolean` | Whether an icon with this name (or alias) is registered. | | `names(): string[]` | All registered icon names (useful for a picker / catalogue). | | `warnMissing(name: string): void` | Dev-mode only: warn once per unknown name with a hint about the opt-in extended set. Silent in production builds and while a `load` is pending (the name may be on its way). Called by ``. | Properties: | Name | Type | Description | | --- | --- | --- | | `changes` | `Signal` | Bumps on every registration. `` reads it, so an icon that arrives late (a lazy `load`, a runtime `register`) renders in place without any re-binding. | | `pending` | `Signal` | Whether a lazy `load` is still in flight. | ### provideMkIcons (function) Import: `import { provideMkIcons } from '@mk-kit/ui/icon';` Registers extra icons at bootstrap — a themed subset of the extended set, a hand-picked few, your own SVGs, or a lazily loaded map. Call it as many times as you like; each call adds to the `MkIconRegistry`. The hand-made defaults are always there; this is for everything else. ```ts import { provideMkIcons } from '@mk-kit/ui/icon'; import { MK_EXTENDED_ICONS_FILES, MK_EXTENDED_ICONS_DATA } from '@mk-kit/ui/icon/extended'; bootstrapApplication(App, { providers: [ // themed subsets — only these glyphs end up in the bundle provideMkIcons(MK_EXTENDED_ICONS_FILES), provideMkIcons(MK_EXTENDED_ICONS_DATA), // your own provideMkIcons({ logo: '…' }), // or the whole extended set in its own lazy chunk, off the critical path provideMkIcons(() => import('@mk-kit/ui/icon/extended').then((m) => m.MK_EXTENDED_ICONS)), ], }); ``` A loader runs once at bootstrap without blocking it: icons already on screen fill in when the chunk lands, and server-side rendering waits for it. Picking single names out of the full map (`{ receipt: MK_EXTENDED_ICONS['receipt'] }`) works but still bundles the whole map — use a subset or copy the SVG when size matters. ```ts function provideMkIcons(icons: MkIconMap | MkIconLoader): EnvironmentProviders ``` ### provideMkMaterialIcons (function) Import: `import { provideMkMaterialIcons } from '@mk-kit/ui/icon';` Installs the Material Symbols name aliases into the `MkIconRegistry`, so ``, `name="expand_more"`, `name="visibility"` etc. resolve to the built-in set. Add it to your bootstrap providers when migrating an app off `` ligatures: ```ts bootstrapApplication(App, { providers: [provideMkMaterialIcons()], }); ``` ```ts function provideMkMaterialIcons(): EnvironmentProviders ``` ### MK_DEFAULT_ICONS (const) Import: `import { MK_DEFAULT_ICONS } from '@mk-kit/ui/icon';` Name → SVG markup map of the default icons (registered by `MkIconRegistry` on construction). ```ts const MK_DEFAULT_ICONS: Readonly>; ``` ### MK_MATERIAL_ICON_ALIASES (const) Import: `import { MK_MATERIAL_ICON_ALIASES } from '@mk-kit/ui/icon';` Material Symbols ligature names → built-in mk icon names. Lets templates written against `delete` conventions keep their icon names when migrating: `` renders the `trash` glyph once `provideMkMaterialIcons` is installed. Several Material names intentionally collapse onto one mk glyph (all the calendar variants → `calendar`, the delete variants → `trash`, …). Every target is a default icon, so the aliases work without the opt-in extended set. Names not listed here have no sensible built-in equivalent — register your own SVG under the Material name via `MkIconRegistry.register`, or alias it onto an extended glyph with `registerAliases` once `provideMkExtendedIcons()` is installed (an alias whose target is missing renders nothing and warns once in dev mode). ```ts const MK_MATERIAL_ICON_ALIASES: Readonly>; ``` ### MkIconLoader (type) Import: `import { MkIconLoader } from '@mk-kit/ui/icon';` Loads an icon map on demand — typically a dynamic import of the extended set: `() => import('@mk-kit/ui/icon/extended').then((m) => m.MK_EXTENDED_ICONS)`. ```ts type MkIconLoader = () => Promise; ``` ### MkIconMap (type) Import: `import { MkIconMap } from '@mk-kit/ui/icon';` A `{ name: '…' }` map — what every registration API accepts. ```ts type MkIconMap = Readonly>; ``` ## @mk-kit/ui/icon/extended 19 exports. `import { … } from '@mk-kit/ui/icon/extended';` ### provideMkExtendedIcons (function) Import: `import { provideMkExtendedIcons } from '@mk-kit/ui/icon/extended';` Registers the whole Lucide-derived extended set (`MK_EXTENDED_ICONS`) so every `` in the catalogue resolves. Opt-in: without it only the hand-made defaults are available and an unknown name warns once in dev mode. ```ts import { provideMkExtendedIcons } from '@mk-kit/ui/icon/extended'; bootstrapApplication(App, { providers: [provideMkExtendedIcons()], }); ``` Size-conscious alternatives (see `provideMkIcons`): register only the themed subsets you use (`provideMkIcons(MK_EXTENDED_ICONS_FILES)`), or load the full set lazily in its own chunk: `provideMkIcons(() => import('@mk-kit/ui/icon/extended').then((m) => m.MK_EXTENDED_ICONS))`. The hand-made defaults keep their names — the generated set never overlaps them. ```ts function provideMkExtendedIcons(): EnvironmentProviders ``` ### MK_EXTENDED_ICON_GROUPS (const) Import: `import { MK_EXTENDED_ICON_GROUPS } from '@mk-kit/ui/icon/extended';` The themed subsets by group name — handy for a picker or for registering several groups at once: `provideMkIcons(MK_EXTENDED_ICON_GROUPS['files'])`. ```ts const MK_EXTENDED_ICON_GROUPS: Readonly>>>; ``` ### MK_EXTENDED_ICONS (const) Import: `import { MK_EXTENDED_ICONS } from '@mk-kit/ui/icon/extended';` Every Lucide-derived icon (305 glyphs). Not registered by default — install it with `provideMkExtendedIcons()`, pass a themed subset to `provideMkIcons()`, or load it lazily: `provideMkIcons(() => import('@mk-kit/ui/icon/extended').then((m) => m.MK_EXTENDED_ICONS))`. ```ts const MK_EXTENDED_ICONS: Readonly>; ``` ### MK_EXTENDED_ICONS_COMMERCE (const) Import: `import { MK_EXTENDED_ICONS_COMMERCE } from '@mk-kit/ui/icon/extended';` `commerce` subset of `MK_EXTENDED_ICONS` (23 icons). ```ts const MK_EXTENDED_ICONS_COMMERCE: Readonly>; ``` ### MK_EXTENDED_ICONS_COMMUNICATION (const) Import: `import { MK_EXTENDED_ICONS_COMMUNICATION } from '@mk-kit/ui/icon/extended';` `communication` subset of `MK_EXTENDED_ICONS` (15 icons). ```ts const MK_EXTENDED_ICONS_COMMUNICATION: Readonly>; ``` ### MK_EXTENDED_ICONS_DATA (const) Import: `import { MK_EXTENDED_ICONS_DATA } from '@mk-kit/ui/icon/extended';` `data` subset of `MK_EXTENDED_ICONS` (15 icons). ```ts const MK_EXTENDED_ICONS_DATA: Readonly>; ``` ### MK_EXTENDED_ICONS_DEVELOPER (const) Import: `import { MK_EXTENDED_ICONS_DEVELOPER } from '@mk-kit/ui/icon/extended';` `developer` subset of `MK_EXTENDED_ICONS` (23 icons). ```ts const MK_EXTENDED_ICONS_DEVELOPER: Readonly>; ``` ### MK_EXTENDED_ICONS_DEVICES (const) Import: `import { MK_EXTENDED_ICONS_DEVICES } from '@mk-kit/ui/icon/extended';` `devices` subset of `MK_EXTENDED_ICONS` (15 icons). ```ts const MK_EXTENDED_ICONS_DEVICES: Readonly>; ``` ### MK_EXTENDED_ICONS_EDITING (const) Import: `import { MK_EXTENDED_ICONS_EDITING } from '@mk-kit/ui/icon/extended';` `editing` subset of `MK_EXTENDED_ICONS` (34 icons). ```ts const MK_EXTENDED_ICONS_EDITING: Readonly>; ``` ### MK_EXTENDED_ICONS_FILES (const) Import: `import { MK_EXTENDED_ICONS_FILES } from '@mk-kit/ui/icon/extended';` `files` subset of `MK_EXTENDED_ICONS` (22 icons). ```ts const MK_EXTENDED_ICONS_FILES: Readonly>; ``` ### MK_EXTENDED_ICONS_LAYOUT (const) Import: `import { MK_EXTENDED_ICONS_LAYOUT } from '@mk-kit/ui/icon/extended';` `layout` subset of `MK_EXTENDED_ICONS` (17 icons). ```ts const MK_EXTENDED_ICONS_LAYOUT: Readonly>; ``` ### MK_EXTENDED_ICONS_LIFESTYLE (const) Import: `import { MK_EXTENDED_ICONS_LIFESTYLE } from '@mk-kit/ui/icon/extended';` `lifestyle` subset of `MK_EXTENDED_ICONS` (40 icons). ```ts const MK_EXTENDED_ICONS_LIFESTYLE: Readonly>; ``` ### MK_EXTENDED_ICONS_MEDIA (const) Import: `import { MK_EXTENDED_ICONS_MEDIA } from '@mk-kit/ui/icon/extended';` `media` subset of `MK_EXTENDED_ICONS` (14 icons). ```ts const MK_EXTENDED_ICONS_MEDIA: Readonly>; ``` ### MK_EXTENDED_ICONS_NAVIGATION (const) Import: `import { MK_EXTENDED_ICONS_NAVIGATION } from '@mk-kit/ui/icon/extended';` `navigation` subset of `MK_EXTENDED_ICONS` (34 icons). ```ts const MK_EXTENDED_ICONS_NAVIGATION: Readonly>; ``` ### MK_EXTENDED_ICONS_PEOPLE (const) Import: `import { MK_EXTENDED_ICONS_PEOPLE } from '@mk-kit/ui/icon/extended';` `people` subset of `MK_EXTENDED_ICONS` (11 icons). ```ts const MK_EXTENDED_ICONS_PEOPLE: Readonly>; ``` ### MK_EXTENDED_ICONS_SECURITY (const) Import: `import { MK_EXTENDED_ICONS_SECURITY } from '@mk-kit/ui/icon/extended';` `security` subset of `MK_EXTENDED_ICONS` (5 icons). ```ts const MK_EXTENDED_ICONS_SECURITY: Readonly>; ``` ### MK_EXTENDED_ICONS_STATUS (const) Import: `import { MK_EXTENDED_ICONS_STATUS } from '@mk-kit/ui/icon/extended';` `status` subset of `MK_EXTENDED_ICONS` (20 icons). ```ts const MK_EXTENDED_ICONS_STATUS: Readonly>; ``` ### MK_EXTENDED_ICONS_TIME (const) Import: `import { MK_EXTENDED_ICONS_TIME } from '@mk-kit/ui/icon/extended';` `time` subset of `MK_EXTENDED_ICONS` (8 icons). ```ts const MK_EXTENDED_ICONS_TIME: Readonly>; ``` ### MK_EXTENDED_ICONS_TRAVEL (const) Import: `import { MK_EXTENDED_ICONS_TRAVEL } from '@mk-kit/ui/icon/extended';` `travel` subset of `MK_EXTENDED_ICONS` (9 icons). ```ts const MK_EXTENDED_ICONS_TRAVEL: Readonly>; ``` ## @mk-kit/ui/chip 2 exports. `import { … } from '@mk-kit/ui/chip';` ### MkChip (component) Selector: `mk-chip` Docs: https://mk-kit.dev/components/badges-avatars Import: `import { MkChip } from '@mk-kit/ui/chip';` Chip — an interactive, optionally removable/selectable token. Use it for filters, active selections or editable input tokens. For a purely decorative label use `MkTag` instead. ```html {{ item.name }} Filter ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `tone` | `MkTone` | `'neutral'` | Semantic color tone. | | `variant` | `MkChipVariant` | `'soft'` | Visual treatment. | | `size` | `MkSize` | `'md'` | Size scale. | | `selectable` | `boolean` | `false` | Make the chip toggle a selected state on click / Enter / Space. | | `removable` | `boolean` | `false` | Show a trailing remove button and enable Delete/Backspace removal. | | `disabled` | `boolean` | `false` | Disable all interaction. | | `removeLabel` | `string` | `this.i18n.remove` | Accessible label for the remove button. | | `selected` (two-way) | `boolean` | `false` | Two-way selected state (only meaningful when `selectable`). | Outputs: | Name | Type | Description | | --- | --- | --- | | `selectedChange` | `boolean` | Emits when `selected` changes (two-way binding). | | `removed` | `void` | Emitted when the chip is removed via the button or Delete/Backspace. | ### MkChipVariant (type) Import: `import { MkChipVariant } from '@mk-kit/ui/chip';` Visual treatment for a `MkChip`. ```ts type MkChipVariant = 'solid' | 'soft' | 'outline'; ``` ## @mk-kit/ui/checkbox 1 exports. `import { … } from '@mk-kit/ui/checkbox';` ### MkCheckbox (component) Selector: `mk-checkbox` · form control (ControlValueAccessor) Docs: https://mk-kit.dev/components/toggles Import: `import { MkCheckbox } from '@mk-kit/ui/checkbox';` Checkbox — a themed checkbox built on a visually-hidden native `input[type=checkbox]` (so keyboard + form semantics are native) with a custom box. Supports an `indeterminate` state and projects its label. Implements `ControlValueAccessor` with a two-way `checked` model, so it works with `[(ngModel)]`, reactive forms and `[(checked)]`. ```html Accept terms Select all ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `checked` (two-way) | `boolean` | `false` | Two-way checked state. | | `indeterminate` (two-way) | `boolean` | `false` | Two-way indeterminate ("mixed") state; cleared when the user toggles. | | `disabled` | `boolean` | `false` | Disable the control. | | `invalid` | `boolean` | `false` | Force the invalid visual + `aria-invalid` when used standalone. | | `required` | `boolean` | `false` | Mark required (adds `aria-required`). | | `size` | `MkSize` | `'md'` | Control size. | | `tone` | `MkTone` | `'primary'` | Semantic color tone for the checked box. | | `aria-label` | `string` | `''` | Accessible label when no text content is projected. | Outputs: | Name | Type | Description | | --- | --- | --- | | `checkedChange` | `boolean` | Emits when `checked` changes (two-way binding). | | `indeterminateChange` | `boolean` | Emits when `indeterminate` changes (two-way binding). | Methods: | Signature | Description | | --- | --- | | `validate(control: AbstractControl): ValidationErrors \| null` | Reports `required` for an unchecked box when `[required]` is set, so `required` on the element behaves like `Validators.requiredTrue`. | ## @mk-kit/ui/button 1 exports. `import { … } from '@mk-kit/ui/button';` ### MkButton (component) Selector: `button[mkButton], a[mkButton]` Docs: https://mk-kit.dev/components/buttons Import: `import { MkButton } from '@mk-kit/ui/button';` Button — enhances a native `

Exporting requires an admin role.

``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `mkCannot` (required) | `string` | | The permission key to check. | | `mkCannotElse` | `TemplateRef \| null` | `null` | Template rendered while the permission is granted (`; else ref`). | ### MkClickOutside (directive) Selector: `[mkClickOutside]` · exportAs: `mkClickOutside` Docs: https://mk-kit.dev/components/utilities Import: `import { MkClickOutside } from '@mk-kit/ui/directives';` Emits when a pointer press lands outside the host element — the building block for dismissing menus, popovers and custom dropdowns. Listens on the document in the capture phase so it fires before the target handles the event. ```html
…
``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `mkClickOutsideEnabled` | `boolean` | `true` | Disable the listener without removing the directive. | Outputs: | Name | Type | Description | | --- | --- | --- | | `mkClickOutside` | `PointerEvent` | Emits the originating event when a pointerdown occurs outside the host. | ### MkCopyToClipboard (directive) Selector: `[mkCopyToClipboard]` · exportAs: `mkCopyToClipboard` Docs: https://mk-kit.dev/components/utilities Import: `import { MkCopyToClipboard } from '@mk-kit/ui/directives';` Copies text to the clipboard when the host is clicked. Emits `(copied)` on success and `(copyFailed)` on error, and exposes a transient `copied` signal (via `exportAs`) so a template can show a "Copied!" state without extra code. ```html ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `mkCopyToClipboard` (required) | `string` | | The text to copy. | | `mkCopyFeedbackDuration` | `number` | `1500` | How long (ms) the `copied` signal stays true after a successful copy. | Outputs: | Name | Type | Description | | --- | --- | --- | | `copied` | `string` | Emits the copied text on success. | | `copyFailed` | `unknown` | Emits the error on failure. | Methods: | Signature | Description | | --- | --- | | `copy(): Promise` | Copy the text now. Bound to the host click, but callable directly too. | Properties: | Name | Type | Description | | --- | --- | --- | | `justCopied` | `Signal` | True for `feedbackDuration` ms after a successful copy. | ### MkField (directive) Selector: `[mkField]` Docs: https://mk-kit.dev/components/text-inputs Import: `import { MkField } from '@mk-kit/ui/directives';` Field — applies the semantic mobile-keyboard and autofill attribute bundle for a kind of field, so you never again ship an email input that iOS capitalises or an address input the browser can't autofill. It sets `type`, `inputmode`, `autocomplete`, `autocapitalize`, `autocorrect`, `spellcheck` and `enterkeyhint` (see `MK_FIELD_PRESETS`) and nothing else — no styling, no value handling — so it composes with `mkInput`, `mk-form-field`, `[(ngModel)]` and reactive forms untouched. ```html ``` ## Precedence A **static** attribute you write on the element wins: the directive reads the seven attributes once at construction (before any host binding has run) and keeps whatever was already there, filling in only what you left out. So `` stays a password field but still gets `autocomplete="username"`, `autocapitalize="off"`, … A **template binding** for the same attribute (`[attr.autocomplete]="…"`) does *not* win — Angular applies directive host bindings after template bindings, so the preset overwrites it. Use a static attribute to override, or drop `mkField` and set the bundle yourself. Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `mkField` (required) | `MkFieldKind` | | Which kind of field this is. | ### MkHotkey (directive) Selector: `[mkHotkey]` · exportAs: `mkHotkey` Docs: https://mk-kit.dev/components/utilities Import: `import { MkHotkey } from '@mk-kit/ui/directives';` `[mkHotkey]` — declaratively bind a keyboard shortcut to a host element. When the combo fires, a `
…
``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `mkHotkey` (required) | `string` | | The combo (or space-separated chord) to bind, e.g. `mod+k`, `g i`, `?`. | | `mkHotkeyAllowInInput` | `boolean` | `false` | Fire even while an editable field is focused. | | `mkHotkeyPreventDefault` | `boolean` | `true` | Call `preventDefault()` when the hotkey fires. Defaults to `true`. | Outputs: | Name | Type | Description | | --- | --- | --- | | `mkHotkeyPressed` | `KeyboardEvent` | Emitted when the hotkey fires and the host is not a button/link. | ### MkInfiniteScroll (directive) Selector: `[mkInfiniteScroll]` · exportAs: `mkInfiniteScroll` Docs: https://mk-kit.dev/components/utilities Import: `import { MkInfiniteScroll } from '@mk-kit/ui/directives';` InfiniteScroll — emits `(mkInfiniteScroll)` when the host scroll container is scrolled within `distance` px of its bottom, so a list can load its next page. Apply it to the scrollable element (`overflow: auto`). It fires once per approach and re-arms after you scroll back up past the threshold, so a single gesture never triggers repeated loads. Set `disabled` while a page is loading or once everything is loaded. ```html
Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `distance` | `number` | `200` | Distance (px) from the bottom at which the output fires. | | `disabled` | `boolean` | `false` | Pause firing (e.g. while a page is loading or all items are loaded). | Outputs: | Name | Type | Description | | --- | --- | --- | | `mkInfiniteScroll` | `void` | Emitted when the host is scrolled near its bottom. | ### MkIntersect (directive) Selector: `[mkIntersect]` · exportAs: `mkIntersect` Docs: https://mk-kit.dev/components/utilities Import: `import { MkIntersect } from '@mk-kit/ui/directives';` Intersect — a thin `IntersectionObserver` wrapper. Emits `(mkIntersect)` with the host's visibility whenever it enters or leaves the viewport (or `root`), and exposes an `intersecting` signal via `exportAs`. Set `once` to fire a single time and disconnect — the primitive for reveal-on-scroll animations and lazy loading. ```html
…
``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `root` | `HTMLElement \| null` | `null` | Element used as the viewport for the check (defaults to the browser one). | | `rootMargin` | `string` | `'0px'` | Margin grown/shrunk around the root before computing intersection. | | `threshold` | `number \| number[]` | `0` | Visibility ratio(s) at which the observer fires. | | `once` | `boolean` | `false` | Emit the first time the host becomes visible, then disconnect. | Outputs: | Name | Type | Description | | --- | --- | --- | | `mkIntersect` | `boolean` | Emits the host's `isIntersecting` state on every change. | Properties: | Name | Type | Description | | --- | --- | --- | | `intersecting` | `WritableSignal` | The current visibility, also readable via `exportAs`. | ### MkMask (directive) Selector: `[mkMask]` · exportAs: `mkMask` Docs: https://mk-kit.dev/components/utilities Import: `import { MkMask } from '@mk-kit/ui/directives';` Mask — formats an `` as the user types against a token pattern (phone, card, date, custom). Apply it to any text input; read the raw value via `(unmaskedChange)` (or the exported `unmasked` getter) and the formatted value via `(maskedChange)`. ```html ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `mkMask` (required) | `string` | | The mask pattern (token string). | | `mkMaskInputmode` | `string \| null` | `null` | Override the derived `inputmode` (`numeric` for digit-only masks). | Outputs: | Name | Type | Description | | --- | --- | --- | | `maskedChange` | `string` | The formatted value, on every change. | | `unmaskedChange` | `string` | The raw value (token characters only), on every change. | Properties: | Name | Type | Description | | --- | --- | --- | | `value` | `string` | The current formatted value. | | `unmasked` | `string` | The current raw value (token characters only). | ### MkRipple (directive) Selector: `[mkRipple]` Docs: https://mk-kit.dev/components/utilities Import: `import { MkRipple } from '@mk-kit/ui/directives';` Ripple — a Material-style touch ripple that expands from the pointer on press. Apply it to any pressable surface (button, list item, card). The directive makes the host a positioned, clipping container and paints a short-lived wave; it respects `prefers-reduced-motion`. ```html
  • Item
  • ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `mkRippleColor` | `string` | `''` | Wave colour (any CSS colour). Defaults to the host's `currentColor`. | | `mkRippleCentered` | `boolean` | `false` | Start every ripple from the centre instead of the pointer. | | `mkRippleDisabled` | `boolean` | `false` | Turn the effect off. | ### MkScrollspy (directive) Selector: `[mkScrollspy]` · exportAs: `mkScrollspy` Docs: https://mk-kit.dev/components/utilities Import: `import { MkScrollspy } from '@mk-kit/ui/directives';` Scrollspy — tracks which section is currently in view and exposes its `id`, so a table of contents / "on this page" nav can highlight the active link. Apply it to any element (typically the nav) and point `mkScrollspy` at a CSS selector matching the section elements to watch (each needs an `id`). Read the active id via the exported instance, or bind `(activeChange)`: ```html
    ``` A section activates once its top passes `offset` px below the top of the scroll root (default the viewport). When scrolling through a gap between sections the previous one stays active until the next crosses the line. Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `mkScrollspy` (required) | `string` | | CSS selector for the section elements to track (queried within `root`). | | `root` | `HTMLElement \| null` | `null` | Scroll container. Sections are queried inside it and its top edge is the activation reference. Defaults to the whole document / viewport. | | `offset` | `number` | `96` | Distance (px) below the scroll root's top at which a section becomes active. Raise it to account for a sticky header. | Outputs: | Name | Type | Description | | --- | --- | --- | | `activeChange` | `string \| null` | Emitted whenever the active section changes. | Methods: | Signature | Description | | --- | --- | | `refresh(): void` | Re-evaluate the active section (call after sections change). | Properties: | Name | Type | Description | | --- | --- | --- | | `activeId` | `WritableSignal` | The id of the currently active section (`null` before the first one). | ### MkCurrencyPipe (pipe) Pipe name: `mkCurrency` · `transform(value: number | string | null | undefined, currency?: string | null, options?: MkCurrencyOptions): string` Import: `import { MkCurrencyPipe } from '@mk-kit/ui/directives';` `mkCurrency` — format a number as money with `Intl.NumberFormat`, honouring the locale and default currency from `provideMkI18n({ locale, currency })`. No Angular locale data is needed. Pure: `null`, `undefined`, `''` and non-numeric input render as `''`. ```html {{ 1234.5 | mkCurrency }} {{ 1234.5 | mkCurrency:'EUR' }} {{ 1234.5 | mkCurrency:'PLN':{ locale: 'pl-PL' } }} {{ 1234567 | mkCurrency:'USD':{ notation: 'compact' } }} {{ total() | mkCurrency:'GBP':{ signDisplay: 'always' } }} ``` ### MkFileSizePipe (pipe) Pipe name: `mkFileSize` · `transform(value: number | string | null | undefined, options?: MkFileSizeOptions): string` Import: `import { MkFileSizePipe } from '@mk-kit/ui/directives';` `mkFileSize` — bytes → a human-readable size such as `1.2 MB`, with the number formatted by `Intl.NumberFormat` in the `provideMkI18n` locale. Pure: `null`, `undefined`, `''` and non-numeric input render as `''`. ```html {{ 1_234_567 | mkFileSize }} {{ 1_234_567 | mkFileSize:{ base: 'binary' } }} {{ 1_234_567 | mkFileSize:{ digits: 2, locale: 'de' } }} {{ 512 | mkFileSize }} ``` ### MkInitialsPipe (pipe) Pipe name: `mkInitials` · `transform(value: string | null | undefined, max?: number): string` Import: `import { MkInitialsPipe } from '@mk-kit/ui/directives';` `mkInitials` — "Ada Lovelace" → "AL", the same rule `mk-avatar` uses for its fallback: first letter of the first and last word, upper-cased. A single word yields its first `max` letters ("Ada" → "AD"); more than two words with `max` > 2 take one letter per word from the start ("Jean Luc Picard" with `max: 3` → "JLP"). Leading/trailing/duplicate whitespace is ignored, and grapheme-aware slicing keeps emoji and accents intact. Pure: `null`, `undefined` and blank input render as `''`. ```html {{ user.name | mkInitials }} {{ user.name | mkInitials:1 }} {{ 'Jean Luc Picard' | mkInitials:3 }} ``` ### MkPluralizePipe (pipe) Pipe name: `mkPluralize` · `transform(value: number | string | null | undefined, singular: string | MkPluralForms, plural?: string | null, options?: MkPluralizeOptions): string` Import: `import { MkPluralizePipe } from '@mk-kit/ui/directives';` `mkPluralize` — pick the right word for a count using the locale's plural rules (`Intl.PluralRules`), optionally prefixed with the formatted count. The English shorthand takes a singular and an optional plural (default `singular + 's'`); other languages pass a `MkPluralForms` map. Pure: `null`, `undefined`, `''` and non-numeric counts render as `''`. ```html {{ count | mkPluralize:'item' }} {{ count | mkPluralize:'entry':'entries' }} {{ count | mkPluralize:'file':null:{ withCount: false } }} {{ n | mkPluralize:{ one: 'plik', few: 'pliki', many: 'plików', other: 'pliku' }:null:{ locale: 'pl' } }} ``` ### MkRelativeTimePipe (pipe) Pipe name: `mkRelativeTime` · `transform(value: Date | number | string | null | undefined, nowOrOptions?: Date | number | string | MkRelativeTimeOptions | null, options?: MkRelativeTimeOptions): string` Import: `import { MkRelativeTimePipe } from '@mk-kit/ui/directives';` `mkRelativeTime` — "3 minutes ago" / "in 2 days" / "yesterday" from a `Date`, timestamp or ISO string, via `Intl.RelativeTimeFormat` in the `provideMkI18n` locale (no Angular locale data). Pure: `null`, `undefined` and unparsable input render as `''`. The pipe picks the largest unit whose magnitude is at least 1 (seconds → minutes → hours → days → weeks → months → years) and rounds. Pass `now` for deterministic output in tests, or bind a ticking signal to keep a list live — a pure pipe only re-runs when an argument changes. The second argument is either that `now` or the options object, so options alone need no `null` placeholder; the three-argument form (`now`, then options) works too: ```html {{ comment.createdAt | mkRelativeTime }} {{ due | mkRelativeTime:now() }} {{ due | mkRelativeTime:{ style: 'short' } }} {{ ts | mkRelativeTime:{ locale: 'pl', numeric: 'always' } }} {{ due | mkRelativeTime:now():{ style: 'short' } }} ``` ### MkTruncatePipe (pipe) Pipe name: `mkTruncate` · `transform(value: string | null | undefined, length?: number, options?: MkTruncateOptions): string` Import: `import { MkTruncatePipe } from '@mk-kit/ui/directives';` `mkTruncate` — shorten text to `length` characters and append an ellipsis. The ellipsis counts toward the limit, so the output never exceeds `length` characters; counting is grapheme-aware (emoji and accented letters are one character). Text that already fits is returned as-is. Pure: `null` and `undefined` render as `''`. ```html {{ post.body | mkTruncate:80 }} {{ post.body | mkTruncate:80:{ wordBoundary: true } }} {{ hash | mkTruncate:12:{ ellipsis: '...' } }} ``` ### MkHistoryService (service) Docs: https://mk-kit.dev/core-services Import: `import { MkHistoryService } from '@mk-kit/ui/directives';` MkHistoryService — the app-wide `MkHistoryStack` singleton. Inject it anywhere; call `MkHistoryStack.createScope` for an isolated local stack, or wire `mod+z` / `mod+shift+z` / `mod+y` with `registerHistoryHotkeys`. ### Recipe — undoable `mk-table` cell edits Wire the table's `(cellEdit)` output so each saved cell becomes one undoable step. Apply the edit yourself first (`push()` records an action that already happened), and match rows by a stable id — the row object is replaced by the immutable update: ```ts // private readonly history = inject(MkHistoryService); readonly rows = signal([...]); onCellEdit(edit: MkCellEdit): void { const previous = edit.row[edit.key as keyof Order]; const apply = (value: unknown) => this.rows.update((rows) => rows.map((r) => (r.id === edit.row.id ? { ...r, [edit.key]: value } : r)), ); apply(edit.value); // first execution is the caller's job this.history.push({ label: `Edit ${edit.key}`, undo: () => apply(previous), redo: () => apply(edit.value), }); } ``` Undoing replays the old value through the same `apply` function; if your change pipeline re-emits into `onCellEdit` during that replay, the re-entrancy guard drops the spurious `push()` (see `MkHistoryStack`). ### MkHotkeysService (service) Docs: https://mk-kit.dev/components/utilities Import: `import { MkHotkeysService } from '@mk-kit/ui/directives';` MkHotkeysService — app-wide keyboard shortcuts. Register a combo string and a handler; a single `keydown` listener (attached lazily on the first registration, browser only) dispatches to every match. Supports single combos (`'mod+k'`, `'ctrl+shift+p'`, `'?'`) and simple two-step chords (`'g i'`). By default hotkeys are ignored while an editable field is focused — pass `allowInInput` to opt in per registration. ```ts const off = hotkeys.register('mod+k', (e) => openPalette(), { preventDefault: true }); // …later off(); ``` Methods: | Signature | Description | | --- | --- | | `register(combo: string, handler: (e: KeyboardEvent) => void, options?: MkHotkeyOptions): () => void` | Register `combo` → `handler`. Returns a disposer that unregisters it. `combo` may be a single combo or a space-separated two-step chord. | | `unregisterAll(): void` | Remove every registration and detach the listener. | ### MkHistoryStack (class) Import: `import { MkHistoryStack } from '@mk-kit/ui/directives';` MkHistoryStack — a pure, signal-based, linear undo/redo command stack with no Angular DI involved. Instantiate it directly for a local editing session (a dialog, a canvas, a form wizard), or use the app-wide singleton `MkHistoryService`. ```ts const stack = new MkHistoryStack(); deleteRow(row); // 1. do the work yourself stack.push({ // 2. record how to revert/redo it label: 'Delete row', undo: () => insertRow(row), redo: () => deleteRow(row), }); stack.undo(); // row is back ``` ### Linear history `push()` clears the redo branch — after undoing twice and pushing a new entry, the two undone entries are gone (the standard editor model). ### ⚠️ Re-entrancy guard — the classic footgun Pushes made **while** `undo()` or `redo()` is executing are **silently ignored**. Naive consumers often record history from a generic change handler (`(cellEdit)`, `valueChanges`, …); when an undo replays the old value, that same handler fires again and would push a mirror entry, corrupting the stack into an undo/redo ping-pong. The guard makes that pattern safe by construction. If you need to record something new in response to an undo, do it after `undo()` returns. Methods: | Signature | Description | | --- | --- | | `push(entry: MkHistoryEntry): void` | Record an already-performed action. Clears the redo branch and evicts the oldest entry beyond `limit`. Ignored while `undo()`/`redo()` is executing (see the re-entrancy note on the class) — inside a `batch()` the entry is collected into the composite instead. | | `undo(): boolean` | Undo the most recent entry. Returns `false` when there is nothing to undo. | | `redo(): boolean` | Redo the most recently undone entry. Returns `false` when there is nothing to redo. | | `clear(): void` | Drop all entries (both branches) and any in-flight batch collection. | | `batch(label: string, work: () => T): T` | Group every `push()` made during `work()` into **one** undoable step. Undo runs the children in reverse order; redo runs them forward. Nested `batch()` calls flatten into the outermost batch (its label wins). An empty batch records nothing. Returns `work()`'s result; if `work()` throws, entries pushed before the throw are still committed. | | `createScope(): MkHistoryStack` | Create an **independent** stack with the same API — e.g. for a dialog's local editing session that should not pollute the app-wide history. Discard it (or `clear()` it) when the session ends. | Properties: | Name | Type | Description | | --- | --- | --- | | `canUndo` | `Signal` | True when at least one entry can be undone. | | `canRedo` | `Signal` | True when at least one undone entry can be redone. | | `undoLabel` | `Signal` | Label of the entry `undo()` would revert, or `null` ("Undo *Delete row*"). | | `redoLabel` | `Signal` | Label of the entry `redo()` would re-apply, or `null`. | | `size` | `Signal` | Number of undoable entries currently on the stack. | | `limit` | `number` | Maximum number of undoable entries kept (default `100`). When exceeded the **oldest** entries are dropped. Settable at any time; lowering it trims the stack immediately. Values below 1 are clamped to 1. | ### MkPermissionPolicy (class) Docs: https://mk-kit.dev/components/utilities Import: `import { MkPermissionPolicy } from '@mk-kit/ui/directives';` Permission policy — the contract the permission directives (`*mkCan`, `*mkCannot`, `[mkCanDisable]`) check against. Provide an implementation once at bootstrap; the directives inject it optionally and, when no policy is provided at all, treat every permission as **granted** — an app that never wires permissions must not have its whole UI hidden. `can` may return a plain `boolean` (static role checks) or a `Signal` (live permissions). The directives normalise both, and a signal-returning policy re-evaluates reactively: views appear/disappear and controls enable/disable the moment the underlying permissions change. ```ts // A signal-based policy fed from an auth service: Methods: | Signature | Description | | --- | --- | | `can(permission: string): boolean \| Signal` | Whether the current user holds `permission`. Return a `Signal` to make the verdict live; a plain boolean is treated as static. | ### mkApplyMask (function) Import: `import { mkApplyMask } from '@mk-kit/ui/directives';` Format `value` against a mask `pattern`. Pattern tokens: `0` = digit, `A` = letter, `*` = alphanumeric; any other character is a literal that is inserted automatically. Characters that don't fit the current token are skipped, so pasted / mistyped input is coerced into shape. Returns the `masked` (display) string and the `unmasked` string (only the token characters — the value you usually store). ```ts function mkApplyMask(value: string, pattern: string): MkMaskResult ``` ### mkMaskCaret (function) Import: `import { mkMaskCaret } from '@mk-kit/ui/directives';` Compute where the caret belongs after re-masking: after the same number of value (alphanumeric) characters the caret used to sit behind, absorbing any literal(s) that immediately follow — so typing "1" in "(0)" lands the caret after the "(". Shared by `MkMask` and the masked form controls. ```ts function mkMaskCaret(oldValue: string, oldCaret: number, masked: string): number ``` ### mkMatchesHotkey (function) Import: `import { mkMatchesHotkey } from '@mk-kit/ui/directives';` Does a `keydown` event satisfy a hotkey? `combo` may be a raw string (parsed on the fly) or an already-parsed `MkParsedHotkey`. The key is compared case-insensitively; modifier flags must match exactly. `mod` resolves to Meta on macOS and Ctrl elsewhere. Shift is not enforced for symbol keys (e.g. `'?'`), whose shifted state varies by keyboard layout. ```ts function mkMatchesHotkey(event: KeyboardEvent, combo: string | MkParsedHotkey): boolean ``` ### mkParseHotkey (function) Import: `import { mkParseHotkey } from '@mk-kit/ui/directives';` Parse a single hotkey combo (e.g. `'mod+k'`, `'ctrl+shift+p'`, `'?'`) into a structured `MkParsedHotkey`. Tokens are joined by `+`; the last non-modifier token is the trigger key. Pure and SSR-safe. For a chord (space-separated sequence like `'g i'`), split on whitespace and parse each step — `MkHotkeysService` does this for you. ```ts function mkParseHotkey(combo: string): MkParsedHotkey ``` ### mkPermissionGranted (function) Import: `import { mkPermissionGranted } from '@mk-kit/ui/directives';` Resolve a policy verdict to a boolean, unwrapping signal-based results. Call it inside a reactive context (`computed` / `effect`) so a signal-returning policy stays live. A missing policy grants everything. ```ts function mkPermissionGranted(policy: MkPermissionPolicy | null, permission: string): boolean ``` ### registerHistoryHotkeys (function) Import: `import { registerHistoryHotkeys } from '@mk-kit/ui/directives';` Opt-in helper wiring the standard editor shortcuts to a history stack through `MkHotkeysService`: - `mod+z` → `undo()` - `mod+shift+z` **and** `mod+y` → `redo()` Must be called in an **injection context** (constructor, field initializer, or `runInInjectionContext`). Nothing is registered automatically — apps own their shortcuts and call this where (and if) they want them: ```ts export class AppShell { private readonly disposeHistoryKeys = registerHistoryHotkeys(); } ``` Pass a specific stack (e.g. a `createScope()` stack for a dialog) to bind the shortcuts to it instead of the app-wide `MkHistoryService`. Returns a dispose function that unregisters all three shortcuts; it is also called automatically when the current injection context is destroyed. Notes: - `MkHotkeysService` ignores keydowns while an editable element (input/textarea/select/contentEditable) is focused, so native text-field undo keeps working — no extra handling needed here. - The shortcuts register with `preventDefault` so the browser's own history/document undo does not fire alongside yours. ```ts function registerHistoryHotkeys(history?: MkHistoryStack): () => void ``` ### MK_FIELD_PRESETS (const) Import: `import { MK_FIELD_PRESETS } from '@mk-kit/ui/directives';` The attribute bundle per field kind. Exported so hosts can inspect what a kind resolves to, or spread an entry into their own preset table. `autocorrect` (non-standard, honoured by iOS Safari) is set to `off` wherever `spellcheck` is `false`. ```ts const MK_FIELD_PRESETS: Readonly>>>; ``` ### MkCurrencyOptions (interface) Import: `import { MkCurrencyOptions } from '@mk-kit/ui/directives';` Options accepted by `MkCurrencyPipe`. They map onto `Intl.NumberFormat` currency options; `locale` overrides the i18n / runtime locale for this call only. Members: | Name | Type | Description | | --- | --- | --- | | `locale`? | `string \| undefined` | BCP 47 locale for this call; defaults to `provideMkI18n({ locale })`, then the runtime locale. | | `display`? | `"symbol" \| "name" \| "narrowSymbol" \| "code" \| undefined` | How the currency is shown. Default `'symbol'` (`€`, `$`, `zł`). | | `minimumFractionDigits`? | `number \| undefined` | Fraction digits; both default to the currency's own (2 for EUR, 0 for JPY). | | `maximumFractionDigits`? | `number \| undefined` | | | `signDisplay`? | `"auto" \| "never" \| "always" \| "exceptZero" \| undefined` | Sign display, e.g. `'always'` for `+€10.00` or `'exceptZero'`. | | `notation`? | `"compact" \| "standard" \| undefined` | Compact notation for dashboards (`$1.2M`). Default `'standard'`. | | `useGrouping`? | `boolean \| undefined` | Thousands grouping; default `true`. | ### MkFileSizeOptions (interface) Import: `import { MkFileSizeOptions } from '@mk-kit/ui/directives';` Options accepted by `MkFileSizePipe`. Members: | Name | Type | Description | | --- | --- | --- | | `locale`? | `string \| undefined` | BCP 47 locale for the number part (decimal separator); defaults to the i18n / runtime locale. | | `base`? | `"decimal" \| "binary" \| undefined` | `'decimal'` (default) divides by 1000 and labels `kB MB GB …` (what operating systems and file dialogs show); `'binary'` divides by 1024 and labels `KiB MiB GiB …`. | | `digits`? | `number \| undefined` | Maximum fraction digits. Default `1`; bytes never get fractions. | ### MkHistoryEntry (interface) Import: `import { MkHistoryEntry } from '@mk-kit/ui/directives';` A single undoable step recorded in an `MkHistoryStack`. The **first** execution of an action is the caller's job — `push()` records an action that has *already happened*. `undo()` reverts it; `redo()` applies it again after an undo. Members: | Name | Type | Description | | --- | --- | --- | | `label` | `string` | Human label for menus/tooltips ("Delete row", "Move card"). | | `undo` | `(): void` | Revert the action. | | `redo` | `(): void` | Re-apply the action after an undo. | ### MkHotkeyOptions (interface) Import: `import { MkHotkeyOptions } from '@mk-kit/ui/directives';` Options accepted by `MkHotkeysService.register`. Members: | Name | Type | Description | | --- | --- | --- | | `preventDefault`? | `boolean \| undefined` | Call `preventDefault()` on the event when the hotkey fires. Default `false`. | | `allowInInput`? | `boolean \| undefined` | Also fire while a text field (text-like input/textarea/select/contentEditable) is focused. Default `false`. | ### MkMaskResult (interface) Import: `import { MkMaskResult } from '@mk-kit/ui/directives';` Result of applying a mask: the formatted string and its raw token chars. Members: | Name | Type | Description | | --- | --- | --- | | `masked` | `string` | | | `unmasked` | `string` | | ### MkParsedHotkey (interface) Import: `import { MkParsedHotkey } from '@mk-kit/ui/directives';` A single hotkey combo parsed into a normalized key + modifier flags. Produced by `mkParseHotkey`; consumed by `mkMatchesHotkey`. Members: | Name | Type | Description | | --- | --- | --- | | `key` | `string` | The non-modifier key, lowercased and alias-normalized (e.g. `k`, `escape`, `?`). | | `mod` | `boolean` | `mod` — Cmd on macOS, Ctrl elsewhere. | | `ctrl` | `boolean` | The Control key. | | `meta` | `boolean` | The Meta / Command / Windows key. | | `alt` | `boolean` | The Alt / Option key. | | `shift` | `boolean` | The Shift key. | ### MkPluralizeOptions (interface) Import: `import { MkPluralizeOptions } from '@mk-kit/ui/directives';` Options accepted by `MkPluralizePipe`. Members: | Name | Type | Description | | --- | --- | --- | | `locale`? | `string \| undefined` | BCP 47 locale for the plural rules and number; defaults to the i18n / runtime locale. | | `withCount`? | `boolean \| undefined` | Prefix the formatted count (`"3 items"`); `false` gives just the word. Default `true`. | ### MkRelativeTimeOptions (interface) Import: `import { MkRelativeTimeOptions } from '@mk-kit/ui/directives';` Options accepted by `MkRelativeTimePipe`. Members: | Name | Type | Description | | --- | --- | --- | | `locale`? | `string \| undefined` | BCP 47 locale for this call; defaults to `provideMkI18n({ locale })`, then the runtime locale. | | `numeric`? | `"auto" \| "always" \| undefined` | `'auto'` (default) uses phrases like "yesterday" / "now" where the locale has them; `'always'` sticks to "1 day ago" / "in 0 seconds". | | `style`? | `"long" \| "short" \| "narrow" \| undefined` | Length of the unit word: `'long'` (default, "minutes"), `'short'` ("min."), `'narrow'` ("m"). | | `maxUnit`? | `Intl.RelativeTimeFormatUnit \| undefined` | Largest unit to use. Default `'year'`; e.g. `'day'` keeps "45 days ago" instead of "1 month ago". | ### MkTruncateOptions (interface) Import: `import { MkTruncateOptions } from '@mk-kit/ui/directives';` Options accepted by `MkTruncatePipe`. Members: | Name | Type | Description | | --- | --- | --- | | `ellipsis`? | `string \| undefined` | Suffix appended when text is cut. Default `'…'` (a single ellipsis character). | | `wordBoundary`? | `boolean \| undefined` | Cut at the last whitespace before the limit instead of mid-word (falls back to a hard cut when the first word alone is longer). Default `false`. | ### MkFieldKind (type) Import: `import { MkFieldKind } from '@mk-kit/ui/directives';` Semantic field kinds understood by `MkField`. ```ts type MkFieldKind = | 'email' | 'tel' | 'url' | 'search' | 'numeric' | 'given-name' | 'family-name' | 'name' | 'organization' | 'street' | 'address-line1' | 'address-line2' | 'city' | 'region' | 'country' | 'postal-code' | 'username' | 'one-time-code'; ``` ### MkFieldPreset (type) Import: `import { MkFieldPreset } from '@mk-kit/ui/directives';` The attribute bundle applied for one `MkFieldKind`. Omitted = not set. ```ts type MkFieldPreset = Partial>; ``` ### MkPluralForms (type) Import: `import { MkPluralForms } from '@mk-kit/ui/directives';` Per-category word forms for `MkPluralizePipe`, keyed by the CLDR plural categories `Intl.PluralRules` returns. `other` is required; the pipe falls back to it for any category you leave out. ```ts const files: MkPluralForms = { one: 'plik', few: 'pliki', many: 'plików', other: 'pliku' }; ``` ```ts type MkPluralForms = { other: string } & Partial>; ``` ## @mk-kit/ui/dnd 13 exports. `import { … } from '@mk-kit/ui/dnd';` ### MkDrag (component) Selector: `[mkDrag]` · exportAs: `mkDrag` Docs: https://mk-kit.dev/components/drag-drop Import: `import { MkDrag } from '@mk-kit/ui/dnd';` Makes an item inside a `[mkDropList]` draggable — by pointer (mouse / touch / pen) **and** by keyboard (WCAG 2.1.1). Every move is announced via `MkLiveAnnouncer`. Which element carries the keyboard interaction depends on the handle: - **No handle, or a decorative one** (``): the item itself is focusable and exposes `aria-roledescription="Draggable item"` with `role="button"` — or `role="option"` when it is an `
  • ` of a `
      `, which then becomes a labelled `listbox` (an `
    • ` may not take the `button` role). - **A focusable handle** (`
    • ``` Methods: | Signature | Description | | --- | --- | | `isFocusable(): boolean` | Whether the handle can take keyboard focus itself — a native control (`
  • … ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `sidebarOpen` (two-way) | `boolean` | `false` | Whether the mobile drawer is open (two-way). | | `sidebarCollapsed` (two-way) | `boolean` | `false` | Whether the desktop sidebar is collapsed to icons (two-way). | Outputs: | Name | Type | Description | | --- | --- | --- | | `sidebarOpenChange` | `boolean` | Emits when `sidebarOpen` changes (two-way binding). | | `sidebarCollapsedChange` | `boolean` | Emits when `sidebarCollapsed` changes (two-way binding). | Methods: | Signature | Description | | --- | --- | | `toggleSidebar(): void` | Toggle the mobile drawer open/closed. Handy for a hamburger button. | | `openSidebar(): void` | Open the mobile drawer. | | `closeSidebar(): void` | Close the mobile drawer. | | `toggleCollapsed(): void` | Toggle the desktop collapsed (icon-only) state. | Properties: | Name | Type | Description | | --- | --- | --- | | `isMobile` | `WritableSignal` | True when the viewport is at/below the mobile breakpoint. | ### MkAppSwitcher (component) Selector: `mk-app-switcher` · exportAs: `mkAppSwitcher` Docs: https://mk-kit.dev/components/navigation Import: `import { MkAppSwitcher } from '@mk-kit/ui/navigation';` The "apps grid" of a family of applications: a header button that opens a grid of links to the other apps, the current one marked. Give it the list (`apps`) or a registry to fetch it from (`src` — JSON, either an array or `{ apps: [...] }`), so every app of a suite shows the same switcher from one shared file. ```html ``` The registry is fetched lazily, the first time the panel opens, and once per page. The panel is a disclosure (a labelled group of links, not a menu): Tab moves through the tiles, arrows too, Escape closes and returns focus. Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `apps` | `MkAppLink[]` | `[]` | The apps, when the host has the list. | | `src` | `string` | `''` | A registry URL to fetch the apps from (JSON: an array or `{ apps }`). Used when `apps` is empty. | | `current` | `string` | `''` | The app this switcher is shown in — its `id` or `url`; marked as current and listed first. | | `label` | `string` | `''` | Accessible name of the trigger. Defaults to the i18n `appSwitcherLabel`. | | `columns` | `number` | `3` | Tiles per row. | | `newTab` | `boolean` | `false` | Open links in a new tab. | Outputs: | Name | Type | Description | | --- | --- | --- | | `openChange` | `boolean` | Emits when the panel opens or closes. | Methods: | Signature | Description | | --- | --- | | `toggle(): void` | | | `show(): void` | | | `close(restoreFocus?: boolean): void` | | ### MkBackToTop (component) Selector: `mk-back-to-top` Docs: https://mk-kit.dev/components/navigation Import: `import { MkBackToTop } from '@mk-kit/ui/navigation';` BackToTop — a floating button that appears once the page (or a scroll target) has scrolled past `threshold`, and smooth-scrolls back to the top on click. ```html ``` Pass `[target]` to watch/scroll a specific scroll container instead of the window. Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `threshold` | `number` | `400` | Scroll distance (px) before the button appears. | | `target` | `HTMLElement \| null` | `null` | Optional scroll container; defaults to the window. | | `ariaLabel` | `string` | `this.i18n.backToTop` | Accessible label. | | `smooth` | `boolean` | `true` | Smooth-scroll on click. Ignored under `prefers-reduced-motion: reduce` (programmatic `scrollTo` is not toned down by browsers, so the component falls back to an instant jump itself). | ### MkBreadcrumb (component) Selector: `mk-breadcrumb` Docs: https://mk-kit.dev/components/navigation Import: `import { MkBreadcrumb } from '@mk-kit/ui/navigation';` Breadcrumb trail. Renders `nav[aria-label="Breadcrumb"] > ol` and marks the final `` as the current page. The separator is drawn in CSS and can be customised via `separator`. ```html Home Users Jane ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `label` | `string` | `this.i18n.breadcrumbLabel` | Accessible label for the navigation landmark. | | `separator` | `string` | `'/'` | Separator character rendered between crumbs. | ### MkBreadcrumbItem (component) Selector: `mk-breadcrumb-item` Docs: https://mk-kit.dev/components/navigation Import: `import { MkBreadcrumbItem } from '@mk-kit/ui/navigation';` A single crumb inside ``. Renders a link when `href` is set, otherwise plain text. The last item is automatically marked `aria-current="page"` by the parent. ```html Home Current page ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `href` | `string \| undefined` | | Optional link target. Rendered as text when omitted or when it is last. | Properties: | Name | Type | Description | | --- | --- | --- | | `last` | `WritableSignal` | Whether this is the final crumb. Set by the parent `MkBreadcrumb`. | ### MkCommandPalette (component) Selector: `mk-command-palette` Docs: https://mk-kit.dev/components/command-nav Import: `import { MkCommandPalette } from '@mk-kit/ui/navigation';` CommandPalette — a modal ⌘K/Ctrl+K menu for fast, keyboard-first actions and navigation. Supply a flat `commands` list (optionally grouped); the palette filters as you type, groups results, and runs the chosen command. Implements the ARIA combobox + listbox pattern with full keyboard support and focus trapping. Mount it once near your app root and bind `open` (the built-in hotkey toggles it, or open it yourself). ```html ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `open` (two-way) | `boolean` | `false` | Whether the palette is open (two-way). | | `commands` | `readonly MkCommand[]` | `[]` | The commands to search and run. | | `placeholder` | `string` | `this.i18n.commandPalettePlaceholder` | Search field placeholder. | | `emptyMessage` | `string` | `this.i18n.noResults` | Message shown when nothing matches. | | `hotkey` | `boolean` | `true` | Toggle open with ⌘K / Ctrl+K anywhere. | Outputs: | Name | Type | Description | | --- | --- | --- | | `openChange` | `boolean` | Emits when `open` changes (two-way binding). | | `commandSelected` | `MkCommand` | Emits the chosen command (its own `run` callback also fires). | ### MkDrawer (component) Selector: `mk-drawer` Docs: https://mk-kit.dev/components/drawer Import: `import { MkDrawer } from '@mk-kit/ui/navigation';` Drawer — a declarative slide-out panel anchored to a viewport edge, driven by a two-way `open`. Ideal for admin/CMS side panels: filters, entity details, settings, quick-create forms. Traps focus while open, closes on backdrop click or Escape, restores focus on close, and locks body scroll when modal. Slots: `[mkDrawerHeader]` (extra header content), default content (body), `[mkDrawerFooter]` (sticky footer). ```html …filter form…
    ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `open` (two-way) | `boolean` | `false` | Whether the drawer is open (two-way). | | `side` | `MkDrawerSide` | `'end'` | Viewport edge to anchor to. | | `size` | `string` | `'20rem'` | Panel width (start/end) or height (top/bottom) — any CSS length. | | `hasBackdrop` | `boolean` | `true` | Render a dimmed backdrop and lock body scroll (modal). | | `closeOnBackdrop` | `boolean` | `true` | Close when the backdrop is clicked. | | `closeOnEscape` | `boolean` | `true` | Close on the Escape key. | | `trapFocus` | `boolean` | `true` | Trap Tab focus inside the panel while open. | | `heading` | `string` | `''` | Optional heading rendered in the header. | | `hideClose` | `boolean` | `false` | Hide the header close button. | | `aria-label` | `string` | `''` | Accessible name when no `heading` is provided. | Outputs: | Name | Type | Description | | --- | --- | --- | | `openChange` | `boolean` | Emits when `open` changes (two-way binding). | Methods: | Signature | Description | | --- | --- | | `close(): void` | Close the drawer. | ### MkFab (component) Selector: `mk-fab` Docs: https://mk-kit.dev/components/navigation Import: `import { MkFab } from '@mk-kit/ui/navigation';` FAB — a floating action button, fixed to a corner (or `static` for inline use). Project the icon as content and set `label` for the accessible name (shown too when `extended`). Add `mkFabAction` buttons to turn it into a speed-dial that reveals them on toggle. ```html … ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `position` | `MkFabPosition` | `'bottom-end'` | Corner placement (or `static` to render inline). | | `tone` | `MkTone` | `'primary'` | Semantic tone. | | `size` | `MkSize` | `'md'` | Size scale. | | `label` | `string` | `this.i18n.fabLabel` | Accessible label (and visible text when `extended`). | | `extended` | `boolean` | `false` | Render as a pill with the label beside the icon. | | `disabled` | `boolean` | `false` | Disable the button. | | `open` (two-way) | `boolean` | `false` | Two-way open state of the speed-dial. | Outputs: | Name | Type | Description | | --- | --- | --- | | `openChange` | `boolean` | Emits when `open` changes (two-way binding). | | `action` | `void` | Emitted when the FAB is activated (only when it has no actions). | ### MkMenu (component) Selector: `mk-menu` · exportAs: `mkMenu` Docs: https://mk-kit.dev/components/navigation Import: `import { MkMenu } from '@mk-kit/ui/navigation';` Dropdown menu implementing the ARIA menu pattern (roving focus, Arrow / Home / End / typeahead, Enter/Space to activate). Attach it to a trigger with the `mkMenuTriggerFor` directive; the trigger controls opening and positioning. The panel is rendered in the browser top layer via `MkAnchoredPanel`, so it is never clipped by an ancestor's `overflow`/`transform` and always flips back on-screen near a viewport edge. ```html Edit Delete ``` **Submenus.** Point an item at a nested menu with `[mkSubmenuFor]`; declare the nested `` anywhere inside the parent menu. The submenu opens beside its item on hover (after a short delay), on ArrowRight / Enter / Space / click, and closes with ArrowLeft or Escape (returning focus to the item) — only that level, per the APG menu pattern. Activating any leaf item closes the whole chain. In RTL the submenu opens on the left and the arrow keys swap. ```html Export CSV PDF ``` Methods: | Signature | Description | | --- | --- | | `open(trigger: HTMLElement, focus?: boolean \| "first" \| "last", placement?: MkPlacement): void` | Open the menu anchored to `trigger`. `focus` picks the item that receives focus once the panel is painted: `true`/`'first'` for the first enabled item, `'last'` for the last (ArrowUp on a menu button, per the APG menu-button pattern), `false` to leave focus where it is (mouse open). `placement` overrides the default `bottom-start` (submenus pass `right-start` / `left-start`). | | `openAt(x: number, y: number, restoreFocusEl?: HTMLElement): void` | Open the menu at viewport coordinates — e.g. a right-click point from a `contextmenu` event. Positioning (and flip/shift back on-screen) is handled by `MkAnchoredPanel` via the point anchor. Focus moves to the first item; `restoreFocusEl` (when provided) regains focus on close. | | `close(restoreFocus?: boolean): void` | Close this menu (and any submenu open under it); optionally restore focus to the trigger — for a submenu that is the item it hangs off. | | `closeAll(restoreFocus?: boolean): void` | Close the whole menu chain from the root down — what activating a leaf item does, wherever in the tree it sits. Focus returns to the root trigger when `restoreFocus` is set. | | `closeChildren(keep?: MkMenu): void` | Close every submenu open under this menu, except `keep`. | | `toggle(trigger: HTMLElement, focusFirst?: boolean): void` | Toggle open/closed from a trigger. | | `focusFirstItem(): void` | Move focus to the first enabled item. Used by the trigger when the menu is already open (e.g. ArrowDown after a mouse open), so arrow keys always reach the items even though focus never left the trigger. | | `focusLastItem(): void` | Move focus to the last enabled item (ArrowUp from the trigger). | | `containsTarget(node: Node \| null): boolean` | Whether `node` lives inside this menu's panel or any submenu open under it. Submenu panels are separate top-layer elements, so a plain `contains` on the parent panel would treat clicks in them as outside. | | `itemHovered(item: MkMenuItem): void` | An item was hovered: close sibling submenus so only the hovered branch stays open (the item opens its own submenu after a delay). | | `submenuPlacement(): MkPlacement` | Placement for a submenu hanging off `item`, honouring text direction. | Properties: | Name | Type | Description | | --- | --- | --- | | `panelId` | `string` | Stable id for `aria-controls` on the trigger. | | `opened` | `Signal` | Whether the menu is currently open. | | `ariaLabel` | `WritableSignal` | Accessible label for the menu (defaults via the trigger if unset). | | `isSubmenu` | `boolean` | Whether this menu is a submenu of another `mk-menu`. Submenus open sideways, close a single level on Escape, and swap ArrowLeft/ArrowRight. | ### MkMenuItem (component) Selector: `mk-menu-item` Docs: https://mk-kit.dev/components/navigation Import: `import { MkMenuItem } from '@mk-kit/ui/navigation';` An item within an ``. Renders as an ARIA `menuitem` with an optional icon slot (`[mkMenuItemIcon]`), disabled and danger states, and either emits `action` or navigates when `href` is set. Activating closes the menu. With `[mkSubmenuFor]` pointing at a nested `` the item becomes a submenu trigger instead: it shows a chevron, exposes `aria-haspopup` / `aria-expanded`, opens the submenu beside itself on hover, ArrowRight, Enter, Space or click, and never emits `action`. ```html … Rename Delete Help More ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `disabled` | `boolean` | `false` | Prevent selection and focus. | | `danger` | `boolean` | `false` | Destructive styling (e.g. Delete). | | `href` | `string \| undefined` | | When set, activating the item navigates here. | | `mkSubmenuFor` | `MkMenu \| undefined` | `undefined` | A nested `mk-menu` this item opens as a submenu. | Outputs: | Name | Type | Description | | --- | --- | --- | | `action` | `void` | Emitted when the item is activated (not for disabled or submenu items). | Methods: | Signature | Description | | --- | --- | | `activate(event?: Event): void` | | | `openSubmenu(focus: boolean): void` | Open the submenu beside this item; `focus` moves focus to its first item. | | `focusEl(): void` | Move DOM focus to this item (roving focus). | | `contains(node: Node \| null): boolean` | Whether `node` lives inside this item. | | `text(): string` | Lowercased text content, used for typeahead matching. | ### MkNavGroup (component) Selector: `mk-nav-group` Docs: https://mk-kit.dev/components/command-nav Import: `import { MkNavGroup } from '@mk-kit/ui/navigation';` A titled section within an `` — the "MAIN" / "SETTINGS" groupings common in admin/CMS sidebars. Static by default; set `collapsible` to make the label a toggle that expands/collapses its items (`aria-expanded` + region). In a collapsed icon rail the label becomes a divider. ```html ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `label` | `string` | `''` | Section title. | | `collapsible` | `boolean` | `false` | Make the label a toggle that shows/hides the items. | | `expanded` (two-way) | `boolean` | `true` | Whether the section is expanded (two-way; only meaningful when collapsible). | Outputs: | Name | Type | Description | | --- | --- | --- | | `expandedChange` | `boolean` | Emits when `expanded` changes (two-way binding). | Properties: | Name | Type | Description | | --- | --- | --- | | `regionId` | `string` | Id of the items region (for `aria-controls`). | | `headerId` | `string` | Id of the header, used to name the nested item list. | ### MkNavItem (component) Selector: `mk-nav-item` Docs: https://mk-kit.dev/components/command-nav Import: `import { MkNavItem } from '@mk-kit/ui/navigation';` A single sidebar entry: icon slot (`[mkNavIcon]`), label, optional badge and active state. Renders a link when `href` is set, otherwise a button that emits `action`. If it contains nested ``s it becomes an expandable disclosure (`aria-expanded`). Collapses to an icon in a collapsed list, exposing the label as a tooltip — and because a sub-list can't be shown at rail width, a parent item there emits `action` (navigate) instead of toggling, so it never becomes a dead button. ```html … … ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `label` | `string` | `''` | Visible label. Also used as the tooltip when collapsed. | | `href` | `string \| undefined` | | Link target. Renders an anchor instead of a button. | | `active` | `boolean` | `false` | Marks the current page (`aria-current="page"`). | | `disabled` | `boolean` | `false` | Disable interaction. | | `badge` | `string \| number \| undefined` | | Optional badge (count or short text). | | `expanded` (two-way) | `boolean` | `false` | Whether nested children are expanded (two-way). | Outputs: | Name | Type | Description | | --- | --- | --- | | `expandedChange` | `boolean` | Emits when `expanded` changes (two-way binding). | | `action` | `void` | Emitted when a button-style item is activated. | ### MkNavList (component) Selector: `mk-nav-list` Docs: https://mk-kit.dev/components/command-nav Import: `import { MkNavList } from '@mk-kit/ui/navigation';` Sidebar navigation list. Hosts ``s and, when `collapsed`, drives them into an icon-only rail (labels hidden, exposed via `title` tooltips). Designed to sit inside the `mkAppSidebar` slot of ``. ```html … ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `collapsed` | `boolean` | `false` | Collapse items to icon-only. Read by descendant `MkNavItem`s. | ### MkPageHeader (component) Selector: `mk-page-header` Docs: https://mk-kit.dev/components/structure Import: `import { MkPageHeader } from '@mk-kit/ui/navigation';` PageHeader — the standard heading block at the top of an admin/CMS page: an optional breadcrumb, a page title with optional description and inline meta (badges/status), a right-aligned actions cluster, and an optional tab row beneath. Everything but the title/description is projected, so it composes with `mk-breadcrumb`, `mk-tabs`, buttons, badges, etc. Slots: `[mkPageHeaderBreadcrumb]`, `[mkPageHeaderMeta]` (beside the title), `[mkPageHeaderActions]` (right), `[mkPageHeaderTabs]` (below). ```html Live
    ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `heading` | `string` | `''` | The page title (rendered as an `

    `). | | `description` | `string` | `''` | Supporting description under the title. | ### MkPagination (component) Selector: `mk-pagination` Docs: https://mk-kit.dev/components/navigation Import: `import { MkPagination } from '@mk-kit/ui/navigation';` Page navigation with previous/next controls and numbered pages that collapse to ellipses for large ranges. Provide either `total` (+ `pageSize`) or a direct `pageCount`. `page` is 1-based and two-way bindable. ```html ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `total` | `number` | `0` | Total number of items (used with `pageSize` when `pageCount` is unset). | | `pageSize` | `number` | `10` | Items per page. | | `pageCount` | `number` | `0` | Explicit page count; overrides `total`/`pageSize` when > 0. | | `page` (two-way) | `number` | `1` | Current 1-based page (two-way). | | `siblingCount` | `number` | `1` | Number of page buttons to keep on each side of the current page. | | `boundaryCount` | `number` | `1` | Number of page buttons pinned at each end. | | `label` | `string` | `this.i18n.paginationLabel` | Accessible label for the navigation landmark. | Outputs: | Name | Type | Description | | --- | --- | --- | | `pageChange` | `number` | Emits when `page` changes (two-way binding). | ### MkScrollArea (component) Selector: `mk-scroll-area` Docs: https://mk-kit.dev/components/structure Import: `import { MkScrollArea } from '@mk-kit/ui/navigation';` ScrollArea — a scroll container that hides the native scrollbar and renders its own themed overlay bars (à la Radix ScrollArea). The projected content scrolls inside a real, keyboard-focusable viewport, so native wheel / arrow scrolling keeps working; the custom bars are decorative (`aria-hidden`) and draggable. ```html

    …lots of content…

    ``` Set `orientation` to `horizontal` / `both` for a horizontal bar, and `hideDelay` to auto-hide the bars after inactivity (`0` = always visible). Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `maxHeight` | `string` | `''` | Optional CSS max-height for the viewport, e.g. `'20rem'`. | | `ariaLabel` | `string` | `''` | Accessible name for the scrollable viewport. When set, the viewport is exposed as a labelled `region` landmark — recommended, since the viewport is keyboard-focusable (`tabindex="0"`) and a focusable scroll container should have an accessible name. When empty, no role / label is added. | | `orientation` | `MkScrollAreaOrientation` | `'vertical'` | Which axes render a custom bar. | | `hideDelay` | `number` | `1000` | Auto-hide the bars after this many ms of inactivity (`0` = always on). | ### MkSplitButton (component) Selector: `mk-split-button` Docs: https://mk-kit.dev/components/buttons Import: `import { MkSplitButton } from '@mk-kit/ui/navigation';` SplitButton — a primary action with an attached menu of alternatives. The main segment emits `action`; the chevron segment is a menu button (`mkMenuTriggerFor`) for the `mk-menu` passed in `[menu]`, with the full keyboard model of the menu trigger (ArrowDown / Enter / Space open and focus the first item, ArrowUp the last, Escape closes). Both segments share `variant`, `tone` and `size`; `disabled` disables both, `loading` shows the main segment's spinner and disables the chevron. ```html Save Save as… Save as template ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `menu` (required) | `MkMenu` | | The menu the chevron segment opens. | | `variant` | `MkVariant` | `'solid'` | Visual treatment shared by both segments. | | `tone` | `MkTone` | `'primary'` | Semantic color tone shared by both segments. | | `size` | `MkSize` | `'md'` | Control size shared by both segments. | | `disabled` | `boolean` | `false` | Disable both segments. | | `loading` | `boolean` | `false` | Spinner on the main segment; the menu segment is disabled meanwhile. | | `fullWidth` | `boolean` | `false` | Stretch to the container width (the main segment grows). | | `type` | `"submit" \| "button"` | `'button'` | `type` of the main segment — `submit` to submit the enclosing form. | | `menuLabel` | `string` | `this.i18n.moreActions` | Accessible name of the chevron segment. | Outputs: | Name | Type | Description | | --- | --- | --- | | `action` | `void` | Emitted when the main segment is activated (not while disabled/loading). | ### MkSplitter (component) Selector: `mk-splitter` Docs: https://mk-kit.dev/components/structure Import: `import { MkSplitter } from '@mk-kit/ui/navigation';` Splitter — two resizable panes with a draggable, keyboard-operable separator (ARIA `separator` with `aria-valuenow`). `horizontal` places the panes side-by-side (a vertical handle); `vertical` stacks them (a horizontal handle). The start pane's size is a two-way `position` model (percent). Project the panes with `mkSplitterStart` / `mkSplitterEnd`: ```html
    …
    ``` Drag the handle, or focus it and use Arrow keys (Home/End jump to min/max). Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `orientation` | `MkSplitterOrientation` | `'horizontal'` | `horizontal` = side-by-side; `vertical` = stacked. | | `position` (two-way) | `number` | `50` | Two-way position of the separator = start-pane size, in percent (0–100). | | `min` | `number` | `10` | Minimum start-pane size (percent). | | `max` | `number` | `90` | Maximum start-pane size (percent). | | `step` | `number` | `5` | Keyboard resize increment (percent). | | `disabled` | `boolean` | `false` | Disable resizing. | | `ariaLabel` | `string` | `this.i18n.resizePanes` | Accessible label for the separator. | Outputs: | Name | Type | Description | | --- | --- | --- | | `positionChange` | `number` | Emits when `position` changes (two-way binding). | ### MkStep (component) Selector: `mk-step` Docs: https://mk-kit.dev/components/stepper Import: `import { MkStep } from '@mk-kit/ui/navigation';` A single step + its content panel. Declared inside ``; the projected content becomes the step body while `label` (and optional `description`) render in the step header. `completed` is a two-way model so a parent can gate a `linear` stepper: ``. ```html … … ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `label` | `string` | `''` | Title shown in the step header. | | `description` | `string` | `''` | Optional secondary line under the label. | | `optional` | `boolean` | `false` | Marks the step optional (skippable in a `linear` stepper). | | `completed` (two-way) | `boolean` | `false` | Whether the step is complete (two-way; drives `linear` gating + the ✓). | | `hasError` | `boolean` | `false` | Show the error state in the header (e.g. failed validation). | | `editable` | `boolean` | `true` | Allow returning to this step after it is completed. | Outputs: | Name | Type | Description | | --- | --- | --- | | `completedChange` | `boolean` | Emits when `completed` changes (two-way binding). | Properties: | Name | Type | Description | | --- | --- | --- | | `headerId` | `string` | Stable id for the header button (wires `aria-labelledby`). | | `panelId` | `string` | Stable id for the panel (wires `aria-controls`). | | `active` | `WritableSignal` | Whether this step is currently selected. Set by the parent `MkStepper`. | ### MkStepper (component) Selector: `mk-stepper` Docs: https://mk-kit.dev/components/stepper Import: `import { MkStepper } from '@mk-kit/ui/navigation';` Stepper — walks a user through an ordered sequence of ``s with an accessible header rail (ARIA `tablist` + roving tabindex, Arrow/Home/End navigation) and a single visible panel. In `linear` mode a step is only reachable once every preceding required (non-`optional`) step reports `completed`. Drive completion from your form state and move with the `next()` / `previous()` / `reset()` API or by clicking a reachable header. ```html … … … ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `selectedIndex` (two-way) | `number` | `0` | Zero-based index of the active step (two-way). | | `orientation` | `MkStepperOrientation` | `'horizontal'` | Header rail orientation. | | `linear` | `boolean` | `false` | Enforce sequential completion before a step becomes reachable. | Outputs: | Name | Type | Description | | --- | --- | --- | | `selectedIndexChange` | `number` | Emits when `selectedIndex` changes (two-way binding). | | `selectionChange` | `number` | Emits the newly selected index whenever the active step changes. | Methods: | Signature | Description | | --- | --- | | `isReachable(index: number): boolean` | Whether a step can be selected. In linear mode every earlier required step must be completed; a completed step is reachable only when `editable`. | | `next(): void` | Advance to the next reachable step, if any. | | `previous(): void` | Return to the previous step, if any. | | `reset(): void` | Reset to the first step and clear every step's completed flag. | ### MkTab (component) Selector: `mk-tab` Docs: https://mk-kit.dev/components/navigation Import: `import { MkTab } from '@mk-kit/ui/navigation';` A single tab + its panel. Declared inside ``; the projected content becomes the tab panel body while `label` is rendered in the tablist. ```html …panel content… … ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `label` | `string` | `''` | Text shown on the tab button in the tablist. | | `disabled` | `boolean` | `false` | Disable selection of this tab. | Properties: | Name | Type | Description | | --- | --- | --- | | `tabId` | `string` | Stable id for the tab button (wires `aria-labelledby`). | | `panelId` | `string` | Stable id for the panel (wires `aria-controls`). | | `active` | `WritableSignal` | Whether this tab is currently selected. Set by the parent `MkTabs`. | ### MkTabs (component) Selector: `mk-tabs` Docs: https://mk-kit.dev/components/navigation Import: `import { MkTabs } from '@mk-kit/ui/navigation';` Accessible tabs implementing the ARIA tabs pattern: a `role="tablist"` with roving tabindex, Arrow/Home/End keyboard navigation and an animated active indicator. Selection is two-way bindable via `selectedIndex`. ```html … … ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `selectedIndex` (two-way) | `number` | `0` | Zero-based index of the active tab (two-way). | | `variant` | `MkTabsVariant` | `'line'` | `line` shows an underline indicator; `pill` uses filled pills. | Outputs: | Name | Type | Description | | --- | --- | --- | | `selectedIndexChange` | `number` | Emits when `selectedIndex` changes (two-way binding). | ### MkToolbar (component) Selector: `mk-toolbar` Docs: https://mk-kit.dev/components/structure Import: `import { MkToolbar } from '@mk-kit/ui/navigation';` Toolbar — a horizontal action bar: content flows on the start side, anything marked `mkToolbarEnd` is pushed to the end. Handy above tables and lists for a title/search on the left and actions on the right. The projected controls are ordinary tab stops (no roving focus), so this is a layout container, not an ARIA `toolbar` widget. ```html Users ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `bordered` | `boolean` | `false` | Wrap the bar in a themed, bordered surface. | | `aria-label` | `string` | `''` | Accessible name (also promotes the bar to an ARIA `group`). | ### MkTree (component) Selector: `mk-tree` Docs: https://mk-kit.dev/components/tree Import: `import { MkTree } from '@mk-kit/ui/navigation';` Tree — renders hierarchical data following the ARIA tree pattern (`role="tree"` / `treeitem` with `aria-level`, `aria-expanded`, `aria-selected`). Supply `nodes`; expansion is managed internally. Keyboard: Up/Down move between visible rows, Right expands (or steps into the first child), Left collapses (or steps out to the parent), Home/End jump, and Enter/Space toggles expansion and selects (when `selectable`). A single roving tabindex keeps the whole tree one tab stop. ```html ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `nodes` | `readonly MkTreeNode[]` | `[]` | The hierarchical data to render. | | `selectable` | `boolean` | `false` | Allow choosing a node (adds selection styling + `aria-selected`). | | `aria-label` | `string` | `''` | Accessible name for the tree. | | `selected` (two-way) | `unknown` | `null` | Two-way selected value (a node's `value`, or the node itself if unset). | Outputs: | Name | Type | Description | | --- | --- | --- | | `selectedChange` | `unknown` | Emits when `selected` changes (two-way binding). | | `selectionChange` | `unknown` | Emits the selected value whenever the selection changes. | | `nodeToggle` | `MkTreeNode` | Emits a node whenever it is expanded or collapsed. | ### MkAccordionHeader (directive) Selector: `[mkAccordionHeader]` Import: `import { MkAccordionHeader } from '@mk-kit/ui/navigation';` Marks projected content as the header of an ``. Use when the header needs rich markup instead of the plain-text `header` input. ```html Account …body… ``` ### MkFabAction (directive) Selector: `[mkFabAction]` Docs: https://mk-kit.dev/components/navigation Import: `import { MkFabAction } from '@mk-kit/ui/navigation';` A speed-dial action button projected into `MkFab`. ### MkMenuTrigger (directive) Selector: `[mkMenuTriggerFor]` · exportAs: `mkMenuTrigger` Docs: https://mk-kit.dev/components/navigation Import: `import { MkMenuTrigger } from '@mk-kit/ui/navigation';` Turns its host button into a trigger for an ``. Wires `aria-haspopup="menu"` / `aria-expanded` / `aria-controls`, toggles on click, opens on ArrowDown / Enter / Space (focusing the first item) and on ArrowUp (focusing the last item, per the APG menu-button pattern), and closes on Escape. When the menu is already open — e.g. after a mouse click, which deliberately leaves focus on the trigger — ArrowDown moves focus to the first item and ArrowUp to the last, so the keyboard is never dead. ```html … ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `mkMenuTriggerFor` (required) | `MkMenu` | | The menu instance to control. | ### MkAppLink (interface) Import: `import { MkAppLink } from '@mk-kit/ui/navigation';` One app in the switcher. Members: | Name | Type | Description | | --- | --- | --- | | `id` | `string` | Stable id; `current` matches on it (or on `url`). | | `name` | `string` | | | `url` | `string` | | | `description`? | `string \| undefined` | One line under the name. | | `icon`? | `string \| undefined` | A short glyph for the tile — an emoji or one or two letters. Defaults to the name's initial. | | `color`? | `string \| undefined` | Tile colour; any CSS colour. Defaults to the primary tone. | ### MkCommand (interface) Import: `import { MkCommand } from '@mk-kit/ui/navigation';` A single actionable entry in the `MkCommandPalette`. Members: | Name | Type | Description | | --- | --- | --- | | `id` | `string` | Stable unique id. | | `label` | `string` | Text shown (and the primary search target). | | `group`? | `string \| undefined` | Optional section heading this command is grouped under. | | `hint`? | `string \| undefined` | Secondary text shown after the label. | | `icon`? | `string \| undefined` | Name of a registered icon (see `MkIconRegistry`). | | `keywords`? | `string \| undefined` | Extra search terms (not shown). | | `shortcut`? | `string \| undefined` | Display-only shortcut hint, e.g. `⌘S`. | | `disabled`? | `boolean \| undefined` | Disable the command (skipped by keyboard, not runnable). | | `run`? | `(() => void) \| undefined` | Invoked when the command is chosen. | ### MkTreeNode (interface) Import: `import { MkTreeNode } from '@mk-kit/ui/navigation';` A node in an `MkTree`. `children` makes it expandable. Members: | Name | Type | Description | | --- | --- | --- | | `label` | `string` | Text shown for the node. | | `value`? | `unknown` | Value bound to the selection when the node is chosen (defaults to the node). | | `children`? | `MkTreeNode[] \| undefined` | Child nodes; a non-empty array makes the node a parent (expandable). | | `disabled`? | `boolean \| undefined` | Disable selection/toggling of this node (still focusable). | | `expanded`? | `boolean \| undefined` | Expand this node initially. | | `icon`? | `string \| undefined` | Optional leading glyph (any short string / emoji). | | `iconName`? | `string \| undefined` | Name of a registered icon (see `MkIconRegistry`), rendered with `mk-icon`; wins over `icon`. | ### MkDrawerSide (type) Import: `import { MkDrawerSide } from '@mk-kit/ui/navigation';` Edge the drawer slides in from. ```ts type MkDrawerSide = 'start' | 'end' | 'top' | 'bottom'; ``` ### MkFabPosition (type) Import: `import { MkFabPosition } from '@mk-kit/ui/navigation';` Corner placement for a fixed `MkFab`. `static` renders it inline. ```ts type MkFabPosition = | 'bottom-end' | 'bottom-start' | 'top-end' | 'top-start' | 'static'; ``` ### MkPageItem (type) Import: `import { MkPageItem } from '@mk-kit/ui/navigation';` A rendered pagination cell: a real page number or a gap marker. ```ts type MkPageItem = number | 'ellipsis'; ``` ### MkScrollAreaOrientation (type) Import: `import { MkScrollAreaOrientation } from '@mk-kit/ui/navigation';` Which axes get a custom scrollbar for `MkScrollArea`. ```ts type MkScrollAreaOrientation = 'vertical' | 'horizontal' | 'both'; ``` ### MkSplitterOrientation (type) Import: `import { MkSplitterOrientation } from '@mk-kit/ui/navigation';` Split direction for `MkSplitter`. ```ts type MkSplitterOrientation = 'horizontal' | 'vertical'; ``` ### MkStepperOrientation (type) Import: `import { MkStepperOrientation } from '@mk-kit/ui/navigation';` Orientation of the step header rail. ```ts type MkStepperOrientation = 'horizontal' | 'vertical'; ``` ### MkTabsVariant (type) Import: `import { MkTabsVariant } from '@mk-kit/ui/navigation';` Visual style for the tablist. ```ts type MkTabsVariant = 'line' | 'pill'; ``` ## @mk-kit/ui/forms 99 exports. `import { … } from '@mk-kit/ui/forms';` ### MkAutocomplete (component) Selector: `mk-autocomplete` · form control (ControlValueAccessor) Docs: https://mk-kit.dev/components/selection Import: `import { MkAutocomplete } from '@mk-kit/ui/forms';` Autocomplete — an accessible text input that suggests options as the user types, implementing the ARIA combobox (`aria-autocomplete="list"`) pattern with a popup listbox. Filtering is built in (`contains` / `startsWith`); set `filterMode="none"` and drive `options` yourself from the `search` output for async/server-side suggestions. Typing arbitrary text is allowed unless `requireSelection` is set, in which case the field clears on blur if it doesn't match an option. Implements `ControlValueAccessor` and exposes a two-way `value` model, so it works with `[(ngModel)]`, reactive forms and `[(value)]`. When nested in an `mk-form-field` it inherits size, label, hint/error and required wiring. ```html ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `aria-label` | `string` | `''` | Accessible name when the control is used without an `mk-form-field` label. | | `options` | `readonly MkAutocompleteOption[]` | `[]` | | | `placeholder` | `string` | `''` | Placeholder shown when the input is empty. | | `size` | `MkSize` | `'md'` | Control size. Ignored when nested in an `mk-form-field`. | | `invalid` | `boolean` | `false` | Force invalid styling + `aria-invalid` when used standalone. | | `required` | `boolean` | `false` | Mark required (adds `aria-required`). Set by Signal Forms' `[formField]` from the schema. | | `disabled` | `boolean` | `false` | Disable the control. | | `filterMode` | `MkAutocompleteFilterMode` | `'contains'` | How the option list is filtered against the typed text. | | `minChars` | `number` | `0` | Only open the list once this many characters have been typed. | | `loading` | `boolean` | `false` | Show a loading row instead of "no results" (for async fetches). | | `requireSelection` | `boolean` | `false` | Clear the input on blur unless the text matches a selectable option. | | `emptyMessage` | `string` | `this.i18n.noResults` | Message shown when there are no matching options. | | `value` (two-way) | `unknown` | `null` | Two-way selected value (the `value` of the chosen option, or `null`). | Outputs: | Name | Type | Description | | --- | --- | --- | | `valueChange` | `unknown` | Emits when `value` changes (two-way binding). | | `search` | `string` | Emits the current input text on every keystroke — drive async loading. | | `optionSelected` | `MkAutocompleteOption` | Emits the option whenever one is committed by click or Enter. | ### MkButtonToggle (component) Selector: `mk-button-toggle` Import: `import { MkButtonToggle } from '@mk-kit/ui/forms';` A single segment inside an `mk-button-toggle-group`. Projected content is the label (text, an icon, or both). Its selected state and keyboard behaviour are driven by the parent group. ```html B ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `value` | `unknown` | `undefined` | The value contributed to the group's selection when this item is on. | | `disabled` | `boolean` | `false` | Disable just this item. | Methods: | Signature | Description | | --- | --- | | `focus(): void` | Move focus to this item's button. Called by the parent group. | Properties: | Name | Type | Description | | --- | --- | --- | | `selected` | `Signal` | Whether this item is currently selected (owned by the parent group). | | `isDisabled` | `Signal` | Disabled if the item or the whole group is disabled. | ### MkButtonToggleGroup (component) Selector: `mk-button-toggle-group` · form control (ControlValueAccessor) Docs: https://mk-kit.dev/components/selection Import: `import { MkButtonToggleGroup } from '@mk-kit/ui/forms';` ButtonToggleGroup — a segmented control grouping one or more `mk-button-toggle` items into a single, keyboard-operable selection. In single-select mode (default) the group is an ARIA `radiogroup`: exactly one item is selected, Arrow keys move and select, and the selected item is the tab stop. Set `multiple` to allow any number of items — the group becomes a toolbar of independent `aria-pressed` buttons. Implements `ControlValueAccessor` and exposes a two-way `value` model. In single mode `value` is the chosen item's `value`; in multiple mode it is an array of the selected values. ```html Grid List ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `multiple` | `boolean` | `false` | Allow selecting any number of items (toolbar of `aria-pressed` buttons). | | `size` | `MkSize` | `'md'` | Control size, applied to every item. Ignored inside an `mk-form-field`. | | `tone` | `MkTone` | `'primary'` | Semantic color tone used for the selected fill. | | `disabled` | `boolean` | `false` | Disable the whole group. | | `invalid` | `boolean` | `false` | Force the invalid visual + `aria-invalid` when used standalone. | | `aria-label` | `string` | `''` | Accessible name for the group (recommended). | | `value` (two-way) | `unknown` | `null` | Two-way selected value. Single mode: the chosen item's `value` (or `null`). Multiple mode: an array of selected values. | Outputs: | Name | Type | Description | | --- | --- | --- | | `valueChange` | `unknown` | Emits when `value` changes (two-way binding). | Methods: | Signature | Description | | --- | --- | | `isSelected(toggle: MkButtonToggle): boolean` | Whether a given item is part of the current selection. | | `tabIndexFor(toggle: MkButtonToggle): number` | `0` for the item that owns the tab stop, `-1` for the rest. | | `select(toggle: MkButtonToggle): void` | Toggle (multiple) or set (single) the selection for an item. | | `onKeydown(event: KeyboardEvent, toggle: MkButtonToggle): void` | | Properties: | Name | Type | Description | | --- | --- | --- | | `effectiveSize` | `Signal` | The size actually applied (the form field's when nested). | ### MkCardNumberInput (component) Selector: `mk-card-number-input` · exportAs: `mkCardNumberInput` · form control (ControlValueAccessor) Docs: https://mk-kit.dev/components/payment Import: `import { MkCardNumberInput } from '@mk-kit/ui/forms';` CardNumberInput — a payment-card number field that groups digits with the detected network's layout (16-digit `0000 0000 0000 0000`, Amex `0000 000000 00000`, Diners `0000 000000 0000`), shows the brand as a badge, and validates the complete number with the Luhn checksum. The form value is the raw digit string (no spaces). `brand()` exposes the detected network (also via `(brandChange)`), and `valid()` reports `true`/`false` for a complete number passing/failing Luhn and `null` while empty or incomplete; invalid styling engages after the field was touched. Implements `ControlValueAccessor` and exposes a two-way `value` model, so `[(ngModel)]`, reactive forms and `[(value)]` all work. ```html ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `showBrand` | `boolean` | `true` | Show the detected brand as a badge inside the field. | | `size` | `MkSize` | `'md'` | Control size. Ignored when nested in an `mk-form-field`. | | `invalid` | `boolean` | `false` | Force invalid styling + `aria-invalid` when used standalone. | | `disabled` | `boolean` | `false` | Disable the control. | | `placeholder` | `string` | `'0000 0000 0000 0000'` | Placeholder shown when empty. | | `value` (two-way) | `string` | `''` | Two-way card number, digits only (no spaces). | Outputs: | Name | Type | Description | | --- | --- | --- | | `valueChange` | `string` | Emits when `value` changes (two-way binding). | | `brandChange` | `MkCardBrand \| null` | Emits whenever the detected brand changes. | Methods: | Signature | Description | | --- | --- | | `validate(control: AbstractControl): ValidationErrors \| null` | Reports `cardNumber` for a number failing the Luhn checksum (which includes a half-typed one). An empty value passes; compose with `Validators.required` to reject it. | Properties: | Name | Type | Description | | --- | --- | --- | | `brand` | `Signal` | The detected card network, `null` while unrecognised. | | `valid` | `Signal` | `true` for a complete number passing Luhn, `false` for a complete number failing it, `null` while empty or incomplete. | ### MkCascader (component) Selector: `mk-cascader` · form control (ControlValueAccessor) Docs: https://mk-kit.dev/components/selection Import: `import { MkCascader } from '@mk-kit/ui/forms';` Cascader — a select whose choices are a hierarchy shown as side-by-side columns (region → country → city, category → subcategory, org unit → team). Each pick opens the next column; picking a leaf commits the whole path. The value is the **path** of option values (`['eu', 'pl', 'krk']`) by default, or just the leaf's value with `valueMode="leaf"`. Parents are only selectable with `selectParents` (a click on one then commits, and its children stay reachable). Keyboard: Up / Down move within a column, Right opens the children, Left goes back, Enter / Space selects, typing jumps to a label, Escape closes. `expandTrigger="hover"` opens columns on pointer hover as well as click. Implements `ControlValueAccessor` and a two-way `value` model. ```html ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `options` | `readonly MkCascaderOption[]` | `[]` | The hierarchy to choose from. | | `value` (two-way) | `unknown` | `null` | Two-way value: the path of values (default) or the leaf value (`valueMode="leaf"`). | | `valueMode` | `"path" \| "leaf"` | `'path'` | Bind the full path of values (default) or only the chosen option's value. | | `selectParents` | `boolean` | `false` | Allow committing a parent option (click / Enter on it) instead of leaves only. | | `expandTrigger` | `"click" \| "hover"` | `'click'` | Open the next column on click (default) or also on pointer hover. | | `placeholder` | `string` | `this.i18n.selectPlaceholder` | | | `separator` | `string` | `' / '` | Text between the labels of the chosen path. | | `clearable` | `boolean` | `false` | | | `disabled` | `boolean` | `false` | | | `invalid` | `boolean` | `false` | | | `size` | `MkSize` | `'md'` | Control size. Ignored when nested in an `mk-form-field`. | Outputs: | Name | Type | Description | | --- | --- | --- | | `valueChange` | `unknown` | Emits when `value` changes (two-way binding). | | `change` | `unknown` | Emitted after the user commits or clears a value. | ### MkCheckbox (component) Selector: `mk-checkbox` · form control (ControlValueAccessor) Docs: https://mk-kit.dev/components/toggles Import: `import { MkCheckbox } from '@mk-kit/ui/forms';` Checkbox — a themed checkbox built on a visually-hidden native `input[type=checkbox]` (so keyboard + form semantics are native) with a custom box. Supports an `indeterminate` state and projects its label. Implements `ControlValueAccessor` with a two-way `checked` model, so it works with `[(ngModel)]`, reactive forms and `[(checked)]`. ```html Accept terms Select all ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `checked` (two-way) | `boolean` | `false` | Two-way checked state. | | `indeterminate` (two-way) | `boolean` | `false` | Two-way indeterminate ("mixed") state; cleared when the user toggles. | | `disabled` | `boolean` | `false` | Disable the control. | | `invalid` | `boolean` | `false` | Force the invalid visual + `aria-invalid` when used standalone. | | `required` | `boolean` | `false` | Mark required (adds `aria-required`). | | `size` | `MkSize` | `'md'` | Control size. | | `tone` | `MkTone` | `'primary'` | Semantic color tone for the checked box. | | `aria-label` | `string` | `''` | Accessible label when no text content is projected. | Outputs: | Name | Type | Description | | --- | --- | --- | | `checkedChange` | `boolean` | Emits when `checked` changes (two-way binding). | | `indeterminateChange` | `boolean` | Emits when `indeterminate` changes (two-way binding). | Methods: | Signature | Description | | --- | --- | | `validate(control: AbstractControl): ValidationErrors \| null` | Reports `required` for an unchecked box when `[required]` is set, so `required` on the element behaves like `Validators.requiredTrue`. | ### MkCodeEditor (component) Selector: `mk-code-editor` · exportAs: `mkCodeEditor` · form control (ControlValueAccessor) Docs: https://mk-kit.dev/components/forms Import: `import { MkCodeEditor } from '@mk-kit/ui/forms';` CodeEditor — a lightweight, dependency-free code field with syntax highlighting, JSON validation and pretty-printing. A ` ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `size` | `MkSize` | `'md'` | Control size. Ignored when nested in an `mk-form-field` (inherits it). | | `invalid` | `boolean` | `false` | Force the invalid visual + `aria-invalid` when used standalone. | ### MkInputGroup (component) Selector: `mk-input-group` Docs: https://mk-kit.dev/components/text-inputs Import: `import { MkInputGroup } from '@mk-kit/ui/forms';` InputGroup — wraps a native `input[mkInput]` with leading / trailing affixes (icons, static text, compact buttons) inside one shared control frame. The group carries the border, background and focus ring; the nested input detects the group and drops its own chrome, so the whole assembly reads as a single field. Project affixes with the `mkInputPrefix` / `mkInputSuffix` attributes. Both are optional; interactive suffixes (a clear or scan button) keep their own focus behaviour. Inside an `mk-form-field` the group inherits the field's size and invalid state, and the field's label association still targets the inner input. ```html zł ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `size` | `MkSize` | `'md'` | Control size. Ignored when nested in an `mk-form-field` (inherits it). | | `invalid` | `boolean` | `false` | Force the invalid visual when used standalone. | | `disabled` | `boolean` | `false` | Visually reflect a disabled inner control. | Properties: | Name | Type | Description | | --- | --- | --- | | `effectiveSize` | `Signal` | The size the group (and its nested input) renders at. | | `isInvalid` | `Signal` | Whether the group renders the invalid frame. | ### MkListbox (component) Selector: `mk-listbox` · form control (ControlValueAccessor) Docs: https://mk-kit.dev/components/selection Import: `import { MkListbox } from '@mk-kit/ui/forms';` Listbox — a standalone, always-visible selection list (the ARIA `listbox` pattern) for one or many values: settings panes, "choose a template" pickers, side-by-side assignments, any place a dropdown would hide choices the user should see at once. Keyboard: Up / Down move, Home / End jump, PageUp / PageDown skip ten, type to jump to a label, Enter / Space select (toggle when `multiple`), Shift+Arrow / Shift+click extend a range, Ctrl/Cmd+A selects all. Focus stays on the list (`aria-activedescendant`). With `filterable`, a search box above the list narrows it by label or description. Implements `ControlValueAccessor` and a two-way `value` model — a single value, or an array when `multiple`. ```html ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `options` | `readonly MkListboxOption[]` | `[]` | The rows to choose from. | | `multiple` | `boolean` | `false` | Allow several values; the model becomes an array. | | `filterable` | `boolean` | `false` | Show a search box that narrows the list by label / description. | | `filterPlaceholder` | `string \| undefined` | `undefined` | | | `selectionFollowsFocus` | `boolean` | `true` | Single-select only: moving with the arrow keys selects immediately (default `true`); `false` requires Enter / Space to commit. | | `size` | `MkSize` | `'md'` | Control size. Ignored when nested in an `mk-form-field`. | | `invalid` | `boolean` | `false` | | | `disabled` | `boolean` | `false` | | | `ariaLabel` | `string \| undefined` | `undefined` | Accessible name when there is no visible label / form field. | | `ariaLabelledby` | `string \| undefined` | `undefined` | | | `emptyText` | `string \| undefined` | `undefined` | Text shown when no option matches the filter. | | `value` (two-way) | `unknown` | `null` | Two-way value: one value, or an array when `multiple`. | Outputs: | Name | Type | Description | | --- | --- | --- | | `valueChange` | `unknown` | Emits when `value` changes (two-way binding). | | `change` | `unknown` | Emitted after the user changes the selection (not on programmatic writes). | Methods: | Signature | Description | | --- | --- | | `focus(): void` | Focus the list. | ### MkMentionPanel (component) Selector: `mk-mention-panel` Import: `import { MkMentionPanel } from '@mk-kit/ui/forms';` Suggestion listbox for `MkMention`. Created dynamically by the directive and wired imperatively right after creation: the directive hands it read-only signals (options, active index, caret anchor point) plus plain callbacks, so the panel re-renders reactively without `setInput` churn. The `
      ` is promoted to the top layer by `mkAnchoredPanel` and positioned at the caret point; this host element stays empty in place. Not intended for direct use — the public API is the `[mkMention]` directive. Methods: | Signature | Description | | --- | --- | | `optionId(index: number): string` | | Properties: | Name | Type | Description | | --- | --- | --- | | `anchorPoint` | `Signal<{ x: number; y: number; }>` | Caret point (viewport px) the panel is anchored to. | | `anchorEl` | `HTMLElement \| undefined` | The mention control itself — passed as the anchored panel's element anchor so pointerdowns inside the control don't count as "outside" dismissals (the point anchor still wins for positioning). | ### MkMultiSelect (component) Selector: `mk-multi-select` · form control (ControlValueAccessor) Docs: https://mk-kit.dev/components/selection Import: `import { MkMultiSelect } from '@mk-kit/ui/forms';` MultiSelect — an accessible combobox that commits **multiple** values, rendering each selection as a removable chip inside the control. Implements the ARIA combobox + multiselectable listbox pattern. Filtering is built in (`contains` / `startsWith`); set `filterMode="none"` and drive `options` from the `search` output for async / server-side sources. Selected options are remembered even after they leave the `options` list, so chips keep their labels across async pages. Implements `ControlValueAccessor` over an **array** value and exposes a two-way `value` model, so it works with `[(ngModel)]`, reactive forms and `[(value)]`. When nested in an `mk-form-field` it inherits size, label, hint/error and required wiring. Keyboard: type to filter, Up/Down to move, Home/End to jump, Enter/Space to toggle the active option, Backspace on an empty query removes the last chip, Escape closes. The dropdown renders in the top layer via `MkAnchoredPanel` so it is never clipped by a container. ```html ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `aria-label` | `string` | `''` | Accessible name when the control is used without an `mk-form-field` label. | | `options` | `readonly MkMultiSelectOption[]` | `[]` | | | `placeholder` | `string` | `''` | Placeholder shown when no value is selected. | | `size` | `MkSize` | `'md'` | Control size. Ignored when nested in an `mk-form-field`. | | `invalid` | `boolean` | `false` | Force invalid styling + `aria-invalid` when used standalone. | | `required` | `boolean` | `false` | Mark required (adds `aria-required`). Set by Signal Forms' `[formField]` from the schema. | | `disabled` | `boolean` | `false` | Disable the control. | | `filterMode` | `MkMultiSelectFilterMode` | `'contains'` | How the option list is filtered against the typed text. | | `minChars` | `number` | `0` | Only open the list once this many characters have been typed. | | `loading` | `boolean` | `false` | Show a loading row instead of "no results" (for async fetches). | | `max` | `number` | `0` | Maximum number of selections (0 = unlimited). | | `closeOnSelect` | `boolean` | `false` | Close the dropdown after each selection. Default keeps it open. | | `emptyMessage` | `string` | `this.i18n.noResults` | Message shown when there are no matching options. | | `value` (two-way) | `unknown[]` | `[]` | Two-way selected values. | Outputs: | Name | Type | Description | | --- | --- | --- | | `valueChange` | `unknown[]` | Emits when `value` changes (two-way binding). | | `search` | `string` | Emits the current query text on every keystroke — drive async loading. | | `optionAdded` | `MkMultiSelectOption` | Emits the option whenever one is added. | | `optionRemoved` | `unknown` | Emits the value whenever a selection is removed. | Methods: | Signature | Description | | --- | --- | | `validate(control: AbstractControl): ValidationErrors \| null` | Reports `mkMaxItems` when more options are selected than `[max]` allows. | ### MkNumberInput (component) Selector: `mk-number-input` · form control (ControlValueAccessor) Docs: https://mk-kit.dev/components/text-inputs Import: `import { MkNumberInput } from '@mk-kit/ui/forms';` NumberInput — a numeric field with −/+ stepper buttons, clamping and keyboard stepping (Arrow keys / Page keys). Implements the ARIA `spinbutton` pattern and `ControlValueAccessor` over `number | null`, with a two-way `value` model. ```html ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `aria-label` | `string` | `''` | Accessible name when the control is used without an `mk-form-field` label. | | `min` | `number \| null` | `null` | | | `max` | `number \| null` | `null` | Maximum value. | | `step` | `number` | `1` | Step increment for buttons + Arrow keys. | | `value` (two-way) | `number \| null` | `null` | Two-way value. | | `placeholder` | `string` | `''` | Placeholder when empty. | | `disabled` | `boolean` | `false` | Disable the control. | | `invalid` | `boolean` | `false` | Force invalid styling when standalone. | | `required` | `boolean` | `false` | Mark required (adds `aria-required`). Set by Signal Forms' `[formField]` from the schema. | | `size` | `MkSize` | `'md'` | Control size. Ignored inside an `mk-form-field`. | Outputs: | Name | Type | Description | | --- | --- | --- | | `valueChange` | `number \| null` | Emits when `value` changes (two-way binding). | Methods: | Signature | Description | | --- | --- | | `validate(control: AbstractControl): ValidationErrors \| null` | Reports `min` / `max` against the `[min]` and `[max]` inputs, using the same error shapes as `Validators.min` / `Validators.max`. | ### MkNumericKeypad (component) Selector: `mk-numeric-keypad` · form control (ControlValueAccessor) Docs: https://mk-kit.dev/components/touch-keys Import: `import { MkNumericKeypad } from '@mk-kit/ui/forms';` Numeric keypad — a touch-first 3×4 digit pad for PIN entry, quantity entry and money amounts (POS-style). `ControlValueAccessor` + two-way `value` model; the value is a **string** in `pin` mode (leading zeros preserved) and a **number | null** in `quantity`/`amount` mode. - `pin`: masked echo row by default; `(submit)` fires automatically when `length` digits are entered. - `quantity`: integer entry; the bottom-left key clears. - `amount`: decimal entry (value uses `.`; the echo shows `decimalSeparator`); capped at `fractionDigits` fraction digits. A physical keyboard works anywhere inside the pad: digits, Backspace, Delete (clear), Enter (submit) and the decimal separator. Arrow keys move between the on-screen keys (roving tabindex). ```html ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `mode` | `MkNumericKeypadMode` | `'quantity'` | Entry mode. Decides the value type and the bottom-left key. | | `length` | `number` | `4` | PIN length (`pin` mode only). Reaching it emits `submit`. | | `min` | `number \| null` | `null` | Lower bound reported through the validator (`quantity`/`amount`). | | `max` | `number \| null` | `null` | Upper bound reported through the validator (`quantity`/`amount`). | | `mask` | `boolean` | `true` | Mask the echo row in `pin` mode. Default `true`. | | `showValue` | `boolean` | `true` | Show the echo row above the keys. Default `true`. | | `decimalSeparator` | `string` | `','` | Echo-row separator for `amount` mode. The VALUE always uses `.`. | | `fractionDigits` | `number` | `2` | Max fraction digits accepted in `amount` mode. | | `disabled` | `boolean` | `false` | Disable the pad. | | `invalid` | `boolean` | `false` | Force invalid styling. | | `ariaLabel` | `string` | `this.i18n.numericKeypadLabel` | Accessible label for the pad. | | `value` (two-way) | `string \| number \| null` | `null` | Two-way value: `string` in `pin` mode, `number \| null` otherwise. | Outputs: | Name | Type | Description | | --- | --- | --- | | `valueChange` | `string \| number \| null` | Emits when `value` changes (two-way binding). | | `submit` | `string \| number \| null` | Enter key / full PIN. Emits the current value. | Methods: | Signature | Description | | --- | --- | | `validate(control: AbstractControl): ValidationErrors \| null` | `pin`: reports `minlength` while the code is incomplete (empty passes — compose with `Validators.required`). `quantity`/`amount`: reports `min`/`max` against the bounds. | ### MkOnScreenKeyboard (component) Selector: `mk-on-screen-keyboard` · exportAs: `mkOnScreenKeyboard` Docs: https://mk-kit.dev/components/touch-keys Import: `import { MkOnScreenKeyboard } from '@mk-kit/ui/forms';` On-screen keyboard — a touch QWERTY panel for kiosk/till screens where no physical keyboard exists. Anchored below its input in the browser top layer (via `MkAnchoredPanel`), it writes caret-aware into the target's native value and dispatches `input` events, so `ngModel`/reactive forms stay in sync with no extra wiring. Pair it with the `mkOnScreenKeyboardFor` directive, which opens the panel on focus and suppresses the OS keyboard (`inputmode="none"`): ```html ``` Layers: base (letters + digit row), shift (auto-resets after one character) and an alternate layer (Polish diacritics + symbols in the default `MK_KEYBOARD_LAYOUT_QWERTY_PL`); pass `layout` for other languages. Enter inserts a newline in a ` ``` Inputs: | Name | Type | Default | Description | | --- | --- | --- | --- | | `mentionTriggers` | `readonly string[]` | `['@']` | Single characters that start a mention session. | | `mentionOptions` | `readonly MkMentionOption[]` | `[]` | The suggestion pool. Update it from `mentionSearch` for async sources. | | `mentionFilter` | `MkMentionFilterMode` | `'contains'` | How suggestions are filtered against the typed query. | | `mentionLoading` | `boolean` | `false` | Keep the panel open with a loading row while async results are pending. | | `mentionInsert` | `((option: MkMentionOption, trigger: string) => string) \| null` | `null` | Builds the text inserted for a picked option. Defaults to `` `${trigger}${option.label} ` `` (note the trailing space). | Outputs: | Name | Type | Description | | --- | --- | --- | | `mentionSearch` | `MkMentionSearchEvent` | Emits `{trigger, query}` whenever the active query changes — drive async loading. | | `mentionSelect` | `MkMentionSelectEvent` | Emits after an option has been inserted into the control. | Properties: | Name | Type | Description | | --- | --- | --- | | `listId` | `string` | Id of the listbox panel, wired to `aria-controls` while open. | ### MkOnScreenKeyboardTrigger (directive) Selector: `input[mkOnScreenKeyboardFor], textarea[mkOnScreenKeyboardFor]` · exportAs: `mkOnScreenKeyboardTrigger` Docs: https://mk-kit.dev/components/touch-keys Import: `import { MkOnScreenKeyboardTrigger } from '@mk-kit/ui/forms';` Binds an ``/`