import { useEffect, useMemo, useRef, useState } from 'react' import { CommandArgument } from 'lib/commandTypes' import { Selections, canSubmitSelectionArg, getSelectionCountByType, } from 'lib/selections' import { useSelector } from '@xstate/react' import { commandBarActor, useCommandBarState } from 'machines/commandBarMachine' import { kclManager } from 'lib/singletons' const selectionSelector = (snapshot: any) => snapshot?.context.selectionRanges export default function CommandBarSelectionMixedInput({ arg, stepBack, onSubmit, }: { arg: CommandArgument & { inputType: 'selectionMixed'; name: string } stepBack: () => void onSubmit: (data: unknown) => void }) { const inputRef = useRef(null) const commandBarState = useCommandBarState() const [hasSubmitted, setHasSubmitted] = useState(false) const [hasAutoSkipped, setHasAutoSkipped] = useState(false) const selection: Selections = useSelector(arg.machineActor, selectionSelector) const selectionsByType = useMemo(() => { return getSelectionCountByType(selection) }, [selection]) const canSubmitSelection = useMemo(() => { if (!selection) return false const isNonZeroRange = selection.graphSelections.some((sel) => { const range = sel.codeRef.range return range[1] - range[0] !== 0 // Non-zero range is always valid }) if (isNonZeroRange) return true return canSubmitSelectionArg(selectionsByType, arg) }, [selectionsByType, selection]) useEffect(() => { inputRef.current?.focus() }, [selection, inputRef]) // Only auto-skip on initial mount if we have a valid selection // different from the component CommandBarSelectionInput in the the dependency array // is empty useEffect(() => { if (!hasAutoSkipped && canSubmitSelection && arg.skip) { const argValue = commandBarState.context.argumentsToSubmit[arg.name] if (argValue === undefined) { handleSubmit() setHasAutoSkipped(true) } } }, []) // Set selection filter if needed, and reset it when the component unmounts useEffect(() => { arg.selectionFilter && kclManager.setSelectionFilter(arg.selectionFilter) return () => kclManager.defaultSelectionFilter(selection) }, [arg.selectionFilter]) function handleChange() { inputRef.current?.focus() } function handleSubmit(e?: React.FormEvent) { e?.preventDefault() if (!canSubmitSelection) { setHasSubmitted(true) return } onSubmit(selection) } const isMixedSelection = arg.inputType === 'selectionMixed' const allowNoSelection = isMixedSelection && arg.allowNoSelection const showSceneSelection = isMixedSelection && arg.selectionSource?.allowSceneSelection return (
) }