CalloutBlock.hooks.ts 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. import { useCallback, useContext, useMemo, useState } from 'react';
  2. import emojiData, { EmojiMartData, Emoji } from '@emoji-mart/data';
  3. import { useAppDispatch } from '$app/stores/store';
  4. import { DocumentControllerContext } from '$app/stores/effects/document/document_controller';
  5. import { updateNodeDataThunk } from '$app_reducers/document/async-actions';
  6. export function useCalloutBlock(nodeId: string) {
  7. const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
  8. const open = useMemo(() => Boolean(anchorEl), [anchorEl]);
  9. const id = useMemo(() => (open ? 'emoji-popover' : undefined), [open]);
  10. const dispatch = useAppDispatch();
  11. const controller = useContext(DocumentControllerContext);
  12. const closeEmojiSelect = useCallback(() => {
  13. setAnchorEl(null);
  14. }, []);
  15. const openEmojiSelect = useCallback((event: React.MouseEvent<HTMLButtonElement>) => {
  16. setAnchorEl(event.currentTarget);
  17. }, []);
  18. const onEmojiSelect = useCallback(
  19. (emoji: { native: string }) => {
  20. if (!controller) return;
  21. void dispatch(
  22. updateNodeDataThunk({
  23. id: nodeId,
  24. controller,
  25. data: {
  26. icon: emoji.native,
  27. },
  28. })
  29. );
  30. closeEmojiSelect();
  31. },
  32. [controller, dispatch, nodeId, closeEmojiSelect]
  33. );
  34. return {
  35. anchorEl,
  36. closeEmojiSelect,
  37. openEmojiSelect,
  38. open,
  39. id,
  40. onEmojiSelect,
  41. };
  42. }