@telus-uds/components-base 1.8.3 → 1.8.4

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 (269) hide show
  1. package/CHANGELOG.md +14 -2
  2. package/component-docs.json +1 -1
  3. package/lib/ActivityIndicator/Spinner.js +7 -7
  4. package/lib/ActivityIndicator/Spinner.native.js +2 -2
  5. package/lib/Button/ButtonBase.js +2 -2
  6. package/lib/Button/ButtonGroup.js +1 -1
  7. package/lib/Checkbox/Checkbox.js +1 -1
  8. package/lib/Checkbox/CheckboxGroup.js +2 -2
  9. package/lib/Divider/Divider.js +2 -2
  10. package/lib/ExpandCollapse/Panel.js +2 -17
  11. package/lib/FlexGrid/Col/Col.js +1 -1
  12. package/lib/Icon/Icon.js +1 -1
  13. package/lib/List/List.js +8 -2
  14. package/lib/Pagination/PageButton.js +2 -2
  15. package/lib/Pagination/Pagination.js +5 -3
  16. package/lib/Pagination/usePagination.js +2 -2
  17. package/lib/Progress/ProgressBar.js +3 -3
  18. package/lib/Progress/ProgressBarBackground.js +3 -3
  19. package/lib/Radio/Radio.js +2 -2
  20. package/lib/Radio/RadioGroup.js +2 -2
  21. package/lib/RadioCard/RadioCard.js +1 -1
  22. package/lib/RadioCard/RadioCardGroup.js +2 -2
  23. package/lib/Search/Search.js +1 -1
  24. package/lib/SideNav/SideNav.js +2 -2
  25. package/lib/Skeleton/Skeleton.js +1 -1
  26. package/lib/Skeleton/skeletonWebAnimation.js +1 -1
  27. package/lib/StackView/StackWrap.js +3 -1
  28. package/lib/StackView/getStackedContent.js +2 -2
  29. package/lib/Tabs/Tabs.js +28 -3
  30. package/lib/Tabs/TabsItem.js +5 -6
  31. package/lib/Tags/Tags.js +1 -1
  32. package/lib/ThemeProvider/utils/styles.js +2 -2
  33. package/lib/ThemeProvider/utils/theme-tokens.js +7 -9
  34. package/lib/ToggleSwitch/ToggleSwitch.js +1 -1
  35. package/lib/ToggleSwitch/ToggleSwitchGroup.js +1 -1
  36. package/lib/Tooltip/Backdrop.js +2 -10
  37. package/lib/utils/animation/useVerticalExpandAnimation.js +40 -14
  38. package/lib/utils/children.js +2 -2
  39. package/lib/utils/input.js +6 -12
  40. package/lib/utils/props/componentPropType.js +3 -3
  41. package/lib/utils/props/selectSystemProps.js +2 -2
  42. package/lib/utils/props/tokens.js +2 -2
  43. package/lib/utils/useSpacingScale.js +3 -1
  44. package/lib/utils/useUniqueId.js +1 -1
  45. package/lib-module/A11yInfoProvider/index.js +63 -0
  46. package/lib-module/A11yText/index.js +56 -0
  47. package/lib-module/ActivityIndicator/Spinner.js +77 -0
  48. package/lib-module/ActivityIndicator/Spinner.native.js +144 -0
  49. package/lib-module/ActivityIndicator/index.js +41 -0
  50. package/lib-module/ActivityIndicator/shared.js +12 -0
  51. package/lib-module/BaseProvider/index.js +29 -0
  52. package/lib-module/Box/Box.js +244 -0
  53. package/lib-module/Box/index.js +2 -0
  54. package/lib-module/Button/Button.js +26 -0
  55. package/lib-module/Button/ButtonBase.js +271 -0
  56. package/lib-module/Button/ButtonGroup.js +247 -0
  57. package/lib-module/Button/ButtonLink.js +40 -0
  58. package/lib-module/Button/index.js +4 -0
  59. package/lib-module/Button/propTypes.js +36 -0
  60. package/lib-module/Card/Card.js +84 -0
  61. package/lib-module/Card/CardBase.js +66 -0
  62. package/lib-module/Card/PressableCardBase.js +114 -0
  63. package/lib-module/Card/index.js +4 -0
  64. package/lib-module/Checkbox/Checkbox.js +346 -0
  65. package/lib-module/Checkbox/CheckboxGroup.js +233 -0
  66. package/lib-module/Checkbox/CheckboxInput.js +60 -0
  67. package/lib-module/Checkbox/CheckboxInput.native.js +6 -0
  68. package/lib-module/Checkbox/index.js +3 -0
  69. package/lib-module/Divider/Divider.js +124 -0
  70. package/lib-module/Divider/index.js +2 -0
  71. package/lib-module/ExpandCollapse/Accordion.js +15 -0
  72. package/lib-module/ExpandCollapse/Control.js +136 -0
  73. package/lib-module/ExpandCollapse/ExpandCollapse.js +95 -0
  74. package/lib-module/ExpandCollapse/Panel.js +151 -0
  75. package/lib-module/ExpandCollapse/index.js +7 -0
  76. package/lib-module/Feedback/Feedback.js +157 -0
  77. package/lib-module/Feedback/index.js +2 -0
  78. package/lib-module/Fieldset/Fieldset.js +153 -0
  79. package/lib-module/Fieldset/FieldsetContainer.js +32 -0
  80. package/lib-module/Fieldset/FieldsetContainer.native.js +23 -0
  81. package/lib-module/Fieldset/Legend.js +24 -0
  82. package/lib-module/Fieldset/Legend.native.js +31 -0
  83. package/lib-module/Fieldset/cssReset.js +14 -0
  84. package/lib-module/Fieldset/index.js +2 -0
  85. package/lib-module/FlexGrid/Col/Col.js +276 -0
  86. package/lib-module/FlexGrid/Col/index.js +2 -0
  87. package/lib-module/FlexGrid/FlexGrid.js +148 -0
  88. package/lib-module/FlexGrid/Row/Row.js +184 -0
  89. package/lib-module/FlexGrid/Row/index.js +2 -0
  90. package/lib-module/FlexGrid/helpers/index.js +18 -0
  91. package/lib-module/FlexGrid/index.js +2 -0
  92. package/lib-module/FlexGrid/providers/GutterContext.js +3 -0
  93. package/lib-module/HorizontalScroll/HorizontalScroll.js +175 -0
  94. package/lib-module/HorizontalScroll/HorizontalScrollButton.js +81 -0
  95. package/lib-module/HorizontalScroll/ScrollViewEnd.js +48 -0
  96. package/lib-module/HorizontalScroll/ScrollViewEnd.native.js +27 -0
  97. package/lib-module/HorizontalScroll/dictionary.js +11 -0
  98. package/lib-module/HorizontalScroll/index.js +11 -0
  99. package/lib-module/HorizontalScroll/itemPositions.js +112 -0
  100. package/lib-module/Icon/Icon.js +62 -0
  101. package/lib-module/Icon/IconText.js +83 -0
  102. package/lib-module/Icon/index.js +4 -0
  103. package/lib-module/IconButton/IconButton.js +122 -0
  104. package/lib-module/IconButton/index.js +2 -0
  105. package/lib-module/InputLabel/InputLabel.js +148 -0
  106. package/lib-module/InputLabel/LabelContent.js +27 -0
  107. package/lib-module/InputLabel/LabelContent.native.js +19 -0
  108. package/lib-module/InputLabel/index.js +2 -0
  109. package/lib-module/InputSupports/InputSupports.js +96 -0
  110. package/lib-module/InputSupports/index.js +2 -0
  111. package/lib-module/InputSupports/useInputSupports.js +32 -0
  112. package/lib-module/Link/ChevronLink.js +52 -0
  113. package/lib-module/Link/InlinePressable.js +40 -0
  114. package/lib-module/Link/InlinePressable.native.js +89 -0
  115. package/lib-module/Link/Link.js +28 -0
  116. package/lib-module/Link/LinkBase.js +240 -0
  117. package/lib-module/Link/TextButton.js +35 -0
  118. package/lib-module/Link/index.js +5 -0
  119. package/lib-module/List/List.js +62 -0
  120. package/lib-module/List/ListItem.js +248 -0
  121. package/lib-module/List/index.js +5 -0
  122. package/lib-module/Modal/Modal.js +222 -0
  123. package/lib-module/Modal/dictionary.js +9 -0
  124. package/lib-module/Modal/index.js +2 -0
  125. package/lib-module/Notification/Notification.js +209 -0
  126. package/lib-module/Notification/dictionary.js +8 -0
  127. package/lib-module/Notification/index.js +2 -0
  128. package/lib-module/Pagination/PageButton.js +66 -0
  129. package/lib-module/Pagination/Pagination.js +153 -0
  130. package/lib-module/Pagination/SideButton.js +106 -0
  131. package/lib-module/Pagination/dictionary.js +18 -0
  132. package/lib-module/Pagination/index.js +2 -0
  133. package/lib-module/Pagination/usePagination.js +73 -0
  134. package/lib-module/Progress/Progress.js +89 -0
  135. package/lib-module/Progress/ProgressBar.js +138 -0
  136. package/lib-module/Progress/ProgressBarBackground.js +42 -0
  137. package/lib-module/Progress/index.js +4 -0
  138. package/lib-module/Radio/Radio.js +285 -0
  139. package/lib-module/Radio/RadioButton.js +138 -0
  140. package/lib-module/Radio/RadioGroup.js +243 -0
  141. package/lib-module/Radio/RadioInput.js +62 -0
  142. package/lib-module/Radio/RadioInput.native.js +6 -0
  143. package/lib-module/Radio/index.js +3 -0
  144. package/lib-module/RadioCard/RadioCard.js +219 -0
  145. package/lib-module/RadioCard/RadioCardGroup.js +250 -0
  146. package/lib-module/RadioCard/index.js +3 -0
  147. package/lib-module/Search/Search.js +261 -0
  148. package/lib-module/Search/dictionary.js +12 -0
  149. package/lib-module/Search/index.js +2 -0
  150. package/lib-module/Select/Group.js +21 -0
  151. package/lib-module/Select/Group.native.js +15 -0
  152. package/lib-module/Select/Item.js +20 -0
  153. package/lib-module/Select/Item.native.js +3 -0
  154. package/lib-module/Select/Picker.js +68 -0
  155. package/lib-module/Select/Picker.native.js +120 -0
  156. package/lib-module/Select/Select.js +337 -0
  157. package/lib-module/Select/index.js +6 -0
  158. package/lib-module/SideNav/Item.js +145 -0
  159. package/lib-module/SideNav/ItemContent.js +48 -0
  160. package/lib-module/SideNav/ItemsGroup.js +117 -0
  161. package/lib-module/SideNav/SideNav.js +136 -0
  162. package/lib-module/SideNav/index.js +1 -0
  163. package/lib-module/Skeleton/Skeleton.js +179 -0
  164. package/lib-module/Skeleton/index.js +2 -0
  165. package/lib-module/Skeleton/skeleton.constant.js +3 -0
  166. package/lib-module/Skeleton/skeletonWebAnimation.js +18 -0
  167. package/lib-module/Skeleton/useSkeletonNativeAnimation.js +24 -0
  168. package/lib-module/Spacer/Spacer.js +98 -0
  169. package/lib-module/Spacer/index.js +2 -0
  170. package/lib-module/StackView/StackView.js +125 -0
  171. package/lib-module/StackView/StackWrap.js +50 -0
  172. package/lib-module/StackView/StackWrap.native.js +3 -0
  173. package/lib-module/StackView/StackWrapBox.js +115 -0
  174. package/lib-module/StackView/StackWrapGap.js +59 -0
  175. package/lib-module/StackView/common.js +35 -0
  176. package/lib-module/StackView/getStackedContent.js +124 -0
  177. package/lib-module/StackView/index.js +5 -0
  178. package/lib-module/StepTracker/Step.js +248 -0
  179. package/lib-module/StepTracker/StepTracker.js +185 -0
  180. package/lib-module/StepTracker/dictionary.js +10 -0
  181. package/lib-module/StepTracker/index.js +2 -0
  182. package/lib-module/Tabs/Tabs.js +143 -0
  183. package/lib-module/Tabs/TabsItem.js +224 -0
  184. package/lib-module/Tabs/index.js +2 -0
  185. package/lib-module/Tags/Tags.js +251 -0
  186. package/lib-module/Tags/index.js +2 -0
  187. package/lib-module/TextInput/TextArea.js +94 -0
  188. package/lib-module/TextInput/TextInput.js +72 -0
  189. package/lib-module/TextInput/TextInputBase.js +245 -0
  190. package/lib-module/TextInput/index.js +3 -0
  191. package/lib-module/TextInput/propTypes.js +37 -0
  192. package/lib-module/ThemeProvider/ThemeProvider.js +36 -0
  193. package/lib-module/ThemeProvider/index.js +6 -0
  194. package/lib-module/ThemeProvider/useSetTheme.js +25 -0
  195. package/lib-module/ThemeProvider/useTheme.js +14 -0
  196. package/lib-module/ThemeProvider/useThemeTokens.js +110 -0
  197. package/lib-module/ThemeProvider/utils/index.js +2 -0
  198. package/lib-module/ThemeProvider/utils/styles.js +181 -0
  199. package/lib-module/ThemeProvider/utils/theme-tokens.js +163 -0
  200. package/lib-module/ToggleSwitch/ToggleSwitch.js +250 -0
  201. package/lib-module/ToggleSwitch/ToggleSwitchGroup.js +220 -0
  202. package/lib-module/ToggleSwitch/index.js +3 -0
  203. package/lib-module/Tooltip/Backdrop.js +45 -0
  204. package/lib-module/Tooltip/Backdrop.native.js +44 -0
  205. package/lib-module/Tooltip/Tooltip.js +348 -0
  206. package/lib-module/Tooltip/dictionary.js +8 -0
  207. package/lib-module/Tooltip/getTooltipPosition.js +175 -0
  208. package/lib-module/Tooltip/index.js +2 -0
  209. package/lib-module/TooltipButton/TooltipButton.js +78 -0
  210. package/lib-module/TooltipButton/index.js +2 -0
  211. package/lib-module/Typography/Typography.js +124 -0
  212. package/lib-module/Typography/index.js +2 -0
  213. package/lib-module/ViewportProvider/ViewportProvider.js +29 -0
  214. package/lib-module/ViewportProvider/index.js +3 -0
  215. package/lib-module/ViewportProvider/useViewport.js +3 -0
  216. package/lib-module/ViewportProvider/useViewportListener.js +46 -0
  217. package/lib-module/index.js +48 -0
  218. package/lib-module/utils/a11y/index.js +2 -0
  219. package/lib-module/utils/a11y/semantics.js +157 -0
  220. package/lib-module/utils/a11y/textSize.js +36 -0
  221. package/lib-module/utils/animation/index.js +2 -0
  222. package/lib-module/utils/animation/useVerticalExpandAnimation.js +88 -0
  223. package/lib-module/utils/children.js +119 -0
  224. package/lib-module/utils/containUniqueFields.js +26 -0
  225. package/lib-module/utils/index.js +16 -0
  226. package/lib-module/utils/info/index.js +7 -0
  227. package/lib-module/utils/info/platform/index.js +11 -0
  228. package/lib-module/utils/info/platform/platform.android.js +1 -0
  229. package/lib-module/utils/info/platform/platform.ios.js +1 -0
  230. package/lib-module/utils/info/platform/platform.js +1 -0
  231. package/lib-module/utils/info/platform/platform.native.js +4 -0
  232. package/lib-module/utils/info/versions.js +5 -0
  233. package/lib-module/utils/input.js +179 -0
  234. package/lib-module/utils/pressability.js +111 -0
  235. package/lib-module/utils/props/a11yProps.js +140 -0
  236. package/lib-module/utils/props/clickProps.js +26 -0
  237. package/lib-module/utils/props/componentPropType.js +63 -0
  238. package/lib-module/utils/props/copyPropTypes.js +2 -0
  239. package/lib-module/utils/props/getPropSelector.js +9 -0
  240. package/lib-module/utils/props/handlerProps.js +65 -0
  241. package/lib-module/utils/props/hrefAttrsProp.js +33 -0
  242. package/lib-module/utils/props/index.js +19 -0
  243. package/lib-module/utils/props/inputSupportsProps.js +62 -0
  244. package/lib-module/utils/props/linkProps.js +44 -0
  245. package/lib-module/utils/props/paddingProp.js +9 -0
  246. package/lib-module/utils/props/pressProps.js +42 -0
  247. package/lib-module/utils/props/rectProp.js +9 -0
  248. package/lib-module/utils/props/responsiveProps.js +30 -0
  249. package/lib-module/utils/props/selectSystemProps.js +24 -0
  250. package/lib-module/utils/props/spacingProps.js +56 -0
  251. package/lib-module/utils/props/textInputProps.js +194 -0
  252. package/lib-module/utils/props/textProps.js +59 -0
  253. package/lib-module/utils/props/tokens.js +133 -0
  254. package/lib-module/utils/props/variantProp.js +18 -0
  255. package/lib-module/utils/props/viewProps.js +22 -0
  256. package/lib-module/utils/ssr.js +38 -0
  257. package/lib-module/utils/useCopy.js +44 -0
  258. package/lib-module/utils/useHash.js +45 -0
  259. package/lib-module/utils/useHash.native.js +7 -0
  260. package/lib-module/utils/useResponsiveProp.js +47 -0
  261. package/lib-module/utils/useSpacingScale.js +125 -0
  262. package/lib-module/utils/useUniqueId.js +13 -0
  263. package/lib-module/utils/withLinkRouter.js +83 -0
  264. package/package.json +2 -2
  265. package/src/ExpandCollapse/Panel.jsx +2 -19
  266. package/src/List/List.jsx +6 -2
  267. package/src/Tabs/Tabs.jsx +24 -2
  268. package/src/Tabs/TabsItem.jsx +6 -5
  269. package/src/utils/animation/useVerticalExpandAnimation.js +47 -13
package/src/Tabs/Tabs.jsx CHANGED
@@ -23,9 +23,24 @@ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, vie
23
23
 
24
24
  const { selectHorizontalScrollTokens, useItemPositions } = horizontalScrollUtils
25
25
 
26
+ const getDefaultTabItemAccessibilityRole = (parentRole) => {
27
+ switch (parentRole) {
28
+ case 'tablist':
29
+ return 'tab'
30
+ case 'navigation':
31
+ return 'link'
32
+ default:
33
+ return undefined
34
+ }
35
+ }
36
+
26
37
  /**
27
38
  * Tabs renders a horizontally-scrolling menu of selectable buttons which may link
28
39
  * to a page or control what content is displayed on this page.
40
+ *
41
+ * If you are using Tabs to navigate to a new page (web-only) you should pass
42
+ * `navigation`as the `accessibilityRole` to te Tabs component, this will cause
43
+ * TabItems to default to a role of link and obtain aria-current behaviour.
29
44
  */
30
45
  const Tabs = forwardRef(
31
46
  (
@@ -61,6 +76,11 @@ const Tabs = forwardRef(
61
76
  isPositioningReady
62
77
  )
63
78
 
79
+ const restProps = selectProps(rest)
80
+ const parentAccessibilityRole = restProps.accessibilityRole ?? 'tablist'
81
+ const defaultTabItemAccessibiltyRole =
82
+ getDefaultTabItemAccessibilityRole(parentAccessibilityRole)
83
+
64
84
  return (
65
85
  <HorizontalScroll
66
86
  ref={ref}
@@ -68,8 +88,8 @@ const Tabs = forwardRef(
68
88
  itemPositions={itemPositions}
69
89
  tokens={selectHorizontalScrollTokens(themeTokens)}
70
90
  scrollButtonTokens={scrollButtonTokens}
71
- accessibilityRole="tablist"
72
- {...selectProps(rest)}
91
+ accessibilityRole={parentAccessibilityRole}
92
+ {...restProps}
73
93
  >
74
94
  <StackView space={space} direction="row">
75
95
  {items.map(
@@ -78,6 +98,7 @@ const Tabs = forwardRef(
78
98
  href,
79
99
  label,
80
100
  id,
101
+ accessibilityRole = defaultTabItemAccessibiltyRole,
81
102
  ref: itemRef,
82
103
  LinkRouter: ItemLinkRouter = LinkRouter,
83
104
  linkRouterProps: itemLinkRouterProps
@@ -98,6 +119,7 @@ const Tabs = forwardRef(
98
119
  selected={isSelected}
99
120
  itemPositions={itemPositions}
100
121
  index={index}
122
+ accessibilityRole={accessibilityRole}
101
123
  LinkRouter={ItemLinkRouter}
102
124
  linkRouterProps={{ ...linkRouterProps, ...itemLinkRouterProps }}
103
125
  >
@@ -86,11 +86,11 @@ const TabsItem = forwardRef(
86
86
  itemPositions,
87
87
  index,
88
88
  children,
89
- accessibilityRole = href ? 'link' : 'tab',
90
- accessibilityState = Platform.OS === 'web' && accessibilityRole === 'link'
91
- ? // Web links can't be aria-selected but can be aria-current
92
- { current: selected ? 'page' : false }
93
- : { selected },
89
+ accessibilityRole,
90
+ accessibilityCurrent = Platform.OS === 'web' && accessibilityRole === 'link' && selected
91
+ ? 'page'
92
+ : undefined,
93
+ accessibilityState = accessibilityRole === 'tab' ? { selected } : undefined,
94
94
  ...rawRest
95
95
  },
96
96
  ref
@@ -121,6 +121,7 @@ const TabsItem = forwardRef(
121
121
 
122
122
  const selectedProps = selectProps({
123
123
  accessibilityRole,
124
+ accessibilityCurrent,
124
125
  accessibilityState,
125
126
  ...rest
126
127
  })
@@ -1,21 +1,27 @@
1
- import { useEffect, useRef, useState } from 'react'
1
+ import { useEffect, useLayoutEffect, useRef, useState } from 'react'
2
2
  import { Animated, Easing, Platform } from 'react-native'
3
3
 
4
4
  // TODO: systematise animations
5
5
  // https://github.com/telus/universal-design-system/issues/487
6
6
  function useVerticalExpandAnimation({ containerHeight, isExpanded, tokens }) {
7
7
  const [isAnimating, setIsAnimating] = useState(false)
8
+ const [wasExpanded, setWasExpanded] = useState(isExpanded)
9
+ const expandStateChanged = isExpanded !== wasExpanded
8
10
 
9
11
  const expandAnimatedValue = useRef(new Animated.Value(0)).current
10
12
  const elementRef = useRef(null)
11
13
 
12
14
  const { expandDuration, collapseDuration } = tokens
13
15
 
14
- // Treat as animating from when expanded state changes, until animation completes
15
- useEffect(() => setIsAnimating(true), [isExpanded])
16
+ useLayoutEffect(() => {
17
+ if (expandStateChanged) {
18
+ setIsAnimating(true)
19
+ setWasExpanded(isExpanded)
20
+ }
21
+ }, [expandStateChanged, isExpanded])
16
22
 
17
23
  useEffect(() => {
18
- const onComplete = () => !isExpanded && setIsAnimating(false)
24
+ const onComplete = () => setIsAnimating(false)
19
25
 
20
26
  if (Platform.OS === 'web') {
21
27
  if (!elementRef.current) return () => {}
@@ -39,19 +45,47 @@ function useVerticalExpandAnimation({ containerHeight, isExpanded, tokens }) {
39
45
  return () => animation.stop()
40
46
  }, [isExpanded, expandAnimatedValue, containerHeight, expandDuration, collapseDuration])
41
47
 
42
- // Without `visibility: 'hidden', descendents are focusable on web even when collapsed
43
- const containerStyles = !isExpanded && !isAnimating ? { visibility: 'hidden' } : {}
48
+ const containerStyles = {}
44
49
 
45
- // don't visually collapse the container until we have it measured
46
- if (containerHeight !== null) {
47
- if (Platform.OS === 'web') {
48
- const transitionDuration = isExpanded ? expandDuration : collapseDuration
49
- containerStyles.transition = `height ${transitionDuration}ms ease-in-out`
50
+ if (isAnimating || expandStateChanged) containerStyles.overflow = 'hidden'
50
51
 
51
- containerStyles.height = isExpanded ? containerHeight : 0
52
+ if (!isExpanded && !isAnimating && !expandStateChanged) {
53
+ if (Platform.OS === 'web') {
54
+ // Without `visibility: 'hidden', descendents are focusable on web even when collapsed.
55
+ containerStyles.visibility = 'hidden'
52
56
  } else {
53
- containerStyles.height = expandAnimatedValue
57
+ // There's no `visibility: hidden` in React Native, and display: none causes a flicker on expand.
58
+ // Without some form of hiding, some children leak through even when closed e.g. `List.Item` bullets.
59
+ containerStyles.opacity = 0
60
+ }
61
+ }
62
+
63
+ // don't visually collapse the container until we have it measured
64
+ if (containerHeight === null) {
65
+ if (Platform.OS === 'web') {
66
+ // on web we can hide the contents until we have the container measured and avoid occasional jitter
67
+ // this won't work on native platforms
68
+ containerStyles.height = 0
69
+ containerStyles.visibility = 'hidden'
54
70
  }
71
+ } else if (Platform.OS === 'web') {
72
+ const transitionDuration = isExpanded ? expandDuration : collapseDuration
73
+ containerStyles.transition = `height ${transitionDuration}ms ease-in-out`
74
+
75
+ containerStyles.height = isExpanded ? containerHeight : 0
76
+ } else if (
77
+ Platform.OS === 'ios' &&
78
+ isExpanded &&
79
+ !isAnimating &&
80
+ !expandStateChanged &&
81
+ typeof containerHeight === 'number'
82
+ ) {
83
+ // iOS reflows text while the height animation is in progress. Sometimes, it hits a timing bug where
84
+ // it fails to reflow properly after the last animation frame, leaving the last line of text not visible.
85
+ // Force reflow after animation completes with a static height non-identical to the last animated height.
86
+ containerStyles.height = containerHeight + 1
87
+ } else {
88
+ containerStyles.height = expandAnimatedValue
55
89
  }
56
90
 
57
91
  return [containerStyles, elementRef]