@times-components/ts-components 1.98.2 → 1.98.3-alpha.15

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 (119) hide show
  1. package/dist/components/article-flag/ArticleFlag.d.ts +1 -4
  2. package/dist/components/article-flag/ArticleFlag.js +1 -1
  3. package/dist/components/article-flag/getActiveFlags.d.ts +1 -1
  4. package/dist/components/article-flag/styles.d.ts +1 -1
  5. package/dist/components/article-flag/types.d.ts +4 -0
  6. package/dist/components/article-flag/types.js +2 -0
  7. package/dist/components/banner/__tests__/banner.test.d.ts +1 -0
  8. package/dist/components/banner/__tests__/banner.test.js +11 -0
  9. package/dist/components/banner/assets/CloseIconBlack.d.ts +3 -0
  10. package/dist/components/banner/assets/CloseIconBlack.js +5 -0
  11. package/dist/components/banner/assets/EmailIcon.d.ts +3 -0
  12. package/dist/components/banner/assets/EmailIcon.js +5 -0
  13. package/dist/components/banner/banner.d.ts +8 -0
  14. package/dist/components/banner/banner.js +17 -0
  15. package/dist/components/banner/styles.d.ts +8 -0
  16. package/dist/components/banner/styles.js +73 -0
  17. package/dist/components/breadcrumb/__tests__/index.test.d.ts +1 -0
  18. package/dist/components/breadcrumb/__tests__/index.test.js +40 -0
  19. package/dist/components/breadcrumb/assets/BreadcrumbIcon.d.ts +2 -0
  20. package/dist/components/breadcrumb/assets/BreadcrumbIcon.js +5 -0
  21. package/dist/components/breadcrumb/breadcrumb.d.ts +9 -0
  22. package/dist/components/breadcrumb/breadcrumb.js +28 -0
  23. package/dist/components/breadcrumb/fixtures/breadcrumbs.json +27 -0
  24. package/dist/components/breadcrumb/styles.d.ts +13 -0
  25. package/dist/components/breadcrumb/styles.js +39 -0
  26. package/dist/components/delayed-component/__tests__/delayed-component.test.d.ts +1 -0
  27. package/dist/components/delayed-component/__tests__/delayed-component.test.js +23 -0
  28. package/dist/components/delayed-component/delayed-component.d.ts +6 -0
  29. package/dist/components/delayed-component/delayed-component.js +11 -0
  30. package/dist/components/in-article-info-card/Card.d.ts +1 -1
  31. package/dist/components/in-article-info-card/InfoCard.d.ts +0 -8
  32. package/dist/components/in-article-info-card/InfoCard.js +1 -1
  33. package/dist/components/in-article-info-card/types.d.ts +8 -0
  34. package/dist/components/in-article-info-card/types.js +2 -0
  35. package/dist/components/job-title/__tests__/index.test.d.ts +1 -0
  36. package/dist/components/job-title/__tests__/index.test.js +45 -0
  37. package/dist/components/job-title/assets/TooltipIcon.d.ts +2 -0
  38. package/dist/components/job-title/assets/TooltipIcon.js +11 -0
  39. package/dist/components/job-title/assets/close-icon.d.ts +2 -0
  40. package/dist/components/job-title/assets/close-icon.js +5 -0
  41. package/dist/components/job-title/job-title.d.ts +11 -0
  42. package/dist/components/job-title/job-title.js +31 -0
  43. package/dist/components/job-title/styles.d.ts +11 -0
  44. package/dist/components/job-title/styles.js +150 -0
  45. package/dist/components/save-star/ContentProvider.d.ts +0 -6
  46. package/dist/components/save-star/ContentProvider.js +1 -1
  47. package/dist/components/save-star/SaveStar.js +1 -1
  48. package/dist/components/save-star/SaveStarUI.d.ts +1 -4
  49. package/dist/components/save-star/SaveStarUI.js +1 -1
  50. package/dist/components/save-star/types.d.ts +8 -0
  51. package/dist/components/save-star/types.js +2 -0
  52. package/dist/components/update-button/__tests__/update-button-with-delay.test.d.ts +1 -0
  53. package/dist/components/update-button/__tests__/update-button-with-delay.test.js +24 -0
  54. package/dist/components/update-button/__tests__/update-button.test.d.ts +1 -0
  55. package/dist/components/update-button/__tests__/update-button.test.js +27 -0
  56. package/dist/components/update-button/assets/FilledArrowIcon.d.ts +3 -0
  57. package/dist/components/update-button/assets/FilledArrowIcon.js +5 -0
  58. package/dist/components/update-button/styles.d.ts +1 -0
  59. package/dist/components/update-button/styles.js +39 -0
  60. package/dist/components/update-button/update-button-with-delay.d.ts +11 -0
  61. package/dist/components/update-button/update-button-with-delay.js +27 -0
  62. package/dist/components/update-button/update-button.d.ts +6 -0
  63. package/dist/components/update-button/update-button.js +9 -0
  64. package/dist/fixtures/article-harness/__tests__/articleHarness.test.d.ts +1 -0
  65. package/dist/fixtures/article-harness/__tests__/articleHarness.test.js +11 -0
  66. package/dist/index.d.ts +7 -2
  67. package/dist/index.js +8 -3
  68. package/jest.config.js +2 -1
  69. package/package.json +17 -16
  70. package/rnw.js +1 -1
  71. package/src/components/article-flag/ArticleFlag.tsx +1 -5
  72. package/src/components/article-flag/getActiveFlags.ts +1 -1
  73. package/src/components/article-flag/styles.ts +1 -1
  74. package/src/components/article-flag/types.ts +4 -0
  75. package/src/components/banner/__tests__/__snapshots__/banner.test.tsx.snap +66 -0
  76. package/src/components/banner/__tests__/banner.test.tsx +13 -0
  77. package/src/components/banner/assets/CloseIconBlack.tsx +24 -0
  78. package/src/components/banner/assets/EmailIcon.tsx +24 -0
  79. package/src/components/banner/banner.stories.mdx +30 -0
  80. package/src/components/banner/banner.tsx +40 -0
  81. package/src/components/banner/styles.ts +80 -0
  82. package/src/components/breadcrumb/__tests__/__snapshots__/index.test.tsx.snap +64 -0
  83. package/src/components/breadcrumb/__tests__/index.test.tsx +51 -0
  84. package/src/components/breadcrumb/assets/BreadcrumbIcon.tsx +16 -0
  85. package/src/components/breadcrumb/breadcrumb.stories.mdx +47 -0
  86. package/src/components/breadcrumb/breadcrumb.tsx +84 -0
  87. package/src/components/breadcrumb/fixtures/breadcrumbs.json +27 -0
  88. package/src/components/breadcrumb/styles.ts +43 -0
  89. package/src/components/delayed-component/__tests__/delayed-component.test.tsx +30 -0
  90. package/src/components/delayed-component/delayed-component.stories.mdx +38 -0
  91. package/src/components/delayed-component/delayed-component.tsx +16 -0
  92. package/src/components/in-article-info-card/Card.tsx +1 -1
  93. package/src/components/in-article-info-card/InfoCard.tsx +1 -8
  94. package/src/components/in-article-info-card/types.ts +8 -0
  95. package/src/components/job-title/__tests__/__snapshots__/index.test.tsx.snap +271 -0
  96. package/src/components/job-title/__tests__/index.test.tsx +71 -0
  97. package/src/components/job-title/assets/TooltipIcon.tsx +37 -0
  98. package/src/components/job-title/assets/close-icon.tsx +18 -0
  99. package/src/components/job-title/job-title.stories.mdx +38 -0
  100. package/src/components/job-title/job-title.tsx +85 -0
  101. package/src/components/job-title/styles.ts +154 -0
  102. package/src/components/save-star/ContentProvider.tsx +1 -7
  103. package/src/components/save-star/SaveStar.tsx +2 -1
  104. package/src/components/save-star/SaveStarUI.tsx +1 -5
  105. package/src/components/save-star/types.ts +9 -0
  106. package/src/components/update-button/__tests__/__snapshots__/update-button-with-delay.test.tsx.snap +23 -0
  107. package/src/components/update-button/__tests__/__snapshots__/update-button.test.tsx.snap +23 -0
  108. package/src/components/update-button/__tests__/update-button-with-delay.test.tsx +67 -0
  109. package/src/components/update-button/__tests__/update-button.test.tsx +31 -0
  110. package/src/components/update-button/assets/FilledArrowIcon.tsx +17 -0
  111. package/src/components/update-button/styles.ts +40 -0
  112. package/src/components/update-button/update-button-with-delay.stories.mdx +40 -0
  113. package/src/components/update-button/update-button-with-delay.tsx +53 -0
  114. package/src/components/update-button/update-button.stories.mdx +32 -0
  115. package/src/components/update-button/update-button.tsx +17 -0
  116. package/src/fixtures/article-harness/__tests__/__snapshots__/articleHarness.test.tsx.snap +34 -0
  117. package/src/fixtures/article-harness/__tests__/articleHarness.test.tsx +11 -0
  118. package/src/index.ts +15 -7
  119. package/tsconfig.json +6 -1
@@ -0,0 +1,154 @@
1
+ import styled from 'styled-components';
2
+
3
+ export const IconButton = styled.button`
4
+ margin: 0;
5
+ padding: 0;
6
+ display: inline-grid;
7
+ column-gap: 8px;
8
+ grid-template-columns: repeat(1, auto);
9
+ width: 32px;
10
+ height: 32px;
11
+ margin-inline-start: 8px;
12
+ padding-inline: 8px;
13
+ padding-block: 8px;
14
+ box-sizing: border-box;
15
+ overflow: hidden;
16
+ border: none;
17
+ appearance: none;
18
+ background-color: #00000000;
19
+ border-radius: 50%;
20
+ color: #333333;
21
+ cursor: pointer;
22
+ `;
23
+
24
+ export const Popover = styled.div`
25
+ position: relative;
26
+ display: inline-block;
27
+ `;
28
+ export const PopoverContext = styled.div<{ isOpen?: boolean }>`
29
+ display: ${({ isOpen }) => (isOpen ? 'grid' : 'none')};
30
+ position: absolute;
31
+ top: -55px;
32
+ left: 4px;
33
+ box-shadow: 0px 20px 32px 0px #11111114;
34
+ border-radius: 0px;
35
+ border-style: none;
36
+ z-index: 80;
37
+
38
+ div {
39
+ margin: 0;
40
+ color: #333333;
41
+ border-radius: 0px;
42
+ background-color: #ffffff;
43
+ white-space: nowrap;
44
+
45
+ display: grid;
46
+ grid-template-areas:
47
+ 'header close'
48
+ 'content content';
49
+ grid-template-columns: 1fr auto;
50
+ grid-template-rows: auto 1fr;
51
+
52
+ /* Pointer Arrow */
53
+ &::after {
54
+ content: '';
55
+ position: absolute;
56
+ -webkit-transform: rotate(45deg);
57
+ -moz-transform: rotate(45deg);
58
+ -ms-transform: rotate(45deg);
59
+ transform: rotate(45deg);
60
+ box-sizing: border-box;
61
+ background-color: #ffffff;
62
+ width: 16px;
63
+ height: 16px;
64
+ left: 12px;
65
+ bottom: calc(-16px / 2);
66
+ }
67
+ }
68
+ `;
69
+
70
+ export const PopoverHeader = styled.div`
71
+ div {
72
+ display: flex;
73
+ grid-area: header;
74
+ align-items: center;
75
+ box-sizing: border-box;
76
+ box-shadow: 0px 20px 32px 0px #11111114;
77
+ border-radius: 0px;
78
+ border-style: none;
79
+ font-family: Roboto;
80
+ font-size: 1.4000000000000001rem;
81
+ line-height: 1.5;
82
+ font-weight: 500;
83
+ letter-spacing: 0em;
84
+ padding-inline: 24px;
85
+ padding-block: 16px;
86
+ }
87
+ `;
88
+
89
+ export const CloseButton = styled.button`
90
+ height: 48px;
91
+ width: 48px;
92
+ border-radius: 50%;
93
+ padding: 16px;
94
+ background-color: transparent;
95
+ border: none;
96
+ outline: none;
97
+ cursor: pointer;
98
+ display: flex;
99
+ justify-content: center;
100
+ align-items: center;
101
+ transition: background-color 0.2s;
102
+ &:focus-visible {
103
+ background-color: #eeeeee;
104
+ border: 1px solid #000;
105
+ }
106
+ &:hover {
107
+ background-color: #eeeeee;
108
+ }
109
+ `;
110
+
111
+ export const Tooltip = styled.div`
112
+ position: relative;
113
+ display: inline-block;
114
+ z-index: 80;
115
+ `;
116
+ export const TooltipContext = styled.div<{ isOpen?: boolean }>`
117
+ display: ${({ isOpen }) => (isOpen ? 'grid' : 'none')};
118
+ position: absolute;
119
+ top: -34px;
120
+ left: 8px;
121
+ grid-template-areas:
122
+ 'header close'
123
+ 'content content';
124
+ grid-template-columns: 1fr auto;
125
+ grid-template-rows: auto 1fr;
126
+
127
+ color: rgb(255, 255, 255);
128
+ background-color: rgb(17, 17, 17);
129
+ font-family: 'Roboto';
130
+ font-size: 14px;
131
+ line-height: 21px;
132
+ font-weight: 500;
133
+ letter-spacing: 0em;
134
+ padding-inline: 8px;
135
+ padding-block: 8px;
136
+ white-space: nowrap;
137
+
138
+ /* Pointer Arrow */
139
+ &::after {
140
+ content: '';
141
+ position: absolute;
142
+ -webkit-transform: rotate(45deg);
143
+ -moz-transform: rotate(45deg);
144
+ -ms-transform: rotate(45deg);
145
+ box-sizing: border-box;
146
+ background-color: #ffffff;
147
+ width: 4px;
148
+ height: 4px;
149
+ left: 14px;
150
+ bottom: calc(-4px / 2);
151
+ box-sizing: border-box;
152
+ background-color: rgb(17, 17, 17);
153
+ }
154
+ `;
@@ -1,12 +1,6 @@
1
1
  import React from 'react';
2
2
  import { useFetch } from '../../helpers/fetch/FetchProvider';
3
- import { ArticleBookmark } from './SaveStarUI';
4
-
5
- export interface ContentProps {
6
- loading?: boolean;
7
- error?: string;
8
- data?: ArticleBookmark;
9
- }
3
+ import { ArticleBookmark, ContentProps } from './types';
10
4
 
11
5
  export const ContentProvider: React.FC = React.memo(({ children }) => {
12
6
  const fetchResponse = useFetch<ArticleBookmark>();
@@ -1,7 +1,8 @@
1
1
  import React, { cloneElement, useCallback, useMemo, useState } from 'react';
2
2
  import { FetchProvider } from '../../helpers/fetch/FetchProvider';
3
- import { SaveStarUI, ArticleBookmark } from './SaveStarUI';
3
+ import { SaveStarUI } from './SaveStarUI';
4
4
  import { ContentProvider } from './ContentProvider';
5
+ import { ArticleBookmark } from './types';
5
6
 
6
7
  export const SaveStar: React.FC<{
7
8
  articleId: string;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { colours } from '@times-components/ts-styleguide';
3
3
  import { IconStar } from '@times-components/icons';
4
- import { ContentProps } from './ContentProvider';
4
+ import { ContentProps } from './types';
5
5
  import {
6
6
  IconContainer,
7
7
  LoadingIcon,
@@ -9,10 +9,6 @@ import {
9
9
  SaveStarButton
10
10
  } from './styles';
11
11
 
12
- export type ArticleBookmark = {
13
- isBookmarked: boolean;
14
- };
15
-
16
12
  const getText = (isSaved: boolean) => (isSaved ? 'Saved' : 'Save');
17
13
 
18
14
  const getIconTitle = (isSaved: boolean) =>
@@ -0,0 +1,9 @@
1
+ export type ArticleBookmark = {
2
+ isBookmarked: boolean;
3
+ };
4
+
5
+ export interface ContentProps {
6
+ loading?: boolean;
7
+ error?: string;
8
+ data?: ArticleBookmark;
9
+ }
@@ -0,0 +1,23 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Render UpdateButtonWithDelay should render the Update button component and the DelayComponent as expected when it has an update 1`] = `
4
+ <DocumentFragment>
5
+ <button
6
+ class="sc-bdVaJa kaAiuV"
7
+ >
8
+ <svg
9
+ data-testid="upward-arrow"
10
+ fill="none"
11
+ height="16"
12
+ width="16"
13
+ xmlns="http://www.w3.org/2000/svg"
14
+ >
15
+ <path
16
+ d="m3.166 8 .94.94 3.727-3.72v8.113h1.333V5.22l3.72 3.727.947-.947-5.334-5.333L3.166 8Z"
17
+ fill="currentcolor"
18
+ />
19
+ </svg>
20
+ New Updates
21
+ </button>
22
+ </DocumentFragment>
23
+ `;
@@ -0,0 +1,23 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Render UpdateButton should render the component 1`] = `
4
+ <DocumentFragment>
5
+ <button
6
+ class="sc-bdVaJa kaAiuV"
7
+ >
8
+ <svg
9
+ data-testid="upward-arrow"
10
+ fill="none"
11
+ height="16"
12
+ width="16"
13
+ xmlns="http://www.w3.org/2000/svg"
14
+ >
15
+ <path
16
+ d="m3.166 8 .94.94 3.727-3.72v8.113h1.333V5.22l3.72 3.727.947-.947-5.334-5.333L3.166 8Z"
17
+ fill="currentcolor"
18
+ />
19
+ </svg>
20
+ New Updates
21
+ </button>
22
+ </DocumentFragment>
23
+ `;
@@ -0,0 +1,67 @@
1
+ import React from 'react';
2
+ import '@testing-library/jest-dom';
3
+ import { render, waitFor } from '@testing-library/react';
4
+ import { UpdateButtonWithDelay } from '../update-button-with-delay';
5
+
6
+ const handleClickMock = jest.fn();
7
+
8
+ const renderComponent = (
9
+ delay: number,
10
+ display: boolean,
11
+ label: string,
12
+ handleClick: any,
13
+ updatedTime: string,
14
+ articleId: string,
15
+ update: boolean
16
+ ) =>
17
+ render(
18
+ <UpdateButtonWithDelay
19
+ delay={delay}
20
+ display={display}
21
+ label={label}
22
+ handleClick={handleClick}
23
+ updatedTime={updatedTime}
24
+ articleId={articleId}
25
+ update={update}
26
+ />
27
+ );
28
+
29
+ describe('Render UpdateButtonWithDelay', () => {
30
+ it('should render the Update button component and the DelayComponent as expected when it has an update', async () => {
31
+ const { asFragment, getByRole, queryByTestId } = renderComponent(
32
+ 800,
33
+ true,
34
+ 'New Updates',
35
+ handleClickMock,
36
+ '2023-10-12T00:00:00.000Z',
37
+ '12345',
38
+ true
39
+ );
40
+ expect(asFragment()).toMatchSnapshot();
41
+ expect(getByRole('button')).toBeVisible();
42
+ await waitFor(() => {
43
+ expect(queryByTestId('button')).toBeFalsy();
44
+ });
45
+ });
46
+
47
+ it('should not render the Update button component and the DelayComponent as expected when it has an update', async () => {
48
+ const { unmount, queryByTestId } = renderComponent(
49
+ 500,
50
+ true,
51
+ 'Update Now',
52
+ handleClickMock,
53
+ '2023-10-12T00:00:00.000Z',
54
+ '12345',
55
+ false
56
+ );
57
+
58
+ await waitFor(
59
+ () => {
60
+ expect(queryByTestId('button')).toBeNull();
61
+ },
62
+ { timeout: 500 }
63
+ );
64
+
65
+ unmount();
66
+ });
67
+ });
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+ import '@testing-library/jest-dom';
3
+ import { render, fireEvent } from '@testing-library/react';
4
+
5
+ import { UpdateButton } from '../update-button';
6
+
7
+ const handleClickMock = jest.fn();
8
+
9
+ const renderComponent = (label: string, handleClick: any) =>
10
+ render(<UpdateButton label={label} handleClick={handleClick} />);
11
+
12
+ describe('Render UpdateButton', () => {
13
+ it('should render the component', () => {
14
+ const { asFragment } = renderComponent('New Updates', handleClickMock);
15
+ expect(asFragment()).toMatchSnapshot();
16
+ });
17
+ it('should render the label text you pass through', () => {
18
+ const { getByText } = renderComponent('Test New Updates', handleClickMock);
19
+ expect(getByText('Test New Updates')).toBeVisible();
20
+ });
21
+ it('should trigger an event on click', () => {
22
+ const { getByRole } = renderComponent('New Update', handleClickMock);
23
+ const Button = getByRole('button');
24
+ fireEvent.click(Button);
25
+ expect(handleClickMock).toHaveBeenCalled();
26
+ });
27
+ it('should render the upward facing arrow icon', () => {
28
+ const { getByTestId } = renderComponent('New Updates', handleClickMock);
29
+ expect(getByTestId('upward-arrow')).toBeVisible();
30
+ });
31
+ });
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+
3
+ const FilledArrowIcon: React.FC = (props: any) => (
4
+ <svg
5
+ xmlns="http://www.w3.org/2000/svg"
6
+ width={16}
7
+ height={16}
8
+ fill="none"
9
+ {...props}
10
+ >
11
+ <path
12
+ fill="currentcolor"
13
+ d="m3.166 8 .94.94 3.727-3.72v8.113h1.333V5.22l3.72 3.727.947-.947-5.334-5.333L3.166 8Z"
14
+ />
15
+ </svg>
16
+ );
17
+ export default FilledArrowIcon;
@@ -0,0 +1,40 @@
1
+ import styled from 'styled-components';
2
+
3
+ const styleMap = {
4
+ colors: {
5
+ interactiveNegative040: '#9f0000',
6
+ interactiveNegative050: '#800000',
7
+ inkInverse: '#FFFFFF'
8
+ },
9
+ spacing: {
10
+ space030: '12px',
11
+ space020: '8px'
12
+ }
13
+ };
14
+
15
+ export const StyledButton = styled.button`
16
+ border: none;
17
+ background-color: ${styleMap.colors.interactiveNegative040};
18
+ padding-block: ${styleMap.spacing.space020};
19
+ padding-inline: ${styleMap.spacing.space030};
20
+ font-family: Roboto;
21
+ font-size: 1.4000000000000001rem;
22
+ font-weight: 500;
23
+ letter-spacing: 0em;
24
+ color: ${styleMap.colors.inkInverse};
25
+ display: inline-grid;
26
+ grid-template-columns: repeat(2, auto);
27
+ column-gap: 8px;
28
+ place-content: center;
29
+ place-items: center;
30
+ cursor: pointer;
31
+ transition-property: background-color;
32
+ transition-duration: 200ms;
33
+ transition-timing-function: cubic-bezier(0, 0, 0.5, 1);
34
+ &:hover {
35
+ background-color: ${styleMap.colors.interactiveNegative050};
36
+ }
37
+ &:active {
38
+ background-color: ${styleMap.colors.interactiveNegative050};
39
+ }
40
+ `;
@@ -0,0 +1,40 @@
1
+ import { Meta, Story, Props } from '@storybook/addon-docs'
2
+
3
+ import { UpdateButtonWithDelay } from './update-button-with-delay.tsx';
4
+
5
+ <Meta
6
+ title="Components/Misc/UpdateButtonWithDelay"
7
+ component={UpdateButtonWithDelay}
8
+ />
9
+
10
+ # UpdateButtonWithDelay component
11
+ The `UpdateButtonWithDelay` component is used to highlight when there is an update in an article.
12
+
13
+ The `UpdateButtonWithDelay` component makes use of the `DelayedComponent` which will set the component to mount or unmount given a delay and intial state.
14
+
15
+ This component takes in a six props:
16
+ - `loading` to display the loading spinner.
17
+ - `delay` to determine the delay in milliseconds for mounting or unmounting the component.
18
+ - `display` which will determine if the component initially displays, or is rendered after the delay has passed.
19
+ - `label` this is for the text label in the button.
20
+ - `handleClick` determines the function called on interaction.
21
+ - `arrowUp` this is to render either the upward arrow icon or the downward icon (depending on where in the article the user is vs where the update is).
22
+
23
+ ## Props
24
+ <Props of={UpdateButtonWithDelay} />
25
+
26
+ ## Code Example
27
+ `<UpdateButtonWithDelay display={true} delay={8000} label='New updates', arrowUp={true} updatedTime="2023-12-12T12:00:00.000Z" articleId="12345"/>`
28
+
29
+ ## View Component
30
+ Please click the 'Canvas' tab for a better viewing experience, where you can update the props and review at the different breakpoints by clicking the preview icon and selecting from our list of pre-defined breakpoints (XS, SM, MD, LG and XL).
31
+
32
+ export const UpdateButtonWithDelayStory = ({ display, delay, label, arrowUp, updatedTime, articleId }) => (
33
+ <UpdateButtonWithDelay display={display} delay={delay} label={label} arrowUp={arrowUp} updatedTime={updatedTime} articleId={articleId} update={true}/>
34
+ );
35
+
36
+ <Story name="UpdateButtonWithDelay"
37
+ args={{ display: true, delay: 8000, label: 'New Updates', arrowUp: true, updatedTime: '2023-07-13T12:00:00.000Z', articleId: '12345'} }
38
+ >
39
+ {UpdateButtonWithDelayStory.bind({})}
40
+ </Story>
@@ -0,0 +1,53 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { DelayedComponent } from '../delayed-component/delayed-component';
3
+ import { UpdateButton } from './update-button';
4
+ import fetch from 'isomorphic-unfetch';
5
+
6
+ type UpdateWithDelayProps = {
7
+ display: boolean;
8
+ delay: number;
9
+ label: string;
10
+ handleClick: () => void;
11
+ updatedTime: string;
12
+ articleId: string;
13
+ update: boolean;
14
+ };
15
+
16
+ export const UpdateButtonWithDelay = ({
17
+ delay,
18
+ display,
19
+ label,
20
+ handleClick,
21
+ updatedTime,
22
+ articleId,
23
+ update = false
24
+ }: UpdateWithDelayProps) => {
25
+ const [hasUpdate, setUpdate] = useState(update);
26
+ useEffect(() => {
27
+ const fetchData = async () => {
28
+ try {
29
+ const response = await fetch(`/api/article-update-time/${articleId}`);
30
+ const json = await response.json();
31
+ return json.article.publishedTime;
32
+ } catch (err) {
33
+ // tslint:disable-next-line:no-console
34
+ console.log(err);
35
+ }
36
+ };
37
+ const interval = setInterval(async () => {
38
+ (await fetchData()) > updatedTime && setUpdate(true);
39
+ }, 120000);
40
+
41
+ return () => clearInterval(interval);
42
+ }, []);
43
+
44
+ return (
45
+ <>
46
+ {hasUpdate ? (
47
+ <DelayedComponent delay={delay} initialState={display}>
48
+ <UpdateButton label={label} handleClick={handleClick} />
49
+ </DelayedComponent>
50
+ ) : null}
51
+ </>
52
+ );
53
+ };
@@ -0,0 +1,32 @@
1
+ import { Meta, Story, Props } from '@storybook/addon-docs'
2
+
3
+ import { UpdateButton } from './update-button.tsx';
4
+
5
+ <Meta
6
+ title="Components/Misc/UpdateButton"
7
+ component={UpdateButton}
8
+ />
9
+
10
+ # UpdateButton component
11
+ The `UpdateButton` component is used to highlight when there is an update.
12
+
13
+ This component takes in a two props, loading to display the loading spinner, arrowUp - determines the position of the arrow Icon, label - which determines the text content of the button, and handleClick which is the function called upon clicking the button.
14
+
15
+ ## Props
16
+ <Props of={UpdateButton} />
17
+
18
+ ## Code Example
19
+ `<UpdateButton loading={loading} label='New updates', arrowUp={true}/>`
20
+
21
+ ## View Component
22
+ Please click the 'Canvas' tab for a better viewing experience, where you can update the props and review at the different breakpoints by clicking the preview icon and selecting from our list of pre-defined breakpoints (XS, SM, MD, LG and XL).
23
+
24
+ export const UpdateButtonStory = ({ loading, label, arrowUp }) => (
25
+ <UpdateButton loading={loading} label={label} arrowUp={arrowUp} />
26
+ );
27
+
28
+ <Story name="UpdateButton"
29
+ args={{ loading: false, label: 'New Updates', arrowUp: true} }
30
+ >
31
+ {UpdateButtonStory.bind({})}
32
+ </Story>
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import FilledArrowIcon from './assets/FilledArrowIcon';
3
+ import { StyledButton } from './styles';
4
+
5
+ type UpdateButtonProps = {
6
+ label: string;
7
+ handleClick: () => void;
8
+ };
9
+
10
+ export const UpdateButton = ({ label, handleClick }: UpdateButtonProps) => {
11
+ return (
12
+ <StyledButton onClick={() => handleClick()}>
13
+ <FilledArrowIcon data-testid="upward-arrow" />
14
+ {label}
15
+ </StyledButton>
16
+ );
17
+ };
@@ -0,0 +1,34 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Render ArticleHarness renders the ArticleHarness 1`] = `
4
+ <DocumentFragment>
5
+ <div
6
+ class="sc-bdVaJa glDQbs"
7
+ >
8
+ <div
9
+ class="sc-bwzfXH fBhOFq"
10
+ >
11
+ <div
12
+ class="sc-htpNat sc-bxivhb gakSZq"
13
+ >
14
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eleifend quis purus eget consequat. Maecenas pellentesque lorem at ipsum egestas sagittis. Quisque eget nisi sed diam auctor luctus. Pellentesque rutrum sem nibh, at placerat elit iaculis in. Curabitur nec turpis nec nisi pulvinar pharetra.
15
+ </div>
16
+ <div
17
+ class="sc-htpNat sc-bxivhb gakSZq"
18
+ >
19
+ Aenean hendrerit erat non augue sagittis rhoncus. Praesent diam lacus, vehicula ut ante et, cursus finibus justo. Curabitur sollicitudin turpis nec diam ullamcorper, sed fermentum diam tempor. Integer maximus ultrices sem, eu facilisis magna condimentum ut. Curabitur orci odio, ornare in ipsum quis, cursus scelerisque sem.
20
+ </div>
21
+ <div
22
+ class="sc-htpNat sc-bxivhb gakSZq"
23
+ >
24
+ Maecenas ultricies risus at libero vulputate, non accumsan ex iaculis. In vel facilisis sapien. Nam imperdiet, elit a mattis consectetur, ex purus efficitur eros, nec condimentum mi tortor facilisis orci. Donec sodales felis tortor, ut dignissim turpis rhoncus ut. Quisque lacinia ornare tortor at convallis.
25
+ </div>
26
+ <div
27
+ class="sc-htpNat sc-bxivhb gakSZq"
28
+ >
29
+ Praesent ac elit quis metus vulputate facilisis. Quisque ac dolor eu felis pharetra dignissim. Sed tristique egestas sollicitudin. Nulla varius, risus ornare tristique lobortis, est libero vestibulum diam, nec mollis turpis ligula eget nibh. Praesent facilisis sem lectus, et consectetur sem fringilla non. Pellentesque condimentum est sed nisl porttitor ultricies.
30
+ </div>
31
+ </div>
32
+ </div>
33
+ </DocumentFragment>
34
+ `;
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import '@testing-library/jest-dom';
3
+ import { render } from '@testing-library/react';
4
+ import { ArticleHarness } from '../ArticleHarness';
5
+
6
+ describe('Render ArticleHarness', () => {
7
+ it('renders the ArticleHarness', () => {
8
+ const { asFragment } = render(<ArticleHarness />);
9
+ expect(asFragment()).toMatchSnapshot();
10
+ });
11
+ });
package/src/index.ts CHANGED
@@ -1,4 +1,12 @@
1
1
  // General Components
2
+ export {
3
+ BreakingArticleFlag,
4
+ LiveArticleFlag
5
+ } from './components/article-flag/LiveArticleFlag';
6
+ export {
7
+ TrackingContext,
8
+ TrackingContextProvider
9
+ } from './helpers/tracking/TrackingContextProvider';
2
10
  export { InArticlePuff } from './components/in-article-puff/InArticlePuff';
3
11
  export { InfoCard } from './components/in-article-info-card/InfoCard';
4
12
  export { GalleryCarousel } from './components/carousel/GalleryCarousel';
@@ -6,10 +14,6 @@ export {
6
14
  InfoCardBulletPoints
7
15
  } from './components/in-article-info-card-bulletpoints/InfoCardBulletPoints';
8
16
  export { BigNumbers } from './components/in-article-big-numbers/BigNumbers';
9
- export {
10
- BreakingArticleFlag,
11
- LiveArticleFlag
12
- } from './components/article-flag/LiveArticleFlag';
13
17
  export {
14
18
  ArticleFlag,
15
19
  ArticleFlags,
@@ -21,6 +25,13 @@ export {
21
25
  } from './components/article-flag/ArticleFlag';
22
26
  export { Timelines } from './components/in-article-timelines/Timelines';
23
27
  export { SaveStar } from './components/save-star/SaveStar';
28
+ export { Breadcrumb } from './components/breadcrumb/breadcrumb';
29
+ export { UpdateButton } from './components/update-button/update-button';
30
+ export {
31
+ UpdateButtonWithDelay
32
+ } from './components/update-button/update-button-with-delay';
33
+ export { Banner } from './components/banner/banner';
34
+ export { JobTitle } from './components/job-title/job-title';
24
35
 
25
36
  // Newsletter Components
26
37
  export {
@@ -83,9 +94,6 @@ export { FetchProvider } from './helpers/fetch/FetchProvider';
83
94
  export {
84
95
  ViewCountWrapper
85
96
  } from './helpers/view-count-wrapper/ViewCountWrapper';
86
- export {
87
- TrackingContextProvider
88
- } from './helpers/tracking/TrackingContextProvider';
89
97
 
90
98
  export { HiddenDiv } from './components/common-styles';
91
99
  export { InlineMessage } from './components/inline-message/InlineMessage';
package/tsconfig.json CHANGED
@@ -9,6 +9,7 @@
9
9
  "declaration": true,
10
10
  "inlineSourceMap": true,
11
11
  "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
12
+ "resolveJsonModule": true,
12
13
 
13
14
  "strict": true /* Enable all strict type-checking options. */,
14
15
 
@@ -40,7 +41,11 @@
40
41
 
41
42
  "lib": ["es6", "dom", "es2017", "dom.iterable"],
42
43
  "types": ["jest"],
43
- "typeRoots": ["node_modules/@types", "src/types", "../../node_modules/@types"]
44
+ "typeRoots": [
45
+ "node_modules/@types",
46
+ "src/types",
47
+ "../../node_modules/@types"
48
+ ]
44
49
  },
45
50
  "include": ["src/**/*.ts", "src/**/*.tsx"],
46
51
  "exclude": ["node_modules/**"],