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 ability to specify custom variants #20203

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion docs/pages/api-docs/typography.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ You can learn more about the difference by [reading this guide](/guides/minimizi
| <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">'h1'<br>&#124;&nbsp;'h2'<br>&#124;&nbsp;'h3'<br>&#124;&nbsp;'h4'<br>&#124;&nbsp;'h5'<br>&#124;&nbsp;'h6'<br>&#124;&nbsp;'subtitle1'<br>&#124;&nbsp;'subtitle2'<br>&#124;&nbsp;'body1'<br>&#124;&nbsp;'body2'<br>&#124;&nbsp;'caption'<br>&#124;&nbsp;'button'<br>&#124;&nbsp;'overline'<br>&#124;&nbsp;'srOnly'<br>&#124;&nbsp;'inherit'</span> | <span class="prop-default">'body1'</span> | Applies the theme typography styles. |
| <span class="prop-name">variant</span> | <span class="prop-type">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',}</span> | The component maps the variant prop to a range of different DOM 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 Down
4 changes: 4 additions & 0 deletions docs/src/pages/components/typography/typography.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ Hopefully, you might be able to take advantage of the [`typography`](/customizat

{{"demo": "pages/components/typography/TypographyTheme.js"}}

## Custom Variants

Sometimes default variants are not enough. For this reason you can [specify your variants via theme](/customization/typography#custom)

## Changing the semantic element

The Typography component uses the `variantMapping` property to associate a UI variant with a semantic element.
Expand Down
44 changes: 44 additions & 0 deletions docs/src/pages/customization/typography/CustomVariants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from 'react';
import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles';
import Typography from '@material-ui/core/Typography';

const theme = createMuiTheme({
typography: {
customVariants: {
special1: {
fontSize: 15,
fontWeight: 600,
fontStyle: 'italic',
textTransform: 'uppercase',
},
special2: {
fontSize: 12,
fontWeight: 300,
fontStyle: 'italic',
},
},
},
props: {
MuiTypography: {
variantMapping: {
special1: 'h1',
special2: 'span',
},
},
},
});

export default function CustomVariants() {
return (
<div>
<ThemeProvider theme={theme}>
<Typography variant="special1" color="primary">
Custom Variant
</Typography>
<Typography variant="special2" color="primary">
Custom Variant
</Typography>
</ThemeProvider>
</div>
);
}
52 changes: 52 additions & 0 deletions docs/src/pages/customization/typography/CustomVariants.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React from 'react';
import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles';
import Typography from '@material-ui/core/Typography';

type CustomVariant = 'special1' | 'special2';

// You need to specify custom variant names via module augmentation
declare module '@material-ui/core/styles/createTypography' {
interface CustomVariants extends Record<CustomVariant, TypographyStyle> {}
interface CustomVariantsOptions extends Record<CustomVariant, TypographyStyleOptions> {}
}

const theme = createMuiTheme({
typography: {
customVariants: {
special1: {
fontSize: 15,
fontWeight: 600,
fontStyle: 'italic',
textTransform: 'uppercase',
},
special2: {
fontSize: 12,
fontWeight: 300,
fontStyle: 'italic',
},
},
},
props: {
MuiTypography: {
variantMapping: {
special1: 'h1',
special2: 'span',
},
},
},
});

export default function CustomVariants() {
return (
<div>
<ThemeProvider theme={theme}>
<Typography variant="special1" color="primary">
Custom Variant
</Typography>
<Typography variant="special2" color="primary">
Custom Variant
</Typography>
</ThemeProvider>
</div>
);
}
28 changes: 28 additions & 0 deletions docs/src/pages/customization/typography/typography.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ To be done: [#15251](https://github.com/mui-org/material-ui/issues/15251).

## Variants

### Built-in

The typography object comes with [13 variants](/components/typography/#component) by default:

- h1
Expand Down Expand Up @@ -210,6 +212,32 @@ const theme = createMuiTheme({

{{"demo": "pages/customization/typography/TypographyVariants.js"}}

### Custom

In addition to default variants, you can specify your custom variants:

```js
const theme = createMuiTheme({
typography: {
customVariants: {
special1: {
fontSize: 15,
fontWeight: 600,
fontStyle: 'italic',
textTransform: 'uppercase',
},
special2: {
fontSize: 12,
fontWeight: 300,
fontStyle: 'italic',
},
},
},
});
```

{{"demo": "pages/customization/typography/CustomVariants.js"}}

## Default values

You can explore the default values of the typography using [the theme explorer](/customization/default-theme/?expand-path=$.typography) or by opening the dev tools console on this page (`window.theme.typography`).
20 changes: 3 additions & 17 deletions packages/material-ui/src/Typography/Typography.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import withStyles from '../styles/withStyles';
import capitalize from '../utils/capitalize';

export const styles = theme => ({
/* Styles applied to the root element if `variant` is from user defined variants (customVariants). */
...theme.typography.customVariants,
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
...theme.typography.customVariants,

/* Styles applied to the root element. */
root: {
margin: 0,
Expand Down Expand Up @@ -219,23 +221,7 @@ Typography.propTypes = {
/**
* Applies the theme typography styles.
*/
variant: PropTypes.oneOf([
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'subtitle1',
'subtitle2',
'body1',
'body2',
'caption',
'button',
'overline',
'srOnly',
'inherit',
]),
variant: PropTypes.string,
Copy link
Member

Choose a reason for hiding this comment

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

To keep enough information in the generated API documentation.

Suggested change
variant: PropTypes.string,
variant: variant: PropTypes.oneOf(PropTypes.string, PropTypes.oneOf([])),

/**
* The component maps the variant prop to a range of different DOM element types.
* For instance, subtitle1 to `<h6>`.
Expand Down
21 changes: 21 additions & 0 deletions packages/material-ui/src/styles/createMuiTheme.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,27 @@ describe('createMuiTheme', () => {
});
});

describe('typography customVariants', () => {
it('should provide the default value', () => {
const muiTheme = createMuiTheme();
assert.deepEqual(muiTheme.typography.customVariants, {});
});

it('should have the customVariants as expected', () => {
const customVariants = {
one: {
fontSize: '1.8rem',
},
two: {
fontWeight: 300,
},
};

const muiTheme = createMuiTheme({ typography: { customVariants } });
assert.deepEqual(muiTheme.typography.customVariants, customVariants);
});
});

it('shallow merges multiple arguments', () => {
const muiTheme = createMuiTheme({ foo: 'I am foo' }, { bar: 'I am bar' });
assert.strictEqual(muiTheme.foo, 'I am foo');
Expand Down
24 changes: 21 additions & 3 deletions packages/material-ui/src/styles/createTypography.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export type Variant =
| 'body2'
| 'caption'
| 'button'
| 'overline';
| 'overline'
| keyof CustomVariants;
Copy link
Member

Choose a reason for hiding this comment

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

We will prefer module augmentation.

Suggested change
| keyof CustomVariants;


export interface FontStyle
extends Required<{
Expand All @@ -38,14 +39,31 @@ export interface FontStyleOptions extends Partial<FontStyle> {
export type TypographyStyle = CSSProperties;
export interface TypographyStyleOptions extends TypographyStyle {}

export interface CustomVariants {}
export interface CustomVariantsOptions {}

export interface TypographyCustomVariants {
customVariants: CustomVariants;
}

export interface TypographyCustomVariantsOptions {
customVariants?: CustomVariantsOptions;
}

export interface TypographyUtils {
pxToRem: (px: number) => string;
}

export interface Typography extends Record<Variant, TypographyStyle>, FontStyle, TypographyUtils {}
export interface Typography
extends Record<Variant, TypographyStyle>,
FontStyle,
TypographyUtils,
TypographyCustomVariants {}

export interface TypographyOptions
extends Partial<Record<Variant, TypographyStyleOptions> & FontStyleOptions> {}
extends Partial<
Record<Variant, TypographyStyleOptions> & FontStyleOptions & TypographyCustomVariantsOptions
> {}

export default function createTypography(
palette: Palette,
Expand Down
2 changes: 2 additions & 0 deletions packages/material-ui/src/styles/createTypography.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default function createTypography(palette, typography) {
// Apply the CSS properties to all the variants.
allVariants,
pxToRem: pxToRem2,
customVariants = {},
Copy link
Member

@oliviertassinari oliviertassinari Mar 21, 2020

Choose a reason for hiding this comment

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

Spreading should already achieve the same.

Suggested change
customVariants = {},

...other
} = typeof typography === 'function' ? typography(palette) : typography;

Expand Down Expand Up @@ -85,6 +86,7 @@ export default function createTypography(palette, typography) {
fontWeightRegular,
fontWeightMedium,
fontWeightBold,
customVariants,
...variants,
},
other,
Expand Down