@telus-uds/components-base 4.0.0-alpha.0 → 4.0.0-alpha.2

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 (82) hide show
  1. package/CHANGELOG.md +62 -6
  2. package/jest.config.cjs +1 -0
  3. package/lib/cjs/ActionCard/ActionCard.js +10 -3
  4. package/lib/cjs/Card/Card.js +3 -3
  5. package/lib/cjs/Carousel/Carousel.js +6 -1
  6. package/lib/cjs/Carousel/CarouselThumbnail.js +125 -33
  7. package/lib/cjs/Carousel/CarouselThumbnailNavigation.js +8 -1
  8. package/lib/cjs/Footnote/FootnoteLink.js +18 -17
  9. package/lib/cjs/InputSupports/InputSupports.js +1 -2
  10. package/lib/cjs/InputSupports/useInputSupports.js +1 -3
  11. package/lib/cjs/Link/ChevronLink.js +1 -2
  12. package/lib/cjs/Notification/Notification.js +4 -12
  13. package/lib/cjs/Progress/Progress.js +30 -5
  14. package/lib/cjs/Progress/ProgressBar.js +3 -3
  15. package/lib/cjs/Progress/ProgressBarBackground.js +2 -3
  16. package/lib/cjs/QuickLinks/QuickLinks.js +7 -0
  17. package/lib/cjs/Scroll/Scroll.js +472 -0
  18. package/lib/cjs/Scroll/ScrollContext.js +55 -0
  19. package/lib/cjs/Scroll/ScrollItem.js +106 -0
  20. package/lib/cjs/Scroll/ScrollProgress.js +100 -0
  21. package/lib/cjs/Scroll/dictionary.js +18 -0
  22. package/lib/cjs/StackView/StackWrapBox.js +9 -1
  23. package/lib/cjs/StackView/StackWrapGap.js +3 -1
  24. package/lib/cjs/StackView/getStackedContent.js +20 -10
  25. package/lib/cjs/index.js +14 -0
  26. package/lib/cjs/utils/animation/useAnimatedValue.js +46 -0
  27. package/lib/cjs/utils/children.js +2 -1
  28. package/lib/esm/ActionCard/ActionCard.js +10 -3
  29. package/lib/esm/Card/Card.js +3 -3
  30. package/lib/esm/Carousel/Carousel.js +6 -1
  31. package/lib/esm/Carousel/CarouselThumbnail.js +126 -34
  32. package/lib/esm/Carousel/CarouselThumbnailNavigation.js +8 -1
  33. package/lib/esm/Footnote/FootnoteLink.js +18 -17
  34. package/lib/esm/InputSupports/InputSupports.js +1 -2
  35. package/lib/esm/InputSupports/useInputSupports.js +1 -3
  36. package/lib/esm/Link/ChevronLink.js +1 -2
  37. package/lib/esm/Notification/Notification.js +4 -12
  38. package/lib/esm/Progress/Progress.js +30 -5
  39. package/lib/esm/Progress/ProgressBar.js +3 -3
  40. package/lib/esm/Progress/ProgressBarBackground.js +2 -3
  41. package/lib/esm/QuickLinks/QuickLinks.js +7 -0
  42. package/lib/esm/Scroll/Scroll.js +465 -0
  43. package/lib/esm/Scroll/ScrollContext.js +46 -0
  44. package/lib/esm/Scroll/ScrollItem.js +100 -0
  45. package/lib/esm/Scroll/ScrollProgress.js +93 -0
  46. package/lib/esm/Scroll/dictionary.js +12 -0
  47. package/lib/esm/StackView/StackWrapBox.js +9 -1
  48. package/lib/esm/StackView/StackWrapGap.js +3 -1
  49. package/lib/esm/StackView/getStackedContent.js +20 -10
  50. package/lib/esm/index.js +2 -0
  51. package/lib/esm/utils/animation/useAnimatedValue.js +38 -0
  52. package/lib/esm/utils/children.js +2 -1
  53. package/lib/package.json +2 -2
  54. package/package.json +2 -2
  55. package/src/ActionCard/ActionCard.jsx +13 -4
  56. package/src/Card/Card.jsx +3 -3
  57. package/src/Carousel/Carousel.jsx +6 -1
  58. package/src/Carousel/CarouselThumbnail.jsx +117 -30
  59. package/src/Carousel/CarouselThumbnailNavigation.jsx +8 -2
  60. package/src/Footnote/FootnoteLink.jsx +17 -12
  61. package/src/InputSupports/InputSupports.jsx +1 -6
  62. package/src/InputSupports/useInputSupports.js +1 -1
  63. package/src/Link/ChevronLink.jsx +1 -2
  64. package/src/Notification/Notification.jsx +5 -21
  65. package/src/Progress/Progress.jsx +22 -3
  66. package/src/Progress/ProgressBar.jsx +3 -3
  67. package/src/Progress/ProgressBarBackground.jsx +2 -3
  68. package/src/QuickLinks/QuickLinks.jsx +8 -0
  69. package/src/Scroll/Scroll.jsx +483 -0
  70. package/src/Scroll/ScrollContext.jsx +39 -0
  71. package/src/Scroll/ScrollItem.jsx +87 -0
  72. package/src/Scroll/ScrollProgress.jsx +74 -0
  73. package/src/Scroll/dictionary.js +12 -0
  74. package/src/StackView/StackWrapBox.jsx +13 -1
  75. package/src/StackView/StackWrapGap.jsx +2 -1
  76. package/src/StackView/getStackedContent.jsx +22 -8
  77. package/src/index.js +2 -0
  78. package/src/utils/animation/useAnimatedValue.js +35 -0
  79. package/src/utils/children.jsx +4 -1
  80. package/types/Link.d.ts +1 -2
  81. package/types/Scroll.d.ts +66 -0
  82. package/types/index.d.ts +9 -0
@@ -55,6 +55,7 @@ export const StackWrapBox = React.forwardRef(
55
55
  variant,
56
56
  tag,
57
57
  accessibilityRole,
58
+ itemAccessibilityRole,
58
59
  ...rest
59
60
  },
60
61
  ref
@@ -73,7 +74,12 @@ export const StackWrapBox = React.forwardRef(
73
74
  const gapSize = useSpacingScale(gap)
74
75
  const offsetStyle = { [offsetSides[direction]]: -1 * gapSize }
75
76
  const boxProps = { [gapSides[direction]]: gap, [spaceSides[direction]]: space }
76
- const content = getStackedContent(children, { direction, space: 0, box: boxProps })
77
+ const content = getStackedContent(children, {
78
+ direction,
79
+ space: 0,
80
+ box: boxProps,
81
+ itemAccessibilityRole
82
+ })
77
83
 
78
84
  return (
79
85
  <View
@@ -116,6 +122,12 @@ StackWrapBox.propTypes = {
116
122
  * is not defined, the accessibilityRole will default to "heading".
117
123
  */
118
124
  tag: PropTypes.oneOf(layoutTags),
125
+ /**
126
+ * Optional accessibility role to apply to each item in the stack.
127
+ * On web, items are wrapped (or cloned) with this role, enabling correct list semantics
128
+ * when the container tag is "ul" or "ol".
129
+ */
130
+ itemAccessibilityRole: PropTypes.string,
119
131
  /**
120
132
  * A StackWrap may take any children, but will have no effect if it is only passed one child or is passed children
121
133
  * wrapped in a component. If necessary, children may be wrapped in one React Fragment.
@@ -35,6 +35,7 @@ export const StackWrapGap = React.forwardRef(
35
35
  children,
36
36
  tag,
37
37
  accessibilityRole,
38
+ itemAccessibilityRole,
38
39
  ...rest
39
40
  },
40
41
  ref
@@ -52,7 +53,7 @@ export const StackWrapGap = React.forwardRef(
52
53
  const size = useSpacingScale(space)
53
54
  const gapStyle = { gap: size }
54
55
 
55
- const content = getStackedContent(children, { direction, space: 0 })
56
+ const content = getStackedContent(children, { direction, space: 0, itemAccessibilityRole })
56
57
 
57
58
  return (
58
59
  <View
@@ -32,7 +32,7 @@ import { Spacer } from '../Spacer/Spacer'
32
32
  */
33
33
  export const getStackedContent = (
34
34
  children,
35
- { divider, space, direction = 'column', box, preserveFragments = false }
35
+ { divider, space, direction = 'column', box, preserveFragments = false, itemAccessibilityRole }
36
36
  ) => {
37
37
  const boxProps = box && typeof box === 'object' ? box : { space }
38
38
  const dividerProps = divider && typeof divider === 'object' ? divider : {}
@@ -42,15 +42,29 @@ export const getStackedContent = (
42
42
  const validChildren = React.Children.toArray(topLevelChildren).filter(Boolean)
43
43
  const content = validChildren.reduce((newChildren, child, index) => {
44
44
  const boxID = `Stack-Box-${index}`
45
- const item = box ? (
45
+
46
+ let item
47
+ if (box) {
46
48
  // If wrapped in Box, that Box needs a key.
47
49
  // If possible, use an existing content key; use an index-based key only if necessary.
48
- <Box {...boxProps} key={child.key || boxID} testID={boxID}>
49
- {child}
50
- </Box>
51
- ) : (
52
- child
53
- )
50
+ item = (
51
+ <Box
52
+ {...boxProps}
53
+ accessibilityRole={itemAccessibilityRole}
54
+ key={child.key || boxID}
55
+ testID={boxID}
56
+ >
57
+ {child}
58
+ </Box>
59
+ )
60
+ } else if (itemAccessibilityRole) {
61
+ item = React.cloneElement(child, {
62
+ accessibilityRole: itemAccessibilityRole,
63
+ key: child.key || boxID
64
+ })
65
+ } else {
66
+ item = child
67
+ }
54
68
  if (!index || (!space && !divider)) return [...newChildren, item]
55
69
 
56
70
  const testID = `Stack-${divider ? 'Divider' : 'Spacer'}-${index}`
package/src/index.js CHANGED
@@ -76,6 +76,8 @@ export { RadioGroup } from './Radio/RadioGroup'
76
76
  export { RadioCard } from './RadioCard/RadioCard'
77
77
  export { RadioCardGroup } from './RadioCard/RadioCardGroup'
78
78
  export { Responsive } from './Responsive/Responsive'
79
+ export { Scroll } from './Scroll/Scroll'
80
+ export { ScrollItem } from './Scroll/ScrollItem'
79
81
  export { Search } from './Search/Search'
80
82
  export { Select } from './Select/Select'
81
83
  export { SelectItem } from './Select/SelectItem'
@@ -0,0 +1,35 @@
1
+ import React from 'react'
2
+ import { Animated, Easing } from 'react-native'
3
+
4
+ const ANIMATION_DURATION = 200
5
+
6
+ /**
7
+ * Smoothly animates a numeric value to a new target using a quadratic ease-in-out
8
+ * curve. Returns the current interpolated value as a plain number so
9
+ * consumers can use it in non-Animated style props.
10
+ *
11
+ * @param {number} targetValue - The value to animate towards.
12
+ * @param {number} [duration=ANIMATION_DURATION] - Animation duration in ms.
13
+ */
14
+ export const useAnimatedValue = (targetValue, duration = ANIMATION_DURATION) => {
15
+ const [currentValue, setCurrentValue] = React.useState(targetValue)
16
+ const animatedValue = React.useRef(new Animated.Value(targetValue)).current
17
+
18
+ React.useEffect(() => {
19
+ const id = animatedValue.addListener(({ value }) => setCurrentValue(value))
20
+ return () => animatedValue.removeListener(id)
21
+ }, [animatedValue])
22
+
23
+ React.useEffect(() => {
24
+ const animation = Animated.timing(animatedValue, {
25
+ toValue: targetValue,
26
+ duration,
27
+ easing: Easing.inOut(Easing.quad),
28
+ useNativeDriver: false
29
+ })
30
+ animation.start()
31
+ return () => animation.stop()
32
+ }, [targetValue, animatedValue, duration])
33
+
34
+ return currentValue
35
+ }
@@ -47,8 +47,11 @@ export const unpackFragment = (child) => {
47
47
 
48
48
  const isStringOrNumber = (child) => typeof child === 'string' || typeof child === 'number'
49
49
  // Wrap an A11yText with neighouring text strings so it doesn't split them into multiple <Text>s
50
+ // Check displayName first as it is explicitly set and reliable regardless of export style (named vs default)
50
51
  const isWrapable = (child) =>
51
- isStringOrNumber(child) || child.type === A11yText || child.type?.name === 'FootnoteLink'
52
+ isStringOrNumber(child) ||
53
+ child.type === A11yText ||
54
+ child.type?.__UDS_COMPONENT_NAME__ === 'FootnoteLink'
52
55
  const combineKeys = (childrenArray) =>
53
56
  childrenArray.reduce((newKey, child) => `${newKey}${child.key || ''}`, '')
54
57
 
package/types/Link.d.ts CHANGED
@@ -22,8 +22,7 @@ export enum LinkSize {
22
22
 
23
23
  export type LinkAndTextButtonVariants = {
24
24
  size?: 'large' | 'small' | 'micro'
25
- alternative?: boolean
26
- inverse?: boolean
25
+ style?: 'inline' | 'subtle' | 'feature' | 'danger' | 'inverse'
27
26
  }
28
27
 
29
28
  export type LinkTokens = {
@@ -0,0 +1,66 @@
1
+ import type { ComponentType, ReactNode } from 'react'
2
+ import type { SemanticTag } from './Common'
3
+
4
+ export interface ScrollDictionary {
5
+ accessibilityLabel: string
6
+ instructionText: string
7
+ progressBarLabel: string
8
+ }
9
+
10
+ export interface ScrollProps {
11
+ /**
12
+ * Scroll items to display. Should be `ScrollItem` components.
13
+ */
14
+ children: ReactNode
15
+ /**
16
+ * Theme tokens for customizing the Scroll appearance.
17
+ */
18
+ tokens?: ScrollTokens
19
+ /**
20
+ * Variant for the Scroll component.
21
+ */
22
+ variant?: ScrollVariant
23
+ /**
24
+ * Select English or French copy for accessible labels.
25
+ */
26
+ copy?: 'en' | 'fr'
27
+ /**
28
+ * Override the default dictionary by passing the complete dictionary object for `en` and `fr`.
29
+ */
30
+ dictionary?: {
31
+ en: ScrollDictionary
32
+ fr: ScrollDictionary
33
+ }
34
+ /**
35
+ * Accessibility label for the scrollable region.
36
+ */
37
+ accessibilityLabel?: string
38
+ }
39
+
40
+ export type ScrollVariant = {}
41
+
42
+ export interface ScrollTokens {
43
+ itemGap?: number
44
+ progressBarColor?: string
45
+ progressBarHeight?: number
46
+ progressHitAreaHeight?: number
47
+ progressSpacing?: number
48
+ progressTrackColor?: string
49
+ progressTrackHeight?: number
50
+ }
51
+
52
+ export interface ScrollItemProps {
53
+ /**
54
+ * Content of the scroll item.
55
+ */
56
+ children: ReactNode
57
+ /**
58
+ * Sets the HTML tag of the outer container. Defaults to `'li'`.
59
+ */
60
+ tag?: SemanticTag
61
+ }
62
+
63
+ declare const Scroll: ComponentType<ScrollProps>
64
+ export declare const ScrollItem: ComponentType<ScrollItemProps>
65
+
66
+ export default Scroll
package/types/index.d.ts CHANGED
@@ -45,6 +45,15 @@ export { LinkProps, LinkSize, LinkAndTextButtonVariants, LinkTokens } from './Li
45
45
  export { default as List } from './List'
46
46
  export { ListVariants, ListTokens, ListProps, ListItemProps, ListItemTokens } from './List'
47
47
 
48
+ export { default as Scroll, ScrollItem } from './Scroll'
49
+ export type {
50
+ ScrollProps,
51
+ ScrollTokens,
52
+ ScrollVariant,
53
+ ScrollItemProps,
54
+ ScrollDictionary
55
+ } from './Scroll'
56
+
48
57
  export { default as Search } from './Search'
49
58
  export { SearchTokens, SearchProps } from './Search'
50
59