feat(web): Field 标签自动关联控件 + 全局壳无障碍(skip link/设置可访问名/抽屉焦点归还)
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user