@telus-uds/components-base 1.18.0 → 1.19.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 (36) hide show
  1. package/CHANGELOG.md +30 -2
  2. package/component-docs.json +111 -16
  3. package/jest.config-android.js +17 -0
  4. package/jest.config-ios.js +18 -0
  5. package/jest.config-web.js +31 -0
  6. package/lib/Button/ButtonBase.js +6 -2
  7. package/lib/Carousel/Carousel.js +32 -4
  8. package/lib/Carousel/CarouselTabs/CarouselTabsPanel.js +1 -10
  9. package/lib/Pagination/SideButton.js +6 -4
  10. package/lib/Responsive/Responsive.js +58 -0
  11. package/lib/Responsive/index.js +13 -0
  12. package/lib/Search/Search.js +37 -62
  13. package/lib/Tags/Tags.js +10 -4
  14. package/lib/TextInput/TextInputBase.js +53 -19
  15. package/lib/index.js +9 -0
  16. package/lib-module/Button/ButtonBase.js +6 -2
  17. package/lib-module/Carousel/Carousel.js +32 -4
  18. package/lib-module/Carousel/CarouselTabs/CarouselTabsPanel.js +1 -10
  19. package/lib-module/Pagination/SideButton.js +6 -4
  20. package/lib-module/Responsive/Responsive.js +45 -0
  21. package/lib-module/Responsive/index.js +2 -0
  22. package/lib-module/Search/Search.js +37 -60
  23. package/lib-module/Tags/Tags.js +10 -4
  24. package/lib-module/TextInput/TextInputBase.js +52 -19
  25. package/lib-module/index.js +1 -0
  26. package/package.json +6 -3
  27. package/src/Button/ButtonBase.jsx +4 -2
  28. package/src/Carousel/Carousel.jsx +42 -10
  29. package/src/Carousel/CarouselTabs/CarouselTabsPanel.jsx +0 -10
  30. package/src/Pagination/SideButton.jsx +5 -5
  31. package/src/Responsive/Responsive.jsx +33 -0
  32. package/src/Responsive/index.js +3 -0
  33. package/src/Search/Search.jsx +20 -32
  34. package/src/Tags/Tags.jsx +46 -33
  35. package/src/TextInput/TextInputBase.jsx +46 -16
  36. package/src/index.js +1 -0
@@ -1,5 +1,5 @@
1
1
  import React, { forwardRef } from 'react'
2
- import { View, StyleSheet } from 'react-native'
2
+ import { View } from 'react-native'
3
3
 
4
4
  import PropTypes from 'prop-types'
5
5
  import { useThemeTokens, useThemeTokensCallback } from '../ThemeProvider'
@@ -17,7 +17,6 @@ import {
17
17
  } from '../utils'
18
18
  import TextInputBase from '../TextInput/TextInputBase'
19
19
  import ButtonBase from '../Button/ButtonBase'
20
- import StackView from '../StackView'
21
20
  import useCopy from '../utils/useCopy'
22
21
  import dictionary from './dictionary'
23
22
 
@@ -42,7 +41,6 @@ const selectInputTokens = ({ searchTokens, buttonTokens, buttonsGapSize }) => {
42
41
  }
43
42
  const selectButtonTokens = (tokens) => selectTokens('Button', tokens)
44
43
 
45
- const selectIconsContainerStyle = ({ paddingRight }) => ({ paddingRight })
46
44
  const selectIconTokens = ({ iconSize, iconColor }) => ({ color: iconColor, size: iconSize })
47
45
 
48
46
  /**
@@ -123,10 +121,13 @@ const Search = forwardRef(
123
121
  const a11yLabelText = accessibilityLabel || getCopy('accessibilityLabel')
124
122
  // Placeholder is optional and may be unset by passing an empty string
125
123
  const placeholderText = placeholder ?? a11yLabelText
124
+ const { nativeID, testID, ...containerProps } = selectContainerProps(rest)
126
125
 
127
126
  return (
128
- <View style={staticStyles.container} {...selectContainerProps(rest)}>
127
+ <View {...containerProps}>
129
128
  <TextInputBase
129
+ nativeID={nativeID}
130
+ testID={testID}
130
131
  {...selectInputProps(rest)}
131
132
  ref={ref}
132
133
  tokens={(appearances) =>
@@ -147,28 +148,28 @@ const Search = forwardRef(
147
148
  onSubmitEditing={handleSubmit}
148
149
  onFocus={handleFocus}
149
150
  accessibilityLabel={a11yLabelText}
150
- />
151
- <View style={[staticStyles.iconsContainer, selectIconsContainerStyle(themeTokens)]}>
152
- <StackView direction="row" space={buttonsGap}>
153
- {ClearButtonIcon && !isEmpty && (
151
+ buttons={[
152
+ ClearButtonIcon && !isEmpty && (
154
153
  <ButtonBase
155
- onPress={handleClear}
156
- inactive={inactive}
157
- accessibilityRole="button"
158
154
  accessibilityLabel={getCopy('clearButtonAccessibilityLabel')}
155
+ accessibilityRole="button"
156
+ inactive={inactive}
157
+ key="clear"
158
+ onPress={handleClear}
159
159
  tokens={(appearances) => selectButtonTokens(getButtonTokens(appearances))}
160
160
  >
161
161
  {(buttonState) => (
162
162
  <ClearButtonIcon {...selectIconTokens(getButtonTokens(buttonState))} />
163
163
  )}
164
164
  </ButtonBase>
165
- )}
166
- {SubmitButtonIcon && (
165
+ ),
166
+ SubmitButtonIcon && (
167
167
  <ButtonBase
168
- onPress={handleSubmit}
169
- inactive={inactive}
170
- accessibilityRole="button"
171
168
  accessibilityLabel={getCopy('submitButtonAccessibilityLabel')}
169
+ accessibilityRole="button"
170
+ inactive={inactive}
171
+ key="submit"
172
+ onPress={handleSubmit}
172
173
  tokens={(buttonState) =>
173
174
  selectButtonTokens(getButtonTokens({ ...buttonState, priority: 'high' }))
174
175
  }
@@ -179,9 +180,9 @@ const Search = forwardRef(
179
180
  />
180
181
  )}
181
182
  </ButtonBase>
182
- )}
183
- </StackView>
184
- </View>
183
+ )
184
+ ]}
185
+ />
185
186
  </View>
186
187
  )
187
188
  }
@@ -245,16 +246,3 @@ Search.propTypes = {
245
246
  }
246
247
 
247
248
  export default Search
248
-
249
- const staticStyles = StyleSheet.create({
250
- container: {
251
- // No styles needed here except the View defaults (position: relative etc)
252
- },
253
- iconsContainer: {
254
- position: 'absolute',
255
- right: 0,
256
- top: 0,
257
- bottom: 0,
258
- justifyContent: 'center'
259
- }
260
- })
package/src/Tags/Tags.jsx CHANGED
@@ -30,39 +30,49 @@ const [selectItemProps, selectedItemPropTypes] = selectSystemProps([
30
30
  viewProps
31
31
  ])
32
32
 
33
- const selectIconTextTokens = ({
34
- icon,
35
- iconPosition,
36
- iconSpace,
37
- iconSize,
38
- iconColor,
39
- iconBackground,
40
- iconBorderRadius,
41
- iconAlignSelf,
42
- iconPadding,
43
- iconTranslateX,
44
- iconTranslateY
45
- }) => ({
46
- icon,
47
- iconPosition,
48
- iconSpace,
49
- iconWrapperStyle: {
50
- backgroundColor: iconBackground,
51
- borderRadius: iconBorderRadius,
52
- alignSelf: iconAlignSelf,
53
- padding: iconPadding,
54
- ...Platform.select({
55
- // TODO: https://github.com/telus/universal-design-system/issues/487
56
- web: { transition: 'color 200ms, background 200ms' }
57
- })
33
+ const separateIconTextTokens = (
34
+ {
35
+ icon,
36
+ iconPosition,
37
+ iconSpace,
38
+ iconSize,
39
+ iconColor,
40
+ iconBackground,
41
+ iconBorderRadius,
42
+ iconAlignSelf,
43
+ iconPadding,
44
+ iconTranslateX,
45
+ iconTranslateY,
46
+ ...rest
58
47
  },
59
- iconTokens: {
60
- size: iconSize,
61
- color: iconColor,
62
- translateX: iconTranslateX,
63
- translateY: iconTranslateY
64
- }
65
- })
48
+ returnRest
49
+ ) =>
50
+ returnRest
51
+ ? rest
52
+ : {
53
+ icon,
54
+ iconPosition,
55
+ iconSpace,
56
+ iconWrapperStyle: {
57
+ backgroundColor: iconBackground,
58
+ borderRadius: iconBorderRadius,
59
+ alignSelf: iconAlignSelf,
60
+ padding: iconPadding,
61
+ ...Platform.select({
62
+ // TODO: https://github.com/telus/universal-design-system/issues/487
63
+ web: { transition: 'color 200ms, background 200ms' }
64
+ })
65
+ },
66
+ iconTokens: {
67
+ size: iconSize,
68
+ color: iconColor,
69
+ translateX: iconTranslateX,
70
+ translateY: iconTranslateY
71
+ }
72
+ }
73
+
74
+ const selectIconTextTokens = (tokens) => separateIconTextTokens(tokens, false)
75
+ const selectNonIconTextTokens = (tokens) => separateIconTextTokens(tokens, true)
66
76
 
67
77
  const Tags = forwardRef(
68
78
  (
@@ -87,7 +97,10 @@ const Tags = forwardRef(
87
97
  const { direction, space } = themeTokens
88
98
 
89
99
  const getItemTokens = useThemeTokensCallback('TagsItem', tokens, variant)
90
- const getButtonTokens = (buttonState) => selectTokens('Button', getItemTokens(buttonState))
100
+
101
+ const getButtonTokens = (buttonState) =>
102
+ // Remove icon-text-related tokens, since we want to handle them ourselves, not use ButtonBase's handling
103
+ selectTokens('Button', selectNonIconTextTokens(getItemTokens(buttonState)))
91
104
 
92
105
  const { currentValues, toggleOneValue } = useMultipleInputValues({
93
106
  initialValues,
@@ -1,8 +1,8 @@
1
1
  import React, { forwardRef, useEffect, useState } from 'react'
2
- import { Platform, StyleSheet, TextInput as NativeTextInput, View } from 'react-native'
3
-
4
2
  import PropTypes from 'prop-types'
3
+ import { Platform, StyleSheet, TextInput as NativeTextInput, View } from 'react-native'
5
4
  import { applyTextStyles, useTheme, useThemeTokens, applyOuterBorder } from '../ThemeProvider'
5
+ import StackView from '../StackView'
6
6
  import {
7
7
  a11yProps,
8
8
  getTokensPropType,
@@ -10,6 +10,7 @@ import {
10
10
  textInputHandlerProps,
11
11
  textInputProps,
12
12
  useInputValue,
13
+ useSpacingScale,
13
14
  variantProp,
14
15
  viewProps
15
16
  } from '../utils'
@@ -116,27 +117,35 @@ const selectIconTokens = ({ iconSize, iconColor }) => ({
116
117
  color: iconColor
117
118
  })
118
119
 
119
- const selectIconContainerStyles = ({ paddingRight, paddingBottom }) => ({
120
- paddingRight,
120
+ const selectIconContainerStyles = (
121
+ { buttonSize, buttonsGapSize, paddingRight, paddingBottom },
122
+ buttonCount
123
+ ) => ({
124
+ paddingRight: paddingRight + buttonCount * (buttonSize + buttonsGapSize),
121
125
  paddingBottom
122
126
  })
123
127
 
128
+ const selectButtonsContainerStyle = ({ buttonsPaddingRight }) => ({
129
+ paddingRight: buttonsPaddingRight
130
+ })
131
+
124
132
  const TextInputBase = forwardRef(
125
133
  (
126
134
  {
127
- value,
135
+ buttons = [],
128
136
  height,
129
- initialValue,
130
137
  inactive,
131
- readOnly,
138
+ initialValue,
139
+ onBlur,
132
140
  onChange,
133
141
  onChangeText,
134
142
  onFocus,
135
- onBlur,
136
- onMouseOver,
137
143
  onMouseOut,
144
+ onMouseOver,
138
145
  pattern,
146
+ readOnly,
139
147
  tokens,
148
+ value,
140
149
  variant = {},
141
150
  ...rest
142
151
  },
@@ -188,7 +197,7 @@ const TextInputBase = forwardRef(
188
197
 
189
198
  const themeTokens = useThemeTokens('TextInput', tokens, variant, states)
190
199
 
191
- const { icon: IconComponent } = themeTokens
200
+ const { icon: IconComponent, buttonsGap } = themeTokens
192
201
 
193
202
  const inputProps = {
194
203
  ...selectProps(rest),
@@ -204,6 +213,9 @@ const TextInputBase = forwardRef(
204
213
  value: isControlled ? currentValue : undefined
205
214
  }
206
215
 
216
+ // Get the actual gap value for the current viewport
217
+ const buttonsGapSize = useSpacingScale(buttonsGap)
218
+
207
219
  const { themeOptions } = useTheme()
208
220
  const nativeInputStyle = selectInputStyles({ ...themeTokens, height }, themeOptions, inactive)
209
221
 
@@ -213,11 +225,21 @@ const TextInputBase = forwardRef(
213
225
  {IconComponent && (
214
226
  <View
215
227
  pointerEvents="none" // avoid hijacking input press events
216
- style={[staticStyles.iconContainer, selectIconContainerStyles(themeTokens)]}
228
+ style={[
229
+ staticStyles.iconContainer,
230
+ selectIconContainerStyles({ ...themeTokens, buttonsGapSize }, buttons?.length)
231
+ ]}
217
232
  >
218
233
  <IconComponent {...selectIconTokens(themeTokens)} />
219
234
  </View>
220
235
  )}
236
+ {buttons?.length > 0 && (
237
+ <View style={[staticStyles.buttonsContainer, selectButtonsContainerStyle(themeTokens)]}>
238
+ <StackView direction="row" space={buttonsGap}>
239
+ {buttons}
240
+ </StackView>
241
+ </View>
242
+ )}
221
243
  </View>
222
244
  )
223
245
  }
@@ -226,24 +248,32 @@ TextInputBase.displayName = 'TextInputBase'
226
248
 
227
249
  TextInputBase.propTypes = {
228
250
  ...selectedSystemPropTypes,
229
- value: PropTypes.string,
251
+ buttons: PropTypes.arrayOf(PropTypes.node),
230
252
  height: PropTypes.number,
231
- initialValue: PropTypes.string,
232
253
  inactive: PropTypes.bool,
233
- readOnly: PropTypes.bool,
254
+ initialValue: PropTypes.string,
255
+ onBlur: PropTypes.func,
234
256
  onChange: PropTypes.func,
235
257
  onChangeText: PropTypes.func,
236
258
  onFocus: PropTypes.func,
237
- onBlur: PropTypes.func,
238
- onMouseOver: PropTypes.func,
239
259
  onMouseOut: PropTypes.func,
260
+ onMouseOver: PropTypes.func,
261
+ readOnly: PropTypes.bool,
240
262
  tokens: getTokensPropType('TextInput', 'TextArea'),
263
+ value: PropTypes.string,
241
264
  variant: variantProp.propType
242
265
  }
243
266
 
244
267
  export default TextInputBase
245
268
 
246
269
  const staticStyles = StyleSheet.create({
270
+ buttonsContainer: {
271
+ position: 'absolute',
272
+ right: 0,
273
+ top: 0,
274
+ bottom: 0,
275
+ justifyContent: 'center'
276
+ },
247
277
  iconContainer: {
248
278
  position: 'absolute',
249
279
  right: 0,
package/src/index.js CHANGED
@@ -29,6 +29,7 @@ export { default as Radio } from './Radio'
29
29
  export * from './Radio'
30
30
  export { default as RadioCard } from './RadioCard'
31
31
  export * from './RadioCard'
32
+ export { default as Responsive } from './Responsive'
32
33
  export { default as Search } from './Search'
33
34
  export { default as Select } from './Select'
34
35
  export { default as SideNav } from './SideNav'