// Copyright 2025 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import type { ReactNode } from 'react'; import React, { memo, useCallback, useEffect } from 'react'; import type { Placement } from 'react-aria'; import { DialogTrigger } from 'react-aria-components'; import { createKeybindingsHandler } from 'tinykeys'; import { FunPickerTabKey } from './constants'; import { FunPopover } from './base/FunPopover'; import { FunPickerTab, FunTabList, FunTabPanel, FunTabs } from './base/FunTabs'; import type { FunEmojiSelection } from './panels/FunPanelEmojis'; import { FunPanelEmojis } from './panels/FunPanelEmojis'; import type { FunGifSelection } from './panels/FunPanelGifs'; import { FunPanelGifs } from './panels/FunPanelGifs'; import type { FunStickerSelection } from './panels/FunPanelStickers'; import { FunPanelStickers } from './panels/FunPanelStickers'; import { useFunContext } from './FunProvider'; import type { ThemeType } from '../../types/Util'; import { FunErrorBoundary } from './base/FunErrorBoundary'; /** * FunPicker */ export type FunPickerProps = Readonly<{ open: boolean; onOpenChange: (open: boolean) => void; onSelectEmoji: (emojiSelection: FunEmojiSelection) => void; onSelectSticker: (stickerSelection: FunStickerSelection) => void; onSelectGif: (gifSelection: FunGifSelection) => void; onAddStickerPack: (() => void) | null; placement?: Placement; theme?: ThemeType; children: ReactNode; }>; export const FunPicker = memo(function FunPicker( props: FunPickerProps ): JSX.Element { const { onOpenChange } = props; const fun = useFunContext(); const { i18n, onOpenChange: onFunOpenChange, onChangeTab } = fun; const handleOpenChange = useCallback( (open: boolean) => { onOpenChange(open); onFunOpenChange(open); }, [onOpenChange, onFunOpenChange] ); const handleClose = useCallback(() => { handleOpenChange(false); }, [handleOpenChange]); useEffect(() => { const onKeyDown = createKeybindingsHandler({ '$mod+Shift+J': () => { onChangeTab(FunPickerTabKey.Emoji); handleOpenChange(true); }, '$mod+Shift+O': () => { onChangeTab(FunPickerTabKey.Stickers); handleOpenChange(true); }, '$mod+Shift+G': () => { onChangeTab(FunPickerTabKey.Gifs); handleOpenChange(true); }, }); window.addEventListener('keydown', onKeyDown); return () => { window.removeEventListener('keydown', onKeyDown); }; }, [handleOpenChange, onChangeTab]); return ( {props.children} {i18n('icu:FunPicker__Tab--Emojis')} {i18n('icu:FunPicker__Tab--Stickers')} {i18n('icu:FunPicker__Tab--Gifs')} ); });