Skip to content

Commit 97e282c

Browse files
authored
<Timeline/> - allow passing a node instead of string only in the item… (#5883)
* <Timeline/> - allow passing a node instead of string only in the item.label prop * update tsx and index.d.ts files * udpate storybook and unit test
1 parent a6e2ea4 commit 97e282c

File tree

7 files changed

+100
-16
lines changed

7 files changed

+100
-16
lines changed

src/Timeline/Timeline.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ Timeline.propTypes = {
3737
/** timeline events items */
3838
items: PropTypes.arrayOf(
3939
PropTypes.shape({
40-
/** event text */
41-
label: PropTypes.string,
40+
/** event text - could be a node or a string */
41+
label: PropTypes.node,
4242
/** action element in the end of event text */
4343
labelAction: PropTypes.node,
4444
/** TODO: still in development. custom bullet element like icon or avatar */

src/Timeline/TimelineItem.js

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Text from '../Text';
55
import { classes } from './TimelineItem.st.css';
66
import { dataHooks } from './constants';
77

8-
const _isString = a => typeof a === 'string';
8+
import { isString } from '../utils/StringUtils';
99

1010
/** A timeline item is a display of a timeline event */
1111
class TimelineItem extends React.PureComponent {
@@ -28,14 +28,18 @@ class TimelineItem extends React.PureComponent {
2828
<div className={classes.line} />
2929
</div>
3030
<div className={classes.label}>
31-
<Text
32-
dataHook={`${dataHooks.timelineLabel}-${idx}`}
33-
weight="normal"
34-
size="small"
35-
className={classes.labelText}
36-
>
37-
{item.label}
38-
</Text>
31+
{isString(item.label) ? (
32+
<Text
33+
dataHook={`${dataHooks.timelineLabel}-${idx}`}
34+
weight="normal"
35+
size="small"
36+
className={classes.labelText}
37+
>
38+
{item.label}
39+
</Text>
40+
) : (
41+
item.label
42+
)}
3943
{item.labelAction ? (
4044
<div
4145
className={classes.labelAction}
@@ -50,7 +54,7 @@ class TimelineItem extends React.PureComponent {
5054
data-hook={`${dataHooks.timelineSuffix}-${idx}`}
5155
>
5256
{item.suffix ? (
53-
_isString(item.suffix) ? (
57+
isString(item.suffix) ? (
5458
<Text
5559
dataHook={`${dataHooks.timelineTextSuffix}-${idx}`}
5660
weight="normal"
@@ -79,8 +83,8 @@ TimelineItem.propTypes = {
7983
idx: PropTypes.number,
8084
/** timeline event item */
8185
item: PropTypes.shape({
82-
/** event text */
83-
label: PropTypes.string,
86+
/** event text - could be a node or a string */
87+
label: PropTypes.node,
8488
/** action element in the end of event text */
8589
labelAction: PropTypes.node,
8690
/** TODO: still in development. custom bullet element like icon or avatar */

src/Timeline/docs/examples.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,50 @@ export const simple = `() => {
5151
5252
return <Card><Card.Content><Timeline items={items} /></Card.Content></Card>;
5353
}`;
54+
55+
export const customExample = `() => {
56+
const items = [
57+
{
58+
label: (
59+
<Layout cols={1} gap={0}>
60+
<Heading appearance="H6">Review Request Date</Heading>
61+
<Text size="small">Jul 05, 2020 at 11:00 AM</Text>
62+
<Box marginTop={2}>
63+
<Badge type="outlined">Waiting for review</Badge>
64+
</Box>
65+
<Box marginTop={3}>
66+
<Text size="small">
67+
Ask your client for a review directly from here. Send this
68+
</Text>
69+
</Box>
70+
<Box>
71+
<TextButton size="small">Request Review link</TextButton>
72+
</Box>
73+
</Layout>
74+
),
75+
},
76+
{
77+
label: (
78+
<Layout cols={1} gap={6}>
79+
<Heading appearance="H6">Submitted Date</Heading>
80+
<Text size="small">Jul 04, 2020 at 09:00 AM</Text>
81+
<Box marginTop={3}>
82+
<Heading appearance="H6">Website Url</Heading>
83+
</Box>
84+
<Box>
85+
<TextButton size="small">www.mycurrentlywebsite.com</TextButton>
86+
</Box>
87+
</Layout>
88+
),
89+
},
90+
];
91+
92+
return (
93+
<Card>
94+
<Card.Content>
95+
<Timeline items={items} />
96+
</Card.Content>
97+
</Card>
98+
);
99+
};
100+
`;

src/Timeline/docs/index.story.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ export default {
6363
text: 'A simple example with compact preview',
6464
source: examples.simple,
6565
}),
66+
67+
example({
68+
title: 'Custom Content',
69+
text:
70+
"Component's label allows to insert any content to build custom layouts.",
71+
source: examples.customExample,
72+
}),
6673
],
6774
}),
6875

src/Timeline/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as React from 'react';
22

33
export interface TimelineItem {
4-
label: string;
4+
label: React.ReactNode;
55
labelAction?: React.ReactNode;
66
customPrefix?: React.ReactNode;
77
suffix?: React.ReactNode | string;

src/Timeline/test/Timeline.spec.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,19 @@ describe(Timeline.displayName, () => {
2727
expect(await driver.getLabelText(0)).toEqual(items[0].label);
2828
});
2929

30+
it('should render the provided `label` node', async () => {
31+
const items = [
32+
{
33+
label: <div data-hook="label-node">timeline item number 1</div>,
34+
},
35+
];
36+
const { driver } = render(<Timeline items={items} />);
37+
38+
expect(
39+
!!(await driver.element()).querySelector('[data-hook="label-node"]'),
40+
).toBe(true);
41+
});
42+
3043
it('should render timeline with text suffix', async () => {
3144
const items = [
3245
{

src/Timeline/test/Timeline.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,20 @@ function timelineWithMandatoryProps() {
1111
}
1212

1313
function timelineWithAllProps() {
14-
return <Timeline dataHook="dataHook" className="className" items={[]} />;
14+
return (
15+
<Timeline
16+
dataHook="dataHook"
17+
className="className"
18+
items={[
19+
{
20+
label: <div>label</div>,
21+
labelAction: <div>labelAction</div>,
22+
customPrefix: <div>customPrefix</div>,
23+
suffix: <div>suffix</div>,
24+
}
25+
]}
26+
/>
27+
)
1528
}
1629

1730
async function testkits() {

0 commit comments

Comments
 (0)