Skip to content

Commit

Permalink
Fix provider issue by using react-shadow-scope (#78)
Browse files Browse the repository at this point in the history
  • Loading branch information
toddkao authored Jul 22, 2024
1 parent 65afa43 commit b22d262
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 56 deletions.
5 changes: 5 additions & 0 deletions .changeset/honest-rings-sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@skip-go/widget': minor
---

Revert shadow dom implentation to use react-shadow-scope
1 change: 1 addition & 0 deletions packages/widget/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
"match-sorter": "^6.3.4",
"react-hot-toast": "^2.4.1",
"react-icons": "^5.2.1",
"react-shadow-scope": "^1.0.5",
"tailwind-merge": "^2.3.0",
"viem": "2.x",
"wagmi": "2.x",
Expand Down
93 changes: 37 additions & 56 deletions packages/widget/src/ui/WithStyledShadowDom.tsx
Original file line number Diff line number Diff line change
@@ -1,70 +1,51 @@
import { ReactNode, useCallback, useEffect, useRef, useState } from 'react';
import { createRoot } from 'react-dom/client';
import { ReactNode, useCallback, useEffect, useState } from 'react';
import { StyleSheetManager } from 'styled-components';
import shadowDomStyles from '../styles/shadowDomStyles.css';
import toastStyles from '../styles/toastStyles.css';
import cssReset from '../styles/cssReset.css';
import { useInjectFontsToDocumentHead } from '../hooks/use-inject-fonts-to-document-head';
import { Scope } from 'react-shadow-scope';

export const WithStyledShadowDom = ({ children }: { children: ReactNode }) => {
const [isClient, setIsClient] = useState(false);
const stopPropagation = (e: Event) => e.stopPropagation();

useEffect(() => {
setIsClient(true);
}, []);
export const WithStyledShadowDom = ({ children }: { children: ReactNode }) => {
const [isClient, setIsClient] = useState<boolean>(false);

useInjectFontsToDocumentHead();
const [shadowDom, setShadowDom] = useState<HTMLElement>();
const [styledComponentContainer, setStyledComponentContainer] =
useState<HTMLElement>();

const onShadowDomLoaded = useCallback((element: HTMLDivElement) => {
setShadowDom(element);
element?.addEventListener('wheel', stopPropagation, true);
element?.addEventListener('touchmove', stopPropagation, true);
}, []);

const onRefLoaded = useCallback((element: HTMLDivElement) => {
if (element !== null) {
const shadowRoot = element.attachShadow({ mode: 'open' });

const styleContainer = document.createElement('div');
const appContainer = document.createElement('div');
const hostStyle = document.createElement('style');
hostStyle.textContent = `
${cssReset}
${toastStyles}
${shadowDomStyles}
`;

shadowRoot.appendChild(hostStyle);
shadowRoot.appendChild(styleContainer);
shadowRoot.appendChild(appContainer);

const Root = ({ children }: { children?: ReactNode }) => {
useEffect(() => {
const stopPropagation = (e: Event) => e.stopPropagation();

element?.shadowRoot?.addEventListener('wheel', stopPropagation, true);
element?.shadowRoot?.addEventListener(
'touchmove',
stopPropagation,
true
);
return () => {
element?.shadowRoot?.removeEventListener(
'wheel',
stopPropagation,
true
);
element?.shadowRoot?.removeEventListener(
'touchmove',
stopPropagation,
true
);
};
}, []);
return (
<StyleSheetManager target={styleContainer}>
{children}
</StyleSheetManager>
);
};
const onStyledComponentContainerLoaded = useCallback(
(element: HTMLDivElement) => {
setStyledComponentContainer(element);
},
[]
);

createRoot(appContainer).render(<Root>{children}</Root>);
}
useEffect(() => {
setIsClient(true);
return () => {
shadowDom?.removeEventListener('wheel', stopPropagation, true);
shadowDom?.removeEventListener('touchmove', stopPropagation, true);
};
}, []);

return isClient ? <div ref={onRefLoaded}></div> : null;
return isClient ? (
<Scope
stylesheets={[cssReset, shadowDomStyles, toastStyles]}
ref={onShadowDomLoaded}
>
<div ref={onStyledComponentContainerLoaded}></div>
<StyleSheetManager target={styledComponentContainer}>
{children}
</StyleSheetManager>
</Scope>
) : null;
};
11 changes: 11 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7954,6 +7954,7 @@ __metadata:
postcss-prefixwrap: ^1.49.0
react-hot-toast: ^2.4.1
react-icons: ^5.2.1
react-shadow-scope: ^1.0.5
rollup-plugin-copy: ^3.5.0
styled-components: ^6.0.0
stylis: ^4.0.0
Expand Down Expand Up @@ -21152,6 +21153,16 @@ __metadata:
languageName: node
linkType: hard

"react-shadow-scope@npm:^1.0.5":
version: 1.0.5
resolution: "react-shadow-scope@npm:1.0.5"
peerDependencies:
react: ^16.8.3 || ^18
react-dom: ^16.14.0 || ^18
checksum: 6ae39c58ac8ea4f18473da47ccb445a116f96fea162c44637dc5f69bd55858d423fee88436ba31319170b439f35b541f156729ff973de809e84e1eaa84c04cc9
languageName: node
linkType: hard

"react-stately@npm:^3.31.1":
version: 3.31.1
resolution: "react-stately@npm:3.31.1"
Expand Down

0 comments on commit b22d262

Please sign in to comment.