NativeSelect 原生下拉
选项写法与 pt-select 相同,展开的是浏览器 / 系统自带的列表。placeholder 是不可选、不出现在列表里的首项。
<pt-native-select placeholder="选择环境" aria-label="环境">
<pt-option value="prod">生产</pt-option>
<pt-option value="staging">预发</pt-option>
<pt-option value="dev">开发</pt-option>
<pt-option value="archived" disabled>已归档</pt-option>
</pt-native-select>影子树里是一个真正的 <select>,展开的是浏览器 / 系统自带的列表:iOS / Android 上是系统的滚轮或底部面板, 桌面上是原生菜单。选项写法与 Select 选择器 完全相同 —— pt-option 与 pt-option-group。
和 Select 怎么选
| 需要 | 用 |
|---|---|
| 选项里放图标、统一的列表样式、窄屏变底部抽屉 | pt-select |
| 系统原生的选择体验、极长列表的原生性能、朴素的表单页面 | pt-native-select |
原生列表的外观由浏览器决定,组件只管收起时的那个框;列表的明暗跟随主题(color-scheme)。
分组
pt-option-group 镜像成原生 <optgroup>,label 是不可选的组标题。
<pt-native-select value="Asia/Tokyo" aria-label="时区">
<pt-option-group label="亚洲">
<pt-option value="Asia/Shanghai">上海</pt-option>
<pt-option value="Asia/Tokyo">东京</pt-option>
</pt-option-group>
<pt-option-group label="欧洲">
<pt-option value="Europe/London">伦敦</pt-option>
<pt-option value="Europe/Paris">巴黎</pt-option>
</pt-option-group>
</pt-native-select>pt-option-group 镜像成原生 <optgroup>,label 是不可选的组标题。原生 <select> 里只能放选项与分组, pt-separator 这类其它子元素会被忽略。
尺寸与状态
三档尺寸对应 24 / 32 / 40 的控件刻度;invalid 描边转危险色,disabled 半透明且不可交互。
<pt-native-select size="sm" value="a" aria-label="小">
<pt-option value="a">小号</pt-option>
</pt-native-select>
<pt-native-select size="lg" value="a" aria-label="大">
<pt-option value="a">大号</pt-option>
</pt-native-select>
<pt-native-select invalid placeholder="出错态" aria-label="出错态">
<pt-option value="a">选项</pt-option>
</pt-native-select>
<pt-native-select disabled value="a" aria-label="禁用">
<pt-option value="a">禁用</pt-option>
</pt-native-select>值不在选项里时
与原生 <select> 一致:
- 给了
placeholder:显示占位项(弱化色)。占位项value=""、不可选、不出现在展开的列表里。 - 没给:显示第一个可选项。
表单提交的是界面上实际显示的那一项(占位项提交空串,required 时校验报「必填」)。 value 属性本身不会被改写 —— 框架常常先写值、后渲染选项,改写的话值会在选项到齐之前被冲掉。 所以受控写法里最好给 placeholder 或一个在选项里的初值,免得绑定的值与显示的不一致。
选项的更新
pt-option / pt-option-group 在这里只是数据:组件读出它们的 value、disabled、文本与 label, 镜像成影子树里的原生选项,它们自己不渲染任何东西。增删选项、改文本、改这几个属性都会立刻同步, 用框架的列表渲染(map / v-for / @for)照常写即可。
只有一种情况不会自动同步:按需注册时没有注册 pt-option / pt-option-group,又用 JS 直接改它们的 property(option.value = …)。没升级的元素上 property 只是普通字段,不会反射成 attribute,谁也观察不到。 组件会在下拉被按下 / 聚焦之前再读一次,展开的列表不会过期;要让显示与表单值立刻跟上,改 attribute, 或者改完调一次 refresh()。三个框架的包装层都会注册 PtOption,不受影响。
无障碍
- 键盘操作完全是原生的:聚焦后方向键 / 首字母切换选项,Space / Enter / Alt+↓ 展开(随平台)。
- 没有可见标签时写
aria-label(包装层里是ariaLabelText),它落在内部的原生<select>上。 invalid同时标注aria-invalid,不只靠颜色。
API
属性
| 属性 | Attribute | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
ariaLabelText | aria-label | string | undefined | — | 无障碍名称:原生 HTML 里写 aria-label,React / Vue / Angular 包装层里属性名是 ariaLabelText。 没有可见 label 时必须给。 |
disabled | disabled | boolean | false | 禁用。只反映使用方自己写的值:外层原生 `<fieldset disabled>`、pt-field / pt-field-set 的禁用另经继承通道生效,不改写它 |
inheritedDisabled | inherited-disabled | boolean | false | 外层 pt-field / pt-field-set 下发的禁用。内部继承通道:由它们以 attribute 维护,不建议使用方直接写。 有效禁用是 `disabled` 与它的并集;父元素只写这一条、不碰 `disabled`,读 `el.disabled` 得到的始终是使用方自己写的值 |
inheritedInvalid | inherited-invalid | boolean | false | 外层 pt-field 下发的出错态。内部继承通道:由 pt-field 维护,不建议使用方直接写。有效出错是 `invalid` 与它的并集 |
inheritedRequired | inherited-required | boolean | false | 外层 pt-field 下发的必填。内部继承通道:由 pt-field 维护,不建议使用方直接写。有效必填是 `required` 与它的并集 |
invalid | invalid | boolean | false | 出错态。校验信息由使用方展示,组件只负责视觉、aria-invalid 与表单校验状态(customError) |
name | name | string | undefined | — | 提交表单时的字段名 |
placeholder | placeholder | string | undefined | — | 占位文案。给了就在最前面渲染一个 `value=""`、不可选、不出现在列表里的占位项, 值为空或不在选项里时显示它(弱化色)。 |
required | required | boolean | false | 必填:提交的值为空(显示着占位项)时表单校验报 valueMissing |
size | size | "lg" | "md" | "sm" | 'md' | 尺寸档位。三档对应 24 / 32 / 40 的控件刻度 |
value | value | string | '' | 当前值。不在选项里时的表现见组件说明 |
事件
| 事件 | detail 类型 | 说明 |
|---|---|---|
ptChange | string | 用户选了另一项(原生 change)。冒泡:它不会自我嵌套 |
方法
| 方法 | 说明 |
|---|---|
refresh() => Promise<void> | 重新读一遍选项。选项的增删、改文本、改 attribute,以及**已升级**的 pt-option / pt-option-group 改 property(它们的 value / disabled / label 都反射成 attribute)都会被自动跟上,不需要调它。 要调它的只有一种情况:pt-option / pt-option-group **没有注册**(按需注册时它们不是本组件的依赖), 又用 JS 改了它们的 property —— 没升级的元素上,property 只是普通字段,不会反射成 attribute, 任何观察器都看不到。组件会在用户按下 / 聚焦下拉之前再读一次,保证展开的列表是新的; 想让界面与表单值立刻跟上就调这个方法,或者改 attribute 而不是 property。 |
可定制的内部元素(::part())
| part | 说明 |
|---|---|
base | 外框:边框、圆角、焦点环、出错色都画在它上面(叠在原生 select 上,不接指针) |
icon | 末端的下拉箭头 |
select | 原生 `<select>`:文字与交互 |
CSS 变量
| 变量 | 说明 |
|---|---|
--pt-native-select-radius | 圆角,默认取控件档位(md / lg 为 --pt-radius-md,sm 为 --pt-radius-sm) |