@telus-uds/components-base 3.30.0 → 3.32.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 +31 -1
- package/lib/cjs/Autocomplete/Autocomplete.js +13 -1
- package/lib/cjs/Autocomplete/constants.js +1 -1
- package/lib/cjs/Button/ButtonGroup.js +91 -23
- package/lib/cjs/Card/CardBase.js +75 -47
- package/lib/cjs/ColourToggle/ColourBubble.js +65 -12
- package/lib/cjs/ColourToggle/ColourToggle.js +40 -11
- package/lib/cjs/ColourToggle/constants.js +15 -0
- package/lib/cjs/ColourToggle/dictionary.js +15 -0
- package/lib/cjs/Listbox/ListboxOverlay.js +7 -1
- package/lib/cjs/MultiSelectFilter/ModalOverlay.js +7 -1
- package/lib/cjs/MultiSelectFilter/MultiSelectFilter.js +2 -28
- package/lib/cjs/TextInput/TextInputBase.js +2 -1
- package/lib/cjs/Validator/Validator.js +5 -1
- package/lib/cjs/utils/useOverlaidPosition.js +83 -42
- package/lib/esm/Autocomplete/Autocomplete.js +13 -1
- package/lib/esm/Autocomplete/constants.js +1 -1
- package/lib/esm/Button/ButtonGroup.js +91 -23
- package/lib/esm/Card/CardBase.js +75 -47
- package/lib/esm/ColourToggle/ColourBubble.js +66 -13
- package/lib/esm/ColourToggle/ColourToggle.js +41 -12
- package/lib/esm/ColourToggle/constants.js +8 -0
- package/lib/esm/ColourToggle/dictionary.js +9 -0
- package/lib/esm/Listbox/ListboxOverlay.js +7 -1
- package/lib/esm/MultiSelectFilter/ModalOverlay.js +8 -2
- package/lib/esm/MultiSelectFilter/MultiSelectFilter.js +2 -28
- package/lib/esm/TextInput/TextInputBase.js +2 -1
- package/lib/esm/Validator/Validator.js +5 -1
- package/lib/esm/utils/useOverlaidPosition.js +83 -42
- package/lib/package.json +2 -2
- package/package.json +2 -2
- package/src/Autocomplete/Autocomplete.jsx +11 -2
- package/src/Autocomplete/constants.js +1 -1
- package/src/Button/ButtonGroup.jsx +93 -24
- package/src/Card/CardBase.jsx +94 -75
- package/src/ColourToggle/ColourBubble.jsx +62 -7
- package/src/ColourToggle/ColourToggle.jsx +50 -10
- package/src/ColourToggle/constants.js +10 -0
- package/src/ColourToggle/dictionary.js +6 -0
- package/src/Listbox/ListboxOverlay.jsx +6 -2
- package/src/MultiSelectFilter/ModalOverlay.jsx +9 -3
- package/src/MultiSelectFilter/MultiSelectFilter.jsx +1 -31
- package/src/TextInput/TextInputBase.jsx +2 -1
- package/src/Validator/Validator.jsx +5 -1
- package/src/utils/useOverlaidPosition.js +84 -34
package/lib/esm/Card/CardBase.js
CHANGED
|
@@ -15,9 +15,7 @@ import FlexGridCol from '../FlexGrid/Col';
|
|
|
15
15
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
16
16
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
17
17
|
const GRID_COLUMNS = 12;
|
|
18
|
-
const isOverlayColor = color =>
|
|
19
|
-
return color && typeof color === 'string' && color.startsWith('rgba(');
|
|
20
|
-
};
|
|
18
|
+
const isOverlayColor = color => color && typeof color === 'string' && color.startsWith('rgba(');
|
|
21
19
|
const setBackgroundImage = _ref => {
|
|
22
20
|
let {
|
|
23
21
|
src,
|
|
@@ -26,7 +24,8 @@ const setBackgroundImage = _ref => {
|
|
|
26
24
|
backgroundImagePosition,
|
|
27
25
|
backgroundImageAlign,
|
|
28
26
|
content,
|
|
29
|
-
cardStyle
|
|
27
|
+
cardStyle,
|
|
28
|
+
testID
|
|
30
29
|
} = _ref;
|
|
31
30
|
const borderRadius = cardStyle?.borderRadius || 0;
|
|
32
31
|
const borderWidth = cardStyle?.borderWidth || 0;
|
|
@@ -86,6 +85,7 @@ const setBackgroundImage = _ref => {
|
|
|
86
85
|
style: [staticStyles.imageBackground, backgroundImageStyle],
|
|
87
86
|
role: "img",
|
|
88
87
|
"aria-label": alt,
|
|
88
|
+
testID: testID,
|
|
89
89
|
children: content
|
|
90
90
|
});
|
|
91
91
|
}
|
|
@@ -100,7 +100,8 @@ const setBackgroundImage = _ref => {
|
|
|
100
100
|
style: [staticStyles.containImage, positionStyles],
|
|
101
101
|
accessible: true,
|
|
102
102
|
accessibilityLabel: alt,
|
|
103
|
-
accessibilityIgnoresInvertColors: true
|
|
103
|
+
accessibilityIgnoresInvertColors: true,
|
|
104
|
+
testID: testID
|
|
104
105
|
}), /*#__PURE__*/_jsx(View, {
|
|
105
106
|
style: staticStyles.contentOverlay,
|
|
106
107
|
children: content
|
|
@@ -116,6 +117,7 @@ const setBackgroundImage = _ref => {
|
|
|
116
117
|
style: staticStyles.imageBackground,
|
|
117
118
|
accessible: true,
|
|
118
119
|
accessibilityLabel: alt,
|
|
120
|
+
testID: testID,
|
|
119
121
|
children: content
|
|
120
122
|
});
|
|
121
123
|
};
|
|
@@ -124,22 +126,13 @@ const selectPaddedContentStyles = _ref2 => {
|
|
|
124
126
|
paddingTop,
|
|
125
127
|
paddingBottom,
|
|
126
128
|
paddingLeft,
|
|
127
|
-
paddingRight
|
|
128
|
-
borderWidth,
|
|
129
|
-
borderColor,
|
|
130
|
-
borderRadius,
|
|
131
|
-
hasInteractiveBorder
|
|
129
|
+
paddingRight
|
|
132
130
|
} = _ref2;
|
|
133
131
|
return {
|
|
134
132
|
paddingTop,
|
|
135
133
|
paddingBottom,
|
|
136
134
|
paddingLeft,
|
|
137
|
-
paddingRight
|
|
138
|
-
...(hasInteractiveBorder ? {
|
|
139
|
-
borderWidth,
|
|
140
|
-
borderColor,
|
|
141
|
-
borderRadius
|
|
142
|
-
} : {})
|
|
135
|
+
paddingRight
|
|
143
136
|
};
|
|
144
137
|
};
|
|
145
138
|
const selectInteractiveOverlayStyles = _ref3 => {
|
|
@@ -158,12 +151,31 @@ const selectInteractiveOverlayStyles = _ref3 => {
|
|
|
158
151
|
backgroundColor,
|
|
159
152
|
borderRadius: adjustedBorderRadius,
|
|
160
153
|
pointerEvents: 'none',
|
|
161
|
-
zIndex:
|
|
154
|
+
zIndex: 3
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
const selectOuterContainerStyles = _ref4 => {
|
|
158
|
+
let {
|
|
159
|
+
containerStyle,
|
|
160
|
+
backgroundColor,
|
|
161
|
+
borderRadius,
|
|
162
|
+
borderColor,
|
|
163
|
+
borderWidth,
|
|
164
|
+
hasGradientToken
|
|
165
|
+
} = _ref4;
|
|
166
|
+
return {
|
|
167
|
+
...containerStyle,
|
|
168
|
+
backgroundColor,
|
|
169
|
+
borderRadius,
|
|
170
|
+
...(hasGradientToken ? {} : {
|
|
171
|
+
borderColor,
|
|
172
|
+
borderWidth
|
|
173
|
+
})
|
|
162
174
|
};
|
|
163
175
|
};
|
|
164
176
|
|
|
165
177
|
// Ensure explicit selection of tokens
|
|
166
|
-
export const selectStyles =
|
|
178
|
+
export const selectStyles = function (_ref5) {
|
|
167
179
|
let {
|
|
168
180
|
flex,
|
|
169
181
|
backgroundColor,
|
|
@@ -184,7 +196,10 @@ export const selectStyles = _ref4 => {
|
|
|
184
196
|
gradient,
|
|
185
197
|
maxHeight,
|
|
186
198
|
overflowY
|
|
187
|
-
} =
|
|
199
|
+
} = _ref5;
|
|
200
|
+
let {
|
|
201
|
+
hasBgImage = false
|
|
202
|
+
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
188
203
|
const hasGradient = (gradient || backgroundGradient) && Platform.OS === 'web';
|
|
189
204
|
let backgroundImageValue = null;
|
|
190
205
|
if (hasGradient) {
|
|
@@ -213,7 +228,11 @@ export const selectStyles = _ref4 => {
|
|
|
213
228
|
...(gradient && Platform.OS === 'web' ? {
|
|
214
229
|
backgroundImage: backgroundImageValue,
|
|
215
230
|
backgroundOrigin: `border-box`,
|
|
216
|
-
|
|
231
|
+
// bgImage child fills the content-box and replaces what the inset shadow
|
|
232
|
+
// used to cover, so we omit it to avoid hiding the image.
|
|
233
|
+
...(hasBgImage ? {} : {
|
|
234
|
+
boxShadow: `inset 0 1000px ${boxShadowColor}`
|
|
235
|
+
}),
|
|
217
236
|
border: `${borderWidth}px solid transparent`
|
|
218
237
|
} : {}),
|
|
219
238
|
...(backgroundGradient && Platform.OS === 'web' ? {
|
|
@@ -230,7 +249,7 @@ export const selectStyles = _ref4 => {
|
|
|
230
249
|
* A themeless base component for Card which components can apply theme tokens to. Not
|
|
231
250
|
* intended to be used in apps or sites directly: build themed components on top of this.
|
|
232
251
|
*/
|
|
233
|
-
const CardBase = /*#__PURE__*/React.forwardRef((
|
|
252
|
+
const CardBase = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
|
|
234
253
|
let {
|
|
235
254
|
children,
|
|
236
255
|
tokens,
|
|
@@ -238,15 +257,14 @@ const CardBase = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
238
257
|
backgroundImage,
|
|
239
258
|
fullBleedContent,
|
|
240
259
|
cardState,
|
|
260
|
+
testID,
|
|
241
261
|
...rest
|
|
242
|
-
} =
|
|
262
|
+
} = _ref6;
|
|
243
263
|
const resolvedTokens = typeof tokens === 'function' ? tokens(cardState) : tokens;
|
|
244
|
-
const
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
} : resolvedTokens;
|
|
249
|
-
const cardStyle = selectStyles(tokensToUse);
|
|
264
|
+
const hasBgImage = Boolean(backgroundImage && backgroundImage.src);
|
|
265
|
+
const cardStyle = selectStyles(resolvedTokens, {
|
|
266
|
+
hasBgImage
|
|
267
|
+
});
|
|
250
268
|
const props = selectProps(rest);
|
|
251
269
|
let content = children;
|
|
252
270
|
const {
|
|
@@ -279,31 +297,29 @@ const CardBase = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
279
297
|
...containerStyle
|
|
280
298
|
} = cardStyle;
|
|
281
299
|
const hasPadding = paddingTop || paddingBottom || paddingLeft || paddingRight;
|
|
282
|
-
const hasInteractiveBorder = borderWidth && borderWidth > 0;
|
|
283
300
|
const hasInteractiveOverlay = isOverlayColor(backgroundColor);
|
|
284
|
-
const
|
|
301
|
+
const outerBackgroundColor = hasInteractiveOverlay ? undefined : backgroundColor;
|
|
302
|
+
const hasGradientToken = Boolean(resolvedTokens.gradient) && Platform.OS === 'web';
|
|
303
|
+
const paddedContent = hasPadding ? /*#__PURE__*/_jsx(View, {
|
|
285
304
|
style: selectPaddedContentStyles({
|
|
286
305
|
paddingTop,
|
|
287
306
|
paddingBottom,
|
|
288
307
|
paddingLeft,
|
|
289
|
-
paddingRight
|
|
290
|
-
borderWidth,
|
|
291
|
-
borderColor,
|
|
292
|
-
borderRadius,
|
|
293
|
-
hasInteractiveBorder
|
|
308
|
+
paddingRight
|
|
294
309
|
}),
|
|
295
310
|
children: children
|
|
296
311
|
}) : children;
|
|
297
312
|
const contentWithOverlay = /*#__PURE__*/_jsxs(_Fragment, {
|
|
298
|
-
children: [
|
|
313
|
+
children: [/*#__PURE__*/_jsx(View, {
|
|
314
|
+
style: staticStyles.contentOverlay,
|
|
315
|
+
children: paddedContent
|
|
316
|
+
}), hasInteractiveOverlay && Platform.OS === 'web' && /*#__PURE__*/_jsx(View, {
|
|
299
317
|
style: selectInteractiveOverlayStyles({
|
|
300
318
|
backgroundColor,
|
|
301
319
|
borderRadius,
|
|
302
320
|
borderWidth
|
|
303
|
-
})
|
|
304
|
-
|
|
305
|
-
style: staticStyles.contentOverlay,
|
|
306
|
-
children: paddedContent
|
|
321
|
+
}),
|
|
322
|
+
testID: testID && `${testID}-card-base-bg-overlay`
|
|
307
323
|
})]
|
|
308
324
|
});
|
|
309
325
|
content = setBackgroundImage({
|
|
@@ -314,17 +330,23 @@ const CardBase = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
314
330
|
backgroundImageAlign,
|
|
315
331
|
content: contentWithOverlay,
|
|
316
332
|
cardStyle: {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
}
|
|
333
|
+
borderRadius,
|
|
334
|
+
borderWidth
|
|
335
|
+
},
|
|
336
|
+
testID: testID && `${testID}-card-base-bg-image`
|
|
320
337
|
});
|
|
321
338
|
return /*#__PURE__*/_jsx(View, {
|
|
322
|
-
style: {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
339
|
+
style: selectOuterContainerStyles({
|
|
340
|
+
containerStyle,
|
|
341
|
+
backgroundColor: outerBackgroundColor,
|
|
342
|
+
borderRadius,
|
|
343
|
+
borderColor,
|
|
344
|
+
borderWidth,
|
|
345
|
+
hasGradientToken
|
|
346
|
+
}),
|
|
326
347
|
dataSet: dataSet,
|
|
327
348
|
ref: ref,
|
|
349
|
+
testID: testID,
|
|
328
350
|
...props,
|
|
329
351
|
children: content
|
|
330
352
|
});
|
|
@@ -364,6 +386,7 @@ const CardBase = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
364
386
|
style: containerStyle,
|
|
365
387
|
dataSet: dataSet,
|
|
366
388
|
ref: ref,
|
|
389
|
+
testID: testID,
|
|
367
390
|
...props,
|
|
368
391
|
children: /*#__PURE__*/_jsx(FlexGrid, {
|
|
369
392
|
children: /*#__PURE__*/_jsx(FlexGridRow, {
|
|
@@ -380,6 +403,7 @@ const CardBase = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
380
403
|
style: cardStyle,
|
|
381
404
|
dataSet: dataSet,
|
|
382
405
|
ref: ref,
|
|
406
|
+
testID: testID,
|
|
383
407
|
...props,
|
|
384
408
|
children: content
|
|
385
409
|
});
|
|
@@ -422,6 +446,10 @@ CardBase.propTypes = {
|
|
|
422
446
|
...selectedSystemPropTypes,
|
|
423
447
|
children: PropTypes.node,
|
|
424
448
|
tokens: getTokensPropType('Card'),
|
|
449
|
+
/**
|
|
450
|
+
* Identifier for testing purposes.
|
|
451
|
+
*/
|
|
452
|
+
testID: PropTypes.string,
|
|
425
453
|
/**
|
|
426
454
|
* Apply background image to the card.
|
|
427
455
|
*/
|
|
@@ -3,11 +3,13 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import View from "react-native-web/dist/exports/View";
|
|
4
4
|
import Pressable from "react-native-web/dist/exports/Pressable";
|
|
5
5
|
import Platform from "react-native-web/dist/exports/Platform";
|
|
6
|
+
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
6
7
|
import { resolvePressableTokens } from '../utils/pressability';
|
|
7
8
|
import { applyShadowToken } from '../ThemeProvider';
|
|
8
9
|
import { getTokensPropType } from '../utils';
|
|
9
10
|
import Tooltip from '../Tooltip';
|
|
10
|
-
import {
|
|
11
|
+
import { UNAVAILABLE_VARIANT } from './constants';
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
13
|
const selectGeneralBubbleTokens = _ref => {
|
|
12
14
|
let {
|
|
13
15
|
outerBubbleHeight,
|
|
@@ -63,37 +65,70 @@ const selectBorderBubbleTokens = _ref3 => {
|
|
|
63
65
|
borderRadius: bubbleBorderRadius
|
|
64
66
|
};
|
|
65
67
|
};
|
|
66
|
-
const
|
|
68
|
+
const selectOverlayStyles = _ref4 => {
|
|
67
69
|
let {
|
|
68
|
-
|
|
70
|
+
overlayColor,
|
|
71
|
+
innerBubbleBorderRadius
|
|
72
|
+
} = _ref4;
|
|
73
|
+
return {
|
|
74
|
+
borderRadius: innerBubbleBorderRadius,
|
|
75
|
+
backgroundColor: overlayColor
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
const selectSlashStyles = (_ref5, unavailable) => {
|
|
79
|
+
let {
|
|
80
|
+
slashLightColor,
|
|
81
|
+
slashDarkColor,
|
|
82
|
+
slashWidth,
|
|
83
|
+
slashOffset
|
|
84
|
+
} = _ref5;
|
|
85
|
+
return {
|
|
86
|
+
width: slashWidth,
|
|
87
|
+
backgroundColor: unavailable === UNAVAILABLE_VARIANT.DARK ? slashDarkColor : slashLightColor,
|
|
88
|
+
marginLeft: slashOffset
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
const ColourBubble = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
|
|
92
|
+
let {
|
|
93
|
+
tokens = () => ({}),
|
|
69
94
|
id,
|
|
70
95
|
colourHexCode,
|
|
71
96
|
colourName,
|
|
72
97
|
isSelected,
|
|
73
98
|
onPress,
|
|
74
|
-
showTooltip
|
|
75
|
-
|
|
99
|
+
showTooltip,
|
|
100
|
+
unavailable,
|
|
101
|
+
isDisabled
|
|
102
|
+
} = _ref6;
|
|
76
103
|
const defaultTokens = tokens({
|
|
77
104
|
selected: isSelected
|
|
78
105
|
});
|
|
79
|
-
const resolveColourBubbleTokens = pressState => resolvePressableTokens(tokens, pressState, {});
|
|
80
|
-
const themeTokens =
|
|
81
|
-
const pressable = /*#__PURE__*/
|
|
106
|
+
const resolveColourBubbleTokens = pressState => resolvePressableTokens(tokens, isDisabled ? {} : pressState, {});
|
|
107
|
+
const themeTokens = tokens();
|
|
108
|
+
const pressable = /*#__PURE__*/_jsxs(Pressable, {
|
|
82
109
|
style: state => [selectGeneralBubbleTokens(resolveColourBubbleTokens(state)), isSelected && selectBorderBubbleTokens(defaultTokens)],
|
|
83
110
|
onPress: onPress,
|
|
111
|
+
disabled: isDisabled,
|
|
112
|
+
focusable: !isDisabled,
|
|
84
113
|
accessible: true,
|
|
85
114
|
accessibilityRole: "radio",
|
|
86
115
|
accessibilityLabel: colourName,
|
|
87
116
|
accessibilityState: {
|
|
88
|
-
checked: isSelected
|
|
117
|
+
checked: isSelected,
|
|
118
|
+
disabled: isDisabled
|
|
89
119
|
},
|
|
90
120
|
ref: ref,
|
|
91
121
|
testID: id,
|
|
92
|
-
children: /*#__PURE__*/_jsx(View, {
|
|
122
|
+
children: [/*#__PURE__*/_jsx(View, {
|
|
93
123
|
style: [selectInnerBubbleTokens(themeTokens), {
|
|
94
124
|
backgroundColor: colourHexCode
|
|
95
|
-
}]
|
|
96
|
-
|
|
125
|
+
}],
|
|
126
|
+
children: unavailable && /*#__PURE__*/_jsx(View, {
|
|
127
|
+
style: [StyleSheet.absoluteFillObject, selectOverlayStyles(themeTokens)]
|
|
128
|
+
})
|
|
129
|
+
}), unavailable && /*#__PURE__*/_jsx(View, {
|
|
130
|
+
style: [staticStyles.indicator, selectSlashStyles(themeTokens, unavailable)]
|
|
131
|
+
})]
|
|
97
132
|
});
|
|
98
133
|
if (showTooltip) {
|
|
99
134
|
return /*#__PURE__*/_jsx(Tooltip, {
|
|
@@ -135,6 +170,24 @@ ColourBubble.propTypes = {
|
|
|
135
170
|
/**
|
|
136
171
|
* When true, wraps the bubble in a Tooltip that displays the colourName on hover (web only).
|
|
137
172
|
*/
|
|
138
|
-
showTooltip: PropTypes.bool
|
|
173
|
+
showTooltip: PropTypes.bool,
|
|
174
|
+
/**
|
|
175
|
+
* When set, renders a diagonal indicator over the bubble. Accepts either 'dark' or 'light' to determine the colour of the indicator.
|
|
176
|
+
*/
|
|
177
|
+
unavailable: PropTypes.oneOf(Object.values(UNAVAILABLE_VARIANT)),
|
|
178
|
+
/**
|
|
179
|
+
* When true, disables interaction on the bubble.
|
|
180
|
+
*/
|
|
181
|
+
isDisabled: PropTypes.bool
|
|
139
182
|
};
|
|
183
|
+
const staticStyles = StyleSheet.create({
|
|
184
|
+
indicator: {
|
|
185
|
+
position: 'absolute',
|
|
186
|
+
top: '50%',
|
|
187
|
+
height: 2,
|
|
188
|
+
transform: [{
|
|
189
|
+
rotate: '-45deg'
|
|
190
|
+
}]
|
|
191
|
+
}
|
|
192
|
+
});
|
|
140
193
|
export default ColourBubble;
|
|
@@ -2,10 +2,12 @@ import React from 'react';
|
|
|
2
2
|
import View from "react-native-web/dist/exports/View";
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import { useThemeTokensCallback } from '../ThemeProvider';
|
|
5
|
-
import { a11yProps, getTokensPropType, selectSystemProps, variantProp, viewProps } from '../utils';
|
|
5
|
+
import { a11yProps, getTokensPropType, selectSystemProps, useCopy, variantProp, viewProps } from '../utils';
|
|
6
6
|
import { StackWrap } from '../StackView';
|
|
7
7
|
import Typography from '../Typography';
|
|
8
8
|
import ColourBubble from './ColourBubble';
|
|
9
|
+
import { UNAVAILABLE_VARIANT, DICTIONARY_CONTENT_SHAPE } from './constants';
|
|
10
|
+
import DEFAULT_COLOUR_TOGGLE_DICTIONARY from './dictionary';
|
|
9
11
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
12
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
11
13
|
const ColourToggle = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
@@ -16,37 +18,49 @@ const ColourToggle = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
16
18
|
items,
|
|
17
19
|
onChange,
|
|
18
20
|
showTooltips,
|
|
21
|
+
copy = 'en',
|
|
22
|
+
dictionary = DEFAULT_COLOUR_TOGGLE_DICTIONARY,
|
|
19
23
|
...rest
|
|
20
24
|
} = _ref;
|
|
21
25
|
const [currentColourId, setCurrentColourId] = React.useState(defaultColourId);
|
|
22
26
|
const getTokens = useThemeTokensCallback('ColourToggle', tokens, variant);
|
|
27
|
+
const getCopy = useCopy({
|
|
28
|
+
dictionary,
|
|
29
|
+
copy
|
|
30
|
+
});
|
|
23
31
|
const {
|
|
24
32
|
space
|
|
25
33
|
} = getTokens();
|
|
26
|
-
const {
|
|
27
|
-
|
|
28
|
-
|
|
34
|
+
const currentItem = items.find(_ref2 => {
|
|
35
|
+
let {
|
|
36
|
+
id
|
|
37
|
+
} = _ref2;
|
|
38
|
+
return id === currentColourId;
|
|
39
|
+
});
|
|
29
40
|
return /*#__PURE__*/_jsxs(View, {
|
|
30
41
|
ref: ref,
|
|
31
42
|
...selectProps(rest),
|
|
32
43
|
children: [/*#__PURE__*/_jsx(Typography, {
|
|
33
|
-
children:
|
|
44
|
+
children: currentItem?.unavailable ? `${currentItem.colourName} ${getCopy('unavailable')}` : currentItem?.colourName ?? ''
|
|
34
45
|
}), /*#__PURE__*/_jsx(StackWrap, {
|
|
35
46
|
space: space,
|
|
36
47
|
accessibilityRole: "radiogroup",
|
|
37
|
-
children: items.map((
|
|
48
|
+
children: items.map((_ref3, index) => {
|
|
38
49
|
let {
|
|
39
50
|
id,
|
|
40
51
|
colourHexCode,
|
|
41
|
-
colourName
|
|
42
|
-
|
|
52
|
+
colourName,
|
|
53
|
+
unavailable,
|
|
54
|
+
disabled
|
|
55
|
+
} = _ref3;
|
|
43
56
|
const colourBubbleId = id || `ColourBubble[${index}]`;
|
|
44
57
|
const handleChangeColour = event => {
|
|
45
58
|
setCurrentColourId(id);
|
|
46
59
|
onChange?.(event, {
|
|
47
60
|
id,
|
|
48
61
|
colourHexCode,
|
|
49
|
-
colourName
|
|
62
|
+
colourName,
|
|
63
|
+
unavailable
|
|
50
64
|
});
|
|
51
65
|
};
|
|
52
66
|
return /*#__PURE__*/_jsx(ColourBubble, {
|
|
@@ -56,7 +70,9 @@ const ColourToggle = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
56
70
|
colourHexCode: colourHexCode,
|
|
57
71
|
colourName: colourName,
|
|
58
72
|
onPress: handleChangeColour,
|
|
59
|
-
showTooltip: showTooltips
|
|
73
|
+
showTooltip: showTooltips,
|
|
74
|
+
unavailable: unavailable,
|
|
75
|
+
isDisabled: !!disabled
|
|
60
76
|
}, colourBubbleId);
|
|
61
77
|
})
|
|
62
78
|
})]
|
|
@@ -83,7 +99,9 @@ ColourToggle.propTypes = {
|
|
|
83
99
|
items: PropTypes.arrayOf(PropTypes.exact({
|
|
84
100
|
colourHexCode: PropTypes.string,
|
|
85
101
|
colourName: PropTypes.string,
|
|
86
|
-
id: PropTypes.string
|
|
102
|
+
id: PropTypes.string,
|
|
103
|
+
unavailable: PropTypes.oneOf(Object.values(UNAVAILABLE_VARIANT)),
|
|
104
|
+
disabled: PropTypes.bool
|
|
87
105
|
})),
|
|
88
106
|
/**
|
|
89
107
|
* 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
|
|
@@ -92,6 +110,17 @@ ColourToggle.propTypes = {
|
|
|
92
110
|
/**
|
|
93
111
|
* When true, displays each colour's name as a tooltip on hover (web only).
|
|
94
112
|
*/
|
|
95
|
-
showTooltips: PropTypes.bool
|
|
113
|
+
showTooltips: PropTypes.bool,
|
|
114
|
+
/**
|
|
115
|
+
* Select English or French copy.
|
|
116
|
+
*/
|
|
117
|
+
copy: PropTypes.oneOf(['en', 'fr']),
|
|
118
|
+
/**
|
|
119
|
+
* Override default labels.
|
|
120
|
+
*/
|
|
121
|
+
dictionary: PropTypes.shape({
|
|
122
|
+
en: DICTIONARY_CONTENT_SHAPE,
|
|
123
|
+
fr: DICTIONARY_CONTENT_SHAPE
|
|
124
|
+
})
|
|
96
125
|
};
|
|
97
126
|
export default ColourToggle;
|
|
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import View from "react-native-web/dist/exports/View";
|
|
4
4
|
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
5
5
|
import Platform from "react-native-web/dist/exports/Platform";
|
|
6
|
+
import ScrollView from "react-native-web/dist/exports/ScrollView";
|
|
6
7
|
import Portal from '../Portal';
|
|
7
8
|
import { useThemeTokens } from '../ThemeProvider';
|
|
8
9
|
import Card from '../Card';
|
|
@@ -60,7 +61,12 @@ const DropdownOverlay = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
60
61
|
paddingLeft: paddingHorizontal,
|
|
61
62
|
paddingRight: paddingHorizontal
|
|
62
63
|
},
|
|
63
|
-
children:
|
|
64
|
+
children: Platform.OS !== 'web' ? /*#__PURE__*/_jsx(ScrollView, {
|
|
65
|
+
style: {
|
|
66
|
+
maxHeight
|
|
67
|
+
},
|
|
68
|
+
children: children
|
|
69
|
+
}) : children
|
|
64
70
|
})
|
|
65
71
|
});
|
|
66
72
|
});
|
|
@@ -3,7 +3,8 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import View from "react-native-web/dist/exports/View";
|
|
4
4
|
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
5
5
|
import Platform from "react-native-web/dist/exports/Platform";
|
|
6
|
-
import { Portal } from '@gorhom/portal';
|
|
6
|
+
import { Portal as GorhomPortal } from '@gorhom/portal';
|
|
7
|
+
import LocalPortal from '../Portal/Portal';
|
|
7
8
|
import { useCopy, copyPropTypes, getTokensPropType, variantProp } from '../utils';
|
|
8
9
|
import { useViewport } from '../ViewportProvider';
|
|
9
10
|
import { useThemeTokens } from '../ThemeProvider';
|
|
@@ -116,7 +117,12 @@ const ModalOverlay = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
116
117
|
copy
|
|
117
118
|
});
|
|
118
119
|
const closeLabel = getCopy('closeButton');
|
|
119
|
-
|
|
120
|
+
|
|
121
|
+
// On web, use the local Portal (always appends to document.body) to ensure correct
|
|
122
|
+
// absolute positioning in MFE/iframe contexts. @gorhom/portal may render its host
|
|
123
|
+
// outside the iframe's document, causing coordinate mismatches when scrolled.
|
|
124
|
+
const PortalComponent = Platform.OS === 'web' ? LocalPortal : GorhomPortal;
|
|
125
|
+
return /*#__PURE__*/_jsx(PortalComponent, {
|
|
120
126
|
children: /*#__PURE__*/_jsx(View, {
|
|
121
127
|
ref: containerRef,
|
|
122
128
|
onLayout: onLayout,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import { Portal } from '@gorhom/portal';
|
|
4
3
|
import View from "react-native-web/dist/exports/View";
|
|
5
4
|
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
6
5
|
import Dimensions from "react-native-web/dist/exports/Dimensions";
|
|
@@ -212,20 +211,6 @@ const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
212
211
|
setIsOpen(false);
|
|
213
212
|
onCancel();
|
|
214
213
|
};
|
|
215
|
-
const appRootRef = React.useRef(null);
|
|
216
|
-
const [rootOffsets, setRootOffsets] = React.useState(null);
|
|
217
|
-
React.useEffect(() => {
|
|
218
|
-
if (rootOffsets) return;
|
|
219
|
-
appRootRef.current?.measureInWindow((x, y) => {
|
|
220
|
-
// Only set offsets if they are positive
|
|
221
|
-
// this is because we want to avoid negative offsets that could cause
|
|
222
|
-
// the dropdown to be positioned incorrectly in some situations
|
|
223
|
-
if (y > 0) setRootOffsets({
|
|
224
|
-
horizontal: x,
|
|
225
|
-
vertical: y
|
|
226
|
-
});
|
|
227
|
-
});
|
|
228
|
-
}, [isOpen, rootOffsets]);
|
|
229
214
|
const {
|
|
230
215
|
align,
|
|
231
216
|
offsets
|
|
@@ -242,8 +227,7 @@ const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
242
227
|
left: 'left'
|
|
243
228
|
},
|
|
244
229
|
offsets: {
|
|
245
|
-
vertical: 4
|
|
246
|
-
horizontal: -rootOffsets?.horizontal || 0
|
|
230
|
+
vertical: 4
|
|
247
231
|
}
|
|
248
232
|
}
|
|
249
233
|
});
|
|
@@ -380,12 +364,7 @@ const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
380
364
|
})]
|
|
381
365
|
});
|
|
382
366
|
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
383
|
-
children: [/*#__PURE__*/_jsx(
|
|
384
|
-
children: /*#__PURE__*/_jsx(View, {
|
|
385
|
-
ref: appRootRef,
|
|
386
|
-
style: styles.appRootRef
|
|
387
|
-
})
|
|
388
|
-
}), /*#__PURE__*/_jsx(ButtonDropdown, {
|
|
367
|
+
children: [/*#__PURE__*/_jsx(ButtonDropdown, {
|
|
389
368
|
ref: sourceRef,
|
|
390
369
|
...pressHandlers,
|
|
391
370
|
value: isOpen,
|
|
@@ -466,11 +445,6 @@ const styles = StyleSheet.create({
|
|
|
466
445
|
},
|
|
467
446
|
scrollContainer: {
|
|
468
447
|
padding: 1
|
|
469
|
-
},
|
|
470
|
-
appRootRef: {
|
|
471
|
-
position: 'absolute',
|
|
472
|
-
top: 0,
|
|
473
|
-
left: 0
|
|
474
448
|
}
|
|
475
449
|
});
|
|
476
450
|
|
|
@@ -272,7 +272,8 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
|
|
|
272
272
|
}, [element, pattern]);
|
|
273
273
|
const handleChangeText = event => {
|
|
274
274
|
const text = event.nativeEvent?.text ?? event.target?.value;
|
|
275
|
-
|
|
275
|
+
// Do NOT use `|| undefined`: empty string is falsy and would break the controlled contract
|
|
276
|
+
let filteredText = isNumeric ? text?.replace(/[^\d]/g, '') ?? '' : text;
|
|
276
277
|
if (type === 'card' && filteredText) {
|
|
277
278
|
const formattedValue = filteredText.replace(/[^a-zA-Z0-9]/g, '');
|
|
278
279
|
const regex = new RegExp(`([a-zA-Z0-9]{4})(?=[a-zA-Z0-9])`, 'g');
|
|
@@ -199,7 +199,11 @@ const Validator = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
199
199
|
|
|
200
200
|
// Sync external value prop to internal state
|
|
201
201
|
React.useEffect(() => {
|
|
202
|
-
if (value
|
|
202
|
+
if (value === '') {
|
|
203
|
+
setCodes(Array(validatorsLength).fill(''));
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
if (Number(value).toString() !== 'NaN') {
|
|
203
207
|
const digits = value.split('').slice(0, validatorsLength);
|
|
204
208
|
const newCodes = Array(validatorsLength).fill('');
|
|
205
209
|
digits.forEach((digit, i) => {
|