组件
Form 表单
L1 表单原子:input / select / textarea / checkbox / radio / switch / range / file 等;校验态与 input-group。数字步进、日期、颜色、上传见独立组件页。
Form overview
典型「账户设置」一屏组合:文本、下拉、多行、勾选、开关与提交钮。
<form class="pvs-stack pvs-gap-4" style="max-width:26rem" onsubmit="return false">
<div class="pvs-form-group">
<label class="pvs-label" for="fo-name">姓名</label>
<input class="pvs-input" id="fo-name" type="text" placeholder="张三" />
</div>
<div class="pvs-form-group">
<label class="pvs-label" for="fo-email">邮箱</label>
<input class="pvs-input" id="fo-email" type="email" placeholder="you@example.com" />
<p class="pvs-form-hint">用于登录与通知</p>
</div>
<div class="pvs-form-group">
<label class="pvs-label" for="fo-pass">密码</label>
<input class="pvs-input" id="fo-pass" type="password" placeholder="••••••" />
</div>
<div class="pvs-form-group">
<label class="pvs-label" for="fo-role">角色</label>
<select class="pvs-select" id="fo-role">
<option>编辑</option>
<option>管理员</option>
</select>
</div>
<div class="pvs-form-group">
<label class="pvs-label" for="fo-bio">简介</label>
<textarea class="pvs-textarea" id="fo-bio" rows="2" placeholder="一句话介绍">
</textarea>
</div>
<div class="pvs-form-check">
<input class="pvs-form-check__input" id="fo-agree" type="checkbox" />
<label class="pvs-label" for="fo-agree" style="margin:0">同意服务条款</label>
</div>
<label class="pvs-switch">
<input class="pvs-switch__input" type="checkbox" checked />
<span class="pvs-switch__track" aria-hidden="true">
</span>
<span class="pvs-text-sm">接收邮件通知</span>
</label>
<div class="pvs-cluster pvs-gap-2">
<button type="submit" class="pvs-btn pvs-btn--primary pvs-btn--sm">保存</button>
<button type="reset" class="pvs-btn pvs-btn--ghost pvs-btn--sm">重置</button>
</div>
</form>基础字段
用于接收通知。
<div class="pvs-form-group" style="max-width:20rem">
<label class="pvs-label" for="fd-email">邮箱</label>
<input class="pvs-input" id="fd-email" type="email" placeholder="you@example.com" />
<p class="pvs-form-hint">用于接收通知。</p>
</div>尺寸
--sm / 默认 / --lg 适用于 input、select、textarea。
<div class="pvs-stack" style="max-width:20rem">
<input class="pvs-input pvs-input--sm" placeholder="pvs-input--sm" />
<input class="pvs-input" placeholder="default" />
<input class="pvs-input pvs-input--lg" placeholder="pvs-input--lg" />
<select class="pvs-select pvs-select--sm">
<option>pvs-select--sm</option>
</select>
<select class="pvs-select pvs-select--lg">
<option>pvs-select--lg</option>
</select>
<textarea class="pvs-textarea" rows="2" placeholder="pvs-textarea">
</textarea>
</div>校验
pvs-input--invalid / --valid 右侧内联 SVG 图标(无图标字体依赖)+ 语义边框色。
至少 3 个字符
格式正确
<div class="pvs-form-group" style="max-width:20rem">
<label class="pvs-label" for="fd-bad">用户名</label>
<input class="pvs-input pvs-input--invalid" id="fd-bad" value="a" />
<p class="pvs-field-error">至少 3 个字符</p>
</div>
<div class="pvs-form-group pvs-mt-4" style="max-width:20rem">
<label class="pvs-label" for="fd-ok">域名</label>
<input class="pvs-input pvs-input--valid" id="fd-ok" value="pivark.com" />
<p class="pvs-field-success">格式正确</p>
</div>Input types
常见 HTML5 type 共用 pvs-input;日期/时间复杂面板见 Date picker。
<div class="pvs-stack pvs-gap-3" style="max-width:20rem">
<div class="pvs-form-group pvs-m-0">
<label class="pvs-label" for="ft-pass">password</label>
<input class="pvs-input" id="ft-pass" type="password" value="secret" />
</div>
<div class="pvs-form-group pvs-m-0">
<label class="pvs-label" for="ft-tel">tel</label>
<input class="pvs-input" id="ft-tel" type="tel" placeholder="13800000000" />
</div>
<div class="pvs-form-group pvs-m-0">
<label class="pvs-label" for="ft-url">url</label>
<input class="pvs-input" id="ft-url" type="url" placeholder="https://pivark.com" />
</div>
<div class="pvs-form-group pvs-m-0">
<label class="pvs-label" for="ft-num">number</label>
<input class="pvs-input" id="ft-num" type="number" min="0" max="99" value="3" />
</div>
<div class="pvs-form-group pvs-m-0">
<label class="pvs-label" for="ft-search">search</label>
<input class="pvs-input" id="ft-search" type="search" placeholder="站内搜索" />
</div>
<div class="pvs-form-group pvs-m-0">
<label class="pvs-label" for="ft-date">date</label>
<input class="pvs-input" id="ft-date" type="date" />
</div>
</div>Textarea & select validation
校验修饰符同样作用于 pvs-textarea / pvs-select。
至少 10 字
已选择有效区域
<div class="pvs-stack pvs-gap-4" style="max-width:20rem">
<div class="pvs-form-group pvs-m-0">
<label class="pvs-label" for="fv-ta">备注</label>
<textarea class="pvs-textarea pvs-textarea--invalid" id="fv-ta" rows="2">太短</textarea>
<p class="pvs-field-error">至少 10 字</p>
</div>
<div class="pvs-form-group pvs-m-0">
<label class="pvs-label" for="fv-sel">地区</label>
<select class="pvs-select pvs-select--valid" id="fv-sel">
<option selected>华东</option>
</select>
<p class="pvs-field-success">已选择有效区域</p>
</div>
</div>复选框
<div class="pvs-form-check">
<input class="pvs-form-check__input" id="fd-agree" type="checkbox" />
<label class="pvs-label" for="fd-agree" style="margin:0">同意服务条款</label>
</div>Checkbox group
多个 pvs-form-check 叠放;横向可用 pvs-cluster 包一层。
<fieldset class="pvs-stack pvs-gap-2" style="max-width:20rem;border:0;padding:0;margin:0">
<legend class="pvs-label">通知渠道</legend>
<div class="pvs-form-check">
<input class="pvs-form-check__input" id="fc-mail" type="checkbox" checked />
<label class="pvs-label" for="fc-mail" style="margin:0">邮件</label>
</div>
<div class="pvs-form-check">
<input class="pvs-form-check__input" id="fc-sms" type="checkbox" />
<label class="pvs-label" for="fc-sms" style="margin:0">短信</label>
</div>
<div class="pvs-form-check">
<input class="pvs-form-check__input" id="fc-push" type="checkbox" />
<label class="pvs-label" for="fc-push" style="margin:0">站内信</label>
</div>
</fieldset>多行与下拉
<div class="pvs-stack" style="max-width:20rem">
<textarea class="pvs-textarea" rows="2" placeholder="pvs-textarea">
</textarea>
<select class="pvs-select">
<option>pvs-select</option>
</select>
</div>行内表单
pvs-form-inline 横向排列表单项。
<form class="pvs-form-inline">
<div class="pvs-form-group">
<label class="pvs-label" for="fd-q">搜索</label>
<input class="pvs-input pvs-input--sm" id="fd-q" type="search" />
</div>
<button type="submit" class="pvs-btn pvs-btn--primary pvs-btn--sm">搜</button>
</form>单选
<div class="pvs-stack pvs-gap-2" style="max-width:20rem">
<div class="pvs-form-check pvs-form-check--radio">
<input class="pvs-form-check__input" id="fd-r1" name="fd-plan" type="radio" checked />
<label class="pvs-label" for="fd-r1" style="margin:0">免费版</label>
</div>
<div class="pvs-form-check pvs-form-check--radio">
<input class="pvs-form-check__input" id="fd-r2" name="fd-plan" type="radio" />
<label class="pvs-label" for="fd-r2" style="margin:0">专业版</label>
</div>
</div>开关
<label class="pvs-switch">
<input class="pvs-switch__input" type="checkbox" checked />
<span class="pvs-switch__track" aria-hidden="true">
</span>
<span class="pvs-text-sm">启用暗色模式</span>
</label>输入组
https://.com
<div class="pvs-input-group" style="max-width:20rem">
<span class="pvs-input-group__addon">https://</span>
<input class="pvs-input" type="text" placeholder="域名" />
<span class="pvs-input-group__addon">.com</span>
</div>Input group + button
前后缀与 pvs-btn 同一行;按钮不参与圆角拼接时需自行控制顺序。
¥
<div class="pvs-input-group" style="max-width:22rem">
<input class="pvs-input" type="search" placeholder="搜索文档" />
<button type="button" class="pvs-btn pvs-btn--primary pvs-btn--sm">搜</button>
</div>
<div class="pvs-input-group pvs-mt-3" style="max-width:22rem">
<span class="pvs-input-group__addon">¥</span>
<input class="pvs-input" type="number" placeholder="0.00" />
<button type="button" class="pvs-btn pvs-btn--outline pvs-btn--sm">应用</button>
</div>禁用态
禁用态适用于 input / select / textarea;开关与原生 checkbox 用 HTML disabled。
<div class="pvs-stack pvs-gap-3" style="max-width:20rem">
<input class="pvs-input" value="不可编辑" disabled />
<select class="pvs-select" disabled>
<option>禁用下拉</option>
</select>
<textarea class="pvs-textarea" rows="2" disabled>禁用多行</textarea>
<label class="pvs-switch">
<input class="pvs-switch__input" type="checkbox" disabled />
<span class="pvs-switch__track" aria-hidden="true">
</span>
<span class="pvs-text-sm">禁用开关</span>
</label>
</div>Readonly
只读可复制,不可改值。
<div class="pvs-form-group" style="max-width:20rem">
<label class="pvs-label" for="fr-id">站点 ID</label>
<input class="pvs-input" id="fr-id" type="text" value="pivark-demo-001" readonly />
<p class="pvs-form-hint">只读可复制,不可改值。</p>
</div>Floating label
pvs-form-floating:标签在输入获得焦点或已有内容时上浮;支持 input / textarea / select。
<div class="pvs-stack pvs-gap-4" style="max-width:20rem">
<div class="pvs-form-floating">
<input class="pvs-input" id="fd-float" type="email" placeholder="you@example.com" />
<label class="pvs-label" for="fd-float">邮箱</label>
</div>
<div class="pvs-form-floating">
<select class="pvs-select" id="fd-float-sel">
<option value="" hidden>
</option>
<option selected>华东</option>
<option>华北</option>
</select>
<label class="pvs-label" for="fd-float-sel">区域</label>
</div>
<div class="pvs-form-floating">
<textarea class="pvs-textarea" id="fd-float-ta" placeholder="备注" rows="1">
</textarea>
<label class="pvs-label" for="fd-float-ta">备注</label>
</div>
</div>Range
<div style="max-width:20rem">
<label class="pvs-label" for="fd-range">音量</label>
<input class="pvs-range" id="fd-range" type="range" min="0" max="100" value="40" />
</div>File input
<div class="pvs-form-group" style="max-width:20rem">
<label class="pvs-label" for="fd-file">附件</label>
<input class="pvs-form-file" id="fd-file" type="file" />
</div>结构
L1 Form 只管原生控件样式与布局原语;带 JS 契约的控件拆成独立页,避免单页混杂 data-pvs-*。
类名速查
| 类名 | 说明 |
|---|---|
pvs-form-group | 字段组 |
pvs-label | 标签 |
pvs-input / pvs-select / pvs-textarea | 控件(:focus-visible 焦点环) |
pvs-input--sm / --lg | input / select 尺寸 |
pvs-input--invalid / --valid | 校验边框 + 右侧 SVG 图标 |
pvs-textarea--invalid / pvs-select--valid | 多行与下拉校验 |
pvs-field-error / pvs-field-success | 校验文案 |
pvs-form-hint | 辅助说明 |
pvs-form-check + __input | 复选 / 单选行 |
pvs-form-check--radio | 单选圆点 |
pvs-switch / __track | 开关 |
pvs-input-group / __addon | 前后缀输入组 |
pvs-form-floating | 浮动标签(input/textarea/select) |
pvs-range | 滑块 |
pvs-form-file | 文件选择 |
pvs-form-inline | 横向表单 |
→ number-input / upload / datepicker / colorpicker | 进阶控件独立页 |