diff options
author | Nate Sesti <sestinj@gmail.com> | 2023-08-17 22:19:55 -0700 |
---|---|---|
committer | Nate Sesti <sestinj@gmail.com> | 2023-08-17 22:19:55 -0700 |
commit | c6a3d8add014ddfe08c62b3ccb1b01dbc47495f5 (patch) | |
tree | 0bb5bb11cf185a575df520908078d310775f4a7c /extension/react-app/src/components/UserInputContainer.tsx | |
parent | 98047dc32a5bfa525eff7089b2ac020ce761f9a9 (diff) | |
download | sncontinue-c6a3d8add014ddfe08c62b3ccb1b01dbc47495f5.tar.gz sncontinue-c6a3d8add014ddfe08c62b3ccb1b01dbc47495f5.tar.bz2 sncontinue-c6a3d8add014ddfe08c62b3ccb1b01dbc47495f5.zip |
feat: :sparkles: edit previous inputs
Diffstat (limited to 'extension/react-app/src/components/UserInputContainer.tsx')
-rw-r--r-- | extension/react-app/src/components/UserInputContainer.tsx | 147 |
1 files changed, 128 insertions, 19 deletions
diff --git a/extension/react-app/src/components/UserInputContainer.tsx b/extension/react-app/src/components/UserInputContainer.tsx index 90cd549b..9784a615 100644 --- a/extension/react-app/src/components/UserInputContainer.tsx +++ b/extension/react-app/src/components/UserInputContainer.tsx @@ -1,16 +1,24 @@ -import React, { useState } from "react"; +import React, { useContext, useEffect, useRef, useState } from "react"; import ReactMarkdown from "react-markdown"; import styled from "styled-components"; -import { defaultBorderRadius, secondaryDark, vscBackground } from "."; +import { + defaultBorderRadius, + secondaryDark, + vscBackground, + vscForeground, +} from "."; import HeaderButtonWithText from "./HeaderButtonWithText"; -import { XMarkIcon } from "@heroicons/react/24/outline"; +import { XMarkIcon, PencilIcon, CheckIcon } from "@heroicons/react/24/outline"; import { HistoryNode } from "../../../schema/HistoryNode"; import StyledMarkdownPreview from "./StyledMarkdownPreview"; +import { GUIClientContext } from "../App"; +import { text } from "stream/consumers"; interface UserInputContainerProps { onDelete: () => void; children: string; historyNode: HistoryNode; + index: number; } const StyledDiv = styled.div` @@ -40,8 +48,69 @@ const StyledPre = styled.pre` font-size: 13px; `; +const TextArea = styled.textarea` + margin: 8px; + margin-right: 22px; + padding: 8px; + white-space: pre-wrap; + word-wrap: break-word; + font-family: "Lexend", sans-serif; + font-size: 13px; + width: 100%; + border-radius: ${defaultBorderRadius}; + height: 100%; + border: none; + background-color: ${vscBackground}; + resize: none; + outline: none; + border: none; + color: ${vscForeground}; + + &:focus { + border: none; + outline: none; + } +`; + const UserInputContainer = (props: UserInputContainerProps) => { const [isHovered, setIsHovered] = useState(false); + const [isEditing, setIsEditing] = useState(false); + + const textAreaRef = useRef<HTMLTextAreaElement>(null); + const client = useContext(GUIClientContext); + + useEffect(() => { + if (isEditing) { + textAreaRef.current?.focus(); + // Select all text + textAreaRef.current?.setSelectionRange( + 0, + textAreaRef.current.value.length + ); + } + }, [isEditing]); + + useEffect(() => { + const handleKeyDown = (event: KeyboardEvent) => { + if (event.key === "Escape") { + setIsEditing(false); + } + }; + document.addEventListener("keydown", handleKeyDown); + return () => { + document.removeEventListener("keydown", handleKeyDown); + }; + }, []); + + const doneEditing = (e: any) => { + if (!textAreaRef.current?.value) { + return; + } + client?.editStepAtIndex(textAreaRef.current.value, props.index); + setIsEditing(false); + e.stopPropagation(); + }; + return ( <StyledDiv onMouseEnter={() => { @@ -51,24 +120,64 @@ const UserInputContainer = (props: UserInputContainerProps) => { setIsHovered(false); }} > - {/* <StyledMarkdownPreview - light={true} - source={props.children} - className="mr-6" - /> */} - <StyledPre className="mr-6">{props.children}</StyledPre> + {isEditing ? ( + <TextArea + ref={textAreaRef} + onKeyDown={(e) => { + if (e.key === "Enter" && !e.shiftKey) { + e.preventDefault(); + doneEditing(e); + } + }} + defaultValue={props.children} + /> + ) : ( + <StyledPre + onClick={() => { + setIsEditing(true); + }} + className="mr-6 cursor-text w-full" + > + {props.children} + </StyledPre> + )} {/* <ReactMarkdown children={props.children} className="w-fit mr-10" /> */} <DeleteButtonDiv> - {isHovered && ( - <HeaderButtonWithText - onClick={(e) => { - props.onDelete(); - e.stopPropagation(); - }} - text="Delete" - > - <XMarkIcon width="1.4em" height="1.4em" /> - </HeaderButtonWithText> + {(isHovered || isEditing) && ( + <div className="flex"> + {isEditing ? ( + <HeaderButtonWithText + onClick={(e) => { + doneEditing(e); + }} + text="Done" + > + <CheckIcon width="1.4em" height="1.4em" /> + </HeaderButtonWithText> + ) : ( + <> + <HeaderButtonWithText + onClick={(e) => { + setIsEditing((prev) => !prev); + e.stopPropagation(); + }} + text="Edit" + > + <PencilIcon width="1.4em" height="1.4em" /> + </HeaderButtonWithText> + + <HeaderButtonWithText + onClick={(e) => { + props.onDelete(); + e.stopPropagation(); + }} + text="Delete" + > + <XMarkIcon width="1.4em" height="1.4em" /> + </HeaderButtonWithText> + </> + )} + </div> )} </DeleteButtonDiv> </StyledDiv> |