@telus-uds/components-base 2.3.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.
package/CHANGELOG.md CHANGED
@@ -1,12 +1,31 @@
1
1
  # Change Log - @telus-uds/components-base
2
2
 
3
- This log was last generated on Thu, 19 Dec 2024 04:54:39 GMT and should not be manually modified.
3
+ This log was last generated on Fri, 10 Jan 2025 21:41:25 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 2.4.0
8
+
9
+ Fri, 10 Jan 2025 21:41:25 GMT
10
+
11
+ ### Minor changes
12
+
13
+ - `Search`: `showLeftIcon` prop added to display the update icon in the left side for the component. (35577399+JoshHC@users.noreply.github.com)
14
+ - `MultiSelectFilter`: add label and button icon tokens (kristina.kirpichnikova@telus.com)
15
+ - Bump @telus-uds/system-theme-tokens to v3.3.0
16
+
17
+ ### Patches
18
+
19
+ - `Link`: add missing outer border tokens for mobile devices (guillermo.peitzner@telus.com)
20
+ - `Modal`: add fallback to avoid error when pressing Tab (Mauricio.BatresMontejo@telus.com)
21
+ - `Select`: fix Option not appearing in component when selected on iOS largest text sizes (sergio.ramirez@telus.com)
22
+ - `InputLabel`: add character count to support InputText and TextArea (Mauricio.BatresMontejo@telus.com)
23
+ - `Notification`: add system style variant retrocompatibility (guillermo.peitzner@telus.com)
24
+ - `InputLabel`: static styles of the label modified to fix hint and tooltip misalignment (35577399+JoshHC@users.noreply.github.com)
25
+
7
26
  ## 2.3.0
8
27
 
9
- Thu, 19 Dec 2024 04:54:39 GMT
28
+ Thu, 19 Dec 2024 05:02:20 GMT
10
29
 
11
30
  ### Minor changes
12
31
 
@@ -49,6 +49,8 @@ const InputLabel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
49
49
  tooltip,
50
50
  tokens,
51
51
  variant,
52
+ characterCount,
53
+ maxCharacterAllowed,
52
54
  ...rest
53
55
  } = _ref3;
54
56
  const themeTokens = useThemeTokens('InputLabel', tokens, variant);
@@ -81,11 +83,26 @@ const InputLabel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
81
83
  content: tooltip,
82
84
  copy: copy
83
85
  })
86
+ }), maxCharacterAllowed && isHintInline && /*#__PURE__*/_jsxs(Text, {
87
+ style: [selectHintStyles({
88
+ ...themeTokens
89
+ }), staticStyles.characterCountlabel],
90
+ children: [characterCount, "/", maxCharacterAllowed]
84
91
  })]
85
- }), hint && !isHintInline && /*#__PURE__*/_jsx(Text, {
92
+ }), hint && !maxCharacterAllowed && !isHintInline && /*#__PURE__*/_jsx(Text, {
86
93
  style: [selectHintStyles(themeTokens), staticStyles.hintBelow],
87
94
  nativeID: hintId,
88
95
  children: hint
96
+ }), hint && maxCharacterAllowed && !isHintInline && /*#__PURE__*/_jsxs(View, {
97
+ style: staticStyles.container,
98
+ children: [/*#__PURE__*/_jsx(Text, {
99
+ style: [selectHintStyles(themeTokens), staticStyles.flexHintBelow],
100
+ nativeID: hintId,
101
+ children: hint
102
+ }), /*#__PURE__*/_jsxs(Text, {
103
+ style: [selectHintStyles(themeTokens), staticStyles.characterCountlabel],
104
+ children: [characterCount, "/", maxCharacterAllowed]
105
+ })]
89
106
  })]
90
107
  });
91
108
  });
@@ -120,6 +137,14 @@ InputLabel.propTypes = {
120
137
  * Content of an optional `Tooltip`. If set, a tooltip button will be shown next to the label.
121
138
  */
122
139
  tooltip: PropTypes.string,
140
+ /**
141
+ * Current number of characterts of an input text.
142
+ */
143
+ characterCount: PropTypes.number,
144
+ /**
145
+ * Max number of characters that allows an input text.
146
+ */
147
+ maxCharacterAllowed: PropTypes.number,
123
148
  tokens: getTokensPropType('InputLabel'),
124
149
  variant: variantProp.propType
125
150
  };
@@ -129,13 +154,22 @@ const staticStyles = StyleSheet.create({
129
154
  flexShrink: 1,
130
155
  flexDirection: 'row'
131
156
  },
157
+ characterCountlabel: {
158
+ marginLeft: 'auto',
159
+ marginTop: 'auto'
160
+ },
132
161
  label: {
133
- flexShrink: 1
162
+ flexShrink: 1,
163
+ alignSelf: 'center'
134
164
  },
135
165
  hintBelow: {
136
166
  flexBasis: '100%',
137
167
  flexShrink: 0
138
168
  },
169
+ flexHintBelow: {
170
+ flexBasis: '100%',
171
+ flexShrink: 1
172
+ },
139
173
  tooltipAlign: {
140
174
  alignSelf: 'center',
141
175
  justifyContent: 'center'
@@ -5,7 +5,8 @@ import Feedback from '../Feedback';
5
5
  import StackView from '../StackView';
6
6
  import { useThemeTokens } from '../ThemeProvider';
7
7
  import useInputSupports from './useInputSupports';
8
- import { getTokensPropType } from '../utils';
8
+ import { getTokensPropType, useCopy } from '../utils';
9
+ import dictionary from './dictionary';
9
10
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
11
  const InputSupports = /*#__PURE__*/React.forwardRef((_ref, ref) => {
11
12
  let {
@@ -19,11 +20,19 @@ const InputSupports = /*#__PURE__*/React.forwardRef((_ref, ref) => {
19
20
  feedbackProps = {},
20
21
  tooltip,
21
22
  validation,
23
+ maxCharacterAllowed,
24
+ inputValue,
22
25
  nativeID
23
26
  } = _ref;
24
27
  const {
25
28
  space
26
29
  } = useThemeTokens('InputSupports');
30
+ const getCopy = useCopy({
31
+ dictionary,
32
+ copy
33
+ });
34
+ const maxCharsReachedErrorMessage = (inputValue === null || inputValue === void 0 ? void 0 : inputValue.length) > maxCharacterAllowed ? getCopy('maxCharsMessage').replace(/%\{charCount\}/g, maxCharacterAllowed) : '';
35
+ const feedbackValidation = (inputValue === null || inputValue === void 0 ? void 0 : inputValue.length) > maxCharacterAllowed ? 'error' : validation;
27
36
  const {
28
37
  inputId,
29
38
  hintId,
@@ -34,7 +43,10 @@ const InputSupports = /*#__PURE__*/React.forwardRef((_ref, ref) => {
34
43
  hint,
35
44
  label,
36
45
  validation,
37
- nativeID
46
+ nativeID,
47
+ copy,
48
+ maxCharacterAllowed,
49
+ charactersCount: maxCharacterAllowed - (inputValue === null || inputValue === void 0 ? void 0 : inputValue.length)
38
50
  });
39
51
  return /*#__PURE__*/_jsxs(StackView, {
40
52
  space: space,
@@ -46,14 +58,17 @@ const InputSupports = /*#__PURE__*/React.forwardRef((_ref, ref) => {
46
58
  hintPosition: hintPosition,
47
59
  hintId: hintId,
48
60
  tooltip: tooltip,
49
- forId: inputId
61
+ forId: inputId,
62
+ characterCount: inputValue === null || inputValue === void 0 ? void 0 : inputValue.length,
63
+ maxCharacterAllowed: maxCharacterAllowed
50
64
  }), typeof children === 'function' ? children({
51
65
  inputId,
52
- ...a11yProps
53
- }) : children, feedback ? /*#__PURE__*/_jsx(Feedback, {
66
+ ...a11yProps,
67
+ validation: feedbackValidation
68
+ }) : children, feedback || maxCharsReachedErrorMessage ? /*#__PURE__*/_jsx(Feedback, {
54
69
  id: feedbackId,
55
- title: feedback,
56
- validation: validation,
70
+ title: feedback || maxCharsReachedErrorMessage,
71
+ validation: feedbackValidation,
57
72
  tokens: feedbackTokens,
58
73
  variant: {
59
74
  icon: feedbackProps.showFeedbackIcon
@@ -105,6 +120,14 @@ InputSupports.propTypes = {
105
120
  /**
106
121
  * ID for DOM element on web
107
122
  */
108
- nativeID: PropTypes.string
123
+ nativeID: PropTypes.string,
124
+ /**
125
+ * The text value of a TextArea or TextInput
126
+ */
127
+ inputValue: PropTypes.string,
128
+ /**
129
+ * Max number of characters that allows an input text.
130
+ */
131
+ maxCharacterAllowed: PropTypes.number
109
132
  };
110
133
  export default InputSupports;
@@ -0,0 +1,12 @@
1
+ export default {
2
+ en: {
3
+ maxCharacters: 'Maximum %{charCount} characters',
4
+ charactersRemaining: '%{charCount} characters remaining',
5
+ maxCharsMessage: 'Must not exceed %{charCount} characters'
6
+ },
7
+ fr: {
8
+ maxCharacters: '%{charCount} caractères maximum',
9
+ charactersRemaining: '%{charCount} caractères restants',
10
+ maxCharsMessage: 'Ne doit pas dépasser %{charCount} caractères'
11
+ }
12
+ };
@@ -1,4 +1,6 @@
1
1
  import useUniqueId from '../utils/useUniqueId';
2
+ import { useCopy } from '../utils';
3
+ import dictionary from './dictionary';
2
4
  const joinDefined = array => array.filter(item => item !== undefined).join(' ');
3
5
  const useInputSupports = _ref => {
4
6
  let {
@@ -6,19 +8,26 @@ const useInputSupports = _ref => {
6
8
  feedback,
7
9
  validation,
8
10
  hint,
9
- nativeID
11
+ nativeID,
12
+ copy,
13
+ maxCharacterAllowed,
14
+ charactersCount
10
15
  } = _ref;
16
+ const getCopy = useCopy({
17
+ dictionary,
18
+ copy
19
+ });
11
20
  const hasValidationError = validation === 'error';
12
21
  const inputId = useUniqueId('input');
13
22
  const hintId = useUniqueId('input-hint');
14
23
  const feedbackId = useUniqueId('input-feedback');
15
24
  const a11yProps = {
16
25
  accessibilityLabel: label,
17
- accessibilityHint: joinDefined([!hasValidationError && feedback, hint]),
26
+ accessibilityHint: joinDefined([!hasValidationError && feedback, hint, maxCharacterAllowed ? getCopy('maxCharacters').replace(/%\{charCount\}/g, maxCharacterAllowed) : undefined]),
18
27
  // native only -> replaced with describedBy on web
19
28
  accessibilityDescribedBy: joinDefined([!hasValidationError && feedback && feedbackId,
20
29
  // feedback receives a11yRole=alert on error, so there's no need to include it here
21
- hint && hintId]),
30
+ hint && hintId, charactersCount ? getCopy('charactersRemaining').replace(/%\{charCount\}/g, charactersCount) : undefined]),
22
31
  accessibilityInvalid: hasValidationError
23
32
  };
24
33
  return {
@@ -19,20 +19,15 @@ const selectOuterBorderStyles = _ref => {
19
19
  borderRadius,
20
20
  outerBorderOutline
21
21
  } = _ref;
22
- return (
23
- // A view wrapper with a border on native messes up inline text alignment
24
- // so for now make focus styles strictly web-only
25
- Platform.OS === 'web' ? {
26
- // Allow theme to define outline, or, turn off outline and use border if rounded corners required
27
- outline: outerBorderOutline,
28
- ...applyOuterBorder({
29
- outerBorderColor,
30
- outerBorderWidth,
31
- outerBorderGap
32
- }),
33
- borderRadius
34
- } : {}
35
- );
22
+ return {
23
+ outline: outerBorderOutline,
24
+ ...applyOuterBorder({
25
+ outerBorderColor,
26
+ outerBorderWidth,
27
+ outerBorderGap
28
+ }),
29
+ borderRadius
30
+ };
36
31
  };
37
32
  const selectTextStyles = _ref2 => {
38
33
  let {
@@ -182,7 +177,7 @@ const LinkBase = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
182
177
  const themeTokens = resolveLinkTokens(linkState);
183
178
  const outerBorderStyles = selectOuterBorderStyles(themeTokens);
184
179
  const decorationStyles = selectDecorationStyles(themeTokens);
185
- return [outerBorderStyles, blockLeftStyle, decorationStyles, hasIcon && staticStyles.rowContainer];
180
+ return [outerBorderStyles, staticStyles.outerBorderStyles, blockLeftStyle, decorationStyles, hasIcon && staticStyles.rowContainer];
186
181
  },
187
182
  children: linkState => {
188
183
  const themeTokens = resolveLinkTokens(linkState);
@@ -264,6 +259,13 @@ const staticStyles = StyleSheet.create({
264
259
  pointerEvents: 'none'
265
260
  }
266
261
  })
262
+ },
263
+ outerBorderStyles: {
264
+ ...(Platform.OS !== 'web' && {
265
+ margin: 0,
266
+ marginHorizontal: 2,
267
+ padding: 0
268
+ })
267
269
  }
268
270
  });
269
271
  export default withLinkRouter(LinkBase);
@@ -148,11 +148,11 @@ const Modal = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
148
148
  const manageFocus = React.useCallback(event => {
149
149
  if (event.key === 'Tab') {
150
150
  var _modalBodyRef$current;
151
- const focusableElements = Array.from(modalBodyRef === null || modalBodyRef === void 0 || (_modalBodyRef$current = modalBodyRef.current) === null || _modalBodyRef$current === void 0 ? void 0 : _modalBodyRef$current.querySelectorAll(`
151
+ const focusableElements = Array.from((modalBodyRef === null || modalBodyRef === void 0 || (_modalBodyRef$current = modalBodyRef.current) === null || _modalBodyRef$current === void 0 ? void 0 : _modalBodyRef$current.querySelectorAll(`
152
152
  a[href], button, textarea, input, select,
153
153
  [tabindex]:not([tabindex="-1"]),
154
154
  [contenteditable="true"]
155
- `));
155
+ `)) || []);
156
156
  const firstElement = focusableElements[0];
157
157
  const lastElement = focusableElements[focusableElements.length - 1];
158
158
  if (event.shiftKey && document.activeElement === firstElement) {
@@ -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;