@blackcube/aurelia-kit 1.0.0-rc6 → 1.0.0-rc7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -496,7 +496,13 @@ Behavior:
496
496
 
497
497
  - Listens on `Channels.Menu`: `MenuAction.Open` applies the show classes and opens the overlay, `MenuAction.Close`
498
498
  applies the hide classes and closes the overlay, `MenuAction.Toggle` does one or the other. `aria-hidden` follows.
499
- - A click on `[data-menu=close]` closes the menu; the menu closes too when the overlay closes.
499
+ - A click on `[data-menu=close]` closes the menu; the menu closes too when the overlay closes, on `Escape` and on a
500
+ click on a link of the menu (the link is followed).
501
+ - Open, the focus is trapped in the menu (`ITrapFocusService`), on `[data-menu=close]` first; once closed, it goes back
502
+ to what opened the menu (the burger).
503
+ - The page follows: `<body>` takes the classes of the menu's `data-menu-page-show` while it is open and of its
504
+ `data-menu-page-hide` once closed — `data-menu-page-show="overflow-hidden"` keeps the page from scrolling under it.
505
+ Without these attributes, the page is left as is.
500
506
  - Publishes `MenuStatus.Opening`, `Opened`, `Closing`, `Closed` on `Channels.MenuStatus`.
501
507
  - `[data-menu=toggle-button-ID]` shows or hides `[data-menu=toggle-list-ID]` (`hidden` attribute), sets the
502
508
  data-menu-show / data-menu-hide classes of its `svg[data-menu=icon]` and its `aria-expanded`. Accordion: opening a
package/dist/index.es.js CHANGED
@@ -473,11 +473,12 @@ var ge = u("bleet-menu"), _e, W;
473
473
  p;
474
474
  transitionService;
475
475
  storageService;
476
+ trapFocusService;
476
477
  static {
477
478
  ({c: [W, _e]} = he(this, [ge], []));
478
479
  }
479
- constructor(e = m(o).scopeTo("bleet-menu"), t = m(a), n = m(s), r = m(c), i = m(b), l = m(v)) {
480
- this.logger = e, this.ea = t, this.element = n, this.p = r, this.transitionService = i, this.storageService = l, this.logger.trace("constructor");
480
+ constructor(e = m(o).scopeTo("bleet-menu"), t = m(a), n = m(s), r = m(c), i = m(b), l = m(v), u = m(S)) {
481
+ this.logger = e, this.ea = t, this.element = n, this.p = r, this.transitionService = i, this.storageService = l, this.trapFocusService = u, this.logger.trace("constructor");
481
482
  }
482
483
  disposable;
483
484
  disposableOverlay;
@@ -485,35 +486,54 @@ var ge = u("bleet-menu"), _e, W;
485
486
  toggleButtons;
486
487
  sublists = /* @__PURE__ */ new Map();
487
488
  isOpen = !1;
489
+ closingFromOverlay = !1;
488
490
  attaching() {
489
491
  this.logger.trace("attaching"), this.closeButton = this.element.querySelector("[data-menu=close]"), this.toggleButtons = this.element.querySelectorAll("[data-menu^=\"toggle-button\"]"), this.initMenuButtons();
490
492
  }
491
493
  attached() {
492
- this.logger.trace("attached"), this.disposable = this.ea.subscribe(E.Menu, this.onMenuEvent), this.disposableOverlay = this.ea.subscribe(E.OverlayStatus, this.onOverlayStatus), this.closeButton?.addEventListener("click", this.onClickClose), this.element.addEventListener("click", this.onClickToggleButtons);
494
+ this.logger.trace("attached"), this.disposable = this.ea.subscribe(E.Menu, this.onMenuEvent), this.disposableOverlay = this.ea.subscribe(E.OverlayStatus, this.onOverlayStatus), this.closeButton?.addEventListener("click", this.onClickClose), this.element.addEventListener("click", this.onClickToggleButtons), this.element.addEventListener("click", this.onClickLink);
493
495
  }
494
496
  detaching() {
495
- this.logger.trace("detaching"), this.closeButton?.removeEventListener("click", this.onClickClose), this.element.removeEventListener("click", this.onClickToggleButtons), this.disposableOverlay?.dispose(), this.disposable?.dispose();
497
+ this.logger.trace("detaching"), this.closeButton?.removeEventListener("click", this.onClickClose), this.element.removeEventListener("click", this.onClickToggleButtons), this.element.removeEventListener("click", this.onClickLink), this.isOpen === !0 && this.trapFocusService.stop().catch((e) => {
498
+ this.logger.trace("detaching: no trap to stop", e);
499
+ }), this.disposableOverlay?.dispose(), this.disposable?.dispose();
496
500
  }
497
501
  dispose() {
498
502
  this.logger.trace("dispose"), this.disposableOverlay?.dispose(), this.disposable?.dispose();
499
503
  }
500
504
  open(e = !1) {
501
- this.isOpen || (this.logger.trace("open"), this.isOpen = !0, this.transitionService.run(this.element, (t) => {
502
- e || this.ea.publish(E.Overlay, { action: O.Open }), this.ea.publish(E.MenuStatus, { status: L.Opening }), w(t, "menu", "show"), t.ariaHidden = "false";
503
- }, (e) => {
504
- this.ea.publish(E.MenuStatus, { status: L.Opened });
505
- }));
505
+ if (!this.isOpen) {
506
+ this.logger.trace("open"), this.isOpen = !0;
507
+ let t = this.p.document.activeElement;
508
+ this.transitionService.run(this.element, (n) => {
509
+ e || this.ea.publish(E.Overlay, { action: O.Open }), this.ea.publish(E.MenuStatus, { status: L.Opening }), w(n, "menu", "show"), w(this.p.document.body, "menu-page", "show", n), n.ariaHidden = "false", this.isOpen === !0 && this.trapFocusService.start(t, n, this.p.document.body, void 0, this.onStopTrapFocus, this.closeButton);
510
+ }, (e) => {
511
+ this.ea.publish(E.MenuStatus, { status: L.Opened });
512
+ });
513
+ }
506
514
  }
507
515
  close(e = !1) {
508
- this.isOpen && (this.logger.trace("close"), this.isOpen = !1, this.transitionService.run(this.element, (t) => {
509
- this.ea.publish(E.MenuStatus, { status: L.Closing }), e || this.ea.publish(E.Overlay, { action: O.Close }), w(t, "menu", "hide"), t.ariaHidden = "true";
516
+ this.isOpen && (this.logger.trace("close"), this.closingFromOverlay = e, this.trapFocusService.stop().catch((e) => {
517
+ this.logger.trace("close: no trap started", e), this.hide();
518
+ }));
519
+ }
520
+ hide() {
521
+ this.logger.trace("hide");
522
+ let e = this.closingFromOverlay;
523
+ this.isOpen = !1, this.closingFromOverlay = !1, this.transitionService.run(this.element, (t) => {
524
+ this.ea.publish(E.MenuStatus, { status: L.Closing }), e || this.ea.publish(E.Overlay, { action: O.Close }), w(t, "menu", "hide"), w(this.p.document.body, "menu-page", "hide", t), t.ariaHidden = "true";
510
525
  }, (e) => {
511
526
  this.ea.publish(E.MenuStatus, { status: L.Closed });
512
- }));
527
+ });
513
528
  }
529
+ onStopTrapFocus = () => (this.logger.trace("onStopTrapFocus"), this.hide(), Promise.resolve());
514
530
  onClickClose = (e) => {
515
531
  this.logger.trace("onClickClose", e), e.preventDefault(), this.close();
516
532
  };
533
+ onClickLink = (e) => {
534
+ let t = e.target.closest("a");
535
+ t !== null && this.isOpen === !0 && (this.logger.trace("onClickLink", t), this.close());
536
+ };
517
537
  onClickToggleButtons = (e) => {
518
538
  let t = e.target.closest("[data-menu^=\"toggle-button\"]");
519
539
  t && t.matches("[data-menu^=\"toggle-button\"]") && (e.preventDefault(), this.toggleButton(t));