npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@nexusui/theme

v5.0.0

Published

This is a simple MUI theme drop in for your React application, which aims to be the source of truth for the NexusUI Design system.

Downloads

2,254

Readme

NexusUI MUI Theme

This is a simple MUI theme drop in for your React application, which aims to be the source of truth for the NexusUI Design system.

NOTE: The NexusUI v5+ theme enables the cssVariables feature and allows wrapping your app with a ThemeProvider. After rendering, you will see the CSS variables in the :root stylesheet of the HTML document. By default, these variables are flattened and prefixed with --mui.

Installation

# With yarn:
yarn add @nexusui/theme

# With npm:
npm install --save @nexusui/theme

Peer Dependencies

Our theme is built to be used with MUI, so you'll need to have all of the MUI peer dependencies installed in your project:

# With yarn:
yarn add @mui/material @emotion/react @emotion/styled @mui/icons-material

# With npm:
npm install --save @mui/material @emotion/react @emotion/styled

Usage

Basic theme & Fonts Import

In your main React application entry point, wrap your whole app with the ThemeProvider and pass in the NexusUI theme to the theme prop. You should also include the CssBaseline component from MUI — this component includes a CSS reset to standardize default styles across browsers for a more consistent experience. Additionally, you should import the fonts file, which provides a self-hosted version of the Open Sans font through Fontsource.

NOTE: The fonts file from the NexusUI theme includes the 400 (regular), 600 (semi-bold), 700 (bold), and 800 (extra-bold) weights. If you need 300 (light) or 500 (medium) for your application, you can include them separately (see below).

import CssBaseline from '@mui/material/CssBaseline';
import { ThemeProvider } from '@mui/material/styles';
import theme from '@nexusui/theme';
import '@nexusui/theme/fonts';
// The theme variables type is not enabled by default. You need to import the module augmentation to enable the typings:
import type {} from '@mui/material/themeCssVarsAugmentation';
// include these only if you need Open Sans light or medium weight in your application
// import '@fontsource/open-sans/300.css;
// import '@fontsource/open-sans/500.css;
...

<ThemeProvider theme={theme}>
  <CssBaseline />
  {/* Your Application Contents Here */}
</ThemeProvider>

Supporting Light & Dark Theme

The NexusUI theme includes both light and dark colorSchemes / themes. You can toggle between light and dark mode using the useColorScheme hook from MUI.

import CssBaseline from '@mui/material/CssBaseline';
import {
  ThemeProvider,
  useColorScheme,
} from '@mui/material/styles'
import theme from "@nexusui/theme";
import '@nexusui/theme/fonts';
// The theme variables type is not enabled by default. You need to import the module augmentation to enable the typings:
import type {} from '@mui/material/themeCssVarsAugmentation';

const defaultMode = localStorage.getItem("theme") || 'light'; // Or read from redux
const { mode, setMode } = useColorScheme();

<ThemeProvider theme={theme} defaultMode={defaultMode}>
  <CssBaseline />
  {/* Your Application Contents Here */}
  <Button
      onClick={() => {
        setMode(mode === 'light' ? 'dark' : 'light');
      }}
    >
      {mode === 'light' ? 'Turn dark' : 'Turn light'}
    </Button>
</ThemeProvider>

Supporting localization

If you also want to support both MUI and Nexus UI components localization switching in your app, you can use useThemeWithLocale to simplify this step:

import {
  ThemeProvider
} from '@mui/material/styles'
import CssBaseline from '@mui/material/CssBaseline';
import { LanguageType, useThemeWithLocale, nexusThemeConfig } from "@nexusui/theme";
import '@nexusui/theme/fonts';
// The theme variables type is not enabled by default. You need to import the module augmentation to enable the typings:
import type {} from '@mui/material/themeCssVarsAugmentation';

// Or read theme mode from redux
const defaultMode = localStorage.getItem("theme") || 'light';

// Or read language from redux
const language = localStorage.getItem("language")  || 'en-US'; // Or read from redux

const themeWithLocale = useThemeWithLocale(language as LanguageType, nexusThemeConfig);

<ThemeProvider theme={themeWithLocale} defaultMode={defaultMode}>
  <CssBaseline />
  {/* Your Application Contents Here */}
</ThemeProvider>

With MUI X Data Grid or MUI X Date Pickers

If you want to add localization for either of these supplemental MUI libraries, you can import their localization configurations and merge them into the theme (you can find instructions here and here).

import { ThemeProvider, extendTheme } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import { LanguageType, useThemeWithLocale, nexusThemeConfig } from "@nexusui/theme";
import '@nexusui/theme/fonts';
// The theme variables type is not enabled by default. You need to import the module augmentation to enable the typings:
import type {} from '@mui/material/themeCssVarsAugmentation';
// import the localization configurations for any languages you support
import * as gridLocales from '@mui/x-data-grid/locales';
import * as dateLocales from '@mui/x-date-pickers/locales';

// Or read theme mode from redux
const defaultMode = localStorage.getItem("theme") || 'light';

// Or read language from redux
const language = localStorage.getItem("language")  || 'en-US'; // Or read from redux

const themeWithLocale = useThemeWithLocale(language as LanguageType, nexusThemeConfig, gridLocales[language], dateLocales[language]);

<ThemeProvider theme={themeWithLocale} defaultMode={defaultMode}>
  <CssBaseline />
  {/* Your Application Contents Here */}
</ThemeProvider>

Migration Guide

4.X.X => 5.0.0

Version 5 eliminates custom theme extensions to help you prepare for the migration to the new Nova theme. All custom theme properties have been eliminated. The theme has also been migrated to the new CSS variables structure from MUI. Refer to the following to help you map any existing styles using these custom properties to a suitable standard theme value:

Typescript & Jest

The theme variables type is not enabled by default. You need to import the module augmentation to enable the typings.

// App.tsx
import type {} from '@mui/material/themeCssVarsAugmentation';
  • You may face "matchMedia" issue after upgrading, please simulate it in jest setup file.
// jest.setup.ts
window.matchMedia = (query) => ({
  matches: false,
  media: query,
  onchange: null,
  addListener: jest.fn(),
  removeListener: jest.fn(),
  addEventListener: jest.fn(),
  removeEventListener: jest.fn(),
  dispatchEvent: jest.fn(),
});

Highlight Palette

Highlight colors have been removed from the theme object, but they are still available through the colors subfolder:

// before
sx={{ color: (theme) => theme.highlight.XXX }}

// after
import { highlight } from '@nexusui/theme/colors';
sx={{ color: highlight.XXX }}

Shades Palette

The shades palette has been removed, but you can use the rgba construction to recreate them where needed:

// before
sx={{ color: (theme) => theme.shades.primary['4p'] }} // 4p, 8p, 12p, 30p, 50p
sx={{ color: (theme) => theme.shades.secondary['4p'] }} // 4p, 8p, 12p, 30p, 50p

// after w/ CSS Vars (preferred)
import { alpha } from '@mui/material/styles';

sx={{ color: (theme) => `rgba(${theme.vars.palette.primary.mainChannel} / 0.04)` }} // 0.04, 0.08, 0.12, 0.30, 0.50
sx={{ color: (theme) => `rgba(${theme.vars.palette.secondary.mainChannel} / 0.04)` }} // 0.04, 0.08, 0.12, 0.30, 0.50

// after with alpha
import { alpha } from '@mui/material/styles';

sx={{ color: (theme) => alpha(theme.palette.primary.main, 0.04) }} // 0.04, 0.08, 0.12, 0.30, 0.50
sx={{ color: (theme) => alpha(theme.palette.secondary.main, 0.04) }} // 0.04, 0.08, 0.12, 0.30, 0.50

Alternate Background

Alternate background color has been removed — switch to using default or paper, whichever is closer for your use case.

// before
sx={{ backgroundColor: 'background.alternate' }}

// after
sx={{ backgroundColor: 'background.default' }} // or 'background.paper'

Typography Variants

Custom typography variants have been removed — replace them with the nearest standard variant:

| Custom Variant | Standard Variant | | -------- | -------- | | display | h1 | | bodyL | body1 | | body | body2 | | bodyS | body2 |

Alternate Component Colors

Previously, some components supported an 'alternate' color option (Button, Checkbox, Chip, Fab, IconButton, Radio, Slider, Switch, ToggleButton, ToggleButtonGroup), which gave the components a white base for use on darker colored backgrounds. This option has been removed, but you can recreate the styles if needed as follows:

Button
// before
<Button color={'alternate'} />
<Button color={'alternate'} variant={'outlined'} />
<Button color={'alternate'} variant={'contained'} />

// after
<Button color={'inherit'} sx={{ color: 'common.white' }} />
<Button color={'inherit'} variant={'outlined'} sx={{ color: 'common.white', borderColor: 'common.white' }} />
<Button 
  color={'inherit'} 
  variant={'contained'} 
  sx={(theme) => ({ 
    backgroundColor: 'common.white', 
    color: 'primary.main',
    ...theme.applyStyles("dark", {
      color: 'primary.dark'
    })
  })} 
/>
IconButton
// before
<IconButton color={'alternate'} />

// after
<IconButton color={'inherit'} sx={{ color: 'common.white' }} />
Checkbox
// before
<Checkbox color={'alternate'} />

// after
<Checkbox color={'default'} sx={{ color: 'primary.200' }} />
Fab
// before
<Fab color={'alternate'} />

// after
<Fab color={'inherit'} sx={{ backgroundColor: 'common.white', color: 'primary.main' }} />
Radio
// before
<Radio color={'alternate'} />

// after
<Radio color={'default'} sx={{ color: 'primary.200' }} />
Slider
// before
<Slider color={'alternate'} />

// after (for dark theme, you can ignore the sx and just use the primary color on its own)
<Slider 
    color={'primary'}
    sx={{
      color: 'primary.400',
      '& .MuiSlider-rail': {
        backgroundColor: 'background.paper',
        opacity: 1
      },
      '& .MuiSlider-markLabel': {
        color: 'common.white'
      },
      '& .MuiSlider-valueLabel': {
        backgroundColor: 'background.paper',
        color: 'primary.main'
      }
    }}
/>
Switch
// before
<Switch color={'alternate'} />

// after (for dark theme, you can use primary or info variant on its own without custom styles)
<Switch
  sx={{
    '& .MuiSwitch-switchBase': {
      '&.Mui-disabled': {
        color: 'grey.300',
        '+ .MuiSwitch-track': {
          backgroundColor: 'grey.400',
          opacity: 1,
        },
      },
      '&.Mui-checked': {
        '+ .MuiSwitch-track': {
          backgroundColor: 'primary.300',
          opacity: 1,
        },
        '&.Mui-disabled': {
          color: 'primary.200',
          '+ .MuiSwitch-track': {
            backgroundColor: 'primary.400',
            opacity: 1,
          },
        },
      },
    },
    '& .MuiSwitch-track': {
      backgroundColor: (theme) => alpha(theme.palette.common.white, 0.38),
      opacity: 1,
    },
  }}
ToggleButton / ToggleButtonGroup
// before
<ToggleButtonGroup color={'alternate'} />

// after
<ToggleButtonGroup 
  color={'info'} 
  sx={{ 
    '& .MuiToggleButton-root':{ 
      color: 'inherit' 
    } 
  }} 
/>
Chip
// before
<Chip color={'alternate'} variant={'filled'} />
<Chip color={'alternate'} variant={'outlined'} />

// after
<Chip
  color={'default'}
  variant={'filled'}
  sx={{
    backgroundColor: 'common.white',
    '& .MuiChip-deleteIcon': {
      color: 'grey.400',
      '&:hover': {
        color: 'grey.500'
      }
    },
    '& .MuiChip-avatar': {
      backgroundColor: 'grey.400',
      color: 'common.white'
    }
  }}
/>
<Chip
  color={'default'}
  variant={'outlined'}
  sx={{
    my: 2,
    borderColor: 'common.white',
    color: 'common.white',
    '& .MuiChip-deleteIcon': {
      color: (theme) => alpha(theme.palette.common.white, 0.7),
      '&:hover': {
        color: 'common.white'
      }
    },
    '& .MuiChip-avatar': {
      backgroundColor: 'common.white',
      color: 'primary.main'
    },
    '&.MuiChip-clickable:hover': {
      backgroundColor: (theme) => alpha(theme.palette.common.white, 0.15)
    }
  }}
/>

Localization

Previously, the Nexus UI theme (themeWithLocale) included built-in localization for MUI X DataGrid and Date/Time Pickers. To reduce peer dependency requirements, these built in localizations have been removed. If you are using any of these components in your application, you can add the localizations yourself and merge them with the Nexus UI theme (instructions for DataGrid and Date Pickers — also see the example in the usage instructions above).

Css Variables utility

The getThemePaletteCssVariables has been removed. If you were using this previously, you can now access CSS variables for theme values directly from the theme object.

// before
import { getThemePaletteCssVariables } from '@nexusui/theme';
const theme = localStorage.getItem('theme') === 'dark' ? 'dark' : 'light';
const cssVariables = getThemePaletteCssVariables(theme);
const html = document.getElementsByTagName('html')[0];
Object.keys(cssVariables).forEach((property) => {
  html.style.setProperty(property, cssVariables[property]);
});
export default function CssVariableUsage() {
  const style = { display: 'flex', flex: 1, padding: '8px', marginTop: '4px', marginRight: '4px' };
  return (
    <div style={{ ...style, margin: 0, padding: 0 }}>
      <div style={{ backgroundColor: 'var(--mui-primary-main)', color: 'var(--mui-primary-contrastText)', ...style }}>primary.main</div>
      <div style={{ backgroundColor: 'var(--mui-secondary-main)', color: 'var(--mui-secondary-contrastText)', ...style }}>secondary.main</div>
      <div style={{ backgroundColor: 'var(--mui-error-main)', color: 'var(--mui-error-contrastText)', ...style }}>error.main</div>
    </div>
  );
}

// after
import { useTheme } from '@mui/material/styles';

const theme = useTheme();

<div style={{backgroundColor: theme.vars.palette.primary.main}} />

3.X.X => 4.0.0

Version 4.0.0 of @nexusui/theme includes a single breaking change with dependencies. When upgrading, you'll need to add the following dependencies:

  • @mui/x-tree-view

You can also remove your @mui/lab dependency if you were only using it for the TreeView component, which was migrated out of the lab.

2.X.X -> 3.0.0

Version 3.0.0 of @nexusui/theme includes a single breaking change with dependencies. When upgrading, you'll need to update your dependencies to the following minimum versions:

  • @mui/x-data-grid to version 6.5.0 or greater.
  • @mui/x-date-pickers to version 6.7.0 or greater.

1.X.X -> 2.0.0

Version 2.0.0 of @nexusui/theme includes a few minor breaking changes to improve consistency and compatibility and also introduces our new dark theme. When upgrading from version 1.x, take note of the following breaking changes.

1) Open Sans fonts no longer automatically included

We previously bundled the Open Sans font dependencies along with our theme automatically to simplify the integration for users. However, including these CSS files automatically in our NPM package caused the theme to no longer be compatible with NextJS applications. We have removed this automatic import in version 2.0.0, so when upgrading, you will need to manually add the following import to your top-level index file:


import '@nexusui/theme/fonts';

2) onDark palette renamed to alternate

We previously had a supplemental palette called 'onDark' (theme.palette.onDark) which was used sparingly for components that were rendered on a dark blue background. We've renamed this palette to be more general in order to make sense for the dark theme. You should be able to use a simple find & replace strategy to replace all instances of onDark with alternate throughout your application.

3) background.blue palette renamed to background.alternate

Similar to the onDark palette, we have renamed the 'background.blue' palette (theme.palette.background.blue) to 'background.alternate' for compatibility with the dark theme (the alternate background is not a shade of blue in the dark theme). This is another case where you can use a find & replace strategy to update the name throughout your application.

0.X.X -> 1.0.0

Version 1.0.0 of @nexusui/theme is a major refactor to better align with Material Design styles and the Material UI theming mechanism. This update also improves alignment with the Nexus design assets currently accessible through Figma.

In general, we recommend trying to reduce your custom style/theme overrides that you may have in place for MUI elements in your application (you can gradually add them back in if they are, in fact, necessary). We've put a lot of effort into making these components look correct for NexusUI applications out-of-the-box with little to no styling required. Any overrides that you currently have in place will likely interfere and prevent you from reaping the full benefits of the updated theme.

When updating to this version, there are some key changes that you will need to be aware of to make the process as smooth as possible.

1) New Peer Dependencies

We converted the theme package to TypeScript. To add custom theming for MUI-X components, we needed to add new dependencies on their type definitions. You will need to install these packages to avoid type errors when using the theme.

# With yarn:
yarn add @mui/x-data-grid @mui/x-date-pickers

# With npm:
npm install --save @mui/x-data-grid @mui/x-date-pickers

2) Color Palette Imports

Individual color palettes are no longer available from a nested colors folder. Instead, import them from the package root:

// before
import { black, blue, green, grey, orange, red } from '@nexusui/theme/colors';

// after
import { black, blue, green, grey, orange, red } from '@nexusui/theme';

3) Updated Color Palette Shades

  • Individual color palettes have been updated for compatibility with the MUI theme mechanism. These now include shades for 50, 100, 200, 300, 400, 500, 600, 700, 800, 900. Note that the 0 and 1000 shades have been removed.
  • All palettes previously included pure white as their lightest shade and pure black as their darkest shade. The lightest/darkest shade in each palette is now a version of the base color. If you need pure white/black, you can access them from the common palette or using the hex code.
// before
import { blue } from '@nexusui/theme/colors';
const myWhite = blue[50];
const myBlack = blue[1000];

// after
import { blue } from '@nexusui/theme';
const myDarkColor = blue[900];
const myLightColor = blue[50];
const myWhite = theme.palette.common.white; // or '#fff'
const myBlack = theme.palette.common.black; // or '#000'
  • Some palettes previously did not have all shades defined, so some shades (e.g., 500 and 700) might have been exactly the same. Every variant in each palette is now a unique shade that evenly progresses from light to dark (this is most notable in the range > 500 — there is a wider variety of darker shades now for most colors).

  • The blue palette was also overhauled (it's actually a combination of the previous blue and secondary blue palettes — we now have blue and darkBlue). Because the base color shifted, there is no direct 1-1 mapping of old shades to new shades, but a reasonable mapping would be:

oldBlue[0] -> theme.palette.common.white
oldBlue[50] -> grey[200]
oldBlue[100] -> blue[50]
oldBlue[200] -> blue[100]
oldBlue[300] -> blue[200]
oldBlue[400] -> blue[600]
oldBlue[500] -> blue[700]
oldBlue[600] -> darkBlue[700]
oldBlue[700] -> darkBlue[700]
oldBlue[800] -> darkBlue[800]
oldBlue[900] -> darkBlue[900]
oldBlue[1000] -> theme.palette.common.black

4) Removed Tertiary and Dark Palettes

We previously extended the default MUI theme structure to include tertiary and dark palettes. Additionally, the primary and secondary palettes were both based on the same blue palette.

To better align with how MUI theming works, we have removed the tertiary palette and moved those definitions to secondary to provide a better accent color (instead of blue and blue).

// before
const myBlueColor = theme.palette.secondary;
const myGreenColor = theme.palette.tertiary;

// after
const myBlueColor = theme.palette.primary;
const myGreenColor = theme.palette.secondary;

The dark palette was previously used to handle variations of components that were displayed on a dark colored background. The spirit of this palette has been maintained, but renamed to alternate. This palette is not meant to be used like the other palettes (it does have all shades defined, but they are all pure white) — it's exclusively for use with the MUI components that support a 'white' version for use on dark backgrounds (Button, IconButton, CheckBox, Fab, Radio, Slider, Switch, ToggleButtonGroup, ToggleButton, Chip) by passing it to the color prop.

// before
<Button color={'dark'}/>

// after
<Button color={'alternate'}/>

5) Updated Typography Variants

The Typography variants have been slightly modified and updated to define the styles for previously undefined defaults from MUI. Notable changes include:

  • added a display variant — this is the biggest and boldest style we offer
  • added a definition for h6, subtitle, and subtitle2
  • custom "body2" styles have been shifted down (subtitle styles take the place of the larger sizes):
    • bodyXL has been removed -> bodyL
    • bodyL -> body
    • body -> bodyS
  • removed additional custom variants in favor of default MUI variants:
    • label -> bodyS
    • strong -> <Typography fontWeight={700}>
    • footer -> caption
    • user -> <Typography variant={"body2"} fontWeight={700}>

6) Default Roundness (Border Radius)

The theme default roundness property in the theme (affects the roundness of corners on various MUI elements) has been changed from 8px to 0.25rem (4px). If you were basing some of your custom styles on the theme roundness, you may need to multiply your values by 2 to maintain the same style as before.