@mk-kit/ui 0.43.0 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/fesm2022/mk-kit-ui-core.mjs +5 -0
- package/fesm2022/mk-kit-ui-core.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-data.mjs +1 -1
- package/fesm2022/mk-kit-ui-data.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-directives.mjs +27 -8
- package/fesm2022/mk-kit-ui-directives.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-dnd.mjs +43 -8
- package/fesm2022/mk-kit-ui-dnd.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-forms.mjs +1 -1
- package/fesm2022/mk-kit-ui-forms.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-media.mjs +1 -1
- package/fesm2022/mk-kit-ui-media.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-table.mjs +658 -22
- package/fesm2022/mk-kit-ui-table.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-testing.mjs +54 -0
- package/fesm2022/mk-kit-ui-testing.mjs.map +1 -1
- package/package.json +1 -1
- package/types/mk-kit-ui-core.d.ts +10 -0
- package/types/mk-kit-ui-directives.d.ts +12 -6
- package/types/mk-kit-ui-dnd.d.ts +32 -4
- package/types/mk-kit-ui-table.d.ts +234 -8
- package/types/mk-kit-ui-testing.d.ts +16 -0
|
@@ -872,7 +872,7 @@ class MkMediaGallery {
|
|
|
872
872
|
event.stopPropagation();
|
|
873
873
|
}
|
|
874
874
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkMediaGallery, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
875
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: MkMediaGallery, isStandalone: true, selector: "mk-media-gallery", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, reorderable: { classPropertyName: "reorderable", publicName: "reorderable", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { items: "itemsChange", selection: "selectionChange", itemClick: "itemClick", reordered: "reordered" }, host: { attributes: { "role": "group" }, properties: { "attr.aria-label": "ariaLabel()" }, classAttribute: "mk-media-gallery" }, queries: [{ propertyName: "actions", first: true, predicate: MkMediaActions, descendants: true, isSignal: true }], exportAs: ["mkMediaGallery"], ngImport: i0, template: "@if (items().length === 0) {\n <div class=\"mk-media-gallery__empty\">{{ i18n.noData }}</div>\n} @else if (reorderable()) {\n <div\n mkDropList\n class=\"mk-media-gallery__grid\"\n [style.--_cols]=\"columns()\"\n [mkDropListData]=\"items()\"\n [mkDropListLabel]=\"ariaLabel()\"\n mkDropListOrientation=\"horizontal\"\n (mkDropListDropped)=\"onDrop($event)\"\n >\n @for (item of items(); track item.id) {\n <div\n mkDrag\n class=\"mk-media-gallery__tile\"\n [class.mk-media-gallery__tile--selected]=\"isSelected(item.id)\"\n [mkDragData]=\"item\"\n >\n <ng-container\n [ngTemplateOutlet]=\"tile\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </div>\n }\n </div>\n} @else {\n <div class=\"mk-media-gallery__grid\" [style.--_cols]=\"columns()\">\n @for (item of items(); track item.id) {\n <div\n class=\"mk-media-gallery__tile\"\n [class.mk-media-gallery__tile--selected]=\"isSelected(item.id)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"tile\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </div>\n }\n </div>\n}\n\n<ng-template #tile let-item>\n <div class=\"mk-media-gallery__media\">\n <button\n type=\"button\"\n class=\"mk-media-gallery__preview\"\n [attr.aria-label]=\"i18n.viewImage(item.alt ?? item.name)\"\n (click)=\"onPreviewClick(item)\"\n (keydown)=\"stopEvent($event)\"\n >\n <img\n class=\"mk-media-gallery__img\"\n [src]=\"item.thumb ?? item.src\"\n [alt]=\"item.alt ?? ''\"\n loading=\"lazy\"\n draggable=\"false\"\n />\n </button>\n\n @if (selectable()) {\n <span\n class=\"mk-media-gallery__check\"\n (keydown)=\"stopEvent($event)\"\n (pointerdown)=\"stopEvent($event)\"\n >\n <input\n type=\"checkbox\"\n class=\"mk-media-gallery__check-input\"\n [checked]=\"isSelected(item.id)\"\n [attr.aria-label]=\"i18n.selectRow(item.name)\"\n (change)=\"onCheckboxChange(item, $event)\"\n />\n <span class=\"mk-media-gallery__check-box\" aria-hidden=\"true\">\n <span class=\"mk-media-gallery__check-mark\"></span>\n </span>\n </span>\n }\n\n @if (actions(); as actionsDir) {\n <div\n class=\"mk-media-gallery__actions\"\n (keydown)=\"stopEvent($event)\"\n (pointerdown)=\"stopEvent($event)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"actionsDir.template\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </div>\n }\n </div>\n\n <div class=\"mk-media-gallery__caption\">\n <span class=\"mk-media-gallery__name\">{{ item.name }}</span>\n @if (item.meta) {\n <span class=\"mk-media-gallery__meta\">{{ item.meta }}</span>\n }\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";:host{display:block;font-family:var(--mk-font-sans);color:var(--mk-text)}.mk-media-gallery__grid{display:grid;grid-template-columns:repeat(var(--_cols, 4),1fr);gap:var(--mk-space-3)}.mk-media-gallery__tile{position:relative;display:flex;flex-direction:column;gap:var(--mk-space-1);min-width:0;border-radius:var(--mk-radius-md)}.mk-media-gallery__tile:focus-visible{outline:var(--mk-focus-ring-width) solid var(--mk-focus-ring);outline-offset:var(--mk-focus-ring-offset)}.mk-media-gallery__media{position:relative;aspect-ratio:1/1;overflow:hidden;background-color:var(--mk-surface-2);border-radius:var(--mk-radius-md)}.mk-media-gallery__tile--selected .mk-media-gallery__media{outline:var(--mk-border-width-strong) solid var(--mk-primary);outline-offset:var(--mk-focus-ring-offset)}.mk-media-gallery__preview{position:absolute;inset:0;display:block;width:100%;height:100%;padding:0;margin:0;cursor:pointer;background:none;border:none;border-radius:inherit}.mk-media-gallery__preview:focus-visible{outline:var(--mk-focus-ring-width) solid var(--mk-focus-ring);outline-offset:calc(-1 * var(--mk-focus-ring-width) - var(--mk-focus-ring-offset))}.mk-media-gallery__img{display:block;width:100%;height:100%;object-fit:cover;transition:transform var(--mk-duration-normal) var(--mk-ease-standard)}.mk-media-gallery__preview:hover .mk-media-gallery__img{transform:scale(1.04)}.mk-media-gallery__check{position:absolute;top:var(--mk-space-2);left:var(--mk-space-2);display:inline-flex;width:1.25rem;height:1.25rem}.mk-media-gallery__check-input{position:absolute;inset:calc(-1 * var(--mk-space-2));width:auto;height:auto;margin:0;cursor:pointer;opacity:0}.mk-media-gallery__check-box{display:inline-flex;align-items:center;justify-content:center;width:100%;height:100%;pointer-events:none;background-color:var(--mk-surface);border:var(--mk-border-width-strong) solid var(--mk-border-strong);border-radius:var(--mk-radius-sm);box-shadow:var(--mk-shadow-sm);transition:background-color var(--mk-duration-fast) var(--mk-ease-standard),border-color var(--mk-duration-fast) var(--mk-ease-standard)}.mk-media-gallery__check-mark{width:30%;height:55%;border-right:2px solid var(--mk-primary-contrast);border-bottom:2px solid var(--mk-primary-contrast);opacity:0;transform:rotate(45deg) translateY(-8%)}.mk-media-gallery__check-input:hover+.mk-media-gallery__check-box{border-color:var(--mk-primary)}.mk-media-gallery__check-input:checked+.mk-media-gallery__check-box{background-color:var(--mk-primary);border-color:var(--mk-primary)}.mk-media-gallery__check-input:checked+.mk-media-gallery__check-box .mk-media-gallery__check-mark{opacity:1}.mk-media-gallery__check-input:focus-visible+.mk-media-gallery__check-box{outline:var(--mk-focus-ring-width) solid var(--mk-focus-ring);outline-offset:var(--mk-focus-ring-offset)}.mk-media-gallery__actions{position:absolute;top:var(--mk-space-2);right:var(--mk-space-2);display:flex;gap:var(--mk-space-1);align-items:center;padding:var(--mk-space-1);background-color:color-mix(in srgb,var(--mk-surface) 85%,transparent);border-radius:var(--mk-radius-sm);box-shadow:var(--mk-shadow-sm);opacity:0;transition:opacity var(--mk-duration-fast) var(--mk-ease-standard)}.mk-media-gallery__tile:hover .mk-media-gallery__actions,.mk-media-gallery__tile:focus-within .mk-media-gallery__actions{opacity:1}@media(hover:none){.mk-media-gallery__actions{opacity:1}}.mk-media-gallery__caption{display:flex;flex-direction:column;min-width:0;padding:0 var(--mk-space-1) var(--mk-space-1)}.mk-media-gallery__name{overflow:hidden;font-size:var(--mk-font-size-sm);font-weight:var(--mk-font-weight-medium);text-overflow:ellipsis;white-space:nowrap}.mk-media-gallery__meta{overflow:hidden;font-size:var(--mk-font-size-xs);color:var(--mk-text-muted);text-overflow:ellipsis;white-space:nowrap}.mk-media-gallery__empty{display:flex;align-items:center;justify-content:center;padding:var(--mk-space-10) var(--mk-space-4);font-size:var(--mk-font-size-sm);color:var(--mk-text-muted);text-align:center;background-color:var(--mk-surface-2);border:var(--mk-border-width) dashed var(--mk-border);border-radius:var(--mk-radius-lg)}@media(prefers-reduced-motion:reduce){.mk-media-gallery__img,.mk-media-gallery__actions,.mk-media-gallery__check-box{transition:none}.mk-media-gallery__preview:hover .mk-media-gallery__img{transform:none}}\n"], dependencies: [{ kind: "component", type: MkDropList, selector: "[mkDropList]", inputs: ["mkDropListData", "mkDropListId", "mkDropListConnectedTo", "mkDropListLabel", "mkDropListOrientation", "mkDropListDisabled"], outputs: ["mkDropListDropped"], exportAs: ["mkDropList"] }, { kind: "component", type: MkDrag, selector: "[mkDrag]", inputs: ["mkDragData", "mkDragDisabled", "mkDragTouchDelay"], exportAs: ["mkDrag"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
875
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: MkMediaGallery, isStandalone: true, selector: "mk-media-gallery", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, reorderable: { classPropertyName: "reorderable", publicName: "reorderable", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { items: "itemsChange", selection: "selectionChange", itemClick: "itemClick", reordered: "reordered" }, host: { attributes: { "role": "group" }, properties: { "attr.aria-label": "ariaLabel()" }, classAttribute: "mk-media-gallery" }, queries: [{ propertyName: "actions", first: true, predicate: MkMediaActions, descendants: true, isSignal: true }], exportAs: ["mkMediaGallery"], ngImport: i0, template: "@if (items().length === 0) {\n <div class=\"mk-media-gallery__empty\">{{ i18n.noData }}</div>\n} @else if (reorderable()) {\n <div\n mkDropList\n class=\"mk-media-gallery__grid\"\n [style.--_cols]=\"columns()\"\n [mkDropListData]=\"items()\"\n [mkDropListLabel]=\"ariaLabel()\"\n mkDropListOrientation=\"horizontal\"\n (mkDropListDropped)=\"onDrop($event)\"\n >\n @for (item of items(); track item.id) {\n <div\n mkDrag\n class=\"mk-media-gallery__tile\"\n [class.mk-media-gallery__tile--selected]=\"isSelected(item.id)\"\n [mkDragData]=\"item\"\n >\n <ng-container\n [ngTemplateOutlet]=\"tile\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </div>\n }\n </div>\n} @else {\n <div class=\"mk-media-gallery__grid\" [style.--_cols]=\"columns()\">\n @for (item of items(); track item.id) {\n <div\n class=\"mk-media-gallery__tile\"\n [class.mk-media-gallery__tile--selected]=\"isSelected(item.id)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"tile\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </div>\n }\n </div>\n}\n\n<ng-template #tile let-item>\n <div class=\"mk-media-gallery__media\">\n <button\n type=\"button\"\n class=\"mk-media-gallery__preview\"\n [attr.aria-label]=\"i18n.viewImage(item.alt ?? item.name)\"\n (click)=\"onPreviewClick(item)\"\n (keydown)=\"stopEvent($event)\"\n >\n <img\n class=\"mk-media-gallery__img\"\n [src]=\"item.thumb ?? item.src\"\n [alt]=\"item.alt ?? ''\"\n loading=\"lazy\"\n draggable=\"false\"\n />\n </button>\n\n @if (selectable()) {\n <span\n class=\"mk-media-gallery__check\"\n (keydown)=\"stopEvent($event)\"\n (pointerdown)=\"stopEvent($event)\"\n >\n <input\n type=\"checkbox\"\n class=\"mk-media-gallery__check-input\"\n [checked]=\"isSelected(item.id)\"\n [attr.aria-label]=\"i18n.selectRow(item.name)\"\n (change)=\"onCheckboxChange(item, $event)\"\n />\n <span class=\"mk-media-gallery__check-box\" aria-hidden=\"true\">\n <span class=\"mk-media-gallery__check-mark\"></span>\n </span>\n </span>\n }\n\n @if (actions(); as actionsDir) {\n <div\n class=\"mk-media-gallery__actions\"\n (keydown)=\"stopEvent($event)\"\n (pointerdown)=\"stopEvent($event)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"actionsDir.template\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </div>\n }\n </div>\n\n <div class=\"mk-media-gallery__caption\">\n <span class=\"mk-media-gallery__name\">{{ item.name }}</span>\n @if (item.meta) {\n <span class=\"mk-media-gallery__meta\">{{ item.meta }}</span>\n }\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";:host{display:block;font-family:var(--mk-font-sans);color:var(--mk-text)}.mk-media-gallery__grid{display:grid;grid-template-columns:repeat(var(--_cols, 4),1fr);gap:var(--mk-space-3)}.mk-media-gallery__tile{position:relative;display:flex;flex-direction:column;gap:var(--mk-space-1);min-width:0;border-radius:var(--mk-radius-md)}.mk-media-gallery__tile:focus-visible{outline:var(--mk-focus-ring-width) solid var(--mk-focus-ring);outline-offset:var(--mk-focus-ring-offset)}.mk-media-gallery__media{position:relative;aspect-ratio:1/1;overflow:hidden;background-color:var(--mk-surface-2);border-radius:var(--mk-radius-md)}.mk-media-gallery__tile--selected .mk-media-gallery__media{outline:var(--mk-border-width-strong) solid var(--mk-primary);outline-offset:var(--mk-focus-ring-offset)}.mk-media-gallery__preview{position:absolute;inset:0;display:block;width:100%;height:100%;padding:0;margin:0;cursor:pointer;background:none;border:none;border-radius:inherit}.mk-media-gallery__preview:focus-visible{outline:var(--mk-focus-ring-width) solid var(--mk-focus-ring);outline-offset:calc(-1 * var(--mk-focus-ring-width) - var(--mk-focus-ring-offset))}.mk-media-gallery__img{display:block;width:100%;height:100%;object-fit:cover;transition:transform var(--mk-duration-normal) var(--mk-ease-standard)}.mk-media-gallery__preview:hover .mk-media-gallery__img{transform:scale(1.04)}.mk-media-gallery__check{position:absolute;top:var(--mk-space-2);left:var(--mk-space-2);display:inline-flex;width:1.25rem;height:1.25rem}.mk-media-gallery__check-input{position:absolute;inset:calc(-1 * var(--mk-space-2));width:auto;height:auto;margin:0;cursor:pointer;opacity:0}.mk-media-gallery__check-box{display:inline-flex;align-items:center;justify-content:center;width:100%;height:100%;pointer-events:none;background-color:var(--mk-surface);border:var(--mk-border-width-strong) solid var(--mk-border-strong);border-radius:var(--mk-radius-sm);box-shadow:var(--mk-shadow-sm);transition:background-color var(--mk-duration-fast) var(--mk-ease-standard),border-color var(--mk-duration-fast) var(--mk-ease-standard)}.mk-media-gallery__check-mark{width:30%;height:55%;border-right:2px solid var(--mk-primary-contrast);border-bottom:2px solid var(--mk-primary-contrast);opacity:0;transform:rotate(45deg) translateY(-8%)}.mk-media-gallery__check-input:hover+.mk-media-gallery__check-box{border-color:var(--mk-primary)}.mk-media-gallery__check-input:checked+.mk-media-gallery__check-box{background-color:var(--mk-primary);border-color:var(--mk-primary)}.mk-media-gallery__check-input:checked+.mk-media-gallery__check-box .mk-media-gallery__check-mark{opacity:1}.mk-media-gallery__check-input:focus-visible+.mk-media-gallery__check-box{outline:var(--mk-focus-ring-width) solid var(--mk-focus-ring);outline-offset:var(--mk-focus-ring-offset)}.mk-media-gallery__actions{position:absolute;top:var(--mk-space-2);right:var(--mk-space-2);display:flex;gap:var(--mk-space-1);align-items:center;padding:var(--mk-space-1);background-color:color-mix(in srgb,var(--mk-surface) 85%,transparent);border-radius:var(--mk-radius-sm);box-shadow:var(--mk-shadow-sm);opacity:0;transition:opacity var(--mk-duration-fast) var(--mk-ease-standard)}.mk-media-gallery__tile:hover .mk-media-gallery__actions,.mk-media-gallery__tile:focus-within .mk-media-gallery__actions{opacity:1}@media(hover:none){.mk-media-gallery__actions{opacity:1}}.mk-media-gallery__caption{display:flex;flex-direction:column;min-width:0;padding:0 var(--mk-space-1) var(--mk-space-1)}.mk-media-gallery__name{overflow:hidden;font-size:var(--mk-font-size-sm);font-weight:var(--mk-font-weight-medium);text-overflow:ellipsis;white-space:nowrap}.mk-media-gallery__meta{overflow:hidden;font-size:var(--mk-font-size-xs);color:var(--mk-text-muted);text-overflow:ellipsis;white-space:nowrap}.mk-media-gallery__empty{display:flex;align-items:center;justify-content:center;padding:var(--mk-space-10) var(--mk-space-4);font-size:var(--mk-font-size-sm);color:var(--mk-text-muted);text-align:center;background-color:var(--mk-surface-2);border:var(--mk-border-width) dashed var(--mk-border);border-radius:var(--mk-radius-lg)}@media(prefers-reduced-motion:reduce){.mk-media-gallery__img,.mk-media-gallery__actions,.mk-media-gallery__check-box{transition:none}.mk-media-gallery__preview:hover .mk-media-gallery__img{transform:none}}\n"], dependencies: [{ kind: "component", type: MkDropList, selector: "[mkDropList]", inputs: ["mkDropListData", "mkDropListId", "mkDropListConnectedTo", "mkDropListLabel", "mkDropListLabelledBy", "mkDropListOrientation", "mkDropListDisabled"], outputs: ["mkDropListDropped"], exportAs: ["mkDropList"] }, { kind: "component", type: MkDrag, selector: "[mkDrag]", inputs: ["mkDragData", "mkDragDisabled", "mkDragTouchDelay"], exportAs: ["mkDrag"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
876
876
|
}
|
|
877
877
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkMediaGallery, decorators: [{
|
|
878
878
|
type: Component,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mk-kit-ui-media.mjs","sources":["../../../projects/mk-kit/media/image/image.ts","../../../projects/mk-kit/media/image/image.html","../../../projects/mk-kit/media/lightbox/lightbox.ts","../../../projects/mk-kit/media/lightbox/lightbox.html","../../../projects/mk-kit/media/lightbox/lightbox.service.ts","../../../projects/mk-kit/media/image-gallery/image-gallery.ts","../../../projects/mk-kit/media/image-gallery/image-gallery.html","../../../projects/mk-kit/media/image-cropper/image-cropper.ts","../../../projects/mk-kit/media/image-cropper/image-cropper.html","../../../projects/mk-kit/media/media-gallery/media-gallery.ts","../../../projects/mk-kit/media/media-gallery/media-gallery.html","../../../projects/mk-kit/media/index.ts","../../../projects/mk-kit/media/mk-kit-ui-media.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n computed,\n Component,\n booleanAttribute,\n inject,\n input,\n linkedSignal,\n output,\n} from '@angular/core';\nimport { MK_I18N } from '@mk-kit/ui/core';\n\n/** How the picture is scaled inside its frame (`object-fit`). */\nexport type MkImageFit = 'cover' | 'contain';\n/** Corner rounding applied to the frame of an {@link MkImage}. */\nexport type MkImageRounded = 'none' | 'md' | 'lg' | 'circle';\n/** Load lifecycle of an {@link MkImage}. */\nexport type MkImageState = 'loading' | 'loaded' | 'error';\n\n/**\n * Image — an enhanced image block. While the picture loads it shows a skeleton\n * shimmer, and when loading fails it swaps to a localised fallback panel\n * (icon + text, never colour alone). The picture is wrapped in a `<figure>`\n * with an optional `<figcaption>`, and changing `src` restarts the whole load\n * cycle.\n *\n * ```html\n * <mk-image\n * src=\"/photos/harbour.jpg\"\n * alt=\"Harbour at dawn\"\n * aspectRatio=\"16 / 9\"\n * caption=\"The old harbour, photographed at dawn\"\n * (loaded)=\"onLoaded()\"\n * (errored)=\"onErrored()\"\n * />\n *\n * <!-- The hero: eager, high priority, and sized per breakpoint so a phone\n * does not download the desktop file. -->\n * <mk-image\n * src=\"/photos/hero-1600.jpg\"\n * srcset=\"/photos/hero-800.jpg 800w, /photos/hero-1600.jpg 1600w\"\n * sizes=\"100vw\"\n * alt=\"\"\n * aspectRatio=\"16 / 9\"\n * priority\n * />\n * ```\n *\n * `aspectRatio` is what keeps this from shifting layout: the frame reserves\n * its box before the picture arrives, so nothing below it moves.\n */\n@Component({\n selector: 'mk-image',\n exportAs: 'mkImage',\n templateUrl: './image.html',\n styleUrl: './image.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'mk-image',\n '[attr.data-fit]': 'fit()',\n '[attr.data-rounded]': 'rounded()',\n '[attr.data-state]': 'state()',\n },\n})\nexport class MkImage {\n /** Localised strings (override globally via `provideMkI18n`). */\n protected readonly i18n = inject(MK_I18N);\n\n /** Image URL. Changing it resets the block to its loading state. */\n readonly src = input.required<string>();\n /** Alt text, always reflected onto the `<img>`. Keep `''` for decorative images. */\n readonly alt = input<string>('');\n /** Any CSS `aspect-ratio` value for the frame, e.g. `'1 / 1'` or `'16 / 9'`. */\n readonly aspectRatio = input<string>('auto');\n /** How the picture fills the frame. */\n readonly fit = input<MkImageFit>('cover');\n /** Corner rounding of the frame. */\n readonly rounded = input<MkImageRounded>('md');\n /** Caption rendered in a `<figcaption>` below the picture. */\n readonly caption = input<string>('');\n /** Defer fetching until near the viewport (`loading=\"lazy\"` vs `\"eager\"`). */\n readonly lazy = input(true, { transform: booleanAttribute });\n /**\n * Mark this as the page's LCP image: fetched eagerly at high priority and\n * decoded synchronously, and `lazy` is ignored. Use it on exactly ONE image\n * per page — the hero. Marking several is worse than marking none, because\n * they then compete for the same bandwidth the real LCP image needs.\n *\n * This does NOT emit a `<link rel=preload>`; the tag has to be in the HTML\n * the server sends to beat the preload scanner, which a component rendered\n * later cannot guarantee. Pair it with a preload hint for a background or\n * late-rendered hero.\n */\n readonly priority = input(false, { transform: booleanAttribute });\n /**\n * Responsive candidates, passed through verbatim to the `<img>`. Serving a\n * 2048px file into a 600px slot is one of the most common LCP mistakes, and\n * this is the fix; pair with {@link sizes}.\n */\n readonly srcset = input<string>('');\n /** `sizes` attribute — how wide the image renders at each breakpoint. */\n readonly sizes = input<string>('');\n\n /** Emits once the picture has finished loading. */\n readonly loaded = output<void>();\n /** Emits when the picture fails to load and the fallback panel is shown. */\n readonly errored = output<void>();\n\n /** `loading` attribute: priority always wins over `lazy`. */\n protected readonly loadingAttr = computed(() =>\n this.priority() ? 'eager' : this.lazy() ? 'lazy' : 'eager',\n );\n\n /** Load lifecycle; snaps back to `'loading'` whenever `src` changes. */\n protected readonly state = linkedSignal<string, MkImageState>({\n source: this.src,\n computation: () => 'loading',\n });\n\n protected onLoad(): void {\n this.state.set('loaded');\n this.loaded.emit();\n }\n\n protected onError(): void {\n this.state.set('error');\n this.errored.emit();\n }\n}\n","<figure class=\"mk-image__figure\">\n <div class=\"mk-image__frame\" [style.aspect-ratio]=\"aspectRatio()\">\n @if (state() !== 'error') {\n <img\n class=\"mk-image__img\"\n [src]=\"src()\"\n [alt]=\"alt()\"\n [attr.srcset]=\"srcset() || null\"\n [attr.sizes]=\"sizes() || null\"\n [attr.loading]=\"loadingAttr()\"\n [attr.fetchpriority]=\"priority() ? 'high' : null\"\n [attr.decoding]=\"priority() ? 'sync' : 'async'\"\n (load)=\"onLoad()\"\n (error)=\"onError()\"\n />\n @if (state() === 'loading') {\n <span class=\"mk-image__skeleton\" aria-hidden=\"true\"></span>\n }\n } @else {\n <div class=\"mk-image__fallback\">\n <svg\n class=\"mk-image__fallback-icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" />\n <circle cx=\"9\" cy=\"10\" r=\"1.5\" />\n <path d=\"m5 17 4-4 3 3 3.5-3.5L20 17\" />\n <path d=\"m4 3 16 18\" />\n </svg>\n <span class=\"mk-image__fallback-text\">{{ i18n.imageFailed }}</span>\n </div>\n }\n </div>\n @if (caption()) {\n <figcaption class=\"mk-image__caption\">{{ caption() }}</figcaption>\n }\n</figure>\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n signal,\n} from '@angular/core';\nimport { MK_I18N, MK_OVERLAY_DATA, MkOverlayRef } from '@mk-kit/ui/core';\nimport type { MkLightboxData, MkLightboxItem } from './lightbox.service';\n\n/**\n * Internal overlay component backing {@link MkLightboxService}. Renders the\n * current image near-fullscreen over the overlay scrim with a caption bar,\n * an `imageOf` counter, a close button and looping previous/next navigation.\n *\n * Keyboard: `ArrowLeft`/`ArrowRight` navigate, `Home`/`End` jump to the first\n * or last image. `Escape` and backdrop clicks are handled by the overlay\n * itself (`closeOnEscape` / `closeOnBackdropClick`), so they are deliberately\n * not re-handled here.\n *\n * Open it via the service — not by placing `<mk-lightbox>` in a template:\n *\n * ```ts\n * inject(MkLightboxService).open(items, 2);\n * ```\n */\n@Component({\n selector: 'mk-lightbox',\n templateUrl: './lightbox.html',\n styleUrl: './lightbox.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n // Bound (not static) so it merges with the overlay's own panel classes —\n // a static host `class` would overwrite `mk-overlay-panel` on the host.\n '[class.mk-lightbox]': 'true',\n '(keydown)': 'onKeydown($event)',\n },\n})\nexport class MkLightbox {\n private readonly ref = inject(MkOverlayRef);\n private readonly data = inject<MkLightboxData | null>(MK_OVERLAY_DATA);\n /** Localised strings (override globally via `provideMkI18n`). */\n protected readonly i18n = inject(MK_I18N);\n\n /** The images being paged through. */\n protected readonly items: readonly MkLightboxItem[] = this.data?.items ?? [];\n /** Total number of images. */\n protected readonly total = this.items.length;\n\n /** Index of the currently displayed image. */\n protected readonly index = signal(\n Math.min(Math.max(this.data?.startIndex ?? 0, 0), Math.max(this.total - 1, 0)),\n );\n /** The currently displayed item. */\n protected readonly current = computed(() => this.items[this.index()]);\n /** Localised \"Image i of n\" counter text. */\n protected readonly counter = computed(() =>\n this.i18n.imageOf(this.index() + 1, this.total),\n );\n\n /** `true` while the current image is still loading. */\n protected readonly loading = signal(true);\n /** `true` when the current image failed to load. */\n protected readonly failed = signal(false);\n\n /** Show the previous image, wrapping from the first to the last. */\n protected previous(): void {\n this.goTo((this.index() - 1 + this.total) % this.total);\n }\n\n /** Show the next image, wrapping from the last back to the first. */\n protected next(): void {\n this.goTo((this.index() + 1) % this.total);\n }\n\n /** Jump to `index`, resetting the loading/error state. */\n protected goTo(index: number): void {\n if (this.total === 0 || index === this.index()) return;\n this.index.set(index);\n this.loading.set(true);\n this.failed.set(false);\n }\n\n /** Close the surrounding overlay. */\n protected close(): void {\n this.ref.close();\n }\n\n /** Current image finished loading — hide the spinner. */\n protected onLoad(): void {\n this.loading.set(false);\n }\n\n /** Current image failed — show the localised failure message instead. */\n protected onError(): void {\n this.loading.set(false);\n this.failed.set(true);\n }\n\n /**\n * Host keydown handler. Escape is intentionally not handled here — the\n * overlay's `closeOnEscape` already closes the lightbox.\n */\n protected onKeydown(event: Event): void {\n const key = (event as KeyboardEvent).key;\n switch (key) {\n case 'ArrowLeft':\n event.preventDefault();\n this.previous();\n break;\n case 'ArrowRight':\n event.preventDefault();\n this.next();\n break;\n case 'Home':\n event.preventDefault();\n this.goTo(0);\n break;\n case 'End':\n event.preventDefault();\n this.goTo(this.total - 1);\n break;\n }\n }\n}\n","@if (current(); as item) {\n <figure class=\"mk-lightbox__figure\">\n <div class=\"mk-lightbox__stage\">\n @if (failed()) {\n <p class=\"mk-lightbox__error\" role=\"alert\">{{ i18n.imageFailed }}</p>\n } @else {\n @if (loading()) {\n <span class=\"mk-lightbox__spinner\" aria-hidden=\"true\"></span>\n }\n <img\n class=\"mk-lightbox__image\"\n [class.mk-lightbox__image--loading]=\"loading()\"\n [src]=\"item.src\"\n [alt]=\"item.alt ?? ''\"\n (load)=\"onLoad()\"\n (error)=\"onError()\"\n />\n }\n </div>\n @if (item.caption) {\n <figcaption class=\"mk-lightbox__caption\">{{ item.caption }}</figcaption>\n }\n <p class=\"mk-lightbox__counter\" aria-live=\"polite\">{{ counter() }}</p>\n </figure>\n}\n\n<button\n type=\"button\"\n class=\"mk-lightbox__button mk-lightbox__close\"\n [attr.aria-label]=\"i18n.close\"\n (click)=\"close()\"\n>\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M6 6l12 12M18 6L6 18\" />\n </svg>\n</button>\n\n@if (total > 1) {\n <button\n type=\"button\"\n class=\"mk-lightbox__button mk-lightbox__nav mk-lightbox__nav--prev\"\n [attr.aria-label]=\"i18n.previousImage\"\n (click)=\"previous()\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M15 5l-7 7 7 7\" />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"mk-lightbox__button mk-lightbox__nav mk-lightbox__nav--next\"\n [attr.aria-label]=\"i18n.nextImage\"\n (click)=\"next()\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n}\n","import { Injectable, inject } from '@angular/core';\nimport { MK_I18N, MkOverlayService } from '@mk-kit/ui/core';\nimport { MkLightbox } from './lightbox';\n\n/** A single image shown by {@link MkLightboxService}. */\nexport interface MkLightboxItem {\n /** Image URL. */\n src: string;\n /** Alternative text for the image. */\n alt?: string;\n /** Optional caption rendered below the image. */\n caption?: string;\n}\n\n/** Data injected into {@link MkLightbox} via `MK_OVERLAY_DATA`. */\nexport interface MkLightboxData {\n /** The images to page through. */\n items: readonly MkLightboxItem[];\n /** Index of the image shown first (already clamped into range). */\n startIndex: number;\n}\n\n/**\n * Fullscreen image lightbox — opens a set of images in a modal overlay with\n * looping previous/next navigation, captions, a counter, keyboard support\n * (Arrow keys, Home/End, Escape) and focus trapping, all powered by\n * {@link MkOverlayService}.\n *\n * ```ts\n * private readonly lightbox = inject(MkLightboxService);\n *\n * viewPhoto(index: number): void {\n * this.lightbox.open(\n * [\n * { src: '/photos/1.jpg', alt: 'Harbour at dawn', caption: 'Dawn' },\n * { src: '/photos/2.jpg', alt: 'Old town square' },\n * ],\n * index,\n * );\n * }\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class MkLightboxService {\n private readonly overlay = inject(MkOverlayService);\n private readonly i18n = inject(MK_I18N);\n\n /**\n * Open the lightbox over the page. Does nothing when `items` is empty.\n * `startIndex` is clamped into `[0, items.length - 1]`.\n */\n open(items: readonly MkLightboxItem[], startIndex = 0): void {\n if (items.length === 0) return;\n const start = Math.min(\n Math.max(Math.trunc(startIndex), 0),\n items.length - 1,\n );\n this.overlay.open<MkLightbox, void, MkLightboxData>(MkLightbox, {\n data: { items, startIndex: start },\n hasBackdrop: true,\n closeOnBackdropClick: true,\n closeOnEscape: true,\n trapFocus: true,\n role: 'dialog',\n ariaLabel: this.i18n.imageOf(start + 1, items.length),\n panelClass: 'mk-lightbox-panel',\n });\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n booleanAttribute,\n computed,\n inject,\n input,\n numberAttribute,\n output,\n} from '@angular/core';\nimport { MK_I18N } from '@mk-kit/ui/core';\nimport { MkImage, type MkImageRounded } from '../image/image';\nimport {\n MkLightboxService,\n type MkLightboxItem,\n} from '../lightbox/lightbox.service';\n\n/** A single picture inside an {@link MkImageGallery}. */\nexport interface MkGalleryItem {\n /** Full-size image URL (what the lightbox opens). */\n src: string;\n /** Optional smaller thumbnail URL for the tile; falls back to `src`. */\n thumb?: string;\n /** Alt text; also drives the tile's accessible label. */\n alt?: string;\n /** Optional caption forwarded to the lightbox. */\n caption?: string;\n}\n\n/** Tile arrangement of an {@link MkImageGallery}. */\nexport type MkImageGalleryLayout = 'grid' | 'masonry' | 'strip';\n\n/** Payload of the {@link MkImageGallery.itemClick} output. */\nexport interface MkGalleryItemClick {\n /** The clicked picture. */\n item: MkGalleryItem;\n /** Its index within `items`. */\n index: number;\n}\n\n/**\n * Image gallery — a wall of clickable picture tiles built on {@link MkImage}.\n * Choose a uniform `grid`, a natural-ratio `masonry` flow, or a snap-scrolling\n * horizontal `strip`. Clicking a tile opens the shared {@link MkLightboxService}\n * at that picture (full-size `src`, not the thumb) and always emits\n * `itemClick`. With `max` set, only the first `max` tiles render and the last\n * one carries a \"+N\" overflow scrim that opens the rest in the lightbox.\n *\n * ```html\n * <mk-image-gallery\n * [items]=\"[\n * { src: '/photos/1.jpg', thumb: '/thumbs/1.jpg', alt: 'Harbour at dawn' },\n * { src: '/photos/2.jpg', alt: 'Old town square', caption: 'Kraków' },\n * ]\"\n * [columns]=\"4\"\n * [max]=\"8\"\n * aspectRatio=\"4 / 3\"\n * (itemClick)=\"onItemClick($event)\"\n * />\n * ```\n */\n@Component({\n selector: 'mk-image-gallery',\n exportAs: 'mkImageGallery',\n templateUrl: './image-gallery.html',\n styleUrl: './image-gallery.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [MkImage],\n host: {\n class: 'mk-image-gallery',\n '[attr.data-layout]': 'layout()',\n '[attr.data-rounded]': 'rounded()',\n '[style.--_cols]': 'columns()',\n },\n})\nexport class MkImageGallery {\n private readonly lightboxService = inject(MkLightboxService);\n /** Localised strings (override globally via `provideMkI18n`). */\n protected readonly i18n = inject(MK_I18N);\n\n /** Pictures to show. */\n readonly items = input.required<readonly MkGalleryItem[]>();\n /** Tile arrangement. */\n readonly layout = input<MkImageGalleryLayout>('grid');\n /** Grid/masonry column count; also sets the visible tile count of a strip. */\n readonly columns = input(3, { transform: numberAttribute });\n /** When set, show only the first `max` tiles plus a \"+N\" overflow tile. */\n readonly max = input<number | null>(null);\n /** Open the shared lightbox on tile click. */\n readonly lightbox = input(true, { transform: booleanAttribute });\n /** CSS aspect-ratio of grid/strip tiles (masonry keeps natural ratios). */\n readonly aspectRatio = input<string>('1 / 1');\n /** Corner rounding of the tiles. */\n readonly rounded = input<MkImageRounded>('md');\n\n /** Emits on every tile click (also when the lightbox opens). */\n readonly itemClick = output<MkGalleryItemClick>();\n\n /** Tiles actually rendered — the first `max` when `max` is set. */\n protected readonly visibleItems = computed(() => {\n const items = this.items();\n const max = this.max();\n return max != null && items.length > max\n ? items.slice(0, Math.max(0, max))\n : items;\n });\n\n /** How many pictures the trailing \"+N\" tile stands for (0 = no overflow). */\n protected readonly overflowCount = computed(\n () => this.items().length - this.visibleItems().length,\n );\n\n /** Frame ratio forwarded to the tiles (`'auto'` in masonry). */\n protected readonly tileAspectRatio = computed(() =>\n this.layout() === 'masonry' ? 'auto' : this.aspectRatio(),\n );\n\n /**\n * Accessible label of tile `index`: `viewImage(alt)` when the picture has\n * alt text, else positional `imageOf(...)`; the overflow tile appends \"+N\".\n */\n protected tileLabel(index: number): string {\n const items = this.items();\n const alt = items[index]?.alt;\n const base = alt\n ? this.i18n.viewImage(alt)\n : this.i18n.imageOf(index + 1, items.length);\n const overflow = this.overflowCount();\n const isOverflowTile =\n overflow > 0 && index === this.visibleItems().length - 1;\n return isOverflowTile ? `${base} (+${overflow})` : base;\n }\n\n protected onTileClick(index: number): void {\n const items = this.items();\n if (this.lightbox()) {\n const lightboxItems: MkLightboxItem[] = items.map(\n ({ src, alt, caption }) => ({ src, alt, caption }),\n );\n this.lightboxService.open(lightboxItems, index);\n }\n this.itemClick.emit({ item: items[index], index });\n }\n}\n","@for (item of visibleItems(); track $index; let i = $index; let last = $last) {\n <button\n type=\"button\"\n class=\"mk-gallery__tile\"\n [attr.aria-label]=\"tileLabel(i)\"\n (click)=\"onTileClick(i)\"\n >\n <mk-image\n [src]=\"item.thumb ?? item.src\"\n [aspectRatio]=\"tileAspectRatio()\"\n [rounded]=\"rounded()\"\n />\n @if (last && overflowCount() > 0) {\n <span class=\"mk-gallery__more\" aria-hidden=\"true\"\n >+{{ overflowCount() }}</span\n >\n }\n </button>\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n PLATFORM_ID,\n afterNextRender,\n booleanAttribute,\n computed,\n effect,\n inject,\n input,\n model,\n numberAttribute,\n output,\n signal,\n untracked,\n viewChild,\n type OnDestroy,\n} from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { MK_I18N } from '@mk-kit/ui/core';\n\n// --- Pure crop geometry -----------------------------------------------------\n// jsdom has no canvas and never loads images, so everything numeric lives in\n// these exported functions where it can be unit-tested directly.\n\n/**\n * Base cover scale for an image in a viewport — the smallest scale at which\n * `imgW × imgH` fully covers `vpW × vpH` (object-fit: cover). Returns `1`\n * for degenerate (non-positive) dimensions.\n */\nexport function mkCoverScale(\n imgW: number,\n imgH: number,\n vpW: number,\n vpH: number,\n): number {\n if (imgW <= 0 || imgH <= 0 || vpW <= 0 || vpH <= 0) return 1;\n return Math.max(vpW / imgW, vpH / imgH);\n}\n\n/**\n * Clamp a pan offset (CSS px, measured from the viewport centre to the image\n * centre) so the image scaled by `scale` still covers the viewport — no empty\n * edges. When the scaled image is not larger than the viewport on an axis the\n * offset collapses to `0` (centred).\n */\nexport function mkClampPan(\n x: number,\n y: number,\n imgW: number,\n imgH: number,\n vpW: number,\n vpH: number,\n scale: number,\n): { x: number; y: number } {\n const maxX = Math.max(0, (imgW * scale - vpW) / 2);\n const maxY = Math.max(0, (imgH * scale - vpH) / 2);\n // `+ 0` normalises the -0 produced when an axis has no slack.\n return {\n x: Math.min(maxX, Math.max(-maxX, x)) + 0,\n y: Math.min(maxY, Math.max(-maxY, y)) + 0,\n };\n}\n\n/**\n * Source rect (in natural image pixels) of the crop region visible through\n * the viewport. `scale` maps natural pixels to CSS pixels (cover scale ×\n * zoom); `panX`/`panY` are the CSS-px offsets of the image centre from the\n * viewport centre. The rect is clamped inside the image bounds.\n */\nexport function mkCropRect(\n imgNaturalW: number,\n imgNaturalH: number,\n vpW: number,\n vpH: number,\n scale: number,\n panX: number,\n panY: number,\n): { sx: number; sy: number; sw: number; sh: number } {\n if (imgNaturalW <= 0 || imgNaturalH <= 0 || vpW <= 0 || vpH <= 0 || scale <= 0) {\n return { sx: 0, sy: 0, sw: Math.max(0, imgNaturalW), sh: Math.max(0, imgNaturalH) };\n }\n const sw = Math.min(vpW / scale, imgNaturalW);\n const sh = Math.min(vpH / scale, imgNaturalH);\n // The image point rendered at the viewport centre.\n const cx = imgNaturalW / 2 - panX / scale;\n const cy = imgNaturalH / 2 - panY / scale;\n const sx = Math.min(Math.max(cx - sw / 2, 0), imgNaturalW - sw);\n const sy = Math.min(Math.max(cy - sh / 2, 0), imgNaturalH - sh);\n return { sx, sy, sw, sh };\n}\n\n/** Zoom step used by the −/+ buttons. */\nconst BUTTON_ZOOM_STEP = 0.25;\n/** Zoom step used by the `+`/`-` keys. */\nconst KEY_ZOOM_STEP = 0.1;\n\ntype CropStatus = 'loading' | 'loaded' | 'error';\n\n/**\n * ImageCropper — pan-and-zoom crop control for avatars, covers and media uploads.\n * The image covers a fixed-aspect viewport (object-fit-cover style); the user\n * drags to pan, scrolls / pinch-zooms via the slider or `+`/`−` controls, and\n * `crop()` renders the visible region to a data-URL on an offscreen canvas.\n *\n * Pan is always clamped so the image keeps covering the viewport, a\n * rule-of-thirds grid appears while dragging, and `round` overlays a circular\n * scrim for avatar crops (the exported bitmap stays rectangular). The crop\n * area is keyboard operable: Arrow keys pan by 10px (1px with Shift), `+`/`-`\n * zoom.\n *\n * ```html\n * <mk-image-cropper #cropper src=\"/assets/photo.jpg\" [aspect]=\"1\" round />\n * <button mkButton (click)=\"avatar = cropper.crop({ size: 512 })\">Save</button>\n * ```\n */\n@Component({\n selector: 'mk-image-cropper',\n templateUrl: './image-cropper.html',\n styleUrl: './image-cropper.scss',\n exportAs: 'mkImageCropper',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'mk-image-cropper',\n '[class.mk-image-cropper--disabled]': 'disabled()',\n '[class.mk-image-cropper--round]': 'round()',\n },\n})\nexport class MkImageCropper implements OnDestroy {\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n /** Localised strings (override globally via `provideMkI18n`). */\n protected readonly i18n = inject(MK_I18N);\n\n private readonly viewportRef =\n viewChild.required<ElementRef<HTMLElement>>('viewport');\n private readonly imageRef = viewChild<ElementRef<HTMLImageElement>>('image');\n\n /** Image URL or data-URL to crop. */\n readonly src = input.required<string>();\n /**\n * Aspect ratio (width / height) of the crop viewport, e.g. `1` for a\n * square or `16 / 9`. `null` makes the viewport fill its container.\n */\n readonly aspect = input<number | null>(1);\n /**\n * Circular mask overlay for avatar crops. Purely visual — the exported\n * bitmap from `crop()` stays rectangular.\n */\n readonly round = input(false, { transform: booleanAttribute });\n /** Lowest allowed zoom factor. */\n readonly minZoom = input(1, { transform: numberAttribute });\n /** Highest allowed zoom factor. */\n readonly maxZoom = input(4, { transform: numberAttribute });\n /** Disable panning and zooming. */\n readonly disabled = input(false, { transform: booleanAttribute });\n /**\n * `crossorigin` for the internal `<img>`. Set to `'anonymous'` when\n * cropping CORS-enabled remote images — without it the canvas is tainted\n * and `crop()` returns `null`. Same-origin and data-URL sources don't\n * need it.\n */\n readonly crossOrigin = input<'anonymous' | 'use-credentials' | null>(null);\n /** Accessible name for the crop area (defaults to the i18n `zoom` label). */\n readonly ariaLabel = input<string | null>(null);\n\n /** Emits on any pan or zoom change. */\n readonly changed = output<void>();\n /** Emits when the image fails to load. */\n readonly imageError = output<void>();\n\n /** Two-way zoom factor, clamped to `[minZoom, maxZoom]`. */\n readonly zoom = model(1);\n\n private readonly natW = signal(0);\n private readonly natH = signal(0);\n private readonly vpW = signal(0);\n private readonly vpH = signal(0);\n private readonly panX = signal(0);\n private readonly panY = signal(0);\n protected readonly status = signal<CropStatus>('loading');\n protected readonly dragging = signal(false);\n\n private dragStart: { x: number; y: number; panX: number; panY: number } | null =\n null;\n private resizeObserver?: ResizeObserver;\n\n private readonly coverScale = computed(() =>\n mkCoverScale(this.natW(), this.natH(), this.vpW(), this.vpH()),\n );\n private readonly totalScale = computed(() => this.coverScale() * this.zoom());\n\n /** CSS transform applied to the image element. */\n protected readonly imageTransform = computed(\n () =>\n `translate(calc(-50% + ${this.panX()}px), calc(-50% + ${this.panY()}px)) ` +\n `scale(${this.totalScale()})`,\n );\n\n constructor() {\n // Restart from scratch whenever the source changes.\n effect(() => {\n this.src();\n untracked(() => {\n this.status.set('loading');\n this.natW.set(0);\n this.natH.set(0);\n this.reset();\n });\n });\n // Keep an externally-written zoom model inside [minZoom, maxZoom].\n effect(() => {\n const clamped = this.clampZoom(this.zoom());\n if (clamped !== this.zoom()) this.zoom.set(clamped);\n });\n // Re-clamp pan when zoom, image or viewport geometry changes.\n effect(() => {\n const scale = this.totalScale();\n const [imgW, imgH, vpW, vpH] = [this.natW(), this.natH(), this.vpW(), this.vpH()];\n untracked(() => {\n const p = mkClampPan(this.panX(), this.panY(), imgW, imgH, vpW, vpH, scale);\n this.panX.set(p.x);\n this.panY.set(p.y);\n });\n });\n\n afterNextRender(() => {\n this.measure();\n const viewport = this.viewportRef().nativeElement;\n // Angular's (wheel) binding may register passively; zooming must be\n // able to preventDefault, so attach by hand.\n viewport.addEventListener('wheel', this.onWheel, { passive: false });\n if ('ResizeObserver' in window) {\n this.resizeObserver = new ResizeObserver(() => this.measure());\n this.resizeObserver.observe(viewport);\n }\n });\n }\n\n ngOnDestroy(): void {\n this.resizeObserver?.disconnect();\n if (this.isBrowser) {\n this.viewportRef().nativeElement.removeEventListener('wheel', this.onWheel);\n }\n }\n\n // --- Public API -----------------------------------------------------------\n\n /** Centre the image and reset zoom to 1 (clamped to `minZoom`). */\n reset(): void {\n const zoom = this.clampZoom(1);\n const dirty =\n this.zoom() !== zoom || this.panX() !== 0 || this.panY() !== 0;\n this.zoom.set(zoom);\n this.panX.set(0);\n this.panY.set(0);\n if (dirty) this.changed.emit();\n }\n\n /**\n * Draw the visible crop region to an offscreen canvas and return it as a\n * data-URL (longest edge capped at `options.size ?? 1024`). Returns `null`\n * when the image is not loaded or the canvas is unavailable (SSR, jsdom).\n */\n /**\n * The visible crop region in natural image pixels — what `crop()` would\n * rasterise, without touching a canvas. Use it when the backend performs\n * the actual crop from the master image (no client-side quality loss).\n * Returns `null` until the image has loaded and the viewport is measured.\n */\n cropRect(): { sx: number; sy: number; sw: number; sh: number } | null {\n if (this.status() !== 'loaded') return null;\n const [natW, natH, vpW, vpH] = [this.natW(), this.natH(), this.vpW(), this.vpH()];\n if (!natW || !natH || !vpW || !vpH) return null;\n return mkCropRect(natW, natH, vpW, vpH, this.totalScale(), this.panX(), this.panY());\n }\n\n crop(options?: { type?: string; quality?: number; size?: number }): string | null {\n const image = this.imageRef()?.nativeElement;\n if (!this.isBrowser || this.status() !== 'loaded' || !image) return null;\n const [natW, natH, vpW, vpH] = [this.natW(), this.natH(), this.vpW(), this.vpH()];\n if (!natW || !natH || !vpW || !vpH) return null;\n\n const { sx, sy, sw, sh } = mkCropRect(\n natW, natH, vpW, vpH, this.totalScale(), this.panX(), this.panY(),\n );\n const cap = options?.size ?? 1024;\n const factor = Math.min(1, cap / Math.max(sw, sh));\n try {\n const canvas = document.createElement('canvas');\n canvas.width = Math.max(1, Math.round(sw * factor));\n canvas.height = Math.max(1, Math.round(sh * factor));\n const ctx = canvas.getContext('2d');\n if (!ctx) return null;\n ctx.drawImage(image, sx, sy, sw, sh, 0, 0, canvas.width, canvas.height);\n return canvas.toDataURL(options?.type ?? 'image/png', options?.quality) || null;\n } catch {\n // Environments without canvas rasterisation (e.g. jsdom).\n return null;\n }\n }\n\n // --- Image lifecycle ------------------------------------------------------\n\n protected onImageLoad(event: Event): void {\n const image = event.target as HTMLImageElement;\n this.natW.set(image.naturalWidth);\n this.natH.set(image.naturalHeight);\n this.status.set('loaded');\n this.reset();\n }\n\n protected onImageError(): void {\n this.status.set('error');\n this.imageError.emit();\n }\n\n // --- Pointer panning ------------------------------------------------------\n\n protected onPointerDown(event: PointerEvent): void {\n if (this.disabled()) return;\n try {\n this.viewportRef().nativeElement.setPointerCapture(event.pointerId);\n } catch {\n // jsdom / detached element.\n }\n this.dragStart = {\n x: event.clientX,\n y: event.clientY,\n panX: this.panX(),\n panY: this.panY(),\n };\n this.dragging.set(true);\n event.preventDefault();\n }\n\n protected onPointerMove(event: PointerEvent): void {\n const start = this.dragStart;\n if (!start) return;\n this.panTo(\n start.panX + event.clientX - start.x,\n start.panY + event.clientY - start.y,\n );\n }\n\n protected onPointerUp(): void {\n this.dragStart = null;\n this.dragging.set(false);\n }\n\n // --- Zooming --------------------------------------------------------------\n\n private readonly onWheel = (event: WheelEvent): void => {\n if (this.disabled()) return;\n event.preventDefault();\n // Multiplicative steps feel uniform across the whole zoom range.\n this.zoomTo(this.zoom() * Math.exp(-event.deltaY * 0.0015));\n };\n\n protected onRangeInput(event: Event): void {\n const value = Number((event.target as HTMLInputElement).value);\n if (!Number.isNaN(value)) this.zoomTo(value);\n }\n\n protected stepZoom(direction: 1 | -1): void {\n this.zoomTo(this.zoom() + direction * BUTTON_ZOOM_STEP);\n }\n\n /**\n * Zoom towards the viewport centre: the pan offset scales with the zoom\n * ratio so the image point at the centre stays put, then re-clamps.\n */\n protected zoomTo(next: number): void {\n const clamped = this.clampZoom(next);\n const previous = this.zoom();\n if (clamped === previous) return;\n const ratio = clamped / previous;\n this.zoom.set(clamped);\n const p = mkClampPan(\n this.panX() * ratio,\n this.panY() * ratio,\n this.natW(),\n this.natH(),\n this.vpW(),\n this.vpH(),\n this.coverScale() * clamped,\n );\n this.panX.set(p.x);\n this.panY.set(p.y);\n this.changed.emit();\n }\n\n // --- Keyboard -------------------------------------------------------------\n\n protected onKeydown(event: KeyboardEvent): void {\n if (this.disabled()) return;\n const step = event.shiftKey ? 1 : 10;\n switch (event.key) {\n case 'ArrowLeft':\n this.panTo(this.panX() - step, this.panY());\n break;\n case 'ArrowRight':\n this.panTo(this.panX() + step, this.panY());\n break;\n case 'ArrowUp':\n this.panTo(this.panX(), this.panY() - step);\n break;\n case 'ArrowDown':\n this.panTo(this.panX(), this.panY() + step);\n break;\n case '+':\n case '=':\n this.zoomTo(this.zoom() + KEY_ZOOM_STEP);\n break;\n case '-':\n case '_':\n this.zoomTo(this.zoom() - KEY_ZOOM_STEP);\n break;\n default:\n return;\n }\n event.preventDefault();\n }\n\n // --- Internals ------------------------------------------------------------\n\n private clampZoom(value: number): number {\n return Math.min(this.maxZoom(), Math.max(this.minZoom(), value));\n }\n\n private panTo(x: number, y: number): void {\n const p = mkClampPan(\n x, y, this.natW(), this.natH(), this.vpW(), this.vpH(), this.totalScale(),\n );\n if (p.x === this.panX() && p.y === this.panY()) return;\n this.panX.set(p.x);\n this.panY.set(p.y);\n this.changed.emit();\n }\n\n /** Capture the viewport's CSS size (initial render + every resize). */\n private measure(): void {\n if (!this.isBrowser) return;\n const rect = this.viewportRef().nativeElement.getBoundingClientRect();\n this.vpW.set(rect.width);\n this.vpH.set(rect.height);\n }\n}\n","<div\n #viewport\n class=\"mk-image-cropper__viewport\"\n role=\"application\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n [attr.aria-label]=\"ariaLabel() || i18n.zoom\"\n [attr.aria-disabled]=\"disabled() || null\"\n [class.mk-image-cropper__viewport--fill]=\"aspect() === null\"\n [class.mk-image-cropper__viewport--dragging]=\"dragging()\"\n [style.aspect-ratio]=\"aspect()\"\n (pointerdown)=\"onPointerDown($event)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp()\"\n (pointercancel)=\"onPointerUp()\"\n (keydown)=\"onKeydown($event)\"\n>\n @if (status() === 'error') {\n <div class=\"mk-image-cropper__error\">{{ i18n.imageFailed }}</div>\n } @else {\n <img\n #image\n class=\"mk-image-cropper__image\"\n [class.mk-image-cropper__image--ready]=\"status() === 'loaded'\"\n [src]=\"src()\"\n alt=\"\"\n draggable=\"false\"\n [attr.crossorigin]=\"crossOrigin()\"\n [style.transform]=\"imageTransform()\"\n (load)=\"onImageLoad($event)\"\n (error)=\"onImageError()\"\n />\n <div class=\"mk-image-cropper__grid\" aria-hidden=\"true\"></div>\n @if (round()) {\n <div class=\"mk-image-cropper__mask\" aria-hidden=\"true\"></div>\n }\n }\n</div>\n\n<div class=\"mk-image-cropper__controls\">\n <button\n type=\"button\"\n class=\"mk-image-cropper__zoom-btn\"\n [attr.aria-label]=\"i18n.zoomOut\"\n [disabled]=\"disabled() || zoom() <= minZoom()\"\n (click)=\"stepZoom(-1)\"\n >\n <span aria-hidden=\"true\">−</span>\n </button>\n <input\n type=\"range\"\n class=\"mk-image-cropper__range\"\n step=\"0.01\"\n [min]=\"minZoom()\"\n [max]=\"maxZoom()\"\n [value]=\"zoom()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"i18n.zoom\"\n (input)=\"onRangeInput($event)\"\n />\n <button\n type=\"button\"\n class=\"mk-image-cropper__zoom-btn\"\n [attr.aria-label]=\"i18n.zoomIn\"\n [disabled]=\"disabled() || zoom() >= maxZoom()\"\n (click)=\"stepZoom(1)\"\n >\n <span aria-hidden=\"true\">+</span>\n </button>\n</div>\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n Directive,\n TemplateRef,\n booleanAttribute,\n contentChild,\n inject,\n input,\n model,\n numberAttribute,\n output,\n} from '@angular/core';\nimport { MK_I18N } from '@mk-kit/ui/core';\nimport { MkDrag, MkDropList, mkMoveItemInArray } from '@mk-kit/ui/dnd';\nimport type { MkDropEvent } from '@mk-kit/ui/dnd';\n\n/** A single asset displayed as a tile in {@link MkMediaGallery}. */\nexport interface MkMediaItem {\n /** Stable identity used for tracking, selection and reorder events. */\n id: string;\n /** Full-size image URL (used for the thumbnail when `thumb` is omitted). */\n src: string;\n /** Optional dedicated thumbnail URL shown in the grid. */\n thumb?: string;\n /** Display name shown under the thumbnail; also names the selection checkbox. */\n name: string;\n /** Alternative text describing the image; falls back to `name` for labels. */\n alt?: string;\n /** Optional caption/meta line shown under the name (e.g. \"1.2 MB · JPG\"). */\n meta?: string;\n}\n\n/** Emitted by {@link MkMediaGallery} after a tile has been reordered. */\nexport interface MkMediaReorderEvent {\n /** Index the item was dragged from. */\n from: number;\n /** Index the item was dropped at. */\n to: number;\n /** The full item array after the move (same reference as the updated model). */\n items: MkMediaItem[];\n}\n\n/**\n * Marks an `<ng-template>` as the per-tile action bar for {@link MkMediaGallery}.\n * The template's implicit context is the {@link MkMediaItem}, so consumers can\n * destructure it with `let-item`. The gallery renders it into each tile's\n * top-right action bar (revealed on hover / focus-within, always visible on\n * touch devices); the consumer supplies the buttons and their handlers.\n *\n * ```html\n * <mk-media-gallery [items]=\"assets()\">\n * <ng-template mkMediaActions let-item>\n * <button mkButton size=\"sm\" variant=\"ghost\" (click)=\"edit(item)\">Edit</button>\n * </ng-template>\n * </mk-media-gallery>\n * ```\n */\n@Directive({\n selector: '[mkMediaActions]',\n})\nexport class MkMediaActions {\n /** The projected action-bar template, rendered once per tile. */\n readonly template = inject<TemplateRef<{ $implicit: MkMediaItem }>>(TemplateRef);\n}\n\n/**\n * Media gallery — a management grid of image tiles for admin media libraries.\n * Each tile shows a square thumbnail (a labelled preview button emitting\n * {@link itemClick}), the item's name and optional meta line, an optional\n * selection checkbox (two-way `selection` model of selected ids) and an\n * optional consumer-projected action bar ({@link MkMediaActions}).\n *\n * With `reorderable`, tiles become draggable via the dnd group's\n * `[mkDropList]` / `[mkDrag]` directives — pointer and keyboard dragging\n * (WCAG 2.1.1) both included. Each drop immutably updates the two-way `items`\n * model and emits {@link reordered}.\n *\n * Clicking a tile always means \"open/preview\" — selection only toggles through\n * the checkbox, never on tile click.\n *\n * ```html\n * <mk-media-gallery\n * [(items)]=\"assets\"\n * [(selection)]=\"selectedIds\"\n * selectable\n * reorderable\n * [columns]=\"5\"\n * (itemClick)=\"openPreview($event)\"\n * (reordered)=\"persistOrder($event)\"\n * >\n * <ng-template mkMediaActions let-item>\n * <button mkButton size=\"sm\" variant=\"ghost\" (click)=\"edit(item)\">Edit</button>\n * <button mkButton size=\"sm\" variant=\"ghost\" tone=\"danger\" (click)=\"remove(item)\">\n * Delete\n * </button>\n * </ng-template>\n * </mk-media-gallery>\n * ```\n */\n@Component({\n selector: 'mk-media-gallery',\n exportAs: 'mkMediaGallery',\n templateUrl: './media-gallery.html',\n styleUrl: './media-gallery.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [MkDropList, MkDrag, NgTemplateOutlet],\n host: {\n class: 'mk-media-gallery',\n role: 'group',\n '[attr.aria-label]': 'ariaLabel()',\n },\n})\nexport class MkMediaGallery {\n /** Localized strings (region label, checkbox/preview labels, empty state). */\n protected readonly i18n = inject(MK_I18N);\n\n /** The gallery's items (two-way). Replaced immutably on every reorder drop. */\n readonly items = model<MkMediaItem[]>([]);\n\n /** Ids of the currently selected items (two-way). */\n readonly selection = model<string[]>([]);\n\n /** Show a selection checkbox on every tile. */\n readonly selectable = input(false, { transform: booleanAttribute });\n\n /** Allow drag-and-drop (pointer + keyboard) reordering of the tiles. */\n readonly reorderable = input(false, { transform: booleanAttribute });\n\n /** Number of grid columns. */\n readonly columns = input(4, { transform: numberAttribute });\n\n /** Accessible name of the gallery region. Defaults to `i18n.mediaLibrary`. */\n readonly ariaLabel = input<string>(this.i18n.mediaLibrary);\n\n /** Emitted when a tile's preview button is activated (click/Enter/Space). */\n readonly itemClick = output<MkMediaItem>();\n\n /** Emitted after a drop has updated the `items` model. */\n readonly reordered = output<MkMediaReorderEvent>();\n\n /** Optional consumer-projected per-tile action bar (`$implicit` = item). */\n protected readonly actions = contentChild(MkMediaActions);\n\n /** Whether the item with `id` is currently selected. */\n protected isSelected(id: string): boolean {\n return this.selection().includes(id);\n }\n\n /** Sync the two-way `selection` model with the checkbox's native state. */\n protected onCheckboxChange(item: MkMediaItem, event: Event): void {\n const checked = (event.target as HTMLInputElement).checked;\n const current = this.selection();\n if (checked) {\n if (!current.includes(item.id)) this.selection.set([...current, item.id]);\n } else {\n this.selection.set(current.filter((id) => id !== item.id));\n }\n }\n\n /** Emit {@link itemClick} for the tile's preview button. */\n protected onPreviewClick(item: MkMediaItem): void {\n this.itemClick.emit(item);\n }\n\n /**\n * Apply a drop from the dnd module: move the item on a copy of `items`,\n * write the copy back to the two-way model and emit {@link reordered}.\n */\n protected onDrop(event: MkDropEvent<MkMediaItem>): void {\n const from = event.previousIndex;\n const to = event.currentIndex;\n if (from === to) return;\n const next = [...this.items()];\n mkMoveItemInArray(next, from, to);\n this.items.set(next);\n this.reordered.emit({ from, to, items: next });\n }\n\n /**\n * Keep events from the tile's nested controls (checkbox, action buttons)\n * inside those controls: without this, Space/Enter on the checkbox or an\n * action button would bubble to the surrounding `[mkDrag]` host and pick the\n * tile up instead, and a pointer press would start a drag session. Native\n * behavior is untouched — only propagation stops.\n */\n protected stopEvent(event: Event): void {\n event.stopPropagation();\n }\n}\n","@if (items().length === 0) {\n <div class=\"mk-media-gallery__empty\">{{ i18n.noData }}</div>\n} @else if (reorderable()) {\n <div\n mkDropList\n class=\"mk-media-gallery__grid\"\n [style.--_cols]=\"columns()\"\n [mkDropListData]=\"items()\"\n [mkDropListLabel]=\"ariaLabel()\"\n mkDropListOrientation=\"horizontal\"\n (mkDropListDropped)=\"onDrop($event)\"\n >\n @for (item of items(); track item.id) {\n <div\n mkDrag\n class=\"mk-media-gallery__tile\"\n [class.mk-media-gallery__tile--selected]=\"isSelected(item.id)\"\n [mkDragData]=\"item\"\n >\n <ng-container\n [ngTemplateOutlet]=\"tile\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </div>\n }\n </div>\n} @else {\n <div class=\"mk-media-gallery__grid\" [style.--_cols]=\"columns()\">\n @for (item of items(); track item.id) {\n <div\n class=\"mk-media-gallery__tile\"\n [class.mk-media-gallery__tile--selected]=\"isSelected(item.id)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"tile\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </div>\n }\n </div>\n}\n\n<ng-template #tile let-item>\n <div class=\"mk-media-gallery__media\">\n <button\n type=\"button\"\n class=\"mk-media-gallery__preview\"\n [attr.aria-label]=\"i18n.viewImage(item.alt ?? item.name)\"\n (click)=\"onPreviewClick(item)\"\n (keydown)=\"stopEvent($event)\"\n >\n <img\n class=\"mk-media-gallery__img\"\n [src]=\"item.thumb ?? item.src\"\n [alt]=\"item.alt ?? ''\"\n loading=\"lazy\"\n draggable=\"false\"\n />\n </button>\n\n @if (selectable()) {\n <span\n class=\"mk-media-gallery__check\"\n (keydown)=\"stopEvent($event)\"\n (pointerdown)=\"stopEvent($event)\"\n >\n <input\n type=\"checkbox\"\n class=\"mk-media-gallery__check-input\"\n [checked]=\"isSelected(item.id)\"\n [attr.aria-label]=\"i18n.selectRow(item.name)\"\n (change)=\"onCheckboxChange(item, $event)\"\n />\n <span class=\"mk-media-gallery__check-box\" aria-hidden=\"true\">\n <span class=\"mk-media-gallery__check-mark\"></span>\n </span>\n </span>\n }\n\n @if (actions(); as actionsDir) {\n <div\n class=\"mk-media-gallery__actions\"\n (keydown)=\"stopEvent($event)\"\n (pointerdown)=\"stopEvent($event)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"actionsDir.template\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </div>\n }\n </div>\n\n <div class=\"mk-media-gallery__caption\">\n <span class=\"mk-media-gallery__name\">{{ item.name }}</span>\n @if (item.meta) {\n <span class=\"mk-media-gallery__meta\">{{ item.meta }}</span>\n }\n </div>\n</ng-template>\n","/**\n * MEDIA components group barrel for @mk-kit/ui.\n * Images, galleries, lightbox, cropping and media management.\n */\nexport * from './image';\nexport * from './lightbox';\nexport * from './image-gallery';\nexport * from './image-cropper';\nexport * from './media-gallery';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mk-kit-ui-media.mjs","sources":["../../../projects/mk-kit/media/image/image.ts","../../../projects/mk-kit/media/image/image.html","../../../projects/mk-kit/media/lightbox/lightbox.ts","../../../projects/mk-kit/media/lightbox/lightbox.html","../../../projects/mk-kit/media/lightbox/lightbox.service.ts","../../../projects/mk-kit/media/image-gallery/image-gallery.ts","../../../projects/mk-kit/media/image-gallery/image-gallery.html","../../../projects/mk-kit/media/image-cropper/image-cropper.ts","../../../projects/mk-kit/media/image-cropper/image-cropper.html","../../../projects/mk-kit/media/media-gallery/media-gallery.ts","../../../projects/mk-kit/media/media-gallery/media-gallery.html","../../../projects/mk-kit/media/index.ts","../../../projects/mk-kit/media/mk-kit-ui-media.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n computed,\n Component,\n booleanAttribute,\n inject,\n input,\n linkedSignal,\n output,\n} from '@angular/core';\nimport { MK_I18N } from '@mk-kit/ui/core';\n\n/** How the picture is scaled inside its frame (`object-fit`). */\nexport type MkImageFit = 'cover' | 'contain';\n/** Corner rounding applied to the frame of an {@link MkImage}. */\nexport type MkImageRounded = 'none' | 'md' | 'lg' | 'circle';\n/** Load lifecycle of an {@link MkImage}. */\nexport type MkImageState = 'loading' | 'loaded' | 'error';\n\n/**\n * Image — an enhanced image block. While the picture loads it shows a skeleton\n * shimmer, and when loading fails it swaps to a localised fallback panel\n * (icon + text, never colour alone). The picture is wrapped in a `<figure>`\n * with an optional `<figcaption>`, and changing `src` restarts the whole load\n * cycle.\n *\n * ```html\n * <mk-image\n * src=\"/photos/harbour.jpg\"\n * alt=\"Harbour at dawn\"\n * aspectRatio=\"16 / 9\"\n * caption=\"The old harbour, photographed at dawn\"\n * (loaded)=\"onLoaded()\"\n * (errored)=\"onErrored()\"\n * />\n *\n * <!-- The hero: eager, high priority, and sized per breakpoint so a phone\n * does not download the desktop file. -->\n * <mk-image\n * src=\"/photos/hero-1600.jpg\"\n * srcset=\"/photos/hero-800.jpg 800w, /photos/hero-1600.jpg 1600w\"\n * sizes=\"100vw\"\n * alt=\"\"\n * aspectRatio=\"16 / 9\"\n * priority\n * />\n * ```\n *\n * `aspectRatio` is what keeps this from shifting layout: the frame reserves\n * its box before the picture arrives, so nothing below it moves.\n */\n@Component({\n selector: 'mk-image',\n exportAs: 'mkImage',\n templateUrl: './image.html',\n styleUrl: './image.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'mk-image',\n '[attr.data-fit]': 'fit()',\n '[attr.data-rounded]': 'rounded()',\n '[attr.data-state]': 'state()',\n },\n})\nexport class MkImage {\n /** Localised strings (override globally via `provideMkI18n`). */\n protected readonly i18n = inject(MK_I18N);\n\n /** Image URL. Changing it resets the block to its loading state. */\n readonly src = input.required<string>();\n /** Alt text, always reflected onto the `<img>`. Keep `''` for decorative images. */\n readonly alt = input<string>('');\n /** Any CSS `aspect-ratio` value for the frame, e.g. `'1 / 1'` or `'16 / 9'`. */\n readonly aspectRatio = input<string>('auto');\n /** How the picture fills the frame. */\n readonly fit = input<MkImageFit>('cover');\n /** Corner rounding of the frame. */\n readonly rounded = input<MkImageRounded>('md');\n /** Caption rendered in a `<figcaption>` below the picture. */\n readonly caption = input<string>('');\n /** Defer fetching until near the viewport (`loading=\"lazy\"` vs `\"eager\"`). */\n readonly lazy = input(true, { transform: booleanAttribute });\n /**\n * Mark this as the page's LCP image: fetched eagerly at high priority and\n * decoded synchronously, and `lazy` is ignored. Use it on exactly ONE image\n * per page — the hero. Marking several is worse than marking none, because\n * they then compete for the same bandwidth the real LCP image needs.\n *\n * This does NOT emit a `<link rel=preload>`; the tag has to be in the HTML\n * the server sends to beat the preload scanner, which a component rendered\n * later cannot guarantee. Pair it with a preload hint for a background or\n * late-rendered hero.\n */\n readonly priority = input(false, { transform: booleanAttribute });\n /**\n * Responsive candidates, passed through verbatim to the `<img>`. Serving a\n * 2048px file into a 600px slot is one of the most common LCP mistakes, and\n * this is the fix; pair with {@link sizes}.\n */\n readonly srcset = input<string>('');\n /** `sizes` attribute — how wide the image renders at each breakpoint. */\n readonly sizes = input<string>('');\n\n /** Emits once the picture has finished loading. */\n readonly loaded = output<void>();\n /** Emits when the picture fails to load and the fallback panel is shown. */\n readonly errored = output<void>();\n\n /** `loading` attribute: priority always wins over `lazy`. */\n protected readonly loadingAttr = computed(() =>\n this.priority() ? 'eager' : this.lazy() ? 'lazy' : 'eager',\n );\n\n /** Load lifecycle; snaps back to `'loading'` whenever `src` changes. */\n protected readonly state = linkedSignal<string, MkImageState>({\n source: this.src,\n computation: () => 'loading',\n });\n\n protected onLoad(): void {\n this.state.set('loaded');\n this.loaded.emit();\n }\n\n protected onError(): void {\n this.state.set('error');\n this.errored.emit();\n }\n}\n","<figure class=\"mk-image__figure\">\n <div class=\"mk-image__frame\" [style.aspect-ratio]=\"aspectRatio()\">\n @if (state() !== 'error') {\n <img\n class=\"mk-image__img\"\n [src]=\"src()\"\n [alt]=\"alt()\"\n [attr.srcset]=\"srcset() || null\"\n [attr.sizes]=\"sizes() || null\"\n [attr.loading]=\"loadingAttr()\"\n [attr.fetchpriority]=\"priority() ? 'high' : null\"\n [attr.decoding]=\"priority() ? 'sync' : 'async'\"\n (load)=\"onLoad()\"\n (error)=\"onError()\"\n />\n @if (state() === 'loading') {\n <span class=\"mk-image__skeleton\" aria-hidden=\"true\"></span>\n }\n } @else {\n <div class=\"mk-image__fallback\">\n <svg\n class=\"mk-image__fallback-icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" />\n <circle cx=\"9\" cy=\"10\" r=\"1.5\" />\n <path d=\"m5 17 4-4 3 3 3.5-3.5L20 17\" />\n <path d=\"m4 3 16 18\" />\n </svg>\n <span class=\"mk-image__fallback-text\">{{ i18n.imageFailed }}</span>\n </div>\n }\n </div>\n @if (caption()) {\n <figcaption class=\"mk-image__caption\">{{ caption() }}</figcaption>\n }\n</figure>\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n signal,\n} from '@angular/core';\nimport { MK_I18N, MK_OVERLAY_DATA, MkOverlayRef } from '@mk-kit/ui/core';\nimport type { MkLightboxData, MkLightboxItem } from './lightbox.service';\n\n/**\n * Internal overlay component backing {@link MkLightboxService}. Renders the\n * current image near-fullscreen over the overlay scrim with a caption bar,\n * an `imageOf` counter, a close button and looping previous/next navigation.\n *\n * Keyboard: `ArrowLeft`/`ArrowRight` navigate, `Home`/`End` jump to the first\n * or last image. `Escape` and backdrop clicks are handled by the overlay\n * itself (`closeOnEscape` / `closeOnBackdropClick`), so they are deliberately\n * not re-handled here.\n *\n * Open it via the service — not by placing `<mk-lightbox>` in a template:\n *\n * ```ts\n * inject(MkLightboxService).open(items, 2);\n * ```\n */\n@Component({\n selector: 'mk-lightbox',\n templateUrl: './lightbox.html',\n styleUrl: './lightbox.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n // Bound (not static) so it merges with the overlay's own panel classes —\n // a static host `class` would overwrite `mk-overlay-panel` on the host.\n '[class.mk-lightbox]': 'true',\n '(keydown)': 'onKeydown($event)',\n },\n})\nexport class MkLightbox {\n private readonly ref = inject(MkOverlayRef);\n private readonly data = inject<MkLightboxData | null>(MK_OVERLAY_DATA);\n /** Localised strings (override globally via `provideMkI18n`). */\n protected readonly i18n = inject(MK_I18N);\n\n /** The images being paged through. */\n protected readonly items: readonly MkLightboxItem[] = this.data?.items ?? [];\n /** Total number of images. */\n protected readonly total = this.items.length;\n\n /** Index of the currently displayed image. */\n protected readonly index = signal(\n Math.min(Math.max(this.data?.startIndex ?? 0, 0), Math.max(this.total - 1, 0)),\n );\n /** The currently displayed item. */\n protected readonly current = computed(() => this.items[this.index()]);\n /** Localised \"Image i of n\" counter text. */\n protected readonly counter = computed(() =>\n this.i18n.imageOf(this.index() + 1, this.total),\n );\n\n /** `true` while the current image is still loading. */\n protected readonly loading = signal(true);\n /** `true` when the current image failed to load. */\n protected readonly failed = signal(false);\n\n /** Show the previous image, wrapping from the first to the last. */\n protected previous(): void {\n this.goTo((this.index() - 1 + this.total) % this.total);\n }\n\n /** Show the next image, wrapping from the last back to the first. */\n protected next(): void {\n this.goTo((this.index() + 1) % this.total);\n }\n\n /** Jump to `index`, resetting the loading/error state. */\n protected goTo(index: number): void {\n if (this.total === 0 || index === this.index()) return;\n this.index.set(index);\n this.loading.set(true);\n this.failed.set(false);\n }\n\n /** Close the surrounding overlay. */\n protected close(): void {\n this.ref.close();\n }\n\n /** Current image finished loading — hide the spinner. */\n protected onLoad(): void {\n this.loading.set(false);\n }\n\n /** Current image failed — show the localised failure message instead. */\n protected onError(): void {\n this.loading.set(false);\n this.failed.set(true);\n }\n\n /**\n * Host keydown handler. Escape is intentionally not handled here — the\n * overlay's `closeOnEscape` already closes the lightbox.\n */\n protected onKeydown(event: Event): void {\n const key = (event as KeyboardEvent).key;\n switch (key) {\n case 'ArrowLeft':\n event.preventDefault();\n this.previous();\n break;\n case 'ArrowRight':\n event.preventDefault();\n this.next();\n break;\n case 'Home':\n event.preventDefault();\n this.goTo(0);\n break;\n case 'End':\n event.preventDefault();\n this.goTo(this.total - 1);\n break;\n }\n }\n}\n","@if (current(); as item) {\n <figure class=\"mk-lightbox__figure\">\n <div class=\"mk-lightbox__stage\">\n @if (failed()) {\n <p class=\"mk-lightbox__error\" role=\"alert\">{{ i18n.imageFailed }}</p>\n } @else {\n @if (loading()) {\n <span class=\"mk-lightbox__spinner\" aria-hidden=\"true\"></span>\n }\n <img\n class=\"mk-lightbox__image\"\n [class.mk-lightbox__image--loading]=\"loading()\"\n [src]=\"item.src\"\n [alt]=\"item.alt ?? ''\"\n (load)=\"onLoad()\"\n (error)=\"onError()\"\n />\n }\n </div>\n @if (item.caption) {\n <figcaption class=\"mk-lightbox__caption\">{{ item.caption }}</figcaption>\n }\n <p class=\"mk-lightbox__counter\" aria-live=\"polite\">{{ counter() }}</p>\n </figure>\n}\n\n<button\n type=\"button\"\n class=\"mk-lightbox__button mk-lightbox__close\"\n [attr.aria-label]=\"i18n.close\"\n (click)=\"close()\"\n>\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M6 6l12 12M18 6L6 18\" />\n </svg>\n</button>\n\n@if (total > 1) {\n <button\n type=\"button\"\n class=\"mk-lightbox__button mk-lightbox__nav mk-lightbox__nav--prev\"\n [attr.aria-label]=\"i18n.previousImage\"\n (click)=\"previous()\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M15 5l-7 7 7 7\" />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"mk-lightbox__button mk-lightbox__nav mk-lightbox__nav--next\"\n [attr.aria-label]=\"i18n.nextImage\"\n (click)=\"next()\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n}\n","import { Injectable, inject } from '@angular/core';\nimport { MK_I18N, MkOverlayService } from '@mk-kit/ui/core';\nimport { MkLightbox } from './lightbox';\n\n/** A single image shown by {@link MkLightboxService}. */\nexport interface MkLightboxItem {\n /** Image URL. */\n src: string;\n /** Alternative text for the image. */\n alt?: string;\n /** Optional caption rendered below the image. */\n caption?: string;\n}\n\n/** Data injected into {@link MkLightbox} via `MK_OVERLAY_DATA`. */\nexport interface MkLightboxData {\n /** The images to page through. */\n items: readonly MkLightboxItem[];\n /** Index of the image shown first (already clamped into range). */\n startIndex: number;\n}\n\n/**\n * Fullscreen image lightbox — opens a set of images in a modal overlay with\n * looping previous/next navigation, captions, a counter, keyboard support\n * (Arrow keys, Home/End, Escape) and focus trapping, all powered by\n * {@link MkOverlayService}.\n *\n * ```ts\n * private readonly lightbox = inject(MkLightboxService);\n *\n * viewPhoto(index: number): void {\n * this.lightbox.open(\n * [\n * { src: '/photos/1.jpg', alt: 'Harbour at dawn', caption: 'Dawn' },\n * { src: '/photos/2.jpg', alt: 'Old town square' },\n * ],\n * index,\n * );\n * }\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class MkLightboxService {\n private readonly overlay = inject(MkOverlayService);\n private readonly i18n = inject(MK_I18N);\n\n /**\n * Open the lightbox over the page. Does nothing when `items` is empty.\n * `startIndex` is clamped into `[0, items.length - 1]`.\n */\n open(items: readonly MkLightboxItem[], startIndex = 0): void {\n if (items.length === 0) return;\n const start = Math.min(\n Math.max(Math.trunc(startIndex), 0),\n items.length - 1,\n );\n this.overlay.open<MkLightbox, void, MkLightboxData>(MkLightbox, {\n data: { items, startIndex: start },\n hasBackdrop: true,\n closeOnBackdropClick: true,\n closeOnEscape: true,\n trapFocus: true,\n role: 'dialog',\n ariaLabel: this.i18n.imageOf(start + 1, items.length),\n panelClass: 'mk-lightbox-panel',\n });\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n booleanAttribute,\n computed,\n inject,\n input,\n numberAttribute,\n output,\n} from '@angular/core';\nimport { MK_I18N } from '@mk-kit/ui/core';\nimport { MkImage, type MkImageRounded } from '../image/image';\nimport {\n MkLightboxService,\n type MkLightboxItem,\n} from '../lightbox/lightbox.service';\n\n/** A single picture inside an {@link MkImageGallery}. */\nexport interface MkGalleryItem {\n /** Full-size image URL (what the lightbox opens). */\n src: string;\n /** Optional smaller thumbnail URL for the tile; falls back to `src`. */\n thumb?: string;\n /** Alt text; also drives the tile's accessible label. */\n alt?: string;\n /** Optional caption forwarded to the lightbox. */\n caption?: string;\n}\n\n/** Tile arrangement of an {@link MkImageGallery}. */\nexport type MkImageGalleryLayout = 'grid' | 'masonry' | 'strip';\n\n/** Payload of the {@link MkImageGallery.itemClick} output. */\nexport interface MkGalleryItemClick {\n /** The clicked picture. */\n item: MkGalleryItem;\n /** Its index within `items`. */\n index: number;\n}\n\n/**\n * Image gallery — a wall of clickable picture tiles built on {@link MkImage}.\n * Choose a uniform `grid`, a natural-ratio `masonry` flow, or a snap-scrolling\n * horizontal `strip`. Clicking a tile opens the shared {@link MkLightboxService}\n * at that picture (full-size `src`, not the thumb) and always emits\n * `itemClick`. With `max` set, only the first `max` tiles render and the last\n * one carries a \"+N\" overflow scrim that opens the rest in the lightbox.\n *\n * ```html\n * <mk-image-gallery\n * [items]=\"[\n * { src: '/photos/1.jpg', thumb: '/thumbs/1.jpg', alt: 'Harbour at dawn' },\n * { src: '/photos/2.jpg', alt: 'Old town square', caption: 'Kraków' },\n * ]\"\n * [columns]=\"4\"\n * [max]=\"8\"\n * aspectRatio=\"4 / 3\"\n * (itemClick)=\"onItemClick($event)\"\n * />\n * ```\n */\n@Component({\n selector: 'mk-image-gallery',\n exportAs: 'mkImageGallery',\n templateUrl: './image-gallery.html',\n styleUrl: './image-gallery.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [MkImage],\n host: {\n class: 'mk-image-gallery',\n '[attr.data-layout]': 'layout()',\n '[attr.data-rounded]': 'rounded()',\n '[style.--_cols]': 'columns()',\n },\n})\nexport class MkImageGallery {\n private readonly lightboxService = inject(MkLightboxService);\n /** Localised strings (override globally via `provideMkI18n`). */\n protected readonly i18n = inject(MK_I18N);\n\n /** Pictures to show. */\n readonly items = input.required<readonly MkGalleryItem[]>();\n /** Tile arrangement. */\n readonly layout = input<MkImageGalleryLayout>('grid');\n /** Grid/masonry column count; also sets the visible tile count of a strip. */\n readonly columns = input(3, { transform: numberAttribute });\n /** When set, show only the first `max` tiles plus a \"+N\" overflow tile. */\n readonly max = input<number | null>(null);\n /** Open the shared lightbox on tile click. */\n readonly lightbox = input(true, { transform: booleanAttribute });\n /** CSS aspect-ratio of grid/strip tiles (masonry keeps natural ratios). */\n readonly aspectRatio = input<string>('1 / 1');\n /** Corner rounding of the tiles. */\n readonly rounded = input<MkImageRounded>('md');\n\n /** Emits on every tile click (also when the lightbox opens). */\n readonly itemClick = output<MkGalleryItemClick>();\n\n /** Tiles actually rendered — the first `max` when `max` is set. */\n protected readonly visibleItems = computed(() => {\n const items = this.items();\n const max = this.max();\n return max != null && items.length > max\n ? items.slice(0, Math.max(0, max))\n : items;\n });\n\n /** How many pictures the trailing \"+N\" tile stands for (0 = no overflow). */\n protected readonly overflowCount = computed(\n () => this.items().length - this.visibleItems().length,\n );\n\n /** Frame ratio forwarded to the tiles (`'auto'` in masonry). */\n protected readonly tileAspectRatio = computed(() =>\n this.layout() === 'masonry' ? 'auto' : this.aspectRatio(),\n );\n\n /**\n * Accessible label of tile `index`: `viewImage(alt)` when the picture has\n * alt text, else positional `imageOf(...)`; the overflow tile appends \"+N\".\n */\n protected tileLabel(index: number): string {\n const items = this.items();\n const alt = items[index]?.alt;\n const base = alt\n ? this.i18n.viewImage(alt)\n : this.i18n.imageOf(index + 1, items.length);\n const overflow = this.overflowCount();\n const isOverflowTile =\n overflow > 0 && index === this.visibleItems().length - 1;\n return isOverflowTile ? `${base} (+${overflow})` : base;\n }\n\n protected onTileClick(index: number): void {\n const items = this.items();\n if (this.lightbox()) {\n const lightboxItems: MkLightboxItem[] = items.map(\n ({ src, alt, caption }) => ({ src, alt, caption }),\n );\n this.lightboxService.open(lightboxItems, index);\n }\n this.itemClick.emit({ item: items[index], index });\n }\n}\n","@for (item of visibleItems(); track $index; let i = $index; let last = $last) {\n <button\n type=\"button\"\n class=\"mk-gallery__tile\"\n [attr.aria-label]=\"tileLabel(i)\"\n (click)=\"onTileClick(i)\"\n >\n <mk-image\n [src]=\"item.thumb ?? item.src\"\n [aspectRatio]=\"tileAspectRatio()\"\n [rounded]=\"rounded()\"\n />\n @if (last && overflowCount() > 0) {\n <span class=\"mk-gallery__more\" aria-hidden=\"true\"\n >+{{ overflowCount() }}</span\n >\n }\n </button>\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n PLATFORM_ID,\n afterNextRender,\n booleanAttribute,\n computed,\n effect,\n inject,\n input,\n model,\n numberAttribute,\n output,\n signal,\n untracked,\n viewChild,\n type OnDestroy,\n} from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { MK_I18N } from '@mk-kit/ui/core';\n\n// --- Pure crop geometry -----------------------------------------------------\n// jsdom has no canvas and never loads images, so everything numeric lives in\n// these exported functions where it can be unit-tested directly.\n\n/**\n * Base cover scale for an image in a viewport — the smallest scale at which\n * `imgW × imgH` fully covers `vpW × vpH` (object-fit: cover). Returns `1`\n * for degenerate (non-positive) dimensions.\n */\nexport function mkCoverScale(\n imgW: number,\n imgH: number,\n vpW: number,\n vpH: number,\n): number {\n if (imgW <= 0 || imgH <= 0 || vpW <= 0 || vpH <= 0) return 1;\n return Math.max(vpW / imgW, vpH / imgH);\n}\n\n/**\n * Clamp a pan offset (CSS px, measured from the viewport centre to the image\n * centre) so the image scaled by `scale` still covers the viewport — no empty\n * edges. When the scaled image is not larger than the viewport on an axis the\n * offset collapses to `0` (centred).\n */\nexport function mkClampPan(\n x: number,\n y: number,\n imgW: number,\n imgH: number,\n vpW: number,\n vpH: number,\n scale: number,\n): { x: number; y: number } {\n const maxX = Math.max(0, (imgW * scale - vpW) / 2);\n const maxY = Math.max(0, (imgH * scale - vpH) / 2);\n // `+ 0` normalises the -0 produced when an axis has no slack.\n return {\n x: Math.min(maxX, Math.max(-maxX, x)) + 0,\n y: Math.min(maxY, Math.max(-maxY, y)) + 0,\n };\n}\n\n/**\n * Source rect (in natural image pixels) of the crop region visible through\n * the viewport. `scale` maps natural pixels to CSS pixels (cover scale ×\n * zoom); `panX`/`panY` are the CSS-px offsets of the image centre from the\n * viewport centre. The rect is clamped inside the image bounds.\n */\nexport function mkCropRect(\n imgNaturalW: number,\n imgNaturalH: number,\n vpW: number,\n vpH: number,\n scale: number,\n panX: number,\n panY: number,\n): { sx: number; sy: number; sw: number; sh: number } {\n if (imgNaturalW <= 0 || imgNaturalH <= 0 || vpW <= 0 || vpH <= 0 || scale <= 0) {\n return { sx: 0, sy: 0, sw: Math.max(0, imgNaturalW), sh: Math.max(0, imgNaturalH) };\n }\n const sw = Math.min(vpW / scale, imgNaturalW);\n const sh = Math.min(vpH / scale, imgNaturalH);\n // The image point rendered at the viewport centre.\n const cx = imgNaturalW / 2 - panX / scale;\n const cy = imgNaturalH / 2 - panY / scale;\n const sx = Math.min(Math.max(cx - sw / 2, 0), imgNaturalW - sw);\n const sy = Math.min(Math.max(cy - sh / 2, 0), imgNaturalH - sh);\n return { sx, sy, sw, sh };\n}\n\n/** Zoom step used by the −/+ buttons. */\nconst BUTTON_ZOOM_STEP = 0.25;\n/** Zoom step used by the `+`/`-` keys. */\nconst KEY_ZOOM_STEP = 0.1;\n\ntype CropStatus = 'loading' | 'loaded' | 'error';\n\n/**\n * ImageCropper — pan-and-zoom crop control for avatars, covers and media uploads.\n * The image covers a fixed-aspect viewport (object-fit-cover style); the user\n * drags to pan, scrolls / pinch-zooms via the slider or `+`/`−` controls, and\n * `crop()` renders the visible region to a data-URL on an offscreen canvas.\n *\n * Pan is always clamped so the image keeps covering the viewport, a\n * rule-of-thirds grid appears while dragging, and `round` overlays a circular\n * scrim for avatar crops (the exported bitmap stays rectangular). The crop\n * area is keyboard operable: Arrow keys pan by 10px (1px with Shift), `+`/`-`\n * zoom.\n *\n * ```html\n * <mk-image-cropper #cropper src=\"/assets/photo.jpg\" [aspect]=\"1\" round />\n * <button mkButton (click)=\"avatar = cropper.crop({ size: 512 })\">Save</button>\n * ```\n */\n@Component({\n selector: 'mk-image-cropper',\n templateUrl: './image-cropper.html',\n styleUrl: './image-cropper.scss',\n exportAs: 'mkImageCropper',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'mk-image-cropper',\n '[class.mk-image-cropper--disabled]': 'disabled()',\n '[class.mk-image-cropper--round]': 'round()',\n },\n})\nexport class MkImageCropper implements OnDestroy {\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n /** Localised strings (override globally via `provideMkI18n`). */\n protected readonly i18n = inject(MK_I18N);\n\n private readonly viewportRef =\n viewChild.required<ElementRef<HTMLElement>>('viewport');\n private readonly imageRef = viewChild<ElementRef<HTMLImageElement>>('image');\n\n /** Image URL or data-URL to crop. */\n readonly src = input.required<string>();\n /**\n * Aspect ratio (width / height) of the crop viewport, e.g. `1` for a\n * square or `16 / 9`. `null` makes the viewport fill its container.\n */\n readonly aspect = input<number | null>(1);\n /**\n * Circular mask overlay for avatar crops. Purely visual — the exported\n * bitmap from `crop()` stays rectangular.\n */\n readonly round = input(false, { transform: booleanAttribute });\n /** Lowest allowed zoom factor. */\n readonly minZoom = input(1, { transform: numberAttribute });\n /** Highest allowed zoom factor. */\n readonly maxZoom = input(4, { transform: numberAttribute });\n /** Disable panning and zooming. */\n readonly disabled = input(false, { transform: booleanAttribute });\n /**\n * `crossorigin` for the internal `<img>`. Set to `'anonymous'` when\n * cropping CORS-enabled remote images — without it the canvas is tainted\n * and `crop()` returns `null`. Same-origin and data-URL sources don't\n * need it.\n */\n readonly crossOrigin = input<'anonymous' | 'use-credentials' | null>(null);\n /** Accessible name for the crop area (defaults to the i18n `zoom` label). */\n readonly ariaLabel = input<string | null>(null);\n\n /** Emits on any pan or zoom change. */\n readonly changed = output<void>();\n /** Emits when the image fails to load. */\n readonly imageError = output<void>();\n\n /** Two-way zoom factor, clamped to `[minZoom, maxZoom]`. */\n readonly zoom = model(1);\n\n private readonly natW = signal(0);\n private readonly natH = signal(0);\n private readonly vpW = signal(0);\n private readonly vpH = signal(0);\n private readonly panX = signal(0);\n private readonly panY = signal(0);\n protected readonly status = signal<CropStatus>('loading');\n protected readonly dragging = signal(false);\n\n private dragStart: { x: number; y: number; panX: number; panY: number } | null =\n null;\n private resizeObserver?: ResizeObserver;\n\n private readonly coverScale = computed(() =>\n mkCoverScale(this.natW(), this.natH(), this.vpW(), this.vpH()),\n );\n private readonly totalScale = computed(() => this.coverScale() * this.zoom());\n\n /** CSS transform applied to the image element. */\n protected readonly imageTransform = computed(\n () =>\n `translate(calc(-50% + ${this.panX()}px), calc(-50% + ${this.panY()}px)) ` +\n `scale(${this.totalScale()})`,\n );\n\n constructor() {\n // Restart from scratch whenever the source changes.\n effect(() => {\n this.src();\n untracked(() => {\n this.status.set('loading');\n this.natW.set(0);\n this.natH.set(0);\n this.reset();\n });\n });\n // Keep an externally-written zoom model inside [minZoom, maxZoom].\n effect(() => {\n const clamped = this.clampZoom(this.zoom());\n if (clamped !== this.zoom()) this.zoom.set(clamped);\n });\n // Re-clamp pan when zoom, image or viewport geometry changes.\n effect(() => {\n const scale = this.totalScale();\n const [imgW, imgH, vpW, vpH] = [this.natW(), this.natH(), this.vpW(), this.vpH()];\n untracked(() => {\n const p = mkClampPan(this.panX(), this.panY(), imgW, imgH, vpW, vpH, scale);\n this.panX.set(p.x);\n this.panY.set(p.y);\n });\n });\n\n afterNextRender(() => {\n this.measure();\n const viewport = this.viewportRef().nativeElement;\n // Angular's (wheel) binding may register passively; zooming must be\n // able to preventDefault, so attach by hand.\n viewport.addEventListener('wheel', this.onWheel, { passive: false });\n if ('ResizeObserver' in window) {\n this.resizeObserver = new ResizeObserver(() => this.measure());\n this.resizeObserver.observe(viewport);\n }\n });\n }\n\n ngOnDestroy(): void {\n this.resizeObserver?.disconnect();\n if (this.isBrowser) {\n this.viewportRef().nativeElement.removeEventListener('wheel', this.onWheel);\n }\n }\n\n // --- Public API -----------------------------------------------------------\n\n /** Centre the image and reset zoom to 1 (clamped to `minZoom`). */\n reset(): void {\n const zoom = this.clampZoom(1);\n const dirty =\n this.zoom() !== zoom || this.panX() !== 0 || this.panY() !== 0;\n this.zoom.set(zoom);\n this.panX.set(0);\n this.panY.set(0);\n if (dirty) this.changed.emit();\n }\n\n /**\n * Draw the visible crop region to an offscreen canvas and return it as a\n * data-URL (longest edge capped at `options.size ?? 1024`). Returns `null`\n * when the image is not loaded or the canvas is unavailable (SSR, jsdom).\n */\n /**\n * The visible crop region in natural image pixels — what `crop()` would\n * rasterise, without touching a canvas. Use it when the backend performs\n * the actual crop from the master image (no client-side quality loss).\n * Returns `null` until the image has loaded and the viewport is measured.\n */\n cropRect(): { sx: number; sy: number; sw: number; sh: number } | null {\n if (this.status() !== 'loaded') return null;\n const [natW, natH, vpW, vpH] = [this.natW(), this.natH(), this.vpW(), this.vpH()];\n if (!natW || !natH || !vpW || !vpH) return null;\n return mkCropRect(natW, natH, vpW, vpH, this.totalScale(), this.panX(), this.panY());\n }\n\n crop(options?: { type?: string; quality?: number; size?: number }): string | null {\n const image = this.imageRef()?.nativeElement;\n if (!this.isBrowser || this.status() !== 'loaded' || !image) return null;\n const [natW, natH, vpW, vpH] = [this.natW(), this.natH(), this.vpW(), this.vpH()];\n if (!natW || !natH || !vpW || !vpH) return null;\n\n const { sx, sy, sw, sh } = mkCropRect(\n natW, natH, vpW, vpH, this.totalScale(), this.panX(), this.panY(),\n );\n const cap = options?.size ?? 1024;\n const factor = Math.min(1, cap / Math.max(sw, sh));\n try {\n const canvas = document.createElement('canvas');\n canvas.width = Math.max(1, Math.round(sw * factor));\n canvas.height = Math.max(1, Math.round(sh * factor));\n const ctx = canvas.getContext('2d');\n if (!ctx) return null;\n ctx.drawImage(image, sx, sy, sw, sh, 0, 0, canvas.width, canvas.height);\n return canvas.toDataURL(options?.type ?? 'image/png', options?.quality) || null;\n } catch {\n // Environments without canvas rasterisation (e.g. jsdom).\n return null;\n }\n }\n\n // --- Image lifecycle ------------------------------------------------------\n\n protected onImageLoad(event: Event): void {\n const image = event.target as HTMLImageElement;\n this.natW.set(image.naturalWidth);\n this.natH.set(image.naturalHeight);\n this.status.set('loaded');\n this.reset();\n }\n\n protected onImageError(): void {\n this.status.set('error');\n this.imageError.emit();\n }\n\n // --- Pointer panning ------------------------------------------------------\n\n protected onPointerDown(event: PointerEvent): void {\n if (this.disabled()) return;\n try {\n this.viewportRef().nativeElement.setPointerCapture(event.pointerId);\n } catch {\n // jsdom / detached element.\n }\n this.dragStart = {\n x: event.clientX,\n y: event.clientY,\n panX: this.panX(),\n panY: this.panY(),\n };\n this.dragging.set(true);\n event.preventDefault();\n }\n\n protected onPointerMove(event: PointerEvent): void {\n const start = this.dragStart;\n if (!start) return;\n this.panTo(\n start.panX + event.clientX - start.x,\n start.panY + event.clientY - start.y,\n );\n }\n\n protected onPointerUp(): void {\n this.dragStart = null;\n this.dragging.set(false);\n }\n\n // --- Zooming --------------------------------------------------------------\n\n private readonly onWheel = (event: WheelEvent): void => {\n if (this.disabled()) return;\n event.preventDefault();\n // Multiplicative steps feel uniform across the whole zoom range.\n this.zoomTo(this.zoom() * Math.exp(-event.deltaY * 0.0015));\n };\n\n protected onRangeInput(event: Event): void {\n const value = Number((event.target as HTMLInputElement).value);\n if (!Number.isNaN(value)) this.zoomTo(value);\n }\n\n protected stepZoom(direction: 1 | -1): void {\n this.zoomTo(this.zoom() + direction * BUTTON_ZOOM_STEP);\n }\n\n /**\n * Zoom towards the viewport centre: the pan offset scales with the zoom\n * ratio so the image point at the centre stays put, then re-clamps.\n */\n protected zoomTo(next: number): void {\n const clamped = this.clampZoom(next);\n const previous = this.zoom();\n if (clamped === previous) return;\n const ratio = clamped / previous;\n this.zoom.set(clamped);\n const p = mkClampPan(\n this.panX() * ratio,\n this.panY() * ratio,\n this.natW(),\n this.natH(),\n this.vpW(),\n this.vpH(),\n this.coverScale() * clamped,\n );\n this.panX.set(p.x);\n this.panY.set(p.y);\n this.changed.emit();\n }\n\n // --- Keyboard -------------------------------------------------------------\n\n protected onKeydown(event: KeyboardEvent): void {\n if (this.disabled()) return;\n const step = event.shiftKey ? 1 : 10;\n switch (event.key) {\n case 'ArrowLeft':\n this.panTo(this.panX() - step, this.panY());\n break;\n case 'ArrowRight':\n this.panTo(this.panX() + step, this.panY());\n break;\n case 'ArrowUp':\n this.panTo(this.panX(), this.panY() - step);\n break;\n case 'ArrowDown':\n this.panTo(this.panX(), this.panY() + step);\n break;\n case '+':\n case '=':\n this.zoomTo(this.zoom() + KEY_ZOOM_STEP);\n break;\n case '-':\n case '_':\n this.zoomTo(this.zoom() - KEY_ZOOM_STEP);\n break;\n default:\n return;\n }\n event.preventDefault();\n }\n\n // --- Internals ------------------------------------------------------------\n\n private clampZoom(value: number): number {\n return Math.min(this.maxZoom(), Math.max(this.minZoom(), value));\n }\n\n private panTo(x: number, y: number): void {\n const p = mkClampPan(\n x, y, this.natW(), this.natH(), this.vpW(), this.vpH(), this.totalScale(),\n );\n if (p.x === this.panX() && p.y === this.panY()) return;\n this.panX.set(p.x);\n this.panY.set(p.y);\n this.changed.emit();\n }\n\n /** Capture the viewport's CSS size (initial render + every resize). */\n private measure(): void {\n if (!this.isBrowser) return;\n const rect = this.viewportRef().nativeElement.getBoundingClientRect();\n this.vpW.set(rect.width);\n this.vpH.set(rect.height);\n }\n}\n","<div\n #viewport\n class=\"mk-image-cropper__viewport\"\n role=\"application\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n [attr.aria-label]=\"ariaLabel() || i18n.zoom\"\n [attr.aria-disabled]=\"disabled() || null\"\n [class.mk-image-cropper__viewport--fill]=\"aspect() === null\"\n [class.mk-image-cropper__viewport--dragging]=\"dragging()\"\n [style.aspect-ratio]=\"aspect()\"\n (pointerdown)=\"onPointerDown($event)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp()\"\n (pointercancel)=\"onPointerUp()\"\n (keydown)=\"onKeydown($event)\"\n>\n @if (status() === 'error') {\n <div class=\"mk-image-cropper__error\">{{ i18n.imageFailed }}</div>\n } @else {\n <img\n #image\n class=\"mk-image-cropper__image\"\n [class.mk-image-cropper__image--ready]=\"status() === 'loaded'\"\n [src]=\"src()\"\n alt=\"\"\n draggable=\"false\"\n [attr.crossorigin]=\"crossOrigin()\"\n [style.transform]=\"imageTransform()\"\n (load)=\"onImageLoad($event)\"\n (error)=\"onImageError()\"\n />\n <div class=\"mk-image-cropper__grid\" aria-hidden=\"true\"></div>\n @if (round()) {\n <div class=\"mk-image-cropper__mask\" aria-hidden=\"true\"></div>\n }\n }\n</div>\n\n<div class=\"mk-image-cropper__controls\">\n <button\n type=\"button\"\n class=\"mk-image-cropper__zoom-btn\"\n [attr.aria-label]=\"i18n.zoomOut\"\n [disabled]=\"disabled() || zoom() <= minZoom()\"\n (click)=\"stepZoom(-1)\"\n >\n <span aria-hidden=\"true\">−</span>\n </button>\n <input\n type=\"range\"\n class=\"mk-image-cropper__range\"\n step=\"0.01\"\n [min]=\"minZoom()\"\n [max]=\"maxZoom()\"\n [value]=\"zoom()\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"i18n.zoom\"\n (input)=\"onRangeInput($event)\"\n />\n <button\n type=\"button\"\n class=\"mk-image-cropper__zoom-btn\"\n [attr.aria-label]=\"i18n.zoomIn\"\n [disabled]=\"disabled() || zoom() >= maxZoom()\"\n (click)=\"stepZoom(1)\"\n >\n <span aria-hidden=\"true\">+</span>\n </button>\n</div>\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n Directive,\n TemplateRef,\n booleanAttribute,\n contentChild,\n inject,\n input,\n model,\n numberAttribute,\n output,\n} from '@angular/core';\nimport { MK_I18N } from '@mk-kit/ui/core';\nimport { MkDrag, MkDropList, mkMoveItemInArray } from '@mk-kit/ui/dnd';\nimport type { MkDropEvent } from '@mk-kit/ui/dnd';\n\n/** A single asset displayed as a tile in {@link MkMediaGallery}. */\nexport interface MkMediaItem {\n /** Stable identity used for tracking, selection and reorder events. */\n id: string;\n /** Full-size image URL (used for the thumbnail when `thumb` is omitted). */\n src: string;\n /** Optional dedicated thumbnail URL shown in the grid. */\n thumb?: string;\n /** Display name shown under the thumbnail; also names the selection checkbox. */\n name: string;\n /** Alternative text describing the image; falls back to `name` for labels. */\n alt?: string;\n /** Optional caption/meta line shown under the name (e.g. \"1.2 MB · JPG\"). */\n meta?: string;\n}\n\n/** Emitted by {@link MkMediaGallery} after a tile has been reordered. */\nexport interface MkMediaReorderEvent {\n /** Index the item was dragged from. */\n from: number;\n /** Index the item was dropped at. */\n to: number;\n /** The full item array after the move (same reference as the updated model). */\n items: MkMediaItem[];\n}\n\n/**\n * Marks an `<ng-template>` as the per-tile action bar for {@link MkMediaGallery}.\n * The template's implicit context is the {@link MkMediaItem}, so consumers can\n * destructure it with `let-item`. The gallery renders it into each tile's\n * top-right action bar (revealed on hover / focus-within, always visible on\n * touch devices); the consumer supplies the buttons and their handlers.\n *\n * ```html\n * <mk-media-gallery [items]=\"assets()\">\n * <ng-template mkMediaActions let-item>\n * <button mkButton size=\"sm\" variant=\"ghost\" (click)=\"edit(item)\">Edit</button>\n * </ng-template>\n * </mk-media-gallery>\n * ```\n */\n@Directive({\n selector: '[mkMediaActions]',\n})\nexport class MkMediaActions {\n /** The projected action-bar template, rendered once per tile. */\n readonly template = inject<TemplateRef<{ $implicit: MkMediaItem }>>(TemplateRef);\n}\n\n/**\n * Media gallery — a management grid of image tiles for admin media libraries.\n * Each tile shows a square thumbnail (a labelled preview button emitting\n * {@link itemClick}), the item's name and optional meta line, an optional\n * selection checkbox (two-way `selection` model of selected ids) and an\n * optional consumer-projected action bar ({@link MkMediaActions}).\n *\n * With `reorderable`, tiles become draggable via the dnd group's\n * `[mkDropList]` / `[mkDrag]` directives — pointer and keyboard dragging\n * (WCAG 2.1.1) both included. Each drop immutably updates the two-way `items`\n * model and emits {@link reordered}.\n *\n * Clicking a tile always means \"open/preview\" — selection only toggles through\n * the checkbox, never on tile click.\n *\n * ```html\n * <mk-media-gallery\n * [(items)]=\"assets\"\n * [(selection)]=\"selectedIds\"\n * selectable\n * reorderable\n * [columns]=\"5\"\n * (itemClick)=\"openPreview($event)\"\n * (reordered)=\"persistOrder($event)\"\n * >\n * <ng-template mkMediaActions let-item>\n * <button mkButton size=\"sm\" variant=\"ghost\" (click)=\"edit(item)\">Edit</button>\n * <button mkButton size=\"sm\" variant=\"ghost\" tone=\"danger\" (click)=\"remove(item)\">\n * Delete\n * </button>\n * </ng-template>\n * </mk-media-gallery>\n * ```\n */\n@Component({\n selector: 'mk-media-gallery',\n exportAs: 'mkMediaGallery',\n templateUrl: './media-gallery.html',\n styleUrl: './media-gallery.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [MkDropList, MkDrag, NgTemplateOutlet],\n host: {\n class: 'mk-media-gallery',\n role: 'group',\n '[attr.aria-label]': 'ariaLabel()',\n },\n})\nexport class MkMediaGallery {\n /** Localized strings (region label, checkbox/preview labels, empty state). */\n protected readonly i18n = inject(MK_I18N);\n\n /** The gallery's items (two-way). Replaced immutably on every reorder drop. */\n readonly items = model<MkMediaItem[]>([]);\n\n /** Ids of the currently selected items (two-way). */\n readonly selection = model<string[]>([]);\n\n /** Show a selection checkbox on every tile. */\n readonly selectable = input(false, { transform: booleanAttribute });\n\n /** Allow drag-and-drop (pointer + keyboard) reordering of the tiles. */\n readonly reorderable = input(false, { transform: booleanAttribute });\n\n /** Number of grid columns. */\n readonly columns = input(4, { transform: numberAttribute });\n\n /** Accessible name of the gallery region. Defaults to `i18n.mediaLibrary`. */\n readonly ariaLabel = input<string>(this.i18n.mediaLibrary);\n\n /** Emitted when a tile's preview button is activated (click/Enter/Space). */\n readonly itemClick = output<MkMediaItem>();\n\n /** Emitted after a drop has updated the `items` model. */\n readonly reordered = output<MkMediaReorderEvent>();\n\n /** Optional consumer-projected per-tile action bar (`$implicit` = item). */\n protected readonly actions = contentChild(MkMediaActions);\n\n /** Whether the item with `id` is currently selected. */\n protected isSelected(id: string): boolean {\n return this.selection().includes(id);\n }\n\n /** Sync the two-way `selection` model with the checkbox's native state. */\n protected onCheckboxChange(item: MkMediaItem, event: Event): void {\n const checked = (event.target as HTMLInputElement).checked;\n const current = this.selection();\n if (checked) {\n if (!current.includes(item.id)) this.selection.set([...current, item.id]);\n } else {\n this.selection.set(current.filter((id) => id !== item.id));\n }\n }\n\n /** Emit {@link itemClick} for the tile's preview button. */\n protected onPreviewClick(item: MkMediaItem): void {\n this.itemClick.emit(item);\n }\n\n /**\n * Apply a drop from the dnd module: move the item on a copy of `items`,\n * write the copy back to the two-way model and emit {@link reordered}.\n */\n protected onDrop(event: MkDropEvent<MkMediaItem>): void {\n const from = event.previousIndex;\n const to = event.currentIndex;\n if (from === to) return;\n const next = [...this.items()];\n mkMoveItemInArray(next, from, to);\n this.items.set(next);\n this.reordered.emit({ from, to, items: next });\n }\n\n /**\n * Keep events from the tile's nested controls (checkbox, action buttons)\n * inside those controls: without this, Space/Enter on the checkbox or an\n * action button would bubble to the surrounding `[mkDrag]` host and pick the\n * tile up instead, and a pointer press would start a drag session. Native\n * behavior is untouched — only propagation stops.\n */\n protected stopEvent(event: Event): void {\n event.stopPropagation();\n }\n}\n","@if (items().length === 0) {\n <div class=\"mk-media-gallery__empty\">{{ i18n.noData }}</div>\n} @else if (reorderable()) {\n <div\n mkDropList\n class=\"mk-media-gallery__grid\"\n [style.--_cols]=\"columns()\"\n [mkDropListData]=\"items()\"\n [mkDropListLabel]=\"ariaLabel()\"\n mkDropListOrientation=\"horizontal\"\n (mkDropListDropped)=\"onDrop($event)\"\n >\n @for (item of items(); track item.id) {\n <div\n mkDrag\n class=\"mk-media-gallery__tile\"\n [class.mk-media-gallery__tile--selected]=\"isSelected(item.id)\"\n [mkDragData]=\"item\"\n >\n <ng-container\n [ngTemplateOutlet]=\"tile\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </div>\n }\n </div>\n} @else {\n <div class=\"mk-media-gallery__grid\" [style.--_cols]=\"columns()\">\n @for (item of items(); track item.id) {\n <div\n class=\"mk-media-gallery__tile\"\n [class.mk-media-gallery__tile--selected]=\"isSelected(item.id)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"tile\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </div>\n }\n </div>\n}\n\n<ng-template #tile let-item>\n <div class=\"mk-media-gallery__media\">\n <button\n type=\"button\"\n class=\"mk-media-gallery__preview\"\n [attr.aria-label]=\"i18n.viewImage(item.alt ?? item.name)\"\n (click)=\"onPreviewClick(item)\"\n (keydown)=\"stopEvent($event)\"\n >\n <img\n class=\"mk-media-gallery__img\"\n [src]=\"item.thumb ?? item.src\"\n [alt]=\"item.alt ?? ''\"\n loading=\"lazy\"\n draggable=\"false\"\n />\n </button>\n\n @if (selectable()) {\n <span\n class=\"mk-media-gallery__check\"\n (keydown)=\"stopEvent($event)\"\n (pointerdown)=\"stopEvent($event)\"\n >\n <input\n type=\"checkbox\"\n class=\"mk-media-gallery__check-input\"\n [checked]=\"isSelected(item.id)\"\n [attr.aria-label]=\"i18n.selectRow(item.name)\"\n (change)=\"onCheckboxChange(item, $event)\"\n />\n <span class=\"mk-media-gallery__check-box\" aria-hidden=\"true\">\n <span class=\"mk-media-gallery__check-mark\"></span>\n </span>\n </span>\n }\n\n @if (actions(); as actionsDir) {\n <div\n class=\"mk-media-gallery__actions\"\n (keydown)=\"stopEvent($event)\"\n (pointerdown)=\"stopEvent($event)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"actionsDir.template\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </div>\n }\n </div>\n\n <div class=\"mk-media-gallery__caption\">\n <span class=\"mk-media-gallery__name\">{{ item.name }}</span>\n @if (item.meta) {\n <span class=\"mk-media-gallery__meta\">{{ item.meta }}</span>\n }\n </div>\n</ng-template>\n","/**\n * MEDIA components group barrel for @mk-kit/ui.\n * Images, galleries, lightbox, cropping and media management.\n */\nexport * from './image';\nexport * from './lightbox';\nexport * from './image-gallery';\nexport * from './image-cropper';\nexport * from './media-gallery';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|