Skip to content

Commit acb4e78

Browse files
authored
feat(typography): add title prop to all typography components (#191)
1 parent 3942129 commit acb4e78

File tree

4 files changed

+77
-5
lines changed

4 files changed

+77
-5
lines changed

src/components/typography/text/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Wraps the given text in the given HTML header `size`.
2424
| ------------- | ---------------- | :------: | -------------------- | ------- | -------------------------------------------------------------- |
2525
| `elementType` | `String` || `['h1', 'h2', 'h3']` | - | - |
2626
| `children` | `PropTypes.node` || - | - | - |
27+
| `title` | `String` | - | - | - | Text to show in a tooltip on hover over the element |
2728
| `truncate` | `Bool` | - | - | `false` | Option for truncate content in case the screen has small width |
2829

2930
#### Where to use
@@ -47,6 +48,7 @@ Wraps the given text in the given HTML header `size`.
4748
| `elementType` | `String` || `['h4', 'h5']` | - |
4849
| `isBold` | `Boolean` | - | - | `false` |
4950
| `children` | `PropTypes.node` || - | - |
51+
| `title` | `String` | - | - | - |
5052
| `truncate` | `Bool` | - | - | `false` |
5153

5254
#### Where to use
@@ -85,6 +87,7 @@ Wraps the given text in a `<p>` element, for normal content.
8587
| `isItalic` | `Boolean` | - | - | `false` |
8688
| `tone` | `String` | - | `['primary', 'secondary', 'positive', 'negative']` | - |
8789
| `children` | `PropTypes.node` || - | - |
90+
| `title` | `String` | - | - | - |
8891
| `truncate` | `Bool` | - | - | `false` |
8992

9093
#### Where to use
@@ -111,6 +114,7 @@ properly style the text.
111114
| `isItalic` | `Boolean` | - | - | `false` |
112115
| `tone` | `String` | - | `['primary', 'secondary', 'positive', 'negative', 'inverted', 'warning'']` | - |
113116
| `children` | `PropTypes.node` || - | - |
117+
| `title` | `String` | - | - | - |
114118
| `truncate` | `Bool` | - | - | `false` |
115119

116120
#### Where to use

src/components/typography/text/text.js

+24-1
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,23 @@ import PropTypes from 'prop-types';
33
import classnames from 'classnames';
44
import styles from './text.mod.css';
55

6+
const nonEmptyString = (props, propName, componentName) => {
7+
const value = props[propName];
8+
if (typeof value === 'string' && !value)
9+
return new Error(
10+
`Invalid prop '${propName}' supplied to '${componentName}'. Expected it to be nonempty string, but it was empty.`
11+
);
12+
return null;
13+
};
14+
615
const Headline = props => {
716
const HeadlineElement = props.elementType;
817
return (
918
<HeadlineElement
1019
className={classnames({
1120
[styles.truncate]: props.truncate,
1221
})}
22+
title={props.title}
1323
>
1424
{props.children}
1525
</HeadlineElement>
@@ -19,6 +29,7 @@ Headline.displayName = 'TextHeadline';
1929
Headline.propTypes = {
2030
elementType: PropTypes.oneOf(['h1', 'h2', 'h3']).isRequired,
2131
children: PropTypes.node.isRequired,
32+
title: nonEmptyString,
2233
truncate: PropTypes.bool,
2334
};
2435

@@ -31,6 +42,7 @@ const Subheadline = props => {
3142
[styles[`${props.tone}`]]: props.tone,
3243
[styles.truncate]: props.truncate,
3344
})}
45+
title={props.title}
3446
>
3547
{props.children}
3648
</SubheadlineElement>
@@ -48,13 +60,19 @@ Subheadline.propTypes = {
4860
'negative',
4961
]),
5062
children: PropTypes.node.isRequired,
63+
title: nonEmptyString,
5164
truncate: PropTypes.bool,
5265
};
5366

54-
const Wrap = props => <div className={styles.wrap}>{props.children}</div>;
67+
const Wrap = props => (
68+
<div className={styles.wrap} title={props.title}>
69+
{props.children}
70+
</div>
71+
);
5572
Wrap.displayName = 'TextWrap';
5673
Wrap.propTypes = {
5774
children: PropTypes.node.isRequired,
75+
title: nonEmptyString,
5876
};
5977

6078
const Body = props =>
@@ -66,6 +84,7 @@ const Body = props =>
6684
[styles[`${props.tone}`]]: props.tone,
6785
[styles.truncate]: props.truncate,
6886
})}
87+
title={props.title}
6988
>
7089
{props.children}
7190
</span>
@@ -77,6 +96,7 @@ const Body = props =>
7796
[styles[`${props.tone}`]]: props.tone,
7897
[styles.truncate]: props.truncate,
7998
})}
99+
title={props.title}
80100
>
81101
{props.children}
82102
</p>
@@ -95,6 +115,7 @@ Body.propTypes = {
95115
'inverted',
96116
]),
97117
children: PropTypes.node.isRequired,
118+
title: nonEmptyString,
98119
truncate: PropTypes.bool,
99120
};
100121

@@ -107,6 +128,7 @@ const Detail = props => (
107128
[styles[`${props.tone}`]]: props.tone,
108129
[styles.truncate]: props.truncate,
109130
})}
131+
title={props.title}
110132
>
111133
{props.children}
112134
</small>
@@ -125,6 +147,7 @@ Detail.propTypes = {
125147
'warning',
126148
]),
127149
children: PropTypes.node.isRequired,
150+
title: nonEmptyString,
128151
truncate: PropTypes.bool,
129152
};
130153

src/components/typography/text/text.spec.js

+42-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ describe('<Headline>', () => {
2828
let wrapper;
2929
beforeEach(() => {
3030
wrapper = shallow(
31-
<Text.Headline elementType="h1">{'Title'}</Text.Headline>
31+
<Text.Headline elementType="h1" title="tooltip text">
32+
{'Title'}
33+
</Text.Headline>
3234
);
3335
});
3436
it('should render element tag h1', () => {
@@ -40,6 +42,9 @@ describe('<Headline>', () => {
4042
it('should render given text', () => {
4143
expect(wrapper.text()).toMatch('Title');
4244
});
45+
it('should has `title` prop', () => {
46+
expect(wrapper).toHaveProp('title', 'tooltip text');
47+
});
4348

4449
describe('with truncated text', () => {
4550
beforeEach(() => {
@@ -92,7 +97,12 @@ describe('<Subheadline>', () => {
9297
describe('with tone', () => {
9398
beforeEach(() => {
9499
wrapper = shallow(
95-
<Text.Subheadline elementType="h4" isBold={true} tone="primary">
100+
<Text.Subheadline
101+
elementType="h4"
102+
isBold={true}
103+
tone="primary"
104+
title="tooltip text"
105+
>
96106
{'Subtitle'}
97107
</Text.Subheadline>
98108
);
@@ -109,6 +119,9 @@ describe('<Subheadline>', () => {
109119
it('should have "primary" class', () => {
110120
expect(wrapper).toContainClass(styles.primary);
111121
});
122+
it('should has `title` prop', () => {
123+
expect(wrapper).toHaveProp('title', 'tooltip text');
124+
});
112125
});
113126
describe('with truncated text', () => {
114127
beforeEach(() => {
@@ -132,14 +145,17 @@ describe('<Subheadline>', () => {
132145
describe('<Wrap>', () => {
133146
let wrapper;
134147
beforeEach(() => {
135-
wrapper = shallow(<Text.Wrap>{'Title'}</Text.Wrap>);
148+
wrapper = shallow(<Text.Wrap title={'tooltip text'}>{'Title'}</Text.Wrap>);
136149
});
137150
it('should have "wrap" class', () => {
138151
expect(wrapper).toContainClass(styles.wrap);
139152
});
140153
it('should render given text', () => {
141154
expect(wrapper.text()).toMatch('Title');
142155
});
156+
it('should has `title` prop', () => {
157+
expect(wrapper).toHaveProp('title', 'tooltip text');
158+
});
143159
});
144160

145161
describe('<Body>', () => {
@@ -199,6 +215,16 @@ describe('<Body>', () => {
199215
expect(wrapper).toHaveText('Detail');
200216
});
201217
});
218+
describe('with title', () => {
219+
beforeEach(() => {
220+
wrapper = shallow(
221+
<Text.Body title="tooltip text">{'Detail'}</Text.Body>
222+
);
223+
});
224+
it('should has `title` prop', () => {
225+
expect(wrapper).toHaveProp('title', 'tooltip text');
226+
});
227+
});
202228
describe('with truncated text', () => {
203229
beforeEach(() => {
204230
wrapper = shallow(
@@ -389,6 +415,19 @@ describe('<Detail>', () => {
389415
});
390416
});
391417

418+
describe('with title', () => {
419+
beforeEach(() => {
420+
wrapper = shallow(
421+
<Text.Detail isInline={true} title="tooltip text">
422+
{'Detail'}
423+
</Text.Detail>
424+
);
425+
});
426+
it('should has `title` prop', () => {
427+
expect(wrapper).toHaveProp('title', 'tooltip text');
428+
});
429+
});
430+
392431
describe('with truncated text', () => {
393432
beforeEach(() => {
394433
wrapper = shallow(

src/components/typography/typography.story.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ storiesOf('Typography/Text', module)
1919
<Section>
2020
<Text.Headline
2121
elementType={select('Element type', ['h1', 'h2', 'h3'], 'h1')}
22+
title={text('title', 'Text to be shown as tooltip on hover')}
2223
truncate={boolean('truncate', false)}
2324
>
2425
{text('Text', 'Sample text Headline')}
@@ -38,6 +39,7 @@ storiesOf('Typography/Text', module)
3839
'positive',
3940
'negative',
4041
])}
42+
title={text('title', 'Text to be shown as tooltip on hover')}
4143
truncate={boolean('truncate', false)}
4244
>
4345
{text('Text', 'Sample text Subheadline')}
@@ -47,7 +49,9 @@ storiesOf('Typography/Text', module)
4749
.add('Wrap', () => (
4850
<Section>
4951
<InlineColorWrapper width={'200px'}>
50-
<Text.Wrap>
52+
<Text.Wrap
53+
title={text('title', 'Text to be shown as tooltip on hover')}
54+
>
5155
{text(
5256
'Text',
5357
'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
@@ -71,6 +75,7 @@ storiesOf('Typography/Text', module)
7175
'negative',
7276
'inverted',
7377
])}
78+
title={text('title', 'Text to be shown as tooltip on hover')}
7479
truncate={boolean('truncate', false)}
7580
>
7681
{text('Text', 'Sample text Body')}
@@ -92,6 +97,7 @@ storiesOf('Typography/Text', module)
9297
'negative',
9398
'warning',
9499
])}
100+
title={text('title', 'Text to be shown as tooltip on hover')}
95101
truncate={boolean('truncate', false)}
96102
>
97103
{text('Text', 'Sample text Detail')}

0 commit comments

Comments
 (0)