@telus-uds/components-base 2.2.0 → 2.4.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 (46) hide show
  1. package/CHANGELOG.md +36 -2
  2. package/lib/Autocomplete/Autocomplete.js +8 -3
  3. package/lib/Card/CardBase.js +7 -1
  4. package/lib/Card/PressableCardBase.js +1 -1
  5. package/lib/FileUpload/FileUpload.js +57 -22
  6. package/lib/FileUpload/dictionary.js +6 -2
  7. package/lib/InputLabel/InputLabel.js +36 -2
  8. package/lib/InputSupports/InputSupports.js +31 -8
  9. package/lib/InputSupports/dictionary.js +12 -0
  10. package/lib/InputSupports/useInputSupports.js +12 -3
  11. package/lib/Link/LinkBase.js +17 -15
  12. package/lib/Listbox/ListboxOverlay.js +6 -3
  13. package/lib/Modal/Modal.js +2 -2
  14. package/lib/MultiSelectFilter/MultiSelectFilter.js +54 -41
  15. package/lib/Notification/Notification.js +7 -3
  16. package/lib/Search/Search.js +39 -8
  17. package/lib/Select/Picker.native.js +8 -4
  18. package/lib/Select/constants.js +4 -2
  19. package/lib/StepTracker/StepTracker.js +10 -3
  20. package/lib/TextInput/TextArea.js +7 -6
  21. package/lib/TextInput/TextInput.js +7 -6
  22. package/lib/TextInput/TextInputBase.js +48 -14
  23. package/lib/utils/props/inputSupportsProps.js +15 -3
  24. package/package.json +3 -3
  25. package/src/Autocomplete/Autocomplete.jsx +9 -2
  26. package/src/Card/CardBase.jsx +5 -2
  27. package/src/Card/PressableCardBase.jsx +12 -1
  28. package/src/FileUpload/FileUpload.jsx +71 -28
  29. package/src/FileUpload/dictionary.js +6 -2
  30. package/src/InputLabel/InputLabel.jsx +39 -2
  31. package/src/InputSupports/InputSupports.jsx +33 -7
  32. package/src/InputSupports/dictionary.js +12 -0
  33. package/src/InputSupports/useInputSupports.js +24 -3
  34. package/src/Link/LinkBase.jsx +17 -15
  35. package/src/Listbox/ListboxOverlay.jsx +5 -3
  36. package/src/Modal/Modal.jsx +1 -1
  37. package/src/MultiSelectFilter/MultiSelectFilter.jsx +55 -27
  38. package/src/Notification/Notification.jsx +9 -3
  39. package/src/Search/Search.jsx +52 -24
  40. package/src/Select/Picker.native.jsx +10 -4
  41. package/src/Select/constants.js +4 -1
  42. package/src/StepTracker/StepTracker.jsx +16 -5
  43. package/src/TextInput/TextArea.jsx +12 -5
  44. package/src/TextInput/TextInput.jsx +13 -6
  45. package/src/TextInput/TextInputBase.jsx +57 -10
  46. package/src/utils/props/inputSupportsProps.js +15 -3
@@ -25,30 +25,14 @@ const {
25
25
  Col,
26
26
  Row
27
27
  } = FlexGrid;
28
- const selectSubTitleTokens = _ref => {
29
- let {
30
- subtitleColor
31
- } = _ref;
32
- return {
33
- color: subtitleColor
34
- };
35
- };
36
- const selectDividerTokens = _ref2 => {
37
- let {
38
- dividerColor
39
- } = _ref2;
40
- return {
41
- color: dividerColor
42
- };
43
- };
44
- const selectHeaderTokens = _ref3 => {
28
+ const selectHeaderTokens = _ref => {
45
29
  let {
46
30
  contentMarginLeft,
47
31
  contentMarginRight,
48
32
  contentMarginTop,
49
33
  contentPaddingLeft,
50
34
  contentPaddingRight
51
- } = _ref3;
35
+ } = _ref;
52
36
  return {
53
37
  marginLeft: contentMarginLeft,
54
38
  marginRight: contentMarginRight,
@@ -58,14 +42,14 @@ const selectHeaderTokens = _ref3 => {
58
42
  flexGrow: 1
59
43
  };
60
44
  };
61
- const selectControlsTokens = _ref4 => {
45
+ const selectControlsTokens = _ref2 => {
62
46
  let {
63
47
  contentMarginBottom,
64
48
  contentMarginLeft,
65
49
  contentMarginRight,
66
50
  contentPaddingLeft,
67
51
  contentPaddingRight
68
- } = _ref4;
52
+ } = _ref2;
69
53
  return {
70
54
  marginBottom: contentMarginBottom,
71
55
  marginLeft: contentMarginLeft,
@@ -80,7 +64,7 @@ const selectContainerStyle = (windowHeight, windowWidth) => ({
80
64
  });
81
65
  const TOTAL_COLUMNS = 12;
82
66
  const MAX_ITEMS_THRESHOLD = 12;
83
- const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
67
+ const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
84
68
  let {
85
69
  label,
86
70
  subtitle,
@@ -102,7 +86,7 @@ const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
102
86
  rowLimit = 12,
103
87
  dictionary = defaultDictionary,
104
88
  ...rest
105
- } = _ref5;
89
+ } = _ref3;
106
90
  const viewport = useViewport();
107
91
  const {
108
92
  currentValues,
@@ -117,23 +101,6 @@ const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
117
101
  const [isOpen, setIsOpen] = React.useState(false);
118
102
  const [checkedIds, setCheckedIds] = React.useState(currentValues ?? []);
119
103
  const [maxWidth, setMaxWidth] = React.useState(false);
120
- const themeTokens = useThemeTokens('ButtonDropdown', tokens, variant);
121
- const getItemTokens = useThemeTokensCallback('ButtonDropdown', tokens, variant);
122
- const getButtonTokens = buttonState => selectTokens('Button', getItemTokens(buttonState));
123
- const getCopy = useCopy({
124
- dictionary,
125
- copy
126
- });
127
- const colSizeNotMobile = items.length > rowLimit ? 2 : 1;
128
- const colSize = viewport !== 'xs' ? colSizeNotMobile : 1;
129
- const itemsLengthNotMobile = items.length > 24 ? items.length / 2 : rowLimit;
130
- const isSelected = currentValues.length > 0;
131
- const rowLength = viewport !== 'xs' ? itemsLengthNotMobile : items.length;
132
- React.useEffect(() => {
133
- if (colSize === 1) return setMaxWidth(false);
134
- return colSize === 2 && setMaxWidth(true);
135
- }, [colSize]);
136
- React.useEffect(() => setCheckedIds(currentValues ?? []), [currentValues]);
137
104
  const {
138
105
  headerFontColor,
139
106
  headerFontSize,
@@ -147,6 +114,20 @@ const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
147
114
  subHeaderLineHeight,
148
115
  minHeight,
149
116
  minWidth,
117
+ labelFontName,
118
+ labelFontSize,
119
+ labelFontWeight,
120
+ labelColor,
121
+ labelLineHeight,
122
+ labelPaddingTop,
123
+ labelPaddingBottom,
124
+ labelPaddingLeft,
125
+ labelPaddingRight,
126
+ buttonBorderColor,
127
+ buttonIconSize,
128
+ buttonIconPadding,
129
+ subtitleColor,
130
+ dividerColor,
150
131
  ...restTokens
151
132
  } = useThemeTokens('MultiSelectFilter', tokens, {
152
133
  ...variant,
@@ -155,6 +136,36 @@ const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
155
136
  }, {
156
137
  viewport
157
138
  });
139
+ const dropdownTokens = {
140
+ borderColor: buttonBorderColor,
141
+ iconSize: buttonIconSize,
142
+ iconPadding: buttonIconPadding,
143
+ lineHeight: labelLineHeight,
144
+ fontName: labelFontName,
145
+ fontSize: labelFontSize,
146
+ fontWeight: labelFontWeight,
147
+ color: labelColor,
148
+ paddingTop: labelPaddingTop,
149
+ paddingBottom: labelPaddingBottom,
150
+ paddingLeft: labelPaddingLeft,
151
+ paddingRight: labelPaddingRight
152
+ };
153
+ const getButtonDropdownTokens = useThemeTokensCallback('ButtonDropdown', dropdownTokens, variant);
154
+ const getButtonTokens = buttonState => selectTokens('ButtonDropdown', getButtonDropdownTokens(buttonState));
155
+ const getCopy = useCopy({
156
+ dictionary,
157
+ copy
158
+ });
159
+ const colSizeNotMobile = items.length > rowLimit ? 2 : 1;
160
+ const colSize = viewport !== 'xs' ? colSizeNotMobile : 1;
161
+ const itemsLengthNotMobile = items.length > 24 ? items.length / 2 : rowLimit;
162
+ const isSelected = currentValues.length > 0;
163
+ const rowLength = viewport !== 'xs' ? itemsLengthNotMobile : items.length;
164
+ React.useEffect(() => {
165
+ if (colSize === 1) return setMaxWidth(false);
166
+ return colSize === 2 && setMaxWidth(true);
167
+ }, [colSize]);
168
+ React.useEffect(() => setCheckedIds(currentValues ?? []), [currentValues]);
158
169
  const uniqueFields = ['id', 'label'];
159
170
  if (!containUniqueFields(items, uniqueFields)) {
160
171
  throw new Error(`MultiSelectFilter items must have unique ${uniqueFields.join(', ')}`);
@@ -213,7 +224,7 @@ const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
213
224
  const subeHeaderStyles = applyTextStyles({
214
225
  fontSize: subHeaderFontSize,
215
226
  fontWeight: subHeaderFontWeight,
216
- fontColor: selectSubTitleTokens(themeTokens)
227
+ fontColor: subtitleColor
217
228
  });
218
229
  const {
219
230
  overlaidPosition,
@@ -299,7 +310,9 @@ const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
299
310
  });
300
311
  const controlsContent = /*#__PURE__*/_jsxs(_Fragment, {
301
312
  children: [isScrolling ? /*#__PURE__*/_jsx(Divider, {
302
- tokens: selectDividerTokens(themeTokens),
313
+ tokens: {
314
+ color: dividerColor
315
+ },
303
316
  space: 4
304
317
  }) : /*#__PURE__*/_jsx(Spacer, {
305
318
  space: 4
@@ -274,6 +274,7 @@ const getDefaultStyles = (themeTokens, themeOptions, maxWidth, dismissible, view
274
274
  * Show system notifications at the top of the page, below the navigation, and expands the full-width of the viewport
275
275
  */
276
276
  const Notification = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
277
+ var _variant$style;
277
278
  let {
278
279
  children,
279
280
  system,
@@ -290,6 +291,9 @@ const Notification = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
290
291
  dictionary,
291
292
  copy
292
293
  });
294
+
295
+ // TODO: Remove this once the system style variant is deprecated
296
+ const isSystemEnabled = system || (variant === null || variant === void 0 || (_variant$style = variant.style) === null || _variant$style === void 0 ? void 0 : _variant$style.includes('system'));
293
297
  const {
294
298
  themeOptions
295
299
  } = useTheme();
@@ -298,7 +302,7 @@ const Notification = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
298
302
  } = themeOptions;
299
303
  const useTokens = enableMediaQueryStyleSheet ? useResponsiveThemeTokens : useThemeTokens;
300
304
  const themeTokens = useTokens('Notification', tokens, variant, {
301
- system,
305
+ system: isSystemEnabled,
302
306
  viewport
303
307
  });
304
308
  const maxWidth = useResponsiveProp(themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.contentMaxWidth);
@@ -323,9 +327,9 @@ const Notification = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
323
327
  selectDismissIconPropsIds: {}
324
328
  });
325
329
  if (enableMediaQueryStyleSheet) {
326
- notificationComponentRef.current = getMediaQueryStyles(themeTokens, themeOptions, mediaIdsRef, dismissible, viewport, system);
330
+ notificationComponentRef.current = getMediaQueryStyles(themeTokens, themeOptions, mediaIdsRef, dismissible, viewport, isSystemEnabled);
327
331
  } else {
328
- notificationComponentRef.current = getDefaultStyles(themeTokens, themeOptions, maxWidth, dismissible, viewport, system);
332
+ notificationComponentRef.current = getDefaultStyles(themeTokens, themeOptions, maxWidth, dismissible, viewport, isSystemEnabled);
329
333
  }
330
334
  if (isDismissed) {
331
335
  return null;
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import View from "react-native-web/dist/exports/View";
3
+ import Platform from "react-native-web/dist/exports/Platform";
3
4
  import PropTypes from 'prop-types';
4
5
  import { useThemeTokens, useThemeTokensCallback } from '../ThemeProvider';
5
6
  import { a11yProps, getTokensPropType, selectSystemProps, selectTokens, useInputValue, useSpacingScale, textInputHandlerProps, textInputProps, variantProp, viewProps, contentfulProps } from '../utils';
@@ -7,6 +8,7 @@ import TextInputBase from '../TextInput/TextInputBase';
7
8
  import ButtonBase from '../Button/ButtonBase';
8
9
  import useCopy from '../utils/useCopy';
9
10
  import dictionary from './dictionary';
11
+ import Icon from '../Icon';
10
12
  import { jsx as _jsx } from "react/jsx-runtime";
11
13
  const [selectContainerProps, selectedContainerPropTypes] = selectSystemProps([a11yProps, viewProps, contentfulProps]);
12
14
  const [selectInputProps, selectedInputPropTypes] = selectSystemProps([textInputHandlerProps, textInputProps]);
@@ -33,7 +35,7 @@ const selectInputTokens = _ref => {
33
35
  paddingRight: paddingWithButtons
34
36
  };
35
37
  };
36
- const selectButtonTokens = tokens => selectTokens('Button', tokens);
38
+ const selectButtonTokens = tokens => selectTokens('SearchButton', tokens);
37
39
  const selectIconTokens = _ref2 => {
38
40
  let {
39
41
  iconSize,
@@ -44,6 +46,26 @@ const selectIconTokens = _ref2 => {
44
46
  size: iconSize
45
47
  };
46
48
  };
49
+ const selectBorderTokens = _ref3 => {
50
+ let {
51
+ borderWidth,
52
+ mobileBorderWidth,
53
+ ...tokens
54
+ } = _ref3;
55
+ return {
56
+ borderWidth: Platform.OS === 'web' ? borderWidth : mobileBorderWidth,
57
+ ...tokens
58
+ };
59
+ };
60
+ const modifyButtonTokens = tokens => {
61
+ const modifiedTokens = {
62
+ ...tokens
63
+ };
64
+ if (Platform.OS !== 'web') {
65
+ modifiedTokens.backgroundColor = tokens.mobileBackgroundColor;
66
+ }
67
+ return modifiedTokens;
68
+ };
47
69
 
48
70
  /**
49
71
  * The `Search` component is a combination of a `TextInput` and 2 different kinds of custom buttons.
@@ -58,7 +80,7 @@ const selectIconTokens = _ref2 => {
58
80
  * Use the following props to supply additional accessibility labels for the input - `accessibilityLabel`,
59
81
  * clear button - `clearButtonAccessibilityLabel`, and submit button - `submitButtonAccessibilityLabel`.
60
82
  */
61
- const Search = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
83
+ const Search = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
62
84
  let {
63
85
  initialValue,
64
86
  value,
@@ -73,9 +95,10 @@ const Search = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
73
95
  tokens,
74
96
  variant,
75
97
  nativeSubmitBtnID,
98
+ searchIconPosition = 'right',
76
99
  dataSet,
77
100
  ...rest
78
- } = _ref3;
101
+ } = _ref4;
79
102
  const {
80
103
  currentValue = '',
81
104
  setValue
@@ -139,8 +162,8 @@ const Search = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
139
162
  testID: testID,
140
163
  ...selectInputProps(rest),
141
164
  ref: ref,
142
- tokens: appearances => selectInputTokens({
143
- searchTokens: getThemeTokens(appearances),
165
+ tokens: pressableStates => selectInputTokens({
166
+ searchTokens: selectBorderTokens(getThemeTokens(pressableStates)),
144
167
  buttonTokens,
145
168
  buttonsGapSize,
146
169
  isEmpty
@@ -155,16 +178,17 @@ const Search = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
155
178
  onSubmitEditing: handleSubmit,
156
179
  onFocus: handleFocus,
157
180
  accessibilityLabel: a11yLabelText,
181
+ direction: searchIconPosition,
158
182
  buttons: [ClearButtonIcon && !isEmpty && /*#__PURE__*/_jsx(ButtonBase, {
159
183
  accessibilityLabel: getCopy('clearButtonAccessibilityLabel'),
160
184
  accessibilityRole: "button",
161
185
  inactive: inactive,
162
186
  onPress: handleClear,
163
- tokens: appearances => selectButtonTokens(getButtonTokens(appearances)),
187
+ tokens: pressableStates => modifyButtonTokens(selectButtonTokens(getButtonTokens(pressableStates))),
164
188
  children: buttonState => /*#__PURE__*/_jsx(ClearButtonIcon, {
165
189
  ...selectIconTokens(getButtonTokens(buttonState))
166
190
  })
167
- }, "clear"), SubmitButtonIcon && /*#__PURE__*/_jsx(ButtonBase, {
191
+ }, "clear"), SubmitButtonIcon && (searchIconPosition === 'right' ? /*#__PURE__*/_jsx(ButtonBase, {
168
192
  accessibilityLabel: getCopy('submitButtonAccessibilityLabel'),
169
193
  accessibilityRole: "button",
170
194
  inactive: inactive,
@@ -180,7 +204,14 @@ const Search = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
180
204
  priority: 'high'
181
205
  }))
182
206
  })
183
- }, "submit")]
207
+ }, "submit-right") : /*#__PURE__*/_jsx(Icon, {
208
+ icon: SubmitButtonIcon,
209
+ testID: "iconLeft",
210
+ tokens: {
211
+ color: themeTokens.iconLeftColor,
212
+ size: themeTokens.iconLeftSize
213
+ }
214
+ }, "submitIcon"))]
184
215
  })
185
216
  });
186
217
  });
@@ -5,7 +5,7 @@ import Platform from "react-native-web/dist/exports/Platform";
5
5
  import NativePicker from 'react-native-picker-select';
6
6
  import { a11yProps, componentPropType } from '../utils';
7
7
  import Group from './Group';
8
- import { ANDROID_HEIGHT_OFFSET, ANDROID_HORIZONTAL_PADDING_OFFSET, ANDROID_DEFAULT_PADDING } from './constants';
8
+ import { ANDROID_HORIZONTAL_PADDING_OFFSET, ANDROID_DEFAULT_PADDING, ALLOW_FONT_SCALING, ADJUSTS_FONT_SIZE_TO_FIT, MAX_FONT_SIZE_MULTIPLIER } from './constants';
9
9
 
10
10
  // Styling of the native input is very limited, most of the styles have to be applied to an additional View
11
11
  import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
@@ -34,8 +34,7 @@ const selectAndroidContainerStyles = _ref2 => {
34
34
  paddingLeft: paddingLeft > ANDROID_HORIZONTAL_PADDING_OFFSET ? paddingLeft - ANDROID_HORIZONTAL_PADDING_OFFSET : ANDROID_DEFAULT_PADDING,
35
35
  paddingRight: paddingRight > ANDROID_HORIZONTAL_PADDING_OFFSET ? paddingRight - ANDROID_HORIZONTAL_PADDING_OFFSET : ANDROID_DEFAULT_PADDING,
36
36
  paddingBottom: ANDROID_DEFAULT_PADDING,
37
- paddingTop: ANDROID_DEFAULT_PADDING,
38
- height: rest.height + ANDROID_HEIGHT_OFFSET
37
+ paddingTop: ANDROID_DEFAULT_PADDING
39
38
  };
40
39
  };
41
40
  const Picker = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
@@ -94,7 +93,12 @@ const Picker = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
94
93
  inputIOS: style,
95
94
  inputAndroid: selectAndroidInputStyles(style)
96
95
  },
97
- placeholder: placeholder !== undefined ? placeholder : {}
96
+ placeholder: placeholder !== undefined ? placeholder : {},
97
+ textInputProps: {
98
+ allowFontScaling: ALLOW_FONT_SCALING,
99
+ adjustFontSizeToFit: ADJUSTS_FONT_SIZE_TO_FIT,
100
+ maxFontSizeMultiplier: MAX_FONT_SIZE_MULTIPLIER
101
+ }
98
102
  });
99
103
  return /*#__PURE__*/_jsx(_Fragment, {
100
104
  children: Platform.OS === 'android' ? /*#__PURE__*/_jsx(View, {
@@ -1,5 +1,7 @@
1
1
  // Because Android
2
2
  export const ANDROID_VALIDATION_ICON_CONTAINER_OFFSET = 5;
3
- export const ANDROID_HEIGHT_OFFSET = 12;
4
3
  export const ANDROID_HORIZONTAL_PADDING_OFFSET = 8;
5
- export const ANDROID_DEFAULT_PADDING = 0;
4
+ export const ANDROID_DEFAULT_PADDING = 0;
5
+ export const ALLOW_FONT_SCALING = true;
6
+ export const ADJUSTS_FONT_SIZE_TO_FIT = true;
7
+ export const MAX_FONT_SIZE_MULTIPLIER = 3;
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
+ import Platform from "react-native-web/dist/exports/Platform";
3
4
  import StyleSheet from "react-native-web/dist/exports/StyleSheet";
4
5
  import Text from "react-native-web/dist/exports/Text";
5
6
  import View from "react-native-web/dist/exports/View";
@@ -108,7 +109,7 @@ const StepTracker = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
108
109
  dictionary,
109
110
  copy
110
111
  });
111
- const stepTrackerLabel = showStepTrackerLabel ? (typeof copy === 'string' ? getCopy(textStepTrackerLabel ?? 1).stepTrackerLabel : getCopy('stepTrackerLabel')).replace('%{stepNumber}', current < steps.length ? current + 1 : steps.length).replace('%{stepCount}', steps.length).replace('%{stepLabel}', current < steps.length ? steps[current] : steps[steps.length - 1]) : '';
112
+ const stepTrackerLabel = showStepTrackerLabel ? (typeof copy === 'string' ? getCopy(textStepTrackerLabel ?? 1).stepTrackerLabel : getCopy('stepTrackerLabel')).replace('%{stepNumber}', current < steps.length ? current + 1 : steps.length).replace('%{stepCount}', steps.length).replace('%{stepLabel}', current < steps.length ? steps[current] : steps[steps.length - 1]) : getCopy('stepTrackerLabel');
112
113
  const getStepLabel = index => {
113
114
  if (themeTokens.showStepLabel) {
114
115
  var _getCopy;
@@ -122,7 +123,6 @@ const StepTracker = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
122
123
  if (!steps.length) return null;
123
124
  const selectedProps = selectProps({
124
125
  accessibilityLabel: stepTrackerLabel,
125
- accessibilityLevel: 1,
126
126
  accessibilityRole: 'progressbar',
127
127
  accessibilityValue: {
128
128
  min: 0,
@@ -132,6 +132,8 @@ const StepTracker = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
132
132
  },
133
133
  ...rest
134
134
  });
135
+ const stepsContainerAccessibilityRole = Platform.OS === 'web' ? 'list' : 'tablist';
136
+ const stepAccessibilityRole = Platform.OS === 'web' ? 'listitem' : 'tab';
135
137
  return /*#__PURE__*/_jsx(View, {
136
138
  ref: ref,
137
139
  style: selectContainerStyles(themeTokens),
@@ -140,6 +142,7 @@ const StepTracker = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
140
142
  space: 0,
141
143
  children: [/*#__PURE__*/_jsx(View, {
142
144
  style: staticStyles.stepsContainer,
145
+ accessibilityRole: stepsContainerAccessibilityRole,
143
146
  children: steps.map((label, index) => {
144
147
  return /*#__PURE__*/_jsx(Step, {
145
148
  status: current,
@@ -147,13 +150,17 @@ const StepTracker = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
147
150
  name: getStepLabel(index),
148
151
  stepIndex: index,
149
152
  stepCount: steps.length,
150
- tokens: themeTokens
153
+ tokens: themeTokens,
154
+ accessibilityRole: stepAccessibilityRole,
155
+ accessibilityCurrent: current === index && Platform.OS === 'web' && 'step'
151
156
  }, label);
152
157
  })
153
158
  }), showStepTrackerLabel && /*#__PURE__*/_jsx(View, {
154
159
  style: [staticStyles.stepTrackerLabelContainer, selectStepTrackerLabelContainerStyles(themeTokens)],
155
160
  children: /*#__PURE__*/_jsx(Text, {
156
161
  style: selectStepTrackerLabelStyles(themeTokens, themeOptions),
162
+ accessibilityRole: "header",
163
+ accessibilityLevel: 2,
157
164
  children: stepTrackerLabel
158
165
  })
159
166
  })]
@@ -61,10 +61,6 @@ const TextArea = /*#__PURE__*/React.forwardRef((_ref, ref) => {
61
61
  } = selectProps(rest);
62
62
  const inputProps = {
63
63
  ...selectedProps,
64
- variant: {
65
- ...variant,
66
- validation: supportsProps.validation
67
- },
68
64
  multiline: true,
69
65
  onContentSizeChange: onHeightChange,
70
66
  height: inputHeight,
@@ -72,6 +68,7 @@ const TextArea = /*#__PURE__*/React.forwardRef((_ref, ref) => {
72
68
  };
73
69
  return /*#__PURE__*/_jsx(InputSupports, {
74
70
  ...supportsProps,
71
+ inputValue: selectedProps === null || selectedProps === void 0 ? void 0 : selectedProps.value,
75
72
  children: _ref3 => {
76
73
  let {
77
74
  inputId,
@@ -79,9 +76,13 @@ const TextArea = /*#__PURE__*/React.forwardRef((_ref, ref) => {
79
76
  } = _ref3;
80
77
  return /*#__PURE__*/_jsx(TextInputBase, {
81
78
  ref: ref,
82
- ...inputProps,
83
79
  nativeID: inputId,
84
- ...props
80
+ ...props,
81
+ ...inputProps,
82
+ variant: {
83
+ ...variant,
84
+ validation: props.validation
85
+ }
85
86
  });
86
87
  }
87
88
  });
@@ -38,16 +38,13 @@ const TextInput = /*#__PURE__*/React.forwardRef((_ref, ref) => {
38
38
  } = selectProps(rest);
39
39
  const inputProps = {
40
40
  ...selectedProps,
41
- tokens,
42
- variant: {
43
- ...variant,
44
- validation: supportsProps.validation
45
- }
41
+ tokens
46
42
  };
47
43
  return /*#__PURE__*/_jsxs(_Fragment, {
48
44
  children: [/*#__PURE__*/_jsx(InputSupports, {
49
45
  nativeID: nativeID,
50
46
  ...supportsProps,
47
+ inputValue: selectedProps === null || selectedProps === void 0 ? void 0 : selectedProps.value,
51
48
  children: _ref2 => {
52
49
  let {
53
50
  inputId,
@@ -57,7 +54,11 @@ const TextInput = /*#__PURE__*/React.forwardRef((_ref, ref) => {
57
54
  ref: ref,
58
55
  nativeID: inputId,
59
56
  ...propsFromInputSupports,
60
- ...inputProps
57
+ ...inputProps,
58
+ variant: {
59
+ ...variant,
60
+ validation: propsFromInputSupports.validation
61
+ }
61
62
  });
62
63
  }
63
64
  }), rest.children]
@@ -37,6 +37,9 @@ const selectInputStyles = function (_ref, themeOptions, inactive, type) {
37
37
  let buttonSize = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
38
38
  let buttonsGapSize = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 0;
39
39
  let isPassword = arguments.length > 7 ? arguments[7] : undefined;
40
+ let iconLeftWidth = arguments.length > 8 ? arguments[8] : undefined;
41
+ let iconLeftGap = arguments.length > 9 ? arguments[9] : undefined;
42
+ let direction = arguments.length > 10 ? arguments[10] : undefined;
40
43
  // Subtract border width from padding so overall input width/height doesn't
41
44
  // jump around if the border width changes (avoiding NaN and negative padding)
42
45
  const offsetBorder = value => typeof value === 'number' ? Math.max(0, value - borderWidth) : value;
@@ -63,6 +66,15 @@ const selectInputStyles = function (_ref, themeOptions, inactive, type) {
63
66
  resize: minHeight !== maxHeight ? 'vertical' : 'none' // does nothing for an input, only needed for textarea
64
67
  }
65
68
  });
69
+ const getPaddingLeft = () => {
70
+ if (type === 'card') {
71
+ return offsetBorder(paddingLeft + 34);
72
+ }
73
+ if (direction === 'left') {
74
+ return offsetBorder(iconLeftWidth + iconLeftGap + staticStyles.iconLeftContainer.paddingLeft);
75
+ }
76
+ return offsetBorder(paddingLeft);
77
+ };
66
78
  const buttonSpacing = isPassword ? buttonsGapSize : -buttonsGapSize;
67
79
  const adjustedPaddingRight = paddingRight + (buttonCount ? 1 : 0) * (buttonSize + buttonSpacing);
68
80
  const adjustedPaddingWithButtons = buttonCount > 1 ? paddingRight : adjustedPaddingRight;
@@ -73,7 +85,7 @@ const selectInputStyles = function (_ref, themeOptions, inactive, type) {
73
85
  borderWidth,
74
86
  borderColor,
75
87
  borderRadius,
76
- paddingLeft: type === 'card' ? offsetBorder(paddingLeft + 34) : offsetBorder(paddingLeft),
88
+ paddingLeft: getPaddingLeft(),
77
89
  paddingRight: icon ? offsetBorder(paddingWithIcon) : offsetBorder(adjustedPaddingWithButtons),
78
90
  paddingTop: offsetBorder(paddingTop),
79
91
  paddingBottom: offsetBorder(paddingBottom),
@@ -123,20 +135,26 @@ const selectIconContainerStyles = (_ref4, buttonCount) => {
123
135
  paddingBottom
124
136
  };
125
137
  };
126
- const selectLeftIconContainerStyles = _ref5 => {
138
+ const selectIconCardLeftContainerStyles = _ref5 => {
127
139
  let {
128
140
  leftIconPaddingBottom
129
141
  } = _ref5;
130
142
  return {
131
- // not tokenizing paddingLeft as it remains same across brands for now
132
- paddingLeft: 10,
133
143
  paddingBottom: leftIconPaddingBottom
134
144
  };
135
145
  };
136
- const selectButtonsContainerStyle = _ref6 => {
146
+ const selectIconLeftContainerStyles = _ref6 => {
137
147
  let {
138
- buttonsPaddingRight
148
+ iconLeftPaddingBottom
139
149
  } = _ref6;
150
+ return {
151
+ paddingBottom: iconLeftPaddingBottom
152
+ };
153
+ };
154
+ const selectButtonsContainerStyle = _ref7 => {
155
+ let {
156
+ buttonsPaddingRight
157
+ } = _ref7;
140
158
  return {
141
159
  paddingRight: buttonsPaddingRight
142
160
  };
@@ -180,7 +198,7 @@ const getIcon = function () {
180
198
  testID: selectedIcon.testID
181
199
  });
182
200
  };
183
- const TextInputBase = /*#__PURE__*/React.forwardRef((_ref7, ref) => {
201
+ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
184
202
  let {
185
203
  buttons = [],
186
204
  copy = 'en',
@@ -201,8 +219,9 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref7, ref) => {
201
219
  variant = {},
202
220
  type,
203
221
  onKeyPress,
222
+ direction,
204
223
  ...rest
205
- } = _ref7;
224
+ } = _ref8;
206
225
  const [isFocused, setIsFocused] = React.useState(false);
207
226
  const [showPassword, setShowPassword] = React.useState(false);
208
227
  const handleFocus = event => {
@@ -288,14 +307,16 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref7, ref) => {
288
307
  defaultCreditIcon,
289
308
  amexIcon,
290
309
  visaIcon,
291
- masterCardIcon
310
+ masterCardIcon,
311
+ iconLeftGap
292
312
  } = themeTokens;
293
313
  const buttonsGapSize = useSpacingScale(buttonsGap);
294
314
  const getCopy = useCopy({
295
315
  dictionary,
296
316
  copy
297
317
  });
298
- const textInputButtons = buttons;
318
+ const textInputButtons = direction === 'left' ? buttons.filter(button => button && button.key !== 'submitIcon') : buttons;
319
+ const submitIcon = direction === 'left' ? buttons.find(button => button && button.key === 'submitIcon') : null;
299
320
  if (onClear && isDirty) {
300
321
  textInputButtons === null || textInputButtons === void 0 || textInputButtons.unshift(/*#__PURE__*/_jsx(IconButton, {
301
322
  accessibilityLabel: getCopy('clearButtonAccessibilityLabel'),
@@ -339,15 +360,20 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref7, ref) => {
339
360
  const {
340
361
  themeOptions
341
362
  } = useTheme();
363
+ const iconLeftWidth = submitIcon ? submitIcon.props.tokens.size ?? 0 : 0;
342
364
  const nativeInputStyle = selectInputStyles({
343
365
  ...themeTokens,
344
366
  height
345
- }, themeOptions, inactive, type, buttons === null || buttons === void 0 ? void 0 : buttons.length, themeTokens.buttonSize, buttonsGapSize, isPassword);
367
+ }, themeOptions, inactive, type, buttons === null || buttons === void 0 ? void 0 : buttons.length, themeTokens.buttonSize, buttonsGapSize, isPassword, iconLeftWidth, iconLeftGap, direction);
368
+ const shouldShowSubmitIcon = submitIcon && direction === 'left' && !inactive;
346
369
  return /*#__PURE__*/_jsxs(View, {
347
370
  style: selectOuterBorderStyles(themeTokens),
348
- children: [type === 'card' && /*#__PURE__*/_jsx(View, {
371
+ children: [shouldShowSubmitIcon && /*#__PURE__*/_jsx(View, {
372
+ style: [staticStyles.iconLeftContainer, selectIconLeftContainerStyles(themeTokens)],
373
+ children: submitIcon
374
+ }), type === 'card' && /*#__PURE__*/_jsx(View, {
349
375
  pointerEvents: "none",
350
- style: [staticStyles.leftIconContainer, selectLeftIconContainerStyles(themeTokens)],
376
+ style: [staticStyles.iconCardLeftContainer, selectIconCardLeftContainerStyles(themeTokens)],
351
377
  children: getIcon(currentValue, {
352
378
  defaultCreditIcon,
353
379
  amexIcon,
@@ -425,7 +451,15 @@ const staticStyles = StyleSheet.create({
425
451
  right: 0,
426
452
  bottom: 0
427
453
  },
428
- leftIconContainer: {
454
+ iconCardLeftContainer: {
455
+ paddingLeft: 10,
456
+ position: 'absolute',
457
+ left: 0,
458
+ bottom: 0,
459
+ zIndex: 1
460
+ },
461
+ iconLeftContainer: {
462
+ paddingLeft: 10,
429
463
  position: 'absolute',
430
464
  left: 0,
431
465
  bottom: 0,
@@ -37,7 +37,15 @@ export default {
37
37
  /**
38
38
  * Use to visually mark an input as valid or invalid.
39
39
  */
40
- validation: PropTypes.oneOf(['error', 'success'])
40
+ validation: PropTypes.oneOf(['error', 'success']),
41
+ /**
42
+ * The text value from an input field.
43
+ */
44
+ inputValue: PropTypes.string,
45
+ /**
46
+ * Max number of characters allowed id an input text.
47
+ */
48
+ maxCharacterAllowed: PropTypes.number
41
49
  },
42
50
  select: _ref => {
43
51
  let {
@@ -49,7 +57,9 @@ export default {
49
57
  feedbackTokens,
50
58
  feedbackProps,
51
59
  tooltip,
52
- validation
60
+ validation,
61
+ inputValue,
62
+ maxCharacterAllowed
53
63
  } = _ref;
54
64
  return {
55
65
  supportsProps: {
@@ -61,7 +71,9 @@ export default {
61
71
  feedbackTokens,
62
72
  feedbackProps,
63
73
  tooltip,
64
- validation
74
+ validation,
75
+ inputValue,
76
+ maxCharacterAllowed
65
77
  }
66
78
  };
67
79
  }