@telus-uds/components-base 3.28.2 → 3.29.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 +16 -1
- package/lib/cjs/Card/CardBase.js +12 -0
- package/lib/cjs/ColourToggle/ColourBubble.js +17 -3
- package/lib/cjs/ColourToggle/ColourToggle.js +8 -2
- package/lib/cjs/ExpandCollapse/Control.js +17 -3
- package/lib/cjs/ExpandCollapse/Panel.js +6 -0
- package/lib/cjs/ExpandCollapseMini/ExpandCollapseMini.js +14 -2
- package/lib/cjs/ExpandCollapseMini/ExpandCollapseMiniControl.js +15 -2
- package/lib/cjs/Link/ChevronLink.js +1 -0
- package/lib/cjs/Link/LinkBase.js +29 -13
- package/lib/cjs/Link/MobileIconTextContent.js +156 -0
- package/lib/cjs/TabBar/TabBar.js +7 -2
- package/lib/esm/Card/CardBase.js +12 -0
- package/lib/esm/ColourToggle/ColourBubble.js +17 -3
- package/lib/esm/ColourToggle/ColourToggle.js +8 -2
- package/lib/esm/ExpandCollapse/Control.js +17 -3
- package/lib/esm/ExpandCollapse/Panel.js +6 -0
- package/lib/esm/ExpandCollapseMini/ExpandCollapseMini.js +14 -2
- package/lib/esm/ExpandCollapseMini/ExpandCollapseMiniControl.js +15 -2
- package/lib/esm/Link/ChevronLink.js +1 -0
- package/lib/esm/Link/LinkBase.js +29 -13
- package/lib/esm/Link/MobileIconTextContent.js +147 -0
- package/lib/esm/TabBar/TabBar.js +7 -2
- package/lib/package.json +1 -1
- package/package.json +1 -1
- package/src/Card/CardBase.jsx +12 -0
- package/src/ColourToggle/ColourBubble.jsx +18 -3
- package/src/ColourToggle/ColourToggle.jsx +7 -2
- package/src/ExpandCollapse/Control.jsx +24 -4
- package/src/ExpandCollapse/Panel.jsx +6 -0
- package/src/ExpandCollapseMini/ExpandCollapseMini.jsx +23 -3
- package/src/ExpandCollapseMini/ExpandCollapseMiniControl.jsx +14 -2
- package/src/Link/ChevronLink.jsx +1 -0
- package/src/Link/LinkBase.jsx +47 -20
- package/src/Link/MobileIconTextContent.jsx +129 -0
- package/src/TabBar/TabBar.jsx +21 -4
|
@@ -15,6 +15,7 @@ const ColourToggle = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
15
15
|
defaultColourId,
|
|
16
16
|
items,
|
|
17
17
|
onChange,
|
|
18
|
+
showTooltips,
|
|
18
19
|
...rest
|
|
19
20
|
} = _ref;
|
|
20
21
|
const [currentColourId, setCurrentColourId] = React.useState(defaultColourId);
|
|
@@ -54,7 +55,8 @@ const ColourToggle = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
54
55
|
isSelected: id === currentColourId,
|
|
55
56
|
colourHexCode: colourHexCode,
|
|
56
57
|
colourName: colourName,
|
|
57
|
-
onPress: handleChangeColour
|
|
58
|
+
onPress: handleChangeColour,
|
|
59
|
+
showTooltip: showTooltips
|
|
58
60
|
}, colourBubbleId);
|
|
59
61
|
})
|
|
60
62
|
})]
|
|
@@ -86,6 +88,10 @@ ColourToggle.propTypes = {
|
|
|
86
88
|
/**
|
|
87
89
|
* If provided, this function is called when the current selection of the color is changed of all currently `items`. Receives two parameters: item object selected and the event
|
|
88
90
|
*/
|
|
89
|
-
onChange: PropTypes.func
|
|
91
|
+
onChange: PropTypes.func,
|
|
92
|
+
/**
|
|
93
|
+
* When true, displays each colour's name as a tooltip on hover (web only).
|
|
94
|
+
*/
|
|
95
|
+
showTooltips: PropTypes.bool
|
|
90
96
|
};
|
|
91
97
|
export default ColourToggle;
|
|
@@ -66,11 +66,15 @@ function selectIconContainerStyles(_ref2) {
|
|
|
66
66
|
}
|
|
67
67
|
function selectTextContainerStyles(_ref3) {
|
|
68
68
|
let {
|
|
69
|
-
textLine
|
|
69
|
+
textLine,
|
|
70
|
+
controlAlign
|
|
70
71
|
} = _ref3;
|
|
71
72
|
return {
|
|
72
73
|
textDecorationLine: textLine,
|
|
73
|
-
flex: 1
|
|
74
|
+
flex: 1,
|
|
75
|
+
...(controlAlign && {
|
|
76
|
+
alignItems: controlAlign
|
|
77
|
+
})
|
|
74
78
|
};
|
|
75
79
|
}
|
|
76
80
|
function selectIconTokens(tokens) {
|
|
@@ -85,6 +89,7 @@ const ExpandCollapseControl = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
|
|
|
85
89
|
isExpanded,
|
|
86
90
|
children,
|
|
87
91
|
tokens,
|
|
92
|
+
controlAlign,
|
|
88
93
|
accessibilityRole = 'button',
|
|
89
94
|
variant,
|
|
90
95
|
...rest
|
|
@@ -135,7 +140,12 @@ const ExpandCollapseControl = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
|
|
|
135
140
|
...selectIconTokens(themeTokens)
|
|
136
141
|
})
|
|
137
142
|
}), /*#__PURE__*/_jsx(View, {
|
|
138
|
-
style: [selectTextContainerStyles(
|
|
143
|
+
style: [selectTextContainerStyles({
|
|
144
|
+
...themeTokens,
|
|
145
|
+
...(controlAlign && {
|
|
146
|
+
controlAlign
|
|
147
|
+
})
|
|
148
|
+
}), staticStyles.bubblePointerEvents],
|
|
139
149
|
children: typeof children === 'function' ? children(getControlState(pressableState)) : children
|
|
140
150
|
})]
|
|
141
151
|
});
|
|
@@ -161,6 +171,10 @@ ExpandCollapseControl.propTypes = {
|
|
|
161
171
|
* Whether the linked ExpandCollapsePanel is opened or closed. Allows themes to set `expanded` styles.
|
|
162
172
|
*/
|
|
163
173
|
isExpanded: PropTypes.bool,
|
|
174
|
+
/**
|
|
175
|
+
* Optional alignment for control content. Overrides token-driven alignment.
|
|
176
|
+
*/
|
|
177
|
+
controlAlign: PropTypes.oneOf(['flex-start', 'center', 'flex-end']),
|
|
164
178
|
/**
|
|
165
179
|
* Function called when the ExpandCollapse is pressed.
|
|
166
180
|
*/
|
|
@@ -97,6 +97,7 @@ const ExpandCollapsePanel = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
97
97
|
onPress,
|
|
98
98
|
control,
|
|
99
99
|
controlTokens,
|
|
100
|
+
controlAlign,
|
|
100
101
|
children,
|
|
101
102
|
tokens,
|
|
102
103
|
variant,
|
|
@@ -166,6 +167,7 @@ const ExpandCollapsePanel = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
166
167
|
...selectedProps,
|
|
167
168
|
isExpanded: isExpanded,
|
|
168
169
|
tokens: controlTokens,
|
|
170
|
+
controlAlign: controlAlign,
|
|
169
171
|
variant: variant,
|
|
170
172
|
onPress: handleControlPress,
|
|
171
173
|
ref: controlRef,
|
|
@@ -265,6 +267,10 @@ ExpandCollapsePanel.propTypes = {
|
|
|
265
267
|
* Optional theme token overrides that may be passed to the ExpandCollapseControl element.
|
|
266
268
|
*/
|
|
267
269
|
controlTokens: getTokensPropType('ExpandCollapseControl'),
|
|
270
|
+
/**
|
|
271
|
+
* Optional alignment for control content.
|
|
272
|
+
*/
|
|
273
|
+
controlAlign: PropTypes.oneOf(['flex-start', 'center', 'flex-end']),
|
|
268
274
|
/**
|
|
269
275
|
* An optional ref to be attached to the control
|
|
270
276
|
*/
|
|
@@ -6,6 +6,11 @@ import { variantProp } from '../utils/props';
|
|
|
6
6
|
import ExpandCollapseMiniControl from './ExpandCollapseMiniControl';
|
|
7
7
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
8
|
const [selectContainerProps, selectedContainerPropTypes] = selectSystemProps([contentfulProps]);
|
|
9
|
+
const alignMap = {
|
|
10
|
+
start: 'flex-start',
|
|
11
|
+
middle: 'center',
|
|
12
|
+
end: 'flex-end'
|
|
13
|
+
};
|
|
9
14
|
const ExpandCollapseMini = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
10
15
|
let {
|
|
11
16
|
children,
|
|
@@ -14,6 +19,7 @@ const ExpandCollapseMini = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
14
19
|
nativeID,
|
|
15
20
|
initialOpen = false,
|
|
16
21
|
dataSet,
|
|
22
|
+
align,
|
|
17
23
|
...rest
|
|
18
24
|
} = _ref;
|
|
19
25
|
const expandCollapeMiniPanelId = useUniqueId('ExpandCollapseMiniPanel');
|
|
@@ -41,12 +47,14 @@ const ExpandCollapseMini = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
41
47
|
borderColor: 'transparent',
|
|
42
48
|
textLine: tokens.textLine ?? 'none',
|
|
43
49
|
backgroundColor: 'transparent'
|
|
44
|
-
}
|
|
50
|
+
},
|
|
51
|
+
controlAlign: align && alignMap[align]
|
|
45
52
|
// TODO refactor
|
|
46
53
|
// eslint-disable-next-line react/no-unstable-nested-components
|
|
47
54
|
,
|
|
48
55
|
control: pressableState => /*#__PURE__*/_jsx(ExpandCollapseMiniControl, {
|
|
49
56
|
pressableState: pressableState,
|
|
57
|
+
align: align,
|
|
50
58
|
...rest
|
|
51
59
|
}),
|
|
52
60
|
controlRef: ref,
|
|
@@ -86,6 +94,10 @@ ExpandCollapseMini.propTypes = {
|
|
|
86
94
|
/**
|
|
87
95
|
* The dataSet prop allows to pass data-* attributes element to the component.
|
|
88
96
|
*/
|
|
89
|
-
dataSet: PropTypes.object
|
|
97
|
+
dataSet: PropTypes.object,
|
|
98
|
+
/**
|
|
99
|
+
* Controls the horizontal alignment of the trigger label and icon within the panel width.
|
|
100
|
+
*/
|
|
101
|
+
align: PropTypes.oneOf(['start', 'middle', 'end'])
|
|
90
102
|
};
|
|
91
103
|
export default ExpandCollapseMini;
|
|
@@ -6,6 +6,11 @@ import { useThemeTokens } from '../ThemeProvider';
|
|
|
6
6
|
import { htmlAttrs, viewProps, selectSystemProps } from '../utils';
|
|
7
7
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
8
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs, viewProps]);
|
|
9
|
+
const alignSelfMap = {
|
|
10
|
+
start: 'flex-start',
|
|
11
|
+
middle: 'center',
|
|
12
|
+
end: 'flex-end'
|
|
13
|
+
};
|
|
9
14
|
|
|
10
15
|
// The ExpandCollapseControl has all the appropriate role, a11y, press handling etc
|
|
11
16
|
// and a more appropriate press area, defer interaction handling to it.
|
|
@@ -24,6 +29,7 @@ const ExpandCollapseMiniControl = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
24
29
|
iconPosition = 'right',
|
|
25
30
|
tokens,
|
|
26
31
|
variant = {},
|
|
32
|
+
align,
|
|
27
33
|
...rest
|
|
28
34
|
} = _ref;
|
|
29
35
|
const {
|
|
@@ -92,7 +98,10 @@ const ExpandCollapseMiniControl = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
92
98
|
...getTokens(linkState),
|
|
93
99
|
iconSize,
|
|
94
100
|
blockFontSize: fontSize,
|
|
95
|
-
blockLineHeight: lineHeight
|
|
101
|
+
blockLineHeight: lineHeight,
|
|
102
|
+
...(align && {
|
|
103
|
+
alignSelf: alignSelfMap[align]
|
|
104
|
+
})
|
|
96
105
|
}),
|
|
97
106
|
ref: ref,
|
|
98
107
|
...presentationOnly,
|
|
@@ -123,6 +132,10 @@ ExpandCollapseMiniControl.propTypes = {
|
|
|
123
132
|
/**
|
|
124
133
|
* Optional variant object to override the default theme tokens
|
|
125
134
|
*/
|
|
126
|
-
variant: PropTypes.object
|
|
135
|
+
variant: PropTypes.object,
|
|
136
|
+
/**
|
|
137
|
+
* Controls the horizontal alignment of the trigger label and icon
|
|
138
|
+
*/
|
|
139
|
+
align: PropTypes.oneOf(['start', 'middle', 'end'])
|
|
127
140
|
};
|
|
128
141
|
export default ExpandCollapseMiniControl;
|
|
@@ -42,6 +42,7 @@ const ChevronLink = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
42
42
|
const getTokens = useThemeTokensCallback('Link', applyChevronTokens, variant);
|
|
43
43
|
return /*#__PURE__*/_jsx(LinkBase, {
|
|
44
44
|
...otherlinkProps,
|
|
45
|
+
useMeasuredMobileIconLayout: true,
|
|
45
46
|
iconPosition: direction,
|
|
46
47
|
tokens: getTokens,
|
|
47
48
|
dataSet: dataSet,
|
package/lib/esm/Link/LinkBase.js
CHANGED
|
@@ -7,6 +7,7 @@ import { a11yProps, clickProps, getTokensPropType, hrefAttrsProp, linkProps, sel
|
|
|
7
7
|
import { resolvePressableTokens } from '../utils/pressability';
|
|
8
8
|
import { withLinkRouter } from '../utils';
|
|
9
9
|
import InlinePressable from './InlinePressable';
|
|
10
|
+
import MobileIconTextContent from './MobileIconTextContent';
|
|
10
11
|
import { applyTextStyles, applyOuterBorder, useTheme } from '../ThemeProvider';
|
|
11
12
|
import { IconText, iconComponentPropTypes } from '../Icon';
|
|
12
13
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
@@ -137,6 +138,7 @@ const LinkBase = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
|
|
|
137
138
|
tokens = {},
|
|
138
139
|
children,
|
|
139
140
|
dataSet,
|
|
141
|
+
useMeasuredMobileIconLayout = false,
|
|
140
142
|
accessibilityRole = 'link',
|
|
141
143
|
...rawRest
|
|
142
144
|
} = _ref6;
|
|
@@ -180,8 +182,8 @@ const LinkBase = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
|
|
|
180
182
|
const themeTokens = resolveLinkTokens(linkState);
|
|
181
183
|
const outerBorderStyles = selectOuterBorderStyles(themeTokens);
|
|
182
184
|
const decorationStyles = selectDecorationStyles(themeTokens);
|
|
183
|
-
const
|
|
184
|
-
return [outerBorderStyles,
|
|
185
|
+
const shouldUseMeasuredMobileContent = Platform.OS !== 'web' && useMeasuredMobileIconLayout;
|
|
186
|
+
return [outerBorderStyles, shouldUseMeasuredMobileContent ? staticStyles.measuredMobileOuterBorderCompensation : null, blockLeftStyle, decorationStyles, hasIcon && staticStyles.rowContainer];
|
|
185
187
|
},
|
|
186
188
|
children: linkState => {
|
|
187
189
|
const themeTokens = resolveLinkTokens(linkState);
|
|
@@ -196,19 +198,32 @@ const LinkBase = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
|
|
|
196
198
|
} = themeTokens;
|
|
197
199
|
const isTextOnlyLink = !IconComponent && !icon && accessibilityRole === 'link';
|
|
198
200
|
const adjustedIconSpace = Platform.OS !== 'web' && isTextOnlyLink ? 0 : iconSpace;
|
|
201
|
+
const shouldUseMeasuredMobileContent = Platform.OS !== 'web' && useMeasuredMobileIconLayout;
|
|
202
|
+
const textBaselineStyle = shouldUseMeasuredMobileContent ? null : staticStyles.baseline;
|
|
203
|
+
const linkTextContent = /*#__PURE__*/_jsx(Text, {
|
|
204
|
+
style: [textStyles, blockTextStyles, textBaselineStyle, staticStyles.bubblePointerEvents],
|
|
205
|
+
children: typeof children === 'function' ? children(linkState) : children
|
|
206
|
+
});
|
|
207
|
+
const sharedIconProps = {
|
|
208
|
+
...iconProps,
|
|
209
|
+
tokens: iconTokens,
|
|
210
|
+
style: staticStyles.bubblePointerEvents
|
|
211
|
+
};
|
|
212
|
+
if (shouldUseMeasuredMobileContent) {
|
|
213
|
+
return /*#__PURE__*/_jsx(MobileIconTextContent, {
|
|
214
|
+
icon: IconComponent,
|
|
215
|
+
iconPosition: iconPosition,
|
|
216
|
+
space: adjustedIconSpace,
|
|
217
|
+
iconProps: sharedIconProps,
|
|
218
|
+
children: linkTextContent
|
|
219
|
+
});
|
|
220
|
+
}
|
|
199
221
|
return /*#__PURE__*/_jsx(IconText, {
|
|
200
222
|
icon: IconComponent,
|
|
201
223
|
iconPosition: iconPosition,
|
|
202
224
|
space: adjustedIconSpace,
|
|
203
|
-
iconProps:
|
|
204
|
-
|
|
205
|
-
tokens: iconTokens,
|
|
206
|
-
style: staticStyles.bubblePointerEvents
|
|
207
|
-
},
|
|
208
|
-
children: /*#__PURE__*/_jsx(Text, {
|
|
209
|
-
style: [textStyles, blockTextStyles, staticStyles.baseline, staticStyles.bubblePointerEvents],
|
|
210
|
-
children: typeof children === 'function' ? children(linkState) : children
|
|
211
|
-
})
|
|
225
|
+
iconProps: sharedIconProps,
|
|
226
|
+
children: linkTextContent
|
|
212
227
|
});
|
|
213
228
|
}
|
|
214
229
|
});
|
|
@@ -266,11 +281,12 @@ const staticStyles = StyleSheet.create({
|
|
|
266
281
|
}
|
|
267
282
|
})
|
|
268
283
|
},
|
|
269
|
-
|
|
284
|
+
measuredMobileOuterBorderCompensation: {
|
|
270
285
|
...(Platform.OS !== 'web' && {
|
|
271
286
|
marginHorizontal: 2,
|
|
287
|
+
marginVertical: 2,
|
|
272
288
|
paddingHorizontal: Platform.OS === 'android' ? 2 : 0,
|
|
273
|
-
|
|
289
|
+
paddingVertical: Platform.OS === 'android' ? 2 : 0
|
|
274
290
|
})
|
|
275
291
|
}
|
|
276
292
|
});
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import Text from "react-native-web/dist/exports/Text";
|
|
4
|
+
import View from "react-native-web/dist/exports/View";
|
|
5
|
+
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
6
|
+
import Icon, { iconComponentPropTypes } from '../Icon/Icon';
|
|
7
|
+
import { spacingProps } from '../utils';
|
|
8
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
|
+
const MobileIconTextContent = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
10
|
+
let {
|
|
11
|
+
space = 0,
|
|
12
|
+
iconPosition = 'left',
|
|
13
|
+
icon: IconComponent,
|
|
14
|
+
iconProps = {},
|
|
15
|
+
children
|
|
16
|
+
} = _ref;
|
|
17
|
+
const [translateY, setTranslateY] = React.useState(0);
|
|
18
|
+
const latestTranslateYRef = React.useRef(0);
|
|
19
|
+
const layoutsRef = React.useRef({
|
|
20
|
+
container: null,
|
|
21
|
+
text: null,
|
|
22
|
+
icon: null
|
|
23
|
+
});
|
|
24
|
+
const applyAlignment = React.useCallback(() => {
|
|
25
|
+
const {
|
|
26
|
+
container,
|
|
27
|
+
text,
|
|
28
|
+
icon
|
|
29
|
+
} = layoutsRef.current;
|
|
30
|
+
if (!container || !icon || !icon.height) return;
|
|
31
|
+
const targetY = text ? text.y + text.height / 2 : container.height / 2;
|
|
32
|
+
const iconY = icon.y + icon.height / 2;
|
|
33
|
+
const nextTranslateY = Math.round((targetY - iconY) * 100) / 100;
|
|
34
|
+
if (!Number.isFinite(nextTranslateY)) return;
|
|
35
|
+
if (Math.abs(nextTranslateY - latestTranslateYRef.current) < 0.5) return;
|
|
36
|
+
latestTranslateYRef.current = nextTranslateY;
|
|
37
|
+
setTranslateY(nextTranslateY);
|
|
38
|
+
}, []);
|
|
39
|
+
const handleContainerLayout = React.useCallback(_ref2 => {
|
|
40
|
+
let {
|
|
41
|
+
nativeEvent: {
|
|
42
|
+
layout
|
|
43
|
+
}
|
|
44
|
+
} = _ref2;
|
|
45
|
+
layoutsRef.current.container = layout;
|
|
46
|
+
applyAlignment();
|
|
47
|
+
}, [applyAlignment]);
|
|
48
|
+
const handleTextLayout = React.useCallback(_ref3 => {
|
|
49
|
+
let {
|
|
50
|
+
nativeEvent: {
|
|
51
|
+
layout
|
|
52
|
+
}
|
|
53
|
+
} = _ref3;
|
|
54
|
+
layoutsRef.current.text = layout;
|
|
55
|
+
applyAlignment();
|
|
56
|
+
}, [applyAlignment]);
|
|
57
|
+
const handleIconLayout = React.useCallback(_ref4 => {
|
|
58
|
+
let {
|
|
59
|
+
nativeEvent: {
|
|
60
|
+
layout
|
|
61
|
+
}
|
|
62
|
+
} = _ref4;
|
|
63
|
+
layoutsRef.current.icon = layout;
|
|
64
|
+
applyAlignment();
|
|
65
|
+
}, [applyAlignment]);
|
|
66
|
+
const iconContent = IconComponent ? /*#__PURE__*/_jsx(Icon, {
|
|
67
|
+
ref: ref,
|
|
68
|
+
icon: IconComponent,
|
|
69
|
+
scalesWithText: true,
|
|
70
|
+
...iconProps
|
|
71
|
+
}) : null;
|
|
72
|
+
const iconWrapper = IconComponent ? /*#__PURE__*/_jsx(View, {
|
|
73
|
+
onLayout: handleIconLayout,
|
|
74
|
+
style: [staticStyles.iconContainer, {
|
|
75
|
+
transform: [{
|
|
76
|
+
translateY
|
|
77
|
+
}]
|
|
78
|
+
}],
|
|
79
|
+
children: iconContent
|
|
80
|
+
}) : null;
|
|
81
|
+
if (iconPosition === 'inline') {
|
|
82
|
+
return /*#__PURE__*/_jsxs(Text, {
|
|
83
|
+
onLayout: handleContainerLayout,
|
|
84
|
+
children: [/*#__PURE__*/_jsx(Text, {
|
|
85
|
+
onLayout: handleTextLayout,
|
|
86
|
+
children: children
|
|
87
|
+
}), ' ', /*#__PURE__*/_jsx(View, {
|
|
88
|
+
style: staticStyles.inlineIconContainer,
|
|
89
|
+
children: iconWrapper
|
|
90
|
+
})]
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
const iconSpaceStyle = iconPosition === 'left' ? {
|
|
94
|
+
marginRight: space
|
|
95
|
+
} : {
|
|
96
|
+
marginLeft: space
|
|
97
|
+
};
|
|
98
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
99
|
+
onLayout: handleContainerLayout,
|
|
100
|
+
style: staticStyles.rowContainer,
|
|
101
|
+
children: [iconPosition === 'left' && /*#__PURE__*/_jsx(View, {
|
|
102
|
+
style: iconSpaceStyle,
|
|
103
|
+
children: iconWrapper
|
|
104
|
+
}), /*#__PURE__*/_jsx(View, {
|
|
105
|
+
onLayout: handleTextLayout,
|
|
106
|
+
children: children
|
|
107
|
+
}), iconPosition === 'right' && /*#__PURE__*/_jsx(View, {
|
|
108
|
+
style: iconSpaceStyle,
|
|
109
|
+
children: iconWrapper
|
|
110
|
+
})]
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
MobileIconTextContent.displayName = 'MobileIconTextContent';
|
|
114
|
+
MobileIconTextContent.propTypes = {
|
|
115
|
+
/**
|
|
116
|
+
* Amount of space between text and icon. Uses the theme spacing scale.
|
|
117
|
+
*/
|
|
118
|
+
space: spacingProps.types.spacingValue,
|
|
119
|
+
/**
|
|
120
|
+
* Position of the icon relative to text.
|
|
121
|
+
*/
|
|
122
|
+
iconPosition: PropTypes.oneOf(['left', 'right', 'inline']),
|
|
123
|
+
/**
|
|
124
|
+
* A valid UDS icon component imported from a UDS palette.
|
|
125
|
+
*/
|
|
126
|
+
icon: PropTypes.elementType,
|
|
127
|
+
/**
|
|
128
|
+
* Props passed to the icon component.
|
|
129
|
+
*/
|
|
130
|
+
iconProps: PropTypes.exact(iconComponentPropTypes),
|
|
131
|
+
/**
|
|
132
|
+
* Content rendered alongside the icon.
|
|
133
|
+
*/
|
|
134
|
+
children: PropTypes.node
|
|
135
|
+
};
|
|
136
|
+
const staticStyles = StyleSheet.create({
|
|
137
|
+
rowContainer: {
|
|
138
|
+
flexDirection: 'row'
|
|
139
|
+
},
|
|
140
|
+
iconContainer: {
|
|
141
|
+
alignSelf: 'flex-start'
|
|
142
|
+
},
|
|
143
|
+
inlineIconContainer: {
|
|
144
|
+
position: 'absolute'
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
export default MobileIconTextContent;
|
package/lib/esm/TabBar/TabBar.js
CHANGED
|
@@ -51,6 +51,7 @@ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, vie
|
|
|
51
51
|
* items={items}
|
|
52
52
|
* initiallySelectedItem="1"
|
|
53
53
|
* onChange={(itemId) => console.log(itemId)}
|
|
54
|
+
* accessibilityLabel="Main navigation"
|
|
54
55
|
* />
|
|
55
56
|
* )
|
|
56
57
|
*/
|
|
@@ -62,6 +63,7 @@ const TabBar = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
62
63
|
onChange,
|
|
63
64
|
variant,
|
|
64
65
|
tokens,
|
|
66
|
+
accessibilityLabel,
|
|
65
67
|
...rest
|
|
66
68
|
} = _ref3;
|
|
67
69
|
const [isSelected, setIsSelected] = React.useState(initiallySelectedItem);
|
|
@@ -76,6 +78,8 @@ const TabBar = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
76
78
|
...selectProps(rest),
|
|
77
79
|
children: /*#__PURE__*/_jsx(View, {
|
|
78
80
|
style: [styles.tabBarItem, selectTabBarItemContainerStyles(themeTokens)],
|
|
81
|
+
accessibilityRole: "tablist",
|
|
82
|
+
accessibilityLabel: accessibilityLabel,
|
|
79
83
|
children: items.map((item, index) => /*#__PURE__*/_jsx(TabBarItem, {
|
|
80
84
|
label: item.label,
|
|
81
85
|
href: item.href,
|
|
@@ -84,7 +88,6 @@ const TabBar = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
84
88
|
iconActive: item.iconActive,
|
|
85
89
|
onPress: () => handlePress(item.id),
|
|
86
90
|
id: `tab-item-${index}`,
|
|
87
|
-
accessibilityRole: "tablist",
|
|
88
91
|
tokens: item.tokens
|
|
89
92
|
}, item.id))
|
|
90
93
|
})
|
|
@@ -109,7 +112,9 @@ TabBar.propTypes = {
|
|
|
109
112
|
/** Variant of TabBar for styling purposes. */
|
|
110
113
|
variant: variantProp.propType,
|
|
111
114
|
/** Tokens for theming and styling. */
|
|
112
|
-
tokens: getTokensPropType('TabBar')
|
|
115
|
+
tokens: getTokensPropType('TabBar'),
|
|
116
|
+
/** Accessible label for the tab bar navigation region, used by screen readers to identify the tablist. */
|
|
117
|
+
accessibilityLabel: PropTypes.string
|
|
113
118
|
};
|
|
114
119
|
const styles = StyleSheet.create({
|
|
115
120
|
tabBar: {
|
package/lib/package.json
CHANGED
package/package.json
CHANGED
package/src/Card/CardBase.jsx
CHANGED
|
@@ -59,9 +59,21 @@ const setBackgroundImage = ({
|
|
|
59
59
|
case 'left-center':
|
|
60
60
|
backgroundPosition = 'left center'
|
|
61
61
|
break
|
|
62
|
+
case 'left-start':
|
|
63
|
+
backgroundPosition = 'left top'
|
|
64
|
+
break
|
|
65
|
+
case 'left-end':
|
|
66
|
+
backgroundPosition = 'left bottom'
|
|
67
|
+
break
|
|
62
68
|
case 'right-center':
|
|
63
69
|
backgroundPosition = 'right center'
|
|
64
70
|
break
|
|
71
|
+
case 'right-start':
|
|
72
|
+
backgroundPosition = 'right top'
|
|
73
|
+
break
|
|
74
|
+
case 'right-end':
|
|
75
|
+
backgroundPosition = 'right bottom'
|
|
76
|
+
break
|
|
65
77
|
default:
|
|
66
78
|
backgroundPosition = 'center center'
|
|
67
79
|
}
|
|
@@ -5,6 +5,7 @@ import { View, Pressable, Platform } from 'react-native'
|
|
|
5
5
|
import { resolvePressableTokens } from '../utils/pressability'
|
|
6
6
|
import { applyShadowToken } from '../ThemeProvider'
|
|
7
7
|
import { getTokensPropType } from '../utils'
|
|
8
|
+
import Tooltip from '../Tooltip'
|
|
8
9
|
|
|
9
10
|
const selectGeneralBubbleTokens = ({
|
|
10
11
|
outerBubbleHeight,
|
|
@@ -52,14 +53,14 @@ const selectBorderBubbleTokens = ({
|
|
|
52
53
|
})
|
|
53
54
|
|
|
54
55
|
const ColourBubble = React.forwardRef(
|
|
55
|
-
({ tokens = {}, id, colourHexCode, colourName, isSelected, onPress }, ref) => {
|
|
56
|
+
({ tokens = {}, id, colourHexCode, colourName, isSelected, onPress, showTooltip }, ref) => {
|
|
56
57
|
const defaultTokens = tokens({ selected: isSelected })
|
|
57
58
|
|
|
58
59
|
const resolveColourBubbleTokens = (pressState) => resolvePressableTokens(tokens, pressState, {})
|
|
59
60
|
|
|
60
61
|
const themeTokens = React.useMemo(() => tokens(), [tokens])
|
|
61
62
|
|
|
62
|
-
|
|
63
|
+
const pressable = (
|
|
63
64
|
<Pressable
|
|
64
65
|
style={(state) => [
|
|
65
66
|
selectGeneralBubbleTokens(resolveColourBubbleTokens(state)),
|
|
@@ -76,6 +77,16 @@ const ColourBubble = React.forwardRef(
|
|
|
76
77
|
<View style={[selectInnerBubbleTokens(themeTokens), { backgroundColor: colourHexCode }]} />
|
|
77
78
|
</Pressable>
|
|
78
79
|
)
|
|
80
|
+
|
|
81
|
+
if (showTooltip) {
|
|
82
|
+
return (
|
|
83
|
+
<Tooltip content={colourName} activateOnHover>
|
|
84
|
+
{pressable}
|
|
85
|
+
</Tooltip>
|
|
86
|
+
)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return pressable
|
|
79
90
|
}
|
|
80
91
|
)
|
|
81
92
|
ColourBubble.displayName = 'ColourBubble'
|
|
@@ -106,7 +117,11 @@ ColourBubble.propTypes = {
|
|
|
106
117
|
* of the color is changed of all currently `items`.
|
|
107
118
|
* Receives two parameters: item object selected and the event
|
|
108
119
|
*/
|
|
109
|
-
onPress: PropTypes.func
|
|
120
|
+
onPress: PropTypes.func,
|
|
121
|
+
/**
|
|
122
|
+
* When true, wraps the bubble in a Tooltip that displays the colourName on hover (web only).
|
|
123
|
+
*/
|
|
124
|
+
showTooltip: PropTypes.bool
|
|
110
125
|
}
|
|
111
126
|
|
|
112
127
|
export default ColourBubble
|
|
@@ -11,7 +11,7 @@ import ColourBubble from './ColourBubble'
|
|
|
11
11
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
|
|
12
12
|
|
|
13
13
|
const ColourToggle = React.forwardRef(
|
|
14
|
-
({ tokens, variant, defaultColourId, items, onChange, ...rest }, ref) => {
|
|
14
|
+
({ tokens, variant, defaultColourId, items, onChange, showTooltips, ...rest }, ref) => {
|
|
15
15
|
const [currentColourId, setCurrentColourId] = React.useState(defaultColourId)
|
|
16
16
|
const getTokens = useThemeTokensCallback('ColourToggle', tokens, variant)
|
|
17
17
|
|
|
@@ -40,6 +40,7 @@ const ColourToggle = React.forwardRef(
|
|
|
40
40
|
colourHexCode={colourHexCode}
|
|
41
41
|
colourName={colourName}
|
|
42
42
|
onPress={handleChangeColour}
|
|
43
|
+
showTooltip={showTooltips}
|
|
43
44
|
/>
|
|
44
45
|
)
|
|
45
46
|
})}
|
|
@@ -77,7 +78,11 @@ ColourToggle.propTypes = {
|
|
|
77
78
|
/**
|
|
78
79
|
* If provided, this function is called when the current selection of the color is changed of all currently `items`. Receives two parameters: item object selected and the event
|
|
79
80
|
*/
|
|
80
|
-
onChange: PropTypes.func
|
|
81
|
+
onChange: PropTypes.func,
|
|
82
|
+
/**
|
|
83
|
+
* When true, displays each colour's name as a tooltip on hover (web only).
|
|
84
|
+
*/
|
|
85
|
+
showTooltips: PropTypes.bool
|
|
81
86
|
}
|
|
82
87
|
|
|
83
88
|
export default ColourToggle
|
|
@@ -54,10 +54,11 @@ function selectIconContainerStyles({ iconGap, iconPaddingTop, iconPosition }) {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
function selectTextContainerStyles({ textLine }) {
|
|
57
|
+
function selectTextContainerStyles({ textLine, controlAlign }) {
|
|
58
58
|
return {
|
|
59
59
|
textDecorationLine: textLine,
|
|
60
|
-
flex: 1
|
|
60
|
+
flex: 1,
|
|
61
|
+
...(controlAlign && { alignItems: controlAlign })
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
64
|
|
|
@@ -70,7 +71,16 @@ function selectIconTokens(tokens) {
|
|
|
70
71
|
|
|
71
72
|
const ExpandCollapseControl = React.forwardRef(
|
|
72
73
|
(
|
|
73
|
-
{
|
|
74
|
+
{
|
|
75
|
+
onPress,
|
|
76
|
+
isExpanded,
|
|
77
|
+
children,
|
|
78
|
+
tokens,
|
|
79
|
+
controlAlign,
|
|
80
|
+
accessibilityRole = 'button',
|
|
81
|
+
variant,
|
|
82
|
+
...rest
|
|
83
|
+
},
|
|
74
84
|
ref
|
|
75
85
|
) => {
|
|
76
86
|
const getTokens = useThemeTokensCallback('ExpandCollapseControl', tokens, variant)
|
|
@@ -110,7 +120,13 @@ const ExpandCollapseControl = React.forwardRef(
|
|
|
110
120
|
</View>
|
|
111
121
|
)}
|
|
112
122
|
<View
|
|
113
|
-
style={[
|
|
123
|
+
style={[
|
|
124
|
+
selectTextContainerStyles({
|
|
125
|
+
...themeTokens,
|
|
126
|
+
...(controlAlign && { controlAlign })
|
|
127
|
+
}),
|
|
128
|
+
staticStyles.bubblePointerEvents
|
|
129
|
+
]}
|
|
114
130
|
>
|
|
115
131
|
{typeof children === 'function'
|
|
116
132
|
? children(getControlState(pressableState))
|
|
@@ -144,6 +160,10 @@ ExpandCollapseControl.propTypes = {
|
|
|
144
160
|
* Whether the linked ExpandCollapsePanel is opened or closed. Allows themes to set `expanded` styles.
|
|
145
161
|
*/
|
|
146
162
|
isExpanded: PropTypes.bool,
|
|
163
|
+
/**
|
|
164
|
+
* Optional alignment for control content. Overrides token-driven alignment.
|
|
165
|
+
*/
|
|
166
|
+
controlAlign: PropTypes.oneOf(['flex-start', 'center', 'flex-end']),
|
|
147
167
|
/**
|
|
148
168
|
* Function called when the ExpandCollapse is pressed.
|
|
149
169
|
*/
|