mantinedev / mantine

A fully featured React components library
https://mantine.dev
MIT License
26.18k stars 1.86k forks source link

Mantine with Next.js 13 app dir #2815

Closed TamjidAhmed10 closed 1 year ago

TamjidAhmed10 commented 1 year ago

What package has an issue

@mantine/core

Describe the bug

I use mantine dev as regular basis with next12. But when i put MantinProvider in app/pages.tsx or app/layout.tsx forlder. The app doesnt seems too work. Where to put __app.tsx requirements? sorry for bad english.

What version of @mantine/hooks page do you have in package.json?

"@mantine/hooks": "^5.6.2",

If possible, please include a link to a codesandbox with the reproduced problem

No response

Do you know how to fix the issue

No

Are you willing to participate in fixing this issue and create a pull request with the fix

No

Possible fix

Server Component support

rtivital commented 1 year ago

app folder is not supported, you can use mantine-next-template in next 13 with pages directory the same way as with next 12.

mikkurogue commented 1 year ago

@rtivital Are you planning on supporting Next 13's app folder in the future?

rtivital commented 1 year ago

Yes, it is planned, but it depends on emotion, there are several opened issues that you can track:

rtivital commented 1 year ago

I got it working based on this issue (https://github.com/emotion-js/emotion/issues/2928) – https://github.com/mantinedev/mantine-next-template/tree/next-13-app/app

nwazuo commented 1 year ago

somehow, the above fix works for app/layout but using any mantine component in app/page throws the same error again. I didn't create my project from mantine-next-template. Creating the project with mantine-next-template makes everything work but I do not want to make a TypeScript project(just JavaScript).

rtivital commented 1 year ago

All Mantine components can be used only if 'use client' is prepended to the file. As far as I know, pages are server only. You can use Mantine components only the way it is demonstrated in the template.

imranbarbhuiya commented 1 year ago

pages are server only

They default to server components but u can add 'use client' in page.tsx file to make it client component.

DenisBessa commented 1 year ago

All Mantine components can be used only if 'use client' is prepended to the file. As far as I know, pages are server only. You can use Mantine components only the way it is demonstrated in the template.

Hi, thanks for the amazing project!

Are there any plans to make Mantine compatible with server components?

rtivital commented 1 year ago

No, server components cannot have state/context/refs, it is not possible to build components without these things. Currently, it is not planned to add 'use client' to all components.

johnhenry commented 1 year ago

Seems like this is technically a Next issue for which they have documentation (beta): https://beta.nextjs.org/docs/rendering/server-and-client-components#rendering-third-party-context-providers-in-server-components.

Whereas third-party maintainers can add the 'use client' directive, it doesn't seem reasonable to expect them to do so.

anthonyalayo commented 1 year ago

Seems like this is technically a Next issue

@johnhenry actually this is a react issue: https://github.com/reactjs/rfcs/pull/227

On the latest RFC: https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md#basic-example

they decided on 'use client';. I personally would have preferred a 'use server'; but I'm sure there is still room for this to change during its beta.

dexter4life commented 1 year ago

I am having this problem

Unhandled Runtime Error TypeError: Cannot read properties of null (reading 'useCallback')

When I upgrade to nextjs 13, any idea how I can fix this?

vymao commented 1 year ago

Thanks for all of this. I'm a bit confused; I have been able to successfully use Mantine components in NextJS 13 without the use client directive?

cjroth commented 1 year ago

I got it working based on this issue (emotion-js/emotion#2928) – https://github.com/mantinedev/mantine-next-template/tree/next-13-app/app

This worked for me until I deployed to Vercel, then I got a blank white page. I managed to fix that using suggestions from https://github.com/emotion-js/emotion/issues/2928 but got flickering issues where the CSS wasn't loaded until a moment after the DOM. Here is the modified version of @rtivital's code that solved everything for me:

'use client'

import { CacheProvider } from '@emotion/react'
import { ColorScheme, ColorSchemeProvider, createEmotionCache, MantineProvider } from '@mantine/core'
import { useLocalStorage } from '@mantine/hooks'
import { useServerInsertedHTML } from 'next/navigation'

// must be created outside of the component to persist across renders
const cache = createEmotionCache({ key: 'my' })
cache.compat = true

export default function RootStyleRegistry({ children }: { children: JSX.Element }) {
    useServerInsertedHTML(() => (
        <style
            data-emotion={`${cache.key} ${Object.keys(cache.inserted).join(' ')}`}
            dangerouslySetInnerHTML={{
                __html: Object.values(cache.inserted).join(' '),
            }}
        />
    ))

    return (
        <CacheProvider value={cache}>
                <MantineProvider
                    withGlobalStyles
                    withNormalizeCSS
                    emotionCache={cache}
                >
                    {children}
                </MantineProvider>
        </CacheProvider>
    )
}
sumiren commented 1 year ago

@rtivital Are there any problems in putting this code into mantine/next? https://github.com/mantinedev/mantine/issues/2815#issuecomment-1368365038

I also tried this code, and confirmed that it works on pre-rendering(SSR/SG) correctly.

If it doesn't bother you, I'll try to make PR.

rtivital commented 1 year ago

It is not ready for production based on issue in emotion repo, I've implemented a POC. I'll update the template once app dir is out of beta and emotion provides documentation.

activenode commented 1 year ago

The version from @rtivital here from this repo seems to work fine for me but I'll see if I run into more problems.

Depechie commented 1 year ago

I know it is still experimental... but I was trying out some layouts in with the NextJS app folder and Mantine. When I try out the AppShell demo from the Mantine site, I do not get the nabar visible. It will only get visible when I give it a specific height and when I do that it is always bottom alligned. Any pointers on this? Someone else tried it already?

screenshot
rtivital commented 1 year ago

@Depechie Your issue is not related to app dir

shawnmclean commented 1 year ago

I tried the appDir template, works well until I tried to implement the theme changing behavior.

I ended up turning that off but if anyone found a way to drop the dark/light mode provider, please share.

ericschmar commented 1 year ago

@cjroth

I got it working based on this issue (emotion-js/emotion#2928) – https://github.com/mantinedev/mantine-next-template/tree/next-13-app/app

This worked for me until I deployed to Vercel, then I got a blank white page. I managed to fix that using suggestions from emotion-js/emotion#2928 but got flickering issues where the CSS wasn't loaded until a moment after the DOM. Here is the modified version of @rtivital's code that solved everything for me:

'use client'

import { CacheProvider } from '@emotion/react'
import { ColorScheme, ColorSchemeProvider, createEmotionCache, MantineProvider } from '@mantine/core'
import { useLocalStorage } from '@mantine/hooks'
import { useServerInsertedHTML } from 'next/navigation'

// must be created outside of the component to persist across renders
const cache = createEmotionCache({ key: 'my' })
cache.compat = true

export default function RootStyleRegistry({ children }: { children: JSX.Element }) {
  useServerInsertedHTML(() => (
      <style
          data-emotion={`${cache.key} ${Object.keys(cache.inserted).join(' ')}`}
          dangerouslySetInnerHTML={{
              __html: Object.values(cache.inserted).join(' '),
          }}
      />
  ))

  return (
      <CacheProvider value={cache}>
              <MantineProvider
                  withGlobalStyles
                  withNormalizeCSS
                  emotionCache={cache}
              >
                  {children}
              </MantineProvider>
      </CacheProvider>
  )
}

I've got this running in my own repo, but I'm still experiencing dramatic layout shifts on the first load of the website. From any page, doing cmd + r will cause pretty bad layout shifts. Does this happen to you?

Before, Mantine docs had a getInitialProps() that was used to modify the document context and supply a styles server that was linked up with emotion. I'm a 0% expert on either of these things, so I'm moreso wondering if this solution should also do the same thing? The previous method I mentioned got rid of layout shifts between refreshes. But now it is back.

zenyr commented 1 year ago

After searching through numerous cases I'd like to share my "current" workaround for Next.js 13 + Mantine + Emotion setup. It seems like working without FOUC/layout shifting for my minimal POC but this might break in certain cases. Please do share your experiences.

Also I've extracted out critical logic into a single hook. You can merge the extracted hook into the 'emotion.tsx' if that's your jam.

// 1. /app/layout.tsx
// use relative imports if you have to
import EmotionProvider from '$/components/Providers/emotion';

export default function RootLayout({ children }: { children: JSX.Element }) {
  return (
    <html>
      <head></head>
      <body>
        <EmotionProvider>
          {children}
        </EmotionProvider>
      </body>
    </html>
  );
}

// since layout.tsx & page.tsx is a Server Component you can do...
// const metadata : MetaData = { title: 'Awesome Mantine' }; jazz as you wish

// 2. /components/Providers/emotion.tsx
'use client';
import { useGluedEmotionCache } from '$/lib/emotionNextjsGlue';
import { CacheProvider } from '@emotion/react';
import { MantineProvider } from '@mantine/core';

export default function EmotionProvider({ children }: { children: JSX.Element }) {
  const cache = useGluedEmotionCache();
  return (
    <CacheProvider value={cache}>
    {/* You can wrap ColorSchemeProvider right here but skipping that for brevity ;) */} 
      <MantineProvider withGlobalStyles withNormalizeCSS emotionCache={cache}>
        {children}
      </MantineProvider>
    </CacheProvider>
  );
}

// 3. /lib/emotionNextjsGlue.tsx
import createCache from '@emotion/cache';
import { useServerInsertedHTML } from 'next/navigation';
import { useState } from 'react';

export const useGluedEmotionCache = (key = 'emotion') => {
  const [cache] = useState(() => {
    const cache = createCache({ key });
    cache.compat = true;
    return cache;
  });

  useServerInsertedHTML(() => {
    const entries = Object.entries(cache.inserted);
    if (entries.length === 0) return null;
    const names = entries
      .map(([n]) => n)
      .filter((n) => typeof n === 'string')
      .join(' ');
    const styles = entries.map(([, s]) => s).join('\n');
    const emotionKey = `${key} ${names}`;
    return <style data-emotion={emotionKey} dangerouslySetInnerHTML={{ __html: styles }} />;
  });

  return cache;
};

I don't use css={...} prop at the moment but if you set up jsx import source properly to @emotion/react, css prop works as expected too.

Edit: simplified hook a bit

Tansi-Jones commented 1 year ago

Hello, please when will mantine ui support next app dir? I've been trying to get it to work to no avail, help?

masterbater commented 1 year ago

I tried the appDir template, works well until I tried to implement the theme changing behavior.

I ended up turning that off but if anyone found a way to drop the dark/light mode provider, please share.

What you need to do is save theme color in cookies in client side and read the cookie in server side. Reading the cookie in client side causes to make it show the light mode first then dark mode. It also causes hydration errors if you read the cookies in client component and supply it to be default value of a state. Use cookies in nextjs import { cookies } from "next/headers to read the mantine-color-scheme cookie in server side of what you set in client side.

import RootStyleRegistry from "./emotion";

import { cookies } from "next/headers";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const cookieStore = cookies();
  const themeColor =
    cookieStore.get("mantine-color-scheme")?.value === "light"
      ? "light"
      : "dark";

  return (
    <html lang="en-US">
      <head />
      <body>
        <RootStyleRegistry themeColor={themeColor}>
          {children}
        </RootStyleRegistry>
      </body>
    </html>
  );
}
"use client";
export const dynamic = "force-dynamic";
import MainLayout from "@/components/layouts/MainLayout";
import { CacheProvider } from "@emotion/react";
import {
  ColorScheme,
  ColorSchemeProvider, MantineProvider, useEmotionCache
} from "@mantine/core";
import { setCookie } from "cookies-next";
import { useServerInsertedHTML } from "next/navigation";
import {
  useState
} from "react";

export default function RootStyleRegistry({
  themeColor,
  children,
}: {
  themeColor: ColorScheme;
  children: React.ReactNode;
}) {
  const cache = useEmotionCache();
  cache.compat = true;

  useServerInsertedHTML(() => (
    <style
      data-emotion={`${cache.key} ${Object.keys(cache.inserted).join(" ")}`}
      dangerouslySetInnerHTML={{
        __html: Object.values(cache.inserted).join(" "),
      }}
    />
  ));
  const [colorScheme, setColorScheme] = useState<ColorScheme>(themeColor);

  const toggleColorScheme = (value?: ColorScheme) => {
    const nextColorScheme =
      value || (colorScheme === "dark" ? "light" : "dark");
    setColorScheme(nextColorScheme);
    setCookie("mantine-color-scheme", nextColorScheme, {
      maxAge: 60 * 60 * 24 * 30,
    });
  };

  return (
    <CacheProvider value={cache}>
      <ColorSchemeProvider
        colorScheme={colorScheme}
        toggleColorScheme={toggleColorScheme}
      >
        <MantineProvider
          theme={{ colorScheme }}
          withGlobalStyles
          withNormalizeCSS
        >
          <MainLayout>{children}</MainLayout>
        </MantineProvider>
      </ColorSchemeProvider>
    </CacheProvider>
  );
}
kevinschaich commented 1 year ago

@rtivital the solution proposed by the React team (and the one being adopted by other packages) would be to add the use client at the top of all Mantine's components. Otherwise, you're enforcing that people use Client Components everywhere they reference a Mantine component – essentially defeating the purpose of the new Server Components structure and Next 13.

A whole page shouldn't need to be rendered on the client just because Mantine needs to support the onHover callback for a single button, and if you don't do it on the Mantine side, writing application code becomes extremely challenging – users would essentially need to create a Client Component wrapper for every Mantine component they want to use, pass props, etc.

Would you be opposed to just doing a find-and-replace to add that to the top of every .tsx file? It's just a string and should be a passive change that doesn't affect component behavior – not much different than just adding a JavaScript comment.

rtivital commented 1 year ago

It is not planned until Next.js app dir is out of beta/alpha

DenisBessa commented 1 year ago

@rtivital the solution proposed by the React team (and the one being adopted by other packages) would be to add the use client at the top of all Mantine's components. Otherwise, you're enforcing that people use Client Components everywhere they reference a Mantine component – essentially defeating the purpose of the new Server Components structure and Next 13.

A whole page shouldn't need to be rendered on the client just because Mantine needs to support the onHover callback for a single button, and if you don't do it on the Mantine side, writing application code becomes extremely challenging – users would essentially need to create a Client Component wrapper for every Mantine component they want to use, pass props, etc.

Would you be opposed to just doing a find-and-replace to add that to the top of every .tsx file? It's just a string and should be a passive change that doesn't affect component behavior – not much different than just adding a JavaScript comment.

In my projects I just created a .tsx file with "use client" on the top of it, imported all Mantine elements and then exported them again.

Not ideal but it works, with some minimal and very specific bugs.

activenode commented 1 year ago

Honestly, until resolved, you can also just use use client in one abstaction of a collected component. Which I did. So I don't see that it makes sense for @rtivital to implement something that is still undergoing a lot of changes (which NextJS13 still is as I am using it a lot in production).

It's not a big hassle to just create components such as MyUserComponent and just use use client in there and that's it. So it's a simple abstraction level until NextJS13 is "final final" and it makes sense for @rtivital to finalize it.

kevinschaich commented 1 year ago

The use client directive is not a Next 13 thing. It's an official React directive spelled out in RFC 0188. So regardless of the development / maturity / beta status of Next 13, it's not going away – Next is one of the early adopters of server components from a framework perspective but others will follow.

aabmets commented 1 year ago

So no SSR for Mantine until Next.js app dir has reached stable in 2023 october? I can't wait that long! Whats the point of using Next.js if you can't use SSR? The whole point of Next.js is builtin SSR support. I might as well use vanilla React at this point.

activenode commented 1 year ago

The use client directive is not a Next 13 thing. It's an official React directive spelled out in RFC 0188. So regardless of the development / maturity / beta status of Next 13, it's not going away – Next is one of the early adopters of server components from a framework perspective but others will follow.

I was trying to pinpoint a different strategy but that was perceived differently. I'm completely with you on this one in theory but we've also seen samples in the last decade of WebDev were "new confirmed strategies" have been changed for the sake of something better. So I can relate to the "do it all when out of beta"-Strategy (I get that it's not specifically NJS but those 2 are basically married, also looking at the respective mainteiners). I do agree as well however with the fact that it probably wouldn't hurt "too much" to add the string now.

@aabmets This is an open source product. I'm sure the company behind mantine is happy to help you specifically if you pay them. Besides also it is true what @masterbater said: I am using app dir with Mantine v6 - today. And that's possible because the main maintainer has helped in this regards, especially in this GitHub issue.

There is nothing stopping you from using it right now. You can equally fork it if it's that urgent. It's open source.

masterbater commented 1 year ago

So no SSR for Mantine until Next.js app dir has reached stable in 2023 october? I can't wait that long! Whats the point of using Next.js if you can't use SSR? The whole point of Next.js is builtin SSR support. I might as well use vanilla React at this point.

You can actually use nextjs the page directory is there and use it with mantine. App directory is beta its up to you to use a beta to a production environment.

Fact check using "use client" is still SERVER RENDERED from nextjs documentation, you might mean RSC Client Components enable you to add client-side interactivity to your application. In Next.js, they are prerendered on the server and hydrated on the client. You can think of Client Components as how Next.js 12 and previous versions worked (i.e. the pages/ directory).

aabmets commented 1 year ago

@activenode No thanks, I'm going back to vanilla JS and the old reliable jQuery.

godfrednanaowusu commented 1 year ago

It is not planned until Next.js app dir is out of beta/alpha

Can you at least give an insight into what is being worked on. That helps devs plan and prepare better.

rtivital commented 1 year ago

I'm working on Mantine 7.0. It will be migrated to native CSS – there won't be any issues related to styles during ssr.

aabmets commented 1 year ago

I'm working on Mantine 7.0. It will be migrated to native CSS – there won't be any issues related to styles during ssr.

Wait, does that mean that there will be no dependency on the emotion library? No CSS-in-JS? What does native CSS mean?

rtivital commented 1 year ago

Yes, there will not be dependency on emotion or other css-in-js libraries. Mantine will ship styles.css file with all styles.

dexter4life commented 1 year ago

Just curious 🧐 what will be the advantage of this new method on mantine?

tstpierre commented 1 year ago

Just curious 🧐 what will be the advantage of this new method on mantine?

Being able to use it in edge runtimes (really any runtimes since its zero-deps).

aabmets commented 1 year ago

Yes, there will not be dependency on emotion or other css-in-js libraries. Mantine will ship styles.css file with all styles.

But does this mean that it is no longer possible to dynamically calculate styles inside JS and all styles have to be prerendered on the server?

viczam commented 1 year ago

Yes, there will not be dependency on emotion or other css-in-js libraries. Mantine will ship styles.css file with all styles.

Why not go with tailwind already? I know you're not a big fan of it, but it's actually pretty good and extremely popular and mantine + tailwind would actually be a killer combination.

polarathene commented 1 year ago

Why not go with tailwind already?

Twin might be a better choice.

no longer possible to dynamically calculate styles inside JS

Also a bit concerned about such a big change? There are options like Linaria and Vanilla Extract for zero-runtime CSS in JS.

Is there an issue / PR to track or discuss that change? More information would be great, and this issue probably should avoid going off on that tangent.

activenode commented 1 year ago

Yes, there will not be dependency on emotion or other css-in-js libraries. Mantine will ship styles.css file with all styles.

Why not go with tailwind already? I know you're not a big fan of it, but it's actually pretty good and extremely popular and mantine + tailwind would actually be a killer combination.

Agreed. Tailwind can solve flexibility and portability.

rtivital commented 1 year ago

Why not go with tailwind already?

I consider tailwind to be an antipattern, I would rather not spend my time writing code that I hate.

no longer possible to dynamically calculate styles inside JS

It is a false statement. Dynamic styles are available with CSS variables.

There are options like Linaria and Vanilla Extract for zero-runtime CSS in JS

There is no reason to use these libraries – they are basically CSS preprocessors written in js – they do not allow to do anything that cannot be done with native CSS.

Is there an issue / PR to track or discuss that change? More information would be great, and this issue probably should avoid going off on that tangent.

No, there is no issue/PR for this. Once the first alpha version is out on npm it will be announced on GitHub discussions and Discord.

activenode commented 1 year ago

I consider tailwind to be an antipattern, I would rather not spend my time writing code that I hate.

Is there good reasons to elaborate on? I am specifically asking because when I didn't dig deep into tailwind I used to hate it because I thought "why not just go vanilla then?"

However, having used it for longer time now, I assume Tailwind has been very much misunderstood from the very beginning and many seem to "inuitively" think that tailwind is just classes. Hence I often read arguments like "it's just classes why not go vanilla?"

But as a matter of fact I feel we need more openness to tech stack changes. People complained in the beginning of CSS-in-JS as well - a lot. And then it became standard. And now we're rethinking it again because "we might not need it" or because it doesn't run Edge. Which is the whole gist about the openness and innovation towards technology.

And I feel like Tailwind deserves the same consideration. I hated it and thought it to be an antipattern when I didn't use it. But once I understood the idea and the details of it it became clear it is a highly extensible framework that is in fact not just classes.

Same as with CSS-in-JS or whatever tech stack you take the classes can be hashed. Same as e.g. current mantine uses size=xs tailwind uses things such as text-xs and that again can be abstracted via @apply to any custom class you wish.

.my-supercool-class {
  @apply text-xs text-primary
}

So at the end of the day it just comes down to another toolset. And that toolset is ultra-fast and extensible.

So opting for tailwind would bring the benefit that people could use their tailwind-based design system to connect with mantine. It's a little bit like a discussion "Vanilla JS vs React" where most people (in our bubble) would choose React for obvious reasons (well-known, stable, onboarding, many contributions/libs, ...)

Also with tailwind you can write your own Design System plugins which seamlessly opt in to existing tailwind systems https://v2.tailwindcss.com/docs/plugins .

IMO, same as with CSS-in-JS libs, through it's clear own patterns Tailwind can improve onboarding into projects drastically and really doesn't come with any kind of downsides (since it seamlessly connects with vanilla css) that i know of other than opinionation

rtivital commented 1 year ago

People complained in the beginning of CSS-in-JS as well - a lot

Well, in the end they turned out to be right, didn't they? At least for me, it was hell to maintain emotion ssr logic – this is the main reason to rewrite to native CSS.

And then it became standard

I would not call it that way. CSS-in-JS libraries are just a tool. Tools come and go over time.

And now we're rethinking it again because "we might not need it" or because it doesn't run Edge.

Same here – tool fails to do its job now, and the future of the tool is not clear – it should be replaced with the other tool.

And I feel like Tailwind deserves the same consideration.

It seems like you think of tw as a standard, the same as about CSS-in-JS. It is not. tw is a tool, that will become irrelevant eventually, even though it is popular now.

So opting for tailwind would bring the benefit that people could use their tailwind-based design system to connect with mantine.

And force people who do not like tw to either use it or drop the library.

since it seamlessly connects with vanilla css

There you go, then you won't have any issues combining tw with native CSS that Mantine provides.

Overall:

polarathene commented 1 year ago

It is a false statement. Dynamic styles are available with CSS variables.

In my experience that's been limited and not without issues.

There is no reason to use these libraries – they are basically CSS preprocessors written in js – they do not allow to do anything that cannot be done with native CSS.

I disagree, but at the same time don't want to debate it much, especially when you've no interest engaging with the community officially about such changes for feedback.

It's going to depend on context and clearly for what you're doing you believe it's worthwhile and will be better. If that makes it easier for you to maintain the project that is great! Personally I find a better DX with JS tooling, but curious to see how it works out for Mantine :+1:

dexter4life commented 1 year ago

From my own experience, mantine is just the best out there. So instead of migrating, rather to focus on improving the performance, and speaking of edge. What's so important about it?

activenode commented 1 year ago

It is a false statement. Dynamic styles are available with CSS variables.

In my experience that's been limited and not without issues.

There is no reason to use these libraries – they are basically CSS preprocessors written in js – they do not allow to do anything that cannot be done with native CSS.

I disagree, but at the same time don't want to debate it much, especially when you've no interest engaging with the community officially about such changes for feedback.

It's going to depend on context and clearly for what you're doing you believe it's worthwhile and will be better. If that makes it easier for you to maintain the project that is great! Personally I find a better DX with JS tooling, but curious to see how it works out for Mantine 👍

Sums it up well. Personally I disagree (for several reasons of which one probably would be that we could argue the towards similiar directions about many stacks and hence maybe find the conclusion that we should get rid of any, including React to get back to vanilla) but at the same time I do see that one would not love to work on technology that he/she does not appreciate.

I just feel, Mantine being such a good library so far, Mantine could benefit from more open discussions that make it more transparent why a decision leads a certain way. I personally found ADRs helpful but I can see that they would bring additionall effort and it's downside could be development slowdown.

So tl;dr I am happy to see with what you come up and how it's going to feel at the end of the day. No doubt it's gonna be cool and I'm also not doubting that a CSS "only" solution can be a good solution.

Songkeys commented 1 year ago

I feel uncomfortable that some people contributed no single commit to a repo but love to keep convincing the maintainers in an issue thread to do an opinionated thing that they've already said they don't like to do. If you want a solution in your way, you are very welcome to fork this repo or make a peripheral tool yourself. (I appreciate the thoughtful and passionate discussion above but that's too much to me. Just my personal opinion. Sorry.)