@telus-uds/components-base 0.0.2-prerelease.9 → 1.1.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.
- package/.eslintrc.js +9 -0
- package/.storybook/main.js +4 -0
- package/.storybook/preview.js +37 -0
- package/.ultra.cache.json +1 -1
- package/CHANGELOG.md +50 -0
- package/README.md +4 -2
- package/__fixtures__/test-utils.js +25 -0
- package/__fixtures__/testTheme.js +4 -2
- package/__tests__/Button/ButtonGroup.test.jsx +4 -5
- package/__tests__/Checkbox/Checkbox.test.jsx +2 -2
- package/__tests__/Checkbox/CheckboxGroup.test.jsx +4 -5
- package/__tests__/ExpandCollapse/ExpandCollapse.test.jsx +2 -2
- package/__tests__/HorizontalScroll/HorizontalScroll.test.jsx +164 -0
- package/__tests__/Link/LinkBase.test.jsx +0 -14
- package/__tests__/Radio/Radio.test.jsx +2 -2
- package/__tests__/Radio/RadioGroup.test.jsx +4 -5
- package/__tests__/RadioCard/RadioCard.test.jsx +2 -2
- package/__tests__/RadioCard/RadioCardGroup.test.jsx +4 -5
- package/__tests__/Search/Search.test.jsx +9 -8
- package/__tests__/Select/Select.test.jsx +3 -2
- package/__tests__/Tabs/Tabs.test.jsx +1 -161
- package/__tests__/Tags/Tags.test.jsx +4 -5
- package/__tests__/TextInput/TextArea.test.jsx +3 -2
- package/__tests__/TextInput/TextInputBase.test.jsx +10 -5
- package/__tests__/ThemeProvider/ThemeProvider.test.jsx +77 -0
- package/__tests__/ThemeProvider/useThemeTokens.test.jsx +9 -5
- package/__tests__/ThemeProvider/utils/theme-tokens.test.js +41 -0
- package/__tests__/ToggleSwitch/ToggleSwitch.test.jsx +3 -2
- package/__tests__/utils/children.test.jsx +128 -0
- package/__tests__/utils/input.test.js +1 -1
- package/__tests__/utils/semantics.test.jsx +43 -0
- package/babel.config.js +9 -16
- package/component-docs.json +10313 -0
- package/generate-component-docs.js +56 -0
- package/lib/A11yText/index.js +10 -5
- package/lib/ActivityIndicator/Spinner.js +16 -13
- package/lib/ActivityIndicator/Spinner.native.js +12 -8
- package/lib/Box/Box.js +103 -8
- package/lib/Button/Button.js +9 -8
- package/lib/Button/ButtonBase.js +14 -7
- package/lib/Button/ButtonGroup.js +25 -10
- package/lib/Button/ButtonLink.js +10 -7
- package/lib/Card/Card.js +2 -0
- package/lib/Card/CardBase.js +13 -5
- package/lib/Card/PressableCardBase.js +12 -8
- package/lib/Checkbox/Checkbox.js +25 -14
- package/lib/Checkbox/CheckboxGroup.js +22 -12
- package/lib/Divider/Divider.js +12 -7
- package/lib/ExpandCollapse/Accordion.js +10 -4
- package/lib/ExpandCollapse/Control.js +12 -6
- package/lib/ExpandCollapse/ExpandCollapse.js +10 -5
- package/lib/ExpandCollapse/Panel.js +8 -7
- package/lib/Feedback/Feedback.js +10 -5
- package/lib/Fieldset/Fieldset.js +10 -5
- package/lib/Fieldset/FieldsetContainer.js +10 -5
- package/lib/Fieldset/FieldsetContainer.native.js +10 -5
- package/lib/Fieldset/Legend.js +10 -5
- package/lib/Fieldset/Legend.native.js +10 -5
- package/lib/FlexGrid/Col/Col.js +8 -5
- package/lib/FlexGrid/FlexGrid.js +31 -6
- package/lib/FlexGrid/Row/Row.js +12 -5
- package/lib/{Tabs → HorizontalScroll}/HorizontalScroll.js +5 -4
- package/lib/{Tabs/TabsScrollButton.js → HorizontalScroll/HorizontalScrollButton.js} +14 -8
- package/lib/{Tabs → HorizontalScroll}/ScrollViewEnd.js +0 -0
- package/lib/{Tabs → HorizontalScroll}/ScrollViewEnd.native.js +0 -0
- package/lib/{Tabs → HorizontalScroll}/dictionary.js +0 -0
- package/lib/HorizontalScroll/index.js +35 -0
- package/lib/{Tabs → HorizontalScroll}/itemPositions.js +0 -0
- package/lib/Icon/Icon.js +16 -9
- package/lib/Icon/IconText.js +8 -7
- package/lib/IconButton/IconButton.js +10 -5
- package/lib/InputLabel/InputLabel.js +33 -5
- package/lib/InputLabel/LabelContent.js +22 -12
- package/lib/InputLabel/LabelContent.native.js +23 -5
- package/lib/InputSupports/InputSupports.js +10 -5
- package/lib/Link/ChevronLink.js +12 -5
- package/lib/Link/InlinePressable.js +10 -4
- package/lib/Link/InlinePressable.native.js +5 -4
- package/lib/Link/Link.js +12 -5
- package/lib/Link/LinkBase.js +12 -5
- package/lib/Link/TextButton.js +10 -5
- package/lib/List/List.js +6 -6
- package/lib/List/ListItem.js +28 -33
- package/lib/List/index.js +15 -0
- package/lib/Modal/Modal.js +10 -5
- package/lib/Notification/Notification.js +21 -5
- package/lib/Pagination/PageButton.js +16 -11
- package/lib/Pagination/Pagination.js +12 -7
- package/lib/Pagination/SideButton.js +12 -7
- package/lib/Pagination/usePagination.js +2 -2
- package/lib/Progress/Progress.js +10 -5
- package/lib/Progress/ProgressBar.js +21 -10
- package/lib/Progress/ProgressBarBackground.js +12 -8
- package/lib/Radio/Radio.js +14 -13
- package/lib/Radio/RadioButton.js +20 -9
- package/lib/Radio/RadioGroup.js +24 -13
- package/lib/RadioCard/RadioCard.js +14 -10
- package/lib/RadioCard/RadioCardGroup.js +13 -12
- package/lib/Search/Search.js +29 -18
- package/lib/Select/Picker.js +11 -6
- package/lib/Select/Picker.native.js +21 -6
- package/lib/Select/Select.js +46 -4
- package/lib/SideNav/Item.js +10 -5
- package/lib/SideNav/ItemsGroup.js +10 -5
- package/lib/SideNav/SideNav.js +11 -7
- package/lib/Skeleton/Skeleton.js +15 -15
- package/lib/Skeleton/skeletonWebAnimation.js +1 -1
- package/lib/Spacer/Spacer.js +19 -7
- package/lib/StackView/StackView.js +26 -7
- package/lib/StackView/StackWrap.js +24 -13
- package/lib/StackView/StackWrapBox.js +34 -8
- package/lib/StackView/StackWrapGap.js +16 -7
- package/lib/StackView/common.js +4 -2
- package/lib/StackView/getStackedContent.js +2 -2
- package/lib/StepTracker/StepTracker.js +10 -5
- package/lib/Tabs/Tabs.js +26 -19
- package/lib/Tabs/TabsItem.js +16 -12
- package/lib/Tags/Tags.js +27 -11
- package/lib/TextInput/TextArea.js +7 -5
- package/lib/TextInput/TextInput.js +12 -6
- package/lib/TextInput/TextInputBase.js +12 -8
- package/lib/ThemeProvider/ThemeProvider.js +14 -10
- package/lib/ThemeProvider/useSetTheme.js +6 -1
- package/lib/ThemeProvider/utils/styles.js +2 -2
- package/lib/ThemeProvider/utils/theme-tokens.js +39 -8
- package/lib/ToggleSwitch/ToggleSwitch.js +11 -6
- package/lib/Tooltip/Backdrop.js +10 -2
- package/lib/Tooltip/Tooltip.js +5 -4
- package/lib/Typography/Typography.js +40 -24
- package/lib/index.js +36 -1
- package/lib/utils/a11y/index.js +13 -0
- package/lib/utils/a11y/propTypes.js +61 -0
- package/lib/utils/a11y/propTypes.native.js +47 -0
- package/lib/utils/a11y/semantics.js +173 -0
- package/lib/utils/animation/useVerticalExpandAnimation.js +1 -1
- package/lib/utils/children.js +55 -8
- package/lib/utils/input.js +27 -17
- package/lib/utils/propTypes.js +40 -68
- package/lib/utils/useCopy.js +1 -1
- package/lib/utils/useHash.js +8 -4
- package/lib/utils/useSpacingScale.js +1 -3
- package/lib/utils/useUniqueId.js +1 -1
- package/package.json +14 -6
- package/release-context.json +4 -4
- package/src/A11yText/index.jsx +6 -4
- package/src/ActivityIndicator/Spinner.jsx +5 -3
- package/src/ActivityIndicator/Spinner.native.jsx +5 -3
- package/src/Box/Box.jsx +125 -39
- package/src/Button/Button.jsx +7 -4
- package/src/Button/ButtonBase.jsx +86 -77
- package/src/Button/ButtonGroup.jsx +81 -69
- package/src/Button/ButtonLink.jsx +18 -13
- package/src/Card/Card.jsx +2 -2
- package/src/Card/CardBase.jsx +6 -4
- package/src/Card/PressableCardBase.jsx +71 -64
- package/src/Checkbox/Checkbox.jsx +118 -108
- package/src/Checkbox/CheckboxGroup.jsx +72 -62
- package/src/Divider/Divider.jsx +7 -4
- package/src/ExpandCollapse/Accordion.jsx +3 -2
- package/src/ExpandCollapse/Control.jsx +40 -43
- package/src/ExpandCollapse/ExpandCollapse.jsx +26 -23
- package/src/ExpandCollapse/Panel.jsx +69 -63
- package/src/Feedback/Feedback.jsx +36 -33
- package/src/Fieldset/Fieldset.jsx +63 -56
- package/src/Fieldset/FieldsetContainer.jsx +14 -5
- package/src/Fieldset/FieldsetContainer.native.jsx +7 -4
- package/src/Fieldset/Legend.jsx +7 -2
- package/src/Fieldset/Legend.native.jsx +7 -2
- package/src/FlexGrid/Col/Col.jsx +139 -132
- package/src/FlexGrid/FlexGrid.jsx +79 -51
- package/src/FlexGrid/Row/Row.jsx +55 -48
- package/src/HorizontalScroll/HorizontalScroll.jsx +168 -0
- package/src/HorizontalScroll/HorizontalScrollButton.jsx +105 -0
- package/src/{Tabs → HorizontalScroll}/ScrollViewEnd.jsx +0 -0
- package/src/{Tabs → HorizontalScroll}/ScrollViewEnd.native.jsx +0 -0
- package/src/{Tabs → HorizontalScroll}/dictionary.js +0 -0
- package/src/HorizontalScroll/index.js +17 -0
- package/src/{Tabs → HorizontalScroll}/itemPositions.js +0 -0
- package/src/Icon/Icon.jsx +37 -35
- package/src/Icon/IconText.jsx +22 -17
- package/src/IconButton/IconButton.jsx +49 -42
- package/src/InputLabel/InputLabel.jsx +53 -38
- package/src/InputLabel/LabelContent.jsx +14 -6
- package/src/InputLabel/LabelContent.native.jsx +11 -2
- package/src/InputSupports/InputSupports.jsx +29 -34
- package/src/Link/ChevronLink.jsx +26 -16
- package/src/Link/InlinePressable.jsx +5 -3
- package/src/Link/InlinePressable.native.jsx +5 -3
- package/src/Link/Link.jsx +22 -16
- package/src/Link/LinkBase.jsx +67 -58
- package/src/Link/TextButton.jsx +30 -23
- package/src/List/List.jsx +6 -7
- package/src/List/ListItem.jsx +70 -90
- package/src/List/index.js +5 -0
- package/src/Modal/Modal.jsx +9 -4
- package/src/Notification/Notification.jsx +58 -43
- package/src/Pagination/PageButton.jsx +37 -34
- package/src/Pagination/Pagination.jsx +88 -92
- package/src/Pagination/SideButton.jsx +44 -41
- package/src/Progress/Progress.jsx +5 -4
- package/src/Progress/ProgressBar.jsx +42 -29
- package/src/Progress/ProgressBarBackground.jsx +5 -3
- package/src/Radio/Radio.jsx +85 -78
- package/src/Radio/RadioButton.jsx +54 -43
- package/src/Radio/RadioGroup.jsx +74 -63
- package/src/RadioCard/RadioCard.jsx +75 -68
- package/src/RadioCard/RadioCardGroup.jsx +82 -75
- package/src/Search/Search.jsx +127 -106
- package/src/Select/Picker.jsx +49 -42
- package/src/Select/Picker.native.jsx +56 -49
- package/src/Select/Select.jsx +115 -72
- package/src/SideNav/Item.jsx +53 -46
- package/src/SideNav/ItemsGroup.jsx +50 -43
- package/src/SideNav/SideNav.jsx +68 -60
- package/src/Skeleton/Skeleton.jsx +9 -13
- package/src/Spacer/Spacer.jsx +11 -4
- package/src/StackView/StackView.jsx +47 -23
- package/src/StackView/StackWrap.jsx +14 -12
- package/src/StackView/StackWrapBox.jsx +62 -28
- package/src/StackView/StackWrapGap.jsx +46 -24
- package/src/StackView/common.jsx +3 -2
- package/src/StepTracker/StepTracker.jsx +73 -62
- package/src/Tabs/Tabs.jsx +70 -62
- package/src/Tabs/TabsItem.jsx +111 -103
- package/src/Tags/Tags.jsx +114 -102
- package/src/TextInput/TextArea.jsx +5 -4
- package/src/TextInput/TextInput.jsx +5 -4
- package/src/TextInput/TextInputBase.jsx +84 -77
- package/src/ThemeProvider/ThemeProvider.jsx +11 -7
- package/src/ThemeProvider/useSetTheme.js +4 -0
- package/src/ThemeProvider/utils/theme-tokens.js +28 -0
- package/src/ToggleSwitch/ToggleSwitch.jsx +49 -50
- package/src/Tooltip/Tooltip.jsx +134 -130
- package/src/Typography/Typography.jsx +67 -44
- package/src/index.js +3 -1
- package/src/utils/a11y/index.js +1 -0
- package/src/utils/a11y/propTypes.js +61 -0
- package/src/utils/a11y/propTypes.native.js +39 -0
- package/src/utils/a11y/semantics.js +162 -0
- package/src/utils/children.jsx +60 -7
- package/src/utils/input.js +20 -17
- package/src/utils/propTypes.js +30 -76
- package/src/utils/useCopy.js +1 -1
- package/src/utils/useHash.js +8 -3
- package/stories/A11yText/A11yText.stories.jsx +3 -3
- package/stories/ActivityIndicator/ActivityIndicator.stories.jsx +2 -2
- package/stories/Box/Box.stories.jsx +2 -2
- package/stories/Button/Button.stories.jsx +3 -3
- package/stories/Button/ButtonGroup.stories.jsx +2 -2
- package/stories/Button/ButtonLink.stories.jsx +2 -2
- package/stories/Card/Card.stories.jsx +2 -2
- package/stories/Checkbox/Checkbox.stories.jsx +2 -2
- package/stories/Divider/Divider.stories.jsx +2 -2
- package/stories/ExpandCollapse/ExpandCollapse.stories.jsx +3 -3
- package/stories/Feedback/Feedback.stories.jsx +2 -2
- package/stories/FlexGrid/01 FlexGrid.stories.jsx +2 -2
- package/stories/FlexGrid/02 Row.stories.jsx +2 -2
- package/stories/FlexGrid/03 Col.stories.jsx +2 -2
- package/stories/Icon/Icon.stories.jsx +2 -2
- package/stories/IconButton/IconButton.stories.jsx +2 -2
- package/stories/InputLabel/InputLabel.stories.jsx +2 -2
- package/stories/Link/ChevronLink.stories.jsx +2 -2
- package/stories/Link/Link.stories.jsx +2 -2
- package/stories/Link/TextButton.stories.jsx +2 -2
- package/stories/List/List.stories.jsx +2 -2
- package/stories/Modal/Modal.stories.jsx +2 -2
- package/stories/Notification/Notification.stories.jsx +2 -2
- package/stories/Pagination/Pagination.stories.jsx +2 -2
- package/stories/Progress/Progress.stories.jsx +2 -2
- package/stories/Radio/Radio.stories.jsx +2 -2
- package/stories/RadioCard/RadioCard.stories.jsx +2 -2
- package/stories/Search/Search.stories.jsx +2 -2
- package/stories/Select/Select.stories.jsx +2 -2
- package/stories/SideNav/SideNav.stories.jsx +2 -2
- package/stories/SideNav/SideNavItem.stories.jsx +2 -2
- package/stories/SideNav/SideNavItemsGroup.stories.jsx +2 -2
- package/stories/Skeleton/Skeleton.stories.jsx +3 -3
- package/stories/Spacer/Spacer.stories.jsx +2 -2
- package/stories/StackView/StackView.stories.jsx +2 -2
- package/stories/StackView/StackWrap.stories.jsx +2 -2
- package/stories/StepTracker/StepTracker.stories.jsx +2 -2
- package/stories/Tabs/Tabs.stories.jsx +2 -2
- package/stories/Tags/Tags.stories.jsx +2 -2
- package/stories/TextInput/TextArea.stories.jsx +2 -2
- package/stories/TextInput/TextInput.stories.jsx +2 -2
- package/stories/ToggleSwitch/ToggleSwitch.stories.jsx +2 -2
- package/stories/Tooltip/Tooltip.stories.jsx +2 -2
- package/stories/TooltipButton/TooltipButton.stories.jsx +2 -2
- package/stories/Typography/Typography.stories.jsx +2 -2
- package/stories/platform-supports.jsx +1 -1
- package/stories/supports.jsx +4 -5
- package/src/Tabs/HorizontalScroll.jsx +0 -165
- package/src/Tabs/TabsScrollButton.jsx +0 -100
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState } from 'react'
|
|
1
|
+
import React, { forwardRef, useState } from 'react'
|
|
2
2
|
|
|
3
3
|
import { Platform } from 'react-native'
|
|
4
4
|
import { getTokensPropType, variantProp } from '../utils'
|
|
@@ -32,7 +32,7 @@ import textInputPropTypes from './propTypes'
|
|
|
32
32
|
* or an indicator that the field is optional.
|
|
33
33
|
* It is a more usable and accessible option than the HTML `placeholder` attribute.
|
|
34
34
|
*/
|
|
35
|
-
|
|
35
|
+
const TextArea = forwardRef(({ tokens, variant = {}, ...remainingProps }, ref) => {
|
|
36
36
|
const themeTokens = useThemeTokens('TextArea', tokens, variant)
|
|
37
37
|
const [inputHeight, setInputHeight] = useState()
|
|
38
38
|
|
|
@@ -62,11 +62,12 @@ function TextArea({ tokens, variant = {}, ...remainingProps }) {
|
|
|
62
62
|
return (
|
|
63
63
|
<InputSupports {...supportsProps}>
|
|
64
64
|
{({ a11yProps, inputId }) => (
|
|
65
|
-
<TextInputBase {...inputProps} {...a11yProps} nativeID={inputId} />
|
|
65
|
+
<TextInputBase ref={ref} {...inputProps} {...a11yProps} nativeID={inputId} />
|
|
66
66
|
)}
|
|
67
67
|
</InputSupports>
|
|
68
68
|
)
|
|
69
|
-
}
|
|
69
|
+
})
|
|
70
|
+
TextArea.displayName = 'TextArea'
|
|
70
71
|
|
|
71
72
|
TextArea.propTypes = {
|
|
72
73
|
...inputSupportProps.types,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
2
|
|
|
3
3
|
import { getTokensPropType, variantProp } from '../utils'
|
|
4
4
|
import InputSupports from '../InputSupports'
|
|
@@ -24,7 +24,7 @@ import textInputPropTypes from './propTypes'
|
|
|
24
24
|
* supported props and <a href="https://reactnative.dev/docs/textinput" target="_blank">React Native Web documentation</a> for
|
|
25
25
|
* their implementation on the web.
|
|
26
26
|
*/
|
|
27
|
-
|
|
27
|
+
const TextInput = forwardRef(({ tokens, variant = {}, ...remainingProps }, ref) => {
|
|
28
28
|
const { props: supportsProps, rest } = inputSupportProps.select(remainingProps)
|
|
29
29
|
|
|
30
30
|
const inputProps = {
|
|
@@ -36,11 +36,12 @@ function TextInput({ tokens, variant = {}, ...remainingProps }) {
|
|
|
36
36
|
return (
|
|
37
37
|
<InputSupports {...supportsProps}>
|
|
38
38
|
{({ a11yProps, inputId }) => (
|
|
39
|
-
<TextInputBase {...inputProps} {...a11yProps} nativeID={inputId} />
|
|
39
|
+
<TextInputBase ref={ref} {...inputProps} {...a11yProps} nativeID={inputId} />
|
|
40
40
|
)}
|
|
41
41
|
</InputSupports>
|
|
42
42
|
)
|
|
43
|
-
}
|
|
43
|
+
})
|
|
44
|
+
TextInput.displayName = 'TextInput'
|
|
44
45
|
|
|
45
46
|
TextInput.propTypes = {
|
|
46
47
|
...inputSupportProps.types,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState } from 'react'
|
|
1
|
+
import React, { forwardRef, useState } from 'react'
|
|
2
2
|
import { Platform, StyleSheet, TextInput as NativeTextInput, View } from 'react-native'
|
|
3
3
|
|
|
4
4
|
import PropTypes from 'prop-types'
|
|
@@ -98,90 +98,97 @@ const selectIconContainerStyles = ({ paddingRight, paddingBottom }) => ({
|
|
|
98
98
|
paddingBottom
|
|
99
99
|
})
|
|
100
100
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
101
|
+
const TextInputBase = forwardRef(
|
|
102
|
+
(
|
|
103
|
+
{
|
|
104
|
+
value,
|
|
105
|
+
height,
|
|
106
|
+
initialValue,
|
|
107
|
+
inactive,
|
|
108
|
+
readOnly,
|
|
109
|
+
onChange,
|
|
110
|
+
onChangeText,
|
|
111
|
+
onFocus,
|
|
112
|
+
onBlur,
|
|
113
|
+
onMouseOver,
|
|
114
|
+
onMouseOut,
|
|
115
|
+
tokens,
|
|
116
|
+
variant = {},
|
|
117
|
+
...remainingProps
|
|
118
|
+
},
|
|
119
|
+
ref
|
|
120
|
+
) => {
|
|
121
|
+
const [isFocused, setIsFocused] = useState(false)
|
|
122
|
+
const handleFocus = (event) => {
|
|
123
|
+
setIsFocused(true)
|
|
124
|
+
if (typeof onFocus === 'function') onFocus(event)
|
|
125
|
+
}
|
|
126
|
+
const handleBlur = (event) => {
|
|
127
|
+
setIsFocused(false)
|
|
128
|
+
if (typeof onBlur === 'function') onBlur(event)
|
|
129
|
+
}
|
|
126
130
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
131
|
+
const [isHovered, setIsHovered] = useState(false)
|
|
132
|
+
const handleMouseOver = (event) => {
|
|
133
|
+
setIsHovered(true)
|
|
134
|
+
if (typeof onMouseOver === 'function') onMouseOver(event)
|
|
135
|
+
}
|
|
136
|
+
const handleMouseOut = (event) => {
|
|
137
|
+
setIsHovered(false)
|
|
138
|
+
if (typeof onMouseOut === 'function') onMouseOut(event)
|
|
139
|
+
}
|
|
136
140
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
141
|
+
const { currentValue, setValue, isControlled } = useInputValue({
|
|
142
|
+
value,
|
|
143
|
+
initialValue,
|
|
144
|
+
onChange,
|
|
145
|
+
readOnly
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
const handleChangeText = (event) => {
|
|
149
|
+
const text = event.nativeEvent?.text || event.target?.value
|
|
150
|
+
setValue(text, event)
|
|
151
|
+
if (typeof onChangeText === 'function') onChangeText(text, event)
|
|
152
|
+
}
|
|
143
153
|
|
|
144
|
-
|
|
145
|
-
setValue(text)
|
|
146
|
-
if (typeof onChangeText === 'function') onChangeText(text)
|
|
147
|
-
}
|
|
154
|
+
const states = { focus: isFocused, hover: isHovered, inactive }
|
|
148
155
|
|
|
149
|
-
|
|
156
|
+
const themeTokens = useThemeTokens('TextInput', tokens, variant, states)
|
|
150
157
|
|
|
151
|
-
|
|
158
|
+
const { icon: IconComponent } = themeTokens
|
|
152
159
|
|
|
153
|
-
|
|
160
|
+
const inputProps = {
|
|
161
|
+
...remainingProps,
|
|
162
|
+
editable: !inactive,
|
|
163
|
+
onFocus: handleFocus,
|
|
164
|
+
onBlur: handleBlur,
|
|
165
|
+
onMouseOver: handleMouseOver,
|
|
166
|
+
onMouseOut: handleMouseOut,
|
|
167
|
+
onChange: handleChangeText,
|
|
168
|
+
defaultValue: initialValue,
|
|
169
|
+
// currentValue is being updated even if the input is not controlled, passing it down to the
|
|
170
|
+
// Input could lead to changing its state from uncontrolled to controlled
|
|
171
|
+
value: isControlled ? currentValue : undefined
|
|
172
|
+
}
|
|
154
173
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
174
|
+
const nativeInputStyle = selectInputStyles({ ...themeTokens, height }, inactive)
|
|
175
|
+
|
|
176
|
+
return (
|
|
177
|
+
<View style={selectOuterBorderStyles(themeTokens)}>
|
|
178
|
+
<NativeTextInput ref={ref} style={nativeInputStyle} {...inputProps} />
|
|
179
|
+
{IconComponent && (
|
|
180
|
+
<View
|
|
181
|
+
pointerEvents="none" // avoid hijacking input press events
|
|
182
|
+
style={[staticStyles.iconContainer, selectIconContainerStyles(themeTokens)]}
|
|
183
|
+
>
|
|
184
|
+
<IconComponent {...selectIconTokens(themeTokens)} />
|
|
185
|
+
</View>
|
|
186
|
+
)}
|
|
187
|
+
</View>
|
|
188
|
+
)
|
|
167
189
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
return (
|
|
172
|
-
<View style={selectOuterBorderStyles(themeTokens)}>
|
|
173
|
-
<NativeTextInput style={nativeInputStyle} {...inputProps} />
|
|
174
|
-
{IconComponent && (
|
|
175
|
-
<View
|
|
176
|
-
pointerEvents="none" // avoid hijacking input press events
|
|
177
|
-
style={[staticStyles.iconContainer, selectIconContainerStyles(themeTokens)]}
|
|
178
|
-
>
|
|
179
|
-
<IconComponent {...selectIconTokens(themeTokens)} />
|
|
180
|
-
</View>
|
|
181
|
-
)}
|
|
182
|
-
</View>
|
|
183
|
-
)
|
|
184
|
-
}
|
|
190
|
+
)
|
|
191
|
+
TextInputBase.displayName = 'TextInputBase'
|
|
185
192
|
|
|
186
193
|
TextInputBase.propTypes = {
|
|
187
194
|
value: PropTypes.string,
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import React, { createContext, useState } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
|
+
import { validateThemeTokensVersion } from './utils'
|
|
3
4
|
|
|
4
5
|
export const uninitialisedError = new Error('Theme context used outside of ThemeProvider')
|
|
5
6
|
|
|
6
7
|
export const ThemeContext = createContext(uninitialisedError)
|
|
7
8
|
export const ThemeSetterContext = createContext(uninitialisedError)
|
|
8
9
|
|
|
9
|
-
// TODO: develop this as theme metadata is added
|
|
10
|
-
// https://github.com/telus/universal-design-system/issues/92
|
|
11
|
-
export const themeType = PropTypes.object
|
|
12
|
-
|
|
13
10
|
const ThemeProvider = ({ children, defaultTheme }) => {
|
|
14
11
|
const [theme, setTheme] = useState(defaultTheme)
|
|
15
12
|
|
|
13
|
+
// Validate the theme tokens version on every render.
|
|
14
|
+
// This will intentionally break the application when attempting to use an invalid theme.
|
|
15
|
+
// This will surface an incompatibility quickly rather than allowing the potential for strange bugs due to missing or incompatible tokens.
|
|
16
|
+
validateThemeTokensVersion(theme)
|
|
17
|
+
|
|
16
18
|
return (
|
|
17
19
|
<ThemeSetterContext.Provider value={setTheme}>
|
|
18
20
|
<ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
|
|
@@ -21,10 +23,12 @@ const ThemeProvider = ({ children, defaultTheme }) => {
|
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
ThemeProvider.propTypes = {
|
|
24
|
-
// TODO: implement a custom propType that validates schema version
|
|
25
|
-
// https://github.com/telus/universal-design-system/issues/92
|
|
26
26
|
children: PropTypes.node.isRequired,
|
|
27
|
-
defaultTheme:
|
|
27
|
+
defaultTheme: PropTypes.shape({
|
|
28
|
+
metadata: PropTypes.shape({
|
|
29
|
+
themeTokensVersion: PropTypes.string.isRequired
|
|
30
|
+
}).isRequired
|
|
31
|
+
}).isRequired
|
|
28
32
|
}
|
|
29
33
|
|
|
30
34
|
export default ThemeProvider
|
|
@@ -4,6 +4,10 @@ import { ThemeSetterContext } from './ThemeProvider'
|
|
|
4
4
|
const useSetTheme = () => {
|
|
5
5
|
// Replace current theme with provided object
|
|
6
6
|
const setTheme = useContext(ThemeSetterContext)
|
|
7
|
+
// Fail fast if dev uses useSetTheme outside of ThemeProvider
|
|
8
|
+
if (setTheme instanceof Error) {
|
|
9
|
+
throw setTheme
|
|
10
|
+
}
|
|
7
11
|
|
|
8
12
|
// Merge provided object into current theme
|
|
9
13
|
const editTheme = useCallback(
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import PropTypes from 'prop-types'
|
|
2
|
+
import semVerSatisfies from 'semver/functions/satisfies'
|
|
3
|
+
import pkg from '../../../package.json'
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* @typedef {import('../../utils/propTypes.js').AppearanceSet} AppearanceSet
|
|
@@ -133,3 +135,29 @@ export const getThemeTokens = (
|
|
|
133
135
|
}
|
|
134
136
|
|
|
135
137
|
export const toArray = (strOrArr) => (Array.isArray(strOrArr) ? strOrArr : [strOrArr])
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Throws an error if the theme was built with an incompatible version of @telus-uds/system-theme-tokens
|
|
141
|
+
*
|
|
142
|
+
* This is used internally by the ThemeProvider to force a fast failure when an incompatible version is detected.
|
|
143
|
+
*
|
|
144
|
+
* Version compatibility is calculated with semver.satisfies.
|
|
145
|
+
* Refer to https://github.com/npm/node-semver and https://semver.npmjs.com/ for details about how
|
|
146
|
+
* semver compatibility.
|
|
147
|
+
*
|
|
148
|
+
* @param {object} theme - UDS theme built for react-native
|
|
149
|
+
*/
|
|
150
|
+
export const validateThemeTokensVersion = (theme) => {
|
|
151
|
+
const expectedThemeTokensVersion = pkg.dependencies['@telus-uds/system-theme-tokens']
|
|
152
|
+
const actualThemeTokensVersion = theme?.metadata?.themeTokensVersion
|
|
153
|
+
|
|
154
|
+
if (!semVerSatisfies(actualThemeTokensVersion, expectedThemeTokensVersion)) {
|
|
155
|
+
throw new Error(
|
|
156
|
+
`Invalid UDS token schema version detected.
|
|
157
|
+
|
|
158
|
+
The UDS base components ${pkg.name} v${pkg.version} are only compatible with UDS themes that are built with @telus-uds/system-theme-tokens version that is semver compatible with ${expectedThemeTokensVersion}. The current theme was built with @telus-uds/system-theme-tokens v${actualThemeTokensVersion}.
|
|
159
|
+
|
|
160
|
+
If you see this error than most likely you have attempted to install ${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
|
+
)
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import { Platform, View, StyleSheet } from 'react-native'
|
|
4
4
|
|
|
@@ -54,62 +54,61 @@ const selectSwitchStyles = ({
|
|
|
54
54
|
})
|
|
55
55
|
})
|
|
56
56
|
|
|
57
|
-
const ToggleSwitch = (
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
variant,
|
|
64
|
-
accessibilityRole = 'switch'
|
|
65
|
-
}) => {
|
|
66
|
-
const getTokens = useThemeTokensCallback('ToggleSwitch', tokens, variant)
|
|
57
|
+
const ToggleSwitch = forwardRef(
|
|
58
|
+
(
|
|
59
|
+
{ value, initialValue, onChange, inactive, tokens, variant, accessibilityRole = 'switch' },
|
|
60
|
+
ref
|
|
61
|
+
) => {
|
|
62
|
+
const getTokens = useThemeTokensCallback('ToggleSwitch', tokens, variant)
|
|
67
63
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
64
|
+
const { currentValue, setValue } = useInputValue({
|
|
65
|
+
value,
|
|
66
|
+
initialValue,
|
|
67
|
+
onChange
|
|
68
|
+
})
|
|
73
69
|
|
|
74
|
-
|
|
70
|
+
const handlePress = (event) => setValue(!currentValue, event)
|
|
75
71
|
|
|
76
|
-
|
|
72
|
+
const getButtonTokens = (buttonState) => selectButtonTokens(getTokens(buttonState))
|
|
77
73
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
74
|
+
return (
|
|
75
|
+
<ButtonBase
|
|
76
|
+
ref={ref}
|
|
77
|
+
selected={currentValue}
|
|
78
|
+
inactive={inactive}
|
|
79
|
+
tokens={getButtonTokens}
|
|
80
|
+
accessibilityRole={accessibilityRole}
|
|
81
|
+
accessibilityState={{ checked: currentValue }}
|
|
82
|
+
onPress={handlePress}
|
|
83
|
+
>
|
|
84
|
+
{(buttonState) => {
|
|
85
|
+
const themeTokens = getTokens(buttonState)
|
|
86
|
+
const IconComponent = themeTokens.icon
|
|
87
|
+
const switchStyles = selectSwitchStyles(themeTokens)
|
|
88
|
+
const trackStyles = selectTrackStyles(themeTokens)
|
|
89
|
+
const iconTokens = selectIconTokens(themeTokens)
|
|
93
90
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
91
|
+
// If drag-slide support is needed, use a PanResponder and apply these to an Animated value.
|
|
92
|
+
// Use translate transforms for smoothest non-thread-blocking animations and to allow drag.
|
|
93
|
+
const slideStart = 0
|
|
94
|
+
const slideEnd =
|
|
95
|
+
themeTokens.width - themeTokens.switchSize - themeTokens.trackBorderWidth * 2
|
|
96
|
+
const switchOffset = buttonState.selected ? slideEnd : slideStart
|
|
97
|
+
const switchPositionStyle = { transform: [{ translateX: switchOffset }] }
|
|
101
98
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
99
|
+
return (
|
|
100
|
+
<View style={[staticStyles.track, trackStyles]}>
|
|
101
|
+
<View style={[staticStyles.switch, switchStyles, switchPositionStyle]}>
|
|
102
|
+
{IconComponent && <IconComponent {...iconTokens} />}
|
|
103
|
+
</View>
|
|
106
104
|
</View>
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
105
|
+
)
|
|
106
|
+
}}
|
|
107
|
+
</ButtonBase>
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
)
|
|
111
|
+
ToggleSwitch.displayName = 'ToggleSwitch'
|
|
113
112
|
|
|
114
113
|
ToggleSwitch.propTypes = {
|
|
115
114
|
...a11yProps.propTypes,
|