@telus-uds/components-base 3.28.2 → 3.29.1
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 -1
- package/jest.config.cjs +1 -0
- package/lib/cjs/ActionCard/ActionCard.js +4 -4
- package/lib/cjs/ActivityIndicator/Dots.native.js +1 -2
- package/lib/cjs/ActivityIndicator/Spinner.native.js +1 -2
- package/lib/cjs/Box/Box.js +1 -2
- package/lib/cjs/Button/Button.js +1 -2
- package/lib/cjs/Button/ButtonBase.js +8 -8
- package/lib/cjs/Button/ButtonDropdown.js +1 -2
- package/lib/cjs/Button/ButtonGroup.js +1 -2
- package/lib/cjs/Button/ButtonLink.js +1 -2
- package/lib/cjs/Card/Card.js +1 -2
- package/lib/cjs/Card/CardBase.js +12 -0
- package/lib/cjs/Card/PressableCardBase.js +1 -2
- package/lib/cjs/Card/index.js +1 -2
- package/lib/cjs/CardGroup/CardGroup.js +1 -2
- package/lib/cjs/Carousel/Carousel.js +6 -6
- package/lib/cjs/CheckboxCard/CheckboxCard.js +1 -2
- package/lib/cjs/CheckboxCardGroup/CheckboxCardGroup.js +1 -2
- 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/HorizontalScroll/index.js +1 -2
- package/lib/cjs/Icon/IconText.js +1 -2
- package/lib/cjs/Icon/index.js +1 -2
- package/lib/cjs/InputSupports/InputSupports.js +1 -2
- package/lib/cjs/InputSupports/useInputSupports.js +1 -3
- package/lib/cjs/Link/ChevronLink.js +1 -0
- package/lib/cjs/Link/LinkBase.js +29 -13
- package/lib/cjs/Link/MobileIconTextContent.js +155 -0
- package/lib/cjs/Listbox/Listbox.js +1 -2
- package/lib/cjs/Modal/Modal.js +1 -1
- package/lib/cjs/Pagination/PageButton.js +1 -2
- package/lib/cjs/Pagination/Pagination.js +1 -2
- package/lib/cjs/QuickLinks/QuickLinks.js +7 -0
- package/lib/cjs/Radio/Radio.js +1 -2
- package/lib/cjs/RadioCard/RadioCard.js +1 -2
- package/lib/cjs/RadioCard/RadioCardGroup.js +1 -2
- package/lib/cjs/Shortcuts/Shortcuts.js +1 -2
- package/lib/cjs/SideNav/SideNav.js +1 -2
- package/lib/cjs/StackView/StackWrapBox.js +9 -1
- package/lib/cjs/StackView/StackWrapGap.js +3 -1
- package/lib/cjs/StackView/getStackedContent.js +21 -12
- package/lib/cjs/TabBar/TabBar.js +7 -2
- package/lib/cjs/Tabs/Tabs.js +1 -2
- package/lib/cjs/Tooltip/Tooltip.native.js +2 -2
- package/lib/cjs/index.js +1 -2
- package/lib/cjs/utils/index.js +1 -2
- package/lib/esm/ActionCard/ActionCard.js +4 -4
- package/lib/esm/Button/ButtonBase.js +8 -8
- package/lib/esm/Card/CardBase.js +12 -0
- package/lib/esm/Carousel/Carousel.js +6 -6
- 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/InputSupports/InputSupports.js +1 -2
- package/lib/esm/InputSupports/useInputSupports.js +1 -3
- 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/Modal/Modal.js +1 -1
- package/lib/esm/QuickLinks/QuickLinks.js +7 -0
- package/lib/esm/StackView/StackWrapBox.js +9 -1
- package/lib/esm/StackView/StackWrapGap.js +3 -1
- package/lib/esm/StackView/getStackedContent.js +20 -10
- package/lib/esm/TabBar/TabBar.js +7 -2
- package/lib/esm/Tooltip/Tooltip.native.js +2 -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/InputSupports/InputSupports.jsx +1 -6
- package/src/InputSupports/useInputSupports.js +1 -1
- package/src/Link/ChevronLink.jsx +1 -0
- package/src/Link/LinkBase.jsx +47 -20
- package/src/Link/MobileIconTextContent.jsx +129 -0
- package/src/Modal/Modal.jsx +1 -1
- package/src/QuickLinks/QuickLinks.jsx +8 -0
- package/src/StackView/StackWrapBox.jsx +13 -1
- package/src/StackView/StackWrapGap.jsx +2 -1
- package/src/StackView/getStackedContent.jsx +22 -8
- package/src/TabBar/TabBar.jsx +21 -4
|
@@ -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/Modal/Modal.js
CHANGED
|
@@ -239,7 +239,7 @@ const Modal = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
239
239
|
})]
|
|
240
240
|
})
|
|
241
241
|
}), /*#__PURE__*/_jsx(TouchableWithoutFeedback, {
|
|
242
|
-
onPress: isBackdropClickable
|
|
242
|
+
onPress: isBackdropClickable ? handleClose : undefined,
|
|
243
243
|
children: /*#__PURE__*/_jsx(View, {
|
|
244
244
|
style: [staticStyles.backdrop, selectBackdropStyles(themeTokens)]
|
|
245
245
|
})
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
+
import Platform from "react-native-web/dist/exports/Platform";
|
|
3
4
|
import { useThemeTokens } from '../ThemeProvider';
|
|
4
5
|
import { useViewport } from '../ViewportProvider';
|
|
5
6
|
import { getTokensPropType, variantProp } from '../utils';
|
|
7
|
+
import { tagsToRoles } from '../utils/a11y/semantics';
|
|
6
8
|
import List from '../List';
|
|
7
9
|
import StackWrap from '../StackView/StackWrap';
|
|
8
10
|
import QuickLinksCard from './QuickLinksCard';
|
|
@@ -35,6 +37,10 @@ const QuickLinks = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
35
37
|
} = useThemeTokens('QuickLinks', tokens, variant, {
|
|
36
38
|
viewport
|
|
37
39
|
});
|
|
40
|
+
const itemAccessibilityRole = Platform.select({
|
|
41
|
+
web: ['ul', 'ol'].includes(tag) ? tagsToRoles.li : undefined,
|
|
42
|
+
default: undefined
|
|
43
|
+
});
|
|
38
44
|
const content = list && /*#__PURE__*/_jsx(List, {
|
|
39
45
|
ref: ref,
|
|
40
46
|
tokens: listTokens,
|
|
@@ -49,6 +55,7 @@ const QuickLinks = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
49
55
|
justifyContent: stackJustify
|
|
50
56
|
},
|
|
51
57
|
tag: tag,
|
|
58
|
+
itemAccessibilityRole: itemAccessibilityRole,
|
|
52
59
|
...rest,
|
|
53
60
|
children: children
|
|
54
61
|
});
|
|
@@ -43,6 +43,7 @@ const StackWrapBox = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
43
43
|
variant,
|
|
44
44
|
tag,
|
|
45
45
|
accessibilityRole,
|
|
46
|
+
itemAccessibilityRole,
|
|
46
47
|
...rest
|
|
47
48
|
} = _ref;
|
|
48
49
|
const viewport = useViewport();
|
|
@@ -69,7 +70,8 @@ const StackWrapBox = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
69
70
|
const content = getStackedContent(children, {
|
|
70
71
|
direction,
|
|
71
72
|
space: 0,
|
|
72
|
-
box: boxProps
|
|
73
|
+
box: boxProps,
|
|
74
|
+
itemAccessibilityRole
|
|
73
75
|
});
|
|
74
76
|
return /*#__PURE__*/_jsx(View, {
|
|
75
77
|
ref: ref,
|
|
@@ -105,6 +107,12 @@ StackWrapBox.propTypes = {
|
|
|
105
107
|
* is not defined, the accessibilityRole will default to "heading".
|
|
106
108
|
*/
|
|
107
109
|
tag: PropTypes.oneOf(layoutTags),
|
|
110
|
+
/**
|
|
111
|
+
* Optional accessibility role to apply to each item in the stack.
|
|
112
|
+
* On web, items are wrapped (or cloned) with this role, enabling correct list semantics
|
|
113
|
+
* when the container tag is "ul" or "ol".
|
|
114
|
+
*/
|
|
115
|
+
itemAccessibilityRole: PropTypes.string,
|
|
108
116
|
/**
|
|
109
117
|
* A StackWrap may take any children, but will have no effect if it is only passed one child or is passed children
|
|
110
118
|
* wrapped in a component. If necessary, children may be wrapped in one React Fragment.
|
|
@@ -28,6 +28,7 @@ const StackWrapGap = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
28
28
|
children,
|
|
29
29
|
tag,
|
|
30
30
|
accessibilityRole,
|
|
31
|
+
itemAccessibilityRole,
|
|
31
32
|
...rest
|
|
32
33
|
} = _ref;
|
|
33
34
|
const viewport = useViewport();
|
|
@@ -47,7 +48,8 @@ const StackWrapGap = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
47
48
|
};
|
|
48
49
|
const content = getStackedContent(children, {
|
|
49
50
|
direction,
|
|
50
|
-
space: 0
|
|
51
|
+
space: 0,
|
|
52
|
+
itemAccessibilityRole
|
|
51
53
|
});
|
|
52
54
|
return /*#__PURE__*/_jsx(View, {
|
|
53
55
|
ref: ref,
|
|
@@ -36,7 +36,8 @@ const getStackedContent = (children, _ref) => {
|
|
|
36
36
|
space,
|
|
37
37
|
direction = 'column',
|
|
38
38
|
box,
|
|
39
|
-
preserveFragments = false
|
|
39
|
+
preserveFragments = false,
|
|
40
|
+
itemAccessibilityRole
|
|
40
41
|
} = _ref;
|
|
41
42
|
const boxProps = box && typeof box === 'object' ? box : {
|
|
42
43
|
space
|
|
@@ -48,15 +49,24 @@ const getStackedContent = (children, _ref) => {
|
|
|
48
49
|
const validChildren = React.Children.toArray(topLevelChildren).filter(Boolean);
|
|
49
50
|
const content = validChildren.reduce((newChildren, child, index) => {
|
|
50
51
|
const boxID = `Stack-Box-${index}`;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
let item;
|
|
53
|
+
if (box) {
|
|
54
|
+
// If wrapped in Box, that Box needs a key.
|
|
55
|
+
// If possible, use an existing content key; use an index-based key only if necessary.
|
|
56
|
+
item = /*#__PURE__*/_createElement(Box, {
|
|
57
|
+
...boxProps,
|
|
58
|
+
accessibilityRole: itemAccessibilityRole,
|
|
59
|
+
key: child.key || boxID,
|
|
60
|
+
testID: boxID
|
|
61
|
+
}, child);
|
|
62
|
+
} else if (itemAccessibilityRole) {
|
|
63
|
+
item = /*#__PURE__*/React.cloneElement(child, {
|
|
64
|
+
accessibilityRole: itemAccessibilityRole,
|
|
65
|
+
key: child.key || boxID
|
|
66
|
+
});
|
|
67
|
+
} else {
|
|
68
|
+
item = child;
|
|
69
|
+
}
|
|
60
70
|
if (!index || !space && !divider) return [...newChildren, item];
|
|
61
71
|
const testID = `Stack-${divider ? 'Divider' : 'Spacer'}-${index}`;
|
|
62
72
|
const commonProps = {
|
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: {
|
|
@@ -206,7 +206,7 @@ const Tooltip = /*#__PURE__*/React.forwardRef((_ref7, ref) => {
|
|
|
206
206
|
focus: focused
|
|
207
207
|
};
|
|
208
208
|
};
|
|
209
|
-
const onTooltipLayout =
|
|
209
|
+
const onTooltipLayout = _ref0 => {
|
|
210
210
|
let {
|
|
211
211
|
nativeEvent: {
|
|
212
212
|
layout: {
|
|
@@ -214,7 +214,7 @@ const Tooltip = /*#__PURE__*/React.forwardRef((_ref7, ref) => {
|
|
|
214
214
|
height
|
|
215
215
|
}
|
|
216
216
|
}
|
|
217
|
-
} =
|
|
217
|
+
} = _ref0;
|
|
218
218
|
if (tooltipDimensions === null || tooltipDimensions.width !== width || tooltipDimensions.height !== height) {
|
|
219
219
|
setTooltipDimensions({
|
|
220
220
|
width: Platform.select({
|
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
|
*/
|
|
@@ -90,6 +90,7 @@ const ExpandCollapsePanel = React.forwardRef(
|
|
|
90
90
|
onPress,
|
|
91
91
|
control,
|
|
92
92
|
controlTokens,
|
|
93
|
+
controlAlign,
|
|
93
94
|
children,
|
|
94
95
|
tokens,
|
|
95
96
|
variant,
|
|
@@ -174,6 +175,7 @@ const ExpandCollapsePanel = React.forwardRef(
|
|
|
174
175
|
{...selectedProps}
|
|
175
176
|
isExpanded={isExpanded}
|
|
176
177
|
tokens={controlTokens}
|
|
178
|
+
controlAlign={controlAlign}
|
|
177
179
|
variant={variant}
|
|
178
180
|
onPress={handleControlPress}
|
|
179
181
|
ref={controlRef}
|
|
@@ -284,6 +286,10 @@ ExpandCollapsePanel.propTypes = {
|
|
|
284
286
|
* Optional theme token overrides that may be passed to the ExpandCollapseControl element.
|
|
285
287
|
*/
|
|
286
288
|
controlTokens: getTokensPropType('ExpandCollapseControl'),
|
|
289
|
+
/**
|
|
290
|
+
* Optional alignment for control content.
|
|
291
|
+
*/
|
|
292
|
+
controlAlign: PropTypes.oneOf(['flex-start', 'center', 'flex-end']),
|
|
287
293
|
/**
|
|
288
294
|
* An optional ref to be attached to the control
|
|
289
295
|
*/
|
|
@@ -7,9 +7,24 @@ import ExpandCollapseMiniControl from './ExpandCollapseMiniControl'
|
|
|
7
7
|
|
|
8
8
|
const [selectContainerProps, selectedContainerPropTypes] = selectSystemProps([contentfulProps])
|
|
9
9
|
|
|
10
|
+
const alignMap = {
|
|
11
|
+
start: 'flex-start',
|
|
12
|
+
middle: 'center',
|
|
13
|
+
end: 'flex-end'
|
|
14
|
+
}
|
|
15
|
+
|
|
10
16
|
const ExpandCollapseMini = React.forwardRef(
|
|
11
17
|
(
|
|
12
|
-
{
|
|
18
|
+
{
|
|
19
|
+
children,
|
|
20
|
+
onToggle = () => {},
|
|
21
|
+
tokens = {},
|
|
22
|
+
nativeID,
|
|
23
|
+
initialOpen = false,
|
|
24
|
+
dataSet,
|
|
25
|
+
align,
|
|
26
|
+
...rest
|
|
27
|
+
},
|
|
13
28
|
ref
|
|
14
29
|
) => {
|
|
15
30
|
const expandCollapeMiniPanelId = useUniqueId('ExpandCollapseMiniPanel')
|
|
@@ -40,10 +55,11 @@ const ExpandCollapseMini = React.forwardRef(
|
|
|
40
55
|
textLine: tokens.textLine ?? 'none',
|
|
41
56
|
backgroundColor: 'transparent'
|
|
42
57
|
}}
|
|
58
|
+
controlAlign={align && alignMap[align]}
|
|
43
59
|
// TODO refactor
|
|
44
60
|
// eslint-disable-next-line react/no-unstable-nested-components
|
|
45
61
|
control={(pressableState) => (
|
|
46
|
-
<ExpandCollapseMiniControl pressableState={pressableState} {...rest} />
|
|
62
|
+
<ExpandCollapseMiniControl pressableState={pressableState} align={align} {...rest} />
|
|
47
63
|
)}
|
|
48
64
|
controlRef={ref}
|
|
49
65
|
nativeID={nativeID}
|
|
@@ -87,7 +103,11 @@ ExpandCollapseMini.propTypes = {
|
|
|
87
103
|
/**
|
|
88
104
|
* The dataSet prop allows to pass data-* attributes element to the component.
|
|
89
105
|
*/
|
|
90
|
-
dataSet: PropTypes.object
|
|
106
|
+
dataSet: PropTypes.object,
|
|
107
|
+
/**
|
|
108
|
+
* Controls the horizontal alignment of the trigger label and icon within the panel width.
|
|
109
|
+
*/
|
|
110
|
+
align: PropTypes.oneOf(['start', 'middle', 'end'])
|
|
91
111
|
}
|
|
92
112
|
|
|
93
113
|
export default ExpandCollapseMini
|
|
@@ -7,6 +7,12 @@ import { htmlAttrs, viewProps, selectSystemProps } from '../utils'
|
|
|
7
7
|
|
|
8
8
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs, viewProps])
|
|
9
9
|
|
|
10
|
+
const alignSelfMap = {
|
|
11
|
+
start: 'flex-start',
|
|
12
|
+
middle: 'center',
|
|
13
|
+
end: 'flex-end'
|
|
14
|
+
}
|
|
15
|
+
|
|
10
16
|
// The ExpandCollapseControl has all the appropriate role, a11y, press handling etc
|
|
11
17
|
// and a more appropriate press area, defer interaction handling to it.
|
|
12
18
|
const presentationOnly = {
|
|
@@ -24,6 +30,7 @@ const ExpandCollapseMiniControl = React.forwardRef(
|
|
|
24
30
|
iconPosition = 'right',
|
|
25
31
|
tokens,
|
|
26
32
|
variant = {},
|
|
33
|
+
align,
|
|
27
34
|
...rest
|
|
28
35
|
},
|
|
29
36
|
ref
|
|
@@ -96,7 +103,8 @@ const ExpandCollapseMiniControl = React.forwardRef(
|
|
|
96
103
|
...getTokens(linkState),
|
|
97
104
|
iconSize,
|
|
98
105
|
blockFontSize: fontSize,
|
|
99
|
-
blockLineHeight: lineHeight
|
|
106
|
+
blockLineHeight: lineHeight,
|
|
107
|
+
...(align && { alignSelf: alignSelfMap[align] })
|
|
100
108
|
})}
|
|
101
109
|
ref={ref}
|
|
102
110
|
{...presentationOnly}
|
|
@@ -132,7 +140,11 @@ ExpandCollapseMiniControl.propTypes = {
|
|
|
132
140
|
/**
|
|
133
141
|
* Optional variant object to override the default theme tokens
|
|
134
142
|
*/
|
|
135
|
-
variant: PropTypes.object
|
|
143
|
+
variant: PropTypes.object,
|
|
144
|
+
/**
|
|
145
|
+
* Controls the horizontal alignment of the trigger label and icon
|
|
146
|
+
*/
|
|
147
|
+
align: PropTypes.oneOf(['start', 'middle', 'end'])
|
|
136
148
|
}
|
|
137
149
|
|
|
138
150
|
export default ExpandCollapseMiniControl
|
|
@@ -66,12 +66,7 @@ const InputSupports = React.forwardRef(
|
|
|
66
66
|
/>
|
|
67
67
|
)}
|
|
68
68
|
{typeof children === 'function'
|
|
69
|
-
? children({
|
|
70
|
-
inputId,
|
|
71
|
-
...a11yProps,
|
|
72
|
-
validation: feedbackValidation,
|
|
73
|
-
accessibilityDescribedBy: feedbackId
|
|
74
|
-
})
|
|
69
|
+
? children({ inputId, ...a11yProps, validation: feedbackValidation })
|
|
75
70
|
: children}
|
|
76
71
|
{feedback || maxCharsReachedErrorMessage ? (
|
|
77
72
|
<Feedback
|
|
@@ -31,8 +31,8 @@ const useInputSupports = ({
|
|
|
31
31
|
: undefined
|
|
32
32
|
]), // native only -> replaced with describedBy on web
|
|
33
33
|
accessibilityDescribedBy: joinDefined([
|
|
34
|
-
!hasValidationError && feedback && feedbackId, // feedback receives a11yRole=alert on error, so there's no need to include it here
|
|
35
34
|
hint && hintId,
|
|
35
|
+
(feedback && feedbackId) || undefined,
|
|
36
36
|
charactersCount
|
|
37
37
|
? getCopy('charactersRemaining').replace(/%\{charCount\}/g, charactersCount)
|
|
38
38
|
: undefined
|