From 13d3f83cd2697da356fe0c86a3c87ea5d6a7ed43 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Tue, 16 Apr 2019 08:40:06 +0200 Subject: [PATCH 1/4] [core] Use implicit children spread (#15354) --- docs/src/pages/demos/pickers/pickers.md | 5 - .../instapaper/components/atoms/Badge.js | 6 +- .../components/molecules/ListItemIcon.js | 6 +- .../pages/premium-themes/onepirate/Privacy.js | 17 ++- .../pages/premium-themes/onepirate/Terms.js | 17 ++- .../onepirate/modules/components/Button.js | 19 +-- .../modules/components/LayoutBody.js | 135 ------------------ .../onepirate/modules/components/Toolbar.js | 7 +- .../onepirate/modules/views/AppFooter.js | 14 +- .../onepirate/modules/views/AppForm.js | 13 +- .../onepirate/modules/views/ProductCTA.js | 6 +- .../modules/views/ProductCategories.js | 6 +- .../onepirate/modules/views/ProductHero.js | 6 +- .../modules/views/ProductHeroLayout.js | 8 +- .../modules/views/ProductHowItWorks.js | 14 +- .../modules/views/ProductSmokingHero.js | 6 +- .../onepirate/modules/views/ProductValues.js | 8 +- .../tweeper/components/atoms/Badge.js | 6 +- .../src/ToggleButton/ToggleButton.js | 2 - packages/material-ui/src/AppBar/AppBar.js | 6 +- .../src/Breadcrumbs/BreadcrumbSeparator.js | 8 +- .../material-ui/src/Container/Container.js | 6 +- .../src/DialogActions/DialogActions.js | 6 +- .../src/DialogContent/DialogContent.js | 6 +- .../ExpansionPanelDetails.js | 8 +- .../material-ui/src/FormGroup/FormGroup.js | 6 +- packages/material-ui/src/Icon/Icon.js | 6 +- .../material-ui/src/InputLabel/InputLabel.js | 5 +- packages/material-ui/src/Link/Link.js | 6 +- .../src/NativeSelect/NativeSelectInput.js | 5 +- .../material-ui/src/TableCell/TableCell.js | 5 +- packages/material-ui/src/Toolbar/Toolbar.js | 7 +- 32 files changed, 95 insertions(+), 286 deletions(-) delete mode 100644 docs/src/pages/premium-themes/onepirate/modules/components/LayoutBody.js diff --git a/docs/src/pages/demos/pickers/pickers.md b/docs/src/pages/demos/pickers/pickers.md index 99365548a8e166..a60b34853df5d6 100644 --- a/docs/src/pages/demos/pickers/pickers.md +++ b/docs/src/pages/demos/pickers/pickers.md @@ -45,8 +45,3 @@ For more advanced use cases you might be able to take advantage of. [material-ui-pickers](https://material-ui-pickers.firebaseapp.com/) provides date and time controls that follow the Material Design spec. {{"demo": "pages/demos/pickers/MaterialUIPickers.js"}} - -### Other - -- [material-ui-time-picker](https://github.com/TeamWertarbyte/material-ui-time-picker): time pickers. -- [material-ui-next-pickers](https://github.com/chingyawhao/material-ui-next-pickers): date pickers and time pickers. diff --git a/docs/src/pages/premium-themes/instapaper/components/atoms/Badge.js b/docs/src/pages/premium-themes/instapaper/components/atoms/Badge.js index 9d876b040d191a..d516a08068f594 100644 --- a/docs/src/pages/premium-themes/instapaper/components/atoms/Badge.js +++ b/docs/src/pages/premium-themes/instapaper/components/atoms/Badge.js @@ -3,10 +3,8 @@ import clsx from 'clsx'; import MuiBadge from '@material-ui/core/Badge'; import { BADGE } from '../../theme/core'; -const Badge = ({ className, dotted, children, ...props }) => ( - - {children} - +const Badge = ({ className, dotted, ...props }) => ( + ); export default Badge; diff --git a/docs/src/pages/premium-themes/instapaper/components/molecules/ListItemIcon.js b/docs/src/pages/premium-themes/instapaper/components/molecules/ListItemIcon.js index 3c0bc3dfeae458..4b2f4fa8d72a13 100644 --- a/docs/src/pages/premium-themes/instapaper/components/molecules/ListItemIcon.js +++ b/docs/src/pages/premium-themes/instapaper/components/molecules/ListItemIcon.js @@ -3,13 +3,11 @@ import clsx from 'clsx'; import MuiListItemIcon from '@material-ui/core/ListItemIcon'; import { LIST_ITEM_ICON } from '../../theme/core'; -const ListItemIcon = ({ className, children, subcategory, ...props }) => ( +const ListItemIcon = ({ className, subcategory, ...props }) => ( - {children} - + /> ); export default ListItemIcon; diff --git a/docs/src/pages/premium-themes/onepirate/Privacy.js b/docs/src/pages/premium-themes/onepirate/Privacy.js index 6daf11cfcf682e..9636759dea6864 100644 --- a/docs/src/pages/premium-themes/onepirate/Privacy.js +++ b/docs/src/pages/premium-themes/onepirate/Privacy.js @@ -1,9 +1,10 @@ import withRoot from './modules/withRoot'; // --- Post bootstrap ----- import React from 'react'; +import Container from '@material-ui/core/Container'; +import Box from '@material-ui/core/Box'; import Markdown from './modules/components/Markdown'; import Typography from './modules/components/Typography'; -import LayoutBody from './modules/components/LayoutBody'; import AppAppBar from './modules/views/AppAppBar'; import privacy from './modules/views/privacy.md'; import AppFooter from './modules/views/AppFooter'; @@ -12,12 +13,14 @@ function Privacy() { return ( - - - Privacy - - {privacy} - + + + + Privacy + + {privacy} + + ); diff --git a/docs/src/pages/premium-themes/onepirate/Terms.js b/docs/src/pages/premium-themes/onepirate/Terms.js index 14aef70d455c02..4792365078220c 100644 --- a/docs/src/pages/premium-themes/onepirate/Terms.js +++ b/docs/src/pages/premium-themes/onepirate/Terms.js @@ -1,9 +1,10 @@ import withRoot from './modules/withRoot'; // --- Post bootstrap ----- import React from 'react'; +import Container from '@material-ui/core/Container'; +import Box from '@material-ui/core/Box'; import Markdown from './modules/components/Markdown'; import Typography from './modules/components/Typography'; -import LayoutBody from './modules/components/LayoutBody'; import AppAppBar from './modules/views/AppAppBar'; import terms from './modules/views/terms.md'; import AppFooter from './modules/views/AppFooter'; @@ -12,12 +13,14 @@ function Terms() { return ( - - - Terms - - {terms} - + + + + Terms + + {terms} + + ); diff --git a/docs/src/pages/premium-themes/onepirate/modules/components/Button.js b/docs/src/pages/premium-themes/onepirate/modules/components/Button.js index 964998f7aa456b..80c6d455c1330f 100644 --- a/docs/src/pages/premium-themes/onepirate/modules/components/Button.js +++ b/docs/src/pages/premium-themes/onepirate/modules/components/Button.js @@ -1,13 +1,12 @@ -import React from 'react'; import { withStyles } from '@material-ui/core/styles'; -import MuiButton from '@material-ui/core/Button'; +import Button from '@material-ui/core/Button'; -const styles = theme => ({ +export default withStyles(theme => ({ root: { borderRadius: 0, fontWeight: theme.typography.fontWeightMedium, fontFamily: theme.typography.fontFamilySecondary, - padding: `${theme.spacing(2) - 1}px ${theme.spacing(4)}px`, + padding: theme.spacing(2, 4), fontSize: theme.typography.pxToRem(14), boxShadow: 'none', '&:active, &:focus': { @@ -15,17 +14,11 @@ const styles = theme => ({ }, }, sizeSmall: { - padding: `${theme.spacing(1)}px ${theme.spacing(3)}px`, + padding: theme.spacing(1, 3), fontSize: theme.typography.pxToRem(13), }, sizeLarge: { - padding: `${theme.spacing(3) - 3}px ${theme.spacing(6)}px`, + padding: theme.spacing(2, 5), fontSize: theme.typography.pxToRem(16), }, -}); - -function Button(props) { - return ; -} - -export default withStyles(styles)(Button); +}))(Button); diff --git a/docs/src/pages/premium-themes/onepirate/modules/components/LayoutBody.js b/docs/src/pages/premium-themes/onepirate/modules/components/LayoutBody.js deleted file mode 100644 index 225d5d10954787..00000000000000 --- a/docs/src/pages/premium-themes/onepirate/modules/components/LayoutBody.js +++ /dev/null @@ -1,135 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import clsx from 'clsx'; -import { withStyles } from '@material-ui/core/styles'; -import { capitalize } from '@material-ui/core/utils/helpers'; - -function round(value) { - return Math.round(value * 1e4) / 1e4; -} - -const styles = theme => ({ - margin: { - margin: theme.spacing(7), - }, - marginBottom: { - marginBottom: theme.spacing(12), - }, - widthSmall: { - width: 'auto', - marginLeft: theme.spacing(3), - marginRight: theme.spacing(3), - [theme.breakpoints.up(660 + theme.spacing(6))]: { - width: 660, - marginLeft: 'auto', - marginRight: 'auto', - }, - }, - widthMedium: { - width: 'auto', - marginLeft: theme.spacing(3), - marginRight: theme.spacing(3), - [theme.breakpoints.up(850 + theme.spacing(6))]: { - width: 850, - marginLeft: 'auto', - marginRight: 'auto', - }, - }, - widthLarge: { - width: 'auto', - marginLeft: theme.spacing(3), - marginRight: theme.spacing(3), - [theme.breakpoints.up('md')]: { - width: 880, - marginLeft: 'auto', - marginRight: 'auto', - }, - [theme.breakpoints.up(round(880 / 0.7777))]: { - width: '77.7777%', - }, - [theme.breakpoints.up(round(1400 / 0.7777))]: { - width: 1400, - }, - }, - widthXlarge: { - width: 'auto', - marginLeft: theme.spacing(3), - marginRight: theme.spacing(3), - [theme.breakpoints.up('md')]: { - width: 900, - marginLeft: 'auto', - marginRight: 'auto', - }, - [theme.breakpoints.up(round(900 / 0.9))]: { - width: '90%', - }, - [theme.breakpoints.up(round(1800 / 0.9))]: { - width: 1800, - }, - }, - widthFull: { - width: '100%', - }, - fullHeight: { - height: '100%', - }, -}); - -function LayoutBody(props) { - const { - children, - classes, - className, - component: Component, - fullHeight, - fullWidth, - margin, - marginBottom, - style, - width, - ...other - } = props; - - return ( - - {children} - - ); -} - -LayoutBody.propTypes = { - children: PropTypes.node, - classes: PropTypes.object.isRequired, - className: PropTypes.string, - component: PropTypes.elementType, - fullHeight: PropTypes.bool, - fullWidth: PropTypes.bool, - margin: PropTypes.bool, - marginBottom: PropTypes.bool, - style: PropTypes.object, - width: PropTypes.oneOf(['small', 'medium', 'large', 'xlarge', 'full']), -}; - -LayoutBody.defaultProps = { - component: 'div', - fullHeight: false, - fullWidth: false, - margin: false, - marginBottom: false, - width: 'medium', -}; - -export default withStyles(styles)(LayoutBody); diff --git a/docs/src/pages/premium-themes/onepirate/modules/components/Toolbar.js b/docs/src/pages/premium-themes/onepirate/modules/components/Toolbar.js index 80cca0a2206ce9..0a3f6e7d88fa0d 100644 --- a/docs/src/pages/premium-themes/onepirate/modules/components/Toolbar.js +++ b/docs/src/pages/premium-themes/onepirate/modules/components/Toolbar.js @@ -1,6 +1,5 @@ -import React from 'react'; import { withStyles } from '@material-ui/core/styles'; -import MuiToolbar from '@material-ui/core/Toolbar'; +import Toolbar from '@material-ui/core/Toolbar'; export const styles = theme => ({ root: { @@ -11,8 +10,4 @@ export const styles = theme => ({ }, }); -function Toolbar(props) { - return ; -} - export default withStyles(styles)(Toolbar); diff --git a/docs/src/pages/premium-themes/onepirate/modules/views/AppFooter.js b/docs/src/pages/premium-themes/onepirate/modules/views/AppFooter.js index 382a6541aa25a7..3fa3dda1d9683a 100644 --- a/docs/src/pages/premium-themes/onepirate/modules/views/AppFooter.js +++ b/docs/src/pages/premium-themes/onepirate/modules/views/AppFooter.js @@ -3,9 +3,9 @@ import PropTypes from 'prop-types'; import { withStyles } from '@material-ui/core/styles'; import Grid from '@material-ui/core/Grid'; import Link from '@material-ui/core/Link'; +import Container from '@material-ui/core/Container'; import Typography from '../components/Typography'; import TextField from '../components/TextField'; -import LayoutBody from '../components/LayoutBody'; import compose from 'docs/src/modules/utils/compose'; const styles = theme => ({ @@ -13,7 +13,7 @@ const styles = theme => ({ display: 'flex', backgroundColor: theme.palette.secondary.light, }, - layoutBody: { + container: { marginTop: theme.spacing(8), marginBottom: theme.spacing(8), display: 'flex', @@ -67,9 +67,9 @@ function AppFooter(props) { return ( - + - + {'Icons made by '} - + Freepik {' from '} - + www.flaticon.com {' is licensed by '} @@ -141,7 +141,7 @@ function AppFooter(props) { - + ); } diff --git a/docs/src/pages/premium-themes/onepirate/modules/views/AppForm.js b/docs/src/pages/premium-themes/onepirate/modules/views/AppForm.js index 0214f72368ed07..89a2aa8ca3c7bf 100644 --- a/docs/src/pages/premium-themes/onepirate/modules/views/AppForm.js +++ b/docs/src/pages/premium-themes/onepirate/modules/views/AppForm.js @@ -1,7 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; +import Container from '@material-ui/core/Container'; +import Box from '@material-ui/core/Box'; import { withStyles } from '@material-ui/core/styles'; -import LayoutBody from '../components/LayoutBody'; import Paper from '../components/Paper'; const styles = theme => ({ @@ -13,7 +14,7 @@ const styles = theme => ({ paper: { padding: theme.spacing(4, 3), [theme.breakpoints.up('md')]: { - padding: theme.spacing(10, 8), + padding: theme.spacing(8, 6), }, }, }); @@ -23,9 +24,11 @@ function AppForm(props) { return (
- - {children} - + + + {children} + +
); } diff --git a/docs/src/pages/premium-themes/onepirate/modules/views/ProductCTA.js b/docs/src/pages/premium-themes/onepirate/modules/views/ProductCTA.js index 383cc0c1d19bb6..6d5e5e82b4a1ae 100644 --- a/docs/src/pages/premium-themes/onepirate/modules/views/ProductCTA.js +++ b/docs/src/pages/premium-themes/onepirate/modules/views/ProductCTA.js @@ -3,10 +3,10 @@ import PropTypes from 'prop-types'; import { withStyles } from '@material-ui/core/styles'; import Grid from '@material-ui/core/Grid'; import Hidden from '@material-ui/core/Hidden'; +import Container from '@material-ui/core/Container'; import Typography from '../components/Typography'; import TextField from '../components/TextField'; import Snackbar from '../components/Snackbar'; -import LayoutBody from '../components/LayoutBody'; import Button from '../components/Button'; const styles = theme => ({ @@ -80,7 +80,7 @@ class ProductCTA extends React.Component { const { classes } = this.props; return ( - +
@@ -119,7 +119,7 @@ class ProductCTA extends React.Component { onClose={this.handleClose} message="We will send you our best offers, once a week." /> - + ); } } diff --git a/docs/src/pages/premium-themes/onepirate/modules/views/ProductCategories.js b/docs/src/pages/premium-themes/onepirate/modules/views/ProductCategories.js index 800acc3482eadd..982dd9f3a6736e 100644 --- a/docs/src/pages/premium-themes/onepirate/modules/views/ProductCategories.js +++ b/docs/src/pages/premium-themes/onepirate/modules/views/ProductCategories.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { withStyles } from '@material-ui/core/styles'; import ButtonBase from '@material-ui/core/ButtonBase'; -import LayoutBody from '../components/LayoutBody'; +import Container from '@material-ui/core/Container'; import Typography from '../components/Typography'; const styles = theme => ({ @@ -144,7 +144,7 @@ function ProductCategories(props) { ]; return ( - + For all tastes and all desires @@ -178,7 +178,7 @@ function ProductCategories(props) { ))}
-
+ ); } diff --git a/docs/src/pages/premium-themes/onepirate/modules/views/ProductHero.js b/docs/src/pages/premium-themes/onepirate/modules/views/ProductHero.js index 31fa213d5ad44f..1ad47fdb169316 100644 --- a/docs/src/pages/premium-themes/onepirate/modules/views/ProductHero.js +++ b/docs/src/pages/premium-themes/onepirate/modules/views/ProductHero.js @@ -1,7 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import { withStyles } from '@material-ui/core/styles'; -import Link from '@material-ui/core/Link'; import Button from '../components/Button'; import Typography from '../components/Typography'; import ProductHeroLayout from './ProductHeroLayout'; @@ -48,9 +47,8 @@ function ProductHero(props) { variant="contained" size="large" className={classes.button} - component={linkProps => ( - - )} + component="a" + href="/premium-themes/onepirate/sign-up" > Register diff --git a/docs/src/pages/premium-themes/onepirate/modules/views/ProductHeroLayout.js b/docs/src/pages/premium-themes/onepirate/modules/views/ProductHeroLayout.js index 7a5a45a773440b..961e797c42eccc 100644 --- a/docs/src/pages/premium-themes/onepirate/modules/views/ProductHeroLayout.js +++ b/docs/src/pages/premium-themes/onepirate/modules/views/ProductHeroLayout.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; import { withStyles } from '@material-ui/core/styles'; -import LayoutBody from '../components/LayoutBody'; +import Container from '@material-ui/core/Container'; const styles = theme => ({ root: { @@ -16,7 +16,7 @@ const styles = theme => ({ maxHeight: 1300, }, }, - layoutBody: { + container: { marginTop: theme.spacing(3), marginBottom: theme.spacing(14), display: 'flex', @@ -54,7 +54,7 @@ function ProductHeroLayout(props) { return (
- + wonder - +
); } diff --git a/docs/src/pages/premium-themes/onepirate/modules/views/ProductHowItWorks.js b/docs/src/pages/premium-themes/onepirate/modules/views/ProductHowItWorks.js index d2c22858206be4..a7339cd987eb3d 100644 --- a/docs/src/pages/premium-themes/onepirate/modules/views/ProductHowItWorks.js +++ b/docs/src/pages/premium-themes/onepirate/modules/views/ProductHowItWorks.js @@ -2,8 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { withStyles } from '@material-ui/core/styles'; import Grid from '@material-ui/core/Grid'; -import Link from '@material-ui/core/Link'; -import LayoutBody from '../components/LayoutBody'; +import Container from '@material-ui/core/Container'; import Button from '../components/Button'; import Typography from '../components/Typography'; @@ -13,7 +12,7 @@ const styles = theme => ({ backgroundColor: theme.palette.secondary.light, overflow: 'hidden', }, - layoutBody: { + container: { marginTop: theme.spacing(10), marginBottom: theme.spacing(15), position: 'relative', @@ -57,7 +56,7 @@ function ProductHowItWorks(props) { return (
- + ( - - )} + component="a" + href="/premium-themes/onepirate/sign-up" > Get started - +
); } diff --git a/docs/src/pages/premium-themes/onepirate/modules/views/ProductSmokingHero.js b/docs/src/pages/premium-themes/onepirate/modules/views/ProductSmokingHero.js index a3e55524598f6e..9202afd3d7947a 100644 --- a/docs/src/pages/premium-themes/onepirate/modules/views/ProductSmokingHero.js +++ b/docs/src/pages/premium-themes/onepirate/modules/views/ProductSmokingHero.js @@ -1,8 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import Button from '@material-ui/core/Button'; +import Container from '@material-ui/core/Container'; import { withStyles } from '@material-ui/core/styles'; -import LayoutBody from '../components/LayoutBody'; import Typography from '../components/Typography'; const styles = theme => ({ @@ -32,7 +32,7 @@ function ProductSmokingHero(props) { const { classes } = props; return ( - + + + + + + ); +} + +export default RealWorld; diff --git a/docs/src/pages/system/basics/StyledComponents.tsx b/docs/src/pages/system/basics/StyledComponents.tsx new file mode 100644 index 00000000000000..72d814733d2e7e --- /dev/null +++ b/docs/src/pages/system/basics/StyledComponents.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import styled from 'styled-components'; +import { palette, PaletteProps, spacing, SpacingProps } from '@material-ui/system'; +import NoSsr from '@material-ui/core/NoSsr'; + +const Box = styled.div` + ${palette} + ${spacing} +`; + +function StyledComponents() { + return ( + + + Styled components + + + ); +} + +export default StyledComponents; diff --git a/docs/src/pages/system/basics/Variant.tsx b/docs/src/pages/system/basics/Variant.tsx new file mode 100644 index 00000000000000..a1be2abc8cde04 --- /dev/null +++ b/docs/src/pages/system/basics/Variant.tsx @@ -0,0 +1,53 @@ +import React from 'react'; +import styled, { ThemeProvider } from 'styled-components'; +import NoSsr from '@material-ui/core/NoSsr'; +import { PropsFor, style, typography, TypographyProps } from '@material-ui/system'; + +const variant = style({ + prop: 'variant', + cssProperty: false, + themeKey: 'typography', +}); + +// ⚠ Text is already defined in the global context: +// https://developer.mozilla.org/en-US/docs/Web/API/Text/Text. +const Text = styled.span & TypographyProps>` + font-family: Helvetica; + ${variant} + ${typography} +`; + +const theme = { + typography: { + h1: { + fontSize: 30, + lineHeight: 1.5, + }, + h2: { + fontSize: 25, + lineHeight: 1.5, + }, + }, +}; + +function Variant() { + return ( + + +
+ + variant=h1 + + + fontWeight=300 + + + variant=h2 + +
+
+
+ ); +} + +export default Variant; diff --git a/packages/material-ui-system/src/index.d.ts b/packages/material-ui-system/src/index.d.ts new file mode 100644 index 00000000000000..53e599b9a73890 --- /dev/null +++ b/packages/material-ui-system/src/index.d.ts @@ -0,0 +1,151 @@ +import { CSSProperties } from '@material-ui/styles'; +import * as CSS from 'csstype'; + +type ThemeOf = Props extends WithTheme ? Theme : never; +type WithThemeOfProps = WithTheme>; +interface WithTheme { + theme?: Theme; +} +export type PropsFor = SomeStyleFunction extends StyleFunction + ? Props + : never; +type StyleFunction = (props: Props) => any; +type SimpleStyleFunction = StyleFunction>>; + +// borders.js +export const border: SimpleStyleFunction<'border'>; +export const borderTop: SimpleStyleFunction<'borderTop'>; +export const borderRight: SimpleStyleFunction<'borderRight'>; +export const borderBottom: SimpleStyleFunction<'borderBottom'>; +export const borderLeft: SimpleStyleFunction<'borderLeft'>; +export const borderColor: SimpleStyleFunction<'borderColor'>; +export const borderRadius: SimpleStyleFunction<'borderRadius'>; +export const borders: SimpleStyleFunction< + | 'border' + | 'borderTop' + | 'borderRight' + | 'borderBottom' + | 'borderLeft' + | 'borderColor' + | 'borderRadius' +>; +export type BordersProps = PropsFor; + +// breakpoints.js +/** + * + * @param styleFunction + * @returns An enhanced stylefunction that considers breakpoints + */ +export function breakpoints( + styleFunction: StyleFunction, +): StyleFunction; + +// compose.js +/** + * given a list of StyleFunction return the intersection of the props each individual + * StyleFunction requires. + * + * If `firstFn` requires { color: string } and `secondFn` requires { spacing: number } + * their composed function requires { color: string, spacing: number } + */ +type ComposedArg = T extends ((arg: infer P) => any)[] ? P : never; +type ComposedStyleProps = ComposedArg; +type Composed[]> = StyleFunction>; +export function compose[]>(...args: T): Composed; + +// css.js +export function css( + styleFunction: StyleFunction, +): StyleFunction }>; + +// default display.js TODO + +// * flexbox.js TODO + +// palette.js +export const color: SimpleStyleFunction<'color'>; +export const bgcolor: SimpleStyleFunction<'bgcolor'>; +export const palette: SimpleStyleFunction<'bgcolor' | 'color'>; +export type PaletteProps = PropsFor; + +// * positions.js TODO + +// default shadows.js TODO + +// * sizing.js TODO +export const width: SimpleStyleFunction<'width'>; +export const maxWidth: SimpleStyleFunction<'maxWidth'>; +export const minWidth: SimpleStyleFunction<'minWidth'>; +export const height: SimpleStyleFunction<'height'>; +export const maxHeight: SimpleStyleFunction<'maxHeight'>; +export const minHeight: SimpleStyleFunction<'minHeight'>; +export const sizeWidth: SimpleStyleFunction<'sizeWidth'>; +export const sizeHeight: SimpleStyleFunction<'sizeHeight'>; +export const sizing: SimpleStyleFunction< + | 'width' + | 'maxWidth' + | 'minWidth' + | 'height' + | 'maxHeight' + | 'minHeight' + | 'sizeWidth' + | 'sizeHeight' +>; +export type SizingProps = PropsFor; + +// spacing.js +export const spacing: SimpleStyleFunction< + | 'm' + | 'mt' + | 'mr' + | 'mb' + | 'ml' + | 'mx' + | 'my' + | 'p' + | 'pt' + | 'pr' + | 'pb' + | 'pl' + | 'px' + | 'py' + | 'margin' + | 'marginLeft' + | 'marginTop' + | 'marginRight' + | 'marginBottom' + | 'padding' + | 'paddingTop' + | 'paddingRight' + | 'paddingBottom' + | 'paddingLeft' +>; +export type SpacingProps = PropsFor; + +// style.js +export interface StyleOptions { + cssProperty?: PropKey | keyof CSS.Properties | false; + prop: PropKey; + /** + * dot access in `Theme` + */ + themeKey?: string; + transform?: (cssValue: unknown) => number | string; +} +export function style( + options: StyleOptions, +): StyleFunction<{ [K in PropKey]: unknown } & { theme: Theme }>; + +// typography.js +export const fontFamily: SimpleStyleFunction<'fontFamily'>; +export const fontSize: SimpleStyleFunction<'fontSize'>; +export const fontWeight: SimpleStyleFunction<'fontWeight'>; +export const textAlign: SimpleStyleFunction<'textAlign'>; +export const typography: SimpleStyleFunction< + 'fontFamily' | 'fontSize' | 'fontWeight' | 'textAlign' +>; +export type TypographyProps = PropsFor; + +// utils +type Omit = Pick>; diff --git a/packages/material-ui-system/src/index.spec.tsx b/packages/material-ui-system/src/index.spec.tsx new file mode 100644 index 00000000000000..e339eb2e041de7 --- /dev/null +++ b/packages/material-ui-system/src/index.spec.tsx @@ -0,0 +1,49 @@ +import { compose, css, palette, StyleFunction, spacing } from '@material-ui/system'; +import * as React from 'react'; +import styled from 'styled-components'; + +function composeTest() { + function first(props: { color: string }) { + return {}; + } + + function second(props: { spacing: number }) { + return {}; + } + + const styler = compose( + first, + second, + ); + // missing `spacing` + styler({ color: 'test' }); // $ExpectError + // missing `color` + styler({ spacing: 1 }); // $ExpectError + styler({ color: 'test', spacing: 1 }); +} + +function cssTest() { + function styleFunction(props: { color: string; spacing: number; theme: object }) { + return {}; + } + + const wideOrNarrowStyleFunction = css(styleFunction); + + // narrow + wideOrNarrowStyleFunction({ theme: {}, css: { color: 'blue', spacing: 2 } }); + // wide + wideOrNarrowStyleFunction({ theme: {}, color: 'blue', spacing: 2 }); + // wide and narrow + wideOrNarrowStyleFunction({ theme: {}, css: { color: 'blue', spacing: 2 }, color: 'red' }); +} + +/** + * Testing inference of TypeScript + styled-components + @material-ui/system + */ +function interopTest() { + // built-in style function + const SystemSpacingBox = styled.div` + ${spacing} + `; + ; +} diff --git a/tsconfig.json b/tsconfig.json index f41a2242d468ed..cfbb20264951a1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,7 +16,8 @@ "@material-ui/core": ["./material-ui/src"], "@material-ui/core/*": ["./material-ui/src/*"], "@material-ui/lab": ["./material-ui-lab/src"], - "@material-ui/lab/*": ["./material-ui-lab/src/*"] + "@material-ui/lab/*": ["./material-ui-lab/src/*"], + "@material-ui/system": ["./material-ui-system/src"] } }, "exclude": ["**/build/"] From 4e4a2ed2e6aee48f8356442d20da3ede20132836 Mon Sep 17 00:00:00 2001 From: Sebastian Silbermann Date: Tue, 16 Apr 2019 15:23:54 +0200 Subject: [PATCH 4/4] [docs] Expand demo by default instead of duplicating the code (#15364) --- docs/src/modules/components/Demo.js | 2 +- docs/src/pages/system/basics/basics.md | 105 ++----------------------- 2 files changed, 7 insertions(+), 100 deletions(-) diff --git a/docs/src/modules/components/Demo.js b/docs/src/modules/components/Demo.js index bbb008f9a88752..af19e721343208 100644 --- a/docs/src/modules/components/Demo.js +++ b/docs/src/modules/components/Demo.js @@ -99,7 +99,7 @@ const styles = theme => ({ class Demo extends React.Component { state = { anchorEl: null, - codeOpen: false, + codeOpen: Boolean(this.props.demoOptions.defaultCodeOpen), demoHovered: false, sourceHintSeen: false, }; diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index 45aba3e0950f19..8c566a6dc50311 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -21,25 +21,7 @@ It's important to understand that this package exposes pure (side-effect free) s In the rest of this *Getting Started* section we are using **styled-components** as the reference example (to emphasize the universality of this package). Alternatively, you can [use JSS](#interoperability). The demos are also based on the **default** Material-UI [theme object](/customization/default-theme/). -```jsx -import { palette, spacing, typography } from '@material-ui/system'; -import styled from 'styled-components'; - -const Box = styled.div`${palette}${spacing}${typography}`; -// or import Box from '@material-ui/core/Box'; - - - @material-ui/system - -``` - -{{"demo": "pages/system/basics/Demo.js"}} +{{"demo": "pages/system/basics/Demo.js", "defaultCodeOpen": true}} ### Installation @@ -142,36 +124,15 @@ If you are already using `@material-ui/core`, we encourage you to start with the ### JSS -```jsx -import { palette, spacing, compose } from '@material-ui/system'; -import { styled } from '@material-ui/styles'; - -const Box = styled(compose(spacing, palette)); -``` - -{{"demo": "pages/system/basics/JSS.js"}} +{{"demo": "pages/system/basics/JSS.js", "defaultCodeOpen": true}} ### Styled components -```jsx -import { palette, spacing } from '@material-ui/system'; -import styled from 'styled-components'; - -const Box = styled.div`${palette}${spacing}`; -``` - -{{"demo": "pages/system/basics/StyledComponents.js"}} +{{"demo": "pages/system/basics/StyledComponents.js", "defaultCodeOpen": true}} ### Emotion -```jsx -import { spacing, palette } from '@material-ui/system'; -import styled from '@emotion/styled'; - -const Box = styled.div`${palette}${spacing}`; -``` - -{{"demo": "pages/system/basics/Emotion.js"}} +{{"demo": "pages/system/basics/Emotion.js", "defaultCodeOpen": true}} ## Responsive @@ -335,68 +296,14 @@ const palette = compose(textColor, bgcolor); The `style()` helper can also be used to maps properties to style objects in a theme. In this example, the `variant` property supports all the keys present in `theme.typography`. -```jsx -import React from 'react'; -import styled, { ThemeProvider } from 'styled-components'; -import { style, typography } from '@material-ui/system'; - -const variant = style({ - prop: 'variant', - cssProperty: false, - themeKey: 'typography', -}); - -// ⚠ Text is already defined in the global context: -// https://developer.mozilla.org/en-US/docs/Web/API/Text/Text. -const Text = styled.span` - font-family: Helvetica; - ${variant} - ${typography} -`; - -const theme = { - typography: { - h1: { - fontSize: 30, - lineHeight: 1.5, - }, - h2: { - fontSize: 25, - lineHeight: 1.5, - }, - }, -}; - -// Renders the theme.typography.h1 style object. -variant=h1 -``` - -{{"demo": "pages/system/basics/Variant.js"}} +{{"demo": "pages/system/basics/Variant.js", "defaultCodeOpen": true}} ## CSS property If you want to support custom CSS values, you can use our `css()` helper. It will process the `css` property. -```jsx -import { compose, spacing, palette, css } from '@material-ui/system'; -import styled from 'styled-components'; - -const Box = styled.div` - ${css( - compose( - spacing, - palette, - ), - )} -`; - - - CssProp - -``` - -{{"demo": "pages/system/basics/CssProp.js"}} +{{"demo": "pages/system/basics/CssProp.js", "defaultCodeOpen": true}} ## How it works