@pega/cosmos-react-core 9.0.0-build.26.0 → 9.0.0-build.26.2
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/lib/components/AppShell/AppHeader.d.ts.map +1 -1
- package/lib/components/AppShell/AppHeader.js +2 -2
- package/lib/components/AppShell/AppHeader.js.map +1 -1
- package/lib/components/AppShell/AppNavigationPanel.d.ts.map +1 -1
- package/lib/components/AppShell/AppNavigationPanel.js +21 -7
- package/lib/components/AppShell/AppNavigationPanel.js.map +1 -1
- package/lib/components/AppShell/AppShell.d.ts.map +1 -1
- package/lib/components/AppShell/AppShell.js +42 -8
- package/lib/components/AppShell/AppShell.js.map +1 -1
- package/lib/components/AppShell/AppShell.styles.d.ts +4 -0
- package/lib/components/AppShell/AppShell.styles.d.ts.map +1 -1
- package/lib/components/AppShell/AppShell.styles.js +102 -51
- package/lib/components/AppShell/AppShell.styles.js.map +1 -1
- package/lib/components/AppShell/AppShell.types.d.ts +9 -3
- package/lib/components/AppShell/AppShell.types.d.ts.map +1 -1
- package/lib/components/AppShell/AppShell.types.js.map +1 -1
- package/lib/components/AppShell/AppShellContext.d.ts +4 -0
- package/lib/components/AppShell/AppShellContext.d.ts.map +1 -1
- package/lib/components/AppShell/AppShellContext.js +3 -1
- package/lib/components/AppShell/AppShellContext.js.map +1 -1
- package/lib/components/AppShell/AppTopNav.d.ts +4 -0
- package/lib/components/AppShell/AppTopNav.d.ts.map +1 -0
- package/lib/components/AppShell/AppTopNav.js +183 -0
- package/lib/components/AppShell/AppTopNav.js.map +1 -0
- package/lib/components/AppShell/AppTopNav.styles.d.ts +946 -0
- package/lib/components/AppShell/AppTopNav.styles.d.ts.map +1 -0
- package/lib/components/AppShell/AppTopNav.styles.js +184 -0
- package/lib/components/AppShell/AppTopNav.styles.js.map +1 -0
- package/lib/components/AppShell/AppTopNav.types.d.ts +16 -0
- package/lib/components/AppShell/AppTopNav.types.d.ts.map +1 -0
- package/lib/components/AppShell/AppTopNav.types.js +2 -0
- package/lib/components/AppShell/AppTopNav.types.js.map +1 -0
- package/lib/components/AppShell/Drawer.d.ts +3 -1
- package/lib/components/AppShell/Drawer.d.ts.map +1 -1
- package/lib/components/AppShell/Drawer.js +13 -12
- package/lib/components/AppShell/Drawer.js.map +1 -1
- package/lib/components/AppShell/Drawer.styles.d.ts +8 -0
- package/lib/components/AppShell/Drawer.styles.d.ts.map +1 -1
- package/lib/components/AppShell/Drawer.styles.js +15 -0
- package/lib/components/AppShell/Drawer.styles.js.map +1 -1
- package/lib/components/AppShell/TopNavMoreMenu.d.ts +9 -0
- package/lib/components/AppShell/TopNavMoreMenu.d.ts.map +1 -0
- package/lib/components/AppShell/TopNavMoreMenu.js +73 -0
- package/lib/components/AppShell/TopNavMoreMenu.js.map +1 -0
- package/lib/components/AppShell/index.d.ts +1 -1
- package/lib/components/AppShell/index.d.ts.map +1 -1
- package/lib/components/AppShell/index.js.map +1 -1
- package/lib/components/AppShell/useTopNavOverflow.d.ts +17 -0
- package/lib/components/AppShell/useTopNavOverflow.d.ts.map +1 -0
- package/lib/components/AppShell/useTopNavOverflow.js +73 -0
- package/lib/components/AppShell/useTopNavOverflow.js.map +1 -0
- package/lib/components/ComboBox/ComboBox.styles.js +1 -1
- package/lib/components/ComboBox/ComboBox.styles.js.map +1 -1
- package/lib/i18n/default.js +1 -1
- package/lib/i18n/default.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { createContext } from 'react';
|
|
2
2
|
export const AppShellDrawerContext = createContext({
|
|
3
3
|
drawerOpen: false,
|
|
4
|
+
openItemName: undefined,
|
|
4
5
|
openDrawer: () => { },
|
|
5
|
-
closeDrawer: () => { }
|
|
6
|
+
closeDrawer: () => { },
|
|
7
|
+
refreshDrawer: () => { }
|
|
6
8
|
});
|
|
7
9
|
const AppShellContext = createContext({
|
|
8
10
|
navOpen: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppShellContext.js","sourceRoot":"","sources":["../../../src/components/AppShell/AppShellContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"AppShellContext.js","sourceRoot":"","sources":["../../../src/components/AppShell/AppShellContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAiBtC,MAAM,CAAC,MAAM,qBAAqB,GAAG,aAAa,CAA6B;IAC7E,UAAU,EAAE,KAAK;IACjB,YAAY,EAAE,SAAS;IACvB,UAAU,EAAE,GAAG,EAAE,GAAE,CAAC;IACpB,WAAW,EAAE,GAAG,EAAE,GAAE,CAAC;IACrB,aAAa,EAAE,GAAG,EAAE,GAAE,CAAC;CACxB,CAAC,CAAC;AAiBH,MAAM,eAAe,GAAG,aAAa,CAAuB;IAC1D,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,KAAK;IACjB,aAAa,EAAE,GAAG,EAAE,GAAE,CAAC;IACvB,QAAQ,EAAE,QAAQ;IAClB,mBAAmB,EAAE,KAAK;IAC1B,mBAAmB,EAAE;QACnB,IAAI,OAAO;YACT,OAAO,KAAK,CAAC;QACf,CAAC;KACF;IACD,QAAQ,EAAE,IAAI;IACd,iBAAiB,EAAE,IAAI;IACvB,oBAAoB,EAAE,GAAG,EAAE,GAAE,CAAC;IAC9B,WAAW,EAAE,KAAK;IAClB,aAAa,EAAE,KAAK;IACpB,gBAAgB,EAAE,GAAG,EAAE,GAAE,CAAC;CAC3B,CAAC,CAAC;AAEH,eAAe,eAAe,CAAC","sourcesContent":["import { createContext } from 'react';\nimport type { Dispatch, MutableRefObject, SetStateAction } from 'react';\n\nimport type { openCloseStates } from '../../hooks/useTransitionState';\n\nimport type { AppShellProps, UtilItemProps } from './AppShell.types';\n\nexport interface AppShellDrawerContextValue {\n drawerOpen: boolean;\n /** Name of the currently open drawer item; undefined when drawer is closed. */\n openItemName: string | undefined;\n openDrawer: (item: UtilItemProps) => void;\n closeDrawer: () => void;\n /** Replace the currently open drawer item with a fresh copy (e.g. after data loads). */\n refreshDrawer: (item: UtilItemProps) => void;\n}\n\nexport const AppShellDrawerContext = createContext<AppShellDrawerContextValue>({\n drawerOpen: false,\n openItemName: undefined,\n openDrawer: () => {},\n closeDrawer: () => {},\n refreshDrawer: () => {}\n});\n\nexport interface AppShellContextValue {\n navOpen: boolean;\n drawerOpen: boolean;\n setDrawerOpen: (val: boolean) => void;\n navState: (typeof openCloseStates)[keyof typeof openCloseStates];\n focusedImperatively: MutableRefObject<boolean>;\n headerEl: HTMLDivElement | null;\n searchContainerEl: HTMLElement | null;\n setSearchContainerEl: (el: HTMLElement | null) => void;\n collapsedHoverMenus?: AppShellProps['collapsedHoverMenus'];\n isMobileNav: boolean;\n previewActive: boolean;\n setPreviewActive: Dispatch<SetStateAction<boolean>>;\n}\n\nconst AppShellContext = createContext<AppShellContextValue>({\n navOpen: false,\n drawerOpen: false,\n setDrawerOpen: () => {},\n navState: 'closed',\n collapsedHoverMenus: false,\n focusedImperatively: {\n get current() {\n return false;\n }\n },\n headerEl: null,\n searchContainerEl: null,\n setSearchContainerEl: () => {},\n isMobileNav: false,\n previewActive: false,\n setPreviewActive: () => {}\n});\n\nexport default AppShellContext;\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AppTopNavProps } from './AppTopNav.types';
|
|
2
|
+
declare const AppTopNav: ({ caseTypes, links, cases, agent, utils, onUtilItemClick }: AppTopNavProps) => import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export default AppTopNav;
|
|
4
|
+
//# sourceMappingURL=AppTopNav.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppTopNav.d.ts","sourceRoot":"","sources":["../../../src/components/AppShell/AppTopNav.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA+PxD,QAAA,MAAM,SAAS,GAAI,4DAA4D,cAAc,4CAwI5F,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import Icon, { registerIcon } from '../Icon';
|
|
4
|
+
import * as caretDownIcon from '../Icon/icons/caret-down.icon';
|
|
5
|
+
import { useEscape, useFocusWithin, useI18n, useTheme } from '../../hooks';
|
|
6
|
+
import { createStringMatcher, isValidElement } from '../../utils';
|
|
7
|
+
import { isSolidColor } from '../../styles';
|
|
8
|
+
import { ThemeOverride } from '../Configuration';
|
|
9
|
+
import Popover from '../Popover';
|
|
10
|
+
import Menu from '../Menu';
|
|
11
|
+
import { StyledTopNav, StyledTopNavList, StyledTopNavMeasureRow, StyledTopNavSection, StyledTopNavUtilBar, StyledTopNavItem, StyledTopNavItemHidden, StyledTopNavUtilButton, StyledTopNavCountBadge, StyledTopNavCreateArea } from './AppTopNav.styles';
|
|
12
|
+
import { navContrastColors } from './style-utils';
|
|
13
|
+
import { CaseTypes } from './AppNavigationPanel';
|
|
14
|
+
import TopNavMoreMenu from './TopNavMoreMenu';
|
|
15
|
+
import { useTopNavOverflow } from './useTopNavOverflow';
|
|
16
|
+
import { AppShellDrawerContext } from './AppShellContext';
|
|
17
|
+
registerIcon(caretDownIcon);
|
|
18
|
+
const hasActiveDescendant = (link) => {
|
|
19
|
+
if (link.active)
|
|
20
|
+
return true;
|
|
21
|
+
return link.links?.some(hasActiveDescendant) ?? false;
|
|
22
|
+
};
|
|
23
|
+
const linkToFlyoutItem = (link) => {
|
|
24
|
+
const userOnClick = link.onClick;
|
|
25
|
+
const children = link.links?.map(linkToFlyoutItem);
|
|
26
|
+
const hasChildren = children && children.length > 0;
|
|
27
|
+
return {
|
|
28
|
+
id: link.id || link.name,
|
|
29
|
+
primary: link.name,
|
|
30
|
+
visual: link.icon ? _jsx(Icon, { name: link.icon }) : undefined,
|
|
31
|
+
href: hasChildren ? undefined : link.href,
|
|
32
|
+
// MenuItem uses `typeof selected !== 'boolean'` to decide expand vs click.
|
|
33
|
+
selected: hasChildren ? undefined : link.active || undefined,
|
|
34
|
+
onClick: userOnClick
|
|
35
|
+
? (_id, e) => {
|
|
36
|
+
userOnClick(e);
|
|
37
|
+
}
|
|
38
|
+
: undefined,
|
|
39
|
+
items: hasChildren ? children : undefined
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
const TopNavMeasureItem = ({ link }) => {
|
|
43
|
+
const hasChildren = !!link.links && link.links.length > 0;
|
|
44
|
+
return (_jsxs(StyledTopNavItem, { as: 'span', tabIndex: -1, children: [link.icon && _jsx(Icon, { name: link.icon }), _jsx("span", { children: link.name }), hasChildren && _jsx(Icon, { name: 'caret-down' })] }));
|
|
45
|
+
};
|
|
46
|
+
const TopNavLink = ({ link }) => {
|
|
47
|
+
const hasChildren = !!link.links && link.links.length > 0;
|
|
48
|
+
const active = hasActiveDescendant(link);
|
|
49
|
+
const triggerRef = useRef(null);
|
|
50
|
+
const popoverRef = useRef(null);
|
|
51
|
+
const [popoverOpen, setPopoverOpen] = useState(false);
|
|
52
|
+
const [filterValue, setFilterValue] = useState('');
|
|
53
|
+
const close = useCallback(() => setPopoverOpen(false), []);
|
|
54
|
+
useFocusWithin([triggerRef, popoverRef], useCallback((isFocused) => {
|
|
55
|
+
if (!isFocused)
|
|
56
|
+
setPopoverOpen(false);
|
|
57
|
+
}, []));
|
|
58
|
+
useEscape(useCallback((e) => {
|
|
59
|
+
if (popoverOpen) {
|
|
60
|
+
setPopoverOpen(false);
|
|
61
|
+
e.stopPropagation();
|
|
62
|
+
triggerRef.current?.focus();
|
|
63
|
+
}
|
|
64
|
+
}, [popoverOpen])
|
|
65
|
+
// No target: attach to document so Escape works when focus is inside the
|
|
66
|
+
// Popover portal (events don't bubble to the trigger element across portals).
|
|
67
|
+
);
|
|
68
|
+
if (hasChildren && link.links) {
|
|
69
|
+
const allItems = link.links.map(linkToFlyoutItem);
|
|
70
|
+
const useFilter = allItems.length >= 5;
|
|
71
|
+
const filterRegex = createStringMatcher(filterValue, 'contains');
|
|
72
|
+
const items = useFilter
|
|
73
|
+
? allItems.filter(it => filterRegex.test(String(it.primary ?? '')))
|
|
74
|
+
: allItems;
|
|
75
|
+
const handleTriggerClick = () => {
|
|
76
|
+
if (!popoverOpen)
|
|
77
|
+
setFilterValue('');
|
|
78
|
+
setPopoverOpen(v => !v);
|
|
79
|
+
};
|
|
80
|
+
return (_jsxs(_Fragment, { children: [_jsxs(StyledTopNavItem, { ref: triggerRef, "$active": active, "aria-haspopup": 'menu', "aria-expanded": popoverOpen, onClick: handleTriggerClick, children: [link.icon && _jsx(Icon, { name: link.icon }), _jsx("span", { children: link.name }), _jsx(Icon, { name: 'caret-down' })] }), popoverOpen && (_jsx(Popover, { ref: popoverRef, target: triggerRef.current, placement: 'bottom-start', children: _jsx(Menu, { mode: 'action', variant: 'flyout', "aria-label": link.name, items: items, onItemClick: close, focusControlEl: triggerRef.current ?? undefined, ...(useFilter
|
|
81
|
+
? {
|
|
82
|
+
filterInputProps: {
|
|
83
|
+
value: filterValue,
|
|
84
|
+
onChange: (e) => setFilterValue(e.target.value)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
: {}) }) }))] }));
|
|
88
|
+
}
|
|
89
|
+
const handleClick = e => {
|
|
90
|
+
link.onClick?.(e);
|
|
91
|
+
};
|
|
92
|
+
return (_jsxs(StyledTopNavItem, { href: link.href, onClick: handleClick, "$active": active, "aria-current": link.active ? 'page' : undefined, children: [link.icon && _jsx(Icon, { name: link.icon }), _jsx("span", { children: link.name })] }));
|
|
93
|
+
};
|
|
94
|
+
const TopNavUtilItem = ({ item, onUtilItemClick }) => {
|
|
95
|
+
const hasMenu = !!item.actions && item.actions.length > 0;
|
|
96
|
+
const triggerRef = useRef(null);
|
|
97
|
+
const popoverRef = useRef(null);
|
|
98
|
+
const [popoverOpen, setPopoverOpen] = useState(false);
|
|
99
|
+
const close = useCallback(() => setPopoverOpen(false), []);
|
|
100
|
+
useFocusWithin([triggerRef, popoverRef], useCallback((isFocused) => {
|
|
101
|
+
if (!isFocused)
|
|
102
|
+
setPopoverOpen(false);
|
|
103
|
+
}, []));
|
|
104
|
+
useEscape(useCallback((e) => {
|
|
105
|
+
if (popoverOpen) {
|
|
106
|
+
setPopoverOpen(false);
|
|
107
|
+
e.stopPropagation();
|
|
108
|
+
triggerRef.current?.focus();
|
|
109
|
+
}
|
|
110
|
+
}, [popoverOpen]));
|
|
111
|
+
if (hasMenu && item.actions) {
|
|
112
|
+
return (_jsxs(_Fragment, { children: [_jsxs(StyledTopNavUtilButton, { ref: triggerRef, "aria-label": item.count ? `${item.name}, ${String(item.count)}` : item.name, "aria-haspopup": 'menu', "aria-expanded": popoverOpen, onClick: () => setPopoverOpen(v => !v), children: [item.visual, !!item.count && (_jsx(StyledTopNavCountBadge, { "aria-hidden": 'true', children: item.count }))] }), popoverOpen && (_jsx(Popover, { ref: popoverRef, target: triggerRef.current, placement: 'bottom-end', children: _jsx(Menu, { mode: 'action', variant: 'flyout', "aria-label": item.name, items: item.actions.map((act) => ({
|
|
113
|
+
id: act.id ?? act.primary,
|
|
114
|
+
primary: act.primary,
|
|
115
|
+
visual: act.visual,
|
|
116
|
+
href: act.href,
|
|
117
|
+
onClick: act.onClick
|
|
118
|
+
? (_id, e) => {
|
|
119
|
+
act.onClick?.(e);
|
|
120
|
+
close();
|
|
121
|
+
}
|
|
122
|
+
: undefined
|
|
123
|
+
})), onItemClick: close, focusControlEl: triggerRef.current ?? undefined }) }))] }));
|
|
124
|
+
}
|
|
125
|
+
return (_jsxs(StyledTopNavUtilButton, { "aria-label": item.count ? `${item.name}, ${String(item.count)}` : item.name, onClick: (e) => {
|
|
126
|
+
if (item.drawerView) {
|
|
127
|
+
onUtilItemClick?.(item);
|
|
128
|
+
}
|
|
129
|
+
item.onClick?.(e);
|
|
130
|
+
}, children: [item.visual, !!item.count && (_jsx(StyledTopNavCountBadge, { "aria-hidden": 'true', children: item.count }))] }));
|
|
131
|
+
};
|
|
132
|
+
const isUtilItemProps = (u) => !isValidElement(u);
|
|
133
|
+
const AppTopNav = ({ caseTypes, links, cases, agent, utils, onUtilItemClick }) => {
|
|
134
|
+
const t = useI18n();
|
|
135
|
+
const theme = useTheme();
|
|
136
|
+
const { openDrawer, drawerOpen, openItemName, refreshDrawer } = useContext(AppShellDrawerContext);
|
|
137
|
+
useEffect(() => {
|
|
138
|
+
if (!drawerOpen || !openItemName || !utils)
|
|
139
|
+
return;
|
|
140
|
+
const freshItem = utils.filter(isUtilItemProps).find(u => u.name === openItemName);
|
|
141
|
+
if (freshItem)
|
|
142
|
+
refreshDrawer(freshItem);
|
|
143
|
+
}, [utils, drawerOpen, openItemName, refreshDrawer]);
|
|
144
|
+
const handleUtilItemClick = (item) => {
|
|
145
|
+
if (onUtilItemClick) {
|
|
146
|
+
onUtilItemClick(item);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if (item.drawerView) {
|
|
150
|
+
openDrawer(item);
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
const navTheme = useMemo(() => {
|
|
154
|
+
const { foreground, interactive, urgent, backgroundColor } = navContrastColors(theme);
|
|
155
|
+
const navBg = theme.components['app-shell'].nav.background;
|
|
156
|
+
return {
|
|
157
|
+
base: {
|
|
158
|
+
palette: {
|
|
159
|
+
'primary-background': isSolidColor(navBg) ? backgroundColor : 'transparent',
|
|
160
|
+
'foreground-color': foreground,
|
|
161
|
+
interactive,
|
|
162
|
+
urgent
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
}, [theme]);
|
|
167
|
+
const linkList = links ?? [];
|
|
168
|
+
const moreButtonRef = useRef(null);
|
|
169
|
+
const { containerRef, measureRef, result } = useTopNavOverflow(linkList, { moreButtonRef });
|
|
170
|
+
const visibleLinks = linkList.slice(0, result.visibleCount);
|
|
171
|
+
const overflowLinks = linkList.slice(result.visibleCount);
|
|
172
|
+
return (_jsx(ThemeOverride, { theme: navTheme, children: _jsxs(StyledTopNav, { "aria-label": t('app_shell_main_navigation_label'), "data-app-region": true, children: [caseTypes && caseTypes.length > 0 && (_jsx(StyledTopNavCreateArea, { container: { alignItems: 'center' }, item: { shrink: 0 }, children: _jsx(CaseTypes, { caseTypes: caseTypes }) })), _jsxs(StyledTopNavList, { ref: containerRef, container: { alignItems: 'center', gap: 1 }, item: { grow: 1 }, children: [_jsx(StyledTopNavMeasureRow, { ref: measureRef, container: { alignItems: 'center', gap: 1 }, "aria-hidden": 'true', children: linkList.map(link => (_jsx(TopNavMeasureItem, { link: link }, link.id))) }), visibleLinks.map(link => (_jsx(TopNavLink, { link: link }, link.id))), _jsxs(StyledTopNavItemHidden, { ref: moreButtonRef, type: 'button', "aria-hidden": 'true', tabIndex: -1, children: [_jsx(Icon, { name: 'bars' }), _jsx("span", { children: t('app_shell_more') })] }), overflowLinks.length > 0 && (_jsx(TopNavMoreMenu, { items: overflowLinks, label: t('app_shell_more'), active: overflowLinks.some(hasActiveDescendant) }))] }), cases && cases.length > 0 && (_jsx(StyledTopNavSection, { container: { alignItems: 'center', gap: 1 }, item: {}, role: 'group', "aria-label": t('active_cases'), children: cases.map(c => (_jsxs(StyledTopNavItem, { onClick: c.onClick, "$active": !!c.active, "aria-current": c.active ? 'page' : undefined, children: [c.visual ?? _jsx(Icon, { name: 'case-solid' }), _jsx("span", { children: c.primary })] }, c.id))) })), _jsxs(StyledTopNavUtilBar, { container: { alignItems: 'center', gap: 1 }, item: { shrink: 0 }, children: [agent && (_jsx(StyledTopNavUtilButton, { "aria-label": agent.name, "aria-current": agent.active ? 'page' : undefined, onClick: (e) => {
|
|
173
|
+
agent.onClick?.(e);
|
|
174
|
+
}, children: agent.icon })), utils?.map((util, idx) => {
|
|
175
|
+
if (isValidElement(util)) {
|
|
176
|
+
const utilKey = util.key ?? `util-el-${String(idx)}`;
|
|
177
|
+
return _jsx("span", { children: util }, utilKey);
|
|
178
|
+
}
|
|
179
|
+
return (_jsx(TopNavUtilItem, { item: util, onUtilItemClick: handleUtilItemClick }, util.name));
|
|
180
|
+
})] })] }) }));
|
|
181
|
+
};
|
|
182
|
+
export default AppTopNav;
|
|
183
|
+
//# sourceMappingURL=AppTopNav.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppTopNav.js","sourceRoot":"","sources":["../../../src/components/AppShell/AppTopNav.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';\nimport type { ChangeEvent, MouseEvent, MouseEventHandler, ReactElement } from 'react';\n\nimport Icon, { registerIcon } from '../Icon';\nimport * as caretDownIcon from '../Icon/icons/caret-down.icon';\nimport { useEscape, useFocusWithin, useI18n, useTheme } from '../../hooks';\nimport { createStringMatcher, isValidElement } from '../../utils';\nimport { isSolidColor } from '../../styles';\nimport { ThemeOverride } from '../Configuration';\nimport Popover from '../Popover';\nimport Menu from '../Menu';\nimport type { MenuItemProps } from '../Menu';\n\nimport type { AppTopNavProps } from './AppTopNav.types';\nimport type { LinkProps, OperatorProps, UtilItemProps } from './AppShell.types';\nimport {\n StyledTopNav,\n StyledTopNavList,\n StyledTopNavMeasureRow,\n StyledTopNavSection,\n StyledTopNavUtilBar,\n StyledTopNavItem,\n StyledTopNavItemHidden,\n StyledTopNavUtilButton,\n StyledTopNavCountBadge,\n StyledTopNavCreateArea\n} from './AppTopNav.styles';\nimport { navContrastColors } from './style-utils';\nimport { CaseTypes } from './AppNavigationPanel';\nimport TopNavMoreMenu from './TopNavMoreMenu';\nimport { useTopNavOverflow } from './useTopNavOverflow';\nimport { AppShellDrawerContext } from './AppShellContext';\n\nregisterIcon(caretDownIcon);\n\nconst hasActiveDescendant = (link: LinkProps): boolean => {\n if (link.active) return true;\n return link.links?.some(hasActiveDescendant) ?? false;\n};\n\nconst linkToFlyoutItem = (link: LinkProps): MenuItemProps => {\n const userOnClick = link.onClick;\n const children = link.links?.map(linkToFlyoutItem);\n const hasChildren = children && children.length > 0;\n return {\n id: link.id || link.name,\n primary: link.name,\n visual: link.icon ? <Icon name={link.icon} /> : undefined,\n href: hasChildren ? undefined : link.href,\n // MenuItem uses `typeof selected !== 'boolean'` to decide expand vs click.\n selected: hasChildren ? undefined : link.active || undefined,\n onClick: userOnClick\n ? (_id, e) => {\n userOnClick(e);\n }\n : undefined,\n items: hasChildren ? children : undefined\n };\n};\n\nconst TopNavMeasureItem = ({ link }: { link: LinkProps }) => {\n const hasChildren = !!link.links && link.links.length > 0;\n return (\n <StyledTopNavItem as='span' tabIndex={-1}>\n {link.icon && <Icon name={link.icon} />}\n <span>{link.name}</span>\n {hasChildren && <Icon name='caret-down' />}\n </StyledTopNavItem>\n );\n};\n\nconst TopNavLink = ({ link }: { link: LinkProps }) => {\n const hasChildren = !!link.links && link.links.length > 0;\n const active = hasActiveDescendant(link);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const popoverRef = useRef<HTMLDivElement>(null);\n const [popoverOpen, setPopoverOpen] = useState(false);\n const [filterValue, setFilterValue] = useState('');\n\n const close = useCallback(() => setPopoverOpen(false), []);\n\n useFocusWithin<HTMLElement>(\n [triggerRef, popoverRef],\n useCallback((isFocused: boolean) => {\n if (!isFocused) setPopoverOpen(false);\n }, [])\n );\n\n useEscape(\n useCallback(\n (e: KeyboardEvent) => {\n if (popoverOpen) {\n setPopoverOpen(false);\n e.stopPropagation();\n triggerRef.current?.focus();\n }\n },\n [popoverOpen]\n )\n // No target: attach to document so Escape works when focus is inside the\n // Popover portal (events don't bubble to the trigger element across portals).\n );\n\n if (hasChildren && link.links) {\n const allItems = link.links.map(linkToFlyoutItem);\n const useFilter = allItems.length >= 5;\n const filterRegex = createStringMatcher(filterValue, 'contains');\n const items = useFilter\n ? allItems.filter(it => filterRegex.test(String(it.primary ?? '')))\n : allItems;\n\n const handleTriggerClick = () => {\n if (!popoverOpen) setFilterValue('');\n setPopoverOpen(v => !v);\n };\n\n return (\n <>\n <StyledTopNavItem\n ref={triggerRef}\n $active={active}\n aria-haspopup='menu'\n aria-expanded={popoverOpen}\n onClick={handleTriggerClick}\n >\n {link.icon && <Icon name={link.icon} />}\n <span>{link.name}</span>\n <Icon name='caret-down' />\n </StyledTopNavItem>\n {popoverOpen && (\n <Popover ref={popoverRef} target={triggerRef.current} placement='bottom-start'>\n <Menu\n mode='action'\n variant='flyout'\n aria-label={link.name}\n items={items}\n onItemClick={close}\n focusControlEl={triggerRef.current ?? undefined}\n {...(useFilter\n ? {\n filterInputProps: {\n value: filterValue,\n onChange: (e: ChangeEvent<HTMLInputElement>) => setFilterValue(e.target.value)\n }\n }\n : {})}\n />\n </Popover>\n )}\n </>\n );\n }\n\n const handleClick: MouseEventHandler<HTMLElement> = e => {\n link.onClick?.(e);\n };\n\n return (\n <StyledTopNavItem\n href={link.href}\n onClick={handleClick}\n $active={active}\n aria-current={link.active ? 'page' : undefined}\n >\n {link.icon && <Icon name={link.icon} />}\n <span>{link.name}</span>\n </StyledTopNavItem>\n );\n};\n\nconst TopNavUtilItem = ({\n item,\n onUtilItemClick\n}: {\n item: UtilItemProps;\n onUtilItemClick?: (item: UtilItemProps) => void;\n}) => {\n const hasMenu = !!item.actions && item.actions.length > 0;\n const triggerRef = useRef<HTMLButtonElement>(null);\n const popoverRef = useRef<HTMLDivElement>(null);\n const [popoverOpen, setPopoverOpen] = useState(false);\n\n const close = useCallback(() => setPopoverOpen(false), []);\n\n useFocusWithin<HTMLElement>(\n [triggerRef, popoverRef],\n useCallback((isFocused: boolean) => {\n if (!isFocused) setPopoverOpen(false);\n }, [])\n );\n\n useEscape(\n useCallback(\n (e: KeyboardEvent) => {\n if (popoverOpen) {\n setPopoverOpen(false);\n e.stopPropagation();\n triggerRef.current?.focus();\n }\n },\n [popoverOpen]\n )\n );\n\n if (hasMenu && item.actions) {\n return (\n <>\n <StyledTopNavUtilButton\n ref={triggerRef}\n aria-label={item.count ? `${item.name}, ${String(item.count)}` : item.name}\n aria-haspopup='menu'\n aria-expanded={popoverOpen}\n onClick={() => setPopoverOpen(v => !v)}\n >\n {item.visual}\n {!!item.count && (\n <StyledTopNavCountBadge aria-hidden='true'>{item.count}</StyledTopNavCountBadge>\n )}\n </StyledTopNavUtilButton>\n {popoverOpen && (\n <Popover ref={popoverRef} target={triggerRef.current} placement='bottom-end'>\n <Menu\n mode='action'\n variant='flyout'\n aria-label={item.name}\n items={item.actions.map(\n (act: OperatorProps['actions'][number]): MenuItemProps => ({\n id: act.id ?? act.primary,\n primary: act.primary,\n visual: act.visual,\n href: act.href,\n onClick: act.onClick\n ? (_id, e) => {\n act.onClick?.(e);\n close();\n }\n : undefined\n })\n )}\n onItemClick={close}\n focusControlEl={triggerRef.current ?? undefined}\n />\n </Popover>\n )}\n </>\n );\n }\n\n return (\n <StyledTopNavUtilButton\n aria-label={item.count ? `${item.name}, ${String(item.count)}` : item.name}\n onClick={(e: MouseEvent<HTMLElement>) => {\n if (item.drawerView) {\n onUtilItemClick?.(item);\n }\n item.onClick?.(e);\n }}\n >\n {item.visual}\n {!!item.count && (\n <StyledTopNavCountBadge aria-hidden='true'>{item.count}</StyledTopNavCountBadge>\n )}\n </StyledTopNavUtilButton>\n );\n};\n\nconst isUtilItemProps = (u: UtilItemProps | ReactElement): u is UtilItemProps => !isValidElement(u);\n\nconst AppTopNav = ({ caseTypes, links, cases, agent, utils, onUtilItemClick }: AppTopNavProps) => {\n const t = useI18n();\n const theme = useTheme();\n const { openDrawer, drawerOpen, openItemName, refreshDrawer } = useContext(AppShellDrawerContext);\n\n useEffect(() => {\n if (!drawerOpen || !openItemName || !utils) return;\n const freshItem = utils.filter(isUtilItemProps).find(u => u.name === openItemName);\n if (freshItem) refreshDrawer(freshItem);\n }, [utils, drawerOpen, openItemName, refreshDrawer]);\n\n const handleUtilItemClick = (item: UtilItemProps) => {\n if (onUtilItemClick) {\n onUtilItemClick(item);\n return;\n }\n if (item.drawerView) {\n openDrawer(item);\n }\n };\n\n const navTheme = useMemo(() => {\n const { foreground, interactive, urgent, backgroundColor } = navContrastColors(theme);\n const navBg = theme.components['app-shell'].nav.background;\n return {\n base: {\n palette: {\n 'primary-background': isSolidColor(navBg) ? backgroundColor : 'transparent',\n 'foreground-color': foreground,\n interactive,\n urgent\n }\n }\n };\n }, [theme]);\n\n const linkList = links ?? [];\n const moreButtonRef = useRef<HTMLButtonElement>(null);\n const { containerRef, measureRef, result } = useTopNavOverflow(linkList, { moreButtonRef });\n\n const visibleLinks = linkList.slice(0, result.visibleCount);\n const overflowLinks = linkList.slice(result.visibleCount);\n\n return (\n <ThemeOverride theme={navTheme}>\n <StyledTopNav aria-label={t('app_shell_main_navigation_label')} data-app-region>\n {caseTypes && caseTypes.length > 0 && (\n <StyledTopNavCreateArea container={{ alignItems: 'center' }} item={{ shrink: 0 }}>\n <CaseTypes caseTypes={caseTypes} />\n </StyledTopNavCreateArea>\n )}\n\n <StyledTopNavList\n ref={containerRef}\n container={{ alignItems: 'center', gap: 1 }}\n item={{ grow: 1 }}\n >\n <StyledTopNavMeasureRow\n ref={measureRef}\n container={{ alignItems: 'center', gap: 1 }}\n aria-hidden='true'\n >\n {linkList.map(link => (\n <TopNavMeasureItem key={link.id} link={link} />\n ))}\n </StyledTopNavMeasureRow>\n\n {visibleLinks.map(link => (\n <TopNavLink key={link.id} link={link} />\n ))}\n\n <StyledTopNavItemHidden\n ref={moreButtonRef}\n type='button'\n aria-hidden='true'\n tabIndex={-1}\n >\n <Icon name='bars' />\n <span>{t('app_shell_more')}</span>\n </StyledTopNavItemHidden>\n\n {overflowLinks.length > 0 && (\n <TopNavMoreMenu\n items={overflowLinks}\n label={t('app_shell_more')}\n active={overflowLinks.some(hasActiveDescendant)}\n />\n )}\n </StyledTopNavList>\n\n {cases && cases.length > 0 && (\n <StyledTopNavSection\n container={{ alignItems: 'center', gap: 1 }}\n item={{}}\n role='group'\n aria-label={t('active_cases')}\n >\n {cases.map(c => (\n <StyledTopNavItem\n key={c.id}\n onClick={c.onClick}\n $active={!!c.active}\n aria-current={c.active ? 'page' : undefined}\n >\n {c.visual ?? <Icon name='case-solid' />}\n <span>{c.primary}</span>\n </StyledTopNavItem>\n ))}\n </StyledTopNavSection>\n )}\n\n <StyledTopNavUtilBar container={{ alignItems: 'center', gap: 1 }} item={{ shrink: 0 }}>\n {agent && (\n <StyledTopNavUtilButton\n aria-label={agent.name}\n aria-current={agent.active ? 'page' : undefined}\n onClick={(e: MouseEvent<HTMLElement>) => {\n agent.onClick?.(e);\n }}\n >\n {agent.icon}\n </StyledTopNavUtilButton>\n )}\n {utils?.map((util, idx) => {\n if (isValidElement(util)) {\n const utilKey = util.key ?? `util-el-${String(idx)}`;\n return <span key={utilKey}>{util}</span>;\n }\n return (\n <TopNavUtilItem key={util.name} item={util} onUtilItemClick={handleUtilItemClick} />\n );\n })}\n </StyledTopNavUtilBar>\n </StyledTopNav>\n </ThemeOverride>\n );\n};\n\nexport default AppTopNav;\n"]}
|