@telus-uds/components-base 1.94.0 → 1.95.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/CHANGELOG.md +20 -2
- package/lib/Autocomplete/Autocomplete.js +2 -1
- package/lib/DownloadApp/DownloadApp.js +168 -0
- package/lib/DownloadApp/dictionary.js +17 -0
- package/lib/DownloadApp/index.js +10 -0
- package/lib/Icon/IconText.js +19 -2
- package/lib/Link/LinkBase.js +2 -2
- package/lib/Modal/Modal.js +1 -1
- package/lib/TabBar/TabBar.js +133 -0
- package/lib/TabBar/TabBarItem.js +184 -0
- package/lib/TabBar/index.js +10 -0
- package/lib/TextInput/TextInputBase.js +2 -1
- package/lib/Tooltip/getTooltipPosition.js +8 -9
- package/lib/index.js +16 -0
- package/lib-module/Autocomplete/Autocomplete.js +2 -1
- package/lib-module/DownloadApp/DownloadApp.js +160 -0
- package/lib-module/DownloadApp/dictionary.js +10 -0
- package/lib-module/DownloadApp/index.js +2 -0
- package/lib-module/Icon/IconText.js +19 -2
- package/lib-module/Link/LinkBase.js +2 -2
- package/lib-module/Modal/Modal.js +1 -1
- package/lib-module/TabBar/TabBar.js +125 -0
- package/lib-module/TabBar/TabBarItem.js +177 -0
- package/lib-module/TabBar/index.js +2 -0
- package/lib-module/TextInput/TextInputBase.js +2 -1
- package/lib-module/Tooltip/getTooltipPosition.js +8 -9
- package/lib-module/index.js +2 -0
- package/package.json +2 -2
- package/src/Autocomplete/Autocomplete.jsx +2 -1
- package/src/DownloadApp/DownloadApp.jsx +165 -0
- package/src/DownloadApp/dictionary.js +10 -0
- package/src/DownloadApp/index.js +3 -0
- package/src/Icon/IconText.jsx +21 -4
- package/src/Link/LinkBase.jsx +2 -2
- package/src/Modal/Modal.jsx +1 -1
- package/src/TabBar/TabBar.jsx +123 -0
- package/src/TabBar/TabBarItem.jsx +149 -0
- package/src/TabBar/index.js +3 -0
- package/src/TextInput/TextInputBase.jsx +1 -1
- package/src/Tooltip/getTooltipPosition.js +11 -12
- package/src/index.js +2 -0
|
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
function
|
|
7
|
+
function getAbsolutePosition(position) {
|
|
8
8
|
const {
|
|
9
9
|
left,
|
|
10
10
|
right,
|
|
@@ -15,7 +15,7 @@ function normalizePosition(position) {
|
|
|
15
15
|
} = position;
|
|
16
16
|
|
|
17
17
|
// adjust the coordinates so that it fits within the window
|
|
18
|
-
const
|
|
18
|
+
const finalPosition = {
|
|
19
19
|
left: Math.max(0, left),
|
|
20
20
|
right: Math.max(0, right),
|
|
21
21
|
top: Math.max(0, top),
|
|
@@ -25,15 +25,14 @@ function normalizePosition(position) {
|
|
|
25
25
|
const getAbsoluteDiff = (value1, value2) => Math.abs(Math.abs(value1) - Math.abs(value2));
|
|
26
26
|
|
|
27
27
|
// adjust the width by whatever has been subtracted from left or right
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
|
|
28
|
+
finalPosition.width = width - Math.abs(getAbsoluteDiff(left, finalPosition.left) - getAbsoluteDiff(right, finalPosition.right));
|
|
29
|
+
if (finalPosition.top !== top) {
|
|
30
|
+
finalPosition.bottom += finalPosition.top - top;
|
|
31
31
|
}
|
|
32
|
-
const isNormalized = normalized.right !== right || normalized.left !== left || normalized.top !== top;
|
|
33
32
|
return {
|
|
34
|
-
...
|
|
33
|
+
...finalPosition,
|
|
35
34
|
...rest,
|
|
36
|
-
isNormalized
|
|
35
|
+
isNormalized: false
|
|
37
36
|
};
|
|
38
37
|
}
|
|
39
38
|
function invertPosition(position) {
|
|
@@ -172,7 +171,7 @@ function getTooltipPosition(position, _ref2) {
|
|
|
172
171
|
|
|
173
172
|
// prefer 'below' over 'above', since we can always expand the document downwards,
|
|
174
173
|
// and 'above' might cause issues on small viewports with large tooltips
|
|
175
|
-
return
|
|
174
|
+
return getAbsolutePosition(leastOverflowing.position === 'above' ? findRectByPosition('below', boundingRects) : leastOverflowing);
|
|
176
175
|
}
|
|
177
176
|
var _default = getTooltipPosition;
|
|
178
177
|
exports.default = _default;
|
package/lib/index.js
CHANGED
|
@@ -19,6 +19,7 @@ var _exportNames = {
|
|
|
19
19
|
CheckboxCard: true,
|
|
20
20
|
CheckboxCardGroup: true,
|
|
21
21
|
ColourToggle: true,
|
|
22
|
+
DownloadApp: true,
|
|
22
23
|
Divider: true,
|
|
23
24
|
ExpandCollapse: true,
|
|
24
25
|
Accordion: true,
|
|
@@ -58,6 +59,7 @@ var _exportNames = {
|
|
|
58
59
|
Status: true,
|
|
59
60
|
StepTracker: true,
|
|
60
61
|
Tabs: true,
|
|
62
|
+
TabBar: true,
|
|
61
63
|
Tags: true,
|
|
62
64
|
Timeline: true,
|
|
63
65
|
Tooltip: true,
|
|
@@ -178,6 +180,12 @@ Object.defineProperty(exports, "Divider", {
|
|
|
178
180
|
return _Divider.default;
|
|
179
181
|
}
|
|
180
182
|
});
|
|
183
|
+
Object.defineProperty(exports, "DownloadApp", {
|
|
184
|
+
enumerable: true,
|
|
185
|
+
get: function () {
|
|
186
|
+
return _DownloadApp.default;
|
|
187
|
+
}
|
|
188
|
+
});
|
|
181
189
|
Object.defineProperty(exports, "ExpandCollapse", {
|
|
182
190
|
enumerable: true,
|
|
183
191
|
get: function () {
|
|
@@ -418,6 +426,12 @@ Object.defineProperty(exports, "StepTracker", {
|
|
|
418
426
|
return _StepTracker.default;
|
|
419
427
|
}
|
|
420
428
|
});
|
|
429
|
+
Object.defineProperty(exports, "TabBar", {
|
|
430
|
+
enumerable: true,
|
|
431
|
+
get: function () {
|
|
432
|
+
return _TabBar.default;
|
|
433
|
+
}
|
|
434
|
+
});
|
|
421
435
|
Object.defineProperty(exports, "Tabs", {
|
|
422
436
|
enumerable: true,
|
|
423
437
|
get: function () {
|
|
@@ -593,6 +607,7 @@ Object.keys(_Checkbox).forEach(function (key) {
|
|
|
593
607
|
var _CheckboxCard = _interopRequireDefault(require("./CheckboxCard"));
|
|
594
608
|
var _CheckboxCardGroup = _interopRequireDefault(require("./CheckboxCardGroup"));
|
|
595
609
|
var _ColourToggle = _interopRequireDefault(require("./ColourToggle"));
|
|
610
|
+
var _DownloadApp = _interopRequireDefault(require("./DownloadApp"));
|
|
596
611
|
var _Divider = _interopRequireDefault(require("./Divider"));
|
|
597
612
|
var _ExpandCollapse = _interopRequireWildcard(require("./ExpandCollapse"));
|
|
598
613
|
var _Feedback = _interopRequireDefault(require("./Feedback"));
|
|
@@ -696,6 +711,7 @@ Object.keys(_StackView).forEach(function (key) {
|
|
|
696
711
|
var _Status = _interopRequireDefault(require("./Status"));
|
|
697
712
|
var _StepTracker = _interopRequireDefault(require("./StepTracker"));
|
|
698
713
|
var _Tabs = _interopRequireDefault(require("./Tabs"));
|
|
714
|
+
var _TabBar = _interopRequireDefault(require("./TabBar"));
|
|
699
715
|
var _Tags = _interopRequireDefault(require("./Tags"));
|
|
700
716
|
var _TextInput = require("./TextInput");
|
|
701
717
|
Object.keys(_TextInput).forEach(function (key) {
|
|
@@ -106,6 +106,7 @@ const Autocomplete = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
106
106
|
validation,
|
|
107
107
|
value,
|
|
108
108
|
helpText = '',
|
|
109
|
+
loadingLabel,
|
|
109
110
|
...rest
|
|
110
111
|
} = _ref2;
|
|
111
112
|
const {
|
|
@@ -341,7 +342,7 @@ const Autocomplete = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
341
342
|
onLayout: handleMeasure,
|
|
342
343
|
ref: openOverlayRef,
|
|
343
344
|
children: isLoading ? /*#__PURE__*/_jsx(Loading, {
|
|
344
|
-
label: getCopy('loading')
|
|
345
|
+
label: loadingLabel ?? getCopy('loading')
|
|
345
346
|
}) : /*#__PURE__*/_jsx(Suggestions, {
|
|
346
347
|
hasResults: getCopy('hasResults'),
|
|
347
348
|
id: "autocomplete",
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import Pressable from "react-native-web/dist/exports/Pressable";
|
|
4
|
+
import Platform from "react-native-web/dist/exports/Platform";
|
|
5
|
+
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
6
|
+
import { a11yProps, linkProps, hrefAttrsProp, viewProps, getTokensPropType, resolvePressableTokens, variantProp, copyPropTypes, selectSystemProps, useCopy } from '../utils';
|
|
7
|
+
import { useThemeTokensCallback } from '../ThemeProvider';
|
|
8
|
+
import defaultDictionary from './dictionary';
|
|
9
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, linkProps, viewProps]);
|
|
11
|
+
const selectOuterStyles = _ref => {
|
|
12
|
+
let {
|
|
13
|
+
borderColor,
|
|
14
|
+
borderWidth,
|
|
15
|
+
borderGap,
|
|
16
|
+
borderRadius,
|
|
17
|
+
padding
|
|
18
|
+
} = _ref;
|
|
19
|
+
return {
|
|
20
|
+
outline: 'none',
|
|
21
|
+
borderColor,
|
|
22
|
+
borderWidth,
|
|
23
|
+
borderGap,
|
|
24
|
+
borderRadius,
|
|
25
|
+
padding
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
const DownloadApp = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
29
|
+
let {
|
|
30
|
+
copy = 'en',
|
|
31
|
+
dictionary = defaultDictionary,
|
|
32
|
+
type = 'ios',
|
|
33
|
+
href,
|
|
34
|
+
onPress,
|
|
35
|
+
tokens = {},
|
|
36
|
+
variant = {},
|
|
37
|
+
...props
|
|
38
|
+
} = _ref2;
|
|
39
|
+
const getCopy = useCopy({
|
|
40
|
+
dictionary,
|
|
41
|
+
copy
|
|
42
|
+
});
|
|
43
|
+
const {
|
|
44
|
+
hrefAttrs,
|
|
45
|
+
rest
|
|
46
|
+
} = hrefAttrsProp.bundle(props);
|
|
47
|
+
const selectedProps = selectProps({
|
|
48
|
+
accessibilityRole: href ? 'link' : 'button',
|
|
49
|
+
href,
|
|
50
|
+
onPress: linkProps.handleHref({
|
|
51
|
+
href,
|
|
52
|
+
onPress
|
|
53
|
+
}),
|
|
54
|
+
hrefAttrs,
|
|
55
|
+
...rest
|
|
56
|
+
});
|
|
57
|
+
const getDownloadAppTokens = useThemeTokensCallback('DownloadApp', tokens, variant);
|
|
58
|
+
const resolveDownloadAppTokens = pressableState => {
|
|
59
|
+
const themeTokens = resolvePressableTokens(getDownloadAppTokens, pressableState, {});
|
|
60
|
+
return selectOuterStyles(themeTokens);
|
|
61
|
+
};
|
|
62
|
+
const {
|
|
63
|
+
androidENIcon,
|
|
64
|
+
androidFRIcon,
|
|
65
|
+
iosENIcon,
|
|
66
|
+
iosFRIcon
|
|
67
|
+
} = getDownloadAppTokens();
|
|
68
|
+
const imageResources = {
|
|
69
|
+
en: {
|
|
70
|
+
android: androidENIcon,
|
|
71
|
+
ios: iosENIcon
|
|
72
|
+
},
|
|
73
|
+
fr: {
|
|
74
|
+
android: androidFRIcon,
|
|
75
|
+
ios: iosFRIcon
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const IconComponent = imageResources[copy][type];
|
|
79
|
+
return /*#__PURE__*/_jsx(Pressable, {
|
|
80
|
+
ref: ref,
|
|
81
|
+
style: pressState => [resolveDownloadAppTokens(pressState), staticStyles.row],
|
|
82
|
+
...selectedProps,
|
|
83
|
+
children: /*#__PURE__*/_jsx(IconComponent, {
|
|
84
|
+
style: staticImageSizes[type][copy],
|
|
85
|
+
alt: type === 'ios' ? getCopy('altTextIos') : getCopy('altTextAndroid')
|
|
86
|
+
})
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
DownloadApp.displayName = 'DownloadApp';
|
|
90
|
+
const dictionaryContentShape = PropTypes.shape({
|
|
91
|
+
altTextAndroid: PropTypes.string.isRequired,
|
|
92
|
+
altTextIos: PropTypes.string.isRequired
|
|
93
|
+
});
|
|
94
|
+
DownloadApp.propTypes = {
|
|
95
|
+
...selectedSystemPropTypes,
|
|
96
|
+
copy: copyPropTypes,
|
|
97
|
+
/**
|
|
98
|
+
* Override the default dictionary, by passing the complete dictionary object for `en` and `fr`
|
|
99
|
+
*/
|
|
100
|
+
dictionary: PropTypes.shape({
|
|
101
|
+
en: dictionaryContentShape,
|
|
102
|
+
fr: dictionaryContentShape
|
|
103
|
+
}),
|
|
104
|
+
/**
|
|
105
|
+
* Select the type of image to show.
|
|
106
|
+
*/
|
|
107
|
+
type: PropTypes.oneOf(['android', 'ios']),
|
|
108
|
+
/**
|
|
109
|
+
* It's a simple link that opens the Download Button instead of the onPress function.
|
|
110
|
+
*/
|
|
111
|
+
href: PropTypes.string,
|
|
112
|
+
/**
|
|
113
|
+
* Function called when the button is pressed. Required unless the button has a href.
|
|
114
|
+
*/
|
|
115
|
+
onPress: PropTypes.func,
|
|
116
|
+
/**
|
|
117
|
+
* DownloadApp tokens.
|
|
118
|
+
*/
|
|
119
|
+
tokens: getTokensPropType('DownloadApp'),
|
|
120
|
+
/**
|
|
121
|
+
* DownloadApp variant.
|
|
122
|
+
*/
|
|
123
|
+
variant: variantProp.propType
|
|
124
|
+
};
|
|
125
|
+
const staticStyles = StyleSheet.create({
|
|
126
|
+
row: {
|
|
127
|
+
...Platform.select({
|
|
128
|
+
web: {
|
|
129
|
+
display: 'inline-flex',
|
|
130
|
+
width: 'fit-content'
|
|
131
|
+
},
|
|
132
|
+
default: {
|
|
133
|
+
alignSelf: 'flex-start'
|
|
134
|
+
}
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
const staticImageSizes = {
|
|
139
|
+
android: {
|
|
140
|
+
en: {
|
|
141
|
+
width: 162,
|
|
142
|
+
height: 48
|
|
143
|
+
},
|
|
144
|
+
fr: {
|
|
145
|
+
width: 162,
|
|
146
|
+
height: 48
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
ios: {
|
|
150
|
+
en: {
|
|
151
|
+
width: 144,
|
|
152
|
+
height: 48
|
|
153
|
+
},
|
|
154
|
+
fr: {
|
|
155
|
+
width: 152,
|
|
156
|
+
height: 48
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
export default DownloadApp;
|
|
@@ -2,6 +2,8 @@ import React from 'react';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import Platform from "react-native-web/dist/exports/Platform";
|
|
4
4
|
import View from "react-native-web/dist/exports/View";
|
|
5
|
+
import Text from "react-native-web/dist/exports/Text";
|
|
6
|
+
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
5
7
|
import Icon, { iconComponentPropTypes } from './Icon';
|
|
6
8
|
import { getStackedContent } from '../StackView';
|
|
7
9
|
import { spacingProps } from '../utils';
|
|
@@ -15,6 +17,7 @@ import { spacingProps } from '../utils';
|
|
|
15
17
|
* - within a container with `flexDirection: 'row'`
|
|
16
18
|
*/
|
|
17
19
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
20
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
18
21
|
const IconText = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
19
22
|
var _iconProps$tokens, _iconProps$tokens2;
|
|
20
23
|
let {
|
|
@@ -59,6 +62,15 @@ const IconText = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
59
62
|
});
|
|
60
63
|
const mobile = Platform.OS === 'android' ? iconAdjustedAndroid : iconAdjustedIOS;
|
|
61
64
|
const adjustedContainer = Platform.OS === 'web' ? iconContent : mobile;
|
|
65
|
+
const adjustedContainerWithPosition = /*#__PURE__*/_jsx(View, {
|
|
66
|
+
style: staticStyles.adjustedContainer,
|
|
67
|
+
children: adjustedContainer
|
|
68
|
+
});
|
|
69
|
+
if (iconPosition === 'inline') {
|
|
70
|
+
return /*#__PURE__*/_jsxs(Text, {
|
|
71
|
+
children: [children, " ", adjustedContainerWithPosition]
|
|
72
|
+
});
|
|
73
|
+
}
|
|
62
74
|
return getStackedContent(iconPosition === 'left' ? [adjustedContainer, children] : [children, adjustedContainer], {
|
|
63
75
|
space,
|
|
64
76
|
direction: 'row'
|
|
@@ -73,9 +85,9 @@ IconText.propTypes = {
|
|
|
73
85
|
*/
|
|
74
86
|
space: spacingProps.types.spacingValue,
|
|
75
87
|
/**
|
|
76
|
-
* Whether the icon should be to the left of the content
|
|
88
|
+
* Whether the icon should be to the left of the content, the right of the content or inline with the content.
|
|
77
89
|
*/
|
|
78
|
-
iconPosition: PropTypes.oneOf(['left', 'right']),
|
|
90
|
+
iconPosition: PropTypes.oneOf(['left', 'right', 'inline']),
|
|
79
91
|
/**
|
|
80
92
|
* A valid UDS icon component imported from a UDS palette.
|
|
81
93
|
*/
|
|
@@ -94,4 +106,9 @@ IconText.propTypes = {
|
|
|
94
106
|
/* eslint-enable react/no-unused-prop-types */
|
|
95
107
|
};
|
|
96
108
|
|
|
109
|
+
const staticStyles = StyleSheet.create({
|
|
110
|
+
adjustedContainer: {
|
|
111
|
+
position: 'absolute'
|
|
112
|
+
}
|
|
113
|
+
});
|
|
97
114
|
export default IconText;
|
|
@@ -238,9 +238,9 @@ LinkBase.propTypes = {
|
|
|
238
238
|
*/
|
|
239
239
|
icon: PropTypes.elementType,
|
|
240
240
|
/**
|
|
241
|
-
* When `icon` is provided, use `iconPosition` to place the Icon to the left or
|
|
241
|
+
* When `icon` is provided, use `iconPosition` to place the Icon to the left, right or inline with Link.
|
|
242
242
|
*/
|
|
243
|
-
iconPosition: PropTypes.oneOf(['left', 'right']),
|
|
243
|
+
iconPosition: PropTypes.oneOf(['left', 'right', 'inline']),
|
|
244
244
|
/**
|
|
245
245
|
* On Web if href is passed, React Native Web maps this object's props to
|
|
246
246
|
* `rel`, `target` and `download` attrs.
|
|
@@ -153,7 +153,7 @@ const Modal = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
153
153
|
if (Platform.OS === 'web') {
|
|
154
154
|
const handleFocus = () => {
|
|
155
155
|
// If the focus is on the last item of the web modal container, move it to the close button
|
|
156
|
-
if (document.activeElement === focusTrapRef.current) {
|
|
156
|
+
if (document.activeElement === focusTrapRef.current && closeButtonRef.current) {
|
|
157
157
|
closeButtonRef.current.focus();
|
|
158
158
|
}
|
|
159
159
|
return undefined;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import View from "react-native-web/dist/exports/View";
|
|
4
|
+
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
5
|
+
import TabBarItem from './TabBarItem';
|
|
6
|
+
import { useThemeTokens } from '../ThemeProvider';
|
|
7
|
+
import { variantProp, getTokensPropType, selectSystemProps, a11yProps, viewProps } from '../utils';
|
|
8
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
|
+
const selectTabBarContainerStyles = _ref => {
|
|
10
|
+
let {
|
|
11
|
+
paddingTop,
|
|
12
|
+
paddingBottom,
|
|
13
|
+
borderTopWidth,
|
|
14
|
+
borderTopColor,
|
|
15
|
+
backgroundColor
|
|
16
|
+
} = _ref;
|
|
17
|
+
return {
|
|
18
|
+
paddingTop,
|
|
19
|
+
paddingBottom,
|
|
20
|
+
borderTopWidth,
|
|
21
|
+
borderTopColor,
|
|
22
|
+
backgroundColor
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
const selectTabBarItemContainerStyles = _ref2 => {
|
|
26
|
+
let {
|
|
27
|
+
paddingLeft,
|
|
28
|
+
paddingRight,
|
|
29
|
+
gap
|
|
30
|
+
} = _ref2;
|
|
31
|
+
return {
|
|
32
|
+
paddingLeft,
|
|
33
|
+
paddingRight,
|
|
34
|
+
gap
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* TabBar component renders a navigation bar with multiple TabBarItems.
|
|
41
|
+
* It allows users to switch between different views or sections.
|
|
42
|
+
*
|
|
43
|
+
* @component
|
|
44
|
+
* @example
|
|
45
|
+
* const items = [
|
|
46
|
+
* { id: '1', label: 'Home', icon: <HomeIcon />, iconActive: <HomeActiveIcon /> },
|
|
47
|
+
* { id: '2', label: 'Profile', icon: <ProfileIcon />, iconActive: <ProfileActiveIcon /> },
|
|
48
|
+
* ]
|
|
49
|
+
* return (
|
|
50
|
+
* <TabBar
|
|
51
|
+
* items={items}
|
|
52
|
+
* initiallySelectedItem="1"
|
|
53
|
+
* onChange={(itemId) => console.log(itemId)}
|
|
54
|
+
* />
|
|
55
|
+
* )
|
|
56
|
+
*/
|
|
57
|
+
|
|
58
|
+
const TabBar = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
59
|
+
let {
|
|
60
|
+
items = [],
|
|
61
|
+
initiallySelectedItem = '0',
|
|
62
|
+
onChange,
|
|
63
|
+
variant,
|
|
64
|
+
tokens,
|
|
65
|
+
...rest
|
|
66
|
+
} = _ref3;
|
|
67
|
+
const [isSelected, setIsSelected] = React.useState(initiallySelectedItem);
|
|
68
|
+
const themeTokens = useThemeTokens('TabBar', tokens, variant);
|
|
69
|
+
const handlePress = itemId => {
|
|
70
|
+
setIsSelected(itemId);
|
|
71
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(itemId);
|
|
72
|
+
};
|
|
73
|
+
return /*#__PURE__*/_jsx(View, {
|
|
74
|
+
ref: ref,
|
|
75
|
+
style: [styles.tabBar, selectTabBarContainerStyles(themeTokens)],
|
|
76
|
+
...selectProps(rest),
|
|
77
|
+
children: /*#__PURE__*/_jsx(View, {
|
|
78
|
+
style: [styles.tabBarItem, selectTabBarItemContainerStyles(themeTokens)],
|
|
79
|
+
children: items.map((item, index) => /*#__PURE__*/_jsx(TabBarItem, {
|
|
80
|
+
label: item.label,
|
|
81
|
+
href: item.href,
|
|
82
|
+
isSelected: isSelected === item.id,
|
|
83
|
+
icon: item.icon,
|
|
84
|
+
iconActive: item.iconActive,
|
|
85
|
+
onPress: () => handlePress(item.id),
|
|
86
|
+
id: `tab-item-${index}`,
|
|
87
|
+
accessibilityRole: "tablist"
|
|
88
|
+
}, item.id))
|
|
89
|
+
})
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
TabBar.displayName = 'TabBar';
|
|
93
|
+
TabBar.propTypes = {
|
|
94
|
+
...selectedSystemPropTypes,
|
|
95
|
+
/** Array of TabBarItems to be displayed in TabBar */
|
|
96
|
+
items: PropTypes.arrayOf(PropTypes.shape({
|
|
97
|
+
id: PropTypes.string.isRequired,
|
|
98
|
+
icon: PropTypes.node,
|
|
99
|
+
iconActive: PropTypes.node,
|
|
100
|
+
label: PropTypes.string.isRequired,
|
|
101
|
+
href: PropTypes.string
|
|
102
|
+
})).isRequired,
|
|
103
|
+
/** Id of the initially selected item. */
|
|
104
|
+
initiallySelectedItem: PropTypes.number,
|
|
105
|
+
/** Callback function to handle item selection change. */
|
|
106
|
+
onChange: PropTypes.func,
|
|
107
|
+
/** Variant of TabBar for styling purposes. */
|
|
108
|
+
variant: variantProp.propType,
|
|
109
|
+
/** Tokens for theming and styling. */
|
|
110
|
+
tokens: getTokensPropType('TabBar')
|
|
111
|
+
};
|
|
112
|
+
const styles = StyleSheet.create({
|
|
113
|
+
tabBar: {
|
|
114
|
+
flex: 1,
|
|
115
|
+
justifyContent: 'center',
|
|
116
|
+
alignItems: 'center'
|
|
117
|
+
},
|
|
118
|
+
tabBarItem: {
|
|
119
|
+
flex: 1,
|
|
120
|
+
flexDirection: 'row',
|
|
121
|
+
justifyContent: 'space-between',
|
|
122
|
+
width: '100%'
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
export default TabBar;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import Pressable from "react-native-web/dist/exports/Pressable";
|
|
4
|
+
import View from "react-native-web/dist/exports/View";
|
|
5
|
+
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
6
|
+
import { getTokensPropType, resolvePressableTokens, variantProp } from '../utils';
|
|
7
|
+
import { useThemeTokensCallback } from '../ThemeProvider';
|
|
8
|
+
import Typography from '../Typography';
|
|
9
|
+
import Spacer from '../Spacer';
|
|
10
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
12
|
+
const selectTypographyStyles = (_ref, isSelected) => {
|
|
13
|
+
let {
|
|
14
|
+
fontWeight,
|
|
15
|
+
color,
|
|
16
|
+
lineHeight,
|
|
17
|
+
fontName,
|
|
18
|
+
activeColor
|
|
19
|
+
} = _ref;
|
|
20
|
+
return {
|
|
21
|
+
fontWeight,
|
|
22
|
+
color: isSelected ? activeColor : color,
|
|
23
|
+
lineHeight,
|
|
24
|
+
fontName
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
const selectIconContainerStyles = _ref2 => {
|
|
28
|
+
let {
|
|
29
|
+
paddingTop,
|
|
30
|
+
paddingBottom
|
|
31
|
+
} = _ref2;
|
|
32
|
+
return {
|
|
33
|
+
paddingTop,
|
|
34
|
+
paddingBottom,
|
|
35
|
+
alignItems: 'center'
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
const selectIconStyles = (_ref3, isSelected) => {
|
|
39
|
+
let {
|
|
40
|
+
iconSize,
|
|
41
|
+
iconColor,
|
|
42
|
+
activeColor
|
|
43
|
+
} = _ref3;
|
|
44
|
+
return {
|
|
45
|
+
size: iconSize,
|
|
46
|
+
color: isSelected ? activeColor : iconColor
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
const selectContainerStyles = _ref4 => {
|
|
50
|
+
let {
|
|
51
|
+
borderRadius,
|
|
52
|
+
backgroundColor
|
|
53
|
+
} = _ref4;
|
|
54
|
+
return {
|
|
55
|
+
borderRadius,
|
|
56
|
+
backgroundColor,
|
|
57
|
+
alignSelf: 'center',
|
|
58
|
+
alignItems: 'center'
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
const TabBarItem = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
62
|
+
let {
|
|
63
|
+
href,
|
|
64
|
+
variant,
|
|
65
|
+
tokens,
|
|
66
|
+
label,
|
|
67
|
+
isSelected,
|
|
68
|
+
id,
|
|
69
|
+
onPress,
|
|
70
|
+
icon: IconComponent,
|
|
71
|
+
iconActive: IconActiveComponent,
|
|
72
|
+
accessibilityRole = 'tab'
|
|
73
|
+
} = _ref5;
|
|
74
|
+
const getTokens = useThemeTokensCallback('TabBarItem', tokens, variant);
|
|
75
|
+
const getPressableStyle = _ref6 => {
|
|
76
|
+
let {
|
|
77
|
+
pressed,
|
|
78
|
+
focused,
|
|
79
|
+
hovered
|
|
80
|
+
} = _ref6;
|
|
81
|
+
const resolvedTokens = resolvePressableTokens(getTokens, {
|
|
82
|
+
pressed,
|
|
83
|
+
focused,
|
|
84
|
+
hovered
|
|
85
|
+
}, {
|
|
86
|
+
isSelected
|
|
87
|
+
});
|
|
88
|
+
return {
|
|
89
|
+
...resolvedTokens,
|
|
90
|
+
outline: 'none' // removes the default browser :focus outline
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
return /*#__PURE__*/_jsx(Pressable, {
|
|
95
|
+
ref: ref,
|
|
96
|
+
href: href,
|
|
97
|
+
nativeID: id,
|
|
98
|
+
onPress: onPress,
|
|
99
|
+
style: _ref7 => {
|
|
100
|
+
let {
|
|
101
|
+
pressed,
|
|
102
|
+
focused,
|
|
103
|
+
hovered
|
|
104
|
+
} = _ref7;
|
|
105
|
+
return [styles.flexContainer, getPressableStyle({
|
|
106
|
+
pressed,
|
|
107
|
+
focused,
|
|
108
|
+
hovered
|
|
109
|
+
})];
|
|
110
|
+
},
|
|
111
|
+
accessibilityRole: accessibilityRole,
|
|
112
|
+
testID: id,
|
|
113
|
+
children: pressableState => {
|
|
114
|
+
const resolvedTokens = getPressableStyle(pressableState);
|
|
115
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
116
|
+
style: selectContainerStyles(resolvedTokens),
|
|
117
|
+
children: [/*#__PURE__*/_jsx(View, {
|
|
118
|
+
style: [selectIconContainerStyles(resolvedTokens), styles.iconContainer],
|
|
119
|
+
children: isSelected ? IconActiveComponent && /*#__PURE__*/_jsx(IconActiveComponent, {
|
|
120
|
+
...selectIconStyles(resolvedTokens, isSelected)
|
|
121
|
+
}) : IconComponent && /*#__PURE__*/_jsx(IconComponent, {
|
|
122
|
+
...selectIconStyles(resolvedTokens)
|
|
123
|
+
})
|
|
124
|
+
}), /*#__PURE__*/_jsx(Spacer, {
|
|
125
|
+
space: 1
|
|
126
|
+
}), /*#__PURE__*/_jsx(Typography, {
|
|
127
|
+
variant: {
|
|
128
|
+
size: 'micro'
|
|
129
|
+
},
|
|
130
|
+
tokens: selectTypographyStyles(resolvedTokens, isSelected),
|
|
131
|
+
align: "center",
|
|
132
|
+
children: label
|
|
133
|
+
}), /*#__PURE__*/_jsx(Spacer, {
|
|
134
|
+
space: 1
|
|
135
|
+
})]
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
TabBarItem.displayName = 'TabBarItem';
|
|
141
|
+
TabBarItem.propTypes = {
|
|
142
|
+
/** The icon to be displayed when the item is not selected. */
|
|
143
|
+
icon: PropTypes.elementType,
|
|
144
|
+
/** The icon to be displayed when the item is selected. */
|
|
145
|
+
iconActive: PropTypes.elementType,
|
|
146
|
+
/** Tokens for theming and styling the TabBarItem. */
|
|
147
|
+
tokens: getTokensPropType('TabBarItem'),
|
|
148
|
+
/** Variant of the TabBarItem for styling purposes. */
|
|
149
|
+
variant: variantProp.propType,
|
|
150
|
+
/** Callback function to handle press events. */
|
|
151
|
+
onPress: PropTypes.func,
|
|
152
|
+
/** URL to navigate to when the item is pressed. */
|
|
153
|
+
href: PropTypes.string,
|
|
154
|
+
/** Indicates whether the item is selected. */
|
|
155
|
+
isSelected: PropTypes.bool,
|
|
156
|
+
/** Unique identifier for the item. */
|
|
157
|
+
id: PropTypes.string,
|
|
158
|
+
/** Label text for the item. */
|
|
159
|
+
label: PropTypes.string.isRequired,
|
|
160
|
+
/** Accessibility role for the item. */
|
|
161
|
+
accessibilityRole: PropTypes.string
|
|
162
|
+
};
|
|
163
|
+
const styles = StyleSheet.create({
|
|
164
|
+
flexContainer: {
|
|
165
|
+
flex: 1,
|
|
166
|
+
alignItems: 'center'
|
|
167
|
+
},
|
|
168
|
+
iconContainer: {
|
|
169
|
+
flex: 1,
|
|
170
|
+
justifyContent: 'center',
|
|
171
|
+
alignItems: 'center',
|
|
172
|
+
minWidth: 44,
|
|
173
|
+
minHeight: 40,
|
|
174
|
+
aspectRatio: 1.1
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
export default TabBarItem;
|
|
@@ -42,7 +42,8 @@ const selectInputStyles = function (_ref, themeOptions, inactive, type) {
|
|
|
42
42
|
// jump around if the border width changes (avoiding NaN and negative padding)
|
|
43
43
|
const offsetBorder = value => typeof value === 'number' ? Math.max(0, value - borderWidth) : value;
|
|
44
44
|
const textStyles = applyTextStyles({
|
|
45
|
-
fontName,
|
|
45
|
+
fontName: isPassword ? undefined : fontName,
|
|
46
|
+
// In this case, we don't want to apply the fontName to the input if it's a password because Monotype don't have support for the masked characters in mobile.
|
|
46
47
|
fontSize,
|
|
47
48
|
lineHeight,
|
|
48
49
|
fontWeight,
|