@telus-uds/components-base 1.14.2 → 1.16.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 (161) hide show
  1. package/CHANGELOG.md +40 -2
  2. package/__tests17__/A11yText/A11yText.test.jsx +34 -0
  3. package/__tests17__/ActivityIndicator/ActivityIndicator.test.jsx +68 -0
  4. package/__tests17__/ActivityIndicator/__snapshots__/ActivityIndicator.test.jsx.snap +299 -0
  5. package/__tests17__/Box/Box.test.jsx +111 -0
  6. package/__tests17__/Button/Button.test.jsx +86 -0
  7. package/__tests17__/Button/ButtonBase.test.jsx +82 -0
  8. package/__tests17__/Button/ButtonGroup.test.jsx +347 -0
  9. package/__tests17__/Button/ButtonLink.test.jsx +61 -0
  10. package/__tests17__/Card/Card.test.jsx +63 -0
  11. package/__tests17__/Carousel/Carousel.test.jsx +128 -0
  12. package/__tests17__/Carousel/CarouselTabs.test.jsx +142 -0
  13. package/__tests17__/Checkbox/Checkbox.test.jsx +94 -0
  14. package/__tests17__/Checkbox/CheckboxGroup.test.jsx +246 -0
  15. package/__tests17__/Divider/Divider.test.jsx +91 -0
  16. package/__tests17__/ExpandCollapse/ExpandCollapse.test.jsx +109 -0
  17. package/__tests17__/Feedback/Feedback.test.jsx +42 -0
  18. package/__tests17__/FlexGrid/Col.test.jsx +261 -0
  19. package/__tests17__/FlexGrid/FlexGrid.test.jsx +136 -0
  20. package/__tests17__/FlexGrid/Row.test.jsx +273 -0
  21. package/__tests17__/HorizontalScroll/HorizontalScroll.test.jsx +165 -0
  22. package/__tests17__/Icon/Icon.test.jsx +61 -0
  23. package/__tests17__/IconButton/IconButton.test.jsx +52 -0
  24. package/__tests17__/InputLabel/InputLabel.test.jsx +28 -0
  25. package/__tests17__/InputLabel/__snapshots__/InputLabel.test.jsx.snap +3 -0
  26. package/__tests17__/InputSupports/InputSupports.test.jsx +60 -0
  27. package/__tests17__/Link/Link.test.jsx +63 -0
  28. package/__tests17__/Link/TextButton.test.jsx +35 -0
  29. package/__tests17__/List/List.test.jsx +82 -0
  30. package/__tests17__/Modal/Modal.test.jsx +47 -0
  31. package/__tests17__/Notification/Notification.test.jsx +20 -0
  32. package/__tests17__/Pagination/Pagination.test.jsx +160 -0
  33. package/__tests17__/Progress/Progress.test.jsx +79 -0
  34. package/__tests17__/Radio/Radio.test.jsx +87 -0
  35. package/__tests17__/Radio/RadioGroup.test.jsx +220 -0
  36. package/__tests17__/RadioCard/RadioCard.test.jsx +87 -0
  37. package/__tests17__/RadioCard/RadioCardGroup.test.jsx +246 -0
  38. package/__tests17__/Search/Search.test.jsx +87 -0
  39. package/__tests17__/Select/Select.test.jsx +94 -0
  40. package/__tests17__/SideNav/SideNav.test.jsx +110 -0
  41. package/__tests17__/Skeleton/Skeleton.test.jsx +61 -0
  42. package/__tests17__/SkipLink/SkipLink.test.jsx +61 -0
  43. package/__tests17__/Spacer/Spacer.test.jsx +63 -0
  44. package/__tests17__/StackView/StackView.test.jsx +211 -0
  45. package/__tests17__/StackView/StackWrap.test.jsx +47 -0
  46. package/__tests17__/StackView/getStackedContent.test.jsx +295 -0
  47. package/__tests17__/StepTracker/StepTracker.test.jsx +108 -0
  48. package/__tests17__/Tabs/Tabs.test.jsx +49 -0
  49. package/__tests17__/Tags/Tags.test.jsx +327 -0
  50. package/__tests17__/TextInput/TextArea.test.jsx +35 -0
  51. package/__tests17__/TextInput/TextInputBase.test.jsx +125 -0
  52. package/__tests17__/ThemeProvider/ThemeProvider.test.jsx +80 -0
  53. package/__tests17__/ThemeProvider/useThemeTokens.test.jsx +514 -0
  54. package/__tests17__/ThemeProvider/utils/theme-tokens.test.js +41 -0
  55. package/__tests17__/ToggleSwitch/ToggleSwitch.test.jsx +82 -0
  56. package/__tests17__/ToggleSwitch/ToggleSwitchGroup.test.jsx +192 -0
  57. package/__tests17__/Tooltip/Tooltip.test.jsx +65 -0
  58. package/__tests17__/Tooltip/getTooltipPosition.test.js +79 -0
  59. package/__tests17__/Typography/typography.test.jsx +90 -0
  60. package/__tests17__/utils/children.test.jsx +128 -0
  61. package/__tests17__/utils/containUniqueFields.test.js +25 -0
  62. package/__tests17__/utils/input.test.js +375 -0
  63. package/__tests17__/utils/props.test.js +36 -0
  64. package/__tests17__/utils/semantics.test.jsx +34 -0
  65. package/__tests17__/utils/useCopy.test.js +42 -0
  66. package/__tests17__/utils/useResponsiveProp.test.jsx +202 -0
  67. package/__tests17__/utils/useSpacingScale.test.jsx +273 -0
  68. package/__tests17__/utils/useUniqueId.test.js +31 -0
  69. package/component-docs.json +120 -85
  70. package/lib/A11yInfoProvider/index.js +14 -5
  71. package/lib/Button/ButtonGroup.js +3 -2
  72. package/lib/Carousel/Carousel.js +18 -2
  73. package/lib/Carousel/CarouselTabs/CarouselTabs.js +6 -7
  74. package/lib/Checkbox/Checkbox.js +9 -6
  75. package/lib/ExpandCollapse/Control.js +6 -5
  76. package/lib/ExpandCollapse/Panel.js +5 -4
  77. package/lib/List/ListItem.js +10 -236
  78. package/lib/List/ListItemBase.js +162 -0
  79. package/lib/List/ListItemContent.js +85 -0
  80. package/lib/List/ListItemMark.js +158 -0
  81. package/lib/List/PressableListItemBase.js +147 -0
  82. package/lib/Notification/Notification.js +2 -1
  83. package/lib/Pagination/Pagination.js +4 -3
  84. package/lib/Radio/Radio.js +9 -6
  85. package/lib/RadioCard/RadioCard.js +9 -6
  86. package/lib/Select/Select.js +1 -0
  87. package/lib/Skeleton/Skeleton.js +18 -13
  88. package/lib/Skeleton/useSkeletonNativeAnimation.js +4 -2
  89. package/lib/Tabs/Tabs.js +12 -3
  90. package/lib/Tags/Tags.js +3 -3
  91. package/lib/TextInput/TextInput.js +5 -4
  92. package/lib/ToggleSwitch/ToggleSwitch.js +24 -19
  93. package/lib/ViewportProvider/useViewportListener.js +11 -5
  94. package/lib/utils/hasOwnProperty.js +18 -0
  95. package/lib/utils/props/a11yProps.js +171 -1
  96. package/lib/utils/props/getPropSelector.js +47 -5
  97. package/lib/utils/ssr.js +116 -1
  98. package/lib/utils/useResponsiveProp.js +5 -3
  99. package/lib/utils/withLinkRouter.js +3 -5
  100. package/lib-module/A11yInfoProvider/index.js +14 -4
  101. package/lib-module/Button/ButtonGroup.js +3 -2
  102. package/lib-module/Carousel/Carousel.js +16 -2
  103. package/lib-module/Carousel/CarouselTabs/CarouselTabs.js +7 -6
  104. package/lib-module/Checkbox/Checkbox.js +9 -6
  105. package/lib-module/ExpandCollapse/Control.js +6 -5
  106. package/lib-module/ExpandCollapse/Panel.js +5 -4
  107. package/lib-module/List/ListItem.js +13 -235
  108. package/lib-module/List/ListItemBase.js +139 -0
  109. package/lib-module/List/ListItemContent.js +66 -0
  110. package/lib-module/List/ListItemMark.js +143 -0
  111. package/lib-module/List/PressableListItemBase.js +117 -0
  112. package/lib-module/Notification/Notification.js +2 -1
  113. package/lib-module/Pagination/Pagination.js +5 -3
  114. package/lib-module/Radio/Radio.js +9 -6
  115. package/lib-module/RadioCard/RadioCard.js +9 -6
  116. package/lib-module/Select/Select.js +1 -0
  117. package/lib-module/Skeleton/Skeleton.js +15 -13
  118. package/lib-module/Skeleton/useSkeletonNativeAnimation.js +3 -2
  119. package/lib-module/Tabs/Tabs.js +13 -4
  120. package/lib-module/Tags/Tags.js +3 -3
  121. package/lib-module/TextInput/TextInput.js +5 -4
  122. package/lib-module/ToggleSwitch/ToggleSwitch.js +24 -19
  123. package/lib-module/ViewportProvider/useViewportListener.js +10 -4
  124. package/lib-module/utils/hasOwnProperty.js +11 -0
  125. package/lib-module/utils/props/a11yProps.js +169 -1
  126. package/lib-module/utils/props/getPropSelector.js +44 -5
  127. package/lib-module/utils/ssr.js +106 -0
  128. package/lib-module/utils/useResponsiveProp.js +3 -4
  129. package/lib-module/utils/withLinkRouter.js +3 -5
  130. package/package.json +12 -17
  131. package/src/A11yInfoProvider/index.jsx +20 -4
  132. package/src/Button/ButtonGroup.jsx +4 -2
  133. package/src/Carousel/Carousel.jsx +15 -2
  134. package/src/Carousel/CarouselTabs/CarouselTabs.jsx +5 -3
  135. package/src/Checkbox/Checkbox.jsx +7 -3
  136. package/src/ExpandCollapse/Control.jsx +8 -5
  137. package/src/ExpandCollapse/Panel.jsx +7 -5
  138. package/src/List/ListItem.jsx +12 -191
  139. package/src/List/ListItemBase.jsx +118 -0
  140. package/src/List/ListItemContent.jsx +52 -0
  141. package/src/List/ListItemMark.jsx +99 -0
  142. package/src/List/PressableListItemBase.jsx +102 -0
  143. package/src/Notification/Notification.jsx +1 -1
  144. package/src/Pagination/Pagination.jsx +6 -1
  145. package/src/Radio/Radio.jsx +7 -3
  146. package/src/RadioCard/RadioCard.jsx +7 -3
  147. package/src/Select/Select.jsx +1 -1
  148. package/src/Skeleton/Skeleton.jsx +25 -19
  149. package/src/Skeleton/useSkeletonNativeAnimation.js +3 -3
  150. package/src/Tabs/Tabs.jsx +19 -2
  151. package/src/Tags/Tags.jsx +3 -3
  152. package/src/TextInput/TextInput.jsx +4 -4
  153. package/src/ToggleSwitch/ToggleSwitch.jsx +3 -3
  154. package/src/ViewportProvider/useViewportListener.js +10 -5
  155. package/src/utils/hasOwnProperty.js +11 -0
  156. package/src/utils/props/a11yProps.js +107 -1
  157. package/src/utils/props/getPropSelector.js +45 -4
  158. package/src/utils/ssr.jsx +124 -0
  159. package/src/utils/useResponsiveProp.js +3 -3
  160. package/src/utils/withLinkRouter.jsx +1 -3
  161. package/src/utils/ssr.js +0 -35
@@ -35,32 +35,39 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
35
35
 
36
36
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
37
37
 
38
- const [selectProps, selectedSystemPropTypes] = (0, _utils.selectSystemProps)([_utils.a11yProps, _utils.focusHandlerProps, _utils.pressProps, _utils.viewProps]);
38
+ const [selectProps, selectedSystemPropTypes] = (0, _utils.selectSystemProps)([_utils.a11yProps, _utils.focusHandlerProps, _utils.pressProps, _utils.viewProps]); // We need to drop the icon before passing it to the `ButtonBase`, because it's
39
+ // being handled separately in this case
39
40
 
40
- const selectButtonTokens = tokens => (0, _utils.selectTokens)('Button', { ...tokens,
41
- // Width tokens are applied to our inner track. Disable Button width token so it wraps our track width.
42
- width: null
43
- }); // Map and rename icon-specific tokens to name used within Icon
41
+ const selectButtonTokens = _ref => {
42
+ let {
43
+ icon: _,
44
+ ...tokens
45
+ } = _ref;
46
+ return (0, _utils.selectTokens)('Button', { ...tokens,
47
+ // Width tokens are applied to our inner track. Disable Button width token so it wraps our track width.
48
+ width: null
49
+ });
50
+ }; // Map and rename icon-specific tokens to name used within Icon
44
51
 
45
52
 
46
- const selectIconTokens = _ref => {
53
+ const selectIconTokens = _ref2 => {
47
54
  let {
48
55
  iconSize,
49
56
  iconColor
50
- } = _ref;
57
+ } = _ref2;
51
58
  return {
52
59
  size: iconSize,
53
60
  color: iconColor
54
61
  };
55
62
  };
56
63
 
57
- const selectTrackStyles = _ref2 => {
64
+ const selectTrackStyles = _ref3 => {
58
65
  let {
59
66
  trackBorderWidth,
60
67
  trackBorderColor,
61
68
  trackBorderRadius,
62
69
  width
63
- } = _ref2;
70
+ } = _ref3;
64
71
  return {
65
72
  borderWidth: trackBorderWidth,
66
73
  borderColor: trackBorderColor,
@@ -69,7 +76,7 @@ const selectTrackStyles = _ref2 => {
69
76
  };
70
77
  };
71
78
 
72
- const selectSwitchStyles = _ref3 => {
79
+ const selectSwitchStyles = _ref4 => {
73
80
  let {
74
81
  switchSize,
75
82
  switchColor,
@@ -77,7 +84,7 @@ const selectSwitchStyles = _ref3 => {
77
84
  switchBorderColor,
78
85
  switchBorderRadius,
79
86
  switchShadow
80
- } = _ref3;
87
+ } = _ref4;
81
88
  return {
82
89
  width: switchSize,
83
90
  height: switchSize,
@@ -95,23 +102,23 @@ const selectSwitchStyles = _ref3 => {
95
102
  };
96
103
  };
97
104
 
98
- const selectLabelStyles = _ref4 => {
105
+ const selectLabelStyles = _ref5 => {
99
106
  let {
100
107
  labelMarginLeft
101
- } = _ref4;
108
+ } = _ref5;
102
109
  return {
103
110
  marginLeft: labelMarginLeft
104
111
  };
105
112
  };
106
113
 
107
- const selectLabelTokens = _ref5 => {
114
+ const selectLabelTokens = _ref6 => {
108
115
  let {
109
116
  labelColor,
110
117
  labelFontName,
111
118
  labelFontSize,
112
119
  labelFontWeight,
113
120
  labelLineHeight
114
- } = _ref5;
121
+ } = _ref6;
115
122
  return {
116
123
  color: labelColor,
117
124
  fontName: labelFontName,
@@ -121,7 +128,7 @@ const selectLabelTokens = _ref5 => {
121
128
  };
122
129
  };
123
130
 
124
- const ToggleSwitch = /*#__PURE__*/(0, _react.forwardRef)((_ref6, ref) => {
131
+ const ToggleSwitch = /*#__PURE__*/(0, _react.forwardRef)((_ref7, ref) => {
125
132
  let {
126
133
  copy = 'en',
127
134
  value,
@@ -136,7 +143,7 @@ const ToggleSwitch = /*#__PURE__*/(0, _react.forwardRef)((_ref6, ref) => {
136
143
  accessibilityRole = 'switch',
137
144
  accessibilityLabel = label,
138
145
  ...rest
139
- } = _ref6;
146
+ } = _ref7;
140
147
  const getTokens = (0, _ThemeProvider.useThemeTokensCallback)('ToggleSwitch', tokens, variant);
141
148
  const themeTokens = getTokens();
142
149
  const {
@@ -260,8 +267,6 @@ ToggleSwitch.propTypes = { ...selectedSystemPropTypes,
260
267
 
261
268
  const staticStyles = _StyleSheet.default.create({
262
269
  track: {
263
- flexGrow: 1,
264
- alignSelf: 'stretch',
265
270
  flexDirection: 'row'
266
271
  },
267
272
  switch: {
@@ -45,11 +45,17 @@ const useViewportListenerCSR = setViewport => {
45
45
  return setViewport(_systemConstants.viewports.select(window.width));
46
46
  };
47
47
 
48
- const listener = _Dimensions.default.addEventListener('change', onChange); // From RN 0.65.0, Dimensions.removeEventListener is deprecated for `remove` on addEventListener return value;
49
- // however, that is not available in RN <=0.64.X, therefore not in any Expo release as of 2021 (Expo SDK 43).
50
-
51
-
52
- return (listener === null || listener === void 0 ? void 0 : listener.remove) || (() => _Dimensions.default.removeEventListener('change', onChange)); // setViewport is a function from `useState` so it is stable and won't make the effect re-run
48
+ const listener = _Dimensions.default.addEventListener('change', onChange);
49
+
50
+ return () => {
51
+ if (typeof (listener === null || listener === void 0 ? void 0 : listener.remove) === 'function') {
52
+ // Can't just return listener.remove because listener.emitter disappears, causing an internal error.
53
+ // See https://github.com/facebook/react-native/issues/34508
54
+ listener.remove(); // From RN 0.65.0, Dimensions.removeEventListener is deprecated for `remove` on addEventListener return value
55
+ } else if (typeof _Dimensions.default.removeEventListener === 'function') {
56
+ _Dimensions.default.removeEventListener('change', onChange);
57
+ }
58
+ };
53
59
  }, [setViewport]);
54
60
  }; // Window is a defined global object in both Web and Native client-side, and undefined in SSR
55
61
 
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = hasOwnProperty;
7
+
8
+ /**
9
+ * Linter disallows object instance prototype methods like someObject.hasOwnProperty(key),
10
+ * but we can use this instead.
11
+ *
12
+ * @param {object} object
13
+ * @param {String} key
14
+ * @returns {Boolean}
15
+ */
16
+ function hasOwnProperty(object, key) {
17
+ return Object.prototype.hasOwnProperty.call(object, key);
18
+ }
@@ -95,6 +95,169 @@ const a11yPropTypes = { ...nativeA11yPropTypes,
95
95
  accessibilityValueNow: _propTypes.default.number,
96
96
  accessibilityValueText: _propTypes.default.string
97
97
  };
98
+
99
+ const a11yPropTypesByPlatform = _Platform.default.select({
100
+ // React Native Web adds many a11y props that alias aria-* attributes
101
+ // Types based on https://necolas.github.io/react-native-web/docs/accessibility/
102
+ web: a11yPropTypes,
103
+ // Ignore web-only props in native builds
104
+ default: nativeA11yPropTypes
105
+ }); // These RNW-only props only exist in RNW >=0.18. Catch them and map them according to platform
106
+ // so all props work on RN, RNW >=0.18 and RNW <=0.18, regardless of which they were written for:
107
+ // - On native, bundle them into objects, like `accessibilityValue: { max: 100 }`
108
+ // - On web, split them into both of:
109
+ // - The appropriate aria-* attr, like `aria-valuenow`, which will work regardless of RNW version
110
+ // - The corresponding RNW >=0.18 prop, like `accessibilityValueNow`, which in some cases does more
111
+ // than just add the aria-* (e.g. `accessibilityDisabled` adds `disabled` if element supports it,
112
+ // and future releases might add more features here).
113
+
114
+
115
+ const rwnPropMappings = {
116
+ // Former accessibilityValue props.
117
+ accessibilityValueMax: value => _Platform.default.select({
118
+ web: {
119
+ 'aria-valuemax': value,
120
+ accessibilityValueMax: value
121
+ },
122
+ default: {
123
+ accessibilityValue: {
124
+ max: value
125
+ }
126
+ }
127
+ }),
128
+ accessibilityValueMin: value => _Platform.default.select({
129
+ web: {
130
+ 'aria-valuemin': value,
131
+ accessibilityValueMin: value
132
+ },
133
+ default: {
134
+ accessibilityValue: {
135
+ min: value
136
+ }
137
+ }
138
+ }),
139
+ accessibilityValueNow: value => _Platform.default.select({
140
+ web: {
141
+ 'aria-valuenow': value,
142
+ accessibilityValueNow: value
143
+ },
144
+ default: {
145
+ accessibilityValue: {
146
+ now: value
147
+ }
148
+ }
149
+ }),
150
+ accessibilityValueText: value => _Platform.default.select({
151
+ web: {
152
+ 'aria-valuetext': value,
153
+ accessibilityValueText: value
154
+ },
155
+ default: {
156
+ accessibilityValue: {
157
+ text: value
158
+ }
159
+ }
160
+ }),
161
+ // Former accessibilityState props
162
+ accessibilityBusy: value => _Platform.default.select({
163
+ web: {
164
+ 'aria-busy': value,
165
+ accessibilityBusy: value
166
+ },
167
+ default: {
168
+ accessibilityState: {
169
+ busy: value
170
+ }
171
+ }
172
+ }),
173
+ accessibilityChecked: value => _Platform.default.select({
174
+ web: {
175
+ 'aria-checked': value,
176
+ accessibilityChecked: value
177
+ },
178
+ default: {
179
+ accessibilityState: {
180
+ checked: value
181
+ }
182
+ }
183
+ }),
184
+ accessibilityDisabled: value => _Platform.default.select({
185
+ web: {
186
+ 'aria-disabled': value,
187
+ // RNW >= 0.18 maps `accessibilityDisabled` to `disabled` attr if element supports it
188
+ accessibilityDisabled: value,
189
+ // As of RNW 0.18.9, Pressable doesn't support `accessibilityDisabled`, only `disabled`,
190
+ // but everything else supports `accessibilityDisabled` but not `disabled`.
191
+ disabled: value
192
+ },
193
+ default: {
194
+ accessibilityState: {
195
+ disabled: value
196
+ }
197
+ }
198
+ }),
199
+ accessibilityExpanded: value => _Platform.default.select({
200
+ web: {
201
+ 'aria-expanded': value,
202
+ accessibilityExpanded: value
203
+ },
204
+ default: {
205
+ accessibilityState: {
206
+ expanded: value
207
+ }
208
+ }
209
+ }),
210
+ accessibilitySelected: value => _Platform.default.select({
211
+ web: {
212
+ 'aria-selected': value,
213
+ accessibilitySelected: value
214
+ },
215
+ default: {
216
+ accessibilityState: {
217
+ selected: value
218
+ }
219
+ }
220
+ })
221
+ };
222
+
223
+ if (_Platform.default.OS === 'web') {
224
+ const mapIfDefined = (value, fn) => value === undefined ? undefined : fn(value); // On Web only, these React Native object props need manual mapping in RNW >=0.18
225
+ // which dropped support for the React Native shape of these props.
226
+ // Re-use our RNW 0.18 prop mappings to support both RNW <0.18 (aria-*) and
227
+ // new features added in >=0.18 (e.g. for accessibilityDisabled).
228
+
229
+
230
+ rwnPropMappings.accessibilityValue = function () {
231
+ let {
232
+ max,
233
+ min,
234
+ now,
235
+ text
236
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
237
+ return { ...mapIfDefined(max, rwnPropMappings.accessibilityValueMax),
238
+ ...mapIfDefined(min, rwnPropMappings.accessibilityValueMin),
239
+ ...mapIfDefined(now, rwnPropMappings.accessibilityValueNow),
240
+ ...mapIfDefined(text, rwnPropMappings.accessibilityValueText)
241
+ };
242
+ };
243
+
244
+ rwnPropMappings.accessibilityState = function () {
245
+ let {
246
+ busy,
247
+ checked,
248
+ disabled,
249
+ expanded,
250
+ selected
251
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
252
+ return { ...mapIfDefined(busy, rwnPropMappings.accessibilityBusy),
253
+ ...mapIfDefined(checked, rwnPropMappings.accessibilityChecked),
254
+ ...mapIfDefined(disabled, rwnPropMappings.accessibilityDisabled),
255
+ ...mapIfDefined(expanded, rwnPropMappings.accessibilityExpanded),
256
+ ...mapIfDefined(selected, rwnPropMappings.accessibilitySelected)
257
+ };
258
+ };
259
+ }
260
+
98
261
  var _default = {
99
262
  /**
100
263
  * Proptypes for recognised React Native accessiblity (a11y) props.
@@ -108,7 +271,14 @@ var _default = {
108
271
  * Where components accept React Native a11y props, pass { ...rest } from its props to this,
109
272
  * then spread the returned object into the component's props (usually its outer container).
110
273
  */
111
- select: (0, _getPropSelector.default)(a11yPropTypes, /^aria-/),
274
+ select: (0, _getPropSelector.default)( // Allow all React Native accessibility props
275
+ a11yPropTypesByPlatform, // Allow any `aria-*` attribute on web; ignore them on native
276
+ _Platform.default.OS === 'web' && /^aria-/, // For the props added and deprecated in React Native Web 0.18, convert them to
277
+ // a form that is platform-appropriate and RNW-version safe
278
+ (key, value) => {
279
+ const rnwPropMapper = rwnPropMappings[key];
280
+ return rnwPropMapper ? rnwPropMapper(value) : undefined;
281
+ }),
112
282
 
113
283
  /**
114
284
  * Use this to disable focus for elements which are visually hidden but still rendered.
@@ -5,12 +5,54 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = getPropSelector;
7
7
 
8
- function getPropSelector(propTypes, regexp) {
9
- const keys = Object.keys(propTypes);
8
+ var _lodash = _interopRequireDefault(require("lodash.merge"));
9
+
10
+ var _hasOwnProperty = _interopRequireDefault(require("../hasOwnProperty"));
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+
14
+ /**
15
+ * @callback PropSelectorCallback - a callback called for each prop passed to a component
16
+ * @param {string} key - the key for the prop to be tested
17
+ * @param {*} value - the value of the prop being passed in to the component
18
+ * @returns {object|undefined}
19
+ */
20
+
21
+ /**
22
+ * @param {PropSelectorCallback} callback
23
+ * @param {object} items
24
+ * @param {string} key
25
+ * @param {*} value
26
+ * @returns {object|undefined}
27
+ */
28
+ const applyCallback = (callback, items, key, value) => {
29
+ // If there's no callback, continue and look up keys as normal
30
+ if (typeof callback !== 'function') return undefined;
31
+ const newItems = callback(key, value); // If the callback doesn't return anything, continue and look up keys as normal
32
+
33
+ if (!newItems) return undefined; // If the callback returns items, merge them in, deep merging props that are objects
34
+
35
+ return (0, _lodash.default)({}, items, newItems);
36
+ };
37
+ /**
38
+ * Generates a function to filter an object of props down to a subset of allowed props, with
39
+ * optional prop alteration and re-mapping via an optional callback.
40
+ *
41
+ * @param {object} propTypes - an object where every defined key is a valid prop
42
+ * @param {*} [regexp] - an optional regular expression where any match is a valid prop
43
+ * @param {PropSelectorCallback} callback - optional function taking `(key, value)` returning either undefined or an object of new props to merge in
44
+ * @returns {object} - valid props for this component
45
+ */
46
+
47
+
48
+ function getPropSelector(propTypes, regexp, callback) {
10
49
  return props => Object.entries(props).reduce((items, _ref) => {
11
50
  let [key, value] = _ref;
12
- return keys.includes(key) || regexp && regexp.test(key) ? { ...items,
13
- [key]: value
14
- } : items;
51
+ return (// If there's a callback and it matches something, applyCallback merges it in; return that
52
+ applyCallback(callback, items, key, value) || ( // If there's no callback match, check if this prop is valid and merge it in if it is
53
+ (0, _hasOwnProperty.default)(propTypes, key) || regexp && regexp.test(key) ? { ...items,
54
+ [key]: value
55
+ } : items)
56
+ );
15
57
  }, {});
16
58
  }
package/lib/utils/ssr.js CHANGED
@@ -3,10 +3,14 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getSSRStyles = exports.getReactNativeWebSSRStyles = void 0;
6
+ exports.ssrStyles = exports.getSSRStyles = exports.getReactNativeWebSSRStyles = exports.default = void 0;
7
+
8
+ var _react = _interopRequireDefault(require("react"));
7
9
 
8
10
  var _AppRegistry = _interopRequireDefault(require("react-native-web/dist/cjs/exports/AppRegistry"));
9
11
 
12
+ var _jsxRuntime = require("react/jsx-runtime");
13
+
10
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
15
 
12
16
  /** @typedef {import('react').ComponentType} ReactComponent */
@@ -14,6 +18,112 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
14
18
  /** @typedef {import('react').ReactElement} ReactElement */
15
19
 
16
20
  /**
21
+ * Returns object with `renderApp` and `getStyles` functions.
22
+ * Weave these into your app's server-side render process:
23
+ *
24
+ * - Call `renderApp` first to do the actual server-side render
25
+ * - After the render is complete, call `getStyles`
26
+ * - Include the style tags returned by `getStyles` in the SSR <head>
27
+ *
28
+ * @param {string} [appName] - optional unique identifier if ssrStyles is called multiple times for multiple apps
29
+ * @param {object} [options] -
30
+ * - `styleGetters`: optional array of additional style getter functions to call after render
31
+ * - `collectStyles`: optional function, takes the rendered app, returns either the same or a new app element
32
+ * @param {boolean} [options.styleGetters]
33
+ * @param {(ReactElement) => ReactElement} [options.collectStyles]
34
+ */
35
+ const ssrStyles = function () {
36
+ let appName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'UDS app';
37
+ let {
38
+ styleGetters = [],
39
+ collectStyles
40
+ } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
41
+ let hasAppRendered = false;
42
+ return {
43
+ /**
44
+ * Server-side-renders the provided app in a way that supports collecting
45
+ * styles for Styled Components and React Native Web stylesheets.
46
+ *
47
+ * @param {ReactComponent} App - the root component for the app
48
+ * @param {object} [props] - props for this render e.g. page routing props
49
+ * @param {object} [options] -
50
+ * - `renderedByRNW`: pass as true if the main render is by AppRegistry.runApplication from React Native
51
+ * - `WrapperComponent`: Component rendered with no props around app content and inside root tag
52
+ * @param {boolean} [options.renderedByRNW]
53
+ * @param {ReactComponent} [options.WrapperComponent]
54
+ *
55
+ * @returns {ReactElement} - the rendered app output
56
+ */
57
+ renderApp: function (App, props) {
58
+ let {
59
+ renderedByRNW = false,
60
+ WrapperComponent
61
+ } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
62
+
63
+ _AppRegistry.default.registerComponent(appName, () => App); // AppRegistry.getApplication renders the app in a container, and collects styles.
64
+
65
+
66
+ const {
67
+ element,
68
+ getStyleElement
69
+ } = _AppRegistry.default.getApplication(appName, {
70
+ WrapperComponent,
71
+ initialProps: props
72
+ });
73
+
74
+ let renderedApp = // React Native Web's AppRegistry.getApplication assumes the app is rendered using
75
+ // AppRegistry.runApplication and wraps it in <AppContainer>, which wraps the entire app
76
+ // in two outer containers resembling <View style={{ flex: 1 }} pointerEvents="box-none">.
77
+ // So, use that IF user says AppRegistry.runApplication will do the client-side render.
78
+ renderedByRNW && element || // If the live app is not rendered using AppRegistry.runApplication, we need to
79
+ // re-render it without the <AppContainer> wrapper, to avoid SSR mismatch errors.
80
+ // Default to this as many platforms (e.g. NextJS) will use their own renderers.
81
+ WrapperComponent ? /*#__PURE__*/(0, _jsxRuntime.jsx)(WrapperComponent, {
82
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(App, { ...props
83
+ })
84
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(App, { ...props
85
+ });
86
+
87
+ const getRNWStyle = () => getStyleElement({
88
+ key: 'react-native-stylesheet'
89
+ });
90
+
91
+ styleGetters.push(getRNWStyle);
92
+
93
+ if (typeof collectStyles === 'function') {
94
+ renderedApp = collectStyles(renderedApp);
95
+ }
96
+
97
+ hasAppRendered = true;
98
+ return renderedApp;
99
+ },
100
+
101
+ /**
102
+ * Turns styles collected during renderApp into an array of React elements of
103
+ * HTML <style> tags ready for insertion into the SSR HTML's <head>.
104
+ *
105
+ * Must be called after `renderApp` has completed.
106
+ *
107
+ * @param {...ReactElement} existingStyles - any existing style tag elements to merge in
108
+ * @returns {ReactElement[]} - flat array of <style> React elements
109
+ */
110
+ getStyles: function () {
111
+ if (!hasAppRendered) throw new Error('Called getStyles before renderApp in ssrStyles');
112
+
113
+ for (var _len = arguments.length, existingStyles = new Array(_len), _key = 0; _key < _len; _key++) {
114
+ existingStyles[_key] = arguments[_key];
115
+ }
116
+
117
+ return [...existingStyles, ...styleGetters.flatMap(getter => getter())];
118
+ }
119
+ };
120
+ };
121
+
122
+ exports.ssrStyles = ssrStyles;
123
+ var _default = ssrStyles;
124
+ /**
125
+ * @deprecated - use ssrStyles instead
126
+ *
17
127
  * Registers the app's root component with React Native Web and generates
18
128
  * the main <style> tag containing React Native Web stylesheet styles.
19
129
  *
@@ -21,6 +131,9 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
21
131
  * @param {string} [appName]
22
132
  * @returns {ReactElement[]}
23
133
  */
134
+
135
+ exports.default = _default;
136
+
24
137
  const getReactNativeWebSSRStyles = function (AppRoot) {
25
138
  let appName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'app';
26
139
 
@@ -33,6 +146,8 @@ const getReactNativeWebSSRStyles = function (AppRoot) {
33
146
  return [getStyleElement()];
34
147
  };
35
148
  /**
149
+ * @deprecated - use ssrStyles instead
150
+ *
36
151
  * Gets style tags for each currently supported CSS-in-JS library and returns
37
152
  * them alongside any existing style tags.
38
153
  *
@@ -9,9 +9,11 @@ var _systemConstants = require("@telus-uds/system-constants");
9
9
 
10
10
  var _ViewportProvider = require("../ViewportProvider");
11
11
 
12
- const hasOwn = (objectProp, key) => Object.prototype.hasOwnProperty.call(objectProp, key);
12
+ var _hasOwnProperty = _interopRequireDefault(require("./hasOwnProperty"));
13
13
 
14
- const hasResponsiveProperties = objectProp => _systemConstants.viewports.keys.some(key => hasOwn(objectProp, key));
14
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
+
16
+ const hasResponsiveProperties = objectProp => _systemConstants.viewports.keys.some(key => (0, _hasOwnProperty.default)(objectProp, key));
15
17
  /**
16
18
  * Resolves a prop which may be a responsive object with keys for viewports.
17
19
  *
@@ -29,7 +31,7 @@ const resolveResponsiveProp = (prop, viewport, defaultValue) => {
29
31
  if (!prop || typeof prop !== 'object' || !hasResponsiveProperties(prop)) return prop;
30
32
  const value = _systemConstants.viewports.keys.includes(viewport) ? // If there's a current viewport, return the closest match at or below it
31
33
  _systemConstants.viewports.inherit(prop)[viewport] : // If no current viewport is available, default to smallest viewport
32
- prop[_systemConstants.viewports.keys.find(key => hasOwn(prop, key))];
34
+ prop[_systemConstants.viewports.keys.find(key => (0, _hasOwnProperty.default)(prop, key))];
33
35
  return value === undefined ? defaultValue : value;
34
36
  };
35
37
  /**
@@ -9,6 +9,8 @@ var _react = _interopRequireWildcard(require("react"));
9
9
 
10
10
  var _propTypes = _interopRequireDefault(require("prop-types"));
11
11
 
12
+ var _hasOwnProperty = _interopRequireDefault(require("./hasOwnProperty"));
13
+
12
14
  var _jsxRuntime = require("react/jsx-runtime");
13
15
 
14
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -17,8 +19,6 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
17
19
 
18
20
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
19
21
 
20
- // Prototype-safe alternative to (linter-forbidden) someObject.hasOwnProperty()
21
- const hasOwnProperty = (object, prop) => Object.prototype.hasOwnProperty.call(object, prop);
22
22
  /**
23
23
  * Higher-order component that has no effect unless an additional prop `LinkRouter` is passed.
24
24
  * This may be used to provide custom wrappers for integrations with third party libraries.
@@ -47,8 +47,6 @@ const hasOwnProperty = (object, prop) => Object.prototype.hasOwnProperty.call(ob
47
47
  * <IconButton icon={SomeIcon} LinkRouter={LinkLinkRouter} linkRouterProps={{ to, options }} ref={iconRef} />
48
48
  * ```
49
49
  */
50
-
51
-
52
50
  const withLinkRouter = Component => {
53
51
  const wrappedComponent = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
54
52
  let {
@@ -84,7 +82,7 @@ const withLinkRouter = Component => {
84
82
 
85
83
  Object.keys(otherProperties).forEach(key => {
86
84
  // Skip internal React properties from wrappedComponent's forwardRef (render, $$typeof, etc)
87
- if (hasOwnProperty(Component, key) && !hasOwnProperty(wrappedComponent, key)) {
85
+ if ((0, _hasOwnProperty.default)(Component, key) && !(0, _hasOwnProperty.default)(wrappedComponent, key)) {
88
86
  wrappedComponent[key] = Component[key];
89
87
  }
90
88
  });
@@ -19,8 +19,8 @@ const A11yInfoProvider = _ref => {
19
19
  return () => {};
20
20
  }
21
21
 
22
- AccessibilityInfo.addEventListener('reduceMotionChanged', setReduceMotionEnabled);
23
- AccessibilityInfo.addEventListener('screenReaderChanged', setScreenReaderEnabled);
22
+ const motionSubscription = AccessibilityInfo.addEventListener('reduceMotionChanged', setReduceMotionEnabled);
23
+ const screenReaderSubscription = AccessibilityInfo.addEventListener('screenReaderChanged', setScreenReaderEnabled);
24
24
 
25
25
  const setInitialA11yInfo = async () => {
26
26
  const [initialReduceMotionEnabled, initialScreenReaderEnabled] = await Promise.all([AccessibilityInfo.isReduceMotionEnabled(), AccessibilityInfo.isScreenReaderEnabled()]); // Browsers can't detect screen readers; in RNW isScreenReaderEnabled() is always `true`
@@ -36,8 +36,18 @@ const A11yInfoProvider = _ref => {
36
36
  }
37
37
 
38
38
  return () => {
39
- AccessibilityInfo.removeEventListener('reduceMotionChanged', setReduceMotionEnabled);
40
- AccessibilityInfo.removeEventListener('screenReaderChanged', setScreenReaderEnabled);
39
+ // From react-native 0.65, AccessibilityInfo.removeEventListener is deprecated for `remove` on addEventListener return value
40
+ if (typeof (motionSubscription === null || motionSubscription === void 0 ? void 0 : motionSubscription.remove) === 'function') {
41
+ motionSubscription === null || motionSubscription === void 0 ? void 0 : motionSubscription.remove();
42
+ } else if (typeof AccessibilityInfo.removeEventListener === 'function') {
43
+ AccessibilityInfo.removeEventListener('reduceMotionChanged', setReduceMotionEnabled);
44
+ }
45
+
46
+ if (typeof (screenReaderSubscription === null || screenReaderSubscription === void 0 ? void 0 : screenReaderSubscription.remove) === 'function') {
47
+ screenReaderSubscription === null || screenReaderSubscription === void 0 ? void 0 : screenReaderSubscription.remove();
48
+ } else if (typeof AccessibilityInfo.removeEventListener === 'function') {
49
+ AccessibilityInfo.removeEventListener('screenReaderChanged', setScreenReaderEnabled);
50
+ }
41
51
  };
42
52
  }, []);
43
53
  return /*#__PURE__*/_jsx(ReducedMotionContext.Provider, {
@@ -130,8 +130,9 @@ const ButtonGroup = /*#__PURE__*/forwardRef((_ref, ref) => {
130
130
  tokens: getButtonTokens,
131
131
  selected: isSelected,
132
132
  inactive: inactive,
133
- ...itemA11y,
134
- ...selectItemProps(itemRest),
133
+ ...selectItemProps({ ...itemRest,
134
+ ...itemA11y
135
+ }),
135
136
  children: label
136
137
  }, id);
137
138
  })