@spark-web/select 1.0.5 → 1.0.8

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.
@@ -1,23 +1,34 @@
1
1
  import type { DataAttributeMap } from '@spark-web/utils/internal';
2
2
  import type { SelectHTMLAttributes } from 'react';
3
- declare type Option = {
3
+ export declare type Option = {
4
+ /** Whether or not the option is disabled. */
4
5
  disabled?: boolean;
6
+ /** Label for the option. */
5
7
  label: string;
8
+ /** Value of the option. */
6
9
  value: string | number;
7
10
  };
8
- declare type Group = {
11
+ export declare type Group = {
12
+ /** List of options for the group. */
9
13
  options: Array<Option>;
14
+ /** Label for the group. */
10
15
  label: string;
11
16
  };
12
17
  export declare type OptionsOrGroups = Array<Option | Group>;
13
- export declare type SelectProps = Pick<SelectHTMLAttributes<HTMLSelectElement>, 'defaultValue' | 'name' | 'onBlur' | 'onChange' | 'required' | 'value'> & {
18
+ export declare type NativeSelectProps = Pick<SelectHTMLAttributes<HTMLSelectElement>, 'defaultValue' | 'name' | 'onBlur' | 'onChange' | 'required' | 'value'>;
19
+ export declare type SelectProps = NativeSelectProps & {
20
+ /** Allows setting of data attributes on the underlying element. */
14
21
  data?: DataAttributeMap;
22
+ /** The values that can be selected by the input. */
15
23
  options: OptionsOrGroups;
24
+ /** Placeholder text for when the input does not have an initial value. */
16
25
  placeholder?: string;
17
26
  };
18
- export declare const Select: import("react").ForwardRefExoticComponent<Pick<SelectHTMLAttributes<HTMLSelectElement>, "name" | "value" | "defaultValue" | "onBlur" | "onChange" | "required"> & {
27
+ export declare const Select: import("react").ForwardRefExoticComponent<NativeSelectProps & {
28
+ /** Allows setting of data attributes on the underlying element. */
19
29
  data?: DataAttributeMap | undefined;
30
+ /** The values that can be selected by the input. */
20
31
  options: OptionsOrGroups;
32
+ /** Placeholder text for when the input does not have an initial value. */
21
33
  placeholder?: string | undefined;
22
34
  } & import("react").RefAttributes<HTMLSelectElement>>;
23
- export {};
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
6
- var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
6
+ var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
7
7
  var css = require('@emotion/css');
8
8
  var box = require('@spark-web/box');
9
9
  var field = require('@spark-web/field');
@@ -13,7 +13,6 @@ var theme = require('@spark-web/theme');
13
13
  var react = require('react');
14
14
  var jsxRuntime = require('react/jsx-runtime');
15
15
 
16
- var _excluded = ["disabled", "invalid"];
17
16
  var Select = /*#__PURE__*/react.forwardRef(function (_ref, forwardedRef) {
18
17
  var data = _ref.data,
19
18
  defaultValue = _ref.defaultValue,
@@ -26,14 +25,20 @@ var Select = /*#__PURE__*/react.forwardRef(function (_ref, forwardedRef) {
26
25
  value = _ref.value;
27
26
 
28
27
  var _useFieldContext = field.useFieldContext(),
29
- disabled = _useFieldContext.disabled,
30
- invalid = _useFieldContext.invalid,
31
- a11yProps = _objectWithoutProperties(_useFieldContext, _excluded);
28
+ _useFieldContext2 = _slicedToArray(_useFieldContext, 2),
29
+ _useFieldContext2$ = _useFieldContext2[0],
30
+ disabled = _useFieldContext2$.disabled,
31
+ invalid = _useFieldContext2$.invalid,
32
+ a11yProps = _useFieldContext2[1];
32
33
 
33
- var styles = useSelectStyles({
34
+ var _useSelectStyles = useSelectStyles({
34
35
  disabled: disabled,
35
36
  invalid: invalid
36
- });
37
+ }),
38
+ _useSelectStyles2 = _slicedToArray(_useSelectStyles, 2),
39
+ boxProps = _useSelectStyles2[0],
40
+ inputStyles = _useSelectStyles2[1];
41
+
37
42
  var mapOptions = react.useCallback(function (opt) {
38
43
  return /*#__PURE__*/jsxRuntime.jsx("option", {
39
44
  value: opt.value,
@@ -41,11 +46,10 @@ var Select = /*#__PURE__*/react.forwardRef(function (_ref, forwardedRef) {
41
46
  children: opt.label
42
47
  }, opt.value);
43
48
  }, []);
44
- return /*#__PURE__*/jsxRuntime.jsxs(box.Box, {
45
- position: "relative",
46
- children: [/*#__PURE__*/jsxRuntime.jsxs(box.Box, _objectSpread(_objectSpread({}, a11yProps), {}, {
47
- "aria-invalid": invalid || undefined,
49
+ return /*#__PURE__*/jsxRuntime.jsxs(textInput.InputContainer, {
50
+ children: [/*#__PURE__*/jsxRuntime.jsx(Indicator, {}), /*#__PURE__*/jsxRuntime.jsxs(box.Box, _objectSpread(_objectSpread(_objectSpread({}, boxProps), a11yProps), {}, {
48
51
  as: "select",
52
+ className: css.css(inputStyles),
49
53
  data: data,
50
54
  defaultValue: (defaultValue !== null && defaultValue !== void 0 ? defaultValue : placeholder) ? '' : undefined,
51
55
  disabled: disabled,
@@ -54,15 +58,8 @@ var Select = /*#__PURE__*/react.forwardRef(function (_ref, forwardedRef) {
54
58
  onChange: onChange,
55
59
  ref: forwardedRef,
56
60
  required: required,
57
- value: value // Styles
58
- ,
59
- background: disabled ? 'inputDisabled' : 'input',
60
- border: invalid ? 'critical' : 'field',
61
- borderRadius: "small",
62
- paddingX: "medium",
63
- height: "medium",
61
+ value: value,
64
62
  width: "full",
65
- className: css.css(styles),
66
63
  children: [placeholder && /*#__PURE__*/jsxRuntime.jsx("option", {
67
64
  value: "",
68
65
  disabled: true,
@@ -79,46 +76,43 @@ var Select = /*#__PURE__*/react.forwardRef(function (_ref, forwardedRef) {
79
76
 
80
77
  return mapOptions(optionOrGroup);
81
78
  })]
82
- })), /*#__PURE__*/jsxRuntime.jsx(box.Box, {
83
- position: "absolute",
84
- top: 0,
85
- bottom: 0,
86
- right: 0,
87
- display: "flex",
88
- alignItems: "center",
89
- padding: "medium",
90
- className: css.css({
91
- pointerEvents: 'none'
92
- }),
93
- children: /*#__PURE__*/jsxRuntime.jsx(icon.ChevronDownIcon, {
94
- size: "xxsmall",
95
- tone: "placeholder"
96
- })
97
- })]
79
+ }))]
98
80
  });
99
81
  });
100
82
  Select.displayName = 'Select';
101
83
 
102
- function useSelectStyles(_ref2) {
103
- var disabled = _ref2.disabled,
104
- invalid = _ref2.invalid;
105
- var theme$1 = theme.useTheme();
106
- var inputStyles = textInput.useInput({
107
- disabled: disabled,
108
- invalid: invalid
84
+ var Indicator = function Indicator() {
85
+ return /*#__PURE__*/jsxRuntime.jsx(box.Box, {
86
+ position: "absolute",
87
+ top: 0,
88
+ bottom: 0,
89
+ right: 0,
90
+ display: "flex",
91
+ alignItems: "center",
92
+ padding: "medium",
93
+ className: css.css({
94
+ pointerEvents: 'none'
95
+ }),
96
+ children: /*#__PURE__*/jsxRuntime.jsx(icon.ChevronDownIcon, {
97
+ size: "xxsmall",
98
+ tone: "placeholder"
99
+ })
109
100
  });
110
- return _objectSpread(_objectSpread({}, inputStyles), {}, {
111
- overflow: 'hidden',
112
- // fix for Safari to prevent unwanted scrolling of parent container to occur
113
- textOverflow: 'ellipsis',
101
+ };
102
+
103
+ function useSelectStyles(props) {
104
+ var _useInputStyles = textInput.useInputStyles(props),
105
+ _useInputStyles2 = _slicedToArray(_useInputStyles, 2),
106
+ boxProps = _useInputStyles2[0],
107
+ inputStyles = _useInputStyles2[1];
108
+
109
+ var theme$1 = theme.useTheme();
110
+ return [boxProps, _objectSpread(_objectSpread({}, inputStyles), {}, {
114
111
  // Prevent text going underneath the chevron icon
115
112
  paddingRight: theme$1.sizing.xxsmall + // size of chevron icon
116
- theme$1.spacing.medium * 2,
117
- // paddingX value
118
- ':invalid': {
119
- color: theme$1.color.foreground.muted
120
- }
121
- });
113
+ theme$1.spacing.medium * 2 // paddingX value
114
+
115
+ })];
122
116
  }
123
117
 
124
118
  exports.Select = Select;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
6
- var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
6
+ var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
7
7
  var css = require('@emotion/css');
8
8
  var box = require('@spark-web/box');
9
9
  var field = require('@spark-web/field');
@@ -13,7 +13,6 @@ var theme = require('@spark-web/theme');
13
13
  var react = require('react');
14
14
  var jsxRuntime = require('react/jsx-runtime');
15
15
 
16
- var _excluded = ["disabled", "invalid"];
17
16
  var Select = /*#__PURE__*/react.forwardRef(function (_ref, forwardedRef) {
18
17
  var data = _ref.data,
19
18
  defaultValue = _ref.defaultValue,
@@ -26,14 +25,20 @@ var Select = /*#__PURE__*/react.forwardRef(function (_ref, forwardedRef) {
26
25
  value = _ref.value;
27
26
 
28
27
  var _useFieldContext = field.useFieldContext(),
29
- disabled = _useFieldContext.disabled,
30
- invalid = _useFieldContext.invalid,
31
- a11yProps = _objectWithoutProperties(_useFieldContext, _excluded);
28
+ _useFieldContext2 = _slicedToArray(_useFieldContext, 2),
29
+ _useFieldContext2$ = _useFieldContext2[0],
30
+ disabled = _useFieldContext2$.disabled,
31
+ invalid = _useFieldContext2$.invalid,
32
+ a11yProps = _useFieldContext2[1];
32
33
 
33
- var styles = useSelectStyles({
34
+ var _useSelectStyles = useSelectStyles({
34
35
  disabled: disabled,
35
36
  invalid: invalid
36
- });
37
+ }),
38
+ _useSelectStyles2 = _slicedToArray(_useSelectStyles, 2),
39
+ boxProps = _useSelectStyles2[0],
40
+ inputStyles = _useSelectStyles2[1];
41
+
37
42
  var mapOptions = react.useCallback(function (opt) {
38
43
  return /*#__PURE__*/jsxRuntime.jsx("option", {
39
44
  value: opt.value,
@@ -41,11 +46,10 @@ var Select = /*#__PURE__*/react.forwardRef(function (_ref, forwardedRef) {
41
46
  children: opt.label
42
47
  }, opt.value);
43
48
  }, []);
44
- return /*#__PURE__*/jsxRuntime.jsxs(box.Box, {
45
- position: "relative",
46
- children: [/*#__PURE__*/jsxRuntime.jsxs(box.Box, _objectSpread(_objectSpread({}, a11yProps), {}, {
47
- "aria-invalid": invalid || undefined,
49
+ return /*#__PURE__*/jsxRuntime.jsxs(textInput.InputContainer, {
50
+ children: [/*#__PURE__*/jsxRuntime.jsx(Indicator, {}), /*#__PURE__*/jsxRuntime.jsxs(box.Box, _objectSpread(_objectSpread(_objectSpread({}, boxProps), a11yProps), {}, {
48
51
  as: "select",
52
+ className: css.css(inputStyles),
49
53
  data: data,
50
54
  defaultValue: (defaultValue !== null && defaultValue !== void 0 ? defaultValue : placeholder) ? '' : undefined,
51
55
  disabled: disabled,
@@ -54,15 +58,8 @@ var Select = /*#__PURE__*/react.forwardRef(function (_ref, forwardedRef) {
54
58
  onChange: onChange,
55
59
  ref: forwardedRef,
56
60
  required: required,
57
- value: value // Styles
58
- ,
59
- background: disabled ? 'inputDisabled' : 'input',
60
- border: invalid ? 'critical' : 'field',
61
- borderRadius: "small",
62
- paddingX: "medium",
63
- height: "medium",
61
+ value: value,
64
62
  width: "full",
65
- className: css.css(styles),
66
63
  children: [placeholder && /*#__PURE__*/jsxRuntime.jsx("option", {
67
64
  value: "",
68
65
  disabled: true,
@@ -79,46 +76,43 @@ var Select = /*#__PURE__*/react.forwardRef(function (_ref, forwardedRef) {
79
76
 
80
77
  return mapOptions(optionOrGroup);
81
78
  })]
82
- })), /*#__PURE__*/jsxRuntime.jsx(box.Box, {
83
- position: "absolute",
84
- top: 0,
85
- bottom: 0,
86
- right: 0,
87
- display: "flex",
88
- alignItems: "center",
89
- padding: "medium",
90
- className: css.css({
91
- pointerEvents: 'none'
92
- }),
93
- children: /*#__PURE__*/jsxRuntime.jsx(icon.ChevronDownIcon, {
94
- size: "xxsmall",
95
- tone: "placeholder"
96
- })
97
- })]
79
+ }))]
98
80
  });
99
81
  });
100
82
  Select.displayName = 'Select';
101
83
 
102
- function useSelectStyles(_ref2) {
103
- var disabled = _ref2.disabled,
104
- invalid = _ref2.invalid;
105
- var theme$1 = theme.useTheme();
106
- var inputStyles = textInput.useInput({
107
- disabled: disabled,
108
- invalid: invalid
84
+ var Indicator = function Indicator() {
85
+ return /*#__PURE__*/jsxRuntime.jsx(box.Box, {
86
+ position: "absolute",
87
+ top: 0,
88
+ bottom: 0,
89
+ right: 0,
90
+ display: "flex",
91
+ alignItems: "center",
92
+ padding: "medium",
93
+ className: css.css({
94
+ pointerEvents: 'none'
95
+ }),
96
+ children: /*#__PURE__*/jsxRuntime.jsx(icon.ChevronDownIcon, {
97
+ size: "xxsmall",
98
+ tone: "placeholder"
99
+ })
109
100
  });
110
- return _objectSpread(_objectSpread({}, inputStyles), {}, {
111
- overflow: 'hidden',
112
- // fix for Safari to prevent unwanted scrolling of parent container to occur
113
- textOverflow: 'ellipsis',
101
+ };
102
+
103
+ function useSelectStyles(props) {
104
+ var _useInputStyles = textInput.useInputStyles(props),
105
+ _useInputStyles2 = _slicedToArray(_useInputStyles, 2),
106
+ boxProps = _useInputStyles2[0],
107
+ inputStyles = _useInputStyles2[1];
108
+
109
+ var theme$1 = theme.useTheme();
110
+ return [boxProps, _objectSpread(_objectSpread({}, inputStyles), {}, {
114
111
  // Prevent text going underneath the chevron icon
115
112
  paddingRight: theme$1.sizing.xxsmall + // size of chevron icon
116
- theme$1.spacing.medium * 2,
117
- // paddingX value
118
- ':invalid': {
119
- color: theme$1.color.foreground.muted
120
- }
121
- });
113
+ theme$1.spacing.medium * 2 // paddingX value
114
+
115
+ })];
122
116
  }
123
117
 
124
118
  exports.Select = Select;
@@ -1,15 +1,14 @@
1
1
  import _objectSpread from '@babel/runtime/helpers/esm/objectSpread2';
2
- import _objectWithoutProperties from '@babel/runtime/helpers/esm/objectWithoutProperties';
2
+ import _slicedToArray from '@babel/runtime/helpers/esm/slicedToArray';
3
3
  import { css } from '@emotion/css';
4
4
  import { Box } from '@spark-web/box';
5
5
  import { useFieldContext } from '@spark-web/field';
6
6
  import { ChevronDownIcon } from '@spark-web/icon';
7
- import { useInput } from '@spark-web/text-input';
7
+ import { InputContainer, useInputStyles } from '@spark-web/text-input';
8
8
  import { useTheme } from '@spark-web/theme';
9
9
  import { forwardRef, useCallback } from 'react';
10
10
  import { jsx, jsxs } from 'react/jsx-runtime';
11
11
 
12
- var _excluded = ["disabled", "invalid"];
13
12
  var Select = /*#__PURE__*/forwardRef(function (_ref, forwardedRef) {
14
13
  var data = _ref.data,
15
14
  defaultValue = _ref.defaultValue,
@@ -22,14 +21,20 @@ var Select = /*#__PURE__*/forwardRef(function (_ref, forwardedRef) {
22
21
  value = _ref.value;
23
22
 
24
23
  var _useFieldContext = useFieldContext(),
25
- disabled = _useFieldContext.disabled,
26
- invalid = _useFieldContext.invalid,
27
- a11yProps = _objectWithoutProperties(_useFieldContext, _excluded);
24
+ _useFieldContext2 = _slicedToArray(_useFieldContext, 2),
25
+ _useFieldContext2$ = _useFieldContext2[0],
26
+ disabled = _useFieldContext2$.disabled,
27
+ invalid = _useFieldContext2$.invalid,
28
+ a11yProps = _useFieldContext2[1];
28
29
 
29
- var styles = useSelectStyles({
30
+ var _useSelectStyles = useSelectStyles({
30
31
  disabled: disabled,
31
32
  invalid: invalid
32
- });
33
+ }),
34
+ _useSelectStyles2 = _slicedToArray(_useSelectStyles, 2),
35
+ boxProps = _useSelectStyles2[0],
36
+ inputStyles = _useSelectStyles2[1];
37
+
33
38
  var mapOptions = useCallback(function (opt) {
34
39
  return /*#__PURE__*/jsx("option", {
35
40
  value: opt.value,
@@ -37,11 +42,10 @@ var Select = /*#__PURE__*/forwardRef(function (_ref, forwardedRef) {
37
42
  children: opt.label
38
43
  }, opt.value);
39
44
  }, []);
40
- return /*#__PURE__*/jsxs(Box, {
41
- position: "relative",
42
- children: [/*#__PURE__*/jsxs(Box, _objectSpread(_objectSpread({}, a11yProps), {}, {
43
- "aria-invalid": invalid || undefined,
45
+ return /*#__PURE__*/jsxs(InputContainer, {
46
+ children: [/*#__PURE__*/jsx(Indicator, {}), /*#__PURE__*/jsxs(Box, _objectSpread(_objectSpread(_objectSpread({}, boxProps), a11yProps), {}, {
44
47
  as: "select",
48
+ className: css(inputStyles),
45
49
  data: data,
46
50
  defaultValue: (defaultValue !== null && defaultValue !== void 0 ? defaultValue : placeholder) ? '' : undefined,
47
51
  disabled: disabled,
@@ -50,15 +54,8 @@ var Select = /*#__PURE__*/forwardRef(function (_ref, forwardedRef) {
50
54
  onChange: onChange,
51
55
  ref: forwardedRef,
52
56
  required: required,
53
- value: value // Styles
54
- ,
55
- background: disabled ? 'inputDisabled' : 'input',
56
- border: invalid ? 'critical' : 'field',
57
- borderRadius: "small",
58
- paddingX: "medium",
59
- height: "medium",
57
+ value: value,
60
58
  width: "full",
61
- className: css(styles),
62
59
  children: [placeholder && /*#__PURE__*/jsx("option", {
63
60
  value: "",
64
61
  disabled: true,
@@ -75,46 +72,43 @@ var Select = /*#__PURE__*/forwardRef(function (_ref, forwardedRef) {
75
72
 
76
73
  return mapOptions(optionOrGroup);
77
74
  })]
78
- })), /*#__PURE__*/jsx(Box, {
79
- position: "absolute",
80
- top: 0,
81
- bottom: 0,
82
- right: 0,
83
- display: "flex",
84
- alignItems: "center",
85
- padding: "medium",
86
- className: css({
87
- pointerEvents: 'none'
88
- }),
89
- children: /*#__PURE__*/jsx(ChevronDownIcon, {
90
- size: "xxsmall",
91
- tone: "placeholder"
92
- })
93
- })]
75
+ }))]
94
76
  });
95
77
  });
96
78
  Select.displayName = 'Select';
97
79
 
98
- function useSelectStyles(_ref2) {
99
- var disabled = _ref2.disabled,
100
- invalid = _ref2.invalid;
101
- var theme = useTheme();
102
- var inputStyles = useInput({
103
- disabled: disabled,
104
- invalid: invalid
80
+ var Indicator = function Indicator() {
81
+ return /*#__PURE__*/jsx(Box, {
82
+ position: "absolute",
83
+ top: 0,
84
+ bottom: 0,
85
+ right: 0,
86
+ display: "flex",
87
+ alignItems: "center",
88
+ padding: "medium",
89
+ className: css({
90
+ pointerEvents: 'none'
91
+ }),
92
+ children: /*#__PURE__*/jsx(ChevronDownIcon, {
93
+ size: "xxsmall",
94
+ tone: "placeholder"
95
+ })
105
96
  });
106
- return _objectSpread(_objectSpread({}, inputStyles), {}, {
107
- overflow: 'hidden',
108
- // fix for Safari to prevent unwanted scrolling of parent container to occur
109
- textOverflow: 'ellipsis',
97
+ };
98
+
99
+ function useSelectStyles(props) {
100
+ var _useInputStyles = useInputStyles(props),
101
+ _useInputStyles2 = _slicedToArray(_useInputStyles, 2),
102
+ boxProps = _useInputStyles2[0],
103
+ inputStyles = _useInputStyles2[1];
104
+
105
+ var theme = useTheme();
106
+ return [boxProps, _objectSpread(_objectSpread({}, inputStyles), {}, {
110
107
  // Prevent text going underneath the chevron icon
111
108
  paddingRight: theme.sizing.xxsmall + // size of chevron icon
112
- theme.spacing.medium * 2,
113
- // paddingX value
114
- ':invalid': {
115
- color: theme.color.foreground.muted
116
- }
117
- });
109
+ theme.spacing.medium * 2 // paddingX value
110
+
111
+ })];
118
112
  }
119
113
 
120
114
  export { Select };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spark-web/select",
3
- "version": "1.0.5",
3
+ "version": "1.0.8",
4
4
  "license": "MIT",
5
5
  "main": "dist/spark-web-select.cjs.js",
6
6
  "module": "dist/spark-web-select.esm.js",
@@ -8,22 +8,21 @@
8
8
  "dist"
9
9
  ],
10
10
  "dependencies": {
11
- "@babel/runtime": "^7.14.6",
12
- "@emotion/css": "^11.7.1",
13
- "@spark-web/a11y": "^1.0.4",
14
- "@spark-web/box": "^1.0.4",
15
- "@spark-web/field": "^1.1.0",
16
- "@spark-web/icon": "^1.1.2",
17
- "@spark-web/text": "^1.0.4",
18
- "@spark-web/text-input": "^1.1.1",
19
- "@spark-web/theme": "^3.0.0",
20
- "@spark-web/utils": "^1.1.2"
11
+ "@babel/runtime": "^7.18.3",
12
+ "@emotion/css": "^11.9.0",
13
+ "@spark-web/box": "^1.0.6",
14
+ "@spark-web/icon": "^1.1.4",
15
+ "@spark-web/text-input": "^2.0.0",
16
+ "@spark-web/theme": "^3.0.2"
21
17
  },
22
18
  "devDependencies": {
19
+ "@spark-web/field": "^3.0.1",
20
+ "@spark-web/utils": "^1.1.5",
23
21
  "@types/react": "^17.0.12",
24
22
  "react": "^17.0.2"
25
23
  },
26
24
  "peerDependencies": {
25
+ "@spark-web/field": "^3.0.1",
27
26
  "react": ">=17.0.2"
28
27
  },
29
28
  "engines": {