Skip to content

Commit

Permalink
moving readme with symlink.
Browse files Browse the repository at this point in the history
  • Loading branch information
RobinTail committed Nov 28, 2024
1 parent eb60249 commit f0b80a4
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 91 deletions.
91 changes: 0 additions & 91 deletions README.md

This file was deleted.

1 change: 1 addition & 0 deletions README.md
91 changes: 91 additions & 0 deletions packages/merge-sx/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# merge-sx

[![Coverage Status](https://coveralls.io/repos/github/RobinTail/merge-sx/badge.svg?branch=master)](https://coveralls.io/github/RobinTail/merge-sx?branch=master)
![NPM Downloads](https://img.shields.io/npm/dw/merge-sx)
![NPM License](https://img.shields.io/npm/l/merge-sx)

Combines multiple [`SxProps`](https://mui.com/system/getting-started/the-sx-prop)
for [Material UI](https://mui.com/) components.

## Installation

```shell
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.

```ts
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

<abbr title="Material UI">MUI</abbr> 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](https://mui.com/system/styled/). 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](https://github.com/mui/material-ui/releases/tag/v5.1.0) of MUI `SxProps`
[can](https://github.com/mui/material-ui/blob/v5.1.0/packages/mui-system/src/styleFunctionSx/styleFunctionSx.d.ts#L60)
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](https://raw.githubusercontent.com/RobinTail/merge-sx/refs/heads/master/performance.svg)

## Examples

### Conditional merging

The utility supports `false`:

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

### Optional merging

The utility supports `undefined`:

```tsx
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.

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

0 comments on commit f0b80a4

Please sign in to comment.