diff options
Diffstat (limited to 'extension/react-app/src/components')
-rw-r--r-- | extension/react-app/src/components/ComboBox.tsx | 102 | ||||
-rw-r--r-- | extension/react-app/src/components/InputAndButton.tsx | 10 | ||||
-rw-r--r-- | extension/react-app/src/components/Onboarding.tsx | 19 | ||||
-rw-r--r-- | extension/react-app/src/components/PillButton.tsx | 172 | ||||
-rw-r--r-- | extension/react-app/src/components/StepContainer.tsx | 116 | ||||
-rw-r--r-- | extension/react-app/src/components/TextDialog.tsx | 71 | ||||
-rw-r--r-- | extension/react-app/src/components/index.ts | 23 |
7 files changed, 278 insertions, 235 deletions
diff --git a/extension/react-app/src/components/ComboBox.tsx b/extension/react-app/src/components/ComboBox.tsx index 7d6541c7..1e2ca135 100644 --- a/extension/react-app/src/components/ComboBox.tsx +++ b/extension/react-app/src/components/ComboBox.tsx @@ -1,30 +1,20 @@ -import React, { - useCallback, - useEffect, - useImperativeHandle, - useState, -} from "react"; +import React, { useEffect, useImperativeHandle, useState } from "react"; import { useCombobox } from "downshift"; import styled from "styled-components"; import { - buttonColor, defaultBorderRadius, lightGray, secondaryDark, vscBackground, + vscForeground, } from "."; import CodeBlock from "./CodeBlock"; -import { RangeInFile } from "../../../src/client"; import PillButton from "./PillButton"; import HeaderButtonWithText from "./HeaderButtonWithText"; -import { - Trash, - LockClosed, - LockOpen, - Plus, - DocumentPlus, -} from "@styled-icons/heroicons-outline"; +import { DocumentPlus } from "@styled-icons/heroicons-outline"; import { HighlightedRangeContext } from "../../../schema/FullState"; +import { postVscMessage } from "../vscode"; +import { getMetaKeyLabel } from "../util"; // #region styled components const mainInputFontSize = 13; @@ -48,21 +38,6 @@ const EmptyPillDiv = styled.div` } `; -const ContextDropdown = styled.div` - position: absolute; - padding: 4px; - width: calc(100% - 16px - 8px); - background-color: ${secondaryDark}; - color: white; - border-bottom-right-radius: ${defaultBorderRadius}; - border-bottom-left-radius: ${defaultBorderRadius}; - /* border: 1px solid white; */ - border-top: none; - margin: 8px; - outline: 1px solid orange; - z-index: 5; -`; - const MainTextInput = styled.textarea` resize: none; @@ -74,7 +49,7 @@ const MainTextInput = styled.textarea` height: auto; width: 100%; background-color: ${secondaryDark}; - color: white; + color: ${vscForeground}; z-index: 1; border: 1px solid transparent; @@ -96,15 +71,15 @@ const Ul = styled.ul<{ : `transform: translateY(${2 * mainInputFontSize}px);`} position: absolute; background: ${vscBackground}; - background-color: ${secondaryDark}; - color: white; + color: ${vscForeground}; max-height: ${UlMaxHeight}px; + width: calc(100% - 16px); overflow-y: scroll; overflow-x: hidden; padding: 0; ${({ hidden }) => hidden && "display: none;"} border-radius: ${defaultBorderRadius}; - border: 0.5px solid gray; + outline: 0.5px solid gray; z-index: 2; // Get rid of scrollbar and its padding scrollbar-width: none; @@ -120,6 +95,7 @@ const Li = styled.li<{ selected: boolean; isLastItem: boolean; }>` + background-color: ${vscBackground}; ${({ highlighted }) => highlighted && "background: #ff000066;"} ${({ selected }) => selected && "font-weight: bold;"} padding: 0.5rem 0.75rem; @@ -149,10 +125,6 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { // The position of the current command you are typing now, so the one that will be appended to history once you press enter const [positionInHistory, setPositionInHistory] = React.useState<number>(0); const [items, setItems] = React.useState(props.items); - const [hoveringButton, setHoveringButton] = React.useState(false); - const [hoveringContextDropdown, setHoveringContextDropdown] = - React.useState(false); - const [pinned, setPinned] = useState(false); const [highlightedCodeSections, setHighlightedCodeSections] = React.useState( props.highlightedCodeSections || [] ); @@ -181,6 +153,7 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { useImperativeHandle(ref, () => downshiftProps, [downshiftProps]); const [metaKeyPressed, setMetaKeyPressed] = useState(false); + const [focused, setFocused] = useState(false); useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (e.key === "Meta") { @@ -241,6 +214,14 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { )} */} {highlightedCodeSections.map((section, idx) => ( <PillButton + warning={ + section.range.contents.length > 4000 && section.editing + ? "Editing such a large range may be slow" + : undefined + } + onlyShowDelete={ + highlightedCodeSections.length <= 1 || section.editing + } editing={section.editing} pinned={section.pinned} index={idx} @@ -258,15 +239,6 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { return newSections; }); }} - onHover={(val: boolean) => { - if (val) { - setHoveringButton(val); - } else { - setTimeout(() => { - setHoveringButton(val); - }, 100); - } - }} /> ))} {props.highlightedCodeSections.length > 0 && @@ -276,11 +248,11 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { props.onToggleAddContext(); }} > - Highlight to Add Context + Highlight code section </EmptyPillDiv> ) : ( <HeaderButtonWithText - text="Add to Context" + text="Add more code to context" onClick={() => { props.onToggleAddContext(); }} @@ -292,7 +264,7 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { <div className="flex px-2" ref={divRef} hidden={!downshiftProps.isOpen}> <MainTextInput disabled={props.disabled} - placeholder="Ask a question, give instructions, or type '/' to see slash commands. ⌘⏎ to edit." + placeholder={`Ask a question, give instructions, or type '/' to see slash commands`} {...getInputProps({ onChange: (e) => { const target = e.target as HTMLTextAreaElement; @@ -305,6 +277,13 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { // setShowContextDropdown(target.value.endsWith("@")); }, + onFocus: (e) => { + setFocused(true); + }, + onBlur: (e) => { + setFocused(false); + postVscMessage("blurContinueInput", {}); + }, onKeyDown: (event) => { if (event.key === "Enter" && event.shiftKey) { // Prevent Downshift's default 'Enter' behavior. @@ -359,6 +338,7 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { })} showAbove={showAbove()} ulHeightPixels={ulRef.current?.getBoundingClientRect().height || 0} + hidden={!downshiftProps.isOpen || items.length === 0} > {downshiftProps.isOpen && items.map((item, index) => ( @@ -378,29 +358,13 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { </div> {highlightedCodeSections.length === 0 && (downshiftProps.inputValue?.startsWith("/edit") || - (metaKeyPressed && downshiftProps.inputValue?.length > 0)) && ( + (focused && + metaKeyPressed && + downshiftProps.inputValue?.length > 0)) && ( <div className="text-trueGray-400 pr-4 text-xs text-right"> Inserting at cursor </div> )} - <ContextDropdown - onMouseEnter={() => { - setHoveringContextDropdown(true); - }} - onMouseLeave={() => { - setHoveringContextDropdown(false); - }} - hidden={true || (!hoveringContextDropdown && !hoveringButton)} - > - {highlightedCodeSections.map((section, idx) => ( - <> - <p>{section.display_name}</p> - <CodeBlock showCopy={false} key={idx}> - {section.range.contents} - </CodeBlock> - </> - ))} - </ContextDropdown> </> ); }); diff --git a/extension/react-app/src/components/InputAndButton.tsx b/extension/react-app/src/components/InputAndButton.tsx index 0a8592f2..8019d014 100644 --- a/extension/react-app/src/components/InputAndButton.tsx +++ b/extension/react-app/src/components/InputAndButton.tsx @@ -1,6 +1,6 @@ import React, { useRef } from "react"; import styled from "styled-components"; -import { vscBackground } from "."; +import { vscBackground, vscForeground } from "."; interface InputAndButtonProps { onUserInput: (input: string) => void; @@ -16,7 +16,7 @@ const Input = styled.input` padding: 0.5rem; border: 1px solid white; background-color: ${vscBackground}; - color: white; + color: ${vscForeground}; border-radius: 4px; border-top-right-radius: 0; border-bottom-right-radius: 0; @@ -27,7 +27,7 @@ const Button = styled.button` padding: 0.5rem; border: 1px solid white; background-color: ${vscBackground}; - color: white; + color: ${vscForeground}; border-radius: 4px; border-top-left-radius: 0; border-bottom-left-radius: 0; @@ -35,8 +35,8 @@ const Button = styled.button` cursor: pointer; &:hover { - background-color: white; - color: black; + background-color: ${vscForeground}; + color: ${vscBackground}; } `; diff --git a/extension/react-app/src/components/Onboarding.tsx b/extension/react-app/src/components/Onboarding.tsx index 7772a25e..231c1e93 100644 --- a/extension/react-app/src/components/Onboarding.tsx +++ b/extension/react-app/src/components/Onboarding.tsx @@ -22,22 +22,17 @@ const StyledSpan = styled.span` &:hover { background-color: #ffffff33; } + white-space: nowrap; `; const Onboarding = () => { const [counter, setCounter] = useState(4); - const gifs = ["intro", "explain", "edit", "generate", "intro"]; + const gifs = ["intro", "highlight", "question", "help"]; const topMessages = [ - "Welcome to Continue!", - "Answer coding questions", - "Edit in natural language", - "Generate files from scratch", - ]; - const bottomMessages = [ - "", - "Ask Continue about a part of your code to get another perspective", - "Highlight a section of code and instruct Continue to refactor it", - "Let Continue build the scaffolding of Python scripts, React components, and more", + "Welcome!", + "Highlight code", + "Ask a question", + "Use /help to learn more", ]; useEffect(() => { @@ -107,7 +102,6 @@ const Onboarding = () => { /> )} </div> - <p>{bottomMessages[counter]}</p> <p style={{ paddingLeft: "50px", @@ -115,6 +109,7 @@ const Onboarding = () => { paddingBottom: "50px", textAlign: "center", cursor: "pointer", + whiteSpace: "nowrap", }} > <StyledSpan diff --git a/extension/react-app/src/components/PillButton.tsx b/extension/react-app/src/components/PillButton.tsx index 31d98c0f..5929d06a 100644 --- a/extension/react-app/src/components/PillButton.tsx +++ b/extension/react-app/src/components/PillButton.tsx @@ -3,15 +3,20 @@ import styled from "styled-components"; import { StyledTooltip, defaultBorderRadius, - lightGray, secondaryDark, + vscBackground, + vscForeground, } from "."; -import { Trash, PaintBrush, MapPin } from "@styled-icons/heroicons-outline"; +import { + Trash, + PaintBrush, + ExclamationTriangle, +} from "@styled-icons/heroicons-outline"; import { GUIClientContext } from "../App"; const Button = styled.button` border: none; - color: white; + color: ${vscForeground}; background-color: ${secondaryDark}; border-radius: ${defaultBorderRadius}; padding: 8px; @@ -28,10 +33,8 @@ const GridDiv = styled.div` height: 100%; display: grid; grid-gap: 0; - grid-template-columns: 1fr 1fr; align-items: center; border-radius: ${defaultBorderRadius}; - overflow: hidden; background-color: ${secondaryDark}; `; @@ -48,6 +51,21 @@ const ButtonDiv = styled.div<{ backgroundColor: string }>` } `; +const CircleDiv = styled.div` + position: absolute; + top: -10px; + right: -10px; + width: 20px; + height: 20px; + border-radius: 50%; + background-color: red; + color: white; + display: flex; + align-items: center; + justify-content: center; + padding: 2px; +`; + interface PillButtonProps { onHover?: (arg0: boolean) => void; onDelete?: () => void; @@ -55,6 +73,8 @@ interface PillButtonProps { index: number; editing: boolean; pinned: boolean; + warning?: string; + onlyShowDelete?: boolean; } const PillButton = (props: PillButtonProps) => { @@ -63,75 +83,103 @@ const PillButton = (props: PillButtonProps) => { return ( <> - <Button - style={{ - position: "relative", - borderColor: props.editing - ? "#8800aa" - : props.pinned - ? "#ffff0099" - : "transparent", - borderWidth: "1px", - borderStyle: "solid", - }} - onMouseEnter={() => { - setIsHovered(true); - if (props.onHover) { - props.onHover(true); - } - }} - onMouseLeave={() => { - setIsHovered(false); - if (props.onHover) { - props.onHover(false); - } - }} - > - {isHovered && ( - <GridDiv> - <ButtonDiv - data-tooltip-id={`edit-${props.index}`} - backgroundColor={"#8800aa55"} - onClick={() => { - client?.setEditingAtIndices([props.index]); + <div style={{ position: "relative" }}> + <Button + style={{ + position: "relative", + borderColor: props.warning + ? "red" + : props.editing + ? "#8800aa" + : props.pinned + ? "#ffff0099" + : "transparent", + borderWidth: "1px", + borderStyle: "solid", + }} + onMouseEnter={() => { + setIsHovered(true); + if (props.onHover) { + props.onHover(true); + } + }} + onMouseLeave={() => { + setIsHovered(false); + if (props.onHover) { + props.onHover(false); + } + }} + > + {isHovered && ( + <GridDiv + style={{ + gridTemplateColumns: props.onlyShowDelete ? "1fr" : "1fr 1fr", + backgroundColor: vscBackground, }} > - <PaintBrush style={{ margin: "auto" }} width="1.6em"></PaintBrush> - </ButtonDiv> + {props.onlyShowDelete || ( + <ButtonDiv + data-tooltip-id={`edit-${props.index}`} + backgroundColor={"#8800aa55"} + onClick={() => { + client?.setEditingAtIndices([props.index]); + }} + > + <PaintBrush + style={{ margin: "auto" }} + width="1.6em" + ></PaintBrush> + </ButtonDiv> + )} - {/* <ButtonDiv + {/* <ButtonDiv data-tooltip-id={`pin-${props.index}`} backgroundColor={"#ffff0055"} onClick={() => { client?.setPinnedAtIndices([props.index]); }} - > + > <MapPin style={{ margin: "auto" }} width="1.6em"></MapPin> </ButtonDiv> */} - <StyledTooltip id={`pin-${props.index}`}> - Edit this range + <StyledTooltip id={`pin-${props.index}`}> + Edit this range + </StyledTooltip> + <ButtonDiv + data-tooltip-id={`delete-${props.index}`} + backgroundColor={"#cc000055"} + onClick={() => { + if (props.onDelete) { + props.onDelete(); + } + }} + > + <Trash style={{ margin: "auto" }} width="1.6em"></Trash> + </ButtonDiv> + </GridDiv> + )} + {props.title} + </Button> + <StyledTooltip id={`edit-${props.index}`}> + {props.editing + ? "Editing this section (with entire file as context)" + : "Edit this section"} + </StyledTooltip> + <StyledTooltip id={`delete-${props.index}`}>Delete</StyledTooltip> + {props.warning && ( + <> + <CircleDiv data-tooltip-id={`circle-div-${props.title}`}> + <ExclamationTriangle + style={{ margin: "auto" }} + width="1.0em" + strokeWidth={2} + /> + </CircleDiv> + <StyledTooltip id={`circle-div-${props.title}`}> + {props.warning} </StyledTooltip> - <ButtonDiv - data-tooltip-id={`delete-${props.index}`} - backgroundColor={"#cc000055"} - onClick={() => { - if (props.onDelete) { - props.onDelete(); - } - }} - > - <Trash style={{ margin: "auto" }} width="1.6em"></Trash> - </ButtonDiv> - </GridDiv> + </> )} - {props.title} - </Button> - <StyledTooltip id={`edit-${props.index}`}> - {props.editing - ? "Editing this range (with rest of file as context)" - : "Edit this range"} - </StyledTooltip> - <StyledTooltip id={`delete-${props.index}`}>Delete</StyledTooltip> + </div> </> ); }; diff --git a/extension/react-app/src/components/StepContainer.tsx b/extension/react-app/src/components/StepContainer.tsx index d1a8a46a..bc8665fd 100644 --- a/extension/react-app/src/components/StepContainer.tsx +++ b/extension/react-app/src/components/StepContainer.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useRef, useState } from "react"; +import { useContext, useEffect, useRef, useState } from "react"; import styled, { keyframes } from "styled-components"; import { appear, @@ -6,18 +6,21 @@ import { secondaryDark, vscBackground, vscBackgroundTransparent, + vscForeground, } from "."; import { ChevronDown, ChevronRight, ArrowPath, XMark, + MagnifyingGlass, } from "@styled-icons/heroicons-outline"; import { StopCircle } from "@styled-icons/heroicons-solid"; import { HistoryNode } from "../../../schema/HistoryNode"; -import ReactMarkdown from "react-markdown"; import HeaderButtonWithText from "./HeaderButtonWithText"; -import CodeBlock from "./CodeBlock"; +import MarkdownPreview from "@uiw/react-markdown-preview"; +import { getMetaKeyLabel, isMetaEquivalentKeyPressed } from "../util"; +import { GUIClientContext } from "../App"; interface StepContainerProps { historyNode: HistoryNode; @@ -31,6 +34,7 @@ interface StepContainerProps { onToggle: () => void; isFirst: boolean; isLast: boolean; + index: number; } // #region styled components @@ -38,7 +42,6 @@ interface StepContainerProps { const MainDiv = styled.div<{ stepDepth: number; inFuture: boolean }>` opacity: ${(props) => (props.inFuture ? 0.3 : 1)}; animation: ${appear} 0.3s ease-in-out; - /* padding-left: ${(props) => props.stepDepth * 20}px; */ overflow: hidden; margin-left: 0px; margin-right: 0px; @@ -52,12 +55,7 @@ const StepContainerDiv = styled.div<{ open: boolean }>` `; const HeaderDiv = styled.div<{ error: boolean; loading: boolean }>` - background-color: ${(props) => - props.error - ? "#522" - : props.loading - ? vscBackgroundTransparent - : vscBackground}; + background-color: ${(props) => (props.error ? "#522" : vscBackground)}; display: grid; grid-template-columns: 1fr auto auto; grid-gap: 8px; @@ -72,19 +70,6 @@ const ContentDiv = styled.div<{ isUserInput: boolean }>` font-size: 13px; `; -const MarkdownPre = styled.pre` - background-color: ${secondaryDark}; - padding: 10px; - border-radius: ${defaultBorderRadius}; - border: 0.5px solid white; -`; - -const StyledCode = styled.code` - word-wrap: break-word; - color: #f69292; - background: transparent; -`; - const gradient = keyframes` 0% { background-position: 0px 0; @@ -124,6 +109,33 @@ const GradientBorder = styled.div<{ background-size: 200% 200%; `; +const StyledMarkdownPreview = styled(MarkdownPreview)` + pre { + background-color: ${secondaryDark}; + padding: 1px; + border-radius: ${defaultBorderRadius}; + border: 0.5px solid white; + } + + code { + color: #f78383; + word-wrap: break-word; + border-radius: ${defaultBorderRadius}; + background-color: ${secondaryDark}; + } + + pre > code { + background-color: ${secondaryDark}; + color: ${vscForeground}; + } + + background-color: ${vscBackground}; + font-family: "Lexend", sans-serif; + font-size: 13px; + padding: 8px; + color: ${vscForeground}; +`; + // #endregion function StepContainer(props: StepContainerProps) { @@ -131,6 +143,7 @@ function StepContainer(props: StepContainerProps) { const naturalLanguageInputRef = useRef<HTMLTextAreaElement>(null); const userInputRef = useRef<HTMLInputElement>(null); const isUserInput = props.historyNode.step.name === "UserInputStep"; + const client = useContext(GUIClientContext); useEffect(() => { if (userInputRef?.current) { @@ -158,7 +171,7 @@ function StepContainer(props: StepContainerProps) { > <StepContainerDiv open={props.open}> <GradientBorder - loading={props.historyNode.active as boolean || false} + loading={(props.historyNode.active as boolean) || false} isFirst={props.isFirst} isLast={props.isLast} borderColor={ @@ -170,7 +183,7 @@ function StepContainer(props: StepContainerProps) { } className="overflow-hidden cursor-pointer" onClick={(e) => { - if (e.metaKey) { + if (isMetaEquivalentKeyPressed(e)) { props.onToggleAll(); } else { props.onToggle(); @@ -178,7 +191,7 @@ function StepContainer(props: StepContainerProps) { }} > <HeaderDiv - loading={props.historyNode.active as boolean || false} + loading={(props.historyNode.active as boolean) || false} error={props.historyNode.observation?.error ? true : false} > <div className="m-2"> @@ -201,12 +214,27 @@ function StepContainer(props: StepContainerProps) { </HeaderButton> */} <> + {(props.historyNode.logs as any)?.length > 0 && ( + <HeaderButtonWithText + text="Logs" + onClick={(e) => { + e.stopPropagation(); + client?.showLogsAtIndex(props.index); + }} + > + <MagnifyingGlass size="1.4em" /> + </HeaderButtonWithText> + )} <HeaderButtonWithText onClick={(e) => { e.stopPropagation(); props.onDelete(); }} - text={props.historyNode.active ? "Stop (⌘⌫)" : "Delete"} + text={ + props.historyNode.active + ? `Stop (${getMetaKeyLabel()}⌫)` + : "Delete" + } > {props.historyNode.active ? ( <StopCircle size="1.6em" onClick={props.onDelete} /> @@ -242,31 +270,19 @@ function StepContainer(props: StepContainerProps) { )} {props.historyNode.observation?.error ? ( - <pre className="overflow-x-scroll"> - {props.historyNode.observation.error as string} - </pre> + <details> + <summary>View Traceback</summary> + <pre className="overflow-x-scroll"> + {props.historyNode.observation.error as string} + </pre> + </details> ) : ( - <ReactMarkdown - key={1} - className="overflow-x-scroll" - components={{ - pre: ({ node, ...props }) => { - return ( - <CodeBlock - children={(props.children[0] as any).props.children[0]} - /> - ); - }, - code: ({ node, ...props }) => { - return <StyledCode children={props.children[0] as any} />; - }, - ul: ({ node, ...props }) => { - return <ul className="ml-0" {...props} />; - }, + <StyledMarkdownPreview + source={props.historyNode.step.description || ""} + wrapperElement={{ + "data-color-mode": "dark", }} - > - {props.historyNode.step.description as any} - </ReactMarkdown> + /> )} </ContentDiv> </StepContainerDiv> diff --git a/extension/react-app/src/components/TextDialog.tsx b/extension/react-app/src/components/TextDialog.tsx index ea5727f0..9597b578 100644 --- a/extension/react-app/src/components/TextDialog.tsx +++ b/extension/react-app/src/components/TextDialog.tsx @@ -1,7 +1,9 @@ // Write a component that displays a dialog box with a text field and a button. import React, { useEffect, useState } from "react"; import styled from "styled-components"; -import { Button, buttonColor, secondaryDark, vscBackground } from "."; +import { Button, secondaryDark, vscBackground, vscForeground } from "."; +import { isMetaEquivalentKeyPressed } from "../util"; +import { ReactMarkdown } from "react-markdown/lib/react-markdown"; const ScreenCover = styled.div` position: absolute; @@ -20,13 +22,13 @@ const DialogContainer = styled.div` `; const Dialog = styled.div` - background-color: white; + color: ${vscForeground}; + background-color: ${vscBackground}; border-radius: 8px; padding: 8px; display: flex; flex-direction: column; - /* box-shadow: 0 0 10px 0 rgba(255, 255, 255, 0.5); */ - border: 2px solid ${buttonColor}; + box-shadow: 0 0 10px 0 ${vscForeground}; width: fit-content; margin: auto; `; @@ -37,14 +39,16 @@ const TextArea = styled.textarea` padding: 8px; outline: 1px solid black; resize: none; + background-color: ${secondaryDark}; + color: ${vscForeground}; &:focus { - outline: 1px solid ${buttonColor}; + outline: 1px solid ${vscForeground}; } `; const P = styled.p` - color: black; + color: ${vscForeground}; margin: 8px auto; `; @@ -53,6 +57,7 @@ const TextDialog = (props: { onEnter: (text: string) => void; onClose: () => void; message?: string; + entryOn?: boolean; }) => { const [text, setText] = useState(""); const textAreaRef = React.createRef<HTMLTextAreaElement>(); @@ -76,29 +81,37 @@ const TextDialog = (props: { }} > <Dialog> - <P>{props.message || ""}</P> - <TextArea - rows={10} - ref={textAreaRef} - onKeyDown={(e) => { - if (e.key === "Enter" && e.metaKey && textAreaRef.current) { - props.onEnter(textAreaRef.current.value); - setText(""); - } else if (e.key === "Escape") { - props.onClose(); - } - }} - /> - <Button - onClick={() => { - if (textAreaRef.current) { - props.onEnter(textAreaRef.current.value); - setText(""); - } - }} - > - Enter - </Button> + <ReactMarkdown>{props.message || ""}</ReactMarkdown> + {props.entryOn && ( + <> + <TextArea + rows={10} + ref={textAreaRef} + onKeyDown={(e) => { + if ( + e.key === "Enter" && + isMetaEquivalentKeyPressed(e) && + textAreaRef.current + ) { + props.onEnter(textAreaRef.current.value); + setText(""); + } else if (e.key === "Escape") { + props.onClose(); + } + }} + /> + <Button + onClick={() => { + if (textAreaRef.current) { + props.onEnter(textAreaRef.current.value); + setText(""); + } + }} + > + Enter + </Button> + </> + )} </Dialog> </DialogContainer> </ScreenCover> diff --git a/extension/react-app/src/components/index.ts b/extension/react-app/src/components/index.ts index 9ae0f097..cb5e7915 100644 --- a/extension/react-app/src/components/index.ts +++ b/extension/react-app/src/components/index.ts @@ -3,12 +3,16 @@ import styled, { keyframes } from "styled-components"; export const defaultBorderRadius = "5px"; export const lightGray = "rgb(100 100 100)"; -export const secondaryDark = "rgb(45 45 45)"; -export const vscBackground = "rgb(30 30 30)"; +// export const secondaryDark = "rgb(45 45 45)"; +// export const vscBackground = "rgb(30 30 30)"; export const vscBackgroundTransparent = "#1e1e1ede"; export const buttonColor = "rgb(113 28 59)"; export const buttonColorHover = "rgb(113 28 59 0.67)"; +export const secondaryDark = "var(--vscode-textBlockQuote-background)"; +export const vscBackground = "var(--vscode-editor-background)"; +export const vscForeground = "var(--vscode-editor-foreground)"; + export const Button = styled.button` padding: 10px 12px; margin: 8px 0; @@ -46,8 +50,8 @@ export const TextArea = styled.textarea` resize: vertical; padding: 4px; - caret-color: white; - color: white; + caret-color: ${vscForeground}; + color: #{vscForeground}; &:focus { outline: 1px solid ${buttonColor}; @@ -120,7 +124,7 @@ export const MainTextInput = styled.textarea` border: 1px solid #ccc; margin: 8px 8px; background-color: ${vscBackground}; - color: white; + color: ${vscForeground}; outline: 1px solid orange; resize: none; `; @@ -137,8 +141,9 @@ export const appear = keyframes` `; export const HeaderButton = styled.button<{ inverted: boolean | undefined }>` - background-color: ${({ inverted }) => (inverted ? "white" : "transparent")}; - color: ${({ inverted }) => (inverted ? "black" : "white")}; + background-color: ${({ inverted }) => + inverted ? vscForeground : "transparent"}; + color: ${({ inverted }) => (inverted ? vscBackground : vscForeground)}; border: none; border-radius: ${defaultBorderRadius}; @@ -146,7 +151,9 @@ export const HeaderButton = styled.button<{ inverted: boolean | undefined }>` &:hover { background-color: ${({ inverted }) => - typeof inverted === "undefined" || inverted ? lightGray : "transparent"}; + typeof inverted === "undefined" || inverted + ? secondaryDark + : "transparent"}; } display: flex; align-items: center; |