@telus-uds/components-base 1.10.0 → 1.11.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 (45) hide show
  1. package/CHANGELOG.md +21 -3
  2. package/component-docs.json +346 -51
  3. package/lib/Carousel/Carousel.js +81 -28
  4. package/lib/Carousel/CarouselItem/CarouselItem.js +24 -9
  5. package/lib/Carousel/dictionary.js +23 -0
  6. package/lib/InputSupports/InputSupports.js +10 -3
  7. package/lib/InputSupports/useInputSupports.js +3 -2
  8. package/lib/Modal/Modal.js +4 -0
  9. package/lib/Skeleton/Skeleton.js +1 -0
  10. package/lib/StepTracker/StepTracker.js +10 -10
  11. package/lib/TextInput/TextInput.js +3 -1
  12. package/lib/index.js +9 -0
  13. package/lib/utils/props/clickProps.js +2 -2
  14. package/lib/utils/props/handlerProps.js +77 -31
  15. package/lib/utils/useScrollBlocking.js +66 -0
  16. package/lib/utils/useScrollBlocking.native.js +11 -0
  17. package/lib-module/Carousel/Carousel.js +76 -29
  18. package/lib-module/Carousel/CarouselItem/CarouselItem.js +25 -10
  19. package/lib-module/Carousel/dictionary.js +16 -0
  20. package/lib-module/InputSupports/InputSupports.js +10 -3
  21. package/lib-module/InputSupports/useInputSupports.js +3 -2
  22. package/lib-module/Modal/Modal.js +3 -0
  23. package/lib-module/Skeleton/Skeleton.js +1 -0
  24. package/lib-module/StepTracker/StepTracker.js +9 -10
  25. package/lib-module/TextInput/TextInput.js +3 -1
  26. package/lib-module/index.js +1 -0
  27. package/lib-module/utils/props/clickProps.js +2 -2
  28. package/lib-module/utils/props/handlerProps.js +78 -31
  29. package/lib-module/utils/useScrollBlocking.js +58 -0
  30. package/lib-module/utils/useScrollBlocking.native.js +2 -0
  31. package/package.json +3 -3
  32. package/src/Carousel/Carousel.jsx +93 -30
  33. package/src/Carousel/CarouselItem/CarouselItem.jsx +26 -8
  34. package/src/Carousel/dictionary.js +16 -0
  35. package/src/InputSupports/InputSupports.jsx +18 -3
  36. package/src/InputSupports/useInputSupports.js +2 -2
  37. package/src/Modal/Modal.jsx +3 -1
  38. package/src/Skeleton/Skeleton.jsx +1 -0
  39. package/src/StepTracker/StepTracker.jsx +9 -3
  40. package/src/TextInput/TextInput.jsx +1 -1
  41. package/src/index.js +1 -0
  42. package/src/utils/props/clickProps.js +2 -2
  43. package/src/utils/props/handlerProps.js +64 -16
  44. package/src/utils/useScrollBlocking.js +57 -0
  45. package/src/utils/useScrollBlocking.native.js +2 -0
@@ -51,7 +51,7 @@ const TextInput = forwardRef(({ tokens, variant = {}, ...rest }, ref) => {
51
51
  }
52
52
 
53
53
  return (
54
- <InputSupports {...supportsProps}>
54
+ <InputSupports nativeID={selectedProps.nativeID} {...supportsProps}>
55
55
  {({ inputId, ...props }) => (
56
56
  <TextInputBase ref={ref} {...inputProps} nativeID={inputId} {...props} />
57
57
  )}
package/src/index.js CHANGED
@@ -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'
@@ -2,8 +2,8 @@ import PropTypes from 'prop-types'
2
2
 
3
3
  const clickHandlerMapping = {
4
4
  onClick: 'onPress',
5
- mouseDown: 'onPressIn',
6
- mouseUp: 'onPressOut'
5
+ onMouseDown: 'onPressIn',
6
+ onMouseUp: 'onPressOut'
7
7
  }
8
8
 
9
9
  export default {
@@ -1,6 +1,8 @@
1
1
  import PropTypes from 'prop-types'
2
+ import { Platform } from 'react-native'
3
+ import getPropSelector from './getPropSelector'
2
4
 
3
- export const focusHandlerProps = {
5
+ const focusHandlerProps = {
4
6
  types: {
5
7
  /**
6
8
  * onBlur handler
@@ -10,14 +12,11 @@ export const focusHandlerProps = {
10
12
  * onFocus handler
11
13
  */
12
14
  onFocus: PropTypes.func
13
- },
14
- select: ({ onBlur, onFocus }) => ({
15
- onBlur,
16
- onFocus
17
- })
15
+ }
18
16
  }
17
+ focusHandlerProps.select = getPropSelector(focusHandlerProps.types)
19
18
 
20
- export const textInputHandlerProps = {
19
+ const textInputHandlerProps = {
21
20
  types: {
22
21
  /**
23
22
  * onChange handler
@@ -34,14 +33,63 @@ export const textInputHandlerProps = {
34
33
  /**
35
34
  * onSubmitEditing handler
36
35
  */
37
- onSubmitEditing: PropTypes.func
38
- },
39
- select: ({ onChange, onChangeText, onSubmit, onSubmitEditing }) => ({
40
- onChange,
41
- onChangeText,
42
- onSubmit,
43
- onSubmitEditing
44
- })
36
+ onSubmitEditing: PropTypes.func,
37
+ /**
38
+ * onContentSizeChange handler
39
+ */
40
+ onContentSizeChange: PropTypes.func,
41
+ /**
42
+ * onEndEditing handler
43
+ */
44
+ onEndEditing: PropTypes.func,
45
+ /**
46
+ * onScroll handler
47
+ */
48
+ onScroll: PropTypes.func,
49
+ /**
50
+ * onSelectionChange handler
51
+ */
52
+ onSelectionChange: PropTypes.func,
53
+ /**
54
+ * onKeyPress handler
55
+ */
56
+ onKeyPress: PropTypes.func,
57
+ /**
58
+ * onKeyUp handler (only supported on Web)
59
+ */
60
+ onKeyUp: PropTypes.func,
61
+ /**
62
+ * onKeyDown handler (only supported on Web)
63
+ */
64
+ onKeyDown: PropTypes.func
65
+ }
66
+ }
67
+ const selectTextInputHandlers = getPropSelector(textInputHandlerProps.types)
68
+ textInputHandlerProps.select = (props) => {
69
+ // Support for onKeyPress/onKeyUp/onKeyDown is inconsistent between React Native and React Native Web
70
+ const { onKeyPress, onKeyUp, onKeyDown, ...resolvedProps } = selectTextInputHandlers(props)
71
+ if (onKeyPress || onKeyUp || onKeyDown) {
72
+ if (Platform.OS !== 'web') {
73
+ // React Native only supports onKeyPress. Call any key handlers supplied in expected order.
74
+ resolvedProps.onKeyPress = (event) => {
75
+ if (typeof onKeyDown === 'function') onKeyDown(event)
76
+ if (typeof onKeyPress === 'function') onKeyPress(event)
77
+ if (typeof onKeyUp === 'function') onKeyUp(event)
78
+ }
79
+ } else {
80
+ // React Native Web supports onKeyUp the normal way.
81
+ if (onKeyUp) resolvedProps.onKeyUp = onKeyUp
82
+ // React Native Web doesn't support the `onKeyDown` prop name, but maps a supplied onKeyPress handler
83
+ // to the onKeyDown event and calls it with a keydown event. Make React Native Web call either or both.
84
+ if (onKeyPress || onKeyDown) {
85
+ resolvedProps.onKeyPress = (event) => {
86
+ if (typeof onKeyDown === 'function') onKeyDown(event)
87
+ if (typeof onKeyPress === 'function') onKeyPress(event)
88
+ }
89
+ }
90
+ }
91
+ }
92
+ return resolvedProps
45
93
  }
46
94
 
47
- export default { focusHandlerProps, textInputHandlerProps }
95
+ export { focusHandlerProps, textInputHandlerProps }
@@ -0,0 +1,57 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react'
2
+
3
+ const addScrollBlocking = (preventScrolling, stopPropagation, ref) => {
4
+ document.body.addEventListener('touchmove', preventScrolling, { passive: false })
5
+ ref.current?.addEventListener('touchmove', stopPropagation)
6
+ document.body.style.overflow = 'hidden'
7
+ }
8
+
9
+ const removeScrollBlocking = (preventScrolling, stopPropagation, ref) => {
10
+ document.body.removeEventListener('touchmove', preventScrolling)
11
+ ref.current?.removeEventListener('touchmove', stopPropagation)
12
+ document.body.style.overflow = 'inherit'
13
+ }
14
+
15
+ /**
16
+ * Disables scrolling when passed `true` or an array where all items are `true`.
17
+ *
18
+ * Returns an optional callback ref. Pass this to an element if it or its children
19
+ * should allow touch-based scrolling within that element's bounds.
20
+ *
21
+ * @param {boolean | boolean[]} conditionProps
22
+ * @returns
23
+ */
24
+ const useScrollBlocking = (conditionProps) => {
25
+ // useRef refs are null on first render and don't trigger a re-render when they get their
26
+ // element. Force re-run when ref mounts to ensure the stopPropagation listener is attached.
27
+ const ref = useRef()
28
+ const [refIsMounted, setRefIsMounted] = useState(false)
29
+ const callbackRef = useCallback((element) => {
30
+ ref.current = element
31
+ setRefIsMounted(Boolean(element))
32
+ }, [])
33
+
34
+ const conditionsMet = Array.isArray(conditionProps)
35
+ ? conditionProps.every((condition) => condition)
36
+ : Boolean(conditionProps)
37
+
38
+ const preventScrolling = useCallback((event) => event.preventDefault(), [])
39
+ const stopPropagation = useCallback((event) => event.stopPropagation(), [])
40
+
41
+ useEffect(() => {
42
+ const cleanup = () => removeScrollBlocking(preventScrolling, stopPropagation, ref)
43
+
44
+ if (conditionsMet) {
45
+ addScrollBlocking(preventScrolling, stopPropagation, ref)
46
+ } else {
47
+ cleanup()
48
+ }
49
+ return cleanup
50
+ // preventScrolling and stopPropagation are stable callbacks with no deps, so this
51
+ // will re-run when conditionsMet or refIsMounted flip between true and false.
52
+ }, [preventScrolling, conditionsMet, stopPropagation, refIsMounted])
53
+
54
+ return callbackRef
55
+ }
56
+
57
+ 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 () => {}