@times-design-system/components-react 0.1.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 (54) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +11 -0
  3. package/__tests__/wordpress.test.js +0 -0
  4. package/dist/AdContainer/AdContainer.d.ts +9 -0
  5. package/dist/Article/ArticleMetaContainer/ArticleMetaContainer.d.ts +8 -0
  6. package/dist/Article/UpNextArticles/UpNextArticles.d.ts +13 -0
  7. package/dist/Button/Button.d.ts +15 -0
  8. package/dist/CommentsDisabled/CommentsDisabled.d.ts +10 -0
  9. package/dist/CommentsDisabled/CommentsDisabled.stories.d.ts +44 -0
  10. package/dist/CommentsDisabled/index.d.ts +2 -0
  11. package/dist/Divider/Divider.d.ts +15 -0
  12. package/dist/Input/Input.d.ts +25 -0
  13. package/dist/Link/Link.d.ts +18 -0
  14. package/dist/Text/Text.d.ts +14 -0
  15. package/dist/index.cjs.js +299 -0
  16. package/dist/index.cjs.js.map +1 -0
  17. package/dist/index.js +289 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/styles.css +151 -0
  20. package/dist/typographyStyles.css +30 -0
  21. package/dist/utils/cn.d.ts +1 -0
  22. package/dist/utils/hooks.d.ts +8 -0
  23. package/lib/wordpress.js +7 -0
  24. package/package.json +43 -0
  25. package/rollup.config.js +58 -0
  26. package/src/AdContainer/AdContainer.tsx +31 -0
  27. package/src/AdContainer/styles.css +58 -0
  28. package/src/Article/ArticleMetaContainer/ArticleMetaContainer.tsx +14 -0
  29. package/src/Article/ArticleMetaContainer/styles.css +151 -0
  30. package/src/Article/UpNextArticles/UpNextArticles.tsx +69 -0
  31. package/src/Article/UpNextArticles/styles.css +151 -0
  32. package/src/Button/Button.tsx +36 -0
  33. package/src/Button/styles.css +30 -0
  34. package/src/CommentsDisabled/CommentsDisabled.stories.tsx +178 -0
  35. package/src/CommentsDisabled/CommentsDisabled.tsx +63 -0
  36. package/src/CommentsDisabled/IMPLEMENTATION_SUMMARY.md +305 -0
  37. package/src/CommentsDisabled/README.md +284 -0
  38. package/src/CommentsDisabled/TOKEN_MAPPING.md +269 -0
  39. package/src/CommentsDisabled/index.ts +2 -0
  40. package/src/CommentsDisabled/styles.css +85 -0
  41. package/src/Divider/Divider.tsx +41 -0
  42. package/src/Divider/styles.css +80 -0
  43. package/src/Input/Input.tsx +62 -0
  44. package/src/Input/styles.css +69 -0
  45. package/src/Link/Link.tsx +49 -0
  46. package/src/Link/styles.css +111 -0
  47. package/src/Text/Text.tsx +38 -0
  48. package/src/Text/styles.css +30 -0
  49. package/src/Text/typographyStyles.css +30 -0
  50. package/src/index.js +13 -0
  51. package/src/utils/cn.js +3 -0
  52. package/src/utils/cn.tsx +3 -0
  53. package/src/utils/hooks.ts +34 -0
  54. package/tsconfig.json +116 -0
@@ -0,0 +1,30 @@
1
+ .storybook-button {
2
+ display: inline-block;
3
+ cursor: pointer;
4
+ border: 0;
5
+ border-radius: 3em;
6
+ font-weight: 700;
7
+ line-height: 1;
8
+ font-family: 'Roboto', 'Roboto-Regular', Helvetica, Arial, sans-serif;
9
+ }
10
+ .storybook-button--primary {
11
+ background-color: #555ab9;
12
+ color: white;
13
+ }
14
+ .storybook-button--secondary {
15
+ box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset;
16
+ background-color: transparent;
17
+ color: #333;
18
+ }
19
+ .storybook-button--small {
20
+ padding: 10px 16px;
21
+ font-size: 12px;
22
+ }
23
+ .storybook-button--medium {
24
+ padding: 11px 20px;
25
+ font-size: 14px;
26
+ }
27
+ .storybook-button--large {
28
+ padding: 12px 24px;
29
+ font-size: 16px;
30
+ }
@@ -0,0 +1 @@
1
+ export declare const cn: (...classNames: (string | undefined)[]) => string;
@@ -0,0 +1,8 @@
1
+ type UseTypographyToken = (typographyToken: string, tokens: {
2
+ breakpoints: {
3
+ [key: string]: number;
4
+ };
5
+ [key: string]: any;
6
+ }) => string;
7
+ export declare const useTypographyToken: UseTypographyToken;
8
+ export {};
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ module.exports = wordpress;
4
+
5
+ function wordpress() {
6
+ return 'Hello from wordpress';
7
+ }
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@times-design-system/components-react",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Times Design System components",
6
+ "keywords": [],
7
+ "author": "douglasmik <michael@viaverso.co.uk>",
8
+ "license": "ISC",
9
+ "main": "dist/index",
10
+ "dev": "src/index",
11
+ "directories": {
12
+ "lib": "lib",
13
+ "test": "__tests__"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/newsuk/times-design-system.git"
18
+ },
19
+ "scripts": {
20
+ "build": "npm run clean && npm run build:rollup",
21
+ "build:rollup": "rollup -c",
22
+ "clean": "rimraf dist",
23
+ "dev": "rollup -c --watch",
24
+ "prepublishOnly": "npm run build",
25
+ "test": "node ./__tests__/*.test.js"
26
+ },
27
+ "bugs": {
28
+ "url": "https://github.com/newsuk/times-design-system/issues"
29
+ },
30
+ "homepage": "https://github.com/newsuk/times-design-system#readme",
31
+ "publishConfig": {
32
+ "access": "public"
33
+ },
34
+ "devDependencies": {
35
+ "@babel/core": "^7.23.0",
36
+ "@babel/preset-env": "^7.23.0",
37
+ "@babel/preset-react": "^7.22.0",
38
+ "@types/react": "19.2.5",
39
+ "postcss": "^8.4.31",
40
+ "typescript": "^5.0.0"
41
+ },
42
+ "gitHead": "f7917d08adf531af85f6a0b0df2d137052a62de0"
43
+ }
@@ -0,0 +1,58 @@
1
+ import babel from '@rollup/plugin-babel';
2
+ import resolve from '@rollup/plugin-node-resolve';
3
+ import commonjs from '@rollup/plugin-commonjs';
4
+ import typescript from '@rollup/plugin-typescript';
5
+ import json from '@rollup/plugin-json';
6
+ import postcss from 'rollup-plugin-postcss';
7
+ import copy from 'rollup-plugin-copy';
8
+
9
+ export default {
10
+ input: 'src/index.js',
11
+ output: [
12
+ {
13
+ file: 'dist/index.js',
14
+ format: 'es',
15
+ sourcemap: true
16
+ },
17
+ {
18
+ file: 'dist/index.cjs.js',
19
+ format: 'cjs',
20
+ sourcemap: true
21
+ }
22
+ ],
23
+ plugins: [
24
+ resolve({
25
+ extensions: ['.js', '.jsx', '.ts', '.tsx']
26
+ }),
27
+ commonjs(),
28
+ json(),
29
+ typescript({
30
+ tsconfig: './tsconfig.json',
31
+ declaration: true,
32
+ declarationDir: 'dist'
33
+ }),
34
+ postcss({
35
+ extract: false, // Inject CSS into JS
36
+ inject: true, // Inject CSS into the head
37
+ minimize: true,
38
+ sourceMap: true,
39
+ modules: {
40
+ generateScopedName: '[name]__[local]___[hash:base64:5]'
41
+ },
42
+ use: {
43
+ sass: {
44
+ data: `@import "src/styles/variables.scss";` // Global SCSS variables
45
+ }
46
+ }
47
+ }),
48
+ babel({
49
+ babelHelpers: 'bundled',
50
+ exclude: 'node_modules/**',
51
+ extensions: ['.js', '.jsx', '.ts', '.tsx']
52
+ }),
53
+ copy({
54
+ targets: [{ src: 'src/**/*.css', dest: 'dist', flatten: false }]
55
+ })
56
+ ],
57
+ external: ['react', 'react-dom'] // Don't bundle React
58
+ };
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+ import { Text } from '../Text/Text';
3
+ import './styles.css';
4
+
5
+ interface AdContainerProps {
6
+ type?: 'header' | 'inline';
7
+ slotID?: string;
8
+ }
9
+
10
+ /** Primary AdContainer UI component for user interaction */
11
+
12
+ export const AdContainer: React.FC<AdContainerProps> = ({
13
+ type = 'inline',
14
+ slotID
15
+ }) => {
16
+ return (
17
+ <div
18
+ className={`ad-${type}-container`}
19
+ data-testid={`ad-${type}-container`}
20
+ >
21
+ {type === 'inline' && (
22
+ <Text as="span" classes="ad-label">
23
+ Advertisement
24
+ </Text>
25
+ )}
26
+ <div className={`ad-${type}-wrapper`}>
27
+ <div id={type === 'header' ? 'ad-header' : slotID}></div>
28
+ </div>
29
+ </div>
30
+ );
31
+ };
@@ -0,0 +1,58 @@
1
+ .ad-inline-container {
2
+ clear: both;
3
+ width: 100%;
4
+ min-height: 283px;
5
+ margin: 30px 0;
6
+ box-sizing: content-box;
7
+ padding: 0 0 10px;
8
+ border-bottom: 1px solid rgb(78, 78, 78);
9
+ }
10
+ @media (min-width: 768px) and (max-width: 1023px) {
11
+ .ad-inline-container {
12
+ min-height: 123px;
13
+ }
14
+ }
15
+
16
+ .ad-inline-container .ad-label {
17
+ border-bottom: 1px solid rgb(78, 78, 78);
18
+ color: rgb(204, 204, 204);
19
+ flex: 1 1 100%;
20
+ font: 14px/17px "TimesDigitalW04-Regular", "TimesDigitalW04-Regular-fallback", serif;
21
+ letter-spacing: 0.6px;
22
+ margin: 0 0 10px;
23
+ padding: 0 0 5px;
24
+ text-align: center;
25
+ text-transform: uppercase;
26
+ display: block;
27
+ }
28
+
29
+ .ad-header {
30
+ display: flex;
31
+ padding-block: 10px 10px;
32
+ margin-left: 0 !important;
33
+ margin-right: 0 !important;
34
+ max-width: 100%;
35
+ border-width: 0 0 1px;
36
+ border-style: solid;
37
+ border-color: var(--wp--preset--color--grey, #dbdbdb);
38
+ flex-direction: column;
39
+ }
40
+ .ad-header-wrapper {
41
+ min-height: 50px;
42
+ align-items: center;
43
+ flex: 1 1 0%;
44
+ display: flex;
45
+ flex-direction: column;
46
+ justify-content: center;
47
+ margin-bottom: 0;
48
+ }
49
+ @media (min-width: 768px) {
50
+ .ad-header-wrapper {
51
+ min-height: 90px;
52
+ }
53
+ }
54
+ @media (min-width: 1024px) {
55
+ .ad-header-wrapper {
56
+ min-height: 250px;
57
+ }
58
+ }
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import './styles.css';
3
+
4
+ interface ArticleMetaProps {
5
+ children?: React.ReactNode;
6
+ }
7
+
8
+ /** Primary ArticleMeta UI component for user interaction */
9
+
10
+ export const ArticleMetaContainer: React.FC<ArticleMetaProps> = ({
11
+ children
12
+ }) => {
13
+ return <div className="article-meta-container">{children}</div>;
14
+ };
@@ -0,0 +1,151 @@
1
+ .video-article-container .video-article-up-next {
2
+ width: 100%;
3
+ background-color: rgb(29, 29, 27);
4
+ position: relative;
5
+ }
6
+ .video-article-container .video-article-up-next * {
7
+ width: 100%;
8
+ }
9
+ @media (min-width: 1024px) {
10
+ .video-article-container .video-article-up-next {
11
+ background-color: unset;
12
+ flex-shrink: 0;
13
+ width: 220px;
14
+ order: 0;
15
+ }
16
+ }
17
+ @media (min-width: 1320px) {
18
+ .video-article-container .video-article-up-next {
19
+ width: 270px;
20
+ }
21
+ }
22
+ .video-article-container .video-article-up-next .vertical-divider {
23
+ display: none;
24
+ }
25
+ @media (min-width: 768px) {
26
+ .video-article-container .video-article-up-next .vertical-divider {
27
+ position: absolute;
28
+ display: block;
29
+ height: 100%;
30
+ width: 1px;
31
+ background-color: #222;
32
+ margin: 0 32px;
33
+ left: -48px;
34
+ }
35
+ }
36
+
37
+ .up-next-articles-container {
38
+ padding: 20px;
39
+ position: relative;
40
+ }
41
+ @media (min-width: 768px) {
42
+ .up-next-articles-container {
43
+ padding: 24px;
44
+ }
45
+ }
46
+ @media (min-width: 1024px) {
47
+ .up-next-articles-container {
48
+ padding: 0;
49
+ }
50
+ }
51
+ .up-next-articles-container .up-next-article-image {
52
+ padding-bottom: 56.25%;
53
+ position: relative;
54
+ overflow: hidden;
55
+ background-color: #333;
56
+ }
57
+ .up-next-articles-container .up-next-article-image picture {
58
+ display: block;
59
+ position: absolute;
60
+ top: 0;
61
+ left: 0;
62
+ width: 100%;
63
+ }
64
+ .up-next-articles-container .up-next-article-image img {
65
+ max-width: 100%;
66
+ }
67
+ .up-next-articles-container .up-next-articles-overlay {
68
+ display: none;
69
+ }
70
+ @media (max-width: 1023px) {
71
+ .up-next-articles-container .up-next-articles-overlay {
72
+ position: absolute;
73
+ top: 0;
74
+ right: 0;
75
+ height: 100%;
76
+ width: 75px;
77
+ z-index: 1;
78
+ }
79
+ }
80
+ .up-next-articles-container .up-next-articles-overlay.up-next-articles-overlay-left {
81
+ left: 0;
82
+ background-image: linear-gradient(to right, rgb(29, 29, 27), transparent);
83
+ }
84
+ .up-next-articles-container .up-next-articles-overlay.up-next-articles-overlay-right {
85
+ right: 0;
86
+ background-image: linear-gradient(to left, rgb(29, 29, 27), transparent);
87
+ }
88
+ .up-next-articles-container.show-left-overlay .up-next-articles-overlay-left, .up-next-articles-container.show-right-overlay .up-next-articles-overlay-right {
89
+ display: flex;
90
+ }
91
+ .up-next-articles-container .up-next-articles-scroll {
92
+ overflow-x: auto;
93
+ position: relative;
94
+ scrollbar-width: none;
95
+ }
96
+ .up-next-articles-container .up-next-articles {
97
+ display: grid;
98
+ grid-template-columns: repeat(4, minmax(156px, 1fr));
99
+ -moz-column-gap: 24px;
100
+ column-gap: 24px;
101
+ }
102
+ @media (min-width: 1024px) {
103
+ .up-next-articles-container .up-next-articles {
104
+ gap: 24px 0;
105
+ grid-template-columns: 1fr;
106
+ }
107
+ }
108
+ .up-next-articles-container .up-next-articles .up-next-article {
109
+ display: flex;
110
+ flex-direction: column;
111
+ gap: 8px;
112
+ position: relative;
113
+ }
114
+ .up-next-articles-container .up-next-articles .up-next-article:not(:last-child)::after {
115
+ content: "";
116
+ position: absolute;
117
+ background-color: #222;
118
+ z-index: 1;
119
+ height: 100%;
120
+ width: 1px;
121
+ right: -12px;
122
+ }
123
+ @media (min-width: 1024px) {
124
+ .up-next-articles-container .up-next-articles .up-next-article:not(:last-child)::after {
125
+ height: 1px;
126
+ width: 100%;
127
+ left: 0;
128
+ bottom: -12px;
129
+ }
130
+ }
131
+ .up-next-articles-container .up-next-articles .up-next-article .up-next-article-image-container {
132
+ position: relative;
133
+ margin-bottom: 12px;
134
+ }
135
+ .up-next-articles-container .up-next-articles .up-next-article .up-next-article-image-container .up-next-article-duration {
136
+ z-index: 2;
137
+ bottom: 0;
138
+ left: 10px;
139
+ position: absolute;
140
+ }
141
+ .up-next-articles-container .up-next-articles .up-next-article .up-next-article-image-container .up-next-article-image-overlay {
142
+ bottom: 0;
143
+ position: absolute;
144
+ width: 100%;
145
+ height: 50%;
146
+ background: linear-gradient(to top, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0) 100%);
147
+ z-index: 1;
148
+ }
149
+ .up-next-articles-container .up-next-articles .up-next-article .up-next-article-image-container .up-next-article-image-container:hover .up-next-article-image-overlay {
150
+ opacity: 1;
151
+ }
@@ -0,0 +1,69 @@
1
+ import React from 'react';
2
+ import { Text } from '../../Text/Text';
3
+ import './styles.css';
4
+
5
+ interface UpNextArticlesProps {
6
+ upNextArticles: {
7
+ url: string;
8
+ headline: string;
9
+ duration?: string;
10
+ thumbnail: string;
11
+ }[];
12
+ }
13
+
14
+ /** Primary UpNextArticles UI component for user interaction */
15
+
16
+ export const UpNextArticles: React.FC<UpNextArticlesProps> = ({
17
+ upNextArticles
18
+ }) => {
19
+ if (!upNextArticles || upNextArticles.length === 0) {
20
+ return;
21
+ }
22
+
23
+ return (
24
+ <div className="video-article-up-next">
25
+ <div className="vertical-divider"></div>
26
+ <div className="up-next-articles-container show-right-overlay">
27
+ <Text as="h4" classes="video-heading video-category">
28
+ Up Next
29
+ </Text>
30
+ <div className="up-next-articles-overlay up-next-articles-overlay-left"></div>
31
+ <div className="up-next-articles-scroll">
32
+ <div className="up-next-articles">
33
+ {upNextArticles.map((up_next_article, index) => (
34
+ <div className="up-next-article" key={index}>
35
+ <a href={up_next_article.url}>
36
+ <div className="up-next-article-image-container">
37
+ <Text classes="up-next-article-duration video-heading">
38
+ {up_next_article.duration}
39
+ </Text>
40
+ <div className="up-next-article-image-overlay"></div>
41
+ <div className="up-next-article-image">
42
+ {up_next_article.thumbnail !== '' && (
43
+ <picture>
44
+ <source
45
+ srcSet={up_next_article.thumbnail}
46
+ type="image/webp"
47
+ />
48
+ <img
49
+ loading="lazy"
50
+ src={up_next_article.thumbnail}
51
+ alt={up_next_article.headline}
52
+ />
53
+ </picture>
54
+ )}
55
+ </div>
56
+ </div>
57
+ <Text as="span" classes="article-heading">
58
+ {up_next_article.headline}
59
+ </Text>
60
+ </a>
61
+ </div>
62
+ ))}
63
+ </div>
64
+ </div>
65
+ <div className="up-next-articles-overlay up-next-articles-overlay-right"></div>
66
+ </div>
67
+ </div>
68
+ );
69
+ };
@@ -0,0 +1,151 @@
1
+ .video-article-container .video-article-up-next {
2
+ width: 100%;
3
+ background-color: rgb(29, 29, 27);
4
+ position: relative;
5
+ }
6
+ .video-article-container .video-article-up-next * {
7
+ width: 100%;
8
+ }
9
+ @media (min-width: 1024px) {
10
+ .video-article-container .video-article-up-next {
11
+ background-color: unset;
12
+ flex-shrink: 0;
13
+ width: 220px;
14
+ order: 0;
15
+ }
16
+ }
17
+ @media (min-width: 1320px) {
18
+ .video-article-container .video-article-up-next {
19
+ width: 270px;
20
+ }
21
+ }
22
+ .video-article-container .video-article-up-next .vertical-divider {
23
+ display: none;
24
+ }
25
+ @media (min-width: 768px) {
26
+ .video-article-container .video-article-up-next .vertical-divider {
27
+ position: absolute;
28
+ display: block;
29
+ height: 100%;
30
+ width: 1px;
31
+ background-color: #222;
32
+ margin: 0 32px;
33
+ left: -48px;
34
+ }
35
+ }
36
+
37
+ .up-next-articles-container {
38
+ padding: 20px;
39
+ position: relative;
40
+ }
41
+ @media (min-width: 768px) {
42
+ .up-next-articles-container {
43
+ padding: 24px;
44
+ }
45
+ }
46
+ @media (min-width: 1024px) {
47
+ .up-next-articles-container {
48
+ padding: 0;
49
+ }
50
+ }
51
+ .up-next-articles-container .up-next-article-image {
52
+ padding-bottom: 56.25%;
53
+ position: relative;
54
+ overflow: hidden;
55
+ background-color: #333;
56
+ }
57
+ .up-next-articles-container .up-next-article-image picture {
58
+ display: block;
59
+ position: absolute;
60
+ top: 0;
61
+ left: 0;
62
+ width: 100%;
63
+ }
64
+ .up-next-articles-container .up-next-article-image img {
65
+ max-width: 100%;
66
+ }
67
+ .up-next-articles-container .up-next-articles-overlay {
68
+ display: none;
69
+ }
70
+ @media (max-width: 1023px) {
71
+ .up-next-articles-container .up-next-articles-overlay {
72
+ position: absolute;
73
+ top: 0;
74
+ right: 0;
75
+ height: 100%;
76
+ width: 75px;
77
+ z-index: 1;
78
+ }
79
+ }
80
+ .up-next-articles-container .up-next-articles-overlay.up-next-articles-overlay-left {
81
+ left: 0;
82
+ background-image: linear-gradient(to right, rgb(29, 29, 27), transparent);
83
+ }
84
+ .up-next-articles-container .up-next-articles-overlay.up-next-articles-overlay-right {
85
+ right: 0;
86
+ background-image: linear-gradient(to left, rgb(29, 29, 27), transparent);
87
+ }
88
+ .up-next-articles-container.show-left-overlay .up-next-articles-overlay-left, .up-next-articles-container.show-right-overlay .up-next-articles-overlay-right {
89
+ display: flex;
90
+ }
91
+ .up-next-articles-container .up-next-articles-scroll {
92
+ overflow-x: auto;
93
+ position: relative;
94
+ scrollbar-width: none;
95
+ }
96
+ .up-next-articles-container .up-next-articles {
97
+ display: grid;
98
+ grid-template-columns: repeat(4, minmax(156px, 1fr));
99
+ -moz-column-gap: 24px;
100
+ column-gap: 24px;
101
+ }
102
+ @media (min-width: 1024px) {
103
+ .up-next-articles-container .up-next-articles {
104
+ gap: 24px 0;
105
+ grid-template-columns: 1fr;
106
+ }
107
+ }
108
+ .up-next-articles-container .up-next-articles .up-next-article {
109
+ display: flex;
110
+ flex-direction: column;
111
+ gap: 8px;
112
+ position: relative;
113
+ }
114
+ .up-next-articles-container .up-next-articles .up-next-article:not(:last-child)::after {
115
+ content: "";
116
+ position: absolute;
117
+ background-color: #222;
118
+ z-index: 1;
119
+ height: 100%;
120
+ width: 1px;
121
+ right: -12px;
122
+ }
123
+ @media (min-width: 1024px) {
124
+ .up-next-articles-container .up-next-articles .up-next-article:not(:last-child)::after {
125
+ height: 1px;
126
+ width: 100%;
127
+ left: 0;
128
+ bottom: -12px;
129
+ }
130
+ }
131
+ .up-next-articles-container .up-next-articles .up-next-article .up-next-article-image-container {
132
+ position: relative;
133
+ margin-bottom: 12px;
134
+ }
135
+ .up-next-articles-container .up-next-articles .up-next-article .up-next-article-image-container .up-next-article-duration {
136
+ z-index: 2;
137
+ bottom: 0;
138
+ left: 10px;
139
+ position: absolute;
140
+ }
141
+ .up-next-articles-container .up-next-articles .up-next-article .up-next-article-image-container .up-next-article-image-overlay {
142
+ bottom: 0;
143
+ position: absolute;
144
+ width: 100%;
145
+ height: 50%;
146
+ background: linear-gradient(to top, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0) 100%);
147
+ z-index: 1;
148
+ }
149
+ .up-next-articles-container .up-next-articles .up-next-article .up-next-article-image-container .up-next-article-image-container:hover .up-next-article-image-overlay {
150
+ opacity: 1;
151
+ }
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import './styles.css';
3
+
4
+ interface ButtonProps {
5
+ /** Is this the principal call to action on the page? */
6
+ primary?: boolean;
7
+ /** How large should the button be? */
8
+ size?: 'small' | 'medium' | 'large';
9
+ /** Button contents */
10
+ label: string;
11
+ /** Optional click handler */
12
+ onClick?: () => void;
13
+ }
14
+
15
+ /** Primary UI component for user interaction */
16
+ export const Button: React.FC<ButtonProps> = ({
17
+ primary,
18
+ size,
19
+ label,
20
+ ...props
21
+ }) => {
22
+ const mode = primary
23
+ ? 'storybook-button--primary'
24
+ : 'storybook-button--secondary';
25
+ return (
26
+ <button
27
+ type="button"
28
+ className={['storybook-button', `storybook-button--${size}`, mode].join(
29
+ ' '
30
+ )}
31
+ {...props}
32
+ >
33
+ {label}
34
+ </button>
35
+ );
36
+ };
@@ -0,0 +1,30 @@
1
+ .storybook-button {
2
+ display: inline-block;
3
+ cursor: pointer;
4
+ border: 0;
5
+ border-radius: 3em;
6
+ font-weight: 700;
7
+ line-height: 1;
8
+ font-family: 'Roboto', 'Helvetica Neue', Helvetica, Arial, sans-serif;
9
+ }
10
+ .storybook-button--primary {
11
+ background-color: #555ab9;
12
+ color: white;
13
+ }
14
+ .storybook-button--secondary {
15
+ box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset;
16
+ background-color: transparent;
17
+ color: #333;
18
+ }
19
+ .storybook-button--small {
20
+ padding: 10px 16px;
21
+ font-size: 12px;
22
+ }
23
+ .storybook-button--medium {
24
+ padding: 11px 20px;
25
+ font-size: 14px;
26
+ }
27
+ .storybook-button--large {
28
+ padding: 12px 24px;
29
+ font-size: 16px;
30
+ }