@fiscozen/文本区
多行文本输入组件,有标签,验证状态,调整大小控制,以及WCAG 2.1 AA可访问性.
关于使用量的文件,见 故事书文档
发展
设置
pnpm install
pnpm --filter @fiscozen/textarea build
建筑
FzTextrea 是一个将本地文件包起来的窗体组件 <textarea> 有标签、验证状态(error/valid)、帮助/error消息,以及完全的ARIA可访问性。 使用错误消息 FzAlert 与 FzInput。 。 。 .
关键设计决定:
- 自动生成的ID: 当无
id提供了道具,通过utils.ts确保标签-文本区协会始终有效。 使用时间戳 + 计数器模式(与@fiscozen/input) (中文(简体) ). - ARIA 三角图案: Boolean ARIA属性使用ternary表达式(例如.
:aria-invalid="error ? 'true' : 'false'"Vue 3 取消了布尔属性false,但ARIA spec需要字符串值. - 通过 FzAlert 出错: 使用错误消息
<FzAlert tone="error" variant="text">与role="alert"匹配FzInput模式。 这个circle-xmark图标由 FzAlert 自动提供。 依赖性 :@fiscozen/alert。 。 。 . - 基于槽的信息: 错误和帮助内容通过
errorMessage财务报告和审定财务报表helpText插槽, 匹配FzInput模式。 用途defineSlots用于类型脚本打字和useSlots()用于运行时段检测(与FzInput) (中文(简体) ). - 自定义焦点环: 浏览器默认大纲被压制 (
outline-none focus:ring-0 focus:outline-none)取而代之的是焦点上的边框颜色变化(focus:border-blue-600) (中文(简体) ). 在错误状态下, 焦点用途focus:border-semantic-error-300以保持错误上下文。 这种办法不同于FzInput用于has-[:focus]在包装上。 这里边界直接在<textarea>键. - 设计符号对齐( 图): 使用边框颜色
semantic-error-200(默认错误) /semantic-error-300(错误+焦点). 占位符用途placeholder:text-grey-300一. 背景情况bg-core-white文字text-core-black文本总是text-base(16px)相匹配的Figma spec(无大小变体). 标签和帮助文本使用font-normal text-base。只应用残疾/只读状态text-grey-300以标签和帮助文本. - 折旧
size道具编号:size道具( r)sm | md | lg)被接受为后向相容但被忽略. 文本区总是由text-base运行时间console.warn当任何值被传递时,会释放。 将在下一个主要版本中删除. inheritAttrs: false+ 键v-bind="$attrs": 额外的属性和本地事件听众直接传送给本地<textarea>元素,而不是 root 包装 div。 无自定义defineEmits用于 DOM 事件——模糊、焦点、粘贴、按键等$attrs自动.defineExpose({ textareaRef }): 向当地人展示<textarea>方案重点或衡量要素参考,模式与FzInput(单位:千美元)inputRef, (中文(简体) ),containerRef) (中文(简体) ).- 标签标识 +
aria-labelledby: 标签元素获得清晰id(单位:千美元){effectiveId}-label)和文本区域使用aria-labelledby提供更强大的屏幕阅读器关联for编号 :id装订。 模式与FzInput。 。 。 . watch折旧: 用途watch(() => props.size, ..., { immediate: true })改为onMounted用于校正警告,与FzInput以观察者为基础的方法。 抓取运行时间道具更改 .- 根识别类数字 :
fz-textarearoot div 上用于调试和外部样式、镜像的类FzInput是因为fz-input课. - 合并状态:错误+残疾,需要+帮助,已禁用+编译均被支持. 当错误+损坏时,两者均
aria-invalid财务报告和审定财务报表aria-disabled设置为“ true”,错误消息仍然可见。 当禁用/ 只读时, 帮助文本会灰化 . - 最小宽度/ 高度数字 :
min-w-[96px]防止水平倒塌;min-h-[77px]执行最小高度rows: 2默认(2行内容 + 10px 垫底+ 10px 垫底+ 1px 边框上+ 1px 边框下方). - 自动身高: 当
autoHeight实值true中,文本区高度按每个v-model通过adjustHeight()A级ResizeObserver用于外部大小变化。 垂直调整大小被禁用;水平保留. 字体度量衡( E)lineHeight, (中文(简体) ),paddingY, (中文(简体) ),borderY)在挂载时被缓存一次,因为它们是由设计系统固定的.maxRows将生长盖上;在此之后会出现滚动条(overflow-y: auto) (中文(简体) ).autoHeight必须在挂载时设置 —— 运行时更改不支持, 因为 hooks (onMounted, (中文(简体) ),watch)在设置时间有条件注册.
代码组织
src/FzTextarea.vue: 主要部件(进口FzAlert、FzIcon)src/types.ts: 类型定义(FzTextareaProps(中文(简体) )src/utils.ts: ID 生成工具generateTextareaId(中文(简体) )src/index.ts: 公共出口
依赖关系
@fiscozen/alert(工作空间): FzAlert 用于错误消息@fiscozen/icons(pier):用于有效检查图标的 FzIcon
关键概念
有效的身份证
组件计算 a effectiveId 回到自动生成的 ID 当没有明确 id 提供了道具。 这确保:
- 标签
for属性总是匹配文本区域id - 标签
id(单位:千美元){effectiveId}-label页:1aria-labelledby文本区域 aria-describedby引用( error/ help ID) 总是有效的- 错误消息容器 ID (E)
{effectiveId}-error)和帮助消息ID({effectiveId}-help)是决定性的
自动高度算法
何时 autoHeight 启用 :
- 挂载数字 :
measureMetrics()读取lineHeight, (中文(简体) ),paddingTop+paddingBottom, (中文(简体) ),borderTopWidth+borderBottomWidth从getComputedStyle()。这些是组件寿命的缓存. - 输入时 (单位:千美元)
watch(model):adjustHeight()后调用nextTick。它重现height改为"auto"这样scrollHeight然后计算受限高度:如果maxRows设置和scrollHeight > maxRows * lineHeight + paddingY,它封顶高度和设置overflow-y: auto; 否则overflow-y: hidden。 。 。 . ResizeObserver: 监视外部宽度变化(例如容器调整大小),这些变化可以回流文本,调用adjustHeight()用于重新计算.- 清理: 观察员已断开
onBeforeUnmount。 。 。 .
这个 autoHeightResizeMap 对象地图 resize 道具值到它们的自发高度等同,在保留水平时会剥去垂直大小.
槽优先级
当两者 errorMessage 财务报告和审定财务报表 helpText 提供了槽,错误优先(仅在 error 道具为真. 这个 ariaDescribedBy 计算用途 useSlots() (runtime)用于检测提供哪个槽,遵循相同的优先级:出错ID > 帮助ID. 这个匹配 FzInput"接近哪里" "这里" defineSlots 仅用于类型脚本打字.
测试
运行测试
pnpm --filter @fiscozen/textarea test:unit
pnpm --filter @fiscozen/textarea coverage
测试结构
试验组织在巢中 describe 块 :
- 渲染: 基本组件渲染, FzAlert 集成
- 道具: 每个道具都有自己的道具
describe块 - 活动: 本地事件通过 $atters, v- model 转发
- 展览数字 :
textareaRef可用性和类型 - 无障碍: ARIA属性(包括
aria-labelledby),角色="提醒",装饰图标,键盘导航 - CSS 类: 静态和动态类应用程序
- 边缘案件: null/未定义/空值,特殊字符,合并状态(error+disabled, help+disabled,需要+帮助)
- 自动高度: 调整类映射大小, 警告( maxRows 不自动Height, 垂直调整大小), 高度调整, 溢出行为
- 抓图: 所有主要州和组合,并有明确的身份证,以促进稳定
稳定
快照测试提供了明确的 id 避免自动生成的ID(包含时间戳)的道具在测试运行中引起片面比较.
添加特性
- 更新类型
src/types.ts与联合来文文件 - 在
src/FzTextarea.vue - 在其中添加测试
src/__tests__/FzTextarea.spec.ts - 更新故事书故事
apps/storybook/src/stories/form/Textarea.stories.ts - 更新 MDX 文档
apps/storybook/src/FzTextarea.mdx
构建
pnpm --filter @fiscozen/textarea build
中断更改
删除 errorMessage 财务报告和审定财务报表 helpMessage 道具(以槽取代)
这个 errorMessage 财务报告和审定财务报表 helpMessage 道具已经取出。 错误和帮助内容现在通过命名槽提供,与 FzInput 财务报告和审定财务报表 FzSelect 模式.
在此之前:
<FzTextarea label="Notes" :error="hasError" errorMessage="Error text" helpMessage="Help text" />
之后:
<FzTextarea label="Notes" :error="hasError">
<template #errorMessage>Error text</template>
<template #helpText>Help text</template>
</FzTextarea>
折旧 size 道具
这个 size 道具被接受但被忽略. 文本区总是使用 text-base (16px) (英语). 当任何值被传递时都会发出运行时间警告 。 将在下一个主要版本中删除.
删除 FzTextareaEvents 类型和明确事件
原生DOM活动(blur, (中文(简体) ), focus, (中文(简体) ), paste不再通过下列方式宣布: defineEmits自动传送给本地人 <textarea> 通过 v-bind="$attrs" (与 inheritAttrs: false) (中文(简体) ). 这个 FzTextareaEvents 类型已经从出口中删除.
在此之前:
<FzTextarea label="Notes" @blur="onBlur" />
<!-- Worked via defineEmits + explicit emit('blur', $event) -->
之后:
<FzTextarea label="Notes" @blur="onBlur" @keydown="onKeydown" />
<!-- Works via $attrs forwarding. Any native event is supported. -->