@telus-uds/components-base 3.28.1 → 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 +25 -1
- package/lib/cjs/Autocomplete/Autocomplete.js +86 -32
- package/lib/cjs/Autocomplete/constants.js +2 -1
- package/lib/cjs/Card/CardBase.js +12 -0
- package/lib/cjs/Carousel/Carousel.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/Link/ChevronLink.js +1 -0
- package/lib/cjs/Link/LinkBase.js +29 -13
- package/lib/cjs/Link/MobileIconTextContent.js +156 -0
- package/lib/cjs/Listbox/ListboxOverlay.js +7 -1
- package/lib/cjs/Listbox/PressableItem.js +2 -2
- package/lib/cjs/TabBar/TabBar.js +7 -2
- package/lib/cjs/TextInput/TextInputBase.js +2 -2
- package/lib/esm/Autocomplete/Autocomplete.js +87 -33
- package/lib/esm/Autocomplete/constants.js +1 -0
- package/lib/esm/Card/CardBase.js +12 -0
- package/lib/esm/Carousel/Carousel.js +1 -2
- 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/Listbox/ListboxOverlay.js +7 -1
- package/lib/esm/Listbox/PressableItem.js +3 -3
- package/lib/esm/TabBar/TabBar.js +7 -2
- package/lib/esm/TextInput/TextInputBase.js +2 -2
- package/lib/package.json +1 -1
- package/package.json +1 -1
- package/src/Autocomplete/Autocomplete.jsx +142 -77
- package/src/Autocomplete/constants.js +1 -0
- package/src/Card/CardBase.jsx +12 -0
- package/src/Carousel/Carousel.jsx +1 -2
- 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/Listbox/ListboxOverlay.jsx +9 -1
- package/src/Listbox/PressableItem.jsx +1 -1
- package/src/TabBar/TabBar.jsx +21 -4
- package/src/TextInput/TextInputBase.jsx +2 -2
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
9
|
+
var _Text = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Text"));
|
|
10
|
+
var _View = _interopRequireDefault(require("react-native-web/dist/cjs/exports/View"));
|
|
11
|
+
var _StyleSheet = _interopRequireDefault(require("react-native-web/dist/cjs/exports/StyleSheet"));
|
|
12
|
+
var _Icon = _interopRequireWildcard(require("../Icon/Icon"));
|
|
13
|
+
var _utils = require("../utils");
|
|
14
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
15
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
16
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
17
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
18
|
+
const MobileIconTextContent = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
|
|
19
|
+
let {
|
|
20
|
+
space = 0,
|
|
21
|
+
iconPosition = 'left',
|
|
22
|
+
icon: IconComponent,
|
|
23
|
+
iconProps = {},
|
|
24
|
+
children
|
|
25
|
+
} = _ref;
|
|
26
|
+
const [translateY, setTranslateY] = _react.default.useState(0);
|
|
27
|
+
const latestTranslateYRef = _react.default.useRef(0);
|
|
28
|
+
const layoutsRef = _react.default.useRef({
|
|
29
|
+
container: null,
|
|
30
|
+
text: null,
|
|
31
|
+
icon: null
|
|
32
|
+
});
|
|
33
|
+
const applyAlignment = _react.default.useCallback(() => {
|
|
34
|
+
const {
|
|
35
|
+
container,
|
|
36
|
+
text,
|
|
37
|
+
icon
|
|
38
|
+
} = layoutsRef.current;
|
|
39
|
+
if (!container || !icon || !icon.height) return;
|
|
40
|
+
const targetY = text ? text.y + text.height / 2 : container.height / 2;
|
|
41
|
+
const iconY = icon.y + icon.height / 2;
|
|
42
|
+
const nextTranslateY = Math.round((targetY - iconY) * 100) / 100;
|
|
43
|
+
if (!Number.isFinite(nextTranslateY)) return;
|
|
44
|
+
if (Math.abs(nextTranslateY - latestTranslateYRef.current) < 0.5) return;
|
|
45
|
+
latestTranslateYRef.current = nextTranslateY;
|
|
46
|
+
setTranslateY(nextTranslateY);
|
|
47
|
+
}, []);
|
|
48
|
+
const handleContainerLayout = _react.default.useCallback(_ref2 => {
|
|
49
|
+
let {
|
|
50
|
+
nativeEvent: {
|
|
51
|
+
layout
|
|
52
|
+
}
|
|
53
|
+
} = _ref2;
|
|
54
|
+
layoutsRef.current.container = layout;
|
|
55
|
+
applyAlignment();
|
|
56
|
+
}, [applyAlignment]);
|
|
57
|
+
const handleTextLayout = _react.default.useCallback(_ref3 => {
|
|
58
|
+
let {
|
|
59
|
+
nativeEvent: {
|
|
60
|
+
layout
|
|
61
|
+
}
|
|
62
|
+
} = _ref3;
|
|
63
|
+
layoutsRef.current.text = layout;
|
|
64
|
+
applyAlignment();
|
|
65
|
+
}, [applyAlignment]);
|
|
66
|
+
const handleIconLayout = _react.default.useCallback(_ref4 => {
|
|
67
|
+
let {
|
|
68
|
+
nativeEvent: {
|
|
69
|
+
layout
|
|
70
|
+
}
|
|
71
|
+
} = _ref4;
|
|
72
|
+
layoutsRef.current.icon = layout;
|
|
73
|
+
applyAlignment();
|
|
74
|
+
}, [applyAlignment]);
|
|
75
|
+
const iconContent = IconComponent ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
|
|
76
|
+
ref: ref,
|
|
77
|
+
icon: IconComponent,
|
|
78
|
+
scalesWithText: true,
|
|
79
|
+
...iconProps
|
|
80
|
+
}) : null;
|
|
81
|
+
const iconWrapper = IconComponent ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
|
|
82
|
+
onLayout: handleIconLayout,
|
|
83
|
+
style: [staticStyles.iconContainer, {
|
|
84
|
+
transform: [{
|
|
85
|
+
translateY
|
|
86
|
+
}]
|
|
87
|
+
}],
|
|
88
|
+
children: iconContent
|
|
89
|
+
}) : null;
|
|
90
|
+
if (iconPosition === 'inline') {
|
|
91
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Text.default, {
|
|
92
|
+
onLayout: handleContainerLayout,
|
|
93
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Text.default, {
|
|
94
|
+
onLayout: handleTextLayout,
|
|
95
|
+
children: children
|
|
96
|
+
}), ' ', /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
|
|
97
|
+
style: staticStyles.inlineIconContainer,
|
|
98
|
+
children: iconWrapper
|
|
99
|
+
})]
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
const iconSpaceStyle = iconPosition === 'left' ? {
|
|
103
|
+
marginRight: space
|
|
104
|
+
} : {
|
|
105
|
+
marginLeft: space
|
|
106
|
+
};
|
|
107
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
|
|
108
|
+
onLayout: handleContainerLayout,
|
|
109
|
+
style: staticStyles.rowContainer,
|
|
110
|
+
children: [iconPosition === 'left' && /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
|
|
111
|
+
style: iconSpaceStyle,
|
|
112
|
+
children: iconWrapper
|
|
113
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
|
|
114
|
+
onLayout: handleTextLayout,
|
|
115
|
+
children: children
|
|
116
|
+
}), iconPosition === 'right' && /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
|
|
117
|
+
style: iconSpaceStyle,
|
|
118
|
+
children: iconWrapper
|
|
119
|
+
})]
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
MobileIconTextContent.displayName = 'MobileIconTextContent';
|
|
123
|
+
MobileIconTextContent.propTypes = {
|
|
124
|
+
/**
|
|
125
|
+
* Amount of space between text and icon. Uses the theme spacing scale.
|
|
126
|
+
*/
|
|
127
|
+
space: _utils.spacingProps.types.spacingValue,
|
|
128
|
+
/**
|
|
129
|
+
* Position of the icon relative to text.
|
|
130
|
+
*/
|
|
131
|
+
iconPosition: _propTypes.default.oneOf(['left', 'right', 'inline']),
|
|
132
|
+
/**
|
|
133
|
+
* A valid UDS icon component imported from a UDS palette.
|
|
134
|
+
*/
|
|
135
|
+
icon: _propTypes.default.elementType,
|
|
136
|
+
/**
|
|
137
|
+
* Props passed to the icon component.
|
|
138
|
+
*/
|
|
139
|
+
iconProps: _propTypes.default.exact(_Icon.iconComponentPropTypes),
|
|
140
|
+
/**
|
|
141
|
+
* Content rendered alongside the icon.
|
|
142
|
+
*/
|
|
143
|
+
children: _propTypes.default.node
|
|
144
|
+
};
|
|
145
|
+
const staticStyles = _StyleSheet.default.create({
|
|
146
|
+
rowContainer: {
|
|
147
|
+
flexDirection: 'row'
|
|
148
|
+
},
|
|
149
|
+
iconContainer: {
|
|
150
|
+
alignSelf: 'flex-start'
|
|
151
|
+
},
|
|
152
|
+
inlineIconContainer: {
|
|
153
|
+
position: 'absolute'
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
var _default = exports.default = MobileIconTextContent;
|
|
@@ -35,6 +35,7 @@ const DropdownOverlay = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
|
|
|
35
35
|
isReady = false,
|
|
36
36
|
overlaidPosition,
|
|
37
37
|
maxWidth,
|
|
38
|
+
maxHeight,
|
|
38
39
|
minWidth,
|
|
39
40
|
onLayout,
|
|
40
41
|
tokens,
|
|
@@ -50,12 +51,16 @@ const DropdownOverlay = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
|
|
|
50
51
|
maxWidth,
|
|
51
52
|
minWidth
|
|
52
53
|
}, staticStyles.positioner, !isReady && staticStyles.hidden],
|
|
54
|
+
onMouseDown: e => {
|
|
55
|
+
e.preventDefault();
|
|
56
|
+
},
|
|
53
57
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Card.default, {
|
|
54
58
|
tokens: {
|
|
55
59
|
shadow: systemTokens.shadow,
|
|
56
60
|
borderRadius: systemTokens.borderRadius,
|
|
57
61
|
...(_Platform.default.OS === 'web' && {
|
|
58
|
-
|
|
62
|
+
maxHeight,
|
|
63
|
+
overflowY: 'auto'
|
|
59
64
|
}),
|
|
60
65
|
paddingBottom: paddingVertical,
|
|
61
66
|
paddingTop: paddingVertical,
|
|
@@ -85,6 +90,7 @@ DropdownOverlay.propTypes = {
|
|
|
85
90
|
width: _propTypes.default.number
|
|
86
91
|
}),
|
|
87
92
|
maxWidth: _propTypes.default.number,
|
|
93
|
+
maxHeight: _propTypes.default.number,
|
|
88
94
|
minWidth: _propTypes.default.number,
|
|
89
95
|
onLayout: _propTypes.default.func,
|
|
90
96
|
tokens: _propTypes.default.object,
|
|
@@ -129,9 +129,9 @@ const PressableItem = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
|
|
|
129
129
|
onPress(event);
|
|
130
130
|
},
|
|
131
131
|
children: pressableState => {
|
|
132
|
-
return /*#__PURE__*/(0, _jsxRuntime.
|
|
132
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Text.default, {
|
|
133
133
|
style: selectTextStyles(resolveButtonTokens(pressableState)),
|
|
134
|
-
children:
|
|
134
|
+
children: children
|
|
135
135
|
});
|
|
136
136
|
}
|
|
137
137
|
});
|
package/lib/cjs/TabBar/TabBar.js
CHANGED
|
@@ -58,6 +58,7 @@ const [selectProps, selectedSystemPropTypes] = (0, _utils.selectSystemProps)([_u
|
|
|
58
58
|
* items={items}
|
|
59
59
|
* initiallySelectedItem="1"
|
|
60
60
|
* onChange={(itemId) => console.log(itemId)}
|
|
61
|
+
* accessibilityLabel="Main navigation"
|
|
61
62
|
* />
|
|
62
63
|
* )
|
|
63
64
|
*/
|
|
@@ -69,6 +70,7 @@ const TabBar = /*#__PURE__*/_react.default.forwardRef((_ref3, ref) => {
|
|
|
69
70
|
onChange,
|
|
70
71
|
variant,
|
|
71
72
|
tokens,
|
|
73
|
+
accessibilityLabel,
|
|
72
74
|
...rest
|
|
73
75
|
} = _ref3;
|
|
74
76
|
const [isSelected, setIsSelected] = _react.default.useState(initiallySelectedItem);
|
|
@@ -83,6 +85,8 @@ const TabBar = /*#__PURE__*/_react.default.forwardRef((_ref3, ref) => {
|
|
|
83
85
|
...selectProps(rest),
|
|
84
86
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
|
|
85
87
|
style: [styles.tabBarItem, selectTabBarItemContainerStyles(themeTokens)],
|
|
88
|
+
accessibilityRole: "tablist",
|
|
89
|
+
accessibilityLabel: accessibilityLabel,
|
|
86
90
|
children: items.map((item, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_TabBarItem.default, {
|
|
87
91
|
label: item.label,
|
|
88
92
|
href: item.href,
|
|
@@ -91,7 +95,6 @@ const TabBar = /*#__PURE__*/_react.default.forwardRef((_ref3, ref) => {
|
|
|
91
95
|
iconActive: item.iconActive,
|
|
92
96
|
onPress: () => handlePress(item.id),
|
|
93
97
|
id: `tab-item-${index}`,
|
|
94
|
-
accessibilityRole: "tablist",
|
|
95
98
|
tokens: item.tokens
|
|
96
99
|
}, item.id))
|
|
97
100
|
})
|
|
@@ -116,7 +119,9 @@ TabBar.propTypes = {
|
|
|
116
119
|
/** Variant of TabBar for styling purposes. */
|
|
117
120
|
variant: _utils.variantProp.propType,
|
|
118
121
|
/** Tokens for theming and styling. */
|
|
119
|
-
tokens: (0, _utils.getTokensPropType)('TabBar')
|
|
122
|
+
tokens: (0, _utils.getTokensPropType)('TabBar'),
|
|
123
|
+
/** Accessible label for the tab bar navigation region, used by screen readers to identify the tablist. */
|
|
124
|
+
accessibilityLabel: _propTypes.default.string
|
|
120
125
|
};
|
|
121
126
|
const styles = _StyleSheet.default.create({
|
|
122
127
|
tabBar: {
|
|
@@ -278,8 +278,8 @@ const TextInputBase = /*#__PURE__*/_react.default.forwardRef((_ref8, ref) => {
|
|
|
278
278
|
}
|
|
279
279
|
}, [element, pattern]);
|
|
280
280
|
const handleChangeText = event => {
|
|
281
|
-
const text = event.nativeEvent?.text
|
|
282
|
-
let filteredText = isNumeric ? text?.replace(/[^\d]/g, '') : text;
|
|
281
|
+
const text = event.nativeEvent?.text ?? event.target?.value;
|
|
282
|
+
let filteredText = isNumeric ? text?.replace(/[^\d]/g, '') || undefined : text;
|
|
283
283
|
if (type === 'card' && filteredText) {
|
|
284
284
|
const formattedValue = filteredText.replace(/[^a-zA-Z0-9]/g, '');
|
|
285
285
|
const regex = new RegExp(`([a-zA-Z0-9]{4})(?=[a-zA-Z0-9])`, 'g');
|
|
@@ -14,7 +14,7 @@ import { TextInput } from '../TextInput';
|
|
|
14
14
|
import InputSupports from '../InputSupports';
|
|
15
15
|
import Loading from './Loading';
|
|
16
16
|
import Suggestions from './Suggestions';
|
|
17
|
-
import { DEFAULT_MAX_SUGGESTIONS, DEFAULT_MIN_TO_SUGGESTION, INPUT_LEFT_PADDING, MIN_LISTBOX_WIDTH } from './constants';
|
|
17
|
+
import { DEFAULT_MAX_SUGGESTIONS, DEFAULT_MIN_TO_SUGGESTION, DEFAULT_MAX_DROPDOWN_HEIGHT, INPUT_LEFT_PADDING, MIN_LISTBOX_WIDTH } from './constants';
|
|
18
18
|
import dictionary from './dictionary';
|
|
19
19
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
20
20
|
const staticStyles = StyleSheet.create({
|
|
@@ -44,22 +44,36 @@ const highlightAllMatches = function (str) {
|
|
|
44
44
|
tokens: {
|
|
45
45
|
color: resultsTextColor
|
|
46
46
|
},
|
|
47
|
-
children: matchIndexes.reduce((acc, matchIndex, index) =>
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
47
|
+
children: matchIndexes.reduce((acc, matchIndex, index) => {
|
|
48
|
+
const prefix = index === 0 ? str.slice(0, matchIndex) : null;
|
|
49
|
+
const match = str.slice(matchIndex, matchIndex + substring.length);
|
|
50
|
+
const suffix = str.slice(matchIndex + substring.length, matchIndexes[index + 1] ?? str.length);
|
|
51
|
+
return [...acc, prefix ? /*#__PURE__*/_jsx(Typography, {
|
|
52
|
+
variant: {
|
|
53
|
+
bold: false
|
|
54
|
+
},
|
|
55
|
+
tokens: {
|
|
56
|
+
color: resultsTextColor
|
|
57
|
+
},
|
|
58
|
+
children: prefix
|
|
59
|
+
}, `pre-${matchIndex}`) : null, /*#__PURE__*/_jsx(Typography, {
|
|
60
|
+
variant: {
|
|
61
|
+
bold: true
|
|
62
|
+
},
|
|
63
|
+
tokens: {
|
|
64
|
+
color: resultsTextColor
|
|
65
|
+
},
|
|
66
|
+
children: match
|
|
67
|
+
}, matchIndex), suffix ? /*#__PURE__*/_jsx(Typography, {
|
|
68
|
+
variant: {
|
|
69
|
+
bold: false
|
|
70
|
+
},
|
|
71
|
+
tokens: {
|
|
72
|
+
color: resultsTextColor
|
|
73
|
+
},
|
|
74
|
+
children: suffix
|
|
75
|
+
}, `post-${matchIndex}`) : null];
|
|
76
|
+
}, []).filter(Boolean)
|
|
63
77
|
})
|
|
64
78
|
);
|
|
65
79
|
};
|
|
@@ -93,12 +107,14 @@ const Autocomplete = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
93
107
|
isLoading = false,
|
|
94
108
|
items,
|
|
95
109
|
maxSuggestions = DEFAULT_MAX_SUGGESTIONS,
|
|
110
|
+
maxDropdownHeight = DEFAULT_MAX_DROPDOWN_HEIGHT,
|
|
96
111
|
minToSuggestion = DEFAULT_MIN_TO_SUGGESTION,
|
|
97
112
|
noResults,
|
|
98
113
|
onChange,
|
|
99
114
|
onClear,
|
|
100
115
|
onSelect,
|
|
101
116
|
readOnly,
|
|
117
|
+
showOptionsOnFocus = false,
|
|
102
118
|
validation,
|
|
103
119
|
value,
|
|
104
120
|
helpText = '',
|
|
@@ -147,7 +163,7 @@ const Autocomplete = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
147
163
|
hint,
|
|
148
164
|
label: inputLabel
|
|
149
165
|
} = supportsProps;
|
|
150
|
-
const hintExpansionEnabled = isFocused && helpText && !currentValue;
|
|
166
|
+
const hintExpansionEnabled = isFocused && !!helpText && !currentValue;
|
|
151
167
|
const {
|
|
152
168
|
overlaidPosition,
|
|
153
169
|
sourceRef: inputRef,
|
|
@@ -201,9 +217,10 @@ const Autocomplete = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
201
217
|
}
|
|
202
218
|
};
|
|
203
219
|
const handleChange = newValue => {
|
|
204
|
-
onChange?.(newValue
|
|
220
|
+
onChange?.(newValue);
|
|
205
221
|
setCurrentValue(newValue);
|
|
206
|
-
|
|
222
|
+
const shouldExpand = newValue?.length >= minToSuggestion || showOptionsOnFocus && isFocused && newValue?.length === 0;
|
|
223
|
+
setIsExpanded(shouldExpand);
|
|
207
224
|
if (!isControlled && initialItems !== undefined) {
|
|
208
225
|
setCurrentItems(initialItems.filter(_ref3 => {
|
|
209
226
|
let {
|
|
@@ -215,25 +232,29 @@ const Autocomplete = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
215
232
|
};
|
|
216
233
|
const handleSelect = selectedId => {
|
|
217
234
|
onSelect?.(selectedId);
|
|
218
|
-
const {
|
|
219
|
-
label: newValue,
|
|
220
|
-
nested,
|
|
221
|
-
title
|
|
222
|
-
} = (isControlled ? items : currentItems)?.find(_ref4 => {
|
|
235
|
+
const selectedItem = (isControlled ? items : currentItems)?.find(_ref4 => {
|
|
223
236
|
let {
|
|
224
237
|
id
|
|
225
238
|
} = _ref4;
|
|
226
239
|
return id === selectedId;
|
|
227
240
|
});
|
|
241
|
+
const {
|
|
242
|
+
label,
|
|
243
|
+
nested,
|
|
244
|
+
title
|
|
245
|
+
} = selectedItem;
|
|
228
246
|
if (title) return;
|
|
229
247
|
if (!nested) {
|
|
230
248
|
setNestedSelectedValue(null);
|
|
231
|
-
onChange?.(
|
|
249
|
+
onChange?.(label);
|
|
232
250
|
setIsExpanded(false);
|
|
251
|
+
setCurrentValue(label);
|
|
252
|
+
}
|
|
253
|
+
if (!isControlled && inputRef?.current) inputRef.current.value = label;
|
|
254
|
+
if (nested) {
|
|
255
|
+
setNestedSelectedValue(label);
|
|
256
|
+
setCurrentValue(label);
|
|
233
257
|
}
|
|
234
|
-
setCurrentValue(newValue);
|
|
235
|
-
if (!isControlled && inputRef?.current) inputRef.current.value = newValue;
|
|
236
|
-
if (nested) setNestedSelectedValue(newValue);
|
|
237
258
|
inputRef.current.focus();
|
|
238
259
|
};
|
|
239
260
|
|
|
@@ -281,15 +302,33 @@ const Autocomplete = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
281
302
|
};
|
|
282
303
|
}, [inputRef]);
|
|
283
304
|
const handleClose = event => {
|
|
284
|
-
if (event.type === 'keydown' && (event.key === 'Escape' || event.key === '27')
|
|
305
|
+
if (event.type === 'keydown' && (event.key === 'Escape' || event.key === '27')) {
|
|
285
306
|
setIsExpanded(false);
|
|
286
307
|
setNestedSelectedValue(null);
|
|
287
|
-
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
if (event.type === 'keydown' && (event.key === 'ArrowDown' || event.key === 'Tab') && isExpanded && !isLoading && targetRef?.current) {
|
|
288
311
|
event.preventDefault();
|
|
289
312
|
targetRef.current.focus();
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
if (event.type === 'click' || event.type === 'touchstart') {
|
|
316
|
+
const clickTarget = event.type === 'click' ? event.target : event.touches[0]?.target;
|
|
317
|
+
const isOutsideOverlay = openOverlayRef?.current && !openOverlayRef.current.contains(clickTarget);
|
|
318
|
+
const isOutsideInput = inputRef?.current && !inputRef.current.contains(clickTarget);
|
|
319
|
+
if (isOutsideOverlay && isOutsideInput) {
|
|
320
|
+
setIsExpanded(false);
|
|
321
|
+
setNestedSelectedValue(null);
|
|
322
|
+
}
|
|
290
323
|
}
|
|
291
324
|
};
|
|
292
|
-
|
|
325
|
+
// Calculate items to show based on current state
|
|
326
|
+
let itemsToShow = [];
|
|
327
|
+
if (currentValue?.length > 0) {
|
|
328
|
+
itemsToShow = itemsToSuggest(highlight(isControlled ? items : currentItems, currentValue, resultsTextColor));
|
|
329
|
+
} else if (showOptionsOnFocus && isFocused) {
|
|
330
|
+
itemsToShow = itemsToSuggest(isControlled ? items : currentItems || initialItems);
|
|
331
|
+
}
|
|
293
332
|
const helpTextToShow = isFocused && !currentValue ? helpText : noResults ?? getCopy('noResults');
|
|
294
333
|
return /*#__PURE__*/_jsxs(View, {
|
|
295
334
|
style: staticStyles.container,
|
|
@@ -326,9 +365,15 @@ const Autocomplete = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
326
365
|
onChange: handleChange,
|
|
327
366
|
onFocus: () => {
|
|
328
367
|
setisFocused(true);
|
|
368
|
+
if (showOptionsOnFocus && (!currentValue || currentValue.length === 0)) {
|
|
369
|
+
setIsExpanded(true);
|
|
370
|
+
}
|
|
329
371
|
},
|
|
330
372
|
onBlur: () => {
|
|
331
373
|
setisFocused(false);
|
|
374
|
+
if (showOptionsOnFocus && (!currentValue || currentValue.length === 0)) {
|
|
375
|
+
setIsExpanded(false);
|
|
376
|
+
}
|
|
332
377
|
},
|
|
333
378
|
onClear: onClear,
|
|
334
379
|
onKeyPress: handleClose,
|
|
@@ -360,12 +405,13 @@ const Autocomplete = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
360
405
|
})
|
|
361
406
|
});
|
|
362
407
|
}
|
|
363
|
-
}), (isExpanded || hintExpansionEnabled) && isInputVisible && /*#__PURE__*/_jsxs(_Fragment, {
|
|
408
|
+
}), (isExpanded || hintExpansionEnabled) && isInputVisible && (itemsToShow.length > 0 || isExpanded || hintExpansionEnabled) && /*#__PURE__*/_jsxs(_Fragment, {
|
|
364
409
|
children: [/*#__PURE__*/_jsx(Listbox.Overlay, {
|
|
365
410
|
overlaidPosition: overlaidPosition,
|
|
366
411
|
isReady: isReady,
|
|
367
412
|
minWidth: fullWidth ? inputWidth : MIN_LISTBOX_WIDTH,
|
|
368
413
|
maxWidth: inputWidth,
|
|
414
|
+
maxHeight: maxDropdownHeight,
|
|
369
415
|
onLayout: handleMeasure,
|
|
370
416
|
tokens: restOfTokens,
|
|
371
417
|
ref: openOverlayRef,
|
|
@@ -449,6 +495,10 @@ Autocomplete.propTypes = {
|
|
|
449
495
|
* Maximum number of suggestions provided at the same time
|
|
450
496
|
*/
|
|
451
497
|
maxSuggestions: PropTypes.number,
|
|
498
|
+
/**
|
|
499
|
+
* Maximum height (in pixels) of the dropdown before scrolling is enabled
|
|
500
|
+
*/
|
|
501
|
+
maxDropdownHeight: PropTypes.number,
|
|
452
502
|
/**
|
|
453
503
|
* Text or JSX to render when no results are available
|
|
454
504
|
*/
|
|
@@ -469,6 +519,10 @@ Autocomplete.propTypes = {
|
|
|
469
519
|
* Callback function to be called when an item is selected from the list
|
|
470
520
|
*/
|
|
471
521
|
onSelect: PropTypes.func,
|
|
522
|
+
/**
|
|
523
|
+
* When true, displays all available options when the input receives focus (even without typing)
|
|
524
|
+
*/
|
|
525
|
+
showOptionsOnFocus: PropTypes.bool,
|
|
472
526
|
/**
|
|
473
527
|
* Input value for controlled usage
|
|
474
528
|
*/
|
package/lib/esm/Card/CardBase.js
CHANGED
|
@@ -57,9 +57,21 @@ const setBackgroundImage = _ref => {
|
|
|
57
57
|
case 'left-center':
|
|
58
58
|
backgroundPosition = 'left center';
|
|
59
59
|
break;
|
|
60
|
+
case 'left-start':
|
|
61
|
+
backgroundPosition = 'left top';
|
|
62
|
+
break;
|
|
63
|
+
case 'left-end':
|
|
64
|
+
backgroundPosition = 'left bottom';
|
|
65
|
+
break;
|
|
60
66
|
case 'right-center':
|
|
61
67
|
backgroundPosition = 'right center';
|
|
62
68
|
break;
|
|
69
|
+
case 'right-start':
|
|
70
|
+
backgroundPosition = 'right top';
|
|
71
|
+
break;
|
|
72
|
+
case 'right-end':
|
|
73
|
+
backgroundPosition = 'right bottom';
|
|
74
|
+
break;
|
|
63
75
|
default:
|
|
64
76
|
backgroundPosition = 'center center';
|
|
65
77
|
}
|
|
@@ -917,8 +917,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
917
917
|
// Related discussion - https://github.com/telus/universal-design-system/issues/1549
|
|
918
918
|
const previousNextIconButtonVariants = {
|
|
919
919
|
size: previousNextIconSize,
|
|
920
|
-
raised:
|
|
921
|
-
inverse: variant?.inverse
|
|
920
|
+
raised: true
|
|
922
921
|
};
|
|
923
922
|
const getCopyWithPlaceholders = React.useCallback(copyKey => {
|
|
924
923
|
const copyText = getCopy(copyKey).replace(/%\{title\}/g, title).replace(/%\{itemLabel\}/g, itemLabel).replace(/%\{stepNumber\}/g, activeIndex + 1).replace(/%\{stepCount\}/g, totalItems);
|
|
@@ -6,6 +6,7 @@ import Platform from "react-native-web/dist/exports/Platform";
|
|
|
6
6
|
import { resolvePressableTokens } from '../utils/pressability';
|
|
7
7
|
import { applyShadowToken } from '../ThemeProvider';
|
|
8
8
|
import { getTokensPropType } from '../utils';
|
|
9
|
+
import Tooltip from '../Tooltip';
|
|
9
10
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
11
|
const selectGeneralBubbleTokens = _ref => {
|
|
11
12
|
let {
|
|
@@ -69,14 +70,15 @@ const ColourBubble = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
|
|
|
69
70
|
colourHexCode,
|
|
70
71
|
colourName,
|
|
71
72
|
isSelected,
|
|
72
|
-
onPress
|
|
73
|
+
onPress,
|
|
74
|
+
showTooltip
|
|
73
75
|
} = _ref4;
|
|
74
76
|
const defaultTokens = tokens({
|
|
75
77
|
selected: isSelected
|
|
76
78
|
});
|
|
77
79
|
const resolveColourBubbleTokens = pressState => resolvePressableTokens(tokens, pressState, {});
|
|
78
80
|
const themeTokens = React.useMemo(() => tokens(), [tokens]);
|
|
79
|
-
|
|
81
|
+
const pressable = /*#__PURE__*/_jsx(Pressable, {
|
|
80
82
|
style: state => [selectGeneralBubbleTokens(resolveColourBubbleTokens(state)), isSelected && selectBorderBubbleTokens(defaultTokens)],
|
|
81
83
|
onPress: onPress,
|
|
82
84
|
accessible: true,
|
|
@@ -93,6 +95,14 @@ const ColourBubble = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
|
|
|
93
95
|
}]
|
|
94
96
|
})
|
|
95
97
|
});
|
|
98
|
+
if (showTooltip) {
|
|
99
|
+
return /*#__PURE__*/_jsx(Tooltip, {
|
|
100
|
+
content: colourName,
|
|
101
|
+
activateOnHover: true,
|
|
102
|
+
children: pressable
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return pressable;
|
|
96
106
|
});
|
|
97
107
|
ColourBubble.displayName = 'ColourBubble';
|
|
98
108
|
ColourBubble.propTypes = {
|
|
@@ -121,6 +131,10 @@ ColourBubble.propTypes = {
|
|
|
121
131
|
* of the color is changed of all currently `items`.
|
|
122
132
|
* Receives two parameters: item object selected and the event
|
|
123
133
|
*/
|
|
124
|
-
onPress: PropTypes.func
|
|
134
|
+
onPress: PropTypes.func,
|
|
135
|
+
/**
|
|
136
|
+
* When true, wraps the bubble in a Tooltip that displays the colourName on hover (web only).
|
|
137
|
+
*/
|
|
138
|
+
showTooltip: PropTypes.bool
|
|
125
139
|
};
|
|
126
140
|
export default ColourBubble;
|
|
@@ -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
|
*/
|