feat(textarea): 新增多行文本组件

- rows / resize / invalid,样式与 Input 一致(焦点只换边框)
- 契约、展示页(#inputs)、README 计数 40 → 41、变更记录同步
This commit is contained in:
stash
2026-10-29 12:58:32 +08:00
parent 12e3047f1a
commit 0d5d7753e2
6 changed files with 113 additions and 2 deletions
+42
View File
@@ -0,0 +1,42 @@
.root {
display: block;
width: 100%;
min-height: 96px;
padding: var(--su-space-2) var(--su-space-3);
border: 1px solid var(--su-border-strong);
border-radius: var(--su-radius-sm);
background-color: var(--su-bg-card);
font-family: inherit;
font-size: var(--su-font-size-md);
line-height: 1.6;
color: var(--su-text-main);
outline: none;
transition: border-color var(--su-duration-base) var(--su-ease-in-out);
}
/* 与 Input 一致:焦点只换边框颜色,不叠 outline */
.root:focus {
border-color: var(--su-color-primary);
}
.root::placeholder {
color: var(--su-text-placeholder);
}
.root:disabled {
cursor: not-allowed;
background-color: var(--su-bg-subtle);
color: var(--su-text-muted);
}
.invalid {
border-color: var(--su-color-danger);
}
.none {
resize: none;
}
.vertical {
resize: vertical;
}
+31
View File
@@ -0,0 +1,31 @@
import type { TextareaHTMLAttributes } from 'react'
import styles from './Textarea.module.css'
/** 多行文本:Markdown 正文、简介、备注。样式与 `Input` 保持一致,只有高度是自适应的。 */
export type TextareaProps = TextareaHTMLAttributes<HTMLTextAreaElement> & {
/** 初始可见行数,默认 4 */
rows?: number
/** 禁止手动拖拽改高度(需要固定版式时用) */
resize?: 'none' | 'vertical'
/** 校验失败态:红边框 */
invalid?: boolean
}
export function Textarea({
rows = 4,
resize = 'vertical',
invalid = false,
className,
...rest
}: TextareaProps) {
return (
<textarea
{...rest}
rows={rows}
aria-invalid={invalid || undefined}
className={[styles.root, styles[resize], invalid ? styles.invalid : '', className]
.filter(Boolean)
.join(' ')}
/>
)
}
+2
View File
@@ -51,6 +51,8 @@ export type { ImageFit, ImageProps, ImageRatio } from './components/Image'
export { FormField } from './components/FormField'
export type { FormFieldProps } from './components/FormField'
export { Textarea } from './components/Textarea'
export type { TextareaProps } from './components/Textarea'
export { Icon } from './components/Icon'
export type { IconName, IconProps } from './components/Icon'