@telus-uds/components-base 3.27.0 → 3.28.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 +21 -5
- package/lib/cjs/Card/CardBase.js +12 -3
- package/lib/cjs/ExpandCollapse/Control.js +5 -1
- package/lib/cjs/ExpandCollapse/ExpandCollapse.js +17 -8
- package/lib/cjs/ExpandCollapse/Panel.js +7 -2
- package/lib/cjs/IconButton/IconButton.js +10 -5
- package/lib/cjs/Modal/Modal.js +21 -11
- package/lib/cjs/Progress/Progress.js +19 -5
- package/lib/cjs/Progress/ProgressBar.js +22 -4
- package/lib/cjs/Progress/ProgressContext.js +11 -0
- package/lib/cjs/SideNav/Item.js +3 -3
- package/lib/cjs/SideNav/ItemsGroup.js +46 -19
- package/lib/cjs/SideNav/SideNav.js +29 -13
- package/lib/esm/Card/CardBase.js +12 -3
- package/lib/esm/ExpandCollapse/Control.js +5 -1
- package/lib/esm/ExpandCollapse/ExpandCollapse.js +17 -8
- package/lib/esm/ExpandCollapse/Panel.js +7 -2
- package/lib/esm/IconButton/IconButton.js +10 -5
- package/lib/esm/Modal/Modal.js +21 -11
- package/lib/esm/Progress/Progress.js +19 -5
- package/lib/esm/Progress/ProgressBar.js +22 -4
- package/lib/esm/Progress/ProgressContext.js +5 -0
- package/lib/esm/SideNav/Item.js +3 -3
- package/lib/esm/SideNav/ItemsGroup.js +45 -20
- package/lib/esm/SideNav/SideNav.js +29 -13
- package/lib/package.json +2 -2
- package/package.json +2 -2
- package/src/Card/CardBase.jsx +9 -3
- package/src/ExpandCollapse/Control.jsx +1 -1
- package/src/ExpandCollapse/ExpandCollapse.jsx +9 -8
- package/src/ExpandCollapse/Panel.jsx +10 -2
- package/src/IconButton/IconButton.jsx +40 -28
- package/src/Modal/Modal.jsx +23 -11
- package/src/Progress/Progress.jsx +18 -7
- package/src/Progress/ProgressBar.jsx +19 -14
- package/src/Progress/ProgressContext.js +5 -0
- package/src/SideNav/Item.jsx +3 -3
- package/src/SideNav/ItemsGroup.jsx +36 -16
- package/src/SideNav/SideNav.jsx +22 -8
|
@@ -6,13 +6,22 @@ import { useThemeTokens } from '../ThemeProvider';
|
|
|
6
6
|
import { a11yProps, getTokensPropType, selectSystemProps, useMultipleInputValues, variantProp, viewProps, contentfulProps, useUniqueId } from '../utils';
|
|
7
7
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
8
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps, contentfulProps]);
|
|
9
|
-
|
|
9
|
+
const selectWrapperStyles = _ref => {
|
|
10
|
+
let {
|
|
11
|
+
borderWidth,
|
|
12
|
+
borderTopWidth,
|
|
13
|
+
borderStyle,
|
|
14
|
+
borderColor
|
|
15
|
+
} = _ref;
|
|
10
16
|
return {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
17
|
+
borderStyle,
|
|
18
|
+
borderColor,
|
|
19
|
+
borderTopWidth,
|
|
20
|
+
borderBottomWidth: borderWidth,
|
|
21
|
+
borderBottomStyle: borderStyle,
|
|
22
|
+
borderBottomColor: borderColor
|
|
14
23
|
};
|
|
15
|
-
}
|
|
24
|
+
};
|
|
16
25
|
|
|
17
26
|
/**
|
|
18
27
|
* Flexible base component for lists where some or all items are collapsible headers.
|
|
@@ -21,7 +30,7 @@ function selectBorderStyles(tokens) {
|
|
|
21
30
|
* <ExpandCollapse.Panel> children, and assign the panels explicit `panelId` props. The panels may be
|
|
22
31
|
* nested (they do not need to be direct children), and non-interactive items may be included too.
|
|
23
32
|
*/
|
|
24
|
-
const ExpandCollapse = /*#__PURE__*/React.forwardRef((
|
|
33
|
+
const ExpandCollapse = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
25
34
|
let {
|
|
26
35
|
children,
|
|
27
36
|
tokens,
|
|
@@ -32,7 +41,7 @@ const ExpandCollapse = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
32
41
|
onChange,
|
|
33
42
|
dataSet,
|
|
34
43
|
...rest
|
|
35
|
-
} =
|
|
44
|
+
} = _ref2;
|
|
36
45
|
const instanceId = useUniqueId('ExpandCollapse');
|
|
37
46
|
const {
|
|
38
47
|
currentValues: openIds,
|
|
@@ -53,7 +62,7 @@ const ExpandCollapse = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
53
62
|
...selectProps(rest),
|
|
54
63
|
dataSet: dataSet,
|
|
55
64
|
children: /*#__PURE__*/_jsx(View, {
|
|
56
|
-
style:
|
|
65
|
+
style: selectWrapperStyles(themeTokens),
|
|
57
66
|
children: typeof children === 'function' ? children({
|
|
58
67
|
openIds,
|
|
59
68
|
onToggle,
|
|
@@ -103,6 +103,7 @@ const ExpandCollapsePanel = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
103
103
|
controlRef,
|
|
104
104
|
content,
|
|
105
105
|
copy = 'en',
|
|
106
|
+
disableMobileScrollBuffer = false,
|
|
106
107
|
...rest
|
|
107
108
|
} = _ref5;
|
|
108
109
|
const [containerHeight, setContainerHeight] = React.useState(null);
|
|
@@ -124,7 +125,7 @@ const ExpandCollapsePanel = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
124
125
|
|
|
125
126
|
// on mobile devices we require a scroll buffer equal to the font size
|
|
126
127
|
// to avoid triggering scrolling unnecessarily
|
|
127
|
-
const mobileScrollBuffer = Platform.OS === 'web' ? 0 : selectTextStyles(themeTokens)?.fontSize;
|
|
128
|
+
const mobileScrollBuffer = Platform.OS === 'web' || disableMobileScrollBuffer ? 0 : selectTextStyles(themeTokens)?.fontSize;
|
|
128
129
|
const handleControlPress = event => {
|
|
129
130
|
onToggle?.(panelId, event);
|
|
130
131
|
if (onPress) onPress(panelId, event);
|
|
@@ -271,6 +272,10 @@ ExpandCollapsePanel.propTypes = {
|
|
|
271
272
|
/**
|
|
272
273
|
* A boolean prop to determine if the panel is a content panel or not. If true, the panel will not have a control
|
|
273
274
|
*/
|
|
274
|
-
content: PropTypes.bool
|
|
275
|
+
content: PropTypes.bool,
|
|
276
|
+
/**
|
|
277
|
+
* A boolean prop to disable the extra scroll buffer on mobile devices (only applicable on iOS/Android, ignored on web)
|
|
278
|
+
*/
|
|
279
|
+
disableMobileScrollBuffer: PropTypes.bool
|
|
275
280
|
};
|
|
276
281
|
export default ExpandCollapsePanel;
|
|
@@ -79,6 +79,11 @@ const selectInnerStyle = (_ref2, password) => {
|
|
|
79
79
|
width,
|
|
80
80
|
height
|
|
81
81
|
} = _ref2;
|
|
82
|
+
const basePadding = calculatePadding(padding, borderWidth);
|
|
83
|
+
const calculateSpecificPadding = (specificPadding, specificBorderWidth) => {
|
|
84
|
+
const calculated = calculatePadding(specificPadding ?? padding, specificBorderWidth ?? borderWidth);
|
|
85
|
+
return calculated !== basePadding && calculated !== undefined ? calculated : undefined;
|
|
86
|
+
};
|
|
82
87
|
return {
|
|
83
88
|
// Inner borders animate with the icon and should be treated like a themable feature of the icon
|
|
84
89
|
borderColor,
|
|
@@ -92,11 +97,11 @@ const selectInnerStyle = (_ref2, password) => {
|
|
|
92
97
|
borderRightWidth,
|
|
93
98
|
borderBottomWidth,
|
|
94
99
|
borderLeftWidth,
|
|
95
|
-
padding:
|
|
96
|
-
paddingLeft:
|
|
97
|
-
paddingRight:
|
|
98
|
-
paddingTop:
|
|
99
|
-
paddingBottom:
|
|
100
|
+
padding: basePadding,
|
|
101
|
+
paddingLeft: calculateSpecificPadding(paddingLeft, borderLeftWidth),
|
|
102
|
+
paddingRight: calculateSpecificPadding(paddingRight, borderRightWidth),
|
|
103
|
+
paddingTop: calculateSpecificPadding(paddingTop, borderTopWidth),
|
|
104
|
+
paddingBottom: calculateSpecificPadding(paddingBottom, borderBottomWidth),
|
|
100
105
|
...Platform.select({
|
|
101
106
|
web: {
|
|
102
107
|
pointerEvents: 'none',
|
package/lib/esm/Modal/Modal.js
CHANGED
|
@@ -64,11 +64,15 @@ const selectModalStyles = _ref2 => {
|
|
|
64
64
|
const selectBackdropStyles = _ref3 => {
|
|
65
65
|
let {
|
|
66
66
|
backdropColor,
|
|
67
|
-
backdropOpacity
|
|
67
|
+
backdropOpacity,
|
|
68
|
+
backdropCursor
|
|
68
69
|
} = _ref3;
|
|
69
70
|
return {
|
|
70
71
|
backgroundColor: backdropColor,
|
|
71
|
-
opacity: backdropOpacity
|
|
72
|
+
opacity: backdropOpacity,
|
|
73
|
+
...(Platform.OS === 'web' && backdropCursor ? {
|
|
74
|
+
cursor: backdropCursor
|
|
75
|
+
} : {})
|
|
72
76
|
};
|
|
73
77
|
};
|
|
74
78
|
const selectCloseButtonContainerStyles = _ref4 => {
|
|
@@ -121,12 +125,15 @@ const Modal = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
121
125
|
cancelButtonText,
|
|
122
126
|
cancelButtonType,
|
|
123
127
|
footer,
|
|
128
|
+
backgroundDismissible = true,
|
|
124
129
|
...rest
|
|
125
130
|
} = _ref5;
|
|
126
131
|
const viewport = useViewport();
|
|
132
|
+
const isBackdropClickable = onClose && backgroundDismissible;
|
|
127
133
|
const themeTokens = useThemeTokens('Modal', tokens, variant, {
|
|
128
134
|
viewport,
|
|
129
|
-
maxWidth
|
|
135
|
+
maxWidth,
|
|
136
|
+
backdropCursor: isBackdropClickable ? 'pointer' : 'default'
|
|
130
137
|
});
|
|
131
138
|
const modalRef = useScrollBlocking(isOpen);
|
|
132
139
|
const modalBodyRef = React.useRef(ref);
|
|
@@ -232,7 +239,7 @@ const Modal = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
232
239
|
})]
|
|
233
240
|
})
|
|
234
241
|
}), /*#__PURE__*/_jsx(TouchableWithoutFeedback, {
|
|
235
|
-
onPress: handleClose,
|
|
242
|
+
onPress: isBackdropClickable && handleClose,
|
|
236
243
|
children: /*#__PURE__*/_jsx(View, {
|
|
237
244
|
style: [staticStyles.backdrop, selectBackdropStyles(themeTokens)]
|
|
238
245
|
})
|
|
@@ -329,7 +336,15 @@ Modal.propTypes = {
|
|
|
329
336
|
/**
|
|
330
337
|
* Receive a react node or an array of nodes to render at the bottom of the modal, above the action buttons.
|
|
331
338
|
*/
|
|
332
|
-
footer: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)])
|
|
339
|
+
footer: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]),
|
|
340
|
+
/**
|
|
341
|
+
* Controls whether the modal can be dismissed by clicking on the backdrop.
|
|
342
|
+
* When set to `false`, clicking the backdrop will not close the modal.
|
|
343
|
+
* The backdrop cursor automatically changes to 'default' to indicate it's not clickable.
|
|
344
|
+
* Note: Backdrop dismissal requires `onClose` to be defined.
|
|
345
|
+
* @default true
|
|
346
|
+
*/
|
|
347
|
+
backgroundDismissible: PropTypes.bool
|
|
333
348
|
};
|
|
334
349
|
export default Modal;
|
|
335
350
|
const staticStyles = StyleSheet.create({
|
|
@@ -339,12 +354,7 @@ const staticStyles = StyleSheet.create({
|
|
|
339
354
|
left: 0,
|
|
340
355
|
right: 0,
|
|
341
356
|
bottom: 0,
|
|
342
|
-
zIndex: -1
|
|
343
|
-
...Platform.select({
|
|
344
|
-
web: {
|
|
345
|
-
cursor: 'pointer'
|
|
346
|
-
}
|
|
347
|
-
})
|
|
357
|
+
zIndex: -1
|
|
348
358
|
},
|
|
349
359
|
positioningContainer: {
|
|
350
360
|
flexBasis: '100%',
|
|
@@ -4,6 +4,7 @@ import View from "react-native-web/dist/exports/View";
|
|
|
4
4
|
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
5
5
|
import { applyShadowToken, useThemeTokens } from '../ThemeProvider';
|
|
6
6
|
import { a11yProps, getTokensPropType, selectSystemProps, variantProp, viewProps } from '../utils';
|
|
7
|
+
import ProgressContext from './ProgressContext';
|
|
7
8
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
9
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
9
10
|
const selectProgressStyles = _ref => {
|
|
@@ -47,6 +48,12 @@ const selectProgressStyles = _ref => {
|
|
|
47
48
|
*
|
|
48
49
|
* - Use the `size` variant to control the height of your progress bars: passing `'mini'` will make your
|
|
49
50
|
* progress bar container narrower.
|
|
51
|
+
* - Use the `layers` variant to control how multiple progress bars are positioned:
|
|
52
|
+
* - `false` (default): bars are positioned vertically one below the other.
|
|
53
|
+
* - `true`: bars overlay on top of each other (layered/stacked on z-axis).
|
|
54
|
+
* Note: The `layers` prop is deprecated. After August 2026, `layers: true` will become the permanent
|
|
55
|
+
* default behavior and the `layers` prop will be removed. To maintain vertical layout after removal,
|
|
56
|
+
* use separate individual Progress components.
|
|
50
57
|
*
|
|
51
58
|
* ## Usability and A11y guidelines
|
|
52
59
|
*
|
|
@@ -63,11 +70,18 @@ const Progress = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
63
70
|
...rest
|
|
64
71
|
} = _ref2;
|
|
65
72
|
const themeTokens = useThemeTokens('Progress', tokens, variant);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
// Default to false (vertical layout) to preserve existing behavior and avoid breaking changes
|
|
74
|
+
const layers = variant?.layers ?? false;
|
|
75
|
+
return /*#__PURE__*/_jsx(ProgressContext.Provider, {
|
|
76
|
+
value: {
|
|
77
|
+
layers
|
|
78
|
+
},
|
|
79
|
+
children: /*#__PURE__*/_jsx(View, {
|
|
80
|
+
ref: ref,
|
|
81
|
+
style: [staticStyles.progressContainer, selectProgressStyles(themeTokens)],
|
|
82
|
+
...selectProps(rest),
|
|
83
|
+
children: children
|
|
84
|
+
})
|
|
71
85
|
});
|
|
72
86
|
});
|
|
73
87
|
Progress.displayName = 'Progress';
|
|
@@ -7,16 +7,23 @@ import ProgressBarBackground from './ProgressBarBackground';
|
|
|
7
7
|
import { applyShadowToken, useThemeTokens } from '../ThemeProvider';
|
|
8
8
|
import { a11yProps, getTokensPropType, selectSystemProps, variantProp, viewProps } from '../utils';
|
|
9
9
|
import { MAX_PERCENT_VALUE, MIN_PERCENT_VALUE } from './constants';
|
|
10
|
+
import ProgressContext from './ProgressContext';
|
|
10
11
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
12
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
12
|
-
const selectBarStyles =
|
|
13
|
+
const selectBarStyles = _ref => {
|
|
13
14
|
let {
|
|
15
|
+
themeTokens,
|
|
16
|
+
calculatedPercentage,
|
|
17
|
+
barPosition,
|
|
18
|
+
layers
|
|
19
|
+
} = _ref;
|
|
20
|
+
const {
|
|
14
21
|
backgroundColor,
|
|
15
22
|
borderRadius,
|
|
16
23
|
outlineWidth,
|
|
17
24
|
outlineColor,
|
|
18
25
|
shadow
|
|
19
|
-
} =
|
|
26
|
+
} = themeTokens;
|
|
20
27
|
return {
|
|
21
28
|
backgroundColor,
|
|
22
29
|
borderRadius,
|
|
@@ -24,7 +31,10 @@ const selectBarStyles = (_ref, calculatedPercentage, barPosition) => {
|
|
|
24
31
|
outlineColor,
|
|
25
32
|
...applyShadowToken(shadow),
|
|
26
33
|
width: `${calculatedPercentage}%`,
|
|
27
|
-
left: `${barPosition}
|
|
34
|
+
left: `${barPosition}%`,
|
|
35
|
+
...(layers ? {
|
|
36
|
+
position: 'absolute'
|
|
37
|
+
} : {})
|
|
28
38
|
};
|
|
29
39
|
};
|
|
30
40
|
|
|
@@ -75,6 +85,9 @@ const ProgressBar = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
75
85
|
},
|
|
76
86
|
...rest
|
|
77
87
|
} = _ref2;
|
|
88
|
+
const {
|
|
89
|
+
layers
|
|
90
|
+
} = React.useContext(ProgressContext);
|
|
78
91
|
const {
|
|
79
92
|
items,
|
|
80
93
|
current
|
|
@@ -107,7 +120,12 @@ const ProgressBar = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
107
120
|
});
|
|
108
121
|
return percentage > MIN_PERCENT_VALUE || items ? /*#__PURE__*/_jsx(View, {
|
|
109
122
|
ref: ref,
|
|
110
|
-
style: [staticStyles.bar, selectBarStyles(
|
|
123
|
+
style: [staticStyles.bar, selectBarStyles({
|
|
124
|
+
themeTokens,
|
|
125
|
+
calculatedPercentage,
|
|
126
|
+
barPosition,
|
|
127
|
+
layers
|
|
128
|
+
})],
|
|
111
129
|
...selectedProps,
|
|
112
130
|
children: children ?? /*#__PURE__*/_jsx(ProgressBarBackground, {
|
|
113
131
|
variant: variant
|
package/lib/esm/SideNav/Item.js
CHANGED
|
@@ -22,9 +22,9 @@ function selectItemStyles(_ref) {
|
|
|
22
22
|
} = _ref;
|
|
23
23
|
return {
|
|
24
24
|
backgroundColor,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
borderBottomColor: borderColor,
|
|
26
|
+
borderBottomWidth: borderWidth,
|
|
27
|
+
borderBottomStyle: borderStyle,
|
|
28
28
|
paddingLeft,
|
|
29
29
|
paddingRight,
|
|
30
30
|
paddingTop,
|
|
@@ -4,6 +4,19 @@ import ItemContent from './ItemContent';
|
|
|
4
4
|
import ExpandCollapse from '../ExpandCollapse';
|
|
5
5
|
import { getTokensPropType, variantProp, componentPropType, selectTokens } from '../utils';
|
|
6
6
|
import { useThemeTokensCallback } from '../ThemeProvider';
|
|
7
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
+
const selectPanelTokens = _ref => {
|
|
9
|
+
let {
|
|
10
|
+
borderWidth,
|
|
11
|
+
borderColor,
|
|
12
|
+
backgroundColor
|
|
13
|
+
} = _ref;
|
|
14
|
+
return {
|
|
15
|
+
contentPanelBackgroundColor: backgroundColor,
|
|
16
|
+
borderBottomWidth: borderWidth,
|
|
17
|
+
borderColor
|
|
18
|
+
};
|
|
19
|
+
};
|
|
7
20
|
|
|
8
21
|
/**
|
|
9
22
|
Expandable content areas for use within `SideNav`.
|
|
@@ -15,8 +28,7 @@ import { useThemeTokensCallback } from '../ThemeProvider';
|
|
|
15
28
|
## Usage Criteria
|
|
16
29
|
- Use `SideNav.ItemsGroup` with large pages that have multiple sections
|
|
17
30
|
*/
|
|
18
|
-
|
|
19
|
-
const ItemsGroup = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
31
|
+
const ItemsGroup = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
20
32
|
let {
|
|
21
33
|
children,
|
|
22
34
|
label,
|
|
@@ -27,7 +39,7 @@ const ItemsGroup = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
27
39
|
tokens,
|
|
28
40
|
itemTokens,
|
|
29
41
|
onToggle
|
|
30
|
-
} =
|
|
42
|
+
} = _ref2;
|
|
31
43
|
// A SideNav control uses the same style and theme as SideNavItem, with a 'parent' variant,
|
|
32
44
|
// plus control-specific tokens from the SideNavItemsGroup theme (e.g. open/close icon, etc).
|
|
33
45
|
const getAppearance = appearance => ({
|
|
@@ -40,28 +52,27 @@ const ItemsGroup = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
40
52
|
type: 'parent'
|
|
41
53
|
});
|
|
42
54
|
const getGroupTokens = useThemeTokensCallback('SideNavItemsGroup', tokens, variant);
|
|
43
|
-
const getPanelTokens = appearance => {
|
|
44
|
-
const {
|
|
45
|
-
panelBorderColor,
|
|
46
|
-
...itemsGroupTokens
|
|
47
|
-
} = getGroupTokens(getAppearance(appearance));
|
|
48
|
-
const groupTokens = {
|
|
49
|
-
...itemsGroupTokens,
|
|
50
|
-
borderWidth: 0,
|
|
51
|
-
marginBottom: 0
|
|
52
|
-
};
|
|
53
|
-
return selectTokens('ExpandCollapsePanel', groupTokens);
|
|
54
|
-
};
|
|
55
55
|
const getItemTokens = useThemeTokensCallback('SideNavItem', itemTokens, variant);
|
|
56
|
-
const
|
|
57
|
-
...
|
|
58
|
-
|
|
59
|
-
...
|
|
56
|
+
const getPanelTokens = appearance => selectTokens('ExpandCollapsePanel', {
|
|
57
|
+
...staticTokens.panel,
|
|
58
|
+
...getGroupTokens(getAppearance(appearance)),
|
|
59
|
+
...selectPanelTokens(getItemTokens(getItemAppearance(appearance)))
|
|
60
|
+
});
|
|
61
|
+
const getControlTokens = appearance => ({
|
|
62
|
+
...selectTokens('ExpandCollapseControl', {
|
|
63
|
+
...getItemTokens(getItemAppearance(appearance)),
|
|
64
|
+
// main style from SideNavItem
|
|
65
|
+
...getGroupTokens(getAppearance(appearance)) // control-specific tokens like icon etc,
|
|
66
|
+
}),
|
|
67
|
+
...staticTokens.control
|
|
60
68
|
});
|
|
61
69
|
const controlContent = controlState => {
|
|
62
70
|
const currentItemTokens = getItemTokens(getItemAppearance(controlState));
|
|
63
71
|
return /*#__PURE__*/_jsx(ItemContent, {
|
|
64
|
-
tokens:
|
|
72
|
+
tokens: {
|
|
73
|
+
...currentItemTokens,
|
|
74
|
+
...staticTokens.content
|
|
75
|
+
},
|
|
65
76
|
children: label
|
|
66
77
|
});
|
|
67
78
|
};
|
|
@@ -77,9 +88,23 @@ const ItemsGroup = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
77
88
|
active: isActive
|
|
78
89
|
} // ExpandCollapse.Panel handles expanded state
|
|
79
90
|
,
|
|
91
|
+
disableMobileScrollBuffer: true,
|
|
80
92
|
children: children
|
|
81
93
|
});
|
|
82
94
|
});
|
|
95
|
+
const staticTokens = {
|
|
96
|
+
panel: {
|
|
97
|
+
borderWidth: 0,
|
|
98
|
+
marginBottom: 0
|
|
99
|
+
},
|
|
100
|
+
control: {
|
|
101
|
+
borderWidth: 0,
|
|
102
|
+
textLine: null
|
|
103
|
+
},
|
|
104
|
+
content: {
|
|
105
|
+
accentWidth: 0
|
|
106
|
+
}
|
|
107
|
+
};
|
|
83
108
|
ItemsGroup.displayName = 'ItemsGroup';
|
|
84
109
|
ItemsGroup.propTypes = {
|
|
85
110
|
/**
|
|
@@ -6,13 +6,28 @@ import ItemsGroup from './ItemsGroup';
|
|
|
6
6
|
import { useThemeTokens } from '../ThemeProvider';
|
|
7
7
|
import { a11yProps, componentPropType, getTokensPropType, selectSystemProps, variantProp, viewProps } from '../utils';
|
|
8
8
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
|
-
|
|
9
|
+
const selectContainerTokens = _ref => {
|
|
10
|
+
let {
|
|
11
|
+
borderWidth,
|
|
12
|
+
borderStyle,
|
|
13
|
+
borderColor
|
|
14
|
+
} = _ref;
|
|
10
15
|
return {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
borderTopWidth: borderWidth,
|
|
17
|
+
borderStyle,
|
|
18
|
+
borderColor
|
|
14
19
|
};
|
|
15
|
-
}
|
|
20
|
+
};
|
|
21
|
+
const selectItemTokens = function () {
|
|
22
|
+
let tokens = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
23
|
+
let isLastItem = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
24
|
+
return {
|
|
25
|
+
...tokens,
|
|
26
|
+
...(isLastItem ? {
|
|
27
|
+
borderWidth: 0
|
|
28
|
+
} : {})
|
|
29
|
+
};
|
|
30
|
+
};
|
|
16
31
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
17
32
|
|
|
18
33
|
/**
|
|
@@ -20,7 +35,7 @@ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, vie
|
|
|
20
35
|
- Use in conjunction with a large amount of educational / informational content
|
|
21
36
|
- Allow the user to navigate between options frequently and efficiently
|
|
22
37
|
*/
|
|
23
|
-
const SideNav = /*#__PURE__*/React.forwardRef((
|
|
38
|
+
const SideNav = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
24
39
|
let {
|
|
25
40
|
children,
|
|
26
41
|
variant = {},
|
|
@@ -29,7 +44,7 @@ const SideNav = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
29
44
|
itemTokens,
|
|
30
45
|
groupTokens,
|
|
31
46
|
...rest
|
|
32
|
-
} =
|
|
47
|
+
} = _ref2;
|
|
33
48
|
const themeTokens = useThemeTokens('SideNav', tokens, variant);
|
|
34
49
|
const [active, setActive] = React.useState({
|
|
35
50
|
groupId: undefined,
|
|
@@ -47,14 +62,15 @@ const SideNav = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
47
62
|
return /*#__PURE__*/_jsx(ExpandCollapse, {
|
|
48
63
|
ref: ref,
|
|
49
64
|
maxOpen: accordion ? 1 : null,
|
|
50
|
-
|
|
65
|
+
tokens: selectContainerTokens(themeTokens),
|
|
51
66
|
...selectProps(rest),
|
|
52
|
-
children:
|
|
67
|
+
children: _ref3 => {
|
|
53
68
|
let {
|
|
54
69
|
openIds,
|
|
55
70
|
onToggle
|
|
56
|
-
} =
|
|
57
|
-
const renderItem = (item, index, groupId)
|
|
71
|
+
} = _ref3;
|
|
72
|
+
const renderItem = function (item, index, groupId) {
|
|
73
|
+
let isLastItem = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
58
74
|
const {
|
|
59
75
|
itemId = `item-${index}`,
|
|
60
76
|
onPress
|
|
@@ -72,7 +88,7 @@ const SideNav = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
72
88
|
...variant,
|
|
73
89
|
type: 'child'
|
|
74
90
|
} : variant,
|
|
75
|
-
tokens: itemTokens,
|
|
91
|
+
tokens: selectItemTokens(itemTokens, isLastItem),
|
|
76
92
|
isActive: isItemActive(itemId, groupId),
|
|
77
93
|
onPress: handlePress
|
|
78
94
|
});
|
|
@@ -96,7 +112,7 @@ const SideNav = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
96
112
|
openGroups: openIds,
|
|
97
113
|
isActive: isGroupActive,
|
|
98
114
|
onToggle: handleToggle
|
|
99
|
-
}, React.Children.map(child.props.children, (item, itemIndex) => renderItem(item, itemIndex, groupId)));
|
|
115
|
+
}, React.Children.map(child.props.children, (item, itemIndex) => renderItem(item, itemIndex, groupId, itemIndex === child.props.children.length - 1)));
|
|
100
116
|
}
|
|
101
117
|
return null;
|
|
102
118
|
});
|
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.20.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.28.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.20.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.28.0",
|
|
88
88
|
"types": "types/index.d.ts"
|
|
89
89
|
}
|
package/src/Card/CardBase.jsx
CHANGED
|
@@ -233,7 +233,13 @@ export const selectStyles = ({
|
|
|
233
233
|
*/
|
|
234
234
|
const CardBase = React.forwardRef(
|
|
235
235
|
({ children, tokens, dataSet, backgroundImage, fullBleedContent, cardState, ...rest }, ref) => {
|
|
236
|
-
const
|
|
236
|
+
const resolvedTokens = typeof tokens === 'function' ? tokens(cardState) : tokens
|
|
237
|
+
const tokensToUse =
|
|
238
|
+
backgroundImage && backgroundImage.src
|
|
239
|
+
? { ...resolvedTokens, gradient: undefined, backgroundGradient: undefined }
|
|
240
|
+
: resolvedTokens
|
|
241
|
+
|
|
242
|
+
const cardStyle = selectStyles(tokensToUse)
|
|
237
243
|
const props = selectProps(rest)
|
|
238
244
|
|
|
239
245
|
let content = children
|
|
@@ -314,7 +320,7 @@ const CardBase = React.forwardRef(
|
|
|
314
320
|
})
|
|
315
321
|
|
|
316
322
|
return (
|
|
317
|
-
<View style={containerStyle} dataSet={dataSet} ref={ref} {...props}>
|
|
323
|
+
<View style={{ ...containerStyle, borderRadius }} dataSet={dataSet} ref={ref} {...props}>
|
|
318
324
|
{content}
|
|
319
325
|
</View>
|
|
320
326
|
)
|
|
@@ -393,7 +399,7 @@ const staticStyles = StyleSheet.create({
|
|
|
393
399
|
contentOverlay: {
|
|
394
400
|
position: 'relative',
|
|
395
401
|
width: '100%',
|
|
396
|
-
|
|
402
|
+
minHeight: '100%',
|
|
397
403
|
zIndex: 2
|
|
398
404
|
},
|
|
399
405
|
containContainer: {
|
|
@@ -50,7 +50,7 @@ function selectIconContainerStyles({ iconGap, iconPaddingTop, iconPosition }) {
|
|
|
50
50
|
const paddingSide = iconPosition === 'right' ? 'paddingLeft' : 'paddingRight'
|
|
51
51
|
return {
|
|
52
52
|
[paddingSide]: iconGap,
|
|
53
|
-
|
|
53
|
+
...(iconPaddingTop && { transform: [{ translateY: iconPaddingTop }] })
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -20,13 +20,14 @@ const [selectProps, selectedSystemPropTypes] = selectSystemProps([
|
|
|
20
20
|
contentfulProps
|
|
21
21
|
])
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
const selectWrapperStyles = ({ borderWidth, borderTopWidth, borderStyle, borderColor }) => ({
|
|
24
|
+
borderStyle,
|
|
25
|
+
borderColor,
|
|
26
|
+
borderTopWidth,
|
|
27
|
+
borderBottomWidth: borderWidth,
|
|
28
|
+
borderBottomStyle: borderStyle,
|
|
29
|
+
borderBottomColor: borderColor
|
|
30
|
+
})
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
33
|
* Flexible base component for lists where some or all items are collapsible headers.
|
|
@@ -55,7 +56,7 @@ const ExpandCollapse = React.forwardRef(
|
|
|
55
56
|
|
|
56
57
|
return (
|
|
57
58
|
<View style={staticStyles.container} ref={ref} {...selectProps(rest)} dataSet={dataSet}>
|
|
58
|
-
<View style={
|
|
59
|
+
<View style={selectWrapperStyles(themeTokens)}>
|
|
59
60
|
{typeof children === 'function'
|
|
60
61
|
? children({ openIds, onToggle, resetValues, setValues, unsetValues, instanceId })
|
|
61
62
|
: children}
|
|
@@ -96,6 +96,7 @@ const ExpandCollapsePanel = React.forwardRef(
|
|
|
96
96
|
controlRef,
|
|
97
97
|
content,
|
|
98
98
|
copy = 'en',
|
|
99
|
+
disableMobileScrollBuffer = false,
|
|
99
100
|
...rest
|
|
100
101
|
},
|
|
101
102
|
ref
|
|
@@ -118,7 +119,10 @@ const ExpandCollapsePanel = React.forwardRef(
|
|
|
118
119
|
|
|
119
120
|
// on mobile devices we require a scroll buffer equal to the font size
|
|
120
121
|
// to avoid triggering scrolling unnecessarily
|
|
121
|
-
const mobileScrollBuffer =
|
|
122
|
+
const mobileScrollBuffer =
|
|
123
|
+
Platform.OS === 'web' || disableMobileScrollBuffer
|
|
124
|
+
? 0
|
|
125
|
+
: selectTextStyles(themeTokens)?.fontSize
|
|
122
126
|
|
|
123
127
|
const handleControlPress = (event) => {
|
|
124
128
|
onToggle?.(panelId, event)
|
|
@@ -287,7 +291,11 @@ ExpandCollapsePanel.propTypes = {
|
|
|
287
291
|
/**
|
|
288
292
|
* A boolean prop to determine if the panel is a content panel or not. If true, the panel will not have a control
|
|
289
293
|
*/
|
|
290
|
-
content: PropTypes.bool
|
|
294
|
+
content: PropTypes.bool,
|
|
295
|
+
/**
|
|
296
|
+
* A boolean prop to disable the extra scroll buffer on mobile devices (only applicable on iOS/Android, ignored on web)
|
|
297
|
+
*/
|
|
298
|
+
disableMobileScrollBuffer: PropTypes.bool
|
|
291
299
|
}
|
|
292
300
|
|
|
293
301
|
export default ExpandCollapsePanel
|