日期输入:onBlur 时校验 YYYY-MM-DD 与日期合法性,无效时高亮边框。 * 允许保留无效字符串(用户可继续编辑);frontmatter 仍写入用户输入,由 PUT * 后的 validate-frontmatter 做最终校验。
({
value,
onChange,
}: {
value: string | undefined;
onChange: (v: string) => void;
})
| 180 | * 允许保留无效字符串(用户可继续编辑);frontmatter 仍写入用户输入,由 PUT |
| 181 | * 后的 validate-frontmatter 做最终校验。 */ |
| 182 | function DateInput({ |
| 183 | value, |
| 184 | onChange, |
| 185 | }: { |
| 186 | value: string | undefined; |
| 187 | onChange: (v: string) => void; |
| 188 | }) { |
| 189 | const [touched, setTouched] = useState(false); |
| 190 | const v = value || ""; |
| 191 | const isInvalid = |
| 192 | touched && v !== "" && (!ISO_DATE_RE.test(v) || isNaN(Date.parse(v))); |
| 193 | return ( |
| 194 | <input |
| 195 | type="text" |
| 196 | value={v} |
| 197 | onChange={(e) => onChange(e.target.value)} |
| 198 | onBlur={() => setTouched(true)} |
| 199 | placeholder="YYYY-MM-DD" |
| 200 | className={ |
| 201 | "w-full rounded border bg-background px-2 py-1 text-sm font-mono " + |
| 202 | (isInvalid ? "border-destructive" : "") |
| 203 | } |
| 204 | aria-invalid={isInvalid || undefined} |
| 205 | /> |
| 206 | ); |
| 207 | } |
nothing calls this directly
no test coverage detected