import { useSelector } from '@xstate/react' import { useCommandsContext } from 'hooks/useCommandsContext' import { useKclContext } from 'lang/KclProvider' import { Artifact } from 'lang/std/artifactGraph' import { CommandArgument } from 'lib/commandTypes' import { canSubmitSelectionArg, getSelectionType, getSelectionTypeDisplayText, } from 'lib/selections' import { modelingMachine } from 'machines/modelingMachine' import { useEffect, useMemo, useRef, useState } from 'react' import { StateFrom } from 'xstate' const semanticEntityNames: { [key: string]: Array } = { face: ['wall', 'cap', 'solid2D'], edge: ['segment', 'sweepEdge', 'edgeCutEdge'], point: [], } function getSemanticSelectionType(selectionType: Array) { const semanticSelectionType = new Set() selectionType.forEach((type) => { Object.entries(semanticEntityNames).forEach(([entity, entityTypes]) => { if (entityTypes.includes(type)) { semanticSelectionType.add(entity) } }) }) return Array.from(semanticSelectionType) } const selectionSelector = (snapshot?: StateFrom) => snapshot?.context.selectionRanges function CommandBarSelectionInput({ arg, stepBack, onSubmit, }: { arg: CommandArgument & { inputType: 'selection'; name: string } stepBack: () => void onSubmit: (data: unknown) => void }) { const { code } = useKclContext() const inputRef = useRef(null) const { commandBarState, commandBarSend } = useCommandsContext() const [hasSubmitted, setHasSubmitted] = useState(false) const selection = useSelector(arg.machineActor, selectionSelector) const selectionsByType = useMemo(() => { const selectionRangeEnd = !selection ? null : selection?.graphSelections[0]?.codeRef?.range[1] return !selectionRangeEnd || selectionRangeEnd === code.length || !selection ? 'none' : !selection ? 'none' : getSelectionType(selection) }, [selection, code]) const canSubmitSelection = useMemo( () => canSubmitSelectionArg(selectionsByType, arg), [selectionsByType] ) useEffect(() => { inputRef.current?.focus() }, [selection, inputRef]) // Fast-forward through this arg if it's marked as skippable // and we have a valid selection already useEffect(() => { const argValue = commandBarState.context.argumentsToSubmit[arg.name] if (canSubmitSelection && arg.skip && argValue === undefined) { handleSubmit() } }, [canSubmitSelection]) function handleChange() { inputRef.current?.focus() } function handleSubmit(e?: React.FormEvent) { e?.preventDefault() if (!canSubmitSelection) { setHasSubmitted(true) return } onSubmit(selection) } return (
) } export default CommandBarSelectionInput