Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Box] Add sx prop #23053

Merged
merged 74 commits into from
Oct 22, 2020
Merged
Show file tree
Hide file tree
Changes from 73 commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
c2d31cc
add emotion peer dependencies
mnajdova Sep 25, 2020
5ae933f
fixed types & tests
mnajdova Sep 25, 2020
18b0668
prettier
mnajdova Sep 25, 2020
f0ef95c
Merge branch 'next' of https://github.com/mui-org/material-ui into next
mnajdova Sep 28, 2020
c7bebb8
Merge branch 'next' of https://github.com/mui-org/material-ui into next
mnajdova Sep 28, 2020
92b2d6e
Merge branch 'next' of https://github.com/mui-org/material-ui into next
mnajdova Sep 28, 2020
13da531
Merge branch 'next' of https://github.com/mui-org/material-ui into next
mnajdova Sep 29, 2020
cf5d9a5
Merge branch 'next' of https://github.com/mui-org/material-ui into next
mnajdova Sep 29, 2020
b8d1291
Merge branch 'next' of https://github.com/mui-org/material-ui into next
mnajdova Sep 30, 2020
a9d8690
Merge branch 'next' of https://github.com/mui-org/material-ui into next
mnajdova Oct 2, 2020
74dc451
wip
mnajdova Oct 2, 2020
688d13a
fixed typo
mnajdova Oct 2, 2020
497830a
Merge branch 'next' of https://github.com/mui-org/material-ui into next
mnajdova Oct 5, 2020
d50ea1e
Merge branch 'next' of https://github.com/mui-org/material-ui into next
mnajdova Oct 5, 2020
a1da207
added cross-env
mnajdova Oct 5, 2020
6ff31f9
yarn lock
mnajdova Oct 5, 2020
9fd7f7b
version
mnajdova Oct 5, 2020
e561135
Merge branch 'feat/benchmark-window-fix' into feat/update-box-to-use-…
mnajdova Oct 5, 2020
2a71a6e
fixes
mnajdova Oct 5, 2020
77d6017
prettier
mnajdova Oct 5, 2020
a3beed3
removed cross-env dependency
mnajdova Oct 5, 2020
0b2d503
removed unused theme
mnajdova Oct 5, 2020
eddfa14
reversed style fn
mnajdova Oct 7, 2020
83e0ea2
sx wip
mnajdova Oct 8, 2020
ff2d4c3
Updated box filterProps
mnajdova Oct 8, 2020
f7a74e9
prettier
mnajdova Oct 8, 2020
bc55cdb
Merge remote-tracking branch 'origin/feat/update-box-to-use-emotion' …
mnajdova Oct 14, 2020
72893a9
merge conflicts
mnajdova Oct 14, 2020
d596058
cleanup
mnajdova Oct 14, 2020
94c905d
Update docs/src/pages/components/slider-styled/ContinuousSlider.js
mnajdova Oct 14, 2020
f179fb9
Update docs/src/pages/components/slider-styled/ContinuousSlider.tsx
mnajdova Oct 14, 2020
0373182
updated scenarios to be in the correct benchmark
mnajdova Oct 14, 2020
6021478
cleaned up benchmark scenarios
mnajdova Oct 14, 2020
5a70cf2
Merge branch 'feat/box-sx-prop' of https://github.com/mnajdova/materi…
mnajdova Oct 14, 2020
92847d7
Merge branch 'next' into feat/box-sx-prop
mnajdova Oct 15, 2020
d438191
fixed typings, updated box page
mnajdova Oct 15, 2020
7bab4bd
moved styleFunction to Box
mnajdova Oct 15, 2020
d966402
Update docs/src/pages/components/box/box.md
mnajdova Oct 15, 2020
76c0f7e
Update packages/material-ui-system/src/palette.js
mnajdova Oct 15, 2020
448bc82
Update packages/material-ui/src/Box/Box.js
mnajdova Oct 15, 2020
a7b690d
Update docs/src/pages/components/box/box.md
mnajdova Oct 15, 2020
59461b3
added support for functions for the values
mnajdova Oct 15, 2020
f6faf73
prettier
mnajdova Oct 15, 2020
c53c4bd
fixed sizing filterProps
mnajdova Oct 15, 2020
ed02098
support sx as function
mnajdova Oct 15, 2020
f1ae038
prettier
mnajdova Oct 15, 2020
d2756c7
implemented breakpoints, fixed types, removed theme function callback
mnajdova Oct 19, 2020
0f64e53
added theme-ui benchmark + sx prop benchmark for the box
mnajdova Oct 19, 2020
b32dd5a
fixed custom breakpoints support
mnajdova Oct 19, 2020
79af939
Update docs/src/pages/components/box/box.md
mnajdova Oct 20, 2020
64174a6
added theme-ui div scenario benchmark
mnajdova Oct 20, 2020
70c1d51
Merge branch 'feat/box-sx-prop' of https://github.com/mnajdova/materi…
mnajdova Oct 20, 2020
502733e
improved examples, added chakra-ui box & added results in readme
mnajdova Oct 20, 2020
49641ac
added tests, fixes
mnajdova Oct 20, 2020
15b118b
breakpoints more tests and fixes
mnajdova Oct 20, 2020
b386b29
improved breakpoints checks
mnajdova Oct 20, 2020
e200326
added more examples
mnajdova Oct 20, 2020
e12c35f
Added Box examples
mnajdova Oct 20, 2020
d32da87
temporarly removed dependency
mnajdova Oct 20, 2020
2d4c5c9
Merge branch 'next' into feat/box-sx-prop
mnajdova Oct 20, 2020
80682d1
reverted yarn.lock changes
mnajdova Oct 20, 2020
6533c27
reverted benchmark changes
mnajdova Oct 20, 2020
5df2f8c
Merge branch 'next' into feat/box-sx-prop
mnajdova Oct 20, 2020
3767add
Update benchmark/browser/README.md
mnajdova Oct 20, 2020
dce99bc
reverted some changes
mnajdova Oct 20, 2020
9671da1
Merge branch 'feat/box-sx-prop' of https://github.com/mnajdova/materi…
mnajdova Oct 20, 2020
b0cc366
fixed lint & tests
mnajdova Oct 20, 2020
0b1ecd5
Merge branch 'next' into feat/box-sx-prop
mnajdova Oct 21, 2020
9e3ad18
fixed breakpoints merging
mnajdova Oct 21, 2020
2e557d4
prettier
mnajdova Oct 21, 2020
f00fd05
lint
mnajdova Oct 21, 2020
43b629d
Update benchmark/browser/scenarios/sx-prop-box-material-ui/index.js
mnajdova Oct 21, 2020
0d57b2d
Update benchmark/browser/scripts/benchmark.js
mnajdova Oct 21, 2020
861d4f6
removed render function code snippet in favor of example
mnajdova Oct 21, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions benchmark/browser/scenarios/sx-prop-box-material-ui/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import * as React from 'react';
import Box from '@material-ui/core/Box';

export default function BoxSxPropMaterialUI() {
return (
<React.Fragment>
{new Array(1000).fill().map(() => (
<Box
sx={{
width: 200,
height: 200,
backgroundColor: [undefined, 'primary.light', 'primary.main', 'primary.dark'],
borderWidth: '3px',
borderColor: 'white',
borderStyle: [undefined, 'dashed', 'solid', 'dotted'],
':hover': {
backgroundColor: (theme) => theme.palette.secondary.dark,
},
}}
>
material-ui
</Box>
))}
</React.Fragment>
);
}
1 change: 1 addition & 0 deletions benchmark/browser/scripts/benchmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ async function run() {
await runMeasures(browser, 'Chakra-UI box component', './box-chakra-ui/index.js', 10);
await runMeasures(browser, 'Theme-UI box sx prop', './sx-prop-box-theme-ui/index.js', 10);
await runMeasures(browser, 'Theme-UI div sx prop', './sx-prop-div-theme-ui/index.js', 10);
await runMeasures(browser, 'Material-UI box sx prop', './sx-prop-box-material-ui/index.js', 10);
} finally {
await Promise.all([browser.close(), server.close()]);
}
Expand Down
11 changes: 11 additions & 0 deletions docs/src/pages/components/box/BoxClone.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react';
import Button from '@material-ui/core/Button';
import Box from '@material-ui/core/Box';

export default function BoxClone() {
return (
<Box border="1px dashed grey" clone>
<Button>Save</Button>
</Box>
);
}
11 changes: 11 additions & 0 deletions docs/src/pages/components/box/BoxClone.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react';
import Button from '@material-ui/core/Button';
import Box from '@material-ui/core/Box';

export default function BoxClone() {
return (
<Box border="1px dashed grey" clone>
<Button>Save</Button>
</Box>
);
}
11 changes: 11 additions & 0 deletions docs/src/pages/components/box/BoxComponent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react';
import Box from '@material-ui/core/Box';
import Button from '@material-ui/core/Button';

export default function BoxComponent() {
return (
<Box component="span" p={2} border="1px dashed grey">
<Button>Save</Button>
</Box>
);
}
11 changes: 11 additions & 0 deletions docs/src/pages/components/box/BoxComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react';
import Box from '@material-ui/core/Box';
import Button from '@material-ui/core/Button';

export default function BoxComponent() {
return (
<Box component="span" p={2} border="1px dashed grey">
<Button>Save</Button>
</Box>
);
}
11 changes: 11 additions & 0 deletions docs/src/pages/components/box/BoxRenderProps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react';
import Button from '@material-ui/core/Button';
import Box from '@material-ui/core/Box';

export default function BoxClone() {
return (
<Box border="1px dashed grey">
{(props) => <Button {...props}>Save</Button>}
</Box>
);
}
11 changes: 11 additions & 0 deletions docs/src/pages/components/box/BoxRenderProps.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react';
import Button from '@material-ui/core/Button';
import Box from '@material-ui/core/Box';

export default function BoxClone() {
return (
<Box border="1px dashed grey">
{(props: { className: string }) => <Button {...props}>Save</Button>}
</Box>
);
}
18 changes: 18 additions & 0 deletions docs/src/pages/components/box/BoxSx.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as React from 'react';
import Box from '@material-ui/core/Box';

export default function BoxSx() {
return (
<Box
sx={{
width: 300,
height: 300,
bgcolor: 'primary.dark',
':hover': {
backgroundColor: 'primary.main',
opacity: [0.9, 0.8, 0.7],
},
}}
/>
);
}
18 changes: 18 additions & 0 deletions docs/src/pages/components/box/BoxSx.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as React from 'react';
import Box from '@material-ui/core/Box';

export default function BoxSx() {
return (
<Box
sx={{
width: 300,
height: 300,
bgcolor: 'primary.dark',
':hover': {
backgroundColor: 'primary.main',
opacity: [0.9, 0.8, 0.7],
},
}}
/>
);
}
20 changes: 10 additions & 10 deletions docs/src/pages/components/box/box.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,7 @@ The Box component wraps your component.
It creates a new DOM element, a `<div>` by default that can be changed with the `component` prop.
Let's say you want to use a `<span>` instead:

```jsx
<Box component="span" m={1}>
<Button />
</Box>
```
{{"demo": "pages/components/box/BoxComponent.js", "defaultCodeOpen": true }}

This works great when the changes can be isolated to a new DOM element.
For instance, you can change the margin this way.
Expand All @@ -40,11 +36,7 @@ To workaround the problem, you have two options:

The Box component has a `clone` prop to enable the use of the clone element method of React.

```jsx
<Box color="text.primary" clone>
<Button />
</Box>
```
{{"demo": "pages/components/box/BoxClone.js", "defaultCodeOpen": true }}

2. Use render props

Expand All @@ -54,9 +46,17 @@ The Box children accepts a render props function. You can pull out the `classNam
<Box color="text.primary">{(props) => <Button {...props} />}</Box>
```

{{"demo": "pages/components/box/BoxRenderProps.js", "defaultCodeOpen": true }}

> ⚠️ The CSS specificity relies on the import order.
> If you want the guarantee that the wrapped component's style will be overridden, you need to import the Box last.

## The sx prop

Sometimes, the props on the Box component are not enough to style the component. To solve this, `Box` supports the `sx` prop. This allows you to specify any CSS rules you want, in addition to the ones already available using system props. Here is an example of how you can use it:

{{"demo": "pages/components/box/BoxSx.js", "defaultCodeOpen": true }}

mnajdova marked this conversation as resolved.
Show resolved Hide resolved
## API

```jsx
Expand Down
8 changes: 7 additions & 1 deletion packages/material-ui-system/src/breakpoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,13 @@ export function handleBreakpoints(props, propValue, styleFromPropValue) {
if (typeof propValue === 'object') {
const themeBreakpoints = props.theme.breakpoints || defaultBreakpoints;
return Object.keys(propValue).reduce((acc, breakpoint) => {
acc[themeBreakpoints.up(breakpoint)] = styleFromPropValue(propValue[breakpoint]);
// key is breakpoint
if (Object.keys(themeBreakpoints.values || values).indexOf(breakpoint) !== -1) {
acc[themeBreakpoints.up(breakpoint)] = styleFromPropValue(propValue[breakpoint]);
} else {
const cssKey = breakpoint;
acc[cssKey] = propValue[cssKey];
}
return acc;
}, {});
}
Expand Down
6 changes: 6 additions & 0 deletions packages/material-ui-system/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ export type BordersProps = PropsFor<typeof borders>;
// breakpoints.js
type DefaultBreakPoints = 'xs' | 'sm' | 'md' | 'lg' | 'xl';

export function handleBreakpoints<Props, Breakpoints extends string = DefaultBreakPoints>(
props: Props,
propValue: any,
styleFromPropValue: (value: any) => any
): any;

/**
* @returns An enhanced stylefunction that considers breakpoints
*/
Expand Down
1 change: 1 addition & 0 deletions packages/material-ui-system/src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export { default as borders } from './borders';
export * from './borders';
export { default as breakpoints } from './breakpoints';
export { handleBreakpoints } from './breakpoints';
export { default as compose } from './compose';
export { default as css } from './css';
export { default as display } from './display';
Expand Down
7 changes: 6 additions & 1 deletion packages/material-ui-system/src/palette.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ export const bgcolor = style({
themeKey: 'palette',
});

const palette = compose(color, bgcolor);
export const backgroundColor = style({
prop: 'backgroundColor',
themeKey: 'palette',
});

const palette = compose(color, bgcolor, backgroundColor);

export default palette;
13 changes: 12 additions & 1 deletion packages/material-ui/src/Box/Box.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ import {
typography,
PropsFor,
} from '@material-ui/system';
import { Theme } from '../styles/createMuiTheme';
import { CSSObject } from '../styles/experimentalStyled';
import { Omit } from '..';

type BoxStyleFunction = ComposedStyleFunction<
export type BoxStyleFunction = ComposedStyleFunction<
[
typeof borders,
typeof display,
Expand All @@ -32,14 +34,23 @@ type BoxStyleFunction = ComposedStyleFunction<

type SystemProps = PropsFor<BoxStyleFunction>;
type ElementProps = Omit<React.HTMLAttributes<HTMLElement>, keyof SystemProps>;
type SxPropsValue = Omit<CSSObject, keyof SystemProps> & SystemProps;
type SxProps = {
[Name in keyof SxPropsValue]?:
| SxPropsValue[Name]
| ((theme: Theme) => CSSObject | SxPropsValue[Name])
| SxProps;
};

export interface BoxProps extends ElementProps, SystemProps {
children?: React.ReactNode | ((props: ElementProps) => React.ReactNode);
// styled API
component?: React.ElementType;
clone?: boolean;
ref?: React.Ref<unknown>;
// workaround for https://github.com/mui-org/material-ui/pull/15611
css?: SystemProps;
sx?: SxProps;
}

declare const Box: React.ComponentType<BoxProps>;
Expand Down
32 changes: 2 additions & 30 deletions packages/material-ui/src/Box/Box.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,9 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import {
borders,
compose,
display,
flexbox,
grid,
palette,
positions,
shadows,
sizing,
spacing,
typography,
css,
} from '@material-ui/system';
import clsx from 'clsx';
import styleFunction from './styleFunction';
import styled from '../styles/experimentalStyled';

export const styleFunction = css(
compose(
borders,
display,
flexbox,
grid,
positions,
palette,
shadows,
sizing,
spacing,
typography,
),
);

function omit(input, fields) {
const output = {};

Expand Down Expand Up @@ -71,7 +43,7 @@ const BoxRoot = React.forwardRef(function StyledComponent(props, ref) {
});

BoxRoot.propTypes = {
children: PropTypes.node,
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
Copy link
Member

@oliviertassinari oliviertassinari Oct 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we get this change moved into a different pull request? It solves #22982. I also think that it depends on #18496 (comment).

className: PropTypes.string,
clone: PropTypes.bool,
component: PropTypes.elementType,
Expand Down
2 changes: 2 additions & 0 deletions packages/material-ui/src/Box/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export { default } from './Box';
export * from './Box';
export { default as styleFunction } from './styleFunction';
export * from './styleFunction';
3 changes: 2 additions & 1 deletion packages/material-ui/src/Box/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { default, styleFunction } from './Box';
export { default } from './Box';
export { default as styleFunction } from './styleFunction';
4 changes: 4 additions & 0 deletions packages/material-ui/src/Box/styleFunction.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { BoxStyleFunction } from './Box';

declare const styleFunction: BoxStyleFunction;
export default styleFunction;
Loading