feat(web): Field 标签自动关联控件 + 全局壳无障碍(skip link/设置可访问名/抽屉焦点归还)

This commit is contained in:
Yaojia Wang
2026-06-29 16:52:43 +02:00
parent dd80b6815d
commit a2849bf6b7
4 changed files with 52 additions and 6 deletions

View File

@@ -1,4 +1,6 @@
import type { ReactNode } from "react";
"use client";
import { cloneElement, isValidElement, useId, type ReactNode } from "react";
import {
cn,
@@ -26,13 +28,20 @@ export function Field({
required = false,
className,
}: FieldProps) {
const autoId = useId();
const id = htmlFor ?? autoId;
const labelText = required ? `${label} *` : label;
// 自动把 id 注入唯一子控件,建立 label↔控件关联仅当子控件自身未带 id
const control =
isValidElement<{ id?: string }>(children) && children.props.id == null
? cloneElement(children, { id })
: children;
return (
<div className={cn("space-y-1.5", className)}>
<label htmlFor={htmlFor} className={fieldLabelClass()}>
<label htmlFor={id} className={fieldLabelClass()}>
{labelText}
</label>
{children}
{control}
{error ? <p className={fieldErrorClass()}>{error}</p> : null}
{!error && help ? <p className={fieldHelpClass()}>{help}</p> : null}
</div>