@automattic/vip-design-system 0.26.7 → 0.27.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.
@@ -7,33 +7,37 @@ exports.Label = void 0;
7
7
 
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
9
 
10
+ var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
11
+
10
12
  var _react = _interopRequireDefault(require("react"));
11
13
 
12
- var _ = require("..");
14
+ var _propTypes = _interopRequireDefault(require("prop-types"));
13
15
 
14
16
  var _jsxRuntime = require("theme-ui/jsx-runtime");
15
17
 
16
- /** @jsxImportSource theme-ui */
17
-
18
- /**
19
- * External dependencies
20
- */
18
+ var _excluded = ["sx"];
21
19
 
22
20
  /**
23
21
  * Internal dependencies
24
22
  */
25
- var Label = /*#__PURE__*/_react["default"].forwardRef(function (props, forwardRef) {
26
- return (0, _jsxRuntime.jsx)(_.Heading, (0, _extends2["default"])({
27
- variant: "h4",
28
- as: "label",
29
- sx: {
23
+ var Label = /*#__PURE__*/_react["default"].forwardRef(function (_ref, forwardRef) {
24
+ var sx = _ref.sx,
25
+ rest = (0, _objectWithoutPropertiesLoose2["default"])(_ref, _excluded);
26
+ return (0, _jsxRuntime.jsx)("label", (0, _extends2["default"])({
27
+ sx: (0, _extends2["default"])({
28
+ fontWeight: 500,
29
+ fontSize: 2,
30
+ lineHeight: 1.5,
30
31
  display: 'block',
31
32
  mb: 2,
32
33
  color: 'muted'
33
- },
34
+ }, sx),
34
35
  ref: forwardRef
35
- }, props));
36
+ }, rest));
36
37
  });
37
38
 
38
39
  exports.Label = Label;
40
+ Label.propTypes = {
41
+ sx: _propTypes["default"].object
42
+ };
39
43
  Label.displayName = 'Label';
@@ -5,34 +5,155 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  exports.__esModule = true;
6
6
  exports.Radio = void 0;
7
7
 
8
- var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
-
10
8
  var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
11
9
 
12
- var _react = _interopRequireDefault(require("react"));
10
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
13
11
 
14
- var _themeUi = require("theme-ui");
12
+ var _react = _interopRequireDefault(require("react"));
15
13
 
16
14
  var _propTypes = _interopRequireDefault(require("prop-types"));
17
15
 
18
- var _jsxRuntime = require("theme-ui/jsx-runtime");
16
+ var _classnames = _interopRequireDefault(require("classnames"));
17
+
18
+ var _Label = require("./Label");
19
19
 
20
- var _excluded = ["disabled"];
20
+ var _ScreenReaderText = require("../ScreenReaderText/ScreenReaderText");
21
21
 
22
- var Radio = /*#__PURE__*/_react["default"].forwardRef(function (_ref, forwardRef) {
23
- var disabled = _ref.disabled,
24
- props = (0, _objectWithoutPropertiesLoose2["default"])(_ref, _excluded);
25
- return (0, _jsxRuntime.jsx)(_themeUi.Radio, (0, _extends2["default"])({
26
- sx: {
27
- opacity: disabled ? 0.4 : 1
22
+ var _jsxRuntime = require("theme-ui/jsx-runtime");
23
+
24
+ var _excluded = ["disabled", "defaultValue", "onChange", "name", "options", "className"];
25
+ var inputStyle = (0, _extends2["default"])({}, _ScreenReaderText.screenReaderTextClass, {
26
+ width: '16px',
27
+ height: '16px',
28
+ '&:focus ~ label:before': function focusLabelBefore(theme) {
29
+ return (0, _extends2["default"])({}, theme.outline, {
30
+ content: '""',
31
+ border: '2px solid',
32
+ borderColor: 'border',
33
+ zIndex: 3,
34
+ left: -1 * (theme.space[4] - theme.space[2]) + "px"
35
+ });
36
+ },
37
+ '&:checked ~ label::after': {
38
+ opacity: 1,
39
+ transform: 'scale(1)'
40
+ }
41
+ });
42
+ var labelStyle = {
43
+ cursor: 'pointer',
44
+ position: 'relative',
45
+ marginLeft: function marginLeft(theme) {
46
+ return theme.space[4] - theme.space[2] + "px";
47
+ },
48
+ marginBottom: 0,
49
+ userSelect: 'none',
50
+ color: 'heading',
51
+ lineHeight: 1.5,
52
+ '&:before, &:after': {
53
+ borderRadius: '50%',
54
+ position: 'absolute',
55
+ top: 0,
56
+ left: function left(theme) {
57
+ return -1 * (theme.space[4] - theme.space[2]) + "px";
28
58
  },
29
- disabled: disabled,
59
+ transition: 'all .3s ease-out',
60
+ zIndex: 2,
61
+ width: '16px',
62
+ height: '16px'
63
+ },
64
+ '&::before': {
65
+ content: '""',
66
+ border: '2px solid',
67
+ borderColor: 'border'
68
+ },
69
+ '&::after': {
70
+ content: '""',
71
+ backgroundColor: 'primary',
72
+ backgroundPosition: 'left 2px top 2px',
73
+ backgroundSize: '70%',
74
+ backgroundRepeat: 'no-repeat',
75
+ backgroundImage: "url(\n\t\t\t\t\t'data:image/svg+xml;utf8,<svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M13.4999 4.9995L5.7254 12.4008L2.5 9.33023L3.83307 7.92994L5.7254 9.73144L12.1668 3.59921L13.4999 4.9995Z\" fill=\"white\"/></svg>')",
76
+ border: '2px solid',
77
+ borderColor: 'border',
78
+ color: 'white',
79
+ transform: 'scale(0)',
80
+ opacity: 0
81
+ }
82
+ };
83
+
84
+ var CustomLabel = function CustomLabel(_ref) {
85
+ var children = _ref.children;
86
+ return (0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
87
+ children: /*#__PURE__*/_react["default"].cloneElement(_react["default"].Children.only(children), (0, _extends2["default"])({}, children.props, {
88
+ sx: (0, _extends2["default"])({}, labelStyle, children.props.sx),
89
+ className: children.props.className + " vip-radio-component-item-label"
90
+ }))
91
+ });
92
+ };
93
+
94
+ CustomLabel.propTypes = {
95
+ children: _propTypes["default"].shape({
96
+ props: {
97
+ className: _propTypes["default"].any,
98
+ sx: _propTypes["default"].object
99
+ }
100
+ }).isRequired
101
+ };
102
+
103
+ var Radio = /*#__PURE__*/_react["default"].forwardRef(function (_ref2, forwardRef) {
104
+ var disabled = _ref2.disabled,
105
+ defaultValue = _ref2.defaultValue,
106
+ onChange = _ref2.onChange,
107
+ _ref2$name = _ref2.name,
108
+ name = _ref2$name === void 0 ? '' : _ref2$name,
109
+ _ref2$options = _ref2.options,
110
+ options = _ref2$options === void 0 ? [] : _ref2$options,
111
+ className = _ref2.className,
112
+ props = (0, _objectWithoutPropertiesLoose2["default"])(_ref2, _excluded);
113
+ var renderedOptions = options.map(function (option) {
114
+ return (0, _jsxRuntime.jsxs)("div", {
115
+ sx: {
116
+ display: 'flex',
117
+ alignItems: 'center',
118
+ minHeight: function minHeight(theme) {
119
+ return theme.space[4] - theme.space[2] + "px";
120
+ }
121
+ },
122
+ className: (0, _classnames["default"])('vip-radio-component-item', "vip-radio-component-item-" + option.id),
123
+ children: [(0, _jsxRuntime.jsx)("input", {
124
+ type: "radio",
125
+ id: option.id,
126
+ name: name,
127
+ value: "" + option.value,
128
+ sx: inputStyle,
129
+ onChange: onChange,
130
+ className: (0, _classnames["default"])('vip-radio-component-item-input', option == null ? void 0 : option.className),
131
+ checked: "" + option.value === "" + defaultValue
132
+ }), typeof option.label === 'string' ? (0, _jsxRuntime.jsx)(_Label.Label, {
133
+ className: (0, _classnames["default"])('vip-radio-component-item-label', option == null ? void 0 : option.className),
134
+ htmlFor: option.id,
135
+ sx: labelStyle,
136
+ children: option.label
137
+ }) : (0, _jsxRuntime.jsx)(CustomLabel, {
138
+ children: option.label
139
+ })]
140
+ }, option.id);
141
+ });
142
+ return (0, _jsxRuntime.jsx)("div", (0, _extends2["default"])({
143
+ className: (0, _classnames["default"])('vip-radio-component', "vip-radio-component-" + name, className),
30
144
  ref: forwardRef
31
- }, props));
145
+ }, props, {
146
+ children: renderedOptions
147
+ }));
32
148
  });
33
149
 
34
150
  exports.Radio = Radio;
35
151
  Radio.displayName = 'Radio';
36
152
  Radio.propTypes = {
37
- disabled: _propTypes["default"].bool
153
+ disabled: _propTypes["default"].bool,
154
+ defaultValue: _propTypes["default"].any,
155
+ onChange: _propTypes["default"].func,
156
+ options: _propTypes["default"].array,
157
+ name: _propTypes["default"].string,
158
+ className: _propTypes["default"].any
38
159
  };
@@ -9,12 +9,14 @@ var _ = require("..");
9
9
 
10
10
  var _Radio = require("./Radio");
11
11
 
12
- var _Label = require("./Label");
13
-
14
12
  var _Flex = require("../Flex");
15
13
 
14
+ var _Label = require("./Label");
15
+
16
16
  var _jsxRuntime = require("theme-ui/jsx-runtime");
17
17
 
18
+ /** @jsxImportSource theme-ui */
19
+
18
20
  /**
19
21
  * External dependencies
20
22
  */
@@ -33,6 +35,10 @@ var Default = function Default() {
33
35
  checked = _useState[0],
34
36
  setChecked = _useState[1];
35
37
 
38
+ var _useState2 = (0, _react.useState)('a'),
39
+ checked2 = _useState2[0],
40
+ setChecked2 = _useState2[1];
41
+
36
42
  return (0, _jsxRuntime.jsxs)(_.Form.Root, {
37
43
  children: [(0, _jsxRuntime.jsxs)("p", {
38
44
  children: ["Per recommendation, if you have a Radio button, use a Fieldset with a legend as wrapper to your options.", ' ', (0, _jsxRuntime.jsx)("a", {
@@ -47,46 +53,63 @@ var Default = function Default() {
47
53
  fontWeight: 'bold'
48
54
  },
49
55
  children: "Apply the policy to these domains"
50
- }), (0, _jsxRuntime.jsxs)(_Flex.Flex, {
56
+ }), (0, _jsxRuntime.jsx)(_Flex.Flex, {
51
57
  sx: {
52
58
  alignItems: 'center'
53
59
  },
54
- children: [(0, _jsxRuntime.jsx)(_Radio.Radio, {
55
- name: "includeSubdomains",
56
- id: "include-all-domains-opt",
57
- onChange: function onChange() {
58
- return setChecked('a');
59
- },
60
- value: 'a',
61
- checked: checked === 'a'
62
- }), (0, _jsxRuntime.jsx)(_Label.Label, {
63
- htmlFor: "include-all-domains-opt",
64
- sx: {
65
- mb: 0
66
- },
67
- children: "All domains listed on this environment, and all subdomains"
68
- })]
69
- }), (0, _jsxRuntime.jsxs)(_Flex.Flex, {
60
+ children: (0, _jsxRuntime.jsx)(_Radio.Radio, {
61
+ name: "the_option",
62
+ defaultValue: checked,
63
+ options: [{
64
+ value: 'a',
65
+ label: 'All domains listed on this environment, and all subdomains',
66
+ id: 'option-a'
67
+ }, {
68
+ value: 'b',
69
+ label: 'All domains listed on this environment',
70
+ id: 'option-b'
71
+ }],
72
+ onChange: function onChange(e) {
73
+ return setChecked(e.target.value);
74
+ }
75
+ })
76
+ })]
77
+ }), (0, _jsxRuntime.jsxs)("fieldset", {
78
+ children: [(0, _jsxRuntime.jsx)("legend", {
70
79
  sx: {
71
- alignItems: 'center',
72
- mb: 1
80
+ mb: 0,
81
+ fontSize: 2,
82
+ fontWeight: 'bold'
83
+ },
84
+ children: "With a custom Label"
85
+ }), (0, _jsxRuntime.jsx)(_Flex.Flex, {
86
+ sx: {
87
+ alignItems: 'center'
73
88
  },
74
- children: [(0, _jsxRuntime.jsx)(_Radio.Radio, {
75
- name: "includeSubdomains",
76
- id: "include-subdomains-opt",
77
- onChange: function onChange() {
78
- return setChecked('b');
79
- },
80
- checked: checked === 'b',
81
- value: 'b'
82
- }), (0, _jsxRuntime.jsx)(_Label.Label, {
83
- id: "exclude-subdomains",
84
- htmlFor: "include-subdomains-opt",
85
- sx: {
86
- mb: 0
87
- },
88
- children: "All domains listed on this environment"
89
- })]
89
+ children: (0, _jsxRuntime.jsx)(_Radio.Radio, {
90
+ name: "the_option_custom",
91
+ defaultValue: checked2,
92
+ options: [{
93
+ value: 'a',
94
+ label: (0, _jsxRuntime.jsx)(_Label.Label, {
95
+ htmlFor: "option-custom-a",
96
+ className: "custom-class",
97
+ sx: {
98
+ color: 'primary'
99
+ },
100
+ children: "(Custom) All domains listed on this environment, and all subdomains"
101
+ }),
102
+ id: 'option-custom-a'
103
+ }, {
104
+ value: 'b',
105
+ label: 'All domains listed on this environment',
106
+ className: 'custom-class-for-this',
107
+ id: 'option-custom-b'
108
+ }],
109
+ onChange: function onChange(e) {
110
+ return setChecked2(e.target.value);
111
+ }
112
+ })
90
113
  })]
91
114
  })]
92
115
  });
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ exports.__esModule = true;
6
+ exports.ResourceItem = void 0;
7
+
8
+ var _propTypes = _interopRequireDefault(require("prop-types"));
9
+
10
+ var _ = require("..");
11
+
12
+ var _jsxRuntime = require("theme-ui/jsx-runtime");
13
+
14
+ /** @jsxImportSource theme-ui */
15
+
16
+ /**
17
+ * External dependencies
18
+ */
19
+
20
+ /**
21
+ * Internal dependencies
22
+ */
23
+ var ResourceItem = function ResourceItem(_ref) {
24
+ var children = _ref.children,
25
+ item = _ref.item,
26
+ renderActions = _ref.renderActions,
27
+ _ref$relativeTime = _ref.relativeTime,
28
+ relativeTime = _ref$relativeTime === void 0 ? false : _ref$relativeTime,
29
+ _ref$timeOnly = _ref.timeOnly,
30
+ timeOnly = _ref$timeOnly === void 0 ? false : _ref$timeOnly,
31
+ dateKey = _ref.dateKey,
32
+ _ref$icon = _ref.icon,
33
+ icon = _ref$icon === void 0 ? null : _ref$icon;
34
+ return (0, _jsxRuntime.jsxs)(_.Flex, {
35
+ sx: {
36
+ alignItems: 'center',
37
+ gap: 3
38
+ },
39
+ children: [icon, (0, _jsxRuntime.jsx)(_.Box, {
40
+ sx: {
41
+ flex: '1 1 auto'
42
+ },
43
+ children: children
44
+ }), (0, _jsxRuntime.jsxs)(_.Flex, {
45
+ sx: {
46
+ flex: '0 0 auto',
47
+ alignItems: 'center',
48
+ gap: 3
49
+ },
50
+ children: [(0, _jsxRuntime.jsx)(_.Time, {
51
+ className: "time",
52
+ relativeTime: relativeTime,
53
+ timeOnly: timeOnly,
54
+ time: item[dateKey],
55
+ sx: {
56
+ color: 'muted',
57
+ mb: 0,
58
+ textAlign: 'right',
59
+ flex: '0 0 auto'
60
+ }
61
+ }), renderActions && (0, _jsxRuntime.jsxs)(_.Flex, {
62
+ className: "actions",
63
+ sx: {
64
+ alignItems: 'center',
65
+ gap: 3
66
+ },
67
+ children: [(0, _jsxRuntime.jsx)(_.Box, {
68
+ sx: {
69
+ width: 4,
70
+ height: 4,
71
+ borderRadius: 4,
72
+ bg: 'border'
73
+ }
74
+ }), renderActions(item)]
75
+ })]
76
+ })]
77
+ });
78
+ };
79
+
80
+ exports.ResourceItem = ResourceItem;
81
+ ResourceItem.propTypes = {
82
+ children: _propTypes["default"].node,
83
+ item: _propTypes["default"].object,
84
+ icon: _propTypes["default"].node,
85
+ relativeTime: _propTypes["default"].bool,
86
+ timeOnly: _propTypes["default"].bool,
87
+ dateKey: _propTypes["default"].string,
88
+ renderActions: _propTypes["default"].func
89
+ };
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ exports.__esModule = true;
6
+ exports.ResourceList = void 0;
7
+
8
+ var _extends3 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
+
10
+ var _propTypes = _interopRequireDefault(require("prop-types"));
11
+
12
+ var _react = require("react");
13
+
14
+ var _ = require("..");
15
+
16
+ var _jsxRuntime = require("theme-ui/jsx-runtime");
17
+
18
+ /** @jsxImportSource theme-ui */
19
+
20
+ /**
21
+ * External dependencies
22
+ */
23
+
24
+ /**
25
+ * Internal dependencies
26
+ */
27
+ var formatterOptions = {
28
+ weekday: 'long',
29
+ year: 'numeric',
30
+ month: 'long',
31
+ day: 'numeric'
32
+ };
33
+
34
+ var formatDate = function formatDate(date) {
35
+ var today = new Date();
36
+
37
+ if (date.getFullYear() !== today.getFullYear()) {
38
+ return date.toLocaleDateString(formatterOptions);
39
+ } else if (date.getMonth() !== today.getMonth()) {
40
+ return date.toLocaleDateString(formatterOptions);
41
+ } else if (date.getDate() < today.getDate() - 1) {
42
+ return date.toLocaleDateString(formatterOptions);
43
+ } else if (date.getDate() === today.getDate() - 1) {
44
+ return 'Yesterday';
45
+ }
46
+
47
+ return 'Today';
48
+ };
49
+
50
+ var StyledListItem = function StyledListItem(props) {
51
+ return (0, _jsxRuntime.jsx)(_.Box, (0, _extends3["default"])({
52
+ as: "li",
53
+ sx: {
54
+ py: 2,
55
+ borderBottom: '1px solid',
56
+ borderColor: 'borders.2',
57
+ listStyleType: 'none',
58
+ margin: 0,
59
+ px: 0
60
+ }
61
+ }, props));
62
+ };
63
+
64
+ var ResourceList = function ResourceList(_ref) {
65
+ var _ref$groupedByDay = _ref.groupedByDay,
66
+ groupedByDay = _ref$groupedByDay === void 0 ? false : _ref$groupedByDay,
67
+ items = _ref.items,
68
+ renderItem = _ref.renderItem,
69
+ dateKey = _ref.dateKey;
70
+ var groupedItems = {};
71
+
72
+ if (groupedByDay) {
73
+ groupedItems = items == null ? void 0 : items.reduce(function (itemGroups, item) {
74
+ var _extends2;
75
+
76
+ var formattedDate = formatDate(item[dateKey]);
77
+ var itemsAtDate = itemGroups[formattedDate];
78
+ return (0, _extends3["default"])({}, itemGroups, (_extends2 = {}, _extends2[formattedDate] = itemsAtDate ? [].concat(itemsAtDate, [item]) : [item], _extends2));
79
+ }, {});
80
+ }
81
+
82
+ var renderItemList = function renderItemList(itemsList) {
83
+ return itemsList.map(function (item, index) {
84
+ return (0, _jsxRuntime.jsx)(StyledListItem, {
85
+ children: renderItem(item)
86
+ }, index);
87
+ });
88
+ };
89
+
90
+ var renderGoupedItems = function renderGoupedItems() {
91
+ return (0, _react.useMemo)(function () {
92
+ return Object.keys(groupedItems).map(function (groupName, index) {
93
+ return (0, _jsxRuntime.jsxs)(_.Box, {
94
+ sx: {
95
+ mb: 4
96
+ },
97
+ as: "li",
98
+ children: [(0, _jsxRuntime.jsx)(_.Heading, {
99
+ variant: "h4",
100
+ as: "h4",
101
+ sx: {
102
+ mb: 3
103
+ },
104
+ children: groupName
105
+ }), (0, _jsxRuntime.jsx)(_.Box, {
106
+ as: "ul",
107
+ sx: {
108
+ listStyleType: 'none',
109
+ m: 0,
110
+ p: 0,
111
+ borderTop: '1px solid',
112
+ borderColor: 'border'
113
+ },
114
+ children: renderItemList(groupedItems[groupName])
115
+ })]
116
+ }, index);
117
+ });
118
+ }, [groupedItems]);
119
+ };
120
+
121
+ return (0, _jsxRuntime.jsx)(_.Box, {
122
+ as: "ul",
123
+ sx: {
124
+ listStyleType: 'none',
125
+ m: 0,
126
+ p: 0
127
+ },
128
+ className: "vip-resource-list-component",
129
+ children: groupedByDay ? renderGoupedItems(groupedItems) : renderItemList(items)
130
+ });
131
+ };
132
+
133
+ exports.ResourceList = ResourceList;
134
+ ResourceList.propTypes = {
135
+ groupedByDay: _propTypes["default"].bool,
136
+ items: _propTypes["default"].array,
137
+ renderItem: _propTypes["default"].func,
138
+ relativeTime: _propTypes["default"].bool,
139
+ dateKey: _propTypes["default"].string
140
+ };
@@ -0,0 +1,379 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ exports.__esModule = true;
6
+ exports["default"] = exports.Relative = exports.Grouped = void 0;
7
+
8
+ var _react = _interopRequireDefault(require("react"));
9
+
10
+ var _bi = require("react-icons/bi");
11
+
12
+ var _ = require("..");
13
+
14
+ var _jsxRuntime = require("theme-ui/jsx-runtime");
15
+
16
+ /** @jsxImportSource theme-ui */
17
+
18
+ /**
19
+ * External dependencies
20
+ */
21
+
22
+ /**
23
+ * Internal dependencies
24
+ */
25
+ var _default = {
26
+ title: 'ResourceList',
27
+ component: _.ResourceList
28
+ };
29
+ exports["default"] = _default;
30
+ var logs = [{
31
+ actor: 'Saxon Fletcher',
32
+ action: 'switched primary domain to',
33
+ object: 'mydomain.com',
34
+ date: new Date()
35
+ }, {
36
+ actor: 'Saxon Fletcher',
37
+ action: 'switched primary domain to',
38
+ object: 'mydomain.com',
39
+ date: new Date(new Date().setHours(11))
40
+ }, {
41
+ actor: 'Simon Wheatley',
42
+ action: 'deployed to',
43
+ object: 'Production',
44
+ showObject: true,
45
+ date: new Date(new Date().setDate(15))
46
+ }, {
47
+ actor: 'Saxon Fletcher',
48
+ action: 'created a backup on',
49
+ object: 'Production',
50
+ date: new Date(new Date().setDate(13))
51
+ }];
52
+
53
+ var Grouped = function Grouped() {
54
+ return (0, _jsxRuntime.jsxs)(_.Box, {
55
+ sx: {
56
+ p: 5,
57
+ pt: 2
58
+ },
59
+ children: [(0, _jsxRuntime.jsx)(_.Heading, {
60
+ sx: {
61
+ mb: 2
62
+ },
63
+ children: "Audit Log"
64
+ }), (0, _jsxRuntime.jsx)(_.Text, {
65
+ sx: {
66
+ mb: 4
67
+ },
68
+ children: "A live trail of system and human events."
69
+ }), (0, _jsxRuntime.jsx)(_.ResourceList, {
70
+ items: logs,
71
+ dateKey: "date",
72
+ groupedByDay: true,
73
+ renderItem: function renderItem(item) {
74
+ return (0, _jsxRuntime.jsxs)(_.ResourceItem, {
75
+ item: item,
76
+ icon: (0, _jsxRuntime.jsx)(_bi.BiGlobe, {
77
+ sx: {
78
+ color: 'red'
79
+ }
80
+ }),
81
+ dateKey: 'date',
82
+ relativeTime: true,
83
+ timeOnly: true,
84
+ children: [(0, _jsxRuntime.jsxs)(_.Flex, {
85
+ sx: {
86
+ alignItems: 'center',
87
+ gap: 3
88
+ },
89
+ children: [(0, _jsxRuntime.jsx)(_.Avatar, {
90
+ name: item.actor,
91
+ src: "https://uifaces.co/our-content/donated/1H_7AxP0.jpg",
92
+ size: 16
93
+ }), (0, _jsxRuntime.jsxs)(_.Heading, {
94
+ variant: "h4",
95
+ as: "p",
96
+ sx: {
97
+ mb: 0,
98
+ fontWeight: 'normal'
99
+ },
100
+ children: [item.actor, ' ', (0, _jsxRuntime.jsx)(_.Text, {
101
+ as: "span",
102
+ sx: {
103
+ color: 'muted',
104
+ mb: 0
105
+ },
106
+ children: item.action
107
+ }), ' ', item.object]
108
+ })]
109
+ }), item.showObject && (0, _jsxRuntime.jsxs)(_.Box, {
110
+ variant: "indent",
111
+ sx: {
112
+ mt: 2,
113
+ display: 'flex',
114
+ flexWrap: 'wrap',
115
+ gap: 3,
116
+ alignItems: 'center'
117
+ },
118
+ children: [(0, _jsxRuntime.jsxs)(_.Heading, {
119
+ variant: "h5",
120
+ as: "div",
121
+ sx: {
122
+ mb: 0
123
+ },
124
+ children: ["Merge pull request", ' ', (0, _jsxRuntime.jsx)(_.Text, {
125
+ as: "span",
126
+ sx: {
127
+ color: 'muted'
128
+ },
129
+ children: "#443"
130
+ })]
131
+ }), (0, _jsxRuntime.jsxs)(_.Text, {
132
+ as: "div",
133
+ sx: {
134
+ mb: 0,
135
+ fontSize: 1,
136
+ display: 'flex',
137
+ alignItems: 'center',
138
+ gap: 1
139
+ },
140
+ children: [(0, _jsxRuntime.jsx)(_.Avatar, {
141
+ name: item.actor,
142
+ src: "https://uifaces.co/our-content/donated/n4Ngwvi7.jpg",
143
+ size: 16
144
+ }), item.actor]
145
+ }), (0, _jsxRuntime.jsxs)(_.Text, {
146
+ sx: {
147
+ mb: 0,
148
+ fontSize: 1,
149
+ display: 'flex',
150
+ alignItems: 'center',
151
+ gap: 1
152
+ },
153
+ children: [(0, _jsxRuntime.jsx)(_bi.BiCheckCircle, {
154
+ size: 16
155
+ }), "Deployed in 31s"]
156
+ })]
157
+ })]
158
+ });
159
+ }
160
+ })]
161
+ });
162
+ };
163
+
164
+ exports.Grouped = Grouped;
165
+ var deploys = [{
166
+ title: 'Merge pull request',
167
+ id: '#773',
168
+ author: 'Saxon Fletcher',
169
+ date: new Date(new Date().setHours(11)),
170
+ status: 'running'
171
+ }, {
172
+ title: 'Update homepage',
173
+ id: '#772',
174
+ author: 'Saxon Fletcher',
175
+ date: new Date(new Date().setHours(9))
176
+ }, {
177
+ title: 'Improve overall performance',
178
+ id: '#771',
179
+ author: 'Saxon Fletcher',
180
+ date: new Date(new Date().setHours(8))
181
+ }, {
182
+ title: 'Merge pull request',
183
+ id: '#770',
184
+ author: 'Saxon Fletcher',
185
+ date: new Date(new Date().setHours(5)),
186
+ status: 'failed'
187
+ }, {
188
+ title: 'Merge pull request',
189
+ id: '#773',
190
+ author: 'Saxon Fletcher',
191
+ date: new Date(new Date().setHours(11))
192
+ }, {
193
+ title: 'Update homepage',
194
+ id: '#772',
195
+ author: 'Saxon Fletcher',
196
+ date: new Date(new Date().setHours(9))
197
+ }, {
198
+ title: 'Improve overall performance',
199
+ id: '#771',
200
+ author: 'Saxon Fletcher',
201
+ date: new Date(new Date().setHours(8))
202
+ }, {
203
+ title: 'Merge pull request',
204
+ id: '#770',
205
+ author: 'Saxon Fletcher',
206
+ date: new Date(new Date().setHours(5))
207
+ }, {
208
+ title: 'Merge pull request',
209
+ id: '#773',
210
+ author: 'Saxon Fletcher',
211
+ date: new Date(new Date().setHours(11))
212
+ }, {
213
+ title: 'Update homepage',
214
+ id: '#772',
215
+ author: 'Saxon Fletcher',
216
+ date: new Date(new Date().setHours(9))
217
+ }, {
218
+ title: 'Improve overall performance',
219
+ id: '#771',
220
+ author: 'Saxon Fletcher',
221
+ date: new Date(new Date().setHours(8))
222
+ }, {
223
+ title: 'Merge pull request',
224
+ id: '#770',
225
+ author: 'Saxon Fletcher',
226
+ date: new Date(new Date().setHours(5))
227
+ }, {
228
+ title: 'Merge pull request',
229
+ id: '#773',
230
+ author: 'Saxon Fletcher',
231
+ date: new Date(new Date().setHours(11))
232
+ }, {
233
+ title: 'Update homepage',
234
+ id: '#772',
235
+ author: 'Saxon Fletcher',
236
+ date: new Date(new Date().setHours(9))
237
+ }, {
238
+ title: 'Improve overall performance',
239
+ id: '#771',
240
+ author: 'Saxon Fletcher',
241
+ date: new Date(new Date().setHours(8))
242
+ }, {
243
+ title: 'Merge pull request',
244
+ id: '#770',
245
+ author: 'Saxon Fletcher',
246
+ date: new Date(new Date().setHours(5))
247
+ }];
248
+
249
+ var Relative = function Relative() {
250
+ return (0, _jsxRuntime.jsxs)(_.Box, {
251
+ sx: {
252
+ p: 5,
253
+ pt: 2
254
+ },
255
+ children: [(0, _jsxRuntime.jsx)(_.Heading, {
256
+ sx: {
257
+ mb: 2
258
+ },
259
+ children: "Deploys"
260
+ }), (0, _jsxRuntime.jsx)(_.Text, {
261
+ sx: {
262
+ mb: 4
263
+ },
264
+ children: "View and manage application deployments."
265
+ }), (0, _jsxRuntime.jsx)(_.Card, {
266
+ variant: "indent",
267
+ sx: {
268
+ mb: 4,
269
+ display: 'flex',
270
+ flexDirection: 'row-reverse',
271
+ gap: 1
272
+ },
273
+ children: deploys.map(function (deploy, index) {
274
+ return (0, _jsxRuntime.jsx)(_.Box, {
275
+ sx: {
276
+ flex: '1 1 auto',
277
+ width: 10,
278
+ height: 4,
279
+ backgroundColor: deploy.status === 'running' ? 'blue.50' : 'green.50',
280
+ borderRadius: 1
281
+ }
282
+ }, index);
283
+ })
284
+ }), (0, _jsxRuntime.jsx)(_.ResourceList, {
285
+ items: deploys,
286
+ dateKey: "date",
287
+ groupedByDay: false,
288
+ renderItem: function renderItem(item) {
289
+ return (0, _jsxRuntime.jsx)(_.ResourceItem, {
290
+ item: item,
291
+ dateKey: 'date',
292
+ relativeTime: true,
293
+ timeOnly: true,
294
+ renderActions: function renderActions() {
295
+ return (0, _jsxRuntime.jsx)(_.Flex, {
296
+ sx: {
297
+ alignItems: 'center'
298
+ },
299
+ children: (0, _jsxRuntime.jsx)(_.Button, {
300
+ variant: "secondary",
301
+ sx: {
302
+ fontSize: 1
303
+ },
304
+ children: "Rollback"
305
+ })
306
+ });
307
+ },
308
+ children: (0, _jsxRuntime.jsxs)(_.Flex, {
309
+ sx: {
310
+ alignItems: 'center',
311
+ gap: 4
312
+ },
313
+ children: [(0, _jsxRuntime.jsxs)(_.Flex, {
314
+ sx: {
315
+ alignItems: 'center',
316
+ gap: 3,
317
+ minWidth: 300
318
+ },
319
+ children: [(0, _jsxRuntime.jsxs)(_.Heading, {
320
+ variant: "h4",
321
+ as: "p",
322
+ sx: {
323
+ mb: 0,
324
+ fontWeight: 'normal'
325
+ },
326
+ children: [item.title, ' ', (0, _jsxRuntime.jsx)(_.Text, {
327
+ as: "span",
328
+ sx: {
329
+ color: 'muted',
330
+ mb: 0
331
+ },
332
+ children: item.id
333
+ })]
334
+ }), item.status === 'running' && (0, _jsxRuntime.jsx)(_.Badge, {
335
+ sx: {
336
+ mb: 0
337
+ },
338
+ children: "Running"
339
+ })]
340
+ }), (0, _jsxRuntime.jsxs)(_.Text, {
341
+ as: "div",
342
+ sx: {
343
+ mb: 0,
344
+ color: 'muted',
345
+ display: 'flex',
346
+ alignItems: 'center',
347
+ gap: 2
348
+ },
349
+ children: [(0, _jsxRuntime.jsx)(_.Avatar, {
350
+ name: item.author,
351
+ size: 16,
352
+ src: "https://randomuser.me/api/portraits/men/46.jpg"
353
+ }), item.author]
354
+ }), (0, _jsxRuntime.jsx)(_.Text, {
355
+ sx: {
356
+ mb: 0,
357
+ color: item.status === 'running' ? 'blue.60' : 'muted',
358
+ display: 'flex',
359
+ alignItems: 'center',
360
+ gap: 1
361
+ },
362
+ children: item.status === 'running' ? (0, _jsxRuntime.jsxs)(_react["default"].Fragment, {
363
+ children: [(0, _jsxRuntime.jsx)(_bi.BiRevision, {
364
+ size: 16
365
+ }), "Running for 31s"]
366
+ }) : (0, _jsxRuntime.jsxs)(_react["default"].Fragment, {
367
+ children: [(0, _jsxRuntime.jsx)(_bi.BiCheckCircle, {
368
+ size: 16
369
+ }), "Deployed in 31s"]
370
+ })
371
+ })]
372
+ })
373
+ });
374
+ }
375
+ })]
376
+ });
377
+ };
378
+
379
+ exports.Relative = Relative;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+
5
+ var _ResourceList = require("./ResourceList");
6
+
7
+ exports.ResourceList = _ResourceList.ResourceList;
8
+
9
+ var _ResourceItem = require("./ResourceItem");
10
+
11
+ exports.ResourceItem = _ResourceItem.ResourceItem;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/vip-design-system",
3
- "version": "0.26.7",
3
+ "version": "0.27.0",
4
4
  "main": "build/system/index.js",
5
5
  "scripts": {
6
6
  "build-storybook": "build-storybook",
@@ -4,22 +4,32 @@
4
4
  * External dependencies
5
5
  */
6
6
  import React from 'react';
7
+ import PropTypes from 'prop-types';
7
8
 
8
9
  /**
9
10
  * Internal dependencies
10
11
  */
11
- import { Heading } from '..';
12
12
 
13
- const Label = React.forwardRef( ( props, forwardRef ) => (
14
- <Heading
15
- variant="h4"
16
- as="label"
17
- sx={ { display: 'block', mb: 2, color: 'muted' } }
13
+ const Label = React.forwardRef( ( { sx, ...rest }, forwardRef ) => (
14
+ <label
15
+ sx={ {
16
+ fontWeight: 500,
17
+ fontSize: 2,
18
+ lineHeight: 1.5,
19
+ display: 'block',
20
+ mb: 2,
21
+ color: 'muted',
22
+ ...sx,
23
+ } }
18
24
  ref={ forwardRef }
19
- { ...props }
25
+ { ...rest }
20
26
  />
21
27
  ) );
22
28
 
29
+ Label.propTypes = {
30
+ sx: PropTypes.object,
31
+ };
32
+
23
33
  Label.displayName = 'Label';
24
34
 
25
35
  export { Label };
@@ -1,25 +1,156 @@
1
+ /* eslint-disable max-len */
1
2
  /** @jsxImportSource theme-ui */
2
3
 
3
4
  /**
4
5
  * External dependencies
5
6
  */
6
7
  import React from 'react';
7
- import { Radio as ThemeRadio } from 'theme-ui';
8
8
  import PropTypes from 'prop-types';
9
+ import classNames from 'classnames';
10
+ import { Label } from './Label';
11
+ import { screenReaderTextClass } from '../ScreenReaderText/ScreenReaderText';
9
12
 
10
- const Radio = React.forwardRef( ( { disabled, ...props }, forwardRef ) => (
11
- <ThemeRadio
12
- sx={ { opacity: disabled ? 0.4 : 1 } }
13
- disabled={ disabled }
14
- ref={ forwardRef }
15
- { ...props }
16
- />
17
- ) );
13
+ const inputStyle = {
14
+ ...screenReaderTextClass,
15
+ width: '16px',
16
+ height: '16px',
17
+ '&:focus ~ label:before': theme => ( {
18
+ ...theme.outline,
19
+ content: '""',
20
+ border: '2px solid',
21
+ borderColor: 'border',
22
+ zIndex: 3,
23
+ left: `${ -1 * ( theme.space[ 4 ] - theme.space[ 2 ] ) }px`,
24
+ } ),
25
+ '&:checked ~ label::after': {
26
+ opacity: 1,
27
+ transform: 'scale(1)',
28
+ },
29
+ };
30
+
31
+ const labelStyle = {
32
+ cursor: 'pointer',
33
+ position: 'relative',
34
+ marginLeft: theme => `${ theme.space[ 4 ] - theme.space[ 2 ] }px`,
35
+ marginBottom: 0,
36
+ userSelect: 'none',
37
+ color: 'heading',
38
+ lineHeight: 1.5,
39
+ '&:before, &:after': {
40
+ borderRadius: '50%',
41
+ position: 'absolute',
42
+ top: 0,
43
+ left: theme => `${ -1 * ( theme.space[ 4 ] - theme.space[ 2 ] ) }px`,
44
+ transition: 'all .3s ease-out',
45
+ zIndex: 2,
46
+ width: '16px',
47
+ height: '16px',
48
+ },
49
+ '&::before': {
50
+ content: '""',
51
+ border: '2px solid',
52
+ borderColor: 'border',
53
+ },
54
+ '&::after': {
55
+ content: '""',
56
+ backgroundColor: 'primary',
57
+ backgroundPosition: 'left 2px top 2px',
58
+ backgroundSize: '70%',
59
+ backgroundRepeat: 'no-repeat',
60
+
61
+ backgroundImage: `url(
62
+ 'data:image/svg+xml;utf8,<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.4999 4.9995L5.7254 12.4008L2.5 9.33023L3.83307 7.92994L5.7254 9.73144L12.1668 3.59921L13.4999 4.9995Z" fill="white"/></svg>')`,
63
+ border: '2px solid',
64
+ borderColor: 'border',
65
+ color: 'white',
66
+ transform: 'scale(0)',
67
+ opacity: 0,
68
+ },
69
+ };
70
+
71
+ const CustomLabel = ( { children } ) => (
72
+ <>
73
+ { React.cloneElement( React.Children.only( children ), {
74
+ ...children.props,
75
+ sx: { ...labelStyle, ...children.props.sx },
76
+ className: `${ children.props.className } vip-radio-component-item-label`,
77
+ } ) }
78
+ </>
79
+ );
80
+
81
+ CustomLabel.propTypes = {
82
+ children: PropTypes.shape( { props: { className: PropTypes.any, sx: PropTypes.object } } )
83
+ .isRequired,
84
+ };
85
+
86
+ const Radio = React.forwardRef(
87
+ (
88
+ { disabled, defaultValue, onChange, name = '', options = [], className, ...props },
89
+ forwardRef
90
+ ) => {
91
+ const renderedOptions = options.map( option => (
92
+ <div
93
+ sx={ {
94
+ display: 'flex',
95
+ alignItems: 'center',
96
+ minHeight: theme => `${ theme.space[ 4 ] - theme.space[ 2 ] }px`,
97
+ } }
98
+ key={ option.id }
99
+ className={ classNames(
100
+ 'vip-radio-component-item',
101
+ `vip-radio-component-item-${ option.id }`
102
+ ) }
103
+ >
104
+ <input
105
+ type="radio"
106
+ id={ option.id }
107
+ name={ name }
108
+ value={ `${ option.value }` }
109
+ sx={ inputStyle }
110
+ onChange={ onChange }
111
+ className={ classNames( 'vip-radio-component-item-input', option?.className ) }
112
+ checked={ `${ option.value }` === `${ defaultValue }` }
113
+ />
114
+
115
+ { typeof option.label === 'string' ? (
116
+ <Label
117
+ className={ classNames( 'vip-radio-component-item-label', option?.className ) }
118
+ htmlFor={ option.id }
119
+ sx={ labelStyle }
120
+ >
121
+ { option.label }
122
+ </Label>
123
+ ) : (
124
+ <CustomLabel>{ option.label }</CustomLabel>
125
+ ) }
126
+ </div>
127
+ ) );
128
+
129
+ return (
130
+ <div
131
+ className={ classNames(
132
+ 'vip-radio-component',
133
+ `vip-radio-component-${ name }`,
134
+ className
135
+ ) }
136
+ ref={ forwardRef }
137
+ { ...props }
138
+ >
139
+ { renderedOptions }
140
+ </div>
141
+ );
142
+ }
143
+ );
18
144
 
19
145
  Radio.displayName = 'Radio';
20
146
 
21
147
  Radio.propTypes = {
22
148
  disabled: PropTypes.bool,
149
+ defaultValue: PropTypes.any,
150
+ onChange: PropTypes.func,
151
+ options: PropTypes.array,
152
+ name: PropTypes.string,
153
+ className: PropTypes.any,
23
154
  };
24
155
 
25
156
  export { Radio };
@@ -1,3 +1,5 @@
1
+ /** @jsxImportSource theme-ui */
2
+
1
3
  /**
2
4
  * External dependencies
3
5
  */
@@ -8,8 +10,8 @@ import { useState } from 'react';
8
10
  */
9
11
  import { Form } from '..';
10
12
  import { Radio } from './Radio';
11
- import { Label } from './Label';
12
13
  import { Flex } from '../Flex';
14
+ import { Label } from './Label';
13
15
 
14
16
  export default {
15
17
  title: 'Form/Radio',
@@ -18,6 +20,7 @@ export default {
18
20
 
19
21
  export const Default = () => {
20
22
  const [ checked, setChecked ] = useState( 'a' );
23
+ const [ checked2, setChecked2 ] = useState( 'a' );
21
24
 
22
25
  return (
23
26
  <Form.Root>
@@ -35,30 +38,51 @@ export const Default = () => {
35
38
 
36
39
  <Flex sx={ { alignItems: 'center' } }>
37
40
  <Radio
38
- name="includeSubdomains"
39
- id="include-all-domains-opt"
40
- onChange={ () => setChecked( 'a' ) }
41
- value={ 'a' }
42
- checked={ checked === 'a' }
41
+ name="the_option"
42
+ defaultValue={ checked }
43
+ options={ [
44
+ {
45
+ value: 'a',
46
+ label: 'All domains listed on this environment, and all subdomains',
47
+ id: 'option-a',
48
+ },
49
+ { value: 'b', label: 'All domains listed on this environment', id: 'option-b' },
50
+ ] }
51
+ onChange={ e => setChecked( e.target.value ) }
43
52
  />
44
-
45
- <Label htmlFor="include-all-domains-opt" sx={ { mb: 0 } }>
46
- All domains listed on this environment, and all subdomains
47
- </Label>
48
53
  </Flex>
54
+ </fieldset>
49
55
 
50
- <Flex sx={ { alignItems: 'center', mb: 1 } }>
56
+ <fieldset>
57
+ <legend sx={ { mb: 0, fontSize: 2, fontWeight: 'bold' } }>With a custom Label</legend>
58
+
59
+ <Flex sx={ { alignItems: 'center' } }>
51
60
  <Radio
52
- name="includeSubdomains"
53
- id="include-subdomains-opt"
54
- onChange={ () => setChecked( 'b' ) }
55
- checked={ checked === 'b' }
56
- value={ 'b' }
61
+ name="the_option_custom"
62
+ defaultValue={ checked2 }
63
+ options={ [
64
+ {
65
+ value: 'a',
66
+ label: (
67
+ <Label
68
+ htmlFor="option-custom-a"
69
+ className="custom-class"
70
+ sx={ { color: 'primary' } }
71
+ >
72
+ (Custom) All domains listed on this environment, and all subdomains
73
+ </Label>
74
+ ),
75
+ id: 'option-custom-a',
76
+ },
77
+ {
78
+ value: 'b',
79
+ label: 'All domains listed on this environment',
80
+ className: 'custom-class-for-this',
81
+ id: 'option-custom-b',
82
+ },
83
+ ] }
84
+ onChange={ e => setChecked2( e.target.value ) }
57
85
  />
58
-
59
- <Label id="exclude-subdomains" htmlFor="include-subdomains-opt" sx={ { mb: 0 } }>
60
- All domains listed on this environment
61
- </Label>
62
86
  </Flex>
63
87
  </fieldset>
64
88
  </Form.Root>