@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
|
@@ -54,46 +54,45 @@ function getOverlaidPosition(_ref2) {
|
|
|
54
54
|
offsets = {},
|
|
55
55
|
align
|
|
56
56
|
} = _ref2;
|
|
57
|
-
// Web-only: this will be difficult to mimic on native because there's no global scroll position.
|
|
58
|
-
// TODO: wire something in e.g. a scroll ref accessible from a provider included in Allium provider
|
|
59
|
-
// that can be passed to the appropriate ScrollView?
|
|
60
|
-
const {
|
|
61
|
-
scrollX = 0,
|
|
62
|
-
scrollY = 0
|
|
63
|
-
} = typeof window === 'object' ? window : {};
|
|
64
|
-
|
|
65
57
|
// Will have top, bottom, left and/or right offsets depending on `align`
|
|
66
58
|
const positioning = {};
|
|
67
59
|
const verticalOffset = offsets.vertical ?? 0;
|
|
68
60
|
const horizontalOffset = offsets.horizontal ?? 0;
|
|
69
61
|
if (align.top) positioning.top = getPosition({
|
|
70
62
|
edge: getEdgeType(align, 'top'),
|
|
71
|
-
fromEdge: sourceLayout.y +
|
|
63
|
+
fromEdge: sourceLayout.y + verticalOffset,
|
|
72
64
|
sourceSize: sourceLayout.height
|
|
73
65
|
});
|
|
74
66
|
if (align.middle) positioning.top = getPosition({
|
|
75
67
|
edge: getEdgeType(align, 'middle'),
|
|
76
|
-
fromEdge: sourceLayout.y +
|
|
77
|
-
sourceSize: sourceLayout.height
|
|
78
|
-
});
|
|
79
|
-
if (align.bottom) positioning.bottom = getPosition({
|
|
80
|
-
edge: getEdgeType(align, 'bottom'),
|
|
81
|
-
fromEdge: windowDimensions.height - (sourceLayout.y + scrollY + sourceLayout.height - verticalOffset),
|
|
68
|
+
fromEdge: sourceLayout.y + verticalOffset - targetDimensions.height / 2,
|
|
82
69
|
sourceSize: sourceLayout.height
|
|
83
70
|
});
|
|
71
|
+
if (align.bottom) {
|
|
72
|
+
if (Platform.OS !== 'web') {
|
|
73
|
+
// On native, position:absolute is parent-relative, so use negative top offset instead of window-based bottom math.
|
|
74
|
+
positioning.top = sourceLayout.y - targetDimensions.height - verticalOffset;
|
|
75
|
+
} else {
|
|
76
|
+
positioning.bottom = getPosition({
|
|
77
|
+
edge: getEdgeType(align, 'bottom'),
|
|
78
|
+
fromEdge: windowDimensions.height - (sourceLayout.y + sourceLayout.height - verticalOffset),
|
|
79
|
+
sourceSize: sourceLayout.height
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
84
83
|
if (align.left) positioning.left = getPosition({
|
|
85
84
|
edge: getEdgeType(align, 'left'),
|
|
86
|
-
fromEdge: sourceLayout.x +
|
|
85
|
+
fromEdge: sourceLayout.x + horizontalOffset,
|
|
87
86
|
sourceSize: sourceLayout.width
|
|
88
87
|
});
|
|
89
88
|
if (align.center) positioning.left = getPosition({
|
|
90
89
|
edge: getEdgeType(align, 'center'),
|
|
91
|
-
fromEdge: sourceLayout.x +
|
|
90
|
+
fromEdge: sourceLayout.x + horizontalOffset - targetDimensions.width / 2,
|
|
92
91
|
sourceSize: sourceLayout.width
|
|
93
92
|
});
|
|
94
93
|
if (align.right) positioning.right = getPosition({
|
|
95
94
|
edge: getEdgeType(align, 'right'),
|
|
96
|
-
fromEdge: windowDimensions.width - (sourceLayout.x +
|
|
95
|
+
fromEdge: windowDimensions.width - (sourceLayout.x + sourceLayout.width - horizontalOffset),
|
|
97
96
|
sourceSize: sourceLayout.width
|
|
98
97
|
});
|
|
99
98
|
if (!(align.left && align.right)) {
|
|
@@ -134,6 +133,32 @@ const useOverlaidPosition = _ref3 => {
|
|
|
134
133
|
const targetRef = useRef(null);
|
|
135
134
|
const [targetDimensions, setTargetDimensions] = useState(null);
|
|
136
135
|
const [windowDimensions, setWindowDimensions] = useState(null);
|
|
136
|
+
const hasRemeasuredRef = useRef(false);
|
|
137
|
+
const applySourceLayout = useCallback((dims, x, y, width, height) => {
|
|
138
|
+
setWindowDimensions(dims);
|
|
139
|
+
setSourceLayout({
|
|
140
|
+
x,
|
|
141
|
+
y,
|
|
142
|
+
width,
|
|
143
|
+
height
|
|
144
|
+
});
|
|
145
|
+
}, []);
|
|
146
|
+
const measureSourceOnWeb = useCallback(windowDims => {
|
|
147
|
+
const el = sourceRef.current;
|
|
148
|
+
if (!el) return;
|
|
149
|
+
const domNode = el._nativeTag ?? el;
|
|
150
|
+
const dims = windowDims ?? Dimensions.get('window');
|
|
151
|
+
const rect = typeof domNode.getBoundingClientRect === 'function' ? domNode.getBoundingClientRect() : null;
|
|
152
|
+
if (rect) {
|
|
153
|
+
const x = rect.left + (typeof window.scrollX === 'number' ? window.scrollX : 0);
|
|
154
|
+
const y = rect.top + (typeof window.scrollY === 'number' ? window.scrollY : 0);
|
|
155
|
+
applySourceLayout(dims, x, y, rect.width, rect.height);
|
|
156
|
+
} else {
|
|
157
|
+
el.measureInWindow((mx, my, width, height) => {
|
|
158
|
+
applySourceLayout(dims, mx, my, width, height);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}, [applySourceLayout]);
|
|
137
162
|
const onTargetLayout = useCallback(_ref4 => {
|
|
138
163
|
let {
|
|
139
164
|
nativeEvent: {
|
|
@@ -164,16 +189,19 @@ const useOverlaidPosition = _ref3 => {
|
|
|
164
189
|
let {
|
|
165
190
|
window
|
|
166
191
|
} = _ref5;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
192
|
+
if (Platform.OS === 'web') {
|
|
193
|
+
measureSourceOnWeb(window);
|
|
194
|
+
} else {
|
|
195
|
+
sourceRef.current?.measure((x, y, width, height) => {
|
|
196
|
+
setWindowDimensions(window);
|
|
197
|
+
setSourceLayout({
|
|
198
|
+
x,
|
|
199
|
+
y,
|
|
200
|
+
width,
|
|
201
|
+
height
|
|
202
|
+
});
|
|
175
203
|
});
|
|
176
|
-
}
|
|
204
|
+
}
|
|
177
205
|
};
|
|
178
206
|
let subscription;
|
|
179
207
|
const unsubscribe = () => {
|
|
@@ -186,6 +214,7 @@ const useOverlaidPosition = _ref3 => {
|
|
|
186
214
|
}
|
|
187
215
|
setSourceLayout(null);
|
|
188
216
|
setTargetDimensions(null);
|
|
217
|
+
hasRemeasuredRef.current = false;
|
|
189
218
|
};
|
|
190
219
|
if (readyToShow) {
|
|
191
220
|
subscription = Dimensions.addEventListener('change', handleDimensionsChange);
|
|
@@ -196,36 +225,48 @@ const useOverlaidPosition = _ref3 => {
|
|
|
196
225
|
unsubscribe();
|
|
197
226
|
}
|
|
198
227
|
return unsubscribe;
|
|
199
|
-
}, [readyToShow]);
|
|
228
|
+
}, [readyToShow, measureSourceOnWeb]);
|
|
229
|
+
|
|
230
|
+
// Re-measure source when targetDimensions first becomes available.
|
|
231
|
+
// Without this, there is a race condition: getBoundingClientRect() resolves faster than
|
|
232
|
+
// measureInWindow used to, so sourceLayout may be set before the dropdown has rendered
|
|
233
|
+
// and reported its dimensions via onTargetLayout. When targetDimensions finally arrives,
|
|
234
|
+
// sourceLayout is stale (no scroll has occurred to trigger handleScroll).
|
|
235
|
+
// Setting hasRemeasuredRef.current=true here also prevents the blink: isReady (on web)
|
|
236
|
+
// won't become true until this effect completes, guaranteeing the dropdown is always shown
|
|
237
|
+
// at its final correct position without an intermediate incorrect-position frame.
|
|
238
|
+
useEffect(() => {
|
|
239
|
+
if (!isShown || !sourceRef.current || !targetDimensions || Platform.OS !== 'web') return;
|
|
240
|
+
measureSourceOnWeb();
|
|
241
|
+
hasRemeasuredRef.current = true;
|
|
242
|
+
}, [targetDimensions, isShown, measureSourceOnWeb]);
|
|
200
243
|
useEffect(() => {
|
|
201
244
|
if (Platform.OS !== 'web') {
|
|
202
245
|
return undefined;
|
|
203
246
|
}
|
|
204
|
-
const handleScroll = debounce(
|
|
205
|
-
sourceRef.current?.measureInWindow((x, y, width, height) => {
|
|
206
|
-
setWindowDimensions(window);
|
|
207
|
-
setSourceLayout({
|
|
208
|
-
x,
|
|
209
|
-
y,
|
|
210
|
-
width,
|
|
211
|
-
height
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
}, DEBOUNCE_DELAY);
|
|
247
|
+
const handleScroll = debounce(measureSourceOnWeb, DEBOUNCE_DELAY);
|
|
215
248
|
window.addEventListener('scroll', handleScroll);
|
|
216
249
|
return () => {
|
|
217
250
|
window.removeEventListener('scroll', handleScroll);
|
|
218
251
|
handleScroll.cancel();
|
|
219
252
|
};
|
|
220
|
-
}, [
|
|
221
|
-
|
|
253
|
+
}, [measureSourceOnWeb]);
|
|
254
|
+
|
|
255
|
+
// On web, require hasRemeasuredRef to be true before declaring isReady. This ensures
|
|
256
|
+
// the dropdown is never shown with an intermediate stale position (the blink).
|
|
257
|
+
// On native, hasRemeasuredRef stays false (the web-only effect never runs), so we skip
|
|
258
|
+
// that check to preserve the original native behaviour.
|
|
259
|
+
const isReady = Boolean(isShown && sourceLayout && windowDimensions && targetDimensions && (Platform.OS !== 'web' || hasRemeasuredRef.current));
|
|
222
260
|
const overlaidPosition = isReady ? getOverlaidPosition({
|
|
223
261
|
sourceLayout,
|
|
224
262
|
targetDimensions,
|
|
225
263
|
windowDimensions,
|
|
226
264
|
offsets,
|
|
227
265
|
align
|
|
228
|
-
}) : {
|
|
266
|
+
}) : {
|
|
267
|
+
top: 0,
|
|
268
|
+
left: 0
|
|
269
|
+
};
|
|
229
270
|
return {
|
|
230
271
|
overlaidPosition,
|
|
231
272
|
sourceRef,
|
package/lib/package.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"@gorhom/portal": "^1.0.14",
|
|
13
13
|
"@react-native-picker/picker": "^2.9.0",
|
|
14
14
|
"@telus-uds/system-constants": "^3.0.0",
|
|
15
|
-
"@telus-uds/system-theme-tokens": "^4.
|
|
15
|
+
"@telus-uds/system-theme-tokens": "^4.22.0",
|
|
16
16
|
"airbnb-prop-types": "^2.16.0",
|
|
17
17
|
"css-mediaquery": "^0.1.2",
|
|
18
18
|
"expo-document-picker": "^13.0.1",
|
|
@@ -84,6 +84,6 @@
|
|
|
84
84
|
"standard-engine": {
|
|
85
85
|
"skip": true
|
|
86
86
|
},
|
|
87
|
-
"version": "3.
|
|
87
|
+
"version": "3.32.0",
|
|
88
88
|
"types": "types/index.d.ts"
|
|
89
89
|
}
|
package/package.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"@gorhom/portal": "^1.0.14",
|
|
13
13
|
"@react-native-picker/picker": "^2.9.0",
|
|
14
14
|
"@telus-uds/system-constants": "^3.0.0",
|
|
15
|
-
"@telus-uds/system-theme-tokens": "^4.
|
|
15
|
+
"@telus-uds/system-theme-tokens": "^4.22.0",
|
|
16
16
|
"airbnb-prop-types": "^2.16.0",
|
|
17
17
|
"css-mediaquery": "^0.1.2",
|
|
18
18
|
"expo-document-picker": "^13.0.1",
|
|
@@ -84,6 +84,6 @@
|
|
|
84
84
|
"standard-engine": {
|
|
85
85
|
"skip": true
|
|
86
86
|
},
|
|
87
|
-
"version": "3.
|
|
87
|
+
"version": "3.32.0",
|
|
88
88
|
"types": "types/index.d.ts"
|
|
89
89
|
}
|
|
@@ -131,6 +131,7 @@ const Autocomplete = React.forwardRef(
|
|
|
131
131
|
value,
|
|
132
132
|
helpText = '',
|
|
133
133
|
loadingLabel,
|
|
134
|
+
dropdownPosition = 'bottom',
|
|
134
135
|
tokens,
|
|
135
136
|
...rest
|
|
136
137
|
},
|
|
@@ -182,7 +183,11 @@ const Autocomplete = React.forwardRef(
|
|
|
182
183
|
isShown: isExpanded || hintExpansionEnabled,
|
|
183
184
|
offsets: {
|
|
184
185
|
vertical: Platform.OS !== 'web' && (hint || inputLabel) ? 28 : 4
|
|
185
|
-
}
|
|
186
|
+
},
|
|
187
|
+
align:
|
|
188
|
+
dropdownPosition === 'top'
|
|
189
|
+
? { center: 'center', bottom: 'top' }
|
|
190
|
+
: { center: 'center', top: 'bottom' }
|
|
186
191
|
})
|
|
187
192
|
const targetRef = React.useRef(null)
|
|
188
193
|
// We limit the number of suggestions displayed to avoid huge lists
|
|
@@ -556,7 +561,11 @@ Autocomplete.propTypes = {
|
|
|
556
561
|
/**
|
|
557
562
|
* Input value for controlled usage
|
|
558
563
|
*/
|
|
559
|
-
value: PropTypes.string
|
|
564
|
+
value: PropTypes.string,
|
|
565
|
+
/**
|
|
566
|
+
* Controls whether the dropdown renders above or below the input. Defaults to 'bottom'.
|
|
567
|
+
*/
|
|
568
|
+
dropdownPosition: PropTypes.oneOf(['top', 'bottom'])
|
|
560
569
|
}
|
|
561
570
|
|
|
562
571
|
export default Autocomplete
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const DEFAULT_MIN_TO_SUGGESTION = 1
|
|
2
2
|
export const DEFAULT_MAX_SUGGESTIONS = 5
|
|
3
|
-
export const DEFAULT_MAX_DROPDOWN_HEIGHT =
|
|
3
|
+
export const DEFAULT_MAX_DROPDOWN_HEIGHT = 500
|
|
4
4
|
export const INPUT_LEFT_PADDING = 16
|
|
5
5
|
export const MIN_LISTBOX_WIDTH = 288
|
|
@@ -28,6 +28,8 @@ const [selectItemProps, selectedItemPropTypes] = selectSystemProps([
|
|
|
28
28
|
pressProps,
|
|
29
29
|
viewProps
|
|
30
30
|
])
|
|
31
|
+
const EQUAL_WIDTH = 'equal'
|
|
32
|
+
const RESPONSIVE_WIDTH = 'responsive'
|
|
31
33
|
|
|
32
34
|
const ButtonGroup = React.forwardRef(
|
|
33
35
|
(
|
|
@@ -70,6 +72,9 @@ const ButtonGroup = React.forwardRef(
|
|
|
70
72
|
const themeButtonTokensCallback = useThemeTokensCallback('ButtonGroupItem', tokens, variant)
|
|
71
73
|
const gapValue = useSpacingScale(gap || space)
|
|
72
74
|
|
|
75
|
+
const isWeb = Platform.OS === 'web'
|
|
76
|
+
const buttonWidthVariant = variant?.width
|
|
77
|
+
|
|
73
78
|
const getButtonTokens = useCallback(
|
|
74
79
|
(state) => {
|
|
75
80
|
const themeButtonTokens = themeButtonTokensCallback(state)
|
|
@@ -77,36 +82,93 @@ const ButtonGroup = React.forwardRef(
|
|
|
77
82
|
const shouldUseTransparentBackground =
|
|
78
83
|
isMobileNonContained && !state.selected && !state.pressed && !state.hover && !state.focus
|
|
79
84
|
|
|
85
|
+
let widthStyle
|
|
86
|
+
|
|
87
|
+
switch (buttonWidthVariant) {
|
|
88
|
+
case EQUAL_WIDTH:
|
|
89
|
+
widthStyle = staticStyles.equalWidth
|
|
90
|
+
break
|
|
91
|
+
case RESPONSIVE_WIDTH:
|
|
92
|
+
widthStyle = staticStyles.responsiveWidth
|
|
93
|
+
break
|
|
94
|
+
// no default
|
|
95
|
+
}
|
|
96
|
+
|
|
80
97
|
return {
|
|
81
98
|
...themeButtonTokens,
|
|
82
|
-
...
|
|
99
|
+
...widthStyle,
|
|
83
100
|
...(shouldUseTransparentBackground && { backgroundColor: 'transparent' }),
|
|
84
101
|
alignSelf: themeButtonTokens.width ? 'flex-start' : 'center'
|
|
85
102
|
}
|
|
86
103
|
},
|
|
87
|
-
[themeButtonTokensCallback, isMobileNonContained,
|
|
104
|
+
[themeButtonTokensCallback, isMobileNonContained, buttonWidthVariant]
|
|
88
105
|
)
|
|
89
106
|
|
|
90
|
-
const fieldsetStyles = useMemo(
|
|
91
|
-
|
|
92
|
-
|
|
107
|
+
const fieldsetStyles = useMemo(() => {
|
|
108
|
+
let fieldSetBase
|
|
109
|
+
switch (buttonWidthVariant) {
|
|
110
|
+
case EQUAL_WIDTH:
|
|
111
|
+
case RESPONSIVE_WIDTH:
|
|
112
|
+
fieldSetBase = staticStyles.fieldSetResponsive
|
|
113
|
+
break
|
|
114
|
+
default:
|
|
115
|
+
fieldSetBase = staticStyles.fieldsetBase
|
|
116
|
+
break
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
...fieldSetBase,
|
|
93
121
|
borderRadius,
|
|
94
122
|
backgroundColor: isMobileNonContained ? 'transparent' : backgroundColor || 'transparent',
|
|
95
|
-
padding
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
[borderRadius, backgroundColor, padding, variant?.width, isMobileNonContained]
|
|
99
|
-
)
|
|
123
|
+
padding
|
|
124
|
+
}
|
|
125
|
+
}, [borderRadius, backgroundColor, padding, isMobileNonContained, buttonWidthVariant])
|
|
100
126
|
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
127
|
+
const buttonsContainerStyles = useMemo(() => {
|
|
128
|
+
let flexWrap
|
|
129
|
+
if (isWeb) {
|
|
130
|
+
flexWrap = 'wrap'
|
|
131
|
+
} else {
|
|
132
|
+
switch (buttonWidthVariant) {
|
|
133
|
+
case EQUAL_WIDTH:
|
|
134
|
+
case RESPONSIVE_WIDTH:
|
|
135
|
+
flexWrap = 'nowrap'
|
|
136
|
+
break
|
|
137
|
+
default:
|
|
138
|
+
flexWrap = 'wrap'
|
|
139
|
+
break
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
let justifyContent
|
|
144
|
+
switch (buttonWidthVariant) {
|
|
145
|
+
case EQUAL_WIDTH:
|
|
146
|
+
justifyContent = 'space-evenly'
|
|
147
|
+
break
|
|
148
|
+
default:
|
|
149
|
+
justifyContent = 'flex-start'
|
|
150
|
+
break
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
let viewBaseStyle
|
|
154
|
+
switch (buttonWidthVariant) {
|
|
155
|
+
case EQUAL_WIDTH:
|
|
156
|
+
case RESPONSIVE_WIDTH:
|
|
157
|
+
viewBaseStyle = {}
|
|
158
|
+
break
|
|
159
|
+
default:
|
|
160
|
+
viewBaseStyle = staticStyles.viewBase
|
|
161
|
+
break
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
...viewBaseStyle,
|
|
166
|
+
flexWrap,
|
|
104
167
|
flexDirection: direction === 'column' ? 'column' : 'row',
|
|
105
168
|
gap: gapValue || 0,
|
|
106
|
-
justifyContent
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
)
|
|
169
|
+
justifyContent
|
|
170
|
+
}
|
|
171
|
+
}, [direction, gapValue, buttonWidthVariant, isWeb])
|
|
110
172
|
|
|
111
173
|
const { currentValues, toggleOneValue } = useMultipleInputValues({
|
|
112
174
|
initialValues,
|
|
@@ -128,7 +190,7 @@ const ButtonGroup = React.forwardRef(
|
|
|
128
190
|
}
|
|
129
191
|
|
|
130
192
|
// Some web screenreaders e.g. MacOS Voiceover don't handle radiogroups properly unless radio is direct child of radiogroup
|
|
131
|
-
const
|
|
193
|
+
const buttonsWrapperRole =
|
|
132
194
|
Platform.OS === 'web' && accessibilityRole === 'radiogroup' ? accessibilityRole : undefined
|
|
133
195
|
|
|
134
196
|
return (
|
|
@@ -149,7 +211,7 @@ const ButtonGroup = React.forwardRef(
|
|
|
149
211
|
style={fieldsetStyles}
|
|
150
212
|
{...selectProps(rest)}
|
|
151
213
|
>
|
|
152
|
-
<View accessibilityRole={
|
|
214
|
+
<View accessibilityRole={buttonsWrapperRole} style={buttonsContainerStyles}>
|
|
153
215
|
{items.map(
|
|
154
216
|
(
|
|
155
217
|
{
|
|
@@ -329,17 +391,24 @@ ButtonGroup.propTypes = {
|
|
|
329
391
|
}
|
|
330
392
|
|
|
331
393
|
const staticStyles = StyleSheet.create({
|
|
394
|
+
equalWidth: {
|
|
395
|
+
width: '100%',
|
|
396
|
+
flex: 1
|
|
397
|
+
},
|
|
398
|
+
responsiveWidth: {
|
|
399
|
+
width: 'auto'
|
|
400
|
+
},
|
|
332
401
|
fieldsetBase: {
|
|
333
402
|
alignSelf: 'flex-start',
|
|
334
|
-
display: 'inline'
|
|
403
|
+
display: 'inline',
|
|
404
|
+
width: 'auto'
|
|
405
|
+
},
|
|
406
|
+
fieldSetResponsive: {
|
|
407
|
+
width: '100%'
|
|
335
408
|
},
|
|
336
409
|
viewBase: {
|
|
337
410
|
flexWrap: 'wrap',
|
|
338
411
|
alignItems: 'center'
|
|
339
|
-
},
|
|
340
|
-
equalWidth: {
|
|
341
|
-
width: '100%',
|
|
342
|
-
flex: 1
|
|
343
412
|
}
|
|
344
413
|
})
|
|
345
414
|
|