/** * AddItemInput — sticky add-item text input at the bottom of ListDetail. * * Design contract (UI-SPEC §AddItemInput): * - Sticky at the bottom, above keyboard on mobile * - Horizontal flex: text input (flex:1) + "Add" button * - Input: --text-body-*, 44px min-height, placeholder "Add an item…" * - Button: "Add" label, --color-member-0 bg, white text, disabled when empty * - Submit: Enter key OR tap "Add" button */ import { useState, useRef } from 'react'; interface AddItemInputProps { onAdd: (text: string) => void; /** Whether the add mutation is pending (parent controls this for optimistic state) */ isPending?: boolean; } export function AddItemInput({ onAdd, isPending = false }: AddItemInputProps) { const [text, setText] = useState(''); const inputRef = useRef(null); function handleSubmit() { const trimmed = text.trim(); if (!trimmed) return; onAdd(trimmed); setText(''); inputRef.current?.focus(); } function handleKeyDown(e: React.KeyboardEvent) { if (e.key === 'Enter') { e.preventDefault(); handleSubmit(); } } return (
setText(e.target.value)} onKeyDown={handleKeyDown} placeholder="Add an item…" disabled={isPending} style={{ flex: 1, fontSize: 'var(--text-body-size, 15px)', background: 'var(--color-surface)', border: '1px solid var(--color-border)', borderRadius: 'var(--space-1)', padding: 'var(--space-2) var(--space-4)', minHeight: '44px', color: 'var(--color-text-primary)', outline: 'none', fontFamily: 'var(--font-family-base)', }} onFocus={(e) => { e.currentTarget.style.borderColor = 'var(--color-focus-ring, #4A90D9)'; }} onBlur={(e) => { e.currentTarget.style.borderColor = 'var(--color-border)'; }} />
); }