Files
ERitors-Scribe-Desktop/components/form/InlineAddInput.tsx
natreex 64ed90d993 Remove unused components and models for improved maintainability
- Deleted redundant components (`AddActionButton`, `AlertBox`, `AlertStack`, `BackButton`, `CancelButton`, and `CollapsableArea`) and related files.
- Removed unused models (`Book`, `BookSerie`, `BookTables`, `Character`, and `Chapter`) to reduce codebase clutter.
- Updated project structure and references to reflect these removals.
2026-03-22 22:37:31 -04:00

73 lines
3.1 KiB
TypeScript

import React, {ChangeEvent, KeyboardEvent, useRef, useState} from "react";
import IconButton from "@/components/ui/IconButton";
import {Plus} from "lucide-react";
interface InlineAddInputProps {
value: string;
setValue: (value: string) => void;
numericalValue?: number;
setNumericalValue?: (value: number) => void;
placeholder: string;
onAdd: () => Promise<void>;
showNumericalInput?: boolean;
}
export default function InlineAddInput(
{
value,
setValue,
numericalValue,
setNumericalValue,
placeholder,
onAdd,
showNumericalInput = false
}: InlineAddInputProps) {
const [isAdding, setIsAdding] = useState<boolean>(false);
const listItemRef = useRef<HTMLLIElement>(null);
async function handleAdd(): Promise<void> {
await onAdd();
setIsAdding(false);
}
return (
<li
ref={listItemRef}
onBlur={(e: React.FocusEvent<HTMLLIElement, Element>): void => {
if (!listItemRef.current?.contains(e.relatedTarget)) {
setIsAdding(false);
}
}}
className="relative flex items-center gap-1 h-[44px] px-3 bg-dark-background rounded-xl border border-secondary hover:border-primary/60 cursor-pointer transition-colors duration-200"
>
{showNumericalInput && numericalValue !== undefined && setNumericalValue && (
<input
className={`bg-dark-background text-primary text-sm px-1.5 py-0.5 rounded border border-secondary transition-all duration-200 !outline-none !ring-0 !shadow-none focus-visible:!outline-none focus-visible:!ring-0 focus-visible:!shadow-none ${isAdding ? 'w-10 opacity-100' : 'w-0 opacity-0 px-0 border-0'}`}
type="number"
value={numericalValue}
onChange={(e: ChangeEvent<HTMLInputElement>) => setNumericalValue(parseInt(e.target.value))}
tabIndex={isAdding ? 0 : -1}
/>
)}
<input
onFocus={(): void => setIsAdding(true)}
onKeyUp={async (e: KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
await handleAdd();
}
}}
className="flex-1 min-w-0 bg-transparent text-text-primary text-sm px-1 py-0.5 cursor-pointer focus:cursor-text placeholder:text-muted/60 transition-all duration-200 !outline-none !ring-0 !shadow-none focus-visible:!outline-none focus-visible:!ring-0 focus-visible:!shadow-none"
type="text"
onChange={(e: ChangeEvent<HTMLInputElement>) => setValue(e.target.value)}
value={value}
placeholder={placeholder}
/>
{isAdding && (
<div className="absolute right-1 opacity-100">
<IconButton icon={Plus} variant="ghost" onClick={handleAdd}/>
</div>
)}
</li>
);
}