radix-ui / themes

Radix Themes is an open-source component library optimized for fast development, easy maintenance, and accessibility. Maintained by @workos.
https://radix-ui.com/themes
MIT License
4.74k stars 163 forks source link

Is `@radix-ui/themes` currently working in plain React (without Next.js)? #59

Closed arielweinberger closed 3 months ago

arielweinberger commented 10 months ago

Hi, I am trying to install Radix in a plain React.js project and getting the following warnings when trying to import @radix-ui/themes:

import { Theme } from "@radix-ui/themes";

Warnings:

WARNING in ../../node_modules/@radix-ui/themes/dist/esm/theme-options.js
Module Warning (from ../../node_modules/source-map-loader/dist/cjs.js):
Failed to parse source map from '/Users/arielweinberger/Development/pezzo/pezzo/node_modules/@radix-ui/themes/src/theme-options.tsx' file: Error: ENOENT: no such file or directory, open '/Users/arielweinberger/Development/pezzo/pezzo/node_modules/@radix-ui/themes/src/theme-options.tsx'

WARNING in ../../node_modules/@radix-ui/themes/dist/esm/theme-panel.js
Module Warning (from ../../node_modules/source-map-loader/dist/cjs.js):
Failed to parse source map from '/Users/arielweinberger/Development/pezzo/pezzo/node_modules/@radix-ui/themes/src/theme-panel.tsx' file: Error: ENOENT: no such file or directory, open '/Users/arielweinberger/Development/pezzo/pezzo/node_modules/@radix-ui/themes/src/theme-panel.tsx'

WARNING in ../../node_modules/@radix-ui/themes/dist/esm/theme.js
Module Warning (from ../../node_modules/source-map-loader/dist/cjs.js):
Failed to parse source map from '/Users/arielweinberger/Development/pezzo/pezzo/node_modules/@radix-ui/themes/src/theme.tsx' file: Error: ENOENT: no such file or directory, open '/Users/arielweinberger/Development/pezzo/pezzo/node_modules/@radix-ui/themes/src/theme.tsx'

I see a few other people facing the same issue:

I see no response about this from the maintainers. Are you able to provide an update about this? Would love to adopt Radix in some of my projects.

I seem to be able to import some components such as DropdownMenu like so:

import * as DropdownMenu from "@radix-ui/react-dropdown-menu";

But cannot import Theme.

Steps to reproduce

  1. Create a new React app with create-react-app
  2. Install Radix UI
  3. Try to import and use <Theme>
xalixilax commented 10 months ago

I have the same issue. Some components seems to work regardless of the error, but the Theme component does not.

maciWils commented 10 months ago

I am having the same issue. I am working with Electron and am not using Next.js. Theme component does not appear to be working, and imports like Button are unresponsive to setting the variant properties within the tag.

needim commented 10 months ago

I have created a sandbox for CRA. Could you check it out?

https://codesandbox.io/s/radix-ui-themes-cra-hvw2lk?file=/src/App.js

needim commented 10 months ago

I am having the same issue. I am working with Electron and am not using Next.js. Theme component does not appear to be working, and imports like Button are unresponsive to setting the variant properties within the tag.

I haven't tried with Electron yet. Can you create an example repository for the repro?

maciWils commented 10 months ago

I poked around this issue a bit more today and found that my issue might be a bit different than what was described, but it is in the same vein. Please refer to this boilerplate Electron app repo for my example.

ISSUE 1: Theme and Theme Panel don't apply styles from @radix-ui/themes/styles.css I made a boilerplate electron app and installed Radix themes. I then put the <Theme> tag in the root of my app (tried both in App.tsx and index.tsx and it didn't make a difference). I then added <ThemePanel/> to see if the panel would show up. When I did this, the panel was showing, but @radix-ui/themes/styles.css was not applying any styles to it. Upon inspecting <Theme> I noticed that the parameters I had passed into <Theme> were still the default and did not match the parameters I gave.

RESOLUTION 1 I copied everything in @radix-ui/themes/styles.css into a new css file called radixThemes.css in my render directory, and was able to get the css to apply to everything under the <Theme> tag and <ThemePanel/> displayed with styling. This suggests there may be a problem with the importing (at least in Electron). There is a note in Electron that suggests using ~ in front of css imports should be used when the css file is in node_modules, but this throws an error, so I did not end up doing that.

ISSUE 2: Dark mode broken Once I got the styling to apply, I noticed that dark theme was having some issues. I passed in appearance='dark' into my <Theme> tag, and opened up the inspector to find that light-theme was applying. In the ThemePanel, clicking the Dark Theme button glitched out and dark theme would not select or apply.

RESOLUTION 2 In my index.ejs file (equivalent to index.html in non-Electron) I changed my body tag to use the dark class: <body class='dark'> and this solved the issue. But, this means I can't toggle between light and dark theme without adding extra handling.

CONCLUSION: My fixes worked in Electron, but they are a temporary way around this issue. Any time Radix's styles.css changes, I will have to re-copy the entire css file into my native one. I also will need to add handling for light and dark mode to apply in <body>. I am not getting warnings like others, however I was experiencing lack of styling and functionality with <Theme> rendering it unusable. Not sure if these solutions can help others in the mean time, but I hope this helps! I can't tell how much of this is related to Electron and how much is related to import issues.

jagretz commented 9 months ago

Thanks for sharing your problem and resolution @maciWils. I noticed the same issue importing @radix-ui/themes/styles.css and thought I could just directly reference the file from node_modules, but that also didn't appear to be working even though I can see the file is there.

FYI. I am also using a custom react + webpack setup and using an index.ejs template.

I am already importing another third-party library CSS from node-modules just fine, so I know my webpack is setup correctly for that. I am not sure why the radix styles.css isn't being imported properly and haven't been building open-source libs for a while to remember the intricacies, but I suspect it's to do with how the file is referenced in the package.json. I could be totally off on that assumption though.

For now, I am following your approach (RESOLUTION 1); manually copy the styles.css, and then ignore the file so stylelint doesn't pick it up. It's also simple enough to run a copy util during my build, but this is fine for now.

reezpatel commented 9 months ago

Extending on @maciWils comment, here is my approach that worked for me, so I basically created an HOC to wrap Theme component… It seems to work for my use case. I am not sure if there is any side effect, I guess not.

main.ts

import '@radix-ui/themes/styles.css';

theme-provider.tsx

/* eslint-disable react/jsx-no-useless-fragment */
import { Theme } from '@radix-ui/themes';
import { WithChildren } from './types.js';
import { ThemeProps } from '@radix-ui/themes/dist/cjs/theme.js';
import { useEffect } from 'react';

export const ThemeProvider: React.FC<WithChildren & ThemeProps> = ({ children, ...props }) => {
  useEffect(() => {
    switch (props.appearance) {
      case 'light': {
        if (document?.body) {
          document.body.classList.remove('light', 'dark');
          document.body.classList.add('light');
        }

        break;
      }
      case 'dark': {
        if (document?.body) {
          document.body.classList.remove('light', 'dark');
          document.body.classList.add('dark');
        }

        break;
      }
    }
  }, [props.appearance]);

  return (
    <Theme {...props}>
      <>{children}</>
    </Theme>
  );
};

app.tsx

export function App() {
  const [appearance, setAppearance] = useState<'dark' | 'light'>('dark');

  const toggle = () => {
    setAppearance(appearance === 'dark' ? 'light' : 'dark');
  };

  return (
    // All props are passed to <Theme></Theme>
    <ThemeProvider appearance={appearance}>
      <button onClick={toggle}></button>
      <TrpcProvider>
        <AppShell />
      </TrpcProvider>
      <ThemePanel></ThemePanel>
    </ThemeProvider>
  );
}
thursdaybw commented 9 months ago

I'm adding my "I am experiencing this too" comment. I am stock standard, basic react app and radix-themes, nothing else. I've simplified it down and for sure that css file just wont' load.

I have attempted an implmentation of reezpatel's solution in previous comment as plain js, but it's not seemed to make any difference in my case.

thursdaybw commented 9 months ago

My current workaround, that I am not happy with is similar to above:

cp node_modules/\@radix-ui/themes/styles.css app/

and then in my root ./app/index.js

import './styles.css'

instead of import '@radix-ui/themes/styles.css';..

Honestly, this is my literal first time ever using radix, like at all. And about 15 mins into using it, I was "this doesn't look right".. hopefully the maintainers will respond?

reezpatel commented 9 months ago

@thursdaybw check this out https://codesandbox.io/s/radix-ui-react-demo-s9zpx2

This is using the default react boilerplate from code sandbox, which, from the looks of it, uses create-react-app. Try, downloading this and see if works.

thursdaybw commented 9 months ago

@reezpatel I have my site inside lando and not keen an setting another up. I tried adapting that code without success.

I've been thinking about setting up next.js for a while, time to look into that then.

thanks for you help.

thursdaybw commented 9 months ago

OK. I moved on to setting up NextJS. And it works (mostly, there's a few niggly bugs) but it works much better than in plain react.

arielweinberger commented 9 months ago

Good to know, but I'd still expect it to work with plain React.

An acknowledgment from the maintainers would be appreciated.

Sebosek commented 9 months ago

Same here. Clean Create React App, but unfortunately, the same errors 😕

reezpatel commented 9 months ago

Wired, check my codesandox link, it's using create-react-app and after the suggested code, it works fine.

Infact I am using same code (but it is generated from nx not cre) in our production service and haven't faced any issue.

nikasepiskveradze commented 8 months ago

I'm experiencing that issue too

Pranit-Harekar commented 7 months ago

I am kind of experiencing a similar issue with Next.js wherein the dark theme is being replaced/ignored upon router navigation router.push("/my/path"). I will open another issue but I wanted to check if anyone is experiencing the same.

henryStelle commented 3 months ago

I have created a sandbox for CRA. Could you check it out?

https://codesandbox.io/s/radix-ui-themes-cra-hvw2lk?file=/src/App.js

I just opened this sandbox and don't see any errors. Maybe the latest version fixed the issue?

vladmoroz commented 3 months ago

The source maps warnings are going to be fixed in the upcoming 3.0

hatimbijjou commented 3 months ago

I poked around this issue a bit more today and found that my issue might be a bit different than what was described, but it is in the same vein. Please refer to this boilerplate Electron app repo for my example.

ISSUE 1: Theme and Theme Panel don't apply styles from @radix-ui/themes/styles.css I made a boilerplate electron app and installed Radix themes. I then put the <Theme> tag in the root of my app (tried both in App.tsx and index.tsx and it didn't make a difference). I then added <ThemePanel/> to see if the panel would show up. When I did this, the panel was showing, but @radix-ui/themes/styles.css was not applying any styles to it. Upon inspecting <Theme> I noticed that the parameters I had passed into <Theme> were still the default and did not match the parameters I gave.

RESOLUTION 1 I copied everything in @radix-ui/themes/styles.css into a new css file called radixThemes.css in my render directory, and was able to get the css to apply to everything under the <Theme> tag and <ThemePanel/> displayed with styling. This suggests there may be a problem with the importing (at least in Electron). There is a note in Electron that suggests using ~ in front of css imports should be used when the css file is in node_modules, but this throws an error, so I did not end up doing that.

ISSUE 2: Dark mode broken Once I got the styling to apply, I noticed that dark theme was having some issues. I passed in appearance='dark' into my <Theme> tag, and opened up the inspector to find that light-theme was applying. In the ThemePanel, clicking the Dark Theme button glitched out and dark theme would not select or apply.

RESOLUTION 2 In my index.ejs file (equivalent to index.html in non-Electron) I changed my body tag to use the dark class: <body class='dark'> and this solved the issue. But, this means I can't toggle between light and dark theme without adding extra handling.

CONCLUSION: My fixes worked in Electron, but they are a temporary way around this issue. Any time Radix's styles.css changes, I will have to re-copy the entire css file into my native one. I also will need to add handling for light and dark mode to apply in <body>. I am not getting warnings like others, however I was experiencing lack of styling and functionality with <Theme> rendering it unusable. Not sure if these solutions can help others in the mean time, but I hope this helps! I can't tell how much of this is related to Electron and how much is related to import issues.

I found the 1 solution helpful, i had the same case => i had react as the render for an electron app, and radix ui styles were not build correctly, the problem is related to imports. so i copied the styles from '@radix-ui/themes/styles.css' and put them in a css file and imported it to my renderer and it worked

Devmond commented 1 month ago

@vladmoroz not sure why this issue is closed, it remains an issue.

I bundled the latest version via webpack but the styles.css is not imported.

I have taken the same work-around that is mentioned above, ie include node_modules/@radix-ui/themes/styles.css directly in an application. In my case just did an old school include in a web page and it works.

Addressing this would save a lot of hassle.

vladmoroz commented 1 month ago

@Devmond the original issue was about the missing source maps warning, which was resolved.

For the stylesheet, there shouldn't be anything for us left to do—the stylesheet is included in the package, mentioned in the "files" field in package.json, and there's a "style" entry point; Radix Themes is confirmed to work fine in a number of frameworks that use different bundlers.

I'm not sure this repo is the best place to get support on configuring webpack, but feel free to open a discussion with a question for that.

FranciscoKloganB commented 1 month ago

I have faced this issue using Nx monorepo with RSpack (rust based webpack counter part).

I don't know why this does not work on webpack or other older or exoteric bundlers, but I would assume that there are so many bundlers that it is often difficult to keep track of everything. However, we don't need fancy work arounds like copying the code into our application, that is never a great idea.

For webpack and rspack users, if you are using CSS or SCSS you can import the styles into your code in a more elegant and scalable manner.

/** assets/stylesheets/global.scss */
@import "@radix-ui/themes/styles";
/** main.tsx */
import './assets/stylesheets/global.scss'

import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'

import App from './App'

const container = document.getElementById('root') as HTMLElement
const root = createRoot(container)

root.render(
  <StrictMode>
    <App />
  </StrictMode>,
)