@coreui/angular 5.7.34 → 5.7.35

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.
@@ -8,7 +8,7 @@ import { ActivatedRoute, NavigationEnd, Router, RouterLink, RouterModule } from
8
8
  import { debounceTime, filter, finalize, tap, withLatestFrom, zipWith } from "rxjs/operators";
9
9
  import { createPopper } from "@popperjs/core";
10
10
  import * as i1 from "@angular/cdk/a11y";
11
- import { A11yModule, FocusKeyManager, FocusMonitor } from "@angular/cdk/a11y";
11
+ import { A11yModule, CdkTrapFocus, FocusKeyManager } from "@angular/cdk/a11y";
12
12
  import { BreakpointObserver } from "@angular/cdk/layout";
13
13
  import { DomPortal, DomPortalOutlet } from "@angular/cdk/portal";
14
14
  import { IconDirective } from "@coreui/icons-angular";
@@ -5733,8 +5733,24 @@ i0.ɵɵngDeclareClassMetadata({
5733
5733
  args: [{ providedIn: "root" }]
5734
5734
  }]
5735
5735
  });
5736
+ const REPLAY_EVENT_PHASE = 101;
5737
+ const isReplayedEvent = (event) => event.eventPhase === REPLAY_EVENT_PHASE;
5738
+ const FORM_CONTROL_SELECTOR = "input:not([type=\"button\"]):not([type=\"image\"]):not([type=\"reset\"]):not([type=\"submit\"]), select, textarea";
5739
+ const isEditableTarget$1 = (target) => {
5740
+ if (!(target instanceof Element)) return false;
5741
+ if (target.closest(FORM_CONTROL_SELECTOR)) return true;
5742
+ for (let host = target.closest("[contenteditable]"); host; host = host.parentElement?.closest("[contenteditable]") ?? null) {
5743
+ const value = host.getAttribute("contenteditable")?.toLowerCase();
5744
+ if (value === "" || value === "true" || value === "plaintext-only") return true;
5745
+ if (value === "false") return false;
5746
+ }
5747
+ return false;
5748
+ };
5749
+ const clicksOnEnter = (element) => element instanceof HTMLButtonElement || element instanceof HTMLInputElement && /^(button|image|reset|submit)$/.test(element.type) || element instanceof HTMLAnchorElement && element.hasAttribute("href") || element.tagName === "SUMMARY";
5750
+ const clicksOnSpace = (element) => element instanceof HTMLButtonElement || element instanceof HTMLInputElement && /^(button|checkbox|image|radio|reset|submit)$/.test(element.type) || element.tagName === "SUMMARY";
5736
5751
  var DropdownMenuDirective = class DropdownMenuDirective {
5737
5752
  #destroyRef = inject(DestroyRef);
5753
+ #injector = inject(Injector);
5738
5754
  elementRef = inject(ElementRef);
5739
5755
  #dropdownService = inject(DropdownService);
5740
5756
  #focusKeyManager;
@@ -5766,16 +5782,13 @@ var DropdownMenuDirective = class DropdownMenuDirective {
5766
5782
  }, ...ngDevMode ? [{ debugName: "hostStyles" }] : /* istanbul ignore next */ []);
5767
5783
  dataPopper = computed(() => this.#dropdownService.popper() ? null : "static", ...ngDevMode ? [{ debugName: "dataPopper" }] : /* istanbul ignore next */ []);
5768
5784
  onKeyDown($event) {
5769
- if (!this.visible()) return;
5770
- if (["Space", "ArrowDown"].includes($event.code)) $event.preventDefault();
5785
+ if (!this.visible() || isReplayedEvent($event) || isEditableTarget$1($event.target)) return;
5786
+ if ($event.code === "ArrowDown" || $event.code === "Space" && !this.#clicksOnSpace($event.target)) $event.preventDefault();
5771
5787
  this.#focusKeyManager.onKeydown($event);
5772
5788
  }
5773
- onKeyUp($event) {
5774
- if (!this.visible()) return;
5775
- if (["Tab"].includes($event.key)) {
5776
- if (this.#focusKeyManager.activeItem) $event.shiftKey ? this.#focusKeyManager.setPreviousItemActive() : this.#focusKeyManager.setNextItemActive();
5777
- else this.#focusKeyManager.setFirstItemActive();
5778
- }
5789
+ onFocusIn($event) {
5790
+ const index = this.dropdownItemsContent().findIndex((item) => item.elementRef.nativeElement.contains($event.target));
5791
+ if (index > -1) this.#focusKeyManager.updateActiveItem(index);
5779
5792
  }
5780
5793
  dropdownItemsContent = contentChildren(forwardRef(() => DropdownItemDirective), {
5781
5794
  ...ngDevMode ? { debugName: "dropdownItemsContent" } : /* istanbul ignore next */ {},
@@ -5794,8 +5807,12 @@ var DropdownMenuDirective = class DropdownMenuDirective {
5794
5807
  this.visible.update((visible) => state.visible === "toggle" ? !visible : state.visible);
5795
5808
  if (!this.visible()) this.#focusKeyManager?.setActiveItem(-1);
5796
5809
  }
5810
+ if (state.focus && this.visible()) afterNextRender(() => state.focus === "first" ? this.#focusKeyManager.setFirstItemActive() : this.#focusKeyManager.setLastItemActive(), { injector: this.#injector });
5797
5811
  }), takeUntilDestroyed(this.#destroyRef)).subscribe();
5798
5812
  }
5813
+ #clicksOnSpace(target) {
5814
+ return target instanceof Element && clicksOnSpace(target);
5815
+ }
5799
5816
  focusKeyManagerInit() {
5800
5817
  this.#focusKeyManager = new FocusKeyManager(this.dropdownItemsContent()).withHomeAndEnd().withPageUpDown().withWrap().skipPredicate((dropdownItem) => dropdownItem.disabled === true);
5801
5818
  }
@@ -5831,8 +5848,8 @@ var DropdownMenuDirective = class DropdownMenuDirective {
5831
5848
  },
5832
5849
  host: {
5833
5850
  listeners: {
5834
- "keydown": "onKeyDown($event)",
5835
- "keyup": "onKeyUp($event)"
5851
+ "focusin": "onFocusIn($event)",
5852
+ "keydown": "onKeyDown($event)"
5836
5853
  },
5837
5854
  properties: {
5838
5855
  "class": "hostClasses()",
@@ -5874,8 +5891,8 @@ i0.ɵɵngDeclareClassMetadata({
5874
5891
  "[class]": "hostClasses()",
5875
5892
  "[style]": "hostStyles()",
5876
5893
  "[attr.data-coreui-popper]": "dataPopper()",
5877
- "(keydown)": "onKeyDown($event)",
5878
- "(keyup)": "onKeyUp($event)"
5894
+ "(focusin)": "onFocusIn($event)",
5895
+ "(keydown)": "onKeyDown($event)"
5879
5896
  }
5880
5897
  }]
5881
5898
  }],
@@ -5910,10 +5927,11 @@ const alignmentClasses = (alignment) => {
5910
5927
  if (typeof alignment === "string") return { [`dropdown-menu-${alignment}`]: true };
5911
5928
  return Object.fromEntries(Object.entries(alignment).map(([breakpoint, direction]) => [`dropdown-menu${breakpoint === BreakpointInfix.xs ? "" : `-${breakpoint}`}-${direction}`, true]));
5912
5929
  };
5930
+ const FOCUSABLE_SELECTOR = "a[href], button, input, select, textarea, [tabindex]";
5913
5931
  var DropdownToken = class {};
5914
5932
  var DropdownToggleDirective = class DropdownToggleDirective {
5915
- #destroyRef = inject(DestroyRef);
5916
5933
  elementRef = inject(ElementRef);
5934
+ #renderer = inject(Renderer2);
5917
5935
  #dropdownService = inject(DropdownService);
5918
5936
  dropdown = inject(DropdownToken, { optional: true });
5919
5937
  dropdownComponent = input(...ngDevMode ? [void 0, { debugName: "dropdownComponent" }] : /* istanbul ignore next */ []);
@@ -5933,30 +5951,46 @@ var DropdownToggleDirective = class DropdownToggleDirective {
5933
5951
  disabled: this.disabled()
5934
5952
  };
5935
5953
  }, ...ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []);
5936
- #ariaExpanded = signal(false, ...ngDevMode ? [{ debugName: "#ariaExpanded" }] : /* istanbul ignore next */ []);
5954
+ #ariaExpanded = computed(() => (this.dropdownComponent() ?? this.dropdown)?.visible() ?? false, ...ngDevMode ? [{ debugName: "#ariaExpanded" }] : /* istanbul ignore next */ []);
5937
5955
  get ariaExpanded() {
5938
5956
  return this.#ariaExpanded();
5939
5957
  }
5940
5958
  onClick($event) {
5941
5959
  $event.preventDefault();
5942
- !this.disabled() && this.#dropdownService.toggle({
5960
+ if (this.disabled()) return;
5961
+ const element = this.elementRef.nativeElement;
5962
+ if (!element.contains(element.ownerDocument.activeElement)) element.focus();
5963
+ this.#dropdownService.toggle({
5943
5964
  visible: "toggle",
5944
5965
  dropdown: this.dropdown
5945
5966
  });
5946
5967
  }
5968
+ onKeyDown($event) {
5969
+ if (this.disabled() || isReplayedEvent($event) || isEditableTarget$1($event.target)) return;
5970
+ const element = this.elementRef.nativeElement;
5971
+ if ($event.target === element && element.tagName === "A" && ($event.key === " " || $event.key === "Enter" && !clicksOnEnter(element))) {
5972
+ $event.preventDefault();
5973
+ if (!$event.repeat) element.click();
5974
+ return;
5975
+ }
5976
+ if (!["ArrowDown", "ArrowUp"].includes($event.key)) return;
5977
+ $event.preventDefault();
5978
+ this.#dropdownService.toggle({
5979
+ visible: true,
5980
+ dropdown: this.dropdown,
5981
+ focus: $event.key === "ArrowDown" ? "first" : "last"
5982
+ });
5983
+ }
5984
+ constructor() {
5985
+ const element = this.elementRef.nativeElement;
5986
+ if (element?.tagName === "A" && !element.hasAttribute("role")) this.#renderer.setAttribute(element, "role", "button");
5987
+ }
5947
5988
  ngAfterViewInit() {
5948
5989
  const dropdownComponent = this.dropdownComponent();
5949
5990
  if (dropdownComponent) {
5950
5991
  this.dropdown = dropdownComponent;
5951
5992
  this.#dropdownService = dropdownComponent?.dropdownService;
5952
- }
5953
- if (this.dropdown) {
5954
- const subscription = this.dropdown?.visibleChange?.subscribe((visible) => {
5955
- this.#ariaExpanded.set(visible);
5956
- });
5957
- if (subscription) this.#destroyRef.onDestroy(() => {
5958
- subscription.unsubscribe();
5959
- });
5993
+ dropdownComponent.toggler = this;
5960
5994
  }
5961
5995
  }
5962
5996
  static ɵfac = i0.ɵɵngDeclareFactory({
@@ -6004,7 +6038,10 @@ var DropdownToggleDirective = class DropdownToggleDirective {
6004
6038
  }
6005
6039
  },
6006
6040
  host: {
6007
- listeners: { "click": "onClick($event)" },
6041
+ listeners: {
6042
+ "click": "onClick($event)",
6043
+ "keydown": "onKeyDown($event)"
6044
+ },
6008
6045
  properties: {
6009
6046
  "class": "hostClasses()",
6010
6047
  "aria-expanded": "ariaExpanded"
@@ -6035,10 +6072,12 @@ i0.ɵɵngDeclareClassMetadata({
6035
6072
  host: {
6036
6073
  "[class]": "hostClasses()",
6037
6074
  "[aria-expanded]": "ariaExpanded",
6038
- "(click)": "onClick($event)"
6075
+ "(click)": "onClick($event)",
6076
+ "(keydown)": "onKeyDown($event)"
6039
6077
  }
6040
6078
  }]
6041
6079
  }],
6080
+ ctorParameters: () => [],
6042
6081
  propDecorators: {
6043
6082
  dropdownComponent: [{
6044
6083
  type: i0.Input,
@@ -6168,6 +6207,7 @@ var DropdownComponent = class DropdownComponent {
6168
6207
  visibleChange = output();
6169
6208
  dropdownContext = { $implicit: this.visible() };
6170
6209
  _toggler = contentChild(DropdownToggleDirective, ...ngDevMode ? [{ debugName: "_toggler" }] : /* istanbul ignore next */ []);
6210
+ toggler;
6171
6211
  _menu = contentChild(DropdownMenuDirective, ...ngDevMode ? [{ debugName: "_menu" }] : /* istanbul ignore next */ []);
6172
6212
  _menuElementRef = contentChild(DropdownMenuDirective, {
6173
6213
  ...ngDevMode ? { debugName: "_menuElementRef" } : /* istanbul ignore next */ {},
@@ -6226,7 +6266,7 @@ var DropdownComponent = class DropdownComponent {
6226
6266
  });
6227
6267
  }
6228
6268
  createPopperInstance() {
6229
- const _toggler = this._toggler();
6269
+ const _toggler = this._toggler() ?? this.toggler;
6230
6270
  const _menu = this._menu();
6231
6271
  if (_toggler && _menu) this.#ngZone.runOutsideAngular(() => {
6232
6272
  _menu.elementRef.nativeElement.style.visibility = "hidden";
@@ -6249,7 +6289,7 @@ var DropdownComponent = class DropdownComponent {
6249
6289
  this.listeners.push(this.#renderer.listen(this.#document, "click", (event) => {
6250
6290
  const target = event.target;
6251
6291
  if (this._menuElementRef()?.nativeElement.contains(event.target)) this.clickedTarget = target;
6252
- if (this._toggler()?.elementRef.nativeElement.contains(event.target)) return;
6292
+ if (this.#togglerElement()?.contains(event.target)) return;
6253
6293
  const autoClose = this.autoClose();
6254
6294
  if (autoClose === true) {
6255
6295
  this.setVisibleState(false);
@@ -6264,20 +6304,35 @@ var DropdownComponent = class DropdownComponent {
6264
6304
  return;
6265
6305
  }
6266
6306
  }));
6267
- this.listeners.push(this.#renderer.listen(this.#elementRef.nativeElement, "keyup", (event) => {
6268
- if (event.key === "Escape" && this.autoClose() !== false) {
6269
- event.stopPropagation();
6270
- this.setVisibleState(false);
6271
- return;
6272
- }
6273
- }));
6307
+ this.listeners.push(this.#renderer.listen(this.#elementRef.nativeElement, "keyup", this.#onEscape));
6308
+ const toggler = this.#togglerElement();
6309
+ if (toggler && !this.#elementRef.nativeElement.contains(toggler)) this.listeners.push(this.#renderer.listen(toggler, "keyup", this.#onEscape));
6274
6310
  this.listeners.push(this.#renderer.listen(this.#document, "keyup", (event) => {
6275
- if (event.key === "Tab" && this.autoClose() !== false && !this.#elementRef.nativeElement.contains(event.target)) {
6276
- this.setVisibleState(false);
6277
- return;
6278
- }
6311
+ const path = event.composedPath();
6312
+ const toggler = this.#togglerElement();
6313
+ if (event.key === "Tab" && this.autoClose() !== false && !path.includes(this.#elementRef.nativeElement) && !(toggler && path.includes(toggler))) this.setVisibleState(false);
6279
6314
  }));
6280
6315
  }
6316
+ #onEscape = (event) => {
6317
+ if (event.key !== "Escape" || this.autoClose() === false) return;
6318
+ event.stopPropagation();
6319
+ const focusInMenu = this._menuElementRef()?.nativeElement.contains(event.target);
6320
+ this.setVisibleState(false);
6321
+ if (focusInMenu) this.#focusToggler();
6322
+ };
6323
+ #togglerElement() {
6324
+ return (this._toggler() ?? this.toggler)?.elementRef.nativeElement;
6325
+ }
6326
+ #focusToggler() {
6327
+ const toggler = this.#togglerElement();
6328
+ if (!toggler) return;
6329
+ const root = toggler.getRootNode();
6330
+ const candidates = [toggler, ...toggler.querySelectorAll(FOCUSABLE_SELECTOR)].filter((candidate) => candidate === toggler || candidate.tabIndex >= 0 && !candidate.closest("[aria-hidden=\"true\"]"));
6331
+ for (const candidate of candidates) {
6332
+ candidate.focus();
6333
+ if (root.activeElement === candidate) return;
6334
+ }
6335
+ }
6281
6336
  clearListeners() {
6282
6337
  this.listeners.forEach((unListen) => {
6283
6338
  unListen();
@@ -6513,7 +6568,7 @@ i0.ɵɵngDeclareClassMetadata({
6513
6568
  }
6514
6569
  });
6515
6570
  var DropdownItemDirective = class DropdownItemDirective {
6516
- #elementRef = inject(ElementRef);
6571
+ elementRef = inject(ElementRef);
6517
6572
  #dropdownService = inject(DropdownService);
6518
6573
  dropdown = inject(DropdownComponent, { optional: true });
6519
6574
  active = input(...ngDevMode ? [void 0, { debugName: "active" }] : /* istanbul ignore next */ []);
@@ -6530,7 +6585,7 @@ var DropdownItemDirective = class DropdownItemDirective {
6530
6585
  get disabled() {
6531
6586
  return this.#disabled();
6532
6587
  }
6533
- role = input("list-item", ...ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []);
6588
+ role = input(...ngDevMode ? [void 0, { debugName: "role" }] : /* istanbul ignore next */ []);
6534
6589
  tabIndexInput = input("0", {
6535
6590
  ...ngDevMode ? { debugName: "tabIndexInput" } : /* istanbul ignore next */ {},
6536
6591
  alias: "tabIndex"
@@ -6541,10 +6596,10 @@ var DropdownItemDirective = class DropdownItemDirective {
6541
6596
  computation: (value) => this.disabled ? "-1" : value
6542
6597
  });
6543
6598
  focus(origin) {
6544
- this.#elementRef?.nativeElement?.focus();
6599
+ this.elementRef?.nativeElement?.focus();
6545
6600
  }
6546
6601
  getLabel() {
6547
- return this.#elementRef?.nativeElement?.textContent.trim();
6602
+ return this.elementRef?.nativeElement?.textContent.trim();
6548
6603
  }
6549
6604
  ariaCurrent = computed(() => {
6550
6605
  return this.active() ? "true" : null;
@@ -6560,7 +6615,8 @@ var DropdownItemDirective = class DropdownItemDirective {
6560
6615
  this.handleInteraction();
6561
6616
  }
6562
6617
  onKeyUp($event) {
6563
- if ($event.key === "Enter") this.handleInteraction();
6618
+ const target = $event.target;
6619
+ if ($event.key === "Enter" && !isEditableTarget$1(target) && !clicksOnEnter(target)) this.handleInteraction();
6564
6620
  }
6565
6621
  handleInteraction() {
6566
6622
  if (this.autoClose()) this.#dropdownService.toggle({
@@ -11288,7 +11344,10 @@ var ModalService = class ModalService {
11288
11344
  #modalState = new Subject();
11289
11345
  modalState$ = this.#modalState.asObservable();
11290
11346
  toggle(action) {
11291
- this.#modalState.next(action);
11347
+ this.#modalState.next({
11348
+ ...action,
11349
+ focusFallback: [...action.focusFallback ?? []]
11350
+ });
11292
11351
  }
11293
11352
  static ɵfac = i0.ɵɵngDeclareFactory({
11294
11353
  minVersion: "12.0.0",
@@ -11317,6 +11376,7 @@ i0.ɵɵngDeclareClassMetadata({
11317
11376
  }]
11318
11377
  });
11319
11378
  var ModalToggleDirective = class ModalToggleDirective {
11379
+ #elementRef = inject(ElementRef);
11320
11380
  #modalService = inject(ModalService);
11321
11381
  toggle = input(void 0, {
11322
11382
  ...ngDevMode ? { debugName: "toggle" } : /* istanbul ignore next */ {},
@@ -11326,7 +11386,8 @@ var ModalToggleDirective = class ModalToggleDirective {
11326
11386
  $event.preventDefault();
11327
11387
  this.#modalService.toggle({
11328
11388
  show: "toggle",
11329
- id: this.toggle()
11389
+ id: this.toggle(),
11390
+ trigger: this.#elementRef.nativeElement
11330
11391
  });
11331
11392
  }
11332
11393
  static ɵfac = i0.ɵɵngDeclareFactory({
@@ -11477,6 +11538,16 @@ i0.ɵɵngDeclareClassMetadata({
11477
11538
  }]
11478
11539
  }]
11479
11540
  });
11541
+ const restoreFocus = (overlay, candidates) => {
11542
+ const document = overlay.ownerDocument;
11543
+ const active = document.activeElement;
11544
+ if (active && active !== document.body && !overlay.contains(active)) return false;
11545
+ for (const target of candidates) if (target?.isConnected && !overlay.contains(target)) {
11546
+ target.focus({ preventScroll: true });
11547
+ if (document.activeElement === target) return true;
11548
+ }
11549
+ return false;
11550
+ };
11480
11551
  var ModalComponent = class ModalComponent {
11481
11552
  static ngAcceptInputType_ariaModalInput;
11482
11553
  static ngAcceptInputType_scrollable;
@@ -11487,7 +11558,7 @@ var ModalComponent = class ModalComponent {
11487
11558
  #modalService = inject(ModalService);
11488
11559
  #backdropService = inject(BackdropService);
11489
11560
  #destroyRef = inject(DestroyRef);
11490
- #focusMonitor = inject(FocusMonitor);
11561
+ #platformId = inject(PLATFORM_ID);
11491
11562
  alignment = input("top", ...ngDevMode ? [{ debugName: "alignment" }] : /* istanbul ignore next */ []);
11492
11563
  backdrop = input(true, ...ngDevMode ? [{ debugName: "backdrop" }] : /* istanbul ignore next */ []);
11493
11564
  container = input(this.#document.body, ...ngDevMode ? [{ debugName: "container" }] : /* istanbul ignore next */ []);
@@ -11559,26 +11630,19 @@ var ModalComponent = class ModalComponent {
11559
11630
  this.visibleChange?.emit(visible);
11560
11631
  });
11561
11632
  }, ...ngDevMode ? [{ debugName: "#visibleInputEffect" }] : /* istanbul ignore next */ []);
11562
- #activeElement = signal(null, ...ngDevMode ? [{ debugName: "#activeElement" }] : /* istanbul ignore next */ []);
11633
+ #focusBeforeShow = null;
11634
+ #openAction = null;
11635
+ #trigger = null;
11563
11636
  #visibleEffect = effect(() => {
11564
11637
  const visible = this.visible();
11565
11638
  const afterViewInit = this.#afterViewInit();
11566
11639
  untracked(() => {
11567
11640
  if (visible && afterViewInit) {
11568
- this.#activeElement.set(this.#document.activeElement);
11641
+ this.#focusBeforeShow = this.#document.activeElement;
11569
11642
  setTimeout(() => {
11570
- const focusable = this.modalContentRef()?.nativeElement.querySelectorAll("[tabindex]:not([tabindex=\"-1\"]), button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled])");
11571
- if (focusable?.length) this.#focusMonitor.focusVia(focusable[0], "keyboard");
11643
+ if (!this.focusTrap()?.focusTrap.focusInitialElement()) this.#hostElement.nativeElement.focus();
11572
11644
  });
11573
- } else {
11574
- const activeElement = this.#activeElement();
11575
- if (activeElement && this.#document.contains(activeElement)) {
11576
- this.#focusMonitor.focusVia(activeElement, "keyboard");
11577
- setTimeout(() => {
11578
- this.#activeElement.set(null);
11579
- });
11580
- }
11581
- }
11645
+ } else this.#restoreFocus();
11582
11646
  });
11583
11647
  }, ...ngDevMode ? [{ debugName: "#visibleEffect" }] : /* istanbul ignore next */ []);
11584
11648
  visibleChange = output();
@@ -11586,6 +11650,7 @@ var ModalComponent = class ModalComponent {
11586
11650
  ...ngDevMode ? { debugName: "modalContentRef" } : /* istanbul ignore next */ {},
11587
11651
  read: ElementRef
11588
11652
  });
11653
+ focusTrap = viewChild(CdkTrapFocus, ...ngDevMode ? [{ debugName: "focusTrap" }] : /* istanbul ignore next */ []);
11589
11654
  modalDialogRef = viewChild.required(ModalDialogComponent, {
11590
11655
  ...ngDevMode ? { debugName: "modalDialogRef" } : /* istanbul ignore next */ {},
11591
11656
  read: ElementRef
@@ -11674,6 +11739,7 @@ var ModalComponent = class ModalComponent {
11674
11739
  this.#afterViewInit.set(true);
11675
11740
  }
11676
11741
  ngOnDestroy() {
11742
+ if (this.#trigger || this.#focusBeforeShow) this.#restoreFocus();
11677
11743
  this.#modalService.toggle({
11678
11744
  show: false,
11679
11745
  modal: this
@@ -11685,10 +11751,35 @@ var ModalComponent = class ModalComponent {
11685
11751
  stateToggleSubscribe() {
11686
11752
  this.#modalService.modalState$.pipe(takeUntilDestroyed(this.#destroyRef)).subscribe((action) => {
11687
11753
  if (this === action.modal || this.id === action.id) {
11688
- if ("show" in action) this.visible.update((visible) => action?.show === "toggle" ? !visible : action.show);
11689
- } else if (this.visible()) this.visible.set(false);
11754
+ if ("show" in action) {
11755
+ const visible = this.visible();
11756
+ const show = action?.show === "toggle" ? !visible : !!action.show;
11757
+ if (show && !visible) {
11758
+ this.#trigger = action.trigger ?? null;
11759
+ this.#openAction = action;
11760
+ }
11761
+ this.visible.set(show);
11762
+ }
11763
+ } else if (this.visible()) {
11764
+ for (const target of this.#focusCandidates()) if (!action.focusFallback?.includes(target)) action.focusFallback?.push(target);
11765
+ this.visible.set(false);
11766
+ }
11690
11767
  });
11691
11768
  }
11769
+ #focusCandidates() {
11770
+ return [
11771
+ this.#trigger,
11772
+ this.#focusBeforeShow,
11773
+ ...this.#openAction?.focusFallback ?? []
11774
+ ];
11775
+ }
11776
+ #restoreFocus() {
11777
+ const candidates = this.#focusCandidates();
11778
+ this.#trigger = null;
11779
+ this.#focusBeforeShow = null;
11780
+ this.#openAction = null;
11781
+ if (isPlatformBrowser(this.#platformId)) restoreFocus(this.#hostElement.nativeElement, candidates);
11782
+ }
11692
11783
  setBackdrop(setBackdrop) {
11693
11784
  this.#activeBackdrop = setBackdrop ? this.#backdropService.setBackdrop("modal") : this.#backdropService.clearBackdrop(this.#activeBackdrop);
11694
11785
  }
@@ -11827,29 +11918,38 @@ var ModalComponent = class ModalComponent {
11827
11918
  "inert": "ariaHidden()",
11828
11919
  "attr.id": "id",
11829
11920
  "aria-modal": "ariaModal()",
11830
- "aria-hidden": "ariaHidden()",
11831
11921
  "attr.tabindex": "-1"
11832
11922
  },
11833
11923
  classAttribute: "modal"
11834
11924
  },
11835
- viewQueries: [{
11836
- propertyName: "modalContentRef",
11837
- first: true,
11838
- predicate: ["modalContentRef"],
11839
- descendants: true,
11840
- read: ElementRef,
11841
- isSignal: true
11842
- }, {
11843
- propertyName: "modalDialogRef",
11844
- first: true,
11845
- predicate: ModalDialogComponent,
11846
- descendants: true,
11847
- read: ElementRef,
11848
- isSignal: true
11849
- }],
11925
+ viewQueries: [
11926
+ {
11927
+ propertyName: "modalContentRef",
11928
+ first: true,
11929
+ predicate: ["modalContentRef"],
11930
+ descendants: true,
11931
+ read: ElementRef,
11932
+ isSignal: true
11933
+ },
11934
+ {
11935
+ propertyName: "focusTrap",
11936
+ first: true,
11937
+ predicate: CdkTrapFocus,
11938
+ descendants: true,
11939
+ isSignal: true
11940
+ },
11941
+ {
11942
+ propertyName: "modalDialogRef",
11943
+ first: true,
11944
+ predicate: ModalDialogComponent,
11945
+ descendants: true,
11946
+ read: ElementRef,
11947
+ isSignal: true
11948
+ }
11949
+ ],
11850
11950
  exportAs: ["cModal"],
11851
11951
  ngImport: i0,
11852
- template: "@let isVisible = visible();\n<c-modal-dialog\n [alignment]=\"alignment()\"\n [fullscreen]=\"fullscreen()\"\n [scrollable]=\"scrollable()\"\n [size]=\"size()\">\n <c-modal-content>\n <div #modalContentRef [cdkTrapFocusAutoCapture]=\"isVisible\" [cdkTrapFocus]=\"isVisible\" style=\"display: contents;\">\n <ng-content />\n </div>\n </c-modal-content>\n</c-modal-dialog>\n",
11952
+ template: "@let isVisible = visible();\n<c-modal-dialog\n [alignment]=\"alignment()\"\n [fullscreen]=\"fullscreen()\"\n [scrollable]=\"scrollable()\"\n [size]=\"size()\">\n <c-modal-content>\n <div #modalContentRef [cdkTrapFocus]=\"isVisible\" style=\"display: contents;\">\n <ng-content />\n </div>\n </c-modal-content>\n</c-modal-dialog>\n",
11853
11953
  dependencies: [
11854
11954
  {
11855
11955
  kind: "component",
@@ -11903,13 +12003,12 @@ i0.ɵɵngDeclareClassMetadata({
11903
12003
  "[inert]": "ariaHidden()",
11904
12004
  "[attr.id]": "id",
11905
12005
  "[aria-modal]": "ariaModal()",
11906
- "[aria-hidden]": "ariaHidden()",
11907
12006
  "[attr.tabindex]": "-1",
11908
12007
  "(mousedown)": "onMouseDownHandler($event)",
11909
12008
  "(click)": "onClickHandler($event)",
11910
12009
  "(document:keydown)": "onKeyDownHandler($event)"
11911
12010
  },
11912
- template: "@let isVisible = visible();\n<c-modal-dialog\n [alignment]=\"alignment()\"\n [fullscreen]=\"fullscreen()\"\n [scrollable]=\"scrollable()\"\n [size]=\"size()\">\n <c-modal-content>\n <div #modalContentRef [cdkTrapFocusAutoCapture]=\"isVisible\" [cdkTrapFocus]=\"isVisible\" style=\"display: contents;\">\n <ng-content />\n </div>\n </c-modal-content>\n</c-modal-dialog>\n"
12011
+ template: "@let isVisible = visible();\n<c-modal-dialog\n [alignment]=\"alignment()\"\n [fullscreen]=\"fullscreen()\"\n [scrollable]=\"scrollable()\"\n [size]=\"size()\">\n <c-modal-content>\n <div #modalContentRef [cdkTrapFocus]=\"isVisible\" style=\"display: contents;\">\n <ng-content />\n </div>\n </c-modal-content>\n</c-modal-dialog>\n"
11913
12012
  }]
11914
12013
  }],
11915
12014
  propDecorators: {
@@ -12028,6 +12127,10 @@ i0.ɵɵngDeclareClassMetadata({
12028
12127
  isSignal: true
12029
12128
  }]
12030
12129
  }],
12130
+ focusTrap: [{
12131
+ type: i0.ViewChild,
12132
+ args: [i0.forwardRef(() => CdkTrapFocus), { isSignal: true }]
12133
+ }],
12031
12134
  modalDialogRef: [{
12032
12135
  type: i0.ViewChild,
12033
12136
  args: [i0.forwardRef(() => ModalDialogComponent), {
@@ -12181,7 +12284,11 @@ var OffcanvasComponent = class OffcanvasComponent {
12181
12284
  #backdropClickSubscription;
12182
12285
  #layoutChangeSubscription;
12183
12286
  #hideFallbackId;
12287
+ #focusBeforeShow = null;
12184
12288
  #isShown = false;
12289
+ #shownAsPanel = false;
12290
+ #trigger = null;
12291
+ #inPlace = signal(false, ...ngDevMode ? [{ debugName: "#inPlace" }] : /* istanbul ignore next */ []);
12185
12292
  scroll = input(false, {
12186
12293
  ...ngDevMode ? { debugName: "scroll" } : /* istanbul ignore next */ {},
12187
12294
  transform: booleanAttribute
@@ -12212,13 +12319,20 @@ var OffcanvasComponent = class OffcanvasComponent {
12212
12319
  }
12213
12320
  });
12214
12321
  }, ...ngDevMode ? [{ debugName: "#portalEffect" }] : /* istanbul ignore next */ []);
12322
+ #afterEveryRenderFn = afterEveryRender({ read: () => this.#readPosition() });
12215
12323
  visibleEffect = effect(() => {
12216
12324
  const visible = this.visible();
12325
+ const wasShown = this.#isShown;
12217
12326
  this.animateStart(visible);
12218
12327
  if (visible) {
12328
+ if (!wasShown) this.#focusBeforeShow = this.#document.activeElement;
12219
12329
  this.setBackdrop(this.backdrop());
12220
12330
  this.setFocus();
12221
- } else this.setBackdrop(false);
12331
+ } else {
12332
+ this.#shownAsPanel = false;
12333
+ this.#restoreFocus();
12334
+ this.setBackdrop(false);
12335
+ }
12222
12336
  this.layoutChangeSubscribe(visible);
12223
12337
  this.visibleChange?.emit(visible);
12224
12338
  }, ...ngDevMode ? [{ debugName: "visibleEffect" }] : /* istanbul ignore next */ []);
@@ -12235,7 +12349,7 @@ var OffcanvasComponent = class OffcanvasComponent {
12235
12349
  };
12236
12350
  }, ...ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []);
12237
12351
  ariaHidden = computed(() => {
12238
- return this.visible() ? null : true;
12352
+ return this.visible() || this.#inPlace() ? null : true;
12239
12353
  }, ...ngDevMode ? [{ debugName: "ariaHidden" }] : /* istanbul ignore next */ []);
12240
12354
  get tabIndex() {
12241
12355
  return "-1";
@@ -12263,8 +12377,10 @@ var OffcanvasComponent = class OffcanvasComponent {
12263
12377
  this.#renderer.addClass(this.#hostElement.nativeElement, "showing");
12264
12378
  } else {
12265
12379
  this.#renderer.removeClass(this.#hostElement.nativeElement, "showing");
12266
- this.#renderer.addClass(this.#hostElement.nativeElement, "hiding");
12267
- if (wasShown) this.#scheduleHideFallback();
12380
+ if (wasShown) {
12381
+ this.#renderer.addClass(this.#hostElement.nativeElement, "hiding");
12382
+ this.#scheduleHideFallback();
12383
+ }
12268
12384
  }
12269
12385
  }
12270
12386
  onKeyDownHandler(event) {
@@ -12273,6 +12389,13 @@ var OffcanvasComponent = class OffcanvasComponent {
12273
12389
  id: this.id()
12274
12390
  });
12275
12391
  }
12392
+ onResizeHandler() {
12393
+ this.#readPosition();
12394
+ if (this.visible() && this.#shownAsPanel && this.#inPlace()) this.#offcanvasService.toggle({
12395
+ show: false,
12396
+ id: this.id()
12397
+ });
12398
+ }
12276
12399
  ngOnInit() {
12277
12400
  this.stateToggleSubscribe();
12278
12401
  setTimeout(() => {
@@ -12281,6 +12404,7 @@ var OffcanvasComponent = class OffcanvasComponent {
12281
12404
  this.#hostElement.nativeElement.addEventListener("transitionend", this.#handleTransitionEnd);
12282
12405
  }
12283
12406
  ngOnDestroy() {
12407
+ if (this.#trigger || this.#focusBeforeShow) this.#restoreFocus();
12284
12408
  this.#offcanvasService.toggle({
12285
12409
  show: false,
12286
12410
  id: this.id()
@@ -12317,13 +12441,29 @@ var OffcanvasComponent = class OffcanvasComponent {
12317
12441
  clearTimeout(this.#hideFallbackId);
12318
12442
  this.#hideFallbackId = void 0;
12319
12443
  }
12444
+ #readPosition() {
12445
+ const position = this.#document.defaultView?.getComputedStyle(this.#hostElement.nativeElement).position;
12446
+ this.#inPlace.set(!!position && position !== "fixed");
12447
+ if (position === "fixed" && this.visible()) this.#shownAsPanel = true;
12448
+ }
12320
12449
  setFocus() {
12321
12450
  if (isPlatformBrowser(this.#platformId)) setTimeout(() => this.#hostElement.nativeElement.focus());
12322
12451
  }
12452
+ #restoreFocus() {
12453
+ const candidates = [this.#trigger, this.#focusBeforeShow];
12454
+ this.#trigger = null;
12455
+ this.#focusBeforeShow = null;
12456
+ if (isPlatformBrowser(this.#platformId)) restoreFocus(this.#hostElement.nativeElement, candidates);
12457
+ }
12323
12458
  stateToggleSubscribe() {
12324
12459
  this.#offcanvasService.offcanvasState$.pipe(takeUntilDestroyed(this.#destroyRef)).subscribe((action) => {
12325
12460
  if (this === action.offcanvas || this.id() === action.id) {
12326
- if ("show" in action) this.visible.update((value) => action?.show === "toggle" ? !value : action.show);
12461
+ if ("show" in action) {
12462
+ const visible = this.visible();
12463
+ const show = action?.show === "toggle" ? !visible : !!action.show;
12464
+ if (show && !visible) this.#trigger = action.trigger ?? null;
12465
+ this.visible.set(show);
12466
+ }
12327
12467
  }
12328
12468
  });
12329
12469
  }
@@ -12445,12 +12585,15 @@ var OffcanvasComponent = class OffcanvasComponent {
12445
12585
  },
12446
12586
  outputs: { visibleChange: "visibleChange" },
12447
12587
  host: {
12448
- listeners: { "document:keydown": "onKeyDownHandler($event)" },
12588
+ listeners: {
12589
+ "document:keydown": "onKeyDownHandler($event)",
12590
+ "window:resize": "onResizeHandler()"
12591
+ },
12449
12592
  properties: {
12450
12593
  "attr.id": "id()",
12451
12594
  "inert": "ariaHidden()",
12452
- "attr.role": "role()",
12453
- "aria-modal": "ariaModal()",
12595
+ "attr.role": "visible() ? role() : null",
12596
+ "aria-modal": "visible() ? ariaModal() : null",
12454
12597
  "attr.tabindex": "tabIndex",
12455
12598
  "class": "hostClasses()"
12456
12599
  }
@@ -12461,7 +12604,7 @@ var OffcanvasComponent = class OffcanvasComponent {
12461
12604
  inputs: ["dark", "dark"]
12462
12605
  }],
12463
12606
  ngImport: i0,
12464
- template: "<div cdkTrapFocus cdkTrapFocusAutoCapture>\n <ng-content />\n</div>\n\n",
12607
+ template: "<div [cdkTrapFocus]=\"visible()\">\n <ng-content />\n</div>\n",
12465
12608
  styles: [":host{display:none}\n"],
12466
12609
  dependencies: [{
12467
12610
  kind: "ngmodule",
@@ -12493,13 +12636,14 @@ i0.ɵɵngDeclareClassMetadata({
12493
12636
  host: {
12494
12637
  "[attr.id]": "id()",
12495
12638
  "[inert]": "ariaHidden()",
12496
- "[attr.role]": "role()",
12497
- "[aria-modal]": "ariaModal()",
12639
+ "[attr.role]": "visible() ? role() : null",
12640
+ "[aria-modal]": "visible() ? ariaModal() : null",
12498
12641
  "[attr.tabindex]": "tabIndex",
12499
12642
  "[class]": "hostClasses()",
12500
- "(document:keydown)": "onKeyDownHandler($event)"
12643
+ "(document:keydown)": "onKeyDownHandler($event)",
12644
+ "(window:resize)": "onResizeHandler()"
12501
12645
  },
12502
- template: "<div cdkTrapFocus cdkTrapFocusAutoCapture>\n <ng-content />\n</div>\n\n",
12646
+ template: "<div [cdkTrapFocus]=\"visible()\">\n <ng-content />\n</div>\n",
12503
12647
  styles: [":host{display:none}\n"]
12504
12648
  }]
12505
12649
  }],
@@ -12703,6 +12847,7 @@ i0.ɵɵngDeclareClassMetadata({
12703
12847
  }]
12704
12848
  });
12705
12849
  var OffcanvasToggleDirective = class OffcanvasToggleDirective {
12850
+ #elementRef = inject(ElementRef);
12706
12851
  #offcanvasService = inject(OffcanvasService);
12707
12852
  id = input(void 0, {
12708
12853
  ...ngDevMode ? { debugName: "id" } : /* istanbul ignore next */ {},
@@ -12712,7 +12857,8 @@ var OffcanvasToggleDirective = class OffcanvasToggleDirective {
12712
12857
  $event.preventDefault();
12713
12858
  this.#offcanvasService.toggle({
12714
12859
  show: "toggle",
12715
- id: this.id()
12860
+ id: this.id(),
12861
+ trigger: this.#elementRef.nativeElement
12716
12862
  });
12717
12863
  }
12718
12864
  static ɵfac = i0.ɵɵngDeclareFactory({