@automattic/vip-design-system 0.26.6 → 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.
@@ -26,9 +26,10 @@ var _Heading = require("../Heading");
26
26
  var _jsxRuntime = require("theme-ui/jsx-runtime");
27
27
 
28
28
  var _excluded = ["children"],
29
- _excluded2 = ["children", "headingVariant"],
29
+ _excluded2 = ["children", "headingVariant", "sx"],
30
30
  _excluded3 = ["children", "icon"],
31
- _excluded4 = ["children", "sx"];
31
+ _excluded4 = ["children", "sx"],
32
+ _excluded5 = ["sx", "children", "className"];
32
33
 
33
34
  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); }
34
35
 
@@ -87,6 +88,8 @@ var Trigger = /*#__PURE__*/_react["default"].forwardRef(function (_ref2, forward
87
88
  var children = _ref2.children,
88
89
  _ref2$headingVariant = _ref2.headingVariant,
89
90
  headingVariant = _ref2$headingVariant === void 0 ? 'h3' : _ref2$headingVariant,
91
+ _ref2$sx = _ref2.sx,
92
+ sx = _ref2$sx === void 0 ? {} : _ref2$sx,
90
93
  props = (0, _objectWithoutPropertiesLoose2["default"])(_ref2, _excluded2);
91
94
  return (0, _jsxRuntime.jsx)(_Heading.Heading, {
92
95
  sx: {
@@ -95,7 +98,7 @@ var Trigger = /*#__PURE__*/_react["default"].forwardRef(function (_ref2, forward
95
98
  },
96
99
  variant: headingVariant,
97
100
  children: (0, _jsxRuntime.jsxs)(AccordionPrimitive.Trigger, (0, _extends2["default"])({
98
- sx: {
101
+ sx: (0, _extends2["default"])({
99
102
  color: 'heading',
100
103
  cursor: 'pointer',
101
104
  all: 'unset',
@@ -134,7 +137,7 @@ var Trigger = /*#__PURE__*/_react["default"].forwardRef(function (_ref2, forward
134
137
  return accordion.background.hover;
135
138
  }
136
139
  }
137
- }
140
+ }, sx)
138
141
  }, props, {
139
142
  ref: forwardedRef,
140
143
  children: [children, (0, _jsxRuntime.jsx)(_md.MdChevronRight, {
@@ -155,7 +158,8 @@ exports.Trigger = Trigger;
155
158
  Trigger.displayName = 'Accordion.Trigger';
156
159
  Trigger.propTypes = {
157
160
  children: _propTypes["default"].node.isRequired,
158
- headingVariant: _propTypes["default"].string
161
+ headingVariant: _propTypes["default"].string,
162
+ sx: _propTypes["default"].object
159
163
  };
160
164
 
161
165
  var TriggerWithIcon = /*#__PURE__*/_react["default"].forwardRef(function (_ref7, forwardedRef) {
@@ -200,6 +204,8 @@ var Content = /*#__PURE__*/_react["default"].forwardRef(function (_ref8, forward
200
204
  color: 'text',
201
205
  fontSize: 2,
202
206
  overflow: 'hidden',
207
+ px: 3,
208
+ py: 2,
203
209
  '&[data-state="open"]': {
204
210
  animation: slideDown + " 300ms cubic-bezier(0.87, 0, 0.13, 1)"
205
211
  },
@@ -209,13 +215,7 @@ var Content = /*#__PURE__*/_react["default"].forwardRef(function (_ref8, forward
209
215
  }, sx)
210
216
  }, props, {
211
217
  ref: forwardedRef,
212
- children: (0, _jsxRuntime.jsx)("div", {
213
- sx: {
214
- px: 3,
215
- py: 2
216
- },
217
- children: children
218
- })
218
+ children: children
219
219
  }));
220
220
  });
221
221
 
@@ -229,21 +229,19 @@ Content.propTypes = {
229
229
  var Root = /*#__PURE__*/_react["default"].forwardRef(function (_ref9, forwardRef) {
230
230
  var _ref9$sx = _ref9.sx,
231
231
  sx = _ref9$sx === void 0 ? {} : _ref9$sx,
232
- defaultValue = _ref9.defaultValue,
233
- type = _ref9.type,
234
232
  children = _ref9.children,
235
- className = _ref9.className;
236
- return (0, _jsxRuntime.jsx)(AccordionPrimitive.Root, {
233
+ className = _ref9.className,
234
+ props = (0, _objectWithoutPropertiesLoose2["default"])(_ref9, _excluded5);
235
+ return (0, _jsxRuntime.jsx)(AccordionPrimitive.Root, (0, _extends2["default"])({
237
236
  className: (0, _classnames["default"])('vip-accordion-component', className),
238
237
  collapsible: true,
239
- defaultValue: defaultValue,
240
238
  ref: forwardRef,
241
239
  sx: (0, _extends2["default"])({
242
240
  borderRadius: 6
243
- }, sx),
244
- type: type,
241
+ }, sx)
242
+ }, props, {
245
243
  children: children
246
- });
244
+ }));
247
245
  });
248
246
 
249
247
  exports.Root = Root;
@@ -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
  });
@@ -27,9 +27,11 @@ var _FormSelectArrow = require("./FormSelectArrow");
27
27
 
28
28
  var _Label = require("../Form/Label");
29
29
 
30
+ var _FormSelectSearch = require("./FormSelectSearch");
31
+
30
32
  var _jsxRuntime = require("theme-ui/jsx-runtime");
31
33
 
32
- var _excluded = ["isInline", "forLabel", "options", "label", "getOptionLabel", "getOptionValue", "onChange", "value", "showAllValues", "displayMenu", "id", "className"];
34
+ var _excluded = ["isInline", "forLabel", "options", "label", "getOptionLabel", "getOptionValue", "onChange", "onInputChange", "value", "showAllValues", "searchIcon", "displayMenu", "noOptionsMessage", "id", "className"];
33
35
 
34
36
  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); }
35
37
 
@@ -100,13 +102,34 @@ var defaultStyles = {
100
102
  '& .autocomplete__wrapper': {
101
103
  width: '100%'
102
104
  },
105
+ '& .autocomplete__option': {
106
+ borderColor: 'borders.2'
107
+ },
108
+ '& .autocomplete__option--odd': {
109
+ bg: 'backgroundSecondary'
110
+ },
111
+ '& .autocomplete__option:hover, & .autocomplete__option--focused': {
112
+ bg: 'midnight',
113
+ borderColor: 'midnight'
114
+ },
103
115
  '& .autocomplete__input--show-all-values': {
104
116
  paddingRight: 0
117
+ },
118
+ '& .autocomplete__hint': {
119
+ border: 'none',
120
+ paddingLeft: 3,
121
+ minHeight: '27px',
122
+ lineHeight: '27px'
105
123
  }
106
124
  };
107
125
  var inlineStyles = {
108
126
  borderWidth: 0
109
127
  };
128
+ var searchIconStyles = {
129
+ '& .autocomplete__input.autocomplete__input--show-all-values': {
130
+ paddingLeft: '30px'
131
+ }
132
+ };
110
133
 
111
134
  var FormAutocomplete = /*#__PURE__*/_react["default"].forwardRef(function (_ref, forwardRef) {
112
135
  var isInline = _ref.isInline,
@@ -117,11 +140,18 @@ var FormAutocomplete = /*#__PURE__*/_react["default"].forwardRef(function (_ref,
117
140
  getOptionValue = _ref.getOptionValue,
118
141
  _ref$onChange = _ref.onChange,
119
142
  onChange = _ref$onChange === void 0 ? function () {} : _ref$onChange,
143
+ onInputChange = _ref.onInputChange,
120
144
  value = _ref.value,
121
145
  _ref$showAllValues = _ref.showAllValues,
122
146
  showAllValues = _ref$showAllValues === void 0 ? true : _ref$showAllValues,
147
+ _ref$searchIcon = _ref.searchIcon,
148
+ searchIcon = _ref$searchIcon === void 0 ? false : _ref$searchIcon,
123
149
  _ref$displayMenu = _ref.displayMenu,
124
150
  displayMenu = _ref$displayMenu === void 0 ? 'overlay' : _ref$displayMenu,
151
+ _ref$noOptionsMessage = _ref.noOptionsMessage,
152
+ noOptionsMessage = _ref$noOptionsMessage === void 0 ? function () {
153
+ return 'No results found.';
154
+ } : _ref$noOptionsMessage,
125
155
  _ref$id = _ref.id,
126
156
  id = _ref$id === void 0 ? 'vip-autocomplete' : _ref$id,
127
157
  className = _ref.className,
@@ -163,13 +193,16 @@ var FormAutocomplete = /*#__PURE__*/_react["default"].forwardRef(function (_ref,
163
193
  onChange(getOptionByLabel(inputValue), inputValue);
164
194
  }
165
195
  }, [onChange, getOptionByLabel]);
196
+ var handleTypeChange = (0, _react.useCallback)(function (query) {
197
+ return options.filter(function (option) {
198
+ return optionLabel(option).toLowerCase().indexOf(query.toLowerCase()) >= 0;
199
+ });
200
+ }, [options]);
166
201
  var suggest = (0, _react.useCallback)(function (query, populateResults) {
167
202
  var data = options;
168
203
 
169
204
  if (isDirty) {
170
- data = options.filter(function (option) {
171
- return optionLabel(option).toLowerCase().indexOf(query.toLowerCase()) >= 0;
172
- });
205
+ data = onInputChange ? onInputChange(query) : handleTypeChange(query);
173
206
  }
174
207
 
175
208
  populateResults(data.map(function (option) {
@@ -190,18 +223,19 @@ var FormAutocomplete = /*#__PURE__*/_react["default"].forwardRef(function (_ref,
190
223
  return (0, _jsxRuntime.jsxs)("div", {
191
224
  className: (0, _classnames["default"])('vip-form-autocomplete-component', className),
192
225
  children: [label && !isInline && (0, _jsxRuntime.jsx)(SelectLabel, {}), (0, _jsxRuntime.jsx)("div", {
193
- sx: (0, _extends2["default"])({}, defaultStyles, isInline && inlineStyles),
226
+ sx: (0, _extends2["default"])({}, defaultStyles, isInline && inlineStyles, searchIcon && searchIconStyles),
194
227
  children: (0, _jsxRuntime.jsxs)(_FormSelectContent.FormSelectContent, {
195
228
  isInline: inlineLabel,
196
229
  label: inlineLabel ? (0, _jsxRuntime.jsx)(SelectLabel, {}) : null,
197
- children: [(0, _jsxRuntime.jsx)(_react2["default"], (0, _extends2["default"])({
230
+ children: [searchIcon && (0, _jsxRuntime.jsx)(_FormSelectSearch.FormSelectSearch, {}), (0, _jsxRuntime.jsx)(_react2["default"], (0, _extends2["default"])({
198
231
  id: id,
199
232
  showAllValues: showAllValues,
200
233
  ref: forwardRef,
201
234
  source: suggest,
202
235
  defaultValue: value,
203
236
  displayMenu: displayMenu,
204
- onConfirm: onValueChange
237
+ onConfirm: onValueChange,
238
+ tNoResults: noOptionsMessage
205
239
  }, props)), (0, _jsxRuntime.jsx)(_FormSelectArrow.FormSelectArrow, {})]
206
240
  })
207
241
  })]
@@ -212,6 +246,7 @@ exports.FormAutocomplete = FormAutocomplete;
212
246
  FormAutocomplete.propTypes = {
213
247
  id: _propTypes["default"].string,
214
248
  showAllValues: _propTypes["default"].bool,
249
+ searchIcon: _propTypes["default"].bool,
215
250
  isInline: _propTypes["default"].bool,
216
251
  forLabel: _propTypes["default"].string,
217
252
  value: _propTypes["default"].string,
@@ -220,6 +255,8 @@ FormAutocomplete.propTypes = {
220
255
  options: _propTypes["default"].array,
221
256
  getOptionLabel: _propTypes["default"].func,
222
257
  getOptionValue: _propTypes["default"].func,
258
+ onInputChange: _propTypes["default"].func,
259
+ noOptionsMessage: _propTypes["default"].func,
223
260
  onChange: _propTypes["default"].func,
224
261
  className: _propTypes["default"].any
225
262
  };
@@ -3,7 +3,7 @@
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
4
 
5
5
  exports.__esModule = true;
6
- exports["default"] = exports.WithDefaultValue = exports.Inline = exports.Default = void 0;
6
+ exports["default"] = exports.WithSearchIcon = exports.WithDefaultValue = exports.WithCustomMessages = exports.Inline = exports.Default = void 0;
7
7
 
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
9
 
@@ -107,4 +107,29 @@ var WithDefaultValue = function WithDefaultValue() {
107
107
  });
108
108
  };
109
109
 
110
- exports.WithDefaultValue = WithDefaultValue;
110
+ exports.WithDefaultValue = WithDefaultValue;
111
+
112
+ var WithSearchIcon = function WithSearchIcon() {
113
+ var customArgs = (0, _extends2["default"])({}, args, {
114
+ searchIcon: true
115
+ });
116
+ return (0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
117
+ children: (0, _jsxRuntime.jsx)(DefaultComponent, (0, _extends2["default"])({}, customArgs))
118
+ });
119
+ };
120
+
121
+ exports.WithSearchIcon = WithSearchIcon;
122
+
123
+ var WithCustomMessages = function WithCustomMessages() {
124
+ var customArgs = (0, _extends2["default"])({}, args, {
125
+ noOptionsMessage: function noOptionsMessage() {
126
+ return 'No data';
127
+ },
128
+ placeholder: 'Type to search'
129
+ });
130
+ return (0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
131
+ children: (0, _jsxRuntime.jsx)(DefaultComponent, (0, _extends2["default"])({}, customArgs))
132
+ });
133
+ };
134
+
135
+ exports.WithCustomMessages = WithCustomMessages;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ exports.__esModule = true;
6
+ exports.FormSelectSearch = void 0;
7
+
8
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
+
10
+ var _react = _interopRequireDefault(require("react"));
11
+
12
+ var _md = require("react-icons/md");
13
+
14
+ var _jsxRuntime = require("theme-ui/jsx-runtime");
15
+
16
+ /** @jsxImportSource theme-ui */
17
+
18
+ /**
19
+ * External dependencies
20
+ */
21
+ var FormSelectSearch = /*#__PURE__*/_react["default"].forwardRef(function (props, forwardRef) {
22
+ return (0, _jsxRuntime.jsx)(_md.MdSearch, (0, _extends2["default"])({
23
+ ref: forwardRef,
24
+ "aria-hidden": "true",
25
+ size: 24,
26
+ sx: {
27
+ position: 'absolute',
28
+ paddingRight: 2,
29
+ left: 2,
30
+ pointerEvents: 'none'
31
+ }
32
+ }, props));
33
+ });
34
+
35
+ exports.FormSelectSearch = FormSelectSearch;
36
+ FormSelectSearch.displayName = 'FormSelectSearch';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/vip-design-system",
3
- "version": "0.26.6",
3
+ "version": "0.27.0",
4
4
  "main": "build/system/index.js",
5
5
  "scripts": {
6
6
  "build-storybook": "build-storybook",
@@ -57,7 +57,7 @@ Item.propTypes = {
57
57
  };
58
58
 
59
59
  export const Trigger = React.forwardRef(
60
- ( { children, headingVariant = 'h3', ...props }, forwardedRef ) => (
60
+ ( { children, headingVariant = 'h3', sx = {}, ...props }, forwardedRef ) => (
61
61
  <Heading
62
62
  sx={ {
63
63
  all: 'unset',
@@ -90,6 +90,7 @@ export const Trigger = React.forwardRef(
90
90
  '.vip-accordion-trigger-indicator': { transform: 'rotate(270deg)' },
91
91
  },
92
92
  '&:hover': { backgroundColor: ( { accordion } ) => accordion.background.hover },
93
+ ...sx,
93
94
  } }
94
95
  { ...props }
95
96
  ref={ forwardedRef }
@@ -115,6 +116,7 @@ Trigger.displayName = 'Accordion.Trigger';
115
116
  Trigger.propTypes = {
116
117
  children: PropTypes.node.isRequired,
117
118
  headingVariant: PropTypes.string,
119
+ sx: PropTypes.object,
118
120
  };
119
121
 
120
122
  export const TriggerWithIcon = React.forwardRef( ( { children, icon, ...props }, forwardedRef ) => (
@@ -139,6 +141,8 @@ export const Content = React.forwardRef( ( { children, sx = {}, ...props }, forw
139
141
  color: 'text',
140
142
  fontSize: 2,
141
143
  overflow: 'hidden',
144
+ px: 3,
145
+ py: 2,
142
146
 
143
147
  '&[data-state="open"]': {
144
148
  animation: `${ slideDown } 300ms cubic-bezier(0.87, 0, 0.13, 1)`,
@@ -151,14 +155,7 @@ export const Content = React.forwardRef( ( { children, sx = {}, ...props }, forw
151
155
  { ...props }
152
156
  ref={ forwardedRef }
153
157
  >
154
- <div
155
- sx={ {
156
- px: 3,
157
- py: 2,
158
- } }
159
- >
160
- { children }
161
- </div>
158
+ { children }
162
159
  </AccordionPrimitive.Content>
163
160
  );
164
161
  } );
@@ -170,23 +167,20 @@ Content.propTypes = {
170
167
  sx: PropTypes.object,
171
168
  };
172
169
 
173
- const Root = React.forwardRef(
174
- ( { sx = {}, defaultValue, type, children, className }, forwardRef ) => (
175
- <AccordionPrimitive.Root
176
- className={ classNames( 'vip-accordion-component', className ) }
177
- collapsible
178
- defaultValue={ defaultValue }
179
- ref={ forwardRef }
180
- sx={ {
181
- borderRadius: 6,
182
- ...sx,
183
- } }
184
- type={ type }
185
- >
186
- { children }
187
- </AccordionPrimitive.Root>
188
- )
189
- );
170
+ const Root = React.forwardRef( ( { sx = {}, children, className, ...props }, forwardRef ) => (
171
+ <AccordionPrimitive.Root
172
+ className={ classNames( 'vip-accordion-component', className ) }
173
+ collapsible
174
+ ref={ forwardRef }
175
+ sx={ {
176
+ borderRadius: 6,
177
+ ...sx,
178
+ } }
179
+ { ...props }
180
+ >
181
+ { children }
182
+ </AccordionPrimitive.Root>
183
+ ) );
190
184
 
191
185
  Root.displayName = 'Accordion';
192
186
 
@@ -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>
@@ -15,6 +15,7 @@ import css from './FormAutocomplete.css';
15
15
  import { FormSelectContent } from './FormSelectContent';
16
16
  import { FormSelectArrow } from './FormSelectArrow';
17
17
  import { Label } from '../Form/Label';
18
+ import { FormSelectSearch } from './FormSelectSearch';
18
19
 
19
20
  const defaultStyles = {
20
21
  width: '100%',
@@ -59,15 +60,37 @@ const defaultStyles = {
59
60
  '& .autocomplete__wrapper': {
60
61
  width: '100%',
61
62
  },
63
+ '& .autocomplete__option': {
64
+ borderColor: 'borders.2',
65
+ },
66
+ '& .autocomplete__option--odd': {
67
+ bg: 'backgroundSecondary',
68
+ },
69
+ '& .autocomplete__option:hover, & .autocomplete__option--focused': {
70
+ bg: 'midnight',
71
+ borderColor: 'midnight',
72
+ },
62
73
  '& .autocomplete__input--show-all-values': {
63
74
  paddingRight: 0,
64
75
  },
76
+ '& .autocomplete__hint': {
77
+ border: 'none',
78
+ paddingLeft: 3,
79
+ minHeight: '27px',
80
+ lineHeight: '27px',
81
+ },
65
82
  };
66
83
 
67
84
  const inlineStyles = {
68
85
  borderWidth: 0,
69
86
  };
70
87
 
88
+ const searchIconStyles = {
89
+ '& .autocomplete__input.autocomplete__input--show-all-values': {
90
+ paddingLeft: '30px',
91
+ },
92
+ };
93
+
71
94
  const FormAutocomplete = React.forwardRef(
72
95
  (
73
96
  {
@@ -78,9 +101,12 @@ const FormAutocomplete = React.forwardRef(
78
101
  getOptionLabel,
79
102
  getOptionValue,
80
103
  onChange = () => {},
104
+ onInputChange,
81
105
  value,
82
106
  showAllValues = true,
107
+ searchIcon = false,
83
108
  displayMenu = 'overlay',
109
+ noOptionsMessage = () => 'No results found.',
84
110
  id = 'vip-autocomplete',
85
111
  className,
86
112
  ...props
@@ -122,13 +148,19 @@ const FormAutocomplete = React.forwardRef(
122
148
  [ onChange, getOptionByLabel ]
123
149
  );
124
150
 
151
+ const handleTypeChange = useCallback(
152
+ query =>
153
+ options.filter(
154
+ option => optionLabel( option ).toLowerCase().indexOf( query.toLowerCase() ) >= 0
155
+ ),
156
+ [ options ]
157
+ );
158
+
125
159
  const suggest = useCallback(
126
160
  ( query, populateResults ) => {
127
161
  let data = options;
128
162
  if ( isDirty ) {
129
- data = options.filter(
130
- option => optionLabel( option ).toLowerCase().indexOf( query.toLowerCase() ) >= 0
131
- );
163
+ data = onInputChange ? onInputChange( query ) : handleTypeChange( query );
132
164
  }
133
165
  populateResults( data.map( option => optionLabel( option ) ) );
134
166
  },
@@ -157,11 +189,18 @@ const FormAutocomplete = React.forwardRef(
157
189
  <div className={ classNames( 'vip-form-autocomplete-component', className ) }>
158
190
  { label && ! isInline && <SelectLabel /> }
159
191
 
160
- <div sx={ { ...defaultStyles, ...( isInline && inlineStyles ) } }>
192
+ <div
193
+ sx={ {
194
+ ...defaultStyles,
195
+ ...( isInline && inlineStyles ),
196
+ ...( searchIcon && searchIconStyles ),
197
+ } }
198
+ >
161
199
  <FormSelectContent
162
200
  isInline={ inlineLabel }
163
201
  label={ inlineLabel ? <SelectLabel /> : null }
164
202
  >
203
+ { searchIcon && <FormSelectSearch /> }
165
204
  <Autocomplete
166
205
  id={ id }
167
206
  showAllValues={ showAllValues }
@@ -170,6 +209,7 @@ const FormAutocomplete = React.forwardRef(
170
209
  defaultValue={ value }
171
210
  displayMenu={ displayMenu }
172
211
  onConfirm={ onValueChange }
212
+ tNoResults={ noOptionsMessage }
173
213
  { ...props }
174
214
  />
175
215
  <FormSelectArrow />
@@ -183,6 +223,7 @@ const FormAutocomplete = React.forwardRef(
183
223
  FormAutocomplete.propTypes = {
184
224
  id: PropTypes.string,
185
225
  showAllValues: PropTypes.bool,
226
+ searchIcon: PropTypes.bool,
186
227
  isInline: PropTypes.bool,
187
228
  forLabel: PropTypes.string,
188
229
  value: PropTypes.string,
@@ -191,6 +232,8 @@ FormAutocomplete.propTypes = {
191
232
  options: PropTypes.array,
192
233
  getOptionLabel: PropTypes.func,
193
234
  getOptionValue: PropTypes.func,
235
+ onInputChange: PropTypes.func,
236
+ noOptionsMessage: PropTypes.func,
194
237
  onChange: PropTypes.func,
195
238
  className: PropTypes.any,
196
239
  };
@@ -74,3 +74,30 @@ export const WithDefaultValue = () => {
74
74
  </>
75
75
  );
76
76
  };
77
+
78
+ export const WithSearchIcon = () => {
79
+ const customArgs = {
80
+ ...args,
81
+ searchIcon: true,
82
+ };
83
+
84
+ return (
85
+ <>
86
+ <DefaultComponent { ...customArgs } />
87
+ </>
88
+ );
89
+ };
90
+
91
+ export const WithCustomMessages = () => {
92
+ const customArgs = {
93
+ ...args,
94
+ noOptionsMessage: () => 'No data',
95
+ placeholder: 'Type to search',
96
+ };
97
+
98
+ return (
99
+ <>
100
+ <DefaultComponent { ...customArgs } />
101
+ </>
102
+ );
103
+ };
@@ -0,0 +1,24 @@
1
+ /** @jsxImportSource theme-ui */
2
+
3
+ /**
4
+ * External dependencies
5
+ */
6
+ import React from 'react';
7
+ import { MdSearch } from 'react-icons/md';
8
+
9
+ export const FormSelectSearch = React.forwardRef( ( props, forwardRef ) => (
10
+ <MdSearch
11
+ ref={ forwardRef }
12
+ aria-hidden="true"
13
+ size={ 24 }
14
+ sx={ {
15
+ position: 'absolute',
16
+ paddingRight: 2,
17
+ left: 2,
18
+ pointerEvents: 'none',
19
+ } }
20
+ { ...props }
21
+ />
22
+ ) );
23
+
24
+ FormSelectSearch.displayName = 'FormSelectSearch';