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

Using Material UI / Preact compatible component library #411

Closed
AravindPrabhs opened this issue Jul 4, 2022 · 11 comments
Closed

Using Material UI / Preact compatible component library #411

AravindPrabhs opened this issue Jul 4, 2022 · 11 comments

Comments

@AravindPrabhs
Copy link

Hi,

I was trying to include Material UI since it is compatible with preact:
https://twitter.com/preactjs/status/1152267975078154240?lang=en-GB

And including MUI core as a dependency as in normal deno: denoland/deno#7282

However I run into [object Object] is not a valid HTML tag name: denoland/deno#7282 when doing it both as a route and as an island.

Would in general all the packages in https://preactjs.com/about/libraries-addons/ technically be usable with Fresh ?

@raymclee
Copy link

raymclee commented Jul 4, 2022

https://mui.com/material-ui/guides/server-rendering/
I think MUI need some setup for server side rendering like the twind in fresh demo

@AravindPrabhs
Copy link
Author

To my understanding this extra configuration is a bonus to make sure there is no flickering since we re-render on the client side - so I assume purely using an island should also work.

However, I did give this a go, but this feels very non-standard and I was unsure how to inject html and css. I end-up getting React not defined error.

import { h } from "preact";
import {CssBaseline} from '@mui';
import { ThemeProvider } from 'mui/styles';
import createCache from 'https://esm.sh/@emotion/cache';
import { CacheProvider } from 'https://esm.sh/@emotion/react';
import createEmotionServer from 'https://esm.sh/@emotion/server/create-instance';
import render from 'preact-render-to-string';
import theme from './theme.ts';

export function createEmotionCache() {
  return createCache({ key: 'css' });
}

export function serverMUI(App: any) {
    const cache = createEmotionCache();
    const { extractCriticalToChunks, constructStyleTagsFromChunks } =
        createEmotionServer(cache);

    // Render the component to a string.
    const html: string = render(
        <CacheProvider value={cache}>
            <ThemeProvider theme={theme}>
                {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
                <CssBaseline />
                <App />
            </ThemeProvider>
        </CacheProvider>
    );

    // Grab the CSS from emotion
    const emotionChunks = extractCriticalToChunks(html);
    const emotionCss: string = constructStyleTagsFromChunks(emotionChunks);

    return <div dangerouslySetInnerHTML={{__html: emotionCss.concat(html)}}/>
}
export * from "mui";

For any component that I want rendered with MUI I just wrap it in a serverMUI call.
Note that replicating the theming and caching and an island gets the same exact error - the previous error described happens if you remove the wrapping CacheProvider etc.

@AravindPrabhs
Copy link
Author

Actually I realise the better way to do the above is using the request handlers instead but I still get the same error.

@raymclee
Copy link

raymclee commented Jul 5, 2022

maybe try adding "react": "preact " in import_map ?

Actually I realise the better way to do the above is using the request handlers instead but I still get the same error.

@AravindPrabhs
Copy link
Author

that isn't a valid map

@tylrw
Copy link

tylrw commented Jul 5, 2022

The approach here might work for you.

@SalvadorLekan
Copy link

I got it to work by adding this to the import_map.json. (I tested with this example from MUI's Website and I got an alert in the browser)
"@mui/material": "https://esm.sh/@mui/material@5.8.7?alias=react:preact/compat,react/jsx-runtime:preact/compat/jsx-runtime&deps=preact@10.8.1"

@AravindPrabhs
Copy link
Author

Thanks guys that works well !

@marsidev
Copy link

Actually I realise the better way to do the above is using the request handlers instead but I still get the same error.

Can you share your final working code? I also want to implement Material UI. I tried using a request handler inside routes/index.tsx but I'm getting the following error:

An error occured during route handling or page rendering. TypeError: Cannot read properties of undefined (reading 'context')
    at Module.w (https://esm.sh/v86/preact@10.9.0/X-YS9yZWFjdC9qc3gtcnVudGltZTpwcmVhY3QvY29tcGF0L2pzeC1ydW50aW1lLHJlYWN0OnByZWFjdC9jb21wYXQ/deno/hooks.js:2:1132)

@gbahamondezc
Copy link

gbahamondezc commented Dec 10, 2022

@marsidev I had the same issue, updating the preact deps version in the @mui/material import line to the same than fresh is using 10.11.0 fixed the issue for me, example.

{
  "imports": {
    "$fresh/": "https://deno.land/x/fresh@1.1.2/",
    "preact": "https://esm.sh/preact@10.11.0",
    "preact/": "https://esm.sh/preact@10.11.0/",
    "preact-render-to-string": "https://esm.sh/*preact-render-to-string@5.2.4",
    "@preact/signals": "https://esm.sh/*@preact/signals@1.0.3",
    "@preact/signals-core": "https://esm.sh/*@preact/signals-core@1.0.1",
    "twind": "https://esm.sh/twind@0.16.17",
    "twind/": "https://esm.sh/twind@0.16.17/",
    "@mui/material": "https://esm.sh/@mui/material@^5.10.17?alias=react:preact/compat,react/jsx-runtime:preact/compat/jsx-runtime&deps=preact@10.11.0"
  }
}

@reosablo
Copy link

reosablo commented Feb 4, 2023

see also: #363

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

No branches or pull requests

7 participants