{"version":3,"sources":["../../src/react/hooks/useComboboxInput.ts","../../src/react/hooks/useHTMLInputCursorState.ts"],"sourcesContent":["import {\n  type HTMLAttributes,\n  type RefObject,\n  useCallback,\n  useEffect,\n  useRef,\n} from 'react';\n\nimport { Hotkeys, isHotkey } from '@udecode/plate';\nimport { useEditorRef, useElement, useSelected } from '@udecode/plate/react';\n\nimport type {\n  CancelComboboxInputCause,\n  ComboboxInputCursorState,\n} from '../../lib';\n\nexport interface UseComboboxInputOptions {\n  ref: RefObject<HTMLElement | null>;\n  autoFocus?: boolean;\n  cancelInputOnArrowLeftRight?: boolean;\n  cancelInputOnBackspace?: boolean;\n  cancelInputOnBlur?: boolean;\n  cancelInputOnDeselect?: boolean;\n  cancelInputOnEscape?: boolean;\n  cursorState?: ComboboxInputCursorState;\n  forwardUndoRedoToEditor?: boolean;\n  onCancelInput?: (cause: CancelComboboxInputCause) => void;\n}\n\nexport interface UseComboboxInputResult {\n  props: Required<Pick<HTMLAttributes<HTMLElement>, 'onBlur' | 'onKeyDown'>>;\n  cancelInput: (\n    cause?: CancelComboboxInputCause,\n    focusEditor?: boolean\n  ) => void;\n  removeInput: (focusEditor?: boolean) => void;\n}\n\nexport const useComboboxInput = ({\n  autoFocus = true,\n  cancelInputOnArrowLeftRight = true,\n  cancelInputOnBackspace = true,\n  cancelInputOnBlur = true,\n  cancelInputOnDeselect = true,\n  cancelInputOnEscape = true,\n  cursorState,\n  forwardUndoRedoToEditor = true,\n  ref,\n  onCancelInput,\n}: UseComboboxInputOptions): UseComboboxInputResult => {\n  const editor = useEditorRef();\n  const element = useElement();\n  const selected = useSelected();\n\n  const cursorAtStart = cursorState?.atStart ?? false;\n  const cursorAtEnd = cursorState?.atEnd ?? false;\n\n  const removeInput = useCallback(\n    (shouldFocusEditor = false) => {\n      const path = editor.api.findPath(element);\n\n      if (!path) return;\n\n      editor.tf.removeNodes({ at: path });\n\n      if (shouldFocusEditor) {\n        editor.tf.focus();\n      }\n    },\n    [editor, element]\n  );\n\n  const cancelInput = useCallback(\n    (cause: CancelComboboxInputCause = 'manual', shouldFocusEditor = false) => {\n      removeInput(shouldFocusEditor);\n      onCancelInput?.(cause);\n    },\n    [onCancelInput, removeInput]\n  );\n\n  /**\n   * Using autoFocus on the input element causes an error: Cannot resolve a\n   * Slate node from DOM node: [object HTMLSpanElement]\n   */\n  useEffect(() => {\n    if (autoFocus) {\n      ref.current?.focus();\n    }\n  }, [autoFocus, ref]);\n\n  /**\n   * Storing the previous selection lets us determine whether the input has been\n   * actively deselected. When undoing or redoing causes a combobox input to be\n   * inserted, selected can be temporarily false. Removing the input at this\n   * point is incorrect and crashes the editor.\n   */\n  const previousSelected = useRef(selected);\n\n  useEffect(() => {\n    if (previousSelected.current && !selected && cancelInputOnDeselect) {\n      cancelInput('deselect');\n    }\n\n    previousSelected.current = selected;\n  }, [selected, cancelInputOnDeselect, cancelInput]);\n\n  return {\n    cancelInput,\n    props: {\n      onBlur: () => {\n        if (cancelInputOnBlur) {\n          cancelInput('blur');\n        }\n      },\n      onKeyDown: (event) => {\n        if (cancelInputOnEscape && isHotkey('escape', event)) {\n          cancelInput('escape', true);\n        }\n        if (\n          cancelInputOnBackspace &&\n          cursorAtStart &&\n          isHotkey('backspace', event)\n        ) {\n          cancelInput('backspace', true);\n        }\n        if (\n          cancelInputOnArrowLeftRight &&\n          cursorAtStart &&\n          isHotkey('arrowleft', event)\n        ) {\n          cancelInput('arrowLeft', true);\n        }\n        if (\n          cancelInputOnArrowLeftRight &&\n          cursorAtEnd &&\n          isHotkey('arrowright', event)\n        ) {\n          cancelInput('arrowRight', true);\n        }\n\n        const isUndo = Hotkeys.isUndo(event) && editor.history.undos.length > 0;\n        const isRedo = Hotkeys.isRedo(event) && editor.history.redos.length > 0;\n\n        if (forwardUndoRedoToEditor && (isUndo || isRedo)) {\n          event.preventDefault();\n          editor[isUndo ? 'undo' : 'redo']();\n          editor.tf.focus();\n        }\n      },\n    },\n    removeInput,\n  };\n};\n","import {\n  type RefObject,\n  useCallback,\n  useEffect,\n  useMemo,\n  useState,\n} from 'react';\n\nimport type { ComboboxInputCursorState } from '../../lib';\n\nexport const useHTMLInputCursorState = (\n  ref: RefObject<HTMLInputElement | null>\n): ComboboxInputCursorState => {\n  const [atStart, setAtStart] = useState(false);\n  const [atEnd, setAtEnd] = useState(false);\n\n  const recomputeCursorState = useCallback(() => {\n    // Wait for events to finish processing\n    setTimeout(() => {\n      if (!ref.current) return;\n\n      const { selectionEnd, selectionStart, value } = ref.current;\n      setAtStart(selectionStart === 0);\n      setAtEnd(selectionEnd === value.length);\n    });\n  }, [ref]);\n\n  useEffect(() => {\n    recomputeCursorState();\n\n    const input = ref.current;\n\n    if (!input) return;\n\n    input.addEventListener('input', recomputeCursorState);\n    input.addEventListener('selectionchange', recomputeCursorState);\n\n    /**\n     * Compat: selectionchange is not supported for <input> except in Firefox,\n     * so we add keydown, pointerdown and pointerup as fallbacks (2024-06-14).\n     */\n    input.addEventListener('keydown', recomputeCursorState);\n    input.addEventListener('pointerdown', recomputeCursorState);\n    input.addEventListener('pointerup', recomputeCursorState);\n\n    return () => {\n      input.removeEventListener('input', recomputeCursorState);\n      input.removeEventListener('selectionchange', recomputeCursorState);\n      input.removeEventListener('keydown', recomputeCursorState);\n      input.removeEventListener('pointerdown', recomputeCursorState);\n      input.removeEventListener('pointerup', recomputeCursorState);\n    };\n  }, [recomputeCursorState, ref]);\n\n  return useMemo(\n    () => ({\n      atEnd,\n      atStart,\n    }),\n    [atStart, atEnd]\n  );\n};\n"],"mappings":"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","names":["useCallback","useEffect"]}