Files
workspace/code/fms/.codebuddy/plans/input-component_ddf8a08f.md
2026-08-16 22:01:32 +08:00

163 lines
8.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: input-component
overview: 在 fms-vue 组件库中新建 Input(基础框)、InputPassword(密码框)、Textarea(多行)三个组件,沿用 button 的「纯 scoped scss + --fms-* tokens」风格,并在 App.vue 增加演示示例。参考 参考组件库/shadcn 与 antdv-next 的设计。
design:
architecture:
framework: vue
styleKeywords:
- Minimalism
- Neutral
- Compact
- Professional
fontSystem:
fontFamily: PingFang SC
heading:
size: 20px
weight: 600
subheading:
size: 14px
weight: 500
body:
size: 14px
weight: 400
colorSystem:
primary:
- "#0f172b"
background:
- "#ffffff"
- "#f5f6f8"
text:
- "#1f2329"
- "#86909c"
functional:
- "#ef4444"
- "#f59e0b"
- "#e5e6eb"
todos:
- id: create-input
content: 创建 input/input.vue 与 input/index.scss(基础框:v-model、size、status、prefix/suffix、allowClear、showCount)
status: completed
- id: create-password
content: 创建 input-password/input-password.vue(复用 Input,Eye/EyeOff 切换)
status: completed
dependencies:
- create-input
- id: create-textarea
content: 创建 textarea/textarea.vue 与 textarea/index.scss(多行 + showCount)
status: completed
- id: app-demo
content: 在 App.vue 增加 input/password/textarea 演示区块
status: completed
dependencies:
- create-input
- create-password
- create-textarea
- id: verify
content: 运行 lint 校验并自查演示渲染与 dark 适配
status: completed
dependencies:
- app-demo
---
## 用户需求
在 fms-vue 组件库中新增 Input 相关组件,设计参考本地 `参考组件库/shadcn` 与 `参考组件库/antdv-next`,样式采用纯 scoped scss + `--fms-*` CSS 变量(延续 button 做法,零运行时)。
## 产品概述
为轻量组件库补充文本输入能力,包含基础输入框、密码框、多行文本域三种独立组件,并在 App.vue 增加演示区块。
## 核心功能
- **Input 基础框**:v-model 双向绑定、disabled 禁用、size(sm/default/lg)、status(error/warning)、prefix/suffix 插槽、allowClear 一键清除、showCount 字数统计(支持 maxlength)。
- **InputPassword 密码框**:在 Input 基础上增加可见性切换(Eye/EyeOff 图标按钮),支持 disabled/size/status。
- **Textarea 多行文本域**:多行输入,支持 disabled/size/status/showCount/maxlength 与自适应高度(可选)。
- **演示示例**:在 App.vue 新增 input 演示区块,覆盖上述主要用法。
## 技术栈
- 框架:Vue 3(`<script setup>` + `defineProps`/`computed`),纯前端组件库
- 样式:scoped SCSS + `@use './index.scss'`,复用 `src/theme/tokens.css` 中的 `--fms-*` 变量
- 图标:`@lucide/vue`(button 已引入),password 用 `Eye`/`EyeOff`,clear 用 `X`
- 无第三方 input 库、无 CSS-in-JS,零运行时
## 实现方案
采用与现有 `button/` 完全一致的组件范式:单 `.vue` 文件 + 同目录 `index.scss`,`computed` 拼 `classes`、`<style scoped lang="scss"> @use './index.scss'`,图标统一 `:deep(svg){width:1em;height:1em}`。
- **Input.vue**:用原生 `<input>` 承载,外层包裹 `.input-wrapper`(相对定位,承载 prefix/suffix/clear/count 绝对定位元素);v-model 通过 `modelValue`/`update:modelValue` + `emit` 实现;`allowClear` 仅在 hover 且有值时显示清除按钮;`showCount` 在右下角显示 `len/maxlength`。复用 shadcn 的 `data-slot="input"` 与 `aria-invalid` 语义,聚焦环用 `outline` + `box-shadow ring`(沿用 button 的 focus-visible 风格)。
- **size 映射**:tokens 仅有默认高度 32px,组件内补全 sm=24px / lg=40px(scss 局部变量,不污染全局 token),字号 sm=12px / default=14px / lg=16px。
- **status 映射**:error 用 `--fms-danger` 边框、warning 用 `--fms-warning` 边框,无现成 status 变量时用 `color-mix(in srgb, var(--fms-danger) 50%, var(--fms-border))` 推导柔和边框,focus 时加深。
- **InputPassword.vue**:基于 Input 组合(包裹 Input 并把 suffix 替换为可见切换按钮),内部 `show = ref(false)` 切换 `type`,切换按钮 `type="button"` 防提交。优先复用 Input 的 prefix/suffix/clear/status 能力,仅覆写 type。
- **Textarea.vue**:原生 `<textarea>`,结构与 Input 平行(含 showCount、status、disabled、size),不做 prefix/suffix(多行场景通常不需要)。
- **架构可扩展性**:Input 的 wrapper/clear/count 逻辑封装为内部私有函数/片段,InputPassword 直接复用 Input 组件而非复制样式,降低后续维护成本。
## 实现注意事项
- 复用 `lucide/vue` 与 button 相同的图标缩放规则,避免重复定义。
- `allowClear` 清除后需 `emit('update:modelValue','')` 并触发 `blur/focus` 可见性关闭。
- `showCount` 与 `maxlength` 联动:未设 maxlength 时仅显示当前长度。
- 禁用态沿用 button 的 `opacity:.5;pointer-events:none` + `disabled` 属性。
- 不改动 `button/`、`button-group/`、`tokens.css` 以外的现有文件;dark 适配靠 token 自动覆盖,组件只引用变量。
- 性能:均为轻量受控组件,无虚拟列表/大量 DOM,聚焦与输入走原生事件,无需防抖(如需可后续加)。
## 架构设计
组件独立、互不影响,InputPassword 依赖 Input 复用其视觉与交互。演示区块为 App.vue 内的纯展示区域,不引入新路由。
## 目录结构
```
fms-vue/src/components/ui/
├── input/
│ ├── input.vue # [NEW] Input 基础框。v-model、disabled、size、status、prefix/suffix 插槽、allowClear、showCount、maxlength。结构:.input-wrapper > (prefix)(input)(suffix/clear)(count)。
│ └── index.scss # [NEW] Input 样式。定义 .input / .input-wrapper / 尺寸 sm/default/lg / 状态 error|warning / prefix|suffix|clear|count 定位,复用 --fms-* tokens。
├── input-password/
│ └── input-password.vue # [NEW] 密码框。包裹 Input,suffix 提供 Eye/EyeOff 切换 type;透传 disabled/size/status/placeholder。
├── textarea/
│ ├── textarea.vue # [NEW] 多行文本域。v-model、disabled、size、status、showCount、maxlength;结构:.textarea-wrapper > (textarea)(count)。
│ └── index.scss # [NEW] Textarea 样式。复用 Input 的部分变量与状态色,定义多行高度与 padding。
fms-vue/src/App.vue # [MODIFY] 新增 input 演示区块,演示上述三种组件的主要用法(含尺寸、状态、前后缀、清除、字数统计、密码切换)。
```
## 关键代码结构
```ts
// Input props(script setup defineProps 示意)
const props = defineProps({
modelValue: { type: [String, Number], default: '' },
type: { type: String, default: 'text' },
disabled: { type: Boolean, default: false },
size: { type: String, default: 'default' }, // 'sm' | 'default' | 'lg'
status: { type: String, default: '' }, // '' | 'error' | 'warning'
allowClear: { type: Boolean, default: false },
showCount: { type: Boolean, default: false },
maxlength: { type: [String, Number], default: undefined },
})
const emit = defineEmits(['update:modelValue', 'change', 'blur', 'focus'])
```
## 设计风格
沿用现有 fms-vue 组件库的克制中性风格(与 button 一致),采用浅色卡片背景 + 细边框 + 主色聚焦环。Input 视觉对齐 antdv-next 的紧凑专业感与 shadcn 的 minimal 边框,演示区块延续 App.vue 现有分区样式(标题 + 卡片容器 + 示例行)。
## 页面区块(App.vue 新增演示)
1. 区块标题「Input 输入框」+ 说明。
2. 基础用法行:默认 input、disabled、三种尺寸(sm/default/lg)。
3. 前后缀与清除行:prefix 图标、suffix 文本、allowClear 演示。
4. 状态行:error / warning 状态展示。
5. 字数统计行:showCount + maxlength。
6. 密码框行:InputPassword 可见切换。
7. 多行文本行:Textarea + showCount。
## Agent Extensions
### Skill
- **antdv-next**
- Purpose: 查询 Input/Password/TextArea 的 props、slots、事件与尺寸/状态 token 定义,确保组件 API 与 antdv-next 设计对齐。
- Expected outcome: 获取准确的属性命名(size/status/allowClear/showCount/prefix/suffix)与默认行为,用于指导 Input 系列组件实现。
- **ui-ux-pro-max**
- Purpose: 参考现代输入框交互与聚焦/禁用/错误态视觉规范,提升组件视觉一致性与可访问性。
- Expected outcome: 输出聚焦环、错误态、前后缀间距等专业 UI 规范,落地到 index.scss。