@telus-uds/components-base 3.5.1 → 3.6.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 +27 -2
- package/lib/cjs/Box/Box.js +53 -7
- package/lib/cjs/Carousel/Carousel.js +34 -47
- package/lib/cjs/Carousel/CarouselItem/CarouselItem.js +4 -6
- package/lib/cjs/Carousel/Constants.js +5 -2
- package/lib/cjs/ExpandCollapseMini/ExpandCollapseMini.js +5 -0
- package/lib/cjs/ExpandCollapseMini/ExpandCollapseMiniControl.js +17 -26
- package/lib/cjs/MultiSelectFilter/MultiSelectFilter.js +8 -2
- package/lib/cjs/Notification/Notification.js +26 -16
- package/lib/cjs/utils/getSpacingScale.js +66 -0
- package/lib/cjs/utils/index.js +9 -1
- package/lib/cjs/utils/useResponsiveProp.js +1 -1
- package/lib/esm/Box/Box.js +55 -9
- package/lib/esm/Carousel/Carousel.js +35 -48
- package/lib/esm/Carousel/CarouselItem/CarouselItem.js +4 -6
- package/lib/esm/Carousel/Constants.js +4 -1
- package/lib/esm/ExpandCollapseMini/ExpandCollapseMini.js +5 -0
- package/lib/esm/ExpandCollapseMini/ExpandCollapseMiniControl.js +17 -26
- package/lib/esm/MultiSelectFilter/MultiSelectFilter.js +8 -2
- package/lib/esm/Notification/Notification.js +27 -17
- package/lib/esm/utils/getSpacingScale.js +61 -0
- package/lib/esm/utils/index.js +2 -1
- package/lib/esm/utils/useResponsiveProp.js +1 -1
- package/lib/package.json +4 -4
- package/package.json +4 -4
- package/src/Box/Box.jsx +61 -8
- package/src/Carousel/Carousel.jsx +47 -58
- package/src/Carousel/CarouselItem/CarouselItem.jsx +4 -6
- package/src/Carousel/Constants.js +3 -0
- package/src/ExpandCollapseMini/ExpandCollapseMini.jsx +5 -0
- package/src/ExpandCollapseMini/ExpandCollapseMiniControl.jsx +17 -21
- package/src/MultiSelectFilter/MultiSelectFilter.jsx +8 -2
- package/src/Notification/Notification.jsx +29 -12
- package/src/utils/getSpacingScale.js +50 -0
- package/src/utils/index.js +1 -0
- package/src/utils/useResponsiveProp.js +1 -1
package/src/Box/Box.jsx
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import { View, ScrollView, Platform, StyleSheet, ImageBackground, Image } from 'react-native'
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
useTheme,
|
|
6
|
+
useThemeTokens,
|
|
7
|
+
useResponsiveThemeTokens,
|
|
8
|
+
useThemeTokensCallback
|
|
9
|
+
} from '../ThemeProvider'
|
|
5
10
|
import {
|
|
6
11
|
a11yProps,
|
|
12
|
+
createMediaQueryStyles,
|
|
7
13
|
getA11yPropsFromHtmlTag,
|
|
8
14
|
getTokensPropType,
|
|
9
15
|
layoutTags,
|
|
@@ -13,9 +19,12 @@ import {
|
|
|
13
19
|
useResponsiveProp,
|
|
14
20
|
useSpacingScale,
|
|
15
21
|
variantProp,
|
|
16
|
-
viewProps
|
|
22
|
+
viewProps,
|
|
23
|
+
StyleSheet as RNMQStyleSheet,
|
|
24
|
+
getSpacingScale
|
|
17
25
|
} from '../utils'
|
|
18
26
|
import backgroundImageStylesMap from './backgroundImageStylesMap'
|
|
27
|
+
import { useViewport } from '../ViewportProvider'
|
|
19
28
|
|
|
20
29
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
|
|
21
30
|
|
|
@@ -212,8 +221,20 @@ const Box = React.forwardRef(
|
|
|
212
221
|
...selectProps(rest)
|
|
213
222
|
}
|
|
214
223
|
|
|
215
|
-
const
|
|
216
|
-
const
|
|
224
|
+
const viewport = useViewport()
|
|
225
|
+
const { themeOptions } = useTheme()
|
|
226
|
+
const { enableMediaQueryStyleSheet } = themeOptions
|
|
227
|
+
|
|
228
|
+
const useTokens = enableMediaQueryStyleSheet ? useResponsiveThemeTokens : useThemeTokens
|
|
229
|
+
const themeTokens = useTokens(
|
|
230
|
+
'Box',
|
|
231
|
+
tokens,
|
|
232
|
+
variant,
|
|
233
|
+
!enableMediaQueryStyleSheet && { viewport }
|
|
234
|
+
)
|
|
235
|
+
const getSpacingTokens = useThemeTokensCallback('spacingScale')
|
|
236
|
+
|
|
237
|
+
let boxStyles = {
|
|
217
238
|
flex,
|
|
218
239
|
paddingLeft: useSpacingScale(left),
|
|
219
240
|
paddingRight: useSpacingScale(right),
|
|
@@ -221,10 +242,40 @@ const Box = React.forwardRef(
|
|
|
221
242
|
paddingBottom: useSpacingScale(bottom),
|
|
222
243
|
...selectBoxStyles(themeTokens, customGradient)
|
|
223
244
|
}
|
|
245
|
+
let boxMediaIds
|
|
246
|
+
|
|
247
|
+
if (enableMediaQueryStyleSheet) {
|
|
248
|
+
const { transformedThemeTokens } = Object.entries(themeTokens).reduce(
|
|
249
|
+
(acc, [vp]) => {
|
|
250
|
+
acc.transformedThemeTokens[vp] = {
|
|
251
|
+
paddingLeft: getSpacingScale(left, vp, getSpacingTokens),
|
|
252
|
+
paddingRight: getSpacingScale(right, vp, getSpacingTokens),
|
|
253
|
+
paddingTop: getSpacingScale(top, vp, getSpacingTokens),
|
|
254
|
+
paddingBottom: getSpacingScale(bottom, vp, getSpacingTokens)
|
|
255
|
+
}
|
|
256
|
+
return acc
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
transformedThemeTokens: {}
|
|
260
|
+
}
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
const mediaQueryStyles = createMediaQueryStyles(transformedThemeTokens)
|
|
264
|
+
const { ids } = RNMQStyleSheet.create({
|
|
265
|
+
box: {
|
|
266
|
+
...mediaQueryStyles
|
|
267
|
+
}
|
|
268
|
+
})
|
|
269
|
+
boxStyles = {
|
|
270
|
+
flex,
|
|
271
|
+
...selectBoxStyles(themeTokens[viewport], customGradient)
|
|
272
|
+
}
|
|
273
|
+
boxMediaIds = ids.box
|
|
274
|
+
}
|
|
224
275
|
|
|
225
276
|
let content = children
|
|
226
277
|
if (typeof customGradient === 'function')
|
|
227
|
-
content = customGradient(
|
|
278
|
+
content = customGradient(boxStyles.colors, boxStyles)(children)
|
|
228
279
|
|
|
229
280
|
const { src = '', alt = '', resizeMode = '', position = '', align = '' } = backgroundImage || {}
|
|
230
281
|
const backgroundImageResizeMode = useResponsiveProp(resizeMode, 'cover')
|
|
@@ -256,17 +307,19 @@ const Box = React.forwardRef(
|
|
|
256
307
|
}
|
|
257
308
|
}, [backgroundImage, backgroundImageWidth, backgroundImageHeight, src])
|
|
258
309
|
|
|
310
|
+
const dataSetValue = boxMediaIds ? { media: boxMediaIds, ...dataSet } : dataSet
|
|
311
|
+
|
|
259
312
|
if (scroll) {
|
|
260
313
|
const scrollProps = typeof scroll === 'object' ? scroll : {}
|
|
261
|
-
scrollProps.contentContainerStyle = [
|
|
314
|
+
scrollProps.contentContainerStyle = [boxStyles, scrollProps.contentContainerStyle]
|
|
262
315
|
return (
|
|
263
|
-
<ScrollView {...scrollProps} {...props} testID={testID} dataSet={
|
|
316
|
+
<ScrollView {...scrollProps} {...props} testID={testID} dataSet={dataSetValue} ref={ref}>
|
|
264
317
|
{content}
|
|
265
318
|
</ScrollView>
|
|
266
319
|
)
|
|
267
320
|
}
|
|
268
321
|
return (
|
|
269
|
-
<View {...props} style={
|
|
322
|
+
<View {...props} style={boxStyles} testID={testID} dataSet={dataSetValue} ref={ref}>
|
|
270
323
|
{content}
|
|
271
324
|
</View>
|
|
272
325
|
)
|
|
@@ -31,7 +31,10 @@ import {
|
|
|
31
31
|
ITEMS_PER_VIEWPORT_LG_XL,
|
|
32
32
|
DEFAULT_POSITION_OFFSET,
|
|
33
33
|
LARGE_VIEWPORT_MARGIN,
|
|
34
|
-
DEFAULT_VIEWPORT_MARGIN
|
|
34
|
+
DEFAULT_VIEWPORT_MARGIN,
|
|
35
|
+
PEEKING_MULTIPLIER,
|
|
36
|
+
ACTIVE_INDEX_OFFSET_MULTIPLIER,
|
|
37
|
+
NEGATIVE_MULTIPLIER
|
|
35
38
|
} from './Constants'
|
|
36
39
|
|
|
37
40
|
const TRANSITION_MODES = {
|
|
@@ -245,63 +248,26 @@ const selectNavigationStyles = (tabs, enableHero, viewport) => {
|
|
|
245
248
|
}
|
|
246
249
|
|
|
247
250
|
/**
|
|
248
|
-
* Calculates the final width of
|
|
251
|
+
* Calculates the final width of a carousel container based on the provided parameters.
|
|
249
252
|
*
|
|
250
|
-
* @param {number} containerWidth - The
|
|
251
|
-
* @param {boolean} enablePeeking - Flag indicating
|
|
252
|
-
* @param {
|
|
253
|
-
* @param {
|
|
254
|
-
* @
|
|
255
|
-
* @param {number} calcDelta - The delta value used for calculations.
|
|
256
|
-
* @returns {number} - The final calculated width of the container.
|
|
257
|
-
*
|
|
258
|
-
* The function adjusts the container width for displacement purposes based on the peeking properties and the position
|
|
259
|
-
* of the active item (first, middle, or last). It considers different peeking spaces and gaps
|
|
260
|
-
* to ensure the correct width is calculated for the carousel to display properly.
|
|
253
|
+
* @param {number} containerWidth - The width of the carousel container.
|
|
254
|
+
* @param {boolean} enablePeeking - Flag indicating whether peeking is enabled.
|
|
255
|
+
* @param {Object} viewport - The viewport configuration object used to determine peeking properties.
|
|
256
|
+
* @param {React.MutableRefObject<number>} activeIndexRef - A ref object holding the current active index of the carousel.
|
|
257
|
+
* @returns {number} The calculated final width of the carousel container.
|
|
261
258
|
*/
|
|
262
|
-
const calculateFinalWidth = (
|
|
263
|
-
containerWidth,
|
|
264
|
-
enablePeeking,
|
|
265
|
-
viewport,
|
|
266
|
-
activeIndexRef,
|
|
267
|
-
totalItems,
|
|
268
|
-
calcDelta
|
|
269
|
-
) => {
|
|
259
|
+
const calculateFinalWidth = (containerWidth, enablePeeking, viewport, activeIndexRef) => {
|
|
270
260
|
let finalWidth = containerWidth
|
|
271
261
|
|
|
272
262
|
if (enablePeeking) {
|
|
273
|
-
const {
|
|
274
|
-
|
|
263
|
+
const { peekingGap, peekingMiddleSpace, peekingMarginLeft } = getPeekingProps(viewport)
|
|
264
|
+
const slideWide =
|
|
265
|
+
containerWidth - (peekingMiddleSpace * PEEKING_MULTIPLIER + peekingGap * PEEKING_MULTIPLIER)
|
|
275
266
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
const basePeekingSpace = peekingFirstSpace + peekingGap + peekingMiddleSpace
|
|
281
|
-
const middlePeekingSpace = peekingMiddleSpace * 2 + peekingGap
|
|
282
|
-
|
|
283
|
-
if (isFirst) {
|
|
284
|
-
finalWidth -= basePeekingSpace
|
|
285
|
-
if (activeIndexRef.current + 1 === totalItems - 1) {
|
|
286
|
-
finalWidth -= peekingLastSpace - peekingMiddleSpace
|
|
287
|
-
}
|
|
288
|
-
} else if (isMiddle) {
|
|
289
|
-
if (calcDelta > 0) {
|
|
290
|
-
finalWidth -= basePeekingSpace + middlePeekingSpace * activeIndexRef.current
|
|
291
|
-
if (activeIndexRef.current + 1 === totalItems - 1) {
|
|
292
|
-
finalWidth -= peekingLastSpace - peekingMiddleSpace
|
|
293
|
-
}
|
|
294
|
-
} else {
|
|
295
|
-
finalWidth += basePeekingSpace + middlePeekingSpace * (activeIndexRef.current - 2)
|
|
296
|
-
if (activeIndexRef.current - 1 === 0) {
|
|
297
|
-
finalWidth -= peekingFirstSpace - peekingMiddleSpace
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
} else if (isLast) {
|
|
301
|
-
finalWidth += basePeekingSpace + middlePeekingSpace * (activeIndexRef.current - 2)
|
|
302
|
-
if (activeIndexRef.current - 1 === 0) {
|
|
303
|
-
finalWidth -= peekingLastSpace - peekingMiddleSpace
|
|
304
|
-
}
|
|
267
|
+
if (activeIndexRef.current === 0) {
|
|
268
|
+
finalWidth = slideWide + peekingMarginLeft - peekingMiddleSpace
|
|
269
|
+
} else {
|
|
270
|
+
finalWidth = slideWide + peekingGap
|
|
305
271
|
}
|
|
306
272
|
}
|
|
307
273
|
|
|
@@ -495,15 +461,40 @@ const Carousel = React.forwardRef(
|
|
|
495
461
|
)
|
|
496
462
|
|
|
497
463
|
const updateOffset = React.useCallback(() => {
|
|
498
|
-
|
|
464
|
+
if (enablePeeking) {
|
|
465
|
+
const { peekingGap, peekingMiddleSpace, peekingMarginLeft } = getPeekingProps(viewport)
|
|
466
|
+
|
|
467
|
+
let finalWidth
|
|
468
|
+
const slideWide =
|
|
469
|
+
containerLayoutRef.current.width -
|
|
470
|
+
(peekingMiddleSpace * PEEKING_MULTIPLIER + peekingGap * PEEKING_MULTIPLIER)
|
|
471
|
+
|
|
472
|
+
if (activeIndexRef.current === 0) {
|
|
473
|
+
finalWidth = 0
|
|
474
|
+
} else {
|
|
475
|
+
finalWidth =
|
|
476
|
+
slideWide +
|
|
477
|
+
peekingMarginLeft -
|
|
478
|
+
peekingMiddleSpace +
|
|
479
|
+
(slideWide + peekingGap) * (activeIndexRef.current - ACTIVE_INDEX_OFFSET_MULTIPLIER)
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
animatedX.current = finalWidth * NEGATIVE_MULTIPLIER
|
|
483
|
+
} else {
|
|
484
|
+
animatedX.current =
|
|
485
|
+
containerLayoutRef.current.width * activeIndexRef.current * NEGATIVE_MULTIPLIER
|
|
486
|
+
}
|
|
487
|
+
|
|
499
488
|
animatedY.current = 0
|
|
500
489
|
pan.setOffset({
|
|
501
490
|
x: animatedX.current,
|
|
502
491
|
y: animatedY.current
|
|
503
492
|
})
|
|
504
493
|
pan.setValue({ x: 0, y: 0 })
|
|
494
|
+
|
|
505
495
|
if (enableHero) {
|
|
506
|
-
heroAnimatedX.current =
|
|
496
|
+
heroAnimatedX.current =
|
|
497
|
+
heroContainerLayoutRef.current.width * activeIndexRef.current * NEGATIVE_MULTIPLIER
|
|
507
498
|
heroAnimatedY.current = 0
|
|
508
499
|
heroPan.setOffset({
|
|
509
500
|
x: heroAnimatedX.current,
|
|
@@ -511,7 +502,7 @@ const Carousel = React.forwardRef(
|
|
|
511
502
|
})
|
|
512
503
|
heroPan.setValue({ x: 0, y: 0 })
|
|
513
504
|
}
|
|
514
|
-
}, [pan, animatedX, heroPan, heroAnimatedX, enableHero])
|
|
505
|
+
}, [pan, animatedX, heroPan, heroAnimatedX, enableHero, viewport, enablePeeking])
|
|
515
506
|
|
|
516
507
|
const animate = React.useCallback(
|
|
517
508
|
(panToAnimate, toValue, toIndex) => {
|
|
@@ -593,9 +584,7 @@ const Carousel = React.forwardRef(
|
|
|
593
584
|
containerLayoutRef.current.width,
|
|
594
585
|
enablePeeking,
|
|
595
586
|
viewport,
|
|
596
|
-
activeIndexRef
|
|
597
|
-
totalItems,
|
|
598
|
-
calcDelta
|
|
587
|
+
activeIndexRef
|
|
599
588
|
)
|
|
600
589
|
|
|
601
590
|
toValue.x = finalWidth * -1 * calcDelta
|
|
@@ -19,19 +19,18 @@ const selectContainerStyle = ({
|
|
|
19
19
|
elementIndex,
|
|
20
20
|
enablePeeking,
|
|
21
21
|
peekingMarginLeft,
|
|
22
|
-
peekingFirstSpace,
|
|
23
22
|
peekingGap,
|
|
24
23
|
hidden,
|
|
25
24
|
enableDisplayMultipleItemsPerSlide,
|
|
26
|
-
viewport
|
|
25
|
+
viewport,
|
|
26
|
+
peekingMiddleSpace
|
|
27
27
|
}) => {
|
|
28
28
|
let adjustedWidth = width
|
|
29
29
|
let marginLeft = 0
|
|
30
|
-
const marginRight = 0
|
|
31
30
|
|
|
32
31
|
if (enablePeeking) {
|
|
33
32
|
const isFirst = elementIndex === 0
|
|
34
|
-
adjustedWidth = width - (
|
|
33
|
+
adjustedWidth = width - (peekingMiddleSpace * 2 + peekingGap * 2)
|
|
35
34
|
if (isFirst) {
|
|
36
35
|
marginLeft = peekingMarginLeft
|
|
37
36
|
} else {
|
|
@@ -73,8 +72,7 @@ const selectContainerStyle = ({
|
|
|
73
72
|
|
|
74
73
|
const style = {
|
|
75
74
|
width: adjustedWidth,
|
|
76
|
-
marginLeft
|
|
77
|
-
marginRight
|
|
75
|
+
marginLeft
|
|
78
76
|
}
|
|
79
77
|
|
|
80
78
|
if (hidden && Platform.OS === 'web') {
|
|
@@ -5,3 +5,6 @@ export const HERO_POSITION_OFFSET = 20
|
|
|
5
5
|
export const DEFAULT_POSITION_OFFSET = 0
|
|
6
6
|
export const LARGE_VIEWPORT_MARGIN = 40
|
|
7
7
|
export const DEFAULT_VIEWPORT_MARGIN = 10
|
|
8
|
+
export const PEEKING_MULTIPLIER = 2
|
|
9
|
+
export const ACTIVE_INDEX_OFFSET_MULTIPLIER = 1
|
|
10
|
+
export const NEGATIVE_MULTIPLIER = -1
|
|
@@ -2,6 +2,7 @@ import React from 'react'
|
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import ExpandCollapse from '../ExpandCollapse'
|
|
4
4
|
import { getTokensPropType, selectSystemProps, contentfulProps } from '../utils'
|
|
5
|
+
import { variantProp } from '../utils/props'
|
|
5
6
|
import ExpandCollapseMiniControl from './ExpandCollapseMiniControl'
|
|
6
7
|
|
|
7
8
|
const [selectContainerProps, selectedContainerPropTypes] = selectSystemProps([contentfulProps])
|
|
@@ -79,6 +80,10 @@ ExpandCollapseMini.propTypes = {
|
|
|
79
80
|
* Optional variant object to override the default theme tokens
|
|
80
81
|
*/
|
|
81
82
|
tokens: getTokensPropType('ExpandCollapseMini'),
|
|
83
|
+
/**
|
|
84
|
+
* ExpandCollapseMini variant.
|
|
85
|
+
*/
|
|
86
|
+
variant: variantProp.propType,
|
|
82
87
|
/**
|
|
83
88
|
* The dataSet prop allows to pass data-* attributes element to the component.
|
|
84
89
|
*/
|
|
@@ -15,13 +15,6 @@ const presentationOnly = {
|
|
|
15
15
|
focusable: false // Stop RNW from setting tabIndex={0}: focus goes to Control only
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
const selectLinkTokens = ({ color, textLine, lineHeight, fontSize }) => ({
|
|
19
|
-
color,
|
|
20
|
-
textLine,
|
|
21
|
-
blockLineHeight: lineHeight,
|
|
22
|
-
blockFontSize: fontSize
|
|
23
|
-
})
|
|
24
|
-
|
|
25
18
|
const ExpandCollapseMiniControl = React.forwardRef(
|
|
26
19
|
(
|
|
27
20
|
{
|
|
@@ -35,20 +28,24 @@ const ExpandCollapseMiniControl = React.forwardRef(
|
|
|
35
28
|
},
|
|
36
29
|
ref
|
|
37
30
|
) => {
|
|
38
|
-
const { expanded, hover, focus } = pressableState || {}
|
|
39
|
-
|
|
40
|
-
const
|
|
31
|
+
const { expanded, hover, focus, pressed } = pressableState || {}
|
|
32
|
+
const { quiet } = variant
|
|
33
|
+
const isFocusVisible = Platform.OS === 'web' ? focus && !pressed && !hover : expanded
|
|
34
|
+
|
|
35
|
+
const linkTokens = useThemeTokens(
|
|
41
36
|
'Link',
|
|
42
37
|
{},
|
|
43
|
-
{},
|
|
44
|
-
{
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
variant,
|
|
50
|
-
{ expanded, focus }
|
|
38
|
+
{ ...variant, quiet: expanded ?? quiet },
|
|
39
|
+
{
|
|
40
|
+
focus: isFocusVisible,
|
|
41
|
+
hover,
|
|
42
|
+
pressed
|
|
43
|
+
}
|
|
51
44
|
)
|
|
45
|
+
const { size, icon } = useThemeTokens('ExpandCollapseMiniControl', tokens, variant, {
|
|
46
|
+
expanded,
|
|
47
|
+
focus
|
|
48
|
+
})
|
|
52
49
|
|
|
53
50
|
// Choose hover styles when any part of Control is hoverred
|
|
54
51
|
const appearance = { ...variant, hover }
|
|
@@ -75,9 +72,8 @@ const ExpandCollapseMiniControl = React.forwardRef(
|
|
|
75
72
|
icon={icon}
|
|
76
73
|
iconPosition={iconPosition}
|
|
77
74
|
tokens={(linkState) => ({
|
|
78
|
-
...
|
|
79
|
-
...
|
|
80
|
-
outerBorderColor
|
|
75
|
+
...linkTokens,
|
|
76
|
+
...getTokens(linkState)
|
|
81
77
|
})}
|
|
82
78
|
ref={ref}
|
|
83
79
|
{...presentationOnly}
|
|
@@ -134,6 +134,10 @@ const MultiSelectFilter = React.forwardRef(
|
|
|
134
134
|
buttonIconPadding,
|
|
135
135
|
subtitleColor,
|
|
136
136
|
dividerColor,
|
|
137
|
+
iconColor,
|
|
138
|
+
buttonBackgroundColor,
|
|
139
|
+
iconColorSelected,
|
|
140
|
+
buttonBackgroundColorSelected,
|
|
137
141
|
...restTokens
|
|
138
142
|
} = useThemeTokens(
|
|
139
143
|
'MultiSelectFilter',
|
|
@@ -154,7 +158,9 @@ const MultiSelectFilter = React.forwardRef(
|
|
|
154
158
|
paddingBottom: labelPaddingBottom,
|
|
155
159
|
paddingLeft: labelPaddingLeft,
|
|
156
160
|
paddingRight: labelPaddingRight,
|
|
157
|
-
iconBackground: buttonIconBackgroundColor
|
|
161
|
+
iconBackground: buttonIconBackgroundColor,
|
|
162
|
+
iconColor: isSelected ? iconColorSelected : iconColor,
|
|
163
|
+
backgroundColor: isSelected ? buttonBackgroundColorSelected : buttonBackgroundColor
|
|
158
164
|
}
|
|
159
165
|
const getButtonDropdownTokens = useThemeTokensCallback(
|
|
160
166
|
'ButtonDropdown',
|
|
@@ -236,7 +242,7 @@ const MultiSelectFilter = React.forwardRef(
|
|
|
236
242
|
const [isScrolling, setIsScrolling] = React.useState(false)
|
|
237
243
|
const [scrollViewHeight, setScrollViewHeight] = React.useState(0)
|
|
238
244
|
const [rowHeight, setRowHeight] = React.useState(0)
|
|
239
|
-
const modalRef = useScrollBlocking(isOpen)
|
|
245
|
+
const modalRef = useScrollBlocking(isOpen && viewport === 'xs')
|
|
240
246
|
const windowWidth = Dimensions.get('window').width
|
|
241
247
|
const windowHeight = Dimensions.get('window').height
|
|
242
248
|
|
|
@@ -18,7 +18,8 @@ import {
|
|
|
18
18
|
viewProps,
|
|
19
19
|
wrapStringsInText,
|
|
20
20
|
createMediaQueryStyles,
|
|
21
|
-
StyleSheet
|
|
21
|
+
StyleSheet,
|
|
22
|
+
useResponsiveProp
|
|
22
23
|
} from '../utils'
|
|
23
24
|
import IconButton from '../IconButton'
|
|
24
25
|
import useCopy from '../utils/useCopy'
|
|
@@ -64,8 +65,8 @@ const selectDismissButtonContainerStyles = ({ dismissButtonGap }) => ({
|
|
|
64
65
|
placeContent: 'start'
|
|
65
66
|
})
|
|
66
67
|
|
|
67
|
-
const selectContentContainerStyle = (themeTokens, maxWidth,
|
|
68
|
-
maxWidth: viewport === 'xl'
|
|
68
|
+
const selectContentContainerStyle = (themeTokens, maxWidth, system, viewport) => ({
|
|
69
|
+
maxWidth: system && viewport === 'xl' ? maxWidth : '100%',
|
|
69
70
|
width: '100%',
|
|
70
71
|
paddingRight: themeTokens?.containerPaddingRight,
|
|
71
72
|
paddingLeft: themeTokens?.containerPaddingLeft
|
|
@@ -82,7 +83,7 @@ const getMediaQueryStyles = (
|
|
|
82
83
|
) => {
|
|
83
84
|
const transformedSelectContainerStyles = Object.entries(themeTokens).reduce(
|
|
84
85
|
(acc, [vp, viewportTokens]) => {
|
|
85
|
-
acc[vp] = selectContainerStyles({ ...viewportTokens })
|
|
86
|
+
acc[vp] = { ...selectContainerStyles({ ...viewportTokens }), flexDirection: 'column' }
|
|
86
87
|
return acc
|
|
87
88
|
},
|
|
88
89
|
{}
|
|
@@ -92,18 +93,31 @@ const getMediaQueryStyles = (
|
|
|
92
93
|
|
|
93
94
|
const { ids: containerIds, styles: containerStyles } = StyleSheet.create({
|
|
94
95
|
container: {
|
|
95
|
-
flexDirection: 'column',
|
|
96
96
|
...selectContainerMediaQueryStyles
|
|
97
97
|
}
|
|
98
98
|
})
|
|
99
99
|
|
|
100
|
+
const transformedSelectContentContainerStyles = Object.entries(themeTokens).reduce(
|
|
101
|
+
(acc, [vp, viewportTokens]) => {
|
|
102
|
+
acc[vp] = {
|
|
103
|
+
...selectContentContainerStyle(viewportTokens, maxWidth, system, vp),
|
|
104
|
+
flexDirection: 'row',
|
|
105
|
+
flexShrink: 1,
|
|
106
|
+
justifyContent: 'space-between',
|
|
107
|
+
...(system && { alignSelf: 'center' })
|
|
108
|
+
}
|
|
109
|
+
return acc
|
|
110
|
+
},
|
|
111
|
+
{}
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
const selectContentContainerMediaQueryStyles = createMediaQueryStyles(
|
|
115
|
+
transformedSelectContentContainerStyles
|
|
116
|
+
)
|
|
117
|
+
|
|
100
118
|
const { ids: contentContainerIds, styles: contentContainerStyles } = StyleSheet.create({
|
|
101
119
|
contentContainer: {
|
|
102
|
-
|
|
103
|
-
flexShrink: 1,
|
|
104
|
-
justifyContent: 'space-between',
|
|
105
|
-
...selectContentContainerStyle(themeTokens, maxWidth, viewport, system),
|
|
106
|
-
...(system && { alignSelf: 'center' })
|
|
120
|
+
...selectContentContainerMediaQueryStyles
|
|
107
121
|
}
|
|
108
122
|
})
|
|
109
123
|
|
|
@@ -167,7 +181,7 @@ const getDefaultStyles = (themeTokens, themeOptions, maxWidth, dismissible, view
|
|
|
167
181
|
flexDirection: 'row',
|
|
168
182
|
flexShrink: 1,
|
|
169
183
|
justifyContent: 'space-between',
|
|
170
|
-
...selectContentContainerStyle(themeTokens, maxWidth,
|
|
184
|
+
...selectContentContainerStyle(themeTokens, maxWidth, system, viewport),
|
|
171
185
|
...(system && { alignSelf: 'center' })
|
|
172
186
|
}
|
|
173
187
|
},
|
|
@@ -252,7 +266,10 @@ const Notification = React.forwardRef(
|
|
|
252
266
|
system: isSystemEnabled,
|
|
253
267
|
viewport
|
|
254
268
|
})
|
|
255
|
-
const maxWidth =
|
|
269
|
+
const maxWidth = useResponsiveProp(
|
|
270
|
+
themeOptions?.contentMaxWidth,
|
|
271
|
+
viewports.map.get(viewports.xl)
|
|
272
|
+
)
|
|
256
273
|
|
|
257
274
|
const notificationComponentRef = React.useRef({
|
|
258
275
|
containerStyles: {},
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { resolveResponsiveProp } from './useResponsiveProp'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Resolves spacing options from the provided space object.
|
|
5
|
+
*
|
|
6
|
+
* @param {Object} space - The space configuration object.
|
|
7
|
+
* @param {Object} [space.options] - The options for spacing.
|
|
8
|
+
* @param {number|string} [space.options.size] - The size of the spacing. Can be a number or a string.
|
|
9
|
+
* @param {string} [space.options.variant] - The variant of the spacing.
|
|
10
|
+
* @param {number} [space.options.subtract=0] - A value to subtract from the spacing size.
|
|
11
|
+
* @returns {Object} An object containing resolved spacing tokens, variant, overridden flag, and subtract value.
|
|
12
|
+
* @property {Object} tokens - The resolved spacing tokens.
|
|
13
|
+
* @property {number|string} tokens.size - The size of the spacing.
|
|
14
|
+
* @property {string} [variant] - The variant of the spacing.
|
|
15
|
+
* @property {boolean} overridden - Indicates if the size is explicitly overridden as a number.
|
|
16
|
+
* @property {number} subtract - The value to subtract from the spacing size.
|
|
17
|
+
*/
|
|
18
|
+
const resolveSpacingOptions = (space) => {
|
|
19
|
+
if (!space?.options) return {}
|
|
20
|
+
|
|
21
|
+
const { size, variant, subtract = 0 } = space.options
|
|
22
|
+
const overridden = typeof size === 'number'
|
|
23
|
+
|
|
24
|
+
return { tokens: { size }, variant, overridden, subtract }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Calculates the spacing scale based on the provided space value, viewport, and spacing tokens.
|
|
29
|
+
*
|
|
30
|
+
* @param {Object} spaceValue - The space value configuration, which may include responsive properties.
|
|
31
|
+
* @param {Object} viewport - The current viewport dimensions or configuration.
|
|
32
|
+
* @param {Function} getSpacingTokens - A function that retrieves spacing tokens based on the provided options.
|
|
33
|
+
* @returns {number} The calculated spacing scale, ensuring it is non-negative.
|
|
34
|
+
*/
|
|
35
|
+
const getSpacingScale = (spaceValue, viewport, getSpacingTokens) => {
|
|
36
|
+
const { tokens, variant, overridden, subtract = 0 } = resolveSpacingOptions(spaceValue)
|
|
37
|
+
const space = !overridden && (spaceValue?.space ?? resolveResponsiveProp(spaceValue, viewport, 0))
|
|
38
|
+
|
|
39
|
+
const { size } = getSpacingTokens(
|
|
40
|
+
{
|
|
41
|
+
...variant,
|
|
42
|
+
space: typeof space === 'number' ? space : 0,
|
|
43
|
+
viewport
|
|
44
|
+
},
|
|
45
|
+
tokens
|
|
46
|
+
)
|
|
47
|
+
return Math.max(size - subtract, 0)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export default getSpacingScale
|
package/src/utils/index.js
CHANGED
|
@@ -23,3 +23,4 @@ export { default as htmlAttrs } from './htmlAttrs'
|
|
|
23
23
|
export { transformGradient } from './transformGradient'
|
|
24
24
|
export { default as convertFromMegaByteToByte } from './convertFromMegaByteToByte'
|
|
25
25
|
export { default as formatImageSource } from './formatImageSource'
|
|
26
|
+
export { default as getSpacingScale } from './getSpacingScale'
|
|
@@ -25,7 +25,7 @@ export const resolveResponsiveProp = (prop, viewport, defaultValue) => {
|
|
|
25
25
|
: // If no current viewport is available, default to smallest viewport
|
|
26
26
|
prop[viewports.keys.find((key) => hasOwnProperty(prop, key))]
|
|
27
27
|
|
|
28
|
-
return value === undefined ? defaultValue : value
|
|
28
|
+
return value === undefined || value === null ? defaultValue : value
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/**
|