@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.
- package/dist/components/organisms/SidePanel/components/SidePanelRegion.cjs +9 -1
- package/dist/components/organisms/SidePanel/components/SidePanelRegion.cjs.map +1 -1
- package/dist/components/organisms/SidePanel/components/SidePanelRegion.d.ts.map +1 -1
- package/dist/components/organisms/SidePanel/components/SidePanelRegion.js +9 -1
- package/dist/components/organisms/SidePanel/components/SidePanelRegion.js.map +1 -1
- package/dist/components/organisms/SlideoutMenu/components/SlideoutShell.cjs +36 -9
- package/dist/components/organisms/SlideoutMenu/components/SlideoutShell.cjs.map +1 -1
- package/dist/components/organisms/SlideoutMenu/components/SlideoutShell.d.ts +2 -2
- package/dist/components/organisms/SlideoutMenu/components/SlideoutShell.d.ts.map +1 -1
- package/dist/components/organisms/SlideoutMenu/components/SlideoutShell.js +37 -10
- package/dist/components/organisms/SlideoutMenu/components/SlideoutShell.js.map +1 -1
- package/dist/components/organisms/SlideoutMenu/hooks/useCloseWhenCovered.cjs +31 -0
- package/dist/components/organisms/SlideoutMenu/hooks/useCloseWhenCovered.cjs.map +1 -0
- package/dist/components/organisms/SlideoutMenu/hooks/useCloseWhenCovered.d.ts +15 -0
- package/dist/components/organisms/SlideoutMenu/hooks/useCloseWhenCovered.d.ts.map +1 -0
- package/dist/components/organisms/SlideoutMenu/hooks/useCloseWhenCovered.js +29 -0
- package/dist/components/organisms/SlideoutMenu/hooks/useCloseWhenCovered.js.map +1 -0
- package/dist/components/organisms/SlideoutMenu/hooks/useSlideoutState.cjs +3 -2
- package/dist/components/organisms/SlideoutMenu/hooks/useSlideoutState.cjs.map +1 -1
- package/dist/components/organisms/SlideoutMenu/hooks/useSlideoutState.d.ts.map +1 -1
- package/dist/components/organisms/SlideoutMenu/hooks/useSlideoutState.js +4 -3
- package/dist/components/organisms/SlideoutMenu/hooks/useSlideoutState.js.map +1 -1
- package/dist/components/organisms/SlideoutMenu/index.cjs +7 -1
- package/dist/components/organisms/SlideoutMenu/index.cjs.map +1 -1
- package/dist/components/organisms/SlideoutMenu/index.d.ts +19 -2
- package/dist/components/organisms/SlideoutMenu/index.d.ts.map +1 -1
- package/dist/components/organisms/SlideoutMenu/index.js +7 -1
- package/dist/components/organisms/SlideoutMenu/index.js.map +1 -1
- package/dist/components/organisms/SlideoutMenu/providers/PageArea.context.cjs +14 -0
- package/dist/components/organisms/SlideoutMenu/providers/PageArea.context.cjs.map +1 -0
- package/dist/components/organisms/SlideoutMenu/providers/PageArea.context.d.ts +9 -0
- package/dist/components/organisms/SlideoutMenu/providers/PageArea.context.d.ts.map +1 -0
- package/dist/components/organisms/SlideoutMenu/providers/PageArea.context.js +12 -0
- package/dist/components/organisms/SlideoutMenu/providers/PageArea.context.js.map +1 -0
- package/dist/components/templates/AppShell/index.cjs +11 -7
- package/dist/components/templates/AppShell/index.cjs.map +1 -1
- package/dist/components/templates/AppShell/index.d.ts +2 -1
- package/dist/components/templates/AppShell/index.d.ts.map +1 -1
- package/dist/components/templates/AppShell/index.js +11 -7
- package/dist/components/templates/AppShell/index.js.map +1 -1
- package/dist/hooks/__internal__/usePanelFocus/usePanelFocus.cjs +156 -0
- package/dist/hooks/__internal__/usePanelFocus/usePanelFocus.cjs.map +1 -0
- package/dist/hooks/__internal__/usePanelFocus/usePanelFocus.d.ts +36 -0
- package/dist/hooks/__internal__/usePanelFocus/usePanelFocus.d.ts.map +1 -0
- package/dist/hooks/__internal__/usePanelFocus/usePanelFocus.js +154 -0
- package/dist/hooks/__internal__/usePanelFocus/usePanelFocus.js.map +1 -0
- package/dist/providers/ThemeProvider/Theme.context.cjs +17 -0
- package/dist/providers/ThemeProvider/Theme.context.cjs.map +1 -0
- package/dist/providers/ThemeProvider/Theme.context.d.ts +16 -0
- package/dist/providers/ThemeProvider/Theme.context.d.ts.map +1 -0
- package/dist/providers/ThemeProvider/Theme.context.js +14 -0
- package/dist/providers/ThemeProvider/Theme.context.js.map +1 -0
- package/dist/providers/ThemeProvider/index.cjs +3 -3
- package/dist/providers/ThemeProvider/index.cjs.map +1 -1
- package/dist/providers/ThemeProvider/index.d.ts +1 -7
- package/dist/providers/ThemeProvider/index.d.ts.map +1 -1
- package/dist/providers/ThemeProvider/index.js +2 -2
- package/dist/providers/ThemeProvider/index.js.map +1 -1
- package/dist/utilities/__internal__/inertUtils/inert.utils.cjs +46 -0
- package/dist/utilities/__internal__/inertUtils/inert.utils.cjs.map +1 -0
- package/dist/utilities/__internal__/inertUtils/inert.utils.d.ts +18 -0
- package/dist/utilities/__internal__/inertUtils/inert.utils.d.ts.map +1 -0
- package/dist/utilities/__internal__/inertUtils/inert.utils.js +43 -0
- package/dist/utilities/__internal__/inertUtils/inert.utils.js.map +1 -0
- package/dist/utilities/__internal__/pageCoverUtils/pageCover.utils.cjs +30 -0
- package/dist/utilities/__internal__/pageCoverUtils/pageCover.utils.cjs.map +1 -0
- package/dist/utilities/__internal__/pageCoverUtils/pageCover.utils.d.ts +19 -0
- package/dist/utilities/__internal__/pageCoverUtils/pageCover.utils.d.ts.map +1 -0
- package/dist/utilities/__internal__/pageCoverUtils/pageCover.utils.js +26 -0
- package/dist/utilities/__internal__/pageCoverUtils/pageCover.utils.js.map +1 -0
- package/package.json +1 -1
- package/dist/components/organisms/SidePanel/hooks/usePanelFocus.cjs +0 -92
- package/dist/components/organisms/SidePanel/hooks/usePanelFocus.cjs.map +0 -1
- package/dist/components/organisms/SidePanel/hooks/usePanelFocus.d.ts +0 -26
- package/dist/components/organisms/SidePanel/hooks/usePanelFocus.d.ts.map +0 -1
- package/dist/components/organisms/SidePanel/hooks/usePanelFocus.js +0 -90
- package/dist/components/organisms/SidePanel/hooks/usePanelFocus.js.map +0 -1
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { useRef, useState, useEffect, useCallback, useLayoutEffect } from 'react';
|
|
2
|
+
import { getFocusedElement } from '../../../utilities/__internal__/focusUtils/focus.utils.js';
|
|
3
|
+
import { coverElement, lastCoverOf } from '../../../utilities/__internal__/inertUtils/inert.utils.js';
|
|
4
|
+
|
|
5
|
+
/** The element before the panel when it can take focus, such as `AppShell`'s scroll area. */
|
|
6
|
+
const focusableSiblingBefore = (panel) => {
|
|
7
|
+
const sibling = panel.previousElementSibling;
|
|
8
|
+
return sibling instanceof HTMLElement && sibling.tabIndex >= 0 ? sibling : null;
|
|
9
|
+
};
|
|
10
|
+
/** Whether a hand-back can land: a control, or a region given a `tabindex`, neither disabled nor under a cover. */
|
|
11
|
+
const canTakeFocus = (element) => element instanceof HTMLElement &&
|
|
12
|
+
(element.tabIndex >= 0 || element.hasAttribute('tabindex')) &&
|
|
13
|
+
!element.matches(':disabled') &&
|
|
14
|
+
element.closest('[inert]') === null;
|
|
15
|
+
/**
|
|
16
|
+
* What covers an element under an inert ancestor: the last panel to cover that ancestor, else the sibling after it, as a
|
|
17
|
+
* side panel sits after the page it covers, else the first region inside that sibling given a `tabindex` that can take
|
|
18
|
+
* focus, as a host wraps its side panel. Nothing when none of those can.
|
|
19
|
+
*/
|
|
20
|
+
const coverOver = (element) => {
|
|
21
|
+
const covered = element.closest('[inert]');
|
|
22
|
+
if (!(covered instanceof HTMLElement))
|
|
23
|
+
return null;
|
|
24
|
+
const candidate = lastCoverOf(covered) ?? covered.nextElementSibling;
|
|
25
|
+
if (canTakeFocus(candidate))
|
|
26
|
+
return candidate;
|
|
27
|
+
const regions = candidate ? [...candidate.querySelectorAll('[tabindex]')] : [];
|
|
28
|
+
return regions.find(canTakeFocus) ?? null;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* What the panel covers: the given element, unless the panel sits inside it, as overlays do without a scoped anchor, when
|
|
32
|
+
* nothing is; without one, the panel's siblings.
|
|
33
|
+
*/
|
|
34
|
+
const resolveCovered = (panel, coveredRef) => {
|
|
35
|
+
if (!coveredRef)
|
|
36
|
+
return panel.parentElement;
|
|
37
|
+
const covered = coveredRef.current;
|
|
38
|
+
return covered && !covered.contains(panel) ? covered : null;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Hands focus into the panel when it opens and back to the control that opened it when it closes,
|
|
42
|
+
* makes a leaving panel inert, and takes what the panel covers out of reach while it covers it.
|
|
43
|
+
* Managed by hand, not with a focus scope: a scope would also reroute Tab at the panel's edges, as
|
|
44
|
+
* a popover does.
|
|
45
|
+
*
|
|
46
|
+
* @param options See `UsePanelFocusOptions`.
|
|
47
|
+
* @returns a capture-phase focus handler to spread onto the panel element, `setOpener`, which points the hand-back on
|
|
48
|
+
* close at another control after a content swap, and `liftCover`, which lifts the cover ahead of the close that follows
|
|
49
|
+
*/
|
|
50
|
+
const usePanelFocus = ({ panelRef, isPresent, isDesktop, coveredRef, shouldFocusOnMount, contentKey }) => {
|
|
51
|
+
const openerRef = useRef(null);
|
|
52
|
+
const previousIsPresent = useRef(null);
|
|
53
|
+
const previousIsDesktop = useRef(isDesktop);
|
|
54
|
+
// Read while rendering, before the content mounts: an `autoFocus` input takes focus during commit, ahead of any effect.
|
|
55
|
+
const [focusedBeforeMount] = useState(getFocusedElement);
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
const panel = panelRef.current;
|
|
58
|
+
if (!panel)
|
|
59
|
+
return;
|
|
60
|
+
const previous = previousIsPresent.current;
|
|
61
|
+
previousIsPresent.current = isPresent;
|
|
62
|
+
// Entering covers a fresh open and a reopen that interrupts the close animation.
|
|
63
|
+
const isEntering = isPresent && (previous === false || (previous === null && shouldFocusOnMount));
|
|
64
|
+
const isLeaving = !isPresent && previous === true;
|
|
65
|
+
const focused = getFocusedElement();
|
|
66
|
+
const hasFocusInside = focused !== null && panel.contains(focused);
|
|
67
|
+
// A panel reopened mid-close is still inert from leaving, and an inert element cannot take focus.
|
|
68
|
+
if (isPresent)
|
|
69
|
+
panel.inert = false;
|
|
70
|
+
if (isEntering) {
|
|
71
|
+
// 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.
|
|
72
|
+
openerRef.current = previous === null ? focusedBeforeMount : focused;
|
|
73
|
+
// Content that focused itself (an `autoFocus` input) keeps focus; otherwise the region takes it.
|
|
74
|
+
// preventScroll: below `lg` the panel starts off-screen, and scrolling it into view would shift the layout.
|
|
75
|
+
if (!hasFocusInside)
|
|
76
|
+
panel.focus({ preventScroll: true });
|
|
77
|
+
}
|
|
78
|
+
// Hand focus back only if it is still in the panel, so a user who has moved on is left alone.
|
|
79
|
+
if (isLeaving && hasFocusInside) {
|
|
80
|
+
const opener = openerRef.current;
|
|
81
|
+
// The opener may have unmounted meanwhile, such as a header button that only renders at one breakpoint.
|
|
82
|
+
const target = opener?.isConnected ? opener : focusableSiblingBefore(panel);
|
|
83
|
+
target?.focus();
|
|
84
|
+
// An opener under a cover, a side panel or another panel over the page below `lg`, refuses focus: what covers it takes it instead.
|
|
85
|
+
if (target && getFocusedElement() !== target)
|
|
86
|
+
coverOver(target)?.focus();
|
|
87
|
+
}
|
|
88
|
+
// A leaving panel must not be reachable while another opens; set last, since inert drops any focus inside it.
|
|
89
|
+
if (!isPresent)
|
|
90
|
+
panel.inert = true;
|
|
91
|
+
}, [panelRef, isPresent, shouldFocusOnMount, focusedBeforeMount]);
|
|
92
|
+
// Before the cover below is applied, so focus leaves the page while the page can still be read as holding it.
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
const hasStartedCoveringPage = previousIsDesktop.current && !isDesktop;
|
|
95
|
+
previousIsDesktop.current = isDesktop;
|
|
96
|
+
const panel = panelRef.current;
|
|
97
|
+
const focused = getFocusedElement();
|
|
98
|
+
// 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.
|
|
99
|
+
const covered = panel && resolveCovered(panel, coveredRef);
|
|
100
|
+
if (hasStartedCoveringPage && panel && focused && !panel.contains(focused) && covered?.contains(focused)) {
|
|
101
|
+
panel.focus({ preventScroll: true });
|
|
102
|
+
}
|
|
103
|
+
}, [panelRef, coveredRef, isDesktop]);
|
|
104
|
+
// React runs every cleanup before any effect in a commit, so the cover lifts before the hand-back above lands focus in the
|
|
105
|
+
// page. Covers are counted per element, so two panels over the same page restore its own `inert` only when the last lifts.
|
|
106
|
+
const isCovering = isPresent && !isDesktop;
|
|
107
|
+
const liftCoverRef = useRef(null);
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
const panel = panelRef.current;
|
|
110
|
+
// Only a given element is covered; the panel's siblings are the layout's to cover, as `AppShell` does for a side panel.
|
|
111
|
+
const covered = isCovering && panel && coveredRef ? resolveCovered(panel, coveredRef) : null;
|
|
112
|
+
if (!panel || !covered)
|
|
113
|
+
return;
|
|
114
|
+
// An area chosen while the panel is open, such as the app root arriving a commit late, may hold focus the hand-off above
|
|
115
|
+
// did not see: it moves into the panel before the area goes out of reach.
|
|
116
|
+
const focused = getFocusedElement();
|
|
117
|
+
if (focused && covered.contains(focused))
|
|
118
|
+
panel.focus({ preventScroll: true });
|
|
119
|
+
const lift = coverElement(covered, panel);
|
|
120
|
+
liftCoverRef.current = lift;
|
|
121
|
+
return () => {
|
|
122
|
+
lift();
|
|
123
|
+
liftCoverRef.current = null;
|
|
124
|
+
};
|
|
125
|
+
}, [panelRef, coveredRef, isCovering]);
|
|
126
|
+
// For a close that another panel caused: that panel is mounting under this cover in the same pass, and its focus call would
|
|
127
|
+
// be refused until the cover lifts at the next commit. Lifting is idempotent, so the effect's own cleanup stays harmless.
|
|
128
|
+
const liftCover = useCallback(() => liftCoverRef.current?.(), []);
|
|
129
|
+
// Swapping content unmounts whatever held focus, which drops it on the page. The region takes it, so Tab stays inside and
|
|
130
|
+
// closing can still hand it back. Content that focuses itself on mount (an `autoFocus` input) has done so by now and keeps it.
|
|
131
|
+
const previousContentKey = useRef(contentKey);
|
|
132
|
+
useLayoutEffect(() => {
|
|
133
|
+
if (previousContentKey.current === contentKey)
|
|
134
|
+
return;
|
|
135
|
+
previousContentKey.current = contentKey;
|
|
136
|
+
const panel = panelRef.current;
|
|
137
|
+
if (panel && isPresent && getFocusedElement() === null)
|
|
138
|
+
panel.focus({ preventScroll: true });
|
|
139
|
+
}, [panelRef, contentKey, isPresent]);
|
|
140
|
+
// A panel that was open on load has no opener, so closing hands focus back to wherever it first came in from.
|
|
141
|
+
const onFocusCapture = (event) => {
|
|
142
|
+
const from = event.relatedTarget;
|
|
143
|
+
if (openerRef.current === null && from instanceof HTMLElement && !event.currentTarget.contains(from))
|
|
144
|
+
openerRef.current = from;
|
|
145
|
+
};
|
|
146
|
+
// 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.
|
|
147
|
+
const setOpener = useCallback((element) => {
|
|
148
|
+
openerRef.current = element;
|
|
149
|
+
}, []);
|
|
150
|
+
return { onFocusCapture, setOpener, liftCover };
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
export { usePanelFocus };
|
|
154
|
+
//# sourceMappingURL=usePanelFocus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePanelFocus.js","sources":["../../../../src/hooks/__internal__/usePanelFocus/usePanelFocus.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
|
|
5
|
+
// Its own file so library components can read it without a public export; one module, so one context for every reader.
|
|
6
|
+
const ThemeContext = React.createContext(undefined);
|
|
7
|
+
/**
|
|
8
|
+
* The element the app's theme cascades from: in a micro-frontend, its whole mount. Unlike `useTheme` it never throws, so a
|
|
9
|
+
* component such as `SlideoutMenu` can adapt to the app's root without requiring the provider.
|
|
10
|
+
*
|
|
11
|
+
* @returns The themed root, or `null` outside a `ThemeProvider` or before it has mounted.
|
|
12
|
+
*/
|
|
13
|
+
const useThemeRoot = () => React.useContext(ThemeContext)?.themeRoot ?? null;
|
|
14
|
+
|
|
15
|
+
exports.ThemeContext = ThemeContext;
|
|
16
|
+
exports.useThemeRoot = useThemeRoot;
|
|
17
|
+
//# sourceMappingURL=Theme.context.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Theme.context.cjs","sources":["../../../src/providers/ThemeProvider/Theme.context.ts"],"sourcesContent":[null],"names":["createContext","useContext"],"mappings":";;;;AAaA;MACa,YAAY,GAAGA,mBAAa,CAA+B,SAAS;AAEjF;;;;;AAKG;AACI,MAAM,YAAY,GAAG,MAA0BC,gBAAU,CAAC,YAAY,CAAC,EAAE,SAAS,IAAI;;;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type Theme = 'light' | 'dark' | 'system';
|
|
2
|
+
export interface ThemeContextType {
|
|
3
|
+
theme: Theme;
|
|
4
|
+
setTheme: (theme: Theme) => void;
|
|
5
|
+
themeRoot: HTMLElement | null;
|
|
6
|
+
resolvedMode: 'light' | 'dark';
|
|
7
|
+
}
|
|
8
|
+
export declare const ThemeContext: import("react").Context<ThemeContextType | undefined>;
|
|
9
|
+
/**
|
|
10
|
+
* The element the app's theme cascades from: in a micro-frontend, its whole mount. Unlike `useTheme` it never throws, so a
|
|
11
|
+
* component such as `SlideoutMenu` can adapt to the app's root without requiring the provider.
|
|
12
|
+
*
|
|
13
|
+
* @returns The themed root, or `null` outside a `ThemeProvider` or before it has mounted.
|
|
14
|
+
*/
|
|
15
|
+
export declare const useThemeRoot: () => HTMLElement | null;
|
|
16
|
+
//# sourceMappingURL=Theme.context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Theme.context.d.ts","sourceRoot":"","sources":["../../../src/providers/ThemeProvider/Theme.context.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEhD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,OAAO,GAAG,MAAM,CAAC;CAChC;AAGD,eAAO,MAAM,YAAY,uDAAyD,CAAC;AAEnF;;;;;GAKG;AACH,eAAO,MAAM,YAAY,QAAO,WAAW,GAAG,IAAmD,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
// Its own file so library components can read it without a public export; one module, so one context for every reader.
|
|
4
|
+
const ThemeContext = createContext(undefined);
|
|
5
|
+
/**
|
|
6
|
+
* The element the app's theme cascades from: in a micro-frontend, its whole mount. Unlike `useTheme` it never throws, so a
|
|
7
|
+
* component such as `SlideoutMenu` can adapt to the app's root without requiring the provider.
|
|
8
|
+
*
|
|
9
|
+
* @returns The themed root, or `null` outside a `ThemeProvider` or before it has mounted.
|
|
10
|
+
*/
|
|
11
|
+
const useThemeRoot = () => useContext(ThemeContext)?.themeRoot ?? null;
|
|
12
|
+
|
|
13
|
+
export { ThemeContext, useThemeRoot };
|
|
14
|
+
//# sourceMappingURL=Theme.context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Theme.context.js","sources":["../../../src/providers/ThemeProvider/Theme.context.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAaA;MACa,YAAY,GAAG,aAAa,CAA+B,SAAS;AAEjF;;;;;AAKG;AACI,MAAM,YAAY,GAAG,MAA0B,UAAU,CAAC,YAAY,CAAC,EAAE,SAAS,IAAI;;"}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var React = require('react');
|
|
5
|
+
var Theme_context = require('./Theme.context.cjs');
|
|
5
6
|
|
|
6
|
-
const ThemeContext = React.createContext(undefined);
|
|
7
7
|
/**
|
|
8
8
|
* Reads the current theme and its setter from the nearest `ThemeProvider`.
|
|
9
9
|
*
|
|
@@ -11,7 +11,7 @@ const ThemeContext = React.createContext(undefined);
|
|
|
11
11
|
* element carrying `data-theme`.
|
|
12
12
|
*/
|
|
13
13
|
const useTheme = () => {
|
|
14
|
-
const context = React.useContext(ThemeContext);
|
|
14
|
+
const context = React.useContext(Theme_context.ThemeContext);
|
|
15
15
|
if (context === undefined) {
|
|
16
16
|
throw new Error('useTheme must be used within a ThemeProvider');
|
|
17
17
|
}
|
|
@@ -80,7 +80,7 @@ const ThemeProvider = ({ children, defaultTheme = 'system', storageKey, themeMod
|
|
|
80
80
|
return () => mediaQuery.removeEventListener('change', handleChange);
|
|
81
81
|
}, []);
|
|
82
82
|
const contextValue = React.useMemo(() => ({ theme: activeTheme, setTheme, themeRoot, resolvedMode }), [activeTheme, themeRoot, resolvedMode]);
|
|
83
|
-
return (jsxRuntime.jsx(ThemeContext.Provider, { value: contextValue, children: jsxRuntime.jsx("div", { ref: setThemeRoot, "data-theme": resolvedMode, "data-mfe-scope": scopeId, style: { display: 'contents' }, children: children }) }));
|
|
83
|
+
return (jsxRuntime.jsx(Theme_context.ThemeContext.Provider, { value: contextValue, children: jsxRuntime.jsx("div", { ref: setThemeRoot, "data-theme": resolvedMode, "data-mfe-scope": scopeId, style: { display: 'contents' }, children: children }) }));
|
|
84
84
|
};
|
|
85
85
|
|
|
86
86
|
exports.ThemeProvider = ThemeProvider;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../src/providers/ThemeProvider/index.tsx"],"sourcesContent":[null],"names":["
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../src/providers/ThemeProvider/index.tsx"],"sourcesContent":[null],"names":["useContext","ThemeContext","useState","useEffect","useMemo","_jsx"],"mappings":"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"}
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
-
type Theme
|
|
3
|
-
interface ThemeContextType {
|
|
4
|
-
theme: Theme;
|
|
5
|
-
setTheme: (theme: Theme) => void;
|
|
6
|
-
themeRoot: HTMLElement | null;
|
|
7
|
-
resolvedMode: 'light' | 'dark';
|
|
8
|
-
}
|
|
2
|
+
import { type Theme, type ThemeContextType } from './Theme.context';
|
|
9
3
|
/**
|
|
10
4
|
* Reads the current theme and its setter from the nearest `ThemeProvider`.
|
|
11
5
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/ThemeProvider/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/ThemeProvider/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAE,KAAK,KAAK,EAAgB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAElF;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,QAAO,gBAQ3B,CAAC;AAWF,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACrC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GAAI,4HAO3B,kBAAkB,gCA0DpB,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import {
|
|
2
|
+
import { useState, useEffect, useMemo, useContext } from 'react';
|
|
3
|
+
import { ThemeContext } from './Theme.context.js';
|
|
3
4
|
|
|
4
|
-
const ThemeContext = createContext(undefined);
|
|
5
5
|
/**
|
|
6
6
|
* Reads the current theme and its setter from the nearest `ThemeProvider`.
|
|
7
7
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/providers/ThemeProvider/index.tsx"],"sourcesContent":[null],"names":["_jsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/providers/ThemeProvider/index.tsx"],"sourcesContent":[null],"names":["_jsx"],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/** Covers in force per element, who holds each, and the `inert` the element had before the first, so the last to lift restores it. */
|
|
4
|
+
const covers = new WeakMap();
|
|
5
|
+
/**
|
|
6
|
+
* Makes an element inert for one cover among possibly several, such as two panels over the same page. The element's own
|
|
7
|
+
* `inert` is read at the first cover and restored only when the last lifts, whatever order the covers lift in, so nothing
|
|
8
|
+
* else may write `inert` on the element meanwhile.
|
|
9
|
+
*
|
|
10
|
+
* @param element The element to take out of reach.
|
|
11
|
+
* @param by The panel covering it, which `lastCoverOf` reports so focus can be handed to it.
|
|
12
|
+
* @returns Lifts this cover; calling it twice is harmless.
|
|
13
|
+
*/
|
|
14
|
+
const coverElement = (element, by) => {
|
|
15
|
+
// The attribute rather than the property: a browser reflects one into the other, and `[inert]` selectors then see the cover.
|
|
16
|
+
const active = covers.get(element) ?? { by: [], wasInert: element.hasAttribute('inert') };
|
|
17
|
+
if (active.by.length === 0)
|
|
18
|
+
element.setAttribute('inert', '');
|
|
19
|
+
active.by.push(by);
|
|
20
|
+
covers.set(element, active);
|
|
21
|
+
let lifted = false;
|
|
22
|
+
return () => {
|
|
23
|
+
if (lifted)
|
|
24
|
+
return;
|
|
25
|
+
lifted = true;
|
|
26
|
+
active.by.splice(active.by.lastIndexOf(by), 1);
|
|
27
|
+
if (active.by.length > 0)
|
|
28
|
+
return;
|
|
29
|
+
covers.delete(element);
|
|
30
|
+
if (active.wasInert)
|
|
31
|
+
element.setAttribute('inert', '');
|
|
32
|
+
else
|
|
33
|
+
element.removeAttribute('inert');
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* The panel most recently covering an element and still over it.
|
|
38
|
+
*
|
|
39
|
+
* @param element The covered element.
|
|
40
|
+
* @returns That panel, or `null` when no cover from `coverElement` is in force.
|
|
41
|
+
*/
|
|
42
|
+
const lastCoverOf = (element) => covers.get(element)?.by.slice(-1)[0] ?? null;
|
|
43
|
+
|
|
44
|
+
exports.coverElement = coverElement;
|
|
45
|
+
exports.lastCoverOf = lastCoverOf;
|
|
46
|
+
//# sourceMappingURL=inert.utils.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inert.utils.cjs","sources":["../../../../src/utilities/__internal__/inertUtils/inert.utils.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAAA;AACA,MAAM,MAAM,GAAG,IAAI,OAAO,EAAyD;AAEnF;;;;;;;;AAQG;MACU,YAAY,GAAG,CAAC,OAAoB,EAAE,EAAe,KAAkB;;IAElF,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE;AACzF,IAAA,IAAI,MAAM,CAAC,EAAE,CAAC,MAAM,KAAK,CAAC;AAAE,QAAA,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC;AAC7D,IAAA,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;AAClB,IAAA,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC;IAE3B,IAAI,MAAM,GAAG,KAAK;AAClB,IAAA,OAAO,MAAK;AACV,QAAA,IAAI,MAAM;YAAE;QACZ,MAAM,GAAG,IAAI;AACb,QAAA,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AAC9C,QAAA,IAAI,MAAM,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC;YAAE;AAC1B,QAAA,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;QACtB,IAAI,MAAM,CAAC,QAAQ;AAAE,YAAA,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC;;AACjD,YAAA,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC;AACvC,IAAA,CAAC;AACH;AAEA;;;;;AAKG;AACI,MAAM,WAAW,GAAG,CAAC,OAAoB,KAAyB,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI;;;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Makes an element inert for one cover among possibly several, such as two panels over the same page. The element's own
|
|
3
|
+
* `inert` is read at the first cover and restored only when the last lifts, whatever order the covers lift in, so nothing
|
|
4
|
+
* else may write `inert` on the element meanwhile.
|
|
5
|
+
*
|
|
6
|
+
* @param element The element to take out of reach.
|
|
7
|
+
* @param by The panel covering it, which `lastCoverOf` reports so focus can be handed to it.
|
|
8
|
+
* @returns Lifts this cover; calling it twice is harmless.
|
|
9
|
+
*/
|
|
10
|
+
export declare const coverElement: (element: HTMLElement, by: HTMLElement) => (() => void);
|
|
11
|
+
/**
|
|
12
|
+
* The panel most recently covering an element and still over it.
|
|
13
|
+
*
|
|
14
|
+
* @param element The covered element.
|
|
15
|
+
* @returns That panel, or `null` when no cover from `coverElement` is in force.
|
|
16
|
+
*/
|
|
17
|
+
export declare const lastCoverOf: (element: HTMLElement) => HTMLElement | null;
|
|
18
|
+
//# sourceMappingURL=inert.utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inert.utils.d.ts","sourceRoot":"","sources":["../../../../src/utilities/__internal__/inertUtils/inert.utils.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,GAAI,SAAS,WAAW,EAAE,IAAI,WAAW,KAAG,CAAC,MAAM,IAAI,CAiB/E,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,SAAS,WAAW,KAAG,WAAW,GAAG,IAAoD,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** Covers in force per element, who holds each, and the `inert` the element had before the first, so the last to lift restores it. */
|
|
2
|
+
const covers = new WeakMap();
|
|
3
|
+
/**
|
|
4
|
+
* Makes an element inert for one cover among possibly several, such as two panels over the same page. The element's own
|
|
5
|
+
* `inert` is read at the first cover and restored only when the last lifts, whatever order the covers lift in, so nothing
|
|
6
|
+
* else may write `inert` on the element meanwhile.
|
|
7
|
+
*
|
|
8
|
+
* @param element The element to take out of reach.
|
|
9
|
+
* @param by The panel covering it, which `lastCoverOf` reports so focus can be handed to it.
|
|
10
|
+
* @returns Lifts this cover; calling it twice is harmless.
|
|
11
|
+
*/
|
|
12
|
+
const coverElement = (element, by) => {
|
|
13
|
+
// The attribute rather than the property: a browser reflects one into the other, and `[inert]` selectors then see the cover.
|
|
14
|
+
const active = covers.get(element) ?? { by: [], wasInert: element.hasAttribute('inert') };
|
|
15
|
+
if (active.by.length === 0)
|
|
16
|
+
element.setAttribute('inert', '');
|
|
17
|
+
active.by.push(by);
|
|
18
|
+
covers.set(element, active);
|
|
19
|
+
let lifted = false;
|
|
20
|
+
return () => {
|
|
21
|
+
if (lifted)
|
|
22
|
+
return;
|
|
23
|
+
lifted = true;
|
|
24
|
+
active.by.splice(active.by.lastIndexOf(by), 1);
|
|
25
|
+
if (active.by.length > 0)
|
|
26
|
+
return;
|
|
27
|
+
covers.delete(element);
|
|
28
|
+
if (active.wasInert)
|
|
29
|
+
element.setAttribute('inert', '');
|
|
30
|
+
else
|
|
31
|
+
element.removeAttribute('inert');
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* The panel most recently covering an element and still over it.
|
|
36
|
+
*
|
|
37
|
+
* @param element The covered element.
|
|
38
|
+
* @returns That panel, or `null` when no cover from `coverElement` is in force.
|
|
39
|
+
*/
|
|
40
|
+
const lastCoverOf = (element) => covers.get(element)?.by.slice(-1)[0] ?? null;
|
|
41
|
+
|
|
42
|
+
export { coverElement, lastCoverOf };
|
|
43
|
+
//# sourceMappingURL=inert.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inert.utils.js","sources":["../../../../src/utilities/__internal__/inertUtils/inert.utils.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;AACA,MAAM,MAAM,GAAG,IAAI,OAAO,EAAyD;AAEnF;;;;;;;;AAQG;MACU,YAAY,GAAG,CAAC,OAAoB,EAAE,EAAe,KAAkB;;IAElF,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE;AACzF,IAAA,IAAI,MAAM,CAAC,EAAE,CAAC,MAAM,KAAK,CAAC;AAAE,QAAA,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC;AAC7D,IAAA,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;AAClB,IAAA,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC;IAE3B,IAAI,MAAM,GAAG,KAAK;AAClB,IAAA,OAAO,MAAK;AACV,QAAA,IAAI,MAAM;YAAE;QACZ,MAAM,GAAG,IAAI;AACb,QAAA,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AAC9C,QAAA,IAAI,MAAM,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC;YAAE;AAC1B,QAAA,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;QACtB,IAAI,MAAM,CAAC,QAAQ;AAAE,YAAA,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC;;AACjD,YAAA,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC;AACvC,IAAA,CAAC;AACH;AAEA;;;;;AAKG;AACI,MAAM,WAAW,GAAG,CAAC,OAAoB,KAAyB,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI;;"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Fired on a side panel, bubbling, as it starts covering the page below `lg`. A DOM event rather than context, so it
|
|
5
|
+
* reaches an overlay in another React root, as a host's panel reaches a micro-frontend's slideout.
|
|
6
|
+
*/
|
|
7
|
+
const PAGE_COVER_EVENT = 'fd-page-cover';
|
|
8
|
+
/**
|
|
9
|
+
* Announces that a panel has started covering the page.
|
|
10
|
+
*
|
|
11
|
+
* @param panel The panel now covering the page.
|
|
12
|
+
*/
|
|
13
|
+
const dispatchPageCover = (panel) => {
|
|
14
|
+
panel.dispatchEvent(new CustomEvent(PAGE_COVER_EVENT, { bubbles: true }));
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Listens for any panel starting to cover the page.
|
|
18
|
+
*
|
|
19
|
+
* @param listener Runs on each cover.
|
|
20
|
+
* @returns Stops listening.
|
|
21
|
+
*/
|
|
22
|
+
const subscribePageCover = (listener) => {
|
|
23
|
+
document.addEventListener(PAGE_COVER_EVENT, listener);
|
|
24
|
+
return () => document.removeEventListener(PAGE_COVER_EVENT, listener);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
exports.PAGE_COVER_EVENT = PAGE_COVER_EVENT;
|
|
28
|
+
exports.dispatchPageCover = dispatchPageCover;
|
|
29
|
+
exports.subscribePageCover = subscribePageCover;
|
|
30
|
+
//# sourceMappingURL=pageCover.utils.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pageCover.utils.cjs","sources":["../../../../src/utilities/__internal__/pageCoverUtils/pageCover.utils.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAAA;;;AAGG;AACI,MAAM,gBAAgB,GAAG;AAEhC;;;;AAIG;AACI,MAAM,iBAAiB,GAAG,CAAC,KAAkB,KAAU;AAC5D,IAAA,KAAK,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,gBAAgB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AAC3E;AAEA;;;;;AAKG;AACI,MAAM,kBAAkB,GAAG,CAAC,QAAoB,KAAkB;AACvE,IAAA,QAAQ,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,QAAQ,CAAC;IACrD,OAAO,MAAM,QAAQ,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,QAAQ,CAAC;AACvE;;;;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fired on a side panel, bubbling, as it starts covering the page below `lg`. A DOM event rather than context, so it
|
|
3
|
+
* reaches an overlay in another React root, as a host's panel reaches a micro-frontend's slideout.
|
|
4
|
+
*/
|
|
5
|
+
export declare const PAGE_COVER_EVENT = "fd-page-cover";
|
|
6
|
+
/**
|
|
7
|
+
* Announces that a panel has started covering the page.
|
|
8
|
+
*
|
|
9
|
+
* @param panel The panel now covering the page.
|
|
10
|
+
*/
|
|
11
|
+
export declare const dispatchPageCover: (panel: HTMLElement) => void;
|
|
12
|
+
/**
|
|
13
|
+
* Listens for any panel starting to cover the page.
|
|
14
|
+
*
|
|
15
|
+
* @param listener Runs on each cover.
|
|
16
|
+
* @returns Stops listening.
|
|
17
|
+
*/
|
|
18
|
+
export declare const subscribePageCover: (listener: () => void) => (() => void);
|
|
19
|
+
//# sourceMappingURL=pageCover.utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pageCover.utils.d.ts","sourceRoot":"","sources":["../../../../src/utilities/__internal__/pageCoverUtils/pageCover.utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,gBAAgB,kBAAkB,CAAC;AAEhD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,WAAW,KAAG,IAEtD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,UAAU,MAAM,IAAI,KAAG,CAAC,MAAM,IAAI,CAGpE,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fired on a side panel, bubbling, as it starts covering the page below `lg`. A DOM event rather than context, so it
|
|
3
|
+
* reaches an overlay in another React root, as a host's panel reaches a micro-frontend's slideout.
|
|
4
|
+
*/
|
|
5
|
+
const PAGE_COVER_EVENT = 'fd-page-cover';
|
|
6
|
+
/**
|
|
7
|
+
* Announces that a panel has started covering the page.
|
|
8
|
+
*
|
|
9
|
+
* @param panel The panel now covering the page.
|
|
10
|
+
*/
|
|
11
|
+
const dispatchPageCover = (panel) => {
|
|
12
|
+
panel.dispatchEvent(new CustomEvent(PAGE_COVER_EVENT, { bubbles: true }));
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Listens for any panel starting to cover the page.
|
|
16
|
+
*
|
|
17
|
+
* @param listener Runs on each cover.
|
|
18
|
+
* @returns Stops listening.
|
|
19
|
+
*/
|
|
20
|
+
const subscribePageCover = (listener) => {
|
|
21
|
+
document.addEventListener(PAGE_COVER_EVENT, listener);
|
|
22
|
+
return () => document.removeEventListener(PAGE_COVER_EVENT, listener);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export { PAGE_COVER_EVENT, dispatchPageCover, subscribePageCover };
|
|
26
|
+
//# sourceMappingURL=pageCover.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pageCover.utils.js","sources":["../../../../src/utilities/__internal__/pageCoverUtils/pageCover.utils.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;;;AAGG;AACI,MAAM,gBAAgB,GAAG;AAEhC;;;;AAIG;AACI,MAAM,iBAAiB,GAAG,CAAC,KAAkB,KAAU;AAC5D,IAAA,KAAK,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,gBAAgB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AAC3E;AAEA;;;;;AAKG;AACI,MAAM,kBAAkB,GAAG,CAAC,QAAoB,KAAkB;AACvE,IAAA,QAAQ,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,QAAQ,CAAC;IACrD,OAAO,MAAM,QAAQ,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,QAAQ,CAAC;AACvE;;"}
|