Skip to content

Commit a37e0de

Browse files
committed
feat: allow rendering layers without react portal
1 parent 6648590 commit a37e0de

File tree

4 files changed

+28
-9
lines changed

4 files changed

+28
-9
lines changed

packages/providers/layers/src/Layer.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ export interface LayerProps {
2323

2424
export const Layer = ({ elevation, children }: Readonly<LayerProps>): React.ReactNode => {
2525
const theme = useThemeContext();
26-
const { createLayer } = useContext(LayersContext);
26+
const { createLayer, usePortal } = useContext(LayersContext);
2727

2828
/** Generates the portal element wrapped by theme */
2929
const layerElement = useMemo(
3030
() =>
31-
createPortal(<ThemeProvider theme={theme.theme}>{children}</ThemeProvider>, document.body),
32-
[children, theme.theme],
31+
usePortal
32+
? createPortal(<ThemeProvider theme={theme.theme}>{children}</ThemeProvider>, document.body)
33+
: children,
34+
[children, theme.theme, usePortal],
3335
);
3436

3537
/** Renders the layer */

packages/providers/layers/src/LayersProvider.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { elevationMap } from "@react-ck/elevation";
66
/** Data type for a layer with an additional 'id' property */
77
type LayerList = Array<LayerData & { id: string }>;
88

9-
export interface LayersProviderProps {
9+
export interface LayersProviderProps extends Pick<LayersContextProps, "usePortal"> {
1010
/** The child components to be wrapped by the LayersProvider */
1111
children?: React.ReactNode;
1212
}
@@ -18,7 +18,10 @@ export interface LayersProviderProps {
1818
* @returns The rendered LayersProvider component
1919
*/
2020

21-
export const LayersProvider = ({ children }: Readonly<LayersProviderProps>): React.ReactElement => {
21+
export const LayersProvider = ({
22+
children,
23+
usePortal,
24+
}: Readonly<LayersProviderProps>): React.ReactElement => {
2225
const currlayer = useRef<number>(0);
2326
const [layers, setLayers] = useState<LayerList>([]);
2427

@@ -41,7 +44,10 @@ export const LayersProvider = ({ children }: Readonly<LayersProviderProps>): Rea
4144
};
4245
}, []);
4346

44-
const contextValue = useMemo<LayersContextProps>(() => ({ createLayer }), [createLayer]);
47+
const contextValue = useMemo<LayersContextProps>(
48+
() => ({ createLayer, usePortal }),
49+
[createLayer, usePortal],
50+
);
4551

4652
// Sort layers by elevation
4753
const computedLayers = useMemo(

packages/providers/layers/src/context.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@ export interface LayerData {
77
}
88

99
export interface LayersContextProps {
10+
/** If true, renders app layers on document body instead of on same level of root element,
11+
* if set to false keep in mind that tit might affect positioning of floating elements */
12+
usePortal: boolean;
1013
createLayer: (data: LayerData) => () => void;
1114
}
1215

1316
export const LayersContext = React.createContext<LayersContextProps>({
17+
usePortal: true,
1418
createLayer: () => {
1519
throw new Error("Layers context not defined");
1620
},
Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import React from "react";
22
import { ThemeProvider, type ThemeProviderProps } from "@react-ck/theme";
3-
import { LayersProvider } from "@react-ck/layers";
3+
import { LayersProvider, type LayersProviderProps } from "@react-ck/layers";
44

55
/** Props for the Manager component */
66
export interface ManagerProps {
77
/** Properties of the {@link ThemeProvider} */
88
theme?: Omit<ThemeProviderProps, "children">;
9+
/** If true, renders app layers on document body instead of on same level of root element,
10+
* if set to false keep in mind that tit might affect positioning of floating elements */
11+
usePortal?: LayersProviderProps["usePortal"];
912
/** Content slot */
1013
children: React.ReactNode;
1114
}
@@ -15,8 +18,12 @@ export interface ManagerProps {
1518
* @param props - {@link ManagerProps}
1619
* @returns The provided content wrapped by theme & layers providers.
1720
*/
18-
export const Manager = ({ theme, children }: Readonly<ManagerProps>): React.ReactElement => (
21+
export const Manager = ({
22+
theme,
23+
children,
24+
usePortal = true,
25+
}: Readonly<ManagerProps>): React.ReactElement => (
1926
<ThemeProvider {...theme}>
20-
<LayersProvider>{children}</LayersProvider>
27+
<LayersProvider usePortal={usePortal}>{children}</LayersProvider>
2128
</ThemeProvider>
2229
);

0 commit comments

Comments
 (0)