refactor textarea

This commit is contained in:
JzoNg 2024-08-08 11:14:22 +08:00
parent b73f05fdf0
commit 6c9a6b99e0
18 changed files with 56 additions and 45 deletions

View File

@ -8,6 +8,7 @@ import { BookOpenIcon } from '@heroicons/react/24/outline'
import cn from '@/utils/classnames'
import IndexMethodRadio from '@/app/components/datasets/settings/index-method-radio'
import Button from '@/app/components/base/button'
import Textarea from '@/app/components/base/textarea'
import type { DataSet } from '@/models/datasets'
import { useToastContext } from '@/app/components/base/toast'
import { updateDatasetSetting } from '@/service/datasets'
@ -192,10 +193,10 @@ const SettingsModal: FC<SettingsModalProps> = ({
{t('datasetSettings.form.desc')}
</div>
<div className='w-full'>
<textarea
<Textarea
value={localeCurrentDataset.description || ''}
onChange={e => handleValueChange('description', e.target.value)}
className='block px-3 py-2 w-full h-[88px] rounded-lg bg-gray-100 text-sm outline-none appearance-none resize-none'
className='resize-none'
placeholder={t('datasetSettings.form.descPlaceholder') || ''}
/>
<a className='mt-2 flex items-center h-[18px] px-3 text-xs text-gray-500' href="https://docs.dify.ai/features/datasets#how-to-write-a-good-dataset-description" target='_blank' rel='noopener noreferrer'>

View File

@ -16,6 +16,7 @@ import { AppType, ModelModeType } from '@/types/app'
import Select from '@/app/components/base/select'
import { DEFAULT_VALUE_MAX_LEN } from '@/config'
import Button from '@/app/components/base/button'
import Textarea from '@/app/components/base/textarea'
import Tooltip from '@/app/components/base/tooltip-plus'
import TextGenerationImageUploader from '@/app/components/base/image-uploader/text-generation-image-uploader'
import type { VisionFile, VisionSettings } from '@/types/app'
@ -145,8 +146,8 @@ const PromptValuePanel: FC<IPromptValuePanelProps> = ({
/>
)}
{type === 'paragraph' && (
<textarea
className="w-full px-3 text-sm leading-9 text-gray-900 border-0 rounded-lg grow h-[120px] bg-gray-50 focus:outline-none focus:ring-1 focus:ring-inset focus:ring-gray-200"
<Textarea
className='grow h-[120px]'
placeholder={`${name}${!required ? `(${t('appDebug.variableTable.optional')})` : ''}`}
value={inputs[key] ? `${inputs[key]}` : ''}
onChange={(e) => { handleInputValueChange(key, e.target.value) }}

View File

@ -3,6 +3,7 @@ import { useContext } from 'use-context-selector'
import type { CodeBasedExtensionForm } from '@/models/common'
import I18n from '@/context/i18n'
import { PortalSelect } from '@/app/components/base/select'
import Textarea from '@/app/components/base/textarea'
import type { ModerationConfig } from '@/models/debug'
type FormGenerationProps = {
@ -44,10 +45,10 @@ const FormGeneration: FC<FormGenerationProps> = ({
}
{
form.type === 'paragraph' && (
<div className='relative px-3 py-2 h-[88px] bg-gray-100 rounded-lg'>
<textarea
<div className='relative'>
<Textarea
className='resize-none'
value={value?.[form.variable] || ''}
className='block w-full h-full bg-transparent text-sm outline-none appearance-none resize-none'
placeholder={form.placeholder}
onChange={e => handleFormChange(form.variable, e.target.value)}
/>

View File

@ -17,6 +17,7 @@ import type { AppMode } from '@/types/app'
import { createApp } from '@/service/apps'
import Modal from '@/app/components/base/modal'
import Button from '@/app/components/base/button'
import Textarea from '@/app/components/base/textarea'
import AppIcon from '@/app/components/base/app-icon'
import EmojiPicker from '@/app/components/base/emoji-picker'
import AppsFull from '@/app/components/billing/apps-full-in-dialog'
@ -291,8 +292,8 @@ const CreateAppModal = ({ show, onSuccess, onClose }: CreateAppDialogProps) => {
{/* description */}
<div className='pt-2 px-8'>
<div className='py-2 text-sm font-medium leading-[20px] text-gray-900'>{t('app.newApp.captionDescription')}</div>
<textarea
className='w-full px-3 py-2 text-sm font-normal bg-gray-100 rounded-lg border border-transparent outline-none appearance-none caret-primary-600 placeholder:text-gray-400 hover:bg-gray-50 hover:border hover:border-gray-300 focus:bg-gray-50 focus:border focus:border-gray-300 focus:shadow-xs h-[80px] resize-none'
<Textarea
className='resize-none'
placeholder={t('app.newApp.appDescriptionPlaceholder') || ''}
value={description}
onChange={e => setDescription(e.target.value)}

View File

@ -7,6 +7,7 @@ import { Trans, useTranslation } from 'react-i18next'
import s from './style.module.css'
import Modal from '@/app/components/base/modal'
import Button from '@/app/components/base/button'
import Textarea from '@/app/components/base/textarea'
import AppIcon from '@/app/components/base/app-icon'
import { SimpleSelect } from '@/app/components/base/select'
import type { AppDetailResponse } from '@/models/app'
@ -156,6 +157,10 @@ const SettingsModal: FC<ISettingsModalProps> = ({
}
}
const onDesChange = (value: string) => {
setInputInfo(item => ({ ...item, desc: value }))
}
return (
<>
<Modal
@ -180,11 +185,10 @@ const SettingsModal: FC<ISettingsModalProps> = ({
</div>
<div className={`mt-6 font-medium ${s.settingTitle} text-gray-900 `}>{t(`${prefixSettings}.webDesc`)}</div>
<p className={`mt-1 ${s.settingsTip} text-gray-500`}>{t(`${prefixSettings}.webDescTip`)}</p>
<textarea
rows={3}
className={`mt-2 pt-2 pb-2 px-3 rounded-lg bg-gray-100 w-full ${s.settingsTip} text-gray-900`}
<Textarea
className='mt-2'
value={inputInfo.desc}
onChange={onChange('desc')}
onChange={e => onDesChange(e.target.value)}
placeholder={t(`${prefixSettings}.webDescPlaceholder`) as string}
/>
<div className={`mt-6 mb-2 font-medium ${s.settingTitle} text-gray-900 `}>{t(`${prefixSettings}.language`)}</div>

View File

@ -1,6 +1,7 @@
import type { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { memo } from 'react'
import Textarea from '@/app/components/base/textarea'
type InputProps = {
form: any
@ -23,9 +24,9 @@ const FormInput: FC<InputProps> = ({
if (type === 'paragraph') {
return (
<textarea
<Textarea
value={value}
className='grow h-[104px] rounded-lg bg-gray-100 px-2.5 py-2 outline-none appearance-none resize-none'
className='resize-none'
onChange={e => onChange(variable, e.target.value)}
placeholder={`${label}${!required ? `(${t('appDebug.variableTable.optional')})` : ''}`}
/>

View File

@ -1,6 +1,7 @@
import type { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { memo } from 'react'
import Textarea from '@/app/components/base/textarea'
type InputProps = {
form: any
@ -23,9 +24,9 @@ const FormInput: FC<InputProps> = ({
if (type === 'paragraph') {
return (
<textarea
<Textarea
value={value}
className='grow h-[104px] rounded-lg bg-gray-100 px-2.5 py-2 outline-none appearance-none resize-none'
className='resize-none'
onChange={e => onChange(variable, e.target.value)}
placeholder={`${label}${!required ? `(${t('appDebug.variableTable.optional')})` : ''}`}
/>

View File

@ -4,6 +4,7 @@ import { useContext } from 'use-context-selector'
import type { CodeBasedExtensionForm } from '@/models/common'
import I18n from '@/context/i18n'
import { PortalSelect } from '@/app/components/base/select'
import Textarea from '@/app/components/base/textarea'
import type { ModerationConfig } from '@/models/debug'
type FormGenerationProps = {
@ -45,10 +46,10 @@ const FormGeneration: FC<FormGenerationProps> = ({
}
{
form.type === 'paragraph' && (
<div className='relative px-3 py-2 h-[88px] bg-gray-100 rounded-lg'>
<textarea
<div className='relative'>
<Textarea
value={value?.[form.variable] || ''}
className='block w-full h-full bg-transparent text-sm outline-none appearance-none resize-none'
className='resize-none'
placeholder={form.placeholder}
onChange={e => handleFormChange(form.variable, e.target.value)}
/>

View File

@ -20,7 +20,6 @@ const textareaVariants = cva(
export type TextareaProps = {
value: string
onChange: (value: string) => void
disabled?: boolean
destructive?: boolean
styleCss?: CSSProperties
@ -40,7 +39,7 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
className,
)}
value={value}
onChange={e => onChange(e.target.value)}
onChange={onChange}
disabled={disabled}
{...props}
>

View File

@ -19,10 +19,6 @@
.desc {
@apply text-sm font-normal text-gray-500;
}
.textarea {
height: 220px;
@apply border-none resize-none font-normal caret-primary-600 text-gray-700 text-sm w-full focus-visible:outline-none placeholder:text-gray-300 placeholder:text-sm placeholder:font-normal !important;
}
.table {
@apply text-[13px] text-gray-500;
}

View File

@ -6,6 +6,7 @@ import Tooltip from '../../base/tooltip'
import { getIcon } from '../common/retrieval-method-info'
import s from './style.module.css'
import cn from '@/utils/classnames'
import Textarea from '@/app/components/base/textarea'
import DatasetDetailContext from '@/context/dataset-detail'
import type { HitTestingResponse } from '@/models/datasets'
import { hitTesting } from '@/service/datasets'
@ -92,11 +93,11 @@ const TextAreaWithButton = ({
<div className='h-2 rounded-tl-xl rounded-tr-xl bg-white'></div>
</div>
<div className='px-4 pb-11'>
<textarea
<Textarea
className='h-[220px] resize-none'
value={text}
onChange={handleTextChange}
placeholder={t('datasetHitTesting.input.placeholder') as string}
className={s.textarea}
/>
<div className="absolute inset-x-0 bottom-0 flex items-center justify-between mx-4 mt-2 mb-2">
{text?.length > 200

View File

@ -8,6 +8,7 @@ import { useContext } from 'use-context-selector'
import { useTranslation } from 'react-i18next'
import cn from '@/utils/classnames'
import Button from '@/app/components/base/button'
import Textarea from '@/app/components/base/textarea'
import Modal from '@/app/components/base/modal'
import { ToastContext } from '@/app/components/base/toast'
import type { DataSet } from '@/models/datasets'
@ -81,10 +82,10 @@ const RenameDatasetModal = ({ show, dataset, onSuccess, onClose }: RenameDataset
{t('datasetSettings.form.desc')}
</div>
<div className='w-full'>
<textarea
<Textarea
value={description}
onChange={e => setDescription(e.target.value)}
className='block px-3 py-2 w-full h-[88px] rounded-lg bg-gray-100 text-sm outline-none appearance-none resize-none'
className='resize-none'
placeholder={t('datasetSettings.form.descPlaceholder') || ''}
/>
<a className='mt-2 flex items-center h-[18px] px-3 text-xs text-gray-500 hover:text-primary-600' href="https://docs.dify.ai/features/datasets#how-to-write-a-good-dataset-description" target='_blank' rel='noopener noreferrer'>

View File

@ -13,6 +13,7 @@ import RetrievalMethodConfig from '@/app/components/datasets/common/retrieval-me
import EconomicalRetrievalMethodConfig from '@/app/components/datasets/common/economical-retrieval-method-config'
import { ToastContext } from '@/app/components/base/toast'
import Button from '@/app/components/base/button'
import Textarea from '@/app/components/base/textarea'
import { updateDatasetSetting } from '@/service/datasets'
import type { DataSetListResponse } from '@/models/datasets'
import DatasetDetailContext from '@/context/dataset-detail'
@ -175,9 +176,9 @@ const Form = () => {
<div>{t('datasetSettings.form.desc')}</div>
</div>
<div className='w-full max-w-[480px]'>
<textarea
<Textarea
disabled={!currentDataset?.embedding_available}
className={cn(`${inputClass} block mb-2 h-[120px] py-2 resize-none`, !currentDataset?.embedding_available && 'opacity-60')}
className='mb-2 h-[120px] resize-none'
placeholder={t('datasetSettings.form.descPlaceholder') || ''}
value={description}
onChange={e => setDescription(e.target.value)}

View File

@ -4,6 +4,7 @@ import { useTranslation } from 'react-i18next'
import { RiCloseLine } from '@remixicon/react'
import Modal from '@/app/components/base/modal'
import Button from '@/app/components/base/button'
import Textarea from '@/app/components/base/textarea'
import Toast from '@/app/components/base/toast'
import AppIcon from '@/app/components/base/app-icon'
import EmojiPicker from '@/app/components/base/emoji-picker'
@ -92,8 +93,8 @@ const CreateAppModal = ({
{/* description */}
<div className='pt-2'>
<div className='py-2 text-sm font-medium leading-[20px] text-gray-900'>{t('app.newApp.captionDescription')}</div>
<textarea
className='w-full h-10 px-3 py-2 text-sm font-normal bg-gray-100 rounded-lg border border-transparent outline-none appearance-none caret-primary-600 placeholder:text-gray-400 hover:bg-gray-50 hover:border hover:border-gray-300 focus:bg-gray-50 focus:border focus:border-gray-300 focus:shadow-xs h-[80px] resize-none'
<Textarea
className='resize-none'
placeholder={t('app.newApp.appDescriptionPlaceholder') || ''}
value={description}
onChange={e => setDescription(e.target.value)}

View File

@ -8,6 +8,7 @@ import Select from '@/app/components/base/select'
import type { SiteInfo } from '@/models/share'
import type { PromptConfig } from '@/models/debug'
import Button from '@/app/components/base/button'
import Textarea from '@/app/components/base/textarea'
import { DEFAULT_VALUE_MAX_LEN } from '@/config'
import TextGenerationImageUploader from '@/app/components/base/image-uploader/text-generation-image-uploader'
import type { VisionFile, VisionSettings } from '@/types/app'
@ -77,8 +78,8 @@ const RunOnce: FC<IRunOnceProps> = ({
/>
)}
{item.type === 'paragraph' && (
<textarea
className="block w-full h-[104px] p-2 text-gray-900 border border-gray-300 rounded-lg bg-gray-50 sm:text-xs focus:ring-blue-500 focus:border-blue-500 "
<Textarea
className='h-[104px] sm:text-xs'
placeholder={`${item.name}${!item.required ? `(${t('appDebug.variableTable.optional')})` : ''}`}
value={inputs[item.key]}
onChange={(e) => { onInputsChange({ ...inputs, [item.key]: e.target.value }) }}

View File

@ -13,6 +13,7 @@ import TestApi from './test-api'
import cn from '@/utils/classnames'
import Drawer from '@/app/components/base/drawer-plus'
import Button from '@/app/components/base/button'
import Textarea from '@/app/components/base/textarea'
import EmojiPicker from '@/app/components/base/emoji-picker'
import AppIcon from '@/app/components/base/app-icon'
import { parseParamsSchema } from '@/service/tools'
@ -72,7 +73,7 @@ const EditCustomCollectionModal: FC<Props> = ({
}
const schema = customCollection.schema
const debouncedSchema = useDebounce(schema, { wait: 500 })
const setSchema = (schema: string) => {
const setSchema = (schema: any) => {
const newCollection = produce(customCollection, (draft) => {
draft.schema = schema
})
@ -226,12 +227,12 @@ const EditCustomCollectionModal: FC<Props> = ({
<GetSchema onChange={setSchema} />
</div>
<textarea
<Textarea
className='h-[240px] resize-none'
value={schema}
onChange={e => setSchema(e.target.value)}
className='w-full h-[240px] px-3 py-2 leading-4 text-xs font-normal text-gray-900 bg-gray-100 rounded-lg overflow-y-auto'
placeholder={t('tools.createTool.schemaPlaceHolder')!}
></textarea>
/>
</div>
{/* Available Tools */}

View File

@ -9,6 +9,7 @@ import produce from 'immer'
import type { Emoji, WorkflowToolProviderParameter, WorkflowToolProviderRequest } from '../types'
import cn from '@/utils/classnames'
import Drawer from '@/app/components/base/drawer-plus'
import Textarea from '@/app/components/base/textarea'
import Button from '@/app/components/base/button'
import Toast from '@/app/components/base/toast'
import EmojiPicker from '@/app/components/base/emoji-picker'
@ -172,8 +173,7 @@ const WorkflowToolAsModal: FC<Props> = ({
{/* description */}
<div>
<div className='py-2 leading-5 text-sm font-medium text-gray-900'>{t('tools.createTool.description')}</div>
<textarea
className='w-full px-3 py-2 text-sm font-normal bg-gray-100 rounded-lg border border-transparent outline-none appearance-none caret-primary-600 placeholder:text-gray-400 hover:bg-gray-50 hover:border hover:border-gray-300 focus:bg-gray-50 focus:border focus:border-gray-300 focus:shadow-xs h-[80px] resize-none'
<Textarea
placeholder={t('tools.createTool.descriptionPlaceholder') || ''}
value={description}
onChange={e => setDescription(e.target.value)}

View File

@ -5,11 +5,11 @@ import { useBoolean } from 'ahooks'
import { useTranslation } from 'react-i18next'
import type { Param } from '../../types'
import { ParamType } from '../../types'
import cn from '@/utils/classnames'
import AddButton from '@/app/components/base/button/add-button'
import Modal from '@/app/components/base/modal'
import Button from '@/app/components/base/button'
import Field from '@/app/components/app/configuration/config-var/config-modal/field'
import Textarea from '@/app/components/base/textarea'
import Select from '@/app/components/base/select'
import Switch from '@/app/components/base/switch'
import Toast from '@/app/components/base/toast'
@ -165,8 +165,7 @@ const AddExtractParameter: FC<Props> = ({
</Field>
)}
<Field title={t(`${i18nPrefix}.addExtractParameterContent.description`)}>
<textarea
className={cn(inputClassName, '!h-[80px]')}
<Textarea
value={param.description}
onChange={e => handleParamChange('description')(e.target.value)}
placeholder={t(`${i18nPrefix}.addExtractParameterContent.descriptionPlaceholder`)!}