refactor(playground): extract input tool state

- move attachment action metadata and development notices into input tool utilities.

- keep the input tools component focused on menu and button rendering.
This commit is contained in:
QuentinHsu
2026-05-30 10:39:59 +08:00
parent a8c19eec50
commit c82242f0d2
3 changed files with 77 additions and 23 deletions
@@ -16,14 +16,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import {
CameraIcon,
FileIcon,
GlobeIcon,
ImageIcon,
PaperclipIcon,
ScreenShareIcon,
} from 'lucide-react'
import { GlobeIcon, PaperclipIcon } from 'lucide-react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import {
@@ -36,31 +29,31 @@ import {
PromptInputButton,
PromptInputTools,
} from '@/components/ai-elements/prompt-input'
import {
ATTACHMENT_ACTIONS,
getAttachmentActionNotice,
getSearchActionNotice,
} from '../lib'
type PlaygroundInputToolsProps = {
disabled?: boolean
}
const attachmentActions = [
{ action: 'upload-file', icon: FileIcon, label: 'Upload file' },
{ action: 'upload-photo', icon: ImageIcon, label: 'Upload photo' },
{
action: 'take-screenshot',
icon: ScreenShareIcon,
label: 'Take screenshot',
},
{ action: 'take-photo', icon: CameraIcon, label: 'Take photo' },
] as const
export function PlaygroundInputTools({ disabled }: PlaygroundInputToolsProps) {
const { t } = useTranslation()
const handleFileAction = (action: string) => {
toast.info(t('Feature in development'), {
description: action,
const notice = getAttachmentActionNotice(action)
toast.info(t(notice.title), {
description: notice.description,
})
}
const handleSearchAction = () => {
const notice = getSearchActionNotice()
toast.info(t(notice.title))
}
return (
<PromptInputTools>
<DropdownMenu>
@@ -78,7 +71,7 @@ export function PlaygroundInputTools({ disabled }: PlaygroundInputToolsProps) {
<span className='sr-only sm:hidden'>{t('Attach')}</span>
</DropdownMenuTrigger>
<DropdownMenuContent align='start'>
{attachmentActions.map(({ action, icon: Icon, label }) => (
{ATTACHMENT_ACTIONS.map(({ action, icon: Icon, label }) => (
<DropdownMenuItem
key={action}
onClick={() => handleFileAction(action)}
@@ -93,7 +86,7 @@ export function PlaygroundInputTools({ disabled }: PlaygroundInputToolsProps) {
<PromptInputButton
className='border font-medium'
disabled={disabled}
onClick={() => toast.info(t('Search feature in development'))}
onClick={handleSearchAction}
variant='outline'
>
<GlobeIcon size={16} />
+1
View File
@@ -18,6 +18,7 @@ For commercial licensing, please contact support@quantumnous.com
*/
export * from './message-utils'
export * from './input-control-utils'
export * from './input-tool-utils'
export * from './message-action-utils'
export * from './message-content-utils'
export * from './message-editor-utils'
@@ -0,0 +1,60 @@
/*
Copyright (C) 2023-2026 QuantumNous
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import {
CameraIcon,
FileIcon,
ImageIcon,
ScreenShareIcon,
type LucideIcon,
} from 'lucide-react'
type AttachmentAction = {
action: string
icon: LucideIcon
label: string
}
type InputToolNotice = {
description?: string
title: string
}
export const ATTACHMENT_ACTIONS = [
{ action: 'upload-file', icon: FileIcon, label: 'Upload file' },
{ action: 'upload-photo', icon: ImageIcon, label: 'Upload photo' },
{
action: 'take-screenshot',
icon: ScreenShareIcon,
label: 'Take screenshot',
},
{ action: 'take-photo', icon: CameraIcon, label: 'Take photo' },
] satisfies AttachmentAction[]
export function getAttachmentActionNotice(action: string): InputToolNotice {
return {
description: action,
title: 'Feature in development',
}
}
export function getSearchActionNotice(): InputToolNotice {
return {
title: 'Search feature in development',
}
}