用途:Shade 中表单控件共用同一套视觉规则,位于 apps/shade/src/components/ui/input-surface.ts,并被 Input、Textarea、InputGroup 与 Select 触发器共用。不要重复实现外壳,应复用该配方。
主要能力与两种模式:inputSurface('self') 直接用在可获得焦点的元素(input、textarea 或任何自身接收焦点的元素)上,覆盖基础外壳、focus-visible 焦点环、aria-[invalid=true] 无效态与 disabled 透明度。inputSurface('within') 用在包含可聚焦子元素的包装器上(如 InputGroup),通过 :has() 响应任意可聚焦后代,覆盖基础外壳加 has-[:focus-visible] 焦点环与 has-[[aria-invalid=true]] 无效态;包装器没有 disabled HTML 属性,因此不含 disabled 原子。
必要用法:从 '@/components/ui/input-surface' 引入 inputSurface、inputSurfaceClasses,并用 cn 组合。当只有某个特定子元素应触发焦点态时,可手动组合原子类:base、invalidWithin、focusSelf、focusWithin、invalidSelf、disabledSelf(disabledSelf 仅用于 self 模式)。注意 Tailwind JIT 需要看到字面量类名字符串,不能拼接非字面量类名。
分工:配方负责边框(border-control-border)、背景(bg-control-surface)、圆角(rounded-md)、过渡(transition-colors)、焦点环(focus-visible:ring-focus-ring/25)、无效态(aria-[invalid=true]:border-destructive)与 self 模式禁用态(disabled:opacity-50);使用方补充高度、内边距、排版、布局、占位符样式、图标与插槽定位等组件专属调整。
限制与反例:不要在表单控件上手写焦点外壳;不要对自身可聚焦元素使用 inputSurface('within')(过于宽泛);不要用 JIT 无法静态识别的动态类名拼接。以该文件中的 JSDoc 为准,人类文档见 Storybook 的 Recipes / inputSurface。