@telus-uds/components-base 3.17.1 → 3.19.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 -4
- package/LICENSE +21 -0
- package/jest.config.cjs +10 -2
- package/lib/cjs/Box/Box.js +114 -62
- package/lib/cjs/Box/backgroundImageStylesMap.js +136 -28
- package/lib/cjs/Carousel/Carousel.js +1 -1
- package/lib/cjs/Modal/Modal.js +7 -1
- package/lib/cjs/Modal/ModalContent.js +6 -4
- package/lib/cjs/MultiSelectFilter/MultiSelectFilter.js +2 -2
- package/lib/cjs/StepTracker/Step.js +12 -1
- package/lib/cjs/StepTracker/StepTracker.js +15 -4
- package/lib/cjs/TabBar/TabBar.js +4 -2
- package/lib/cjs/TabBar/index.js +2 -0
- package/lib/cjs/Tooltip/Backdrop.js +1 -1
- package/lib/cjs/utils/index.js +9 -1
- package/lib/cjs/utils/isTouchDevice.js +34 -0
- package/lib/esm/Box/Box.js +113 -63
- package/lib/esm/Box/backgroundImageStylesMap.js +134 -27
- package/lib/esm/Carousel/Carousel.js +2 -2
- package/lib/esm/Modal/Modal.js +7 -1
- package/lib/esm/Modal/ModalContent.js +6 -4
- package/lib/esm/MultiSelectFilter/MultiSelectFilter.js +2 -2
- package/lib/esm/StepTracker/Step.js +12 -1
- package/lib/esm/StepTracker/StepTracker.js +15 -4
- package/lib/esm/TabBar/TabBar.js +4 -2
- package/lib/esm/TabBar/index.js +2 -0
- package/lib/esm/Tooltip/Backdrop.js +1 -1
- package/lib/esm/utils/index.js +2 -1
- package/lib/esm/utils/isTouchDevice.js +27 -0
- package/lib/package.json +2 -2
- package/package.json +2 -2
- package/src/Box/Box.jsx +97 -55
- package/src/Box/backgroundImageStylesMap.js +48 -15
- package/src/Carousel/Carousel.jsx +3 -2
- package/src/Modal/Modal.jsx +7 -1
- package/src/Modal/ModalContent.jsx +6 -3
- package/src/MultiSelectFilter/MultiSelectFilter.jsx +2 -2
- package/src/StepTracker/Step.jsx +47 -27
- package/src/StepTracker/StepTracker.jsx +9 -1
- package/src/TabBar/TabBar.jsx +3 -1
- package/src/TabBar/index.js +3 -0
- package/src/Tooltip/Backdrop.jsx +1 -1
- package/src/utils/index.js +1 -0
- package/src/utils/isTouchDevice.js +34 -0
|
@@ -28,7 +28,8 @@ const ModalContent = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
28
28
|
cancelButtonText,
|
|
29
29
|
cancelButtonType: CancelButton = TextButton,
|
|
30
30
|
children,
|
|
31
|
-
onCancel
|
|
31
|
+
onCancel,
|
|
32
|
+
footer
|
|
32
33
|
} = _ref;
|
|
33
34
|
const viewport = useViewport();
|
|
34
35
|
const {
|
|
@@ -142,7 +143,7 @@ const ModalContent = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
142
143
|
children: /*#__PURE__*/_jsx(Typography, {
|
|
143
144
|
children: bodyText
|
|
144
145
|
})
|
|
145
|
-
}), children, (hasConfirmButton || hasCancelButton) && /*#__PURE__*/_jsxs(View, {
|
|
146
|
+
}), children, (hasConfirmButton || hasCancelButton) && !footer && /*#__PURE__*/_jsxs(View, {
|
|
146
147
|
style: [selectFooterContainerStyles({
|
|
147
148
|
...themeTokens,
|
|
148
149
|
hasBorder: isContentOverflowing
|
|
@@ -164,7 +165,7 @@ const ModalContent = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
164
165
|
children: cancelButtonText
|
|
165
166
|
})
|
|
166
167
|
}) : null]
|
|
167
|
-
})]
|
|
168
|
+
}), footer]
|
|
168
169
|
});
|
|
169
170
|
});
|
|
170
171
|
ModalContent.displayName = 'ModalContent';
|
|
@@ -193,6 +194,7 @@ ModalContent.propTypes = {
|
|
|
193
194
|
cancelButtonType: PropTypes.elementType,
|
|
194
195
|
// TODO: figure out a way of passing an icon to the TextButton
|
|
195
196
|
children: PropTypes.node,
|
|
196
|
-
onCancel: PropTypes.func
|
|
197
|
+
onCancel: PropTypes.func,
|
|
198
|
+
footer: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)])
|
|
197
199
|
};
|
|
198
200
|
export default ModalContent;
|
|
@@ -482,9 +482,9 @@ MultiSelectFilter.propTypes = {
|
|
|
482
482
|
*/
|
|
483
483
|
label: PropTypes.string.isRequired,
|
|
484
484
|
/**
|
|
485
|
-
* The text for the subtitle
|
|
485
|
+
* The text for the subtitle. Can also be JSX.
|
|
486
486
|
*/
|
|
487
|
-
subtitle: PropTypes.string,
|
|
487
|
+
subtitle: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
488
488
|
/**
|
|
489
489
|
* An optional unique string may be provided to identify the ButtonDropdown.
|
|
490
490
|
* If not provided, the label is used.
|
|
@@ -150,6 +150,13 @@ const getStepTestID = (isCompleted, isCurrent) => {
|
|
|
150
150
|
}
|
|
151
151
|
return testID;
|
|
152
152
|
};
|
|
153
|
+
const selectBarContainerStyles = (themeTokens, isCompleted, isCurrent) => ({
|
|
154
|
+
backgroundColor: isCompleted ? themeTokens.barCompletedBackgroundColor : themeTokens.barBackgroundColor,
|
|
155
|
+
height: themeTokens.barHeight,
|
|
156
|
+
...(isCurrent && {
|
|
157
|
+
backgroundColor: themeTokens.barCurrentBackgroundColor
|
|
158
|
+
})
|
|
159
|
+
});
|
|
153
160
|
|
|
154
161
|
/**
|
|
155
162
|
* A single step of a StepTracker.
|
|
@@ -162,6 +169,7 @@ const Step = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
|
|
|
162
169
|
stepCount = 0,
|
|
163
170
|
stepIndex = 0,
|
|
164
171
|
tokens,
|
|
172
|
+
isBarVariant,
|
|
165
173
|
...rest
|
|
166
174
|
} = _ref8;
|
|
167
175
|
const {
|
|
@@ -190,7 +198,10 @@ const Step = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
|
|
|
190
198
|
accessibilityCurrent: status === stepIndex,
|
|
191
199
|
ref: ref,
|
|
192
200
|
...selectProps(rest),
|
|
193
|
-
children: [/*#__PURE__*/
|
|
201
|
+
children: [isBarVariant && /*#__PURE__*/_jsx(View, {
|
|
202
|
+
style: selectBarContainerStyles(themeTokens, isCompleted, isCurrent),
|
|
203
|
+
testID: getStepTestID(isCompleted, isCurrent)
|
|
204
|
+
}), !isBarVariant && /*#__PURE__*/_jsxs(StackView, {
|
|
194
205
|
direction: "row",
|
|
195
206
|
space: 0,
|
|
196
207
|
tokens: {
|
|
@@ -12,6 +12,7 @@ import useCopy from '../utils/useCopy';
|
|
|
12
12
|
import Step from './Step';
|
|
13
13
|
import defaultDictionary from './dictionary';
|
|
14
14
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
15
|
+
const STYLE_BAR_VARIANT = 'bar';
|
|
15
16
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
16
17
|
const selectContainerStyles = _ref => {
|
|
17
18
|
let {
|
|
@@ -52,6 +53,14 @@ const selectStepTrackerLabelStyles = (_ref3, themeOptions) => {
|
|
|
52
53
|
themeOptions
|
|
53
54
|
});
|
|
54
55
|
};
|
|
56
|
+
const selectStepsContainerStyles = _ref4 => {
|
|
57
|
+
let {
|
|
58
|
+
barGap
|
|
59
|
+
} = _ref4;
|
|
60
|
+
return {
|
|
61
|
+
gap: barGap
|
|
62
|
+
};
|
|
63
|
+
};
|
|
55
64
|
|
|
56
65
|
/**
|
|
57
66
|
* StepTracker component shows the current position in a sequence of steps.
|
|
@@ -85,7 +94,7 @@ const selectStepTrackerLabelStyles = (_ref3, themeOptions) => {
|
|
|
85
94
|
* - `accessibilityValue.text` (`aria-valuetext`): `<Current Step Label>`,
|
|
86
95
|
*
|
|
87
96
|
*/
|
|
88
|
-
const StepTracker = /*#__PURE__*/React.forwardRef((
|
|
97
|
+
const StepTracker = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
89
98
|
let {
|
|
90
99
|
current = 0,
|
|
91
100
|
copy = 'en',
|
|
@@ -94,7 +103,8 @@ const StepTracker = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
|
|
|
94
103
|
tokens,
|
|
95
104
|
variant,
|
|
96
105
|
...rest
|
|
97
|
-
} =
|
|
106
|
+
} = _ref5;
|
|
107
|
+
const isBarVariant = variant?.style === STYLE_BAR_VARIANT;
|
|
98
108
|
const viewport = useViewport();
|
|
99
109
|
const {
|
|
100
110
|
showStepTrackerLabel,
|
|
@@ -140,7 +150,7 @@ const StepTracker = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
|
|
|
140
150
|
children: /*#__PURE__*/_jsxs(StackView, {
|
|
141
151
|
space: 0,
|
|
142
152
|
children: [/*#__PURE__*/_jsx(View, {
|
|
143
|
-
style: staticStyles.stepsContainer,
|
|
153
|
+
style: [staticStyles.stepsContainer, selectStepsContainerStyles(themeTokens)],
|
|
144
154
|
accessibilityRole: stepsContainerAccessibilityRole,
|
|
145
155
|
children: steps.map((label, index) => {
|
|
146
156
|
return /*#__PURE__*/_jsx(Step, {
|
|
@@ -151,7 +161,8 @@ const StepTracker = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
|
|
|
151
161
|
stepCount: steps.length,
|
|
152
162
|
tokens: themeTokens,
|
|
153
163
|
accessibilityRole: stepAccessibilityRole,
|
|
154
|
-
accessibilityCurrent: current === index && Platform.OS === 'web' && 'step'
|
|
164
|
+
accessibilityCurrent: current === index && Platform.OS === 'web' && 'step',
|
|
165
|
+
isBarVariant: isBarVariant
|
|
155
166
|
}, label);
|
|
156
167
|
})
|
|
157
168
|
}), showStepTrackerLabel && /*#__PURE__*/_jsx(View, {
|
package/lib/esm/TabBar/TabBar.js
CHANGED
|
@@ -84,7 +84,8 @@ const TabBar = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
84
84
|
iconActive: item.iconActive,
|
|
85
85
|
onPress: () => handlePress(item.id),
|
|
86
86
|
id: `tab-item-${index}`,
|
|
87
|
-
accessibilityRole: "tablist"
|
|
87
|
+
accessibilityRole: "tablist",
|
|
88
|
+
tokens: item.tokens
|
|
88
89
|
}, item.id))
|
|
89
90
|
})
|
|
90
91
|
});
|
|
@@ -98,7 +99,8 @@ TabBar.propTypes = {
|
|
|
98
99
|
icon: PropTypes.node,
|
|
99
100
|
iconActive: PropTypes.node,
|
|
100
101
|
label: PropTypes.string.isRequired,
|
|
101
|
-
href: PropTypes.string
|
|
102
|
+
href: PropTypes.string,
|
|
103
|
+
tokens: getTokensPropType('TabBarItem')
|
|
102
104
|
})).isRequired,
|
|
103
105
|
/** Id of the initially selected item. */
|
|
104
106
|
initiallySelectedItem: PropTypes.number,
|
package/lib/esm/TabBar/index.js
CHANGED
package/lib/esm/utils/index.js
CHANGED
|
@@ -24,4 +24,5 @@ export { transformGradient } from './transformGradient';
|
|
|
24
24
|
export { default as convertFromMegaByteToByte } from './convertFromMegaByteToByte';
|
|
25
25
|
export { default as formatImageSource } from './formatImageSource';
|
|
26
26
|
export { default as getSpacingScale } from './getSpacingScale';
|
|
27
|
-
export { default as useVariants } from './useVariants';
|
|
27
|
+
export { default as useVariants } from './useVariants';
|
|
28
|
+
export { default as isTouchDevice } from './isTouchDevice';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import Platform from "react-native-web/dist/exports/Platform";
|
|
2
|
+
/**
|
|
3
|
+
* Determines if the current device supports touch interactions
|
|
4
|
+
*
|
|
5
|
+
* @returns {boolean} True if the device supports touch, false otherwise
|
|
6
|
+
*/
|
|
7
|
+
const isTouchDevice = () => {
|
|
8
|
+
if (Platform.OS !== 'web') {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
if (typeof window !== 'undefined') {
|
|
12
|
+
if ('ontouchstart' in window) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
if (window.navigator && window.navigator.maxTouchPoints > 0) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
if (window.navigator && window.navigator.msMaxTouchPoints > 0) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
if (window.matchMedia && window.matchMedia('(pointer: coarse)').matches) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
};
|
|
27
|
+
export default isTouchDevice;
|
package/lib/package.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"@gorhom/portal": "^1.0.14",
|
|
13
13
|
"@react-native-picker/picker": "^2.9.0",
|
|
14
14
|
"@telus-uds/system-constants": "^3.0.0",
|
|
15
|
-
"@telus-uds/system-theme-tokens": "^4.
|
|
15
|
+
"@telus-uds/system-theme-tokens": "^4.15.0",
|
|
16
16
|
"airbnb-prop-types": "^2.16.0",
|
|
17
17
|
"css-mediaquery": "^0.1.2",
|
|
18
18
|
"expo-document-picker": "^13.0.1",
|
|
@@ -84,6 +84,6 @@
|
|
|
84
84
|
"standard-engine": {
|
|
85
85
|
"skip": true
|
|
86
86
|
},
|
|
87
|
-
"version": "3.
|
|
87
|
+
"version": "3.19.0",
|
|
88
88
|
"types": "types/index.d.ts"
|
|
89
89
|
}
|
package/package.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"@gorhom/portal": "^1.0.14",
|
|
13
13
|
"@react-native-picker/picker": "^2.9.0",
|
|
14
14
|
"@telus-uds/system-constants": "^3.0.0",
|
|
15
|
-
"@telus-uds/system-theme-tokens": "^4.
|
|
15
|
+
"@telus-uds/system-theme-tokens": "^4.15.0",
|
|
16
16
|
"airbnb-prop-types": "^2.16.0",
|
|
17
17
|
"css-mediaquery": "^0.1.2",
|
|
18
18
|
"expo-document-picker": "^13.0.1",
|
|
@@ -84,6 +84,6 @@
|
|
|
84
84
|
"standard-engine": {
|
|
85
85
|
"skip": true
|
|
86
86
|
},
|
|
87
|
-
"version": "3.
|
|
87
|
+
"version": "3.19.0",
|
|
88
88
|
"types": "types/index.d.ts"
|
|
89
89
|
}
|
package/src/Box/Box.jsx
CHANGED
|
@@ -21,9 +21,10 @@ import {
|
|
|
21
21
|
variantProp,
|
|
22
22
|
viewProps,
|
|
23
23
|
StyleSheet as RNMQStyleSheet,
|
|
24
|
-
getSpacingScale
|
|
24
|
+
getSpacingScale,
|
|
25
|
+
formatImageSource
|
|
25
26
|
} from '../utils'
|
|
26
|
-
import backgroundImageStylesMap from './backgroundImageStylesMap'
|
|
27
|
+
import backgroundImageStylesMap, { backgroundPositions } from './backgroundImageStylesMap'
|
|
27
28
|
import { useViewport } from '../ViewportProvider'
|
|
28
29
|
|
|
29
30
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
|
|
@@ -87,38 +88,60 @@ const setBackgroundImage = ({
|
|
|
87
88
|
backgroundImageResizeMode,
|
|
88
89
|
backgroundImagePosition,
|
|
89
90
|
backgroundImageAlign,
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
content
|
|
91
|
+
content,
|
|
92
|
+
testID
|
|
93
93
|
}) => {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
94
|
+
const backgroundImageTestID = testID ? `${testID}-background-image` : undefined
|
|
95
|
+
|
|
96
|
+
if (backgroundImageResizeMode === 'contain' && backgroundImagePosition && backgroundImageAlign) {
|
|
97
|
+
const positionKey = `${backgroundImagePosition}-${backgroundImageAlign}`
|
|
98
|
+
|
|
99
|
+
if (Platform.OS === 'web') {
|
|
100
|
+
const backgroundPosition = backgroundPositions[positionKey] || 'center center'
|
|
101
|
+
|
|
102
|
+
const backgroundImageStyle = {
|
|
103
|
+
backgroundImage: `url(${src})`,
|
|
104
|
+
backgroundSize: 'contain',
|
|
105
|
+
backgroundRepeat: 'no-repeat',
|
|
106
|
+
backgroundPosition
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<View
|
|
111
|
+
style={[staticStyles.imageBackground, backgroundImageStyle]}
|
|
112
|
+
aria-label={alt}
|
|
113
|
+
testID={backgroundImageTestID}
|
|
114
|
+
>
|
|
115
|
+
{content}
|
|
116
|
+
</View>
|
|
117
|
+
)
|
|
100
118
|
}
|
|
119
|
+
const positionStyles = backgroundImageStylesMap[positionKey] || {}
|
|
101
120
|
|
|
102
121
|
return (
|
|
103
|
-
<View style={staticStyles.
|
|
104
|
-
<
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
122
|
+
<View style={staticStyles.containContainer}>
|
|
123
|
+
<Image
|
|
124
|
+
source={src}
|
|
125
|
+
resizeMode={backgroundImageResizeMode}
|
|
126
|
+
style={[staticStyles.containImage, positionStyles]}
|
|
127
|
+
accessible={true}
|
|
128
|
+
accessibilityLabel={alt}
|
|
129
|
+
accessibilityIgnoresInvertColors={true}
|
|
130
|
+
testID={backgroundImageTestID}
|
|
131
|
+
/>
|
|
132
|
+
<View style={staticStyles.contentOverlay}>{content}</View>
|
|
113
133
|
</View>
|
|
114
134
|
)
|
|
115
135
|
}
|
|
136
|
+
|
|
116
137
|
return (
|
|
117
138
|
<ImageBackground
|
|
118
|
-
source={
|
|
119
|
-
alt={alt}
|
|
120
|
-
style={staticStyles.backgroundImageContainer}
|
|
139
|
+
source={src}
|
|
121
140
|
resizeMode={backgroundImageResizeMode}
|
|
141
|
+
style={staticStyles.imageBackground}
|
|
142
|
+
accessible={true}
|
|
143
|
+
accessibilityLabel={alt}
|
|
144
|
+
testID={backgroundImageTestID}
|
|
122
145
|
>
|
|
123
146
|
{content}
|
|
124
147
|
</ImageBackground>
|
|
@@ -279,33 +302,47 @@ const Box = React.forwardRef(
|
|
|
279
302
|
|
|
280
303
|
const { src = '', alt = '', resizeMode = '', position = '', align = '' } = backgroundImage || {}
|
|
281
304
|
const backgroundImageResizeMode = useResponsiveProp(resizeMode, 'cover')
|
|
282
|
-
const backgroundImagePosition = useResponsiveProp(position
|
|
283
|
-
const backgroundImageAlign = useResponsiveProp(align
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
if (backgroundImage)
|
|
305
|
+
const backgroundImagePosition = useResponsiveProp(position)
|
|
306
|
+
const backgroundImageAlign = useResponsiveProp(align)
|
|
307
|
+
const imageSourceViewport = formatImageSource(useResponsiveProp(src))
|
|
308
|
+
|
|
309
|
+
if (backgroundImage && src) {
|
|
310
|
+
const { paddingTop, paddingBottom, paddingLeft, paddingRight, ...containerStyle } = boxStyles
|
|
311
|
+
|
|
312
|
+
const hasPadding = paddingTop || paddingBottom || paddingLeft || paddingRight
|
|
313
|
+
const paddedContent = hasPadding ? (
|
|
314
|
+
<View style={{ paddingTop, paddingBottom, paddingLeft, paddingRight }}>{children}</View>
|
|
315
|
+
) : (
|
|
316
|
+
children
|
|
317
|
+
)
|
|
318
|
+
|
|
287
319
|
content = setBackgroundImage({
|
|
288
|
-
src,
|
|
320
|
+
src: imageSourceViewport,
|
|
289
321
|
alt,
|
|
290
322
|
backgroundImageResizeMode,
|
|
291
323
|
backgroundImagePosition,
|
|
292
324
|
backgroundImageAlign,
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
content
|
|
325
|
+
content: paddedContent,
|
|
326
|
+
testID
|
|
296
327
|
})
|
|
297
328
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
329
|
+
const dataSetValue = boxMediaIds ? { media: boxMediaIds, ...dataSet } : dataSet
|
|
330
|
+
|
|
331
|
+
if (scroll) {
|
|
332
|
+
const scrollProps = typeof scroll === 'object' ? scroll : {}
|
|
333
|
+
scrollProps.contentContainerStyle = [containerStyle, scrollProps.contentContainerStyle]
|
|
334
|
+
return (
|
|
335
|
+
<ScrollView {...scrollProps} {...props} testID={testID} dataSet={dataSetValue} ref={ref}>
|
|
336
|
+
{content}
|
|
337
|
+
</ScrollView>
|
|
338
|
+
)
|
|
307
339
|
}
|
|
308
|
-
|
|
340
|
+
return (
|
|
341
|
+
<View {...props} style={containerStyle} testID={testID} dataSet={dataSetValue} ref={ref}>
|
|
342
|
+
{content}
|
|
343
|
+
</View>
|
|
344
|
+
)
|
|
345
|
+
}
|
|
309
346
|
|
|
310
347
|
const dataSetValue = boxMediaIds ? { media: boxMediaIds, ...dataSet } : dataSet
|
|
311
348
|
|
|
@@ -416,10 +453,12 @@ Box.propTypes = {
|
|
|
416
453
|
*/
|
|
417
454
|
customGradient: PropTypes.func,
|
|
418
455
|
/**
|
|
419
|
-
*
|
|
456
|
+
* Apply background image to the box.
|
|
420
457
|
*/
|
|
421
458
|
backgroundImage: PropTypes.shape({
|
|
422
|
-
src
|
|
459
|
+
// The image src is either a URI string or a number (when a local image src is bundled in IOS or Android app)
|
|
460
|
+
// src is an object when used responsively to provide different image sources for different screen sizes
|
|
461
|
+
src: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.object]).isRequired,
|
|
423
462
|
alt: PropTypes.string,
|
|
424
463
|
resizeMode: responsiveProps.getTypeOptionallyByViewport(
|
|
425
464
|
PropTypes.oneOf(['cover', 'contain', 'stretch', 'repeat', 'center'])
|
|
@@ -436,18 +475,21 @@ Box.propTypes = {
|
|
|
436
475
|
export default Box
|
|
437
476
|
|
|
438
477
|
const staticStyles = StyleSheet.create({
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
478
|
+
imageBackground: { width: '100%', height: '100%' },
|
|
479
|
+
contentOverlay: {
|
|
480
|
+
position: 'relative',
|
|
481
|
+
width: '100%',
|
|
482
|
+
height: '100%',
|
|
483
|
+
zIndex: 1
|
|
445
484
|
},
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
485
|
+
containContainer: {
|
|
486
|
+
width: '100%',
|
|
487
|
+
height: '100%',
|
|
488
|
+
overflow: 'hidden',
|
|
489
|
+
position: 'relative'
|
|
449
490
|
},
|
|
450
|
-
|
|
491
|
+
containImage: {
|
|
492
|
+
position: 'absolute',
|
|
451
493
|
width: '100%',
|
|
452
494
|
height: '100%'
|
|
453
495
|
}
|
|
@@ -1,21 +1,54 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { Platform } from 'react-native'
|
|
2
|
+
|
|
3
|
+
const webStyles = {
|
|
4
|
+
'top-start': { top: 0, left: 0 },
|
|
5
|
+
'top-center': { top: 0, left: '50%', transform: [{ translateX: '-50%' }] },
|
|
4
6
|
'top-end': { top: 0, right: 0 },
|
|
5
7
|
'right-start': { top: 0, right: 0 },
|
|
6
|
-
'left-start': { top: 0 },
|
|
7
|
-
'left-center': { top:
|
|
8
|
-
'
|
|
9
|
-
'none-center': { top: 0, bottom: 0, left: 0, right: 0, margin: 'auto' },
|
|
10
|
-
'right-center': { top: 0, bottom: 0, right: 0, marginVertical: 'auto' },
|
|
11
|
-
'none-end': { top: 0, bottom: 0, right: 0, marginVertical: 'auto' },
|
|
8
|
+
'left-start': { top: 0, left: 0 },
|
|
9
|
+
'left-center': { top: '50%', left: 0, transform: [{ translateY: '-50%' }] },
|
|
10
|
+
'right-center': { top: '50%', right: 0, transform: [{ translateY: '-50%' }] },
|
|
12
11
|
'bottom-start': { bottom: 0, left: 0 },
|
|
13
12
|
'left-end': { bottom: 0, left: 0 },
|
|
14
|
-
'bottom-center': {
|
|
15
|
-
'bottom-end': {
|
|
16
|
-
'right-end': {
|
|
17
|
-
'top-stretch': { left: 0, right: 0, width: '100%' },
|
|
18
|
-
'left-stretch': { top: 0, bottom: 0, height: '100%' },
|
|
13
|
+
'bottom-center': { bottom: 0, left: '50%', transform: [{ translateX: '-50%' }] },
|
|
14
|
+
'bottom-end': { bottom: 0, right: 0 },
|
|
15
|
+
'right-end': { bottom: 0, right: 0 },
|
|
16
|
+
'top-stretch': { top: 0, left: 0, right: 0, width: '100%' },
|
|
17
|
+
'left-stretch': { top: 0, bottom: 0, left: 0, height: '100%' },
|
|
19
18
|
'right-stretch': { top: 0, bottom: 0, right: 0, height: '100%' },
|
|
20
|
-
'bottom-stretch': {
|
|
19
|
+
'bottom-stretch': { bottom: 0, left: 0, right: 0, width: '100%' }
|
|
21
20
|
}
|
|
21
|
+
|
|
22
|
+
const webBackgroundPositions = {
|
|
23
|
+
'top-start': 'left top',
|
|
24
|
+
'top-center': 'center top',
|
|
25
|
+
'top-end': 'right top',
|
|
26
|
+
'bottom-start': 'left bottom',
|
|
27
|
+
'bottom-center': 'center bottom',
|
|
28
|
+
'bottom-end': 'right bottom',
|
|
29
|
+
'left-center': 'left center',
|
|
30
|
+
'right-center': 'right center'
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const nativeStyles = {
|
|
34
|
+
'top-start': { top: 0, left: 0, width: 150, height: 200 },
|
|
35
|
+
'top-center': { top: 0, left: '50%', marginLeft: -75, width: 150, height: 200 },
|
|
36
|
+
'top-end': { top: 0, right: 0, width: 150, height: 200 },
|
|
37
|
+
'right-start': { top: 0, right: 0, width: 150, height: 200 },
|
|
38
|
+
'left-start': { top: 0, left: 0, width: 150, height: 200 },
|
|
39
|
+
'left-center': { left: 0, top: '50%', marginTop: -100, width: 150, height: 200 },
|
|
40
|
+
'right-center': { right: 0, top: '50%', marginTop: -100, width: 150, height: 200 },
|
|
41
|
+
'bottom-start': { bottom: 0, left: 0, width: 150, height: 200 },
|
|
42
|
+
'left-end': { bottom: 0, left: 0, width: 150, height: 200 },
|
|
43
|
+
'bottom-center': { bottom: 0, left: '50%', marginLeft: -75, width: 150, height: 200 },
|
|
44
|
+
'bottom-end': { bottom: 0, right: 0, width: 150, height: 200 },
|
|
45
|
+
'right-end': { bottom: 0, right: 0, width: 150, height: 200 },
|
|
46
|
+
'top-stretch': { top: 0, left: 0, right: 0, width: '100%' },
|
|
47
|
+
'left-stretch': { top: 0, bottom: 0, left: 0, height: '100%' },
|
|
48
|
+
'right-stretch': { top: 0, bottom: 0, right: 0, height: '100%' },
|
|
49
|
+
'bottom-stretch': { bottom: 0, left: 0, right: 0, width: '100%' }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const backgroundPositions = Platform.OS === 'web' ? webBackgroundPositions : {}
|
|
53
|
+
|
|
54
|
+
export default Platform.OS === 'web' ? webStyles : nativeStyles
|
|
@@ -12,7 +12,8 @@ import {
|
|
|
12
12
|
a11yProps,
|
|
13
13
|
viewProps,
|
|
14
14
|
useCopy,
|
|
15
|
-
unpackFragment
|
|
15
|
+
unpackFragment,
|
|
16
|
+
isTouchDevice
|
|
16
17
|
} from '../utils'
|
|
17
18
|
import { useA11yInfo } from '../A11yInfoProvider'
|
|
18
19
|
import { CarouselProvider } from './CarouselContext'
|
|
@@ -799,7 +800,7 @@ const Carousel = React.forwardRef(
|
|
|
799
800
|
return false
|
|
800
801
|
}
|
|
801
802
|
if (Platform.OS === 'web') {
|
|
802
|
-
return !!(viewport === 'xs' || viewport === 'sm')
|
|
803
|
+
return !!(viewport === 'xs' || viewport === 'sm' || (viewport === 'md' && isTouchDevice()))
|
|
803
804
|
}
|
|
804
805
|
return true
|
|
805
806
|
}, [viewport, totalItems])
|
package/src/Modal/Modal.jsx
CHANGED
|
@@ -118,6 +118,7 @@ const Modal = React.forwardRef(
|
|
|
118
118
|
confirmButtonVariant,
|
|
119
119
|
cancelButtonText,
|
|
120
120
|
cancelButtonType,
|
|
121
|
+
footer,
|
|
121
122
|
...rest
|
|
122
123
|
},
|
|
123
124
|
ref
|
|
@@ -240,6 +241,7 @@ const Modal = React.forwardRef(
|
|
|
240
241
|
confirmButtonVariant={confirmButtonVariant}
|
|
241
242
|
cancelButtonText={cancelButtonText}
|
|
242
243
|
cancelButtonType={cancelButtonType}
|
|
244
|
+
footer={footer}
|
|
243
245
|
>
|
|
244
246
|
{Platform.OS !== 'web' ? (
|
|
245
247
|
<ScrollView style={selectScrollViewStyles}>{children}</ScrollView>
|
|
@@ -343,7 +345,11 @@ Modal.propTypes = {
|
|
|
343
345
|
/**
|
|
344
346
|
* Receive a function for the onCancel event in the cancel button.
|
|
345
347
|
*/
|
|
346
|
-
onCancel: PropTypes.func
|
|
348
|
+
onCancel: PropTypes.func,
|
|
349
|
+
/**
|
|
350
|
+
* Receive a react node or an array of nodes to render at the bottom of the modal, above the action buttons.
|
|
351
|
+
*/
|
|
352
|
+
footer: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)])
|
|
347
353
|
}
|
|
348
354
|
|
|
349
355
|
export default Modal
|
|
@@ -25,7 +25,8 @@ const ModalContent = React.forwardRef(
|
|
|
25
25
|
cancelButtonText,
|
|
26
26
|
cancelButtonType: CancelButton = TextButton,
|
|
27
27
|
children,
|
|
28
|
-
onCancel
|
|
28
|
+
onCancel,
|
|
29
|
+
footer
|
|
29
30
|
},
|
|
30
31
|
ref
|
|
31
32
|
) => {
|
|
@@ -131,7 +132,7 @@ const ModalContent = React.forwardRef(
|
|
|
131
132
|
</Box>
|
|
132
133
|
)}
|
|
133
134
|
{children}
|
|
134
|
-
{(hasConfirmButton || hasCancelButton) && (
|
|
135
|
+
{(hasConfirmButton || hasCancelButton) && !footer && (
|
|
135
136
|
<View
|
|
136
137
|
style={[
|
|
137
138
|
selectFooterContainerStyles({
|
|
@@ -158,6 +159,7 @@ const ModalContent = React.forwardRef(
|
|
|
158
159
|
) : null}
|
|
159
160
|
</View>
|
|
160
161
|
)}
|
|
162
|
+
{footer}
|
|
161
163
|
</View>
|
|
162
164
|
)
|
|
163
165
|
}
|
|
@@ -190,7 +192,8 @@ ModalContent.propTypes = {
|
|
|
190
192
|
cancelButtonText: PropTypes.string,
|
|
191
193
|
cancelButtonType: PropTypes.elementType, // TODO: figure out a way of passing an icon to the TextButton
|
|
192
194
|
children: PropTypes.node,
|
|
193
|
-
onCancel: PropTypes.func
|
|
195
|
+
onCancel: PropTypes.func,
|
|
196
|
+
footer: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)])
|
|
194
197
|
}
|
|
195
198
|
|
|
196
199
|
export default ModalContent
|
|
@@ -479,9 +479,9 @@ MultiSelectFilter.propTypes = {
|
|
|
479
479
|
*/
|
|
480
480
|
label: PropTypes.string.isRequired,
|
|
481
481
|
/**
|
|
482
|
-
* The text for the subtitle
|
|
482
|
+
* The text for the subtitle. Can also be JSX.
|
|
483
483
|
*/
|
|
484
|
-
subtitle: PropTypes.string,
|
|
484
|
+
subtitle: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
485
485
|
/**
|
|
486
486
|
* An optional unique string may be provided to identify the ButtonDropdown.
|
|
487
487
|
* If not provided, the label is used.
|