UNPKG

1.78 kBJavaScriptView Raw
1import React, {PureComponent} from 'react';
2import PropTypes from 'prop-types';
3import classNames from 'classnames';
4import deprecate from 'util-deprecate';
5
6import styles from './heading.css';
7
8/**
9 * @name Heading
10 */
11
12const Levels = {
13 H1: 1,
14 H2: 2,
15 H3: 3,
16 H4: 4
17};
18
19const fallbackHeading = deprecate(
20 () => 'h3',
21 'Headings of level 5 and higher are replaced with h3'
22);
23
24export default class Heading extends PureComponent {
25 static Levels = Levels;
26
27 static propTypes = {
28 children: PropTypes.node,
29 className: PropTypes.string,
30 level: PropTypes.number
31 };
32
33 static defaultProps = {
34 level: Levels.H1
35 };
36
37 render() {
38 const {children, className, level, ...restProps} = this.props;
39 const classes = classNames(styles.heading, className);
40
41 const Tag = level <= Levels.H4 ? `h${level}` : fallbackHeading();
42
43 return (
44 <Tag
45 {...restProps}
46 className={classes}
47 >
48 {children}
49 </Tag>
50 );
51 }
52}
53
54function makeHeading(level, useCaps) {
55 return class H extends PureComponent { //eslint-disable-line react/no-multi-comp
56 static propTypes = {
57 children: PropTypes.node,
58 className: PropTypes.string,
59 // use only for short h1 headers, no longer than three words
60 caps: PropTypes.bool
61 };
62
63 render() {
64 const {className, caps, ...restProps} = this.props;
65
66 const classes = classNames(className, {
67 [styles.caps]: useCaps && caps
68 });
69
70 return (
71 <Heading
72 {...restProps}
73 level={level}
74 className={classes}
75 />
76 );
77 }
78 };
79}
80
81const H1 = makeHeading(Levels.H1, true);
82const H2 = makeHeading(Levels.H2);
83const H3 = makeHeading(Levels.H3);
84const H4 = makeHeading(Levels.H4);
85
86export {H1, H2, H3, H4};