mirror of
https://github.com/langgenius/dify.git
synced 2026-04-15 09:57:03 +08:00
fix(web): handle IME composition in DelimiterInput (#34660)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
fbcab757d5
commit
f8b249e649
@ -33,6 +33,22 @@ describe('DelimiterInput', () => {
|
||||
// Tooltip triggers render; component mounts without error
|
||||
expect(screen.getByText(`${ns}.stepTwo.separator`)).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should suppress onChange during IME composition', () => {
|
||||
const onChange = vi.fn()
|
||||
const finalValue = 'wu'
|
||||
render(<DelimiterInput value="" onChange={onChange} />)
|
||||
const input = screen.getByPlaceholderText(`${ns}.stepTwo.separatorPlaceholder`)
|
||||
|
||||
fireEvent.compositionStart(input)
|
||||
fireEvent.change(input, { target: { value: 'w' } })
|
||||
fireEvent.change(input, { target: { value: finalValue } })
|
||||
expect(onChange).not.toHaveBeenCalled()
|
||||
|
||||
fireEvent.compositionEnd(input)
|
||||
expect(onChange).toHaveBeenCalledTimes(1)
|
||||
expect(onChange.mock.calls[0][0].target.value).toBe(finalValue)
|
||||
})
|
||||
})
|
||||
|
||||
describe('MaxLengthInput', () => {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import type { FC, PropsWithChildren, ReactNode } from 'react'
|
||||
import type { InputProps } from '@/app/components/base/input'
|
||||
import type { NumberFieldInputProps, NumberFieldRootProps, NumberFieldSize } from '@/app/components/base/ui/number-field'
|
||||
import { useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Input from '@/app/components/base/input'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
@ -16,7 +17,7 @@ import {
|
||||
import { env } from '@/env'
|
||||
|
||||
const TextLabel: FC<PropsWithChildren> = (props) => {
|
||||
return <label className="text-xs font-semibold leading-none text-text-secondary">{props.children}</label>
|
||||
return <label className="text-xs leading-none font-semibold text-text-secondary">{props.children}</label>
|
||||
}
|
||||
|
||||
const FormField: FC<PropsWithChildren<{ label: ReactNode }>> = (props) => {
|
||||
@ -28,8 +29,11 @@ const FormField: FC<PropsWithChildren<{ label: ReactNode }>> = (props) => {
|
||||
)
|
||||
}
|
||||
|
||||
export const DelimiterInput: FC<InputProps & { tooltip?: string }> = (props) => {
|
||||
export const DelimiterInput: FC<InputProps & { tooltip?: string }> = ({ tooltip, onChange, value, ...rest }) => {
|
||||
const { t } = useTranslation()
|
||||
const isComposing = useRef(false)
|
||||
const [compositionValue, setCompositionValue] = useState('')
|
||||
|
||||
return (
|
||||
<FormField label={(
|
||||
<div className="mb-1 flex items-center">
|
||||
@ -37,7 +41,7 @@ export const DelimiterInput: FC<InputProps & { tooltip?: string }> = (props) =>
|
||||
<Tooltip
|
||||
popupContent={(
|
||||
<div className="max-w-[200px]">
|
||||
{props.tooltip || t('stepTwo.separatorTip', { ns: 'datasetCreation' })}
|
||||
{tooltip || t('stepTwo.separatorTip', { ns: 'datasetCreation' })}
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
@ -48,7 +52,24 @@ export const DelimiterInput: FC<InputProps & { tooltip?: string }> = (props) =>
|
||||
type="text"
|
||||
className="h-9"
|
||||
placeholder={t('stepTwo.separatorPlaceholder', { ns: 'datasetCreation' })!}
|
||||
{...props}
|
||||
value={isComposing.current ? compositionValue : value}
|
||||
onChange={(e) => {
|
||||
if (isComposing.current)
|
||||
setCompositionValue(e.target.value)
|
||||
else
|
||||
onChange?.(e)
|
||||
}}
|
||||
onCompositionStart={() => {
|
||||
isComposing.current = true
|
||||
setCompositionValue(String(value ?? ''))
|
||||
}}
|
||||
onCompositionEnd={(e) => {
|
||||
const committed = e.currentTarget.value
|
||||
isComposing.current = false
|
||||
setCompositionValue('')
|
||||
onChange?.({ ...e, target: { ...e.target, value: committed } } as unknown as React.ChangeEvent<HTMLInputElement>)
|
||||
}}
|
||||
{...rest}
|
||||
/>
|
||||
</FormField>
|
||||
)
|
||||
|
||||
@ -4291,9 +4291,6 @@
|
||||
"app/components/datasets/create/step-two/components/inputs.tsx": {
|
||||
"no-restricted-imports": {
|
||||
"count": 1
|
||||
},
|
||||
"tailwindcss/enforce-consistent-class-order": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"app/components/datasets/create/step-two/components/option-card.tsx": {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user