@automattic/vip-design-system 0.9.4 → 0.9.5

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 (42) hide show
  1. package/build/system/Avatar/Avatar.stories.js +23 -8
  2. package/build/system/Badge/Badge.stories.js +25 -8
  3. package/build/system/BlankState/BlankState.stories.js +27 -11
  4. package/build/system/Box/Box.stories.js +25 -8
  5. package/build/system/Button/Button.stories.js +36 -23
  6. package/build/system/Card/Card.stories.js +25 -8
  7. package/build/system/Code/Code.stories.js +25 -8
  8. package/build/system/ConfirmationDialog/ConfirmationDialog.stories.js +45 -22
  9. package/build/system/Dialog/Dialog.stories.js +71 -31
  10. package/build/system/Flex/Flex.stories.js +25 -8
  11. package/build/system/Form/AsyncSearchSelect.js +38 -0
  12. package/build/system/Form/Input.stories.js +23 -8
  13. package/build/system/Form/SearchSelect.js +47 -11
  14. package/build/system/Form/Select.js +21 -2
  15. package/build/system/Form/Select.stories.js +108 -78
  16. package/build/system/Form/Select.test.js +52 -0
  17. package/build/system/Grid/Grid.stories.js +25 -8
  18. package/build/system/Heading/Heading.stories.js +43 -20
  19. package/build/system/Link/Link.stories.js +26 -10
  20. package/build/system/Notice/Notice.stories.js +47 -81
  21. package/build/system/Notification/Notification.stories.js +23 -8
  22. package/build/system/OptionRow/OptionRow.stories.js +36 -20
  23. package/build/system/Progress/Progress.stories.js +23 -8
  24. package/build/system/Spinner/Spinner.stories.js +23 -8
  25. package/build/system/Table/Table.stories.js +64 -42
  26. package/build/system/Tabs/Tabs.stories.js +32 -10
  27. package/build/system/Text/Text.stories.js +25 -8
  28. package/build/system/Timeline/Timeline.js +69 -0
  29. package/build/system/Timeline/Timeline.stories.js +44 -21
  30. package/build/system/Timeline/index.js +2 -66
  31. package/build/system/Tooltip/Tooltip.stories.js +41 -19
  32. package/build/system/Wizard/Wizard.stories.js +65 -37
  33. package/package.json +3 -2
  34. package/src/system/Form/AsyncSearchSelect.js +29 -0
  35. package/src/system/Form/SearchSelect.js +43 -3
  36. package/src/system/Form/Select.js +15 -2
  37. package/src/system/Form/Select.stories.js +30 -0
  38. package/src/system/Form/Select.test.js +37 -0
  39. package/src/system/Timeline/Timeline.js +46 -0
  40. package/src/system/Timeline/Timeline.stories.js +34 -0
  41. package/src/system/Timeline/index.js +2 -41
  42. package/build/system/UsageChart/UsageChart.stories.js +0 -20
@@ -1,29 +1,52 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.Default = exports["default"] = void 0;
5
+
6
+ var _react = _interopRequireDefault(require("react"));
7
+
8
+ var _ = require("..");
9
+
10
+ var _jsxRuntime = require("theme-ui/jsx-runtime");
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
13
+
1
14
  /**
2
15
  * External dependencies
3
16
  */
4
- import React from 'react';
17
+
5
18
  /**
6
19
  * Internal dependencies
7
20
  */
8
-
9
- import { Timeline, Grid, Box } from '..';
10
- export default {
21
+ var _default = {
11
22
  title: 'Timeline',
12
- component: Timeline
23
+ component: _.Timeline
13
24
  };
14
- export var Default = function Default() {
15
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Grid, {
16
- gap: 2,
17
- columns: [2, '100px 300px'],
18
- sx: {
19
- mb: '20px'
20
- }
21
- }, /*#__PURE__*/React.createElement(Timeline, {
22
- time: "7pm"
23
- }), /*#__PURE__*/React.createElement(Box, null, "It looks like everything is recovered now. You can forget about the last event.")), /*#__PURE__*/React.createElement(Grid, {
24
- gap: 2,
25
- columns: [2, '100px 200px']
26
- }, /*#__PURE__*/React.createElement(Timeline, {
27
- time: "6pm"
28
- }), /*#__PURE__*/React.createElement(Box, null, "At this particular moment in the day, something happened with your environment.")));
29
- };
25
+ exports["default"] = _default;
26
+
27
+ var Default = function Default() {
28
+ return (0, _jsxRuntime.jsxs)(_react["default"].Fragment, {
29
+ children: [(0, _jsxRuntime.jsxs)(_.Grid, {
30
+ gap: 2,
31
+ columns: [2, '100px 300px'],
32
+ sx: {
33
+ mb: '20px'
34
+ },
35
+ children: [(0, _jsxRuntime.jsx)(_.Timeline, {
36
+ time: "7pm"
37
+ }), (0, _jsxRuntime.jsx)(_.Box, {
38
+ children: "It looks like everything is recovered now. You can forget about the last event."
39
+ })]
40
+ }), (0, _jsxRuntime.jsxs)(_.Grid, {
41
+ gap: 2,
42
+ columns: [2, '100px 200px'],
43
+ children: [(0, _jsxRuntime.jsx)(_.Timeline, {
44
+ time: "6pm"
45
+ }), (0, _jsxRuntime.jsx)(_.Box, {
46
+ children: "At this particular moment in the day, something happened with your environment."
47
+ })]
48
+ })]
49
+ });
50
+ };
51
+
52
+ exports.Default = Default;
@@ -1,71 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  exports.__esModule = true;
4
- exports.Timeline = void 0;
5
4
 
6
- var _themeUi = require("theme-ui");
5
+ var _Timeline = require("./Timeline");
7
6
 
8
- var _md = require("react-icons/md");
9
-
10
- var _propTypes = _interopRequireDefault(require("prop-types"));
11
-
12
- var _jsxRuntime = require("theme-ui/jsx-runtime");
13
-
14
- var _excluded = ["time", "first", "last"];
15
-
16
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
17
-
18
- function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
19
-
20
- function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
21
-
22
- var VerticalLine = function VerticalLine() {
23
- return (0, _jsxRuntime.jsx)("div", {
24
- sx: {
25
- borderLeft: '2px solid',
26
- borderColor: 'border',
27
- height: 'calc( 50% - 16px )',
28
- borderRadius: '2px'
29
- }
30
- });
31
- };
32
-
33
- var Timeline = function Timeline(_ref) {
34
- var time = _ref.time,
35
- _ref$first = _ref.first,
36
- first = _ref$first === void 0 ? false : _ref$first,
37
- _ref$last = _ref.last,
38
- last = _ref$last === void 0 ? false : _ref$last,
39
- props = _objectWithoutPropertiesLoose(_ref, _excluded);
40
-
41
- return (0, _jsxRuntime.jsxs)(_themeUi.Flex, _extends({}, props, {
42
- children: [(0, _jsxRuntime.jsxs)(_themeUi.Flex, {
43
- sx: {
44
- flexDirection: 'column',
45
- justifyContent: 'space-evenly',
46
- alignItems: 'center'
47
- },
48
- children: [!first && (0, _jsxRuntime.jsx)(VerticalLine, {}), (0, _jsxRuntime.jsx)(_md.MdWatchLater, {
49
- sx: {
50
- color: 'border'
51
- },
52
- size: 18
53
- }), !last && (0, _jsxRuntime.jsx)(VerticalLine, {})]
54
- }), (0, _jsxRuntime.jsx)(_themeUi.Flex, {
55
- sx: {
56
- alignItems: 'center',
57
- ml: 2
58
- },
59
- children: (0, _jsxRuntime.jsx)("span", {
60
- children: time
61
- })
62
- })]
63
- }));
64
- };
65
-
66
- exports.Timeline = Timeline;
67
- Timeline.propTypes = {
68
- first: _propTypes["default"].bool,
69
- time: _propTypes["default"].string,
70
- last: _propTypes["default"].bool
71
- };
7
+ exports.Timeline = _Timeline.Timeline;
@@ -1,29 +1,51 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.Default = exports["default"] = void 0;
5
+
6
+ var _react = _interopRequireDefault(require("react"));
7
+
8
+ var _ = require("..");
9
+
10
+ var _jsxRuntime = require("theme-ui/jsx-runtime");
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
13
+
1
14
  /**
2
15
  * External dependencies
3
16
  */
4
- import React from 'react';
17
+
5
18
  /**
6
19
  * Internal dependencies
7
20
  */
8
-
9
- import { Flex, Heading, Tooltip, Text, Link } from '..';
10
- export default {
21
+ var _default = {
11
22
  title: 'Tooltip',
12
- component: Tooltip
23
+ component: _.Tooltip
13
24
  };
14
- export var Default = function Default() {
15
- return /*#__PURE__*/React.createElement(Flex, {
25
+ exports["default"] = _default;
26
+
27
+ var Default = function Default() {
28
+ return (0, _jsxRuntime.jsxs)(_.Flex, {
16
29
  sx: {
17
30
  alignItems: 'center'
18
- }
19
- }, /*#__PURE__*/React.createElement(Heading, {
20
- sx: {
21
- mb: 0,
22
- mr: 2
23
- }
24
- }, "My Section Heading"), /*#__PURE__*/React.createElement(Tooltip, null, /*#__PURE__*/React.createElement(Text, {
25
- sx: {
26
- fontSize: 1
27
- }
28
- }, "This is a tooltip that can be used to describe various pieces of functionality.", /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(Link, null, "Find out more \u2192"))));
29
- };
31
+ },
32
+ children: [(0, _jsxRuntime.jsx)(_.Heading, {
33
+ sx: {
34
+ mb: 0,
35
+ mr: 2
36
+ },
37
+ children: "My Section Heading"
38
+ }), (0, _jsxRuntime.jsx)(_.Tooltip, {
39
+ children: (0, _jsxRuntime.jsxs)(_.Text, {
40
+ sx: {
41
+ fontSize: 1
42
+ },
43
+ children: ["This is a tooltip that can be used to describe various pieces of functionality.", (0, _jsxRuntime.jsx)("br", {}), (0, _jsxRuntime.jsx)(_.Link, {
44
+ children: "Find out more \u2192"
45
+ })]
46
+ })
47
+ })]
48
+ });
49
+ };
50
+
51
+ exports.Default = Default;
@@ -1,24 +1,43 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.Default = exports["default"] = void 0;
5
+
6
+ var _react = _interopRequireDefault(require("react"));
7
+
8
+ var _ = require("..");
9
+
10
+ var _jsxRuntime = require("theme-ui/jsx-runtime");
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
13
+
1
14
  /**
2
15
  * External dependencies
3
16
  */
4
- import React from 'react';
17
+
5
18
  /**
6
19
  * Internal dependencies
7
20
  */
8
-
9
- import { Wizard, Flex, Box, Heading, Label, Input, Button } from '..';
10
- export default {
21
+ var _default = {
11
22
  title: 'Wizard',
12
- component: Wizard
23
+ component: _.Wizard
13
24
  };
14
- export var Default = function Default() {
25
+ exports["default"] = _default;
26
+
27
+ var Default = function Default() {
15
28
  var steps = [{
16
29
  title: 'Choose Domain',
17
30
  subTitle: 'You can bring a domain name you already own, or buy a new one.',
18
- children: /*#__PURE__*/React.createElement(Box, null, /*#__PURE__*/React.createElement(Label, null, "Domain"), /*#__PURE__*/React.createElement(Input, {
19
- autoFocus: true,
20
- placeholder: "yourdomain.com"
21
- }), /*#__PURE__*/React.createElement(Button, null, "Continue"))
31
+ children: (0, _jsxRuntime.jsxs)(_.Box, {
32
+ children: [(0, _jsxRuntime.jsx)(_.Label, {
33
+ children: "Domain"
34
+ }), (0, _jsxRuntime.jsx)(_.Input, {
35
+ autoFocus: true,
36
+ placeholder: "yourdomain.com"
37
+ }), (0, _jsxRuntime.jsx)(_.Button, {
38
+ children: "Continue"
39
+ })]
40
+ })
22
41
  }, {
23
42
  title: 'Configure DNS'
24
43
  }, {
@@ -26,30 +45,39 @@ export var Default = function Default() {
26
45
  }, {
27
46
  title: 'Verify Domain'
28
47
  }];
29
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Flex, {
30
- sx: {
31
- alignItems: 'center'
32
- }
33
- }, /*#__PURE__*/React.createElement(Box, {
34
- sx: {
35
- flex: '1 1 auto'
36
- }
37
- }, /*#__PURE__*/React.createElement(Heading, {
38
- variant: "h1",
39
- sx: {
40
- display: 'flex',
41
- alignItems: 'center',
42
- mb: 1
43
- }
44
- }, "Add Domain:", ' ', /*#__PURE__*/React.createElement("span", {
45
- sx: {
46
- color: 'muted',
47
- ml: 2
48
- }
49
- }, "Production")))), /*#__PURE__*/React.createElement(Box, {
50
- mt: 4
51
- }, /*#__PURE__*/React.createElement(Wizard, {
52
- activeStep: 0,
53
- steps: steps
54
- })));
55
- };
48
+ return (0, _jsxRuntime.jsxs)(_react["default"].Fragment, {
49
+ children: [(0, _jsxRuntime.jsx)(_.Flex, {
50
+ sx: {
51
+ alignItems: 'center'
52
+ },
53
+ children: (0, _jsxRuntime.jsx)(_.Box, {
54
+ sx: {
55
+ flex: '1 1 auto'
56
+ },
57
+ children: (0, _jsxRuntime.jsxs)(_.Heading, {
58
+ variant: "h1",
59
+ sx: {
60
+ display: 'flex',
61
+ alignItems: 'center',
62
+ mb: 1
63
+ },
64
+ children: ["Add Domain:", ' ', (0, _jsxRuntime.jsx)("span", {
65
+ sx: {
66
+ color: 'muted',
67
+ ml: 2
68
+ },
69
+ children: "Production"
70
+ })]
71
+ })
72
+ })
73
+ }), (0, _jsxRuntime.jsx)(_.Box, {
74
+ mt: 4,
75
+ children: (0, _jsxRuntime.jsx)(_.Wizard, {
76
+ activeStep: 0,
77
+ steps: steps
78
+ })
79
+ })]
80
+ });
81
+ };
82
+
83
+ exports.Default = Default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/vip-design-system",
3
- "version": "0.9.4",
3
+ "version": "0.9.5",
4
4
  "main": "build/system/index.js",
5
5
  "scripts": {
6
6
  "build-storybook": "build-storybook",
@@ -21,7 +21,8 @@
21
21
  "babel-loader": "^8.2.2",
22
22
  "framer-motion": "^3.9.1",
23
23
  "react-icons": "^4.2.0",
24
- "react-select": "^4.3.1"
24
+ "react-select": "^4.3.1",
25
+ "react-select-async-paginate": "^0.6.1"
25
26
  },
26
27
  "peerDependencies": {
27
28
  "react": "*",
@@ -0,0 +1,29 @@
1
+ /** @jsxImportSource theme-ui */
2
+
3
+ /**
4
+ * External dependencies
5
+ */
6
+ import PropTypes from 'prop-types';
7
+ import { withAsyncPaginate } from 'react-select-async-paginate';
8
+
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import { SearchSelect } from './SearchSelect';
13
+
14
+ // Asynchronous search select to load paginated results asynchronously
15
+ const CustomAsyncPaginate = withAsyncPaginate( SearchSelect );
16
+
17
+ const AsyncSearchSelect = ( { options, ...props } ) => (
18
+ <CustomAsyncPaginate
19
+ SelectComponent={ SearchSelect }
20
+ loadOptions={ options }
21
+ { ...props }
22
+ />
23
+ );
24
+
25
+ AsyncSearchSelect.propTypes = {
26
+ options: PropTypes.array,
27
+ };
28
+
29
+ export { AsyncSearchSelect };
@@ -12,6 +12,7 @@ import PropTypes from 'prop-types';
12
12
  */
13
13
  import { Flex, Text } from '..';
14
14
 
15
+ // Option component
15
16
  export const Option = ( { label, isSelected, ...props } ) => (
16
17
  <components.Option {...props}>
17
18
  <Flex sx={{ alignItems: 'center' }}>
@@ -32,7 +33,45 @@ Option.propTypes = {
32
33
  isSelected: PropTypes.bool,
33
34
  };
34
35
 
35
- export const DropdownIndicator = props => <MdExpandMore {...props} sx={{ color: 'text', mr: 2 }} />;
36
+ // DropdownIndicator component
37
+ export const DropdownIndicator = ( {
38
+ innerProps,
39
+ isFocused,
40
+ isDisabled,
41
+ clearValue,
42
+ cx,
43
+ getStyles,
44
+ getValue,
45
+ hasValue,
46
+ isMulti,
47
+ isRtl,
48
+ options,
49
+ selectProps,
50
+ setValue,
51
+ selectOption,
52
+ theme,
53
+ ...props
54
+ } ) => <MdExpandMore { ...props } sx={ { color: 'text', mr: 2 } } />;
55
+
56
+ DropdownIndicator.propTypes = {
57
+ innerProps: PropTypes.object,
58
+ isFocused: PropTypes.bool,
59
+ isDisabled: PropTypes.bool,
60
+ clearValue: PropTypes.func,
61
+ cx: PropTypes.func,
62
+ getStyles: PropTypes.func,
63
+ getValue: PropTypes.func,
64
+ hasValue: PropTypes.bool,
65
+ isMulti: PropTypes.bool,
66
+ isRtl: PropTypes.bool,
67
+ options: PropTypes.array,
68
+ selectProps: PropTypes.object,
69
+ setValue: PropTypes.func,
70
+ selectOption: PropTypes.func,
71
+ theme: PropTypes.object,
72
+ };
73
+
74
+ // ClearIndicator component
36
75
  const ClearIndicator = ( { innerProps: { ref, ...restInnerProps }, ...props } ) => (
37
76
  <MdClose ref={ref} {...restInnerProps} {...props} sx={{ color: 'text', mr: 2 }} />
38
77
  );
@@ -41,11 +80,12 @@ ClearIndicator.propTypes = {
41
80
  innerProps: PropTypes.object,
42
81
  };
43
82
 
83
+ // Parent SearchSelect component
44
84
  const SearchSelect = props => (
45
85
  <Select
46
- {...props}
86
+ { ...props }
47
87
  classNamePrefix={ 'select' }
48
- components={{ Option, DropdownIndicator, ClearIndicator }}
88
+ components={ { Option, DropdownIndicator, ClearIndicator } }
49
89
  sx={ {
50
90
  '.select__control': {
51
91
  background: 'none',
@@ -11,8 +11,10 @@ import PropTypes from 'prop-types';
11
11
  */
12
12
  import { SearchSelect } from './SearchSelect';
13
13
  import { InlineSelect } from './InlineSelect';
14
+ import { AsyncSearchSelect } from './AsyncSearchSelect';
14
15
 
15
- const Select = ( { isMulti = false, isInline, options, label, isSearch, usePortal, ...props } ) => {
16
+ const Select = ( { isMulti = false, isInline, isAsync, options, label, isSearch, usePortal, ...props } ) => {
17
+ let Component;
16
18
  const selectRef = React.useRef();
17
19
  const portalProps = {};
18
20
 
@@ -22,7 +24,17 @@ const Select = ( { isMulti = false, isInline, options, label, isSearch, usePorta
22
24
  portalProps.styles = { menuPortal: base => ( { ...base, position: 'fixed' } ) };
23
25
  }
24
26
 
25
- const Component = isInline ? InlineSelect : SearchSelect;
27
+ switch ( true ) {
28
+ case isInline:
29
+ Component = InlineSelect;
30
+ break;
31
+ case isAsync:
32
+ Component = AsyncSearchSelect;
33
+ break;
34
+ default:
35
+ Component = SearchSelect;
36
+ break;
37
+ }
26
38
 
27
39
  return <div ref={selectRef}><Component isMulti={isMulti} label={label} options={options} {...portalProps} {...props} /></div>;
28
40
  };
@@ -30,6 +42,7 @@ const Select = ( { isMulti = false, isInline, options, label, isSearch, usePorta
30
42
  Select.propTypes = {
31
43
  isInline: PropTypes.bool,
32
44
  isMulti: PropTypes.bool,
45
+ isAsync: PropTypes.bool,
33
46
  isSearch: PropTypes.bool,
34
47
  label: PropTypes.string,
35
48
  options: PropTypes.array,
@@ -105,6 +105,36 @@ export const Inline = () => {
105
105
  );
106
106
  };
107
107
 
108
+ export const Async = () => {
109
+ const [ value, setValue ] = useState( [] );
110
+ const loadOptions = async () => new Promise( resolve => {
111
+ setTimeout( () => {
112
+ resolve( {
113
+ options: [
114
+ ...options,
115
+ { value: 'newvanilla', label: 'New Vanilla' },
116
+ ],
117
+ } );
118
+ }, 2000 );
119
+ } );
120
+
121
+ return (
122
+ <Box sx={{ mr: 2, width: 200 }}>
123
+ <Select
124
+ label="Async Select"
125
+ value={value}
126
+ isAsync
127
+ usePortal
128
+ loadOptions={ loadOptions }
129
+ noneLabel="Everyone"
130
+ placeholder="Load async..."
131
+ options={options}
132
+ onChange={newValue => setValue( newValue )}
133
+ />
134
+ </Box>
135
+ );
136
+ };
137
+
108
138
  export const DropdownMenu = () => {
109
139
  return (
110
140
  <Box sx={{ mr: 2, width: 200 }}>
@@ -0,0 +1,37 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { render, screen } from '@testing-library/react';
5
+ import { axe } from 'jest-axe';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { Select } from './Select';
11
+
12
+ describe( '<Select />', () => {
13
+ it( 'renders the Select component with the specified placeholder', () => {
14
+ render(
15
+ <Select
16
+ inputId={ 'search-select' }
17
+ placeholder={ 'Search...' }
18
+ />
19
+ );
20
+
21
+ // Can't use `getByPlaceholderText` here since it's not actually being rendered as a placeholder element
22
+ const placeholder = screen.getByText( 'Search...' );
23
+
24
+ expect( placeholder ).toBeInTheDocument();
25
+ } );
26
+
27
+ it( 'renders the Select component with accessibility props', async () => {
28
+ const { container } = render(
29
+ <Select
30
+ inputId={ 'search-select' }
31
+ aria-label={ 'Search or select from the dropdown list' }
32
+ />
33
+ );
34
+
35
+ expect( await axe( container ) ).toHaveNoViolations();
36
+ } );
37
+ } );
@@ -0,0 +1,46 @@
1
+ /** @jsxImportSource theme-ui */
2
+
3
+ /**
4
+ * External dependencies
5
+ */
6
+ import { Flex } from 'theme-ui';
7
+ import { MdWatchLater } from 'react-icons/md';
8
+ import PropTypes from 'prop-types';
9
+
10
+ const VerticalLine = () => {
11
+ return (
12
+ <div
13
+ sx={ {
14
+ borderLeft: '2px solid',
15
+ borderColor: 'border',
16
+ height: 'calc( 50% - 16px )',
17
+ borderRadius: '2px',
18
+ } }>
19
+ </div>
20
+ );
21
+ };
22
+
23
+ const Timeline = ( { time, first = false, last = false, ...props } ) => (
24
+ <Flex { ...props }>
25
+ <Flex sx={ { flexDirection: 'column', justifyContent: 'space-evenly', alignItems: 'center' } }>
26
+ { ! first && (
27
+ <VerticalLine />
28
+ ) }
29
+ <MdWatchLater sx={ { color: 'border' } } size={ 18 }/>
30
+ { ! last && (
31
+ <VerticalLine />
32
+ ) }
33
+ </Flex>
34
+ <Flex sx={ { alignItems: 'center', ml: 2 } }>
35
+ { time }
36
+ </Flex>
37
+ </Flex>
38
+ );
39
+
40
+ Timeline.propTypes = {
41
+ first: PropTypes.bool,
42
+ time: PropTypes.node,
43
+ last: PropTypes.bool,
44
+ };
45
+
46
+ export { Timeline };
@@ -0,0 +1,34 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { Timeline } from '..';
10
+ import { Link } from '../Link';
11
+
12
+ export default {
13
+ title: 'Timeline',
14
+ component: Timeline,
15
+ };
16
+
17
+ export const Default = () => {
18
+ return (
19
+ <React.Fragment>
20
+ <Timeline
21
+ time="13:00"
22
+ title="21:00 UTC"
23
+ />
24
+ <Timeline
25
+ time={ <Link>14:00</Link> }
26
+ title="22:00 UTC"
27
+ />
28
+ <Timeline
29
+ time="15:00"
30
+ title="23:00 UTC"
31
+ />
32
+ </React.Fragment>
33
+ );
34
+ };