diff --git a/docs/pages/api-docs/typography.md b/docs/pages/api-docs/typography.md
index 62e430719bcfd3..019ccd0273d5cf 100644
--- a/docs/pages/api-docs/typography.md
+++ b/docs/pages/api-docs/typography.md
@@ -33,7 +33,7 @@ You can learn more about the difference by [reading this guide](/guides/minimizi
| gutterBottom | bool | false | If `true`, the text will have a bottom margin. |
| noWrap | bool | false | If `true`, the text will not wrap, but instead will truncate with a text overflow ellipsis.
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). |
| paragraph | bool | false | If `true`, the text will have a bottom margin. |
-| variant | 'h1'
| 'h2'
| 'h3'
| 'h4'
| 'h5'
| 'h6'
| 'subtitle1'
| 'subtitle2'
| 'body1'
| 'body2'
| 'caption'
| 'button'
| 'overline'
| 'srOnly'
| 'inherit' | 'body1' | Applies the theme typography styles. |
+| variant | string | 'body1' | Applies the theme typography styles. |
| variantMapping | object | { h1: 'h1', h2: 'h2', h3: 'h3', h4: 'h4', h5: 'h5', h6: 'h6', subtitle1: 'h6', subtitle2: 'h6', body1: 'p', body2: 'p',} | The component maps the variant prop to a range of different DOM element types. For instance, subtitle1 to `
`. 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.
diff --git a/docs/src/pages/components/typography/typography.md b/docs/src/pages/components/typography/typography.md
index 2755101df3603b..ee1e9376e77f12 100644
--- a/docs/src/pages/components/typography/typography.md
+++ b/docs/src/pages/components/typography/typography.md
@@ -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.
diff --git a/docs/src/pages/customization/typography/CustomVariants.js b/docs/src/pages/customization/typography/CustomVariants.js
new file mode 100644
index 00000000000000..f5112dc0b594e8
--- /dev/null
+++ b/docs/src/pages/customization/typography/CustomVariants.js
@@ -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 (
+
+
+
+ Custom Variant
+
+
+ Custom Variant
+
+
+
+ );
+}
diff --git a/docs/src/pages/customization/typography/CustomVariants.tsx b/docs/src/pages/customization/typography/CustomVariants.tsx
new file mode 100644
index 00000000000000..ea9caab8c0b876
--- /dev/null
+++ b/docs/src/pages/customization/typography/CustomVariants.tsx
@@ -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 {}
+ interface CustomVariantsOptions extends Record {}
+}
+
+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 (
+
+
+
+ Custom Variant
+
+
+ Custom Variant
+
+
+
+ );
+}
diff --git a/docs/src/pages/customization/typography/typography.md b/docs/src/pages/customization/typography/typography.md
index ef19e6a2217d70..68391e597bf86c 100644
--- a/docs/src/pages/customization/typography/typography.md
+++ b/docs/src/pages/customization/typography/typography.md
@@ -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
@@ -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`).
diff --git a/packages/material-ui/src/Typography/Typography.js b/packages/material-ui/src/Typography/Typography.js
index b12f64103901f4..f7e090444f102e 100644
--- a/packages/material-ui/src/Typography/Typography.js
+++ b/packages/material-ui/src/Typography/Typography.js
@@ -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,
/* Styles applied to the root element. */
root: {
margin: 0,
@@ -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,
/**
* The component maps the variant prop to a range of different DOM element types.
* For instance, subtitle1 to ``.
diff --git a/packages/material-ui/src/styles/createMuiTheme.test.js b/packages/material-ui/src/styles/createMuiTheme.test.js
index bf23075e880458..cf4eec006b9cfd 100644
--- a/packages/material-ui/src/styles/createMuiTheme.test.js
+++ b/packages/material-ui/src/styles/createMuiTheme.test.js
@@ -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');
diff --git a/packages/material-ui/src/styles/createTypography.d.ts b/packages/material-ui/src/styles/createTypography.d.ts
index 8bdcd0da96c225..8981271e63d184 100644
--- a/packages/material-ui/src/styles/createTypography.d.ts
+++ b/packages/material-ui/src/styles/createTypography.d.ts
@@ -15,7 +15,8 @@ export type Variant =
| 'body2'
| 'caption'
| 'button'
- | 'overline';
+ | 'overline'
+ | keyof CustomVariants;
export interface FontStyle
extends Required<{
@@ -38,14 +39,31 @@ export interface FontStyleOptions extends Partial {
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, FontStyle, TypographyUtils {}
+export interface Typography
+ extends Record,
+ FontStyle,
+ TypographyUtils,
+ TypographyCustomVariants {}
export interface TypographyOptions
- extends Partial & FontStyleOptions> {}
+ extends Partial<
+ Record & FontStyleOptions & TypographyCustomVariantsOptions
+ > {}
export default function createTypography(
palette: Palette,
diff --git a/packages/material-ui/src/styles/createTypography.js b/packages/material-ui/src/styles/createTypography.js
index bb3b6fe572692f..bc9a8c3a46956b 100644
--- a/packages/material-ui/src/styles/createTypography.js
+++ b/packages/material-ui/src/styles/createTypography.js
@@ -28,6 +28,7 @@ export default function createTypography(palette, typography) {
// Apply the CSS properties to all the variants.
allVariants,
pxToRem: pxToRem2,
+ customVariants = {},
...other
} = typeof typography === 'function' ? typography(palette) : typography;
@@ -85,6 +86,7 @@ export default function createTypography(palette, typography) {
fontWeightRegular,
fontWeightMedium,
fontWeightBold,
+ customVariants,
...variants,
},
other,