@oxy.so/bloom 4.23.0 → 4.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/adoption-matrix.mdx +10 -10
- package/docs/ai-chat.mdx +7 -3
- package/docs/bottom-sheet.mdx +2 -0
- package/docs/dialog.mdx +28 -0
- package/docs/sidebar.mdx +2 -0
- package/lib/commonjs/ai-chat/AiChatContainer.js +22 -11
- package/lib/commonjs/ai-chat/AiChatContainer.js.map +1 -1
- package/lib/commonjs/ai-chat/AiChatShell.js +8 -2
- package/lib/commonjs/ai-chat/AiChatShell.js.map +1 -1
- package/lib/commonjs/ai-chat/use-panel-interaction.js +20 -33
- package/lib/commonjs/ai-chat/use-panel-interaction.js.map +1 -1
- package/lib/commonjs/bottom-bar/BottomBarBase.js +5 -2
- package/lib/commonjs/bottom-bar/BottomBarBase.js.map +1 -1
- package/lib/commonjs/bottom-sheet/BottomSheetBase.js +10 -3
- package/lib/commonjs/bottom-sheet/BottomSheetBase.js.map +1 -1
- package/lib/commonjs/dialog/Dialog.web.js +28 -22
- package/lib/commonjs/dialog/Dialog.web.js.map +1 -1
- package/lib/commonjs/dialog/DialogBottomSheet.js +9 -4
- package/lib/commonjs/dialog/DialogBottomSheet.js.map +1 -1
- package/lib/commonjs/overlay/ModalKeyboard.js +88 -0
- package/lib/commonjs/overlay/ModalKeyboard.js.map +1 -0
- package/lib/commonjs/overlay/modal-keyboard.js +131 -0
- package/lib/commonjs/overlay/modal-keyboard.js.map +1 -0
- package/lib/commonjs/overlay/stack.js +16 -0
- package/lib/commonjs/overlay/stack.js.map +1 -1
- package/lib/commonjs/sidebar/Sidebar.js +18 -6
- package/lib/commonjs/sidebar/Sidebar.js.map +1 -1
- package/lib/module/ai-chat/AiChatContainer.js +22 -11
- package/lib/module/ai-chat/AiChatContainer.js.map +1 -1
- package/lib/module/ai-chat/AiChatShell.js +8 -2
- package/lib/module/ai-chat/AiChatShell.js.map +1 -1
- package/lib/module/ai-chat/use-panel-interaction.js +20 -32
- package/lib/module/ai-chat/use-panel-interaction.js.map +1 -1
- package/lib/module/bottom-bar/BottomBarBase.js +5 -2
- package/lib/module/bottom-bar/BottomBarBase.js.map +1 -1
- package/lib/module/bottom-sheet/BottomSheetBase.js +10 -3
- package/lib/module/bottom-sheet/BottomSheetBase.js.map +1 -1
- package/lib/module/dialog/Dialog.web.js +28 -22
- package/lib/module/dialog/Dialog.web.js.map +1 -1
- package/lib/module/dialog/DialogBottomSheet.js +9 -4
- package/lib/module/dialog/DialogBottomSheet.js.map +1 -1
- package/lib/module/overlay/ModalKeyboard.js +84 -0
- package/lib/module/overlay/ModalKeyboard.js.map +1 -0
- package/lib/module/overlay/modal-keyboard.js +124 -0
- package/lib/module/overlay/modal-keyboard.js.map +1 -0
- package/lib/module/overlay/stack.js +15 -0
- package/lib/module/overlay/stack.js.map +1 -1
- package/lib/module/sidebar/Sidebar.js +18 -6
- package/lib/module/sidebar/Sidebar.js.map +1 -1
- package/lib/typescript/commonjs/ai-chat/AiChatContainer.d.ts +5 -4
- package/lib/typescript/commonjs/ai-chat/AiChatContainer.d.ts.map +1 -1
- package/lib/typescript/commonjs/ai-chat/AiChatShell.d.ts.map +1 -1
- package/lib/typescript/commonjs/ai-chat/use-panel-interaction.d.ts +10 -1
- package/lib/typescript/commonjs/ai-chat/use-panel-interaction.d.ts.map +1 -1
- package/lib/typescript/commonjs/bottom-bar/BottomBarBase.d.ts.map +1 -1
- package/lib/typescript/commonjs/bottom-sheet/BottomSheetBase.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/DialogBottomSheet.d.ts.map +1 -1
- package/lib/typescript/commonjs/overlay/ModalKeyboard.d.ts +32 -0
- package/lib/typescript/commonjs/overlay/ModalKeyboard.d.ts.map +1 -0
- package/lib/typescript/commonjs/overlay/modal-keyboard.d.ts +17 -0
- package/lib/typescript/commonjs/overlay/modal-keyboard.d.ts.map +1 -0
- package/lib/typescript/commonjs/overlay/stack.d.ts +6 -0
- package/lib/typescript/commonjs/overlay/stack.d.ts.map +1 -1
- package/lib/typescript/commonjs/sidebar/Sidebar.d.ts.map +1 -1
- package/lib/typescript/module/ai-chat/AiChatContainer.d.ts +5 -4
- package/lib/typescript/module/ai-chat/AiChatContainer.d.ts.map +1 -1
- package/lib/typescript/module/ai-chat/AiChatShell.d.ts.map +1 -1
- package/lib/typescript/module/ai-chat/use-panel-interaction.d.ts +10 -1
- package/lib/typescript/module/ai-chat/use-panel-interaction.d.ts.map +1 -1
- package/lib/typescript/module/bottom-bar/BottomBarBase.d.ts.map +1 -1
- package/lib/typescript/module/bottom-sheet/BottomSheetBase.d.ts.map +1 -1
- package/lib/typescript/module/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/module/dialog/DialogBottomSheet.d.ts.map +1 -1
- package/lib/typescript/module/overlay/ModalKeyboard.d.ts +32 -0
- package/lib/typescript/module/overlay/ModalKeyboard.d.ts.map +1 -0
- package/lib/typescript/module/overlay/modal-keyboard.d.ts +17 -0
- package/lib/typescript/module/overlay/modal-keyboard.d.ts.map +1 -0
- package/lib/typescript/module/overlay/stack.d.ts +6 -0
- package/lib/typescript/module/overlay/stack.d.ts.map +1 -1
- package/lib/typescript/module/sidebar/Sidebar.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/ai-chat/AiChatContainer.tsx +18 -8
- package/src/ai-chat/AiChatShell.tsx +12 -2
- package/src/ai-chat/use-panel-interaction.ts +20 -34
- package/src/bottom-bar/BottomBarBase.tsx +5 -2
- package/src/bottom-sheet/BottomSheetBase.tsx +8 -0
- package/src/dialog/Dialog.web.tsx +22 -18
- package/src/dialog/DialogBottomSheet.tsx +9 -4
- package/src/overlay/ModalKeyboard.tsx +88 -0
- package/src/overlay/modal-keyboard.ts +133 -0
- package/src/overlay/stack.ts +13 -0
- package/src/sidebar/Sidebar.tsx +13 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiChatShell.d.ts","sourceRoot":"","sources":["../../../../src/ai-chat/AiChatShell.tsx"],"names":[],"mappings":"AACA,OAAO,EAML,KAAK,qBAAqB,EAI3B,MAAM,cAAc,CAAC;AA4BtB,OAAO,KAAK,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AA4DlG;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,aAAa,EACb,QAAQ,EACR,WAAW,EACX,KAA6B,EAC7B,OAAO,EACP,KAAK,EACL,MAAM,GACP,EAAE,uBAAuB,2CAoHzB;AAMD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,uBAAuB,kDAoCnF;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,YAAY,EACZ,gBAAwB,EACxB,qBAAqB,EACrB,aAAa,EACb,QAAQ,EACR,KAAK,EACL,UAAmB,EACnB,SAAuB,EACvB,iBAAuB,EACvB,aAAmB,EACnB,aAAmB,EACnB,OAAO,EAAE,WAAW,EACpB,eAAe,EACf,eAAsB,EACtB,SAAS,EAAE,aAAa,EACxB,iBAAiB,EACjB,UAAU,EACV,OAAc,EACd,MAAoB,EACpB,MAAM,EACN,KAAK,EACL,MAAM,GACP,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"AiChatShell.d.ts","sourceRoot":"","sources":["../../../../src/ai-chat/AiChatShell.tsx"],"names":[],"mappings":"AACA,OAAO,EAML,KAAK,qBAAqB,EAI3B,MAAM,cAAc,CAAC;AA4BtB,OAAO,KAAK,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AA4DlG;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,aAAa,EACb,QAAQ,EACR,WAAW,EACX,KAA6B,EAC7B,OAAO,EACP,KAAK,EACL,MAAM,GACP,EAAE,uBAAuB,2CAoHzB;AAMD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,uBAAuB,kDAoCnF;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,YAAY,EACZ,gBAAwB,EACxB,qBAAqB,EACrB,aAAa,EACb,QAAQ,EACR,KAAK,EACL,UAAmB,EACnB,SAAuB,EACvB,iBAAuB,EACvB,aAAmB,EACnB,aAAmB,EACnB,OAAO,EAAE,WAAW,EACpB,eAAe,EACf,eAAsB,EACtB,SAAS,EAAE,aAAa,EACxB,iBAAiB,EACjB,UAAU,EACV,OAAc,EACd,MAAoB,EACpB,MAAM,EACN,KAAK,EACL,MAAM,GACP,EAAE,gBAAgB,2CAoalB;AAED,YAAY,EAAE,qBAAqB,EAAE,CAAC"}
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import { type View } from 'react-native';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* Interaction only: the shell continues to own the drawer's layout and motion.
|
|
4
|
+
* Used by both shell drawers — the panel and the navigation.
|
|
5
|
+
*
|
|
6
|
+
* open Escape (web) and back (Android) close it
|
|
7
|
+
* modal it covers the workspace: focus moves in on open, Tab is kept
|
|
8
|
+
* inside, and focus goes back to the opener on close
|
|
9
|
+
*
|
|
10
|
+
* Any portaled overlay above (a dialog, a menu) takes all of it first.
|
|
11
|
+
*/
|
|
3
12
|
export declare function usePanelInteraction(open: boolean, modal: boolean, close: () => void): import("react").RefObject<View | null>;
|
|
4
13
|
//# sourceMappingURL=use-panel-interaction.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-panel-interaction.d.ts","sourceRoot":"","sources":["../../../../src/ai-chat/use-panel-interaction.ts"],"names":[],"mappings":"AACA,OAAO,EAAyB,KAAK,IAAI,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"use-panel-interaction.d.ts","sourceRoot":"","sources":["../../../../src/ai-chat/use-panel-interaction.ts"],"names":[],"mappings":"AACA,OAAO,EAAyB,KAAK,IAAI,EAAE,MAAM,cAAc,CAAC;AAKhE;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,0CAwCnF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BottomBarBase.d.ts","sourceRoot":"","sources":["../../../../src/bottom-bar/BottomBarBase.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAYzE,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,UAAU,KAAM,SAAQ,cAAc;IACpC,UAAU,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IACvC,IAAI,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IACvC,IAAI,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;CAC3C;AACD,wBAAgB,aAAa,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,EAC3H,eAAwB,EAAE,cAAuB,EAAE,QAAwB,EAAE,gBAAgB,EAAE,IAAW,EAAE,QAAc,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"BottomBarBase.d.ts","sourceRoot":"","sources":["../../../../src/bottom-bar/BottomBarBase.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAYzE,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,UAAU,KAAM,SAAQ,cAAc;IACpC,UAAU,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IACvC,IAAI,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IACvC,IAAI,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;CAC3C;AACD,wBAAgB,aAAa,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,EAC3H,eAAwB,EAAE,cAAuB,EAAE,QAAwB,EAAE,gBAAgB,EAAE,IAAW,EAAE,QAAc,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,kDAyEnJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BottomSheetBase.d.ts","sourceRoot":"","sources":["../../../../src/bottom-sheet/BottomSheetBase.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"BottomSheetBase.d.ts","sourceRoot":"","sources":["../../../../src/bottom-sheet/BottomSheetBase.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAoC/B,OAAO,KAAK,EAAE,cAAc,EAA2C,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAsB7G,eAAO,MAAM,eAAe,6FA8rB1B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.web.d.ts","sourceRoot":"","sources":["../../../../src/dialog/Dialog.web.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Dialog.web.d.ts","sourceRoot":"","sources":["../../../../src/dialog/Dialog.web.tsx"],"names":[],"mappings":"AA4EA,OAAO,KAAK,EAIV,WAAW,EACZ,MAAM,SAAS,CAAC;AAmDjB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,WAAW,2CAazD;AAiuBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,gBAAgB,8PAG5B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DialogBottomSheet.d.ts","sourceRoot":"","sources":["../../../../src/dialog/DialogBottomSheet.tsx"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAsB,WAAW,EAAE,MAAM,SAAS,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,IAAI,EAAE,cAAc,EACpB,SAAS,EACT,OAAO,EACP,MAAM,EACN,KAAK,EACL,WAAW,EACX,OAAO,EACP,MAAM,EACN,cAAyC,EACzC,UAAiB,EACjB,iBAAwB,EACxB,cAA+C,EAC/C,UAAU,EACV,KAAK,EACL,KAAK,EACL,UAAU,EACV,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,KAAK,EACL,QAAQ,GACT,EAAE,sBAAsB,
|
|
1
|
+
{"version":3,"file":"DialogBottomSheet.d.ts","sourceRoot":"","sources":["../../../../src/dialog/DialogBottomSheet.tsx"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAsB,WAAW,EAAE,MAAM,SAAS,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,IAAI,EAAE,cAAc,EACpB,SAAS,EACT,OAAO,EACP,MAAM,EACN,KAAK,EACL,WAAW,EACX,OAAO,EACP,MAAM,EACN,cAAyC,EACzC,UAAiB,EACjB,iBAAwB,EACxB,cAA+C,EAC/C,UAAU,EACV,KAAK,EACL,KAAK,EACL,UAAU,EACV,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,KAAK,EACL,QAAQ,GACT,EAAE,sBAAsB,2CAkRxB;AAQD;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,WAAW,EACT,SAAS,GACT,MAAM,GACN,WAAW,GACX,SAAS,GACT,QAAQ,GACR,OAAO,GACP,aAAa,GACb,SAAS,GACT,QAAQ,GACR,gBAAgB,GAChB,YAAY,GACZ,mBAAmB,GACnB,gBAAgB,GAChB,YAAY,GACZ,OAAO,GACP,OAAO,GACP,YAAY,GACZ,gBAAgB,GAChB,gBAAgB,GAChB,oBAAoB,GACpB,OAAO,GACP,UAAU,CACb,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { View } from 'react-native';
|
|
3
|
+
export interface ModalKeyboardProps {
|
|
4
|
+
/** The surface's panel: where focus goes, and what Tab stays inside. */
|
|
5
|
+
panelRef: React.RefObject<View | null>;
|
|
6
|
+
/** The surface has started its exit: focus goes back now, Escape is spent. */
|
|
7
|
+
closing?: boolean;
|
|
8
|
+
/** Whether Escape may dismiss it (a dialog's `dismissOnBackdrop`). */
|
|
9
|
+
dismissible: boolean;
|
|
10
|
+
dismiss: () => void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* An open modal surface's keyboard and focus, WEB. Renders nothing; it must
|
|
14
|
+
* sit INSIDE the surface's `OverlayRoot`, which is how it knows the surface's
|
|
15
|
+
* place in the overlay stack. Used by the web `Dialog` (card and side drawers)
|
|
16
|
+
* and the web `BottomSheet`.
|
|
17
|
+
*
|
|
18
|
+
* - Focus moves INTO the panel when it opens — to whatever the content
|
|
19
|
+
* focused itself (an `autoFocus` field), else the first tabbable, else the
|
|
20
|
+
* panel — and goes BACK to the element that had it once the surface starts
|
|
21
|
+
* closing (or unmounts), unless the host has already put it somewhere else.
|
|
22
|
+
* - Tab and Shift+Tab wrap at the panel's edges.
|
|
23
|
+
* - Escape dismisses (when `dismissible`), from anywhere — a text field of the
|
|
24
|
+
* surface included, which react-native-web keeps every keydown from
|
|
25
|
+
* bubbling out of (`./modal-keyboard.ts`).
|
|
26
|
+
*
|
|
27
|
+
* All three belong to the TOP-MOST surface only: a menu or a second dialog
|
|
28
|
+
* opened from this one takes them until it closes, so Escape closes one layer
|
|
29
|
+
* at a time. Inert without a DOM, so native never runs any of it.
|
|
30
|
+
*/
|
|
31
|
+
export declare function ModalKeyboard({ panelRef, closing, dismissible, dismiss }: ModalKeyboardProps): null;
|
|
32
|
+
//# sourceMappingURL=ModalKeyboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModalKeyboard.d.ts","sourceRoot":"","sources":["../../../../src/overlay/ModalKeyboard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAC9D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAMzC,MAAM,WAAW,kBAAkB;IACjC,wEAAwE;IACxE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IACvC,8EAA8E;IAC9E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sEAAsE;IACtE,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,OAAe,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,kBAAkB,QAmDpG"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** The elements inside `node` that Tab can land on, in document order. */
|
|
2
|
+
export declare function tabbablesWithin(node: HTMLElement | null): HTMLElement[];
|
|
3
|
+
/**
|
|
4
|
+
* Keep Tab inside `node`: from the last tabbable (or from outside) forward to
|
|
5
|
+
* the first, from the first (or from outside) backward to the last. Returns
|
|
6
|
+
* whether it moved focus.
|
|
7
|
+
*/
|
|
8
|
+
export declare function wrapTab(event: KeyboardEvent, node: HTMLElement | null): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Dismiss on Escape — see the file comment for the three steps. `claim` runs
|
|
11
|
+
* in the capture phase and says whether this surface is the one the key is
|
|
12
|
+
* for (the top-most, nothing anchored open above it). An open anchored
|
|
13
|
+
* surface (a menu, a select's list) always keeps the key: it is the top layer
|
|
14
|
+
* whatever the caller's own bookkeeping says.
|
|
15
|
+
*/
|
|
16
|
+
export declare function listenForEscape(claim: () => boolean, dismiss: () => void): () => void;
|
|
17
|
+
//# sourceMappingURL=modal-keyboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modal-keyboard.d.ts","sourceRoot":"","sources":["../../../../src/overlay/modal-keyboard.ts"],"names":[],"mappings":"AAiDA,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,WAAW,EAAE,CASvE;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,CAa/E;AAYD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAkCrF"}
|
|
@@ -120,5 +120,11 @@ export declare function releaseOverlayRank(rank: number): void;
|
|
|
120
120
|
export declare function resetOverlayStack(): void;
|
|
121
121
|
/** In-flow shell drawers yield interaction to any portaled surface above them. */
|
|
122
122
|
export declare function hasActiveOverlays(): boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Whether the surface painting at `layer` is the top-most one open — the one
|
|
125
|
+
* Escape and Tab belong to. A menu opened from inside a dialog takes a higher
|
|
126
|
+
* rank than the dialog, so the dialog stands aside until it closes.
|
|
127
|
+
*/
|
|
128
|
+
export declare function isTopmostOverlayLayer(layer: OverlayLayer): boolean;
|
|
123
129
|
export {};
|
|
124
130
|
//# sourceMappingURL=stack.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../../../../src/overlay/stack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAEH;;;GAGG;AACH,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C;;;GAGG;AACH,eAAO,MAAM,aAAa,QAC8C,CAAC;AAEzE,0EAA0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,UAAU,QAAQ;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACnB;AAED,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,8BAA8B,EAAE,QAAQ,GAAG,SAAS,CAAC;CAC1D;AAgBD,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAIvD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAI3C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAItD;AAED,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAIrD;AAED,4CAA4C;AAC5C,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED,kFAAkF;AAClF,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C"}
|
|
1
|
+
{"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../../../../src/overlay/stack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAEH;;;GAGG;AACH,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C;;;GAGG;AACH,eAAO,MAAM,aAAa,QAC8C,CAAC;AAEzE,0EAA0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,UAAU,QAAQ;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACnB;AAED,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,8BAA8B,EAAE,QAAQ,GAAG,SAAS,CAAC;CAC1D;AAgBD,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAIvD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAI3C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAItD;AAED,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAIrD;AAED,4CAA4C;AAC5C,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED,kFAAkF;AAClF,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAMlE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["../../../../src/sidebar/Sidebar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAkE,MAAM,OAAO,CAAC;AA4CvF,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["../../../../src/sidebar/Sidebar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAkE,MAAM,OAAO,CAAC;AA4CvF,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,SAAS,CAAC;AAquB5D,eAAO,MAAM,OAAO,0CAAyB,CAAC"}
|
|
@@ -21,10 +21,11 @@ import type { AiChatContainerProps, AiChatThreadHandle, AiChatThreadProps } from
|
|
|
21
21
|
* `floatingChrome` changes the geometry, not the parts:
|
|
22
22
|
*
|
|
23
23
|
* thread the `children` fill the whole card, under everything below
|
|
24
|
-
* header the `header` slot + breadcrumb row, absolute at the top, no band
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
24
|
+
* header the `header` slot + breadcrumb row, absolute at the top, no band
|
|
25
|
+
* at rest; once the transcript scrolls under it, the surface fades
|
|
26
|
+
* in behind it over the first 16px — solid across the whole block,
|
|
27
|
+
* then a ramp to nothing `SCRIM_TAIL_RATIO` below it — so no turn
|
|
28
|
+
* ever shows through the title or the crumbs
|
|
28
29
|
* footer absolute at the bottom, with no band of its own: the transcript
|
|
29
30
|
* passes behind the composer and stays in sight around it
|
|
30
31
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiChatContainer.d.ts","sourceRoot":"","sources":["../../../../src/ai-chat/AiChatContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAUN,MAAM,OAAO,CAAC;AA0Cf,OAAO,KAAK,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAqB3F
|
|
1
|
+
{"version":3,"file":"AiChatContainer.d.ts","sourceRoot":"","sources":["../../../../src/ai-chat/AiChatContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAUN,MAAM,OAAO,CAAC;AA0Cf,OAAO,KAAK,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAqB3F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,OAAO,EACP,KAAK,EACL,WAA0B,EAC1B,cAAc,EACd,OAAO,EACP,MAAM,EACN,OAAO,EACP,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,OAAe,EACf,YAAY,EACZ,UAAU,EACV,OAAc,EACd,cAAsB,EACtB,MAAM,EACN,KAAK,EACL,MAAM,GACP,EAAE,oBAAoB,2CAsHtB;AAiOD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,YAAY,8FAGvB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiChatShell.d.ts","sourceRoot":"","sources":["../../../../src/ai-chat/AiChatShell.tsx"],"names":[],"mappings":"AACA,OAAO,EAML,KAAK,qBAAqB,EAI3B,MAAM,cAAc,CAAC;AA4BtB,OAAO,KAAK,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AA4DlG;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,aAAa,EACb,QAAQ,EACR,WAAW,EACX,KAA6B,EAC7B,OAAO,EACP,KAAK,EACL,MAAM,GACP,EAAE,uBAAuB,2CAoHzB;AAMD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,uBAAuB,kDAoCnF;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,YAAY,EACZ,gBAAwB,EACxB,qBAAqB,EACrB,aAAa,EACb,QAAQ,EACR,KAAK,EACL,UAAmB,EACnB,SAAuB,EACvB,iBAAuB,EACvB,aAAmB,EACnB,aAAmB,EACnB,OAAO,EAAE,WAAW,EACpB,eAAe,EACf,eAAsB,EACtB,SAAS,EAAE,aAAa,EACxB,iBAAiB,EACjB,UAAU,EACV,OAAc,EACd,MAAoB,EACpB,MAAM,EACN,KAAK,EACL,MAAM,GACP,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"AiChatShell.d.ts","sourceRoot":"","sources":["../../../../src/ai-chat/AiChatShell.tsx"],"names":[],"mappings":"AACA,OAAO,EAML,KAAK,qBAAqB,EAI3B,MAAM,cAAc,CAAC;AA4BtB,OAAO,KAAK,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AA4DlG;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,aAAa,EACb,QAAQ,EACR,WAAW,EACX,KAA6B,EAC7B,OAAO,EACP,KAAK,EACL,MAAM,GACP,EAAE,uBAAuB,2CAoHzB;AAMD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,uBAAuB,kDAoCnF;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,YAAY,EACZ,gBAAwB,EACxB,qBAAqB,EACrB,aAAa,EACb,QAAQ,EACR,KAAK,EACL,UAAmB,EACnB,SAAuB,EACvB,iBAAuB,EACvB,aAAmB,EACnB,aAAmB,EACnB,OAAO,EAAE,WAAW,EACpB,eAAe,EACf,eAAsB,EACtB,SAAS,EAAE,aAAa,EACxB,iBAAiB,EACjB,UAAU,EACV,OAAc,EACd,MAAoB,EACpB,MAAM,EACN,KAAK,EACL,MAAM,GACP,EAAE,gBAAgB,2CAoalB;AAED,YAAY,EAAE,qBAAqB,EAAE,CAAC"}
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import { type View } from 'react-native';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* Interaction only: the shell continues to own the drawer's layout and motion.
|
|
4
|
+
* Used by both shell drawers — the panel and the navigation.
|
|
5
|
+
*
|
|
6
|
+
* open Escape (web) and back (Android) close it
|
|
7
|
+
* modal it covers the workspace: focus moves in on open, Tab is kept
|
|
8
|
+
* inside, and focus goes back to the opener on close
|
|
9
|
+
*
|
|
10
|
+
* Any portaled overlay above (a dialog, a menu) takes all of it first.
|
|
11
|
+
*/
|
|
3
12
|
export declare function usePanelInteraction(open: boolean, modal: boolean, close: () => void): import("react").RefObject<View | null>;
|
|
4
13
|
//# sourceMappingURL=use-panel-interaction.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-panel-interaction.d.ts","sourceRoot":"","sources":["../../../../src/ai-chat/use-panel-interaction.ts"],"names":[],"mappings":"AACA,OAAO,EAAyB,KAAK,IAAI,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"use-panel-interaction.d.ts","sourceRoot":"","sources":["../../../../src/ai-chat/use-panel-interaction.ts"],"names":[],"mappings":"AACA,OAAO,EAAyB,KAAK,IAAI,EAAE,MAAM,cAAc,CAAC;AAKhE;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,0CAwCnF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BottomBarBase.d.ts","sourceRoot":"","sources":["../../../../src/bottom-bar/BottomBarBase.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAYzE,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,UAAU,KAAM,SAAQ,cAAc;IACpC,UAAU,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IACvC,IAAI,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IACvC,IAAI,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;CAC3C;AACD,wBAAgB,aAAa,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,EAC3H,eAAwB,EAAE,cAAuB,EAAE,QAAwB,EAAE,gBAAgB,EAAE,IAAW,EAAE,QAAc,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"BottomBarBase.d.ts","sourceRoot":"","sources":["../../../../src/bottom-bar/BottomBarBase.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAYzE,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,UAAU,KAAM,SAAQ,cAAc;IACpC,UAAU,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IACvC,IAAI,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IACvC,IAAI,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;CAC3C;AACD,wBAAgB,aAAa,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,EAC3H,eAAwB,EAAE,cAAuB,EAAE,QAAwB,EAAE,gBAAgB,EAAE,IAAW,EAAE,QAAc,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,kDAyEnJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BottomSheetBase.d.ts","sourceRoot":"","sources":["../../../../src/bottom-sheet/BottomSheetBase.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"BottomSheetBase.d.ts","sourceRoot":"","sources":["../../../../src/bottom-sheet/BottomSheetBase.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAoC/B,OAAO,KAAK,EAAE,cAAc,EAA2C,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAsB7G,eAAO,MAAM,eAAe,6FA8rB1B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.web.d.ts","sourceRoot":"","sources":["../../../../src/dialog/Dialog.web.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Dialog.web.d.ts","sourceRoot":"","sources":["../../../../src/dialog/Dialog.web.tsx"],"names":[],"mappings":"AA4EA,OAAO,KAAK,EAIV,WAAW,EACZ,MAAM,SAAS,CAAC;AAmDjB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,WAAW,2CAazD;AAiuBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,gBAAgB,8PAG5B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DialogBottomSheet.d.ts","sourceRoot":"","sources":["../../../../src/dialog/DialogBottomSheet.tsx"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAsB,WAAW,EAAE,MAAM,SAAS,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,IAAI,EAAE,cAAc,EACpB,SAAS,EACT,OAAO,EACP,MAAM,EACN,KAAK,EACL,WAAW,EACX,OAAO,EACP,MAAM,EACN,cAAyC,EACzC,UAAiB,EACjB,iBAAwB,EACxB,cAA+C,EAC/C,UAAU,EACV,KAAK,EACL,KAAK,EACL,UAAU,EACV,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,KAAK,EACL,QAAQ,GACT,EAAE,sBAAsB,
|
|
1
|
+
{"version":3,"file":"DialogBottomSheet.d.ts","sourceRoot":"","sources":["../../../../src/dialog/DialogBottomSheet.tsx"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAsB,WAAW,EAAE,MAAM,SAAS,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,IAAI,EAAE,cAAc,EACpB,SAAS,EACT,OAAO,EACP,MAAM,EACN,KAAK,EACL,WAAW,EACX,OAAO,EACP,MAAM,EACN,cAAyC,EACzC,UAAiB,EACjB,iBAAwB,EACxB,cAA+C,EAC/C,UAAU,EACV,KAAK,EACL,KAAK,EACL,UAAU,EACV,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,KAAK,EACL,QAAQ,GACT,EAAE,sBAAsB,2CAkRxB;AAQD;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,WAAW,EACT,SAAS,GACT,MAAM,GACN,WAAW,GACX,SAAS,GACT,QAAQ,GACR,OAAO,GACP,aAAa,GACb,SAAS,GACT,QAAQ,GACR,gBAAgB,GAChB,YAAY,GACZ,mBAAmB,GACnB,gBAAgB,GAChB,YAAY,GACZ,OAAO,GACP,OAAO,GACP,YAAY,GACZ,gBAAgB,GAChB,gBAAgB,GAChB,oBAAoB,GACpB,OAAO,GACP,UAAU,CACb,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { View } from 'react-native';
|
|
3
|
+
export interface ModalKeyboardProps {
|
|
4
|
+
/** The surface's panel: where focus goes, and what Tab stays inside. */
|
|
5
|
+
panelRef: React.RefObject<View | null>;
|
|
6
|
+
/** The surface has started its exit: focus goes back now, Escape is spent. */
|
|
7
|
+
closing?: boolean;
|
|
8
|
+
/** Whether Escape may dismiss it (a dialog's `dismissOnBackdrop`). */
|
|
9
|
+
dismissible: boolean;
|
|
10
|
+
dismiss: () => void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* An open modal surface's keyboard and focus, WEB. Renders nothing; it must
|
|
14
|
+
* sit INSIDE the surface's `OverlayRoot`, which is how it knows the surface's
|
|
15
|
+
* place in the overlay stack. Used by the web `Dialog` (card and side drawers)
|
|
16
|
+
* and the web `BottomSheet`.
|
|
17
|
+
*
|
|
18
|
+
* - Focus moves INTO the panel when it opens — to whatever the content
|
|
19
|
+
* focused itself (an `autoFocus` field), else the first tabbable, else the
|
|
20
|
+
* panel — and goes BACK to the element that had it once the surface starts
|
|
21
|
+
* closing (or unmounts), unless the host has already put it somewhere else.
|
|
22
|
+
* - Tab and Shift+Tab wrap at the panel's edges.
|
|
23
|
+
* - Escape dismisses (when `dismissible`), from anywhere — a text field of the
|
|
24
|
+
* surface included, which react-native-web keeps every keydown from
|
|
25
|
+
* bubbling out of (`./modal-keyboard.ts`).
|
|
26
|
+
*
|
|
27
|
+
* All three belong to the TOP-MOST surface only: a menu or a second dialog
|
|
28
|
+
* opened from this one takes them until it closes, so Escape closes one layer
|
|
29
|
+
* at a time. Inert without a DOM, so native never runs any of it.
|
|
30
|
+
*/
|
|
31
|
+
export declare function ModalKeyboard({ panelRef, closing, dismissible, dismiss }: ModalKeyboardProps): null;
|
|
32
|
+
//# sourceMappingURL=ModalKeyboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModalKeyboard.d.ts","sourceRoot":"","sources":["../../../../src/overlay/ModalKeyboard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAC9D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAMzC,MAAM,WAAW,kBAAkB;IACjC,wEAAwE;IACxE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IACvC,8EAA8E;IAC9E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sEAAsE;IACtE,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,OAAe,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,kBAAkB,QAmDpG"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** The elements inside `node` that Tab can land on, in document order. */
|
|
2
|
+
export declare function tabbablesWithin(node: HTMLElement | null): HTMLElement[];
|
|
3
|
+
/**
|
|
4
|
+
* Keep Tab inside `node`: from the last tabbable (or from outside) forward to
|
|
5
|
+
* the first, from the first (or from outside) backward to the last. Returns
|
|
6
|
+
* whether it moved focus.
|
|
7
|
+
*/
|
|
8
|
+
export declare function wrapTab(event: KeyboardEvent, node: HTMLElement | null): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Dismiss on Escape — see the file comment for the three steps. `claim` runs
|
|
11
|
+
* in the capture phase and says whether this surface is the one the key is
|
|
12
|
+
* for (the top-most, nothing anchored open above it). An open anchored
|
|
13
|
+
* surface (a menu, a select's list) always keeps the key: it is the top layer
|
|
14
|
+
* whatever the caller's own bookkeeping says.
|
|
15
|
+
*/
|
|
16
|
+
export declare function listenForEscape(claim: () => boolean, dismiss: () => void): () => void;
|
|
17
|
+
//# sourceMappingURL=modal-keyboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modal-keyboard.d.ts","sourceRoot":"","sources":["../../../../src/overlay/modal-keyboard.ts"],"names":[],"mappings":"AAiDA,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,WAAW,EAAE,CASvE;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,CAa/E;AAYD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAkCrF"}
|
|
@@ -120,5 +120,11 @@ export declare function releaseOverlayRank(rank: number): void;
|
|
|
120
120
|
export declare function resetOverlayStack(): void;
|
|
121
121
|
/** In-flow shell drawers yield interaction to any portaled surface above them. */
|
|
122
122
|
export declare function hasActiveOverlays(): boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Whether the surface painting at `layer` is the top-most one open — the one
|
|
125
|
+
* Escape and Tab belong to. A menu opened from inside a dialog takes a higher
|
|
126
|
+
* rank than the dialog, so the dialog stands aside until it closes.
|
|
127
|
+
*/
|
|
128
|
+
export declare function isTopmostOverlayLayer(layer: OverlayLayer): boolean;
|
|
123
129
|
export {};
|
|
124
130
|
//# sourceMappingURL=stack.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../../../../src/overlay/stack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAEH;;;GAGG;AACH,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C;;;GAGG;AACH,eAAO,MAAM,aAAa,QAC8C,CAAC;AAEzE,0EAA0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,UAAU,QAAQ;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACnB;AAED,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,8BAA8B,EAAE,QAAQ,GAAG,SAAS,CAAC;CAC1D;AAgBD,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAIvD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAI3C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAItD;AAED,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAIrD;AAED,4CAA4C;AAC5C,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED,kFAAkF;AAClF,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C"}
|
|
1
|
+
{"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../../../../src/overlay/stack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAEH;;;GAGG;AACH,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C;;;GAGG;AACH,eAAO,MAAM,aAAa,QAC8C,CAAC;AAEzE,0EAA0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,UAAU,QAAQ;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACnB;AAED,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,8BAA8B,EAAE,QAAQ,GAAG,SAAS,CAAC;CAC1D;AAgBD,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAIvD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAI3C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAItD;AAED,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAIrD;AAED,4CAA4C;AAC5C,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED,kFAAkF;AAClF,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAMlE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["../../../../src/sidebar/Sidebar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAkE,MAAM,OAAO,CAAC;AA4CvF,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["../../../../src/sidebar/Sidebar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAkE,MAAM,OAAO,CAAC;AA4CvF,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,SAAS,CAAC;AAquB5D,eAAO,MAAM,OAAO,0CAAyB,CAAC"}
|
package/package.json
CHANGED
|
@@ -92,10 +92,11 @@ const HIDDEN_FROM_A11Y = {
|
|
|
92
92
|
* `floatingChrome` changes the geometry, not the parts:
|
|
93
93
|
*
|
|
94
94
|
* thread the `children` fill the whole card, under everything below
|
|
95
|
-
* header the `header` slot + breadcrumb row, absolute at the top, no band
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
95
|
+
* header the `header` slot + breadcrumb row, absolute at the top, no band
|
|
96
|
+
* at rest; once the transcript scrolls under it, the surface fades
|
|
97
|
+
* in behind it over the first 16px — solid across the whole block,
|
|
98
|
+
* then a ramp to nothing `SCRIM_TAIL_RATIO` below it — so no turn
|
|
99
|
+
* ever shows through the title or the crumbs
|
|
99
100
|
* footer absolute at the bottom, with no band of its own: the transcript
|
|
100
101
|
* passes behind the composer and stays in sight around it
|
|
101
102
|
*
|
|
@@ -340,6 +341,7 @@ function FloatingChrome({
|
|
|
340
341
|
const alpha = parsed?.a ?? 1;
|
|
341
342
|
const topStyle = useAnimatedStyle(() => ({ opacity: topFade.value * alpha }), [topFade, alpha]);
|
|
342
343
|
const prefix = testID ?? 'ai-chat';
|
|
344
|
+
const scrimTail = Math.round(headerHeight * SCRIM_TAIL_RATIO);
|
|
343
345
|
|
|
344
346
|
// Absolute over a card of fixed height; sticky in the flow of a card that
|
|
345
347
|
// grows with the document, pinned to the screen's gutter.
|
|
@@ -363,9 +365,7 @@ function FloatingChrome({
|
|
|
363
365
|
top: 0,
|
|
364
366
|
left: 0,
|
|
365
367
|
right: 0,
|
|
366
|
-
|
|
367
|
-
// does is a line across the transcript again.
|
|
368
|
-
height: Math.round(headerHeight * (1 + SCRIM_TAIL_RATIO)),
|
|
368
|
+
height: headerHeight + scrimTail,
|
|
369
369
|
// The card's own corners, since nothing clips a document card.
|
|
370
370
|
...(documentScroll
|
|
371
371
|
? { borderTopLeftRadius: DOCUMENT_CARD_RADIUS, borderTopRightRadius: DOCUMENT_CARD_RADIUS, overflow: 'hidden' as const }
|
|
@@ -373,7 +373,17 @@ function FloatingChrome({
|
|
|
373
373
|
},
|
|
374
374
|
topStyle,
|
|
375
375
|
]}>
|
|
376
|
-
|
|
376
|
+
{/* SOLID behind the header's own block. A ramp that starts fading
|
|
377
|
+
inside the block leaves the breadcrumb row over half-covered
|
|
378
|
+
turns — measured in a browser, a code block's lines read straight
|
|
379
|
+
through the chat's title and crumbs at every width. The ramp
|
|
380
|
+
only starts where the block ends. */}
|
|
381
|
+
<View testID={`${prefix}-fade-top-surface`} style={{ height: headerHeight, backgroundColor: solid }} />
|
|
382
|
+
{/* Past the block's own bottom: a ramp that ends where the layout
|
|
383
|
+
does is a line across the transcript again. */}
|
|
384
|
+
<View style={{ height: scrimTail }}>
|
|
385
|
+
<EdgeScrim color={solid} />
|
|
386
|
+
</View>
|
|
377
387
|
</Animated.View>
|
|
378
388
|
) : null}
|
|
379
389
|
{header}
|
|
@@ -368,6 +368,10 @@ export function AiChatShell({
|
|
|
368
368
|
const panelOpen = panelOpenState && !wide && !!panel;
|
|
369
369
|
const dismissPanel = useCallback(() => setPanelOpen(false), [setPanelOpen]);
|
|
370
370
|
const panelRef = usePanelInteraction(panelOpenState && !!panel, panelOpen, dismissPanel);
|
|
371
|
+
const dismissNav = useCallback(() => setNavOpen(false), [setNavOpen]);
|
|
372
|
+
// The nav drawer covers the workspace whenever it is open: Escape closes it,
|
|
373
|
+
// focus moves in and is kept there, and returns to the opener on close.
|
|
374
|
+
const navRef = usePanelInteraction(navOpen, navOpen, dismissNav);
|
|
371
375
|
// The swipe's handlers are built once and read the drawer's state from here.
|
|
372
376
|
const navOpenRef = useRef(navOpen);
|
|
373
377
|
navOpenRef.current = navOpen;
|
|
@@ -608,6 +612,7 @@ export function AiChatShell({
|
|
|
608
612
|
) : null}
|
|
609
613
|
{!navInFlow && mobileSidebar ? (
|
|
610
614
|
<View
|
|
615
|
+
ref={navRef}
|
|
611
616
|
{...(navOpen ? null : CLOSED_LAYER)}
|
|
612
617
|
pointerEvents={navOpen ? 'box-none' : 'none'}
|
|
613
618
|
style={{ position: overlayPosition, top: 0, bottom: 0, left: 0, zIndex: 10, width: 272, paddingTop: 12, paddingBottom: 12, paddingLeft: 6 }}>
|
|
@@ -652,12 +657,17 @@ export function AiChatShell({
|
|
|
652
657
|
]}>
|
|
653
658
|
{!navInFlow ? (
|
|
654
659
|
<Animated.View
|
|
660
|
+
{...(navOpen ? null : CLOSED_LAYER)}
|
|
655
661
|
pointerEvents={navOpen ? 'auto' : 'none'}
|
|
656
662
|
style={[{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, zIndex: 50 }, veilStyle]}>
|
|
663
|
+
{/* Never a Tab stop: open, focus is kept in the drawer and Escape
|
|
664
|
+
closes it; closed, the veil is not there at all. `tabIndex`,
|
|
665
|
+
not `focusable` — react-native-web's Pressable writes its own
|
|
666
|
+
tabIndex 0 over `focusable`. */}
|
|
657
667
|
<Pressable
|
|
658
668
|
accessibilityRole="button"
|
|
659
669
|
accessibilityLabel={l.closeNavigation}
|
|
660
|
-
|
|
670
|
+
tabIndex={-1}
|
|
661
671
|
onPress={() => setNavOpen(false)}
|
|
662
672
|
style={{ flex: 1, backgroundColor: veil }}
|
|
663
673
|
/>
|
|
@@ -701,7 +711,7 @@ export function AiChatShell({
|
|
|
701
711
|
<Pressable
|
|
702
712
|
accessibilityRole="button"
|
|
703
713
|
accessibilityLabel={l.closePanel(panelLabel)}
|
|
704
|
-
|
|
714
|
+
tabIndex={panelOpen ? 0 : -1}
|
|
705
715
|
onPress={() => setPanelOpen(false)}
|
|
706
716
|
style={{ flex: 1, backgroundColor: 'rgba(0, 0, 0, 0.4)' }}
|
|
707
717
|
/>
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { useEffect, useRef } from 'react';
|
|
2
2
|
import { BackHandler, Platform, type View } from 'react-native';
|
|
3
3
|
import { useAccessibilityFocus } from '../hooks/use-accessibility-focus';
|
|
4
|
+
import { listenForEscape, tabbablesWithin, wrapTab } from '../overlay/modal-keyboard';
|
|
4
5
|
import { hasActiveOverlays } from '../overlay/stack';
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
/** Interaction only: the shell continues to own the drawer's layout and motion. */
|
|
7
|
+
/**
|
|
8
|
+
* Interaction only: the shell continues to own the drawer's layout and motion.
|
|
9
|
+
* Used by both shell drawers — the panel and the navigation.
|
|
10
|
+
*
|
|
11
|
+
* open Escape (web) and back (Android) close it
|
|
12
|
+
* modal it covers the workspace: focus moves in on open, Tab is kept
|
|
13
|
+
* inside, and focus goes back to the opener on close
|
|
14
|
+
*
|
|
15
|
+
* Any portaled overlay above (a dialog, a menu) takes all of it first.
|
|
16
|
+
*/
|
|
17
17
|
export function usePanelInteraction(open: boolean, modal: boolean, close: () => void) {
|
|
18
18
|
const ref = useAccessibilityFocus<View>(modal);
|
|
19
19
|
const closeRef = useRef(close);
|
|
@@ -33,36 +33,22 @@ export function usePanelInteraction(open: boolean, modal: boolean, close: () =>
|
|
|
33
33
|
// This ref is a native View on native, a DOM host on web.
|
|
34
34
|
const node = ref.current as unknown as HTMLElement | null;
|
|
35
35
|
const opener = document.activeElement as HTMLElement | null;
|
|
36
|
-
const
|
|
37
|
-
.filter(element => element.tabIndex >= 0 && !element.matches(':disabled, [aria-disabled="true"]') &&
|
|
38
|
-
!element.closest('[hidden], [aria-hidden="true"]') && visible(element));
|
|
39
|
-
const focusFirst = () => candidates()[0]?.focus();
|
|
36
|
+
const focusFirst = () => tabbablesWithin(node)[0]?.focus();
|
|
40
37
|
if (modal) focusFirst();
|
|
41
38
|
const onFocus = (event: FocusEvent) => {
|
|
42
39
|
if (modal && !hasActiveOverlays() && node && !node.contains(event.target as Node)) focusFirst();
|
|
43
40
|
};
|
|
44
|
-
const
|
|
45
|
-
if (event.defaultPrevented
|
|
46
|
-
if (event.key === 'Escape') {
|
|
47
|
-
event.preventDefault();
|
|
48
|
-
event.stopPropagation();
|
|
49
|
-
closeRef.current();
|
|
50
|
-
} else if (modal && event.key === 'Tab') {
|
|
51
|
-
const items = candidates();
|
|
52
|
-
const first = items[0];
|
|
53
|
-
const last = items[items.length - 1];
|
|
54
|
-
if (event.shiftKey && (document.activeElement === first || !node?.contains(document.activeElement))) {
|
|
55
|
-
event.preventDefault(); last?.focus();
|
|
56
|
-
} else if (!event.shiftKey && (document.activeElement === last || !node?.contains(document.activeElement))) {
|
|
57
|
-
event.preventDefault(); first?.focus();
|
|
58
|
-
}
|
|
59
|
-
}
|
|
41
|
+
const onTab = (event: KeyboardEvent) => {
|
|
42
|
+
if (modal && !event.defaultPrevented && !hasActiveOverlays()) wrapTab(event, node);
|
|
60
43
|
};
|
|
61
|
-
|
|
62
|
-
|
|
44
|
+
const stopEscape = listenForEscape(() => !hasActiveOverlays(), () => closeRef.current());
|
|
45
|
+
// Capture: a text field inside the drawer stops its own keydowns (see
|
|
46
|
+
// `overlay/modal-keyboard.ts`), and Tab must wrap from there too.
|
|
47
|
+
window.addEventListener('keydown', onTab, true);
|
|
63
48
|
document.addEventListener('focusin', onFocus);
|
|
64
49
|
return () => {
|
|
65
|
-
|
|
50
|
+
stopEscape();
|
|
51
|
+
window.removeEventListener('keydown', onTab, true);
|
|
66
52
|
document.removeEventListener('focusin', onFocus);
|
|
67
53
|
if (opener?.isConnected) opener.focus();
|
|
68
54
|
};
|
|
@@ -61,6 +61,9 @@ export function BottomBarBase({ Navigation, Item, Blur, items, value, onValueCha
|
|
|
61
61
|
const rowStyle = useAnimatedStyle(() => ({
|
|
62
62
|
height: interpolate(reducedMotion ? Number(progress.value > 0.01) : progress.value, [0, 1], [EXPANDED_HEIGHT, MINIMIZED_HEIGHT], 'clamp'),
|
|
63
63
|
}), [progress, reducedMotion]);
|
|
64
|
+
// Not `items.length` in the mapper: a worklet copies `items` whole to the UI
|
|
65
|
+
// runtime, icon elements and all (`worklet-captures.test.ts`).
|
|
66
|
+
const hasItems = items.length > 0;
|
|
64
67
|
const actionStyle = useAnimatedStyle(() => {
|
|
65
68
|
const amount = hideAction ? Math.min(1, Math.max(0, reducedMotion ? Number(progress.value > 0.01) : progress.value)) : 0;
|
|
66
69
|
return {
|
|
@@ -68,11 +71,11 @@ export function BottomBarBase({ Navigation, Item, Blur, items, value, onValueCha
|
|
|
68
71
|
// Logical, and the CSS name rather than RN's `marginStart`: reanimated's
|
|
69
72
|
// web writer hands a mapper's result to RNW's `createReactDOMStyle`,
|
|
70
73
|
// which never rewrites `marginStart`, so the browser would drop it.
|
|
71
|
-
marginInlineStart:
|
|
74
|
+
marginInlineStart: hasItems && !above ? 10 * (1 - amount) : 0,
|
|
72
75
|
opacity: 1 - amount,
|
|
73
76
|
transform: [{ scale: 1 - amount * 0.15 }],
|
|
74
77
|
};
|
|
75
|
-
}, [progress, hideAction, reducedMotion, actionWidth,
|
|
78
|
+
}, [progress, hideAction, reducedMotion, actionWidth, hasItems, above]);
|
|
76
79
|
if (keyboardVisible || (!items.length && !action)) return null;
|
|
77
80
|
return <View {...dirProps} testID={testID} pointerEvents="box-none" style={[{ height: bottom + footprint, justifyContent: 'flex-end' }, style]}>
|
|
78
81
|
{blur && material === 'translucent' && <Blur direction="bottom" style={{ position: 'absolute', left: 0, right: 0, bottom: 0, height: bottom + footprint + BLUR_BLEED }} />}
|
|
@@ -32,6 +32,7 @@ import Animated, {
|
|
|
32
32
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
33
33
|
import { EDGE_GAP, windowEdgeGap } from '../layout/edge';
|
|
34
34
|
import { Backdrop, BACKDROP_DIM_OPACITY } from '../overlay';
|
|
35
|
+
import { ModalKeyboard } from '../overlay/ModalKeyboard';
|
|
35
36
|
import { useTheme } from '../theme/use-theme';
|
|
36
37
|
import type { BottomSheetRef, BottomSheetProps, BottomSheetShellProps, BottomSheetBaseProps } from './types';
|
|
37
38
|
|
|
@@ -92,6 +93,7 @@ export const BottomSheetBase = forwardRef((props: BottomSheetBaseProps, ref: Rea
|
|
|
92
93
|
const closeTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
93
94
|
const hasClosedRef = useRef(false);
|
|
94
95
|
const scrollViewRef = useRef<Animated.ScrollView>(null);
|
|
96
|
+
const sheetRef = useRef<View>(null);
|
|
95
97
|
/**
|
|
96
98
|
* Monotonically increasing counter that identifies "the current close
|
|
97
99
|
* attempt". Bumped every time the sheet re-opens (`present()`), so any
|
|
@@ -696,6 +698,11 @@ export const BottomSheetBase = forwardRef((props: BottomSheetBaseProps, ref: Rea
|
|
|
696
698
|
|
|
697
699
|
return (
|
|
698
700
|
<Shell visible={rendered} onRequestClose={dismiss} keyboardHeight={keyboardHeight}>
|
|
701
|
+
{/* Web keyboard and focus: in on open, back on close, Tab kept in
|
|
702
|
+
the sheet, Escape a USER dismissal — through `onDismissAttempt`,
|
|
703
|
+
exactly like the backdrop. The sheet had no keyboard path at
|
|
704
|
+
all. Inside the shell's `OverlayRoot`; inert on native. */}
|
|
705
|
+
<ModalKeyboard panelRef={sheetRef} dismissible dismiss={handleBackdropPress} />
|
|
699
706
|
<View style={StyleSheet.absoluteFill}>
|
|
700
707
|
{backdropComponent ? (
|
|
701
708
|
<Animated.View style={[StyleSheet.absoluteFill, customBackdropStyle]}>
|
|
@@ -723,6 +730,7 @@ export const BottomSheetBase = forwardRef((props: BottomSheetBaseProps, ref: Rea
|
|
|
723
730
|
|
|
724
731
|
<GestureDetector gesture={panGesture}>
|
|
725
732
|
<Animated.View
|
|
733
|
+
ref={sheetRef}
|
|
726
734
|
onLayout={onLayout}
|
|
727
735
|
style={[
|
|
728
736
|
dynamicStyles.sheet,
|