@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
package/lib/utils/input.js
CHANGED
|
@@ -23,23 +23,29 @@ const validateProps = ({
|
|
|
23
23
|
const usageError = error => {
|
|
24
24
|
// Errors inside hooks in React Native get incomplete stack traces pointing at parent component only.
|
|
25
25
|
// Help devs out by telling them exactly which hook threw the error as well as why.
|
|
26
|
-
throw new Error(
|
|
26
|
+
throw new Error(`${hookName} ${error}.
|
|
27
|
+
|
|
28
|
+
Consumers of this hook must be one of:
|
|
29
|
+
1. An "uncontrolled" component responding directly to user actions, with an optional \`initialValue${s}\` but no \`value${s}\` prop,
|
|
30
|
+
2. A "controlled" component where an always-defined \`value${s}\` prop is managed by an \`onChange\` handler, with no \`initialValue${s}\`,
|
|
31
|
+
3. A "read-only" component, with \`readOnly\` prop set as \`true\`.
|
|
32
|
+
`);
|
|
27
33
|
};
|
|
28
34
|
|
|
29
35
|
if (value && !onChange && !readOnly) {
|
|
30
|
-
usageError(
|
|
36
|
+
usageError(`has \`value${s}\` prop without \`onChange\` or \`readOnly\``);
|
|
31
37
|
}
|
|
32
38
|
|
|
33
39
|
if (initialValue && value) {
|
|
34
|
-
usageError(
|
|
40
|
+
usageError(`has both \`initialValue${s}\` and \`value${s}\``);
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
if (isControlled && !isCurrentlyControlled) {
|
|
38
|
-
usageError(
|
|
44
|
+
usageError(`stopped receiving \`value${s}\` from parent after delegating state management`);
|
|
39
45
|
}
|
|
40
46
|
|
|
41
47
|
if (!isControlled && isCurrentlyControlled) {
|
|
42
|
-
usageError(
|
|
48
|
+
usageError(`started receiving \`value${s}\` from parent after starting managing own state`);
|
|
43
49
|
}
|
|
44
50
|
};
|
|
45
51
|
/**
|
|
@@ -92,14 +98,14 @@ const useInputValue = (props = {}, hookName = 'useInputValue') => {
|
|
|
92
98
|
}); // Make current value accessible inside useCallback without rememoizing every time the value changes
|
|
93
99
|
|
|
94
100
|
valueRef.current.value = currentValue;
|
|
95
|
-
const setValue = (0, _react.useCallback)(arg => {
|
|
101
|
+
const setValue = (0, _react.useCallback)((arg, event) => {
|
|
96
102
|
if (readOnly) return;
|
|
97
|
-
const newValue = typeof arg === 'function' ? arg(valueRef.current.value) : arg;
|
|
103
|
+
const newValue = typeof arg === 'function' ? arg(valueRef.current.value) : arg;
|
|
104
|
+
if (!isControlled) setOwnValue(newValue); // Call onChange handler if there's something for it to handle (event or a changed value)
|
|
98
105
|
|
|
99
|
-
if (onChange && valueRef.current.value !== newValue) onChange(newValue);
|
|
100
|
-
if (!isControlled) setOwnValue(newValue);
|
|
106
|
+
if (onChange && (event || valueRef.current.value !== newValue)) onChange(newValue, event);
|
|
101
107
|
}, [isControlled, onChange, readOnly]);
|
|
102
|
-
const resetValue = (0, _react.useCallback)(
|
|
108
|
+
const resetValue = (0, _react.useCallback)(event => setValue(valueRef.current.initial, event), [setValue]);
|
|
103
109
|
return {
|
|
104
110
|
currentValue,
|
|
105
111
|
setValue,
|
|
@@ -154,7 +160,7 @@ const useMultipleInputValues = ({
|
|
|
154
160
|
onChange,
|
|
155
161
|
value: values,
|
|
156
162
|
// if we're controlling our own state, always start with an array
|
|
157
|
-
initialValue: initialValues
|
|
163
|
+
initialValue: initialValues ?? (values === undefined ? [] : undefined)
|
|
158
164
|
}, 'useMultipleInputValues');
|
|
159
165
|
const enforceMaxValues = (0, _react.useCallback)(newValues => {
|
|
160
166
|
if (!maxValues) return newValues;
|
|
@@ -162,14 +168,18 @@ const useMultipleInputValues = ({
|
|
|
162
168
|
return excess > 0 ? newValues.slice(excess) : newValues;
|
|
163
169
|
}, [maxValues]);
|
|
164
170
|
const currentValues = enforceMaxValues(currentValue);
|
|
165
|
-
const setValues = (0, _react.useCallback)(
|
|
171
|
+
const setValues = (0, _react.useCallback)((newValues, event) => {
|
|
172
|
+
const validNewValues = enforceMaxValues(newValues);
|
|
173
|
+
setValue(validNewValues, event);
|
|
174
|
+
}, [setValue, enforceMaxValues]);
|
|
166
175
|
const resetValues = resetValue;
|
|
167
|
-
const unsetValues = (0, _react.useCallback)(
|
|
168
|
-
const toggleOneValue = (0, _react.useCallback)(newValue => {
|
|
169
|
-
if (readOnly) return;
|
|
170
|
-
setValues( // This will only work with primitive values (e.g. strings, numbers), swap for .some() and
|
|
176
|
+
const unsetValues = (0, _react.useCallback)(event => setValues([], event), [setValues]);
|
|
177
|
+
const toggleOneValue = (0, _react.useCallback)((newValue, event) => {
|
|
178
|
+
if (readOnly) return; // This will only work with primitive values (e.g. strings, numbers), swap for .some() and
|
|
171
179
|
// a deepEqual() function if there's any use case for toggling stored objects or arrays.
|
|
172
|
-
|
|
180
|
+
|
|
181
|
+
const newValues = currentValues.includes(newValue) ? currentValues.filter(oldValue => oldValue !== newValue) : [...currentValues, newValue];
|
|
182
|
+
setValues(newValues, event);
|
|
173
183
|
}, [currentValues, readOnly, setValues]);
|
|
174
184
|
return {
|
|
175
185
|
currentValues,
|
package/lib/utils/propTypes.js
CHANGED
|
@@ -11,7 +11,9 @@ var _Linking = _interopRequireDefault(require("react-native-web/dist/cjs/exports
|
|
|
11
11
|
|
|
12
12
|
var _Platform = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Platform"));
|
|
13
13
|
|
|
14
|
-
var
|
|
14
|
+
var _systemThemeTokens = require("@telus-uds/system-theme-tokens");
|
|
15
|
+
|
|
16
|
+
var _propTypes2 = _interopRequireDefault(require("./a11y/propTypes"));
|
|
15
17
|
|
|
16
18
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
19
|
|
|
@@ -60,13 +62,13 @@ const tokenValue = _propTypes.default.oneOfType([_propTypes.default.string, _pro
|
|
|
60
62
|
const tokenValueType = _propTypes.default.oneOfType([tokenValue, _propTypes.default.objectOf(tokenValue)]);
|
|
61
63
|
|
|
62
64
|
const getTokenNames = componentName => {
|
|
63
|
-
const
|
|
65
|
+
const componentTokenSchema = _systemThemeTokens.components[componentName];
|
|
64
66
|
|
|
65
|
-
if (!
|
|
66
|
-
throw new Error(
|
|
67
|
+
if (!componentTokenSchema) {
|
|
68
|
+
throw new Error(`No "${componentName}" tokenKeys in @telus-uds/system-theme-tokens`);
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
return
|
|
71
|
+
return Object.keys(componentTokenSchema);
|
|
70
72
|
};
|
|
71
73
|
/**
|
|
72
74
|
* Returns the subset of a set of tokens that may be accepted by the `tokens` prop of a named component
|
|
@@ -104,7 +106,7 @@ exports.getTokenNames = getTokenNames;
|
|
|
104
106
|
const selectTokens = (specifier, tokens, prefix) => {
|
|
105
107
|
const tokenNames = typeof specifier === 'string' ? getTokenNames(specifier) : specifier;
|
|
106
108
|
const filteredTokens = tokenNames.reduce((validTokens, key) => {
|
|
107
|
-
const prefixedKey = prefix ?
|
|
109
|
+
const prefixedKey = prefix ? `${prefix}${key[0].toUpperCase()}${key.slice(1)}` : key;
|
|
108
110
|
const token = tokens[prefixedKey];
|
|
109
111
|
return token !== undefined ? { ...validTokens,
|
|
110
112
|
[key]: token
|
|
@@ -190,49 +192,14 @@ function getPropSelector(propTypes, regexp) {
|
|
|
190
192
|
return props => Object.entries(props).reduce((items, [key, value]) => keys.includes(key) || regexp && regexp.test(key) ? { ...items,
|
|
191
193
|
[key]: value
|
|
192
194
|
} : items, {});
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
const a11yPropTypes = {
|
|
198
|
-
accessible: _propTypes.default.bool,
|
|
199
|
-
focusable: _propTypes.default.bool,
|
|
200
|
-
accessibilityElementsHidden: _propTypes.default.bool,
|
|
201
|
-
accessibilityHint: _propTypes.default.string,
|
|
202
|
-
// react-native-web ignores `accessibilityHint`
|
|
203
|
-
accessibilityIgnoresInvertColors: _propTypes.default.bool,
|
|
204
|
-
accessibilityLabel: _propTypes.default.string,
|
|
205
|
-
accessibilityRole: _propTypes.default.string,
|
|
206
|
-
accessibilityActions: _propTypes.default.arrayOf(_propTypes.default.shape({
|
|
207
|
-
name: _propTypes.default.string.isRequired,
|
|
208
|
-
label: _propTypes.default.string
|
|
209
|
-
})),
|
|
210
|
-
accessibilityLiveRegion: _propTypes.default.oneOf(['none', 'polite', 'assertive']),
|
|
211
|
-
accessibilityState: _propTypes.default.shape({
|
|
212
|
-
disabled: _propTypes.default.bool,
|
|
213
|
-
selected: _propTypes.default.bool,
|
|
214
|
-
checked: _propTypes.default.oneOf([true, false, 'mixed']),
|
|
215
|
-
busy: _propTypes.default.bool,
|
|
216
|
-
expanded: _propTypes.default.bool
|
|
217
|
-
}),
|
|
218
|
-
accessibilityValue: _propTypes.default.shape({
|
|
219
|
-
min: _propTypes.default.number,
|
|
220
|
-
max: _propTypes.default.number,
|
|
221
|
-
now: _propTypes.default.number,
|
|
222
|
-
text: _propTypes.default.string
|
|
223
|
-
}),
|
|
224
|
-
accessibilityViewIsModal: _propTypes.default.bool,
|
|
225
|
-
importantForAccessibility: _propTypes.default.oneOf(['auto', 'yes', 'no', 'no-hide-descendants']),
|
|
226
|
-
onAccessibilityAction: _propTypes.default.func,
|
|
227
|
-
onAccessibilityEscape: _propTypes.default.func,
|
|
228
|
-
onAccessibilityTap: _propTypes.default.func
|
|
229
|
-
};
|
|
195
|
+
}
|
|
196
|
+
|
|
230
197
|
const a11yProps = {
|
|
231
198
|
/**
|
|
232
199
|
* Proptypes for recognised React Native accessiblity (a11y) props.
|
|
233
200
|
* Spread this in the propTypes of components that accept React Native a11y props.
|
|
234
201
|
*/
|
|
235
|
-
types:
|
|
202
|
+
types: _propTypes2.default,
|
|
236
203
|
|
|
237
204
|
/**
|
|
238
205
|
* Filters a props object, returning only recognised React Native accessiblity (a11y) props.
|
|
@@ -240,7 +207,7 @@ const a11yProps = {
|
|
|
240
207
|
* Where components accept React Native a11y props, pass { ...rest } from its props to this,
|
|
241
208
|
* then spread the returned object into the component's props (usually its outer container).
|
|
242
209
|
*/
|
|
243
|
-
select: getPropSelector(
|
|
210
|
+
select: getPropSelector(_propTypes2.default, /^aria-/),
|
|
244
211
|
|
|
245
212
|
/**
|
|
246
213
|
* Use this to disable focus for elements which are visually hidden but still rendered.
|
|
@@ -332,8 +299,11 @@ const pressHandlerPropTypes = {
|
|
|
332
299
|
const pressPropTypes = { ...pressHandlerPropTypes,
|
|
333
300
|
disabled: _propTypes.default.bool,
|
|
334
301
|
..._Platform.default.select({
|
|
335
|
-
|
|
336
|
-
|
|
302
|
+
web: {},
|
|
303
|
+
default: {
|
|
304
|
+
hitSlop: _propTypes.default.number,
|
|
305
|
+
pressRetentionOffset: _propTypes.default.oneOfType([_propTypes.default.number, rectProp.propType])
|
|
306
|
+
}
|
|
337
307
|
})
|
|
338
308
|
};
|
|
339
309
|
const pressProps = {
|
|
@@ -352,7 +322,7 @@ exports.pressProps = pressProps;
|
|
|
352
322
|
const linkPropTypes = { ...pressPropTypes,
|
|
353
323
|
href: _propTypes.default.string,
|
|
354
324
|
hrefAttrs: _propTypes.default.shape(hrefAttrsProp.types),
|
|
355
|
-
...
|
|
325
|
+
..._propTypes2.default
|
|
356
326
|
};
|
|
357
327
|
const linkProps = {
|
|
358
328
|
/**
|
|
@@ -366,7 +336,7 @@ const linkProps = {
|
|
|
366
336
|
select: getPropSelector(linkPropTypes),
|
|
367
337
|
|
|
368
338
|
/**
|
|
369
|
-
* Turn hrefs into press handlers on Native and throw if not given `onPress`
|
|
339
|
+
* Turn hrefs into press handlers on Native and throw if not given `onPress` or `href`.
|
|
370
340
|
*
|
|
371
341
|
* @param {({ onPress?: () => void, href?: string })}
|
|
372
342
|
* @returns {(() => void)|undefined} Returns a press handler, or undefined on web if href
|
|
@@ -376,24 +346,26 @@ const linkProps = {
|
|
|
376
346
|
onPress,
|
|
377
347
|
href
|
|
378
348
|
}) => {
|
|
379
|
-
// TODO: revisit this when integrating routing packages
|
|
380
|
-
// https://github.com/telus/universal-design-system/issues/24
|
|
381
|
-
if (href && onPress) {
|
|
382
|
-
throw new Error("handleHref currently doesn't support both href and onPress");
|
|
383
|
-
}
|
|
384
|
-
|
|
385
349
|
if (!href && !onPress) {
|
|
386
350
|
throw new Error('handleHref requires either href or onPress');
|
|
387
351
|
}
|
|
388
352
|
|
|
389
|
-
return _Platform.default.
|
|
353
|
+
return _Platform.default.select({
|
|
354
|
+
web: onPress,
|
|
355
|
+
default: (...args) => {
|
|
356
|
+
if (onPress) onPress(...args);
|
|
357
|
+
if (href) _Linking.default.openURL(href);
|
|
358
|
+
}
|
|
359
|
+
});
|
|
390
360
|
}
|
|
391
361
|
};
|
|
392
362
|
exports.linkProps = linkProps;
|
|
393
363
|
const viewPropTypes = {
|
|
394
364
|
pointerEvents: _propTypes.default.oneOf(['all', 'none', 'box-only', 'box-none']),
|
|
395
365
|
onLayout: _propTypes.default.func,
|
|
396
|
-
nativeID: _propTypes.default.string
|
|
366
|
+
nativeID: _propTypes.default.string,
|
|
367
|
+
testID: _propTypes.default.string,
|
|
368
|
+
dataSet: _propTypes.default.object
|
|
397
369
|
};
|
|
398
370
|
const viewProps = {
|
|
399
371
|
/**
|
|
@@ -496,23 +468,24 @@ const spacingProps = {
|
|
|
496
468
|
}
|
|
497
469
|
};
|
|
498
470
|
/**
|
|
499
|
-
* Returns a prop type validator which checks whether a prop is either a component or an array of
|
|
500
|
-
* type, based on their `name`
|
|
471
|
+
* Returns a prop type validator which checks whether a prop is either a component or an array of
|
|
472
|
+
* components of a given type, based on their `name` or `displayName` properties.
|
|
501
473
|
* Use an array of strings for `passedName` to accept more than one component type.
|
|
502
474
|
* For an array the validation fails on the first occurrence of an invalid element.
|
|
503
475
|
*
|
|
504
476
|
* @param {string|string[]} passedName
|
|
505
|
-
* @param {boolean} [checkDisplayName] - if `true` then `displayName` property on the component will be validated instead of `name`
|
|
506
477
|
* @return {function}
|
|
507
478
|
*/
|
|
508
479
|
|
|
509
480
|
exports.spacingProps = spacingProps;
|
|
510
481
|
|
|
511
|
-
const componentPropType =
|
|
482
|
+
const componentPropType = passedName => {
|
|
512
483
|
const passedNames = typeof passedName === 'string' ? [passedName] : passedName;
|
|
513
484
|
|
|
514
485
|
const checkProp = (props, propName, componentName) => {
|
|
515
|
-
|
|
486
|
+
var _props$propName$type, _props$propName$type2;
|
|
487
|
+
|
|
488
|
+
if (props[propName] === undefined || props[propName] === null) {
|
|
516
489
|
return undefined;
|
|
517
490
|
}
|
|
518
491
|
|
|
@@ -522,12 +495,11 @@ const componentPropType = (passedName, checkDisplayName = false) => {
|
|
|
522
495
|
return props[propName].map((_, index) => checkProp(props[propName], index, componentName)).find(Boolean);
|
|
523
496
|
}
|
|
524
497
|
|
|
525
|
-
const
|
|
526
|
-
|
|
527
|
-
const testNameInFunction = () => typeof props[propName] === 'function' && (!checkDisplayName && !passedNames.includes(props[propName].name) || checkDisplayName && !passedNames.includes(props[propName].displayName));
|
|
498
|
+
const nameInProp = ((_props$propName$type = props[propName].type) === null || _props$propName$type === void 0 ? void 0 : _props$propName$type.displayName) || ((_props$propName$type2 = props[propName].type) === null || _props$propName$type2 === void 0 ? void 0 : _props$propName$type2.name);
|
|
528
499
|
|
|
529
|
-
if (
|
|
530
|
-
|
|
500
|
+
if (!nameInProp || !passedNames.includes(nameInProp)) {
|
|
501
|
+
const propDescription = nameInProp ? `Component ${nameInProp}` : typeof props[propName];
|
|
502
|
+
return new Error(`${componentName}: ${propDescription} was passed to \`${propName}\` prop; should be ${passedNames.join(' or ')}`);
|
|
531
503
|
}
|
|
532
504
|
|
|
533
505
|
return undefined;
|
|
@@ -535,7 +507,7 @@ const componentPropType = (passedName, checkDisplayName = false) => {
|
|
|
535
507
|
|
|
536
508
|
const checkRequired = (props, propName, componentName) => {
|
|
537
509
|
if (props[propName] === undefined) {
|
|
538
|
-
return new Error(
|
|
510
|
+
return new Error(`The prop \`${propName}\` is marked as required in \`${componentName}\`, but its value is ${props[propName]}.`);
|
|
539
511
|
}
|
|
540
512
|
|
|
541
513
|
return undefined;
|
package/lib/utils/useCopy.js
CHANGED
|
@@ -40,7 +40,7 @@ function useCopy({
|
|
|
40
40
|
copy = DEFAULT_COPY
|
|
41
41
|
}) {
|
|
42
42
|
if (typeof copy === 'string') {
|
|
43
|
-
return key => dictionary[copy][key];
|
|
43
|
+
return key => key ? dictionary[copy][key] : dictionary[copy];
|
|
44
44
|
} // support overriding the entire copy dictionary with an object for a single language
|
|
45
45
|
|
|
46
46
|
|
package/lib/utils/useHash.js
CHANGED
|
@@ -7,11 +7,15 @@ exports.default = void 0;
|
|
|
7
7
|
|
|
8
8
|
var _react = require("react");
|
|
9
9
|
|
|
10
|
-
const doAction = action => {
|
|
10
|
+
const doAction = (action, event) => {
|
|
11
11
|
var _window, _window$location;
|
|
12
12
|
|
|
13
|
-
return typeof action === 'function' && action((_window = window) === null || _window === void 0 ? void 0 : (_window$location = _window.location) === null || _window$location === void 0 ? void 0 : _window$location.hash);
|
|
13
|
+
return typeof action === 'function' && action((_window = window) === null || _window === void 0 ? void 0 : (_window$location = _window.location) === null || _window$location === void 0 ? void 0 : _window$location.hash, event);
|
|
14
14
|
};
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {import('react').SyntheticEvent} SyntheticEvent
|
|
17
|
+
*/
|
|
18
|
+
|
|
15
19
|
/**
|
|
16
20
|
* Calls a function (passing it the current hash) based on the current hash state on mount,
|
|
17
21
|
* and binds it to call it again any time the hash changes.
|
|
@@ -20,7 +24,7 @@ const doAction = action => {
|
|
|
20
24
|
*
|
|
21
25
|
* On Native, this is replaced with a harmless no-op function as there is no direct equivalent.
|
|
22
26
|
*
|
|
23
|
-
* @param {(hash: string) => void} action - a function to act on the current hash on load and when it changes
|
|
27
|
+
* @param {(hash: string, event?: SyntheticEvent) => void} action - a function to act on the current hash on load and when it changes
|
|
24
28
|
* @returns
|
|
25
29
|
*/
|
|
26
30
|
|
|
@@ -37,7 +41,7 @@ const useHash = (action, isReady = true) => {
|
|
|
37
41
|
}, [isToDo, action]); // Bind the action for each hash change; do re-bind if the function changes.
|
|
38
42
|
|
|
39
43
|
(0, _react.useEffect)(() => {
|
|
40
|
-
const handleChange =
|
|
44
|
+
const handleChange = event => doAction(action, event);
|
|
41
45
|
|
|
42
46
|
window.addEventListener('hashchange', handleChange);
|
|
43
47
|
return () => window.removeEventListener('hashchange', handleChange);
|
|
@@ -110,8 +110,6 @@ const resolveSpacingOptions = space => {
|
|
|
110
110
|
|
|
111
111
|
|
|
112
112
|
const useSpacingScale = spaceValue => {
|
|
113
|
-
var _spaceValue$space;
|
|
114
|
-
|
|
115
113
|
// In future, may need to consider window height as well as width, particularly for native apps,
|
|
116
114
|
// e.g. to ensure designs don't look lost on large, tall, not-so-wide portrait screens.
|
|
117
115
|
const viewport = (0, _ViewportProvider.useViewport)();
|
|
@@ -121,7 +119,7 @@ const useSpacingScale = spaceValue => {
|
|
|
121
119
|
overridden,
|
|
122
120
|
subtract = 0
|
|
123
121
|
} = resolveSpacingOptions(spaceValue);
|
|
124
|
-
const space = !overridden && ((
|
|
122
|
+
const space = !overridden && ((spaceValue === null || spaceValue === void 0 ? void 0 : spaceValue.space) ?? (0, _useResponsiveProp.resolveResponsiveProp)(spaceValue, viewport, 0));
|
|
125
123
|
const {
|
|
126
124
|
size
|
|
127
125
|
} = (0, _ThemeProvider.useThemeTokens)('spacingScale', tokens, variant, {
|
package/lib/utils/useUniqueId.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telus-uds/components-base",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Base components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"base"
|
|
@@ -23,8 +23,11 @@
|
|
|
23
23
|
"lint": "telus-standard",
|
|
24
24
|
"lint:fix": "telus-standard --fix",
|
|
25
25
|
"format": "prettier --write .",
|
|
26
|
-
"build": "
|
|
27
|
-
"
|
|
26
|
+
"build": "yarn build:code && yarn build:docs",
|
|
27
|
+
"build:code": "babel src -d lib",
|
|
28
|
+
"build:docs": "babel-node --plugins=react-docgen-alpha generate-component-docs.js",
|
|
29
|
+
"storybook": "start-storybook",
|
|
30
|
+
"dev": "yarn build:code --watch",
|
|
28
31
|
"release": "standard-version"
|
|
29
32
|
},
|
|
30
33
|
"bugs": {
|
|
@@ -33,6 +36,9 @@
|
|
|
33
36
|
"standard-engine": {
|
|
34
37
|
"skip": true
|
|
35
38
|
},
|
|
39
|
+
"browserslist": [
|
|
40
|
+
"extends @telus-uds/browserslist-config"
|
|
41
|
+
],
|
|
36
42
|
"peerDependencies": {
|
|
37
43
|
"react": "^17.0.2",
|
|
38
44
|
"react-dom": "*",
|
|
@@ -40,6 +46,7 @@
|
|
|
40
46
|
"react-native-web": "^0.17.0"
|
|
41
47
|
},
|
|
42
48
|
"devDependencies": {
|
|
49
|
+
"@telus-uds/browserslist-config": "^1.0.0",
|
|
43
50
|
"@testing-library/jest-native": "^4.0.1",
|
|
44
51
|
"@testing-library/react-hooks": "^7.0.1",
|
|
45
52
|
"@testing-library/react-native": "^7.2.0",
|
|
@@ -47,11 +54,12 @@
|
|
|
47
54
|
},
|
|
48
55
|
"dependencies": {
|
|
49
56
|
"airbnb-prop-types": "^2.16.0",
|
|
50
|
-
"@telus-uds/system-constants": "^
|
|
51
|
-
"@telus-uds/system-
|
|
57
|
+
"@telus-uds/system-constants": "^1.0.1-prerelease.0",
|
|
58
|
+
"@telus-uds/system-theme-tokens": "^1.1.0",
|
|
52
59
|
"lodash.debounce": "^4.0.8",
|
|
53
60
|
"lodash.merge": "^4.6.2",
|
|
54
61
|
"prop-types": "^15.7.2",
|
|
55
|
-
"react-native-picker-select": "^8.0.4"
|
|
62
|
+
"react-native-picker-select": "^8.0.4",
|
|
63
|
+
"semver": "^7.3.5"
|
|
56
64
|
}
|
|
57
65
|
}
|
package/release-context.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"previousReleaseTag": "@telus-uds/components-base/
|
|
3
|
-
"changelog": "
|
|
4
|
-
"releaseTag": "@telus-uds/components-base/
|
|
5
|
-
"newVersion": "
|
|
2
|
+
"previousReleaseTag": "@telus-uds/components-base/v1.0.1",
|
|
3
|
+
"changelog": "## [1.1.0](https://github.com/telus/universal-design-system/compare/@telus-uds/components-base/v1.0.1...@telus-uds/components-base/v1.1.0) (2022-02-28)\n\n\n### Features\n\n* **component-base:** add some fixes to the list component ([#1226](https://github.com/telus/universal-design-system/issues/1226)) ([35a42e0](https://github.com/telus/universal-design-system/commit/35a42e05e23630696286e7c8607e7a1e8da9d6c2))\n* **ds-allium:** add an Allium List ([#1304](https://github.com/telus/universal-design-system/issues/1304)) ([2f91c74](https://github.com/telus/universal-design-system/commit/2f91c74d6c0b30f09089e8f11beb3739e5be1887))\n* generate component docs ([#1292](https://github.com/telus/universal-design-system/issues/1292)) ([e0c03a5](https://github.com/telus/universal-design-system/commit/e0c03a5c4b5186e97d424c5b1c4594b1dda8201f))\n\n\n### Bug Fixes\n\n* **base:** no SSR crash on transpiled global CSS ([#1311](https://github.com/telus/universal-design-system/issues/1311)) ([7bc585c](https://github.com/telus/universal-design-system/commit/7bc585cc76bf7d760b1630a6f90f336f2be2abda))\n",
|
|
4
|
+
"releaseTag": "@telus-uds/components-base/v1.1.0",
|
|
5
|
+
"newVersion": "1.1.0",
|
|
6
6
|
"packageName": "@telus-uds/components-base"
|
|
7
7
|
}
|
package/src/A11yText/index.jsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
2
|
import { Platform, StyleSheet, View } from 'react-native'
|
|
3
3
|
import PropTypes from 'prop-types'
|
|
4
4
|
|
|
@@ -10,7 +10,7 @@ import { a11yProps } from '../utils/propTypes'
|
|
|
10
10
|
* It should be used to add selectable screen-reader-only text to the main document flow,
|
|
11
11
|
* as a sibling to blocks of text like paragraphs and interactive elements like buttons.
|
|
12
12
|
*/
|
|
13
|
-
const A11yText = ({ text, heading, ...rest }) => {
|
|
13
|
+
const A11yText = forwardRef(({ text, heading, ...rest }, ref) => {
|
|
14
14
|
const a11y = a11yProps.select({
|
|
15
15
|
// On iOS, needs `accessible` to be true to be focusable without non-a11y content.
|
|
16
16
|
// On Web, `accessible` causes RNW to set attributes that may make the element be treated as a group.
|
|
@@ -21,8 +21,10 @@ const A11yText = ({ text, heading, ...rest }) => {
|
|
|
21
21
|
accessibilityRole: heading ? 'header' : 'text',
|
|
22
22
|
...rest
|
|
23
23
|
})
|
|
24
|
-
return <View style={styles.invisible} {...a11y} />
|
|
25
|
-
}
|
|
24
|
+
return <View style={styles.invisible} ref={ref} {...a11y} />
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
A11yText.displayName = 'A11yText'
|
|
26
28
|
|
|
27
29
|
A11yText.propTypes = {
|
|
28
30
|
text: PropTypes.string.isRequired,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
2
|
import { DURATION, MIN_EMPTY_ANGLE, MIN_STROKE_ANGLE, BEZIER, propTypes } from './shared'
|
|
3
3
|
|
|
4
4
|
const SVG_RADIUS = 20
|
|
@@ -20,8 +20,9 @@ const bezierProps = {
|
|
|
20
20
|
}
|
|
21
21
|
// We're using svg rather than css here to define the animation to avoid needing to introduce css injection mechanism
|
|
22
22
|
// It's possible to replicate this functionality with RNW animations, but it snags on chrome at least, see https://github.com/telus/universal-design-system/pull/477 for details.
|
|
23
|
-
const Spinner = ({ size, color, thickness, label }) => (
|
|
23
|
+
const Spinner = forwardRef(({ size, color, thickness, label }, ref) => (
|
|
24
24
|
<svg
|
|
25
|
+
ref={ref}
|
|
25
26
|
width={`${size}px`}
|
|
26
27
|
height={`${size}px`}
|
|
27
28
|
viewBox="0 0 48 48"
|
|
@@ -62,7 +63,8 @@ const Spinner = ({ size, color, thickness, label }) => (
|
|
|
62
63
|
</circle>
|
|
63
64
|
</g>
|
|
64
65
|
</svg>
|
|
65
|
-
)
|
|
66
|
+
))
|
|
67
|
+
Spinner.displayName = 'Spinner'
|
|
66
68
|
|
|
67
69
|
Spinner.propTypes = propTypes
|
|
68
70
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
2
|
import { Animated, Easing, StyleSheet, View } from 'react-native'
|
|
3
3
|
import { DURATION, MIN_EMPTY_ANGLE, MIN_STROKE_ANGLE, BEZIER, propTypes } from './shared'
|
|
4
4
|
|
|
5
5
|
const ea = MIN_EMPTY_ANGLE / 2
|
|
6
6
|
const sa = MIN_STROKE_ANGLE / 2
|
|
7
7
|
|
|
8
|
-
const Spinner = ({ size, color, thickness, label }) => {
|
|
8
|
+
const Spinner = forwardRef(({ size, color, thickness, label }, ref) => {
|
|
9
9
|
const { current: timer } = React.useRef(new Animated.Value(0))
|
|
10
10
|
|
|
11
11
|
React.useLayoutEffect(() => {
|
|
@@ -31,6 +31,7 @@ const Spinner = ({ size, color, thickness, label }) => {
|
|
|
31
31
|
// Credit to https://github.com/n4kz/react-native-indicators and https://github.com/callstack/react-native-paper for this
|
|
32
32
|
return (
|
|
33
33
|
<View
|
|
34
|
+
ref={ref}
|
|
34
35
|
style={[styles.container]}
|
|
35
36
|
accessible
|
|
36
37
|
accessibilityLabel={label}
|
|
@@ -109,7 +110,8 @@ const Spinner = ({ size, color, thickness, label }) => {
|
|
|
109
110
|
</Animated.View>
|
|
110
111
|
</View>
|
|
111
112
|
)
|
|
112
|
-
}
|
|
113
|
+
})
|
|
114
|
+
Spinner.displayName = 'Spinner'
|
|
113
115
|
|
|
114
116
|
Spinner.propTypes = propTypes
|
|
115
117
|
|