@telus-uds/components-base 1.10.0 → 1.12.1

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 (117) hide show
  1. package/CHANGELOG.md +37 -3
  2. package/component-docs.json +413 -62
  3. package/lib/BaseProvider/index.js +7 -2
  4. package/lib/Button/ButtonBase.js +18 -14
  5. package/lib/Carousel/Carousel.js +92 -71
  6. package/lib/Carousel/CarouselContext.js +12 -4
  7. package/lib/Carousel/CarouselItem/CarouselItem.js +24 -9
  8. package/lib/Carousel/CarouselStepTracker/CarouselStepTracker.js +56 -0
  9. package/lib/Carousel/CarouselStepTracker/index.js +13 -0
  10. package/lib/Carousel/dictionary.js +23 -0
  11. package/lib/Checkbox/Checkbox.js +7 -3
  12. package/lib/Checkbox/CheckboxGroup.js +1 -1
  13. package/lib/Feedback/Feedback.js +18 -10
  14. package/lib/Icon/IconText.js +5 -0
  15. package/lib/InputLabel/InputLabel.js +11 -5
  16. package/lib/InputSupports/InputSupports.js +10 -3
  17. package/lib/InputSupports/useInputSupports.js +3 -2
  18. package/lib/Link/LinkBase.js +7 -3
  19. package/lib/List/ListItem.js +7 -3
  20. package/lib/Modal/Modal.js +4 -0
  21. package/lib/Notification/Notification.js +7 -2
  22. package/lib/Pagination/Pagination.js +7 -3
  23. package/lib/RadioCard/RadioCard.js +6 -1
  24. package/lib/Select/Select.js +7 -3
  25. package/lib/Skeleton/Skeleton.js +1 -0
  26. package/lib/StepTracker/Step.js +8 -4
  27. package/lib/StepTracker/StepTracker.js +17 -13
  28. package/lib/Tabs/TabsItem.js +4 -0
  29. package/lib/TextInput/TextInput.js +3 -1
  30. package/lib/TextInput/TextInputBase.js +7 -3
  31. package/lib/ThemeProvider/ThemeProvider.js +20 -3
  32. package/lib/ThemeProvider/utils/styles.js +8 -1
  33. package/lib/ThemeProvider/utils/theme-tokens.js +1 -1
  34. package/lib/Typography/Typography.js +6 -2
  35. package/lib/index.js +9 -0
  36. package/lib/utils/index.js +9 -0
  37. package/lib/utils/props/clickProps.js +2 -2
  38. package/lib/utils/props/handlerProps.js +77 -31
  39. package/lib/utils/useScrollBlocking.js +66 -0
  40. package/lib/utils/useScrollBlocking.native.js +11 -0
  41. package/lib-module/BaseProvider/index.js +7 -2
  42. package/lib-module/Button/ButtonBase.js +7 -3
  43. package/lib-module/Carousel/Carousel.js +85 -70
  44. package/lib-module/Carousel/CarouselContext.js +11 -4
  45. package/lib-module/Carousel/CarouselItem/CarouselItem.js +25 -10
  46. package/lib-module/Carousel/CarouselStepTracker/CarouselStepTracker.js +42 -0
  47. package/lib-module/Carousel/CarouselStepTracker/index.js +2 -0
  48. package/lib-module/Carousel/dictionary.js +16 -0
  49. package/lib-module/Checkbox/Checkbox.js +8 -4
  50. package/lib-module/Checkbox/CheckboxGroup.js +1 -1
  51. package/lib-module/Feedback/Feedback.js +19 -11
  52. package/lib-module/Icon/IconText.js +5 -0
  53. package/lib-module/InputLabel/InputLabel.js +12 -6
  54. package/lib-module/InputSupports/InputSupports.js +10 -3
  55. package/lib-module/InputSupports/useInputSupports.js +3 -2
  56. package/lib-module/Link/LinkBase.js +8 -4
  57. package/lib-module/List/ListItem.js +8 -4
  58. package/lib-module/Modal/Modal.js +3 -0
  59. package/lib-module/Notification/Notification.js +8 -3
  60. package/lib-module/Pagination/Pagination.js +8 -4
  61. package/lib-module/RadioCard/RadioCard.js +7 -2
  62. package/lib-module/Select/Select.js +8 -4
  63. package/lib-module/Skeleton/Skeleton.js +1 -0
  64. package/lib-module/StepTracker/Step.js +9 -5
  65. package/lib-module/StepTracker/StepTracker.js +17 -14
  66. package/lib-module/Tabs/TabsItem.js +5 -1
  67. package/lib-module/TextInput/TextInput.js +3 -1
  68. package/lib-module/TextInput/TextInputBase.js +8 -4
  69. package/lib-module/ThemeProvider/ThemeProvider.js +20 -3
  70. package/lib-module/ThemeProvider/utils/styles.js +8 -1
  71. package/lib-module/ThemeProvider/utils/theme-tokens.js +1 -1
  72. package/lib-module/Typography/Typography.js +7 -3
  73. package/lib-module/index.js +1 -0
  74. package/lib-module/utils/index.js +1 -0
  75. package/lib-module/utils/props/clickProps.js +2 -2
  76. package/lib-module/utils/props/handlerProps.js +78 -31
  77. package/lib-module/utils/useScrollBlocking.js +58 -0
  78. package/lib-module/utils/useScrollBlocking.native.js +2 -0
  79. package/package.json +3 -3
  80. package/src/BaseProvider/index.jsx +6 -3
  81. package/src/Button/ButtonBase.jsx +8 -3
  82. package/src/Carousel/Carousel.jsx +106 -74
  83. package/src/Carousel/CarouselContext.jsx +15 -4
  84. package/src/Carousel/CarouselItem/CarouselItem.jsx +26 -8
  85. package/src/Carousel/CarouselStepTracker/CarouselStepTracker.jsx +36 -0
  86. package/src/Carousel/CarouselStepTracker/index.js +3 -0
  87. package/src/Carousel/dictionary.js +16 -0
  88. package/src/Checkbox/Checkbox.jsx +14 -11
  89. package/src/Checkbox/CheckboxGroup.jsx +1 -1
  90. package/src/Feedback/Feedback.jsx +14 -7
  91. package/src/Icon/IconText.jsx +2 -0
  92. package/src/InputLabel/InputLabel.jsx +13 -12
  93. package/src/InputSupports/InputSupports.jsx +18 -3
  94. package/src/InputSupports/useInputSupports.js +2 -2
  95. package/src/Link/LinkBase.jsx +10 -4
  96. package/src/List/ListItem.jsx +9 -4
  97. package/src/Modal/Modal.jsx +3 -1
  98. package/src/Notification/Notification.jsx +5 -3
  99. package/src/Pagination/Pagination.jsx +6 -4
  100. package/src/RadioCard/RadioCard.jsx +3 -2
  101. package/src/Select/Select.jsx +12 -3
  102. package/src/Skeleton/Skeleton.jsx +1 -0
  103. package/src/StepTracker/Step.jsx +12 -4
  104. package/src/StepTracker/StepTracker.jsx +20 -13
  105. package/src/Tabs/TabsItem.jsx +3 -2
  106. package/src/TextInput/TextInput.jsx +1 -1
  107. package/src/TextInput/TextInputBase.jsx +11 -3
  108. package/src/ThemeProvider/ThemeProvider.jsx +16 -3
  109. package/src/ThemeProvider/utils/styles.js +9 -1
  110. package/src/ThemeProvider/utils/theme-tokens.js +1 -1
  111. package/src/Typography/Typography.jsx +11 -12
  112. package/src/index.js +1 -0
  113. package/src/utils/index.js +1 -0
  114. package/src/utils/props/clickProps.js +2 -2
  115. package/src/utils/props/handlerProps.js +64 -16
  116. package/src/utils/useScrollBlocking.js +57 -0
  117. package/src/utils/useScrollBlocking.native.js +2 -0
@@ -158,6 +158,6 @@ export const validateThemeTokensVersion = theme => {
158
158
  const actualThemeTokensVersion = theme === null || theme === void 0 ? void 0 : (_theme$metadata2 = theme.metadata) === null || _theme$metadata2 === void 0 ? void 0 : _theme$metadata2.themeTokensVersion;
159
159
 
160
160
  if (!semVerSatisfies(actualThemeTokensVersion, expectedThemeTokensVersion)) {
161
- throw new Error("Invalid UDS token schema version detected.\n\nThe UDS base components ".concat(pkg.name, " v").concat(pkg.version, " are only compatible with UDS themes that are built with @telus-uds/system-theme-tokens version that is semver compatible with ").concat(expectedThemeTokensVersion, ". The current theme was built with @telus-uds/system-theme-tokens v").concat(actualThemeTokensVersion, ".\n\nIf you see this error than most likely you have attempted to install ").concat(pkg.name, " and a UDS theme manually because you are building a multi-brand application. If you are building a single brand application, consider installing the brand specific design system package such as @telus-uds/ds-allium. For more information, see https://github.com/telus/universal-design-system/blob/main/packages/docs-uds/docs/multi-brand-usage.md"));
161
+ throw new Error("Invalid UDS token schema version detected.\n\nThe UDS base components ".concat(pkg.name, " v").concat(pkg.version, " are only compatible with UDS themes that are built with @telus-uds/system-theme-tokens version that is semver compatible with ").concat(expectedThemeTokensVersion, ". The current theme was built with @telus-uds/system-theme-tokens v").concat(actualThemeTokensVersion, ".\n\nIf you see this error than most likely you have attempted to install ").concat(pkg.name, " and a UDS theme manually because you are building a multi-brand application. If you are building a single brand application, consider installing the brand specific design system package such as @telus-uds/ds-allium. For more information, see https://github.com/telus/universal-design-system/blob/main/docs/docs/multi-brand-usage.md"));
162
162
  }
163
163
  };
@@ -2,7 +2,7 @@ import React, { forwardRef } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import Text from "react-native-web/dist/exports/Text";
4
4
  import View from "react-native-web/dist/exports/View";
5
- import { useThemeTokens } from '../ThemeProvider';
5
+ import { useTheme, useThemeTokens } from '../ThemeProvider';
6
6
  import { useViewport } from '../ViewportProvider';
7
7
  import { applyTextStyles } from '../ThemeProvider/utils';
8
8
  import { a11yProps, variantProp, getTokensPropType, getMaxFontMultiplier, headingTags, selectSystemProps, textTags, textProps, viewProps, getA11yPropsFromHtmlTag } from '../utils';
@@ -14,7 +14,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
14
14
  const [selectContainerProps, selectedContainerPropTypes] = selectSystemProps([a11yProps, viewProps]);
15
15
  const [selectTextProps, selectedTextPropTypes] = selectSystemProps([textProps]);
16
16
 
17
- const selectTextStyles = _ref => {
17
+ const selectTextStyles = (_ref, themeOptions) => {
18
18
  let {
19
19
  fontWeight,
20
20
  fontSize,
@@ -31,6 +31,7 @@ const selectTextStyles = _ref => {
31
31
  color,
32
32
  lineHeight,
33
33
  fontName,
34
+ themeOptions,
34
35
  textAlign,
35
36
  textTransform,
36
37
  letterSpacing
@@ -55,10 +56,13 @@ const Typography = /*#__PURE__*/forwardRef((_ref2, ref) => {
55
56
  const themeTokens = useThemeTokens('Typography', tokens, variant, {
56
57
  viewport
57
58
  });
59
+ const {
60
+ themeOptions
61
+ } = useTheme();
58
62
  const resolvedTextProps = { ...selectTextProps(rest),
59
63
  style: selectTextStyles(align ? { ...themeTokens,
60
64
  textAlign: align
61
- } : themeTokens),
65
+ } : themeTokens, themeOptions),
62
66
  dataSet,
63
67
  maxFontSizeMultiplier: getMaxFontMultiplier(themeTokens)
64
68
  };
@@ -17,6 +17,7 @@ export { default as Icon } from './Icon';
17
17
  export * from './Icon';
18
18
  export { default as IconButton } from './IconButton';
19
19
  export { default as InputLabel } from './InputLabel';
20
+ export { default as InputSupports } from './InputSupports';
20
21
  export * from './Link';
21
22
  export { default as List, ListItem, ListBase } from './List';
22
23
  export { default as Modal } from './Modal';
@@ -9,6 +9,7 @@ export { default as useCopy } from './useCopy';
9
9
  export { default as useHash } from './useHash';
10
10
  export { default as useSpacingScale } from './useSpacingScale';
11
11
  export { default as useResponsiveProp } from './useResponsiveProp';
12
+ export { default as useScrollBlocking } from './useScrollBlocking';
12
13
  export * from './useResponsiveProp';
13
14
  export { default as useUniqueId } from './useUniqueId';
14
15
  export { default as withLinkRouter } from './withLinkRouter';
@@ -1,8 +1,8 @@
1
1
  import PropTypes from 'prop-types';
2
2
  const clickHandlerMapping = {
3
3
  onClick: 'onPress',
4
- mouseDown: 'onPressIn',
5
- mouseUp: 'onPressOut'
4
+ onMouseDown: 'onPressIn',
5
+ onMouseUp: 'onPressOut'
6
6
  };
7
7
  export default {
8
8
  /**
@@ -1,5 +1,7 @@
1
1
  import PropTypes from 'prop-types';
2
- export const focusHandlerProps = {
2
+ import Platform from "react-native-web/dist/exports/Platform";
3
+ import getPropSelector from './getPropSelector';
4
+ const focusHandlerProps = {
3
5
  types: {
4
6
  /**
5
7
  * onBlur handler
@@ -10,19 +12,10 @@ export const focusHandlerProps = {
10
12
  * onFocus handler
11
13
  */
12
14
  onFocus: PropTypes.func
13
- },
14
- select: _ref => {
15
- let {
16
- onBlur,
17
- onFocus
18
- } = _ref;
19
- return {
20
- onBlur,
21
- onFocus
22
- };
23
15
  }
24
16
  };
25
- export const textInputHandlerProps = {
17
+ focusHandlerProps.select = getPropSelector(focusHandlerProps.types);
18
+ const textInputHandlerProps = {
26
19
  types: {
27
20
  /**
28
21
  * onChange handler
@@ -42,24 +35,78 @@ export const textInputHandlerProps = {
42
35
  /**
43
36
  * onSubmitEditing handler
44
37
  */
45
- onSubmitEditing: PropTypes.func
46
- },
47
- select: _ref2 => {
48
- let {
49
- onChange,
50
- onChangeText,
51
- onSubmit,
52
- onSubmitEditing
53
- } = _ref2;
54
- return {
55
- onChange,
56
- onChangeText,
57
- onSubmit,
58
- onSubmitEditing
59
- };
38
+ onSubmitEditing: PropTypes.func,
39
+
40
+ /**
41
+ * onContentSizeChange handler
42
+ */
43
+ onContentSizeChange: PropTypes.func,
44
+
45
+ /**
46
+ * onEndEditing handler
47
+ */
48
+ onEndEditing: PropTypes.func,
49
+
50
+ /**
51
+ * onScroll handler
52
+ */
53
+ onScroll: PropTypes.func,
54
+
55
+ /**
56
+ * onSelectionChange handler
57
+ */
58
+ onSelectionChange: PropTypes.func,
59
+
60
+ /**
61
+ * onKeyPress handler
62
+ */
63
+ onKeyPress: PropTypes.func,
64
+
65
+ /**
66
+ * onKeyUp handler (only supported on Web)
67
+ */
68
+ onKeyUp: PropTypes.func,
69
+
70
+ /**
71
+ * onKeyDown handler (only supported on Web)
72
+ */
73
+ onKeyDown: PropTypes.func
60
74
  }
61
75
  };
62
- export default {
63
- focusHandlerProps,
64
- textInputHandlerProps
65
- };
76
+ const selectTextInputHandlers = getPropSelector(textInputHandlerProps.types);
77
+
78
+ textInputHandlerProps.select = props => {
79
+ // Support for onKeyPress/onKeyUp/onKeyDown is inconsistent between React Native and React Native Web
80
+ const {
81
+ onKeyPress,
82
+ onKeyUp,
83
+ onKeyDown,
84
+ ...resolvedProps
85
+ } = selectTextInputHandlers(props);
86
+
87
+ if (onKeyPress || onKeyUp || onKeyDown) {
88
+ if (Platform.OS !== 'web') {
89
+ // React Native only supports onKeyPress. Call any key handlers supplied in expected order.
90
+ resolvedProps.onKeyPress = event => {
91
+ if (typeof onKeyDown === 'function') onKeyDown(event);
92
+ if (typeof onKeyPress === 'function') onKeyPress(event);
93
+ if (typeof onKeyUp === 'function') onKeyUp(event);
94
+ };
95
+ } else {
96
+ // React Native Web supports onKeyUp the normal way.
97
+ if (onKeyUp) resolvedProps.onKeyUp = onKeyUp; // React Native Web doesn't support the `onKeyDown` prop name, but maps a supplied onKeyPress handler
98
+ // to the onKeyDown event and calls it with a keydown event. Make React Native Web call either or both.
99
+
100
+ if (onKeyPress || onKeyDown) {
101
+ resolvedProps.onKeyPress = event => {
102
+ if (typeof onKeyDown === 'function') onKeyDown(event);
103
+ if (typeof onKeyPress === 'function') onKeyPress(event);
104
+ };
105
+ }
106
+ }
107
+ }
108
+
109
+ return resolvedProps;
110
+ };
111
+
112
+ export { focusHandlerProps, textInputHandlerProps };
@@ -0,0 +1,58 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react';
2
+
3
+ const addScrollBlocking = (preventScrolling, stopPropagation, ref) => {
4
+ var _ref$current;
5
+
6
+ document.body.addEventListener('touchmove', preventScrolling, {
7
+ passive: false
8
+ });
9
+ (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.addEventListener('touchmove', stopPropagation);
10
+ document.body.style.overflow = 'hidden';
11
+ };
12
+
13
+ const removeScrollBlocking = (preventScrolling, stopPropagation, ref) => {
14
+ var _ref$current2;
15
+
16
+ document.body.removeEventListener('touchmove', preventScrolling);
17
+ (_ref$current2 = ref.current) === null || _ref$current2 === void 0 ? void 0 : _ref$current2.removeEventListener('touchmove', stopPropagation);
18
+ document.body.style.overflow = 'inherit';
19
+ };
20
+ /**
21
+ * Disables scrolling when passed `true` or an array where all items are `true`.
22
+ *
23
+ * Returns an optional callback ref. Pass this to an element if it or its children
24
+ * should allow touch-based scrolling within that element's bounds.
25
+ *
26
+ * @param {boolean | boolean[]} conditionProps
27
+ * @returns
28
+ */
29
+
30
+
31
+ const useScrollBlocking = conditionProps => {
32
+ // useRef refs are null on first render and don't trigger a re-render when they get their
33
+ // element. Force re-run when ref mounts to ensure the stopPropagation listener is attached.
34
+ const ref = useRef();
35
+ const [refIsMounted, setRefIsMounted] = useState(false);
36
+ const callbackRef = useCallback(element => {
37
+ ref.current = element;
38
+ setRefIsMounted(Boolean(element));
39
+ }, []);
40
+ const conditionsMet = Array.isArray(conditionProps) ? conditionProps.every(condition => condition) : Boolean(conditionProps);
41
+ const preventScrolling = useCallback(event => event.preventDefault(), []);
42
+ const stopPropagation = useCallback(event => event.stopPropagation(), []);
43
+ useEffect(() => {
44
+ const cleanup = () => removeScrollBlocking(preventScrolling, stopPropagation, ref);
45
+
46
+ if (conditionsMet) {
47
+ addScrollBlocking(preventScrolling, stopPropagation, ref);
48
+ } else {
49
+ cleanup();
50
+ }
51
+
52
+ return cleanup; // preventScrolling and stopPropagation are stable callbacks with no deps, so this
53
+ // will re-run when conditionsMet or refIsMounted flip between true and false.
54
+ }, [preventScrolling, conditionsMet, stopPropagation, refIsMounted]);
55
+ return callbackRef;
56
+ };
57
+
58
+ export default useScrollBlocking;
@@ -0,0 +1,2 @@
1
+ // This is a no-op to emphasize that the original hook is web-only
2
+ export default (() => {});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telus-uds/components-base",
3
- "version": "1.10.0",
3
+ "version": "1.12.1",
4
4
  "description": "Base components",
5
5
  "keywords": [
6
6
  "base"
@@ -46,8 +46,8 @@
46
46
  "peerDependencies": {
47
47
  "react": "^17.0.2",
48
48
  "react-dom": "^17.0.2",
49
- "react-native": "0.68.2",
50
- "react-native-web": "^0.17.0"
49
+ "react-native": "*",
50
+ "react-native-web": "~0.17.5"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@storybook/addon-a11y": "^6.5.6",
@@ -4,17 +4,20 @@ import A11yInfoProvider from '../A11yInfoProvider'
4
4
  import ViewportProvider from '../ViewportProvider'
5
5
  import ThemeProvider from '../ThemeProvider'
6
6
 
7
- const BaseProvider = ({ defaultTheme, children }) => (
7
+ const BaseProvider = ({ defaultTheme, children, themeOptions }) => (
8
8
  <A11yInfoProvider>
9
9
  <ViewportProvider>
10
- <ThemeProvider defaultTheme={defaultTheme}>{children}</ThemeProvider>
10
+ <ThemeProvider defaultTheme={defaultTheme} themeOptions={themeOptions}>
11
+ {children}
12
+ </ThemeProvider>
11
13
  </ViewportProvider>
12
14
  </A11yInfoProvider>
13
15
  )
14
16
 
15
17
  BaseProvider.propTypes = {
18
+ children: PropTypes.node.isRequired,
16
19
  defaultTheme: ThemeProvider.propTypes?.defaultTheme,
17
- children: PropTypes.node.isRequired
20
+ themeOptions: PropTypes.shape({ forceAbsoluteFontSizing: PropTypes.bool })
18
21
  }
19
22
 
20
23
  export default BaseProvider
@@ -2,7 +2,7 @@ import React, { forwardRef } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import { Pressable, View, StyleSheet, Platform } from 'react-native'
4
4
 
5
- import { applyTextStyles, applyShadowToken, applyOuterBorder } from '../ThemeProvider/utils'
5
+ import { applyTextStyles, applyShadowToken, applyOuterBorder, useTheme } from '../ThemeProvider'
6
6
  import buttonPropTypes from './propTypes'
7
7
  import {
8
8
  a11yProps,
@@ -121,13 +121,17 @@ const selectBorderStyles = ({ borderColor, borderWidth, borderRadius }) => ({
121
121
  borderRadius
122
122
  })
123
123
 
124
- const selectTextStyles = ({ fontSize, color, lineHeight, fontName, fontWeight, textAlign }) =>
124
+ const selectTextStyles = (
125
+ { fontSize, color, lineHeight, fontName, fontWeight, textAlign },
126
+ themeOptions
127
+ ) =>
125
128
  applyTextStyles({
126
129
  fontSize,
127
130
  color,
128
131
  lineHeight,
129
132
  fontName,
130
133
  fontWeight,
134
+ themeOptions,
131
135
  textAlign
132
136
  })
133
137
 
@@ -174,6 +178,7 @@ const ButtonBase = forwardRef(
174
178
  selectOuterWidthStyles(themeTokens)
175
179
  ]
176
180
  }
181
+ const { themeOptions } = useTheme()
177
182
 
178
183
  return (
179
184
  <Pressable
@@ -189,7 +194,7 @@ const ButtonBase = forwardRef(
189
194
  const themeTokens = resolveButtonTokens(pressableState)
190
195
  const containerStyles = selectInnerContainerStyles(themeTokens)
191
196
  const borderStyles = selectBorderStyles(themeTokens)
192
- const textStyles = [selectTextStyles(themeTokens), staticStyles.text]
197
+ const textStyles = [selectTextStyles(themeTokens, themeOptions), staticStyles.text]
193
198
 
194
199
  // If the container has a width set, fill it instead of sizing from content.
195
200
  // If in future we support text alignments other than center, add here.