@oxyhq/bloom 0.6.1 → 0.6.3
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/lib/commonjs/context-menu/index.web.js +6 -2
- package/lib/commonjs/context-menu/index.web.js.map +1 -1
- package/lib/commonjs/dialog/Dialog.web.js +7 -2
- package/lib/commonjs/dialog/Dialog.web.js.map +1 -1
- package/lib/commonjs/menu/index.web.js +3 -1
- package/lib/commonjs/menu/index.web.js.map +1 -1
- package/lib/commonjs/portal/index.web.js +23 -3
- package/lib/commonjs/portal/index.web.js.map +1 -1
- package/lib/commonjs/prompt-input/PromptInput.js +4 -1
- package/lib/commonjs/prompt-input/PromptInput.js.map +1 -1
- package/lib/commonjs/segmented-control/index.js +48 -11
- package/lib/commonjs/segmented-control/index.js.map +1 -1
- package/lib/commonjs/select/index.web.js +6 -2
- package/lib/commonjs/select/index.web.js.map +1 -1
- package/lib/module/context-menu/index.web.js +6 -2
- package/lib/module/context-menu/index.web.js.map +1 -1
- package/lib/module/dialog/Dialog.web.js +7 -2
- package/lib/module/dialog/Dialog.web.js.map +1 -1
- package/lib/module/menu/index.web.js +3 -1
- package/lib/module/menu/index.web.js.map +1 -1
- package/lib/module/portal/index.web.js +23 -3
- package/lib/module/portal/index.web.js.map +1 -1
- package/lib/module/prompt-input/PromptInput.js +4 -1
- package/lib/module/prompt-input/PromptInput.js.map +1 -1
- package/lib/module/segmented-control/index.js +49 -12
- package/lib/module/segmented-control/index.js.map +1 -1
- package/lib/module/select/index.web.js +6 -2
- package/lib/module/select/index.web.js.map +1 -1
- package/lib/typescript/commonjs/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/portal/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/prompt-input/PromptInput.d.ts.map +1 -1
- package/lib/typescript/commonjs/segmented-control/index.d.ts +9 -4
- package/lib/typescript/commonjs/segmented-control/index.d.ts.map +1 -1
- package/lib/typescript/module/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/module/portal/index.web.d.ts.map +1 -1
- package/lib/typescript/module/prompt-input/PromptInput.d.ts.map +1 -1
- package/lib/typescript/module/segmented-control/index.d.ts +9 -4
- package/lib/typescript/module/segmented-control/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/context-menu/index.web.tsx +4 -0
- package/src/dialog/Dialog.web.tsx +4 -0
- package/src/menu/index.web.tsx +2 -0
- package/src/portal/index.web.tsx +23 -3
- package/src/prompt-input/PromptInput.tsx +3 -0
- package/src/segmented-control/index.tsx +65 -14
- package/src/select/index.web.tsx +4 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/segmented-control/index.tsx"],"names":[],"mappings":"AASA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/segmented-control/index.tsx"],"names":[],"mappings":"AASA,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,IAAI,EACJ,KAAK,SAAS,EAEd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAkBtB;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,EAAE,EACrC,KAAK,EACL,IAAc,EACd,IAAc,EACd,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,iBAAiB,GAClB,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IACzB,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC7B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,2CAoEA;AAMD,wBAAgB,IAAI,CAAC,EACnB,KAAK,EACL,KAAK,EACL,QAAQ,EACR,OAAO,EAAE,WAAW,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,MAAM,EACN,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;CACvC,2CA2FA;AAED,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,QAAQ,EACR,GAAG,KAAK,EACT,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,GAAG,IAAI,CACnE,KAAK,CAAC,cAAc,CAAC,OAAO,IAAI,CAAC,EACjC,OAAO,GAAG,UAAU,CACrB,2CAyBA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.web.d.ts","sourceRoot":"","sources":["../../../../src/dialog/Dialog.web.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EACV,YAAY,EAGZ,WAAW,EACZ,MAAM,SAAS,CAAC;AAQjB;;;;;;;;;;;;GAYG;AACH,wBAAgB,MAAM,CAAC,EACrB,OAAO,EACP,OAAO,EACP,MAAM,EACN,KAAK,EACL,WAAW,EACX,OAAO,EACP,KAAK,EACL,KAAK,EACL,QAAQ,GACT,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"Dialog.web.d.ts","sourceRoot":"","sources":["../../../../src/dialog/Dialog.web.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EACV,YAAY,EAGZ,WAAW,EACZ,MAAM,SAAS,CAAC;AAQjB;;;;;;;;;;;;GAYG;AACH,wBAAgB,MAAM,CAAC,EACrB,OAAO,EACP,OAAO,EACP,MAAM,EACN,KAAK,EACL,WAAW,EACX,OAAO,EACP,KAAK,EACL,KAAK,EACL,QAAQ,GACT,EAAE,WAAW,kDA4Gb;AA8LD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,WAAW,EACX,OAAO,EACP,SAAS,GACV,EAAE;IACD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB,2CAgBA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,mZAK5B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.web.d.ts","sourceRoot":"","sources":["../../../../src/portal/index.web.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAoD,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.web.d.ts","sourceRoot":"","sources":["../../../../src/portal/index.web.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAoD,MAAM,OAAO,CAAC;AA6CzE,wBAAgB,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,4BAOnE;AAKD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,2CAE9D;AAED,eAAO,MAAM,MAAM,oCAEjB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PromptInput.d.ts","sourceRoot":"","sources":["../../../../src/prompt-input/PromptInput.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,wBAAgB,WAAW,CAAC,EAC1B,SAAiB,EACjB,SAAe,EACf,KAAK,EACL,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,QAAgB,EAChB,YAAY,EACZ,WAAW,EACX,WAAW,EACX,MAAM,EACN,WAAW,EACX,WAAW,EAAE,qBAAqB,EAClC,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,wBAAgC,EAChC,UAAU,EACV,YAAY,EACZ,MAAM,GACP,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"PromptInput.d.ts","sourceRoot":"","sources":["../../../../src/prompt-input/PromptInput.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,wBAAgB,WAAW,CAAC,EAC1B,SAAiB,EACjB,SAAe,EACf,KAAK,EACL,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,QAAgB,EAChB,YAAY,EACZ,WAAW,EACX,WAAW,EACX,MAAM,EACN,WAAW,EACX,WAAW,EAAE,qBAAqB,EAClC,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,wBAAgC,EAChC,UAAU,EACV,YAAY,EACZ,MAAM,GACP,EAAE,gBAAgB,2CA+NlB;yBArPe,WAAW"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { type StyleProp, Text, type TextStyle, type ViewStyle } from 'react-native';
|
|
2
|
-
import { type ButtonProps } from '../button';
|
|
1
|
+
import { type PressableProps, type StyleProp, Text, type TextStyle, type ViewStyle } from 'react-native';
|
|
3
2
|
/**
|
|
4
3
|
* Segmented control component.
|
|
5
4
|
*
|
|
@@ -29,10 +28,16 @@ export declare function Root<T extends string>({ label, type, size, value, onCha
|
|
|
29
28
|
style?: StyleProp<ViewStyle>;
|
|
30
29
|
accessibilityHint?: string;
|
|
31
30
|
}): import("react/jsx-runtime").JSX.Element;
|
|
32
|
-
export declare function Item({ value, style, children, onPress: onPressProp,
|
|
31
|
+
export declare function Item({ value, style, children, onPress: onPressProp, accessibilityLabel, accessibilityHint, testID, disabled, }: {
|
|
33
32
|
value: string;
|
|
34
33
|
children: React.ReactNode;
|
|
35
|
-
|
|
34
|
+
style?: StyleProp<ViewStyle>;
|
|
35
|
+
onPress?: () => void;
|
|
36
|
+
accessibilityLabel?: string;
|
|
37
|
+
accessibilityHint?: string;
|
|
38
|
+
testID?: string;
|
|
39
|
+
disabled?: PressableProps['disabled'];
|
|
40
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
36
41
|
export declare function ItemText({ style, children, ...props }: {
|
|
37
42
|
children: React.ReactNode;
|
|
38
43
|
style?: StyleProp<TextStyle>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/segmented-control/index.tsx"],"names":[],"mappings":"AASA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/segmented-control/index.tsx"],"names":[],"mappings":"AASA,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,IAAI,EACJ,KAAK,SAAS,EAEd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAkBtB;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,EAAE,EACrC,KAAK,EACL,IAAc,EACd,IAAc,EACd,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,iBAAiB,GAClB,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IACzB,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC7B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,2CAoEA;AAMD,wBAAgB,IAAI,CAAC,EACnB,KAAK,EACL,KAAK,EACL,QAAQ,EACR,OAAO,EAAE,WAAW,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,MAAM,EACN,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;CACvC,2CA2FA;AAED,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,QAAQ,EACR,GAAG,KAAK,EACT,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,GAAG,IAAI,CACnE,KAAK,CAAC,cAAc,CAAC,OAAO,IAAI,CAAC,EACjC,OAAO,GAAG,UAAU,CACrB,2CAyBA"}
|
package/package.json
CHANGED
|
@@ -328,6 +328,8 @@ const styles = StyleSheet.create({
|
|
|
328
328
|
right: 0,
|
|
329
329
|
bottom: 0,
|
|
330
330
|
zIndex: 50,
|
|
331
|
+
// Opt back in from the Portal root's `pointer-events: none`.
|
|
332
|
+
pointerEvents: 'auto',
|
|
331
333
|
},
|
|
332
334
|
dropdown: {
|
|
333
335
|
position: 'fixed' as 'absolute',
|
|
@@ -341,6 +343,8 @@ const styles = StyleSheet.create({
|
|
|
341
343
|
shadowOffset: { width: 0, height: 4 },
|
|
342
344
|
minWidth: 180,
|
|
343
345
|
maxWidth: 280,
|
|
346
|
+
// Opt back in from the Portal root's `pointer-events: none`.
|
|
347
|
+
pointerEvents: 'auto',
|
|
344
348
|
},
|
|
345
349
|
item: {
|
|
346
350
|
flexDirection: 'row',
|
|
@@ -134,6 +134,9 @@ export function Dialog({
|
|
|
134
134
|
<RemoveScrollBar />
|
|
135
135
|
<Pressable
|
|
136
136
|
onPress={() => close()}
|
|
137
|
+
// `pointerEvents: 'auto'` opts back in from the Portal root's
|
|
138
|
+
// `pointer-events: none`, which is set so the idle portal
|
|
139
|
+
// doesn't intercept clicks on the underlying app.
|
|
137
140
|
style={{
|
|
138
141
|
position: 'fixed' as 'absolute',
|
|
139
142
|
top: 0,
|
|
@@ -144,6 +147,7 @@ export function Dialog({
|
|
|
144
147
|
alignItems: 'center',
|
|
145
148
|
justifyContent: 'center',
|
|
146
149
|
paddingHorizontal: 20,
|
|
150
|
+
pointerEvents: 'auto',
|
|
147
151
|
}}
|
|
148
152
|
>
|
|
149
153
|
<DialogBackdrop isClosing={isClosing} />
|
package/src/menu/index.web.tsx
CHANGED
package/src/portal/index.web.tsx
CHANGED
|
@@ -17,7 +17,20 @@ import React, { Fragment, memo, useLayoutEffect, useState } from 'react';
|
|
|
17
17
|
import { createPortal } from 'react-dom';
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
* Render children into a stable container
|
|
20
|
+
* Render children into a stable container appended to `document.body`.
|
|
21
|
+
*
|
|
22
|
+
* The container is positioned `fixed` and stretched edge-to-edge so it
|
|
23
|
+
* fills the viewport. This makes it a valid containing block for any
|
|
24
|
+
* portaled descendant that uses `position: absolute` (e.g. RN's
|
|
25
|
+
* `StyleSheet.absoluteFillObject`) — without it those children anchor to a
|
|
26
|
+
* zero-area block at the end of `<body>` and render off-screen.
|
|
27
|
+
*
|
|
28
|
+
* `pointer-events: none` lets clicks fall through to the underlying app
|
|
29
|
+
* while the portal is idle. Interactive descendants (backdrops, modal
|
|
30
|
+
* panels, dropdowns, etc.) must opt back in with `pointer-events: auto`
|
|
31
|
+
* (or RN's `pointerEvents="auto"` / `"box-only"`). Bloom's own overlay
|
|
32
|
+
* components do this on the elements they actually want to receive
|
|
33
|
+
* events.
|
|
21
34
|
*
|
|
22
35
|
* Lazy-creates the container on first mount so SSR (where `document` does
|
|
23
36
|
* not exist) doesn't crash — the portal simply renders nothing on the
|
|
@@ -29,9 +42,16 @@ function getPortalRoot(): HTMLElement | null {
|
|
|
29
42
|
if (!root) {
|
|
30
43
|
root = document.createElement('div');
|
|
31
44
|
root.id = 'bloom-portal-root';
|
|
32
|
-
|
|
45
|
+
root.style.position = 'fixed';
|
|
46
|
+
root.style.top = '0';
|
|
47
|
+
root.style.left = '0';
|
|
48
|
+
root.style.right = '0';
|
|
49
|
+
root.style.bottom = '0';
|
|
50
|
+
// Idle portal must not intercept clicks on the underlying app.
|
|
51
|
+
// Children opt back in to receive events via their own pointer-events.
|
|
52
|
+
root.style.pointerEvents = 'none';
|
|
53
|
+
// Above the document flow; individual portaled components can use
|
|
33
54
|
// their own z-index for stacking among themselves.
|
|
34
|
-
root.style.position = 'relative';
|
|
35
55
|
root.style.zIndex = '999999';
|
|
36
56
|
document.body.appendChild(root);
|
|
37
57
|
}
|
|
@@ -235,6 +235,9 @@ export function PromptInput({
|
|
|
235
235
|
{
|
|
236
236
|
zIndex: 9998,
|
|
237
237
|
backgroundColor: theme.colors.background,
|
|
238
|
+
// Opt back in from the Portal root's `pointer-events: none`
|
|
239
|
+
// (web only — harmless on native).
|
|
240
|
+
pointerEvents: 'auto',
|
|
238
241
|
},
|
|
239
242
|
]}
|
|
240
243
|
>
|
|
@@ -7,12 +7,20 @@ import {
|
|
|
7
7
|
useRef,
|
|
8
8
|
useState,
|
|
9
9
|
} from 'react';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
Platform,
|
|
12
|
+
Pressable,
|
|
13
|
+
type PressableProps,
|
|
14
|
+
type StyleProp,
|
|
15
|
+
Text,
|
|
16
|
+
type TextStyle,
|
|
17
|
+
View,
|
|
18
|
+
type ViewStyle,
|
|
19
|
+
} from 'react-native';
|
|
11
20
|
import Animated, { Easing, LinearTransition } from 'react-native-reanimated';
|
|
12
21
|
|
|
13
22
|
import { useTheme } from '../theme/use-theme';
|
|
14
23
|
import { atoms as a, platform } from '../styles';
|
|
15
|
-
import { Button, type ButtonProps } from '../button';
|
|
16
24
|
|
|
17
25
|
const InternalContext = createContext<{
|
|
18
26
|
type: 'tabs' | 'radio';
|
|
@@ -98,17 +106,27 @@ export function Root<T extends string>({
|
|
|
98
106
|
};
|
|
99
107
|
}, [value, selectedPosition, setSelectedPosition, onChange, type, size]);
|
|
100
108
|
|
|
109
|
+
// Height of the wrapping pill matches the active item height (item
|
|
110
|
+
// `minHeight` + 4px outer `p_xs` padding on both sides). Locking the
|
|
111
|
+
// outer View to this exact height keeps the control as a tight inline
|
|
112
|
+
// pill on every platform — without it, a parent column flex context
|
|
113
|
+
// (the default on a `<View>`) would let the Root stretch vertically
|
|
114
|
+
// and the items inside would inherit that stretched height, blowing
|
|
115
|
+
// the control up into a giant block on native.
|
|
116
|
+
const itemMinHeight = size === 'large' ? 40 : 32;
|
|
117
|
+
const pillHeight = itemMinHeight + 8;
|
|
118
|
+
|
|
101
119
|
return (
|
|
102
120
|
<View
|
|
103
121
|
accessibilityLabel={label}
|
|
104
122
|
accessibilityHint={accessibilityHint ?? ''}
|
|
105
123
|
style={[
|
|
106
124
|
a.w_full,
|
|
107
|
-
a.flex_1,
|
|
108
125
|
a.relative,
|
|
109
126
|
a.flex_row,
|
|
127
|
+
a.align_center,
|
|
110
128
|
{ backgroundColor: theme.colors.contrast50 },
|
|
111
|
-
{ borderRadius: 14 },
|
|
129
|
+
{ borderRadius: 14, height: pillHeight },
|
|
112
130
|
a.p_xs,
|
|
113
131
|
style,
|
|
114
132
|
]}
|
|
@@ -132,8 +150,20 @@ export function Item({
|
|
|
132
150
|
style,
|
|
133
151
|
children,
|
|
134
152
|
onPress: onPressProp,
|
|
135
|
-
|
|
136
|
-
|
|
153
|
+
accessibilityLabel,
|
|
154
|
+
accessibilityHint,
|
|
155
|
+
testID,
|
|
156
|
+
disabled,
|
|
157
|
+
}: {
|
|
158
|
+
value: string;
|
|
159
|
+
children: React.ReactNode;
|
|
160
|
+
style?: StyleProp<ViewStyle>;
|
|
161
|
+
onPress?: () => void;
|
|
162
|
+
accessibilityLabel?: string;
|
|
163
|
+
accessibilityHint?: string;
|
|
164
|
+
testID?: string;
|
|
165
|
+
disabled?: PressableProps['disabled'];
|
|
166
|
+
}) {
|
|
137
167
|
const [position, setPosition] = useState<{ x: number; width: number } | null>(
|
|
138
168
|
null,
|
|
139
169
|
);
|
|
@@ -171,9 +201,23 @@ export function Item({
|
|
|
171
201
|
onPressProp?.();
|
|
172
202
|
}, [ctx, value, position, onPressProp]);
|
|
173
203
|
|
|
204
|
+
// We render the segment as a flat `Pressable` (not Bloom's `Button`)
|
|
205
|
+
// for two reasons:
|
|
206
|
+
// 1. Layout: we need the touch target to participate directly in the
|
|
207
|
+
// Root's row flex layout so `flex: 1` distributes the items
|
|
208
|
+
// evenly on every platform. Bloom Button wraps its Pressable in
|
|
209
|
+
// an Animated.View that doesn't forward layout-affecting styles,
|
|
210
|
+
// which would collapse the segment to its natural text width.
|
|
211
|
+
// 2. Semantics: the Root carries `role="tablist"`/`"radiogroup"` and
|
|
212
|
+
// each item carries `role="tab"`/`"radio"`. Bloom Button always
|
|
213
|
+
// adds `accessibilityRole="button"` — that overrides the correct
|
|
214
|
+
// a11y role for tablist children.
|
|
215
|
+
const itemRole = ctx.type === 'tabs' ? 'tab' : 'radio';
|
|
216
|
+
const itemMinHeight = ctx.size === 'large' ? 40 : 32;
|
|
217
|
+
|
|
174
218
|
return (
|
|
175
219
|
<View
|
|
176
|
-
style={[a.flex_1, a.flex_row]}
|
|
220
|
+
style={[a.flex_1, a.flex_row, a.align_stretch]}
|
|
177
221
|
onLayout={evt => {
|
|
178
222
|
const measuredPosition = {
|
|
179
223
|
x: evt.nativeEvent.layout.x,
|
|
@@ -184,23 +228,30 @@ export function Item({
|
|
|
184
228
|
}
|
|
185
229
|
setPosition(measuredPosition);
|
|
186
230
|
}}>
|
|
187
|
-
<
|
|
188
|
-
{...props}
|
|
231
|
+
<Pressable
|
|
189
232
|
onPress={onPress}
|
|
190
|
-
accessibilityLabel={
|
|
191
|
-
accessibilityHint={
|
|
192
|
-
|
|
233
|
+
accessibilityLabel={accessibilityLabel}
|
|
234
|
+
accessibilityHint={accessibilityHint}
|
|
235
|
+
accessibilityState={{ selected: active, disabled: !!disabled }}
|
|
236
|
+
role={itemRole}
|
|
237
|
+
disabled={disabled}
|
|
238
|
+
testID={testID}
|
|
239
|
+
style={({ pressed }) => [
|
|
193
240
|
a.flex_1,
|
|
241
|
+
a.flex_row,
|
|
242
|
+
a.align_center,
|
|
243
|
+
a.justify_center,
|
|
194
244
|
a.bg_transparent,
|
|
195
245
|
a.px_sm,
|
|
196
246
|
a.py_xs,
|
|
197
|
-
{ minHeight:
|
|
247
|
+
{ minHeight: itemMinHeight, borderRadius: 10 },
|
|
248
|
+
pressed && !disabled && { opacity: 0.7 },
|
|
198
249
|
style,
|
|
199
250
|
]}>
|
|
200
251
|
<InternalItemContext.Provider value={{ active }}>
|
|
201
252
|
{children}
|
|
202
253
|
</InternalItemContext.Provider>
|
|
203
|
-
</
|
|
254
|
+
</Pressable>
|
|
204
255
|
</View>
|
|
205
256
|
);
|
|
206
257
|
}
|
package/src/select/index.web.tsx
CHANGED
|
@@ -338,6 +338,8 @@ const styles = StyleSheet.create({
|
|
|
338
338
|
right: 0,
|
|
339
339
|
bottom: 0,
|
|
340
340
|
zIndex: 50,
|
|
341
|
+
// Opt back in from the Portal root's `pointer-events: none`.
|
|
342
|
+
pointerEvents: 'auto',
|
|
341
343
|
},
|
|
342
344
|
dropdown: {
|
|
343
345
|
position: 'absolute',
|
|
@@ -350,6 +352,8 @@ const styles = StyleSheet.create({
|
|
|
350
352
|
shadowOpacity: 0.15,
|
|
351
353
|
shadowRadius: 12,
|
|
352
354
|
shadowOffset: { width: 0, height: 4 },
|
|
355
|
+
// Opt back in from the Portal root's `pointer-events: none`.
|
|
356
|
+
pointerEvents: 'auto',
|
|
353
357
|
},
|
|
354
358
|
item: {
|
|
355
359
|
position: 'relative',
|