@automattic/vip-design-system 0.19.1 → 0.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/README.md CHANGED
@@ -102,3 +102,15 @@ git push origin trunk
102
102
  ```
103
103
 
104
104
  8. For major versions or breaking changes, it's recommended to [create a RELEASE](https://github.com/Automattic/vip-design-system/releases) with the published tag.
105
+
106
+ ### Troubleshooting
107
+
108
+ ### Dialog + Dropdown usage
109
+
110
+ If you are facing a Dialog overlaping a Dropdown content, add this CSS to your application:
111
+
112
+ ```css
113
+ div[data-radix-popper-content-wrapper][data-aria-hidden='true'] {
114
+ opacity: 0;
115
+ }
116
+ ```
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.MultiSelect = void 0;
5
+
6
+ var _reactSelect = _interopRequireDefault(require("react-select"));
7
+
8
+ var _jsxRuntime = require("theme-ui/jsx-runtime");
9
+
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
11
+
12
+ 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); }
13
+
14
+ var vipGold = '#c29c69'; // hardcoding for now
15
+
16
+ var vipGrey2 = '#d7dee2';
17
+ var customStyles = {
18
+ control: function control(styles) {
19
+ return _extends({}, styles, {
20
+ border: "1px solid " + vipGrey2,
21
+ boxShadow: 'none',
22
+ '&:hover': {
23
+ border: "1px solid " + vipGold
24
+ },
25
+ '&:focus': {
26
+ border: "1px solid " + vipGold
27
+ }
28
+ });
29
+ }
30
+ };
31
+
32
+ var MultiSelect = function MultiSelect(props) {
33
+ return (0, _jsxRuntime.jsx)(_reactSelect["default"], _extends({}, props, {
34
+ styles: customStyles
35
+ }));
36
+ };
37
+
38
+ exports.MultiSelect = MultiSelect;
@@ -4,10 +4,10 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
 
5
5
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
6
6
 
7
- var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
8
-
9
7
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
10
8
 
9
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
+
11
11
  var _react = require("@testing-library/react");
12
12
 
13
13
  var _jestAxe = require("jest-axe");
@@ -38,6 +38,15 @@ var defaultProps = {
38
38
  forLabel: 'my_desert_list',
39
39
  options: options
40
40
  };
41
+ var groupedProps = (0, _extends2["default"])({}, defaultProps, {
42
+ options: [{
43
+ label: 'Group name',
44
+ options: [options[0]]
45
+ }, {
46
+ label: 'Another Group name',
47
+ options: [options[1], options[2]]
48
+ }]
49
+ });
41
50
  describe('<FormSelect />', function () {
42
51
  it('renders the FormSelect component', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() {
43
52
  var _render, container;
@@ -50,22 +59,85 @@ describe('<FormSelect />', function () {
50
59
  id: "my_desert_list"
51
60
  }, defaultProps))), container = _render.container;
52
61
  expect(_react.screen.getByLabelText(defaultProps.label)).toBeInTheDocument();
53
- expect(_react.screen.getByRole('combobox')).toBeInTheDocument(); // Check for accessibility issues
62
+ expect(_react.screen.getByRole('combobox')).toBeInTheDocument();
63
+ expect(_react.screen.getAllByRole('option')).toHaveLength(3);
64
+ expect(_react.screen.queryByRole('group')).not.toBeInTheDocument(); // Check for accessibility issues
54
65
 
55
66
  _context.t0 = expect;
56
- _context.next = 6;
67
+ _context.next = 8;
57
68
  return (0, _jestAxe.axe)(container);
58
69
 
59
- case 6:
70
+ case 8:
60
71
  _context.t1 = _context.sent;
61
- _context.next = 9;
72
+ _context.next = 11;
62
73
  return (0, _context.t0)(_context.t1).toHaveNoViolations();
63
74
 
64
- case 9:
75
+ case 11:
65
76
  case "end":
66
77
  return _context.stop();
67
78
  }
68
79
  }
69
80
  }, _callee);
70
81
  })));
82
+ it('renders the FormSelect component with optgroup when options are grouped', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() {
83
+ var _render2, container;
84
+
85
+ return _regenerator["default"].wrap(function _callee2$(_context2) {
86
+ while (1) {
87
+ switch (_context2.prev = _context2.next) {
88
+ case 0:
89
+ _render2 = (0, _react.render)((0, _jsxRuntime.jsx)(_FormSelect.FormSelect, (0, _extends2["default"])({
90
+ id: "my_desert_list"
91
+ }, groupedProps))), container = _render2.container;
92
+ expect(_react.screen.getByLabelText(defaultProps.label)).toBeInTheDocument();
93
+ expect(_react.screen.getByRole('combobox')).toBeInTheDocument();
94
+ expect(_react.screen.getAllByRole('option')).toHaveLength(3);
95
+ expect(_react.screen.getAllByRole('group')).toHaveLength(2); // Check for accessibility issues
96
+
97
+ _context2.t0 = expect;
98
+ _context2.next = 8;
99
+ return (0, _jestAxe.axe)(container);
100
+
101
+ case 8:
102
+ _context2.t1 = _context2.sent;
103
+ _context2.next = 11;
104
+ return (0, _context2.t0)(_context2.t1).toHaveNoViolations();
105
+
106
+ case 11:
107
+ case "end":
108
+ return _context2.stop();
109
+ }
110
+ }
111
+ }, _callee2);
112
+ })));
113
+ it('renders the FormSelect component when isInline is true', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3() {
114
+ var _render3, container;
115
+
116
+ return _regenerator["default"].wrap(function _callee3$(_context3) {
117
+ while (1) {
118
+ switch (_context3.prev = _context3.next) {
119
+ case 0:
120
+ _render3 = (0, _react.render)((0, _jsxRuntime.jsx)(_FormSelect.FormSelect, (0, _extends2["default"])({
121
+ id: "my_desert_list",
122
+ isInline: true
123
+ }, defaultProps))), container = _render3.container;
124
+ expect(_react.screen.getByLabelText(defaultProps.label)).toBeInTheDocument();
125
+ expect(_react.screen.getByRole('combobox')).toBeInTheDocument(); // Check for accessibility issues
126
+
127
+ _context3.t0 = expect;
128
+ _context3.next = 6;
129
+ return (0, _jestAxe.axe)(container);
130
+
131
+ case 6:
132
+ _context3.t1 = _context3.sent;
133
+ _context3.next = 9;
134
+ return (0, _context3.t0)(_context3.t1).toHaveNoViolations();
135
+
136
+ case 9:
137
+ case "end":
138
+ return _context3.stop();
139
+ }
140
+ }
141
+ }, _callee3);
142
+ })));
71
143
  });
@@ -53,7 +53,7 @@ var StyledListItem = function StyledListItem(props) {
53
53
  sx: {
54
54
  py: 2,
55
55
  borderBottom: '1px solid',
56
- borderColor: 'borders.2',
56
+ borderColor: 'border',
57
57
  listStyleType: 'none',
58
58
  margin: 0,
59
59
  px: 0
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.UsageChart = void 0;
5
+
6
+ var _framerMotion = require("framer-motion");
7
+
8
+ var _propTypes = _interopRequireDefault(require("prop-types"));
9
+
10
+ var _jsxRuntime = require("theme-ui/jsx-runtime");
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
13
+
14
+ /**
15
+ * External dependencies
16
+ */
17
+ var UsageChart = function UsageChart(_ref) {
18
+ var total = _ref.total,
19
+ max = _ref.max,
20
+ _ref$variant = _ref.variant,
21
+ variant = _ref$variant === void 0 ? 'primary' : _ref$variant;
22
+ var width = total / max * 100 + '%';
23
+ var formattedTotal = total;
24
+
25
+ if (total > 1000000) {
26
+ formattedTotal = (total / 1000000).toFixed(2) + "M";
27
+ } else if (total > 1000) {
28
+ formattedTotal = (total / 1000).toFixed(2) + "K";
29
+ }
30
+
31
+ return (0, _jsxRuntime.jsx)("div", {
32
+ sx: {
33
+ height: variant === 'primary' ? 32 : 8,
34
+ overflow: 'hidden',
35
+ backgroundColor: variant === 'primary' ? 'border' : 'transparent'
36
+ },
37
+ children: (0, _jsxRuntime.jsx)(_framerMotion.motion.div, {
38
+ initial: {
39
+ width: 0
40
+ },
41
+ animate: {
42
+ width: width
43
+ },
44
+ transition: {
45
+ duration: 0.7
46
+ },
47
+ sx: {
48
+ height: '100%',
49
+ backgroundColor: variant === 'primary' ? 'primary' : 'grey.40'
50
+ }
51
+ })
52
+ });
53
+ };
54
+
55
+ exports.UsageChart = UsageChart;
56
+ UsageChart.propTypes = {
57
+ total: _propTypes["default"].number,
58
+ max: _propTypes["default"].number,
59
+ variant: _propTypes["default"].string
60
+ };
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+
5
+ var _UsageChart = require("./UsageChart");
6
+
7
+ exports.UsageChart = _UsageChart.UsageChart;
@@ -63,15 +63,13 @@ var Wizard = function Wizard(_ref) {
63
63
  }) : steps.map(function (_ref3, index) {
64
64
  var title = _ref3.title,
65
65
  subTitle = _ref3.subTitle,
66
- children = _ref3.children,
67
- titleVariant = _ref3.titleVariant;
66
+ children = _ref3.children;
68
67
  return (0, _jsxRuntime.jsx)(_.WizardStep, {
69
68
  active: index === activeStep,
70
69
  complete: completed.includes(index),
71
70
  order: index + 1,
72
71
  subTitle: subTitle,
73
72
  title: title,
74
- titleVariant: titleVariant,
75
73
  children: children
76
74
  }, index);
77
75
  })
@@ -3,7 +3,7 @@
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
4
 
5
5
  exports.__esModule = true;
6
- exports["default"] = exports.Default = exports.CustomHeadingVariant = void 0;
6
+ exports["default"] = exports.Default = exports.CustomTitle = void 0;
7
7
 
8
8
  var _react = _interopRequireDefault(require("react"));
9
9
 
@@ -11,6 +11,8 @@ var _ = require("..");
11
11
 
12
12
  var _jsxRuntime = require("theme-ui/jsx-runtime");
13
13
 
14
+ /** @jsxImportSource theme-ui */
15
+
14
16
  /**
15
17
  * External dependencies
16
18
  */
@@ -83,16 +85,24 @@ var Default = function Default() {
83
85
 
84
86
  exports.Default = Default;
85
87
 
86
- var CustomHeadingVariant = function CustomHeadingVariant() {
88
+ var CustomTitle = function CustomTitle() {
87
89
  var steps = [{
88
- title: 'Choose Domain',
89
- titleVariant: 'h1',
90
- subTitle: (0, _jsxRuntime.jsx)("h2", {
90
+ title: (0, _jsxRuntime.jsx)("h3", {
91
+ sx: {
92
+ m: 0
93
+ },
94
+ children: "Choose Domain"
95
+ }),
96
+ subTitle: (0, _jsxRuntime.jsx)("span", {
91
97
  children: "You can bring a domain name you already own, or buy a new one."
92
98
  })
93
99
  }, {
94
- title: 'Configure DNS',
95
- titleVariant: 'h1'
100
+ title: (0, _jsxRuntime.jsx)("h3", {
101
+ sx: {
102
+ m: 0
103
+ },
104
+ children: "Configure DNS"
105
+ })
96
106
  }];
97
107
  return (0, _jsxRuntime.jsx)(_react["default"].Fragment, {
98
108
  children: (0, _jsxRuntime.jsx)(_.Wizard, {
@@ -103,4 +113,4 @@ var CustomHeadingVariant = function CustomHeadingVariant() {
103
113
  });
104
114
  };
105
115
 
106
- exports.CustomHeadingVariant = CustomHeadingVariant;
116
+ exports.CustomTitle = CustomTitle;
@@ -29,10 +29,8 @@ var WizardStep = function WizardStep(_ref) {
29
29
  complete = _ref$complete === void 0 ? false : _ref$complete,
30
30
  children = _ref.children,
31
31
  active = _ref.active,
32
- order = _ref.order,
33
- _ref$titleVariant = _ref.titleVariant,
34
- titleVariant = _ref$titleVariant === void 0 ? 'h4' : _ref$titleVariant;
35
- var borderLeftColor = 'borders.2';
32
+ order = _ref.order;
33
+ var borderLeftColor = 'border';
36
34
 
37
35
  if (complete) {
38
36
  borderLeftColor = 'success';
@@ -66,20 +64,30 @@ var WizardStep = function WizardStep(_ref) {
66
64
  },
67
65
  "data-step": order,
68
66
  "data-active": active || undefined,
69
- children: [(0, _jsxRuntime.jsxs)(_.Heading, {
70
- variant: titleVariant,
67
+ children: [typeof title === 'string' ? (0, _jsxRuntime.jsxs)(_.Heading, {
68
+ variant: "h4",
71
69
  sx: {
72
70
  mb: 0,
73
71
  display: 'flex',
74
72
  alignItems: 'center',
75
- color: color,
76
- fontSize: 2
73
+ color: color
77
74
  },
78
75
  children: [(0, _jsxRuntime.jsx)(_md.MdCheckCircle, {
76
+ "aria-hidden": "true",
79
77
  sx: {
80
78
  mr: 2
81
- },
82
- size: 18
79
+ }
80
+ }), title]
81
+ }) : (0, _jsxRuntime.jsxs)(_.Flex, {
82
+ sx: {
83
+ alignItems: 'center',
84
+ color: color
85
+ },
86
+ children: [(0, _jsxRuntime.jsx)(_md.MdCheckCircle, {
87
+ "aria-hidden": "true",
88
+ sx: {
89
+ mr: 2
90
+ }
83
91
  }), title]
84
92
  }), subTitle && active && (0, _jsxRuntime.jsx)(_.Text, {
85
93
  sx: {
@@ -97,6 +105,5 @@ WizardStep.propTypes = {
97
105
  complete: _propTypes["default"].bool,
98
106
  order: _propTypes["default"].number.isRequired,
99
107
  subTitle: _propTypes["default"].node,
100
- title: _propTypes["default"].node,
101
- titleVariant: _propTypes["default"].string
108
+ title: _propTypes["default"].node
102
109
  };
@@ -25,20 +25,31 @@ var _jsxRuntime = require("theme-ui/jsx-runtime");
25
25
  var WizardStepHorizontal = function WizardStepHorizontal(_ref) {
26
26
  var title = _ref.title,
27
27
  active = _ref.active,
28
- order = _ref.order,
29
- _ref$titleVariant = _ref.titleVariant,
30
- titleVariant = _ref$titleVariant === void 0 ? 'h4' : _ref$titleVariant;
31
- return (0, _jsxRuntime.jsxs)(_.Heading, {
32
- variant: titleVariant,
28
+ order = _ref.order;
29
+ var color = active ? 'heading' : 'muted';
30
+ return typeof title === 'string' ? (0, _jsxRuntime.jsxs)(_.Heading, {
31
+ variant: "h4",
33
32
  sx: {
34
33
  mb: 0,
35
34
  display: 'flex',
36
35
  alignItems: 'center',
37
- color: active ? 'heading' : 'muted'
36
+ color: color
38
37
  },
39
38
  "data-step": order,
40
39
  "data-active": active || undefined,
41
40
  children: [(0, _jsxRuntime.jsx)(_md.MdCheckCircle, {
41
+ "aria-hidden": "true",
42
+ sx: {
43
+ mr: 2
44
+ }
45
+ }), title]
46
+ }) : (0, _jsxRuntime.jsxs)(_.Flex, {
47
+ sx: {
48
+ alignItems: 'center',
49
+ color: color
50
+ },
51
+ children: [(0, _jsxRuntime.jsx)(_md.MdCheckCircle, {
52
+ "aria-hidden": "true",
42
53
  sx: {
43
54
  mr: 2
44
55
  }
@@ -51,6 +62,5 @@ WizardStepHorizontal.propTypes = {
51
62
  active: _propTypes["default"].bool,
52
63
  order: _propTypes["default"].number.isRequired,
53
64
  subTitle: _propTypes["default"].node,
54
- title: _propTypes["default"].node,
55
- titleVariant: _propTypes["default"].string
65
+ title: _propTypes["default"].node
56
66
  };
@@ -105,11 +105,6 @@ var _Spinner = require("./Spinner");
105
105
 
106
106
  exports.Spinner = _Spinner.Spinner;
107
107
 
108
- var _ResourceList = require("./ResourceList");
109
-
110
- exports.ResourceList = _ResourceList.ResourceList;
111
- exports.ResourceItem = _ResourceList.ResourceItem;
112
-
113
108
  var _Tooltip = require("./Tooltip");
114
109
 
115
110
  exports.Tooltip = _Tooltip.Tooltip;
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@automattic/vip-design-system",
3
- "version": "0.19.1",
3
+ "version": "0.19.2",
4
4
  "main": "build/system/index.js",
5
5
  "scripts": {
6
6
  "build-storybook": "build-storybook",
7
+ "prepare": "npm run build",
7
8
  "build": "npm run theme-update && cross-env NODE_ENV=production babel src --out-dir build && npm run theme-builder-copy",
8
9
  "format": "prettier --write \"src/**/*.{js,ts,tsx,md,mdx,json}\"",
9
10
  "format:check": "prettier --list-different -- \"src/system/**/*.{js,ts,tsx,md,mdx,json}\"",
@@ -21,10 +21,48 @@ const defaultProps = {
21
21
  options,
22
22
  };
23
23
 
24
+ const groupedProps = {
25
+ ...defaultProps,
26
+ options: [
27
+ {
28
+ label: 'Group name',
29
+ options: [ options[ 0 ] ],
30
+ },
31
+ {
32
+ label: 'Another Group name',
33
+ options: [ options[ 1 ], options[ 2 ] ],
34
+ },
35
+ ],
36
+ };
37
+
24
38
  describe( '<FormSelect />', () => {
25
39
  it( 'renders the FormSelect component', async () => {
26
40
  const { container } = render( <FormSelect id="my_desert_list" { ...defaultProps } /> );
27
41
 
42
+ expect( screen.getByLabelText( defaultProps.label ) ).toBeInTheDocument();
43
+ expect( screen.getByRole( 'combobox' ) ).toBeInTheDocument();
44
+ expect( screen.getAllByRole( 'option' ) ).toHaveLength( 3 );
45
+ expect( screen.queryByRole( 'group' ) ).not.toBeInTheDocument();
46
+
47
+ // Check for accessibility issues
48
+ await expect( await axe( container ) ).toHaveNoViolations();
49
+ } );
50
+
51
+ it( 'renders the FormSelect component with optgroup when options are grouped', async () => {
52
+ const { container } = render( <FormSelect id="my_desert_list" { ...groupedProps } /> );
53
+
54
+ expect( screen.getByLabelText( defaultProps.label ) ).toBeInTheDocument();
55
+ expect( screen.getByRole( 'combobox' ) ).toBeInTheDocument();
56
+ expect( screen.getAllByRole( 'option' ) ).toHaveLength( 3 );
57
+ expect( screen.getAllByRole( 'group' ) ).toHaveLength( 2 );
58
+
59
+ // Check for accessibility issues
60
+ await expect( await axe( container ) ).toHaveNoViolations();
61
+ } );
62
+
63
+ it( 'renders the FormSelect component when isInline is true', async () => {
64
+ const { container } = render( <FormSelect id="my_desert_list" isInline { ...defaultProps } /> );
65
+
28
66
  expect( screen.getByLabelText( defaultProps.label ) ).toBeInTheDocument();
29
67
  expect( screen.getByRole( 'combobox' ) ).toBeInTheDocument();
30
68
 
@@ -42,7 +42,7 @@ const Wizard = ( { steps, activeStep, variant, completed = [], className = null,
42
42
  { steps[ activeStep ].children }
43
43
  </Box>
44
44
  ) : (
45
- steps.map( ( { title, subTitle, children, titleVariant }, index ) => (
45
+ steps.map( ( { title, subTitle, children }, index ) => (
46
46
  <WizardStep
47
47
  active={ index === activeStep }
48
48
  complete={ completed.includes( index ) }
@@ -50,7 +50,6 @@ const Wizard = ( { steps, activeStep, variant, completed = [], className = null,
50
50
  order={ index + 1 }
51
51
  subTitle={ subTitle }
52
52
  title={ title }
53
- titleVariant={ titleVariant }
54
53
  >
55
54
  { children }
56
55
  </WizardStep>
@@ -1,3 +1,5 @@
1
+ /** @jsxImportSource theme-ui */
2
+
1
3
  /**
2
4
  * External dependencies
3
5
  */
@@ -52,16 +54,14 @@ export const Default = () => {
52
54
  );
53
55
  };
54
56
 
55
- export const CustomHeadingVariant = () => {
57
+ export const CustomTitle = () => {
56
58
  const steps = [
57
59
  {
58
- title: 'Choose Domain',
59
- titleVariant: 'h1',
60
- subTitle: <h2>You can bring a domain name you already own, or buy a new one.</h2>,
60
+ title: <h3 sx={ { m: 0 } }>Choose Domain</h3>,
61
+ subTitle: <span>You can bring a domain name you already own, or buy a new one.</span>,
61
62
  },
62
63
  {
63
- title: 'Configure DNS',
64
- titleVariant: 'h1',
64
+ title: <h3 sx={ { m: 0 } }>Configure DNS</h3>,
65
65
  },
66
66
  ];
67
67
  return (
@@ -9,18 +9,10 @@ import PropTypes from 'prop-types';
9
9
  /**
10
10
  * Internal dependencies
11
11
  */
12
- import { Card, Heading, Text } from '..';
12
+ import { Card, Heading, Text, Flex } from '..';
13
13
 
14
- const WizardStep = ( {
15
- title,
16
- subTitle,
17
- complete = false,
18
- children,
19
- active,
20
- order,
21
- titleVariant = 'h4',
22
- } ) => {
23
- let borderLeftColor = 'borders.2';
14
+ const WizardStep = ( { title, subTitle, complete = false, children, active, order } ) => {
15
+ let borderLeftColor = 'border';
24
16
 
25
17
  if ( complete ) {
26
18
  borderLeftColor = 'success';
@@ -56,19 +48,26 @@ const WizardStep = ( {
56
48
  data-step={ order }
57
49
  data-active={ active || undefined }
58
50
  >
59
- <Heading
60
- variant={ titleVariant }
61
- sx={ {
62
- mb: 0,
63
- display: 'flex',
64
- alignItems: 'center',
65
- color,
66
- fontSize: 2,
67
- } }
68
- >
69
- <MdCheckCircle sx={ { mr: 2 } } size={ 18 } />
70
- { title }
71
- </Heading>
51
+ { typeof title === 'string' ? (
52
+ <Heading
53
+ variant="h4"
54
+ sx={ {
55
+ mb: 0,
56
+ display: 'flex',
57
+ alignItems: 'center',
58
+ color: color,
59
+ } }
60
+ >
61
+ <MdCheckCircle aria-hidden="true" sx={ { mr: 2 } } />
62
+ { title }
63
+ </Heading>
64
+ ) : (
65
+ <Flex sx={ { alignItems: 'center', color } }>
66
+ <MdCheckCircle aria-hidden="true" sx={ { mr: 2 } } />
67
+ { title }
68
+ </Flex>
69
+ ) }
70
+
72
71
  { subTitle && active && <Text sx={ { mb: 3 } }>{ subTitle }</Text> }
73
72
 
74
73
  { active && children }
@@ -83,7 +82,6 @@ WizardStep.propTypes = {
83
82
  order: PropTypes.number.isRequired,
84
83
  subTitle: PropTypes.node,
85
84
  title: PropTypes.node,
86
- titleVariant: PropTypes.string,
87
85
  };
88
86
 
89
87
  export { WizardStep };
@@ -9,24 +9,31 @@ import PropTypes from 'prop-types';
9
9
  /**
10
10
  * Internal dependencies
11
11
  */
12
- import { Heading } from '..';
12
+ import { Heading, Flex } from '..';
13
13
 
14
- const WizardStepHorizontal = ( { title, active, order, titleVariant = 'h4' } ) => {
15
- return (
14
+ const WizardStepHorizontal = ( { title, active, order } ) => {
15
+ const color = active ? 'heading' : 'muted';
16
+
17
+ return typeof title === 'string' ? (
16
18
  <Heading
17
- variant={ titleVariant }
19
+ variant="h4"
18
20
  sx={ {
19
21
  mb: 0,
20
22
  display: 'flex',
21
23
  alignItems: 'center',
22
- color: active ? 'heading' : 'muted',
24
+ color,
23
25
  } }
24
26
  data-step={ order }
25
27
  data-active={ active || undefined }
26
28
  >
27
- <MdCheckCircle sx={ { mr: 2 } } />
29
+ <MdCheckCircle aria-hidden="true" sx={ { mr: 2 } } />
28
30
  { title }
29
31
  </Heading>
32
+ ) : (
33
+ <Flex sx={ { alignItems: 'center', color } }>
34
+ <MdCheckCircle aria-hidden="true" sx={ { mr: 2 } } />
35
+ { title }
36
+ </Flex>
30
37
  );
31
38
  };
32
39
 
@@ -35,7 +42,6 @@ WizardStepHorizontal.propTypes = {
35
42
  order: PropTypes.number.isRequired,
36
43
  subTitle: PropTypes.node,
37
44
  title: PropTypes.node,
38
- titleVariant: PropTypes.string,
39
45
  };
40
46
 
41
47
  export { WizardStepHorizontal };
@@ -44,7 +44,6 @@ import { Link } from './Link';
44
44
  import { Notice } from './Notice';
45
45
  import { Progress } from './Progress';
46
46
  import { Spinner } from './Spinner';
47
- import { ResourceList, ResourceItem } from './ResourceList';
48
47
  import { Tooltip } from './Tooltip';
49
48
  import { Time } from './Time';
50
49
  import { Timeline } from './Timeline';
@@ -94,8 +93,6 @@ export {
94
93
  Select,
95
94
  Radio,
96
95
  RadioBoxGroup,
97
- ResourceList,
98
- ResourceItem,
99
96
  Textarea,
100
97
  Progress,
101
98
  Text,
@@ -1,66 +0,0 @@
1
- /** @jsxImportSource theme-ui */
2
-
3
- /**
4
- * External dependencies
5
- */
6
- import PropTypes from 'prop-types';
7
-
8
- /**
9
- * Internal dependencies
10
- */
11
- import { Box, Flex, Time } from '..';
12
-
13
- const ResourceItem = ( {
14
- children,
15
- item,
16
- renderActions,
17
- relativeTime = false,
18
- timeOnly = false,
19
- dateKey,
20
- icon = null,
21
- } ) => {
22
- return (
23
- <Flex
24
- sx={ {
25
- alignItems: 'center',
26
- gap: 3,
27
- } }
28
- >
29
- { icon }
30
- <Box sx={ { flex: '1 1 auto' } }>{ children }</Box>
31
- <Flex
32
- sx={ {
33
- flex: '0 0 auto',
34
- alignItems: 'center',
35
- gap: 3,
36
- } }
37
- >
38
- <Time
39
- className="time"
40
- relativeTime={ relativeTime }
41
- timeOnly={ timeOnly }
42
- time={ item[ dateKey ] }
43
- sx={ { color: 'muted', mb: 0, textAlign: 'right', flex: '0 0 auto' } }
44
- />
45
- { renderActions && (
46
- <Flex className="actions" sx={ { alignItems: 'center', gap: 3 } }>
47
- <Box sx={ { width: 4, height: 4, borderRadius: 4, bg: 'border' } } />
48
- { renderActions( item ) }
49
- </Flex>
50
- ) }
51
- </Flex>
52
- </Flex>
53
- );
54
- };
55
-
56
- ResourceItem.propTypes = {
57
- children: PropTypes.node,
58
- item: PropTypes.object,
59
- icon: PropTypes.node,
60
- relativeTime: PropTypes.bool,
61
- timeOnly: PropTypes.bool,
62
- dateKey: PropTypes.string,
63
- renderActions: PropTypes.func,
64
- };
65
-
66
- export { ResourceItem };
@@ -1,108 +0,0 @@
1
- /** @jsxImportSource theme-ui */
2
-
3
- /**
4
- * External dependencies
5
- */
6
- import PropTypes from 'prop-types';
7
- import { useMemo } from 'react';
8
-
9
- /**
10
- * Internal dependencies
11
- */
12
- import { Box, Heading } from '..';
13
-
14
- const formatterOptions = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
15
-
16
- const formatDate = date => {
17
- const today = new Date();
18
- if ( date.getFullYear() !== today.getFullYear() ) {
19
- return date.toLocaleDateString( formatterOptions );
20
- } else if ( date.getMonth() !== today.getMonth() ) {
21
- return date.toLocaleDateString( formatterOptions );
22
- } else if ( date.getDate() < today.getDate() - 1 ) {
23
- return date.toLocaleDateString( formatterOptions );
24
- } else if ( date.getDate() === today.getDate() - 1 ) {
25
- return 'Yesterday';
26
- }
27
- return 'Today';
28
- };
29
-
30
- const StyledListItem = props => (
31
- <Box
32
- as="li"
33
- sx={ {
34
- py: 2,
35
- borderBottom: '1px solid',
36
- borderColor: 'borders.2',
37
- listStyleType: 'none',
38
- margin: 0,
39
- px: 0,
40
- } }
41
- { ...props }
42
- />
43
- );
44
-
45
- const ResourceList = ( { groupedByDay = false, items, renderItem, dateKey } ) => {
46
- let groupedItems = {};
47
- if ( groupedByDay ) {
48
- groupedItems = items?.reduce( ( itemGroups, item ) => {
49
- const formattedDate = formatDate( item[ dateKey ] );
50
- const itemsAtDate = itemGroups[ formattedDate ];
51
-
52
- return {
53
- ...itemGroups,
54
- [ formattedDate ]: itemsAtDate ? [ ...itemsAtDate, item ] : [ item ],
55
- };
56
- }, {} );
57
- }
58
-
59
- const renderItemList = itemsList =>
60
- itemsList.map( ( item, index ) => (
61
- <StyledListItem key={ index }>{ renderItem( item ) }</StyledListItem>
62
- ) );
63
-
64
- const renderGoupedItems = () =>
65
- useMemo(
66
- () =>
67
- Object.keys( groupedItems ).map( ( groupName, index ) => (
68
- <Box sx={ { mb: 4 } } key={ index } as="li">
69
- <Heading variant="h4" as="h4" sx={ { mb: 3 } }>
70
- { groupName }
71
- </Heading>
72
- <Box
73
- as="ul"
74
- sx={ {
75
- listStyleType: 'none',
76
- m: 0,
77
- p: 0,
78
- borderTop: '1px solid',
79
- borderColor: 'border',
80
- } }
81
- >
82
- { renderItemList( groupedItems[ groupName ] ) }
83
- </Box>
84
- </Box>
85
- ) ),
86
- [ groupedItems ]
87
- );
88
-
89
- return (
90
- <Box
91
- as="ul"
92
- sx={ { listStyleType: 'none', m: 0, p: 0 } }
93
- className="vip-resource-list-component"
94
- >
95
- { groupedByDay ? renderGoupedItems( groupedItems ) : renderItemList( items ) }
96
- </Box>
97
- );
98
- };
99
-
100
- ResourceList.propTypes = {
101
- groupedByDay: PropTypes.bool,
102
- items: PropTypes.array,
103
- renderItem: PropTypes.func,
104
- relativeTime: PropTypes.bool,
105
- dateKey: PropTypes.string,
106
- };
107
-
108
- export { ResourceList };
@@ -1,306 +0,0 @@
1
- /** @jsxImportSource theme-ui */
2
-
3
- /**
4
- * External dependencies
5
- */
6
- import React from 'react';
7
- import { BiGlobe, BiCheckCircle, BiRevision } from 'react-icons/bi';
8
-
9
- /**
10
- * Internal dependencies
11
- */
12
- import {
13
- Avatar,
14
- Badge,
15
- Box,
16
- Card,
17
- Flex,
18
- Button,
19
- ResourceList,
20
- ResourceItem,
21
- Text,
22
- Heading,
23
- } from '..';
24
-
25
- export default {
26
- title: 'ResourceList',
27
- component: ResourceList,
28
- };
29
-
30
- const logs = [
31
- {
32
- actor: 'Saxon Fletcher',
33
- action: 'switched primary domain to',
34
- object: 'mydomain.com',
35
- date: new Date(),
36
- },
37
- {
38
- actor: 'Saxon Fletcher',
39
- action: 'switched primary domain to',
40
- object: 'mydomain.com',
41
- date: new Date( new Date().setHours( 11 ) ),
42
- },
43
- {
44
- actor: 'Simon Wheatley',
45
- action: 'deployed to',
46
- object: 'Production',
47
- showObject: true,
48
- date: new Date( new Date().setDate( 15 ) ),
49
- },
50
- {
51
- actor: 'Saxon Fletcher',
52
- action: 'created a backup on',
53
- object: 'Production',
54
- date: new Date( new Date().setDate( 13 ) ),
55
- },
56
- ];
57
-
58
- export const Grouped = () => (
59
- <Box sx={ { p: 5, pt: 2 } }>
60
- <Heading sx={ { mb: 2 } }>Audit Log</Heading>
61
- <Text sx={ { mb: 4 } }>A live trail of system and human events.</Text>
62
- <ResourceList
63
- items={ logs }
64
- dateKey="date"
65
- groupedByDay={ true }
66
- renderItem={ item => (
67
- <ResourceItem
68
- item={ item }
69
- icon={ <BiGlobe sx={ { color: 'red' } } /> }
70
- dateKey={ 'date' }
71
- relativeTime={ true }
72
- timeOnly={ true }
73
- >
74
- <Flex sx={ { alignItems: 'center', gap: 3 } }>
75
- <Avatar
76
- name={ item.actor }
77
- src="https://uifaces.co/our-content/donated/1H_7AxP0.jpg"
78
- size={ 16 }
79
- />
80
- <Heading variant="h4" as="p" sx={ { mb: 0, fontWeight: 'normal' } }>
81
- { item.actor }{ ' ' }
82
- <Text as="span" sx={ { color: 'muted', mb: 0 } }>
83
- { item.action }
84
- </Text>{ ' ' }
85
- { item.object }
86
- </Heading>
87
- </Flex>
88
- { item.showObject && (
89
- <Box
90
- variant="indent"
91
- sx={ { mt: 2, display: 'flex', flexWrap: 'wrap', gap: 3, alignItems: 'center' } }
92
- >
93
- <Heading variant="h5" as="div" sx={ { mb: 0 } }>
94
- Merge pull request{ ' ' }
95
- <Text as="span" sx={ { color: 'muted' } }>
96
- #443
97
- </Text>
98
- </Heading>
99
- <Text
100
- as="div"
101
- sx={ { mb: 0, fontSize: 1, display: 'flex', alignItems: 'center', gap: 1 } }
102
- >
103
- <Avatar
104
- name={ item.actor }
105
- src="https://uifaces.co/our-content/donated/n4Ngwvi7.jpg"
106
- size={ 16 }
107
- />
108
- { item.actor }
109
- </Text>
110
- <Text sx={ { mb: 0, fontSize: 1, display: 'flex', alignItems: 'center', gap: 1 } }>
111
- <BiCheckCircle size={ 16 } />
112
- Deployed in 31s
113
- </Text>
114
- </Box>
115
- ) }
116
- </ResourceItem>
117
- ) }
118
- />
119
- </Box>
120
- );
121
-
122
- const deploys = [
123
- {
124
- title: 'Merge pull request',
125
- id: '#773',
126
- author: 'Saxon Fletcher',
127
- date: new Date( new Date().setHours( 11 ) ),
128
- status: 'running',
129
- },
130
- {
131
- title: 'Update homepage',
132
- id: '#772',
133
- author: 'Saxon Fletcher',
134
- date: new Date( new Date().setHours( 9 ) ),
135
- },
136
- {
137
- title: 'Improve overall performance',
138
- id: '#771',
139
- author: 'Saxon Fletcher',
140
- date: new Date( new Date().setHours( 8 ) ),
141
- },
142
- {
143
- title: 'Merge pull request',
144
- id: '#770',
145
- author: 'Saxon Fletcher',
146
- date: new Date( new Date().setHours( 5 ) ),
147
- status: 'failed',
148
- },
149
- {
150
- title: 'Merge pull request',
151
- id: '#773',
152
- author: 'Saxon Fletcher',
153
- date: new Date( new Date().setHours( 11 ) ),
154
- },
155
- {
156
- title: 'Update homepage',
157
- id: '#772',
158
- author: 'Saxon Fletcher',
159
- date: new Date( new Date().setHours( 9 ) ),
160
- },
161
- {
162
- title: 'Improve overall performance',
163
- id: '#771',
164
- author: 'Saxon Fletcher',
165
- date: new Date( new Date().setHours( 8 ) ),
166
- },
167
- {
168
- title: 'Merge pull request',
169
- id: '#770',
170
- author: 'Saxon Fletcher',
171
- date: new Date( new Date().setHours( 5 ) ),
172
- },
173
- {
174
- title: 'Merge pull request',
175
- id: '#773',
176
- author: 'Saxon Fletcher',
177
- date: new Date( new Date().setHours( 11 ) ),
178
- },
179
- {
180
- title: 'Update homepage',
181
- id: '#772',
182
- author: 'Saxon Fletcher',
183
- date: new Date( new Date().setHours( 9 ) ),
184
- },
185
- {
186
- title: 'Improve overall performance',
187
- id: '#771',
188
- author: 'Saxon Fletcher',
189
- date: new Date( new Date().setHours( 8 ) ),
190
- },
191
- {
192
- title: 'Merge pull request',
193
- id: '#770',
194
- author: 'Saxon Fletcher',
195
- date: new Date( new Date().setHours( 5 ) ),
196
- },
197
- {
198
- title: 'Merge pull request',
199
- id: '#773',
200
- author: 'Saxon Fletcher',
201
- date: new Date( new Date().setHours( 11 ) ),
202
- },
203
- {
204
- title: 'Update homepage',
205
- id: '#772',
206
- author: 'Saxon Fletcher',
207
- date: new Date( new Date().setHours( 9 ) ),
208
- },
209
- {
210
- title: 'Improve overall performance',
211
- id: '#771',
212
- author: 'Saxon Fletcher',
213
- date: new Date( new Date().setHours( 8 ) ),
214
- },
215
- {
216
- title: 'Merge pull request',
217
- id: '#770',
218
- author: 'Saxon Fletcher',
219
- date: new Date( new Date().setHours( 5 ) ),
220
- },
221
- ];
222
-
223
- export const Relative = () => (
224
- <Box sx={ { p: 5, pt: 2 } }>
225
- <Heading sx={ { mb: 2 } }>Deploys</Heading>
226
- <Text sx={ { mb: 4 } }>View and manage application deployments.</Text>
227
- <Card variant="indent" sx={ { mb: 4, display: 'flex', flexDirection: 'row-reverse', gap: 1 } }>
228
- { deploys.map( ( deploy, index ) => (
229
- <Box
230
- key={ index }
231
- sx={ {
232
- flex: '1 1 auto',
233
- width: 10,
234
- height: 4,
235
- backgroundColor: deploy.status === 'running' ? 'blue.50' : 'green.50',
236
- borderRadius: 1,
237
- } }
238
- ></Box>
239
- ) ) }
240
- </Card>
241
- <ResourceList
242
- items={ deploys }
243
- dateKey="date"
244
- groupedByDay={ false }
245
- renderItem={ item => (
246
- <ResourceItem
247
- item={ item }
248
- dateKey={ 'date' }
249
- relativeTime={ true }
250
- timeOnly={ true }
251
- renderActions={ () => (
252
- <Flex sx={ { alignItems: 'center' } }>
253
- <Button variant="secondary" sx={ { fontSize: 1 } }>
254
- Rollback
255
- </Button>
256
- </Flex>
257
- ) }
258
- >
259
- <Flex sx={ { alignItems: 'center', gap: 4 } }>
260
- <Flex sx={ { alignItems: 'center', gap: 3, minWidth: 300 } }>
261
- <Heading variant="h4" as="p" sx={ { mb: 0, fontWeight: 'normal' } }>
262
- { item.title }{ ' ' }
263
- <Text as="span" sx={ { color: 'muted', mb: 0 } }>
264
- { item.id }
265
- </Text>
266
- </Heading>
267
- { item.status === 'running' && <Badge sx={ { mb: 0 } }>Running</Badge> }
268
- </Flex>
269
- <Text
270
- as="div"
271
- sx={ { mb: 0, color: 'muted', display: 'flex', alignItems: 'center', gap: 2 } }
272
- >
273
- <Avatar
274
- name={ item.author }
275
- size={ 16 }
276
- src="https://randomuser.me/api/portraits/men/46.jpg"
277
- />
278
- { item.author }
279
- </Text>
280
- <Text
281
- sx={ {
282
- mb: 0,
283
- color: item.status === 'running' ? 'blue.60' : 'muted',
284
- display: 'flex',
285
- alignItems: 'center',
286
- gap: 1,
287
- } }
288
- >
289
- { item.status === 'running' ? (
290
- <React.Fragment>
291
- <BiRevision size={ 16 } />
292
- Running for 31s
293
- </React.Fragment>
294
- ) : (
295
- <React.Fragment>
296
- <BiCheckCircle size={ 16 } />
297
- Deployed in 31s
298
- </React.Fragment>
299
- ) }
300
- </Text>
301
- </Flex>
302
- </ResourceItem>
303
- ) }
304
- />
305
- </Box>
306
- );
@@ -1,7 +0,0 @@
1
- /**
2
- * Internal dependencies
3
- */
4
- import { ResourceList } from './ResourceList';
5
- import { ResourceItem } from './ResourceItem';
6
-
7
- export { ResourceList, ResourceItem };