From a7c4a1b179afdaad3ca1234d6ebfa97deb1efdf2 Mon Sep 17 00:00:00 2001 From: mp Date: Mon, 16 Dec 2024 23:01:41 -0800 Subject: [PATCH] input box style --- .../react/src/sidebar-tsx/SidebarChat.tsx | 172 ++++++++++-------- .../void/browser/react/src/util/inputs.tsx | 14 +- 2 files changed, 101 insertions(+), 85 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx index 924f75a6..8fd4be9b 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx @@ -102,7 +102,7 @@ const ScrollToBottomContainer = ({ children, className, style }: { children: Rea const isBottom = Math.abs( div.scrollHeight - div.clientHeight - div.scrollTop - ) < 1; + ) < 4; setIsAtBottom(isBottom); }; @@ -159,71 +159,66 @@ export const SelectedFiles = ( return ( !!selections && selections.length !== 0 && ( -
- {selections.map((selection, i) => ( - - {/* selected file summary */} -
+ {selections.map((selection, i) => { + + const showSelectionText = selection.selectionStr && selectionIsOpened[i] + + return ( +
+ {/* selection summary */} +
{ - setSelectionIsOpened(s => { - const newS = [...s] - newS[i] = !newS[i] - return newS - }); - }} - > - - - {/* file name */} - {getBasename(selection.fileURI.fsPath)} - {/* selection range */} - {selection.selectionStr !== null ? ` (${selection.range.startLineNumber}-${selection.range.endLineNumber})` : ''} - - - {/* type of selection */} - {selection.selectionStr !== null ? 'Selection' : 'File'} - - {/* X button */} - {type === 'staging' && // hoveredIdx === i - { - e.stopPropagation(); - if (type !== 'staging') return; - setStaging([...selections.slice(0, i), ...selections.slice(i + 1)]) - setSelectionIsOpened(o => [...o.slice(0, i), ...o.slice(i + 1)]) - }} - > - + onClick={() => { + setSelectionIsOpened(s => { + const newS = [...s] + newS[i] = !newS[i] + return newS + }); + }} + > + + {/* file name */} + {getBasename(selection.fileURI.fsPath)} + {/* selection range */} + {selection.selectionStr !== null ? ` (${selection.range.startLineNumber}-${selection.range.endLineNumber})` : ''} + + {/* type of selection */} + {selection.selectionStr !== null ? 'Selection' : 'File'} + + {/* X button */} + {type === 'staging' && // hoveredIdx === i + { + e.stopPropagation(); + if (type !== 'staging') return; + setStaging([...selections.slice(0, i), ...selections.slice(i + 1)]) + setSelectionIsOpened(o => [...o.slice(0, i), ...o.slice(i + 1)]) + }} + > + + + } +
+ {/* selection text */} + {showSelectionText && +
+ +
}
- {/* selection full text */} - {selection.selectionStr && selectionIsOpened[i] && - { // clear the selection string but keep the file - // // setStaging([...selections.slice(0, i), { ...selection, selectionStr: null }, ...selections.slice(i + 1, Infinity)]) - // // }} - // onClick={() => { - // if (type !== 'staging') return - // setStaging([...selections.slice(0, i), ...selections.slice(i + 1, Infinity)]) - // }} - // className="btn btn-secondary btn-sm border border-vscode-input-border rounded" - // >Remove - // )} - /> - } - - )) - } + ) + })}
) ) @@ -296,7 +291,7 @@ export const SidebarChat = () => { // state of current message const [instructions, setInstructions] = useState('') // the user's instructions const isDisabled = !instructions.trim() - const [formHeight, setFormHeight] = useState(0) + const [formHeight, setFormHeight] = useState(0) // TODO should use resize observer instead const [sidebarHeight, setSidebarHeight] = useState(0) const onChangeText = useCallback((newStr: string) => { setInstructions(newStr) }, [setInstructions]) @@ -405,8 +400,7 @@ export const SidebarChat = () => { const previousMessages = currentThread?.messages ?? [] - - const [_test, _setTest] = useState([]) + // const [_test_messages, _set_test_messages] = useState([]) return
{ if (ref) { setSidebarHeight(ref.clientHeight); } }} @@ -414,7 +408,7 @@ export const SidebarChat = () => { > {/* previous messages */} {previousMessages.map((message, i) => )} @@ -422,12 +416,11 @@ export const SidebarChat = () => { {/* message stream */} - - {_test.map((_, i) =>
div {i}
)} -
{`totalHeight: ${sidebarHeight - formHeight - 30}`}
-
{`sidebarHeight: ${sidebarHeight}`}
-
{`formHeight: ${formHeight}`}
- + {/* {_test_messages.map((_, i) =>
div {i}
)} +
{`totalHeight: ${sidebarHeight - formHeight - 30}`}
+
{`sidebarHeight: ${sidebarHeight}`}
+
{`formHeight: ${formHeight}`}
+ */}
@@ -454,9 +447,14 @@ export const SidebarChat = () => { console.log('submit!') onSubmit(e) }} + onClick={(e) => { + if (e.currentTarget === e.target) { + inputBoxRef.current?.focus() + } + }} > {/* top row */} -
+ <> {/* selections */} {(selections && selections.length !== 0) && @@ -471,10 +469,24 @@ export const SidebarChat = () => { showDismiss={true} /> } -
+ {/* middle row */} -
+
`@@[&_textarea]:!void-${style}`) // apply styles to ancestor input and textarea elements + // .join(' ') + + // ` outline-none` + // .split(' ') + // .map(style => `@@[&_div.monaco-inputbox]:!void-${style}`) // apply styles to ancestor input and textarea elements + // .join(' '); + `@@[&_textarea]:!void-bg-transparent @@[&_textarea]:!void-outline-none @@[&_textarea]:!void-text-vscode-input-fg @@[&_textarea]:!void-min-h-[81px] @@[&_textarea]:!void-max-h-[500px]@@[&_div.monaco-inputbox]:!void- @@[&_div.monaco-inputbox]:!void-outline-none` + } + > + {/* text input */} {
{/* bottom row */} -
+
{/* submit options */}
@@ -495,7 +509,7 @@ export const SidebarChat = () => { {isLoading ? // stop button }
-
-
+
+
} diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx index 769056ed..adeb6930 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx @@ -3,9 +3,9 @@ * Void Editor additions licensed under the AGPL 3.0 License. *--------------------------------------------------------------------------------------------*/ -import React, { useCallback, useEffect, useRef, useState } from 'react'; -import { useService } from './services.js'; -import { InputBox } from '../../../../../../../base/browser/ui/inputbox/inputBox.js'; +import React, { useCallback, useEffect, useRef } from 'react'; +import { useService } from '../util/services.js'; +import { , InputBox } from '../../../../../../../base/browser/ui/inputbox/inputBox.js'; import { defaultInputBoxStyles, defaultSelectBoxStyles } from '../../../../../../../platform/theme/browser/defaultStyles.js'; import { SelectBox } from '../../../../../../../base/browser/ui/selectBox/selectBox.js'; import { IDisposable } from '../../../../../../../base/common/lifecycle.js'; @@ -39,15 +39,15 @@ export const WidgetComponent = ({ ctor, prop -export const VoidInputBox = ({ onChangeText, onCreateInstance, inputBoxRef, placeholder, multiline }: { +export const VoidInputBox = ({ onChangeText, onCreateInstance, inputBoxRef, placeholder, multiline, styles }: { onChangeText: (value: string) => void; + styles?: Partial, onCreateInstance?: (instance: InputBox) => void | IDisposable[]; inputBoxRef?: { current: InputBox | null }; placeholder: string; multiline: boolean; }) => { - const contextViewProvider = useService('contextViewService'); return