Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

merge-sx

RobinTail27.5kMIT3.4.0TypeScript support: included

Combines multiple SxProps for Material UI components.

react, typescript, styled-components, reactjs, material-ui, styling, css-in-js, jss, strict, mui, merge, combine, merging, muiv5

readme

merge-sx

Coverage Status NPM Downloads NPM License

Combines multiple SxProps for Material UI components.

Installation

npm install merge-sx
# or
yarn add merge-sx

Usage

The utility provides a very simple and semantically clean interface, that supports conditional and optional inclusions.

import { mergeSx } from "merge-sx";

// Merge your SxProps
mergeSx(sx1, sx2 /*, ... */);
// Merge optionally
mergeSx(internalSx, props?.sx); // supports undefined
// Merge conditionally
mergeSx(commonSx, isMobile && mobileSx); // supports false

Why might you need it

MUI 5 has introduced a new way of styling React components using a Theme-aware sx property. It can be necessary to create your own styled components while still allowing for additional styling by the consumer. In this case your component will have its own sx property, most likely optional. This makes it necessary somehow to combine your own styles with the styles coming from the consumer of your component. One approach might be using a styling wrapper, an alternative way to style your component with the styled() utility. Thus, you could apply the consumer's sx to the pre-styled component. However, this approach can be inconvenient for several reasons.

I came to conclusion that merging several sx properties is better. However, the SxProps has rather complex data type. It can be an object with styling properties, can be function, can be null. It can be a challenge to perform a merge under strict typing of Typescript.

How it works

Luckily, starting version 5.1.0 of MUI SxProps can also be array. However, nested arrays are not allowed, so this utility does exactly the flat merge, also bringing support for conditional and optional inclusions, providing a very simple and semantically clean interface.

Performance

The utility has been tested to support up to 65535 arguments.

Performance chart

Examples

Conditional merging

The utility supports false:

<Button sx={mergeSx(commonSx, isMobile && mobileSx)}>Click me</Button>

Optional merging

The utility supports undefined:

interface MyButtonProps {
  sx?: SxProps<Theme>; // optional prop for consumer
}

const MyButton = ({ sx: consumerSx }: MyButtonProps) => (
  <Button sx={mergeSx(internalSx, consumerSx)}>Click me</Button>
);

Inline Theme supplying

The utility is generic and accepts the type argument.

// theme is Theme
mergeSx<Theme>(sx1, (theme) => ({ mb: theme.spacing(1) }));

changelog

Changelog

Version 3

v3.4.0

  • Supporting MUI 7.

v3.3.2

  • Technical update.

v3.3.1

  • Restored missing license in the distributed package.json.

v3.3.0

  • Technical update:
    • Upgraded all dependencies and tested on latest MUI 6;
    • Implemented workspaces to avoid duplicated dependencies for the integration test;
    • Releasing using bun publish.

v3.2.3

v3.2.2

  • JSDoc restored on the distributed declaration files (since 3.0.0).

v3.2.1

  • Technical update:
    • Faster CI with bun lock-file diff control;
    • Reduced dev dependencies;
    • Upgraded dependencies.

v3.2.0

v3.1.0

  • Supporting Material UI v6.

v3.0.1

  • Fixed peer dependency: the minimal @mui/material version set back to 5.1.0.

v3.0.0

  • There are no breaking changes (*), but the distribution build process has changed:
  • (*) — a peer dependency increase was found later and fixed in 3.0.1.

Version 2

v2.0.3

  • Technical release before v3: several chores, no changes.

v2.0.2

  • Replaced any with unknown for internally used type.

v2.0.1

  • Optimization for consumption in browser.

v2.0.0

  • Breaking changes:
    • Targeting ES6,
    • Default export removed,
    • IIFE build removed.
  • The distribution becomes ESM first, while remaining dual (CJS support remains).
    • The right files should be chosen automatically from the dist folder:
      • for ESM: index.js and index.d.ts,
      • for CJS: index.cjs and index.d.cts.
  • Features:
    • Performance improvement: 1.6 times faster.
  • How to migrate:
    • Replace default import with a named one.
// before:
import mergeSx from "merge-sx";
// after:
import { mergeSx } from "merge-sx";

Version 1

v1.4.0

  • Upgraded dependencies.
  • Tested on MUI versions up to 5.15.0.

v1.3.1

  • Fixed issue #205 reported by @mwskwong.
    • The issue was introduced in v1.3.0.
    • Next.js and Webpack used to complain on importing the module with the following error message:

Module not found: Error: Default condition should be last one

v1.3.0

  • Both CJS and ESM bundles have their own declaration files:
    • /dist/index.d.ts for CJS,
    • /dist/index.d.mts for ESM.
    • The exports entry of package.json is adjusted accordingly.

v1.2.0

  • Just a technical update, no new features or fixes.
  • Tested on MUI versions from 5.1.0 to 5.12.0.

v1.1.0

  • Just a technical update, no new features or fixes.
  • Tested on MUI versions from 5.1.0 to 5.11.0.

v1.0.0

  • First stable release according to SemVer.
  • No breaking changes.
  • Tested on MUI versions from 5.1.0 to 5.10.13.

Version 0

v0.1.5

  • Fixing the installation warning introduced in v0.1.1.
  • The required peer dependency changed back from @mui/system@^5.1.0 to @mui/material@^5.1.0.
warning " > merge-sx@0.1.4" has unmet peer dependency "@mui/system@^5.1.0".

v0.1.4

  • Another performance improvement. This time by 878% for 10 arguments.
  • I switched from using reducer to for..of syntax.
┌─────────────┬─────────┬────────┬───────┬───────┐
│ N arguments10100100010000 │
├─────────────┼─────────┼────────┼───────┼───────┤
│ ops/s       │ 6475799718229745897636  │
└─────────────┴─────────┴────────┴───────┴───────┘

v0.1.3

  • The performance has been improved by 24% for 10 arguments.
┌─────────────┬────────┬───────┬──────┬───────┐
│ N arguments10100100010000 │
├─────────────┼────────┼───────┼──────┼───────┤
│ ops/s       │ 60146348255206825   │
└─────────────┴────────┴───────┴──────┴───────┘

v0.1.2

  • No changes to the code. Descriptive works only.

v0.1.1

  • The required peer dependency changed from @mui/material@^5.1.0 to @mui/system@^5.1.0.

v0.1.0

  • The first release of the utility.