@flipdish/ui-library 0.30.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/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/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/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/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/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__/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,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;;;;"}
|
|
@@ -6,11 +6,17 @@ var cx = require('@flipdish/ui-library/utilities/cx');
|
|
|
6
6
|
var testIdUtils = require('@flipdish/ui-library/utilities/testIdUtils');
|
|
7
7
|
var reactAriaComponents = require('react-aria-components');
|
|
8
8
|
|
|
9
|
-
const ModalOverlay = (props) => {
|
|
10
|
-
return (jsxRuntime.jsx(reactAriaComponents.ModalOverlay, { ...props, className: (state) => cx.cx('fixed inset-0 z-50 flex min-h-dvh w-full items-center justify-end
|
|
9
|
+
const ModalOverlay = ({ children, ...props }) => {
|
|
10
|
+
return (jsxRuntime.jsx(reactAriaComponents.ModalOverlay, { ...props, className: (state) => cx.cx('fixed inset-0 z-50 flex min-h-dvh w-full items-center justify-end pl-6 outline-hidden md:pl-10',
|
|
11
|
+
// Nothing visible changes on the overlay itself; the bare animation keeps it mounted while its children animate.
|
|
12
|
+
state.isEntering && 'duration-300 animate-in', state.isExiting && 'duration-500 animate-out', typeof props.className === 'function' ? props.className(state) : props.className), children: (state) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { "aria-hidden": "true", className: cx.cx('absolute inset-0 bg-overlay/70 ease-linear', state.isEntering && 'duration-300 animate-in fade-in', state.isExiting && 'duration-500 animate-out fade-out') }), typeof children === 'function' ? children(state) : children] })) }));
|
|
11
13
|
};
|
|
12
14
|
ModalOverlay.displayName = 'ModalOverlay';
|
|
13
|
-
const Modal = (props) => (jsxRuntime.jsx(reactAriaComponents.Modal, { ...props, className: (state) => cx.cx(
|
|
15
|
+
const Modal = (props) => (jsxRuntime.jsx(reactAriaComponents.Modal, { ...props, className: (state) => cx.cx(
|
|
16
|
+
// relative, so the panel paints above the dimmer layer.
|
|
17
|
+
'relative inset-y-0 right-0 h-full w-full max-w-100 shadow-xl transition',
|
|
18
|
+
// The distance is spelled out: the bare utilities resolve to 0.25rem here, which reads as a fade, not a slide.
|
|
19
|
+
state.isEntering && 'duration-300 animate-in slide-in-from-right-[100%]', state.isExiting && 'duration-500 animate-out slide-out-to-right-[100%]', typeof props.className === 'function' ? props.className(state) : props.className) }));
|
|
14
20
|
Modal.displayName = 'Modal';
|
|
15
21
|
const Dialog = ({ 'data-testid': dataTestId, ...props }) => {
|
|
16
22
|
const rootTestId = testIdUtils.useResolvedTestId({ testId: dataTestId, segment: 'slideout-menu', rootName: 'slideout-menu' });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../../src/components/organisms/SlideoutMenu/index.tsx"],"sourcesContent":[null],"names":["_jsx","AriaModalOverlay","cx","AriaModal","useResolvedTestId","TestIdProvider","AriaDialog","useTestIdPrefix","joinTestId","
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../../src/components/organisms/SlideoutMenu/index.tsx"],"sourcesContent":[null],"names":["_jsx","AriaModalOverlay","cx","_jsxs","_Fragment","AriaModal","useResolvedTestId","TestIdProvider","AriaDialog","useTestIdPrefix","joinTestId","CloseButton","AriaDialogTrigger"],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import { DialogTrigger as AriaDialogTrigger } from 'react-aria-components';
|
|
|
4
4
|
interface ModalOverlayProps extends AriaModalOverlayProps, RefAttributes<HTMLDivElement> {
|
|
5
5
|
}
|
|
6
6
|
export declare const ModalOverlay: {
|
|
7
|
-
(props: ModalOverlayProps): import("react").JSX.Element;
|
|
7
|
+
({ children, ...props }: ModalOverlayProps): import("react").JSX.Element;
|
|
8
8
|
displayName: string;
|
|
9
9
|
};
|
|
10
10
|
interface ModalProps extends AriaModalOverlayProps, RefAttributes<HTMLDivElement> {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/SlideoutMenu/index.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC7E,OAAO,KAAK,EACV,WAAW,IAAI,eAAe,EAC9B,iBAAiB,IAAI,qBAAqB,EAC1C,gBAAgB,IAAI,oBAAoB,EACzC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,aAAa,IAAI,iBAAiB,EAGnC,MAAM,uBAAuB,CAAC;AAE/B,UAAU,iBAAkB,SAAQ,qBAAqB,EAAE,aAAa,CAAC,cAAc,CAAC;CAAG;AAE3F,eAAO,MAAM,YAAY;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/SlideoutMenu/index.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC7E,OAAO,KAAK,EACV,WAAW,IAAI,eAAe,EAC9B,iBAAiB,IAAI,qBAAqB,EAC1C,gBAAgB,IAAI,oBAAoB,EACzC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,aAAa,IAAI,iBAAiB,EAGnC,MAAM,uBAAuB,CAAC;AAE/B,UAAU,iBAAkB,SAAQ,qBAAqB,EAAE,aAAa,CAAC,cAAc,CAAC;CAAG;AAE3F,eAAO,MAAM,YAAY;6BAA4B,iBAAiB;;CA8BrE,CAAC;AAGF,UAAU,UAAW,SAAQ,qBAAqB,EAAE,aAAa,CAAC,cAAc,CAAC;CAAG;AAEpF,eAAO,MAAM,KAAK;YAAW,UAAU;;CActC,CAAC;AAGF,UAAU,WAAY,SAAQ,eAAe,EAAE,aAAa,CAAC,WAAW,CAAC;IACvE,wHAAwH;IACxH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,MAAM;8CAA6C,WAAW;;CAiB1E,CAAC;AAGF,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,EAAE,aAAa,CAAC,cAAc,CAAC;IAC/G,QAAQ,EAAE,SAAS,GAAG,CAAC,CAAC,QAAQ,EAAE,oBAAoB,GAAG;QAAE,KAAK,EAAE,MAAM,IAAI,CAAA;KAAE,KAAK,SAAS,CAAC,CAAC;IAC9F,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wHAAwH;IACxH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,QAAA,MAAM,IAAI;yEAAwE,iBAAiB;;CAclG,CAAC;AAGF,QAAA,MAAM,OAAO;oDAA4D,qBAAqB,CAAC,KAAK,CAAC,GAAG;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE;;CAYjI,CAAC;AAGF,MAAM,WAAW,mBAAoB,SAAQ,qBAAqB,CAAC,QAAQ,CAAC;IAC1E,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,QAAA,MAAM,MAAM;4EAA2E,mBAAmB;;CAezG,CAAC;AAGF,QAAA,MAAM,MAAM;8CAA6C,qBAAqB,CAAC,QAAQ,CAAC,GAAG;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE;;CAWpH,CAAC;AAGF,QAAA,MAAM,YAAY,EAAW,OAAO,IAAI,GAAG;IACzC,OAAO,EAAE,OAAO,iBAAiB,CAAC;IAClC,OAAO,EAAE,OAAO,OAAO,CAAC;IACxB,MAAM,EAAE,OAAO,MAAM,CAAC;IACtB,MAAM,EAAE,OAAO,MAAM,CAAC;CACvB,CAAC;AAQF,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -1,14 +1,20 @@
|
|
|
1
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import { CloseButton } from '@flipdish/ui-library/components/atoms/CloseButton';
|
|
3
3
|
import { cx } from '@flipdish/ui-library/utilities/cx';
|
|
4
4
|
import { useResolvedTestId, TestIdProvider, useTestIdPrefix, joinTestId } from '@flipdish/ui-library/utilities/testIdUtils';
|
|
5
5
|
import { Dialog as Dialog$1, Modal as Modal$1, ModalOverlay as ModalOverlay$1, DialogTrigger } from 'react-aria-components';
|
|
6
6
|
|
|
7
|
-
const ModalOverlay = (props) => {
|
|
8
|
-
return (jsx(ModalOverlay$1, { ...props, className: (state) => cx('fixed inset-0 z-50 flex min-h-dvh w-full items-center justify-end
|
|
7
|
+
const ModalOverlay = ({ children, ...props }) => {
|
|
8
|
+
return (jsx(ModalOverlay$1, { ...props, className: (state) => cx('fixed inset-0 z-50 flex min-h-dvh w-full items-center justify-end pl-6 outline-hidden md:pl-10',
|
|
9
|
+
// Nothing visible changes on the overlay itself; the bare animation keeps it mounted while its children animate.
|
|
10
|
+
state.isEntering && 'duration-300 animate-in', state.isExiting && 'duration-500 animate-out', typeof props.className === 'function' ? props.className(state) : props.className), children: (state) => (jsxs(Fragment, { children: [jsx("div", { "aria-hidden": "true", className: cx('absolute inset-0 bg-overlay/70 ease-linear', state.isEntering && 'duration-300 animate-in fade-in', state.isExiting && 'duration-500 animate-out fade-out') }), typeof children === 'function' ? children(state) : children] })) }));
|
|
9
11
|
};
|
|
10
12
|
ModalOverlay.displayName = 'ModalOverlay';
|
|
11
|
-
const Modal = (props) => (jsx(Modal$1, { ...props, className: (state) => cx(
|
|
13
|
+
const Modal = (props) => (jsx(Modal$1, { ...props, className: (state) => cx(
|
|
14
|
+
// relative, so the panel paints above the dimmer layer.
|
|
15
|
+
'relative inset-y-0 right-0 h-full w-full max-w-100 shadow-xl transition',
|
|
16
|
+
// The distance is spelled out: the bare utilities resolve to 0.25rem here, which reads as a fade, not a slide.
|
|
17
|
+
state.isEntering && 'duration-300 animate-in slide-in-from-right-[100%]', state.isExiting && 'duration-500 animate-out slide-out-to-right-[100%]', typeof props.className === 'function' ? props.className(state) : props.className) }));
|
|
12
18
|
Modal.displayName = 'Modal';
|
|
13
19
|
const Dialog = ({ 'data-testid': dataTestId, ...props }) => {
|
|
14
20
|
const rootTestId = useResolvedTestId({ testId: dataTestId, segment: 'slideout-menu', rootName: 'slideout-menu' });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/components/organisms/SlideoutMenu/index.tsx"],"sourcesContent":[null],"names":["_jsx","AriaModalOverlay","
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/organisms/SlideoutMenu/index.tsx"],"sourcesContent":[null],"names":["_jsx","AriaModalOverlay","_jsxs","_Fragment","AriaModal","AriaDialog","AriaDialogTrigger"],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var utils = require('@react-aria/utils');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Takes the page area out of reach while a `SidePanel` covers it below `lg`. The shell keeps its own
|
|
8
|
+
* handle on the scroll area while still forwarding the app's ref. `inert` is written to the element
|
|
9
|
+
* rather than held in state: the closing panel hands focus back in the same effect pass, and a page
|
|
10
|
+
* still inert would refuse it.
|
|
11
|
+
*
|
|
12
|
+
* @returns the ref to put on the scroll area, and the setter to provide through `PageCoverContext`
|
|
13
|
+
*/
|
|
14
|
+
const usePageCover = (forwardedRef) => {
|
|
15
|
+
const scrollAreaRef = utils.useObjectRef(forwardedRef);
|
|
16
|
+
const setPageCovered = React.useCallback((isCovered) => {
|
|
17
|
+
if (scrollAreaRef.current)
|
|
18
|
+
scrollAreaRef.current.inert = isCovered;
|
|
19
|
+
}, [scrollAreaRef]);
|
|
20
|
+
return { scrollAreaRef, setPageCovered };
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
exports.usePageCover = usePageCover;
|
|
24
|
+
//# sourceMappingURL=usePageCover.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePageCover.cjs","sources":["../../../../../src/components/templates/AppShell/hooks/usePageCover.ts"],"sourcesContent":[null],"names":["useObjectRef","useCallback"],"mappings":";;;;;AAMA;;;;;;;AAOG;AACI,MAAM,YAAY,GAAG,CAAC,YAA6C,KAAI;AAC5E,IAAA,MAAM,aAAa,GAAGA,kBAAY,CAAC,YAAY,CAAC;AAEhD,IAAA,MAAM,cAAc,GAAGC,iBAAW,CAChC,CAAC,SAAkB,KAAI;QACrB,IAAI,aAAa,CAAC,OAAO;AAAE,YAAA,aAAa,CAAC,OAAO,CAAC,KAAK,GAAG,SAAS;AACpE,IAAA,CAAC,EACD,CAAC,aAAa,CAAC,CAChB;AAED,IAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE;AAC1C;;;;"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Ref } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Takes the page area out of reach while a `SidePanel` covers it below `lg`. The shell keeps its own
|
|
4
|
+
* handle on the scroll area while still forwarding the app's ref. `inert` is written to the element
|
|
5
|
+
* rather than held in state: the closing panel hands focus back in the same effect pass, and a page
|
|
6
|
+
* still inert would refuse it.
|
|
7
|
+
*
|
|
8
|
+
* @returns the ref to put on the scroll area, and the setter to provide through `PageCoverContext`
|
|
9
|
+
*/
|
|
10
|
+
export declare const usePageCover: (forwardedRef: Ref<HTMLDivElement> | undefined) => {
|
|
11
|
+
scrollAreaRef: import("react").MutableRefObject<HTMLDivElement | null>;
|
|
12
|
+
setPageCovered: (isCovered: boolean) => void;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=usePageCover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePageCover.d.ts","sourceRoot":"","sources":["../../../../../src/components/templates/AppShell/hooks/usePageCover.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAGjC;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,GAAI,cAAc,GAAG,CAAC,cAAc,CAAC,GAAG,SAAS;;gCAI1D,OAAO;CAOtB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useObjectRef } from '@react-aria/utils';
|
|
2
|
+
import { useCallback } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Takes the page area out of reach while a `SidePanel` covers it below `lg`. The shell keeps its own
|
|
6
|
+
* handle on the scroll area while still forwarding the app's ref. `inert` is written to the element
|
|
7
|
+
* rather than held in state: the closing panel hands focus back in the same effect pass, and a page
|
|
8
|
+
* still inert would refuse it.
|
|
9
|
+
*
|
|
10
|
+
* @returns the ref to put on the scroll area, and the setter to provide through `PageCoverContext`
|
|
11
|
+
*/
|
|
12
|
+
const usePageCover = (forwardedRef) => {
|
|
13
|
+
const scrollAreaRef = useObjectRef(forwardedRef);
|
|
14
|
+
const setPageCovered = useCallback((isCovered) => {
|
|
15
|
+
if (scrollAreaRef.current)
|
|
16
|
+
scrollAreaRef.current.inert = isCovered;
|
|
17
|
+
}, [scrollAreaRef]);
|
|
18
|
+
return { scrollAreaRef, setPageCovered };
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export { usePageCover };
|
|
22
|
+
//# sourceMappingURL=usePageCover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePageCover.js","sources":["../../../../../src/components/templates/AppShell/hooks/usePageCover.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAMA;;;;;;;AAOG;AACI,MAAM,YAAY,GAAG,CAAC,YAA6C,KAAI;AAC5E,IAAA,MAAM,aAAa,GAAG,YAAY,CAAC,YAAY,CAAC;AAEhD,IAAA,MAAM,cAAc,GAAG,WAAW,CAChC,CAAC,SAAkB,KAAI;QACrB,IAAI,aAAa,CAAC,OAAO;AAAE,YAAA,aAAa,CAAC,OAAO,CAAC,KAAK,GAAG,SAAS;AACpE,IAAA,CAAC,EACD,CAAC,aAAa,CAAC,CAChB;AAED,IAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE;AAC1C;;;;"}
|
|
@@ -3,25 +3,31 @@
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var cx = require('@flipdish/ui-library/utilities/cx');
|
|
5
5
|
var testIdUtils = require('@flipdish/ui-library/utilities/testIdUtils');
|
|
6
|
+
var pageCoverContext = require('../../organisms/SidePanel/providers/page-cover-context.cjs');
|
|
7
|
+
var usePageCover = require('./hooks/usePageCover.cjs');
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* Layout-only template for an app shell: navigation beside a content column that stacks the
|
|
9
|
-
* header above the page, with an optional side panel
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* header above the page, with an optional side panel under the header. The shell is exactly the
|
|
12
|
+
* height of the window and the document never scrolls: the page content scrolls in its own area
|
|
13
|
+
* under the header, so the header, navigation and side panel stay in place with no sticky
|
|
14
|
+
* positioning. It holds no state and renders whatever is passed to its slots, so the app keeps
|
|
15
|
+
* ownership of navigation, search and panel state.
|
|
14
16
|
*
|
|
15
17
|
* @summary window-height layout template placing navigation, header, a scrolling page area and a side panel
|
|
16
18
|
*/
|
|
17
19
|
const AppShell = ({ sidebar, header, panel, children, scrollAreaProps, className, 'data-testid': dataTestId }) => {
|
|
18
20
|
const appShellTestId = testIdUtils.useResolvedTestId({ testId: dataTestId, segment: 'app-shell', rootName: 'app-shell' });
|
|
21
|
+
// A `SidePanel` in the `panel` slot calls the setter while it covers the page area below `lg`.
|
|
22
|
+
const { scrollAreaRef, setPageCovered } = usePageCover.usePageCover(scrollAreaProps?.ref);
|
|
19
23
|
return (
|
|
20
24
|
// A column below `lg`, so a navigation that renders its own mobile top bar stacks above the content.
|
|
21
|
-
jsxRuntime.jsxs("div", { "data-testid": appShellTestId, className: cx.cx('flex h-dvh w-full flex-col overflow-hidden bg-primary lg:flex-row', className), children: [sidebar, jsxRuntime.jsxs("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col", children: [header, jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1", children: [jsxRuntime.jsx("div", { id: scrollAreaProps?.id, ref:
|
|
25
|
+
jsxRuntime.jsxs("div", { "data-testid": appShellTestId, className: cx.cx('flex h-dvh w-full flex-col overflow-hidden bg-primary lg:flex-row', className), children: [sidebar, jsxRuntime.jsxs("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col", children: [header, jsxRuntime.jsxs("div", { className: "relative flex min-h-0 flex-1 overflow-clip", children: [jsxRuntime.jsx("div", { id: scrollAreaProps?.id, ref: scrollAreaRef, "data-testid": scrollAreaProps?.['data-testid'] ?? testIdUtils.joinTestId(appShellTestId, 'scroll-area'),
|
|
22
26
|
// Focusable so keyboard users can scroll a page that has no focusable content of its own (axe: scrollable-region-focusable).
|
|
23
27
|
// biome-ignore lint/a11y/noNoninteractiveTabindex: a scrollable region must be reachable by keyboard
|
|
24
|
-
tabIndex: 0,
|
|
28
|
+
tabIndex: 0,
|
|
29
|
+
// isolate keeps the page's own stacked content (sticky headers) under a panel that covers it.
|
|
30
|
+
className: "isolate flex min-w-0 flex-1 flex-col overflow-y-auto outline-focus-ring focus-visible:outline-2 focus-visible:-outline-offset-2", children: children }), jsxRuntime.jsx(pageCoverContext.PageCoverContext.Provider, { value: setPageCovered, children: panel })] })] })] }));
|
|
25
31
|
};
|
|
26
32
|
|
|
27
33
|
exports.AppShell = AppShell;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../../src/components/templates/AppShell/index.tsx"],"sourcesContent":[null],"names":["useResolvedTestId","_jsxs","cx","_jsx","joinTestId"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../../src/components/templates/AppShell/index.tsx"],"sourcesContent":[null],"names":["useResolvedTestId","usePageCover","_jsxs","cx","_jsx","joinTestId","PageCoverContext"],"mappings":";;;;;;;;AAsCA;;;;;;;;;AASG;MACU,QAAQ,GAAG,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAiB,KAAe;AAChJ,IAAA,MAAM,cAAc,GAAGA,6BAAiB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;;AAE7G,IAAA,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,GAAGC,yBAAY,CAAC,eAAe,EAAE,GAAG,CAAC;IAE5E;;IAEEC,eAAA,CAAA,KAAA,EAAA,EAAA,aAAA,EAAkB,cAAc,EAAE,SAAS,EAAEC,KAAE,CAAC,mEAAmE,EAAE,SAAS,CAAC,aAC5H,OAAO,EAGRD,yBAAK,SAAS,EAAC,sCAAsC,EAAA,QAAA,EAAA,CAClD,MAAM,EAGPA,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,4CAA4C,EAAA,QAAA,EAAA,CACzDE,cAAA,CAAA,KAAA,EAAA,EACE,EAAE,EAAE,eAAe,EAAE,EAAE,EACvB,GAAG,EAAE,aAAa,EAAA,aAAA,EACL,eAAe,GAAG,aAAa,CAAC,IAAIC,sBAAU,CAAC,cAAc,EAAE,aAAa,CAAC;;;AAG1F,gCAAA,QAAQ,EAAE,CAAC;;gCAEX,SAAS,EAAC,iIAAiI,EAAA,QAAA,EAE1I,QAAQ,GACL,EAEND,cAAA,CAACE,iCAAgB,CAAC,QAAQ,IAAC,KAAK,EAAE,cAAc,EAAA,QAAA,EAAG,KAAK,GAA6B,CAAA,EAAA,CACjF,CAAA,EAAA,CACF,CAAA,EAAA,CACF;AAEV;;;;"}
|
|
@@ -13,8 +13,9 @@ export interface AppShellProps {
|
|
|
13
13
|
/** Top bar, rendered at the top of the content column. It stays in place while the page area scrolls. Compose `<ApplicationHeader>` here. */
|
|
14
14
|
header?: ReactNode;
|
|
15
15
|
/**
|
|
16
|
-
* Side panel rendered under the header
|
|
17
|
-
*
|
|
16
|
+
* Side panel rendered under the header. From `lg` it sits beside the page area, which narrows to make
|
|
17
|
+
* room. Below `lg` it covers the page area, which is then out of reach of keyboard and assistive
|
|
18
|
+
* technology until the panel closes. Compose one `<SidePanel>` here and switch its content.
|
|
18
19
|
*/
|
|
19
20
|
panel?: ReactNode;
|
|
20
21
|
/** Page content, normally a `<PageLayout>`. Rendered inside the shell's scroll area. */
|
|
@@ -28,11 +29,11 @@ export interface AppShellProps {
|
|
|
28
29
|
}
|
|
29
30
|
/**
|
|
30
31
|
* Layout-only template for an app shell: navigation beside a content column that stacks the
|
|
31
|
-
* header above the page, with an optional side panel
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
32
|
+
* header above the page, with an optional side panel under the header. The shell is exactly the
|
|
33
|
+
* height of the window and the document never scrolls: the page content scrolls in its own area
|
|
34
|
+
* under the header, so the header, navigation and side panel stay in place with no sticky
|
|
35
|
+
* positioning. It holds no state and renders whatever is passed to its slots, so the app keeps
|
|
36
|
+
* ownership of navigation, search and panel state.
|
|
36
37
|
*
|
|
37
38
|
* @summary window-height layout template placing navigation, header, a scrolling page area and a side panel
|
|
38
39
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/templates/AppShell/index.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/templates/AppShell/index.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAI5C,MAAM,WAAW,uBAAuB;IACtC,wFAAwF;IACxF,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,yGAAyG;IACzG,GAAG,CAAC,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IAC1B,2FAA2F;IAC3F,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,wGAAwG;IACxG,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,6IAA6I;IAC7I,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,wFAAwF;IACxF,QAAQ,EAAE,SAAS,CAAC;IACpB,sGAAsG;IACtG,eAAe,CAAC,EAAE,uBAAuB,CAAC;IAC1C,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,QAAQ,GAAI,6FAA6F,aAAa,KAAG,SAkCrI,CAAC"}
|