| 1 | import { useComposerHandleContext } from "../../composerHandleContext"; |
| 2 | |
| 3 | const COMPOSER_FLOATING_LAYER_SELECTOR = [ |
| 4 | '[data-composer-drawer-layer="true"]', |
| 5 | '[data-chat-composer-floating-layer="true"]', |
| 6 | ].join(","); |
| 7 | |
| 8 | export const composerFloatingLayerProps = { |
| 9 | "data-chat-composer-floating-layer": "true", |
| 10 | } as const; |
| 11 | |
| 12 | export function useComposerMenuProps() { |
| 13 | const composerRef = useComposerHandleContext(); |
| 14 | |
| 15 | return { |
| 16 | ...composerFloatingLayerProps, |
| 17 | finalFocus: composerRef |
| 18 | ? () => { |
| 19 | const activeElement = document.activeElement; |
| 20 | if (activeElement !== document.body && !isInsideComposerFloatingLayer(activeElement)) { |
| 21 | return false; |
| 22 | } |
| 23 | composerRef.current?.focusAtEnd(); |
| 24 | return false; |
| 25 | } |
| 26 | : undefined, |
| 27 | }; |
| 28 | } |
| 29 | |
| 30 | export function isInsideComposerFloatingLayer(target: EventTarget | null): boolean { |
| 31 | return target instanceof Element && target.closest(COMPOSER_FLOATING_LAYER_SELECTOR) !== null; |
| 32 | } |
| 33 | |
| 34 | // Banners, the approval row, and the tasks badge dock above the surface. A |
| 35 | // pointer or focus landing on one of them acts on that control and must not |
| 36 | // expand a resting or collapsed composer. |
| 37 | export function isInsideCollapsedComposerControls(target: EventTarget | null): boolean { |
| 38 | return ( |
| 39 | target instanceof Element && |
| 40 | target.closest('[data-chat-composer-collapsed-controls="true"]') !== null |
| 41 | ); |
| 42 | } |
| 43 | |
| 44 | export function isInsideRestingComposerControlScope(target: EventTarget | null): boolean { |
| 45 | return ( |
| 46 | target instanceof Element && |
| 47 | (target.closest('[data-chat-composer-resting-controls="true"]') !== null || |
| 48 | target.closest('[data-chat-composer-resting-images="true"]') !== null || |
| 49 | target.closest("[data-composer-context-control]") !== null || |
| 50 | isInsideComposerFloatingLayer(target)) |
| 51 | ); |
| 52 | } |