@telus-uds/components-base 1.6.0 → 1.7.1

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 (48) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/.turbo/turbo-lint.log +13 -13
  3. package/CHANGELOG.json +72 -1
  4. package/CHANGELOG.md +33 -2
  5. package/component-docs.json +60 -24
  6. package/generate-component-docs.js +20 -7
  7. package/lib/Link/TextButton.js +1 -10
  8. package/lib/List/ListItem.js +22 -12
  9. package/lib/Search/Search.js +27 -19
  10. package/lib/TextInput/TextArea.js +1 -1
  11. package/lib/TextInput/TextInput.js +1 -1
  12. package/lib/TextInput/TextInputBase.js +1 -1
  13. package/lib/Typography/Typography.js +12 -10
  14. package/lib/index.js +22 -1
  15. package/lib/utils/input.js +5 -6
  16. package/lib/utils/props/index.js +18 -0
  17. package/lib/utils/props/linkProps.js +3 -7
  18. package/lib/utils/props/textInputProps.js +207 -0
  19. package/lib/utils/props/textProps.js +72 -0
  20. package/lib-module/Link/TextButton.js +1 -10
  21. package/lib-module/List/ListItem.js +22 -12
  22. package/lib-module/Search/Search.js +29 -21
  23. package/lib-module/TextInput/TextArea.js +2 -2
  24. package/lib-module/TextInput/TextInput.js +2 -2
  25. package/lib-module/TextInput/TextInputBase.js +2 -2
  26. package/lib-module/Typography/Typography.js +13 -11
  27. package/lib-module/index.js +1 -1
  28. package/lib-module/utils/input.js +6 -6
  29. package/lib-module/utils/props/index.js +2 -0
  30. package/lib-module/utils/props/linkProps.js +3 -7
  31. package/lib-module/utils/props/textInputProps.js +194 -0
  32. package/lib-module/utils/props/textProps.js +59 -0
  33. package/package.json +1 -1
  34. package/src/Link/TextButton.jsx +1 -19
  35. package/src/List/ListItem.jsx +17 -9
  36. package/src/Search/Search.jsx +33 -21
  37. package/src/TextInput/TextArea.jsx +2 -0
  38. package/src/TextInput/TextInput.jsx +2 -0
  39. package/src/TextInput/TextInputBase.jsx +2 -0
  40. package/src/Typography/Typography.jsx +13 -9
  41. package/src/index.js +4 -1
  42. package/src/utils/input.js +5 -7
  43. package/src/utils/props/index.js +2 -0
  44. package/src/utils/props/linkProps.js +3 -6
  45. package/src/utils/props/textInputProps.js +178 -0
  46. package/src/utils/props/textProps.js +58 -0
  47. package/stories/Search/Search.stories.jsx +49 -2
  48. package/__tests__/Link/LinkBase.test.jsx +0 -22
package/lib/index.js CHANGED
@@ -51,7 +51,10 @@ var _exportNames = {
51
51
  useTheme: true,
52
52
  useSetTheme: true,
53
53
  useThemeTokens: true,
54
- getThemeTokens: true
54
+ getThemeTokens: true,
55
+ applyOuterBorder: true,
56
+ applyTextStyles: true,
57
+ applyShadowToken: true
55
58
  };
56
59
  Object.defineProperty(exports, "A11yText", {
57
60
  enumerable: true,
@@ -341,6 +344,24 @@ Object.defineProperty(exports, "getThemeTokens", {
341
344
  return _ThemeProvider.getThemeTokens;
342
345
  }
343
346
  });
347
+ Object.defineProperty(exports, "applyOuterBorder", {
348
+ enumerable: true,
349
+ get: function () {
350
+ return _ThemeProvider.applyOuterBorder;
351
+ }
352
+ });
353
+ Object.defineProperty(exports, "applyTextStyles", {
354
+ enumerable: true,
355
+ get: function () {
356
+ return _ThemeProvider.applyTextStyles;
357
+ }
358
+ });
359
+ Object.defineProperty(exports, "applyShadowToken", {
360
+ enumerable: true,
361
+ get: function () {
362
+ return _ThemeProvider.applyShadowToken;
363
+ }
364
+ });
344
365
 
345
366
  var _A11yText = _interopRequireDefault(require("./A11yText"));
346
367
 
@@ -7,6 +7,9 @@ exports.useMultipleInputValues = exports.useInputValue = void 0;
7
7
 
8
8
  var _react = require("react");
9
9
 
10
+ /**
11
+ * @typedef {import('react').SyntheticEvent} Event
12
+ */
10
13
  const pluralHooks = ['useMultipleInputValues'];
11
14
 
12
15
  const validateProps = ({
@@ -64,11 +67,9 @@ Consumers of this hook must be one of:
64
67
  *
65
68
  * @param {string} hookName - optional, used for tailoring error messages
66
69
  *
67
- * @typedef {(oldValue: string|number|null) => string|number|null} UpdaterFunction - `setValue` takes a value or
68
- * a function returning a new value from the old value
69
70
  * @returns {{
70
71
  * currentValue: string|number|null
71
- * setValue: (newValue: string|number|null|UpdaterFunction) => void
72
+ * setValue: (newValue: string|number|null|(oldValue: string|number) => string|number, event: Event) => void
72
73
  * resetValue: () => void
73
74
  * isControlled: bool
74
75
  * }}
@@ -130,12 +131,10 @@ const useInputValue = (props = {}, hookName = 'useInputValue') => {
130
131
  *
131
132
  * @param {string} componentName - optional, used in error messages
132
133
  *
133
- * @typedef {(oldValues: string[]|number[]) => string[]|number[]} UpdaterFunction - `setValues` takes values or
134
- * a function returning new values from old values
135
134
  * @returns {{
136
135
  * currentValues: any
137
136
  * resetValues: () => void
138
- * setValues: (newValues: string[]|number[]|UpdaterFunction) => void
137
+ * setValues: (newValues: string[]|number[]|(oldValues: string[]|number[]) => string[]|number[], event: Event) => void
139
138
  * toggleOneValue: (value: string|number) => void
140
139
  * unsetValues: () => void
141
140
  * }}
@@ -17,6 +17,8 @@ var _exportNames = {
17
17
  responsiveProps: true,
18
18
  spacingProps: true,
19
19
  selectSystemProps: true,
20
+ textInputProps: true,
21
+ textProps: true,
20
22
  variantProp: true,
21
23
  viewProps: true
22
24
  };
@@ -98,6 +100,18 @@ Object.defineProperty(exports, "selectSystemProps", {
98
100
  return _selectSystemProps.default;
99
101
  }
100
102
  });
103
+ Object.defineProperty(exports, "textInputProps", {
104
+ enumerable: true,
105
+ get: function () {
106
+ return _textInputProps.default;
107
+ }
108
+ });
109
+ Object.defineProperty(exports, "textProps", {
110
+ enumerable: true,
111
+ get: function () {
112
+ return _textProps.default;
113
+ }
114
+ });
101
115
  Object.defineProperty(exports, "variantProp", {
102
116
  enumerable: true,
103
117
  get: function () {
@@ -165,6 +179,10 @@ var _spacingProps = _interopRequireDefault(require("./spacingProps"));
165
179
 
166
180
  var _selectSystemProps = _interopRequireDefault(require("./selectSystemProps"));
167
181
 
182
+ var _textInputProps = _interopRequireDefault(require("./textInputProps"));
183
+
184
+ var _textProps = _interopRequireDefault(require("./textProps"));
185
+
168
186
  var _variantProp = _interopRequireDefault(require("./variantProp"));
169
187
 
170
188
  var _viewProps = _interopRequireDefault(require("./viewProps"));
@@ -38,20 +38,16 @@ var _default = {
38
38
  select: (0, _getPropSelector.default)(linkPropTypes),
39
39
 
40
40
  /**
41
- * Turn hrefs into press handlers on Native and throw if not given `onPress` or `href`.
41
+ * Turn hrefs into press handlers that open links on Native.
42
42
  *
43
43
  * @param {({ onPress?: () => void, href?: string })}
44
- * @returns {(() => void)|undefined} Returns a press handler, or undefined on web if href
45
- * string is provided. Expects calling component to use href string on web (e.g. in `<a>`).
44
+ * @returns {(() => void)|undefined} Returns a press handler, or undefined on web if no press
45
+ * handler is provided (expects calling component to render as `<a href={href}>` on web).
46
46
  */
47
47
  handleHref: ({
48
48
  onPress,
49
49
  href
50
50
  }) => {
51
- if (!href && !onPress) {
52
- throw new Error('handleHref requires either href or onPress');
53
- }
54
-
55
51
  return _Platform.default.select({
56
52
  web: onPress,
57
53
  default: (...args) => {
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _propTypes = _interopRequireDefault(require("prop-types"));
9
+
10
+ var _Platform = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Platform"));
11
+
12
+ var _getPropSelector = _interopRequireDefault(require("./getPropSelector"));
13
+
14
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
+
16
+ // This file contains common props for components that render a React Native TextInput
17
+ // It excludes interaction handler functions which are in `./handlerProps.js`
18
+
19
+ /**
20
+ * TextInput (web and native) supports some common React Native props
21
+ * shared with React Native's Text component.
22
+ */
23
+ const textProps = {
24
+ maxFontSizeMultiplier: _propTypes.default.number,
25
+ nativeId: _propTypes.default.string,
26
+ onLayout: _propTypes.default.func
27
+ };
28
+ /**
29
+ * UDS text inputs accept props related to UDS's useInputValue hook
30
+ */
31
+
32
+ const inputValueProps = {
33
+ value: _propTypes.default.string,
34
+ initialValue: _propTypes.default.string,
35
+ readOnly: _propTypes.default.bool,
36
+ inactive: _propTypes.default.bool
37
+ };
38
+ /**
39
+ * This collection adds props that can be passed through to both React Native's
40
+ * and React Native Web's implementations of the React Native TextInput component.
41
+ */
42
+
43
+ const crossPlatform = { ...textProps,
44
+ ...inputValueProps,
45
+
46
+ /**
47
+ * Web and Android; 'off' disables device autocomplete, other strings are platform-specific.
48
+ * Valid values on Native: https://reactnative.dev/docs/textinput#autocomplete-android
49
+ * Valid values on Web: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete
50
+ */
51
+ autoComplete: _propTypes.default.string,
52
+
53
+ /**
54
+ * On Native, default is `true`, passing `false` disables autoCorrect.
55
+ * On web, only supported by Safari and expects "on" or "off" strings.
56
+ */
57
+ autoCorrect: _propTypes.default.oneOf([true, false, 'on', 'off']),
58
+
59
+ /**
60
+ * Focuses the element on mount. On Web, only the first form element with autoFocus is focussed.
61
+ */
62
+ autoFocus: _propTypes.default.bool,
63
+
64
+ /**
65
+ * Default is `true` for single line, `false` for multi-line
66
+ */
67
+ blurOnSubmit: _propTypes.default.bool,
68
+
69
+ /**
70
+ * iOS and Web only, no effect on Android
71
+ */
72
+ clearTextOnFocus: _propTypes.default.bool,
73
+
74
+ /**
75
+ * Default is `true`. On web, this works by mapping to input's `readonly` attribute
76
+ */
77
+ editable: _propTypes.default.bool,
78
+
79
+ /**
80
+ * See documentation for allowed values (varies between Web, Android and iOS) and important notes:
81
+ * - Native: https://reactnative.dev/docs/textinput#keyboardtype
82
+ * - Web: equivalent to `inputmode` but see https://necolas.github.io/react-native-web/docs/text-input/
83
+ */
84
+ keyboardType: _propTypes.default.string,
85
+
86
+ /**
87
+ * Uses native tools (no flicker) to cap the maximum number of characters.
88
+ * On Web, works via `maxlength` attr.
89
+ */
90
+ maxLength: _propTypes.default.number,
91
+
92
+ /**
93
+ * If passed as true, the text input can be multiple lines.
94
+ *
95
+ * > It is important to note that this aligns the text to the top on iOS, and centers it on Android.
96
+ * > Use with textAlignVertical set to top for the same behavior in both platforms.
97
+ */
98
+ multiline: _propTypes.default.bool,
99
+
100
+ /**
101
+ * Web and Android only, requires `multiline` to be `true`.
102
+ */
103
+ numberOfLines: _propTypes.default.number,
104
+
105
+ /**
106
+ * Text to display when no value set.
107
+ * Accesibility guidelines recommend using labels to describe the input and using
108
+ * placeholders rarely and sparingly to prompt a particular format.
109
+ */
110
+ placeholder: _propTypes.default.string,
111
+
112
+ /**
113
+ * Sets placeholder colour. On Web, uses `::placeholder { color: ... }` selector.
114
+ */
115
+ placeholderTextColor: _propTypes.default.string,
116
+
117
+ /**
118
+ * One of a subset of platform-specific options that controls labelling and presentation
119
+ * in on-screen keyboards and accessibility tools. Uses `enterkeyhint` attr on Web.
120
+ *
121
+ * 'done', 'go', 'next', 'search', and 'send' are available for Web, Android and iOS.
122
+ */
123
+ returnKeyType: _propTypes.default.string,
124
+
125
+ /**
126
+ * Obscures passwords and similar. Equivalent to type="password" on Web.
127
+ * Does not work if multiline is true.
128
+ */
129
+ secureTextEntry: _propTypes.default.bool,
130
+
131
+ /**
132
+ * If true, all text will automatically be selected on focus.
133
+ */
134
+ selectTextOnFocus: _propTypes.default.bool,
135
+
136
+ /**
137
+ * Web and iOS. On iOS, default inherits from `autoCorrect`.
138
+ * On Web, equivalent to `spellcheck` attr.
139
+ */
140
+ spellCheck: _propTypes.default.bool
141
+ };
142
+ /**
143
+ * These web-only props all control HTML `input` attributes of the same name.
144
+ * Refer to general HTML documentation for more details.
145
+ */
146
+
147
+ const webOnly = {
148
+ disabled: _propTypes.default.bool,
149
+ dir: _propTypes.default.oneOf(['auto', 'ltr', 'rtl']),
150
+ lang: _propTypes.default.string
151
+ };
152
+ /**
153
+ * These props are supported in React Native but not React Native Web.
154
+ *
155
+ * React Native text inputs can be quirky, so a full set of props should be allowed to handle edge cases.
156
+ * Refer to React Native documentation for details, allowed values, and Android/iOS support and versions:
157
+ * https://reactnative.dev/docs/textinput
158
+ *
159
+ * Beware that many React Native text input props apply via complicated logic that chooses a built-in
160
+ * native component based on the values of multiple boolean flags, and may sometimes appear to pick an
161
+ * option that is inappropriate for one flag based on the values of one or more other other flags.
162
+ */
163
+
164
+ const nativeOnly = {
165
+ caretHidden: _propTypes.default.bool,
166
+ clearButtonMode: _propTypes.default.string,
167
+ contextMenuHidden: _propTypes.default.bool,
168
+ dataDetectorTypes: _propTypes.default.string,
169
+ disableFullscreenUI: _propTypes.default.bool,
170
+ enablesReturnKeyAutomatically: _propTypes.default.bool,
171
+ importantForAutofill: _propTypes.default.string,
172
+ inlineImageLeft: _propTypes.default.string,
173
+ keyboardAppearance: _propTypes.default.string,
174
+ returnKeyLabel: _propTypes.default.string,
175
+ rejectResponderTermination: _propTypes.default.bool,
176
+ scrollEnabled: _propTypes.default.bool,
177
+ selection: _propTypes.default.object,
178
+ selectionColor: _propTypes.default.string,
179
+ showSoftInputOnFocus: _propTypes.default.bool,
180
+ textAlign: _propTypes.default.string,
181
+ textContentType: _propTypes.default.string,
182
+ passwordRules: _propTypes.default.string,
183
+ textBreakStrategy: _propTypes.default.string,
184
+ underlineColorAndroid: _propTypes.default.string
185
+ };
186
+ var _default = {
187
+ /**
188
+ * Subset of proptypes that can be passed down to a React Native or React Native Web
189
+ * `TextInput` component. Allow regardless of platform, so cross-platform apps don't warn.
190
+ */
191
+ types: { ...crossPlatform,
192
+ ...webOnly,
193
+ ...nativeOnly
194
+ },
195
+
196
+ /**
197
+ * Filters a props object. Return only platform-appropriate TextInput props, native inputs
198
+ * may throw errors on receiving unknown props.
199
+ */
200
+ select: (0, _getPropSelector.default)({ ...crossPlatform,
201
+ ..._Platform.default.select({
202
+ web: webOnly,
203
+ default: nativeOnly
204
+ })
205
+ })
206
+ };
207
+ exports.default = _default;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _propTypes = _interopRequireDefault(require("prop-types"));
9
+
10
+ var _Platform = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Platform"));
11
+
12
+ var _getPropSelector = _interopRequireDefault(require("./getPropSelector"));
13
+
14
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
+
16
+ // These are the props accepted specifically on React Native (Web) `Text` elements.
17
+ // They are generally concerned with the behaviour of multiline text.
18
+ const crossPlatform = {
19
+ /**
20
+ * Truncates text after this many lines with an ellipsis at the end.
21
+ * On native, ellipsis behaviour may be changed with `ellipsizeMode` prop.
22
+ */
23
+ numberOfLines: _propTypes.default.number,
24
+
25
+ /**
26
+ * Default is true on web and false on native
27
+ */
28
+ selectable: _propTypes.default.bool
29
+ };
30
+ /**
31
+ * See React Native docs for latest details on these.
32
+ * https://reactnative.dev/docs/text
33
+ */
34
+
35
+ const nativeOnly = {
36
+ ellipsizeMode: _propTypes.default.string,
37
+ maxFontSizeMultiplier: _propTypes.default.number,
38
+ minimumFontScale: _propTypes.default.number,
39
+ onTextLayout: _propTypes.default.func,
40
+ suppressHighlighting: _propTypes.default.bool,
41
+ textBreakStrategy: _propTypes.default.string
42
+ };
43
+ /**
44
+ * These set HTML attributes of the same name.
45
+ */
46
+
47
+ const webOnly = {
48
+ dir: _propTypes.default.oneOf(['auto', 'ltr', 'rtl']),
49
+ lang: _propTypes.default.string
50
+ };
51
+ var _default = {
52
+ /**
53
+ * Set of prop types specific to React Native and React Native Web `Text`,
54
+ * which largely revolve around the behaviour of multiline non-pressable text.
55
+ */
56
+ types: { ...crossPlatform,
57
+ ...webOnly,
58
+ ...nativeOnly
59
+ },
60
+
61
+ /**
62
+ * Filters a props object, returning only props specific to `Text` elements
63
+ * on the current platform. Does not include props applicable to `Text` and `View`.
64
+ */
65
+ select: (0, _getPropSelector.default)({ ...crossPlatform,
66
+ ..._Platform.default.select({
67
+ web: webOnly,
68
+ default: nativeOnly
69
+ })
70
+ })
71
+ };
72
+ exports.default = _default;
@@ -1,5 +1,3 @@
1
- var _TextButton$propTypes;
2
-
3
1
  import React, { forwardRef } from 'react';
4
2
  import PropTypes from 'prop-types';
5
3
  import { useThemeTokensCallback } from '../ThemeProvider';
@@ -16,8 +14,6 @@ const TextButton = /*#__PURE__*/forwardRef(({
16
14
  children,
17
15
  variant,
18
16
  tokens,
19
- // TODO: this may need to use `link` role on Web in the case of being passed both `href` and
20
- // `onPress` in an omniplatform app that uses React Navigation's useLinkProps for internal nav.
21
17
  accessibilityRole = 'button',
22
18
  ...linkProps
23
19
  }, ref) => {
@@ -34,10 +30,5 @@ const TextButton = /*#__PURE__*/forwardRef(({
34
30
  TextButton.displayName = 'TextButton';
35
31
  TextButton.propTypes = { ...LinkBase.propTypes,
36
32
  onPress: PropTypes.func.isRequired
37
- }; // Remove incompatible Link prop (if this build includes propTypes)
38
- // TODO: test if this works with web navigation in omniplatform React Navigation
39
- // https://github.com/telus/universal-design-system/issues/665
40
- // eslint-disable-next-line react/forbid-foreign-prop-types
41
-
42
- if ((_TextButton$propTypes = TextButton.propTypes) !== null && _TextButton$propTypes !== void 0 && _TextButton$propTypes.href) delete TextButton.propTypes.href;
33
+ };
43
34
  export default TextButton;
@@ -26,8 +26,7 @@ const selectBulletContainerStyles = ({
26
26
  itemBulletContainerAlign
27
27
  }) => ({
28
28
  width: itemBulletContainerWidth,
29
- alignItems: itemBulletContainerAlign,
30
- justifyContent: itemBulletContainerAlign
29
+ alignItems: itemBulletContainerAlign
31
30
  });
32
31
 
33
32
  const selectItemIconTokens = ({
@@ -38,16 +37,20 @@ const selectItemIconTokens = ({
38
37
  color: itemIconColor
39
38
  });
40
39
 
41
- const selectCommonIconStyles = ({
40
+ const selectSideItemContainerStyles = ({
41
+ listGutter,
42
42
  iconMarginTop
43
43
  }) => ({
44
- marginTop: iconMarginTop
45
- });
44
+ marginTop: iconMarginTop,
45
+ marginRight: listGutter
46
+ }); // Align bullets with the top line of text the same way icons are aligned
46
47
 
47
- const selectSideItemContainerStyles = ({
48
- listGutter
48
+
49
+ const selectBulletPositioningStyles = ({
50
+ itemIconSize
49
51
  }) => ({
50
- marginRight: listGutter
52
+ width: itemIconSize,
53
+ height: itemIconSize
51
54
  });
52
55
 
53
56
  const selectItemStyles = ({
@@ -100,8 +103,8 @@ const ListItem = /*#__PURE__*/forwardRef(({
100
103
  const dividerStyles = selectDividerStyles(themeTokens);
101
104
  const itemBulletContainerStyles = selectBulletContainerStyles(themeTokens);
102
105
  const itemBulletStyles = selectBulletStyles(themeTokens);
106
+ const itemBulletPositioningStyles = selectBulletPositioningStyles(themeTokens);
103
107
  const iconTokens = selectItemIconTokens(themeTokens);
104
- const commonIconStyles = selectCommonIconStyles(themeTokens);
105
108
  const sideItemContainerStyles = selectSideItemContainerStyles(themeTokens);
106
109
  const accessibilityRole = Platform.select({
107
110
  web: 'listitem',
@@ -144,7 +147,7 @@ const ListItem = /*#__PURE__*/forwardRef(({
144
147
 
145
148
  if (icon) {
146
149
  return /*#__PURE__*/_jsx(View, {
147
- style: [sideItemContainerStyles, commonIconStyles],
150
+ style: sideItemContainerStyles,
148
151
  children: /*#__PURE__*/_jsx(IconComponent, {
149
152
  size: iconSize || iconTokens.size,
150
153
  color: iconColor || iconTokens.color
@@ -155,8 +158,11 @@ const ListItem = /*#__PURE__*/forwardRef(({
155
158
  return /*#__PURE__*/_jsx(View, {
156
159
  style: [sideItemContainerStyles, itemBulletContainerStyles],
157
160
  children: /*#__PURE__*/_jsx(View, {
158
- style: itemBulletStyles,
159
- testID: "unordered-item-bullet"
161
+ style: [staticStyles.bulletPositioning, itemBulletPositioningStyles],
162
+ children: /*#__PURE__*/_jsx(View, {
163
+ style: itemBulletStyles,
164
+ testID: "unordered-item-bullet"
165
+ })
160
166
  })
161
167
  });
162
168
  };
@@ -176,6 +182,10 @@ const staticStyles = StyleSheet.create({
176
182
  },
177
183
  wrap: {
178
184
  flex: 1
185
+ },
186
+ bulletPositioning: {
187
+ alignItems: 'center',
188
+ justifyContent: 'center'
179
189
  }
180
190
  });
181
191
  ListItem.propTypes = { ...selectedSystemPropTypes,
@@ -1,9 +1,9 @@
1
- import React, { forwardRef, useState } from 'react';
1
+ import React, { forwardRef } from 'react';
2
2
  import View from "react-native-web/dist/exports/View";
3
3
  import StyleSheet from "react-native-web/dist/exports/StyleSheet";
4
4
  import PropTypes from 'prop-types';
5
5
  import { useThemeTokens, useThemeTokensCallback } from '../ThemeProvider';
6
- import { a11yProps, getTokensPropType, selectSystemProps, selectTokens, useSpacingScale, variantProp, viewProps } from '../utils';
6
+ import { a11yProps, getTokensPropType, selectSystemProps, selectTokens, useInputValue, useSpacingScale, textInputHandlerProps, textInputProps, variantProp, viewProps } from '../utils';
7
7
  import TextInputBase from '../TextInput/TextInputBase';
8
8
  import ButtonBase from '../Button/ButtonBase';
9
9
  import StackView from '../StackView';
@@ -11,7 +11,8 @@ import useCopy from '../utils/useCopy';
11
11
  import dictionary from './dictionary';
12
12
  import { jsx as _jsx } from "react/jsx-runtime";
13
13
  import { jsxs as _jsxs } from "react/jsx-runtime";
14
- const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
14
+ const [selectContainerProps, selectedContainerPropTypes] = selectSystemProps([a11yProps, viewProps]);
15
+ const [selectInputProps, selectedInputPropTypes] = selectSystemProps([textInputHandlerProps, textInputProps]);
15
16
 
16
17
  const selectInputTokens = ({
17
18
  searchTokens,
@@ -66,8 +67,9 @@ const selectIconTokens = ({
66
67
 
67
68
 
68
69
  const Search = /*#__PURE__*/forwardRef(({
69
- initialValue = '',
70
- placeholder = 'Search',
70
+ initialValue,
71
+ value,
72
+ placeholder,
71
73
  inactive,
72
74
  onChange,
73
75
  onSubmit,
@@ -78,7 +80,14 @@ const Search = /*#__PURE__*/forwardRef(({
78
80
  variant,
79
81
  ...rest
80
82
  }, ref) => {
81
- const [value, setValue] = useState(initialValue);
83
+ const {
84
+ currentValue = '',
85
+ setValue
86
+ } = useInputValue({
87
+ value,
88
+ initialValue,
89
+ onChange
90
+ });
82
91
  const themeTokens = useThemeTokens('Search', tokens, variant);
83
92
  const buttonTokens = useThemeTokens('SearchButton', tokens, variant);
84
93
  const getThemeTokens = useThemeTokensCallback('Search', tokens, variant);
@@ -99,26 +108,24 @@ const Search = /*#__PURE__*/forwardRef(({
99
108
 
100
109
  const handleSubmit = event => {
101
110
  if (onSubmit !== undefined) {
102
- onSubmit(value, event);
111
+ onSubmit(currentValue, event);
103
112
  }
104
113
  };
105
114
 
106
- const handleChange = (currentValue, event) => {
107
- setValue(currentValue, event);
108
- if (onChange !== undefined) onChange(currentValue, event);
109
- };
110
-
111
115
  const handleClear = event => {
112
116
  setValue('', event);
113
117
  if (onClear !== undefined) onClear('', event);
114
- if (onChange !== undefined) onChange('', event);
115
118
  };
116
119
 
117
- const isEmpty = value === '';
120
+ const isEmpty = currentValue === ''; // Accessibility label should always be present and correctly localised
121
+
122
+ const a11yLabelText = accessibilityLabel || getCopy('accessibilityLabel'); // Placeholder is optional and may be unset by passing an empty string
123
+
124
+ const placeholderText = placeholder ?? a11yLabelText;
118
125
  return /*#__PURE__*/_jsxs(View, {
119
126
  style: staticStyles.container,
120
- ...selectProps(rest),
121
- children: [/*#__PURE__*/_jsx(TextInputBase, {
127
+ ...selectContainerProps(rest),
128
+ children: [/*#__PURE__*/_jsx(TextInputBase, { ...selectInputProps(rest),
122
129
  ref: ref,
123
130
  tokens: appearances => selectInputTokens({
124
131
  searchTokens: getThemeTokens(appearances),
@@ -126,15 +133,15 @@ const Search = /*#__PURE__*/forwardRef(({
126
133
  buttonsGapSize,
127
134
  isEmpty
128
135
  }),
129
- placeholder: placeholder,
136
+ placeholder: placeholderText,
130
137
  placeholderTextColor: placeholderColor,
131
138
  inactive: inactive,
132
139
  enablesReturnKeyAutomatically: true,
133
140
  returnKeyType: "search",
134
- value: value,
135
- onChange: handleChange,
141
+ value: currentValue,
142
+ onChange: setValue,
136
143
  onSubmitEditing: handleSubmit,
137
- accessibilityLabel: accessibilityLabel || getCopy('accessibilityLabel')
144
+ accessibilityLabel: a11yLabelText
138
145
  }), /*#__PURE__*/_jsx(View, {
139
146
  style: [staticStyles.iconsContainer, selectIconsContainerStyle(themeTokens)],
140
147
  children: /*#__PURE__*/_jsxs(StackView, {
@@ -166,7 +173,8 @@ const Search = /*#__PURE__*/forwardRef(({
166
173
  });
167
174
  });
168
175
  Search.displayName = 'Search';
169
- Search.propTypes = { ...selectedSystemPropTypes,
176
+ Search.propTypes = { ...selectedContainerPropTypes,
177
+ ...selectedInputPropTypes,
170
178
 
171
179
  /**
172
180
  * Use this to set the initial value of the search input.
@@ -1,12 +1,12 @@
1
1
  import React, { forwardRef, useState } from 'react';
2
2
  import Platform from "react-native-web/dist/exports/Platform";
3
- import { a11yProps, focusHandlerProps, getTokensPropType, inputSupportsProps, selectSystemProps, textInputHandlerProps, variantProp, viewProps } from '../utils';
3
+ import { a11yProps, focusHandlerProps, getTokensPropType, inputSupportsProps, selectSystemProps, textInputHandlerProps, textInputProps, variantProp, viewProps } from '../utils';
4
4
  import InputSupports from '../InputSupports';
5
5
  import TextInputBase from './TextInputBase';
6
6
  import { useThemeTokens } from '../ThemeProvider';
7
7
  import textInputPropTypes from './propTypes';
8
8
  import { jsx as _jsx } from "react/jsx-runtime";
9
- const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, inputSupportsProps, textInputHandlerProps, viewProps]);
9
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, inputSupportsProps, textInputHandlerProps, textInputProps, viewProps]);
10
10
  /**
11
11
  * Use to collect long-form information such as product feedback or support queries.
12
12
  * Due to React Native's implementation of `TextInput` it's not possible to access the current value by passing a ref.
@@ -1,11 +1,11 @@
1
1
  import React, { forwardRef } from 'react';
2
2
  import Platform from "react-native-web/dist/exports/Platform";
3
- import { a11yProps, focusHandlerProps, getTokensPropType, inputSupportsProps, selectSystemProps, textInputHandlerProps, variantProp, viewProps } from '../utils';
3
+ import { a11yProps, focusHandlerProps, getTokensPropType, inputSupportsProps, selectSystemProps, textInputHandlerProps, textInputProps, variantProp, viewProps } from '../utils';
4
4
  import InputSupports from '../InputSupports';
5
5
  import TextInputBase from './TextInputBase';
6
6
  import textInputPropTypes from './propTypes';
7
7
  import { jsx as _jsx } from "react/jsx-runtime";
8
- const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, inputSupportsProps, textInputHandlerProps, viewProps]);
8
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, inputSupportsProps, textInputHandlerProps, textInputProps, viewProps]);
9
9
  /**
10
10
  * A basic text input component. Use in forms or individually to receive user's input.
11
11
  * Due to React Native's implementation of `TextInput` it's not possible to access the current value by passing a ref.
@@ -5,10 +5,10 @@ import NativeTextInput from "react-native-web/dist/exports/TextInput";
5
5
  import View from "react-native-web/dist/exports/View";
6
6
  import PropTypes from 'prop-types';
7
7
  import { applyTextStyles, useThemeTokens, applyOuterBorder } from '../ThemeProvider';
8
- import { a11yProps, getTokensPropType, selectSystemProps, textInputHandlerProps, useInputValue, variantProp, viewProps } from '../utils';
8
+ import { a11yProps, getTokensPropType, selectSystemProps, textInputHandlerProps, textInputProps, useInputValue, variantProp, viewProps } from '../utils';
9
9
  import { jsx as _jsx } from "react/jsx-runtime";
10
10
  import { jsxs as _jsxs } from "react/jsx-runtime";
11
- const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, textInputHandlerProps, viewProps]);
11
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, textInputHandlerProps, textInputProps, viewProps]);
12
12
 
13
13
  const selectInputStyles = ({
14
14
  backgroundColor,