Special tag works on short input

This commit is contained in:
Emir Karabeg
2025-01-30 13:39:17 -08:00
parent 2dc677b4ff
commit ffc6cb0613

View File

@@ -24,13 +24,25 @@ export function ShortInput({
const inputRef = useRef<HTMLInputElement>(null) const inputRef = useRef<HTMLInputElement>(null)
const [isFocused, setIsFocused] = useState(false) const [isFocused, setIsFocused] = useState(false)
const [value, setValue] = useSubBlockValue(blockId, subBlockId) const [value, setValue] = useSubBlockValue(blockId, subBlockId)
const overlayRef = useRef<HTMLDivElement>(null)
// Auto-scroll effect for input // Sync scroll position between input and overlay
const handleScroll = (e: React.UIEvent<HTMLInputElement>) => {
if (overlayRef.current) {
overlayRef.current.scrollLeft = e.currentTarget.scrollLeft
}
}
// Update the auto-scroll effect to handle both input and overlay
useEffect(() => { useEffect(() => {
if (inputRef.current && isFocused) { if (inputRef.current && isFocused) {
const input = inputRef.current const input = inputRef.current
const scrollPosition = (input.selectionStart ?? 0) * 8 const scrollPosition = (input.selectionStart ?? 0) * 8
input.scrollLeft = scrollPosition - input.offsetWidth / 2 input.scrollLeft = scrollPosition - input.offsetWidth / 2
if (overlayRef.current) {
overlayRef.current.scrollLeft = input.scrollLeft
}
} }
}, [value, isFocused]) }, [value, isFocused])
@@ -72,24 +84,55 @@ export function ShortInput({
? '•'.repeat(value?.toString().length ?? 0) ? '•'.repeat(value?.toString().length ?? 0)
: value?.toString() ?? '' : value?.toString() ?? ''
// Add this function to format the text with tags
const formatDisplayText = (text: string) => {
if (!text) return null
// Split the text by tag pattern <something.something>
const parts = text.split(/(<[^>]+>)/g)
return parts.map((part, index) => {
// Check if the part matches tag pattern
if (part.match(/^<[^>]+>$/)) {
return (
<span key={index} className="text-blue-500">
{part}
</span>
)
}
return <span key={index}>{part}</span>
})
}
// Component render // Component render
return ( return (
<Input <div className="relative w-full">
ref={inputRef} <Input
className={cn( ref={inputRef}
'w-full placeholder:text-muted-foreground/50 allow-scroll', className={cn(
isConnecting && 'w-full placeholder:text-muted-foreground/50 allow-scroll text-transparent caret-foreground',
'focus-visible:ring-blue-500 ring-2 ring-blue-500 ring-offset-2' isConnecting &&
)} 'focus-visible:ring-blue-500 ring-2 ring-blue-500 ring-offset-2'
placeholder={placeholder ?? ''} )}
type="text" placeholder={placeholder ?? ''}
value={displayValue} type="text"
onChange={(e) => setValue(e.target.value)} value={displayValue}
onFocus={() => setIsFocused(true)} onChange={(e) => setValue(e.target.value)}
onBlur={() => setIsFocused(false)} onFocus={() => setIsFocused(true)}
onDrop={handleDrop} onBlur={() => setIsFocused(false)}
onDragOver={handleDragOver} onDrop={handleDrop}
autoComplete="off" onDragOver={handleDragOver}
/> onScroll={handleScroll}
autoComplete="off"
/>
<div
ref={overlayRef}
className="absolute inset-0 pointer-events-none px-3 flex items-center overflow-x-auto whitespace-pre scrollbar-none text-sm bg-transparent"
>
{password && !isFocused
? '•'.repeat(value?.toString().length ?? 0)
: formatDisplayText(value?.toString() ?? '')}
</div>
</div>
) )
} }