@telus-uds/components-base 3.24.0 → 3.26.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 +24 -1
- package/lib/cjs/Button/ButtonGroup.js +9 -2
- package/lib/cjs/Carousel/Carousel.js +90 -30
- package/lib/cjs/Carousel/Constants.js +13 -2
- package/lib/cjs/FlexGrid/FlexGrid.js +31 -35
- package/lib/cjs/IconButton/IconButton.js +15 -5
- package/lib/cjs/InputSupports/InputSupports.js +2 -1
- package/lib/cjs/PriceLockup/PriceLockup.js +1 -1
- package/lib/cjs/TextInput/TextInputBase.js +2 -3
- package/lib/cjs/utils/index.js +9 -1
- package/lib/cjs/utils/resolveContentMaxWidth.js +30 -0
- package/lib/esm/Button/ButtonGroup.js +9 -2
- package/lib/esm/Carousel/Carousel.js +84 -24
- package/lib/esm/Carousel/Constants.js +12 -1
- package/lib/esm/FlexGrid/FlexGrid.js +31 -35
- package/lib/esm/IconButton/IconButton.js +15 -5
- package/lib/esm/InputSupports/InputSupports.js +2 -1
- package/lib/esm/PriceLockup/PriceLockup.js +1 -1
- package/lib/esm/TextInput/TextInputBase.js +2 -3
- package/lib/esm/utils/index.js +2 -1
- package/lib/esm/utils/resolveContentMaxWidth.js +24 -0
- package/lib/package.json +2 -2
- package/package.json +2 -2
- package/src/Button/ButtonGroup.jsx +20 -3
- package/src/Carousel/Carousel.jsx +104 -30
- package/src/Carousel/Constants.js +14 -0
- package/src/FlexGrid/FlexGrid.jsx +30 -39
- package/src/IconButton/IconButton.jsx +12 -5
- package/src/InputSupports/InputSupports.jsx +6 -1
- package/src/PriceLockup/PriceLockup.jsx +1 -1
- package/src/TextInput/TextInputBase.jsx +2 -2
- package/src/utils/index.js +1 -0
- package/src/utils/resolveContentMaxWidth.js +28 -0
- package/types/Status.d.ts +42 -0
- package/types/index.d.ts +3 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
const CONTENT_MAX_WIDTH = 'max';
|
|
8
|
+
const CONTENT_FULL_WIDTH = 'full';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Resolves the maximum width for content based on the provided value and responsive width.
|
|
12
|
+
*
|
|
13
|
+
* @param {number|string|null|undefined} contentMaxWidthValue - The maximum width value for the content.
|
|
14
|
+
* Can be a number, a special string constant (e.g., CONTENT_FULL_WIDTH, CONTENT_MAX_WIDTH), or null/undefined.
|
|
15
|
+
* @param {number} responsiveWidth - The responsive width to use when contentMaxWidthValue is CONTENT_MAX_WIDTH.
|
|
16
|
+
* @returns {number|string|null} The resolved maximum width value, or null if full width is desired.
|
|
17
|
+
*/
|
|
18
|
+
const resolveContentMaxWidth = (contentMaxWidthValue, responsiveWidth) => {
|
|
19
|
+
if (!contentMaxWidthValue || contentMaxWidthValue === CONTENT_FULL_WIDTH) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
if (Number.isFinite(contentMaxWidthValue)) {
|
|
23
|
+
return contentMaxWidthValue;
|
|
24
|
+
}
|
|
25
|
+
if (contentMaxWidthValue === CONTENT_MAX_WIDTH) {
|
|
26
|
+
return responsiveWidth;
|
|
27
|
+
}
|
|
28
|
+
return contentMaxWidthValue;
|
|
29
|
+
};
|
|
30
|
+
var _default = exports.default = resolveContentMaxWidth;
|
|
@@ -129,6 +129,7 @@ const ButtonGroup = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
129
129
|
id = label,
|
|
130
130
|
accessibilityLabel,
|
|
131
131
|
ref: itemRef,
|
|
132
|
+
inactive: itemInactive,
|
|
132
133
|
...itemRest
|
|
133
134
|
} = _ref2;
|
|
134
135
|
const isSelected = currentValues.includes(id);
|
|
@@ -152,6 +153,7 @@ const ButtonGroup = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
152
153
|
accessibilityLabel,
|
|
153
154
|
...a11yProps.getPositionInSet(items.length, index)
|
|
154
155
|
};
|
|
156
|
+
const isInactive = itemInactive !== undefined ? itemInactive : inactive;
|
|
155
157
|
|
|
156
158
|
// Ensure button is direct child of group as MacOS voiceover only applies "X of Y" to
|
|
157
159
|
// "radio" if it's a direct child of "radiogroup", even if aria-posinset etc exists
|
|
@@ -162,7 +164,7 @@ const ButtonGroup = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
162
164
|
onPress: handlePress,
|
|
163
165
|
tokens: getButtonTokens,
|
|
164
166
|
selected: isSelected,
|
|
165
|
-
inactive:
|
|
167
|
+
inactive: isInactive,
|
|
166
168
|
icon: iconProp,
|
|
167
169
|
...selectItemProps({
|
|
168
170
|
...itemRest,
|
|
@@ -216,7 +218,12 @@ ButtonGroup.propTypes = {
|
|
|
216
218
|
/**
|
|
217
219
|
* An optional ref for one individual button in the ButtonGroup
|
|
218
220
|
*/
|
|
219
|
-
ref: ABBPropTypes.ref()
|
|
221
|
+
ref: ABBPropTypes.ref(),
|
|
222
|
+
/**
|
|
223
|
+
* If true, this individual button cannot be interacted with. Takes precedence
|
|
224
|
+
* over the group-level `inactive` prop. Useful for disabling specific options.
|
|
225
|
+
*/
|
|
226
|
+
inactive: PropTypes.bool
|
|
220
227
|
})),
|
|
221
228
|
/**
|
|
222
229
|
* If provided, this function is called when the current selection is changed
|
|
@@ -5,10 +5,11 @@ import PanResponder from "react-native-web/dist/exports/PanResponder";
|
|
|
5
5
|
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
6
6
|
import Platform from "react-native-web/dist/exports/Platform";
|
|
7
7
|
import Dimensions from "react-native-web/dist/exports/Dimensions";
|
|
8
|
+
import Easing from "react-native-web/dist/exports/Easing";
|
|
8
9
|
import PropTypes from 'prop-types';
|
|
9
|
-
import { useThemeTokens } from '../ThemeProvider';
|
|
10
|
+
import { useThemeTokens, useTheme } from '../ThemeProvider';
|
|
10
11
|
import { useViewport } from '../ViewportProvider';
|
|
11
|
-
import { getTokensPropType, getA11yPropsFromHtmlTag, layoutTags, variantProp, selectSystemProps, a11yProps, viewProps, useCopy, unpackFragment, isTouchDevice } from '../utils';
|
|
12
|
+
import { getTokensPropType, getA11yPropsFromHtmlTag, layoutTags, variantProp, selectSystemProps, a11yProps, viewProps, useCopy, unpackFragment, isTouchDevice, useResponsiveProp, resolveContentMaxWidth } from '../utils';
|
|
12
13
|
import { useA11yInfo } from '../A11yInfoProvider';
|
|
13
14
|
import { CarouselProvider } from './CarouselContext';
|
|
14
15
|
import CarouselItem from './CarouselItem';
|
|
@@ -21,13 +22,8 @@ import CarouselTabsPanel from './CarouselTabs/CarouselTabsPanel';
|
|
|
21
22
|
import CarouselTabsPanelItem from './CarouselTabs/CarouselTabsPanelItem';
|
|
22
23
|
import dictionary from './dictionary';
|
|
23
24
|
import Box from '../Box';
|
|
24
|
-
import { ITEMS_PER_VIEWPORT_XS_SM, ITEMS_PER_VIEWPORT_MD, ITEMS_PER_VIEWPORT_LG_XL, DEFAULT_POSITION_OFFSET, LARGE_VIEWPORT_MARGIN, DEFAULT_VIEWPORT_MARGIN, PEEKING_MULTIPLIER, ACTIVE_INDEX_OFFSET_MULTIPLIER, NEGATIVE_MULTIPLIER } from './Constants';
|
|
25
|
+
import { ITEMS_PER_VIEWPORT_XS_SM, ITEMS_PER_VIEWPORT_MD, ITEMS_PER_VIEWPORT_LG_XL, DEFAULT_POSITION_OFFSET, LARGE_VIEWPORT_MARGIN, DEFAULT_VIEWPORT_MARGIN, PEEKING_MULTIPLIER, ACTIVE_INDEX_OFFSET_MULTIPLIER, NEGATIVE_MULTIPLIER, TRANSITION_MODES, SWIPE_RELEASE_STYLES, INSTANT_ANIMATION_DURATION, DEFAULT_SWIPE_RELEASE_DURATION } from './Constants';
|
|
25
26
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
26
|
-
const TRANSITION_MODES = {
|
|
27
|
-
MANUAL: 'manual',
|
|
28
|
-
AUTOMATIC: 'automatic',
|
|
29
|
-
SWIPE: 'swipe'
|
|
30
|
-
};
|
|
31
27
|
const staticStyles = StyleSheet.create({
|
|
32
28
|
root: {
|
|
33
29
|
backgroundColor: 'transparent',
|
|
@@ -203,11 +199,18 @@ const selectRootContainerStyles = (enableHero, viewport) => {
|
|
|
203
199
|
}
|
|
204
200
|
return {};
|
|
205
201
|
};
|
|
206
|
-
const selectMainContainerStyles = (enableHero, viewport) => {
|
|
202
|
+
const selectMainContainerStyles = (enableHero, viewport, maxWidth) => {
|
|
207
203
|
if (enableHero && viewport === 'xl' && Platform.OS === 'web') {
|
|
208
204
|
return {
|
|
209
205
|
width: '100%',
|
|
210
|
-
maxWidth: 1200
|
|
206
|
+
maxWidth: maxWidth || 1200
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
if (maxWidth !== null && maxWidth !== undefined) {
|
|
210
|
+
return {
|
|
211
|
+
maxWidth,
|
|
212
|
+
alignSelf: 'center',
|
|
213
|
+
width: '100%'
|
|
211
214
|
};
|
|
212
215
|
}
|
|
213
216
|
return {};
|
|
@@ -354,11 +357,20 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
354
357
|
loopDuration = transitionDuration,
|
|
355
358
|
autoPlay = false,
|
|
356
359
|
enablePeeking = false,
|
|
360
|
+
contentMaxWidth,
|
|
361
|
+
swipeReleaseStyle = SWIPE_RELEASE_STYLES.INSTANT,
|
|
362
|
+
swipeReleaseDuration = DEFAULT_SWIPE_RELEASE_DURATION,
|
|
357
363
|
...rest
|
|
358
364
|
} = _ref3;
|
|
359
365
|
let childrenArray = unpackFragment(children);
|
|
360
366
|
const isTransitioningRef = React.useRef(false);
|
|
361
367
|
const viewport = useViewport();
|
|
368
|
+
const {
|
|
369
|
+
themeOptions
|
|
370
|
+
} = useTheme();
|
|
371
|
+
const contentMaxWidthValue = useResponsiveProp(contentMaxWidth);
|
|
372
|
+
const responsiveWidth = useResponsiveProp(themeOptions?.contentMaxWidth);
|
|
373
|
+
const maxWidth = resolveContentMaxWidth(contentMaxWidthValue, responsiveWidth);
|
|
362
374
|
const totalItems = getTotalItems(enableDisplayMultipleItemsPerSlide, childrenArray, viewport);
|
|
363
375
|
const autoPlayFeatureEnabled = autoPlay && slideDuration > 0 && transitionDuration > 0 && totalItems > 1;
|
|
364
376
|
// if `Carousel` only has one `Carousel.Item`, convert this to a single-item array
|
|
@@ -476,7 +488,8 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
476
488
|
});
|
|
477
489
|
}
|
|
478
490
|
}, [pan, animatedX, heroPan, heroAnimatedX, enableHero, viewport, enablePeeking]);
|
|
479
|
-
const animate = React.useCallback((panToAnimate, toValue, toIndex)
|
|
491
|
+
const animate = React.useCallback(function (panToAnimate, toValue, toIndex) {
|
|
492
|
+
let isSwipeRelease = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
480
493
|
const applicableTransitionDuration = isLastSlide && toIndex === 0 ? loopDuration : transitionDuration;
|
|
481
494
|
const handleAnimationEndToIndex = function () {
|
|
482
495
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
@@ -484,10 +497,23 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
484
497
|
}
|
|
485
498
|
return handleAnimationEnd(toIndex, ...args);
|
|
486
499
|
};
|
|
487
|
-
if (reduceMotionRef.current
|
|
500
|
+
if (reduceMotionRef.current) {
|
|
501
|
+
Animated.timing(panToAnimate, {
|
|
502
|
+
toValue,
|
|
503
|
+
duration: INSTANT_ANIMATION_DURATION,
|
|
504
|
+
useNativeDriver: false
|
|
505
|
+
}).start(handleAnimationEndToIndex);
|
|
506
|
+
} else if (isSwipeRelease && swipeReleaseStyle === SWIPE_RELEASE_STYLES.EASE_OUT) {
|
|
507
|
+
Animated.timing(panToAnimate, {
|
|
508
|
+
toValue,
|
|
509
|
+
duration: swipeReleaseDuration,
|
|
510
|
+
easing: Easing.out(Easing.cubic),
|
|
511
|
+
useNativeDriver: false
|
|
512
|
+
}).start(handleAnimationEndToIndex);
|
|
513
|
+
} else if (isSwiping.current || isSwipeRelease) {
|
|
488
514
|
Animated.timing(panToAnimate, {
|
|
489
515
|
toValue,
|
|
490
|
-
duration:
|
|
516
|
+
duration: INSTANT_ANIMATION_DURATION,
|
|
491
517
|
useNativeDriver: false
|
|
492
518
|
}).start(handleAnimationEndToIndex);
|
|
493
519
|
} else if (isAutoPlayEnabled) {
|
|
@@ -511,7 +537,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
511
537
|
useNativeDriver: false
|
|
512
538
|
}).start(handleAnimationEndToIndex);
|
|
513
539
|
}
|
|
514
|
-
}, [springConfig, handleAnimationEnd, transitionDuration, loopDuration, isLastSlide, isAutoPlayEnabled, enablePeeking, enableDisplayMultipleItemsPerSlide]);
|
|
540
|
+
}, [springConfig, handleAnimationEnd, transitionDuration, loopDuration, isLastSlide, isAutoPlayEnabled, enablePeeking, enableDisplayMultipleItemsPerSlide, swipeReleaseStyle, swipeReleaseDuration]);
|
|
515
541
|
const stopAutoplay = React.useCallback(() => {
|
|
516
542
|
if (autoPlayRef?.current) {
|
|
517
543
|
clearTimeout(autoPlayRef?.current);
|
|
@@ -534,6 +560,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
534
560
|
};
|
|
535
561
|
let skipChanges = !delta;
|
|
536
562
|
let calcDelta = delta;
|
|
563
|
+
const isSwipeRelease = transitionMode === TRANSITION_MODES.SWIPE;
|
|
537
564
|
if (activeIndexRef.current <= 0 && delta < 0) {
|
|
538
565
|
skipChanges = transitionMode !== TRANSITION_MODES.AUTOMATIC;
|
|
539
566
|
calcDelta = totalItems + delta;
|
|
@@ -544,9 +571,9 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
544
571
|
const index = activeIndexRef.current + calcDelta;
|
|
545
572
|
if (skipChanges) {
|
|
546
573
|
isTransitioningRef.current = true;
|
|
547
|
-
animate(pan, toValue, index);
|
|
574
|
+
animate(pan, toValue, index, isSwipeRelease);
|
|
548
575
|
if (enableHero) {
|
|
549
|
-
animate(heroPan, toValue, index);
|
|
576
|
+
animate(heroPan, toValue, index, isSwipeRelease);
|
|
550
577
|
}
|
|
551
578
|
return calcDelta;
|
|
552
579
|
}
|
|
@@ -560,9 +587,9 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
560
587
|
};
|
|
561
588
|
heroToValue.x = heroContainerLayoutRef.current.width * -1 * calcDelta;
|
|
562
589
|
isTransitioningRef.current = true;
|
|
563
|
-
animate(pan, toValue, index);
|
|
590
|
+
animate(pan, toValue, index, isSwipeRelease);
|
|
564
591
|
if (enableHero) {
|
|
565
|
-
animate(heroPan, heroToValue, index);
|
|
592
|
+
animate(heroPan, heroToValue, index, isSwipeRelease);
|
|
566
593
|
}
|
|
567
594
|
if (isCarouselPlaying) {
|
|
568
595
|
stopAutoplay();
|
|
@@ -759,16 +786,16 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
759
786
|
startAutoplay();
|
|
760
787
|
}
|
|
761
788
|
const correction = gesture.moveX - gesture.x0;
|
|
789
|
+
isSwiping.current = false;
|
|
762
790
|
if (Math.abs(correction) < containerLayoutRef.current.width * minDistanceForAction) {
|
|
763
791
|
animate(pan, {
|
|
764
792
|
x: 0,
|
|
765
793
|
y: 0
|
|
766
|
-
},
|
|
794
|
+
}, activeIndexRef.current, true);
|
|
767
795
|
} else {
|
|
768
796
|
const delta = correction > 0 ? -1 : 1;
|
|
769
797
|
updateIndex(delta, TRANSITION_MODES.SWIPE);
|
|
770
798
|
}
|
|
771
|
-
isSwiping.current = false;
|
|
772
799
|
}
|
|
773
800
|
}), [pan, updateIndex, updateOffset, animate, isSwipeAllowed, minDistanceForAction, handleAnimationStart, minDistanceToCapture, startAutoplay, stopAutoplay, isCarouselPlaying]);
|
|
774
801
|
const heroPanResponder = React.useMemo(() => PanResponder.create({
|
|
@@ -799,16 +826,16 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
799
826
|
startAutoplay();
|
|
800
827
|
}
|
|
801
828
|
const correction = gesture.moveX - gesture.x0;
|
|
829
|
+
isSwiping.current = false;
|
|
802
830
|
if (Math.abs(correction) < containerLayoutRef.current.width * minDistanceForAction) {
|
|
803
831
|
animate(heroPan, {
|
|
804
832
|
x: 0,
|
|
805
833
|
y: 0
|
|
806
|
-
},
|
|
834
|
+
}, activeIndexRef.current, true);
|
|
807
835
|
} else {
|
|
808
836
|
const delta = correction > 0 ? -1 : 1;
|
|
809
837
|
updateIndex(delta, TRANSITION_MODES.SWIPE);
|
|
810
838
|
}
|
|
811
|
-
isSwiping.current = false;
|
|
812
839
|
}
|
|
813
840
|
}), [heroPan, updateIndex, updateOffset, animate, isSwipeAllowed, minDistanceForAction, handleAnimationStart, minDistanceToCapture, startAutoplay, stopAutoplay, isCarouselPlaying]);
|
|
814
841
|
const goToNext = React.useCallback(() => {
|
|
@@ -889,7 +916,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
889
916
|
return /*#__PURE__*/_jsxs(View, {
|
|
890
917
|
style: selectRootContainerStyles(enableHero, viewport),
|
|
891
918
|
children: [/*#__PURE__*/_jsx(View, {
|
|
892
|
-
style: selectMainContainerStyles(enableHero, viewport),
|
|
919
|
+
style: selectMainContainerStyles(enableHero, viewport, maxWidth),
|
|
893
920
|
children: /*#__PURE__*/_jsxs(CarouselProvider, {
|
|
894
921
|
activeIndex: activeIndex,
|
|
895
922
|
goTo: goTo,
|
|
@@ -1247,7 +1274,40 @@ Carousel.propTypes = {
|
|
|
1247
1274
|
* If set to `true`, the Carousel will show multiple slides at once
|
|
1248
1275
|
* - Default value is `false`
|
|
1249
1276
|
*/
|
|
1250
|
-
enableDisplayMultipleItemsPerSlide: PropTypes.bool
|
|
1277
|
+
enableDisplayMultipleItemsPerSlide: PropTypes.bool,
|
|
1278
|
+
/**
|
|
1279
|
+
* The maximum width of the content in the Carousel.
|
|
1280
|
+
* This prop accepts responsive values for different viewports. If a number is provided,
|
|
1281
|
+
* it will be the max content width for the desired viewport.
|
|
1282
|
+
* - `xs`: 'max' | 'full' | <number>
|
|
1283
|
+
* - `sm`: 'max' | 'full' | <number>
|
|
1284
|
+
* - `md`: 'max' | 'full' | <number>
|
|
1285
|
+
* - `lg`: 'max' | 'full' | <number>
|
|
1286
|
+
* - `xl`: 'max' | 'full' | <number>
|
|
1287
|
+
*/
|
|
1288
|
+
contentMaxWidth: PropTypes.shape({
|
|
1289
|
+
xl: PropTypes.oneOfType([PropTypes.oneOf(['max', 'full']), PropTypes.number]),
|
|
1290
|
+
lg: PropTypes.oneOfType([PropTypes.oneOf(['max', 'full']), PropTypes.number]),
|
|
1291
|
+
md: PropTypes.oneOfType([PropTypes.oneOf(['max', 'full']), PropTypes.number]),
|
|
1292
|
+
sm: PropTypes.oneOfType([PropTypes.oneOf(['max', 'full']), PropTypes.number]),
|
|
1293
|
+
xs: PropTypes.oneOfType([PropTypes.oneOf(['max', 'full']), PropTypes.number])
|
|
1294
|
+
}),
|
|
1295
|
+
/**
|
|
1296
|
+
* Animation style for swipe release transitions.
|
|
1297
|
+
* - `'instant'`: Immediate snap to position (current default)
|
|
1298
|
+
* - `'ease-out'`: Smooth deceleration animation
|
|
1299
|
+
* - Default value is `'instant'`
|
|
1300
|
+
* - Use `swipeReleaseDuration` to customize the animation duration when using `'ease-out'`
|
|
1301
|
+
*
|
|
1302
|
+
* @deprecated The default will change to `'ease-out'` in Q2 2026 (introduced Jan 2026).
|
|
1303
|
+
*/
|
|
1304
|
+
swipeReleaseStyle: PropTypes.oneOf(['instant', 'ease-out']),
|
|
1305
|
+
/**
|
|
1306
|
+
* Duration in milliseconds of the ease-out animation when releasing a swipe gesture.
|
|
1307
|
+
* Only applies when `swipeReleaseStyle` is set to `'ease-out'`.
|
|
1308
|
+
* - Default value is `500` (500ms)
|
|
1309
|
+
*/
|
|
1310
|
+
swipeReleaseDuration: PropTypes.number
|
|
1251
1311
|
};
|
|
1252
1312
|
Carousel.Item = CarouselItem;
|
|
1253
1313
|
Carousel.displayName = 'Carousel';
|
|
@@ -8,4 +8,15 @@ export const LARGE_VIEWPORT_MARGIN = 40;
|
|
|
8
8
|
export const DEFAULT_VIEWPORT_MARGIN = 10;
|
|
9
9
|
export const PEEKING_MULTIPLIER = 2;
|
|
10
10
|
export const ACTIVE_INDEX_OFFSET_MULTIPLIER = 1;
|
|
11
|
-
export const NEGATIVE_MULTIPLIER = -1;
|
|
11
|
+
export const NEGATIVE_MULTIPLIER = -1;
|
|
12
|
+
export const TRANSITION_MODES = {
|
|
13
|
+
MANUAL: 'manual',
|
|
14
|
+
AUTOMATIC: 'automatic',
|
|
15
|
+
SWIPE: 'swipe'
|
|
16
|
+
};
|
|
17
|
+
export const SWIPE_RELEASE_STYLES = {
|
|
18
|
+
INSTANT: 'instant',
|
|
19
|
+
EASE_OUT: 'ease-out'
|
|
20
|
+
};
|
|
21
|
+
export const INSTANT_ANIMATION_DURATION = 1;
|
|
22
|
+
export const DEFAULT_SWIPE_RELEASE_DURATION = 500;
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { viewports } from '@telus-uds/system-constants';
|
|
4
4
|
import { a11yProps, viewProps, getA11yPropsFromHtmlTag, layoutTags, selectSystemProps, BaseView, StyleSheet, createMediaQueryStyles, useResponsiveProp } from '../utils';
|
|
5
|
+
import resolveContentMaxWidth from '../utils/resolveContentMaxWidth';
|
|
5
6
|
import Row from './Row';
|
|
6
7
|
import Col from './Col';
|
|
7
8
|
import GutterContext from './providers/GutterContext';
|
|
@@ -10,47 +11,24 @@ import { useTheme } from '../ThemeProvider';
|
|
|
10
11
|
import { useViewport } from '../ViewportProvider';
|
|
11
12
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
13
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
13
|
-
const CONTENT_MAX_WIDTH = 'max';
|
|
14
|
-
const CONTENT_FULL_WIDTH = 'full';
|
|
15
14
|
|
|
16
15
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* @param {number|string|null|undefined} contentMinWidthValue - The minimum width value for the content.
|
|
20
|
-
* Can be a number, a special string constant (e.g., CONTENT_FULL_WIDTH, CONTENT_MAX_WIDTH), or null/undefined.
|
|
21
|
-
* @param {number} responsiveWidth - The responsive width to use when contentMinWidthValue is CONTENT_MAX_WIDTH.
|
|
22
|
-
* @returns {number|string|null} The resolved maximum width value, or null if full width is desired.
|
|
23
|
-
*/
|
|
24
|
-
const resolveContentMaxWidth = (contentMinWidthValue, responsiveWidth) => {
|
|
25
|
-
if (!contentMinWidthValue || contentMinWidthValue === CONTENT_FULL_WIDTH) {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
if (Number.isFinite(contentMinWidthValue)) {
|
|
29
|
-
return contentMinWidthValue;
|
|
30
|
-
}
|
|
31
|
-
if (contentMinWidthValue === CONTENT_MAX_WIDTH) {
|
|
32
|
-
return responsiveWidth;
|
|
33
|
-
}
|
|
34
|
-
return contentMinWidthValue;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Calculates the maximum width for a given viewport based on limitWidth and contentMinWidth settings.
|
|
16
|
+
* Calculates the maximum width for a given viewport based on limitWidth and contentMaxWidth settings.
|
|
39
17
|
*
|
|
40
18
|
* @param {string} viewportKey - The viewport key ('xs', 'sm', 'md', 'lg', 'xl')
|
|
41
19
|
* @param {boolean} limitWidth - Whether to limit the width to viewport breakpoints
|
|
42
|
-
* @param {any}
|
|
20
|
+
* @param {any} contentWidthProp - The contentMaxWidth (or contentMinWidth) prop value
|
|
43
21
|
* @param {number|string|null} maxWidth - The resolved max width value
|
|
44
22
|
* @returns {number|string|null} The calculated maximum width for the viewport
|
|
45
23
|
*/
|
|
46
|
-
const getMaxWidthForViewport = (viewportKey, limitWidth,
|
|
24
|
+
const getMaxWidthForViewport = (viewportKey, limitWidth, contentWidthProp, maxWidth) => {
|
|
47
25
|
if (limitWidth) {
|
|
48
26
|
if (viewportKey === 'xs') {
|
|
49
27
|
return null;
|
|
50
28
|
}
|
|
51
29
|
return viewports.map.get(viewportKey);
|
|
52
30
|
}
|
|
53
|
-
if (
|
|
31
|
+
if (contentWidthProp) {
|
|
54
32
|
return maxWidth;
|
|
55
33
|
}
|
|
56
34
|
return null;
|
|
@@ -74,6 +52,7 @@ const FlexGrid = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
74
52
|
accessibilityRole,
|
|
75
53
|
children,
|
|
76
54
|
dataSet,
|
|
55
|
+
contentMaxWidth,
|
|
77
56
|
contentMinWidth,
|
|
78
57
|
...rest
|
|
79
58
|
} = _ref;
|
|
@@ -87,28 +66,31 @@ const FlexGrid = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
87
66
|
} = useTheme();
|
|
88
67
|
let flexgridStyles;
|
|
89
68
|
let mediaIds;
|
|
90
|
-
|
|
69
|
+
|
|
70
|
+
// Support both contentMaxWidth and deprecated contentMinWidth for backwards compatibility
|
|
71
|
+
const contentWidthProp = contentMaxWidth || contentMinWidth;
|
|
72
|
+
const contentWidthValue = useResponsiveProp(contentWidthProp);
|
|
91
73
|
const responsiveWidth = useResponsiveProp(themeOptions?.contentMaxWidth);
|
|
92
|
-
const maxWidth = resolveContentMaxWidth(
|
|
74
|
+
const maxWidth = resolveContentMaxWidth(contentWidthValue, responsiveWidth);
|
|
93
75
|
const stylesByViewport = {
|
|
94
76
|
xs: {
|
|
95
|
-
maxWidth: getMaxWidthForViewport('xs', limitWidth,
|
|
77
|
+
maxWidth: getMaxWidthForViewport('xs', limitWidth, contentWidthProp, maxWidth),
|
|
96
78
|
flexDirection: reverseLevel[0] ? 'column-reverse' : 'column'
|
|
97
79
|
},
|
|
98
80
|
sm: {
|
|
99
|
-
maxWidth: getMaxWidthForViewport('sm', limitWidth,
|
|
81
|
+
maxWidth: getMaxWidthForViewport('sm', limitWidth, contentWidthProp, maxWidth),
|
|
100
82
|
flexDirection: reverseLevel[1] ? 'column-reverse' : 'column'
|
|
101
83
|
},
|
|
102
84
|
md: {
|
|
103
|
-
maxWidth: getMaxWidthForViewport('md', limitWidth,
|
|
85
|
+
maxWidth: getMaxWidthForViewport('md', limitWidth, contentWidthProp, maxWidth),
|
|
104
86
|
flexDirection: reverseLevel[2] ? 'column-reverse' : 'column'
|
|
105
87
|
},
|
|
106
88
|
lg: {
|
|
107
|
-
maxWidth: getMaxWidthForViewport('lg', limitWidth,
|
|
89
|
+
maxWidth: getMaxWidthForViewport('lg', limitWidth, contentWidthProp, maxWidth),
|
|
108
90
|
flexDirection: reverseLevel[3] ? 'column-reverse' : 'column'
|
|
109
91
|
},
|
|
110
92
|
xl: {
|
|
111
|
-
maxWidth: getMaxWidthForViewport('xl', limitWidth,
|
|
93
|
+
maxWidth: getMaxWidthForViewport('xl', limitWidth, contentWidthProp, maxWidth),
|
|
112
94
|
flexDirection: reverseLevel[4] ? 'column-reverse' : 'column'
|
|
113
95
|
}
|
|
114
96
|
};
|
|
@@ -204,7 +186,7 @@ FlexGrid.propTypes = {
|
|
|
204
186
|
*/
|
|
205
187
|
children: PropTypes.node.isRequired,
|
|
206
188
|
/**
|
|
207
|
-
* The
|
|
189
|
+
* The maximum width of the content in the FlexGrid.
|
|
208
190
|
* This prop accepts responsive values for different viewports. If a number is provided,
|
|
209
191
|
* it will be the max content width for the desired viewport.
|
|
210
192
|
* - `xs`: 'max' | 'full' | <number>
|
|
@@ -213,6 +195,20 @@ FlexGrid.propTypes = {
|
|
|
213
195
|
* - `lg`: 'max' | 'full' | <number>
|
|
214
196
|
* - `xl`: 'max' | 'full' | <number>
|
|
215
197
|
*/
|
|
198
|
+
contentMaxWidth: PropTypes.shape({
|
|
199
|
+
xl: PropTypes.oneOfType([PropTypes.oneOf(['max', 'full']), PropTypes.number]),
|
|
200
|
+
lg: PropTypes.oneOfType([PropTypes.oneOf(['max', 'full']), PropTypes.number]),
|
|
201
|
+
md: PropTypes.oneOfType([PropTypes.oneOf(['max', 'full']), PropTypes.number]),
|
|
202
|
+
sm: PropTypes.oneOfType([PropTypes.oneOf(['max', 'full']), PropTypes.number]),
|
|
203
|
+
xs: PropTypes.oneOfType([PropTypes.oneOf(['max', 'full']), PropTypes.number])
|
|
204
|
+
}),
|
|
205
|
+
/**
|
|
206
|
+
* @deprecated Use `contentMaxWidth` instead. This prop will be removed in a future version.
|
|
207
|
+
*
|
|
208
|
+
* The minimum width of the content in the FlexGrid.
|
|
209
|
+
* This prop accepts responsive values for different viewports. If a number is provided,
|
|
210
|
+
* it will be the max content width for the desired viewport.
|
|
211
|
+
*/
|
|
216
212
|
contentMinWidth: PropTypes.shape({
|
|
217
213
|
xl: PropTypes.oneOfType([PropTypes.oneOf(['max', 'full']), PropTypes.number]),
|
|
218
214
|
lg: PropTypes.oneOfType([PropTypes.oneOf(['max', 'full']), PropTypes.number]),
|
|
@@ -123,6 +123,7 @@ const IconButton = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
123
123
|
hrefAttrs,
|
|
124
124
|
testID,
|
|
125
125
|
accessibilityRole = href ? 'link' : 'button',
|
|
126
|
+
inactive = false,
|
|
126
127
|
...rawRest
|
|
127
128
|
} = _ref3;
|
|
128
129
|
const {
|
|
@@ -143,8 +144,12 @@ const IconButton = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
143
144
|
}
|
|
144
145
|
});
|
|
145
146
|
};
|
|
146
|
-
const
|
|
147
|
-
|
|
147
|
+
const mergedVariant = inactive ? {
|
|
148
|
+
...variant,
|
|
149
|
+
inactive: true
|
|
150
|
+
} : variant;
|
|
151
|
+
const getTokens = useThemeTokensCallback('IconButton', tokens, mergedVariant);
|
|
152
|
+
const getOuterStyle = pressableState => selectOuterStyle(getTokens(resolvePressableState(pressableState), mergedVariant.password));
|
|
148
153
|
return /*#__PURE__*/_jsx(Pressable, {
|
|
149
154
|
ref: ref,
|
|
150
155
|
href: href,
|
|
@@ -153,15 +158,16 @@ const IconButton = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
153
158
|
style: getOuterStyle,
|
|
154
159
|
...selectedProps,
|
|
155
160
|
testID: testID,
|
|
161
|
+
disabled: inactive,
|
|
156
162
|
children: pressableState => {
|
|
157
163
|
const themeTokens = getTokens(resolvePressableState(pressableState));
|
|
158
164
|
return /*#__PURE__*/_jsx(View, {
|
|
159
|
-
style: selectInnerStyle(themeTokens,
|
|
165
|
+
style: selectInnerStyle(themeTokens, mergedVariant.password),
|
|
160
166
|
children: /*#__PURE__*/_jsx(Icon, {
|
|
161
167
|
icon: IconComponent || themeTokens.icon,
|
|
162
168
|
title: selectedProps.accessibilityLabel,
|
|
163
169
|
tokens: selectTokens('Icon', themeTokens, 'icon'),
|
|
164
|
-
variant:
|
|
170
|
+
variant: mergedVariant
|
|
165
171
|
})
|
|
166
172
|
});
|
|
167
173
|
}
|
|
@@ -192,7 +198,11 @@ IconButton.propTypes = {
|
|
|
192
198
|
/**
|
|
193
199
|
* Function to execute when the `Iconbutton` is pressed
|
|
194
200
|
*/
|
|
195
|
-
onPress: PropTypes.func
|
|
201
|
+
onPress: PropTypes.func,
|
|
202
|
+
/**
|
|
203
|
+
* When true, applies the inactive variant styling
|
|
204
|
+
*/
|
|
205
|
+
inactive: PropTypes.bool
|
|
196
206
|
};
|
|
197
207
|
const staticStyles = StyleSheet.create({
|
|
198
208
|
outer: {
|
|
@@ -65,7 +65,8 @@ const InputSupports = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
65
65
|
}), typeof children === 'function' ? children({
|
|
66
66
|
inputId,
|
|
67
67
|
...a11yProps,
|
|
68
|
-
validation: feedbackValidation
|
|
68
|
+
validation: feedbackValidation,
|
|
69
|
+
accessibilityDescribedBy: feedbackId
|
|
69
70
|
}) : children, feedback || maxCharsReachedErrorMessage ? /*#__PURE__*/_jsx(Feedback, {
|
|
70
71
|
id: feedbackId,
|
|
71
72
|
title: feedback || maxCharsReachedErrorMessage,
|
|
@@ -142,7 +142,7 @@ const PriceLockup = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
|
|
|
142
142
|
...selectProps(rest),
|
|
143
143
|
children: [topText ? /*#__PURE__*/_jsx(View, {
|
|
144
144
|
style: staticStyles.topText,
|
|
145
|
-
children: renderTypography(topText, topTextTypographyTokens)
|
|
145
|
+
children: renderTypography(topText, topTextTypographyTokens, undefined, fontColor)
|
|
146
146
|
}) : null, renderPrice(price, rateText, ratePosition, signDirection, currencySymbol, currencySymbolTypographyTokens, amountTypographyTokens, centsTypographyTokens, rateTypographyTokens, fontColor, strikeThrough, a11yText, bottomText, bottomLinksMarginLeft, footnoteLinks, onClickFootnote, themeTokens, isPriceBaseline), bottomText ? /*#__PURE__*/_jsxs(_Fragment, {
|
|
147
147
|
children: [/*#__PURE__*/_jsx(Divider, {
|
|
148
148
|
testID: "price-lockup-divider",
|
|
@@ -325,7 +325,7 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
|
|
|
325
325
|
icon: ClearButtonIcon,
|
|
326
326
|
onPress: handleClear,
|
|
327
327
|
variant: {
|
|
328
|
-
|
|
328
|
+
subtle: true
|
|
329
329
|
}
|
|
330
330
|
}, "clear"));
|
|
331
331
|
}
|
|
@@ -335,8 +335,7 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
|
|
|
335
335
|
icon: !showPassword ? passwordShowButtonIcon : passwordHideButtonIcon,
|
|
336
336
|
onPress: handleShowOrHide,
|
|
337
337
|
variant: {
|
|
338
|
-
|
|
339
|
-
password: true,
|
|
338
|
+
subtle: true,
|
|
340
339
|
inactive: variant.inactive,
|
|
341
340
|
size: 'large'
|
|
342
341
|
},
|
package/lib/esm/utils/index.js
CHANGED
|
@@ -26,4 +26,5 @@ export { default as convertFromMegaByteToByte } from './convertFromMegaByteToByt
|
|
|
26
26
|
export { default as formatImageSource } from './formatImageSource';
|
|
27
27
|
export { default as getSpacingScale } from './getSpacingScale';
|
|
28
28
|
export { default as useVariants } from './useVariants';
|
|
29
|
-
export { default as isTouchDevice } from './isTouchDevice';
|
|
29
|
+
export { default as isTouchDevice } from './isTouchDevice';
|
|
30
|
+
export { default as resolveContentMaxWidth } from './resolveContentMaxWidth';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const CONTENT_MAX_WIDTH = 'max';
|
|
2
|
+
const CONTENT_FULL_WIDTH = 'full';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Resolves the maximum width for content based on the provided value and responsive width.
|
|
6
|
+
*
|
|
7
|
+
* @param {number|string|null|undefined} contentMaxWidthValue - The maximum width value for the content.
|
|
8
|
+
* Can be a number, a special string constant (e.g., CONTENT_FULL_WIDTH, CONTENT_MAX_WIDTH), or null/undefined.
|
|
9
|
+
* @param {number} responsiveWidth - The responsive width to use when contentMaxWidthValue is CONTENT_MAX_WIDTH.
|
|
10
|
+
* @returns {number|string|null} The resolved maximum width value, or null if full width is desired.
|
|
11
|
+
*/
|
|
12
|
+
const resolveContentMaxWidth = (contentMaxWidthValue, responsiveWidth) => {
|
|
13
|
+
if (!contentMaxWidthValue || contentMaxWidthValue === CONTENT_FULL_WIDTH) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
if (Number.isFinite(contentMaxWidthValue)) {
|
|
17
|
+
return contentMaxWidthValue;
|
|
18
|
+
}
|
|
19
|
+
if (contentMaxWidthValue === CONTENT_MAX_WIDTH) {
|
|
20
|
+
return responsiveWidth;
|
|
21
|
+
}
|
|
22
|
+
return contentMaxWidthValue;
|
|
23
|
+
};
|
|
24
|
+
export default resolveContentMaxWidth;
|
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.18.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.26.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.18.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.26.0",
|
|
88
88
|
"types": "types/index.d.ts"
|
|
89
89
|
}
|