Skip to content

Commit efd0a4f

Browse files
committed
refactor: use portal to render layers
1 parent ae965d8 commit efd0a4f

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

packages/providers/layers/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
},
2929
"dependencies": {
3030
"@react-ck/elevation": "^1.1.11",
31-
"@react-ck/react-utils": "^1.2.9"
31+
"@react-ck/react-utils": "^1.2.9",
32+
"@react-ck/theme": "^1.7.0"
3233
}
3334
}

packages/providers/layers/src/Layer.tsx

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import React, { isValidElement, useContext, useEffect } from "react";
1+
import React, { isValidElement, useContext, useEffect, useMemo } from "react";
2+
import { createPortal } from "react-dom";
23
import { LayersContext } from "./context";
34
import { type Elevation } from "@react-ck/elevation";
45
import { getDisplayName } from "@react-ck/react-utils";
6+
import { ThemeProvider, useThemeContext } from "@react-ck/theme";
57

68
export interface LayerProps {
79
/** The elevation level for the layer */
@@ -12,21 +14,35 @@ export interface LayerProps {
1214

1315
/**
1416
* Component for creating a layer with a specific elevation level,
15-
* works like React portal - will render its children on app root
17+
* works with React portal - will render its children on document body
18+
* It also wraps the content in a theme provider
1619
*
1720
* @param props - {@link LayerProps}.
1821
* @returns The rendered content of the layer
1922
*/
2023

2124
export const Layer = ({ elevation, children }: Readonly<LayerProps>): React.ReactNode => {
25+
const theme = useThemeContext();
2226
const { createLayer } = useContext(LayersContext);
2327

28+
/** Generates the portal element wrapped by theme */
29+
const layerElement = useMemo(
30+
() =>
31+
createPortal(<ThemeProvider theme={theme.theme}>{children}</ThemeProvider>, document.body),
32+
[children, theme.theme],
33+
);
34+
35+
/** Renders the layer */
2436
useEffect(() => {
25-
const removeLayer = createLayer({ elevationKey: elevation, node: children });
37+
const removeLayer = createLayer({
38+
elevationKey: elevation,
39+
node: layerElement,
40+
});
2641

2742
return removeLayer;
28-
}, [elevation, children, createLayer]);
43+
}, [elevation, children, createLayer, theme, layerElement]);
2944

45+
/** Validate children */
3046
useEffect(() => {
3147
// Validate icon usage (icon should be set through specific prop)
3248
for (const i of React.Children.toArray(children).filter(isValidElement)) {

0 commit comments

Comments
 (0)