emotion-js / emotion

šŸ‘©ā€šŸŽ¤ CSS-in-JS library designed for high performance style composition
https://emotion.sh/
MIT License
17.32k stars 1.1k forks source link

Plans to support Next.js 13 - /app directory #2928

Open fcisio opened 1 year ago

fcisio commented 1 year ago

The problem

Next JS just release their v13 publicly. As seen in their docs, emotion has not yet added support.

Is there any plan to add support in the near future?

Thanks.

mi-na-bot commented 1 year ago

We know that Emotion will not work exactly the same in server components, but it is rather a stretch that, "the writing is on the wall". The /app directory with Next.js is not production ready, and afaik there is not another popular React framework offering server components at all. How Emotion might interface with server components is going to be based on how people use them, which is thus unknown.

There are already a few ideas in this thread about how CSS styles might be applied to server components, either by wrapping with a client component which styles named classes, or somehow offering a static output of CSS styles for the server component. This would be more consistent with the current Emotion best practices of avoiding dynamic styles anyways. How much this breaks things will depend a lot on how much people put into server components. Client components will still exist and work fine.

mi-na-bot commented 1 year ago

@paluchi Server components and SSR are totally different things. Emotion supports SSR just fine.

karlhorky commented 1 year ago

What would be interesting is if Emotion could offer a subset of its features in server components (features that would not require context and all other client component technologies, similar to the framework-agnostic @emotion/css), allowing for styling of eg. Layout components without using either client components or a different styling solution. Switching components that you want to style to client components seems like a pretty big drawback. React Server Components will come to other frameworks as well, so it would be good to support this.

In our team, even though we're huge supporters of Emotion and CSS-in-JS, we have made the difficult decision to switch back to CSS Modules because of lack of support for styling in Server Components.

karlhorky commented 1 year ago

@Andarist Thinking more about my comment above, do you think it would be a temporary workaround to recommend @emotion/css to React Server Components users who want to avoid client components for styling? Or generally, what are your thoughts on my suggestions, for users who absolutely do not want to switch to client components for styling?

mi-na-bot commented 1 year ago

@karlhorky Are you using server components in production?

Andarist commented 1 year ago

The main problem with CSS-in-JS styles on the server is not that they need React context. In this context, React context is just a "state" (don't confuse it with React state). It's a "registry" of generated styles and stuff like that. So @emotion/css doesn't solve anything here - it's still impossible with it to reliably "transfer" styles from the server to the client without putting all the "current"* styles in the payload. You don't want to send all the "current" styles in the payload because those styles could have already been sent to the client in previous requests or they could have already been generated on the client. This would be a huge waste of network traffic.

*current as in - the ones used by what is currently fetched from the server, this could be a whole document, a page, a nested layout, or just a single component. Remember that server components are not only about fetching the initial document but they also support "refetching" things.

karlhorky commented 1 year ago

You don't want to send all the "current" styles in the payload because those styles could have already been sent to the client in previous requests...

This would be a huge waste of network traffic

Ok, I think I understand the optimization that Emotion is attempting to do here.

I guess what I'm asking is: is there a different way that Emotion could offer a subset of its features in React Server Components without downsides like this. Eg. wonder how CSS Modules does it - I'm assuming that they are not re-transferring all of the styles every time (eg. maybe they are generating a static CSS file for use with a <link> tag?)

mi-na-bot commented 1 year ago

@karlhorky CSS modules compile to a CSS file with generated unique classnames and return an object mapping friendly classnames to the unique ones. They send the styles all at once upfront.

pigoz commented 1 year ago

@karlhorky If you like emotion because you can mix in typescript variables but CSS modules is enough for your use case you might want to look at vanilla extract

karlhorky commented 1 year ago

Vanilla Extract looks cool! But it does not support normal CSS in strings (they only have object syntax) which is a dealbreaker for us, because we teach CSS to beginners.

Seems like there is a discussion to possibly include support for CSS strings in Vanilla Extract, I will watch over there.

snelsi commented 1 year ago

@karlhorky Sounds like you want to use linaria

paales commented 1 year ago

@Andarist You wrote:

You don't want to send all the "current" styles in the payload because those styles could have already been sent to the client in previous requests or they could have already been generated on the client. This would be a huge waste of network traffic.

Might be possible to split the server styles and client styles? This would reduce the 'overfetching' of the styles to only be the server styles? That doesn't sound so bad, when refreshing the server components it's styles should be refreshed as well in that case?

In any case, this isn't some big amount of kB's, is it? This probably beats moving the styles to client components in terms of perf. Especially for the first paint, as it doesn't need to render those client components? For refetching it it only needs to download, doesn't need to execute much, which trades kB's for CPU?

Sashkan commented 1 year ago

Is there a way to override this new SSR-oriented behavior ? I'm stuck between a rock and a hard place at the moment: I'm really fond of the new layout system, but my whole app is based on a design system that relies on Chakra UI, which relies on emotion, and I don't want to prefix every single file that includes one of these components with a 'use client';

On a non emotion-related level, I'm also using other providers which seem to conflict with the new appDir (SWR and react-intl), which makes me wonder: should I keep my current version of the app, and ditch this new wonderful layout system, or should I just turn almost 99% of my app into client-side components ?

Andarist commented 1 year ago

Might be possible to split the server styles and client styles? This would reduce the 'overfetching' of the styles to only be the server styles?

It would reduce it only to server styles. It would raise the complexity level on the client side because it still has to do something with the received styles, it might have to hydrate them into the cache, it might have to move them in the DOM, and more. My current PoV is that when it comes to styles in server components it's mostly YAGNI. We are mostly discussing this in a vacuum right now anyway. I think that it's best to have this constraint in place right now and let people use this in production. Once they do it we will actually get informed feedback rather than a theoretical one.

Especially for the first paint, as it doesn't need to render those client components?

Client components have to very much render for the first paint - or at least, they would render in the majority of use cases. Remember that you can SSR render client components - you just can't "refetch" them.

I don't want to prefix every single file that includes one of these components with a 'use client';

But you don't have to do that. It's optional and will probably be done within Chakra, Emotion, etc. You don't necessarily have to leak this into your app code.

karlhorky commented 1 year ago

My current PoV is that when it comes to styles in server components it's mostly YAGNI. We are mostly discussing this in a vacuum right now anyway. I think that it's best to have this constraint in place right now and let people use this in production.

Not to make this into a heated discussion or anything, but that is what my feedback in my comments above is: feedback from our team from using it in production (and also trying to develop a teaching curriculum around it).

I want to have a Layout component (eg. RootLayout) that is a Server Component, and have my styling for that layout also stay in Server Components (potentially even in the same Layout file). I only want to switch to a Client Component if there is some client-only features I'm using such as useState. I think this would not be an uncommon wish from others.

This also aligns with the current guidance from the Next.js team to just leave everything a server component until you absolutely need a client component.

Andarist commented 1 year ago

Hm, maybe we'll have to think about smth like useServerStyles (or something else) then. The refetching story is quite fuzzy to me and I'm not sure how to "plug" into it anything - so far I was only investigating the rendering of the initial document.

I feel like that should probably be a separate discussion - with its own thread. Let's keep this thread about "basic" /app directory support.

karlhorky commented 1 year ago

Thanks for the consideration. Sounds reasonable to move it šŸ‘ I've opened https://github.com/emotion-js/emotion/issues/2978 for Emotion + React Server Components.

bpossolo commented 1 year ago

My current PoV is that when it comes to styles in server components it's mostly YAGNI. We are mostly discussing this in a vacuum right now anyway. I think that it's best to have this constraint in place right now and let people use this in production.

I'm currently porting a production site (server rendered by PlayFramework) into a NextJS 13 app with app dir + MUI component library (using Emotion).

For our existing site:

The site is highly responsive to viewport sizing. What I find really helpful/useful about MUI + Emotion is the support for responsive css properties in js. So for the new NextJS site, I've configured all our breakpoints in the MUI theme like so:

breakpoints: {
  values: {
    bp0: 0,
    bp1: 375, // iphone 5 landscape & iphone 6/7/8/X/X+ portrait
    bp2: 414, // iphone 7+/8+ portrait
    bp3: 667, // iphone 6/7/7+/8/8+ landscape
    bp4: 768, // ipad portrait & iphone X/X+ landscape
    bp5: 1024, // ipad landscape & ipad pro portrait
    bp6: 1366, // ipad pro landscape
  },
}

And then reference those breakpoints in MUI components like so:

<Box
  component="aside"
  display={{
    bp0: 'none',
    bp4: 'block', // visible on screens 768+ css pixels wide
  }}>
  <Box
    component="section"
    display="flex"
    flexDirection={{
      bp4: 'column',
      bp6: 'row',
    }}>
    <div>column on medium sized screens</div>
    <div>row on larger screens</div>
  </Box>
</Box>

I would use css modules but media queries don't support css-variables and the browser env() spec doesn't support user-defined values yet. This means my css modules would have the literal breakpoint values littered all over...

As @karlhorky mentioned above, I'd like to reserve client components for things that actually require client side only functionality (local storage, event handlers, use state hook, effect hooks, etc).

Right now, my workaround is to mark virtually all "layout" components with 'use client' while I wait/pray/hope that I'll eventually be able to remove it.

garronej commented 1 year ago

@bpossolo

server-rendered html is critical (for seo reasons)

SSR is working fine, adding "use client"; isn't equivalent to using < NoSsr />.
Server components are components that render only on the server. Classic components are components that renders on the server and the client.
The goal of server component is to reduce the size of JS shipped to the client by keeping component code only on the server side. I.e., the rendering happens and only happens on the server side, even if the loading of the component is triggered on the client side (via client-side routing).. It also makes life easyer by enabling to write async code in the comoponents body.

bpossolo commented 1 year ago

@garronej yah, as I mentioned, the majority of our pages are comprised of components which only need to be rendered on the server.. i.e. we don't need/want all the associated js being shipped to the client when it's purely html + css + media queries that don't change after the initial rendering... ergo, I don't want to mark everything as 'use client'. and yes, I'm also using async/await in the server pages for retrieving the graphql data.

mwskwong commented 1 year ago

@garronej yah, as I mentioned, the majority of our pages are comprised of components which only need to be rendered on the server.. i.e. we don't need/want all the associated js being shipped to the client when it's purely html + css + media queries that don't change after the initial rendering... ergo, I don't want to mark everything as 'use client'. and yes, I'm also using async/await in the server pages for retrieving the graphql data.

Unfortunately, hydration is crucial to CSS-in-JS and I doubt they can move away from it any time soon. It takes great effort to do so.

To be honest, you already made a bad decision of trying to use an unstable feature in a company project. And further making another bad decision of not reading the Next.js document carefully on what is currently supported and what's not. And it is to be expected that early adopters have a few hiccups here and there.

You have nothing to lose from using use client in terms of performance. It is basically equivalent to using /pages. The most problematic thing is properly data fetching, where you have to create a server component wrapper for every place you need to fetch data because MUI components can only be client components.

Also, you properly constantly facing this:

import ServerComponent from './ServerComponent';

export default function ClientComponent() {
  return (
    <SomeMuiComponent>
      <ServerComponent />
    </SomeMuiComponent>
  );
}
bpossolo commented 1 year ago

To be honest, you already made a bad decision of trying to use an unstable feature in a company project. And further making another bad decision of not reading the Next.js document carefully on what is currently supported and what's not. And it is to be expected that early adopters have a few hiccups here and there.

@mwskwong I'm not sure what the point of your pretty condescending comment is but you're making all sorts of assumptions that are just incorrect... the devs asked for examples of real world use-cases for /app + server components + emotion so @karlhorky and I gave examples. also, I haven't had to wrap any components like your example so I have no idea what you're talking about... it sounds like you have little-to-no faith in the /app dir feature + server components (which for the most part work really well) so I'm not sure why you're chiming in here.

mwskwong commented 1 year ago

To be honest, you already made a bad decision of trying to use an unstable feature in a company project. And further making another bad decision of not reading the Next.js document carefully on what is currently supported and what's not. And it is to be expected that early adopters have a few hiccups here and there.

@mwskwong I'm not sure what the point of your pretty condescending comment is but you're making all sorts of assumptions that are just incorrect... the devs asked for examples of real world use-cases for /app + server components + emotion so @karlhorky and I gave examples. also, I haven't had to wrap any components like your example so I have no idea what you're talking about... it sounds like you have little-to-no faith in the /app dir feature + server components (which for the most part work really well) so I'm not sure why you're chiming in here.

Then perhaps I misunderstood, my apologies. Not trying to be a dick here. That's what happens when joining a discussion without context and making up my mind too quickly. But TBH, if I just look at the conversations on this topic alone, it does sound like you are trying to migrate a production site to the next 13 app/ dir for real.

As for you mentioning that you never faced the situation of wrapping server components in client components, I'm actually pretty surprised.

Are you only doing data fetching at the page level? Because if you do (some) data fetching at the component level, then you have to make the corresponding component a server component (properly by wrapping it in a server component wrapper), and may need to import it into a client component since you are using MUI. (Yes, I know a workaround is available, but that just makes the structure weird).

brandonscript commented 1 year ago

Update: Turns out it's useSearchParams hook causing tags never to show up, see https://github.com/vercel/next.js/issues/44868. Replacing with a custom hook watching popstate instead in a useEffect. Still, the principles here for blending client and server components is still relevant.


A couple of additional issues I've run across trying to work around this (thanks to https://github.com/emotion-js/emotion/issues/2928#issuecomment-1368709980 so much!)

Primarily this came out of the discovery that if your layout.tsx is a client only component, none of the Next server-side head will render ā€“ meaning any meta tags like title, description, or opengraph properties will not be available to crawlers or unfurlers. Likely related issue: https://github.com/vercel/next.js/issues/42268

To fix this, and a few other issues with theme loading, I tried moving client-only code into separate components, which is recommended in the docs.

I ended up with a hybrid server-side root component, so Next will handle conditionally rendering client leaves.

In my case, I had to do some extra legwork. This is probably a better approach, but unfortunately it still doesn't seem to get the tags to load server-side šŸ˜”.

  1. If you're creating a custom theme and exporting it, that theme needs a use client directive at the top:

// styles/mainTheme.ts

'use client'; 
// ^ must have

import { createTheme, responsiveFontSizes, Theme } from "@mui/material/styles";

const theme: Theme = createTheme({
  // ... your theme here
});

const responsive = responsiveFontSizes(theme), {
  factor: 1.25,
});

export default responsive;
  1. If you're using <ThemeProvider />, you have to create a lightweight client wrapper around it

// lib/SSR/theme.provider.tsx

"use client";

import { ThemeProvider } from "@mui/material";
import { DefaultTheme, ThemeProviderProps } from "@mui/styles";
import React from "react";

export const SSRThemeProvider = <T = DefaultTheme,>(
  props: ThemeProviderProps<T>
): React.ReactElement<ThemeProviderProps<T>> => {
  return (
    <React.StrictMode>
      <ThemeProvider {...props} />
    </React.StrictMode>
  );
};
  1. Your client-only content must have the use-client directive and wrap your content in the RootStyleRegistry.

// content/home.tsx

"use client";

import { CssBaseline } from "@mui/material";
import RootStyleRegistry from "lib/SSR"; // this is the emotion file from the linked post in this thread, I moved it

export const HomePage = () => {

  // do some cool client side stuff here like useEffect or useState like a boss

  return (
    <>
      <CssBaseline key="css-baseline" />
      <RootStyleRegistry>
      <body>
        <main>
          // your content here
        </main>
      </body>
    </>
  );
};

Then your page.tsx, layout.tsx, and head.tsx will look like:

// head.tsx

export default function Head() {
  return (
     <>
       <title>Your page title</title>
       // other meta tags
     </>
   );
}

// layout.tsx

import { SSRThemeProvider } from "lib/SSR/theme";
import React from "react";
import theme from "styles/mainTheme";

// This layout is now can handle both server and client rendering
// and in particular, will render <head> tags on the server.

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <React.StrictMode>
      <html lang="en" key="root">
        <head />
      </html>
      {/* ^ duplicate your HTML here with an empty body (or fallback plain text) and make sure the key matches. */}
      <SSRThemeProvider theme={theme} key="theme-provider">
        <html lang="en" key="root">
          {/*
            <head /> will contain the components returned by the nearest parent
            head.tsx. Find out more at https://beta.nextjs.org/docs/api-reference/file-conventions/head
            */}
          <head />
          <body>{children}</body>
        </html>
      </SSRThemeProvider>
    </React.StrictMode>
  );
};

// home.tsx

// This page is now can handle both server and client rendering

import { HomePage } from "content/home";

export default async function HybridHome() {
  return <HomePage />;
};
karlhorky commented 1 year ago

@karlhorky Sounds like you want to use linaria

Yep, Linaria also seems like another nice alternative to Emotion, which offers some of the functionality of Emotion's CSS-in-JS without the downsides of switching to Client Components.

However up until recently, the example / plugin was not updated for the Next.js 13 app directory, now it seems there is a solution for this:

MartinXPN commented 1 year ago

Has anyone encountered an issue with switching the light/dark theme? Some parts seem to not update (I'm using MUI)

arobert93 commented 1 year ago

Has anyone encountered an issue with switching the light/dark theme? Some parts seem to not update (I'm using MUI)

Yes, there seems to be a hydration error when creating the theme based on selected mode (light/dark).

image

DenisBessa commented 1 year ago

Has anyone encountered an issue with switching the light/dark theme? Some parts seem to not update (I'm using MUI)

Yes, there seems to be a hydration error when creating the theme based on selected mode (light/dark).

image

Yes, I'm experiencing this too

MartinXPN commented 1 year ago

I'm currently forced to do a full-page reload to be able to switch between light/dark mode.

arobert93 commented 1 year ago

@MartinXPN I've also did that using cookies as state for the selected theme. Read from cookies the value on SSR, then pass it to the client to build the theme. To switch it, update the cookies on client side (js-cookies) and reload the page. This is a nasty hack, but until we have a stable solution this does the job.

mririgoyen commented 1 year ago

Next's App Router is officially stable. Would love to know progress on Emotion's efforts to support Server Components and Next's App directory.

oalexdoda commented 1 year ago

Managed to get decent support for appDir using the suggestions in this thread, but every time a fast reload takes place it flickers in/out the Global Styles. Additionally, this earning keeps popping up on every route build.

image

Which is just a fragment that inserts CSSBaseline and GlobalStyles from MUI into the ThemeProvider.

image

Anybody else having this issue?

haukurmar commented 1 year ago

Next's App Router is officially stable. Would love to know progress on Emotion's efforts to support Server Components and Next's App directory.

@Andarist please... pretty please :)

MoZZANG commented 1 year ago

Hi, Team emotion. I'm not sure if you guys will watch this, Recently, nextJS13 is finally released stable version which is 13.4.1. So Our FE team is trying to use it with our own made common components styled by emotion(@emotion/styled v11.10.5, @Emotion Slack Inviter/react v11.10.5). But we got an error which is the photo. As you know, next13 has a lot of changes like separate client and server component. But as you can see the error, emotion styled or css tags only use client component they say. I think all of developers around world need to use both side. Iā€™m sure you guys know this problem and currently working on support NextJS latest version. So can you tell me when developing for supporting will be done and release? Thank you for reading

image

gabrielleacuba commented 1 year ago

Can someone explain to me, why when I'm going to use a css-in-js library, I need to do the configuration using the registry.tsx file (for example styled components or emotion) in the app folder ? And why is it not just install and use like in other versions of next and in the component that I need to style I put 'use client' ?

rtrembecky commented 1 year ago

@gabrielleacuba I'll answer the second question. The app directory is not only about another way to structure code. The issue (feature) is that it enables React Server Components (note: this is not a distinction between SSR and client, this is a new concept). Every component imported into the app directory is treated as a server component by default and needs to be marked with "use client" if it needs to run on the client (e.g. when it uses hooks). The Emotion styling depends on the theme in the context provided by ThemeProvider and as of the error above, context can't be used on the server, it's a client thing. Emotion will probably need to rethink and rework the approach in order to support the server components out-of-the-box.

cherealnice commented 1 year ago

@MoZZANG I was able to resolve this issue by doing the following:

  1. Isolating the providers for my app to a separate client component as described here
  2. Removing "jsxImportSource": "@emotion/react" from my .tsconfig, and setting it to "react".

Hope this helps :)

vaibhavM55 commented 1 year ago

Would be nice if Material UI website provided like a warning at the installation page for new people trying to use the latest Nextjs /app dir with Material UI, along with maybe a link to a timeline for the people / companies who already use Material UI and are considering migrating to the /app dir.

I know that Nextjs has it in it's documentation at css-in-js as "not currently supported and working on support" but it's way below and most newbies wouldn't know to look for it first. And them trying out MUI with app/ will lead to a lot of frustration and would leave a bad taste and poor first impression about MUI (when it's not really MUI's fault).

Also, about the "link" to a timeline / expected date of support, I know that there are these github threads and I (and most other people) am keeping track of them from time to time. But they are too long and started from Oct 2022 (when /app was in beta) and has hundreds of comments to "look for the right solution / answer". Again especially for newbies or people just looking into the issue for the first time and considering migrating to the /app since it's now stable.

Those two simple things (warning & timeline link) in mui website installation page would save a lot of frustration and time for a lot of people.

Also, thanks for your hard work, I know it must have been frustrating for you people too. I hope people at Next js had already considered the effects of their changes and would have devised a solution or at least a roadmap to a solution for libraries like MUI and emotion to help ease the transition. :)

bpossolo commented 1 year ago

I use MUI with the app directory and it works just fine. I need to mark components that directly use an mui component with ā€œuse clientā€ but everything works. Iā€™m not sure what all the fuss is about.

takecchi commented 1 year ago

Iā€™m not sure what all the fuss is about.

@bpossolo Because using "use client" would be merely a temporary makeshift solution and "emotion" wouldn't be able to benefit from React Server Components.

bpossolo commented 1 year ago

@takecchi yes there is the downside that it sends superfluous js to the browser but thereā€™s nothing stopping a person from using mui with the app directory right now as many are implying. Thatā€™s what I mean when I say I donā€™t know what the fuss is all about.

takecchi commented 1 year ago

@bpossolo I see. I think this discussion has become too lengthy and has strayed off topic

mwskwong commented 1 year ago

@takecchi yes there is the downside that it sends superfluous js to the browser but thereā€™s nothing stopping a person from using mui with the app directory right now as many are implying. Thatā€™s what I mean when I say I donā€™t know what the fuss is all about.

Another thing is since every MUI component has to be a client component, it makes it practically impossible to do server-side data fetching on the component level.

a-saven commented 1 year ago

Can anyone leave just plain answer: When will it work? It's main topic and link from every place, and it's flooded. For now server components won't work with 'use client' because of db access and that mad cache 'context' will break them as client components, even if not used. It makes all emotion based frameworks useless. So it's pretty important to know what the status, and what is going on. For now answer is: move to tailwind and forget.

poteboy commented 1 year ago

As a long-time user and big fan of Emotion, Iā€™m eagerly awaiting Next.js v13.4 support.

While weā€™re waiting for the official support, Iā€™ve been working on my personal project which may serve as a temporary alternative. It provides similar APIs (such as styled and css) to Emotion and avoids the current Next.js App Router limitation by handling style extraction at compile-time.

Though it might not be the perfect solution for everyone, I thought Iā€™d share it here in case anyone finds it useful in this interim period.

robertpiosik commented 1 year ago

@poteboy Your library doesn't support props and you should clearly state it before recommending it to anyone already using emotion, so no one will feel discomfort after spending some time reading the docs šŸ¤“

poteboy commented 1 year ago

@robertpiosik Thanks for taking the time to check out the doc, and sorry if it ended up disappointing you.

Just to give a little context, RSCs are essentially static - they get rendered on the server, then sent off to the browser as HTML. This means they can't be updated using JavaScript on the client side, which includes any DOM manipulations that Emotion operates under the hood for dynamic props. At this stage, we're unable to pull that off without some support from Vercel. So, that's why I referred to Kuma (my library) as a 'temporary alternative' :)

However, if your props are static and don't need to be changed after they're rendered, you can totally use them like this in Kuma:

const Box = styled('div')``
<Box fontSize={24} color='red' />

Hope this clears things up! :)

arobert93 commented 1 year ago

@robertpiosik Thanks for taking the time to check out the doc, and sorry if it ended up disappointing you.

Just to give a little context, RSCs are essentially static - they get rendered on the server, then sent off to the browser as HTML. This means they can't be updated using JavaScript on the client side, which includes any DOM manipulations that Emotion operates under the hood for dynamic props. At this stage, we're unable to pull that off without some support from Vercel. So, that's why I referred to Kuma (my library) as a 'temporary alternative' :)

However, if your props are static and don't need to be changed after they're rendered, you can totally use them like this in Kuma:

const Box = styled('div')``
<Box fontSize={24} color='red' />

Hope this clears things up! :)

Thank you for offering this solution! I disagree with Robert's aggressive tone, but they are right to some extent. I, as a builder and also consumer of UI component libraries, don't see how I should use Kuma to create components that are customizable since dynamic props cannot be used. I've checked the code of your library and I fully understand why dynamic props aren't available. Did you find any solution? For me it seems that I have to create a different styled component (using @kuma-ui/system) for each possible component variant.

mi-na-bot commented 1 year ago

@a-saven I have been following this issue for a while, and the plain answer is nothing is coming soon. Tailwind is probably what you should have always been using if the performance claims of the /app dir and server components feel essential. Otherwise, there is actually zero downside to using client components.

The /pages directory is still supported and works fine in Next. Also, you can simulate the get...Props data fetching methods with the /app directory by querying the DB in server components and passing the results to client components as props.

cosmictoby commented 1 year ago

@a-saven I have been following this issue for a while, and the plain answer is nothing is coming soon. Tailwind is probably what you should have always been using if the performance claims of the /app dir and server components feel essential. Otherwise, there is actually zero downside to using client components.

The /pages directory is still supported and works fine in Next. Also, you can simulate the get...Props data fetching methods with the /app directory by querying the DB in server components and passing the results to client components as props.

I know its slightly off topic here, but I think the page + client components isn't actually that bad structurally. It adds a level of demarcation.