@times-components/ts-components 1.21.0 → 1.22.0

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/components/article-flag/ArticleFlag.stories.js +21 -3
  3. package/dist/components/article-flag/LiveArticleFlag.js +13 -6
  4. package/dist/components/article-flag/styles.d.ts +1 -0
  5. package/dist/components/article-flag/styles.js +6 -1
  6. package/dist/components/updated-timestamp/UpdatedTimestamp.d.ts +4 -0
  7. package/dist/components/updated-timestamp/UpdatedTimestamp.js +21 -0
  8. package/dist/components/updated-timestamp/UpdatedTimestamp.stories.d.ts +1 -0
  9. package/dist/components/updated-timestamp/UpdatedTimestamp.stories.js +13 -0
  10. package/dist/components/updated-timestamp/__tests__/UpdatedTimestamp.test.d.ts +1 -0
  11. package/dist/components/updated-timestamp/__tests__/UpdatedTimestamp.test.js +34 -0
  12. package/dist/components/updated-timestamp/styles.d.ts +2 -0
  13. package/dist/components/updated-timestamp/styles.js +14 -0
  14. package/dist/helpers/time/UpdatedTimeProvider.d.ts +5 -0
  15. package/dist/helpers/time/UpdatedTimeProvider.js +9 -0
  16. package/dist/helpers/time/__tests__/UpdatedTimeProvider.test.d.ts +1 -0
  17. package/dist/helpers/time/__tests__/UpdatedTimeProvider.test.js +17 -0
  18. package/dist/index.d.ts +2 -0
  19. package/dist/index.js +3 -1
  20. package/package.json +5 -5
  21. package/rnw.js +1 -1
  22. package/src/components/article-flag/ArticleFlag.stories.tsx +28 -2
  23. package/src/components/article-flag/LiveArticleFlag.tsx +19 -9
  24. package/src/components/article-flag/__tests__/__snapshots__/ArticleFlag.test.tsx.snap +73 -73
  25. package/src/components/article-flag/__tests__/__snapshots__/LiveArticleFlag.test.tsx.snap +39 -27
  26. package/src/components/article-flag/styles.ts +6 -0
  27. package/src/components/article-header/__tests__/__snapshots__/ArticleHeader.test.tsx.snap +13 -9
  28. package/src/components/updated-timestamp/UpdatedTimestamp.stories.tsx +18 -0
  29. package/src/components/updated-timestamp/UpdatedTimestamp.tsx +38 -0
  30. package/src/components/updated-timestamp/__tests__/UpdatedTimestamp.test.tsx +50 -0
  31. package/src/components/updated-timestamp/__tests__/__snapshots__/UpdatedTimestamp.test.tsx.snap +11 -0
  32. package/src/components/updated-timestamp/styles.ts +15 -0
  33. package/src/helpers/time/UpdatedTimeProvider.tsx +17 -0
  34. package/src/helpers/time/__tests__/UpdatedTimeProvider.test.tsx +23 -0
  35. package/src/index.ts +6 -0
@@ -16,19 +16,23 @@ exports[`ArticleHeader In one calendar day Within the first minute of update - B
16
16
  class="sc-dnqmqq bGasAc"
17
17
  >
18
18
  <div
19
- class="sc-gZMcBi bcfOTp"
19
+ class="sc-gZMcBi erfHmy"
20
20
  >
21
21
  <div
22
- class="sc-VigVT bvOrBW"
22
+ class="sc-gqjmRU fwGLTx"
23
23
  >
24
-
25
- </div>
26
- <div>
27
- <span
28
- class="sc-fjdhpX cvtGYv"
24
+ <div
25
+ class="sc-jTzLTM bTqqzd"
29
26
  >
30
- BREAKING
31
- </span>
27
+
28
+ </div>
29
+ <div>
30
+ <span
31
+ class="sc-jzJRlG erbwEj"
32
+ >
33
+ BREAKING
34
+ </span>
35
+ </div>
32
36
  </div>
33
37
  </div>
34
38
  </div>
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import { storiesOf } from '@storybook/react';
3
+ import { date } from '@storybook/addon-knobs';
4
+
5
+ import { UpdatedTimestamp } from './UpdatedTimestamp';
6
+
7
+ storiesOf('Typescript Component/Updated Timestamp', module).add(
8
+ 'Updated Timestamp',
9
+ () => {
10
+ const label = 'Updated Date/Time';
11
+ const defaultValue = new Date();
12
+ const groupId = 'Options';
13
+ const value = date(label, defaultValue, groupId);
14
+ const updated = new Date(value).toISOString();
15
+
16
+ return <UpdatedTimestamp updatedTime={updated} />;
17
+ }
18
+ );
@@ -0,0 +1,38 @@
1
+ import React from 'react';
2
+ import { differenceInSeconds, format, formatDistanceStrict } from 'date-fns';
3
+
4
+ import { Container, TimeSinceUpdate } from './styles';
5
+
6
+ export const UpdatedTimestamp: React.FC<{
7
+ updatedTime?: string;
8
+ }> = ({ updatedTime }) => {
9
+ if (!updatedTime) {
10
+ return null;
11
+ }
12
+ const currentDateTime = new Date();
13
+ const updatedDate = new Date(updatedTime);
14
+ const timeSincePublishing =
15
+ formatDistanceStrict(updatedDate, currentDateTime, {
16
+ roundingMethod: 'floor'
17
+ }) + ' ago';
18
+ const diffInSeconds = differenceInSeconds(currentDateTime, updatedDate);
19
+
20
+ const isLessThan1Minute = diffInSeconds < 60;
21
+ const isLessThan13Hours = diffInSeconds < 60 * 60 * 13;
22
+
23
+ return (
24
+ <Container>
25
+ {!isLessThan1Minute && isLessThan13Hours ? (
26
+ <TimeSinceUpdate data-testId="MinutesHoursSinceUpdate">
27
+ {`Updated ${timeSincePublishing}`}
28
+ </TimeSinceUpdate>
29
+ ) : !isLessThan13Hours ? (
30
+ <TimeSinceUpdate data-testId="DateTimeUpdated">
31
+ {`Updated `}
32
+ {format(updatedDate, 'MMMM d, ')}
33
+ {format(updatedDate, 'h.mmaaa')}
34
+ </TimeSinceUpdate>
35
+ ) : null}
36
+ </Container>
37
+ );
38
+ };
@@ -0,0 +1,50 @@
1
+ import React from 'react';
2
+ import { render } from '@testing-library/react';
3
+ import '@testing-library/jest-dom';
4
+
5
+ import { UpdatedTimestamp } from '../UpdatedTimestamp';
6
+ import MockDate from 'mockdate';
7
+
8
+ describe('UpdatedTimestamp', () => {
9
+ const updated = '2022-02-28T09:00:00Z';
10
+ afterEach(() => MockDate.reset());
11
+
12
+ it('does not show the timestamp within the first minute after the last update', () => {
13
+ MockDate.set('2022-02-28T09:00:00Z');
14
+ const { baseElement, queryByTestId } = render(
15
+ <UpdatedTimestamp updatedTime={updated} />
16
+ );
17
+ expect(baseElement).toMatchSnapshot();
18
+ expect(queryByTestId('MinutesHoursSinceUpdate')).toBeFalsy();
19
+ });
20
+ it('appears one minute after the last update', () => {
21
+ MockDate.set('2022-02-28T09:01:00Z');
22
+ const { queryByTestId } = render(
23
+ <UpdatedTimestamp updatedTime={updated} />
24
+ );
25
+ expect(queryByTestId('MinutesHoursSinceUpdate')).toBeTruthy();
26
+ expect(queryByTestId('MinutesHoursSinceUpdate')!.textContent).toBe(
27
+ 'Updated 1 minute ago'
28
+ );
29
+ });
30
+ it('appears between 1 and 12 hours after the last update', () => {
31
+ MockDate.set('2022-02-28T11:30:00Z');
32
+ const { queryByTestId } = render(
33
+ <UpdatedTimestamp updatedTime={updated} />
34
+ );
35
+ expect(queryByTestId('MinutesHoursSinceUpdate')).toBeTruthy();
36
+ expect(queryByTestId('MinutesHoursSinceUpdate')!.textContent).toBe(
37
+ 'Updated 2 hours ago'
38
+ );
39
+ });
40
+ it('shows the date and time of update 13 hours or more after the last update', () => {
41
+ MockDate.set('2022-02-28T23:30:00Z');
42
+ const { queryByTestId } = render(
43
+ <UpdatedTimestamp updatedTime={updated} />
44
+ );
45
+ expect(queryByTestId('DateTimeUpdated')).toBeTruthy();
46
+ expect(queryByTestId('DateTimeUpdated')!.textContent).toBe(
47
+ 'Updated February 28, 9.00am'
48
+ );
49
+ });
50
+ });
@@ -0,0 +1,11 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`UpdatedTimestamp does not show the timestamp within the first minute after the last update 1`] = `
4
+ <body>
5
+ <div>
6
+ <div
7
+ class="sc-bdVaJa cSmEjS"
8
+ />
9
+ </div>
10
+ </body>
11
+ `;
@@ -0,0 +1,15 @@
1
+ import styled from 'styled-components';
2
+ import { colours, fonts } from '@times-components/styleguide';
3
+
4
+ export const Container = styled.div`
5
+ display: flex;
6
+ flex-direction: column;
7
+ padding: 3px 0 0 8px;
8
+ `;
9
+
10
+ export const TimeSinceUpdate = styled.div`
11
+ color: ${colours.functional.primary};
12
+ font-family: ${fonts.supporting};
13
+ font-size: 12px;
14
+ line-height: 16px;
15
+ `;
@@ -0,0 +1,17 @@
1
+ import React, { createContext, useContext } from 'react';
2
+
3
+ const UpdatedTimeProviderContext = createContext<string | undefined>(undefined);
4
+
5
+ export const UpdatedTimeProvider: React.FC<{
6
+ updatedTime: string;
7
+ }> = ({ updatedTime, children }) => {
8
+ return (
9
+ <UpdatedTimeProviderContext.Provider value={updatedTime}>
10
+ {children}
11
+ </UpdatedTimeProviderContext.Provider>
12
+ );
13
+ };
14
+
15
+ export const useUpdatedTime = () => {
16
+ return useContext(UpdatedTimeProviderContext);
17
+ };
@@ -0,0 +1,23 @@
1
+ import { render } from '@testing-library/react';
2
+ import React from 'react';
3
+ import { useUpdatedTime, UpdatedTimeProvider } from '../UpdatedTimeProvider';
4
+ import 'regenerator-runtime';
5
+
6
+ const TestComponent = () => {
7
+ const updatedTime = useUpdatedTime();
8
+ return <>{updatedTime}</>;
9
+ };
10
+
11
+ describe('UpdatedTimeProvider', () => {
12
+ it('should pass the updated time to the context value', () => {
13
+ const updatedTime = '2022-03-01T09:00:00.000Z';
14
+
15
+ const { findByText } = render(
16
+ <UpdatedTimeProvider updatedTime={updatedTime}>
17
+ <TestComponent />
18
+ </UpdatedTimeProvider>
19
+ );
20
+
21
+ findByText(updatedTime);
22
+ });
23
+ });
package/src/index.ts CHANGED
@@ -88,6 +88,12 @@ export {
88
88
  default as ArticleHeader
89
89
  } from './components/article-header/ArticleHeader';
90
90
 
91
+ export {
92
+ UpdatedTimestamp
93
+ } from './components/updated-timestamp/UpdatedTimestamp';
94
+
95
+ export { UpdatedTimeProvider } from './helpers/time/UpdatedTimeProvider';
96
+
91
97
  export {
92
98
  default as safeDecodeURIComponent
93
99
  } from './utils/safeDecodeURIComponent';