@flipdish/ui-library 0.29.0 → 0.31.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/components/atoms/Input/index.cjs +3 -1
- package/dist/components/atoms/Input/index.cjs.map +1 -1
- package/dist/components/atoms/Input/index.d.ts +5 -1
- package/dist/components/atoms/Input/index.d.ts.map +1 -1
- package/dist/components/atoms/Input/index.js +3 -1
- package/dist/components/atoms/Input/index.js.map +1 -1
- package/dist/components/molecules/Select/components/combobox.cjs +3 -1
- package/dist/components/molecules/Select/components/combobox.cjs.map +1 -1
- package/dist/components/molecules/Select/components/combobox.d.ts.map +1 -1
- package/dist/components/molecules/Select/components/combobox.js +3 -1
- package/dist/components/molecules/Select/components/combobox.js.map +1 -1
- package/dist/components/organisms/ApplicationHeader/applicationHeader.types.d.ts +12 -5
- package/dist/components/organisms/ApplicationHeader/applicationHeader.types.d.ts.map +1 -1
- package/dist/components/organisms/ApplicationHeader/index.cjs +12 -17
- package/dist/components/organisms/ApplicationHeader/index.cjs.map +1 -1
- package/dist/components/organisms/ApplicationHeader/index.d.ts +9 -5
- package/dist/components/organisms/ApplicationHeader/index.d.ts.map +1 -1
- package/dist/components/organisms/ApplicationHeader/index.js +12 -18
- package/dist/components/organisms/ApplicationHeader/index.js.map +1 -1
- package/dist/components/organisms/Calendar/index.cjs +3 -3
- package/dist/components/organisms/Calendar/index.cjs.map +1 -1
- package/dist/components/organisms/Calendar/index.js +3 -3
- package/dist/components/organisms/Calendar/index.js.map +1 -1
- package/dist/components/organisms/CommandMenu/commandMenu.utils.cjs +0 -21
- package/dist/components/organisms/CommandMenu/commandMenu.utils.cjs.map +1 -1
- package/dist/components/organisms/CommandMenu/commandMenu.utils.d.ts +0 -9
- package/dist/components/organisms/CommandMenu/commandMenu.utils.d.ts.map +1 -1
- package/dist/components/organisms/CommandMenu/commandMenu.utils.js +1 -21
- package/dist/components/organisms/CommandMenu/commandMenu.utils.js.map +1 -1
- package/dist/components/organisms/CommandMenu/components/command-input.cjs +2 -2
- package/dist/components/organisms/CommandMenu/components/command-input.cjs.map +1 -1
- package/dist/components/organisms/CommandMenu/components/command-input.d.ts +3 -2
- package/dist/components/organisms/CommandMenu/components/command-input.d.ts.map +1 -1
- package/dist/components/organisms/CommandMenu/components/command-input.js +2 -2
- package/dist/components/organisms/CommandMenu/components/command-input.js.map +1 -1
- package/dist/components/organisms/CommandMenu/components/command-menu-item.cjs +15 -2
- package/dist/components/organisms/CommandMenu/components/command-menu-item.cjs.map +1 -1
- package/dist/components/organisms/CommandMenu/components/command-menu-item.d.ts +9 -1
- package/dist/components/organisms/CommandMenu/components/command-menu-item.d.ts.map +1 -1
- package/dist/components/organisms/CommandMenu/components/command-menu-item.js +15 -2
- package/dist/components/organisms/CommandMenu/components/command-menu-item.js.map +1 -1
- package/dist/components/organisms/CommandMenu/components/command-shortcut.cjs +2 -2
- package/dist/components/organisms/CommandMenu/components/command-shortcut.cjs.map +1 -1
- package/dist/components/organisms/CommandMenu/components/command-shortcut.d.ts +1 -0
- package/dist/components/organisms/CommandMenu/components/command-shortcut.d.ts.map +1 -1
- package/dist/components/organisms/CommandMenu/components/command-shortcut.js +2 -2
- package/dist/components/organisms/CommandMenu/components/command-shortcut.js.map +1 -1
- package/dist/components/organisms/CommandMenu/index.cjs +65 -29
- package/dist/components/organisms/CommandMenu/index.cjs.map +1 -1
- package/dist/components/organisms/CommandMenu/index.d.ts +29 -2
- package/dist/components/organisms/CommandMenu/index.d.ts.map +1 -1
- package/dist/components/organisms/CommandMenu/index.js +69 -33
- package/dist/components/organisms/CommandMenu/index.js.map +1 -1
- package/dist/components/organisms/CommandMenu/providers/command-menu-link-context.cjs +9 -0
- package/dist/components/organisms/CommandMenu/providers/command-menu-link-context.cjs.map +1 -0
- package/dist/components/organisms/CommandMenu/providers/command-menu-link-context.d.ts +3 -0
- package/dist/components/organisms/CommandMenu/providers/command-menu-link-context.d.ts.map +1 -0
- package/dist/components/organisms/CommandMenu/providers/command-menu-link-context.js +7 -0
- package/dist/components/organisms/CommandMenu/providers/command-menu-link-context.js.map +1 -0
- package/dist/components/organisms/DatePicker/components/input-date.cjs +3 -1
- package/dist/components/organisms/DatePicker/components/input-date.cjs.map +1 -1
- package/dist/components/organisms/DatePicker/components/input-date.d.ts +5 -1
- package/dist/components/organisms/DatePicker/components/input-date.d.ts.map +1 -1
- package/dist/components/organisms/DatePicker/components/input-date.js +3 -1
- package/dist/components/organisms/DatePicker/components/input-date.js.map +1 -1
- package/dist/components/organisms/HeaderNavigation/components/nav-account-card.cjs +3 -1
- package/dist/components/organisms/HeaderNavigation/components/nav-account-card.cjs.map +1 -1
- package/dist/components/organisms/HeaderNavigation/components/nav-account-card.d.ts +1 -1
- package/dist/components/organisms/HeaderNavigation/components/nav-account-card.d.ts.map +1 -1
- package/dist/components/organisms/HeaderNavigation/components/nav-account-card.js +3 -1
- package/dist/components/organisms/HeaderNavigation/components/nav-account-card.js.map +1 -1
- package/dist/components/organisms/SidePanel/components/side-panel-content.cjs +15 -0
- package/dist/components/organisms/SidePanel/components/side-panel-content.cjs.map +1 -0
- package/dist/components/organisms/SidePanel/components/side-panel-content.d.ts +11 -0
- package/dist/components/organisms/SidePanel/components/side-panel-content.d.ts.map +1 -0
- package/dist/components/organisms/SidePanel/components/side-panel-content.js +13 -0
- package/dist/components/organisms/SidePanel/components/side-panel-content.js.map +1 -0
- package/dist/components/organisms/SidePanel/components/side-panel-footer.cjs +15 -0
- package/dist/components/organisms/SidePanel/components/side-panel-footer.cjs.map +1 -0
- package/dist/components/organisms/SidePanel/components/side-panel-footer.d.ts +11 -0
- package/dist/components/organisms/SidePanel/components/side-panel-footer.d.ts.map +1 -0
- package/dist/components/organisms/SidePanel/components/side-panel-footer.js +13 -0
- package/dist/components/organisms/SidePanel/components/side-panel-footer.js.map +1 -0
- package/dist/components/organisms/SidePanel/components/side-panel-header.cjs +19 -0
- package/dist/components/organisms/SidePanel/components/side-panel-header.cjs.map +1 -0
- package/dist/components/organisms/SidePanel/components/side-panel-header.d.ts +15 -0
- package/dist/components/organisms/SidePanel/components/side-panel-header.d.ts.map +1 -0
- package/dist/components/organisms/SidePanel/components/side-panel-header.js +17 -0
- package/dist/components/organisms/SidePanel/components/side-panel-header.js.map +1 -0
- package/dist/components/organisms/SidePanel/components/side-panel-region.cjs +42 -0
- package/dist/components/organisms/SidePanel/components/side-panel-region.cjs.map +1 -0
- package/dist/components/organisms/SidePanel/components/side-panel-region.d.ts +15 -0
- package/dist/components/organisms/SidePanel/components/side-panel-region.d.ts.map +1 -0
- package/dist/components/organisms/SidePanel/components/side-panel-region.js +39 -0
- package/dist/components/organisms/SidePanel/components/side-panel-region.js.map +1 -0
- package/dist/components/organisms/SidePanel/hooks/useOpenOnMount.cjs +29 -0
- package/dist/components/organisms/SidePanel/hooks/useOpenOnMount.cjs.map +1 -0
- package/dist/components/organisms/SidePanel/hooks/useOpenOnMount.d.ts +13 -0
- package/dist/components/organisms/SidePanel/hooks/useOpenOnMount.d.ts.map +1 -0
- package/dist/components/organisms/SidePanel/hooks/useOpenOnMount.js +27 -0
- package/dist/components/organisms/SidePanel/hooks/useOpenOnMount.js.map +1 -0
- package/dist/components/organisms/SidePanel/hooks/usePanelFocus.cjs +76 -0
- package/dist/components/organisms/SidePanel/hooks/usePanelFocus.cjs.map +1 -0
- package/dist/components/organisms/SidePanel/hooks/usePanelFocus.d.ts +22 -0
- package/dist/components/organisms/SidePanel/hooks/usePanelFocus.d.ts.map +1 -0
- package/dist/components/organisms/SidePanel/hooks/usePanelFocus.js +74 -0
- package/dist/components/organisms/SidePanel/hooks/usePanelFocus.js.map +1 -0
- package/dist/components/organisms/SidePanel/index.cjs +51 -0
- package/dist/components/organisms/SidePanel/index.cjs.map +1 -0
- package/dist/components/organisms/SidePanel/index.d.ts +48 -0
- package/dist/components/organisms/SidePanel/index.d.ts.map +1 -0
- package/dist/components/organisms/SidePanel/index.js +49 -0
- package/dist/components/organisms/SidePanel/index.js.map +1 -0
- package/dist/components/organisms/SidePanel/providers/page-cover-context.cjs +12 -0
- package/dist/components/organisms/SidePanel/providers/page-cover-context.cjs.map +1 -0
- package/dist/components/organisms/SidePanel/providers/page-cover-context.d.ts +6 -0
- package/dist/components/organisms/SidePanel/providers/page-cover-context.d.ts.map +1 -0
- package/dist/components/organisms/SidePanel/providers/page-cover-context.js +10 -0
- package/dist/components/organisms/SidePanel/providers/page-cover-context.js.map +1 -0
- package/dist/components/organisms/SidePanel/providers/side-panel-context.cjs +9 -0
- package/dist/components/organisms/SidePanel/providers/side-panel-context.cjs.map +1 -0
- package/dist/components/organisms/SidePanel/providers/side-panel-context.d.ts +8 -0
- package/dist/components/organisms/SidePanel/providers/side-panel-context.d.ts.map +1 -0
- package/dist/components/organisms/SidePanel/providers/side-panel-context.js +7 -0
- package/dist/components/organisms/SidePanel/providers/side-panel-context.js.map +1 -0
- package/dist/components/organisms/SidebarNavigation/components/mobile-header.cjs +1 -1
- package/dist/components/organisms/SidebarNavigation/components/mobile-header.cjs.map +1 -1
- package/dist/components/organisms/SidebarNavigation/components/mobile-header.js +1 -1
- package/dist/components/organisms/SidebarNavigation/components/mobile-header.js.map +1 -1
- package/dist/components/organisms/SidebarNavigation/components/nav-account-card.cjs +3 -1
- package/dist/components/organisms/SidebarNavigation/components/nav-account-card.cjs.map +1 -1
- package/dist/components/organisms/SidebarNavigation/components/nav-account-card.d.ts +1 -1
- package/dist/components/organisms/SidebarNavigation/components/nav-account-card.d.ts.map +1 -1
- package/dist/components/organisms/SidebarNavigation/components/nav-account-card.js +3 -1
- package/dist/components/organisms/SidebarNavigation/components/nav-account-card.js.map +1 -1
- package/dist/components/organisms/SidebarNavigation/index.cjs +15 -5
- package/dist/components/organisms/SidebarNavigation/index.cjs.map +1 -1
- package/dist/components/organisms/SidebarNavigation/index.d.ts +3 -2
- package/dist/components/organisms/SidebarNavigation/index.d.ts.map +1 -1
- package/dist/components/organisms/SidebarNavigation/index.js +15 -5
- package/dist/components/organisms/SidebarNavigation/index.js.map +1 -1
- package/dist/components/organisms/SlideoutMenu/index.cjs +9 -3
- package/dist/components/organisms/SlideoutMenu/index.cjs.map +1 -1
- package/dist/components/organisms/SlideoutMenu/index.d.ts +1 -1
- package/dist/components/organisms/SlideoutMenu/index.d.ts.map +1 -1
- package/dist/components/organisms/SlideoutMenu/index.js +10 -4
- package/dist/components/organisms/SlideoutMenu/index.js.map +1 -1
- package/dist/components/organisms/TextEditor/components/text-editor-extensions.cjs +9 -4
- package/dist/components/organisms/TextEditor/components/text-editor-extensions.cjs.map +1 -1
- package/dist/components/organisms/TextEditor/components/text-editor-extensions.d.ts.map +1 -1
- package/dist/components/organisms/TextEditor/components/text-editor-extensions.js +10 -5
- package/dist/components/organisms/TextEditor/components/text-editor-extensions.js.map +1 -1
- package/dist/components/organisms/TextEditor/components/text-editor-toolbar.cjs +8 -2
- package/dist/components/organisms/TextEditor/components/text-editor-toolbar.cjs.map +1 -1
- package/dist/components/organisms/TextEditor/components/text-editor-toolbar.d.ts.map +1 -1
- package/dist/components/organisms/TextEditor/components/text-editor-toolbar.js +8 -2
- package/dist/components/organisms/TextEditor/components/text-editor-toolbar.js.map +1 -1
- package/dist/components/organisms/TextEditor/textEditor.utils.cjs +3 -0
- package/dist/components/organisms/TextEditor/textEditor.utils.cjs.map +1 -1
- package/dist/components/organisms/TextEditor/textEditor.utils.d.ts +4 -0
- package/dist/components/organisms/TextEditor/textEditor.utils.d.ts.map +1 -1
- package/dist/components/organisms/TextEditor/textEditor.utils.js +3 -1
- package/dist/components/organisms/TextEditor/textEditor.utils.js.map +1 -1
- package/dist/components/templates/AppShell/hooks/usePageCover.cjs +24 -0
- package/dist/components/templates/AppShell/hooks/usePageCover.cjs.map +1 -0
- package/dist/components/templates/AppShell/hooks/usePageCover.d.ts +14 -0
- package/dist/components/templates/AppShell/hooks/usePageCover.d.ts.map +1 -0
- package/dist/components/templates/AppShell/hooks/usePageCover.js +22 -0
- package/dist/components/templates/AppShell/hooks/usePageCover.js.map +1 -0
- package/dist/components/templates/AppShell/index.cjs +13 -7
- package/dist/components/templates/AppShell/index.cjs.map +1 -1
- package/dist/components/templates/AppShell/index.d.ts +8 -7
- package/dist/components/templates/AppShell/index.d.ts.map +1 -1
- package/dist/components/templates/AppShell/index.js +13 -7
- package/dist/components/templates/AppShell/index.js.map +1 -1
- package/dist/hooks/__internal__/useHotkeyHint/useHotkeyHint.cjs +24 -0
- package/dist/hooks/__internal__/useHotkeyHint/useHotkeyHint.cjs.map +1 -0
- package/dist/hooks/__internal__/useHotkeyHint/useHotkeyHint.d.ts +22 -0
- package/dist/hooks/__internal__/useHotkeyHint/useHotkeyHint.d.ts.map +1 -0
- package/dist/hooks/__internal__/useHotkeyHint/useHotkeyHint.js +22 -0
- package/dist/hooks/__internal__/useHotkeyHint/useHotkeyHint.js.map +1 -0
- package/dist/hooks/__internal__/useKeySequences/useKeySequences.cjs +54 -0
- package/dist/hooks/__internal__/useKeySequences/useKeySequences.cjs.map +1 -0
- package/dist/hooks/__internal__/useKeySequences/useKeySequences.d.ts +11 -0
- package/dist/hooks/__internal__/useKeySequences/useKeySequences.d.ts.map +1 -0
- package/dist/hooks/__internal__/useKeySequences/useKeySequences.js +52 -0
- package/dist/hooks/__internal__/useKeySequences/useKeySequences.js.map +1 -0
- package/dist/hooks/usePlatform/index.cjs +22 -0
- package/dist/hooks/usePlatform/index.cjs.map +1 -0
- package/dist/hooks/usePlatform/index.d.ts +22 -0
- package/dist/hooks/usePlatform/index.d.ts.map +1 -0
- package/dist/hooks/usePlatform/index.js +20 -0
- package/dist/hooks/usePlatform/index.js.map +1 -0
- package/dist/hooks/useSidePanel/index.cjs +61 -0
- package/dist/hooks/useSidePanel/index.cjs.map +1 -0
- package/dist/hooks/useSidePanel/index.d.ts +31 -0
- package/dist/hooks/useSidePanel/index.d.ts.map +1 -0
- package/dist/hooks/useSidePanel/index.js +59 -0
- package/dist/hooks/useSidePanel/index.js.map +1 -0
- package/dist/native/components/organisms/SidePanel/index.d.ts +12 -0
- package/dist/native/hooks/usePlatform/index.d.ts +12 -0
- package/dist/native/hooks/useSidePanel/index.d.ts +12 -0
- package/dist/utilities/__internal__/focusUtils/focus.utils.cjs +12 -0
- package/dist/utilities/__internal__/focusUtils/focus.utils.cjs.map +1 -0
- package/dist/utilities/__internal__/focusUtils/focus.utils.d.ts +3 -0
- package/dist/utilities/__internal__/focusUtils/focus.utils.d.ts.map +1 -0
- package/dist/utilities/__internal__/focusUtils/focus.utils.js +10 -0
- package/dist/utilities/__internal__/focusUtils/focus.utils.js.map +1 -0
- package/dist/utilities/__internal__/hotkeysUtils/hotkeys.utils.cjs +222 -15
- package/dist/utilities/__internal__/hotkeysUtils/hotkeys.utils.cjs.map +1 -1
- package/dist/utilities/__internal__/hotkeysUtils/hotkeys.utils.d.ts +60 -5
- package/dist/utilities/__internal__/hotkeysUtils/hotkeys.utils.d.ts.map +1 -1
- package/dist/utilities/__internal__/hotkeysUtils/hotkeys.utils.js +215 -15
- package/dist/utilities/__internal__/hotkeysUtils/hotkeys.utils.js.map +1 -1
- package/dist/utilities/__internal__/platformUtils/platform.utils.cjs +26 -0
- package/dist/utilities/__internal__/platformUtils/platform.utils.cjs.map +1 -0
- package/dist/utilities/__internal__/platformUtils/platform.utils.d.ts +10 -0
- package/dist/utilities/__internal__/platformUtils/platform.utils.d.ts.map +1 -0
- package/dist/utilities/__internal__/platformUtils/platform.utils.js +23 -0
- package/dist/utilities/__internal__/platformUtils/platform.utils.js.map +1 -0
- package/dist/utilities/__internal__/webStorageUtils/webStorage.utils.cjs +3 -0
- package/dist/utilities/__internal__/webStorageUtils/webStorage.utils.cjs.map +1 -1
- package/dist/utilities/__internal__/webStorageUtils/webStorage.utils.d.ts +2 -0
- package/dist/utilities/__internal__/webStorageUtils/webStorage.utils.d.ts.map +1 -1
- package/dist/utilities/__internal__/webStorageUtils/webStorage.utils.js +3 -1
- package/dist/utilities/__internal__/webStorageUtils/webStorage.utils.js.map +1 -1
- package/dist/utilities/localStorageUtils/index.cjs +7 -0
- package/dist/utilities/localStorageUtils/index.cjs.map +1 -1
- package/dist/utilities/localStorageUtils/index.d.ts +2 -0
- package/dist/utilities/localStorageUtils/index.d.ts.map +1 -1
- package/dist/utilities/localStorageUtils/index.js +8 -2
- package/dist/utilities/localStorageUtils/index.js.map +1 -1
- package/dist/utilities/localStorageUtils/localStorageUtils.constants.cjs +2 -0
- package/dist/utilities/localStorageUtils/localStorageUtils.constants.cjs.map +1 -1
- package/dist/utilities/localStorageUtils/localStorageUtils.constants.d.ts +2 -0
- package/dist/utilities/localStorageUtils/localStorageUtils.constants.d.ts.map +1 -1
- package/dist/utilities/localStorageUtils/localStorageUtils.constants.js +2 -0
- package/dist/utilities/localStorageUtils/localStorageUtils.constants.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var focus_utils = require('../../../../utilities/__internal__/focusUtils/focus.utils.cjs');
|
|
5
|
+
|
|
6
|
+
/** The element before the panel when it can take focus, such as `AppShell`'s scroll area. */
|
|
7
|
+
const focusableSiblingBefore = (panel) => {
|
|
8
|
+
const sibling = panel.previousElementSibling;
|
|
9
|
+
return sibling instanceof HTMLElement && sibling.tabIndex >= 0 ? sibling : null;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Hands focus into the panel when it opens and back to the control that opened it when it closes,
|
|
13
|
+
* and makes a leaving panel inert. Managed by hand, not with a focus scope: a scope would also
|
|
14
|
+
* reroute Tab at the panel's edges, as a popover does.
|
|
15
|
+
*
|
|
16
|
+
* @returns a capture-phase focus handler to spread onto the panel element
|
|
17
|
+
*/
|
|
18
|
+
const usePanelFocus = ({ panelRef, isPresent, isDesktop, shouldFocusOnMount }) => {
|
|
19
|
+
const openerRef = React.useRef(null);
|
|
20
|
+
const previousIsPresent = React.useRef(null);
|
|
21
|
+
const previousIsDesktop = React.useRef(isDesktop);
|
|
22
|
+
// Read while rendering, before the content mounts: an `autoFocus` input takes focus during commit, ahead of any effect.
|
|
23
|
+
const [focusedBeforeMount] = React.useState(focus_utils.getFocusedElement);
|
|
24
|
+
React.useEffect(() => {
|
|
25
|
+
const panel = panelRef.current;
|
|
26
|
+
if (!panel)
|
|
27
|
+
return;
|
|
28
|
+
const previous = previousIsPresent.current;
|
|
29
|
+
previousIsPresent.current = isPresent;
|
|
30
|
+
// Entering covers a fresh open and a reopen that interrupts the close animation.
|
|
31
|
+
const isEntering = isPresent && (previous === false || (previous === null && shouldFocusOnMount));
|
|
32
|
+
const isLeaving = !isPresent && previous === true;
|
|
33
|
+
const focused = focus_utils.getFocusedElement();
|
|
34
|
+
const hasFocusInside = focused !== null && panel.contains(focused);
|
|
35
|
+
// A panel reopened mid-close is still inert from leaving, and an inert element cannot take focus.
|
|
36
|
+
if (isPresent)
|
|
37
|
+
panel.inert = false;
|
|
38
|
+
if (isEntering) {
|
|
39
|
+
// On mount the content may already hold focus, so the opener is what was focused before it. A reopen mid-close finds focus still outside.
|
|
40
|
+
openerRef.current = previous === null ? focusedBeforeMount : focused;
|
|
41
|
+
// Content that focused itself (an `autoFocus` input) keeps focus; otherwise the region takes it.
|
|
42
|
+
// preventScroll: below `lg` the panel starts off-screen, and scrolling it into view would shift the layout.
|
|
43
|
+
if (!hasFocusInside)
|
|
44
|
+
panel.focus({ preventScroll: true });
|
|
45
|
+
}
|
|
46
|
+
// Hand focus back only if it is still in the panel, so a user who has moved on is left alone.
|
|
47
|
+
if (isLeaving && hasFocusInside) {
|
|
48
|
+
const opener = openerRef.current;
|
|
49
|
+
// The opener may have unmounted meanwhile, such as a header button that only renders at one breakpoint.
|
|
50
|
+
(opener?.isConnected ? opener : focusableSiblingBefore(panel))?.focus();
|
|
51
|
+
}
|
|
52
|
+
// A leaving panel must not be reachable while another opens; set last, since inert drops any focus inside it.
|
|
53
|
+
if (!isPresent)
|
|
54
|
+
panel.inert = true;
|
|
55
|
+
}, [panelRef, isPresent, shouldFocusOnMount, focusedBeforeMount]);
|
|
56
|
+
React.useEffect(() => {
|
|
57
|
+
const hasStartedCoveringPage = previousIsDesktop.current && !isDesktop;
|
|
58
|
+
previousIsDesktop.current = isDesktop;
|
|
59
|
+
const panel = panelRef.current;
|
|
60
|
+
const focused = focus_utils.getFocusedElement();
|
|
61
|
+
// The page beside the panel is about to go out of reach, so focus must not be left in it.
|
|
62
|
+
if (hasStartedCoveringPage && panel && focused && !panel.contains(focused) && panel.parentElement?.contains(focused)) {
|
|
63
|
+
panel.focus({ preventScroll: true });
|
|
64
|
+
}
|
|
65
|
+
}, [panelRef, isDesktop]);
|
|
66
|
+
// A panel that was open on load has no opener, so closing hands focus back to wherever it first came in from.
|
|
67
|
+
const onFocusCapture = (event) => {
|
|
68
|
+
const from = event.relatedTarget;
|
|
69
|
+
if (openerRef.current === null && from instanceof HTMLElement && !event.currentTarget.contains(from))
|
|
70
|
+
openerRef.current = from;
|
|
71
|
+
};
|
|
72
|
+
return { onFocusCapture };
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
exports.usePanelFocus = usePanelFocus;
|
|
76
|
+
//# sourceMappingURL=usePanelFocus.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePanelFocus.cjs","sources":["../../../../../src/components/organisms/SidePanel/hooks/usePanelFocus.ts"],"sourcesContent":[null],"names":["useRef","useState","getFocusedElement","useEffect"],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { FocusEvent, RefObject } from 'react';
|
|
2
|
+
interface UsePanelFocusOptions {
|
|
3
|
+
panelRef: RefObject<HTMLElement | null>;
|
|
4
|
+
/** From `useIsPresent`: false once the panel is animating out. */
|
|
5
|
+
isPresent: boolean;
|
|
6
|
+
/** Whether the panel is docked beside the page rather than covering it. */
|
|
7
|
+
isDesktop: boolean;
|
|
8
|
+
/** False for a panel that is open on the first render, which must not pull focus away from the page. */
|
|
9
|
+
shouldFocusOnMount: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Hands focus into the panel when it opens and back to the control that opened it when it closes,
|
|
13
|
+
* and makes a leaving panel inert. Managed by hand, not with a focus scope: a scope would also
|
|
14
|
+
* reroute Tab at the panel's edges, as a popover does.
|
|
15
|
+
*
|
|
16
|
+
* @returns a capture-phase focus handler to spread onto the panel element
|
|
17
|
+
*/
|
|
18
|
+
export declare const usePanelFocus: ({ panelRef, isPresent, isDesktop, shouldFocusOnMount }: UsePanelFocusOptions) => {
|
|
19
|
+
onFocusCapture: (event: FocusEvent<HTMLElement>) => void;
|
|
20
|
+
};
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=usePanelFocus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePanelFocus.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/SidePanel/hooks/usePanelFocus.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAWnD,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACxC,kEAAkE;IAClE,SAAS,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,SAAS,EAAE,OAAO,CAAC;IACnB,wGAAwG;IACxG,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GAAI,wDAAwD,oBAAoB;4BAmDzE,UAAU,CAAC,WAAW,CAAC;CAMvD,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { useRef, useState, useEffect } from 'react';
|
|
2
|
+
import { getFocusedElement } from '../../../../utilities/__internal__/focusUtils/focus.utils.js';
|
|
3
|
+
|
|
4
|
+
/** The element before the panel when it can take focus, such as `AppShell`'s scroll area. */
|
|
5
|
+
const focusableSiblingBefore = (panel) => {
|
|
6
|
+
const sibling = panel.previousElementSibling;
|
|
7
|
+
return sibling instanceof HTMLElement && sibling.tabIndex >= 0 ? sibling : null;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Hands focus into the panel when it opens and back to the control that opened it when it closes,
|
|
11
|
+
* and makes a leaving panel inert. Managed by hand, not with a focus scope: a scope would also
|
|
12
|
+
* reroute Tab at the panel's edges, as a popover does.
|
|
13
|
+
*
|
|
14
|
+
* @returns a capture-phase focus handler to spread onto the panel element
|
|
15
|
+
*/
|
|
16
|
+
const usePanelFocus = ({ panelRef, isPresent, isDesktop, shouldFocusOnMount }) => {
|
|
17
|
+
const openerRef = useRef(null);
|
|
18
|
+
const previousIsPresent = useRef(null);
|
|
19
|
+
const previousIsDesktop = useRef(isDesktop);
|
|
20
|
+
// Read while rendering, before the content mounts: an `autoFocus` input takes focus during commit, ahead of any effect.
|
|
21
|
+
const [focusedBeforeMount] = useState(getFocusedElement);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
const panel = panelRef.current;
|
|
24
|
+
if (!panel)
|
|
25
|
+
return;
|
|
26
|
+
const previous = previousIsPresent.current;
|
|
27
|
+
previousIsPresent.current = isPresent;
|
|
28
|
+
// Entering covers a fresh open and a reopen that interrupts the close animation.
|
|
29
|
+
const isEntering = isPresent && (previous === false || (previous === null && shouldFocusOnMount));
|
|
30
|
+
const isLeaving = !isPresent && previous === true;
|
|
31
|
+
const focused = getFocusedElement();
|
|
32
|
+
const hasFocusInside = focused !== null && panel.contains(focused);
|
|
33
|
+
// A panel reopened mid-close is still inert from leaving, and an inert element cannot take focus.
|
|
34
|
+
if (isPresent)
|
|
35
|
+
panel.inert = false;
|
|
36
|
+
if (isEntering) {
|
|
37
|
+
// On mount the content may already hold focus, so the opener is what was focused before it. A reopen mid-close finds focus still outside.
|
|
38
|
+
openerRef.current = previous === null ? focusedBeforeMount : focused;
|
|
39
|
+
// Content that focused itself (an `autoFocus` input) keeps focus; otherwise the region takes it.
|
|
40
|
+
// preventScroll: below `lg` the panel starts off-screen, and scrolling it into view would shift the layout.
|
|
41
|
+
if (!hasFocusInside)
|
|
42
|
+
panel.focus({ preventScroll: true });
|
|
43
|
+
}
|
|
44
|
+
// Hand focus back only if it is still in the panel, so a user who has moved on is left alone.
|
|
45
|
+
if (isLeaving && hasFocusInside) {
|
|
46
|
+
const opener = openerRef.current;
|
|
47
|
+
// The opener may have unmounted meanwhile, such as a header button that only renders at one breakpoint.
|
|
48
|
+
(opener?.isConnected ? opener : focusableSiblingBefore(panel))?.focus();
|
|
49
|
+
}
|
|
50
|
+
// A leaving panel must not be reachable while another opens; set last, since inert drops any focus inside it.
|
|
51
|
+
if (!isPresent)
|
|
52
|
+
panel.inert = true;
|
|
53
|
+
}, [panelRef, isPresent, shouldFocusOnMount, focusedBeforeMount]);
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
const hasStartedCoveringPage = previousIsDesktop.current && !isDesktop;
|
|
56
|
+
previousIsDesktop.current = isDesktop;
|
|
57
|
+
const panel = panelRef.current;
|
|
58
|
+
const focused = getFocusedElement();
|
|
59
|
+
// The page beside the panel is about to go out of reach, so focus must not be left in it.
|
|
60
|
+
if (hasStartedCoveringPage && panel && focused && !panel.contains(focused) && panel.parentElement?.contains(focused)) {
|
|
61
|
+
panel.focus({ preventScroll: true });
|
|
62
|
+
}
|
|
63
|
+
}, [panelRef, isDesktop]);
|
|
64
|
+
// A panel that was open on load has no opener, so closing hands focus back to wherever it first came in from.
|
|
65
|
+
const onFocusCapture = (event) => {
|
|
66
|
+
const from = event.relatedTarget;
|
|
67
|
+
if (openerRef.current === null && from instanceof HTMLElement && !event.currentTarget.contains(from))
|
|
68
|
+
openerRef.current = from;
|
|
69
|
+
};
|
|
70
|
+
return { onFocusCapture };
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export { usePanelFocus };
|
|
74
|
+
//# sourceMappingURL=usePanelFocus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePanelFocus.js","sources":["../../../../../src/components/organisms/SidePanel/hooks/usePanelFocus.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var useBreakpoints = require('@flipdish/ui-library/hooks/useBreakpoints');
|
|
5
|
+
var testIdUtils = require('@flipdish/ui-library/utilities/testIdUtils');
|
|
6
|
+
var react = require('motion/react');
|
|
7
|
+
var React = require('react');
|
|
8
|
+
var sidePanelContent = require('./components/side-panel-content.cjs');
|
|
9
|
+
var sidePanelFooter = require('./components/side-panel-footer.cjs');
|
|
10
|
+
var sidePanelHeader = require('./components/side-panel-header.cjs');
|
|
11
|
+
var sidePanelRegion = require('./components/side-panel-region.cjs');
|
|
12
|
+
var useOpenOnMount = require('./hooks/useOpenOnMount.cjs');
|
|
13
|
+
var pageCoverContext = require('./providers/page-cover-context.cjs');
|
|
14
|
+
var sidePanelContext = require('./providers/side-panel-context.cjs');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* A side panel the user can keep open while they work, such as an AI assistant or a notifications
|
|
18
|
+
* list. It is never a modal: no backdrop, no focus trap, no scroll lock. From `lg` it is docked
|
|
19
|
+
* beside the page, which narrows to make room. Below `lg` there is no room to push, so it covers
|
|
20
|
+
* the page area under the header, which stays in reach to close it. Place it in `AppShell`'s `panel`
|
|
21
|
+
* slot, or as the last child of your own content row, and render it always: `isOpen` decides
|
|
22
|
+
* whether it shows.
|
|
23
|
+
*
|
|
24
|
+
* @summary non-modal side panel that pushes the page on desktop and covers it under the header on mobile
|
|
25
|
+
*/
|
|
26
|
+
const SidePanelRoot = ({ isOpen, onOpenChange, 'aria-label': ariaLabel, children, className, 'data-testid': dataTestId, }) => {
|
|
27
|
+
const rootTestId = testIdUtils.useResolvedTestId({ testId: dataTestId, segment: 'side-panel', rootName: 'side-panel' });
|
|
28
|
+
const isDesktop = useBreakpoints.useBreakpoints('lg');
|
|
29
|
+
const setPageCovered = React.useContext(pageCoverContext.PageCoverContext);
|
|
30
|
+
// Nothing renders until the viewport is known, so server and client markup agree.
|
|
31
|
+
const { canMeasureViewport, shouldFocusOnMount } = useOpenOnMount.useOpenOnMount(isOpen);
|
|
32
|
+
const coversPage = canMeasureViewport && isOpen && !isDesktop;
|
|
33
|
+
React.useEffect(() => {
|
|
34
|
+
if (!setPageCovered || !coversPage)
|
|
35
|
+
return;
|
|
36
|
+
setPageCovered(true);
|
|
37
|
+
return () => setPageCovered(false);
|
|
38
|
+
}, [setPageCovered, coversPage]);
|
|
39
|
+
if (!canMeasureViewport)
|
|
40
|
+
return null;
|
|
41
|
+
return (jsxRuntime.jsx(sidePanelContext.SidePanelContext.Provider, { value: { close: () => onOpenChange(false), label: ariaLabel }, children: jsxRuntime.jsx(testIdUtils.TestIdProvider, { value: rootTestId, children: jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: isOpen && (jsxRuntime.jsx(sidePanelRegion.SidePanelRegion, { "aria-label": ariaLabel, className: className, testId: rootTestId, isDesktop: isDesktop, shouldFocusOnMount: shouldFocusOnMount, children: children }, "side-panel")) }) }) }));
|
|
42
|
+
};
|
|
43
|
+
SidePanelRoot.displayName = 'SidePanel';
|
|
44
|
+
const SidePanel = SidePanelRoot;
|
|
45
|
+
SidePanel.Header = sidePanelHeader.SidePanelHeader;
|
|
46
|
+
SidePanel.Content = sidePanelContent.SidePanelContent;
|
|
47
|
+
SidePanel.Footer = sidePanelFooter.SidePanelFooter;
|
|
48
|
+
|
|
49
|
+
exports.SIDE_PANEL_WIDTH = sidePanelRegion.SIDE_PANEL_WIDTH;
|
|
50
|
+
exports.SidePanel = SidePanel;
|
|
51
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../../src/components/organisms/SidePanel/index.tsx"],"sourcesContent":[null],"names":["useResolvedTestId","useBreakpoints","useContext","PageCoverContext","useOpenOnMount","useEffect","_jsx","SidePanelContext","TestIdProvider","AnimatePresence","SidePanelRegion","SidePanelHeader","SidePanelContent","SidePanelFooter"],"mappings":";;;;;;;;;;;;;;;AAwCA;;;;;;;;;AASG;AACH,MAAM,aAAa,GAAG,CAAC,EACrB,MAAM,EACN,YAAY,EACZ,YAAY,EAAE,SAAS,EACvB,QAAQ,EACR,SAAS,EACT,aAAa,EAAE,UAAU,GACV,KAAe;AAC9B,IAAA,MAAM,UAAU,GAAGA,6BAAiB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;AAC3G,IAAA,MAAM,SAAS,GAAGC,6BAAc,CAAC,IAAI,CAAC;AACtC,IAAA,MAAM,cAAc,GAAGC,gBAAU,CAACC,iCAAgB,CAAC;;IAEnD,MAAM,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,GAAGC,6BAAc,CAAC,MAAM,CAAC;IAEzE,MAAM,UAAU,GAAG,kBAAkB,IAAI,MAAM,IAAI,CAAC,SAAS;IAC7DC,eAAS,CAAC,MAAK;AACb,QAAA,IAAI,CAAC,cAAc,IAAI,CAAC,UAAU;YAAE;QACpC,cAAc,CAAC,IAAI,CAAC;AACpB,QAAA,OAAO,MAAM,cAAc,CAAC,KAAK,CAAC;AACpC,IAAA,CAAC,EAAE,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;AAEhC,IAAA,IAAI,CAAC,kBAAkB;AAAE,QAAA,OAAO,IAAI;AAEpC,IAAA,QACEC,cAAA,CAACC,iCAAgB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAA,QAAA,EACtFD,cAAA,CAACE,0BAAc,EAAA,EAAC,KAAK,EAAE,UAAU,EAAA,QAAA,EAC/BF,cAAA,CAACG,qBAAe,EAAA,EAAC,OAAO,EAAE,KAAK,EAAA,QAAA,EAC5B,MAAM,KACLH,eAACI,+BAAe,EAAA,EAAA,YAAA,EAEF,SAAS,EACrB,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,SAAS,EACpB,kBAAkB,EAAE,kBAAkB,EAAA,QAAA,EAErC,QAAQ,EAAA,EAPL,YAAY,CAQA,CACnB,EAAA,CACe,EAAA,CACH,EAAA,CACS;AAEhC,CAAC;AACD,aAAa,CAAC,WAAW,GAAG,WAAW;AAEvC,MAAM,SAAS,GAAG;AAMlB,SAAS,CAAC,MAAM,GAAGC,+BAAe;AAClC,SAAS,CAAC,OAAO,GAAGC,iCAAgB;AACpC,SAAS,CAAC,MAAM,GAAGC,+BAAe;;;;;"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { SidePanelContent } from './components/side-panel-content';
|
|
3
|
+
import { SidePanelFooter } from './components/side-panel-footer';
|
|
4
|
+
import { SidePanelHeader } from './components/side-panel-header';
|
|
5
|
+
export type { SidePanelContentProps } from './components/side-panel-content';
|
|
6
|
+
export type { SidePanelFooterProps } from './components/side-panel-footer';
|
|
7
|
+
export type { SidePanelHeaderProps } from './components/side-panel-header';
|
|
8
|
+
export { SIDE_PANEL_WIDTH } from './components/side-panel-region';
|
|
9
|
+
export interface SidePanelProps {
|
|
10
|
+
/**
|
|
11
|
+
* Whether the panel is open. Share it with the control that opens the panel, e.g. `assistant.isOpen`
|
|
12
|
+
* on `ApplicationHeader`. Opening moves focus into the panel, except when it is already open on the
|
|
13
|
+
* first render. So restore a saved open state as the initial state, as `useSidePanel` does, not in a
|
|
14
|
+
* mount effect, which would pull focus away from the page.
|
|
15
|
+
*/
|
|
16
|
+
isOpen: boolean;
|
|
17
|
+
/** Called with `false` when the panel's close button is pressed. */
|
|
18
|
+
onOpenChange: (isOpen: boolean) => void;
|
|
19
|
+
/** Names the side region for assistive technology. */
|
|
20
|
+
'aria-label': string;
|
|
21
|
+
/** Compose `SidePanel.Header`, `SidePanel.Content` and `SidePanel.Footer`. */
|
|
22
|
+
children: ReactNode;
|
|
23
|
+
/** Extra classes merged onto the panel. */
|
|
24
|
+
className?: string;
|
|
25
|
+
/** Overrides the root `data-testid` (defaults to `fd-side-panel`). Descendants derive their ids from this prefix. */
|
|
26
|
+
'data-testid'?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A side panel the user can keep open while they work, such as an AI assistant or a notifications
|
|
30
|
+
* list. It is never a modal: no backdrop, no focus trap, no scroll lock. From `lg` it is docked
|
|
31
|
+
* beside the page, which narrows to make room. Below `lg` there is no room to push, so it covers
|
|
32
|
+
* the page area under the header, which stays in reach to close it. Place it in `AppShell`'s `panel`
|
|
33
|
+
* slot, or as the last child of your own content row, and render it always: `isOpen` decides
|
|
34
|
+
* whether it shows.
|
|
35
|
+
*
|
|
36
|
+
* @summary non-modal side panel that pushes the page on desktop and covers it under the header on mobile
|
|
37
|
+
*/
|
|
38
|
+
declare const SidePanelRoot: {
|
|
39
|
+
({ isOpen, onOpenChange, "aria-label": ariaLabel, children, className, "data-testid": dataTestId, }: SidePanelProps): ReactNode;
|
|
40
|
+
displayName: string;
|
|
41
|
+
};
|
|
42
|
+
declare const SidePanel: typeof SidePanelRoot & {
|
|
43
|
+
Header: typeof SidePanelHeader;
|
|
44
|
+
Content: typeof SidePanelContent;
|
|
45
|
+
Footer: typeof SidePanelFooter;
|
|
46
|
+
};
|
|
47
|
+
export { SidePanel };
|
|
48
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/SidePanel/index.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAMjE,YAAY,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAC7E,YAAY,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,YAAY,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAElE,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB,oEAAoE;IACpE,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,sDAAsD;IACtD,YAAY,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,QAAQ,EAAE,SAAS,CAAC;IACpB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qHAAqH;IACrH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,QAAA,MAAM,aAAa;yGAOhB,cAAc,GAAG,SAAS;;CAoC5B,CAAC;AAGF,QAAA,MAAM,SAAS,EAAoB,OAAO,aAAa,GAAG;IACxD,MAAM,EAAE,OAAO,eAAe,CAAC;IAC/B,OAAO,EAAE,OAAO,gBAAgB,CAAC;IACjC,MAAM,EAAE,OAAO,eAAe,CAAC;CAChC,CAAC;AAMF,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useBreakpoints } from '@flipdish/ui-library/hooks/useBreakpoints';
|
|
3
|
+
import { useResolvedTestId, TestIdProvider } from '@flipdish/ui-library/utilities/testIdUtils';
|
|
4
|
+
import { AnimatePresence } from 'motion/react';
|
|
5
|
+
import { useContext, useEffect } from 'react';
|
|
6
|
+
import { SidePanelContent } from './components/side-panel-content.js';
|
|
7
|
+
import { SidePanelFooter } from './components/side-panel-footer.js';
|
|
8
|
+
import { SidePanelHeader } from './components/side-panel-header.js';
|
|
9
|
+
import { SidePanelRegion } from './components/side-panel-region.js';
|
|
10
|
+
export { SIDE_PANEL_WIDTH } from './components/side-panel-region.js';
|
|
11
|
+
import { useOpenOnMount } from './hooks/useOpenOnMount.js';
|
|
12
|
+
import { PageCoverContext } from './providers/page-cover-context.js';
|
|
13
|
+
import { SidePanelContext } from './providers/side-panel-context.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A side panel the user can keep open while they work, such as an AI assistant or a notifications
|
|
17
|
+
* list. It is never a modal: no backdrop, no focus trap, no scroll lock. From `lg` it is docked
|
|
18
|
+
* beside the page, which narrows to make room. Below `lg` there is no room to push, so it covers
|
|
19
|
+
* the page area under the header, which stays in reach to close it. Place it in `AppShell`'s `panel`
|
|
20
|
+
* slot, or as the last child of your own content row, and render it always: `isOpen` decides
|
|
21
|
+
* whether it shows.
|
|
22
|
+
*
|
|
23
|
+
* @summary non-modal side panel that pushes the page on desktop and covers it under the header on mobile
|
|
24
|
+
*/
|
|
25
|
+
const SidePanelRoot = ({ isOpen, onOpenChange, 'aria-label': ariaLabel, children, className, 'data-testid': dataTestId, }) => {
|
|
26
|
+
const rootTestId = useResolvedTestId({ testId: dataTestId, segment: 'side-panel', rootName: 'side-panel' });
|
|
27
|
+
const isDesktop = useBreakpoints('lg');
|
|
28
|
+
const setPageCovered = useContext(PageCoverContext);
|
|
29
|
+
// Nothing renders until the viewport is known, so server and client markup agree.
|
|
30
|
+
const { canMeasureViewport, shouldFocusOnMount } = useOpenOnMount(isOpen);
|
|
31
|
+
const coversPage = canMeasureViewport && isOpen && !isDesktop;
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (!setPageCovered || !coversPage)
|
|
34
|
+
return;
|
|
35
|
+
setPageCovered(true);
|
|
36
|
+
return () => setPageCovered(false);
|
|
37
|
+
}, [setPageCovered, coversPage]);
|
|
38
|
+
if (!canMeasureViewport)
|
|
39
|
+
return null;
|
|
40
|
+
return (jsx(SidePanelContext.Provider, { value: { close: () => onOpenChange(false), label: ariaLabel }, children: jsx(TestIdProvider, { value: rootTestId, children: jsx(AnimatePresence, { initial: false, children: isOpen && (jsx(SidePanelRegion, { "aria-label": ariaLabel, className: className, testId: rootTestId, isDesktop: isDesktop, shouldFocusOnMount: shouldFocusOnMount, children: children }, "side-panel")) }) }) }));
|
|
41
|
+
};
|
|
42
|
+
SidePanelRoot.displayName = 'SidePanel';
|
|
43
|
+
const SidePanel = SidePanelRoot;
|
|
44
|
+
SidePanel.Header = SidePanelHeader;
|
|
45
|
+
SidePanel.Content = SidePanelContent;
|
|
46
|
+
SidePanel.Footer = SidePanelFooter;
|
|
47
|
+
|
|
48
|
+
export { SidePanel };
|
|
49
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/organisms/SidePanel/index.tsx"],"sourcesContent":[null],"names":["_jsx"],"mappings":";;;;;;;;;;;;;;AAwCA;;;;;;;;;AASG;AACH,MAAM,aAAa,GAAG,CAAC,EACrB,MAAM,EACN,YAAY,EACZ,YAAY,EAAE,SAAS,EACvB,QAAQ,EACR,SAAS,EACT,aAAa,EAAE,UAAU,GACV,KAAe;AAC9B,IAAA,MAAM,UAAU,GAAG,iBAAiB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;AAC3G,IAAA,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,CAAC;AACtC,IAAA,MAAM,cAAc,GAAG,UAAU,CAAC,gBAAgB,CAAC;;IAEnD,MAAM,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC;IAEzE,MAAM,UAAU,GAAG,kBAAkB,IAAI,MAAM,IAAI,CAAC,SAAS;IAC7D,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,CAAC,cAAc,IAAI,CAAC,UAAU;YAAE;QACpC,cAAc,CAAC,IAAI,CAAC;AACpB,QAAA,OAAO,MAAM,cAAc,CAAC,KAAK,CAAC;AACpC,IAAA,CAAC,EAAE,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;AAEhC,IAAA,IAAI,CAAC,kBAAkB;AAAE,QAAA,OAAO,IAAI;AAEpC,IAAA,QACEA,GAAA,CAAC,gBAAgB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAA,QAAA,EACtFA,GAAA,CAAC,cAAc,EAAA,EAAC,KAAK,EAAE,UAAU,EAAA,QAAA,EAC/BA,GAAA,CAAC,eAAe,EAAA,EAAC,OAAO,EAAE,KAAK,EAAA,QAAA,EAC5B,MAAM,KACLA,IAAC,eAAe,EAAA,EAAA,YAAA,EAEF,SAAS,EACrB,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,SAAS,EACpB,kBAAkB,EAAE,kBAAkB,EAAA,QAAA,EAErC,QAAQ,EAAA,EAPL,YAAY,CAQA,CACnB,EAAA,CACe,EAAA,CACH,EAAA,CACS;AAEhC,CAAC;AACD,aAAa,CAAC,WAAW,GAAG,WAAW;AAEvC,MAAM,SAAS,GAAG;AAMlB,SAAS,CAAC,MAAM,GAAG,eAAe;AAClC,SAAS,CAAC,OAAO,GAAG,gBAAgB;AACpC,SAAS,CAAC,MAAM,GAAG,eAAe;;;;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Lets the panel tell the layout around it that it is covering the page below `lg`, so the layout
|
|
7
|
+
* can take the page out of reach. `AppShell` provides it; without a provider the panel calls nothing.
|
|
8
|
+
*/
|
|
9
|
+
const PageCoverContext = React.createContext(undefined);
|
|
10
|
+
|
|
11
|
+
exports.PageCoverContext = PageCoverContext;
|
|
12
|
+
//# sourceMappingURL=page-cover-context.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-cover-context.cjs","sources":["../../../../../src/components/organisms/SidePanel/providers/page-cover-context.ts"],"sourcesContent":[null],"names":["createContext"],"mappings":";;;;AAIA;;;AAGG;MACU,gBAAgB,GAAGA,mBAAa,CAA6C,SAAS;;;;"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lets the panel tell the layout around it that it is covering the page below `lg`, so the layout
|
|
3
|
+
* can take the page out of reach. `AppShell` provides it; without a provider the panel calls nothing.
|
|
4
|
+
*/
|
|
5
|
+
export declare const PageCoverContext: import("react").Context<((isCovered: boolean) => void) | undefined>;
|
|
6
|
+
//# sourceMappingURL=page-cover-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-cover-context.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/SidePanel/providers/page-cover-context.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,eAAO,MAAM,gBAAgB,uCAA8B,OAAO,KAAK,IAAI,cAAyB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createContext } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Lets the panel tell the layout around it that it is covering the page below `lg`, so the layout
|
|
5
|
+
* can take the page out of reach. `AppShell` provides it; without a provider the panel calls nothing.
|
|
6
|
+
*/
|
|
7
|
+
const PageCoverContext = createContext(undefined);
|
|
8
|
+
|
|
9
|
+
export { PageCoverContext };
|
|
10
|
+
//# sourceMappingURL=page-cover-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-cover-context.js","sources":["../../../../../src/components/organisms/SidePanel/providers/page-cover-context.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAIA;;;AAGG;MACU,gBAAgB,GAAG,aAAa,CAA6C,SAAS;;;;"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
|
|
5
|
+
/** Provided by the panel root, read by its header, so the sections never import `../index`. */
|
|
6
|
+
const SidePanelContext = React.createContext(undefined);
|
|
7
|
+
|
|
8
|
+
exports.SidePanelContext = SidePanelContext;
|
|
9
|
+
//# sourceMappingURL=side-panel-context.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"side-panel-context.cjs","sources":["../../../../../src/components/organisms/SidePanel/providers/side-panel-context.ts"],"sourcesContent":[null],"names":["createContext"],"mappings":";;;;AAUA;MACa,gBAAgB,GAAGA,mBAAa,CAAoC,SAAS;;;;"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface SidePanelContextValue {
|
|
2
|
+
close: () => void;
|
|
3
|
+
/** The panel's `aria-label`, so the close button can say which panel it closes. */
|
|
4
|
+
label: string;
|
|
5
|
+
}
|
|
6
|
+
/** Provided by the panel root, read by its header, so the sections never import `../index`. */
|
|
7
|
+
export declare const SidePanelContext: import("react").Context<SidePanelContextValue | undefined>;
|
|
8
|
+
//# sourceMappingURL=side-panel-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"side-panel-context.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/SidePanel/providers/side-panel-context.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,mFAAmF;IACnF,KAAK,EAAE,MAAM,CAAC;CACf;AAED,+FAA+F;AAC/F,eAAO,MAAM,gBAAgB,4DAA8D,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createContext } from 'react';
|
|
2
|
+
|
|
3
|
+
/** Provided by the panel root, read by its header, so the sections never import `../index`. */
|
|
4
|
+
const SidePanelContext = createContext(undefined);
|
|
5
|
+
|
|
6
|
+
export { SidePanelContext };
|
|
7
|
+
//# sourceMappingURL=side-panel-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"side-panel-context.js","sources":["../../../../../src/components/organisms/SidePanel/providers/side-panel-context.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAUA;MACa,gBAAgB,GAAG,aAAa,CAAoC,SAAS;;;;"}
|
|
@@ -13,7 +13,7 @@ var sidebarMenuButton = require('./sidebar-menu-button.cjs');
|
|
|
13
13
|
* Consumers who supply their own header instead should set `showMobileHeader={false}`
|
|
14
14
|
* and embed a {@link SidebarMenuButton}.
|
|
15
15
|
*/
|
|
16
|
-
const MobileNavigationHeader = ({ isOpen, onOpenChange, controls, homeHref, onHomePress, logoTestId, 'data-testid': dataTestId, }) => (jsxRuntime.jsxs("header", { className: "flex h-14 items-center justify-between border-b border-secondary bg-
|
|
16
|
+
const MobileNavigationHeader = ({ isOpen, onOpenChange, controls, homeHref, onHomePress, logoTestId, 'data-testid': dataTestId, }) => (jsxRuntime.jsxs("header", { className: "flex h-14 items-center justify-between border-b border-secondary bg-primary p-3 pl-4 lg:hidden", children: [jsxRuntime.jsx(logoLink.LogoLink, { href: homeHref, size: "sm", onClick: onHomePress, "data-testid": logoTestId }), jsxRuntime.jsx(sidebarMenuButton.SidebarMenuButton, { isOpen: isOpen, onPress: () => onOpenChange(!isOpen), controls: controls, "data-testid": dataTestId })] }));
|
|
17
17
|
/**
|
|
18
18
|
* The controlled slide-over drawer that holds the mobile navigation. Its open
|
|
19
19
|
* state is owned by `SidebarNavigation`, so it can be driven by either the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mobile-header.cjs","sources":["../../../../../src/components/organisms/SidebarNavigation/components/mobile-header.tsx"],"sourcesContent":[null],"names":["_jsxs","_jsx","LogoLink","SidebarMenuButton","AriaModalOverlay","cx","_Fragment","AriaButton","CloseIcon","AriaModal","AriaDialog"],"mappings":";;;;;;;;;AA0BA;;;;;AAKG;AACI,MAAM,sBAAsB,GAAG,CAAC,EACrC,MAAM,EACN,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,UAAU,EACV,aAAa,EAAE,UAAU,GACG,MAC5BA,eAAA,CAAA,QAAA,EAAA,EAAQ,SAAS,EAAC,
|
|
1
|
+
{"version":3,"file":"mobile-header.cjs","sources":["../../../../../src/components/organisms/SidebarNavigation/components/mobile-header.tsx"],"sourcesContent":[null],"names":["_jsxs","_jsx","LogoLink","SidebarMenuButton","AriaModalOverlay","cx","_Fragment","AriaButton","CloseIcon","AriaModal","AriaDialog"],"mappings":";;;;;;;;;AA0BA;;;;;AAKG;AACI,MAAM,sBAAsB,GAAG,CAAC,EACrC,MAAM,EACN,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,UAAU,EACV,aAAa,EAAE,UAAU,GACG,MAC5BA,eAAA,CAAA,QAAA,EAAA,EAAQ,SAAS,EAAC,gGAAgG,EAAA,QAAA,EAAA,CAChHC,cAAA,CAACC,iBAAQ,EAAA,EAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAC,IAAI,EAAC,OAAO,EAAE,WAAW,EAAA,aAAA,EAAe,UAAU,EAAA,CAAI,EACrFD,eAACE,mCAAiB,EAAA,EAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAA,aAAA,EAAe,UAAU,EAAA,CAAI,CAAA,EAAA,CACjH;AAgBX;;;;;AAKG;AACI,MAAM,sBAAsB,GAAG,CAAC,EACrC,MAAM,EACN,YAAY,EACZ,EAAE,EACF,QAAQ,EACR,YAAY,EAAE,SAAS,GAAG,iBAAiB,EAC3C,aAAa,EAAE,UAAU,GACG,MAC5BF,eAACG,gCAAgB,EAAA,EACf,aAAa,EAAA,IAAA,EACb,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,KACnCC,KAAE,CACA,kFAAkF,EAClF,UAAU,IAAI,6CAA6C,EAC3D,SAAS,IAAI,+CAA+C,CAC7D,EAAA,QAAA,EAGF,CAAC,EAAE,KAAK,EAAE,MACTL,eAAA,CAAAM,mBAAA,EAAA,EAAA,QAAA,EAAA,CACEL,cAAA,CAACM,0BAAU,EAAA,EAAA,YAAA,EACE,uBAAuB,EAAA,aAAA,EACrB,UAAU,EACvB,OAAO,EAAE,MAAM,KAAK,CAAC,KAAK,EAAE,EAC5B,SAAS,EAAC,uNAAuN,EAAA,QAAA,EAEjON,cAAA,CAACO,SAAS,EAAA,EAAC,SAAS,EAAC,QAAQ,EAAA,CAAG,EAAA,CACrB,EAEbP,cAAA,CAACQ,yBAAS,EAAA,EAAC,SAAS,EAAC,mDAAmD,EAAA,QAAA,EACtER,cAAA,CAACS,0BAAU,IAAC,EAAE,EAAE,EAAE,EAAA,YAAA,EAAc,SAAS,EAAE,SAAS,EAAC,2CAA2C,EAAA,QAAA,EAC7F,QAAQ,EAAA,CACE,EAAA,CACH,CAAA,EAAA,CACX,CACJ,EAAA,CACgB;;;;;"}
|
|
@@ -11,7 +11,7 @@ import { SidebarMenuButton } from './sidebar-menu-button.js';
|
|
|
11
11
|
* Consumers who supply their own header instead should set `showMobileHeader={false}`
|
|
12
12
|
* and embed a {@link SidebarMenuButton}.
|
|
13
13
|
*/
|
|
14
|
-
const MobileNavigationHeader = ({ isOpen, onOpenChange, controls, homeHref, onHomePress, logoTestId, 'data-testid': dataTestId, }) => (jsxs("header", { className: "flex h-14 items-center justify-between border-b border-secondary bg-
|
|
14
|
+
const MobileNavigationHeader = ({ isOpen, onOpenChange, controls, homeHref, onHomePress, logoTestId, 'data-testid': dataTestId, }) => (jsxs("header", { className: "flex h-14 items-center justify-between border-b border-secondary bg-primary p-3 pl-4 lg:hidden", children: [jsx(LogoLink, { href: homeHref, size: "sm", onClick: onHomePress, "data-testid": logoTestId }), jsx(SidebarMenuButton, { isOpen: isOpen, onPress: () => onOpenChange(!isOpen), controls: controls, "data-testid": dataTestId })] }));
|
|
15
15
|
/**
|
|
16
16
|
* The controlled slide-over drawer that holds the mobile navigation. Its open
|
|
17
17
|
* state is owned by `SidebarNavigation`, so it can be driven by either the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mobile-header.js","sources":["../../../../../src/components/organisms/SidebarNavigation/components/mobile-header.tsx"],"sourcesContent":[null],"names":["_jsxs","_jsx","AriaModalOverlay","_Fragment","AriaButton","CloseIcon","AriaModal","AriaDialog"],"mappings":";;;;;;;AA0BA;;;;;AAKG;AACI,MAAM,sBAAsB,GAAG,CAAC,EACrC,MAAM,EACN,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,UAAU,EACV,aAAa,EAAE,UAAU,GACG,MAC5BA,IAAA,CAAA,QAAA,EAAA,EAAQ,SAAS,EAAC,
|
|
1
|
+
{"version":3,"file":"mobile-header.js","sources":["../../../../../src/components/organisms/SidebarNavigation/components/mobile-header.tsx"],"sourcesContent":[null],"names":["_jsxs","_jsx","AriaModalOverlay","_Fragment","AriaButton","CloseIcon","AriaModal","AriaDialog"],"mappings":";;;;;;;AA0BA;;;;;AAKG;AACI,MAAM,sBAAsB,GAAG,CAAC,EACrC,MAAM,EACN,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,UAAU,EACV,aAAa,EAAE,UAAU,GACG,MAC5BA,IAAA,CAAA,QAAA,EAAA,EAAQ,SAAS,EAAC,gGAAgG,EAAA,QAAA,EAAA,CAChHC,GAAA,CAAC,QAAQ,EAAA,EAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAC,IAAI,EAAC,OAAO,EAAE,WAAW,EAAA,aAAA,EAAe,UAAU,EAAA,CAAI,EACrFA,IAAC,iBAAiB,EAAA,EAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAA,aAAA,EAAe,UAAU,EAAA,CAAI,CAAA,EAAA,CACjH;AAgBX;;;;;AAKG;AACI,MAAM,sBAAsB,GAAG,CAAC,EACrC,MAAM,EACN,YAAY,EACZ,EAAE,EACF,QAAQ,EACR,YAAY,EAAE,SAAS,GAAG,iBAAiB,EAC3C,aAAa,EAAE,UAAU,GACG,MAC5BA,IAACC,YAAgB,EAAA,EACf,aAAa,EAAA,IAAA,EACb,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,KACnC,EAAE,CACA,kFAAkF,EAClF,UAAU,IAAI,6CAA6C,EAC3D,SAAS,IAAI,+CAA+C,CAC7D,EAAA,QAAA,EAGF,CAAC,EAAE,KAAK,EAAE,MACTF,IAAA,CAAAG,QAAA,EAAA,EAAA,QAAA,EAAA,CACEF,GAAA,CAACG,MAAU,EAAA,EAAA,YAAA,EACE,uBAAuB,EAAA,aAAA,EACrB,UAAU,EACvB,OAAO,EAAE,MAAM,KAAK,CAAC,KAAK,EAAE,EAC5B,SAAS,EAAC,uNAAuN,EAAA,QAAA,EAEjOH,GAAA,CAACI,CAAS,EAAA,EAAC,SAAS,EAAC,QAAQ,EAAA,CAAG,EAAA,CACrB,EAEbJ,GAAA,CAACK,KAAS,EAAA,EAAC,SAAS,EAAC,mDAAmD,EAAA,QAAA,EACtEL,GAAA,CAACM,MAAU,IAAC,EAAE,EAAE,EAAE,EAAA,YAAA,EAAc,SAAS,EAAE,SAAS,EAAC,2CAA2C,EAAA,QAAA,EAC7F,QAAQ,EAAA,CACE,EAAA,CACH,CAAA,EAAA,CACX,CACJ,EAAA,CACgB;;;;"}
|
|
@@ -9,6 +9,7 @@ var hrefUtils = require('@flipdish/ui-library/utilities/hrefUtils');
|
|
|
9
9
|
var testIdUtils = require('@flipdish/ui-library/utilities/testIdUtils');
|
|
10
10
|
var React = require('react');
|
|
11
11
|
var reactAriaComponents = require('react-aria-components');
|
|
12
|
+
var useHotkeyHint = require('../../../../hooks/__internal__/useHotkeyHint/useHotkeyHint.cjs');
|
|
12
13
|
|
|
13
14
|
/** Derive a menu item's testid: explicit override wins, else `<prefix>--menu-item-<id|slug(label)>`. */
|
|
14
15
|
const menuItemTestId = (prefix, item) => item['data-testid'] ?? testIdUtils.joinTestId(prefix, `menu-item-${item.id ?? testIdUtils.slugifyTestId(item.label)}`);
|
|
@@ -17,7 +18,8 @@ const POPOVER_ANIMATION = ({ isEntering, isExiting }) => cx.cx('origin-(--trigge
|
|
|
17
18
|
'duration-100 ease-in animate-out fade-out placement-right:slide-out-to-left-0.5 placement-top:slide-out-to-bottom-0.5 placement-bottom:slide-out-to-top-0.5');
|
|
18
19
|
const MENU_ITEM_CLASSNAME = 'group/item flex w-full cursor-pointer px-1.5 focus:outline-hidden';
|
|
19
20
|
const NavAccountCardMenuItem = ({ icon: Icon, label, shortcut, href, onClick, 'data-testid': dataTestId, }) => {
|
|
20
|
-
const
|
|
21
|
+
const shortcutLabel = useHotkeyHint.useHotkeyHint(shortcut);
|
|
22
|
+
const content = (jsxRuntime.jsxs("div", { className: cx.cx('flex w-full items-center justify-between gap-3 rounded-md p-2 group-hover/item:bg-primary_hover', 'outline-focus-ring group-focus-visible/item:outline-2 group-focus-visible/item:outline-offset-2'), children: [jsxRuntime.jsxs("div", { className: "flex gap-2 text-sm font-semibold text-secondary group-hover/item:text-secondary_hover", children: [Icon && jsxRuntime.jsx(Icon, { className: "size-5 text-fg-quaternary group-hover/item:text-fg-quaternary_hover" }), " ", label] }), shortcutLabel && (jsxRuntime.jsx("kbd", { className: "flex rounded px-1 py-px font-body text-xs font-medium text-tertiary ring-1 ring-secondary ring-inset", children: shortcutLabel }))] }));
|
|
21
23
|
// A destination renders as a real anchor so it routes through `RouteProvider` and supports middle-click / new tab.
|
|
22
24
|
if (href !== undefined) {
|
|
23
25
|
const isExternal = hrefUtils.isExternalHref(href);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav-account-card.cjs","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-account-card.tsx"],"sourcesContent":[null],"names":["joinTestId","slugifyTestId","cx","_jsxs","_jsx","isExternalHref","AriaLink","safeHref","rootTestId","AriaDialog","_Fragment","useRef","useBreakpoints","useResolvedTestId","AriaDialogTrigger","AriaButton","testIdProps","Avatar","AriaPopover","AvatarLabelGroup","ChevronSelectorVertical"],"mappings":"
|
|
1
|
+
{"version":3,"file":"nav-account-card.cjs","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-account-card.tsx"],"sourcesContent":[null],"names":["joinTestId","slugifyTestId","cx","useHotkeyHint","_jsxs","_jsx","isExternalHref","AriaLink","safeHref","rootTestId","AriaDialog","_Fragment","useRef","useBreakpoints","useResolvedTestId","AriaDialogTrigger","AriaButton","testIdProps","Avatar","AriaPopover","AvatarLabelGroup","ChevronSelectorVertical"],"mappings":"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"}
|
|
@@ -19,7 +19,7 @@ export type NavAccountMenuItemType = {
|
|
|
19
19
|
icon?: FC<{
|
|
20
20
|
className?: string;
|
|
21
21
|
}>;
|
|
22
|
-
/** Keyboard shortcut hint to display. */
|
|
22
|
+
/** Keyboard shortcut hint to display. A shortcut (`⌘S`, `mod+s`) is drawn for the user's platform; text that is not a shortcut is shown as written. */
|
|
23
23
|
shortcut?: string;
|
|
24
24
|
/**
|
|
25
25
|
* Destination URL. When set the item renders as a real link (router integration, middle-click,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav-account-card.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-account-card.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,KAAK,EAAE,WAAW,IAAI,eAAe,EAAqB,SAAS,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"nav-account-card.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-account-card.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,KAAK,EAAE,WAAW,IAAI,eAAe,EAAqB,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAU1G,MAAM,MAAM,cAAc,GAAG;IAC3B,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,IAAI,CAAC,EAAE,EAAE,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClC,uJAAuJ;IACvJ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6FAA6F;IAC7F,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,uGAAuG;IACvG,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,0CAA0C;IAC1C,OAAO,EAAE,cAAc,CAAC;IACxB,uEAAuE;IACvE,SAAS,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACrC,gDAAgD;IAChD,eAAe,CAAC,EAAE,sBAAsB,EAAE,CAAC;IAC3C,0DAA0D;IAC1D,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAkEF,eAAO,MAAM,cAAc,GAAI,yEAM5B,eAAe,GAAG;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACrC,eAAe,CAAC,EAAE,sBAAsB,EAAE,CAAC;IAC3C,2FAA2F;IAC3F,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,gCAkCA,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,6HAS5B;IACD,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,8BAA8B;IAC9B,OAAO,EAAE,cAAc,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,uEAAuE;IACvE,SAAS,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACrC,gDAAgD;IAChD,eAAe,CAAC,EAAE,sBAAsB,EAAE,CAAC;IAC3C;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC5B,gEAAgE;IAChE,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,gCA4DA,CAAC"}
|
|
@@ -7,6 +7,7 @@ import { isExternalHref, safeHref } from '@flipdish/ui-library/utilities/hrefUti
|
|
|
7
7
|
import { useResolvedTestId, testIdProps, rootTestId, joinTestId, slugifyTestId } from '@flipdish/ui-library/utilities/testIdUtils';
|
|
8
8
|
import { useRef } from 'react';
|
|
9
9
|
import { DialogTrigger, Button, Popover, Dialog, Link } from 'react-aria-components';
|
|
10
|
+
import { useHotkeyHint } from '../../../../hooks/__internal__/useHotkeyHint/useHotkeyHint.js';
|
|
10
11
|
|
|
11
12
|
/** Derive a menu item's testid: explicit override wins, else `<prefix>--menu-item-<id|slug(label)>`. */
|
|
12
13
|
const menuItemTestId = (prefix, item) => item['data-testid'] ?? joinTestId(prefix, `menu-item-${item.id ?? slugifyTestId(item.label)}`);
|
|
@@ -15,7 +16,8 @@ const POPOVER_ANIMATION = ({ isEntering, isExiting }) => cx('origin-(--trigger-a
|
|
|
15
16
|
'duration-100 ease-in animate-out fade-out placement-right:slide-out-to-left-0.5 placement-top:slide-out-to-bottom-0.5 placement-bottom:slide-out-to-top-0.5');
|
|
16
17
|
const MENU_ITEM_CLASSNAME = 'group/item flex w-full cursor-pointer px-1.5 focus:outline-hidden';
|
|
17
18
|
const NavAccountCardMenuItem = ({ icon: Icon, label, shortcut, href, onClick, 'data-testid': dataTestId, }) => {
|
|
18
|
-
const
|
|
19
|
+
const shortcutLabel = useHotkeyHint(shortcut);
|
|
20
|
+
const content = (jsxs("div", { className: cx('flex w-full items-center justify-between gap-3 rounded-md p-2 group-hover/item:bg-primary_hover', 'outline-focus-ring group-focus-visible/item:outline-2 group-focus-visible/item:outline-offset-2'), children: [jsxs("div", { className: "flex gap-2 text-sm font-semibold text-secondary group-hover/item:text-secondary_hover", children: [Icon && jsx(Icon, { className: "size-5 text-fg-quaternary group-hover/item:text-fg-quaternary_hover" }), " ", label] }), shortcutLabel && (jsx("kbd", { className: "flex rounded px-1 py-px font-body text-xs font-medium text-tertiary ring-1 ring-secondary ring-inset", children: shortcutLabel }))] }));
|
|
19
21
|
// A destination renders as a real anchor so it routes through `RouteProvider` and supports middle-click / new tab.
|
|
20
22
|
if (href !== undefined) {
|
|
21
23
|
const isExternal = isExternalHref(href);
|