diff --git a/docs/src/pages.js b/docs/src/pages.js index 663088aa77f74d..80a67433f2e55a 100644 --- a/docs/src/pages.js +++ b/docs/src/pages.js @@ -164,14 +164,7 @@ const pages = [ ), }, { - pathname: '/styles', - children: [ - { pathname: '/styles/basics' }, - { pathname: '/styles/advanced' }, - { pathname: '/styles/api', title: 'API' }, - ], - }, - { + title: 'Style system', pathname: '/system', children: [ { pathname: '/system/basics' }, @@ -188,6 +181,14 @@ const pages = [ { pathname: '/system/properties' }, ], }, + { + pathname: '/styles', + children: [ + { pathname: '/styles/basics' }, + { pathname: '/styles/advanced' }, + { pathname: '/styles/api', title: 'API' }, + ], + }, { pathname: '/customization', children: [ diff --git a/docs/src/pages/system/basics/Demo.js b/docs/src/pages/system/basics/Demo.js index b8bbbdfca70e8a..ccbb40abb99884 100644 --- a/docs/src/pages/system/basics/Demo.js +++ b/docs/src/pages/system/basics/Demo.js @@ -32,7 +32,7 @@ export default function Demo() { }} > - 123 Main St, Pheonix AZ + 123 Main St, Phoenix AZ $280,000 — $310,000 diff --git a/docs/src/pages/system/basics/Demo.tsx b/docs/src/pages/system/basics/Demo.tsx index 887a28a16ea980..61f44c53086e68 100644 --- a/docs/src/pages/system/basics/Demo.tsx +++ b/docs/src/pages/system/basics/Demo.tsx @@ -32,7 +32,7 @@ export default function Demo() { }} > - 123 Main St, Pheonix AZ + 123 Main St, Phoenix AZ $280,000 — $310,000 diff --git a/docs/src/pages/system/basics/basics.md b/docs/src/pages/system/basics/basics.md index d34e3e6bf747b7..3ad3616726f60c 100644 --- a/docs/src/pages/system/basics/basics.md +++ b/docs/src/pages/system/basics/basics.md @@ -1,87 +1,36 @@ -# Material-UI System +# Material-UI style system

Utility-first style functions for rapidly building custom design systems.

-The system lets you quickly build custom UI components leveraging the design tokens defined in your theme. +The style system lets you quickly build custom UI components leveraging the design tokens defined in your theme. ## Demo {{"demo": "pages/system/basics/Demo.js", "bg": true, "defaultCodeOpen": true}} -## Why +## Why use the style system -There are several reasons why you may need the system offered by Material-UI. Here are few of them: +There are several reasons why you may want to use the style system. Here are few: -### 1. Building consistent UIs is hard +### 1. Simplfy building consistent UIs -This is especially true when there is more than one person building the application. There has to be some synchronization as to what the design tokens are and how they are used, what parts of the theme structure should be used with what CSS properties, etc. +Building consistent UIs is hard. This is especially true when more than one person is building the application, as there has to be some coordination amongst members of the team regardingchoice of design tokens and how they are used, what parts of the theme structure should be used with what CSS properties, and so on. -### 2. Switching context +### 2. Reduce context switching -Often we find ourselves jumping from the JS to CSS, or from a component definition to an instance in order to understand where and how some styles are defined. This is particularly true as the complexity (LOCs/# of elements) of the component we are working on increases. We could save a lot of time by removing this constraint. +We often find ourselves jumping from JS to CSS, or from a component definition to an instance in order to understand where and how some styles are defined. This is particularly true as the complexity (LOCs/# of elements) of the component we are working on increases. We could save a lot of time by removing this overhead. -```diff -import * as React from 'react'; --import styled from 'styled-components'; -+import Box from '@material-ui/core/Box'; - --const Card = styled('div)({ -- width: '200px', -- height: '200px', -- boxShadow: theme => theme.shadows[3], --}); -- --const Header = styled('h4')({ -- color: 'grey', --}); -- --const Content = styled('p')({ -- fontSize: '14px;, -- marginTop: '10px', --}); - -export default function Demo() { -- return ( -+ return ( theme.shadows[3], -+ }} -+ > --
-+ - 123 Main St, Pheonix AZ --
-+
-- -+ - $280,000 — $310,000 -- -+
-- ); -+
); -} -``` - -### 3. Less code to type - -Usually when defining styles for a React component we need to either define a separate stylesheet, use some kind of factory for creating the component (`styled()`), or use some kind of hook for generating the styles (for example `makeStyles()` & `useStyles()`), which not only means we need to switch context from where we are currently in the code, but we need to also type much more code than the actual styles we want to have on some element. - -## How do we solve this? +### 3. Type less code -In order to solve these issues, we need to have a simple way of pulling & wiring the correct design tokens for specific CSS properties, and adding them directly on the React element where we want the styles to be applied with a prop that is easily discoverable. +Usually when defining styles for a React component we need to either define a separate stylesheet, use a factory for creating the component (e.g. `styled()`), or use a hook for generating the styles (e.g. `makeStyles()` & `useStyles()`). This not only means we need to switch to another part of the code, but we also need much more code than just the styles we want to have on some element. -The `sx` prop, as part of the system, solves these problems. The example above shows how it can be used in MUI components. +## The `sx` prop -The prop provides a superset of CSS that maps values directly from the theme, depending on the CSS property used. In addition, it allows a simple way of defining responsive values that correspond to the breakpoints defined in the theme. +The `sx` prop, as part of the style system, solves these problems by providing a simple way of applying the correct design tokens for specific CSS properties directly to a React element. The [demo above](#demo) shows how it can be used in Material-UI components. -With it you can build easily your custom visual components, like `Card`, `Badge`, `Chip` that could accept the props & behave exactlly as your design system specifies. +This prop provides a superset of CSS that maps values directly from the theme, depending on the CSS property used. In addition, it allows a simple way of defining responsive values that correspond to the breakpoints defined in the theme. -In the following sections we will dive deeper into the features of the `sx` prop. +With it you can easily build your custom visual components, such as `Card`, `Badge`, `Chip`, exactly as your design system specifies. In the sections following this one, we will dive deeper into the features of the `sx` prop. ## Installation @@ -93,27 +42,15 @@ npm install @material-ui/system yarn add @material-ui/system ``` -## The `sx` prop - -We mentioned that you can use the `sx` prop on all MUI components. In addition to this, you may add the prop on your custom components too by using the `experimentalStyled` utility from `@material-ui/core/styles`. - -```jsx -import { experimentalStyled as styled } from '@material-ui/core/styles'; - -const Div = styled('div')``; -``` - -Note: - -You should use this prop whenever you need to add a style override to a Material-UI component. If you repeatedly apply the same styles to a component, then `styled()` is better alternative, as it allows you to specify the overrides only once, and reuse them in all component instances. +## Usage ### Design tokens in the theme You can explore the [System properties](/system/properties/) page to discover how the different CSS (and custom) properties are mapped to the theme keys. -### Many shorthands +### Shorthands -There are lots of shorthands on the CSS properties. Here are few examples: +There are lots of shorthands available for the CSS properties. Here are few examples: ```jsx ``` +These are documented in the following sections. + ### Superset of CSS -As the property is a superset of CSS, you can use child or pseudo selectors, media queries, raw CSS values etc. Here are few examples: +As the prop supports a superset of CSS, you can use child or pseudo selectors, media queries, raw CSS values etc. Here are few examples: ```jsx // Using pseudo selectors @@ -163,39 +102,23 @@ As the property is a superset of CSS, you can use child or pseudo selectors, med > ``` -## Usage - -It can be used from 3 different sources: - -### Box - -The `Box` component is a light component that gives you access to this functionality. - -### Babel plugin - -TODO: For #23220 - -### Core components - -All core Material-UI components will support the `sx` prop. - -## Responsive values +### Responsive values If you would like to have responsive values for a CSS property, you can use the breakpoints shorthand syntax. There are two ways of defining the breakpoints: -### 1. Breakpoints as an array +#### 1. Breakpoints as an array The first option is to define your breakpoints as an array, from the smallest to the largest breakpoint. {{"demo": "pages/system/basics/BreakpointsAsArray.js"}} -### 2. Breakpoints as an object +#### 2. Breakpoints as an object The second option for defining breakpoints is to define them as an object, using the breakpoints as keys. Here is the previous example again, using the object syntax. {{"demo": "pages/system/basics/BreakpointsAsObject.js"}} -## Custom breakpoints +### Custom breakpoints You can also specify your own custom breakpoints, and use them as keys when defining the breakpoints object. Here is an example of how to do that. @@ -233,7 +156,7 @@ export default function CustomBreakpoints() { } ``` -If you are using TypeScript, you would also need to use [module augmentation](/guides/typescript/#customization-of-theme) for the theme to accept the above values. +If you are using TypeScript, you will also need to use [module augmentation](/guides/typescript/#customization-of-theme) for the theme to accept the above values. ```ts declare module '@material-ui/core/styles/createBreakpoints' { @@ -250,23 +173,37 @@ declare module '@material-ui/core/styles/createBreakpoints' { } ``` -## Theme getter +### Theme getter -If you wish to use the theme for a CSS property that is not supported natively by the system, you can use a function as the value, in which you can access the theme object. +If you wish to use the theme for a CSS property that is not supported natively by the style system, you can use a function as the value, in which you can access the theme object. {{"demo": "pages/system/basics/ValueAsFunction.js"}} -## Prior art +### Availability +The `sx` prop can be used in four different places: + +#### 1. Core components + +All core Material-UI components will support the `sx` prop. + +#### 2. Box -`@material-ui/system` synthesizes ideas & APIs from several different sources: +[`Box`](/components/box/) is a lightweight component that gives access to the `sx` prop, and can be used as a utility component, and as a wrapper for other components. -- [Tachyons](https://tachyons.io/) was one of the first (2014) CSS libraries to promote the [Atomic CSS pattern](https://css-tricks.com/lets-define-exactly-atomic-css/) (or Functional CSS). -- Tachyons was later on (2017) followed by [Tailwind CSS](https://tailwindcss.com/). They have made Atomic CSS more popular. -- [Twitter Bootstrap](https://getbootstrap.com/docs/4.1/utilities/borders/) has slowly introduced atomic class names in v2, v3, and v4. The way they group their "Helper classes" was used as inspiration. -- In the React world, [Styled System](https://github.com/jxnblk/styled-system) was one of the first (2017) to promote the style functions. - It can be used as a generic Box component replacing the atomic CSS helpers as well as helpers to write new components. -- Large companies such as Pinterest, GitHub, and Segment.io are using the same approach in different flavours: - - [Evergreen Box](https://evergreen.segment.com/components/layout-primitives/) - - [Gestalt Box](https://pinterest.github.io/gestalt/#/Box) - - [Primer Box](https://primer.style/components/docs/Box) -- The actual implementation and the object responsive API was inspired by the [Smooth-UI's system](https://smooth-ui.smooth-code.com/docs-basics-system). +#### 3. Custom components + +In addition to Material-UI components, you can add the `sx` prop to your custom components too, by using the `experimentalStyled` utility from `@material-ui/core/styles`. + +```jsx +import { experimentalStyled as styled } from '@material-ui/core/styles'; + +const Div = styled('div')``; +``` + +> Note: +> +> You should use this prop whenever you need to add or override a component style. If you find you are repeatedly applying the same styles to a component, then `styled()` may be a better option, as it allows you to specify the styles only once, and reuse them in all component instances. See [Customizing components](/customization/components/) for all the alternatives. + +#### 4. Babel plugin + +TODO: For #23220 diff --git a/docs/translations/translations.json b/docs/translations/translations.json index 69761b1452de6e..cb83fbbf7e017d 100644 --- a/docs/translations/translations.json +++ b/docs/translations/translations.json @@ -210,7 +210,7 @@ "/styles": "Styles", "/styles/basics": "Basics", "/styles/advanced": "Advanced", - "/system": "System", + "/system": "Style system", "/system/basics": "Basics", "/system/borders": "Borders", "/system/display": "Display",