@telus-uds/components-base 1.19.0 → 1.21.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 (97) hide show
  1. package/CHANGELOG.md +34 -2
  2. package/__tests17__/ThemeProvider/ThemeProvider.test.jsx +3 -1
  3. package/component-docs.json +838 -125
  4. package/lib/BaseProvider/index.js +2 -1
  5. package/lib/Box/Box.js +14 -1
  6. package/lib/Button/ButtonDropdown.js +207 -0
  7. package/lib/Button/index.js +8 -0
  8. package/lib/Carousel/Carousel.js +2 -2
  9. package/lib/Carousel/CarouselItem/CarouselItem.js +7 -1
  10. package/lib/Carousel/CarouselTabs/CarouselTabsPanel.js +21 -4
  11. package/lib/FlexGrid/Col/Col.js +1 -3
  12. package/lib/FlexGrid/FlexGrid.js +3 -5
  13. package/lib/FlexGrid/Row/Row.js +3 -3
  14. package/lib/IconButton/IconButton.js +12 -4
  15. package/lib/MultiSelectFilter/MultiSelectFilter.js +276 -0
  16. package/lib/MultiSelectFilter/dictionary.js +19 -0
  17. package/lib/MultiSelectFilter/index.js +13 -0
  18. package/lib/Search/Search.js +4 -1
  19. package/lib/Select/Picker.native.js +16 -13
  20. package/lib/Select/Select.js +7 -1
  21. package/lib/Select/constants.js +15 -0
  22. package/lib/StepTracker/Step.js +2 -1
  23. package/lib/TextInput/TextInput.js +9 -2
  24. package/lib/TextInput/TextInputBase.js +52 -8
  25. package/lib/TextInput/dictionary.js +15 -0
  26. package/lib/ThemeProvider/ThemeProvider.js +24 -7
  27. package/lib/ThemeProvider/utils/styles.js +3 -1
  28. package/lib/index.js +18 -0
  29. package/lib/utils/BaseView/BaseView.js +64 -0
  30. package/lib/utils/BaseView/BaseView.native.js +16 -0
  31. package/lib/utils/BaseView/index.js +13 -0
  32. package/lib/utils/index.js +10 -1
  33. package/lib/utils/input.js +11 -3
  34. package/lib/utils/props/handlerProps.js +5 -0
  35. package/lib-module/BaseProvider/index.js +2 -1
  36. package/lib-module/Box/Box.js +14 -1
  37. package/lib-module/Button/ButtonDropdown.js +181 -0
  38. package/lib-module/Button/index.js +2 -1
  39. package/lib-module/Carousel/Carousel.js +2 -2
  40. package/lib-module/Carousel/CarouselItem/CarouselItem.js +8 -2
  41. package/lib-module/Carousel/CarouselTabs/CarouselTabsPanel.js +23 -6
  42. package/lib-module/FlexGrid/Col/Col.js +2 -3
  43. package/lib-module/FlexGrid/FlexGrid.js +2 -3
  44. package/lib-module/FlexGrid/Row/Row.js +2 -2
  45. package/lib-module/IconButton/IconButton.js +14 -4
  46. package/lib-module/MultiSelectFilter/MultiSelectFilter.js +248 -0
  47. package/lib-module/MultiSelectFilter/dictionary.js +12 -0
  48. package/lib-module/MultiSelectFilter/index.js +2 -0
  49. package/lib-module/Search/Search.js +4 -1
  50. package/lib-module/Select/Picker.native.js +15 -13
  51. package/lib-module/Select/Select.js +6 -1
  52. package/lib-module/Select/constants.js +5 -0
  53. package/lib-module/StepTracker/Step.js +2 -1
  54. package/lib-module/TextInput/TextInput.js +6 -0
  55. package/lib-module/TextInput/TextInputBase.js +52 -10
  56. package/lib-module/TextInput/dictionary.js +8 -0
  57. package/lib-module/ThemeProvider/ThemeProvider.js +24 -7
  58. package/lib-module/ThemeProvider/utils/styles.js +3 -1
  59. package/lib-module/index.js +2 -0
  60. package/lib-module/utils/BaseView/BaseView.js +43 -0
  61. package/lib-module/utils/BaseView/BaseView.native.js +6 -0
  62. package/lib-module/utils/BaseView/index.js +2 -0
  63. package/lib-module/utils/index.js +2 -1
  64. package/lib-module/utils/input.js +11 -3
  65. package/lib-module/utils/props/handlerProps.js +5 -0
  66. package/package.json +3 -3
  67. package/src/BaseProvider/index.jsx +4 -1
  68. package/src/Box/Box.jsx +14 -1
  69. package/src/Button/ButtonDropdown.jsx +179 -0
  70. package/src/Button/index.js +2 -1
  71. package/src/Carousel/Carousel.jsx +6 -3
  72. package/src/Carousel/CarouselItem/CarouselItem.jsx +9 -2
  73. package/src/Carousel/CarouselTabs/CarouselTabsPanel.jsx +19 -5
  74. package/src/FlexGrid/Col/Col.jsx +4 -4
  75. package/src/FlexGrid/FlexGrid.jsx +11 -10
  76. package/src/FlexGrid/Row/Row.jsx +4 -3
  77. package/src/IconButton/IconButton.jsx +3 -1
  78. package/src/MultiSelectFilter/MultiSelectFilter.jsx +227 -0
  79. package/src/MultiSelectFilter/dictionary.js +12 -0
  80. package/src/MultiSelectFilter/index.js +3 -0
  81. package/src/Search/Search.jsx +2 -1
  82. package/src/Select/Picker.native.jsx +29 -14
  83. package/src/Select/Select.jsx +7 -1
  84. package/src/Select/constants.js +5 -0
  85. package/src/StepTracker/Step.jsx +5 -1
  86. package/src/TextInput/TextInput.jsx +5 -0
  87. package/src/TextInput/TextInputBase.jsx +43 -8
  88. package/src/TextInput/dictionary.js +8 -0
  89. package/src/ThemeProvider/ThemeProvider.jsx +23 -6
  90. package/src/ThemeProvider/utils/styles.js +3 -1
  91. package/src/index.js +2 -0
  92. package/src/utils/BaseView/BaseView.jsx +38 -0
  93. package/src/utils/BaseView/BaseView.native.jsx +6 -0
  94. package/src/utils/BaseView/index.js +3 -0
  95. package/src/utils/index.js +1 -0
  96. package/src/utils/input.js +9 -4
  97. package/src/utils/props/handlerProps.js +4 -0
@@ -0,0 +1,276 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _react = _interopRequireWildcard(require("react"));
9
+
10
+ var _propTypes = _interopRequireDefault(require("prop-types"));
11
+
12
+ var _ThemeProvider = require("../ThemeProvider");
13
+
14
+ var _utils = require("../utils");
15
+
16
+ var _dictionary = _interopRequireDefault(require("./dictionary"));
17
+
18
+ var _Box = _interopRequireDefault(require("../Box"));
19
+
20
+ var _Button = require("../Button");
21
+
22
+ var _Checkbox = require("../Checkbox");
23
+
24
+ var _Divider = _interopRequireDefault(require("../Divider"));
25
+
26
+ var _FlexGrid = _interopRequireDefault(require("../FlexGrid"));
27
+
28
+ var _Modal = _interopRequireDefault(require("../Modal"));
29
+
30
+ var _Spacer = _interopRequireDefault(require("../Spacer"));
31
+
32
+ var _StackView = _interopRequireDefault(require("../StackView"));
33
+
34
+ var _Typography = _interopRequireDefault(require("../Typography"));
35
+
36
+ var _Link = require("../Link");
37
+
38
+ var _jsxRuntime = require("react/jsx-runtime");
39
+
40
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
41
+
42
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
43
+
44
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
45
+
46
+ const {
47
+ Col,
48
+ Row
49
+ } = _FlexGrid.default;
50
+ const MultiSelectFilter = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
51
+ let {
52
+ label,
53
+ id = label,
54
+ variant,
55
+ tokens,
56
+ items = [],
57
+ values,
58
+ initialValues,
59
+ maxValues,
60
+ onChange,
61
+ copy = 'en',
62
+ readOnly = false,
63
+ inactive = false,
64
+ rowLimit = 12,
65
+ ...rest
66
+ } = _ref;
67
+ const {
68
+ currentValues,
69
+ setValues
70
+ } = (0, _utils.useMultipleInputValues)({
71
+ initialValues,
72
+ values,
73
+ maxValues,
74
+ onChange,
75
+ readOnly
76
+ });
77
+ const getItemTokens = (0, _ThemeProvider.useThemeTokensCallback)('ButtonDropdown', tokens, variant);
78
+
79
+ const getButtonTokens = buttonState => (0, _utils.selectTokens)('Button', getItemTokens(buttonState));
80
+
81
+ const getCopy = (0, _utils.useCopy)({
82
+ dictionary: _dictionary.default,
83
+ copy
84
+ });
85
+ const [isOpen, setIsOpen] = (0, _react.useState)(false);
86
+ const [checkedIds, setCheckedIds] = (0, _react.useState)(currentValues !== null && currentValues !== void 0 ? currentValues : []);
87
+ const colSize = items.length > rowLimit ? 2 : 1;
88
+ const isSelected = currentValues.length > 0;
89
+ const uniqueFields = ['id', 'label'];
90
+
91
+ if (!(0, _utils.containUniqueFields)(items, uniqueFields)) {
92
+ throw new Error("MultiSelectFilter items must have unique ".concat(uniqueFields.join(', ')));
93
+ } // Pass an object of relevant component state as first argument for any passed-in press handlers
94
+
95
+
96
+ const pressHandlers = (0, _utils.getPressHandlersWithArgs)(rest, [{
97
+ id,
98
+ label,
99
+ currentValues
100
+ }]);
101
+
102
+ const handleChange = event => {
103
+ if (pressHandlers.onPress) pressHandlers === null || pressHandlers === void 0 ? void 0 : pressHandlers.onPress(event);
104
+ setIsOpen(true);
105
+ };
106
+
107
+ const onApply = e => {
108
+ setValues(e);
109
+ setIsOpen(false);
110
+ };
111
+
112
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
113
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_Modal.default, {
114
+ isOpen: isOpen,
115
+ onClose: () => setIsOpen(false),
116
+ variant: {
117
+ width: colSize > 1 ? 'size576' : 's'
118
+ },
119
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(Row, {
120
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Typography.default, {
121
+ variant: {
122
+ size: 'h4'
123
+ },
124
+ children: getCopy('filterByLabel').replace(/%\{filterCategory\}/g, label.toLowerCase())
125
+ })
126
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Spacer.default, {
127
+ space: 4
128
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Spacer.default, {
129
+ space: 1
130
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, {
131
+ scroll: true,
132
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Row, {
133
+ distribute: "between",
134
+ children: [...Array(colSize).keys()].map(i => /*#__PURE__*/(0, _jsxRuntime.jsxs)(Col, {
135
+ xs: 12 / colSize,
136
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Checkbox.CheckboxGroup, {
137
+ items: items.slice(i * rowLimit, (i + 1) * rowLimit),
138
+ checkedIds: checkedIds,
139
+ onChange: e => setCheckedIds(e, i)
140
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Spacer.default, {
141
+ size: 4
142
+ })]
143
+ }, i))
144
+ })
145
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Divider.default, {
146
+ variant: {
147
+ width: 'full',
148
+ color: 'E3E6E8',
149
+ decorative: true,
150
+ weight: 'thin'
151
+ },
152
+ space: 4
153
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(Row, {
154
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_StackView.default, {
155
+ direction: "row",
156
+ space: 3,
157
+ tokens: {
158
+ alignItems: 'center'
159
+ },
160
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.Button, {
161
+ onPress: () => onApply(checkedIds),
162
+ variant: {
163
+ size: 'small',
164
+ priority: 'high'
165
+ },
166
+ children: getCopy('applyButtonLabel')
167
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, {
168
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Link.TextButton, {
169
+ onPress: () => setCheckedIds([]),
170
+ children: getCopy('clearButtonLabel')
171
+ })
172
+ })]
173
+ })
174
+ })]
175
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.ButtonDropdown, {
176
+ ref: ref,
177
+ ...pressHandlers,
178
+ value: isOpen,
179
+ selected: isSelected,
180
+ label: label,
181
+ onChange: handleChange,
182
+ tokens: getButtonTokens,
183
+ inactive: inactive
184
+ }, id)]
185
+ });
186
+ });
187
+ MultiSelectFilter.displayName = 'MultiSelectFilter';
188
+ MultiSelectFilter.propTypes = {
189
+ /**
190
+ * The text displayed to the user in a ButtonDropdown.
191
+ */
192
+ label: _propTypes.default.string.isRequired,
193
+
194
+ /**
195
+ * An optional unique string may be provided to identify the ButtonDropdown.
196
+ * If not provided, the label is used.
197
+ */
198
+ id: _propTypes.default.string,
199
+
200
+ /**
201
+ * Sets the variant for ButtonDropdown element.
202
+ */
203
+ variant: _utils.variantProp.propType,
204
+
205
+ /**
206
+ * Sets the tokens for ButtonDropdown element.
207
+ */
208
+ tokens: (0, _utils.getTokensPropType)('ButtonDropdown'),
209
+
210
+ /**
211
+ * The options a user may select.
212
+ */
213
+ items: _propTypes.default.arrayOf(_propTypes.default.shape({
214
+ /**
215
+ * The text displayed to the user with a checkbox, describing this option.
216
+ */
217
+ label: _propTypes.default.string.isRequired,
218
+
219
+ /**
220
+ * An optional unique string may be provided to identify this option.
221
+ * If not provided, the label is used.
222
+ */
223
+ id: _propTypes.default.string
224
+ })),
225
+
226
+ /**
227
+ * If the selected item(s) in the checkbox group(s) are to be controlled externally by
228
+ * a parent component, pass an array of strings as well as an `onChange` handler.
229
+ * Passing an array for "values" makes the MultiSelectFilter a "controlled" component that
230
+ * expects its state to be handled via `onChange` and so doesn't handle it itself.
231
+ */
232
+ values: _propTypes.default.arrayOf(_propTypes.default.string),
233
+
234
+ /**
235
+ * If `values` is not passed, making the MultiSelectFilter an "uncontrolled" component
236
+ * managing its own selected state, a default set of selections may be provided.
237
+ * Changing the `initialValues` does not change the user's selections.
238
+ */
239
+ initialValues: _propTypes.default.arrayOf(_propTypes.default.string),
240
+
241
+ /**
242
+ * If provided, sets a maximum number of items a user may select at once.
243
+ */
244
+ maxValues: _propTypes.default.number,
245
+
246
+ /**
247
+ * If provided, this function is called when the current selection is changed
248
+ * and is passed an array of the `id`s of all currently selected `items`.
249
+ */
250
+ onChange: _propTypes.default.func,
251
+
252
+ /**
253
+ * Select English or French copy for the accessible label.
254
+ */
255
+ copy: _propTypes.default.oneOf(['en', 'fr']),
256
+
257
+ /**
258
+ * If true, the ButtonDropdown cannot be selected by the user and simply show their current state.
259
+ */
260
+ readOnly: _propTypes.default.string,
261
+
262
+ /**
263
+ * If true, the MultiSelectFilter cannot be interacted with, ButtonDropdown is
264
+ * set as `disabled` and if the theme supports `inactive` appearances rules, these
265
+ * are applied.
266
+ */
267
+ inactive: _propTypes.default.string,
268
+
269
+ /**
270
+ * Sets the maximum number of items in one column. If number of items are more
271
+ * than the `rowLimit`, they will be rendered in 2 columns.
272
+ */
273
+ rowLimit: _propTypes.default.number
274
+ };
275
+ var _default = MultiSelectFilter;
276
+ exports.default = _default;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _default = {
8
+ en: {
9
+ filterByLabel: 'Filter by %{filterCategory}:',
10
+ applyButtonLabel: 'Apply',
11
+ clearButtonLabel: 'Clear'
12
+ },
13
+ fr: {
14
+ filterByLabel: 'Filtrer par %{filterCategory}:',
15
+ applyButtonLabel: 'Appliquer',
16
+ clearButtonLabel: 'Effacer'
17
+ }
18
+ };
19
+ exports.default = _default;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _MultiSelectFilter = _interopRequireDefault(require("./MultiSelectFilter"));
9
+
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+
12
+ var _default = _MultiSelectFilter.default;
13
+ exports.default = _default;
@@ -133,8 +133,11 @@ const Search = /*#__PURE__*/(0, _react.forwardRef)((_ref3, ref) => {
133
133
  };
134
134
 
135
135
  const handleClear = event => {
136
+ var _ref$current;
137
+
136
138
  setValue('', event);
137
- if (onClear !== undefined) onClear('', event);
139
+ onClear === null || onClear === void 0 ? void 0 : onClear('', event);
140
+ ref === null || ref === void 0 ? void 0 : (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.focus();
138
141
  };
139
142
 
140
143
  const handleFocus = event => {
@@ -19,6 +19,8 @@ var _utils = require("../utils");
19
19
 
20
20
  var _Group = _interopRequireDefault(require("./Group"));
21
21
 
22
+ var _constants = require("./constants");
23
+
22
24
  var _jsxRuntime = require("react/jsx-runtime");
23
25
 
24
26
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -27,32 +29,33 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
27
29
 
28
30
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
29
31
 
30
- // styling of the native input is very limited, most of the styles have to be applied to an additional View
32
+ // Styling of the native input is very limited, most of the styles have to be applied to an additional View
31
33
  const selectAndroidInputStyles = _ref => {
32
34
  let {
33
35
  height = 0,
34
- paddingBottom = 0,
35
- paddingTop = 0,
36
- borderWidth = 0,
37
36
  color
38
37
  } = _ref;
39
38
  return {
40
- height: height - paddingTop - paddingBottom - 2 * borderWidth,
39
+ height,
40
+ paddingBottom: 0,
41
+ paddingTop: 0,
41
42
  color
42
43
  };
43
- }; // the native input has a side padding of 8px, which can't be adjusted, so we have to account for that in the container
44
+ }; // The native input has a side padding of 8px, which can't be adjusted, so we have to account for that in the container
44
45
 
45
46
 
46
47
  const selectAndroidContainerStyles = _ref2 => {
47
48
  let {
48
- paddingLeft = 0,
49
- paddingRight = 0,
49
+ paddingLeft = _constants.ANDROID_DEFAULT_PADDING,
50
+ paddingRight = _constants.ANDROID_DEFAULT_PADDING,
50
51
  ...rest
51
52
  } = _ref2;
52
- return {
53
- paddingLeft: paddingLeft > 8 ? paddingLeft - 8 : 0,
54
- paddingRight: paddingRight > 8 ? paddingRight - 8 : 0,
55
- ...rest
53
+ return { ...rest,
54
+ paddingLeft: paddingLeft > _constants.ANDROID_HORIZONTAL_PADDING_OFFSET ? paddingLeft - _constants.ANDROID_HORIZONTAL_PADDING_OFFSET : _constants.ANDROID_DEFAULT_PADDING,
55
+ paddingRight: paddingRight > _constants.ANDROID_HORIZONTAL_PADDING_OFFSET ? paddingRight - _constants.ANDROID_HORIZONTAL_PADDING_OFFSET : _constants.ANDROID_DEFAULT_PADDING,
56
+ paddingBottom: _constants.ANDROID_DEFAULT_PADDING,
57
+ paddingTop: _constants.ANDROID_DEFAULT_PADDING,
58
+ height: rest.height + _constants.ANDROID_HEIGHT_OFFSET
56
59
  };
57
60
  };
58
61
 
@@ -69,7 +72,7 @@ const Picker = /*#__PURE__*/(0, _react.forwardRef)((_ref3, ref) => {
69
72
  ...rest
70
73
  } = _ref3;
71
74
 
72
- // ungroup items, since there's no way to support groups on native
75
+ // Ungroup items, since there's no way to support groups on native
73
76
  const flatChildren = _react.Children.toArray(children).flatMap(child => {
74
77
  if (child.type === _Group.default) {
75
78
  return child.props.children;
@@ -23,6 +23,8 @@ var _Picker = _interopRequireDefault(require("./Picker"));
23
23
 
24
24
  var _InputSupports = _interopRequireDefault(require("../InputSupports"));
25
25
 
26
+ var _constants = require("./constants");
27
+
26
28
  var _jsxRuntime = require("react/jsx-runtime");
27
29
 
28
30
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -166,7 +168,11 @@ const selectValidationIconContainerStyles = _ref6 => {
166
168
  } = _ref6;
167
169
  return {
168
170
  paddingRight: icon ? paddingRight + iconSize : paddingRight,
169
- paddingBottom
171
+ ...(_Platform.default.OS === 'android' ? {
172
+ paddingBottom: paddingBottom + _constants.ANDROID_VALIDATION_ICON_CONTAINER_OFFSET
173
+ } : {
174
+ paddingBottom
175
+ })
170
176
  };
171
177
  };
172
178
  /**
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ANDROID_VALIDATION_ICON_CONTAINER_OFFSET = exports.ANDROID_HORIZONTAL_PADDING_OFFSET = exports.ANDROID_HEIGHT_OFFSET = exports.ANDROID_DEFAULT_PADDING = void 0;
7
+ // Because Android
8
+ const ANDROID_VALIDATION_ICON_CONTAINER_OFFSET = 5;
9
+ exports.ANDROID_VALIDATION_ICON_CONTAINER_OFFSET = ANDROID_VALIDATION_ICON_CONTAINER_OFFSET;
10
+ const ANDROID_HEIGHT_OFFSET = 12;
11
+ exports.ANDROID_HEIGHT_OFFSET = ANDROID_HEIGHT_OFFSET;
12
+ const ANDROID_HORIZONTAL_PADDING_OFFSET = 8;
13
+ exports.ANDROID_HORIZONTAL_PADDING_OFFSET = ANDROID_HORIZONTAL_PADDING_OFFSET;
14
+ const ANDROID_DEFAULT_PADDING = 0;
15
+ exports.ANDROID_DEFAULT_PADDING = ANDROID_DEFAULT_PADDING;
@@ -203,7 +203,8 @@ const Step = _ref7 => {
203
203
  space: 0,
204
204
  tokens: {
205
205
  alignItems: 'center',
206
- flexGrow: 0
206
+ flexGrow: 0,
207
+ justifyContent: 'center'
207
208
  },
208
209
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
209
210
  style: [staticStyles.connector, !isFirst && selectConnectorStyles(themeTokens, isActive)]
@@ -7,13 +7,15 @@ exports.default = void 0;
7
7
 
8
8
  var _react = _interopRequireWildcard(require("react"));
9
9
 
10
+ var _propTypes = _interopRequireDefault(require("prop-types"));
11
+
10
12
  var _utils = require("../utils");
11
13
 
12
14
  var _InputSupports = _interopRequireDefault(require("../InputSupports"));
13
15
 
14
16
  var _TextInputBase = _interopRequireDefault(require("./TextInputBase"));
15
17
 
16
- var _propTypes = _interopRequireDefault(require("./propTypes"));
18
+ var _propTypes2 = _interopRequireDefault(require("./propTypes"));
17
19
 
18
20
  var _jsxRuntime = require("react/jsx-runtime");
19
21
 
@@ -79,7 +81,12 @@ const TextInput = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
79
81
  });
80
82
  TextInput.displayName = 'TextInput';
81
83
  TextInput.propTypes = { ...selectedSystemPropTypes,
82
- ..._propTypes.default,
84
+ ..._propTypes2.default,
85
+
86
+ /**
87
+ * A callback which if provided will get a clear button rendered and will be called whenever that button gets pressed.
88
+ */
89
+ onClear: _propTypes.default.func,
83
90
  tokens: (0, _utils.getTokensPropType)('TextInput'),
84
91
  variant: _utils.variantProp.propType
85
92
  };
@@ -21,8 +21,12 @@ var _ThemeProvider = require("../ThemeProvider");
21
21
 
22
22
  var _StackView = _interopRequireDefault(require("../StackView"));
23
23
 
24
+ var _IconButton = _interopRequireDefault(require("../IconButton"));
25
+
24
26
  var _utils = require("../utils");
25
27
 
28
+ var _dictionary = _interopRequireDefault(require("./dictionary"));
29
+
26
30
  var _jsxRuntime = require("react/jsx-runtime");
27
31
 
28
32
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -160,12 +164,14 @@ const selectButtonsContainerStyle = _ref5 => {
160
164
  const TextInputBase = /*#__PURE__*/(0, _react.forwardRef)((_ref6, ref) => {
161
165
  let {
162
166
  buttons = [],
167
+ copy = 'en',
163
168
  height,
164
169
  inactive,
165
170
  initialValue,
166
171
  onBlur,
167
172
  onChange,
168
173
  onChangeText,
174
+ onClear,
169
175
  onFocus,
170
176
  onMouseOut,
171
177
  onMouseOver,
@@ -200,17 +206,22 @@ const TextInputBase = /*#__PURE__*/(0, _react.forwardRef)((_ref6, ref) => {
200
206
  if (typeof onMouseOut === 'function') onMouseOut(event);
201
207
  };
202
208
 
209
+ const defaultRef = (0, _react.useRef)();
210
+ const inputRef = ref !== null && ref !== void 0 ? ref : defaultRef;
203
211
  const {
204
212
  currentValue,
213
+ resetValue,
205
214
  setValue,
206
- isControlled
215
+ isControlled,
216
+ isDirty
207
217
  } = (0, _utils.useInputValue)({
208
218
  value,
209
219
  initialValue,
220
+ inputRef,
210
221
  onChange,
211
222
  readOnly
212
223
  });
213
- const element = ref === null || ref === void 0 ? void 0 : ref.current;
224
+ const element = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current;
214
225
  (0, _react.useEffect)(() => {
215
226
  if (_Platform.default.OS === 'web' && pattern && element) {
216
227
  // React Native Web doesn't support `pattern`, so we have to attach it via a ref,
@@ -234,9 +245,35 @@ const TextInputBase = /*#__PURE__*/(0, _react.forwardRef)((_ref6, ref) => {
234
245
  };
235
246
  const themeTokens = (0, _ThemeProvider.useThemeTokens)('TextInput', tokens, variant, states);
236
247
  const {
237
- icon: IconComponent,
238
- buttonsGap
248
+ buttonsGap,
249
+ clearButtonIcon: ClearButtonIcon,
250
+ icon: IconComponent
239
251
  } = themeTokens;
252
+ const buttonsGapSize = (0, _utils.useSpacingScale)(buttonsGap);
253
+ const getCopy = (0, _utils.useCopy)({
254
+ dictionary: _dictionary.default,
255
+ copy
256
+ });
257
+
258
+ if (onClear && isDirty) {
259
+ const handleClear = event => {
260
+ var _inputRef$current;
261
+
262
+ onClear === null || onClear === void 0 ? void 0 : onClear(event);
263
+ resetValue(event);
264
+ inputRef === null || inputRef === void 0 ? void 0 : (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 ? void 0 : _inputRef$current.focus();
265
+ };
266
+
267
+ buttons === null || buttons === void 0 ? void 0 : buttons.unshift( /*#__PURE__*/(0, _jsxRuntime.jsx)(_IconButton.default, {
268
+ accessibilityLabel: getCopy('clearButtonAccessibilityLabel'),
269
+ icon: ClearButtonIcon,
270
+ onPress: handleClear,
271
+ variant: {
272
+ compact: true
273
+ }
274
+ }, "clear"));
275
+ }
276
+
240
277
  const inputProps = { ...selectProps(rest),
241
278
  editable: !inactive,
242
279
  onFocus: handleFocus,
@@ -248,9 +285,7 @@ const TextInputBase = /*#__PURE__*/(0, _react.forwardRef)((_ref6, ref) => {
248
285
  // currentValue is being updated even if the input is not controlled, passing it down to the
249
286
  // Input could lead to changing its state from uncontrolled to controlled
250
287
  value: isControlled ? currentValue : undefined
251
- }; // Get the actual gap value for the current viewport
252
-
253
- const buttonsGapSize = (0, _utils.useSpacingScale)(buttonsGap);
288
+ };
254
289
  const {
255
290
  themeOptions
256
291
  } = (0, _ThemeProvider.useTheme)();
@@ -260,7 +295,7 @@ const TextInputBase = /*#__PURE__*/(0, _react.forwardRef)((_ref6, ref) => {
260
295
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
261
296
  style: selectOuterBorderStyles(themeTokens),
262
297
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_TextInput.default, {
263
- ref: ref,
298
+ ref: inputRef,
264
299
  style: nativeInputStyle,
265
300
  ...inputProps
266
301
  }), IconComponent && /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
@@ -284,12 +319,21 @@ const TextInputBase = /*#__PURE__*/(0, _react.forwardRef)((_ref6, ref) => {
284
319
  TextInputBase.displayName = 'TextInputBase';
285
320
  TextInputBase.propTypes = { ...selectedSystemPropTypes,
286
321
  buttons: _propTypes.default.arrayOf(_propTypes.default.node),
322
+
323
+ /**
324
+ * Select English or French copy for the accessible labels.
325
+ * You may also pass in a custom dictionary object.
326
+ */
327
+ copy: _propTypes.default.oneOfType([_propTypes.default.oneOf(['en', 'fr']), _propTypes.default.shape({
328
+ clearButtonAccessibilityLabel: _propTypes.default.string
329
+ })]),
287
330
  height: _propTypes.default.number,
288
331
  inactive: _propTypes.default.bool,
289
332
  initialValue: _propTypes.default.string,
290
333
  onBlur: _propTypes.default.func,
291
334
  onChange: _propTypes.default.func,
292
335
  onChangeText: _propTypes.default.func,
336
+ onClear: _propTypes.default.func,
293
337
  onFocus: _propTypes.default.func,
294
338
  onMouseOut: _propTypes.default.func,
295
339
  onMouseOver: _propTypes.default.func,
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _default = {
8
+ en: {
9
+ clearButtonAccessibilityLabel: 'Clear'
10
+ },
11
+ fr: {
12
+ clearButtonAccessibilityLabel: 'Effacer'
13
+ }
14
+ };
15
+ exports.default = _default;
@@ -25,19 +25,29 @@ const uninitialisedError = new Error('Theme context used outside of ThemeProvide
25
25
  exports.uninitialisedError = uninitialisedError;
26
26
  const ThemeContext = /*#__PURE__*/(0, _react.createContext)(uninitialisedError);
27
27
  exports.ThemeContext = ThemeContext;
28
- const ThemeSetterContext = /*#__PURE__*/(0, _react.createContext)(uninitialisedError);
28
+ const ThemeSetterContext = /*#__PURE__*/(0, _react.createContext)(uninitialisedError); // These options default to `true` in v1.x to match legacy defaults and avoid breaking changes.
29
+ // This should change in future major releases to become "opt-in" legacy support.
30
+
29
31
  exports.ThemeSetterContext = ThemeSetterContext;
32
+ const defaultThemeOptions = {
33
+ // TODO: switch `forceAbsoluteFontSizing` to be false by default in the next major version
34
+ forceAbsoluteFontSizing: true,
35
+ // TODO: switch `forceZIndex` to be false by default in the next major version
36
+ forceZIndex: true,
37
+ // TODO: switch `enableHelmetSSR` to be false by default in the next major version
38
+ enableHelmetSSR: true
39
+ };
30
40
 
31
41
  const ThemeProvider = _ref => {
32
42
  let {
33
43
  children,
34
44
  defaultTheme,
35
- // TODO: switch `forceAbsoluteFontSizing` to be false by default in the next major version
36
- themeOptions = {
37
- forceAbsoluteFontSizing: true
38
- }
45
+ themeOptions = {}
39
46
  } = _ref;
40
- const [theme, setTheme] = (0, _react.useState)(defaultTheme); // Validate the theme tokens version on every render.
47
+ const [theme, setTheme] = (0, _react.useState)(defaultTheme);
48
+ const appliedThemeOptions = { ...defaultThemeOptions,
49
+ ...themeOptions
50
+ }; // Validate the theme tokens version on every render.
41
51
  // This will intentionally break the application when attempting to use an invalid theme.
42
52
  // This will surface an incompatibility quickly rather than allowing the potential for strange bugs due to missing or incompatible tokens.
43
53
 
@@ -46,7 +56,7 @@ const ThemeProvider = _ref => {
46
56
  value: setTheme,
47
57
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(ThemeContext.Provider, {
48
58
  value: { ...theme,
49
- themeOptions
59
+ themeOptions: appliedThemeOptions
50
60
  },
51
61
  children: children
52
62
  })
@@ -69,9 +79,16 @@ ThemeProvider.propTypes = {
69
79
  * relative sizing (in `rem`, scales depending on the browser settings)
70
80
  * - `contentMaxWidth`: allows configuration of the content max width to be used in components
71
81
  * such as Footnote and Notification to avoid content to stretch width more then the page's width
82
+ * - `forceZIndex`: available on web only, when set to false, sets zIndex on `View` to be `auto`
83
+ * and when true, sets zIndex to be `0` (the default from `react-native-web`)
84
+ * - `enableHelmetSSR`: on Web SSR, allows React Helmet to run during server-side rendering. This should be
85
+ * disabled unless a web app has been specifically configured to stop React Helmet accumulating
86
+ * instances (which may cause a memory leak). See React Helmet's docs: https://github.com/nfl/react-helmet
72
87
  */
73
88
  themeOptions: _propTypes.default.shape({
74
89
  forceAbsoluteFontSizing: _propTypes.default.bool,
90
+ forceZIndex: _propTypes.default.bool,
91
+ enableHelmetSSR: _propTypes.default.bool,
75
92
  contentMaxWidth: _responsiveProps.default.getTypeOptionallyByViewport(_propTypes.default.number)
76
93
  })
77
94
  };