@flipdish/ui-library 0.43.2 → 0.45.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.
Files changed (77) hide show
  1. package/dist/components/organisms/SidePanel/components/SidePanelRegion.cjs +9 -1
  2. package/dist/components/organisms/SidePanel/components/SidePanelRegion.cjs.map +1 -1
  3. package/dist/components/organisms/SidePanel/components/SidePanelRegion.d.ts.map +1 -1
  4. package/dist/components/organisms/SidePanel/components/SidePanelRegion.js +9 -1
  5. package/dist/components/organisms/SidePanel/components/SidePanelRegion.js.map +1 -1
  6. package/dist/components/organisms/SlideoutMenu/components/SlideoutShell.cjs +36 -9
  7. package/dist/components/organisms/SlideoutMenu/components/SlideoutShell.cjs.map +1 -1
  8. package/dist/components/organisms/SlideoutMenu/components/SlideoutShell.d.ts +2 -2
  9. package/dist/components/organisms/SlideoutMenu/components/SlideoutShell.d.ts.map +1 -1
  10. package/dist/components/organisms/SlideoutMenu/components/SlideoutShell.js +37 -10
  11. package/dist/components/organisms/SlideoutMenu/components/SlideoutShell.js.map +1 -1
  12. package/dist/components/organisms/SlideoutMenu/hooks/useCloseWhenCovered.cjs +31 -0
  13. package/dist/components/organisms/SlideoutMenu/hooks/useCloseWhenCovered.cjs.map +1 -0
  14. package/dist/components/organisms/SlideoutMenu/hooks/useCloseWhenCovered.d.ts +15 -0
  15. package/dist/components/organisms/SlideoutMenu/hooks/useCloseWhenCovered.d.ts.map +1 -0
  16. package/dist/components/organisms/SlideoutMenu/hooks/useCloseWhenCovered.js +29 -0
  17. package/dist/components/organisms/SlideoutMenu/hooks/useCloseWhenCovered.js.map +1 -0
  18. package/dist/components/organisms/SlideoutMenu/hooks/useSlideoutState.cjs +3 -2
  19. package/dist/components/organisms/SlideoutMenu/hooks/useSlideoutState.cjs.map +1 -1
  20. package/dist/components/organisms/SlideoutMenu/hooks/useSlideoutState.d.ts.map +1 -1
  21. package/dist/components/organisms/SlideoutMenu/hooks/useSlideoutState.js +4 -3
  22. package/dist/components/organisms/SlideoutMenu/hooks/useSlideoutState.js.map +1 -1
  23. package/dist/components/organisms/SlideoutMenu/index.cjs +7 -1
  24. package/dist/components/organisms/SlideoutMenu/index.cjs.map +1 -1
  25. package/dist/components/organisms/SlideoutMenu/index.d.ts +19 -2
  26. package/dist/components/organisms/SlideoutMenu/index.d.ts.map +1 -1
  27. package/dist/components/organisms/SlideoutMenu/index.js +7 -1
  28. package/dist/components/organisms/SlideoutMenu/index.js.map +1 -1
  29. package/dist/components/organisms/SlideoutMenu/providers/PageArea.context.cjs +14 -0
  30. package/dist/components/organisms/SlideoutMenu/providers/PageArea.context.cjs.map +1 -0
  31. package/dist/components/organisms/SlideoutMenu/providers/PageArea.context.d.ts +9 -0
  32. package/dist/components/organisms/SlideoutMenu/providers/PageArea.context.d.ts.map +1 -0
  33. package/dist/components/organisms/SlideoutMenu/providers/PageArea.context.js +12 -0
  34. package/dist/components/organisms/SlideoutMenu/providers/PageArea.context.js.map +1 -0
  35. package/dist/components/templates/AppShell/index.cjs +11 -7
  36. package/dist/components/templates/AppShell/index.cjs.map +1 -1
  37. package/dist/components/templates/AppShell/index.d.ts +2 -1
  38. package/dist/components/templates/AppShell/index.d.ts.map +1 -1
  39. package/dist/components/templates/AppShell/index.js +11 -7
  40. package/dist/components/templates/AppShell/index.js.map +1 -1
  41. package/dist/hooks/__internal__/usePanelFocus/usePanelFocus.cjs +156 -0
  42. package/dist/hooks/__internal__/usePanelFocus/usePanelFocus.cjs.map +1 -0
  43. package/dist/hooks/__internal__/usePanelFocus/usePanelFocus.d.ts +36 -0
  44. package/dist/hooks/__internal__/usePanelFocus/usePanelFocus.d.ts.map +1 -0
  45. package/dist/hooks/__internal__/usePanelFocus/usePanelFocus.js +154 -0
  46. package/dist/hooks/__internal__/usePanelFocus/usePanelFocus.js.map +1 -0
  47. package/dist/providers/ThemeProvider/Theme.context.cjs +17 -0
  48. package/dist/providers/ThemeProvider/Theme.context.cjs.map +1 -0
  49. package/dist/providers/ThemeProvider/Theme.context.d.ts +16 -0
  50. package/dist/providers/ThemeProvider/Theme.context.d.ts.map +1 -0
  51. package/dist/providers/ThemeProvider/Theme.context.js +14 -0
  52. package/dist/providers/ThemeProvider/Theme.context.js.map +1 -0
  53. package/dist/providers/ThemeProvider/index.cjs +3 -3
  54. package/dist/providers/ThemeProvider/index.cjs.map +1 -1
  55. package/dist/providers/ThemeProvider/index.d.ts +1 -7
  56. package/dist/providers/ThemeProvider/index.d.ts.map +1 -1
  57. package/dist/providers/ThemeProvider/index.js +2 -2
  58. package/dist/providers/ThemeProvider/index.js.map +1 -1
  59. package/dist/utilities/__internal__/inertUtils/inert.utils.cjs +46 -0
  60. package/dist/utilities/__internal__/inertUtils/inert.utils.cjs.map +1 -0
  61. package/dist/utilities/__internal__/inertUtils/inert.utils.d.ts +18 -0
  62. package/dist/utilities/__internal__/inertUtils/inert.utils.d.ts.map +1 -0
  63. package/dist/utilities/__internal__/inertUtils/inert.utils.js +43 -0
  64. package/dist/utilities/__internal__/inertUtils/inert.utils.js.map +1 -0
  65. package/dist/utilities/__internal__/pageCoverUtils/pageCover.utils.cjs +30 -0
  66. package/dist/utilities/__internal__/pageCoverUtils/pageCover.utils.cjs.map +1 -0
  67. package/dist/utilities/__internal__/pageCoverUtils/pageCover.utils.d.ts +19 -0
  68. package/dist/utilities/__internal__/pageCoverUtils/pageCover.utils.d.ts.map +1 -0
  69. package/dist/utilities/__internal__/pageCoverUtils/pageCover.utils.js +26 -0
  70. package/dist/utilities/__internal__/pageCoverUtils/pageCover.utils.js.map +1 -0
  71. package/package.json +1 -1
  72. package/dist/components/organisms/SidePanel/hooks/usePanelFocus.cjs +0 -92
  73. package/dist/components/organisms/SidePanel/hooks/usePanelFocus.cjs.map +0 -1
  74. package/dist/components/organisms/SidePanel/hooks/usePanelFocus.d.ts +0 -26
  75. package/dist/components/organisms/SidePanel/hooks/usePanelFocus.d.ts.map +0 -1
  76. package/dist/components/organisms/SidePanel/hooks/usePanelFocus.js +0 -90
  77. package/dist/components/organisms/SidePanel/hooks/usePanelFocus.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import type { ComponentPropsWithRef, ReactNode } from 'react';
1
+ import type { ComponentPropsWithRef, ReactNode, RefObject } from 'react';
2
2
  import { DialogTrigger as AriaDialogTrigger } from 'react-aria-components';
3
3
  import type { SlideoutRenderProps } from './components/SlideoutShell';
4
4
  import type { SlideoutBounds } from './utilities/slideoutMenu.utils';
@@ -71,10 +71,26 @@ declare const Footer: {
71
71
  }): import("react").JSX.Element;
72
72
  displayName: string;
73
73
  };
74
+ export interface SlideoutPageAreaProps {
75
+ /**
76
+ * The element under the box slideouts cover below `lg`: the page area, with a side panel that covers it, never the header
77
+ * or the sidebar. It goes `inert` while a slideout covers it and is restored as the slideout closes, so it must stay
78
+ * mounted meanwhile, and nothing else may write `inert` on it.
79
+ */
80
+ areaRef: RefObject<HTMLElement | null>;
81
+ /** The layout, wrapping every place a slideout renders from, such as the header as well as the page. */
82
+ children: ReactNode;
83
+ }
84
+ /** Names what the slideouts below it cover below `lg`, for a layout of its own; `AppShell` does it for its page area. */
85
+ declare const PageArea: {
86
+ ({ areaRef, children }: SlideoutPageAreaProps): import("react").JSX.Element;
87
+ displayName: string;
88
+ };
74
89
  /**
75
90
  * Panel that slides in from the right edge and floats over the page without dimming or blocking it,
76
91
  * for the detail of the record the user just selected. It covers the page area only, never the header, the
77
- * sidebar or a docked side panel; compose `Header`, `Content` and `Footer` inside it.
92
+ * sidebar or a docked side panel; below `lg` it fills that area and the page under it goes inert until it
93
+ * closes. Compose `Header`, `Content` and `Footer` inside it.
78
94
  *
79
95
  * @summary non-modal right-edge panel for the selected record's detail
80
96
  */
@@ -83,6 +99,7 @@ declare const SlideoutMenu: typeof Menu & {
83
99
  Content: typeof Content;
84
100
  Header: typeof Header;
85
101
  Footer: typeof Footer;
102
+ PageArea: typeof PageArea;
86
103
  };
87
104
  export { SlideoutMenu };
88
105
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/SlideoutMenu/index.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D,OAAO,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAErE,YAAY,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,YAAY,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAExH,MAAM,WAAW,iBAAiB;IAChC,uGAAuG;IACvG,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,wFAAwF;IACxF,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,uHAAuH;IACvH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0GAA0G;IAC1G,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yDAAyD;IACzD,QAAQ,EAAE,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,mBAAmB,KAAK,SAAS,CAAC,CAAC;IAClE,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wHAAwH;IACxH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,QAAA,MAAM,IAAI;YAAW,iBAAiB;;CAAiC,CAAC;AAGxE,QAAA,MAAM,OAAO;8CAA6C,qBAAqB,CAAC,KAAK,CAAC,GAAG;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE;;CAYlH,CAAC;AAGF,MAAM,WAAW,mBAAoB,SAAQ,qBAAqB,CAAC,KAAK,CAAC;IACvE,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,gIAAgI;IAChI,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uIAAuI;IACvI,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6IAA6I;IAC7I,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,QAAA,MAAM,MAAM;2HAWT,mBAAmB;;CA+CrB,CAAC;AAGF,QAAA,MAAM,MAAM;8CAA6C,qBAAqB,CAAC,KAAK,CAAC,GAAG;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE;;CAYjH,CAAC;AAGF;;;;;;GAMG;AACH,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
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/SlideoutMenu/index.tsx"],"names":[],"mappings":"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"}
@@ -8,6 +8,7 @@ import { useObjectRef } from '@react-aria/utils';
8
8
  import { useContext, useRef, useLayoutEffect } from 'react';
9
9
  import { DialogTrigger } from 'react-aria-components';
10
10
  import { SlideoutShell } from './components/SlideoutShell.js';
11
+ import { PageAreaContext } from './providers/PageArea.context.js';
11
12
  import { SlideoutMenuContext } from './providers/SlideoutMenu.context.js';
12
13
  export { APP_HEADER_HEIGHT_VAR, APP_SIDEBAR_WIDTH_VAR, APP_SIDE_PANEL_WIDTH_VAR } from './utilities/slideoutMenu.utils.js';
13
14
 
@@ -45,10 +46,14 @@ const Footer = ({ 'data-testid': dataTestId, ...props }) => {
45
46
  return (jsx("div", { ...props, "data-testid": footerTestId, className: cx('w-full p-4 shadow-[inset_0px_1px_0px_0px] shadow-border-secondary md:px-6', props.className) }));
46
47
  };
47
48
  Footer.displayName = 'SlideoutFooter';
49
+ /** Names what the slideouts below it cover below `lg`, for a layout of its own; `AppShell` does it for its page area. */
50
+ const PageArea = ({ areaRef, children }) => jsx(PageAreaContext.Provider, { value: areaRef, children: children });
51
+ PageArea.displayName = 'SlideoutPageArea';
48
52
  /**
49
53
  * Panel that slides in from the right edge and floats over the page without dimming or blocking it,
50
54
  * for the detail of the record the user just selected. It covers the page area only, never the header, the
51
- * sidebar or a docked side panel; compose `Header`, `Content` and `Footer` inside it.
55
+ * sidebar or a docked side panel; below `lg` it fills that area and the page under it goes inert until it
56
+ * closes. Compose `Header`, `Content` and `Footer` inside it.
52
57
  *
53
58
  * @summary non-modal right-edge panel for the selected record's detail
54
59
  */
@@ -58,6 +63,7 @@ SlideoutMenu.Trigger = DialogTrigger;
58
63
  SlideoutMenu.Content = Content;
59
64
  SlideoutMenu.Header = Header;
60
65
  SlideoutMenu.Footer = Footer;
66
+ SlideoutMenu.PageArea = PageArea;
61
67
 
62
68
  export { SlideoutMenu };
63
69
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/components/organisms/SlideoutMenu/index.tsx"],"sourcesContent":[null],"names":["_jsx","_jsxs","AriaDialogTrigger"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/components/organisms/SlideoutMenu/index.tsx"],"sourcesContent":[null],"names":["_jsx","_jsxs","AriaDialogTrigger"],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+
5
+ /**
6
+ * Provided by `AppShell`, or by `SlideoutMenu.PageArea` in a layout of its own: the element under the box a
7
+ * `SlideoutMenu` covers below `lg`, the page area together with a side panel beside it. The panel makes it
8
+ * inert while it covers it, so keyboard and assistive technology skip what nobody can see. Context, so a
9
+ * panel anywhere in the layout finds it, the header included.
10
+ */
11
+ const PageAreaContext = React.createContext(undefined);
12
+
13
+ exports.PageAreaContext = PageAreaContext;
14
+ //# sourceMappingURL=PageArea.context.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageArea.context.cjs","sources":["../../../../../src/components/organisms/SlideoutMenu/providers/PageArea.context.ts"],"sourcesContent":[null],"names":["createContext"],"mappings":";;;;AAKA;;;;;AAKG;MACU,eAAe,GAAGA,mBAAa,CAA4C,SAAS;;"}
@@ -0,0 +1,9 @@
1
+ import type { RefObject } from 'react';
2
+ /**
3
+ * Provided by `AppShell`, or by `SlideoutMenu.PageArea` in a layout of its own: the element under the box a
4
+ * `SlideoutMenu` covers below `lg`, the page area together with a side panel beside it. The panel makes it
5
+ * inert while it covers it, so keyboard and assistive technology skip what nobody can see. Context, so a
6
+ * panel anywhere in the layout finds it, the header included.
7
+ */
8
+ export declare const PageAreaContext: import("react").Context<RefObject<HTMLElement | null> | undefined>;
9
+ //# sourceMappingURL=PageArea.context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageArea.context.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/SlideoutMenu/providers/PageArea.context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC;;;;;GAKG;AACH,eAAO,MAAM,eAAe,oEAAsE,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { createContext } from 'react';
2
+
3
+ /**
4
+ * Provided by `AppShell`, or by `SlideoutMenu.PageArea` in a layout of its own: the element under the box a
5
+ * `SlideoutMenu` covers below `lg`, the page area together with a side panel beside it. The panel makes it
6
+ * inert while it covers it, so keyboard and assistive technology skip what nobody can see. Context, so a
7
+ * panel anywhere in the layout finds it, the header included.
8
+ */
9
+ const PageAreaContext = createContext(undefined);
10
+
11
+ export { PageAreaContext };
12
+ //# sourceMappingURL=PageArea.context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageArea.context.js","sources":["../../../../../src/components/organisms/SlideoutMenu/providers/PageArea.context.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAKA;;;;;AAKG;MACU,eAAe,GAAG,aAAa,CAA4C,SAAS;;"}
@@ -3,8 +3,10 @@
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 React = require('react');
6
7
  var PageCover_context = require('../../organisms/SidePanel/providers/PageCover.context.cjs');
7
8
  var OverlayBounds_context = require('../../organisms/SlideoutMenu/providers/OverlayBounds.context.cjs');
9
+ var PageArea_context = require('../../organisms/SlideoutMenu/providers/PageArea.context.cjs');
8
10
  var usePageAreaBounds = require('./hooks/usePageAreaBounds.cjs');
9
11
  var usePageCover = require('./hooks/usePageCover.cjs');
10
12
 
@@ -20,16 +22,18 @@ const AppShell = ({ sidebar, header, panel, children, scrollAreaProps, className
20
22
  const appShellTestId = testIdUtils.useResolvedTestId({ testId: dataTestId, segment: 'app-shell', rootName: 'app-shell' });
21
23
  // A `SidePanel` in the `panel` slot calls the setter while it covers the page area below `lg`.
22
24
  const { scrollAreaRef, setPageCovered } = usePageCover.usePageCover(scrollAreaProps?.ref);
23
- // A `SlideoutMenu` anywhere in the shell reads the page area so it covers that box and nothing else.
25
+ // A `SlideoutMenu` anywhere in the shell reads the page area so it covers that box and nothing else, and below `lg` makes the
26
+ // row under that box inert: the page and a side panel covering it, which the slideout then covers in turn.
24
27
  const pageAreaBounds = usePageAreaBounds.usePageAreaBounds(scrollAreaRef);
28
+ const pageRowRef = React.useRef(null);
25
29
  return (
26
30
  // A column below `lg`, so a navigation that renders its own mobile top bar stacks above the content.
27
- jsxRuntime.jsx("div", { "data-testid": appShellTestId, className: cx.cx('flex h-dvh w-full flex-col overflow-hidden bg-primary lg:flex-row', className), children: jsxRuntime.jsxs(OverlayBounds_context.OverlayBoundsContext.Provider, { value: pageAreaBounds, 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'),
28
- // Focusable so keyboard users can scroll a page that has no focusable content of its own (axe: scrollable-region-focusable).
29
- // biome-ignore lint/a11y/noNoninteractiveTabindex: a scrollable region must be reachable by keyboard
30
- tabIndex: 0,
31
- // isolate keeps the page's own stacked content (sticky headers) under a panel that covers it.
32
- 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(PageCover_context.PageCoverContext.Provider, { value: setPageCovered, children: panel })] })] })] }) }));
31
+ jsxRuntime.jsx("div", { "data-testid": appShellTestId, className: cx.cx('flex h-dvh w-full flex-col overflow-hidden bg-primary lg:flex-row', className), children: jsxRuntime.jsx(OverlayBounds_context.OverlayBoundsContext.Provider, { value: pageAreaBounds, children: jsxRuntime.jsxs(PageArea_context.PageAreaContext.Provider, { value: pageRowRef, children: [sidebar, jsxRuntime.jsxs("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col", children: [header, jsxRuntime.jsxs("div", { ref: pageRowRef, 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'),
32
+ // Focusable so keyboard users can scroll a page that has no focusable content of its own (axe: scrollable-region-focusable).
33
+ // biome-ignore lint/a11y/noNoninteractiveTabindex: a scrollable region must be reachable by keyboard
34
+ tabIndex: 0,
35
+ // isolate keeps the page's own stacked content (sticky headers) under a panel that covers it.
36
+ 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(PageCover_context.PageCoverContext.Provider, { value: setPageCovered, children: panel })] })] })] }) }) }));
33
37
  };
34
38
 
35
39
  exports.AppShell = AppShell;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../../src/components/templates/AppShell/index.tsx"],"sourcesContent":[null],"names":["useResolvedTestId","usePageCover","usePageAreaBounds","_jsx","cx","_jsxs","OverlayBoundsContext","joinTestId","PageCoverContext"],"mappings":";;;;;;;;;;AAwCA;;;;;;;AAOG;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;;AAE5E,IAAA,MAAM,cAAc,GAAGC,mCAAiB,CAAC,aAAa,CAAC;IAEvD;;IAEEC,cAAA,CAAA,KAAA,EAAA,EAAA,aAAA,EAAkB,cAAc,EAAE,SAAS,EAAEC,KAAE,CAAC,mEAAmE,EAAE,SAAS,CAAC,EAAA,QAAA,EAC7HC,eAAA,CAACC,0CAAoB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,cAAc,EAAA,QAAA,EAAA,CACjD,OAAO,EAGRD,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,sCAAsC,EAAA,QAAA,EAAA,CAClD,MAAM,EAGPA,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,4CAA4C,EAAA,QAAA,EAAA,CACzDF,cAAA,CAAA,KAAA,EAAA,EACE,EAAE,EAAE,eAAe,EAAE,EAAE,EACvB,GAAG,EAAE,aAAa,EAAA,aAAA,EACL,eAAe,GAAG,aAAa,CAAC,IAAII,sBAAU,CAAC,cAAc,EAAE,aAAa,CAAC;;;AAG1F,oCAAA,QAAQ,EAAE,CAAC;;oCAEX,SAAS,EAAC,iIAAiI,EAAA,QAAA,EAE1I,QAAQ,GACL,EAENJ,cAAA,CAACK,kCAAgB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,cAAc,YAAG,KAAK,EAAA,CAA6B,IACjF,CAAA,EAAA,CACF,CAAA,EAAA,CACwB,EAAA,CAC5B;AAEV;;"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../../src/components/templates/AppShell/index.tsx"],"sourcesContent":[null],"names":["useResolvedTestId","usePageCover","usePageAreaBounds","useRef","_jsx","cx","OverlayBoundsContext","_jsxs","PageAreaContext","joinTestId","PageCoverContext"],"mappings":";;;;;;;;;;;;AA2CA;;;;;;;AAOG;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;;;AAG5E,IAAA,MAAM,cAAc,GAAGC,mCAAiB,CAAC,aAAa,CAAC;AACvD,IAAA,MAAM,UAAU,GAAGC,YAAM,CAAiB,IAAI,CAAC;IAE/C;;AAEE,IAAAC,cAAA,CAAA,KAAA,EAAA,EAAA,aAAA,EAAkB,cAAc,EAAE,SAAS,EAAEC,KAAE,CAAC,mEAAmE,EAAE,SAAS,CAAC,EAAA,QAAA,EAC7HD,cAAA,CAACE,0CAAoB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,cAAc,EAAA,QAAA,EAClDC,eAAA,CAACC,gCAAe,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,UAAU,EAAA,QAAA,EAAA,CACxC,OAAO,EAGRD,yBAAK,SAAS,EAAC,sCAAsC,EAAA,QAAA,EAAA,CAClD,MAAM,EAGPA,eAAA,CAAA,KAAA,EAAA,EAAK,GAAG,EAAE,UAAU,EAAE,SAAS,EAAC,4CAA4C,EAAA,QAAA,EAAA,CAC1EH,cAAA,CAAA,KAAA,EAAA,EACE,EAAE,EAAE,eAAe,EAAE,EAAE,EACvB,GAAG,EAAE,aAAa,EAAA,aAAA,EACL,eAAe,GAAG,aAAa,CAAC,IAAIK,sBAAU,CAAC,cAAc,EAAE,aAAa,CAAC;;;AAG1F,wCAAA,QAAQ,EAAE,CAAC;;wCAEX,SAAS,EAAC,iIAAiI,EAAA,QAAA,EAE1I,QAAQ,GACL,EAENL,cAAA,CAACM,kCAAgB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,cAAc,EAAA,QAAA,EAAG,KAAK,EAAA,CAA6B,CAAA,EAAA,CACjF,IACF,CAAA,EAAA,CACmB,EAAA,CACG,EAAA,CAC5B;AAEV;;"}
@@ -15,7 +15,8 @@ export interface AppShellProps {
15
15
  /**
16
16
  * Side panel rendered under the header. From `lg` it sits beside the page area, which narrows to make
17
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
+ * technology until the panel closes, as the panel itself is while a `SlideoutMenu` covers both. Compose
19
+ * one `<SidePanel>` here and switch its content.
19
20
  */
20
21
  panel?: ReactNode;
21
22
  /** Page content, normally a `<PageLayout>`. Rendered inside the shell's scroll area. */
@@ -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;AAM5C,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,sLAAsL;IACtL,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;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,GAAI,6FAA6F,aAAa,KAAG,SAsCrI,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;AAQ5C,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,sLAAsL;IACtL,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;OAKG;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;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,GAAI,6FAA6F,aAAa,KAAG,SA0CrI,CAAC"}
@@ -1,8 +1,10 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import { cx } from '@flipdish/ui-library/utilities/cx';
3
3
  import { useResolvedTestId, joinTestId } from '@flipdish/ui-library/utilities/testIdUtils';
4
+ import { useRef } from 'react';
4
5
  import { PageCoverContext } from '../../organisms/SidePanel/providers/PageCover.context.js';
5
6
  import { OverlayBoundsContext } from '../../organisms/SlideoutMenu/providers/OverlayBounds.context.js';
7
+ import { PageAreaContext } from '../../organisms/SlideoutMenu/providers/PageArea.context.js';
6
8
  import { usePageAreaBounds } from './hooks/usePageAreaBounds.js';
7
9
  import { usePageCover } from './hooks/usePageCover.js';
8
10
 
@@ -18,16 +20,18 @@ const AppShell = ({ sidebar, header, panel, children, scrollAreaProps, className
18
20
  const appShellTestId = useResolvedTestId({ testId: dataTestId, segment: 'app-shell', rootName: 'app-shell' });
19
21
  // A `SidePanel` in the `panel` slot calls the setter while it covers the page area below `lg`.
20
22
  const { scrollAreaRef, setPageCovered } = usePageCover(scrollAreaProps?.ref);
21
- // A `SlideoutMenu` anywhere in the shell reads the page area so it covers that box and nothing else.
23
+ // A `SlideoutMenu` anywhere in the shell reads the page area so it covers that box and nothing else, and below `lg` makes the
24
+ // row under that box inert: the page and a side panel covering it, which the slideout then covers in turn.
22
25
  const pageAreaBounds = usePageAreaBounds(scrollAreaRef);
26
+ const pageRowRef = useRef(null);
23
27
  return (
24
28
  // A column below `lg`, so a navigation that renders its own mobile top bar stacks above the content.
25
- jsx("div", { "data-testid": appShellTestId, className: cx('flex h-dvh w-full flex-col overflow-hidden bg-primary lg:flex-row', className), children: jsxs(OverlayBoundsContext.Provider, { value: pageAreaBounds, children: [sidebar, jsxs("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col", children: [header, jsxs("div", { className: "relative flex min-h-0 flex-1 overflow-clip", children: [jsx("div", { id: scrollAreaProps?.id, ref: scrollAreaRef, "data-testid": scrollAreaProps?.['data-testid'] ?? joinTestId(appShellTestId, 'scroll-area'),
26
- // Focusable so keyboard users can scroll a page that has no focusable content of its own (axe: scrollable-region-focusable).
27
- // biome-ignore lint/a11y/noNoninteractiveTabindex: a scrollable region must be reachable by keyboard
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 }), jsx(PageCoverContext.Provider, { value: setPageCovered, children: panel })] })] })] }) }));
29
+ jsx("div", { "data-testid": appShellTestId, className: cx('flex h-dvh w-full flex-col overflow-hidden bg-primary lg:flex-row', className), children: jsx(OverlayBoundsContext.Provider, { value: pageAreaBounds, children: jsxs(PageAreaContext.Provider, { value: pageRowRef, children: [sidebar, jsxs("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col", children: [header, jsxs("div", { ref: pageRowRef, className: "relative flex min-h-0 flex-1 overflow-clip", children: [jsx("div", { id: scrollAreaProps?.id, ref: scrollAreaRef, "data-testid": scrollAreaProps?.['data-testid'] ?? joinTestId(appShellTestId, 'scroll-area'),
30
+ // Focusable so keyboard users can scroll a page that has no focusable content of its own (axe: scrollable-region-focusable).
31
+ // biome-ignore lint/a11y/noNoninteractiveTabindex: a scrollable region must be reachable by keyboard
32
+ tabIndex: 0,
33
+ // isolate keeps the page's own stacked content (sticky headers) under a panel that covers it.
34
+ 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 }), jsx(PageCoverContext.Provider, { value: setPageCovered, children: panel })] })] })] }) }) }));
31
35
  };
32
36
 
33
37
  export { AppShell };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/components/templates/AppShell/index.tsx"],"sourcesContent":[null],"names":["_jsx","_jsxs"],"mappings":";;;;;;;;AAwCA;;;;;;;AAOG;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,GAAG,iBAAiB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;;AAE7G,IAAA,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,GAAG,YAAY,CAAC,eAAe,EAAE,GAAG,CAAC;;AAE5E,IAAA,MAAM,cAAc,GAAG,iBAAiB,CAAC,aAAa,CAAC;IAEvD;;IAEEA,GAAA,CAAA,KAAA,EAAA,EAAA,aAAA,EAAkB,cAAc,EAAE,SAAS,EAAE,EAAE,CAAC,mEAAmE,EAAE,SAAS,CAAC,EAAA,QAAA,EAC7HC,IAAA,CAAC,oBAAoB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,cAAc,EAAA,QAAA,EAAA,CACjD,OAAO,EAGRA,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,sCAAsC,EAAA,QAAA,EAAA,CAClD,MAAM,EAGPA,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,4CAA4C,EAAA,QAAA,EAAA,CACzDD,GAAA,CAAA,KAAA,EAAA,EACE,EAAE,EAAE,eAAe,EAAE,EAAE,EACvB,GAAG,EAAE,aAAa,EAAA,aAAA,EACL,eAAe,GAAG,aAAa,CAAC,IAAI,UAAU,CAAC,cAAc,EAAE,aAAa,CAAC;;;AAG1F,oCAAA,QAAQ,EAAE,CAAC;;oCAEX,SAAS,EAAC,iIAAiI,EAAA,QAAA,EAE1I,QAAQ,GACL,EAENA,GAAA,CAAC,gBAAgB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,cAAc,YAAG,KAAK,EAAA,CAA6B,IACjF,CAAA,EAAA,CACF,CAAA,EAAA,CACwB,EAAA,CAC5B;AAEV;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/components/templates/AppShell/index.tsx"],"sourcesContent":[null],"names":["_jsx","_jsxs"],"mappings":";;;;;;;;;;AA2CA;;;;;;;AAOG;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,GAAG,iBAAiB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;;AAE7G,IAAA,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,GAAG,YAAY,CAAC,eAAe,EAAE,GAAG,CAAC;;;AAG5E,IAAA,MAAM,cAAc,GAAG,iBAAiB,CAAC,aAAa,CAAC;AACvD,IAAA,MAAM,UAAU,GAAG,MAAM,CAAiB,IAAI,CAAC;IAE/C;;AAEE,IAAAA,GAAA,CAAA,KAAA,EAAA,EAAA,aAAA,EAAkB,cAAc,EAAE,SAAS,EAAE,EAAE,CAAC,mEAAmE,EAAE,SAAS,CAAC,EAAA,QAAA,EAC7HA,GAAA,CAAC,oBAAoB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,cAAc,EAAA,QAAA,EAClDC,IAAA,CAAC,eAAe,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,UAAU,EAAA,QAAA,EAAA,CACxC,OAAO,EAGRA,cAAK,SAAS,EAAC,sCAAsC,EAAA,QAAA,EAAA,CAClD,MAAM,EAGPA,IAAA,CAAA,KAAA,EAAA,EAAK,GAAG,EAAE,UAAU,EAAE,SAAS,EAAC,4CAA4C,EAAA,QAAA,EAAA,CAC1ED,GAAA,CAAA,KAAA,EAAA,EACE,EAAE,EAAE,eAAe,EAAE,EAAE,EACvB,GAAG,EAAE,aAAa,EAAA,aAAA,EACL,eAAe,GAAG,aAAa,CAAC,IAAI,UAAU,CAAC,cAAc,EAAE,aAAa,CAAC;;;AAG1F,wCAAA,QAAQ,EAAE,CAAC;;wCAEX,SAAS,EAAC,iIAAiI,EAAA,QAAA,EAE1I,QAAQ,GACL,EAENA,GAAA,CAAC,gBAAgB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,cAAc,EAAA,QAAA,EAAG,KAAK,EAAA,CAA6B,CAAA,EAAA,CACjF,IACF,CAAA,EAAA,CACmB,EAAA,CACG,EAAA,CAC5B;AAEV;;"}
@@ -0,0 +1,156 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var focus_utils = require('../../../utilities/__internal__/focusUtils/focus.utils.cjs');
5
+ var inert_utils = require('../../../utilities/__internal__/inertUtils/inert.utils.cjs');
6
+
7
+ /** The element before the panel when it can take focus, such as `AppShell`'s scroll area. */
8
+ const focusableSiblingBefore = (panel) => {
9
+ const sibling = panel.previousElementSibling;
10
+ return sibling instanceof HTMLElement && sibling.tabIndex >= 0 ? sibling : null;
11
+ };
12
+ /** Whether a hand-back can land: a control, or a region given a `tabindex`, neither disabled nor under a cover. */
13
+ const canTakeFocus = (element) => element instanceof HTMLElement &&
14
+ (element.tabIndex >= 0 || element.hasAttribute('tabindex')) &&
15
+ !element.matches(':disabled') &&
16
+ element.closest('[inert]') === null;
17
+ /**
18
+ * What covers an element under an inert ancestor: the last panel to cover that ancestor, else the sibling after it, as a
19
+ * side panel sits after the page it covers, else the first region inside that sibling given a `tabindex` that can take
20
+ * focus, as a host wraps its side panel. Nothing when none of those can.
21
+ */
22
+ const coverOver = (element) => {
23
+ const covered = element.closest('[inert]');
24
+ if (!(covered instanceof HTMLElement))
25
+ return null;
26
+ const candidate = inert_utils.lastCoverOf(covered) ?? covered.nextElementSibling;
27
+ if (canTakeFocus(candidate))
28
+ return candidate;
29
+ const regions = candidate ? [...candidate.querySelectorAll('[tabindex]')] : [];
30
+ return regions.find(canTakeFocus) ?? null;
31
+ };
32
+ /**
33
+ * What the panel covers: the given element, unless the panel sits inside it, as overlays do without a scoped anchor, when
34
+ * nothing is; without one, the panel's siblings.
35
+ */
36
+ const resolveCovered = (panel, coveredRef) => {
37
+ if (!coveredRef)
38
+ return panel.parentElement;
39
+ const covered = coveredRef.current;
40
+ return covered && !covered.contains(panel) ? covered : null;
41
+ };
42
+ /**
43
+ * Hands focus into the panel when it opens and back to the control that opened it when it closes,
44
+ * makes a leaving panel inert, and takes what the panel covers out of reach while it covers it.
45
+ * Managed by hand, not with a focus scope: a scope would also reroute Tab at the panel's edges, as
46
+ * a popover does.
47
+ *
48
+ * @param options See `UsePanelFocusOptions`.
49
+ * @returns a capture-phase focus handler to spread onto the panel element, `setOpener`, which points the hand-back on
50
+ * close at another control after a content swap, and `liftCover`, which lifts the cover ahead of the close that follows
51
+ */
52
+ const usePanelFocus = ({ panelRef, isPresent, isDesktop, coveredRef, shouldFocusOnMount, contentKey }) => {
53
+ const openerRef = React.useRef(null);
54
+ const previousIsPresent = React.useRef(null);
55
+ const previousIsDesktop = React.useRef(isDesktop);
56
+ // Read while rendering, before the content mounts: an `autoFocus` input takes focus during commit, ahead of any effect.
57
+ const [focusedBeforeMount] = React.useState(focus_utils.getFocusedElement);
58
+ React.useEffect(() => {
59
+ const panel = panelRef.current;
60
+ if (!panel)
61
+ return;
62
+ const previous = previousIsPresent.current;
63
+ previousIsPresent.current = isPresent;
64
+ // Entering covers a fresh open and a reopen that interrupts the close animation.
65
+ const isEntering = isPresent && (previous === false || (previous === null && shouldFocusOnMount));
66
+ const isLeaving = !isPresent && previous === true;
67
+ const focused = focus_utils.getFocusedElement();
68
+ const hasFocusInside = focused !== null && panel.contains(focused);
69
+ // A panel reopened mid-close is still inert from leaving, and an inert element cannot take focus.
70
+ if (isPresent)
71
+ panel.inert = false;
72
+ if (isEntering) {
73
+ // 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.
74
+ openerRef.current = previous === null ? focusedBeforeMount : focused;
75
+ // Content that focused itself (an `autoFocus` input) keeps focus; otherwise the region takes it.
76
+ // preventScroll: below `lg` the panel starts off-screen, and scrolling it into view would shift the layout.
77
+ if (!hasFocusInside)
78
+ panel.focus({ preventScroll: true });
79
+ }
80
+ // Hand focus back only if it is still in the panel, so a user who has moved on is left alone.
81
+ if (isLeaving && hasFocusInside) {
82
+ const opener = openerRef.current;
83
+ // The opener may have unmounted meanwhile, such as a header button that only renders at one breakpoint.
84
+ const target = opener?.isConnected ? opener : focusableSiblingBefore(panel);
85
+ target?.focus();
86
+ // An opener under a cover, a side panel or another panel over the page below `lg`, refuses focus: what covers it takes it instead.
87
+ if (target && focus_utils.getFocusedElement() !== target)
88
+ coverOver(target)?.focus();
89
+ }
90
+ // A leaving panel must not be reachable while another opens; set last, since inert drops any focus inside it.
91
+ if (!isPresent)
92
+ panel.inert = true;
93
+ }, [panelRef, isPresent, shouldFocusOnMount, focusedBeforeMount]);
94
+ // Before the cover below is applied, so focus leaves the page while the page can still be read as holding it.
95
+ React.useEffect(() => {
96
+ const hasStartedCoveringPage = previousIsDesktop.current && !isDesktop;
97
+ previousIsDesktop.current = isDesktop;
98
+ const panel = panelRef.current;
99
+ const focused = focus_utils.getFocusedElement();
100
+ // The page the panel covers is about to go out of reach, so focus must not be left in it, where inert would drop it on nothing.
101
+ const covered = panel && resolveCovered(panel, coveredRef);
102
+ if (hasStartedCoveringPage && panel && focused && !panel.contains(focused) && covered?.contains(focused)) {
103
+ panel.focus({ preventScroll: true });
104
+ }
105
+ }, [panelRef, coveredRef, isDesktop]);
106
+ // React runs every cleanup before any effect in a commit, so the cover lifts before the hand-back above lands focus in the
107
+ // page. Covers are counted per element, so two panels over the same page restore its own `inert` only when the last lifts.
108
+ const isCovering = isPresent && !isDesktop;
109
+ const liftCoverRef = React.useRef(null);
110
+ React.useEffect(() => {
111
+ const panel = panelRef.current;
112
+ // Only a given element is covered; the panel's siblings are the layout's to cover, as `AppShell` does for a side panel.
113
+ const covered = isCovering && panel && coveredRef ? resolveCovered(panel, coveredRef) : null;
114
+ if (!panel || !covered)
115
+ return;
116
+ // An area chosen while the panel is open, such as the app root arriving a commit late, may hold focus the hand-off above
117
+ // did not see: it moves into the panel before the area goes out of reach.
118
+ const focused = focus_utils.getFocusedElement();
119
+ if (focused && covered.contains(focused))
120
+ panel.focus({ preventScroll: true });
121
+ const lift = inert_utils.coverElement(covered, panel);
122
+ liftCoverRef.current = lift;
123
+ return () => {
124
+ lift();
125
+ liftCoverRef.current = null;
126
+ };
127
+ }, [panelRef, coveredRef, isCovering]);
128
+ // For a close that another panel caused: that panel is mounting under this cover in the same pass, and its focus call would
129
+ // be refused until the cover lifts at the next commit. Lifting is idempotent, so the effect's own cleanup stays harmless.
130
+ const liftCover = React.useCallback(() => liftCoverRef.current?.(), []);
131
+ // Swapping content unmounts whatever held focus, which drops it on the page. The region takes it, so Tab stays inside and
132
+ // closing can still hand it back. Content that focuses itself on mount (an `autoFocus` input) has done so by now and keeps it.
133
+ const previousContentKey = React.useRef(contentKey);
134
+ React.useLayoutEffect(() => {
135
+ if (previousContentKey.current === contentKey)
136
+ return;
137
+ previousContentKey.current = contentKey;
138
+ const panel = panelRef.current;
139
+ if (panel && isPresent && focus_utils.getFocusedElement() === null)
140
+ panel.focus({ preventScroll: true });
141
+ }, [panelRef, contentKey, isPresent]);
142
+ // A panel that was open on load has no opener, so closing hands focus back to wherever it first came in from.
143
+ const onFocusCapture = (event) => {
144
+ const from = event.relatedTarget;
145
+ if (openerRef.current === null && from instanceof HTMLElement && !event.currentTarget.contains(from))
146
+ openerRef.current = from;
147
+ };
148
+ // A panel whose content swaps while open follows the user's latest gesture, so closing lands on the row they are on, not the first one.
149
+ const setOpener = React.useCallback((element) => {
150
+ openerRef.current = element;
151
+ }, []);
152
+ return { onFocusCapture, setOpener, liftCover };
153
+ };
154
+
155
+ exports.usePanelFocus = usePanelFocus;
156
+ //# sourceMappingURL=usePanelFocus.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePanelFocus.cjs","sources":["../../../../src/hooks/__internal__/usePanelFocus/usePanelFocus.ts"],"sourcesContent":[null],"names":["lastCoverOf","useRef","useState","getFocusedElement","useEffect","coverElement","useCallback","useLayoutEffect"],"mappings":"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"}
@@ -0,0 +1,36 @@
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
+ /**
9
+ * What the panel covers when it is not docked, for a panel that is not the page's sibling, such as one portaled over it.
10
+ * Made inert while covered and restored as the panel leaves, before focus is handed back into it; left alone when the
11
+ * panel sits inside it. Read when the cover starts, so the element must stay mounted while the panel is open. Omitted,
12
+ * the page is taken to be the panel's siblings and its cover is the layout's job.
13
+ */
14
+ coveredRef?: RefObject<HTMLElement | null>;
15
+ /** False for a panel that is open on the first render, which must not pull focus away from the page. */
16
+ shouldFocusOnMount: boolean;
17
+ /** Identifies the content shown; a change means the content, and whatever held focus in it, was replaced. */
18
+ contentKey?: string;
19
+ }
20
+ /**
21
+ * Hands focus into the panel when it opens and back to the control that opened it when it closes,
22
+ * makes a leaving panel inert, and takes what the panel covers out of reach while it covers it.
23
+ * Managed by hand, not with a focus scope: a scope would also reroute Tab at the panel's edges, as
24
+ * a popover does.
25
+ *
26
+ * @param options See `UsePanelFocusOptions`.
27
+ * @returns a capture-phase focus handler to spread onto the panel element, `setOpener`, which points the hand-back on
28
+ * close at another control after a content swap, and `liftCover`, which lifts the cover ahead of the close that follows
29
+ */
30
+ export declare const usePanelFocus: ({ panelRef, isPresent, isDesktop, coveredRef, shouldFocusOnMount, contentKey }: UsePanelFocusOptions) => {
31
+ onFocusCapture: (event: FocusEvent<HTMLElement>) => void;
32
+ setOpener: (element: HTMLElement) => void;
33
+ liftCover: () => void | undefined;
34
+ };
35
+ export {};
36
+ //# sourceMappingURL=usePanelFocus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePanelFocus.d.ts","sourceRoot":"","sources":["../../../../src/hooks/__internal__/usePanelFocus/usePanelFocus.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AA6CnD,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;;;;;OAKG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC3C,wGAAwG;IACxG,kBAAkB,EAAE,OAAO,CAAC;IAC5B,6GAA6G;IAC7G,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,GAAI,gFAAgF,oBAAoB;4BA2FjG,UAAU,CAAC,WAAW,CAAC;yBAMd,WAAW;;CAKpD,CAAC"}