@telus-uds/components-base 1.8.4 → 1.10.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 (51) hide show
  1. package/CHANGELOG.md +38 -2
  2. package/component-docs.json +344 -0
  3. package/lib/Card/Card.js +9 -4
  4. package/lib/Carousel/Carousel.js +619 -0
  5. package/lib/Carousel/CarouselContext.js +59 -0
  6. package/lib/Carousel/CarouselItem/CarouselItem.js +77 -0
  7. package/lib/Carousel/CarouselItem/index.js +13 -0
  8. package/lib/Carousel/index.js +32 -0
  9. package/lib/Checkbox/Checkbox.js +4 -2
  10. package/lib/ExpandCollapse/Panel.js +10 -1
  11. package/lib/Link/InlinePressable.js +5 -1
  12. package/lib/Link/LinkBase.js +5 -2
  13. package/lib/StepTracker/StepTracker.js +5 -2
  14. package/lib/TextInput/TextInput.js +0 -11
  15. package/lib/TextInput/TextInputBase.js +9 -0
  16. package/lib/TextInput/propTypes.js +3 -8
  17. package/lib/index.js +14 -0
  18. package/lib/utils/props/textInputProps.js +8 -1
  19. package/lib-module/Card/Card.js +5 -4
  20. package/lib-module/Carousel/Carousel.js +570 -0
  21. package/lib-module/Carousel/CarouselContext.js +43 -0
  22. package/lib-module/Carousel/CarouselItem/CarouselItem.js +60 -0
  23. package/lib-module/Carousel/CarouselItem/index.js +2 -0
  24. package/lib-module/Carousel/index.js +2 -0
  25. package/lib-module/Checkbox/Checkbox.js +4 -2
  26. package/lib-module/ExpandCollapse/Panel.js +9 -1
  27. package/lib-module/Link/InlinePressable.js +5 -1
  28. package/lib-module/Link/LinkBase.js +5 -2
  29. package/lib-module/StepTracker/StepTracker.js +5 -2
  30. package/lib-module/TextInput/TextInput.js +0 -8
  31. package/lib-module/TextInput/TextInputBase.js +10 -1
  32. package/lib-module/TextInput/propTypes.js +4 -8
  33. package/lib-module/index.js +1 -0
  34. package/lib-module/utils/props/textInputProps.js +8 -1
  35. package/package.json +3 -3
  36. package/src/Card/Card.jsx +6 -4
  37. package/src/Carousel/Carousel.jsx +586 -0
  38. package/src/Carousel/CarouselContext.jsx +30 -0
  39. package/src/Carousel/CarouselItem/CarouselItem.jsx +48 -0
  40. package/src/Carousel/CarouselItem/index.js +3 -0
  41. package/src/Carousel/index.js +2 -0
  42. package/src/Checkbox/Checkbox.jsx +3 -1
  43. package/src/ExpandCollapse/Panel.jsx +8 -1
  44. package/src/Link/InlinePressable.jsx +5 -2
  45. package/src/Link/LinkBase.jsx +4 -1
  46. package/src/StepTracker/StepTracker.jsx +12 -5
  47. package/src/TextInput/TextInput.jsx +1 -8
  48. package/src/TextInput/TextInputBase.jsx +11 -1
  49. package/src/TextInput/propTypes.js +3 -7
  50. package/src/index.js +1 -0
  51. package/src/utils/props/textInputProps.js +7 -1
@@ -1,6 +1,7 @@
1
1
  import React, { forwardRef, useState } from 'react'
2
2
  import { Animated, Platform, View } from 'react-native'
3
3
  import PropTypes from 'prop-types'
4
+ import ABBPropTypes from 'airbnb-prop-types'
4
5
 
5
6
  import ExpandCollapseControl from './Control'
6
7
  import { useThemeTokens } from '../ThemeProvider'
@@ -51,6 +52,7 @@ const ExpandCollapsePanel = forwardRef(
51
52
  children,
52
53
  tokens,
53
54
  variant,
55
+ controlRef,
54
56
  ...rest
55
57
  },
56
58
  ref
@@ -95,6 +97,7 @@ const ExpandCollapsePanel = forwardRef(
95
97
  isExpanded={isExpanded}
96
98
  tokens={controlTokens}
97
99
  onPress={handleControlPress}
100
+ ref={controlRef}
98
101
  >
99
102
  {control}
100
103
  </ExpandCollapseControl>
@@ -142,7 +145,11 @@ ExpandCollapsePanel.propTypes = {
142
145
  /**
143
146
  * Optional theme token overrides that may be passed to the ExpandCollapseControl element.
144
147
  */
145
- controlTokens: getTokensPropType('ExpandCollapseControl')
148
+ controlTokens: getTokensPropType('ExpandCollapseControl'),
149
+ /**
150
+ * An optional ref to be attached to the control
151
+ */
152
+ controlRef: ABBPropTypes.ref()
146
153
  }
147
154
 
148
155
  export default ExpandCollapsePanel
@@ -15,11 +15,11 @@ import { Pressable, StyleSheet } from 'react-native'
15
15
  */
16
16
  // React Native exports prop Types but not propTypes, use JSDoc types here rather than duplicate RN
17
17
  // eslint-disable-next-line react/prop-types
18
- const InlinePressable = forwardRef(({ children, style, ...props }, ref) => (
18
+ const InlinePressable = forwardRef(({ children, style, inline = false, ...props }, ref) => (
19
19
  <Pressable
20
20
  ref={ref}
21
21
  style={(pressState) => [
22
- staticStyles.inline,
22
+ staticStyles[inline ? 'inline' : 'inlineFlex'],
23
23
  typeof style === 'function' ? style(pressState) : style
24
24
  ]}
25
25
  {...props}
@@ -32,6 +32,9 @@ InlinePressable.displayName = 'InlinePressable'
32
32
  const staticStyles = StyleSheet.create({
33
33
  inline: {
34
34
  // Stop Pressable defaulting to (block) flex
35
+ display: 'inline'
36
+ },
37
+ inlineFlex: {
35
38
  display: 'inline-flex'
36
39
  }
37
40
  })
@@ -132,18 +132,21 @@ const LinkBase = forwardRef(
132
132
  const resolveLinkTokens = (pressState) =>
133
133
  resolvePressableTokens(tokens, pressState, { iconPosition })
134
134
 
135
+ const defaultThemeTokens = resolveLinkTokens({})
136
+ const hasIcon = Boolean(icon || defaultThemeTokens.icon)
137
+
135
138
  // On web, this makes focus rings wrap only the link, not the entire block
136
139
  const blockLeftStyle = Platform.OS === 'web' && staticStyles.blockLeft
137
140
 
138
141
  return (
139
142
  <InlinePressable
140
143
  {...selectedProps}
144
+ inline={hasIcon} // assuming links without icons should be inline (even if they are long)
141
145
  ref={ref}
142
146
  style={(linkState) => {
143
147
  const themeTokens = resolveLinkTokens(linkState)
144
148
  const outerBorderStyles = selectOuterBorderStyles(themeTokens)
145
149
  const decorationStyles = selectDecorationStyles(themeTokens)
146
- const hasIcon = Boolean(icon || themeTokens.icon)
147
150
  return [
148
151
  outerBorderStyles,
149
152
  blockLeftStyle,
@@ -95,10 +95,17 @@ const StepTracker = forwardRef(
95
95
  }
96
96
  )
97
97
  const getCopy = useCopy({ dictionary, copy })
98
- const stepTrackerLabel = getCopy('stepTrackerLabel')
99
- .replace('%{stepNumber}', current < steps.length ? current + 1 : steps.length)
100
- .replace('%{stepCount}', steps.length)
101
- .replace('%{stepLabel}', current < steps.length ? steps[current] : steps[steps.length - 1])
98
+ const stepTrackerLabel = showStepTrackerLabel
99
+ ? getCopy('stepTrackerLabel')
100
+ .replace('%{stepNumber}', current < steps.length ? current + 1 : steps.length)
101
+ .replace('%{stepCount}', steps.length)
102
+ .replace(
103
+ '%{stepLabel}',
104
+ current < steps.length ? steps[current] : steps[steps.length - 1]
105
+ )
106
+ : ''
107
+ const getStepLabel = (index) =>
108
+ themeTokens.showStepLabel ? getCopy('stepLabel').replace('%{stepNumber}', index + 1) : ''
102
109
  if (!steps.length) return null
103
110
  const selectedProps = selectProps({
104
111
  accessibilityLabel: stepTrackerLabel,
@@ -123,7 +130,7 @@ const StepTracker = forwardRef(
123
130
  status={current}
124
131
  key={label}
125
132
  label={label}
126
- name={getCopy('stepLabel').replace('%{stepNumber}', index + 1)}
133
+ name={getStepLabel(index)}
127
134
  stepIndex={index}
128
135
  stepCount={steps.length}
129
136
  tokens={themeTokens}
@@ -1,5 +1,4 @@
1
1
  import React, { forwardRef } from 'react'
2
- import { Platform } from 'react-native'
3
2
  import {
4
3
  a11yProps,
5
4
  focusHandlerProps,
@@ -42,13 +41,7 @@ const [selectProps, selectedSystemPropTypes] = selectSystemProps([
42
41
  * supported props and <a href="https://reactnative.dev/docs/textinput" target="_blank">React Native Web documentation</a> for
43
42
  * their implementation on the web.
44
43
  */
45
- const TextInput = forwardRef(({ tokens, variant = {}, pattern, ...rest }, ref) => {
46
- React.useEffect(() => {
47
- if (Platform.OS === 'web' && pattern && ref.current) {
48
- // eslint-disable-next-line no-param-reassign
49
- ref.current.pattern = pattern
50
- }
51
- }, [ref, pattern])
44
+ const TextInput = forwardRef(({ tokens, variant = {}, ...rest }, ref) => {
52
45
  const { supportsProps, ...selectedProps } = selectProps(rest)
53
46
 
54
47
  const inputProps = {
@@ -1,4 +1,4 @@
1
- import React, { forwardRef, useState } from 'react'
1
+ import React, { forwardRef, useEffect, useState } from 'react'
2
2
  import { Platform, StyleSheet, TextInput as NativeTextInput, View } from 'react-native'
3
3
 
4
4
  import PropTypes from 'prop-types'
@@ -128,6 +128,7 @@ const TextInputBase = forwardRef(
128
128
  onBlur,
129
129
  onMouseOver,
130
130
  onMouseOut,
131
+ pattern,
131
132
  tokens,
132
133
  variant = {},
133
134
  ...rest
@@ -161,6 +162,15 @@ const TextInputBase = forwardRef(
161
162
  readOnly
162
163
  })
163
164
 
165
+ const element = ref?.current
166
+ useEffect(() => {
167
+ if (Platform.OS === 'web' && pattern && element) {
168
+ // React Native Web doesn't support `pattern`, so we have to attach it via a ref,
169
+ // which a `pattern` user must provide anyway to call .checkValidity() on the element.
170
+ element.pattern = pattern
171
+ }
172
+ }, [element, pattern])
173
+
164
174
  const handleChangeText = (event) => {
165
175
  const text = event.nativeEvent?.text || event.target?.value
166
176
  setValue(text, event)
@@ -1,6 +1,7 @@
1
1
  import PropTypes from 'prop-types'
2
- import { Platform } from 'react-native'
3
2
 
3
+ // These are prop types specific to UDS TextInput; see also ../utils/props/textInputProps
4
+ // for generic React Native props and HTML input attrs that are passed through.
4
5
  const textInputPropTypes = {
5
6
  /**
6
7
  * If the input's state is to be controlled by a parent component, use this prop
@@ -24,12 +25,7 @@ const textInputPropTypes = {
24
25
  * Use to react upon input's value changes. Required when the `value` prop is set.
25
26
  * Will receive the input's value as an argument.
26
27
  */
27
- onChange: PropTypes.func,
28
- ...Platform.select({
29
- web: {
30
- pattern: PropTypes.string
31
- }
32
- })
28
+ onChange: PropTypes.func
33
29
  }
34
30
 
35
31
  export default textInputPropTypes
package/src/index.js CHANGED
@@ -3,6 +3,7 @@ export { default as ActivityIndicator } from './ActivityIndicator'
3
3
  export { default as Box } from './Box'
4
4
  export * from './Button'
5
5
  export { default as Card, PressableCardBase } from './Card'
6
+ export * from './Carousel'
6
7
  export { default as Checkbox } from './Checkbox'
7
8
  export * from './Checkbox'
8
9
  export { default as Divider } from './Divider'
@@ -121,7 +121,13 @@ const crossPlatform = {
121
121
  const webOnly = {
122
122
  disabled: PropTypes.bool,
123
123
  dir: PropTypes.oneOf(['auto', 'ltr', 'rtl']),
124
- lang: PropTypes.string
124
+ lang: PropTypes.string,
125
+ /**
126
+ * Sets the HTML input `pattern` attr. Not supported by React Native Web, but is supported by UDS.
127
+ * Must also pass in a ref and check validity by calling the HTML element's checkValidity method:
128
+ * https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/checkValidity
129
+ */
130
+ pattern: PropTypes.string
125
131
  }
126
132
 
127
133
  /**