feat: Add popover to ChatPanel
This commit adds a popover to ChatPanel that contains a dropdown menu for commands and contexts. The dropdown menu can be opened by clicking on the ChatPanel's textarea. The dropdown menu contains a list of commands and contexts that can be clicked to insert them into the textarea. The popover also contains a tooltip that provides instructions on how to select code or file and right-click to access the context menu.
This commit is contained in:
parent
8e84acab08
commit
1aaf8a6ec9
@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import { Accordion, AccordionControlProps, Avatar, Box, Center, Code, Container, CopyButton, Divider, Flex, Grid, Stack, Textarea, TypographyStylesProvider, px, rem, useMantineTheme } from '@mantine/core';
|
||||
import { Accordion, AccordionControlProps, Avatar, Box, Center, Code, Container, CopyButton, Divider, Flex, Grid, Popover, Stack, Textarea, TypographyStylesProvider, px, rem, useMantineTheme } from '@mantine/core';
|
||||
import { Input, Tooltip } from '@mantine/core';
|
||||
import { List } from '@mantine/core';
|
||||
import { ScrollArea } from '@mantine/core';
|
||||
@ -235,62 +235,96 @@ const chatPanel = () => {
|
||||
|
||||
const commandMenusNode = commandMenus.map(({ pattern, description, name }, index) => {
|
||||
return (
|
||||
<Menu.Item
|
||||
<Flex
|
||||
mih={40}
|
||||
gap="md"
|
||||
justify="flex-start"
|
||||
align="flex-start"
|
||||
direction="row"
|
||||
wrap="wrap"
|
||||
sx={{
|
||||
'&:hover, &[data-hovered]': {
|
||||
color: 'var(--vscode-menu-selectionForeground)',
|
||||
border: 'var(--vscode-menu-selectionBorder)',
|
||||
backgroundColor: 'var(--vscode-menu-selectionBackground)'
|
||||
padding: '5px 0',
|
||||
'&:hover': {
|
||||
cursor: 'pointer',
|
||||
color: 'var(--vscode-commandCenter-activeForeground)',
|
||||
backgroundColor: 'var(--vscode-commandCenter-activeBackground)'
|
||||
}
|
||||
}}
|
||||
onClick={() => { setInput(`/${pattern} `); }}
|
||||
icon={<IconTerminal2 size={16} color='var(--vscode-menu-foreground)' />}
|
||||
onClick={() => {
|
||||
setInput(`/${pattern} `);
|
||||
setMenuOpend(false);
|
||||
}}
|
||||
>
|
||||
<Text sx={{
|
||||
fontSize: 'sm',
|
||||
fontWeight: 'bolder',
|
||||
color: 'var(--vscode-menu-foreground)'
|
||||
}}>
|
||||
/{pattern}
|
||||
</Text>
|
||||
<Text sx={{
|
||||
fontSize: 'sm',
|
||||
color: theme.colors.gray[6],
|
||||
}}>
|
||||
{description}
|
||||
</Text>
|
||||
</Menu.Item>);
|
||||
<IconTerminal2
|
||||
size={16}
|
||||
color='var(--vscode-menu-foreground)'
|
||||
style={{
|
||||
marginTop: 8,
|
||||
marginLeft: 8,
|
||||
}} />
|
||||
<Stack spacing={0}>
|
||||
<Text sx={{
|
||||
fontSize: 'sm',
|
||||
fontWeight: 'bolder',
|
||||
color: 'var(--vscode-menu-foreground)'
|
||||
}}>
|
||||
/{pattern}
|
||||
</Text>
|
||||
<Text sx={{
|
||||
fontSize: 'sm',
|
||||
color: theme.colors.gray[6],
|
||||
}}>
|
||||
{description}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Flex>);
|
||||
});
|
||||
|
||||
const contextMenusNode = contextMenus.map(({ pattern, description, name }, index) => {
|
||||
return (
|
||||
<Menu.Item
|
||||
<Flex
|
||||
mih={40}
|
||||
gap="md"
|
||||
justify="flex-start"
|
||||
align="flex-start"
|
||||
direction="row"
|
||||
wrap="wrap"
|
||||
sx={{
|
||||
'&:hover, &[data-hovered]': {
|
||||
color: 'var(--vscode-menu-selectionForeground)',
|
||||
border: 'var(--vscode-menu-selectionBorder)',
|
||||
backgroundColor: 'var(--vscode-menu-selectionBackground)'
|
||||
padding: '5px 0',
|
||||
'&:hover': {
|
||||
cursor: 'pointer',
|
||||
color: 'var(--vscode-commandCenter-activeForeground)',
|
||||
backgroundColor: 'var(--vscode-commandCenter-activeBackground)'
|
||||
}
|
||||
}}
|
||||
onClick={() => {
|
||||
handleContextClick(name);
|
||||
setMenuOpend(false);
|
||||
}}
|
||||
icon={<IconMessagePlus size={16} color='var(--vscode-menu-foreground)' />}
|
||||
>
|
||||
<Text sx={{
|
||||
fontSize: 'sm',
|
||||
fontWeight: 'bolder',
|
||||
color: 'var(--vscode-menu-foreground)'
|
||||
}}>
|
||||
{name}
|
||||
</Text>
|
||||
<Text sx={{
|
||||
fontSize: 'sm',
|
||||
color: theme.colors.gray[6],
|
||||
}}>
|
||||
{description}
|
||||
</Text>
|
||||
</Menu.Item>);
|
||||
<IconMessagePlus
|
||||
size={16}
|
||||
color='var(--vscode-menu-foreground)'
|
||||
style={{
|
||||
marginTop: 8,
|
||||
marginLeft: 8,
|
||||
}} />
|
||||
<Stack spacing={0}>
|
||||
<Text sx={{
|
||||
fontSize: 'sm',
|
||||
fontWeight: 'bolder',
|
||||
color: 'var(--vscode-menu-foreground)'
|
||||
}}>
|
||||
{name}
|
||||
</Text>
|
||||
<Text sx={{
|
||||
fontSize: 'sm',
|
||||
color: theme.colors.gray[6],
|
||||
}}>
|
||||
{description}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Flex>);
|
||||
});
|
||||
|
||||
const messageList = messages.map(({ message: messageText, type: messageType, contexts }, index) => {
|
||||
@ -330,7 +364,7 @@ const chatPanel = () => {
|
||||
}}
|
||||
styles={{
|
||||
item: {
|
||||
border: 'var(--vscode-menu-border)',
|
||||
borderColor: 'var(--vscode-menu-border)',
|
||||
backgroundColor: 'var(--vscode-menu-background)',
|
||||
},
|
||||
control: {
|
||||
@ -556,7 +590,7 @@ const chatPanel = () => {
|
||||
}}
|
||||
styles={{
|
||||
item: {
|
||||
border: 'var(--vscode-menu-border)',
|
||||
borderColor: 'var(--vscode-menu-border)',
|
||||
backgroundColor: 'var(--vscode-menu-background)',
|
||||
},
|
||||
control: {
|
||||
@ -626,7 +660,7 @@ const chatPanel = () => {
|
||||
}
|
||||
</Accordion>
|
||||
}
|
||||
<Menu
|
||||
<Popover
|
||||
id='commandMenu'
|
||||
position='top-start'
|
||||
closeOnClickOutside={true}
|
||||
@ -641,7 +675,7 @@ const chatPanel = () => {
|
||||
onOpen={() => menuType !== '' ? setMenuOpend(true) : setMenuOpend(false)}
|
||||
returnFocus={true}
|
||||
>
|
||||
<Menu.Target>
|
||||
<Popover.Target>
|
||||
<Textarea
|
||||
id='chat-textarea'
|
||||
disabled={generating}
|
||||
@ -661,7 +695,7 @@ const chatPanel = () => {
|
||||
rightSection: { alignItems: 'flex-start', paddingTop: '9px' },
|
||||
input: {
|
||||
backgroundColor: 'var(--vscode-input-background)',
|
||||
border: 'var(--vscode-input-border)',
|
||||
borderColor: 'var(--vscode-input-border)',
|
||||
color: 'var(--vscode-input-foreground)',
|
||||
'&[data-disabled]': {
|
||||
color: 'var(--vscode-disabledForeground)'
|
||||
@ -678,7 +712,7 @@ const chatPanel = () => {
|
||||
backgroundColor: 'var(--vscode-toolbar-activeBackground)'
|
||||
},
|
||||
'&[data-disabled]': {
|
||||
border: 'var(--vscode-input-border)',
|
||||
borderColor: 'var(--vscode-input-border)',
|
||||
backgroundColor: 'var(--vscode-toolbar-activeBackground)'
|
||||
}
|
||||
}}
|
||||
@ -696,7 +730,7 @@ const chatPanel = () => {
|
||||
backgroundColor: 'var(--vscode-toolbar-activeBackground)'
|
||||
},
|
||||
'&[data-disabled]': {
|
||||
border: 'var(--vscode-input-border)',
|
||||
borderColor: 'var(--vscode-input-border)',
|
||||
backgroundColor: 'var(--vscode-toolbar-activeBackground)'
|
||||
}
|
||||
}}
|
||||
@ -705,13 +739,14 @@ const chatPanel = () => {
|
||||
</ActionIcon>
|
||||
}
|
||||
/>
|
||||
</Menu.Target>
|
||||
</Popover.Target>
|
||||
{
|
||||
menuType === 'contexts'
|
||||
? (<Menu.Dropdown
|
||||
? (<Popover.Dropdown
|
||||
sx={{
|
||||
padding: 0,
|
||||
color: 'var(--vscode-menu-foreground)',
|
||||
border: 'var(--vscode-menu-border)',
|
||||
borderColor: 'var(--vscode-menu-border)',
|
||||
backgroundColor: 'var(--vscode-menu-background)'
|
||||
}}>
|
||||
<Text
|
||||
@ -723,22 +758,23 @@ const chatPanel = () => {
|
||||
Tips: Select code or file & right click
|
||||
</Text>
|
||||
<Divider />
|
||||
<Menu.Label>DevChat Contexts</Menu.Label>
|
||||
<Text sx={{ padding: '5px 5px 5px 10px' }}>DevChat Contexts</Text>
|
||||
{contextMenusNode}
|
||||
</Menu.Dropdown>)
|
||||
</Popover.Dropdown>)
|
||||
: menuType === 'commands'
|
||||
? <Menu.Dropdown
|
||||
? <Popover.Dropdown
|
||||
sx={{
|
||||
padding: 0,
|
||||
color: 'var(--vscode-menu-foreground)',
|
||||
border: 'var(--vscode-menu-border)',
|
||||
borderColor: 'var(--vscode-menu-border)',
|
||||
backgroundColor: 'var(--vscode-menu-background)'
|
||||
}}>
|
||||
<Menu.Label>DevChat Commands</Menu.Label>
|
||||
<Text sx={{ padding: '5px 5px 5px 10px' }}>DevChat Commands</Text>
|
||||
{commandMenusNode}
|
||||
</Menu.Dropdown>
|
||||
</Popover.Dropdown>
|
||||
: <></>
|
||||
}
|
||||
</Menu>
|
||||
</Popover>
|
||||
</Stack>
|
||||
</Container >
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user