@mk-kit/ui 0.34.0 → 0.35.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.
@@ -1,7 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, booleanAttribute, signal, ChangeDetectionStrategy, Component, contentChildren, viewChildren, model, effect, inject, Directive, computed, numberAttribute, ElementRef, DOCUMENT, output, Injector, PLATFORM_ID, afterNextRender, viewChild, TemplateRef, linkedSignal } from '@angular/core';
2
+ import { input, booleanAttribute, signal, ChangeDetectionStrategy, Component, contentChildren, viewChildren, model, effect, inject, Directive, computed, numberAttribute, ElementRef, DOCUMENT, output, Injector, PLATFORM_ID, viewChild, afterNextRender, TemplateRef, linkedSignal } from '@angular/core';
3
3
  import { mkUniqueId, MK_I18N, MkAnchoredPanel, MkFocusTrap } from '@mk-kit/ui/core';
4
4
  import { NgTemplateOutlet, isPlatformBrowser, isPlatformServer } from '@angular/common';
5
+ import { MkButton } from '@mk-kit/ui/button';
5
6
  import { MkIcon } from '@mk-kit/ui/icon';
6
7
 
7
8
  /**
@@ -450,17 +451,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
450
451
  }, template: "<nav [attr.aria-label]=\"label()\">\n <ul class=\"mk-pagination__list\" role=\"list\">\n <li>\n <button\n type=\"button\"\n class=\"mk-pagination__btn mk-pagination__btn--nav\"\n [attr.aria-label]=\"i18n.previousPage\"\n [disabled]=\"!hasPrev()\"\n (click)=\"prev()\"\n >\n <svg viewBox=\"0 0 24 24\" width=\"1em\" height=\"1em\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <polyline points=\"15 18 9 12 15 6\" />\n </svg>\n </button>\n </li>\n\n @for (item of items(); track $index) {\n @if (item === 'ellipsis') {\n <li>\n <span class=\"mk-pagination__ellipsis\" aria-hidden=\"true\">\u2026</span>\n </li>\n } @else {\n <li>\n <button\n type=\"button\"\n class=\"mk-pagination__btn\"\n [class.mk-pagination__btn--active]=\"item === current()\"\n [attr.aria-label]=\"i18n.goToPage(item)\"\n [attr.aria-current]=\"item === current() ? 'page' : null\"\n (click)=\"goTo(item)\"\n >\n {{ item }}\n </button>\n </li>\n }\n }\n\n <li>\n <button\n type=\"button\"\n class=\"mk-pagination__btn mk-pagination__btn--nav\"\n [attr.aria-label]=\"i18n.nextPage\"\n [disabled]=\"!hasNext()\"\n (click)=\"next()\"\n >\n <svg viewBox=\"0 0 24 24\" width=\"1em\" height=\"1em\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n </button>\n </li>\n </ul>\n</nav>\n", styles: [":host{display:block}.mk-pagination__list{display:flex;flex-wrap:wrap;align-items:center;gap:var(--mk-space-1);margin:0;padding:0;list-style:none}.mk-pagination__btn{display:inline-flex;align-items:center;justify-content:center;min-width:var(--mk-control-height-md);height:var(--mk-control-height-md);padding:0 var(--mk-space-2);background:transparent;border:var(--mk-border-width) solid transparent;border-radius:var(--mk-radius-md);color:var(--mk-text);font-family:inherit;font-size:var(--mk-font-size-sm);font-weight:var(--mk-font-weight-medium);line-height:1;cursor:pointer;transition:background-color var(--mk-duration-fast) var(--mk-ease-standard),color var(--mk-duration-fast) var(--mk-ease-standard),border-color var(--mk-duration-fast) var(--mk-ease-standard)}.mk-pagination__btn:hover:not(:disabled):not(.mk-pagination__btn--active){background:var(--mk-hover-overlay)}.mk-pagination__btn:focus-visible{outline:var(--mk-focus-ring-width) solid var(--mk-focus-ring);outline-offset:var(--mk-focus-ring-offset)}.mk-pagination__btn:disabled{color:var(--mk-text-disabled);cursor:not-allowed}.mk-pagination__btn--nav{color:var(--mk-text-muted)}:host(:dir(rtl)) .mk-pagination__btn--nav svg{transform:scaleX(-1)}.mk-pagination__btn--active{background:var(--mk-primary);color:var(--mk-primary-contrast);cursor:default}.mk-pagination__ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:var(--mk-control-height-md);height:var(--mk-control-height-md);color:var(--mk-text-subtle);-webkit-user-select:none;user-select:none}\n"] }]
451
452
  }], propDecorators: { total: [{ type: i0.Input, args: [{ isSignal: true, alias: "total", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], pageCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageCount", required: false }] }], page: [{ type: i0.Input, args: [{ isSignal: true, alias: "page", required: false }] }, { type: i0.Output, args: ["pageChange"] }], siblingCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "siblingCount", required: false }] }], boundaryCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "boundaryCount", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }] } });
452
453
 
454
+ /** Hover dwell before a submenu opens, so sweeping past an item does not flash it. */
455
+ const SUBMENU_HOVER_DELAY = 150;
453
456
  /**
454
457
  * An item within an `<mk-menu>`. Renders as an ARIA `menuitem` with an optional
455
458
  * icon slot (`[mkMenuItemIcon]`), disabled and danger states, and either emits
456
459
  * `action` or navigates when `href` is set. Activating closes the menu.
457
460
  *
461
+ * With `[mkSubmenuFor]` pointing at a nested `<mk-menu>` the item becomes a
462
+ * submenu trigger instead: it shows a chevron, exposes `aria-haspopup` /
463
+ * `aria-expanded`, opens the submenu beside itself on hover, ArrowRight,
464
+ * Enter, Space or click, and never emits `action`.
465
+ *
458
466
  * ```html
459
467
  * <mk-menu-item (action)="rename()">
460
468
  * <svg mkMenuItemIcon>…</svg> Rename
461
469
  * </mk-menu-item>
462
470
  * <mk-menu-item danger (action)="remove()">Delete</mk-menu-item>
463
471
  * <mk-menu-item href="/help">Help</mk-menu-item>
472
+ * <mk-menu-item [mkSubmenuFor]="more">More</mk-menu-item>
464
473
  * ```
465
474
  */
466
475
  class MkMenuItem {
@@ -474,21 +483,62 @@ class MkMenuItem {
474
483
  /** When set, activating the item navigates here. */
475
484
  href = input(/* @ts-ignore */
476
485
  ...(ngDevMode ? [undefined, { debugName: "href" }] : /* istanbul ignore next */ []));
477
- /** Emitted when the item is activated (not for disabled items). */
486
+ /** A nested `mk-menu` this item opens as a submenu. */
487
+ submenu = input(undefined, { ...(ngDevMode ? { debugName: "submenu" } : /* istanbul ignore next */ {}), alias: 'mkSubmenuFor' });
488
+ /** Emitted when the item is activated (not for disabled or submenu items). */
478
489
  action = output();
490
+ hoverTimer;
479
491
  activate(event) {
480
492
  if (this.disabled()) {
481
493
  event?.preventDefault();
482
494
  event?.stopPropagation();
483
495
  return;
484
496
  }
497
+ if (this.submenu()) {
498
+ // A pointer click keeps focus where it is; keyboard activation (Enter /
499
+ // Space arrive here through the panel handler without an event) moves
500
+ // focus into the submenu.
501
+ this.openSubmenu(!event);
502
+ return;
503
+ }
485
504
  this.action.emit();
486
505
  const href = this.href();
487
- this.menu?.close(true);
506
+ this.menu?.closeAll(true);
488
507
  if (href) {
489
508
  this.document.defaultView?.location.assign(href);
490
509
  }
491
510
  }
511
+ /** Open the submenu beside this item; `focus` moves focus to its first item. */
512
+ openSubmenu(focus) {
513
+ const sub = this.submenu();
514
+ if (!sub || this.disabled())
515
+ return;
516
+ this.cancelHover();
517
+ if (sub.opened()) {
518
+ if (focus)
519
+ sub.focusFirstItem();
520
+ return;
521
+ }
522
+ sub.open(this.el.nativeElement, focus ? 'first' : false, this.menu?.submenuPlacement() ?? 'right-start');
523
+ }
524
+ onMouseEnter() {
525
+ if (this.disabled())
526
+ return;
527
+ this.menu?.itemHovered(this);
528
+ if (this.submenu() && !this.submenu().opened()) {
529
+ this.cancelHover();
530
+ this.hoverTimer = setTimeout(() => this.openSubmenu(false), SUBMENU_HOVER_DELAY);
531
+ }
532
+ }
533
+ onMouseLeave() {
534
+ this.cancelHover();
535
+ }
536
+ cancelHover() {
537
+ if (this.hoverTimer) {
538
+ clearTimeout(this.hoverTimer);
539
+ this.hoverTimer = undefined;
540
+ }
541
+ }
492
542
  /** Move DOM focus to this item (roving focus). */
493
543
  focusEl() {
494
544
  this.el.nativeElement.focus();
@@ -501,8 +551,11 @@ class MkMenuItem {
501
551
  text() {
502
552
  return (this.el.nativeElement.textContent ?? '').trim().toLowerCase();
503
553
  }
554
+ ngOnDestroy() {
555
+ this.cancelHover();
556
+ }
504
557
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkMenuItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
505
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.7", type: MkMenuItem, isStandalone: true, selector: "mk-menu-item", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, danger: { classPropertyName: "danger", publicName: "danger", isSignal: true, isRequired: false, transformFunction: null }, href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, host: { attributes: { "role": "menuitem", "tabindex": "-1" }, listeners: { "click": "activate($event)" }, properties: { "attr.aria-disabled": "disabled() || null", "class.mk-menu-item--danger": "danger()", "class.mk-menu-item--disabled": "disabled()" }, classAttribute: "mk-menu-item" }, ngImport: i0, template: "<span class=\"mk-menu-item__icon\" aria-hidden=\"true\">\n <ng-content select=\"[mkMenuItemIcon]\" />\n</span>\n<span class=\"mk-menu-item__label\">\n <ng-content />\n</span>\n", styles: [":host{display:flex;align-items:center;gap:var(--mk-space-2);min-height:36px;padding:var(--mk-space-2) var(--mk-space-3);border-radius:var(--mk-radius-sm);color:var(--mk-text);font-size:var(--mk-font-size-sm);line-height:var(--mk-line-height-snug);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color var(--mk-duration-fast) var(--mk-ease-standard)}:host(:hover:not(.mk-menu-item--disabled)),:host(:focus){background:var(--mk-hover-overlay);outline:none}:host(:focus-visible){outline:var(--mk-focus-ring-width) solid var(--mk-focus-ring);outline-offset:calc(-1 * var(--mk-focus-ring-width))}:host(.mk-menu-item--danger){color:var(--mk-danger-text)}:host(.mk-menu-item--danger:hover:not(.mk-menu-item--disabled)),:host(.mk-menu-item--danger:focus){background:var(--mk-danger-subtle);color:var(--mk-danger-subtle-text)}:host(.mk-menu-item--disabled){color:var(--mk-text-disabled);cursor:not-allowed;pointer-events:none}.mk-menu-item__icon{display:inline-flex;align-items:center;flex:none;font-size:var(--mk-font-size-md)}.mk-menu-item__icon:empty{display:none}.mk-menu-item__label{flex:1 1 auto;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
558
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: MkMenuItem, isStandalone: true, selector: "mk-menu-item", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, danger: { classPropertyName: "danger", publicName: "danger", isSignal: true, isRequired: false, transformFunction: null }, href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: false, transformFunction: null }, submenu: { classPropertyName: "submenu", publicName: "mkSubmenuFor", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, host: { attributes: { "role": "menuitem", "tabindex": "-1" }, listeners: { "click": "activate($event)", "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()" }, properties: { "attr.aria-disabled": "disabled() || null", "attr.aria-haspopup": "submenu() ? 'menu' : null", "attr.aria-expanded": "submenu() ? submenu()!.opened() : null", "attr.aria-controls": "submenu()?.panelId ?? null", "class.mk-menu-item--danger": "danger()", "class.mk-menu-item--disabled": "disabled()", "class.mk-menu-item--submenu": "!!submenu()", "class.mk-menu-item--expanded": "submenu()?.opened() ?? false" }, classAttribute: "mk-menu-item" }, ngImport: i0, template: "<span class=\"mk-menu-item__icon\" aria-hidden=\"true\">\n <ng-content select=\"[mkMenuItemIcon]\" />\n</span>\n<span class=\"mk-menu-item__label\">\n <ng-content />\n</span>\n@if (submenu()) {\n <svg\n class=\"mk-menu-item__chevron\"\n viewBox=\"0 0 16 16\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.75\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M6 3.5 10.5 8 6 12.5\" />\n </svg>\n}\n", styles: [":host{display:flex;align-items:center;gap:var(--mk-space-2);min-height:36px;padding:var(--mk-space-2) var(--mk-space-3);border-radius:var(--mk-radius-sm);color:var(--mk-text);font-size:var(--mk-font-size-sm);line-height:var(--mk-line-height-snug);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color var(--mk-duration-fast) var(--mk-ease-standard)}:host(:hover:not(.mk-menu-item--disabled)),:host(:focus){background:var(--mk-hover-overlay);outline:none}:host(:focus-visible){outline:var(--mk-focus-ring-width) solid var(--mk-focus-ring);outline-offset:calc(-1 * var(--mk-focus-ring-width))}:host(.mk-menu-item--danger){color:var(--mk-danger-text)}:host(.mk-menu-item--danger:hover:not(.mk-menu-item--disabled)),:host(.mk-menu-item--danger:focus){background:var(--mk-danger-subtle);color:var(--mk-danger-subtle-text)}:host(.mk-menu-item--disabled){color:var(--mk-text-disabled);cursor:not-allowed;pointer-events:none}.mk-menu-item__icon{display:inline-flex;align-items:center;flex:none;font-size:var(--mk-font-size-md)}.mk-menu-item__icon:empty{display:none}.mk-menu-item__label{flex:1 1 auto;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mk-menu-item__chevron{flex:none;margin-inline-start:auto;color:var(--mk-text-muted)}:host(:dir(rtl)) .mk-menu-item__chevron{transform:scaleX(-1)}:host(.mk-menu-item--expanded){background:var(--mk-hover-overlay)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
506
559
  }
507
560
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkMenuItem, decorators: [{
508
561
  type: Component,
@@ -511,11 +564,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
511
564
  role: 'menuitem',
512
565
  tabindex: '-1',
513
566
  '[attr.aria-disabled]': 'disabled() || null',
567
+ '[attr.aria-haspopup]': "submenu() ? 'menu' : null",
568
+ '[attr.aria-expanded]': 'submenu() ? submenu()!.opened() : null',
569
+ '[attr.aria-controls]': 'submenu()?.panelId ?? null',
514
570
  '[class.mk-menu-item--danger]': 'danger()',
515
571
  '[class.mk-menu-item--disabled]': 'disabled()',
572
+ '[class.mk-menu-item--submenu]': '!!submenu()',
573
+ '[class.mk-menu-item--expanded]': 'submenu()?.opened() ?? false',
516
574
  '(click)': 'activate($event)',
517
- }, template: "<span class=\"mk-menu-item__icon\" aria-hidden=\"true\">\n <ng-content select=\"[mkMenuItemIcon]\" />\n</span>\n<span class=\"mk-menu-item__label\">\n <ng-content />\n</span>\n", styles: [":host{display:flex;align-items:center;gap:var(--mk-space-2);min-height:36px;padding:var(--mk-space-2) var(--mk-space-3);border-radius:var(--mk-radius-sm);color:var(--mk-text);font-size:var(--mk-font-size-sm);line-height:var(--mk-line-height-snug);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color var(--mk-duration-fast) var(--mk-ease-standard)}:host(:hover:not(.mk-menu-item--disabled)),:host(:focus){background:var(--mk-hover-overlay);outline:none}:host(:focus-visible){outline:var(--mk-focus-ring-width) solid var(--mk-focus-ring);outline-offset:calc(-1 * var(--mk-focus-ring-width))}:host(.mk-menu-item--danger){color:var(--mk-danger-text)}:host(.mk-menu-item--danger:hover:not(.mk-menu-item--disabled)),:host(.mk-menu-item--danger:focus){background:var(--mk-danger-subtle);color:var(--mk-danger-subtle-text)}:host(.mk-menu-item--disabled){color:var(--mk-text-disabled);cursor:not-allowed;pointer-events:none}.mk-menu-item__icon{display:inline-flex;align-items:center;flex:none;font-size:var(--mk-font-size-md)}.mk-menu-item__icon:empty{display:none}.mk-menu-item__label{flex:1 1 auto;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"] }]
518
- }], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], danger: [{ type: i0.Input, args: [{ isSignal: true, alias: "danger", required: false }] }], href: [{ type: i0.Input, args: [{ isSignal: true, alias: "href", required: false }] }], action: [{ type: i0.Output, args: ["action"] }] } });
575
+ '(mouseenter)': 'onMouseEnter()',
576
+ '(mouseleave)': 'onMouseLeave()',
577
+ }, template: "<span class=\"mk-menu-item__icon\" aria-hidden=\"true\">\n <ng-content select=\"[mkMenuItemIcon]\" />\n</span>\n<span class=\"mk-menu-item__label\">\n <ng-content />\n</span>\n@if (submenu()) {\n <svg\n class=\"mk-menu-item__chevron\"\n viewBox=\"0 0 16 16\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.75\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M6 3.5 10.5 8 6 12.5\" />\n </svg>\n}\n", styles: [":host{display:flex;align-items:center;gap:var(--mk-space-2);min-height:36px;padding:var(--mk-space-2) var(--mk-space-3);border-radius:var(--mk-radius-sm);color:var(--mk-text);font-size:var(--mk-font-size-sm);line-height:var(--mk-line-height-snug);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color var(--mk-duration-fast) var(--mk-ease-standard)}:host(:hover:not(.mk-menu-item--disabled)),:host(:focus){background:var(--mk-hover-overlay);outline:none}:host(:focus-visible){outline:var(--mk-focus-ring-width) solid var(--mk-focus-ring);outline-offset:calc(-1 * var(--mk-focus-ring-width))}:host(.mk-menu-item--danger){color:var(--mk-danger-text)}:host(.mk-menu-item--danger:hover:not(.mk-menu-item--disabled)),:host(.mk-menu-item--danger:focus){background:var(--mk-danger-subtle);color:var(--mk-danger-subtle-text)}:host(.mk-menu-item--disabled){color:var(--mk-text-disabled);cursor:not-allowed;pointer-events:none}.mk-menu-item__icon{display:inline-flex;align-items:center;flex:none;font-size:var(--mk-font-size-md)}.mk-menu-item__icon:empty{display:none}.mk-menu-item__label{flex:1 1 auto;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mk-menu-item__chevron{flex:none;margin-inline-start:auto;color:var(--mk-text-muted)}:host(:dir(rtl)) .mk-menu-item__chevron{transform:scaleX(-1)}:host(.mk-menu-item--expanded){background:var(--mk-hover-overlay)}\n"] }]
578
+ }], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], danger: [{ type: i0.Input, args: [{ isSignal: true, alias: "danger", required: false }] }], href: [{ type: i0.Input, args: [{ isSignal: true, alias: "href", required: false }] }], submenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "mkSubmenuFor", required: false }] }], action: [{ type: i0.Output, args: ["action"] }] } });
519
579
 
520
580
  /**
521
581
  * Dropdown menu implementing the ARIA menu pattern (roving focus, Arrow / Home
@@ -533,13 +593,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
533
593
  * <mk-menu-item danger (action)="del()">Delete</mk-menu-item>
534
594
  * </mk-menu>
535
595
  * ```
596
+ *
597
+ * **Submenus.** Point an item at a nested menu with `[mkSubmenuFor]`; declare
598
+ * the nested `<mk-menu>` anywhere inside the parent menu. The submenu opens
599
+ * beside its item on hover (after a short delay), on ArrowRight / Enter /
600
+ * Space / click, and closes with ArrowLeft or Escape (returning focus to the
601
+ * item) — only that level, per the APG menu pattern. Activating any leaf item
602
+ * closes the whole chain. In RTL the submenu opens on the left and the arrow
603
+ * keys swap.
604
+ *
605
+ * ```html
606
+ * <mk-menu #menu>
607
+ * <mk-menu-item [mkSubmenuFor]="exportMenu">Export</mk-menu-item>
608
+ * <mk-menu #exportMenu>
609
+ * <mk-menu-item (action)="csv()">CSV</mk-menu-item>
610
+ * <mk-menu-item (action)="pdf()">PDF</mk-menu-item>
611
+ * </mk-menu>
612
+ * </mk-menu>
613
+ * ```
536
614
  */
537
615
  class MkMenu {
538
616
  document = inject(DOCUMENT);
539
617
  injector = inject(Injector);
540
618
  isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
619
+ /** The enclosing menu when this one is a submenu. */
620
+ parent = inject(MkMenu, { optional: true, skipSelf: true });
541
621
  items = contentChildren(MkMenuItem, /* @ts-ignore */
542
622
  ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
623
+ panelRef = viewChild('panel', /* @ts-ignore */
624
+ ...(ngDevMode ? [{ debugName: "panelRef" }] : /* istanbul ignore next */ []));
543
625
  /** Stable id for `aria-controls` on the trigger. */
544
626
  panelId = mkUniqueId('mk-menu');
545
627
  _open = signal(false, /* @ts-ignore */
@@ -555,22 +637,38 @@ class MkMenu {
555
637
  /** Viewport point to anchor to (`openAt` / context menu). */
556
638
  anchorPoint = signal(undefined, /* @ts-ignore */
557
639
  ...(ngDevMode ? [{ debugName: "anchorPoint" }] : /* istanbul ignore next */ []));
640
+ /** Where the panel sits relative to its anchor (submenus open sideways). */
641
+ placement = signal('bottom-start', /* @ts-ignore */
642
+ ...(ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []));
558
643
  triggerEl = null;
559
644
  typeahead = '';
560
645
  typeaheadTimer;
646
+ /** Submenus that are currently open under this menu. */
647
+ openChildren = new Set();
648
+ /**
649
+ * Whether this menu is a submenu of another `mk-menu`. Submenus open
650
+ * sideways, close a single level on Escape, and swap ArrowLeft/ArrowRight.
651
+ */
652
+ get isSubmenu() {
653
+ return this.parent !== null;
654
+ }
561
655
  /**
562
656
  * Open the menu anchored to `trigger`. `focus` picks the item that receives
563
657
  * focus once the panel is painted: `true`/`'first'` for the first enabled
564
658
  * item, `'last'` for the last (ArrowUp on a menu button, per the APG
565
659
  * menu-button pattern), `false` to leave focus where it is (mouse open).
660
+ * `placement` overrides the default `bottom-start` (submenus pass
661
+ * `right-start` / `left-start`).
566
662
  */
567
- open(trigger, focus = true) {
663
+ open(trigger, focus = true, placement = 'bottom-start') {
568
664
  if (!this.isBrowser || this._open())
569
665
  return;
570
666
  this.triggerEl = trigger;
571
667
  this.anchorEl.set(trigger);
572
668
  this.anchorPoint.set(undefined);
669
+ this.placement.set(placement);
573
670
  this._open.set(true);
671
+ this.parent?.childOpened(this);
574
672
  if (focus)
575
673
  this.focusAfterOpen(focus === 'last' ? 'last' : 'first');
576
674
  }
@@ -586,21 +684,42 @@ class MkMenu {
586
684
  this.triggerEl = restoreFocusEl ?? null;
587
685
  this.anchorEl.set(undefined);
588
686
  this.anchorPoint.set({ x, y });
687
+ this.placement.set('bottom-start');
589
688
  this._open.set(true);
590
689
  this.focusAfterOpen('first');
591
690
  }
592
- /** Close the menu; optionally restore focus to the trigger. */
691
+ /**
692
+ * Close this menu (and any submenu open under it); optionally restore focus
693
+ * to the trigger — for a submenu that is the item it hangs off.
694
+ */
593
695
  close(restoreFocus = true) {
594
696
  if (!this._open())
595
697
  return;
698
+ this.closeChildren();
596
699
  this._open.set(false);
597
700
  this.anchorEl.set(undefined);
598
701
  this.anchorPoint.set(undefined);
599
702
  const trigger = this.triggerEl;
600
703
  this.triggerEl = null;
704
+ this.parent?.childClosed(this);
601
705
  if (restoreFocus)
602
706
  trigger?.focus();
603
707
  }
708
+ /**
709
+ * Close the whole menu chain from the root down — what activating a leaf
710
+ * item does, wherever in the tree it sits. Focus returns to the root
711
+ * trigger when `restoreFocus` is set.
712
+ */
713
+ closeAll(restoreFocus = true) {
714
+ this.root().close(restoreFocus);
715
+ }
716
+ /** Close every submenu open under this menu, except `keep`. */
717
+ closeChildren(keep) {
718
+ for (const child of [...this.openChildren]) {
719
+ if (child !== keep)
720
+ child.close(false);
721
+ }
722
+ }
604
723
  /** Toggle open/closed from a trigger. */
605
724
  toggle(trigger, focusFirst = true) {
606
725
  if (this._open()) {
@@ -622,6 +741,46 @@ class MkMenu {
622
741
  focusLastItem() {
623
742
  this.focusLast();
624
743
  }
744
+ /**
745
+ * Whether `node` lives inside this menu's panel or any submenu open under
746
+ * it. Submenu panels are separate top-layer elements, so a plain
747
+ * `contains` on the parent panel would treat clicks in them as outside.
748
+ */
749
+ containsTarget(node) {
750
+ if (!node)
751
+ return false;
752
+ if (this.panelRef()?.nativeElement.contains(node))
753
+ return true;
754
+ for (const child of this.openChildren) {
755
+ if (child.containsTarget(node))
756
+ return true;
757
+ }
758
+ return false;
759
+ }
760
+ /** Bound for the anchored panel's `keepOpenWhen` (stable identity). */
761
+ keepOpenWhen = (target) => [...this.openChildren].some((c) => c.containsTarget(target));
762
+ /**
763
+ * An item was hovered: close sibling submenus so only the hovered branch
764
+ * stays open (the item opens its own submenu after a delay).
765
+ */
766
+ itemHovered(item) {
767
+ this.closeChildren(item.submenu());
768
+ }
769
+ /** @internal */
770
+ childOpened(child) {
771
+ this.closeChildren(child);
772
+ this.openChildren.add(child);
773
+ }
774
+ /** @internal */
775
+ childClosed(child) {
776
+ this.openChildren.delete(child);
777
+ }
778
+ root() {
779
+ let m = this;
780
+ while (m.parent)
781
+ m = m.parent;
782
+ return m;
783
+ }
625
784
  /** Focus an item once the panel is in the top layer and painted. */
626
785
  focusAfterOpen(which) {
627
786
  afterNextRender({
@@ -633,7 +792,27 @@ class MkMenu {
633
792
  },
634
793
  }, { injector: this.injector });
635
794
  }
795
+ /**
796
+ * Whether the menu is laid out right-to-left (submenu side + arrow keys).
797
+ * Read from the trigger's nearest `dir` attribute — the panel itself lives
798
+ * in the top layer, outside any `dir` container — then from computed style.
799
+ */
800
+ isRtl() {
801
+ // A submenu's trigger is an item inside a teleported panel, so climb to
802
+ // the root menu, whose trigger sits in the consumer's DOM.
803
+ const el = this.root().triggerEl ?? this.panelRef()?.nativeElement;
804
+ if (!el)
805
+ return this.document.dir === 'rtl';
806
+ const dir = el.closest('[dir]')?.getAttribute('dir');
807
+ if (dir)
808
+ return dir.toLowerCase() === 'rtl';
809
+ const view = this.document.defaultView;
810
+ return (view?.getComputedStyle(el).direction ?? 'ltr') === 'rtl';
811
+ }
636
812
  onPanelKeydown(event) {
813
+ const rtl = this.isRtl();
814
+ const openKey = rtl ? 'ArrowLeft' : 'ArrowRight';
815
+ const closeKey = rtl ? 'ArrowRight' : 'ArrowLeft';
637
816
  switch (event.key) {
638
817
  case 'ArrowDown':
639
818
  event.preventDefault();
@@ -656,13 +835,27 @@ class MkMenu {
656
835
  event.preventDefault();
657
836
  this.activeItem()?.activate();
658
837
  break;
838
+ case openKey: {
839
+ const item = this.activeItem();
840
+ if (item?.submenu()) {
841
+ event.preventDefault();
842
+ item.openSubmenu(true);
843
+ }
844
+ break;
845
+ }
846
+ case closeKey:
847
+ if (this.isSubmenu) {
848
+ event.preventDefault();
849
+ this.close(true);
850
+ }
851
+ break;
659
852
  case 'Escape':
660
853
  event.preventDefault();
661
854
  this.close(true);
662
855
  break;
663
856
  case 'Tab':
664
857
  event.preventDefault();
665
- this.close(true);
858
+ this.closeAll(true);
666
859
  break;
667
860
  default:
668
861
  if (event.key.length === 1 && !event.ctrlKey && !event.metaKey) {
@@ -670,6 +863,10 @@ class MkMenu {
670
863
  }
671
864
  }
672
865
  }
866
+ /** Placement for a submenu hanging off `item`, honouring text direction. */
867
+ submenuPlacement() {
868
+ return this.isRtl() ? 'left-start' : 'right-start';
869
+ }
673
870
  enabled() {
674
871
  return this.items().filter((i) => !i.disabled());
675
872
  }
@@ -718,16 +915,18 @@ class MkMenu {
718
915
  ngOnDestroy() {
719
916
  if (this.typeaheadTimer)
720
917
  clearTimeout(this.typeaheadTimer);
918
+ if (this._open())
919
+ this.close(false);
721
920
  }
722
921
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
723
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: MkMenu, isStandalone: true, selector: "mk-menu", host: { classAttribute: "mk-menu" }, queries: [{ propertyName: "items", predicate: MkMenuItem, isSignal: true }], exportAs: ["mkMenu"], ngImport: i0, template: "@if (opened()) {\n <div\n class=\"mk-menu__panel\"\n role=\"menu\"\n [id]=\"panelId\"\n mkAnchoredPanel\n [mkAnchoredPanelFor]=\"anchorEl()\"\n [anchorRect]=\"anchorPoint()\"\n placement=\"bottom-start\"\n (dismiss)=\"close(false)\"\n [attr.aria-label]=\"ariaLabel()\"\n (keydown)=\"onPanelKeydown($event)\"\n >\n <ng-content />\n </div>\n}\n", styles: [":host{display:contents}.mk-menu__panel{min-width:12rem;max-width:min(20rem,100vw - var(--mk-space-4));max-height:calc(100vh - var(--mk-space-8));max-height:calc(100dvh - var(--mk-space-8));overflow-y:auto;overscroll-behavior:contain;padding:var(--mk-space-1);background:var(--mk-surface);border:var(--mk-border-width) solid var(--mk-border);border-radius:var(--mk-radius-lg);box-shadow:var(--mk-shadow-lg);animation:mk-menu-in var(--mk-duration-fast) var(--mk-ease-out)}@keyframes mk-menu-in{0%{opacity:0;transform:translateY(calc(-1 * var(--mk-space-1))) scale(.98)}to{opacity:1;transform:none}}@media(prefers-reduced-motion:reduce){.mk-menu__panel{animation:none}}\n"], dependencies: [{ kind: "directive", type: MkAnchoredPanel, selector: "[mkAnchoredPanel]", inputs: ["mkAnchoredPanelFor", "anchorRect", "placement", "gap", "matchWidth", "flip", "clamp"], outputs: ["dismiss"], exportAs: ["mkAnchoredPanel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
922
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: MkMenu, isStandalone: true, selector: "mk-menu", host: { classAttribute: "mk-menu" }, queries: [{ propertyName: "items", predicate: MkMenuItem, isSignal: true }], viewQueries: [{ propertyName: "panelRef", first: true, predicate: ["panel"], descendants: true, isSignal: true }], exportAs: ["mkMenu"], ngImport: i0, template: "@if (opened()) {\n <div\n #panel\n class=\"mk-menu__panel\"\n [class.mk-menu__panel--submenu]=\"isSubmenu\"\n role=\"menu\"\n [id]=\"panelId\"\n mkAnchoredPanel\n [mkAnchoredPanelFor]=\"anchorEl()\"\n [anchorRect]=\"anchorPoint()\"\n [placement]=\"placement()\"\n [keepOpenWhen]=\"keepOpenWhen\"\n (dismiss)=\"close(false)\"\n [attr.aria-label]=\"ariaLabel()\"\n (keydown)=\"onPanelKeydown($event)\"\n >\n <ng-content />\n </div>\n}\n", styles: [":host{display:contents}.mk-menu__panel{min-width:12rem;max-width:min(20rem,100vw - var(--mk-space-4));max-height:calc(100vh - var(--mk-space-8));max-height:calc(100dvh - var(--mk-space-8));overflow-y:auto;overscroll-behavior:contain;padding:var(--mk-space-1);background:var(--mk-surface);border:var(--mk-border-width) solid var(--mk-border);border-radius:var(--mk-radius-lg);box-shadow:var(--mk-shadow-lg);animation:mk-menu-in var(--mk-duration-fast) var(--mk-ease-out)}@keyframes mk-menu-in{0%{opacity:0;transform:translateY(calc(-1 * var(--mk-space-1))) scale(.98)}to{opacity:1;transform:none}}@media(prefers-reduced-motion:reduce){.mk-menu__panel{animation:none}}.mk-menu__panel--submenu{animation-name:mk-menu-fade}@keyframes mk-menu-fade{0%{opacity:0}to{opacity:1}}\n"], dependencies: [{ kind: "directive", type: MkAnchoredPanel, selector: "[mkAnchoredPanel]", inputs: ["mkAnchoredPanelFor", "anchorRect", "placement", "gap", "matchWidth", "flip", "clamp", "keepOpenWhen"], outputs: ["dismiss"], exportAs: ["mkAnchoredPanel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
724
923
  }
725
924
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkMenu, decorators: [{
726
925
  type: Component,
727
926
  args: [{ selector: 'mk-menu', exportAs: 'mkMenu', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MkAnchoredPanel], host: {
728
927
  class: 'mk-menu',
729
- }, template: "@if (opened()) {\n <div\n class=\"mk-menu__panel\"\n role=\"menu\"\n [id]=\"panelId\"\n mkAnchoredPanel\n [mkAnchoredPanelFor]=\"anchorEl()\"\n [anchorRect]=\"anchorPoint()\"\n placement=\"bottom-start\"\n (dismiss)=\"close(false)\"\n [attr.aria-label]=\"ariaLabel()\"\n (keydown)=\"onPanelKeydown($event)\"\n >\n <ng-content />\n </div>\n}\n", styles: [":host{display:contents}.mk-menu__panel{min-width:12rem;max-width:min(20rem,100vw - var(--mk-space-4));max-height:calc(100vh - var(--mk-space-8));max-height:calc(100dvh - var(--mk-space-8));overflow-y:auto;overscroll-behavior:contain;padding:var(--mk-space-1);background:var(--mk-surface);border:var(--mk-border-width) solid var(--mk-border);border-radius:var(--mk-radius-lg);box-shadow:var(--mk-shadow-lg);animation:mk-menu-in var(--mk-duration-fast) var(--mk-ease-out)}@keyframes mk-menu-in{0%{opacity:0;transform:translateY(calc(-1 * var(--mk-space-1))) scale(.98)}to{opacity:1;transform:none}}@media(prefers-reduced-motion:reduce){.mk-menu__panel{animation:none}}\n"] }]
730
- }], propDecorators: { items: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => MkMenuItem), { isSignal: true }] }] } });
928
+ }, template: "@if (opened()) {\n <div\n #panel\n class=\"mk-menu__panel\"\n [class.mk-menu__panel--submenu]=\"isSubmenu\"\n role=\"menu\"\n [id]=\"panelId\"\n mkAnchoredPanel\n [mkAnchoredPanelFor]=\"anchorEl()\"\n [anchorRect]=\"anchorPoint()\"\n [placement]=\"placement()\"\n [keepOpenWhen]=\"keepOpenWhen\"\n (dismiss)=\"close(false)\"\n [attr.aria-label]=\"ariaLabel()\"\n (keydown)=\"onPanelKeydown($event)\"\n >\n <ng-content />\n </div>\n}\n", styles: [":host{display:contents}.mk-menu__panel{min-width:12rem;max-width:min(20rem,100vw - var(--mk-space-4));max-height:calc(100vh - var(--mk-space-8));max-height:calc(100dvh - var(--mk-space-8));overflow-y:auto;overscroll-behavior:contain;padding:var(--mk-space-1);background:var(--mk-surface);border:var(--mk-border-width) solid var(--mk-border);border-radius:var(--mk-radius-lg);box-shadow:var(--mk-shadow-lg);animation:mk-menu-in var(--mk-duration-fast) var(--mk-ease-out)}@keyframes mk-menu-in{0%{opacity:0;transform:translateY(calc(-1 * var(--mk-space-1))) scale(.98)}to{opacity:1;transform:none}}@media(prefers-reduced-motion:reduce){.mk-menu__panel{animation:none}}.mk-menu__panel--submenu{animation-name:mk-menu-fade}@keyframes mk-menu-fade{0%{opacity:0}to{opacity:1}}\n"] }]
929
+ }], propDecorators: { items: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => MkMenuItem), { isSignal: true }] }], panelRef: [{ type: i0.ViewChild, args: ['panel', { isSignal: true }] }] } });
731
930
 
732
931
  /**
733
932
  * Turns its host button into a trigger for an `<mk-menu>`. Wires
@@ -802,6 +1001,76 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
802
1001
  }]
803
1002
  }], propDecorators: { menu: [{ type: i0.Input, args: [{ isSignal: true, alias: "mkMenuTriggerFor", required: true }] }] } });
804
1003
 
1004
+ /**
1005
+ * SplitButton — a primary action with an attached menu of alternatives.
1006
+ * The main segment emits `action`; the chevron segment is a menu button
1007
+ * (`mkMenuTriggerFor`) for the `mk-menu` passed in `[menu]`, with the full
1008
+ * keyboard model of the menu trigger (ArrowDown / Enter / Space open and focus
1009
+ * the first item, ArrowUp the last, Escape closes).
1010
+ *
1011
+ * Both segments share `variant`, `tone` and `size`; `disabled` disables both,
1012
+ * `loading` shows the main segment's spinner and disables the chevron.
1013
+ *
1014
+ * ```html
1015
+ * <mk-split-button [menu]="saveMenu" tone="primary" (action)="save()">
1016
+ * Save
1017
+ * </mk-split-button>
1018
+ * <mk-menu #saveMenu>
1019
+ * <mk-menu-item (action)="saveAs()">Save as…</mk-menu-item>
1020
+ * <mk-menu-item (action)="saveTemplate()">Save as template</mk-menu-item>
1021
+ * </mk-menu>
1022
+ * ```
1023
+ */
1024
+ class MkSplitButton {
1025
+ i18n = inject(MK_I18N);
1026
+ /** The menu the chevron segment opens. */
1027
+ menu = input.required(/* @ts-ignore */
1028
+ ...(ngDevMode ? [{ debugName: "menu" }] : /* istanbul ignore next */ []));
1029
+ /** Visual treatment shared by both segments. */
1030
+ variant = input('solid', /* @ts-ignore */
1031
+ ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
1032
+ /** Semantic color tone shared by both segments. */
1033
+ tone = input('primary', /* @ts-ignore */
1034
+ ...(ngDevMode ? [{ debugName: "tone" }] : /* istanbul ignore next */ []));
1035
+ /** Control size shared by both segments. */
1036
+ size = input('md', /* @ts-ignore */
1037
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
1038
+ /** Disable both segments. */
1039
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1040
+ /** Spinner on the main segment; the menu segment is disabled meanwhile. */
1041
+ loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1042
+ /** Stretch to the container width (the main segment grows). */
1043
+ fullWidth = input(false, { ...(ngDevMode ? { debugName: "fullWidth" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1044
+ /** `type` of the main segment — `submit` to submit the enclosing form. */
1045
+ type = input('button', /* @ts-ignore */
1046
+ ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
1047
+ /** Accessible name of the chevron segment. */
1048
+ menuLabel = input(this.i18n.moreActions, /* @ts-ignore */
1049
+ ...(ngDevMode ? [{ debugName: "menuLabel" }] : /* istanbul ignore next */ []));
1050
+ /** Emitted when the main segment is activated (not while disabled/loading). */
1051
+ action = output();
1052
+ menuDisabled = computed(() => this.disabled() || this.loading(), /* @ts-ignore */
1053
+ ...(ngDevMode ? [{ debugName: "menuDisabled" }] : /* istanbul ignore next */ []));
1054
+ onMain() {
1055
+ if (this.disabled() || this.loading())
1056
+ return;
1057
+ this.action.emit();
1058
+ }
1059
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkSplitButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
1060
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.7", type: MkSplitButton, isStandalone: true, selector: "mk-split-button", inputs: { menu: { classPropertyName: "menu", publicName: "menu", isSignal: true, isRequired: true, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, menuLabel: { classPropertyName: "menuLabel", publicName: "menuLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, host: { attributes: { "role": "group" }, properties: { "class.mk-split-button--block": "fullWidth()", "class.mk-split-button--sm": "size() === 'sm'", "class.mk-split-button--lg": "size() === 'lg'", "class.mk-split-button--outline": "variant() === 'outline'" }, classAttribute: "mk-split-button" }, ngImport: i0, template: "<button\n mkButton\n class=\"mk-split-button__main\"\n [type]=\"type()\"\n [variant]=\"variant()\"\n [tone]=\"tone()\"\n [size]=\"size()\"\n [disabled]=\"disabled()\"\n [loading]=\"loading()\"\n (click)=\"onMain()\"\n>\n <ng-content />\n</button>\n<button\n mkButton\n class=\"mk-split-button__toggle\"\n type=\"button\"\n iconOnly\n [variant]=\"variant()\"\n [tone]=\"tone()\"\n [size]=\"size()\"\n [disabled]=\"menuDisabled()\"\n [mkMenuTriggerFor]=\"menu()\"\n [attr.aria-label]=\"menuLabel()\"\n>\n <svg\n class=\"mk-split-button__chevron\"\n viewBox=\"0 0 16 16\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.75\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M3.5 6 8 10.5 12.5 6\" />\n </svg>\n</button>\n", styles: [":host{display:inline-flex;align-items:stretch;vertical-align:middle;max-width:100%}:host(.mk-split-button--block){display:flex;width:100%}:host .mk-split-button__main{border-start-end-radius:0;border-end-end-radius:0}:host(.mk-split-button--block) .mk-split-button__main{flex:1 1 auto;min-width:0}:host .mk-split-button__toggle{border-start-start-radius:0;border-end-start-radius:0;box-shadow:inset 1px 0 color-mix(in srgb,currentColor 28%,transparent)}:host(:dir(rtl)) .mk-split-button__toggle{box-shadow:inset -1px 0 color-mix(in srgb,currentColor 28%,transparent)}:host(.mk-split-button--outline) .mk-split-button__toggle{margin-inline-start:calc(-1 * var(--mk-border-width));box-shadow:none}:host .mk-split-button__main:focus-visible,:host .mk-split-button__toggle:focus-visible{position:relative;z-index:1}.mk-split-button__chevron{transition:transform var(--mk-duration-fast) var(--mk-ease-standard)}:host .mk-split-button__toggle[aria-expanded=true] .mk-split-button__chevron{transform:rotate(180deg)}@media(prefers-reduced-motion:reduce){.mk-split-button__chevron{transition:none}}\n"], dependencies: [{ kind: "component", type: MkButton, selector: "button[mkButton], a[mkButton]", inputs: ["variant", "tone", "size", "loading", "fullWidth", "iconOnly", "disabled"] }, { kind: "directive", type: MkMenuTrigger, selector: "[mkMenuTriggerFor]", inputs: ["mkMenuTriggerFor"], exportAs: ["mkMenuTrigger"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1061
+ }
1062
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkSplitButton, decorators: [{
1063
+ type: Component,
1064
+ args: [{ selector: 'mk-split-button', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MkButton, MkMenuTrigger], host: {
1065
+ class: 'mk-split-button',
1066
+ role: 'group',
1067
+ '[class.mk-split-button--block]': 'fullWidth()',
1068
+ '[class.mk-split-button--sm]': "size() === 'sm'",
1069
+ '[class.mk-split-button--lg]': "size() === 'lg'",
1070
+ '[class.mk-split-button--outline]': "variant() === 'outline'",
1071
+ }, template: "<button\n mkButton\n class=\"mk-split-button__main\"\n [type]=\"type()\"\n [variant]=\"variant()\"\n [tone]=\"tone()\"\n [size]=\"size()\"\n [disabled]=\"disabled()\"\n [loading]=\"loading()\"\n (click)=\"onMain()\"\n>\n <ng-content />\n</button>\n<button\n mkButton\n class=\"mk-split-button__toggle\"\n type=\"button\"\n iconOnly\n [variant]=\"variant()\"\n [tone]=\"tone()\"\n [size]=\"size()\"\n [disabled]=\"menuDisabled()\"\n [mkMenuTriggerFor]=\"menu()\"\n [attr.aria-label]=\"menuLabel()\"\n>\n <svg\n class=\"mk-split-button__chevron\"\n viewBox=\"0 0 16 16\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.75\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M3.5 6 8 10.5 12.5 6\" />\n </svg>\n</button>\n", styles: [":host{display:inline-flex;align-items:stretch;vertical-align:middle;max-width:100%}:host(.mk-split-button--block){display:flex;width:100%}:host .mk-split-button__main{border-start-end-radius:0;border-end-end-radius:0}:host(.mk-split-button--block) .mk-split-button__main{flex:1 1 auto;min-width:0}:host .mk-split-button__toggle{border-start-start-radius:0;border-end-start-radius:0;box-shadow:inset 1px 0 color-mix(in srgb,currentColor 28%,transparent)}:host(:dir(rtl)) .mk-split-button__toggle{box-shadow:inset -1px 0 color-mix(in srgb,currentColor 28%,transparent)}:host(.mk-split-button--outline) .mk-split-button__toggle{margin-inline-start:calc(-1 * var(--mk-border-width));box-shadow:none}:host .mk-split-button__main:focus-visible,:host .mk-split-button__toggle:focus-visible{position:relative;z-index:1}.mk-split-button__chevron{transition:transform var(--mk-duration-fast) var(--mk-ease-standard)}:host .mk-split-button__toggle[aria-expanded=true] .mk-split-button__chevron{transform:rotate(180deg)}@media(prefers-reduced-motion:reduce){.mk-split-button__chevron{transition:none}}\n"] }]
1072
+ }], propDecorators: { menu: [{ type: i0.Input, args: [{ isSignal: true, alias: "menu", required: true }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], menuLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuLabel", required: false }] }], action: [{ type: i0.Output, args: ["action"] }] } });
1073
+
805
1074
  /** Viewport width (px) at/below which the sidebar becomes an off-canvas drawer. */
806
1075
  const MOBILE_BREAKPOINT = 1024;
807
1076
  /**
@@ -1684,7 +1953,7 @@ class MkToolbar {
1684
1953
  /** Accessible name (also promotes the bar to an ARIA `group`). */
1685
1954
  ariaLabel = input('', { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
1686
1955
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkToolbar, deps: [], target: i0.ɵɵFactoryTarget.Component });
1687
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.7", type: MkToolbar, isStandalone: true, selector: "mk-toolbar", inputs: { bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.mk-toolbar--bordered": "bordered()", "attr.role": "ariaLabel() ? 'group' : null", "attr.aria-label": "ariaLabel() || null" }, classAttribute: "mk-toolbar" }, ngImport: i0, template: "<div class=\"mk-toolbar__start\">\n <ng-content />\n</div>\n<div class=\"mk-toolbar__end\">\n <ng-content select=\"[mkToolbarEnd]\" />\n</div>\n", styles: [":host{display:flex;align-items:center;gap:var(--mk-space-2);padding:var(--mk-space-2) var(--mk-space-3);font-family:var(--mk-font-sans);color:var(--mk-text)}:host(.mk-toolbar--bordered){background-color:var(--mk-surface);border:var(--mk-border-width) solid var(--mk-border-subtle);border-radius:var(--mk-radius-md)}.mk-toolbar__start{display:flex;align-items:center;gap:var(--mk-space-2);flex:1 1 auto;min-width:0;flex-wrap:wrap}.mk-toolbar__end{display:flex;align-items:center;gap:var(--mk-space-2);flex:none}.mk-toolbar__end:empty{display:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1956
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.7", type: MkToolbar, isStandalone: true, selector: "mk-toolbar", inputs: { bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.mk-toolbar--bordered": "bordered()", "attr.role": "ariaLabel() ? 'group' : null", "attr.aria-label": "ariaLabel() || null" }, classAttribute: "mk-toolbar" }, ngImport: i0, template: "<div class=\"mk-toolbar__start\">\n <ng-content />\n</div>\n<div class=\"mk-toolbar__end\">\n <ng-content select=\"[mkToolbarEnd]\" />\n</div>\n", styles: [":host{display:flex;align-items:center;gap:var(--mk-space-2);padding:var(--mk-space-2) var(--mk-space-3);font-family:var(--mk-font-sans);color:var(--mk-text)}:host(.mk-toolbar--bordered){background-color:var(--mk-surface);border:var(--mk-border-width) solid var(--mk-border-subtle);border-radius:var(--mk-radius-md)}.mk-toolbar__start{display:flex;align-items:center;gap:var(--mk-space-2);flex:1 1 auto;min-width:0;flex-wrap:wrap}.mk-toolbar__end{display:flex;align-items:center;gap:var(--mk-space-2);flex:none}:host ::ng-deep [mkToolbarEnd]{display:inline-flex;align-items:center;gap:var(--mk-space-2)}.mk-toolbar__end:empty{display:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1688
1957
  }
1689
1958
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkToolbar, decorators: [{
1690
1959
  type: Component,
@@ -1693,7 +1962,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
1693
1962
  '[class.mk-toolbar--bordered]': 'bordered()',
1694
1963
  '[attr.role]': "ariaLabel() ? 'group' : null",
1695
1964
  '[attr.aria-label]': 'ariaLabel() || null',
1696
- }, template: "<div class=\"mk-toolbar__start\">\n <ng-content />\n</div>\n<div class=\"mk-toolbar__end\">\n <ng-content select=\"[mkToolbarEnd]\" />\n</div>\n", styles: [":host{display:flex;align-items:center;gap:var(--mk-space-2);padding:var(--mk-space-2) var(--mk-space-3);font-family:var(--mk-font-sans);color:var(--mk-text)}:host(.mk-toolbar--bordered){background-color:var(--mk-surface);border:var(--mk-border-width) solid var(--mk-border-subtle);border-radius:var(--mk-radius-md)}.mk-toolbar__start{display:flex;align-items:center;gap:var(--mk-space-2);flex:1 1 auto;min-width:0;flex-wrap:wrap}.mk-toolbar__end{display:flex;align-items:center;gap:var(--mk-space-2);flex:none}.mk-toolbar__end:empty{display:none}\n"] }]
1965
+ }, template: "<div class=\"mk-toolbar__start\">\n <ng-content />\n</div>\n<div class=\"mk-toolbar__end\">\n <ng-content select=\"[mkToolbarEnd]\" />\n</div>\n", styles: [":host{display:flex;align-items:center;gap:var(--mk-space-2);padding:var(--mk-space-2) var(--mk-space-3);font-family:var(--mk-font-sans);color:var(--mk-text)}:host(.mk-toolbar--bordered){background-color:var(--mk-surface);border:var(--mk-border-width) solid var(--mk-border-subtle);border-radius:var(--mk-radius-md)}.mk-toolbar__start{display:flex;align-items:center;gap:var(--mk-space-2);flex:1 1 auto;min-width:0;flex-wrap:wrap}.mk-toolbar__end{display:flex;align-items:center;gap:var(--mk-space-2);flex:none}:host ::ng-deep [mkToolbarEnd]{display:inline-flex;align-items:center;gap:var(--mk-space-2)}.mk-toolbar__end:empty{display:none}\n"] }]
1697
1966
  }], propDecorators: { bordered: [{ type: i0.Input, args: [{ isSignal: true, alias: "bordered", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }] } });
1698
1967
 
1699
1968
  /**
@@ -1725,11 +1994,11 @@ class MkPageHeader {
1725
1994
  description = input('', /* @ts-ignore */
1726
1995
  ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
1727
1996
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkPageHeader, deps: [], target: i0.ɵɵFactoryTarget.Component });
1728
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: MkPageHeader, isStandalone: true, selector: "mk-page-header", inputs: { heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "mk-page-header" }, ngImport: i0, template: "<div class=\"mk-page-header__breadcrumb\">\n <ng-content select=\"[mkPageHeaderBreadcrumb]\" />\n</div>\n\n<div class=\"mk-page-header__main\">\n <div class=\"mk-page-header__media\">\n <ng-content select=\"[mkPageHeaderMedia]\" />\n </div>\n <div class=\"mk-page-header__heading\">\n <div class=\"mk-page-header__title-row\">\n @if (heading(); as h) {\n <h1 class=\"mk-page-header__title\">{{ h }}</h1>\n }\n <div class=\"mk-page-header__meta\">\n <ng-content select=\"[mkPageHeaderMeta]\" />\n </div>\n </div>\n @if (description(); as d) {\n <p class=\"mk-page-header__description\">{{ d }}</p>\n }\n </div>\n\n <div class=\"mk-page-header__actions\">\n <ng-content select=\"[mkPageHeaderActions]\" />\n </div>\n</div>\n\n<div class=\"mk-page-header__tabs\">\n <ng-content select=\"[mkPageHeaderTabs]\" />\n</div>\n", styles: [":host{display:block;font-family:var(--mk-font-sans);color:var(--mk-text)}.mk-page-header__breadcrumb{margin-bottom:var(--mk-space-2)}.mk-page-header__breadcrumb:empty{display:none}.mk-page-header__main{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--mk-space-4);flex-wrap:wrap}.mk-page-header__heading{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:var(--mk-space-1)}.mk-page-header__title-row{display:flex;align-items:center;gap:var(--mk-space-3);flex-wrap:wrap}.mk-page-header__title{margin:0;font-size:var(--mk-font-size-2xl);font-weight:var(--mk-font-weight-bold);line-height:var(--mk-line-height-tight);letter-spacing:var(--mk-letter-spacing-tight);color:var(--mk-text)}.mk-page-header__meta{display:inline-flex;align-items:center;gap:var(--mk-space-2)}.mk-page-header__meta:empty{display:none}.mk-page-header__description{margin:0;max-width:68ch;font-size:var(--mk-font-size-md);line-height:var(--mk-line-height-normal);color:var(--mk-text-muted)}.mk-page-header__actions{flex:none;display:flex;align-items:center;gap:var(--mk-space-2);flex-wrap:wrap}.mk-page-header__actions:empty{display:none}.mk-page-header__tabs{margin-top:var(--mk-space-4)}.mk-page-header__tabs:empty{display:none}.mk-page-header__media{display:flex;align-items:center;flex-shrink:0}.mk-page-header__media:empty{display:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1997
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: MkPageHeader, isStandalone: true, selector: "mk-page-header", inputs: { heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "mk-page-header" }, ngImport: i0, template: "<div class=\"mk-page-header__breadcrumb\">\n <ng-content select=\"[mkPageHeaderBreadcrumb]\" />\n</div>\n\n<div class=\"mk-page-header__main\">\n <div class=\"mk-page-header__media\">\n <ng-content select=\"[mkPageHeaderMedia]\" />\n </div>\n <div class=\"mk-page-header__heading\">\n <div class=\"mk-page-header__title-row\">\n @if (heading(); as h) {\n <h1 class=\"mk-page-header__title\">{{ h }}</h1>\n }\n <div class=\"mk-page-header__meta\">\n <ng-content select=\"[mkPageHeaderMeta]\" />\n </div>\n </div>\n @if (description(); as d) {\n <p class=\"mk-page-header__description\">{{ d }}</p>\n }\n </div>\n\n <div class=\"mk-page-header__actions\">\n <ng-content select=\"[mkPageHeaderActions]\" />\n </div>\n</div>\n\n<div class=\"mk-page-header__tabs\">\n <ng-content select=\"[mkPageHeaderTabs]\" />\n</div>\n", styles: [":host{display:block;font-family:var(--mk-font-sans);color:var(--mk-text)}.mk-page-header__breadcrumb{margin-bottom:var(--mk-space-2)}.mk-page-header__breadcrumb:empty{display:none}.mk-page-header__main{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--mk-space-4);flex-wrap:wrap}.mk-page-header__heading{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:var(--mk-space-1)}.mk-page-header__title-row{display:flex;align-items:center;gap:var(--mk-space-3);flex-wrap:wrap}.mk-page-header__title{margin:0;font-size:var(--mk-font-size-2xl);font-weight:var(--mk-font-weight-bold);line-height:var(--mk-line-height-tight);letter-spacing:var(--mk-letter-spacing-tight);color:var(--mk-text)}.mk-page-header__meta{display:inline-flex;align-items:center;gap:var(--mk-space-2)}.mk-page-header__meta:empty{display:none}.mk-page-header__description{margin:0;max-width:68ch;font-size:var(--mk-font-size-md);line-height:var(--mk-line-height-normal);color:var(--mk-text-muted)}.mk-page-header__actions{flex:none;display:flex;align-items:center;gap:var(--mk-space-2);flex-wrap:wrap}.mk-page-header__actions:empty{display:none}:host ::ng-deep [mkPageHeaderActions]{display:inline-flex;align-items:center;gap:var(--mk-space-2);flex-wrap:wrap}.mk-page-header__tabs{margin-top:var(--mk-space-4)}.mk-page-header__tabs:empty{display:none}.mk-page-header__media{display:flex;align-items:center;flex-shrink:0}.mk-page-header__media:empty{display:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1729
1998
  }
1730
1999
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkPageHeader, decorators: [{
1731
2000
  type: Component,
1732
- args: [{ selector: 'mk-page-header', changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'mk-page-header' }, template: "<div class=\"mk-page-header__breadcrumb\">\n <ng-content select=\"[mkPageHeaderBreadcrumb]\" />\n</div>\n\n<div class=\"mk-page-header__main\">\n <div class=\"mk-page-header__media\">\n <ng-content select=\"[mkPageHeaderMedia]\" />\n </div>\n <div class=\"mk-page-header__heading\">\n <div class=\"mk-page-header__title-row\">\n @if (heading(); as h) {\n <h1 class=\"mk-page-header__title\">{{ h }}</h1>\n }\n <div class=\"mk-page-header__meta\">\n <ng-content select=\"[mkPageHeaderMeta]\" />\n </div>\n </div>\n @if (description(); as d) {\n <p class=\"mk-page-header__description\">{{ d }}</p>\n }\n </div>\n\n <div class=\"mk-page-header__actions\">\n <ng-content select=\"[mkPageHeaderActions]\" />\n </div>\n</div>\n\n<div class=\"mk-page-header__tabs\">\n <ng-content select=\"[mkPageHeaderTabs]\" />\n</div>\n", styles: [":host{display:block;font-family:var(--mk-font-sans);color:var(--mk-text)}.mk-page-header__breadcrumb{margin-bottom:var(--mk-space-2)}.mk-page-header__breadcrumb:empty{display:none}.mk-page-header__main{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--mk-space-4);flex-wrap:wrap}.mk-page-header__heading{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:var(--mk-space-1)}.mk-page-header__title-row{display:flex;align-items:center;gap:var(--mk-space-3);flex-wrap:wrap}.mk-page-header__title{margin:0;font-size:var(--mk-font-size-2xl);font-weight:var(--mk-font-weight-bold);line-height:var(--mk-line-height-tight);letter-spacing:var(--mk-letter-spacing-tight);color:var(--mk-text)}.mk-page-header__meta{display:inline-flex;align-items:center;gap:var(--mk-space-2)}.mk-page-header__meta:empty{display:none}.mk-page-header__description{margin:0;max-width:68ch;font-size:var(--mk-font-size-md);line-height:var(--mk-line-height-normal);color:var(--mk-text-muted)}.mk-page-header__actions{flex:none;display:flex;align-items:center;gap:var(--mk-space-2);flex-wrap:wrap}.mk-page-header__actions:empty{display:none}.mk-page-header__tabs{margin-top:var(--mk-space-4)}.mk-page-header__tabs:empty{display:none}.mk-page-header__media{display:flex;align-items:center;flex-shrink:0}.mk-page-header__media:empty{display:none}\n"] }]
2001
+ args: [{ selector: 'mk-page-header', changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'mk-page-header' }, template: "<div class=\"mk-page-header__breadcrumb\">\n <ng-content select=\"[mkPageHeaderBreadcrumb]\" />\n</div>\n\n<div class=\"mk-page-header__main\">\n <div class=\"mk-page-header__media\">\n <ng-content select=\"[mkPageHeaderMedia]\" />\n </div>\n <div class=\"mk-page-header__heading\">\n <div class=\"mk-page-header__title-row\">\n @if (heading(); as h) {\n <h1 class=\"mk-page-header__title\">{{ h }}</h1>\n }\n <div class=\"mk-page-header__meta\">\n <ng-content select=\"[mkPageHeaderMeta]\" />\n </div>\n </div>\n @if (description(); as d) {\n <p class=\"mk-page-header__description\">{{ d }}</p>\n }\n </div>\n\n <div class=\"mk-page-header__actions\">\n <ng-content select=\"[mkPageHeaderActions]\" />\n </div>\n</div>\n\n<div class=\"mk-page-header__tabs\">\n <ng-content select=\"[mkPageHeaderTabs]\" />\n</div>\n", styles: [":host{display:block;font-family:var(--mk-font-sans);color:var(--mk-text)}.mk-page-header__breadcrumb{margin-bottom:var(--mk-space-2)}.mk-page-header__breadcrumb:empty{display:none}.mk-page-header__main{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--mk-space-4);flex-wrap:wrap}.mk-page-header__heading{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:var(--mk-space-1)}.mk-page-header__title-row{display:flex;align-items:center;gap:var(--mk-space-3);flex-wrap:wrap}.mk-page-header__title{margin:0;font-size:var(--mk-font-size-2xl);font-weight:var(--mk-font-weight-bold);line-height:var(--mk-line-height-tight);letter-spacing:var(--mk-letter-spacing-tight);color:var(--mk-text)}.mk-page-header__meta{display:inline-flex;align-items:center;gap:var(--mk-space-2)}.mk-page-header__meta:empty{display:none}.mk-page-header__description{margin:0;max-width:68ch;font-size:var(--mk-font-size-md);line-height:var(--mk-line-height-normal);color:var(--mk-text-muted)}.mk-page-header__actions{flex:none;display:flex;align-items:center;gap:var(--mk-space-2);flex-wrap:wrap}.mk-page-header__actions:empty{display:none}:host ::ng-deep [mkPageHeaderActions]{display:inline-flex;align-items:center;gap:var(--mk-space-2);flex-wrap:wrap}.mk-page-header__tabs{margin-top:var(--mk-space-4)}.mk-page-header__tabs:empty{display:none}.mk-page-header__media{display:flex;align-items:center;flex-shrink:0}.mk-page-header__media:empty{display:none}\n"] }]
1733
2002
  }], propDecorators: { heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }] } });
1734
2003
 
1735
2004
  /**
@@ -2538,5 +2807,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
2538
2807
  * Generated bundle index. Do not edit.
2539
2808
  */
2540
2809
 
2541
- export { MkAccordion, MkAccordionHeader, MkAccordionItem, MkAppShell, MkBackToTop, MkBreadcrumb, MkBreadcrumbItem, MkCommandPalette, MkDrawer, MkFab, MkFabAction, MkMenu, MkMenuItem, MkMenuTrigger, MkNavGroup, MkNavItem, MkNavList, MkPageHeader, MkPagination, MkScrollArea, MkSplitter, MkStep, MkStepper, MkTab, MkTabs, MkToolbar, MkTree };
2810
+ export { MkAccordion, MkAccordionHeader, MkAccordionItem, MkAppShell, MkBackToTop, MkBreadcrumb, MkBreadcrumbItem, MkCommandPalette, MkDrawer, MkFab, MkFabAction, MkMenu, MkMenuItem, MkMenuTrigger, MkNavGroup, MkNavItem, MkNavList, MkPageHeader, MkPagination, MkScrollArea, MkSplitButton, MkSplitter, MkStep, MkStepper, MkTab, MkTabs, MkToolbar, MkTree };
2542
2811
  //# sourceMappingURL=mk-kit-ui-navigation.mjs.map