Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add documentation on various techniques of handling CSS #242

Open
ryanseddon opened this issue Mar 17, 2023 · 8 comments
Open

Add documentation on various techniques of handling CSS #242

ryanseddon opened this issue Mar 17, 2023 · 8 comments

Comments

@ryanseddon
Copy link
Owner

This project gets a lot of questions on how to make CSS work inside the iframe from various CSS-in-JS libraries to CSS modules, SCSS etc.

Add some good examples covering how this can be done in the read me.

See latest issue with demo and code examples on solving that.

@aboveyunhai
Copy link

For Next.js and tailwindCSS, I cannot guarantee it will work consistently

  const { document: doc } = useFrame();

  useLayoutEffect(() => {
    // this covers development case as well as part of production
    document.head.querySelectorAll("style").forEach((style) => {
      const frameStyles = style.cloneNode(true);
      doc?.head.append(frameStyles);
    });
   // inject the production minified styles into the iframe
    if (process && process.env.NODE_ENV === "production") {
      document.head.querySelectorAll('link[as="style"]').forEach((ele) => {
        doc?.head.append(ele.cloneNode(true));
      });
      document.head
        .querySelectorAll('link[rel="stylesheet"]')
        .forEach((ele) => {
          doc?.head.append(ele.cloneNode(true));
        });
    }
  }, [doc]);

@paulm17
Copy link

paulm17 commented Apr 12, 2023

@aboveyunhai What version of next and what version of this lib are you running?

I'm running 13.1.1 and 5.2.6. All I get is a blank screen. If I regress to 4.1.3 of the lib. It works, but then I don't get the useFrame helper.

Found out here, that it's possibly a state issue: #192

I have partial success but then

const { document: doc } = useFrame();

Outputs the same as document. Both giving the same parent html and not the parent AND iframe.

Too many issues. If you could supply the full code, would be great! Thanks

@aboveyunhai
Copy link

aboveyunhai commented Apr 12, 2023

@paulm17 it's a react issue, you need to call useFrame() inside the instead of at the same level.

const Inner = () => {
 useFrame();
}

const Outer = () => {
// useFrame();    call hook here will fail because it's outside of <Frame />

<Frame>
 <Inner/>
</Frame>
}

@paulm17
Copy link

paulm17 commented Apr 12, 2023

@aboveyunhai Thanks for the quick reply.

That's what I needed, I've written a wrapper function.

My code in case this helps someone else.

interface wrapperProps {
  children: React.ReactNode
}

function Wrapper({children}: wrapperProps) {
  const { document: doc } = useFrame();

  document.head.querySelectorAll("style").forEach((style) => {
    const frameStyles = style.cloneNode(true);
    doc?.head?.append(frameStyles);
  });   

  return <>{children}</>
}

This is how I'm using it in my proof of concept app.

const Home: NextPage = () => {  
  const [isMounted, setMounted] = useState(false)
  
  useEffect(() => {
    setMounted(true)
  }, [])

  return (
    <>
      <Head>
        <title>Create T3 App</title>
        <meta name="description" content="Generated by create-t3-app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      {isMounted && <Frame    
        id="frame"    
        style={{
          border: "none",
          width: "100%",
          height: "100vh",
        }}
      >
        <Wrapper>
          <Sortable/>       
        </Wrapper>
      </Frame>}
    </>
  );
};

I saw the examples from @ryanseddon but perhaps they work for CRA only? 🤷‍♂️

Anyway, I now have the latest 5.2.6 working with the help from the other thread.

@aboveyunhai
Copy link

aboveyunhai commented Apr 12, 2023

@paulm17 you are missing my production insert part, so it will only work on dev, if you use build step npm run build, npm run start, the production probably will miss all the stylings.

@paulm17
Copy link

paulm17 commented Apr 12, 2023

proof of concept app.

Thanks, but you missed the part where I said ^. The app won't ever see production.

@sscaff1
Copy link

sscaff1 commented Aug 30, 2024

If anyone is using react-jss. This can help:

  1. Create a wrapper for JSSProvider
import { create } from 'jss';
import { ReactNode } from 'react';
import { useFrame } from 'react-frame-component';
import { JssProvider } from 'react-jss';
import preset from 'jss-preset-default';

const JssProviderWrapper = ({ children }: { children: ReactNode }) => {
  const { document } = useFrame();
  const jss = create({ insertionPoint: document.head });
  jss.setup(preset());
  return <JssProvider jss={jss}>{children}</JssProvider>;
};

export default JssProviderWrapper;

Then use it:

const App = () => (
  <Frame initialContent={initialContent}>
    <JssProviderWrapper>
      <MyApp />
    </JssProviderWrapper>
  </Frame>
);

@sakib412
Copy link

How to load css from installed packages(node_modules)?
For example: import '@ezy/ui/styles.css';
How to load this css inside iframe, currently in link tag only public route css is working.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants