@broberg/app-shell 0.19.0 → 0.20.1
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 +16 -0
- package/css/app-shell.css +5 -2
- package/dist/preact.cjs +115 -86
- package/dist/preact.cjs.map +1 -1
- package/dist/preact.d.cts +29 -1
- package/dist/preact.d.ts +29 -1
- package/dist/preact.js +117 -89
- package/dist/preact.js.map +1 -1
- package/package.json +1 -1
package/dist/preact.d.cts
CHANGED
|
@@ -459,6 +459,34 @@ type PreactNavGroup = NavGroup<Icon>;
|
|
|
459
459
|
type Navigate = (href: string) => void;
|
|
460
460
|
/** True below 768px. Follows the window as it resizes. */
|
|
461
461
|
declare function useIsMobile(): boolean;
|
|
462
|
+
interface ItemActionsMenuProps {
|
|
463
|
+
/** The menu's items — the same NavAction[] a sidebar row takes (kbd, submenu, input, confirm, danger). */
|
|
464
|
+
actions: NavAction[];
|
|
465
|
+
/** What the menu opens from: positioned from it, and focus returns to it on close. */
|
|
466
|
+
anchor: HTMLElement;
|
|
467
|
+
/** An action was chosen (value = the text, for an input action). The menu has closed. */
|
|
468
|
+
onAction: (actionId: string, value?: string) => void;
|
|
469
|
+
/** The menu closed — by a pick, Escape, a click outside, scroll or resize. Unmount it here. */
|
|
470
|
+
onClose: () => void;
|
|
471
|
+
lang: Lang;
|
|
472
|
+
/** The menu's accessible name, e.g. the conversation's title. */
|
|
473
|
+
label: string;
|
|
474
|
+
/** "auto" (default): below the anchor if it fits, else above. "down": always below. */
|
|
475
|
+
placement?: "auto" | "down";
|
|
476
|
+
/** testids: `<prefix>-menu`, `<prefix>-action-<id>`, `<prefix>-back`, `<prefix>-input`, `<prefix>-save`. Default "item-actions". */
|
|
477
|
+
testidPrefix?: string;
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* F092.29 — the row-action menu on its own, so a title «⌄» and a sidebar row «…»
|
|
481
|
+
* open THE SAME menu (scout #2745). The sidebar's row menu is this component: one
|
|
482
|
+
* implementation, so keyboard, confirm, input and submenu cannot drift apart.
|
|
483
|
+
* Mount it while open; it closes itself through onClose.
|
|
484
|
+
*
|
|
485
|
+
* Keys (F092.21/.22): focus moves into the menu when it opens; arrows move real
|
|
486
|
+
* focus; Enter/Space act on the FOCUSED item; a kbd letter picks; ←/Backspace goes
|
|
487
|
+
* back from a submenu; Escape closes and returns focus to the anchor.
|
|
488
|
+
*/
|
|
489
|
+
declare function ItemActionsMenu(props: ItemActionsMenuProps): JSX.Element;
|
|
462
490
|
interface SidebarProps {
|
|
463
491
|
groups: PreactNavGroup[];
|
|
464
492
|
footer?: PreactNavItem[];
|
|
@@ -774,4 +802,4 @@ interface ConfirmDialogProps {
|
|
|
774
802
|
}
|
|
775
803
|
declare function ConfirmDialog(p: ConfirmDialogProps): JSX.Element | null;
|
|
776
804
|
|
|
777
|
-
export { AVATAR_MAX_BYTES, AVATAR_TYPES, type AccountAdapter, AccountError, AccountPage, type AccountPageProps, type AccountProfile, type AnalyticsAdapter, type AnalyticsData, type AnalyticsDay, AnalyticsError, AnalyticsPage, type AnalyticsPageProps, AppShell, type AppShellProps, Avatar, ConfirmDialog, type ConfirmDialogProps, type Lang, type NavAction, type NavGroup, type NavItem, type NavSection, type Navigate, NotificationBell, type NotificationBellProps, type NotificationSource, PageHeader, type PageTab, PageTabs, type PreactNavGroup, type PreactNavItem, type ShellUser, Sidebar, type SidebarProps, TEXT, type TenantAdapter, TenantLoadError, type TenantMembershipRow, TenantSwitcher, type TenantSwitcherProps, TopBar, type TopBarProps, UserMenu, type UserMenuItem, type UserMenuProps, type UserMenuSection, accountErrorKind, activeNavLabel, analyticsErrorKind, badgeLabel, changePct, checkAvatarFile, copenhagenDay, createFetchAccountAdapter, createFetchAnalyticsAdapter, createFetchNotificationSource, createFetchTenantAdapter, createMemoryNotificationSource, defaultReauthHref, fillDays, initials, isActivePath, isExternal, readFlag, readSet, relativeTime, safeNavigate, useIsMobile, writeFlag, writeSet };
|
|
805
|
+
export { AVATAR_MAX_BYTES, AVATAR_TYPES, type AccountAdapter, AccountError, AccountPage, type AccountPageProps, type AccountProfile, type AnalyticsAdapter, type AnalyticsData, type AnalyticsDay, AnalyticsError, AnalyticsPage, type AnalyticsPageProps, AppShell, type AppShellProps, Avatar, ConfirmDialog, type ConfirmDialogProps, ItemActionsMenu, type ItemActionsMenuProps, type Lang, type NavAction, type NavGroup, type NavItem, type NavSection, type Navigate, NotificationBell, type NotificationBellProps, type NotificationSource, PageHeader, type PageTab, PageTabs, type PreactNavGroup, type PreactNavItem, type ShellUser, Sidebar, type SidebarProps, TEXT, type TenantAdapter, TenantLoadError, type TenantMembershipRow, TenantSwitcher, type TenantSwitcherProps, TopBar, type TopBarProps, UserMenu, type UserMenuItem, type UserMenuProps, type UserMenuSection, accountErrorKind, activeNavLabel, analyticsErrorKind, badgeLabel, changePct, checkAvatarFile, copenhagenDay, createFetchAccountAdapter, createFetchAnalyticsAdapter, createFetchNotificationSource, createFetchTenantAdapter, createMemoryNotificationSource, defaultReauthHref, fillDays, initials, isActivePath, isExternal, readFlag, readSet, relativeTime, safeNavigate, useIsMobile, writeFlag, writeSet };
|
package/dist/preact.d.ts
CHANGED
|
@@ -459,6 +459,34 @@ type PreactNavGroup = NavGroup<Icon>;
|
|
|
459
459
|
type Navigate = (href: string) => void;
|
|
460
460
|
/** True below 768px. Follows the window as it resizes. */
|
|
461
461
|
declare function useIsMobile(): boolean;
|
|
462
|
+
interface ItemActionsMenuProps {
|
|
463
|
+
/** The menu's items — the same NavAction[] a sidebar row takes (kbd, submenu, input, confirm, danger). */
|
|
464
|
+
actions: NavAction[];
|
|
465
|
+
/** What the menu opens from: positioned from it, and focus returns to it on close. */
|
|
466
|
+
anchor: HTMLElement;
|
|
467
|
+
/** An action was chosen (value = the text, for an input action). The menu has closed. */
|
|
468
|
+
onAction: (actionId: string, value?: string) => void;
|
|
469
|
+
/** The menu closed — by a pick, Escape, a click outside, scroll or resize. Unmount it here. */
|
|
470
|
+
onClose: () => void;
|
|
471
|
+
lang: Lang;
|
|
472
|
+
/** The menu's accessible name, e.g. the conversation's title. */
|
|
473
|
+
label: string;
|
|
474
|
+
/** "auto" (default): below the anchor if it fits, else above. "down": always below. */
|
|
475
|
+
placement?: "auto" | "down";
|
|
476
|
+
/** testids: `<prefix>-menu`, `<prefix>-action-<id>`, `<prefix>-back`, `<prefix>-input`, `<prefix>-save`. Default "item-actions". */
|
|
477
|
+
testidPrefix?: string;
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* F092.29 — the row-action menu on its own, so a title «⌄» and a sidebar row «…»
|
|
481
|
+
* open THE SAME menu (scout #2745). The sidebar's row menu is this component: one
|
|
482
|
+
* implementation, so keyboard, confirm, input and submenu cannot drift apart.
|
|
483
|
+
* Mount it while open; it closes itself through onClose.
|
|
484
|
+
*
|
|
485
|
+
* Keys (F092.21/.22): focus moves into the menu when it opens; arrows move real
|
|
486
|
+
* focus; Enter/Space act on the FOCUSED item; a kbd letter picks; ←/Backspace goes
|
|
487
|
+
* back from a submenu; Escape closes and returns focus to the anchor.
|
|
488
|
+
*/
|
|
489
|
+
declare function ItemActionsMenu(props: ItemActionsMenuProps): JSX.Element;
|
|
462
490
|
interface SidebarProps {
|
|
463
491
|
groups: PreactNavGroup[];
|
|
464
492
|
footer?: PreactNavItem[];
|
|
@@ -774,4 +802,4 @@ interface ConfirmDialogProps {
|
|
|
774
802
|
}
|
|
775
803
|
declare function ConfirmDialog(p: ConfirmDialogProps): JSX.Element | null;
|
|
776
804
|
|
|
777
|
-
export { AVATAR_MAX_BYTES, AVATAR_TYPES, type AccountAdapter, AccountError, AccountPage, type AccountPageProps, type AccountProfile, type AnalyticsAdapter, type AnalyticsData, type AnalyticsDay, AnalyticsError, AnalyticsPage, type AnalyticsPageProps, AppShell, type AppShellProps, Avatar, ConfirmDialog, type ConfirmDialogProps, type Lang, type NavAction, type NavGroup, type NavItem, type NavSection, type Navigate, NotificationBell, type NotificationBellProps, type NotificationSource, PageHeader, type PageTab, PageTabs, type PreactNavGroup, type PreactNavItem, type ShellUser, Sidebar, type SidebarProps, TEXT, type TenantAdapter, TenantLoadError, type TenantMembershipRow, TenantSwitcher, type TenantSwitcherProps, TopBar, type TopBarProps, UserMenu, type UserMenuItem, type UserMenuProps, type UserMenuSection, accountErrorKind, activeNavLabel, analyticsErrorKind, badgeLabel, changePct, checkAvatarFile, copenhagenDay, createFetchAccountAdapter, createFetchAnalyticsAdapter, createFetchNotificationSource, createFetchTenantAdapter, createMemoryNotificationSource, defaultReauthHref, fillDays, initials, isActivePath, isExternal, readFlag, readSet, relativeTime, safeNavigate, useIsMobile, writeFlag, writeSet };
|
|
805
|
+
export { AVATAR_MAX_BYTES, AVATAR_TYPES, type AccountAdapter, AccountError, AccountPage, type AccountPageProps, type AccountProfile, type AnalyticsAdapter, type AnalyticsData, type AnalyticsDay, AnalyticsError, AnalyticsPage, type AnalyticsPageProps, AppShell, type AppShellProps, Avatar, ConfirmDialog, type ConfirmDialogProps, ItemActionsMenu, type ItemActionsMenuProps, type Lang, type NavAction, type NavGroup, type NavItem, type NavSection, type Navigate, NotificationBell, type NotificationBellProps, type NotificationSource, PageHeader, type PageTab, PageTabs, type PreactNavGroup, type PreactNavItem, type ShellUser, Sidebar, type SidebarProps, TEXT, type TenantAdapter, TenantLoadError, type TenantMembershipRow, TenantSwitcher, type TenantSwitcherProps, TopBar, type TopBarProps, UserMenu, type UserMenuItem, type UserMenuProps, type UserMenuSection, accountErrorKind, activeNavLabel, analyticsErrorKind, badgeLabel, changePct, checkAvatarFile, copenhagenDay, createFetchAccountAdapter, createFetchAnalyticsAdapter, createFetchNotificationSource, createFetchTenantAdapter, createMemoryNotificationSource, defaultReauthHref, fillDays, initials, isActivePath, isExternal, readFlag, readSet, relativeTime, safeNavigate, useIsMobile, writeFlag, writeSet };
|
package/dist/preact.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { useState, useEffect, useRef,
|
|
1
|
+
import { useState, useEffect, useRef, useLayoutEffect, useMemo } from 'preact/hooks';
|
|
2
2
|
import { createBellShell } from '@broberg/notifications/shell';
|
|
3
3
|
import { selectKeyReducer } from '@broberg/ui-controls-core';
|
|
4
4
|
import { getPreference, getPalette, getSurfaces, getBackdrop, onThemeChange, onPaletteChange, onSurfacesChange, onBackdropChange, setPreference, setPalette, PALETTES, PALETTE_LABELS, setSurfaces, setBackdrop } from '@broberg/theme';
|
|
5
|
-
import { jsxs,
|
|
5
|
+
import { jsxs, jsx, Fragment } from 'preact/jsx-runtime';
|
|
6
6
|
|
|
7
7
|
// src/preact.tsx
|
|
8
8
|
|
|
@@ -514,12 +514,17 @@ var IconBuilding = () => svg(/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
|
514
514
|
/* @__PURE__ */ jsx("path", { d: "M9 22v-4h6v4" }),
|
|
515
515
|
/* @__PURE__ */ jsx("path", { d: "M8 6h.01M16 6h.01M12 6h.01M12 10h.01M12 14h.01M16 10h.01M16 14h.01M8 10h.01M8 14h.01" })
|
|
516
516
|
] }), 15);
|
|
517
|
-
function
|
|
517
|
+
function ItemActionsMenu(props) {
|
|
518
518
|
const t = TEXT[props.lang];
|
|
519
|
-
const
|
|
520
|
-
const btn = useRef(null);
|
|
519
|
+
const pre = props.testidPrefix ?? "item-actions";
|
|
521
520
|
const menu = useRef(null);
|
|
522
|
-
const [
|
|
521
|
+
const first = [{ kind: "list", actions: props.actions }];
|
|
522
|
+
const [stack, setStack] = useState(first);
|
|
523
|
+
const stackRef = useRef(first);
|
|
524
|
+
const setStackNow = (next) => {
|
|
525
|
+
stackRef.current = next;
|
|
526
|
+
setStack(next);
|
|
527
|
+
};
|
|
523
528
|
const [hi, setHiState] = useState(0);
|
|
524
529
|
const hiRef = useRef(0);
|
|
525
530
|
const setHi = (n) => {
|
|
@@ -538,16 +543,12 @@ function RowActions(props) {
|
|
|
538
543
|
const [value, setValue] = useState("");
|
|
539
544
|
const [pos, setPos] = useState(void 0);
|
|
540
545
|
const view = stack[stack.length - 1];
|
|
541
|
-
const
|
|
542
|
-
const stackRef = useRef([]);
|
|
543
|
-
const setStackNow = (next) => {
|
|
544
|
-
stackRef.current = next;
|
|
545
|
-
setStack(next);
|
|
546
|
-
};
|
|
546
|
+
const closed = useRef(false);
|
|
547
547
|
const close = (refocus = true) => {
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
if (refocus)
|
|
548
|
+
if (closed.current) return;
|
|
549
|
+
closed.current = true;
|
|
550
|
+
if (refocus) props.anchor.focus();
|
|
551
|
+
props.onClose();
|
|
551
552
|
};
|
|
552
553
|
const show = (v) => {
|
|
553
554
|
setStackNow([...stackRef.current, v]);
|
|
@@ -572,25 +573,24 @@ function RowActions(props) {
|
|
|
572
573
|
props.onAction(a.id, value);
|
|
573
574
|
};
|
|
574
575
|
useLayoutEffect(() => {
|
|
575
|
-
|
|
576
|
-
const r = btn.current.getBoundingClientRect();
|
|
576
|
+
const r = props.anchor.getBoundingClientRect();
|
|
577
577
|
const vw = window.innerWidth, vh = window.innerHeight, m = 8;
|
|
578
578
|
const w = Math.min(240, vw - 2 * m);
|
|
579
579
|
const h = menu.current?.offsetHeight ?? 0;
|
|
580
580
|
const left = Math.max(m, Math.min(r.right - w, vw - w - m));
|
|
581
|
-
const
|
|
581
|
+
const fitsBelow = r.bottom + 4 + h <= vh - m;
|
|
582
|
+
const top = props.placement === "down" || fitsBelow || r.top - 4 - h < m ? Math.min(r.bottom + 4, vh - m - h) : r.top - 4 - h;
|
|
582
583
|
setPos({ position: "fixed", left: `${left}px`, top: `${Math.max(m, top)}px`, width: `${w}px` });
|
|
583
|
-
}, [
|
|
584
|
+
}, [stack.length]);
|
|
584
585
|
useLayoutEffect(() => {
|
|
585
|
-
if (!
|
|
586
|
-
if (view
|
|
586
|
+
if (!pos) return;
|
|
587
|
+
if (view.kind === "input") menu.current?.querySelector("input")?.focus();
|
|
587
588
|
else items.current[hiRef.current]?.focus();
|
|
588
|
-
}, [
|
|
589
|
+
}, [pos, hi, stack.length]);
|
|
589
590
|
useLayoutEffect(() => {
|
|
590
|
-
if (!open) return;
|
|
591
591
|
const outside = (e) => {
|
|
592
592
|
const n = e.target instanceof Node ? e.target : null;
|
|
593
|
-
if (n && (menu.current?.contains(n) ||
|
|
593
|
+
if (n && (menu.current?.contains(n) || props.anchor.contains(n))) return;
|
|
594
594
|
close(false);
|
|
595
595
|
};
|
|
596
596
|
const early = (e) => {
|
|
@@ -609,8 +609,9 @@ function RowActions(props) {
|
|
|
609
609
|
window.removeEventListener("scroll", outside, true);
|
|
610
610
|
window.removeEventListener("resize", outside);
|
|
611
611
|
};
|
|
612
|
-
}, [
|
|
612
|
+
}, []);
|
|
613
613
|
const onKeyDown = (e) => {
|
|
614
|
+
if (closed.current) return;
|
|
614
615
|
const stack2 = stackRef.current;
|
|
615
616
|
const view2 = stack2[stack2.length - 1];
|
|
616
617
|
if (!view2) return;
|
|
@@ -653,6 +654,82 @@ function RowActions(props) {
|
|
|
653
654
|
}
|
|
654
655
|
};
|
|
655
656
|
onKeyDownRef.current = onKeyDown;
|
|
657
|
+
return /* @__PURE__ */ jsxs(
|
|
658
|
+
"div",
|
|
659
|
+
{
|
|
660
|
+
ref: menu,
|
|
661
|
+
class: "bas-rowmenu",
|
|
662
|
+
role: "menu",
|
|
663
|
+
tabIndex: -1,
|
|
664
|
+
"aria-label": view.kind === "list" && view.title ? view.title : props.label,
|
|
665
|
+
"data-testid": `${pre}-menu`,
|
|
666
|
+
style: pos ?? { position: "fixed", visibility: "hidden" },
|
|
667
|
+
onKeyDown,
|
|
668
|
+
children: [
|
|
669
|
+
stack.length > 1 ? /* @__PURE__ */ jsxs("button", { type: "button", class: "bas-rowmenu__back", "data-testid": `${pre}-back`, "aria-label": t.back, onClick: back, children: [
|
|
670
|
+
/* @__PURE__ */ jsx(IconChevronLeft, {}),
|
|
671
|
+
/* @__PURE__ */ jsx("span", { children: view.kind === "list" ? view.title : view.action.label })
|
|
672
|
+
] }) : null,
|
|
673
|
+
view.kind === "list" ? view.actions.map((a, i) => /* @__PURE__ */ jsxs(
|
|
674
|
+
"button",
|
|
675
|
+
{
|
|
676
|
+
type: "button",
|
|
677
|
+
role: "menuitem",
|
|
678
|
+
ref: (el) => {
|
|
679
|
+
items.current[i] = el;
|
|
680
|
+
},
|
|
681
|
+
tabIndex: i === hi ? 0 : -1,
|
|
682
|
+
class: "bas-rowmenu__item" + (i === hi ? " is-active" : "") + (a.danger ? " is-danger" : "") + (armed === a.id ? " is-armed" : ""),
|
|
683
|
+
"data-testid": `${pre}-action-${a.id}`,
|
|
684
|
+
onMouseEnter: () => setHi(i),
|
|
685
|
+
onFocus: () => setHi(i),
|
|
686
|
+
onClick: () => pick(a),
|
|
687
|
+
children: [
|
|
688
|
+
a.icon ? /* @__PURE__ */ jsx("span", { class: "bas-rowmenu__icon", children: a.icon }) : null,
|
|
689
|
+
/* @__PURE__ */ jsx("span", { class: "bas-rowmenu__label", children: armed === a.id && a.confirm ? a.confirm.label : a.label }),
|
|
690
|
+
a.submenu?.length ? /* @__PURE__ */ jsx(IconChevronRight, {}) : a.kbd ? /* @__PURE__ */ jsx("kbd", { class: "bas-rowmenu__kbd", children: a.kbd.toUpperCase() }) : null
|
|
691
|
+
]
|
|
692
|
+
},
|
|
693
|
+
a.id
|
|
694
|
+
)) : /* @__PURE__ */ jsxs(
|
|
695
|
+
"form",
|
|
696
|
+
{
|
|
697
|
+
class: "bas-rowmenu__form",
|
|
698
|
+
"data-testid": `${pre}-form`,
|
|
699
|
+
onSubmit: (e) => {
|
|
700
|
+
e.preventDefault();
|
|
701
|
+
save(view.action);
|
|
702
|
+
},
|
|
703
|
+
children: [
|
|
704
|
+
/* @__PURE__ */ jsx(
|
|
705
|
+
"input",
|
|
706
|
+
{
|
|
707
|
+
class: "bas-rowmenu__input",
|
|
708
|
+
"data-testid": `${pre}-input`,
|
|
709
|
+
"aria-label": view.action.label,
|
|
710
|
+
value,
|
|
711
|
+
placeholder: view.action.input.placeholder,
|
|
712
|
+
onInput: (e) => setValue(e.currentTarget.value)
|
|
713
|
+
}
|
|
714
|
+
),
|
|
715
|
+
/* @__PURE__ */ jsx("button", { type: "submit", class: "bas-rowmenu__save", "data-testid": `${pre}-save`, children: view.action.input.saveLabel ?? t.save })
|
|
716
|
+
]
|
|
717
|
+
}
|
|
718
|
+
)
|
|
719
|
+
]
|
|
720
|
+
}
|
|
721
|
+
);
|
|
722
|
+
}
|
|
723
|
+
function RowActions(props) {
|
|
724
|
+
const t = TEXT[props.lang];
|
|
725
|
+
const id = props.item.id;
|
|
726
|
+
const btn = useRef(null);
|
|
727
|
+
const [open, setOpenState] = useState(false);
|
|
728
|
+
const openRef = useRef(false);
|
|
729
|
+
const setOpen = (v) => {
|
|
730
|
+
openRef.current = v;
|
|
731
|
+
setOpenState(v);
|
|
732
|
+
};
|
|
656
733
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
657
734
|
/* @__PURE__ */ jsx(
|
|
658
735
|
"button",
|
|
@@ -664,73 +741,24 @@ function RowActions(props) {
|
|
|
664
741
|
"aria-label": `${t.moreFor} ${props.item.label}`,
|
|
665
742
|
"aria-haspopup": "menu",
|
|
666
743
|
"aria-expanded": open,
|
|
667
|
-
onClick: () =>
|
|
744
|
+
onClick: () => {
|
|
745
|
+
if (!openRef.current) return setOpen(true);
|
|
746
|
+
setOpen(false);
|
|
747
|
+
btn.current?.focus();
|
|
748
|
+
},
|
|
668
749
|
children: /* @__PURE__ */ jsx(IconMore, {})
|
|
669
750
|
}
|
|
670
751
|
),
|
|
671
|
-
|
|
672
|
-
|
|
752
|
+
open && btn.current ? /* @__PURE__ */ jsx(
|
|
753
|
+
ItemActionsMenu,
|
|
673
754
|
{
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
onKeyDown,
|
|
682
|
-
children: [
|
|
683
|
-
stack.length > 1 ? /* @__PURE__ */ jsxs("button", { type: "button", class: "bas-rowmenu__back", "data-testid": `sidebar-item-${id}-back`, "aria-label": t.back, onClick: back, children: [
|
|
684
|
-
/* @__PURE__ */ jsx(IconChevronLeft, {}),
|
|
685
|
-
/* @__PURE__ */ jsx("span", { children: view.kind === "list" ? view.title : view.action.label })
|
|
686
|
-
] }) : null,
|
|
687
|
-
view.kind === "list" ? view.actions.map((a, i) => /* @__PURE__ */ jsxs(
|
|
688
|
-
"button",
|
|
689
|
-
{
|
|
690
|
-
type: "button",
|
|
691
|
-
role: "menuitem",
|
|
692
|
-
ref: (el) => {
|
|
693
|
-
items.current[i] = el;
|
|
694
|
-
},
|
|
695
|
-
tabIndex: i === hi ? 0 : -1,
|
|
696
|
-
class: "bas-rowmenu__item" + (i === hi ? " is-active" : "") + (a.danger ? " is-danger" : "") + (armed === a.id ? " is-armed" : ""),
|
|
697
|
-
"data-testid": `sidebar-item-${id}-action-${a.id}`,
|
|
698
|
-
onMouseEnter: () => setHi(i),
|
|
699
|
-
onFocus: () => setHi(i),
|
|
700
|
-
onClick: () => pick(a),
|
|
701
|
-
children: [
|
|
702
|
-
a.icon ? /* @__PURE__ */ jsx("span", { class: "bas-rowmenu__icon", children: a.icon }) : null,
|
|
703
|
-
/* @__PURE__ */ jsx("span", { class: "bas-rowmenu__label", children: armed === a.id && a.confirm ? a.confirm.label : a.label }),
|
|
704
|
-
a.submenu?.length ? /* @__PURE__ */ jsx(IconChevronRight, {}) : a.kbd ? /* @__PURE__ */ jsx("kbd", { class: "bas-rowmenu__kbd", children: a.kbd.toUpperCase() }) : null
|
|
705
|
-
]
|
|
706
|
-
},
|
|
707
|
-
a.id
|
|
708
|
-
)) : /* @__PURE__ */ jsxs(
|
|
709
|
-
"form",
|
|
710
|
-
{
|
|
711
|
-
class: "bas-rowmenu__form",
|
|
712
|
-
"data-testid": `sidebar-item-${id}-form`,
|
|
713
|
-
onSubmit: (e) => {
|
|
714
|
-
e.preventDefault();
|
|
715
|
-
save(view.action);
|
|
716
|
-
},
|
|
717
|
-
children: [
|
|
718
|
-
/* @__PURE__ */ jsx(
|
|
719
|
-
"input",
|
|
720
|
-
{
|
|
721
|
-
class: "bas-rowmenu__input",
|
|
722
|
-
"data-testid": `sidebar-item-${id}-input`,
|
|
723
|
-
"aria-label": view.action.label,
|
|
724
|
-
value,
|
|
725
|
-
placeholder: view.action.input.placeholder,
|
|
726
|
-
onInput: (e) => setValue(e.currentTarget.value)
|
|
727
|
-
}
|
|
728
|
-
),
|
|
729
|
-
/* @__PURE__ */ jsx("button", { type: "submit", class: "bas-rowmenu__save", "data-testid": `sidebar-item-${id}-save`, children: view.action.input.saveLabel ?? t.save })
|
|
730
|
-
]
|
|
731
|
-
}
|
|
732
|
-
)
|
|
733
|
-
]
|
|
755
|
+
actions: props.item.actions,
|
|
756
|
+
anchor: btn.current,
|
|
757
|
+
lang: props.lang,
|
|
758
|
+
label: props.item.label,
|
|
759
|
+
testidPrefix: `sidebar-item-${id}`,
|
|
760
|
+
onAction: props.onAction,
|
|
761
|
+
onClose: () => setOpen(false)
|
|
734
762
|
}
|
|
735
763
|
) : null
|
|
736
764
|
] });
|
|
@@ -2026,6 +2054,6 @@ function ConfirmDialog(p) {
|
|
|
2026
2054
|
);
|
|
2027
2055
|
}
|
|
2028
2056
|
|
|
2029
|
-
export { AVATAR_MAX_BYTES, AVATAR_TYPES, AccountError, AccountPage, AnalyticsError, AnalyticsPage, AppShell, Avatar, ConfirmDialog, NotificationBell, PageHeader, PageTabs, Sidebar, TEXT, TenantLoadError, TenantSwitcher, TopBar, UserMenu, accountErrorKind, activeNavLabel, analyticsErrorKind, badgeLabel, changePct, checkAvatarFile, copenhagenDay, createFetchAccountAdapter, createFetchAnalyticsAdapter, createFetchNotificationSource, createFetchTenantAdapter, createMemoryNotificationSource, defaultReauthHref, fillDays, initials, isActivePath, isExternal, readFlag, readSet, relativeTime, safeNavigate, useIsMobile, writeFlag, writeSet };
|
|
2057
|
+
export { AVATAR_MAX_BYTES, AVATAR_TYPES, AccountError, AccountPage, AnalyticsError, AnalyticsPage, AppShell, Avatar, ConfirmDialog, ItemActionsMenu, NotificationBell, PageHeader, PageTabs, Sidebar, TEXT, TenantLoadError, TenantSwitcher, TopBar, UserMenu, accountErrorKind, activeNavLabel, analyticsErrorKind, badgeLabel, changePct, checkAvatarFile, copenhagenDay, createFetchAccountAdapter, createFetchAnalyticsAdapter, createFetchNotificationSource, createFetchTenantAdapter, createMemoryNotificationSource, defaultReauthHref, fillDays, initials, isActivePath, isExternal, readFlag, readSet, relativeTime, safeNavigate, useIsMobile, writeFlag, writeSet };
|
|
2030
2058
|
//# sourceMappingURL=preact.js.map
|
|
2031
2059
|
//# sourceMappingURL=preact.js.map
|