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

[Typography] Add custom variants support #22006

Merged
merged 18 commits into from
Aug 4, 2020
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
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
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
1 change: 1 addition & 0 deletions framer/scripts/framerConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ export const componentSettings = {
'gutterBottom',
'internalDeprecatedVariant',
'paragraph',
'varaint',
Copy link
Member

Choose a reason for hiding this comment

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

There's a typo but why do we want to ignore it? Seems pretty important for prototyping to me.

Copy link
Member Author

Choose a reason for hiding this comment

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

The variants is now a union of enums + string, my understanding was that we are excluding those props.

Copy link
Member

Choose a reason for hiding this comment

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

my understanding was that we are excluding those props.

Why?

Copy link
Member

Choose a reason for hiding this comment

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

Why?

I believe we would need to fix the Framer generation script, not sure it's worth it:

https://github.com/mui-org/material-ui/blob/41e81f229e8f878287ea082b88b5808061a189ad/framer/scripts/framerConfig.js#L289

'variantMapping',
],
propValues: {
Expand Down
2 changes: 1 addition & 1 deletion packages/material-ui-styles/src/makeStyles/makeStyles.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ export default function makeStyles(stylesOrCreator, options = {}) {
React.useDebugValue(classes);
}
if (process.env.NODE_ENV !== 'production') {
const whitelistedComponents = ['MuiButton'];
const allowlistedComponents = ['MuiButton', 'MuiTypography'];

if (
name &&
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: {},
Copy link
Member Author

Choose a reason for hiding this comment

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

For consistency I've added this variant classKey. This way we don't need to update the warnings as the variant classKey will always exists. If we don't want to make this change, I can work on the warning.

/* 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,
Copy link
Member Author

Choose a reason for hiding this comment

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

With adding new variants new keys can be added here, so this was relaxed to object.

};

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