@mk-kit/mcp 0.54.0 → 0.55.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/data/api.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "@mk-kit/ui",
3
- "version": "0.54.0",
3
+ "version": "0.55.1",
4
4
  "site": "https://mk-kit.dev",
5
5
  "entries": [
6
6
  {
@@ -2637,6 +2637,16 @@
2637
2637
  "type": "(position: number) => string",
2638
2638
  "description": "Announced when the item is dropped."
2639
2639
  },
2640
+ {
2641
+ "name": "dndMovedToZone",
2642
+ "type": "(zone: string) => string",
2643
+ "description": "Announced as a lifted item reaches a drop zone (a target that is not a list)."
2644
+ },
2645
+ {
2646
+ "name": "dndDroppedInZone",
2647
+ "type": "(zone: string) => string",
2648
+ "description": "Announced when the item is dropped on a zone."
2649
+ },
2640
2650
  {
2641
2651
  "name": "dndCancelled",
2642
2652
  "type": "string",
@@ -4973,7 +4983,7 @@
4973
4983
  "exports": [
4974
4984
  {
4975
4985
  "name": "MkDrag",
4976
- "description": "Makes an item inside a `[mkDropList]` draggable — by pointer (mouse / touch /\npen) **and** by keyboard (WCAG 2.1.1). Every move is announced via\n`MkLiveAnnouncer`. Which element carries the keyboard interaction\ndepends on the handle:\n\n- **No handle, or a decorative one** (`<span mkDragHandle aria-hidden>`):\n the item itself is focusable and exposes `aria-roledescription=\"Draggable\n item\"` with `role=\"button\"` — or `role=\"option\"` when it is an `<li>` of a\n `<ul mkDropList>`, which then becomes a labelled `listbox` (an `<li>` may\n not take the `button` role).\n- **A focusable handle** (`<button mkDragHandle aria-label=\"…\">`, or any\n handle with `tabindex`): the handle is the keyboard target and receives\n the `aria-roledescription` / `aria-pressed` / `aria-grabbed` state; the\n item stays a plain container with no role and no `tabindex`, so it can hold\n inputs, links and buttons of its own (no nested interactive controls) and\n `<li>` items keep their list semantics.\n\nKeyboard: focus the item (or its handle) and press **Space/Enter** to pick\nit up, **Arrow** keys to move it (crossing into connected lists at the ends /\nacross the perpendicular axis), **Space/Enter** to drop, **Escape** to cancel.\n\nTouch: a swipe scrolls the page as usual — the drag only arms after a\nlong-press (`mkDragTouchDelay`, default 300 ms). While armed the item\ngets the `mk-drag--armed` class so consumers can style the lift moment.\nMouse and pen drags start immediately, as before.\n\nPerformance: pointer moves are rAF-coalesced (one hit-test + one set of\nstyle/DOM writes per frame) against list/item rects snapshotted when the\ndrag lifts, so a move never forces layout. The pending frame is flushed\nsynchronously on release so drops land exactly where the pointer ended.\n\n```html\n<div mkDrag [mkDragData]=\"row\" [mkDragDisabled]=\"row.locked\">\n <span mkDragHandle aria-hidden=\"true\">⠿</span> {{ row.title }}\n</div>\n```",
4986
+ "description": "Makes an item inside a `[mkDropList]` draggable — by pointer (mouse / touch /\npen) **and** by keyboard (WCAG 2.1.1). Every move is announced via\n`MkLiveAnnouncer`. Which element carries the keyboard interaction\ndepends on the handle:\n\n- **No handle, or a decorative one** (`<span mkDragHandle aria-hidden>`):\n the item itself is focusable and exposes `aria-roledescription=\"Draggable\n item\"` with `role=\"button\"` — or `role=\"option\"` when it is an `<li>` of a\n `<ul mkDropList>`, which then becomes a labelled `listbox` (an `<li>` may\n not take the `button` role).\n- **A focusable handle** (`<button mkDragHandle aria-label=\"…\">`, or any\n handle with `tabindex`): the handle is the keyboard target and receives\n the `aria-roledescription` / `aria-pressed` / `aria-grabbed` state; the\n item stays a plain container with no role and no `tabindex`, so it can hold\n inputs, links and buttons of its own (no nested interactive controls) and\n `<li>` items keep their list semantics.\n\nKeyboard: focus the item (or its handle) and press **Space/Enter** to pick\nit up, **Arrow** keys to move it (crossing into connected lists at the ends /\nacross the perpendicular axis), **Space/Enter** to drop, **Escape** to cancel.\n\nBesides lists, an item can be released on a connected `[mkDropZone]` — a\ntarget that reports *where* it was dropped instead of an index (a timeline,\na priority band, a \"focus on this\" pane). Zones sit in the same keyboard\ntravel group as lists, in document order; while an item hovers a zone no\nplaceholder is shown and the zone streams `mkDropZoneMoved` events.\n\nTouch: a swipe scrolls the page as usual — the drag only arms after a\nlong-press (`mkDragTouchDelay`, default 300 ms). While armed the item\ngets the `mk-drag--armed` class so consumers can style the lift moment.\nMouse and pen drags start immediately, as before.\n\nPerformance: pointer moves are rAF-coalesced (one hit-test + one set of\nstyle/DOM writes per frame) against list/item rects snapshotted when the\ndrag lifts, so a move never forces layout. The pending frame is flushed\nsynchronously on release so drops land exactly where the pointer ended.\n\n```html\n<div mkDrag [mkDragData]=\"row\" [mkDragDisabled]=\"row.locked\">\n <span mkDragHandle aria-hidden=\"true\">⠿</span> {{ row.title }}\n</div>\n```",
4977
4987
  "file": "projects/mk-kit/dnd/drag.ts",
4978
4988
  "kind": "component",
4979
4989
  "selector": "[mkDrag]",
@@ -5147,6 +5157,117 @@
5147
5157
  "queries": [],
5148
5158
  "docs": "/components/drag-drop"
5149
5159
  },
5160
+ {
5161
+ "name": "MkDropZone",
5162
+ "description": "A drop **target** that is not a list: an item dragged out of a connected\n`[mkDropList]` can be released anywhere on it, and the zone reports *where*\n— client coordinates, the offset inside the zone and the 0–1 fraction along\neach axis — so the consumer can turn a position into meaning: a time on a\ntimeline, a priority band, a \"focus on this\" pane, a trash can.\n\nNothing reorders and no placeholder is shown while an item hovers a zone;\nthe zone gets the `mk-drop-zone--receiving` class and a stream of\n`mkDropZoneMoved` events instead. Zones and lists can overlap — the\ninnermost target under the pointer wins, so a column can hold three\npriority bands and still accept plain drops between the bands.\n\nWire a zone exactly like another list: give it an id and name that id in\nthe source list's `mkDropListConnectedTo`.\n\nKeyboard: a lifted item reaches zones with the arrow keys that cross lists\n(Left/Right in a vertical list, Up/Down in a horizontal one) — zones sit in\nthe same DOM-ordered travel group as connected lists; Space/Enter drops at\nthe zone's centre. Every step is announced.\n\n```html\n<ul mkDropList mkDropListId=\"backlog\" [mkDropListConnectedTo]=\"['now', 'rail']\" …>\n<section mkDropZone mkDropZoneId=\"now\" mkDropZoneLabel=\"Focus now\"\n (mkDropZoneDropped)=\"focus($event.item.mkDragData())\">\n<div mkDropZone mkDropZoneId=\"rail\" mkDropZoneLabel=\"Today\"\n (mkDropZoneMoved)=\"preview($event.fractionY)\"\n (mkDropZoneDropped)=\"schedule($event.item.mkDragData(), $event.fractionY)\">\n```",
5163
+ "file": "projects/mk-kit/dnd/drop-zone.ts",
5164
+ "kind": "component",
5165
+ "selector": "[mkDropZone]",
5166
+ "selectors": [
5167
+ "mkDropZone"
5168
+ ],
5169
+ "exportAs": "mkDropZone",
5170
+ "inputs": [
5171
+ {
5172
+ "name": "mkDropZoneId",
5173
+ "type": "string | undefined",
5174
+ "description": "Stable id source lists name in `mkDropListConnectedTo`. Auto-generated when omitted."
5175
+ },
5176
+ {
5177
+ "name": "mkDropZoneLabel",
5178
+ "type": "string",
5179
+ "description": "Human-readable name, used in screen-reader announcements when a lifted\nitem reaches the zone (\"Moved to Focus now\") and as the zone's accessible\nname. Set it: the fallback is the id, which may be generated gibberish.",
5180
+ "default": "''"
5181
+ },
5182
+ {
5183
+ "name": "mkDropZoneLabelledBy",
5184
+ "type": "string",
5185
+ "description": "Id of a visible element that names the zone (`aria-labelledby`); wins over the label as the accessible name.",
5186
+ "default": "''"
5187
+ },
5188
+ {
5189
+ "name": "mkDropZoneData",
5190
+ "type": "Z | undefined",
5191
+ "description": "Arbitrary payload handed back on every hover and drop event."
5192
+ },
5193
+ {
5194
+ "name": "mkDropZoneDisabled",
5195
+ "type": "boolean",
5196
+ "description": "Disable dropping onto this zone (it leaves the travel group too).",
5197
+ "default": "false"
5198
+ }
5199
+ ],
5200
+ "outputs": [
5201
+ {
5202
+ "name": "mkDropZoneEntered",
5203
+ "type": "MkDropZoneHover<T, Z>",
5204
+ "description": "An item entered the zone (pointer or keyboard)."
5205
+ },
5206
+ {
5207
+ "name": "mkDropZoneMoved",
5208
+ "type": "MkDropZoneHover<T, Z>",
5209
+ "description": "The pointer moved while over the zone (one per frame, pointer only)."
5210
+ },
5211
+ {
5212
+ "name": "mkDropZoneLeft",
5213
+ "type": "MkDrag<T>",
5214
+ "description": "The item left the zone without dropping (moved on, or the drag was cancelled)."
5215
+ },
5216
+ {
5217
+ "name": "mkDropZoneDropped",
5218
+ "type": "MkDropZoneEvent<T, Z>",
5219
+ "description": "The item was released on the zone."
5220
+ }
5221
+ ],
5222
+ "methods": [
5223
+ {
5224
+ "name": "setReceiving",
5225
+ "signature": "(value: boolean): void",
5226
+ "description": "Toggle the \"receiving\" highlight (called by the active drag)."
5227
+ },
5228
+ {
5229
+ "name": "emitEntered",
5230
+ "signature": "(event: MkDropZoneHover<T, Z>): void",
5231
+ "description": "Called by the active `MkDrag` — not part of the consumer API."
5232
+ },
5233
+ {
5234
+ "name": "emitMoved",
5235
+ "signature": "(event: MkDropZoneHover<T, Z>): void",
5236
+ "description": ""
5237
+ },
5238
+ {
5239
+ "name": "emitLeft",
5240
+ "signature": "(item: MkDrag<T>): void",
5241
+ "description": ""
5242
+ },
5243
+ {
5244
+ "name": "emitDrop",
5245
+ "signature": "(event: MkDropZoneEvent<T, Z>): void",
5246
+ "description": ""
5247
+ }
5248
+ ],
5249
+ "properties": [
5250
+ {
5251
+ "name": "element",
5252
+ "type": "HTMLElement",
5253
+ "description": "The zone's host element (drop target bounds).",
5254
+ "readonly": true
5255
+ },
5256
+ {
5257
+ "name": "id",
5258
+ "type": "Signal<string>",
5259
+ "description": "Resolved id (input or generated).",
5260
+ "readonly": true
5261
+ },
5262
+ {
5263
+ "name": "label",
5264
+ "type": "Signal<string>",
5265
+ "description": "Announceable name: the label when set, otherwise the resolved id.",
5266
+ "readonly": true
5267
+ }
5268
+ ],
5269
+ "queries": []
5270
+ },
5150
5271
  {
5151
5272
  "name": "MkSortableList",
5152
5273
  "description": "Thin convenience wrapper over a single `[mkDropList]` for the common\n\"reorderable list\" case. Bind `items` two-way and provide an `<ng-template>`\nto render each row; drops are applied to the model for you (via\n`mkMoveItemInArray`).\n\nFor connected buckets / kanban, use `[mkDropList]` + `[mkDrag]` directly.\n\nThe list renders as a named `group` of `button` items: pass `label` (or\n`labelledBy` pointing at a visible heading) so screen readers say what is\nbeing reordered — the i18n `sortableListLabel` (\"Sortable list\") is the\nfallback.\n\n```html\n<mk-sortable-list [(items)]=\"rows\" label=\"Steps\">\n <ng-template let-row let-i=\"index\">\n <span mkDragHandle aria-hidden=\"true\">⠿</span> {{ i + 1 }}. {{ row.name }}\n </ng-template>\n</mk-sortable-list>\n```",
@@ -5272,6 +5393,31 @@
5272
5393
  "name": "connectedGroup",
5273
5394
  "signature": "(list: MkDropList<any>): MkDropList<any>[]",
5274
5395
  "description": "The ordered travel group for `list`: `list` itself plus every enabled list\nit is `mkDropListConnectedTo`, in registration (roughly DOM) order. Used to\nresolve \"adjacent\" lists for keyboard column-to-column movement and to\nhit-test the pointer against candidate targets."
5396
+ },
5397
+ {
5398
+ "name": "registerZone",
5399
+ "signature": "(id: string, zone: MkDropZone<any>): void",
5400
+ "description": "Register (or replace) the zone published under `id`."
5401
+ },
5402
+ {
5403
+ "name": "unregisterZone",
5404
+ "signature": "(id: string, zone: MkDropZone<any>): void",
5405
+ "description": "Remove `zone` from the registry if it is still the holder of `id`."
5406
+ },
5407
+ {
5408
+ "name": "getZone",
5409
+ "signature": "(id: string): MkDropZone<any> | undefined",
5410
+ "description": "Look up a zone by its `mkDropZoneId`."
5411
+ },
5412
+ {
5413
+ "name": "connectedZones",
5414
+ "signature": "(list: MkDropList<any>): MkDropZone<any>[]",
5415
+ "description": "Every enabled zone named in `list`'s `mkDropListConnectedTo`, in registration order."
5416
+ },
5417
+ {
5418
+ "name": "travelGroup",
5419
+ "signature": "(list: MkDropList<any>): MkDropTarget[]",
5420
+ "description": "The keyboard travel group for `list`: its connected lists **and** zones,\nin document order, so arrow keys walk targets the way they appear on\nscreen regardless of when each registered."
5275
5421
  }
5276
5422
  ],
5277
5423
  "properties": []
@@ -5333,12 +5479,95 @@
5333
5479
  }
5334
5480
  ]
5335
5481
  },
5482
+ {
5483
+ "name": "MkDropZoneEvent",
5484
+ "description": "Emitted by `[mkDropZone]` (`mkDropZoneDropped`) when an item is released on\nit. Carries the same position fields as `MkDropZoneHover` plus where\nthe item came from — the consumer removes it from that list (or not: a\n\"focus on this\" zone may leave the card where it is).",
5485
+ "file": "projects/mk-kit/dnd/drag-drop.types.ts",
5486
+ "kind": "interface",
5487
+ "typeParams": "<T = unknown, Z = unknown>",
5488
+ "extends": [
5489
+ "MkDropZoneHover<T, Z>"
5490
+ ],
5491
+ "members": [
5492
+ {
5493
+ "name": "previousContainer",
5494
+ "type": "MkDropList<T>",
5495
+ "description": "The list the item came from."
5496
+ },
5497
+ {
5498
+ "name": "previousIndex",
5499
+ "type": "number",
5500
+ "description": "Index of the item within `previousContainer`'s data."
5501
+ }
5502
+ ]
5503
+ },
5504
+ {
5505
+ "name": "MkDropZoneHover",
5506
+ "description": "Where an item is over a `[mkDropZone]`, emitted on enter and on every\npointer frame (`mkDropZoneEntered` / `mkDropZoneMoved`). Keyboard entries\nreport the zone's centre.",
5507
+ "file": "projects/mk-kit/dnd/drag-drop.types.ts",
5508
+ "kind": "interface",
5509
+ "typeParams": "<T = unknown, Z = unknown>",
5510
+ "members": [
5511
+ {
5512
+ "name": "item",
5513
+ "type": "MkDrag<T>",
5514
+ "description": "The `MkDrag` directive instance being dragged."
5515
+ },
5516
+ {
5517
+ "name": "zone",
5518
+ "type": "MkDropZone<Z, any>",
5519
+ "description": "The zone under the pointer."
5520
+ },
5521
+ {
5522
+ "name": "x",
5523
+ "type": "number",
5524
+ "description": "Pointer position in client (viewport) coordinates."
5525
+ },
5526
+ {
5527
+ "name": "y",
5528
+ "type": "number",
5529
+ "description": ""
5530
+ },
5531
+ {
5532
+ "name": "offsetX",
5533
+ "type": "number",
5534
+ "description": "Pointer position relative to the zone's top-left corner, in CSS pixels."
5535
+ },
5536
+ {
5537
+ "name": "offsetY",
5538
+ "type": "number",
5539
+ "description": ""
5540
+ },
5541
+ {
5542
+ "name": "fractionX",
5543
+ "type": "number",
5544
+ "description": "Pointer position as a 0–1 fraction of the zone's width / height (clamped)."
5545
+ },
5546
+ {
5547
+ "name": "fractionY",
5548
+ "type": "number",
5549
+ "description": ""
5550
+ },
5551
+ {
5552
+ "name": "isPointerEvent",
5553
+ "type": "boolean",
5554
+ "description": "`true` for pointer (mouse/touch/pen) hovers, `false` for keyboard steps."
5555
+ }
5556
+ ]
5557
+ },
5336
5558
  {
5337
5559
  "name": "MkDropListOrientation",
5338
5560
  "description": "Layout axis a drop list lays its items along.",
5339
5561
  "file": "projects/mk-kit/dnd/drag-drop.types.ts",
5340
5562
  "kind": "type",
5341
5563
  "definition": "'vertical' | 'horizontal'"
5564
+ },
5565
+ {
5566
+ "name": "MkDropTarget",
5567
+ "description": "A keyboard-reachable drop target: a connected list or a connected zone.",
5568
+ "file": "projects/mk-kit/dnd/drag-drop-registry.ts",
5569
+ "kind": "type",
5570
+ "definition": "MkDropList<any> | MkDropZone<any>"
5342
5571
  }
5343
5572
  ]
5344
5573
  },
@@ -17976,6 +18205,323 @@
17976
18205
  }
17977
18206
  ]
17978
18207
  },
18208
+ {
18209
+ "name": "translate",
18210
+ "import": "@mk-kit/ui/translate",
18211
+ "exports": [
18212
+ {
18213
+ "name": "MkTranslatePipe",
18214
+ "description": "`translate` — the key's string in the active language, with `{{name}}`\nplaceholders filled from `params`. Impure so a language switch (or a\n`patch()`) re-renders every use; the signal reads inside `instant()` mark\nthe host view dirty, so this stays cheap under OnPush and zoneless.\n\n```html\n{{ 'menu.title' | translate }}\n{{ 'cart.items' | translate: { count: 3 } }}\n```",
18215
+ "file": "projects/mk-kit/translate/translate.pipe.ts",
18216
+ "kind": "pipe",
18217
+ "pipeName": "translate",
18218
+ "signature": "(key: string | null | undefined, params?: MkTranslateParams): string"
18219
+ },
18220
+ {
18221
+ "name": "MkTranslatePluralPipe",
18222
+ "description": "`translatePlural` — the CLDR plural form under `keyBase` for a count\n(see `MkTranslate.plural`), interpolated with `{ count, ...params }`.\n\n```html\n{{ guests | translatePlural: 'reservation.guests' }} <!-- 2 osoby / 5 osób -->\n```",
18223
+ "file": "projects/mk-kit/translate/translate.pipe.ts",
18224
+ "kind": "pipe",
18225
+ "pipeName": "translatePlural",
18226
+ "signature": "(count: number | string | null | undefined, keyBase: string, params?: MkTranslateParams): string"
18227
+ },
18228
+ {
18229
+ "name": "MkTranslate",
18230
+ "description": "App translations as signals: a `lang` you switch with `use()`, `instant()`\nfor code, the `translate` pipe for templates, and `plural()` for CLDR\ncount forms. Dictionaries are the plain nested JSON you already have; an\noptional overrides loader (a database of edits, say) is merged on top per\nlanguage. On the server the loaded strings ride to the browser through\n`TransferState`, so hydration never refetches or flashes raw keys.\n\n```ts\nprovideMkTranslate({\n lang: 'pl',\n fallbackLang: 'pl',\n loader: mkHttpTranslateLoader({ prefix: '/assets/i18n/' }),\n});\n```\n```html\n{{ 'checkout.cart.total' | translate }}\n{{ 'checkout.cart.freeDeliveryMissing' | translate: { amount: 12 } }}\n```",
18231
+ "file": "projects/mk-kit/translate/translate.service.ts",
18232
+ "kind": "service",
18233
+ "providedIn": "root",
18234
+ "methods": [
18235
+ {
18236
+ "name": "getCurrentLang",
18237
+ "signature": "(): string",
18238
+ "description": "The active language as a plain string (for non-reactive call sites)."
18239
+ },
18240
+ {
18241
+ "name": "getLangs",
18242
+ "signature": "(): string[]",
18243
+ "description": "Languages known to the service: loaded ones plus any added with `addLangs`."
18244
+ },
18245
+ {
18246
+ "name": "addLangs",
18247
+ "signature": "(langs: string[]): void",
18248
+ "description": "Declare languages up front (a switcher's list); loading still happens on `use()`."
18249
+ },
18250
+ {
18251
+ "name": "setTranslation",
18252
+ "signature": "(lang: string, strings: MkTranslationTree | MkFlatTranslations, shouldMerge?: boolean): void",
18253
+ "description": "ngx-translate-compatible alias: `setTranslation(lang, strings, true)`\nmerges like `patch`, `false` (the default there) replaces like\n`set`."
18254
+ },
18255
+ {
18256
+ "name": "use",
18257
+ "signature": "(lang: string): Promise<void>",
18258
+ "description": "Load `lang` (once — later calls are cached) and make it active. Resolves\nwhen the strings are in memory; a failed load rejects and leaves the\nprevious language active."
18259
+ },
18260
+ {
18261
+ "name": "load",
18262
+ "signature": "(lang: string): Promise<void>",
18263
+ "description": "Load a language into memory without switching to it."
18264
+ },
18265
+ {
18266
+ "name": "instant",
18267
+ "signature": "(key: string, params?: MkTranslateParams): string",
18268
+ "description": "Translate `key` in the active language, then the fallback; `{{name}}`\nplaceholders come from `params`. A missing key renders as the key\nitself (or whatever `onMissing` returns) and is recorded in\n`missingKeys`. Reactive: reading it inside a template or a\n`computed()` re-runs on language switch and after `patch()`."
18269
+ },
18270
+ {
18271
+ "name": "has",
18272
+ "signature": "(key: string, lang?: string): boolean",
18273
+ "description": "Whether `key` exists in `lang` (default: the active language) or its fallback."
18274
+ },
18275
+ {
18276
+ "name": "plural",
18277
+ "signature": "(keyBase: string, count: number, params?: MkTranslateParams): string",
18278
+ "description": "CLDR plural form: `keyBase.{zero|one|two|few|many|other}` picked with\n`Intl.PluralRules` for the active language, `other` as the fallback,\ninterpolated with `{ count, ...params }`.\n\n```json\n{ \"guests\": { \"one\": \"{{count}} osoba\", \"few\": \"{{count}} osoby\", \"many\": \"{{count}} osób\", \"other\": \"{{count}} osoby\" } }\n```"
18279
+ },
18280
+ {
18281
+ "name": "translations",
18282
+ "signature": "(lang?: string): MkFlatTranslations",
18283
+ "description": "The flat dictionary of `lang` (default: active), `{}` before it loads."
18284
+ },
18285
+ {
18286
+ "name": "loadedLangs",
18287
+ "signature": "(): string[]",
18288
+ "description": "Languages currently in memory."
18289
+ },
18290
+ {
18291
+ "name": "patch",
18292
+ "signature": "(lang: string, strings: MkTranslationTree | MkFlatTranslations): void",
18293
+ "description": "Merge strings into `lang` at runtime — a translation editor previewing\nan edit, or a late-arriving overrides payload. Nested or flat."
18294
+ },
18295
+ {
18296
+ "name": "set",
18297
+ "signature": "(lang: string, strings: MkTranslationTree | MkFlatTranslations): void",
18298
+ "description": "Replace `lang` entirely (tests, editors reloading from source)."
18299
+ },
18300
+ {
18301
+ "name": "isPartial",
18302
+ "signature": "(lang?: string): boolean",
18303
+ "description": "`true` while `lang` holds only a server render's keys and the rest is still loading."
18304
+ }
18305
+ ],
18306
+ "properties": [
18307
+ {
18308
+ "name": "lang",
18309
+ "type": "WritableSignal<string>",
18310
+ "description": "The active language. Read it in a `computed()` to follow switches.",
18311
+ "readonly": true
18312
+ },
18313
+ {
18314
+ "name": "ready",
18315
+ "type": "Signal<boolean>",
18316
+ "description": "`true` once the active language's strings are in memory.",
18317
+ "readonly": true
18318
+ },
18319
+ {
18320
+ "name": "langChange",
18321
+ "type": "Observable<string>",
18322
+ "description": "`lang` as an observable, for code still written around streams.",
18323
+ "readonly": true
18324
+ },
18325
+ {
18326
+ "name": "missingKeys",
18327
+ "type": "Signal<string[]>",
18328
+ "description": "Keys asked for that neither the active nor the fallback language has.",
18329
+ "readonly": true
18330
+ },
18331
+ {
18332
+ "name": "currentLang",
18333
+ "type": "string",
18334
+ "description": "ngx-translate-compatible alias of `getCurrentLang`.",
18335
+ "readonly": true
18336
+ }
18337
+ ],
18338
+ "docs": "/components/translate"
18339
+ },
18340
+ {
18341
+ "name": "mkFlattenTranslations",
18342
+ "description": "`{ a: { b: 'x' } }` → `{ 'a.b': 'x' }`; already-dotted keys pass through.",
18343
+ "file": "projects/mk-kit/translate/translate.service.ts",
18344
+ "kind": "function",
18345
+ "signatures": [
18346
+ "(tree: MkTranslationTree | null | undefined, prefix?: string, out?: MkFlatTranslations): MkFlatTranslations"
18347
+ ]
18348
+ },
18349
+ {
18350
+ "name": "mkHttpTranslateLoader",
18351
+ "description": "Fetch `<prefix><lang><suffix>` with `HttpClient` — the bundled JSON files\nin `assets/i18n/`. Needs `provideHttpClient()`; SSR apps that read the\nfiles from disk can supply their own `MkTranslateLoader` instead.",
18352
+ "file": "projects/mk-kit/translate/translate.loaders.ts",
18353
+ "kind": "function",
18354
+ "signatures": [
18355
+ "(options?: MkHttpTranslateLoaderOptions): MkTranslateLoaderFactory"
18356
+ ]
18357
+ },
18358
+ {
18359
+ "name": "mkInterpolate",
18360
+ "description": "Replace `{{name}}` placeholders; unknown names are left in place.",
18361
+ "file": "projects/mk-kit/translate/translate.service.ts",
18362
+ "kind": "function",
18363
+ "signatures": [
18364
+ "(template: string, params?: MkTranslateParams): string"
18365
+ ]
18366
+ },
18367
+ {
18368
+ "name": "mkStaticTranslateLoader",
18369
+ "description": "Strings given up front, keyed by language — tests, storybooks, tiny apps.\nA language not in the map resolves to `{}`.",
18370
+ "file": "projects/mk-kit/translate/translate.loaders.ts",
18371
+ "kind": "function",
18372
+ "signatures": [
18373
+ "(byLang: Record<string, MkTranslationTree>): MkTranslateLoaderFactory"
18374
+ ]
18375
+ },
18376
+ {
18377
+ "name": "mkUnflattenTranslations",
18378
+ "description": "`{ 'a.b': 'x' }` → `{ a: { b: 'x' } }` — for editors that write files back.",
18379
+ "file": "projects/mk-kit/translate/translate.service.ts",
18380
+ "kind": "function",
18381
+ "signatures": [
18382
+ "(flat: MkFlatTranslations): MkTranslationTree"
18383
+ ]
18384
+ },
18385
+ {
18386
+ "name": "provideMkTranslate",
18387
+ "description": "Register app translations. By default the initial language is loaded\nbefore the first render (`preload`), so no view ever shows raw keys and\nnothing caches them.\n\n```ts\nproviders: [\n provideHttpClient(withFetch()),\n provideMkTranslate({\n lang: 'pl',\n fallbackLang: 'pl',\n loader: mkHttpTranslateLoader(),\n overrides: () => inject(TranslationOverridesApi), // optional\n }),\n]\n```",
18388
+ "file": "projects/mk-kit/translate/translate.providers.ts",
18389
+ "kind": "function",
18390
+ "signatures": [
18391
+ "(config: MkTranslateConfig): EnvironmentProviders"
18392
+ ]
18393
+ },
18394
+ {
18395
+ "name": "MK_TRANSLATE_CONFIG",
18396
+ "description": "Configuration token; set by `provideMkTranslate`.",
18397
+ "file": "projects/mk-kit/translate/translate.service.ts",
18398
+ "kind": "token",
18399
+ "type": "InjectionToken<MkTranslateConfig>"
18400
+ },
18401
+ {
18402
+ "name": "MkTranslateImports",
18403
+ "description": "Everything a template needs, for `imports: [...MkTranslateImports]` — the\none-line replacement for an ngx-translate `TranslateModule` import.",
18404
+ "file": "projects/mk-kit/translate/translate.pipe.ts",
18405
+ "kind": "const",
18406
+ "type": "readonly [typeof MkTranslatePipe, typeof MkTranslatePluralPipe]"
18407
+ },
18408
+ {
18409
+ "name": "MkHttpTranslateLoaderOptions",
18410
+ "description": "Options for `mkHttpTranslateLoader`.",
18411
+ "file": "projects/mk-kit/translate/translate.loaders.ts",
18412
+ "kind": "interface",
18413
+ "members": [
18414
+ {
18415
+ "name": "prefix",
18416
+ "type": "string | undefined",
18417
+ "description": "URL prefix; the language code is appended. Default `/assets/i18n/`.",
18418
+ "optional": true
18419
+ },
18420
+ {
18421
+ "name": "suffix",
18422
+ "type": "string | undefined",
18423
+ "description": "URL suffix after the language code. Default `.json`.",
18424
+ "optional": true
18425
+ }
18426
+ ]
18427
+ },
18428
+ {
18429
+ "name": "MkTranslateConfig",
18430
+ "description": "Options for `provideMkTranslate`.",
18431
+ "file": "projects/mk-kit/translate/translate.types.ts",
18432
+ "kind": "interface",
18433
+ "members": [
18434
+ {
18435
+ "name": "lang",
18436
+ "type": "string",
18437
+ "description": "Language loaded first and used until `use()` switches it."
18438
+ },
18439
+ {
18440
+ "name": "fallbackLang",
18441
+ "type": "string | undefined",
18442
+ "description": "Looked up when the active language lacks a key. Default: none.",
18443
+ "optional": true
18444
+ },
18445
+ {
18446
+ "name": "loader",
18447
+ "type": "MkTranslateLoaderFactory",
18448
+ "description": "Base strings — the bundled JSON, typically (`mkHttpTranslateLoader`)."
18449
+ },
18450
+ {
18451
+ "name": "overrides",
18452
+ "type": "MkTranslateLoaderFactory | undefined",
18453
+ "description": "Optional second source merged OVER the base per language: edits kept in\na database, a tenant's wording, a translator's work in progress. A\nloader that throws or resolves `{}` leaves the base untouched.",
18454
+ "optional": true
18455
+ },
18456
+ {
18457
+ "name": "preload",
18458
+ "type": "boolean | undefined",
18459
+ "description": "Block application bootstrap until the initial language is loaded, so the\nfirst render never shows raw keys and `instant()` calls inside\n`computed()` never cache them. Default `true`.",
18460
+ "optional": true
18461
+ },
18462
+ {
18463
+ "name": "transfer",
18464
+ "type": "\"none\" | \"used\" | \"all\" | undefined",
18465
+ "description": "What a server render hands to the browser through `TransferState`:\n- `'used'` (default): only the keys read while rendering this page —\n a few KB — so hydration never flashes raw keys, while the full\n dictionary loads in the background right after;\n- `'all'`: the whole dictionary (no second request, but every page\n carries it);\n- `'none'`: nothing; the browser loads the file itself before bootstrap.",
18466
+ "optional": true
18467
+ },
18468
+ {
18469
+ "name": "documentLang",
18470
+ "type": "boolean | undefined",
18471
+ "description": "Mirror the active language onto `<html lang>` (server and browser), so\nscreen readers, hyphenation and search engines follow `use()`. Default\n`true`.",
18472
+ "optional": true
18473
+ },
18474
+ {
18475
+ "name": "onMissing",
18476
+ "type": "((key: string, lang: string) => string | undefined | void) | undefined",
18477
+ "description": "Called for a key missing in both the active and the fallback language.\nReturn a string to render instead of the key. Missing keys are also\ncollected in `MkTranslate.missingKeys`.",
18478
+ "optional": true
18479
+ }
18480
+ ]
18481
+ },
18482
+ {
18483
+ "name": "MkTranslateLoader",
18484
+ "description": "Where a language's strings come from. Return the tree (or a promise of\nit); the service flattens, caches per language and merges overrides.",
18485
+ "file": "projects/mk-kit/translate/translate.types.ts",
18486
+ "kind": "interface",
18487
+ "members": [
18488
+ {
18489
+ "name": "load",
18490
+ "type": "(lang: string): Promise<MkTranslationTree> | MkTranslationTree",
18491
+ "description": ""
18492
+ }
18493
+ ]
18494
+ },
18495
+ {
18496
+ "name": "MkTranslationTree",
18497
+ "description": "A translation file: nested objects of strings. Keys are addressed with\ndots (`checkout.cart.total`), so `{ checkout: { cart: { total: '…' } } }`\nand `{ 'checkout.cart.total': '…' }` are the same dictionary. This is the\nplain JSON most apps already ship (ngx-translate's format included).",
18498
+ "file": "projects/mk-kit/translate/translate.types.ts",
18499
+ "kind": "interface",
18500
+ "members": []
18501
+ },
18502
+ {
18503
+ "name": "MkFlatTranslations",
18504
+ "description": "Flattened dictionary: dotted key → string.",
18505
+ "file": "projects/mk-kit/translate/translate.types.ts",
18506
+ "kind": "type",
18507
+ "definition": "Record<string, string>"
18508
+ },
18509
+ {
18510
+ "name": "MkTranslateLoaderFactory",
18511
+ "description": "A loader factory; runs inside an injection context, so `inject()` works.",
18512
+ "file": "projects/mk-kit/translate/translate.types.ts",
18513
+ "kind": "type",
18514
+ "definition": "() => MkTranslateLoader"
18515
+ },
18516
+ {
18517
+ "name": "MkTranslateParams",
18518
+ "description": "Values interpolated into `{{name}}` placeholders.",
18519
+ "file": "projects/mk-kit/translate/translate.types.ts",
18520
+ "kind": "type",
18521
+ "definition": "Record<string, unknown>"
18522
+ }
18523
+ ]
18524
+ },
17979
18525
  {
17980
18526
  "name": "feedback",
17981
18527
  "import": "@mk-kit/ui/feedback",
@@ -24212,6 +24758,46 @@
24212
24758
  "definition": "| 'Enter' | 'Escape' | 'Tab' | 'Backspace' | 'Delete' | ' ' | 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight' | 'Home' | 'End' | 'PageUp' | 'PageDown'"
24213
24759
  }
24214
24760
  ]
24761
+ },
24762
+ {
24763
+ "name": "translate/server",
24764
+ "import": "@mk-kit/ui/translate/server",
24765
+ "exports": [
24766
+ {
24767
+ "name": "mkFsTranslateLoader",
24768
+ "description": "Server-side loader that reads the translation JSON from disk instead of\nfetching the app's own HTTP endpoint during SSR — no self-request, no\nproxy hop, no interceptor ordering to get right. Register it in the\nserver config only (`app.config.server.ts`); the browser keeps\n`mkHttpTranslateLoader`. Files are parsed once per process.\n\n```ts\n// app.config.server.ts\nprovideMkTranslate({\n ...browserTranslateConfig,\n loader: mkFsTranslateLoader({\n dirs: [join(import.meta.dirname, '../browser/assets/i18n'), join(process.cwd(), 'src/assets/i18n')],\n }),\n})\n```",
24769
+ "file": "projects/mk-kit/translate/server/fs-loader.ts",
24770
+ "kind": "function",
24771
+ "signatures": [
24772
+ "(options: MkFsTranslateLoaderOptions): MkTranslateLoaderFactory"
24773
+ ]
24774
+ },
24775
+ {
24776
+ "name": "MkFsTranslateLoaderOptions",
24777
+ "description": "Options for `mkFsTranslateLoader`.",
24778
+ "file": "projects/mk-kit/translate/server/fs-loader.ts",
24779
+ "kind": "interface",
24780
+ "members": [
24781
+ {
24782
+ "name": "dirs",
24783
+ "type": "string[]",
24784
+ "description": "Directories searched in order for `<lang><suffix>`; the first readable\nfile wins. Typical: the built browser assets next to the server bundle,\nthen the source tree for `ng serve`."
24785
+ },
24786
+ {
24787
+ "name": "suffix",
24788
+ "type": "string | undefined",
24789
+ "description": "File suffix after the language code. Default `.json`.",
24790
+ "optional": true
24791
+ },
24792
+ {
24793
+ "name": "onNotFound",
24794
+ "type": "\"empty\" | \"throw\" | undefined",
24795
+ "description": "When no directory has the file: return `{}` (default) so the app boots\nwith keys as text, or throw so the failure surfaces at once.",
24796
+ "optional": true
24797
+ }
24798
+ ]
24799
+ }
24800
+ ]
24215
24801
  }
24216
24802
  ]
24217
24803
  }
@@ -1,4 +1,4 @@
1
- # @mk-kit/ui 0.54.0 — full API reference
1
+ # @mk-kit/ui 0.55.1 — full API reference
2
2
 
3
3
  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
4
4
 
@@ -1129,6 +1129,8 @@ Members:
1129
1129
  | `dndMoved` | `(position: number, total: number) => string` | Announced as the item moves within its list. |
1130
1130
  | `dndMovedToList` | `(list: string, position: number, total: number) => string` | Announced as the item moves into another list. |
1131
1131
  | `dndDropped` | `(position: number) => string` | Announced when the item is dropped. |
1132
+ | `dndMovedToZone` | `(zone: string) => string` | Announced as a lifted item reaches a drop zone (a target that is not a list). |
1133
+ | `dndDroppedInZone` | `(zone: string) => string` | Announced when the item is dropped on a zone. |
1132
1134
  | `dndCancelled` | `string` | Announced when the drag is cancelled. |
1133
1135
  | `repeaterAddRow` | `string` | Repeater add-row button caption (default when no `addLabel` is given). |
1134
1136
  | `repeaterRemoveRow` | `(index: number) => string` | Repeater per-row remove button label (1-based row number). |
@@ -3186,7 +3188,7 @@ type MkPluralForms = { other: string } & Partial<Record<Intl.LDMLPluralRule, str
3186
3188
 
3187
3189
  ## @mk-kit/ui/dnd
3188
3190
 
3189
- 9 exports. `import { … } from '@mk-kit/ui/dnd';`
3191
+ 13 exports. `import { … } from '@mk-kit/ui/dnd';`
3190
3192
 
3191
3193
  ### MkDrag (component)
3192
3194
 
@@ -3217,6 +3219,12 @@ Keyboard: focus the item (or its handle) and press **Space/Enter** to pick
3217
3219
  it up, **Arrow** keys to move it (crossing into connected lists at the ends /
3218
3220
  across the perpendicular axis), **Space/Enter** to drop, **Escape** to cancel.
3219
3221
 
3222
+ Besides lists, an item can be released on a connected `[mkDropZone]` — a
3223
+ target that reports *where* it was dropped instead of an index (a timeline,
3224
+ a priority band, a "focus on this" pane). Zones sit in the same keyboard
3225
+ travel group as lists, in document order; while an item hovers a zone no
3226
+ placeholder is shown and the zone streams `mkDropZoneMoved` events.
3227
+
3220
3228
  Touch: a swipe scrolls the page as usual — the drag only arms after a
3221
3229
  long-press (`mkDragTouchDelay`, default 300 ms). While armed the item
3222
3230
  gets the `mk-drag--armed` class so consumers can style the lift moment.
@@ -3325,6 +3333,78 @@ Properties:
3325
3333
  | `role` | `Signal<string \| null>` | The role the host exposes. One set in the template wins. A `<ul>`/`<ol>` keeps its implicit `list` role (`null` — nothing is written) while every item hands the keyboard drag to a focusable handle, and becomes a `listbox` (its items `option`s) otherwise. Any other element is a `group`. |
3326
3334
  | `connectedTo` | `Signal<readonly string[]>` | Connected-list ids, normalised to a plain array. |
3327
3335
 
3336
+ ### MkDropZone (component)
3337
+
3338
+ Selector: `[mkDropZone]` · exportAs: `mkDropZone`
3339
+
3340
+ Import: `import { MkDropZone } from '@mk-kit/ui/dnd';`
3341
+
3342
+ A drop **target** that is not a list: an item dragged out of a connected
3343
+ `[mkDropList]` can be released anywhere on it, and the zone reports *where*
3344
+ — client coordinates, the offset inside the zone and the 0–1 fraction along
3345
+ each axis — so the consumer can turn a position into meaning: a time on a
3346
+ timeline, a priority band, a "focus on this" pane, a trash can.
3347
+
3348
+ Nothing reorders and no placeholder is shown while an item hovers a zone;
3349
+ the zone gets the `mk-drop-zone--receiving` class and a stream of
3350
+ `mkDropZoneMoved` events instead. Zones and lists can overlap — the
3351
+ innermost target under the pointer wins, so a column can hold three
3352
+ priority bands and still accept plain drops between the bands.
3353
+
3354
+ Wire a zone exactly like another list: give it an id and name that id in
3355
+ the source list's `mkDropListConnectedTo`.
3356
+
3357
+ Keyboard: a lifted item reaches zones with the arrow keys that cross lists
3358
+ (Left/Right in a vertical list, Up/Down in a horizontal one) — zones sit in
3359
+ the same DOM-ordered travel group as connected lists; Space/Enter drops at
3360
+ the zone's centre. Every step is announced.
3361
+
3362
+ ```html
3363
+ <ul mkDropList mkDropListId="backlog" [mkDropListConnectedTo]="['now', 'rail']" …>
3364
+ <section mkDropZone mkDropZoneId="now" mkDropZoneLabel="Focus now"
3365
+ (mkDropZoneDropped)="focus($event.item.mkDragData())">
3366
+ <div mkDropZone mkDropZoneId="rail" mkDropZoneLabel="Today"
3367
+ (mkDropZoneMoved)="preview($event.fractionY)"
3368
+ (mkDropZoneDropped)="schedule($event.item.mkDragData(), $event.fractionY)">
3369
+ ```
3370
+
3371
+ Inputs:
3372
+
3373
+ | Name | Type | Default | Description |
3374
+ | --- | --- | --- | --- |
3375
+ | `mkDropZoneId` | `string \| undefined` | | Stable id source lists name in `mkDropListConnectedTo`. Auto-generated when omitted. |
3376
+ | `mkDropZoneLabel` | `string` | `''` | Human-readable name, used in screen-reader announcements when a lifted item reaches the zone ("Moved to Focus now") and as the zone's accessible name. Set it: the fallback is the id, which may be generated gibberish. |
3377
+ | `mkDropZoneLabelledBy` | `string` | `''` | Id of a visible element that names the zone (`aria-labelledby`); wins over the label as the accessible name. |
3378
+ | `mkDropZoneData` | `Z \| undefined` | | Arbitrary payload handed back on every hover and drop event. |
3379
+ | `mkDropZoneDisabled` | `boolean` | `false` | Disable dropping onto this zone (it leaves the travel group too). |
3380
+
3381
+ Outputs:
3382
+
3383
+ | Name | Type | Description |
3384
+ | --- | --- | --- |
3385
+ | `mkDropZoneEntered` | `MkDropZoneHover<T, Z>` | An item entered the zone (pointer or keyboard). |
3386
+ | `mkDropZoneMoved` | `MkDropZoneHover<T, Z>` | The pointer moved while over the zone (one per frame, pointer only). |
3387
+ | `mkDropZoneLeft` | `MkDrag<T>` | The item left the zone without dropping (moved on, or the drag was cancelled). |
3388
+ | `mkDropZoneDropped` | `MkDropZoneEvent<T, Z>` | The item was released on the zone. |
3389
+
3390
+ Methods:
3391
+
3392
+ | Signature | Description |
3393
+ | --- | --- |
3394
+ | `setReceiving(value: boolean): void` | Toggle the "receiving" highlight (called by the active drag). |
3395
+ | `emitEntered(event: MkDropZoneHover<T, Z>): void` | Called by the active `MkDrag` — not part of the consumer API. |
3396
+ | `emitMoved(event: MkDropZoneHover<T, Z>): void` | |
3397
+ | `emitLeft(item: MkDrag<T>): void` | |
3398
+ | `emitDrop(event: MkDropZoneEvent<T, Z>): void` | |
3399
+
3400
+ Properties:
3401
+
3402
+ | Name | Type | Description |
3403
+ | --- | --- | --- |
3404
+ | `element` | `HTMLElement` | The zone's host element (drop target bounds). |
3405
+ | `id` | `Signal<string>` | Resolved id (input or generated). |
3406
+ | `label` | `Signal<string>` | Announceable name: the label when set, otherwise the resolved id. |
3407
+
3328
3408
  ### MkSortableList (component)
3329
3409
 
3330
3410
  Selector: `mk-sortable-list`
@@ -3446,6 +3526,11 @@ Methods:
3446
3526
  | `get(id: string): MkDropList<any> \| undefined` | Look up a list by its `mkDropListId`. |
3447
3527
  | `all(): MkDropList<any>[]` | All registered lists, in registration order. |
3448
3528
  | `connectedGroup(list: MkDropList<any>): MkDropList<any>[]` | The ordered travel group for `list`: `list` itself plus every enabled list it is `mkDropListConnectedTo`, in registration (roughly DOM) order. Used to resolve "adjacent" lists for keyboard column-to-column movement and to hit-test the pointer against candidate targets. |
3529
+ | `registerZone(id: string, zone: MkDropZone<any>): void` | Register (or replace) the zone published under `id`. |
3530
+ | `unregisterZone(id: string, zone: MkDropZone<any>): void` | Remove `zone` from the registry if it is still the holder of `id`. |
3531
+ | `getZone(id: string): MkDropZone<any> \| undefined` | Look up a zone by its `mkDropZoneId`. |
3532
+ | `connectedZones(list: MkDropList<any>): MkDropZone<any>[]` | Every enabled zone named in `list`'s `mkDropListConnectedTo`, in registration order. |
3533
+ | `travelGroup(list: MkDropList<any>): MkDropTarget[]` | The keyboard travel group for `list`: its connected lists **and** zones, in document order, so arrow keys walk targets the way they appear on screen regardless of when each registered. |
3449
3534
 
3450
3535
  ### mkMoveItemInArray (function)
3451
3536
 
@@ -3513,6 +3598,44 @@ Members:
3513
3598
  | `container` | `MkDropList<T>` | The list the item was dropped into (same as `previousContainer` for a re-sort). |
3514
3599
  | `isPointerEvent` | `boolean` | `true` for pointer (mouse/touch/pen) drops, `false` for keyboard drops. |
3515
3600
 
3601
+ ### MkDropZoneEvent (interface)
3602
+
3603
+ Import: `import { MkDropZoneEvent } from '@mk-kit/ui/dnd';`
3604
+
3605
+ Emitted by `[mkDropZone]` (`mkDropZoneDropped`) when an item is released on
3606
+ it. Carries the same position fields as `MkDropZoneHover` plus where
3607
+ the item came from — the consumer removes it from that list (or not: a
3608
+ "focus on this" zone may leave the card where it is).
3609
+
3610
+ Members (extends `MkDropZoneHover<T, Z>`):
3611
+
3612
+ | Name | Type | Description |
3613
+ | --- | --- | --- |
3614
+ | `previousContainer` | `MkDropList<T>` | The list the item came from. |
3615
+ | `previousIndex` | `number` | Index of the item within `previousContainer`'s data. |
3616
+
3617
+ ### MkDropZoneHover (interface)
3618
+
3619
+ Import: `import { MkDropZoneHover } from '@mk-kit/ui/dnd';`
3620
+
3621
+ Where an item is over a `[mkDropZone]`, emitted on enter and on every
3622
+ pointer frame (`mkDropZoneEntered` / `mkDropZoneMoved`). Keyboard entries
3623
+ report the zone's centre.
3624
+
3625
+ Members:
3626
+
3627
+ | Name | Type | Description |
3628
+ | --- | --- | --- |
3629
+ | `item` | `MkDrag<T>` | The `MkDrag` directive instance being dragged. |
3630
+ | `zone` | `MkDropZone<Z, any>` | The zone under the pointer. |
3631
+ | `x` | `number` | Pointer position in client (viewport) coordinates. |
3632
+ | `y` | `number` | |
3633
+ | `offsetX` | `number` | Pointer position relative to the zone's top-left corner, in CSS pixels. |
3634
+ | `offsetY` | `number` | |
3635
+ | `fractionX` | `number` | Pointer position as a 0–1 fraction of the zone's width / height (clamped). |
3636
+ | `fractionY` | `number` | |
3637
+ | `isPointerEvent` | `boolean` | `true` for pointer (mouse/touch/pen) hovers, `false` for keyboard steps. |
3638
+
3516
3639
  ### MkDropListOrientation (type)
3517
3640
 
3518
3641
  Import: `import { MkDropListOrientation } from '@mk-kit/ui/dnd';`
@@ -3523,6 +3646,16 @@ Layout axis a drop list lays its items along.
3523
3646
  type MkDropListOrientation = 'vertical' | 'horizontal';
3524
3647
  ```
3525
3648
 
3649
+ ### MkDropTarget (type)
3650
+
3651
+ Import: `import { MkDropTarget } from '@mk-kit/ui/dnd';`
3652
+
3653
+ A keyboard-reachable drop target: a connected list or a connected zone.
3654
+
3655
+ ```ts
3656
+ type MkDropTarget = MkDropList<any> | MkDropZone<any>;
3657
+ ```
3658
+
3526
3659
  ## @mk-kit/ui/navigation
3527
3660
 
3528
3661
  37 exports. `import { … } from '@mk-kit/ui/navigation';`
@@ -11917,6 +12050,275 @@ Members:
11917
12050
  | `index` | `number` | Its position in `columns`. |
11918
12051
  | `count` | `number` | `column.cards.length`, for a count badge. |
11919
12052
 
12053
+ ## @mk-kit/ui/translate
12054
+
12055
+ 18 exports. `import { … } from '@mk-kit/ui/translate';`
12056
+
12057
+ ### MkTranslatePipe (pipe)
12058
+
12059
+ Pipe name: `translate` · `transform(key: string | null | undefined, params?: MkTranslateParams): string`
12060
+
12061
+ Import: `import { MkTranslatePipe } from '@mk-kit/ui/translate';`
12062
+
12063
+ `translate` — the key's string in the active language, with `{{name}}`
12064
+ placeholders filled from `params`. Impure so a language switch (or a
12065
+ `patch()`) re-renders every use; the signal reads inside `instant()` mark
12066
+ the host view dirty, so this stays cheap under OnPush and zoneless.
12067
+
12068
+ ```html
12069
+ {{ 'menu.title' | translate }}
12070
+ {{ 'cart.items' | translate: { count: 3 } }}
12071
+ ```
12072
+
12073
+ ### MkTranslatePluralPipe (pipe)
12074
+
12075
+ Pipe name: `translatePlural` · `transform(count: number | string | null | undefined, keyBase: string, params?: MkTranslateParams): string`
12076
+
12077
+ Import: `import { MkTranslatePluralPipe } from '@mk-kit/ui/translate';`
12078
+
12079
+ `translatePlural` — the CLDR plural form under `keyBase` for a count
12080
+ (see `MkTranslate.plural`), interpolated with `{ count, ...params }`.
12081
+
12082
+ ```html
12083
+ {{ guests | translatePlural: 'reservation.guests' }} <!-- 2 osoby / 5 osób -->
12084
+ ```
12085
+
12086
+ ### MkTranslate (service)
12087
+
12088
+ Docs: https://mk-kit.dev/components/translate
12089
+
12090
+ Import: `import { MkTranslate } from '@mk-kit/ui/translate';`
12091
+
12092
+ App translations as signals: a `lang` you switch with `use()`, `instant()`
12093
+ for code, the `translate` pipe for templates, and `plural()` for CLDR
12094
+ count forms. Dictionaries are the plain nested JSON you already have; an
12095
+ optional overrides loader (a database of edits, say) is merged on top per
12096
+ language. On the server the loaded strings ride to the browser through
12097
+ `TransferState`, so hydration never refetches or flashes raw keys.
12098
+
12099
+ ```ts
12100
+ provideMkTranslate({
12101
+ lang: 'pl',
12102
+ fallbackLang: 'pl',
12103
+ loader: mkHttpTranslateLoader({ prefix: '/assets/i18n/' }),
12104
+ });
12105
+ ```
12106
+ ```html
12107
+ {{ 'checkout.cart.total' | translate }}
12108
+ {{ 'checkout.cart.freeDeliveryMissing' | translate: { amount: 12 } }}
12109
+ ```
12110
+
12111
+ Methods:
12112
+
12113
+ | Signature | Description |
12114
+ | --- | --- |
12115
+ | `getCurrentLang(): string` | The active language as a plain string (for non-reactive call sites). |
12116
+ | `getLangs(): string[]` | Languages known to the service: loaded ones plus any added with `addLangs`. |
12117
+ | `addLangs(langs: string[]): void` | Declare languages up front (a switcher's list); loading still happens on `use()`. |
12118
+ | `setTranslation(lang: string, strings: MkTranslationTree \| MkFlatTranslations, shouldMerge?: boolean): void` | ngx-translate-compatible alias: `setTranslation(lang, strings, true)` merges like `patch`, `false` (the default there) replaces like `set`. |
12119
+ | `use(lang: string): Promise<void>` | Load `lang` (once — later calls are cached) and make it active. Resolves when the strings are in memory; a failed load rejects and leaves the previous language active. |
12120
+ | `load(lang: string): Promise<void>` | Load a language into memory without switching to it. |
12121
+ | `instant(key: string, params?: MkTranslateParams): string` | Translate `key` in the active language, then the fallback; `{{name}}` placeholders come from `params`. A missing key renders as the key itself (or whatever `onMissing` returns) and is recorded in `missingKeys`. Reactive: reading it inside a template or a `computed()` re-runs on language switch and after `patch()`. |
12122
+ | `has(key: string, lang?: string): boolean` | Whether `key` exists in `lang` (default: the active language) or its fallback. |
12123
+ | `plural(keyBase: string, count: number, params?: MkTranslateParams): string` | CLDR plural form: `keyBase.{zero\|one\|two\|few\|many\|other}` picked with `Intl.PluralRules` for the active language, `other` as the fallback, interpolated with `{ count, ...params }`. ```json { "guests": { "one": "{{count}} osoba", "few": "{{count}} osoby", "many": "{{count}} osób", "other": "{{count}} osoby" } } ``` |
12124
+ | `translations(lang?: string): MkFlatTranslations` | The flat dictionary of `lang` (default: active), `{}` before it loads. |
12125
+ | `loadedLangs(): string[]` | Languages currently in memory. |
12126
+ | `patch(lang: string, strings: MkTranslationTree \| MkFlatTranslations): void` | Merge strings into `lang` at runtime — a translation editor previewing an edit, or a late-arriving overrides payload. Nested or flat. |
12127
+ | `set(lang: string, strings: MkTranslationTree \| MkFlatTranslations): void` | Replace `lang` entirely (tests, editors reloading from source). |
12128
+ | `isPartial(lang?: string): boolean` | `true` while `lang` holds only a server render's keys and the rest is still loading. |
12129
+
12130
+ Properties:
12131
+
12132
+ | Name | Type | Description |
12133
+ | --- | --- | --- |
12134
+ | `lang` | `WritableSignal<string>` | The active language. Read it in a `computed()` to follow switches. |
12135
+ | `ready` | `Signal<boolean>` | `true` once the active language's strings are in memory. |
12136
+ | `langChange` | `Observable<string>` | `lang` as an observable, for code still written around streams. |
12137
+ | `missingKeys` | `Signal<string[]>` | Keys asked for that neither the active nor the fallback language has. |
12138
+ | `currentLang` | `string` | ngx-translate-compatible alias of `getCurrentLang`. |
12139
+
12140
+ ### mkFlattenTranslations (function)
12141
+
12142
+ Import: `import { mkFlattenTranslations } from '@mk-kit/ui/translate';`
12143
+
12144
+ `{ a: { b: 'x' } }` → `{ 'a.b': 'x' }`; already-dotted keys pass through.
12145
+
12146
+ ```ts
12147
+ function mkFlattenTranslations(tree: MkTranslationTree | null | undefined, prefix?: string, out?: MkFlatTranslations): MkFlatTranslations
12148
+ ```
12149
+
12150
+ ### mkHttpTranslateLoader (function)
12151
+
12152
+ Import: `import { mkHttpTranslateLoader } from '@mk-kit/ui/translate';`
12153
+
12154
+ Fetch `<prefix><lang><suffix>` with `HttpClient` — the bundled JSON files
12155
+ in `assets/i18n/`. Needs `provideHttpClient()`; SSR apps that read the
12156
+ files from disk can supply their own `MkTranslateLoader` instead.
12157
+
12158
+ ```ts
12159
+ function mkHttpTranslateLoader(options?: MkHttpTranslateLoaderOptions): MkTranslateLoaderFactory
12160
+ ```
12161
+
12162
+ ### mkInterpolate (function)
12163
+
12164
+ Import: `import { mkInterpolate } from '@mk-kit/ui/translate';`
12165
+
12166
+ Replace `{{name}}` placeholders; unknown names are left in place.
12167
+
12168
+ ```ts
12169
+ function mkInterpolate(template: string, params?: MkTranslateParams): string
12170
+ ```
12171
+
12172
+ ### mkStaticTranslateLoader (function)
12173
+
12174
+ Import: `import { mkStaticTranslateLoader } from '@mk-kit/ui/translate';`
12175
+
12176
+ Strings given up front, keyed by language — tests, storybooks, tiny apps.
12177
+ A language not in the map resolves to `{}`.
12178
+
12179
+ ```ts
12180
+ function mkStaticTranslateLoader(byLang: Record<string, MkTranslationTree>): MkTranslateLoaderFactory
12181
+ ```
12182
+
12183
+ ### mkUnflattenTranslations (function)
12184
+
12185
+ Import: `import { mkUnflattenTranslations } from '@mk-kit/ui/translate';`
12186
+
12187
+ `{ 'a.b': 'x' }` → `{ a: { b: 'x' } }` — for editors that write files back.
12188
+
12189
+ ```ts
12190
+ function mkUnflattenTranslations(flat: MkFlatTranslations): MkTranslationTree
12191
+ ```
12192
+
12193
+ ### provideMkTranslate (function)
12194
+
12195
+ Import: `import { provideMkTranslate } from '@mk-kit/ui/translate';`
12196
+
12197
+ Register app translations. By default the initial language is loaded
12198
+ before the first render (`preload`), so no view ever shows raw keys and
12199
+ nothing caches them.
12200
+
12201
+ ```ts
12202
+ providers: [
12203
+ provideHttpClient(withFetch()),
12204
+ provideMkTranslate({
12205
+ lang: 'pl',
12206
+ fallbackLang: 'pl',
12207
+ loader: mkHttpTranslateLoader(),
12208
+ overrides: () => inject(TranslationOverridesApi), // optional
12209
+ }),
12210
+ ]
12211
+ ```
12212
+
12213
+ ```ts
12214
+ function provideMkTranslate(config: MkTranslateConfig): EnvironmentProviders
12215
+ ```
12216
+
12217
+ ### MK_TRANSLATE_CONFIG (token)
12218
+
12219
+ Import: `import { MK_TRANSLATE_CONFIG } from '@mk-kit/ui/translate';`
12220
+
12221
+ Configuration token; set by `provideMkTranslate`.
12222
+
12223
+ ```ts
12224
+ const MK_TRANSLATE_CONFIG: InjectionToken<MkTranslateConfig>;
12225
+ ```
12226
+
12227
+ ### MkTranslateImports (const)
12228
+
12229
+ Import: `import { MkTranslateImports } from '@mk-kit/ui/translate';`
12230
+
12231
+ Everything a template needs, for `imports: [...MkTranslateImports]` — the
12232
+ one-line replacement for an ngx-translate `TranslateModule` import.
12233
+
12234
+ ```ts
12235
+ const MkTranslateImports: readonly [typeof MkTranslatePipe, typeof MkTranslatePluralPipe];
12236
+ ```
12237
+
12238
+ ### MkHttpTranslateLoaderOptions (interface)
12239
+
12240
+ Import: `import { MkHttpTranslateLoaderOptions } from '@mk-kit/ui/translate';`
12241
+
12242
+ Options for `mkHttpTranslateLoader`.
12243
+
12244
+ Members:
12245
+
12246
+ | Name | Type | Description |
12247
+ | --- | --- | --- |
12248
+ | `prefix`? | `string \| undefined` | URL prefix; the language code is appended. Default `/assets/i18n/`. |
12249
+ | `suffix`? | `string \| undefined` | URL suffix after the language code. Default `.json`. |
12250
+
12251
+ ### MkTranslateConfig (interface)
12252
+
12253
+ Import: `import { MkTranslateConfig } from '@mk-kit/ui/translate';`
12254
+
12255
+ Options for `provideMkTranslate`.
12256
+
12257
+ Members:
12258
+
12259
+ | Name | Type | Description |
12260
+ | --- | --- | --- |
12261
+ | `lang` | `string` | Language loaded first and used until `use()` switches it. |
12262
+ | `fallbackLang`? | `string \| undefined` | Looked up when the active language lacks a key. Default: none. |
12263
+ | `loader` | `MkTranslateLoaderFactory` | Base strings — the bundled JSON, typically (`mkHttpTranslateLoader`). |
12264
+ | `overrides`? | `MkTranslateLoaderFactory \| undefined` | Optional second source merged OVER the base per language: edits kept in a database, a tenant's wording, a translator's work in progress. A loader that throws or resolves `{}` leaves the base untouched. |
12265
+ | `preload`? | `boolean \| undefined` | Block application bootstrap until the initial language is loaded, so the first render never shows raw keys and `instant()` calls inside `computed()` never cache them. Default `true`. |
12266
+ | `transfer`? | `"none" \| "used" \| "all" \| undefined` | What a server render hands to the browser through `TransferState`: - `'used'` (default): only the keys read while rendering this page — a few KB — so hydration never flashes raw keys, while the full dictionary loads in the background right after; - `'all'`: the whole dictionary (no second request, but every page carries it); - `'none'`: nothing; the browser loads the file itself before bootstrap. |
12267
+ | `documentLang`? | `boolean \| undefined` | Mirror the active language onto `<html lang>` (server and browser), so screen readers, hyphenation and search engines follow `use()`. Default `true`. |
12268
+ | `onMissing`? | `((key: string, lang: string) => string \| undefined \| void) \| undefined` | Called for a key missing in both the active and the fallback language. Return a string to render instead of the key. Missing keys are also collected in `MkTranslate.missingKeys`. |
12269
+
12270
+ ### MkTranslateLoader (interface)
12271
+
12272
+ Import: `import { MkTranslateLoader } from '@mk-kit/ui/translate';`
12273
+
12274
+ Where a language's strings come from. Return the tree (or a promise of
12275
+ it); the service flattens, caches per language and merges overrides.
12276
+
12277
+ Members:
12278
+
12279
+ | Name | Type | Description |
12280
+ | --- | --- | --- |
12281
+ | `load` | `(lang: string): Promise<MkTranslationTree> \| MkTranslationTree` | |
12282
+
12283
+ ### MkTranslationTree (interface)
12284
+
12285
+ Import: `import { MkTranslationTree } from '@mk-kit/ui/translate';`
12286
+
12287
+ A translation file: nested objects of strings. Keys are addressed with
12288
+ dots (`checkout.cart.total`), so `{ checkout: { cart: { total: '…' } } }`
12289
+ and `{ 'checkout.cart.total': '…' }` are the same dictionary. This is the
12290
+ plain JSON most apps already ship (ngx-translate's format included).
12291
+
12292
+ ### MkFlatTranslations (type)
12293
+
12294
+ Import: `import { MkFlatTranslations } from '@mk-kit/ui/translate';`
12295
+
12296
+ Flattened dictionary: dotted key → string.
12297
+
12298
+ ```ts
12299
+ type MkFlatTranslations = Record<string, string>;
12300
+ ```
12301
+
12302
+ ### MkTranslateLoaderFactory (type)
12303
+
12304
+ Import: `import { MkTranslateLoaderFactory } from '@mk-kit/ui/translate';`
12305
+
12306
+ A loader factory; runs inside an injection context, so `inject()` works.
12307
+
12308
+ ```ts
12309
+ type MkTranslateLoaderFactory = () => MkTranslateLoader;
12310
+ ```
12311
+
12312
+ ### MkTranslateParams (type)
12313
+
12314
+ Import: `import { MkTranslateParams } from '@mk-kit/ui/translate';`
12315
+
12316
+ Values interpolated into `{{name}}` placeholders.
12317
+
12318
+ ```ts
12319
+ type MkTranslateParams = Record<string, unknown>;
12320
+ ```
12321
+
11920
12322
  ## @mk-kit/ui/feedback
11921
12323
 
11922
12324
  55 exports. `import { … } from '@mk-kit/ui/feedback';`
@@ -16241,3 +16643,45 @@ Keys accepted by `MkTestElement.sendKeys` besides printable characters.
16241
16643
  ```ts
16242
16644
  type MkTestKey = | 'Enter' | 'Escape' | 'Tab' | 'Backspace' | 'Delete' | ' ' | 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight' | 'Home' | 'End' | 'PageUp' | 'PageDown';
16243
16645
  ```
16646
+
16647
+ ## @mk-kit/ui/translate/server
16648
+
16649
+ 2 exports. `import { … } from '@mk-kit/ui/translate/server';`
16650
+
16651
+ ### mkFsTranslateLoader (function)
16652
+
16653
+ Import: `import { mkFsTranslateLoader } from '@mk-kit/ui/translate/server';`
16654
+
16655
+ Server-side loader that reads the translation JSON from disk instead of
16656
+ fetching the app's own HTTP endpoint during SSR — no self-request, no
16657
+ proxy hop, no interceptor ordering to get right. Register it in the
16658
+ server config only (`app.config.server.ts`); the browser keeps
16659
+ `mkHttpTranslateLoader`. Files are parsed once per process.
16660
+
16661
+ ```ts
16662
+ // app.config.server.ts
16663
+ provideMkTranslate({
16664
+ ...browserTranslateConfig,
16665
+ loader: mkFsTranslateLoader({
16666
+ dirs: [join(import.meta.dirname, '../browser/assets/i18n'), join(process.cwd(), 'src/assets/i18n')],
16667
+ }),
16668
+ })
16669
+ ```
16670
+
16671
+ ```ts
16672
+ function mkFsTranslateLoader(options: MkFsTranslateLoaderOptions): MkTranslateLoaderFactory
16673
+ ```
16674
+
16675
+ ### MkFsTranslateLoaderOptions (interface)
16676
+
16677
+ Import: `import { MkFsTranslateLoaderOptions } from '@mk-kit/ui/translate/server';`
16678
+
16679
+ Options for `mkFsTranslateLoader`.
16680
+
16681
+ Members:
16682
+
16683
+ | Name | Type | Description |
16684
+ | --- | --- | --- |
16685
+ | `dirs` | `string[]` | Directories searched in order for `<lang><suffix>`; the first readable file wins. Typical: the built browser assets next to the server bundle, then the source tree for `ng serve`. |
16686
+ | `suffix`? | `string \| undefined` | File suffix after the language code. Default `.json`. |
16687
+ | `onNotFound`? | `"empty" \| "throw" \| undefined` | When no directory has the file: return `{}` (default) so the app boots with keys as text, or throw so the failure surfaces at once. |
package/data/llms.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  # mk-kit
2
2
 
3
- > Themable, accessible Angular 22 component library for admin dashboards and UIs. Signals-based, WCAG 2.1 AA, controlled entirely through CSS variables with light/dark out of the box. — `@mk-kit/ui` 0.54.0. 172 components, 45 directives, 16 services and 145 helper functions across 32 tree-shakeable entry points. MIT licensed, zero runtime dependencies beyond Angular. Standalone components, signals, OnPush, zoneless-ready, SSR-safe, RTL and i18n via `provideMkI18n`.
3
+ > Themable, accessible Angular 22 component library for admin dashboards and UIs. Signals-based, WCAG 2.1 AA, controlled entirely through CSS variables with light/dark out of the box. — `@mk-kit/ui` 0.55.1. 173 components, 45 directives, 17 services and 152 helper functions across 34 tree-shakeable entry points. MIT licensed, zero runtime dependencies beyond Angular. Standalone components, signals, OnPush, zoneless-ready, SSR-safe, RTL and i18n via `provideMkI18n`.
4
4
 
5
5
  Install with `ng add @mk-kit/ui` (or `npm i @mk-kit/ui` + import `@mk-kit/ui/styles/mk-kit.css`). Import from the group entry points (`@mk-kit/ui/forms`, `@mk-kit/ui/table`, …) so each lazy chunk only carries what it uses; the root `@mk-kit/ui` entry re-exports everything. Every component is standalone: add the class to a component's `imports`. Theme with `--mk-*` CSS custom properties; `MkThemeService` switches light/dark/system and density.
6
6
 
@@ -35,6 +35,7 @@ Install with `ng add @mk-kit/ui` (or `npm i @mk-kit/ui` + import `@mk-kit/ui/sty
35
35
  - [Sliders & rating](https://mk-kit.dev/components/sliders)
36
36
  - [Tooltips & popovers](https://mk-kit.dev/components/popovers)
37
37
  - [Dialogs](https://mk-kit.dev/components/dialogs)
38
+ - [Translate](https://mk-kit.dev/components/translate)
38
39
  - [Status & notifications](https://mk-kit.dev/components/status)
39
40
  - [Proportion & KPI charts](https://mk-kit.dev/components/proportion-charts)
40
41
  - [Dashboard example](https://mk-kit.dev/examples/dashboard)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mk-kit/mcp",
3
- "version": "0.54.0",
3
+ "version": "0.55.1",
4
4
  "description": "MCP server for @mk-kit/ui — lets AI coding assistants look up every component, directive, service and helper of the mk-kit Angular library (inputs, outputs, methods, import paths, docs links).",
5
5
  "license": "MIT",
6
6
  "type": "module",