@times-components/ts-components 1.18.3 → 1.19.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -0
- package/dist/components/article-flag/LiveArticleFlag.js +5 -4
- package/dist/components/article-flag/styles.d.ts +2 -2
- package/dist/components/article-flag/styles.js +5 -5
- package/dist/components/article-header/ArticleHeader.d.ts +7 -0
- package/dist/components/article-header/ArticleHeader.js +32 -0
- package/dist/components/article-header/ArticleHeader.stories.d.ts +1 -0
- package/dist/components/article-header/ArticleHeader.stories.js +33 -0
- package/dist/components/article-header/__tests__/ArticleHeader.test.d.ts +1 -0
- package/dist/components/article-header/__tests__/ArticleHeader.test.js +126 -0
- package/dist/components/article-header/styles.d.ts +16 -0
- package/dist/components/article-header/styles.js +78 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -1
- package/package.json +16 -15
- package/rnw.js +1 -1
- package/src/components/article-flag/LiveArticleFlag.tsx +6 -4
- package/src/components/article-flag/__tests__/__snapshots__/LiveArticleFlag.test.tsx.snap +24 -18
- package/src/components/article-flag/styles.ts +5 -4
- package/src/components/article-header/ArticleHeader.stories.tsx +50 -0
- package/src/components/article-header/ArticleHeader.tsx +83 -0
- package/src/components/article-header/__tests__/ArticleHeader.test.tsx +183 -0
- package/src/components/article-header/__tests__/__snapshots__/ArticleHeader.test.tsx.snap +106 -0
- package/src/components/article-header/styles.ts +88 -0
- package/src/index.ts +4 -0
|
@@ -7,14 +7,16 @@ exports[`LiveArticleFlag should render the base live article flag 1`] = `
|
|
|
7
7
|
class="sc-bwzfXH WFEid"
|
|
8
8
|
>
|
|
9
9
|
<div
|
|
10
|
-
class="sc-bxivhb
|
|
10
|
+
class="sc-bxivhb fnsGfe"
|
|
11
11
|
>
|
|
12
|
-
|
|
12
|
+
■
|
|
13
13
|
</div>
|
|
14
|
-
<div
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
<div>
|
|
15
|
+
<span
|
|
16
|
+
class="sc-EHOje jboioV"
|
|
17
|
+
>
|
|
18
|
+
BASE
|
|
19
|
+
</span>
|
|
18
20
|
</div>
|
|
19
21
|
</div>
|
|
20
22
|
</div>
|
|
@@ -28,14 +30,16 @@ exports[`LiveArticleFlag should render the breaking article flag 1`] = `
|
|
|
28
30
|
class="sc-bwzfXH WFEid"
|
|
29
31
|
>
|
|
30
32
|
<div
|
|
31
|
-
class="sc-bxivhb
|
|
33
|
+
class="sc-bxivhb fnsGfe"
|
|
32
34
|
>
|
|
33
|
-
|
|
35
|
+
■
|
|
34
36
|
</div>
|
|
35
|
-
<div
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
<div>
|
|
38
|
+
<span
|
|
39
|
+
class="sc-EHOje jboioV"
|
|
40
|
+
>
|
|
41
|
+
BREAKING
|
|
42
|
+
</span>
|
|
39
43
|
</div>
|
|
40
44
|
</div>
|
|
41
45
|
</div>
|
|
@@ -49,14 +53,16 @@ exports[`LiveArticleFlag should render the live article flag 1`] = `
|
|
|
49
53
|
class="sc-bwzfXH WFEid"
|
|
50
54
|
>
|
|
51
55
|
<div
|
|
52
|
-
class="sc-bxivhb
|
|
56
|
+
class="sc-bxivhb fnsGfe"
|
|
53
57
|
>
|
|
54
|
-
|
|
58
|
+
■
|
|
55
59
|
</div>
|
|
56
|
-
<div
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
<div>
|
|
61
|
+
<span
|
|
62
|
+
class="sc-EHOje jboioV"
|
|
63
|
+
>
|
|
64
|
+
LIVE
|
|
65
|
+
</span>
|
|
60
66
|
</div>
|
|
61
67
|
</div>
|
|
62
68
|
</div>
|
|
@@ -23,10 +23,10 @@ export const ArticleFlagBullet = styled.div`
|
|
|
23
23
|
background-color: ${({ color }) => gqlRgbaToStyle(color) || color};
|
|
24
24
|
`;
|
|
25
25
|
|
|
26
|
-
export const
|
|
27
|
-
margin-right:
|
|
26
|
+
export const LiveIconContainer = styled.div`
|
|
27
|
+
margin-right: 8px;
|
|
28
28
|
color: #ffffff;
|
|
29
|
-
|
|
29
|
+
align-self: self-start;
|
|
30
30
|
`;
|
|
31
31
|
|
|
32
32
|
export const ArticleFlagTextContainer = styled.div`
|
|
@@ -38,7 +38,8 @@ export const ArticleFlagTextContainer = styled.div`
|
|
|
38
38
|
margin-left: 5px;
|
|
39
39
|
color: ${({ color }) => gqlRgbaToStyle(color) || color};
|
|
40
40
|
`;
|
|
41
|
-
|
|
41
|
+
|
|
42
|
+
export const LiveArticleFlagText = styled.span`
|
|
42
43
|
font-family: ${fonts.supporting};
|
|
43
44
|
color: #ffffff;
|
|
44
45
|
font-weight: 500;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { storiesOf } from '@storybook/react';
|
|
3
|
+
import { date, select, text } from '@storybook/addon-knobs';
|
|
4
|
+
|
|
5
|
+
import { ArticleHarness } from '../../fixtures/article-harness/ArticleHarness';
|
|
6
|
+
import ArticleHeader from './ArticleHeader';
|
|
7
|
+
|
|
8
|
+
storiesOf('Typescript Component/Article Header', module)
|
|
9
|
+
.addDecorator((storyFn: () => React.ReactNode) => (
|
|
10
|
+
<ArticleHarness>{storyFn()}</ArticleHarness>
|
|
11
|
+
))
|
|
12
|
+
.add('Article Header with headline', () => {
|
|
13
|
+
const label = 'Updated Date/Time';
|
|
14
|
+
const defaultValue = new Date();
|
|
15
|
+
const groupId = 'Options';
|
|
16
|
+
const value = date(label, defaultValue, groupId);
|
|
17
|
+
const breakingOptions = {
|
|
18
|
+
True: 'true',
|
|
19
|
+
False: undefined
|
|
20
|
+
};
|
|
21
|
+
const updated = new Date(value).toISOString();
|
|
22
|
+
|
|
23
|
+
const headline = text('Headline', 'This is the headline', groupId);
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<ArticleHeader
|
|
27
|
+
updated={updated}
|
|
28
|
+
breaking={select('Breaking', breakingOptions, undefined, groupId)}
|
|
29
|
+
headline={encodeURIComponent(headline)}
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
32
|
+
})
|
|
33
|
+
.add('Article Header without headline', () => {
|
|
34
|
+
const label = 'Updated Date/Time';
|
|
35
|
+
const defaultValue = new Date();
|
|
36
|
+
const groupId = 'Options';
|
|
37
|
+
const value = date(label, defaultValue, groupId);
|
|
38
|
+
const breakingOptions = {
|
|
39
|
+
True: 'true',
|
|
40
|
+
False: undefined
|
|
41
|
+
};
|
|
42
|
+
const updated = new Date(value).toISOString();
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<ArticleHeader
|
|
46
|
+
updated={updated}
|
|
47
|
+
breaking={select('Breaking', breakingOptions, undefined, groupId)}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
format,
|
|
4
|
+
differenceInSeconds,
|
|
5
|
+
differenceInCalendarDays,
|
|
6
|
+
formatDistanceStrict
|
|
7
|
+
} from 'date-fns';
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
Container,
|
|
11
|
+
Divider,
|
|
12
|
+
Headline,
|
|
13
|
+
TimeSincePublishing,
|
|
14
|
+
TimeSincePublishingContainer,
|
|
15
|
+
UpdatedDate,
|
|
16
|
+
UpdatedTime,
|
|
17
|
+
UpdatedTimeItems,
|
|
18
|
+
UpdatesContainer,
|
|
19
|
+
FlagContainer
|
|
20
|
+
} from './styles';
|
|
21
|
+
import { BreakingArticleFlag } from '../article-flag/LiveArticleFlag';
|
|
22
|
+
|
|
23
|
+
const ArticleHeader: React.FC<{
|
|
24
|
+
updated: string;
|
|
25
|
+
breaking?: string;
|
|
26
|
+
headline?: string;
|
|
27
|
+
}> = ({ updated, breaking, headline }) => {
|
|
28
|
+
const currentDateTime = new Date();
|
|
29
|
+
const updatedDate = new Date(updated);
|
|
30
|
+
const timeSincePublishing =
|
|
31
|
+
formatDistanceStrict(updatedDate, currentDateTime, {
|
|
32
|
+
roundingMethod: 'floor'
|
|
33
|
+
}) + ' ago';
|
|
34
|
+
const diffInSeconds = differenceInSeconds(currentDateTime, updatedDate);
|
|
35
|
+
|
|
36
|
+
const isLessThan1Minute = diffInSeconds < 60;
|
|
37
|
+
const isLessThan1Hour = diffInSeconds < 60 * 60;
|
|
38
|
+
const isLessThan13Hours = diffInSeconds < 60 * 60 * 13;
|
|
39
|
+
const isDaysAgo = differenceInCalendarDays(currentDateTime, updatedDate) >= 1;
|
|
40
|
+
|
|
41
|
+
const isBreaking = breaking
|
|
42
|
+
? Boolean(breaking.toLowerCase() === 'true')
|
|
43
|
+
: false;
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<Container isBreaking={isBreaking && isLessThan1Hour}>
|
|
47
|
+
<UpdatesContainer>
|
|
48
|
+
<UpdatedTimeItems>
|
|
49
|
+
{isBreaking && isLessThan1Hour ? (
|
|
50
|
+
<FlagContainer>
|
|
51
|
+
<BreakingArticleFlag />
|
|
52
|
+
</FlagContainer>
|
|
53
|
+
) : null}
|
|
54
|
+
{!isLessThan1Minute && isLessThan13Hours ? (
|
|
55
|
+
<TimeSincePublishingContainer>
|
|
56
|
+
<TimeSincePublishing
|
|
57
|
+
isBreaking={isBreaking}
|
|
58
|
+
data-testId="TimeSincePublishing"
|
|
59
|
+
>
|
|
60
|
+
{timeSincePublishing}
|
|
61
|
+
</TimeSincePublishing>
|
|
62
|
+
<Divider />
|
|
63
|
+
</TimeSincePublishingContainer>
|
|
64
|
+
) : null}
|
|
65
|
+
<UpdatedTime
|
|
66
|
+
isLessThan13Hours={!isLessThan1Minute && isLessThan13Hours}
|
|
67
|
+
data-testId="UpdatedTime"
|
|
68
|
+
>
|
|
69
|
+
{format(updatedDate, 'h.mmaaa')}
|
|
70
|
+
</UpdatedTime>
|
|
71
|
+
</UpdatedTimeItems>
|
|
72
|
+
{isDaysAgo ? (
|
|
73
|
+
<UpdatedDate data-testid="UpdatedDate">
|
|
74
|
+
{format(updatedDate, 'MMMM d yyyy')}
|
|
75
|
+
</UpdatedDate>
|
|
76
|
+
) : null}
|
|
77
|
+
</UpdatesContainer>
|
|
78
|
+
{headline && <Headline>{decodeURI(headline)}</Headline>}
|
|
79
|
+
</Container>
|
|
80
|
+
);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export default ArticleHeader;
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render } from '@testing-library/react';
|
|
3
|
+
import '@testing-library/jest-dom';
|
|
4
|
+
|
|
5
|
+
import ArticleHeader from '../ArticleHeader';
|
|
6
|
+
import MockDate from 'mockdate';
|
|
7
|
+
|
|
8
|
+
describe('ArticleHeader', () => {
|
|
9
|
+
describe('In one calendar day', () => {
|
|
10
|
+
const updated = '2021-12-31T06:30:00Z';
|
|
11
|
+
afterEach(() => MockDate.reset());
|
|
12
|
+
it('Within the first minute of update - Breaking', () => {
|
|
13
|
+
MockDate.set('2021-12-31T06:30:00Z');
|
|
14
|
+
const { baseElement, getByText, queryByTestId } = render(
|
|
15
|
+
<ArticleHeader
|
|
16
|
+
updated={updated}
|
|
17
|
+
breaking="true"
|
|
18
|
+
headline="This%20is%20the%20headline"
|
|
19
|
+
/>
|
|
20
|
+
);
|
|
21
|
+
expect(baseElement).toMatchSnapshot();
|
|
22
|
+
expect(getByText('BREAKING')).toBeVisible();
|
|
23
|
+
expect(queryByTestId('UpdatedTime')).toBeTruthy();
|
|
24
|
+
expect(getByText('6.30am')).toBeVisible();
|
|
25
|
+
expect(queryByTestId('TimeSincePublishing')).toBeFalsy();
|
|
26
|
+
expect(queryByTestId('UpdatedDate')).toBeFalsy();
|
|
27
|
+
expect(getByText('This is the headline')).toBeVisible();
|
|
28
|
+
});
|
|
29
|
+
it('Within the first minute of update - Not Breaking', () => {
|
|
30
|
+
MockDate.set('2021-12-31T06:30:00Z');
|
|
31
|
+
const { baseElement, getByText, queryByTestId, queryByText } = render(
|
|
32
|
+
<ArticleHeader
|
|
33
|
+
updated={updated}
|
|
34
|
+
breaking="false"
|
|
35
|
+
headline="This%20is%20the%20headline"
|
|
36
|
+
/>
|
|
37
|
+
);
|
|
38
|
+
expect(baseElement).toMatchSnapshot();
|
|
39
|
+
expect(queryByText('BREAKING')).toBeFalsy();
|
|
40
|
+
expect(queryByTestId('UpdatedTime')).toBeTruthy();
|
|
41
|
+
expect(getByText('6.30am')).toBeVisible();
|
|
42
|
+
expect(queryByTestId('TimeSincePublishing')).toBeFalsy();
|
|
43
|
+
expect(queryByTestId('UpdatedDate')).toBeFalsy();
|
|
44
|
+
expect(getByText('This is the headline')).toBeVisible();
|
|
45
|
+
});
|
|
46
|
+
it('Within the first minute of update - No headline not breaking', () => {
|
|
47
|
+
MockDate.set('2021-12-31T06:30:00Z');
|
|
48
|
+
const { baseElement, getByText, queryByTestId, queryByText } = render(
|
|
49
|
+
<ArticleHeader updated={updated} />
|
|
50
|
+
);
|
|
51
|
+
expect(baseElement).toMatchSnapshot();
|
|
52
|
+
expect(queryByText('This is the headline')).toBeFalsy();
|
|
53
|
+
expect(queryByText('BREAKING')).toBeFalsy();
|
|
54
|
+
expect(queryByTestId('UpdatedTime')).toBeTruthy();
|
|
55
|
+
expect(getByText('6.30am')).toBeVisible();
|
|
56
|
+
expect(queryByTestId('TimeSincePublishing')).toBeFalsy();
|
|
57
|
+
expect(queryByTestId('UpdatedDate')).toBeFalsy();
|
|
58
|
+
});
|
|
59
|
+
it('within an hour of updating', () => {
|
|
60
|
+
MockDate.set('2021-12-31T07:00:00Z');
|
|
61
|
+
const { getByText, queryByTestId } = render(
|
|
62
|
+
<ArticleHeader
|
|
63
|
+
updated={updated}
|
|
64
|
+
breaking="true"
|
|
65
|
+
headline="This%20is%20the%20headline"
|
|
66
|
+
/>
|
|
67
|
+
);
|
|
68
|
+
expect(getByText('BREAKING')).toBeVisible();
|
|
69
|
+
expect(queryByTestId('UpdatedTime')).toBeTruthy();
|
|
70
|
+
expect(getByText('6.30am')).toBeVisible();
|
|
71
|
+
expect(queryByTestId('TimeSincePublishing')).toBeTruthy();
|
|
72
|
+
expect(getByText('30 minutes ago')).toBeVisible();
|
|
73
|
+
expect(queryByTestId('UpdatedDate')).toBeFalsy();
|
|
74
|
+
expect(getByText('This is the headline')).toBeVisible();
|
|
75
|
+
});
|
|
76
|
+
it('between 1 and 12 hours after update time', () => {
|
|
77
|
+
MockDate.set('2021-12-31T08:30:00Z');
|
|
78
|
+
const { getByText, queryByTestId, queryByText } = render(
|
|
79
|
+
<ArticleHeader
|
|
80
|
+
updated={updated}
|
|
81
|
+
breaking="true"
|
|
82
|
+
headline="This%20is%20the%20headline"
|
|
83
|
+
/>
|
|
84
|
+
);
|
|
85
|
+
expect(queryByText('BREAKING')).toBeFalsy();
|
|
86
|
+
expect(queryByTestId('UpdatedTime')).toBeTruthy();
|
|
87
|
+
expect(getByText('6.30am')).toBeVisible();
|
|
88
|
+
expect(queryByTestId('TimeSincePublishing')).toBeTruthy();
|
|
89
|
+
expect(getByText('2 hours ago')).toBeVisible();
|
|
90
|
+
expect(queryByTestId('UpdatedDate')).toBeFalsy();
|
|
91
|
+
expect(getByText('This is the headline')).toBeVisible();
|
|
92
|
+
});
|
|
93
|
+
it('after 12 hours but on the same calendar day', () => {
|
|
94
|
+
MockDate.set('2021-12-31T19:30:00Z');
|
|
95
|
+
const { getByText, queryByTestId, queryByText } = render(
|
|
96
|
+
<ArticleHeader
|
|
97
|
+
updated={updated}
|
|
98
|
+
breaking="true"
|
|
99
|
+
headline="This%20is%20the%20headline"
|
|
100
|
+
/>
|
|
101
|
+
);
|
|
102
|
+
expect(queryByText('BREAKING')).toBeFalsy();
|
|
103
|
+
expect(queryByTestId('UpdatedTime')).toBeTruthy();
|
|
104
|
+
expect(getByText('6.30am')).toBeVisible();
|
|
105
|
+
expect(queryByTestId('TimeSincePublishing')).toBeFalsy();
|
|
106
|
+
expect(queryByTestId('UpdatedDate')).toBeFalsy();
|
|
107
|
+
expect(getByText('This is the headline')).toBeVisible();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
describe('Across calendar days', () => {
|
|
111
|
+
const updated = '2021-12-31T23:30:00Z';
|
|
112
|
+
afterEach(() => MockDate.reset());
|
|
113
|
+
it('within an hour of updating but on a different calendar day', () => {
|
|
114
|
+
MockDate.set('2022-01-01T00:29:00Z');
|
|
115
|
+
const { getByTestId, queryByTestId, getByText } = render(
|
|
116
|
+
<ArticleHeader
|
|
117
|
+
updated={updated}
|
|
118
|
+
breaking="true"
|
|
119
|
+
headline="This%20is%20the%20headline"
|
|
120
|
+
/>
|
|
121
|
+
);
|
|
122
|
+
expect(getByText('BREAKING')).toBeVisible();
|
|
123
|
+
expect(queryByTestId('UpdatedTime')).toBeTruthy();
|
|
124
|
+
expect(getByText('11.30pm')).toBeVisible();
|
|
125
|
+
expect(getByTestId('TimeSincePublishing')).toBeTruthy();
|
|
126
|
+
expect(getByTestId('UpdatedDate')).toBeVisible();
|
|
127
|
+
expect(getByText('December 31 2021')).toBeVisible();
|
|
128
|
+
expect(getByText('This is the headline')).toBeVisible();
|
|
129
|
+
});
|
|
130
|
+
it('between 1-12 hours of updating but on a different calendar day', () => {
|
|
131
|
+
MockDate.set('2022-01-01T02:00:00Z');
|
|
132
|
+
const { getByTestId, queryByText, queryByTestId, getByText } = render(
|
|
133
|
+
<ArticleHeader
|
|
134
|
+
updated={updated}
|
|
135
|
+
breaking="true"
|
|
136
|
+
headline="This%20is%20the%20headline"
|
|
137
|
+
/>
|
|
138
|
+
);
|
|
139
|
+
expect(queryByText('BREAKING')).toBeFalsy();
|
|
140
|
+
expect(queryByTestId('UpdatedTime')).toBeTruthy();
|
|
141
|
+
expect(getByText('11.30pm')).toBeVisible();
|
|
142
|
+
expect(getByTestId('TimeSincePublishing')).toBeTruthy();
|
|
143
|
+
expect(getByText('2 hours ago')).toBeVisible();
|
|
144
|
+
expect(getByTestId('UpdatedDate')).toBeVisible();
|
|
145
|
+
expect(getByText('December 31 2021')).toBeVisible();
|
|
146
|
+
expect(getByText('This is the headline')).toBeVisible();
|
|
147
|
+
});
|
|
148
|
+
it('after 12 hours but on a different calendar day', () => {
|
|
149
|
+
MockDate.set('2022-01-01T14:30:00Z');
|
|
150
|
+
const { getByTestId, queryByText, queryByTestId, getByText } = render(
|
|
151
|
+
<ArticleHeader
|
|
152
|
+
updated={updated}
|
|
153
|
+
breaking="true"
|
|
154
|
+
headline="This%20is%20the%20headline"
|
|
155
|
+
/>
|
|
156
|
+
);
|
|
157
|
+
expect(queryByText('BREAKING')).toBeFalsy();
|
|
158
|
+
expect(queryByTestId('UpdatedTime')).toBeTruthy();
|
|
159
|
+
expect(getByText('11.30pm')).toBeVisible();
|
|
160
|
+
expect(queryByTestId('TimeSincePublishing')).toBeFalsy();
|
|
161
|
+
expect(getByTestId('UpdatedDate')).toBeVisible();
|
|
162
|
+
expect(getByText('December 31 2021')).toBeVisible();
|
|
163
|
+
expect(getByText('This is the headline')).toBeVisible();
|
|
164
|
+
});
|
|
165
|
+
it('after multiple calendar days', () => {
|
|
166
|
+
MockDate.set('2022-01-03T14:30:00Z');
|
|
167
|
+
const { getByTestId, queryByText, queryByTestId, getByText } = render(
|
|
168
|
+
<ArticleHeader
|
|
169
|
+
updated={updated}
|
|
170
|
+
breaking="true"
|
|
171
|
+
headline="This%20is%20the%20headline"
|
|
172
|
+
/>
|
|
173
|
+
);
|
|
174
|
+
expect(queryByText('BREAKING')).toBeFalsy();
|
|
175
|
+
expect(queryByTestId('UpdatedTime')).toBeTruthy();
|
|
176
|
+
expect(getByText('11.30pm')).toBeVisible();
|
|
177
|
+
expect(queryByTestId('TimeSincePublishing')).toBeFalsy();
|
|
178
|
+
expect(getByTestId('UpdatedDate')).toBeVisible();
|
|
179
|
+
expect(getByText('December 31 2021')).toBeVisible();
|
|
180
|
+
expect(getByText('This is the headline')).toBeVisible();
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
});
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`ArticleHeader In one calendar day Within the first minute of update - Breaking 1`] = `
|
|
4
|
+
<body>
|
|
5
|
+
<div>
|
|
6
|
+
<div
|
|
7
|
+
class="sc-bdVaJa cQBRMp"
|
|
8
|
+
>
|
|
9
|
+
<div
|
|
10
|
+
class="sc-bwzfXH htoLMg"
|
|
11
|
+
>
|
|
12
|
+
<div
|
|
13
|
+
class="sc-ifAKCX iDsMnF"
|
|
14
|
+
>
|
|
15
|
+
<div
|
|
16
|
+
class="sc-dnqmqq bGasAc"
|
|
17
|
+
>
|
|
18
|
+
<div
|
|
19
|
+
class="sc-gZMcBi bcfOTp"
|
|
20
|
+
>
|
|
21
|
+
<div
|
|
22
|
+
class="sc-VigVT bvOrBW"
|
|
23
|
+
>
|
|
24
|
+
■
|
|
25
|
+
</div>
|
|
26
|
+
<div>
|
|
27
|
+
<span
|
|
28
|
+
class="sc-fjdhpX cvtGYv"
|
|
29
|
+
>
|
|
30
|
+
BREAKING
|
|
31
|
+
</span>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
<div
|
|
36
|
+
class="sc-EHOje cDoFHw"
|
|
37
|
+
data-testid="UpdatedTime"
|
|
38
|
+
>
|
|
39
|
+
6.30am
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
<h2
|
|
44
|
+
class="sc-htoDjs ccbbfo"
|
|
45
|
+
>
|
|
46
|
+
This is the headline
|
|
47
|
+
</h2>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</body>
|
|
51
|
+
`;
|
|
52
|
+
|
|
53
|
+
exports[`ArticleHeader In one calendar day Within the first minute of update - No headline not breaking 1`] = `
|
|
54
|
+
<body>
|
|
55
|
+
<div>
|
|
56
|
+
<div
|
|
57
|
+
class="sc-bdVaJa fLcQHz"
|
|
58
|
+
>
|
|
59
|
+
<div
|
|
60
|
+
class="sc-bwzfXH htoLMg"
|
|
61
|
+
>
|
|
62
|
+
<div
|
|
63
|
+
class="sc-ifAKCX iDsMnF"
|
|
64
|
+
>
|
|
65
|
+
<div
|
|
66
|
+
class="sc-EHOje cDoFHw"
|
|
67
|
+
data-testid="UpdatedTime"
|
|
68
|
+
>
|
|
69
|
+
6.30am
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</body>
|
|
76
|
+
`;
|
|
77
|
+
|
|
78
|
+
exports[`ArticleHeader In one calendar day Within the first minute of update - Not Breaking 1`] = `
|
|
79
|
+
<body>
|
|
80
|
+
<div>
|
|
81
|
+
<div
|
|
82
|
+
class="sc-bdVaJa fLcQHz"
|
|
83
|
+
>
|
|
84
|
+
<div
|
|
85
|
+
class="sc-bwzfXH htoLMg"
|
|
86
|
+
>
|
|
87
|
+
<div
|
|
88
|
+
class="sc-ifAKCX iDsMnF"
|
|
89
|
+
>
|
|
90
|
+
<div
|
|
91
|
+
class="sc-EHOje cDoFHw"
|
|
92
|
+
data-testid="UpdatedTime"
|
|
93
|
+
>
|
|
94
|
+
6.30am
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
<h2
|
|
99
|
+
class="sc-htoDjs ccbbfo"
|
|
100
|
+
>
|
|
101
|
+
This is the headline
|
|
102
|
+
</h2>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
</body>
|
|
106
|
+
`;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import styled, { css } from 'styled-components';
|
|
2
|
+
import { breakpoints, colours, fonts } from '@times-components/styleguide';
|
|
3
|
+
|
|
4
|
+
export const Container = styled.div<{ isBreaking: boolean }>`
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
justify-content: center;
|
|
8
|
+
margin: 48px 10px 24px 10px;
|
|
9
|
+
padding-top: ${({ isBreaking }) => (isBreaking ? '8px' : '5px')};
|
|
10
|
+
border-top: 2px solid #9f0000;
|
|
11
|
+
|
|
12
|
+
@media (min-width: ${breakpoints.medium}px) {
|
|
13
|
+
width: 80.8%;
|
|
14
|
+
margin: 64px 0 24px 10%;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@media (min-width: ${breakpoints.wide}px) {
|
|
18
|
+
width: 56.2%;
|
|
19
|
+
margin: 64px 0 24px 22%;
|
|
20
|
+
}
|
|
21
|
+
`;
|
|
22
|
+
|
|
23
|
+
export const UpdatesContainer = styled.div`
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: row;
|
|
26
|
+
justify-content: space-between;
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
export const TimeSincePublishingContainer = styled.div`
|
|
30
|
+
display: flex;
|
|
31
|
+
flex-direction: row;
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
export const TimeSincePublishing = styled.div<{ isBreaking?: boolean }>`
|
|
35
|
+
color: ${colours.functional.brandColour};
|
|
36
|
+
font-family: ${fonts.supporting};
|
|
37
|
+
font-size: 14px;
|
|
38
|
+
line-height: 18px;
|
|
39
|
+
`;
|
|
40
|
+
|
|
41
|
+
const updatedStyle = css`
|
|
42
|
+
color: ${colours.functional.secondary};
|
|
43
|
+
font-family: ${fonts.supporting};
|
|
44
|
+
font-size: 14px;
|
|
45
|
+
line-height: 18px;
|
|
46
|
+
`;
|
|
47
|
+
|
|
48
|
+
export const UpdatedTimeItems = styled.div`
|
|
49
|
+
display: flex;
|
|
50
|
+
justify-content: space-between;
|
|
51
|
+
align-items: baseline;
|
|
52
|
+
`;
|
|
53
|
+
|
|
54
|
+
export const UpdatedTime = styled.div<{ isLessThan13Hours?: boolean }>`
|
|
55
|
+
${updatedStyle};
|
|
56
|
+
`;
|
|
57
|
+
|
|
58
|
+
export const UpdatedDate = styled.div`
|
|
59
|
+
${updatedStyle} justify-content: end;
|
|
60
|
+
padding: 0 4px 0 0;
|
|
61
|
+
`;
|
|
62
|
+
|
|
63
|
+
export const Divider = styled.div`
|
|
64
|
+
background-color: ${colours.functional.greyLabel};
|
|
65
|
+
width: 1px;
|
|
66
|
+
margin: 2px 8px 6px 12px;
|
|
67
|
+
`;
|
|
68
|
+
|
|
69
|
+
export const Headline = styled.h2`
|
|
70
|
+
color: ${colours.functional.brandColour};
|
|
71
|
+
font-family: ${fonts.headline};
|
|
72
|
+
font-size: 28px;
|
|
73
|
+
line-height: 28px;
|
|
74
|
+
margin-top: 22px;
|
|
75
|
+
margin-bottom: 0px;
|
|
76
|
+
font-weight: 400;
|
|
77
|
+
|
|
78
|
+
@media (min-width: ${breakpoints.medium}px) {
|
|
79
|
+
font-size: 36px;
|
|
80
|
+
line-height: 36px;
|
|
81
|
+
margin-top: 20px;
|
|
82
|
+
margin-bottom: 0px;
|
|
83
|
+
}
|
|
84
|
+
`;
|
|
85
|
+
|
|
86
|
+
export const FlagContainer = styled.div`
|
|
87
|
+
margin-right: 8px;
|
|
88
|
+
`;
|
package/src/index.ts
CHANGED
|
@@ -83,3 +83,7 @@ export { HiddenDiv } from './components/common-styles';
|
|
|
83
83
|
export { InlineMessage } from './components/inline-message/InlineMessage';
|
|
84
84
|
|
|
85
85
|
export { InlineDialog } from './components/inline-dialog/InlineDialog';
|
|
86
|
+
|
|
87
|
+
export {
|
|
88
|
+
default as ArticleHeader
|
|
89
|
+
} from './components/article-header/ArticleHeader';
|