@automattic/vip-design-system 0.28.7 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/build/system/Badge/Badge.js +2 -5
  2. package/build/system/Button/Button.stories.js +2 -2
  3. package/build/system/Button/ButtonSubmit.js +7 -14
  4. package/build/system/Button/ButtonSubmit.stories.js +3 -3
  5. package/build/system/Button/index.js +1 -8
  6. package/build/system/Button/variants.js +6 -0
  7. package/build/system/Form/Input.js +1 -0
  8. package/build/system/Form/Radio.js +4 -4
  9. package/build/system/Form/index.js +0 -4
  10. package/build/system/NewForm/FormAutocomplete.js +26 -13
  11. package/build/system/NewForm/FormAutocomplete.stories.js +3 -2
  12. package/build/system/NewForm/FormAutocomplete.test.js +2 -2
  13. package/build/system/NewForm/FormSelect.js +15 -11
  14. package/build/system/NewForm/FormSelect.stories.js +1 -1
  15. package/build/system/index.js +0 -1
  16. package/package.json +1 -1
  17. package/src/system/Badge/Badge.js +2 -5
  18. package/src/system/Button/Button.stories.jsx +1 -1
  19. package/src/system/Button/ButtonSubmit.js +5 -10
  20. package/src/system/Button/ButtonSubmit.stories.jsx +1 -1
  21. package/src/system/Button/index.js +1 -12
  22. package/src/system/Button/variants.js +1 -0
  23. package/src/system/Form/Input.js +1 -0
  24. package/src/system/Form/Radio.js +3 -3
  25. package/src/system/Form/index.js +0 -2
  26. package/src/system/NewForm/FormAutocomplete.js +28 -8
  27. package/src/system/NewForm/FormAutocomplete.stories.jsx +3 -2
  28. package/src/system/NewForm/FormAutocomplete.test.js +4 -2
  29. package/src/system/NewForm/FormSelect.js +18 -10
  30. package/src/system/NewForm/FormSelect.stories.jsx +1 -1
  31. package/src/system/index.js +0 -2
  32. package/src/system/Form/ToggleGroup.js +0 -67
  33. package/src/system/Form/ToggleGroup.stories.jsx +0 -41
@@ -41,16 +41,13 @@ var Badge = /*#__PURE__*/_react["default"].forwardRef(function (_ref, forwardRef
41
41
  display: 'inline-block',
42
42
  borderRadius: 1,
43
43
  fontWeight: 'heading',
44
- '&:hover, &:focus': {
45
- backgroundColor: "tag." + variant + ".hover"
46
- },
47
44
  a: {
48
45
  color: "tag." + variant + ".text",
49
46
  '&:hover, &:focus, &:active': {
50
47
  textDecoration: 'none'
51
48
  },
52
- '&:active': {
53
- color: variant + ".active"
49
+ '&:active, &:visited': {
50
+ color: "tag." + variant + ".text"
54
51
  }
55
52
  }
56
53
  }, sx),
@@ -15,7 +15,7 @@ var _ScreenReaderText = _interopRequireDefault(require("../ScreenReaderText"));
15
15
 
16
16
  var _ = require("..");
17
17
 
18
- var _2 = require(".");
18
+ var _variants = _interopRequireDefault(require("./variants"));
19
19
 
20
20
  var _jsxRuntime = require("theme-ui/jsx-runtime");
21
21
 
@@ -38,7 +38,7 @@ var _default = {
38
38
  },
39
39
  variant: {
40
40
  type: 'select',
41
- options: _2.variants
41
+ options: _variants["default"]
42
42
  }
43
43
  }
44
44
  };
@@ -19,11 +19,11 @@ var _Spinner = require("../Spinner");
19
19
 
20
20
  var _classnames = _interopRequireDefault(require("classnames"));
21
21
 
22
- var _ = require(".");
22
+ var _variants = _interopRequireDefault(require("./variants"));
23
23
 
24
24
  var _jsxRuntime = require("theme-ui/jsx-runtime");
25
25
 
26
- var _excluded = ["show", "variant", "label", "loading", "disabled", "loadingIcon", "loadingIconSize", "loadingIconColor"];
26
+ var _excluded = ["show", "variant", "label", "loading", "disabled", "loadingIcon", "loadingIconSize"];
27
27
 
28
28
  var DefaultSpinner = function DefaultSpinner(_ref) {
29
29
  var size = _ref.size,
@@ -49,7 +49,7 @@ var ButtonSubmit = /*#__PURE__*/_react["default"].forwardRef(function (_ref2, fo
49
49
  var _ref2$show = _ref2.show,
50
50
  show = _ref2$show === void 0 ? true : _ref2$show,
51
51
  _ref2$variant = _ref2.variant,
52
- variant = _ref2$variant === void 0 ? 'secondary' : _ref2$variant,
52
+ variant = _ref2$variant === void 0 ? _variants["default"][1] : _ref2$variant,
53
53
  label = _ref2.label,
54
54
  _ref2$loading = _ref2.loading,
55
55
  loading = _ref2$loading === void 0 ? false : _ref2$loading,
@@ -59,18 +59,12 @@ var ButtonSubmit = /*#__PURE__*/_react["default"].forwardRef(function (_ref2, fo
59
59
  loadingIcon = _ref2$loadingIcon === void 0 ? DefaultSpinner : _ref2$loadingIcon,
60
60
  _ref2$loadingIconSize = _ref2.loadingIconSize,
61
61
  loadingIconSize = _ref2$loadingIconSize === void 0 ? 20 : _ref2$loadingIconSize,
62
- _ref2$loadingIconColo = _ref2.loadingIconColor,
63
- loadingIconColor = _ref2$loadingIconColo === void 0 ? undefined : _ref2$loadingIconColo,
64
62
  rest = (0, _objectWithoutPropertiesLoose2["default"])(_ref2, _excluded);
65
63
 
66
64
  if (!show) {
67
65
  return null;
68
66
  }
69
67
 
70
- if (!loadingIconColor && variant === 'display') {
71
- loadingIconColor = 'button.display.label.default';
72
- }
73
-
74
68
  return (0, _jsxRuntime.jsxs)(_Button.Button, (0, _extends2["default"])({
75
69
  ref: forwardRef,
76
70
  className: (0, _classnames["default"])('vip-button-submit-component', "vip-button-submit-" + variant),
@@ -80,7 +74,7 @@ var ButtonSubmit = /*#__PURE__*/_react["default"].forwardRef(function (_ref2, fo
80
74
  }, rest, {
81
75
  children: [label, ' ', !!loading && loadingIcon({
82
76
  size: loadingIconSize,
83
- color: loadingIconColor
77
+ color: "button." + variant + ".label.default"
84
78
  })]
85
79
  }));
86
80
  });
@@ -88,12 +82,11 @@ var ButtonSubmit = /*#__PURE__*/_react["default"].forwardRef(function (_ref2, fo
88
82
  exports.ButtonSubmit = ButtonSubmit;
89
83
  ButtonSubmit.displayName = 'ButtonSubmit';
90
84
  ButtonSubmit.propTypes = {
91
- label: _propTypes["default"].string.isRequired,
85
+ label: _propTypes["default"].node.isRequired,
92
86
  disabled: _propTypes["default"].bool,
93
87
  loading: _propTypes["default"].bool,
94
- variant: _propTypes["default"].oneOf(_.variants),
88
+ variant: _propTypes["default"].oneOf(_variants["default"]),
95
89
  show: _propTypes["default"].bool,
96
90
  loadingIcon: _propTypes["default"].any,
97
- loadingIconSize: _propTypes["default"].number,
98
- loadingIconColor: _propTypes["default"].string
91
+ loadingIconSize: _propTypes["default"].number
99
92
  };
@@ -11,7 +11,7 @@ var _react = _interopRequireDefault(require("react"));
11
11
 
12
12
  var _ = require("..");
13
13
 
14
- var _2 = require(".");
14
+ var _variants = _interopRequireDefault(require("./variants"));
15
15
 
16
16
  var _jsxRuntime = require("theme-ui/jsx-runtime");
17
17
 
@@ -48,7 +48,7 @@ var _default = {
48
48
  },
49
49
  variant: {
50
50
  type: 'select',
51
- options: _2.variants
51
+ options: _variants["default"]
52
52
  }
53
53
  }
54
54
  };
@@ -56,7 +56,7 @@ exports["default"] = _default;
56
56
 
57
57
  var Template = function Template(args) {
58
58
  return (0, _jsxRuntime.jsx)(_react["default"].Fragment, {
59
- children: _2.variants.map(function (v) {
59
+ children: _variants["default"].map(function (v) {
60
60
  return (0, _jsxRuntime.jsx)(_.ButtonSubmit, (0, _extends2["default"])({
61
61
  sx: {
62
62
  m: 3
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
 
3
3
  exports.__esModule = true;
4
- exports.variants = void 0;
5
4
 
6
5
  var _Button = require("./Button");
7
6
 
@@ -9,10 +8,4 @@ exports.Button = _Button.Button;
9
8
 
10
9
  var _ButtonSubmit = require("./ButtonSubmit");
11
10
 
12
- exports.ButtonSubmit = _ButtonSubmit.ButtonSubmit;
13
-
14
- /**
15
- * Internal dependencies
16
- */
17
- var variants = ['primary', 'secondary', 'text', 'icon', 'tertiary', 'ghost', 'danger', 'display'];
18
- exports.variants = variants;
11
+ exports.ButtonSubmit = _ButtonSubmit.ButtonSubmit;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports["default"] = void 0;
5
+ var _default = ['primary', 'secondary', 'text', 'icon', 'tertiary', 'ghost', 'danger', 'display'];
6
+ exports["default"] = _default;
@@ -53,6 +53,7 @@ var Input = /*#__PURE__*/_react["default"].forwardRef(function (_ref, ref) {
53
53
  ref: ref,
54
54
  id: forLabel,
55
55
  required: required,
56
+ "aria-required": required,
56
57
  "aria-describedby": hasError ? "describe-" + forLabel + "-validation" : undefined,
57
58
  sx: (0, _extends2["default"])({}, inputStyles, sx)
58
59
  }, props)), hasError && errorMessage && (0, _jsxRuntime.jsx)(_.Validation, {
@@ -188,10 +188,10 @@ var Radio = /*#__PURE__*/_react["default"].forwardRef(function (_ref3, forwardRe
188
188
  exports.Radio = Radio;
189
189
  Radio.displayName = 'Radio';
190
190
  Radio.propTypes = {
191
- disabled: _propTypes["default"].bool,
191
+ className: _propTypes["default"].any,
192
192
  defaultValue: _propTypes["default"].any,
193
- onChange: _propTypes["default"].func,
194
- options: _propTypes["default"].any,
193
+ disabled: _propTypes["default"].bool,
195
194
  name: _propTypes["default"].string,
196
- className: _propTypes["default"].any
195
+ onChange: _propTypes["default"].func,
196
+ options: _propTypes["default"].any
197
197
  };
@@ -22,10 +22,6 @@ var _ToggleRow = require("./ToggleRow");
22
22
 
23
23
  exports.ToggleRow = _ToggleRow.ToggleRow;
24
24
 
25
- var _ToggleGroup = require("./ToggleGroup");
26
-
27
- exports.ToggleGroup = _ToggleGroup.ToggleGroup;
28
-
29
25
  var _Select = require("./Select");
30
26
 
31
27
  exports.Select = _Select.Select;
@@ -37,7 +37,7 @@ var _Form = require("../Form");
37
37
 
38
38
  var _jsxRuntime = require("theme-ui/jsx-runtime");
39
39
 
40
- var _excluded = ["autoFilter", "className", "debounce", "displayMenu", "forLabel", "getOptionLabel", "getOptionValue", "id", "isInline", "label", "loading", "minLength", "noOptionsMessage", "onChange", "onInputChange", "options", "required", "searchIcon", "showAllValues", "source", "value", "hasError", "errorMessage"];
40
+ var _excluded = ["autoFilter", "className", "debounce", "displayMenu", "forLabel", "getOptionLabel", "getOptionValue", "isInline", "label", "loading", "minLength", "noOptionsMessage", "onChange", "onInputChange", "options", "required", "searchIcon", "showAllValues", "source", "value", "hasError", "errorMessage"];
41
41
 
42
42
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
43
43
 
@@ -138,11 +138,10 @@ var FormAutocomplete = /*#__PURE__*/_react["default"].forwardRef(function (_ref,
138
138
  debounce = _ref$debounce === void 0 ? 0 : _ref$debounce,
139
139
  _ref$displayMenu = _ref.displayMenu,
140
140
  displayMenu = _ref$displayMenu === void 0 ? 'overlay' : _ref$displayMenu,
141
- forLabel = _ref.forLabel,
141
+ _ref$forLabel = _ref.forLabel,
142
+ forLabel = _ref$forLabel === void 0 ? 'vip-autocomplete' : _ref$forLabel,
142
143
  getOptionLabel = _ref.getOptionLabel,
143
144
  getOptionValue = _ref.getOptionValue,
144
- _ref$id = _ref.id,
145
- id = _ref$id === void 0 ? 'vip-autocomplete' : _ref$id,
146
145
  isInline = _ref.isInline,
147
146
  label = _ref.label,
148
147
  loading = _ref.loading,
@@ -176,7 +175,7 @@ var FormAutocomplete = /*#__PURE__*/_react["default"].forwardRef(function (_ref,
176
175
  var SelectLabel = function SelectLabel() {
177
176
  return (0, _jsxRuntime.jsx)(_Label.Label, {
178
177
  required: required,
179
- htmlFor: forLabel || id,
178
+ htmlFor: forLabel,
180
179
  children: label
181
180
  });
182
181
  };
@@ -248,10 +247,24 @@ var FormAutocomplete = /*#__PURE__*/_react["default"].forwardRef(function (_ref,
248
247
  global.document.querySelector('.autocomplete__menu').setAttribute('aria-label', label + " list");
249
248
  }, [label]);
250
249
  (0, _react.useEffect)(function () {
251
- global.document.querySelector("#" + id).addEventListener('keydown', function () {
250
+ var input = global.document.querySelector("#" + forLabel);
251
+
252
+ if (!input || required === undefined) {
253
+ return;
254
+ }
255
+
256
+ input.setAttribute('aria-required', required);
257
+ }, [required]);
258
+ (0, _react.useEffect)(function () {
259
+ global.document.querySelector("#" + forLabel).addEventListener('keydown', function () {
252
260
  setIsDirty(true);
253
261
  });
254
- }, [setIsDirty]);
262
+ }, [setIsDirty]); // For accessibility, we need to add the error message to the aria-describedby attribute
263
+
264
+ (0, _react.useEffect)(function () {
265
+ var input = global.document.querySelector("#" + forLabel);
266
+ input == null ? void 0 : input.setAttribute('aria-describedby', "describe-" + forLabel + "-validation " + input.getAttribute('aria-describedby'));
267
+ }, []);
255
268
  return (0, _jsxRuntime.jsxs)("div", {
256
269
  className: (0, _classnames["default"])('vip-form-autocomplete-component', className),
257
270
  children: [label && !isInline && (0, _jsxRuntime.jsx)(SelectLabel, {}), (0, _jsxRuntime.jsx)("div", {
@@ -260,7 +273,7 @@ var FormAutocomplete = /*#__PURE__*/_react["default"].forwardRef(function (_ref,
260
273
  isInline: inlineLabel,
261
274
  label: inlineLabel ? (0, _jsxRuntime.jsx)(SelectLabel, {}) : null,
262
275
  children: [searchIcon && (0, _jsxRuntime.jsx)(_FormSelectSearch.FormSelectSearch, {}), (0, _jsxRuntime.jsx)(_react2["default"], (0, _extends2["default"])({
263
- id: id,
276
+ id: forLabel,
264
277
  "aria-busy": loading,
265
278
  showAllValues: showAllValues,
266
279
  ref: forwardRef,
@@ -268,7 +281,8 @@ var FormAutocomplete = /*#__PURE__*/_react["default"].forwardRef(function (_ref,
268
281
  defaultValue: value,
269
282
  displayMenu: displayMenu,
270
283
  onConfirm: onValueChange,
271
- tNoResults: noOptionsMessage
284
+ tNoResults: noOptionsMessage,
285
+ required: required
272
286
  }, props)), loading && (0, _jsxRuntime.jsx)(_FormSelectLoading.FormSelectLoading, {}), (0, _jsxRuntime.jsx)(_FormSelectArrow.FormSelectArrow, {})]
273
287
  })
274
288
  }), hasError && errorMessage && (0, _jsxRuntime.jsx)(_Form.Validation, {
@@ -285,10 +299,11 @@ FormAutocomplete.propTypes = {
285
299
  className: _propTypes["default"].any,
286
300
  debounce: _propTypes["default"].number,
287
301
  displayMenu: _propTypes["default"].string,
302
+ errorMessage: _propTypes["default"].string,
288
303
  forLabel: _propTypes["default"].string,
289
304
  getOptionLabel: _propTypes["default"].func,
290
305
  getOptionValue: _propTypes["default"].func,
291
- id: _propTypes["default"].string,
306
+ hasError: _propTypes["default"].bool,
292
307
  isInline: _propTypes["default"].bool,
293
308
  label: _propTypes["default"].string,
294
309
  loading: _propTypes["default"].bool,
@@ -301,8 +316,6 @@ FormAutocomplete.propTypes = {
301
316
  searchIcon: _propTypes["default"].bool,
302
317
  showAllValues: _propTypes["default"].bool,
303
318
  source: _propTypes["default"].func,
304
- value: _propTypes["default"].string,
305
- hasError: _propTypes["default"].bool,
306
- errorMessage: _propTypes["default"].string
319
+ value: _propTypes["default"].string
307
320
  };
308
321
  FormAutocomplete.displayName = 'FormAutocomplete';
@@ -73,7 +73,7 @@ var DefaultComponent = function DefaultComponent(_ref) {
73
73
  width: width
74
74
  },
75
75
  children: (0, _jsxRuntime.jsx)(Form.Autocomplete, (0, _extends2["default"])({
76
- id: "form-autocomplete",
76
+ forLabel: "form-autocomplete",
77
77
  label: label
78
78
  }, rest))
79
79
  })
@@ -171,7 +171,8 @@ exports.WithCustomMessages = WithCustomMessages;
171
171
  var WithErrors = function WithErrors() {
172
172
  var customArgs = (0, _extends2["default"])({}, args, {
173
173
  hasError: true,
174
- errorMessage: 'Please select a value'
174
+ errorMessage: 'Please select a value.',
175
+ required: true
175
176
  });
176
177
  return (0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
177
178
  children: (0, _jsxRuntime.jsx)(DefaultComponent, (0, _extends2["default"])({}, customArgs))
@@ -46,7 +46,7 @@ describe('<FormAutocomplete />', function () {
46
46
  switch (_context.prev = _context.next) {
47
47
  case 0:
48
48
  _render = (0, _react.render)((0, _jsxRuntime.jsx)(_FormAutocomplete.FormAutocomplete, {
49
- id: "my_desert_list",
49
+ forLabel: "my_desert_list",
50
50
  label: "This is a label"
51
51
  })), container = _render.container; // Check for accessibility issues
52
52
 
@@ -74,7 +74,7 @@ describe('<FormAutocomplete />', function () {
74
74
  switch (_context2.prev = _context2.next) {
75
75
  case 0:
76
76
  _render2 = (0, _react.render)((0, _jsxRuntime.jsx)(_FormAutocomplete.FormAutocomplete, (0, _extends2["default"])({
77
- id: "my_desert_list"
77
+ forLabel: "my_desert_list"
78
78
  }, defaultProps))), container = _render2.container;
79
79
  expect(_react.screen.getByLabelText(defaultProps.label)).toBeInTheDocument(); // Check for accessibility issues
80
80
 
@@ -65,7 +65,8 @@ var renderGroup = function renderGroup(groupLabel, groupOptions) {
65
65
  var FormSelect = /*#__PURE__*/_react["default"].forwardRef(function (_ref2, forwardRef) {
66
66
  var isInline = _ref2.isInline,
67
67
  placeholder = _ref2.placeholder,
68
- forLabel = _ref2.forLabel,
68
+ _ref2$forLabel = _ref2.forLabel,
69
+ forLabel = _ref2$forLabel === void 0 ? 'vip-form-select' : _ref2$forLabel,
69
70
  options = _ref2.options,
70
71
  required = _ref2.required,
71
72
  label = _ref2.label,
@@ -110,7 +111,7 @@ var FormSelect = /*#__PURE__*/_react["default"].forwardRef(function (_ref2, forw
110
111
  var SelectLabel = function SelectLabel() {
111
112
  return (0, _jsxRuntime.jsx)(_Label.Label, {
112
113
  required: required,
113
- htmlFor: forLabel || props.id,
114
+ htmlFor: forLabel,
114
115
  children: label
115
116
  });
116
117
  };
@@ -123,7 +124,11 @@ var FormSelect = /*#__PURE__*/_react["default"].forwardRef(function (_ref2, forw
123
124
  children: [(0, _jsxRuntime.jsxs)("select", (0, _extends2["default"])({
124
125
  onChange: onValueChange,
125
126
  ref: forwardRef,
126
- sx: defaultStyles
127
+ sx: defaultStyles,
128
+ required: required,
129
+ "aria-required": required,
130
+ "aria-describedby": hasError ? "describe-" + forLabel + "-validation" : undefined,
131
+ id: forLabel
127
132
  }, props, {
128
133
  children: [placeholder && (0, _jsxRuntime.jsx)("option", {
129
134
  children: placeholder
@@ -143,17 +148,16 @@ var FormSelect = /*#__PURE__*/_react["default"].forwardRef(function (_ref2, forw
143
148
 
144
149
  exports.FormSelect = FormSelect;
145
150
  FormSelect.propTypes = {
146
- id: _propTypes["default"].string,
147
- isInline: _propTypes["default"].bool,
148
- required: _propTypes["default"].bool,
151
+ errorMessage: _propTypes["default"].string,
149
152
  forLabel: _propTypes["default"].string,
150
- placeholder: _propTypes["default"].string,
151
- label: _propTypes["default"].string,
152
- options: _propTypes["default"].array,
153
153
  getOptionLabel: _propTypes["default"].func,
154
154
  getOptionValue: _propTypes["default"].func,
155
155
  hasError: _propTypes["default"].bool,
156
- errorMessage: _propTypes["default"].string,
157
- onChange: _propTypes["default"].func
156
+ isInline: _propTypes["default"].bool,
157
+ label: _propTypes["default"].string,
158
+ onChange: _propTypes["default"].func,
159
+ options: _propTypes["default"].array,
160
+ placeholder: _propTypes["default"].string,
161
+ required: _propTypes["default"].bool
158
162
  };
159
163
  FormSelect.displayName = 'FormSelect';
@@ -90,7 +90,7 @@ var DefaultComponent = function DefaultComponent(_ref) {
90
90
  width: width
91
91
  },
92
92
  children: (0, _jsxRuntime.jsx)(Form.Select, (0, _extends2["default"])({
93
- id: "form-select",
93
+ forLabel: "form-select",
94
94
  label: label,
95
95
  onChange: onChange
96
96
  }, rest))
@@ -74,7 +74,6 @@ exports.Input = _Form.Input;
74
74
  exports.Label = _Form.Label;
75
75
  exports.Toggle = _Form.Toggle;
76
76
  exports.ToggleRow = _Form.ToggleRow;
77
- exports.ToggleGroup = _Form.ToggleGroup;
78
77
  exports.Validation = _Form.Validation;
79
78
  exports.Radio = _Form.Radio;
80
79
  exports.RadioBoxGroup = _Form.RadioBoxGroup;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/vip-design-system",
3
- "version": "0.28.7",
3
+ "version": "0.30.0",
4
4
  "main": "build/system/index.js",
5
5
  "scripts": {
6
6
  "build-storybook": "build-storybook",
@@ -27,16 +27,13 @@ const Badge = React.forwardRef(
27
27
  display: 'inline-block',
28
28
  borderRadius: 1,
29
29
  fontWeight: 'heading',
30
- '&:hover, &:focus': {
31
- backgroundColor: `tag.${ variant }.hover`,
32
- },
33
30
  a: {
34
31
  color: `tag.${ variant }.text`,
35
32
  '&:hover, &:focus, &:active': {
36
33
  textDecoration: 'none',
37
34
  },
38
- '&:active': {
39
- color: `${ variant }.active`,
35
+ '&:active, &:visited': {
36
+ color: `tag.${ variant }.text`,
40
37
  },
41
38
  },
42
39
  ...sx,
@@ -9,7 +9,7 @@ import { BiCalendarHeart } from 'react-icons/bi';
9
9
  */
10
10
  import ScreenReaderText from '../ScreenReaderText';
11
11
  import { Button } from '..';
12
- import { variants } from '.';
12
+ import variants from './variants';
13
13
 
14
14
  export default {
15
15
  title: 'Button',
@@ -8,7 +8,7 @@ import PropTypes from 'prop-types';
8
8
  import { Button } from './Button';
9
9
  import { Spinner } from '../Spinner';
10
10
  import classNames from 'classnames';
11
- import { variants } from '.';
11
+ import variants from './variants';
12
12
 
13
13
  const DefaultSpinner = ( { size, color = 'link' } ) => (
14
14
  <Spinner size={ size } sx={ { ml: 2, color } } className="vip-button-submit-spinner" />
@@ -25,13 +25,12 @@ export const ButtonSubmit = React.forwardRef(
25
25
  (
26
26
  {
27
27
  show = true,
28
- variant = 'secondary',
28
+ variant = variants[ 1 ],
29
29
  label,
30
30
  loading = false,
31
31
  disabled = false,
32
32
  loadingIcon = DefaultSpinner,
33
33
  loadingIconSize = 20,
34
- loadingIconColor = undefined,
35
34
  ...rest
36
35
  },
37
36
  forwardRef
@@ -40,10 +39,6 @@ export const ButtonSubmit = React.forwardRef(
40
39
  return null;
41
40
  }
42
41
 
43
- if ( ! loadingIconColor && variant === 'display' ) {
44
- loadingIconColor = 'button.display.label.default';
45
- }
46
-
47
42
  return (
48
43
  <Button
49
44
  ref={ forwardRef }
@@ -54,7 +49,8 @@ export const ButtonSubmit = React.forwardRef(
54
49
  { ...rest }
55
50
  >
56
51
  { label }{ ' ' }
57
- { !! loading && loadingIcon( { size: loadingIconSize, color: loadingIconColor } ) }
52
+ { !! loading &&
53
+ loadingIcon( { size: loadingIconSize, color: `button.${ variant }.label.default` } ) }
58
54
  </Button>
59
55
  );
60
56
  }
@@ -63,12 +59,11 @@ export const ButtonSubmit = React.forwardRef(
63
59
  ButtonSubmit.displayName = 'ButtonSubmit';
64
60
 
65
61
  ButtonSubmit.propTypes = {
66
- label: PropTypes.string.isRequired,
62
+ label: PropTypes.node.isRequired,
67
63
  disabled: PropTypes.bool,
68
64
  loading: PropTypes.bool,
69
65
  variant: PropTypes.oneOf( variants ),
70
66
  show: PropTypes.bool,
71
67
  loadingIcon: PropTypes.any,
72
68
  loadingIconSize: PropTypes.number,
73
- loadingIconColor: PropTypes.string,
74
69
  };
@@ -7,7 +7,7 @@ import React from 'react';
7
7
  * Internal dependencies
8
8
  */
9
9
  import { ButtonSubmit } from '..';
10
- import { variants } from '.';
10
+ import variants from './variants';
11
11
 
12
12
  export default {
13
13
  title: 'ButtonSubmit',
@@ -2,18 +2,7 @@
2
2
  * Internal dependencies
3
3
  */
4
4
 
5
- const variants = [
6
- 'primary',
7
- 'secondary',
8
- 'text',
9
- 'icon',
10
- 'tertiary',
11
- 'ghost',
12
- 'danger',
13
- 'display',
14
- ];
15
-
16
5
  import { Button } from './Button';
17
6
  import { ButtonSubmit } from './ButtonSubmit';
18
7
 
19
- export { Button, ButtonSubmit, variants };
8
+ export { Button, ButtonSubmit };
@@ -0,0 +1 @@
1
+ export default [ 'primary', 'secondary', 'text', 'icon', 'tertiary', 'ghost', 'danger', 'display' ];
@@ -38,6 +38,7 @@ const Input = React.forwardRef(
38
38
  ref={ ref }
39
39
  id={ forLabel }
40
40
  required={ required }
41
+ aria-required={ required }
41
42
  aria-describedby={ hasError ? `describe-${ forLabel }-validation` : undefined }
42
43
  sx={ { ...inputStyles, ...sx } }
43
44
  { ...props }
@@ -183,12 +183,12 @@ const Radio = React.forwardRef(
183
183
  Radio.displayName = 'Radio';
184
184
 
185
185
  Radio.propTypes = {
186
- disabled: PropTypes.bool,
186
+ className: PropTypes.any,
187
187
  defaultValue: PropTypes.any,
188
+ disabled: PropTypes.bool,
189
+ name: PropTypes.string,
188
190
  onChange: PropTypes.func,
189
191
  options: PropTypes.any,
190
- name: PropTypes.string,
191
- className: PropTypes.any,
192
192
  };
193
193
 
194
194
  export { Radio };
@@ -6,7 +6,6 @@ import { Label } from './Label';
6
6
  import { Toggle } from './Toggle';
7
7
  import { Validation } from './Validation';
8
8
  import { ToggleRow } from './ToggleRow';
9
- import { ToggleGroup } from './ToggleGroup';
10
9
  import { Select } from './Select';
11
10
  import { Radio } from './Radio';
12
11
  import { RadioBoxGroup } from './RadioBoxGroup';
@@ -18,7 +17,6 @@ export {
18
17
  Label,
19
18
  Radio,
20
19
  RadioBoxGroup,
21
- ToggleGroup,
22
20
  Select,
23
21
  Textarea,
24
22
  Toggle,
@@ -99,10 +99,9 @@ const FormAutocomplete = React.forwardRef(
99
99
  className,
100
100
  debounce = 0,
101
101
  displayMenu = 'overlay',
102
- forLabel,
102
+ forLabel = 'vip-autocomplete',
103
103
  getOptionLabel,
104
104
  getOptionValue,
105
- id = 'vip-autocomplete',
106
105
  isInline,
107
106
  label,
108
107
  loading,
@@ -126,7 +125,7 @@ const FormAutocomplete = React.forwardRef(
126
125
  let debounceTimeout;
127
126
 
128
127
  const SelectLabel = () => (
129
- <Label required={ required } htmlFor={ forLabel || id }>
128
+ <Label required={ required } htmlFor={ forLabel }>
130
129
  { label }
131
130
  </Label>
132
131
  );
@@ -212,11 +211,31 @@ const FormAutocomplete = React.forwardRef(
212
211
  }, [ label ] );
213
212
 
214
213
  useEffect( () => {
215
- global.document.querySelector( `#${ id }` ).addEventListener( 'keydown', () => {
214
+ const input = global.document.querySelector( `#${ forLabel }` );
215
+
216
+ if ( ! input || required === undefined ) {
217
+ return;
218
+ }
219
+
220
+ input.setAttribute( 'aria-required', required );
221
+ }, [ required ] );
222
+
223
+ useEffect( () => {
224
+ global.document.querySelector( `#${ forLabel }` ).addEventListener( 'keydown', () => {
216
225
  setIsDirty( true );
217
226
  } );
218
227
  }, [ setIsDirty ] );
219
228
 
229
+ // For accessibility, we need to add the error message to the aria-describedby attribute
230
+ useEffect( () => {
231
+ const input = global.document.querySelector( `#${ forLabel }` );
232
+
233
+ input?.setAttribute(
234
+ 'aria-describedby',
235
+ `describe-${ forLabel }-validation ${ input.getAttribute( 'aria-describedby' ) }`
236
+ );
237
+ }, [] );
238
+
220
239
  return (
221
240
  <div className={ classNames( 'vip-form-autocomplete-component', className ) }>
222
241
  { label && ! isInline && <SelectLabel /> }
@@ -233,8 +252,9 @@ const FormAutocomplete = React.forwardRef(
233
252
  label={ inlineLabel ? <SelectLabel /> : null }
234
253
  >
235
254
  { searchIcon && <FormSelectSearch /> }
255
+
236
256
  <Autocomplete
237
- id={ id }
257
+ id={ forLabel }
238
258
  aria-busy={ loading }
239
259
  showAllValues={ showAllValues }
240
260
  ref={ forwardRef }
@@ -243,6 +263,7 @@ const FormAutocomplete = React.forwardRef(
243
263
  displayMenu={ displayMenu }
244
264
  onConfirm={ onValueChange }
245
265
  tNoResults={ noOptionsMessage }
266
+ required={ required }
246
267
  { ...props }
247
268
  />
248
269
  { loading && <FormSelectLoading /> }
@@ -265,10 +286,11 @@ FormAutocomplete.propTypes = {
265
286
  className: PropTypes.any,
266
287
  debounce: PropTypes.number,
267
288
  displayMenu: PropTypes.string,
289
+ errorMessage: PropTypes.string,
268
290
  forLabel: PropTypes.string,
269
291
  getOptionLabel: PropTypes.func,
270
292
  getOptionValue: PropTypes.func,
271
- id: PropTypes.string,
293
+ hasError: PropTypes.bool,
272
294
  isInline: PropTypes.bool,
273
295
  label: PropTypes.string,
274
296
  loading: PropTypes.bool,
@@ -282,8 +304,6 @@ FormAutocomplete.propTypes = {
282
304
  showAllValues: PropTypes.bool,
283
305
  source: PropTypes.func,
284
306
  value: PropTypes.string,
285
- hasError: PropTypes.bool,
286
- errorMessage: PropTypes.string,
287
307
  };
288
308
 
289
309
  FormAutocomplete.displayName = 'FormAutocomplete';
@@ -36,7 +36,7 @@ const DefaultComponent = ( { label = 'Label', width = 250, ...rest } ) => (
36
36
  <>
37
37
  <Form.Root>
38
38
  <div sx={ { width } }>
39
- <Form.Autocomplete id="form-autocomplete" label={ label } { ...rest } />
39
+ <Form.Autocomplete forLabel="form-autocomplete" label={ label } { ...rest } />
40
40
  </div>
41
41
  </Form.Root>
42
42
  </>
@@ -138,7 +138,8 @@ export const WithErrors = () => {
138
138
  const customArgs = {
139
139
  ...args,
140
140
  hasError: true,
141
- errorMessage: 'Please select a value',
141
+ errorMessage: 'Please select a value.',
142
+ required: true,
142
143
  };
143
144
 
144
145
  return (
@@ -23,7 +23,7 @@ const defaultProps = {
23
23
  describe( '<FormAutocomplete />', () => {
24
24
  it( 'renders the FormAutocomplete component', async () => {
25
25
  const { container } = render(
26
- <FormAutocomplete id="my_desert_list" label="This is a label" />
26
+ <FormAutocomplete forLabel="my_desert_list" label="This is a label" />
27
27
  );
28
28
 
29
29
  // Check for accessibility issues
@@ -31,7 +31,9 @@ describe( '<FormAutocomplete />', () => {
31
31
  } );
32
32
 
33
33
  it( 'renders the FormAutocomplete component with options', async () => {
34
- const { container } = render( <FormAutocomplete id="my_desert_list" { ...defaultProps } /> );
34
+ const { container } = render(
35
+ <FormAutocomplete forLabel="my_desert_list" { ...defaultProps } />
36
+ );
35
37
 
36
38
  expect( screen.getByLabelText( defaultProps.label ) ).toBeInTheDocument();
37
39
 
@@ -49,7 +49,7 @@ const FormSelect = React.forwardRef(
49
49
  {
50
50
  isInline,
51
51
  placeholder,
52
- forLabel,
52
+ forLabel = 'vip-form-select',
53
53
  options,
54
54
  required,
55
55
  label,
@@ -102,7 +102,7 @@ const FormSelect = React.forwardRef(
102
102
  );
103
103
 
104
104
  const SelectLabel = () => (
105
- <Label required={ required } htmlFor={ forLabel || props.id }>
105
+ <Label required={ required } htmlFor={ forLabel }>
106
106
  { label }
107
107
  </Label>
108
108
  );
@@ -114,7 +114,16 @@ const FormSelect = React.forwardRef(
114
114
  { label && ! isInline && <SelectLabel /> }
115
115
 
116
116
  <FormSelectContent isInline={ inlineLabel } label={ inlineLabel ? <SelectLabel /> : null }>
117
- <select onChange={ onValueChange } ref={ forwardRef } sx={ defaultStyles } { ...props }>
117
+ <select
118
+ onChange={ onValueChange }
119
+ ref={ forwardRef }
120
+ sx={ defaultStyles }
121
+ required={ required }
122
+ aria-required={ required }
123
+ aria-describedby={ hasError ? `describe-${ forLabel }-validation` : undefined }
124
+ id={ forLabel }
125
+ { ...props }
126
+ >
118
127
  { placeholder && <option>{ placeholder }</option> }
119
128
  { options.map( ( { options: groupOptions, ...option } ) =>
120
129
  groupOptions
@@ -136,18 +145,17 @@ const FormSelect = React.forwardRef(
136
145
  );
137
146
 
138
147
  FormSelect.propTypes = {
139
- id: PropTypes.string,
140
- isInline: PropTypes.bool,
141
- required: PropTypes.bool,
148
+ errorMessage: PropTypes.string,
142
149
  forLabel: PropTypes.string,
143
- placeholder: PropTypes.string,
144
- label: PropTypes.string,
145
- options: PropTypes.array,
146
150
  getOptionLabel: PropTypes.func,
147
151
  getOptionValue: PropTypes.func,
148
152
  hasError: PropTypes.bool,
149
- errorMessage: PropTypes.string,
153
+ isInline: PropTypes.bool,
154
+ label: PropTypes.string,
150
155
  onChange: PropTypes.func,
156
+ options: PropTypes.array,
157
+ placeholder: PropTypes.string,
158
+ required: PropTypes.bool,
151
159
  };
152
160
 
153
161
  FormSelect.displayName = 'FormSelect';
@@ -62,7 +62,7 @@ const DefaultComponent = ( { label = 'Label', width = 250, onChange, ...rest } )
62
62
  </p>
63
63
  <Form.Root>
64
64
  <div sx={ { width } }>
65
- <Form.Select id="form-select" label={ label } onChange={ onChange } { ...rest } />
65
+ <Form.Select forLabel="form-select" label={ label } onChange={ onChange } { ...rest } />
66
66
  </div>
67
67
  </Form.Root>
68
68
  </>
@@ -30,7 +30,6 @@ import {
30
30
  Label,
31
31
  Toggle,
32
32
  ToggleRow,
33
- ToggleGroup,
34
33
  Validation,
35
34
  Radio,
36
35
  RadioBoxGroup,
@@ -105,7 +104,6 @@ export {
105
104
  TabsList,
106
105
  Toggle,
107
106
  ToggleRow,
108
- ToggleGroup,
109
107
  Time,
110
108
  Timeline,
111
109
  Validation,
@@ -1,67 +0,0 @@
1
- /** @jsxImportSource theme-ui */
2
-
3
- /**
4
- * External dependencies
5
- */
6
- import React from 'react';
7
- import PropTypes from 'prop-types';
8
- import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
9
-
10
- const ToggleGroup = React.forwardRef(
11
- ( { onChange, groupLabel, value, options, ...props }, forwardRef ) => (
12
- <RadioGroupPrimitive.Root
13
- onValueChange={ onChange }
14
- value={ value }
15
- aria-label={ groupLabel }
16
- sx={ {
17
- bg: 'backgroundSecondary',
18
- p: 1,
19
- display: 'flex',
20
- alignItems: 'center',
21
- } }
22
- ref={ forwardRef }
23
- { ...props }
24
- >
25
- { options.map( ( option, index ) => (
26
- <RadioGroupPrimitive.Item
27
- key={ option.value }
28
- value={ option.value }
29
- id={ `o${ index }` }
30
- sx={ {
31
- fontSize: 1,
32
- color: 'muted',
33
- background: 'none',
34
- border: 'none',
35
- cursor: 'pointer',
36
- borderRadius: 1,
37
- py: 1,
38
- px: 2,
39
- flex: '1 1 auto',
40
- textAlign: 'center',
41
- '&:hover': {
42
- color: 'heading',
43
- },
44
- '&[data-state=checked]': {
45
- backgroundColor: 'background',
46
- boxShadow: 'low',
47
- color: 'heading',
48
- },
49
- } }
50
- >
51
- { option.label }
52
- </RadioGroupPrimitive.Item>
53
- ) ) }
54
- </RadioGroupPrimitive.Root>
55
- )
56
- );
57
-
58
- ToggleGroup.displayName = 'ToggleGroup';
59
-
60
- ToggleGroup.propTypes = {
61
- onChange: PropTypes.func,
62
- options: PropTypes.array,
63
- value: PropTypes.string,
64
- groupLabel: PropTypes.string,
65
- };
66
-
67
- export { ToggleGroup };
@@ -1,41 +0,0 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { useState } from 'react';
5
-
6
- /**
7
- * Internal dependencies
8
- */
9
- import { ToggleGroup } from '..';
10
-
11
- export default {
12
- title: 'ToggleGroup',
13
- component: ToggleGroup,
14
- };
15
-
16
- const options = [
17
- {
18
- label: 'One',
19
- value: 'one',
20
- },
21
- {
22
- label: 'Two',
23
- value: 'two',
24
- },
25
- {
26
- label: 'Three',
27
- value: 'three',
28
- },
29
- ];
30
-
31
- export const Default = () => {
32
- const [ value, setValue ] = useState( 'one' );
33
- return (
34
- <ToggleGroup
35
- value={ value }
36
- onChange={ newValue => setValue( newValue ) }
37
- groupLabel="group"
38
- options={ options }
39
- />
40
- );
41
- };