mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-17 11:15:57 +08:00
feat: implement AutoWidthInput component for dynamic input sizing in visual editor
This commit is contained in:
parent
d29b3292f0
commit
e250f5aab2
@ -18,8 +18,8 @@ const Card: FC<CardProps> = ({
|
||||
|
||||
return (
|
||||
<div className='flex flex-col py-0.5'>
|
||||
<div className='flex items-center gap-x-1 p-0.5 pl-1'>
|
||||
<div className='system-sm-semibold truncate px-1 py-0.5 text-text-primary'>
|
||||
<div className='flex h-6 items-center gap-x-1 pl-1 pr-0.5'>
|
||||
<div className='system-sm-semibold truncate border border-transparent px-1 py-px text-text-primary'>
|
||||
{name}
|
||||
</div>
|
||||
<div className='system-xs-medium px-1 py-0.5 text-text-tertiary'>
|
||||
|
@ -0,0 +1,81 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import type { FC } from 'react'
|
||||
import cn from '@/utils/classnames'
|
||||
|
||||
type AutoWidthInputProps = {
|
||||
value: string
|
||||
placeholder: string
|
||||
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void
|
||||
onBlur: () => void
|
||||
minWidth?: number
|
||||
maxWidth?: number
|
||||
} & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange'>
|
||||
|
||||
const AutoWidthInput: FC<AutoWidthInputProps> = ({
|
||||
value,
|
||||
placeholder,
|
||||
onChange,
|
||||
onBlur,
|
||||
minWidth = 60,
|
||||
maxWidth = 300,
|
||||
className,
|
||||
...props
|
||||
}) => {
|
||||
const [width, setWidth] = useState(minWidth)
|
||||
const textRef = React.useRef<HTMLSpanElement>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (textRef.current) {
|
||||
textRef.current.textContent = value || placeholder
|
||||
const textWidth = textRef.current.offsetWidth
|
||||
const newWidth = Math.max(minWidth, Math.min(textWidth + 16, maxWidth))
|
||||
if (width !== newWidth)
|
||||
setWidth(newWidth)
|
||||
}
|
||||
}, [value, placeholder, minWidth, maxWidth, width])
|
||||
|
||||
// Handle Enter key
|
||||
const handleKeyUp = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
if (e.key === 'Enter' && e.currentTarget.blur)
|
||||
e.currentTarget.blur()
|
||||
if (props.onKeyUp)
|
||||
props.onKeyUp(e)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='relative inline-flex items-center'>
|
||||
{/* Hidden measurement span */}
|
||||
<span
|
||||
ref={textRef}
|
||||
className='system-sm-semibold invisible absolute left-0 top-0 -z-10 whitespace-pre px-1'
|
||||
aria-hidden="true"
|
||||
>
|
||||
{value || placeholder}
|
||||
</span>
|
||||
|
||||
{/* Actual input element */}
|
||||
<input
|
||||
value={value}
|
||||
className={cn(
|
||||
'system-sm-semibold placeholder:system-sm-semibold h-5 rounded-[5px] border border-transparent px-1',
|
||||
'py-px text-text-primary caret-[#295EFF] shadow-shadow-shadow-3 outline-none',
|
||||
'placeholder:text-text-placeholder hover:bg-state-base-hover focus:border-components-input-border-active focus:bg-components-input-bg-active focus:shadow-xs',
|
||||
className,
|
||||
)}
|
||||
style={{
|
||||
width: `${width}px`,
|
||||
minWidth: `${minWidth}px`,
|
||||
maxWidth: `${maxWidth}px`,
|
||||
transition: 'width 100ms ease-out',
|
||||
}}
|
||||
placeholder={placeholder}
|
||||
onChange={onChange}
|
||||
onBlur={onBlur}
|
||||
onKeyUp={handleKeyUp}
|
||||
{...props}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(AutoWidthInput)
|
@ -14,6 +14,7 @@ import { useVisualEditorStore } from '../store'
|
||||
import { useMittContext } from '../context'
|
||||
import { useUnmount } from 'ahooks'
|
||||
import { JSON_SCHEMA_MAX_DEPTH } from '@/config'
|
||||
import AutoWidthInput from './auto-width-input'
|
||||
|
||||
export type EditData = {
|
||||
name: string
|
||||
@ -192,17 +193,15 @@ const EditCard: FC<EditCardProps> = ({
|
||||
|
||||
return (
|
||||
<div className='flex flex-col rounded-lg bg-components-panel-bg py-0.5 shadow-sm shadow-shadow-shadow-4'>
|
||||
<div className='flex items-center pl-1 pr-0.5'>
|
||||
<div className='flex h-6 items-center pl-1 pr-0.5'>
|
||||
<div className='flex grow items-center gap-x-1'>
|
||||
<input
|
||||
<AutoWidthInput
|
||||
value={currentFields.name}
|
||||
className='system-sm-semibold placeholder:system-sm-semibold h-5 max-w-20 rounded-[5px] border border-transparent px-1
|
||||
py-0.5 text-text-primary caret-[#295EFF] shadow-shadow-shadow-3 outline-none
|
||||
placeholder:text-text-placeholder hover:bg-state-base-hover focus:border-components-input-border-active focus:bg-components-input-bg-active focus:shadow-xs'
|
||||
placeholder={t('workflow.nodes.llm.jsonSchema.fieldNamePlaceholder')}
|
||||
minWidth={80}
|
||||
maxWidth={300}
|
||||
onChange={handlePropertyNameChange}
|
||||
onBlur={handlePropertyNameBlur}
|
||||
onKeyUp={e => e.key === 'Enter' && e.currentTarget.blur()}
|
||||
/>
|
||||
<TypeSelector
|
||||
currentValue={currentFields.type}
|
||||
|
@ -48,9 +48,6 @@ export default function Page() {
|
||||
],
|
||||
},
|
||||
},
|
||||
completed: {
|
||||
type: Type.boolean,
|
||||
},
|
||||
},
|
||||
required: [
|
||||
'userId',
|
||||
|
Loading…
x
Reference in New Issue
Block a user