#!/usr/bin/env python3 """Phase-36: standalone form inputs — Input, Textarea, Select, SearchBox.""" from __future__ import annotations import asyncio, datetime, json, sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent)) from phase2_features import Feature, FileGen, ROOT, log, log_section from phase3_features import run_feature_v2 PHASE_STATE = ROOT / ".phase36-state.json" FEATURES: list[Feature] = [ Feature( name="input-component", description="Input mit Label + Error-State", files=[FileGen( path="apps/web/src/components/Input.tsx", purpose=( "Input-Component. Props: value, onChange, label?, error?, placeholder?, type?, leftIcon?, rightIcon?, disabled?. " "Wrapper-div mit Label oben, Input mit optional Icons left/right (absolute positioned + Input padding), " "Error-Text rot drunter wenn error. focus:ring-2 ring-blue-500, border-red-500 wenn error. Tailwind. Export default." ), )], ), Feature( name="textarea-component", description="Textarea mit auto-resize + char-count", files=[FileGen( path="apps/web/src/components/Textarea.tsx", purpose=( "Textarea-Component. Props: value, onChange, label?, error?, placeholder?, rows? (default 4), maxLength?, autoResize?: boolean. " "Wenn autoResize: useEffect setzt height = scrollHeight. Wenn maxLength: zeigt char-count rechts unten ({value.length}/{maxLength}). " "Tailwind. Export default." ), )], ), Feature( name="select-component", description="Select mit custom-styling", files=[FileGen( path="apps/web/src/components/Select.tsx", purpose=( "Select-Component. Props: value, onChange, options (array {value, label, disabled?}), label?, placeholder?, error?, disabled?. " "Native