Skip to content

Commit

Permalink
[Typography] Add custom variants support (#22006)
Browse files Browse the repository at this point in the history
* added custom variants support to Typography

* updated whitelistComponents list

* typings

* ts

* inherit to p mapping

* removed tests

* added warnings test, removed unused imports

* prettier

* docs:api

* variantsMapping propType

* reverted some changes

* Update packages/material-ui-styles/src/makeStyles/makeStyles.js

Co-authored-by: Olivier Tassinari <[email protected]>

* framer fix

* typo

* fixed prop rename

* Update framer/scripts/framerConfig.js

Co-authored-by: Olivier Tassinari <[email protected]>

Co-authored-by: Olivier Tassinari <[email protected]>
  • Loading branch information
mnajdova and oliviertassinari authored Aug 4, 2020
1 parent bca632c commit 30e912b
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 73 deletions.
5 changes: 3 additions & 2 deletions docs/pages/api-docs/typography.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ The `MuiTypography` name can be used for providing [default props](/customizatio
| <span class="prop-name">gutterBottom</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the text will have a bottom margin. |
| <span class="prop-name">noWrap</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the text will not wrap, but instead will truncate with a text overflow ellipsis.<br>Note that text overflow can only happen with block or inline-block level elements (the element needs to have a width in order to overflow). |
| <span class="prop-name">paragraph</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the text will have a bottom margin. |
| <span class="prop-name">variant</span> | <span class="prop-type">'body1'<br>&#124;&nbsp;'body2'<br>&#124;&nbsp;'button'<br>&#124;&nbsp;'caption'<br>&#124;&nbsp;'h1'<br>&#124;&nbsp;'h2'<br>&#124;&nbsp;'h3'<br>&#124;&nbsp;'h4'<br>&#124;&nbsp;'h5'<br>&#124;&nbsp;'h6'<br>&#124;&nbsp;'inherit'<br>&#124;&nbsp;'overline'<br>&#124;&nbsp;'subtitle1'<br>&#124;&nbsp;'subtitle2'</span> | <span class="prop-default">'body1'</span> | Applies the theme typography styles. |
| <span class="prop-name">variantMapping</span> | <span class="prop-type">{ body1?: string, body2?: string, button?: string, caption?: string, h1?: string, h2?: string, h3?: string, h4?: string, h5?: string, h6?: string, overline?: string, subtitle1?: string, subtitle2?: string }</span> | <span class="prop-default">{ h1: 'h1', h2: 'h2', h3: 'h3', h4: 'h4', h5: 'h5', h6: 'h6', subtitle1: 'h6', subtitle2: 'h6', body1: 'p', body2: 'p',}</span> | The component maps the variant prop to a range of different HTML element types. For instance, subtitle1 to `<h6>`. If you wish to change that mapping, you can provide your own. Alternatively, you can use the `component` prop. |
| <span class="prop-name">variant</span> | <span class="prop-type">'body1'<br>&#124;&nbsp;'body2'<br>&#124;&nbsp;'button'<br>&#124;&nbsp;'caption'<br>&#124;&nbsp;'h1'<br>&#124;&nbsp;'h2'<br>&#124;&nbsp;'h3'<br>&#124;&nbsp;'h4'<br>&#124;&nbsp;'h5'<br>&#124;&nbsp;'h6'<br>&#124;&nbsp;'inherit'<br>&#124;&nbsp;'overline'<br>&#124;&nbsp;'subtitle1'<br>&#124;&nbsp;'subtitle2'<br>&#124;&nbsp;string</span> | <span class="prop-default">'body1'</span> | Applies the theme typography styles. |
| <span class="prop-name">variantMapping</span> | <span class="prop-type">object</span> | <span class="prop-default">{ h1: 'h1', h2: 'h2', h3: 'h3', h4: 'h4', h5: 'h5', h6: 'h6', subtitle1: 'h6', subtitle2: 'h6', body1: 'p', body2: 'p', inherit: 'p',}</span> | The component maps the variant prop to a range of different HTML element types. For instance, subtitle1 to `<h6>`. If you wish to change that mapping, you can provide your own. Alternatively, you can use the `component` prop. |

The `ref` is forwarded to the root element.

Expand All @@ -62,6 +62,7 @@ Any other props supplied will be provided to the root element (native element).
| <span class="prop-name">subtitle1</span> | <span class="prop-name">.MuiTypography-subtitle1</span> | Styles applied to the root element if `variant="subtitle1"`.
| <span class="prop-name">subtitle2</span> | <span class="prop-name">.MuiTypography-subtitle2</span> | Styles applied to the root element if `variant="subtitle2"`.
| <span class="prop-name">overline</span> | <span class="prop-name">.MuiTypography-overline</span> | Styles applied to the root element if `variant="overline"`.
| <span class="prop-name">inherit</span> | <span class="prop-name">.MuiTypography-inherit</span> | Styles applied to the root element if `variant="inherit"`.
| <span class="prop-name">alignLeft</span> | <span class="prop-name">.MuiTypography-alignLeft</span> | Styles applied to the root element if `align="left"`.
| <span class="prop-name">alignCenter</span> | <span class="prop-name">.MuiTypography-alignCenter</span> | Styles applied to the root element if `align="center"`.
| <span class="prop-name">alignRight</span> | <span class="prop-name">.MuiTypography-alignRight</span> | Styles applied to the root element if `align="right"`.
Expand Down
36 changes: 0 additions & 36 deletions framer/Material-UI.framerfx/code/Typography.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,6 @@ interface Props {
| 'textPrimary'
| 'textSecondary';
noWrap: boolean;
variant:
| 'body1'
| 'body2'
| 'button'
| 'caption'
| 'h1'
| 'h2'
| 'h3'
| 'h4'
| 'h5'
| 'h6'
| 'inherit'
| 'overline'
| 'subtitle1'
| 'subtitle2';
label: string;
width: number | string;
height: number;
Expand All @@ -42,7 +27,6 @@ Typography.defaultProps = {
align: 'inherit' as 'inherit',
color: 'initial' as 'initial',
noWrap: false,
variant: 'body1' as 'body1',
label: 'Typography',
width: 100,
height: 38,
Expand Down Expand Up @@ -71,26 +55,6 @@ addPropertyControls(Typography, {
type: ControlType.Boolean,
title: 'No wrap',
},
variant: {
type: ControlType.Enum,
title: 'Variant',
options: [
'body1',
'body2',
'button',
'caption',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'inherit',
'overline',
'subtitle1',
'subtitle2',
],
},
label: {
type: ControlType.String,
title: 'Label',
Expand Down
2 changes: 2 additions & 0 deletions framer/scripts/framerConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,8 @@ export const componentSettings = {
'gutterBottom',
'internalDeprecatedVariant',
'paragraph',
// FIXME: `Union`
'variant',
'variantMapping',
],
propValues: {
Expand Down
4 changes: 2 additions & 2 deletions packages/material-ui-styles/src/makeStyles/makeStyles.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,11 @@ export default function makeStyles(stylesOrCreator, options = {}) {
React.useDebugValue(classes);
}
if (process.env.NODE_ENV !== 'production') {
const whitelistedComponents = ['MuiButton'];
const allowlistedComponents = ['MuiButton', 'MuiTypography'];

if (
name &&
whitelistedComponents.indexOf(name) >= 0 &&
allowlistedComponents.indexOf(name) >= 0 &&
props.variant &&
!classes[props.variant]
) {
Expand Down
14 changes: 12 additions & 2 deletions packages/material-ui/src/Typography/Typography.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import * as React from 'react';
import { OverridableStringUnion } from '@material-ui/types';
import { PropTypes } from '..';
import { OverrideProps, OverridableComponent } from '../OverridableComponent';
import { Variant } from '../styles/createTypography';

export interface TypographyPropsVariantOverrides {}
export type TypographyVariantDefaults = Record<Variant | 'inherit', true>;

export interface TypographyTypeMap<P = {}, D extends React.ElementType = 'span'> {
props: P & {
/**
Expand Down Expand Up @@ -46,14 +50,19 @@ export interface TypographyTypeMap<P = {}, D extends React.ElementType = 'span'>
/**
* Applies the theme typography styles.
*/
variant?: Variant | 'inherit';
variant?: OverridableStringUnion<TypographyVariantDefaults, TypographyPropsVariantOverrides>;
/**
* The component maps the variant prop to a range of different HTML element types.
* For instance, subtitle1 to `<h6>`.
* If you wish to change that mapping, you can provide your own.
* Alternatively, you can use the `component` prop.
*/
variantMapping?: Partial<Record<Variant, string>>;
variantMapping?: Partial<
Record<
OverridableStringUnion<TypographyVariantDefaults, TypographyPropsVariantOverrides>,
string
>
>;
};
defaultComponent: D;
classKey: TypographyClassKey;
Expand Down Expand Up @@ -92,6 +101,7 @@ export type TypographyClassKey =
| 'caption'
| 'button'
| 'overline'
| 'inherit'
| 'alignLeft'
| 'alignCenter'
| 'alignRight'
Expand Down
71 changes: 40 additions & 31 deletions packages/material-ui/src/Typography/Typography.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { useThemeVariants } from '@material-ui/styles';
import withStyles from '../styles/withStyles';
import capitalize from '../utils/capitalize';

Expand Down Expand Up @@ -35,6 +36,8 @@ export const styles = (theme) => ({
subtitle2: theme.typography.subtitle2,
/* Styles applied to the root element if `variant="overline"`. */
overline: theme.typography.overline,
/* Styles applied to the root element if `variant="inherit"`. */
inherit: {},
/* Styles applied to the root element if `align="left"`. */
alignLeft: {
textAlign: 'left',
Expand Down Expand Up @@ -110,6 +113,7 @@ const defaultVariantMapping = {
subtitle2: 'h6',
body1: 'p',
body2: 'p',
inherit: 'p',
};

const Typography = React.forwardRef(function Typography(props, ref) {
Expand All @@ -128,6 +132,21 @@ const Typography = React.forwardRef(function Typography(props, ref) {
...other
} = props;

const themeVariantsClasses = useThemeVariants(
{
...props,
align,
color,
display,
gutterBottom,
noWrap,
paragraph,
variant,
variantMapping,
},
'MuiTypography',
);

const Component =
component ||
(paragraph ? 'p' : variantMapping[variant] || defaultVariantMapping[variant]) ||
Expand All @@ -137,15 +156,16 @@ const Typography = React.forwardRef(function Typography(props, ref) {
<Component
className={clsx(
classes.root,
classes[variant],
{
[classes[variant]]: variant !== 'inherit',
[classes[`color${capitalize(color)}`]]: color !== 'initial',
[classes.noWrap]: noWrap,
[classes.gutterBottom]: gutterBottom,
[classes.paragraph]: paragraph,
[classes[`align${capitalize(align)}`]]: align !== 'inherit',
[classes[`display${capitalize(display)}`]]: display !== 'initial',
},
themeVariantsClasses,
className,
)}
ref={ref}
Expand Down Expand Up @@ -215,43 +235,32 @@ Typography.propTypes = {
/**
* Applies the theme typography styles.
*/
variant: PropTypes.oneOf([
'body1',
'body2',
'button',
'caption',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'inherit',
'overline',
'subtitle1',
'subtitle2',
variant: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
PropTypes.oneOf([
'body1',
'body2',
'button',
'caption',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'inherit',
'overline',
'subtitle1',
'subtitle2',
]),
PropTypes.string,
]),
/**
* The component maps the variant prop to a range of different HTML element types.
* For instance, subtitle1 to `<h6>`.
* If you wish to change that mapping, you can provide your own.
* Alternatively, you can use the `component` prop.
*/
variantMapping: PropTypes.shape({
body1: PropTypes.string,
body2: PropTypes.string,
button: PropTypes.string,
caption: PropTypes.string,
h1: PropTypes.string,
h2: PropTypes.string,
h3: PropTypes.string,
h4: PropTypes.string,
h5: PropTypes.string,
h6: PropTypes.string,
overline: PropTypes.string,
subtitle1: PropTypes.string,
subtitle2: PropTypes.string,
}),
variantMapping: PropTypes /* @typescript-to-proptypes-ignore */.object,
};

export default withStyles(styles, { name: 'MuiTypography' })(Typography);

0 comments on commit 30e912b

Please sign in to comment.