@broberg/app-shell 0.20.1 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/preact.cjs CHANGED
@@ -546,6 +546,7 @@ function ItemActionsMenu(props) {
546
546
  const [pos, setPos] = hooks.useState(void 0);
547
547
  const view = stack[stack.length - 1];
548
548
  const closed = hooks.useRef(false);
549
+ const [kbd, setKbd] = hooks.useState(() => props.anchor.matches(":focus-visible"));
549
550
  const close = (refocus = true) => {
550
551
  if (closed.current) return;
551
552
  closed.current = true;
@@ -579,9 +580,12 @@ function ItemActionsMenu(props) {
579
580
  const vw = window.innerWidth, vh = window.innerHeight, m = 8;
580
581
  const w = Math.min(240, vw - 2 * m);
581
582
  const h = menu.current?.offsetHeight ?? 0;
582
- const left = Math.max(m, Math.min(r.right - w, vw - w - m));
583
+ const start = props.placement === "up-start";
584
+ const left = Math.max(m, Math.min(start ? r.left : r.right - w, vw - w - m));
583
585
  const fitsBelow = r.bottom + 4 + h <= vh - m;
584
- const top = props.placement === "down" || fitsBelow || r.top - 4 - h < m ? Math.min(r.bottom + 4, vh - m - h) : r.top - 4 - h;
586
+ const fitsAbove = r.top - 4 - h >= m;
587
+ const below = start ? !fitsAbove : props.placement === "down" || fitsBelow || !fitsAbove;
588
+ const top = below ? Math.min(r.bottom + 4, vh - m - h) : r.top - 4 - h;
585
589
  setPos({ position: "fixed", left: `${left}px`, top: `${Math.max(m, top)}px`, width: `${w}px` });
586
590
  }, [stack.length]);
587
591
  hooks.useLayoutEffect(() => {
@@ -618,6 +622,7 @@ function ItemActionsMenu(props) {
618
622
  const view2 = stack2[stack2.length - 1];
619
623
  if (!view2) return;
620
624
  e.stopPropagation();
625
+ setKbd(true);
621
626
  if (e.key === "Escape") {
622
627
  e.preventDefault();
623
628
  return close();
@@ -660,7 +665,7 @@ function ItemActionsMenu(props) {
660
665
  "div",
661
666
  {
662
667
  ref: menu,
663
- class: "bas-rowmenu",
668
+ class: "bas-rowmenu" + (kbd ? " is-kbd" : ""),
664
669
  role: "menu",
665
670
  tabIndex: -1,
666
671
  "aria-label": view.kind === "list" && view.title ? view.title : props.label,
@@ -672,28 +677,32 @@ function ItemActionsMenu(props) {
672
677
  /* @__PURE__ */ jsxRuntime.jsx(IconChevronLeft, {}),
673
678
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: view.kind === "list" ? view.title : view.action.label })
674
679
  ] }) : null,
675
- view.kind === "list" ? view.actions.map((a, i) => /* @__PURE__ */ jsxRuntime.jsxs(
676
- "button",
677
- {
678
- type: "button",
679
- role: "menuitem",
680
- ref: (el) => {
681
- items.current[i] = el;
680
+ view.kind === "list" ? view.actions.map((a, i) => [
681
+ a.separator ? /* @__PURE__ */ jsxRuntime.jsx("div", { class: "bas-rowmenu__sep", role: "separator" }, `${a.id}-sep`) : null,
682
+ /* @__PURE__ */ jsxRuntime.jsxs(
683
+ "button",
684
+ {
685
+ type: "button",
686
+ role: "menuitem",
687
+ ref: (el) => {
688
+ items.current[i] = el;
689
+ },
690
+ tabIndex: i === hi ? 0 : -1,
691
+ class: "bas-rowmenu__item" + (i === hi ? " is-active" : "") + (a.danger ? " is-danger" : "") + (armed === a.id ? " is-armed" : ""),
692
+ "data-testid": `${pre}-action-${a.id}`,
693
+ onMouseEnter: () => setHi(i),
694
+ onFocus: () => setHi(i),
695
+ onClick: () => pick(a),
696
+ children: [
697
+ a.icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { class: "bas-rowmenu__icon", children: a.icon }) : null,
698
+ /* @__PURE__ */ jsxRuntime.jsx("span", { class: "bas-rowmenu__label", children: armed === a.id && a.confirm ? a.confirm.label : a.label }),
699
+ a.value ? /* @__PURE__ */ jsxRuntime.jsx("span", { class: "bas-rowmenu__value", "data-testid": `${pre}-action-${a.id}-value`, children: a.value }) : null,
700
+ a.submenu?.length ? /* @__PURE__ */ jsxRuntime.jsx(IconChevronRight, {}) : a.kbd ? /* @__PURE__ */ jsxRuntime.jsx("kbd", { class: "bas-rowmenu__kbd", children: a.kbd.toUpperCase() }) : null
701
+ ]
682
702
  },
683
- tabIndex: i === hi ? 0 : -1,
684
- class: "bas-rowmenu__item" + (i === hi ? " is-active" : "") + (a.danger ? " is-danger" : "") + (armed === a.id ? " is-armed" : ""),
685
- "data-testid": `${pre}-action-${a.id}`,
686
- onMouseEnter: () => setHi(i),
687
- onFocus: () => setHi(i),
688
- onClick: () => pick(a),
689
- children: [
690
- a.icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { class: "bas-rowmenu__icon", children: a.icon }) : null,
691
- /* @__PURE__ */ jsxRuntime.jsx("span", { class: "bas-rowmenu__label", children: armed === a.id && a.confirm ? a.confirm.label : a.label }),
692
- a.submenu?.length ? /* @__PURE__ */ jsxRuntime.jsx(IconChevronRight, {}) : a.kbd ? /* @__PURE__ */ jsxRuntime.jsx("kbd", { class: "bas-rowmenu__kbd", children: a.kbd.toUpperCase() }) : null
693
- ]
694
- },
695
- a.id
696
- )) : /* @__PURE__ */ jsxRuntime.jsxs(
703
+ a.id
704
+ )
705
+ ]) : /* @__PURE__ */ jsxRuntime.jsxs(
697
706
  "form",
698
707
  {
699
708
  class: "bas-rowmenu__form",