Skip to content

Select 选择器 ​

基础用法

选项写成子元素而不是数组属性 —— 原生 HTML 里才能不写一行 JS 就用起来。窄屏下弹层会切换成底部抽屉。

<pt-select placeholder="选择环境">
  <pt-option value="prod">生产</pt-option>
  <pt-option value="staging">预发</pt-option>
  <pt-option value="dev">开发</pt-option>
</pt-select>

选项写成 pt-option 子元素而不是 options 数组属性:这样在原生 HTML 里 不写一行 JS 就能用起来,也才能往选项里塞图标。

分组与分隔线 ​

分组与分隔线

pt-option-group 给一组选项加上不可选的组标题,pt-separator 在组与组之间画线。方向键与首字母跳转只在选项之间移动,跨过组标题与分隔线。

<pt-select placeholder="选择时区">
  <pt-option-group label="亚洲">
    <pt-option value="Asia/Shanghai" keywords="china beijing">上海</pt-option>
    <pt-option value="Asia/Tokyo" keywords="japan">东京</pt-option>
  </pt-option-group>
  <pt-separator></pt-separator>
  <pt-option-group label="欧洲">
    <pt-option value="Europe/London" keywords="uk gmt">伦敦</pt-option>
    <pt-option value="Europe/Paris" keywords="france">巴黎</pt-option>
  </pt-option-group>
</pt-select>

选项多了按类别归组时,用 pt-option-group 包住一组 pt-option,label 是不可选的组标题; 组与组、选项与选项之间可以夹一条 pt-separator。

  • 选择与键盘导航只认 pt-option:组里的选项和直接写的选项一样参与选中、方向键、首字母跳转, 组标题与分隔线被自然跨过,首字母跳转也不会匹配到组标题。
  • 无障碍结构是 listbox > group > option,组标题经 aria-labelledby 成为这一组的名字,读屏进入组时先念组名。
  • 分隔线在列表里默认改用更淡的颜色(--pt-bg-secondary)并左右贯通到弹层边缘; 要换颜色直接在 pt-separator 上设 --pt-separator-color。它必须保持默认的装饰性(不要写 decorative="false")—— listbox 里只允许出现选项与分组。

pt-option 的 keywords(空格分隔)只存储、不影响显示,留给可搜索的下拉按别名匹配用; pt-select 的首字母跳转仍只看选项文案。

键盘操作 ​

按 WAI-ARIA 的 listbox 模式实现:

按键行为
Enter / Space展开;已展开时选中当前项
↑ / ↓移动高亮项(未展开时先展开)
Home / End跳到首尾
Esc收起
字母键跳到以该字母开头的选项(1 秒内连打可匹配多字符;从当前项之后找,同一字母连按在以它开头的选项间循环)

弹层 ​

列表进浏览器的顶层(top layer),放在 overflow: hidden 或带 transform 的容器里也不会被裁切, 不需要调 z-index。默认在触发器下方展开、与触发器起始边对齐、至少与触发器同宽;下方放不下时翻到上方。 「起始边」随书写方向:在 dir="rtl" 的页面或容器里,列表与触发器的右边缘对齐。

移动端 ​

窄屏(≤640px)下弹层切换为底部抽屉形态:触屏上贴着触发器的浮层既够不着也容易误触。 抽屉与遮罩同样在顶层,始终贴着视口底边、遮罩盖住整页。 选项行的视觉高度不变,命中区靠伪元素外扩到 44px 的触控目标。

API ​

属性

属性Attribute类型默认值说明
ariaLabelTextaria-labelstring | undefined—无障碍名称:原生 HTML 里写 aria-label,React / Vue / Angular 包装层里属性名是 ariaLabelText。 没有可见 label 时必须给;不给时读屏念的是当前显示的值或占位文案。
disableddisabledbooleanfalse禁用。只反映使用方自己写的值:外层原生 `<fieldset disabled>`、pt-field / pt-field-set 的禁用另经继承通道生效,不改写它
inheritedDisabledinherited-disabledbooleanfalse外层 pt-field / pt-field-set 下发的禁用。内部继承通道:由它们以 attribute 维护,不建议使用方直接写。 有效禁用是 `disabled` 与它的并集;父元素只写这一条、不碰 `disabled`,读 `el.disabled` 得到的始终是使用方自己写的值
inheritedInvalidinherited-invalidbooleanfalse外层 pt-field 下发的出错态。内部继承通道:由 pt-field 维护,不建议使用方直接写。有效出错是 `invalid` 与它的并集
inheritedRequiredinherited-requiredbooleanfalse外层 pt-field 下发的必填。内部继承通道:由 pt-field 维护,不建议使用方直接写。有效必填是 `required` 与它的并集
invalidinvalidbooleanfalse出错态。校验信息由使用方展示,组件只负责视觉、aria-invalid 与表单校验状态(customError)
namenamestring | undefined—提交表单时的字段名
openopenbooleanfalse列表是否展开。可读可写,一般不用手动设置
placeholderplaceholderstring | undefined—未选中时的占位文案
requiredrequiredbooleanfalse必填:值为空时表单校验报 valueMissing,并标注 aria-required
sizesize"lg" | "md" | "sm"'md'尺寸档位。三档对应 24 / 32 / 40 的控件刻度,与 pt-input 一致
valuevaluestring''当前值。与某个 pt-option 的 value 对应

事件

事件detail 类型说明
ptBlurvoid内部控件失去焦点
ptChangestring选中值变化
ptClose{ reason: PtSelectCloseReason; }列表收起,detail 说明是怎么收起的(与 pt-modal 的 ptClose 同形) **不冒泡**:弹层常互相嵌套(弹窗里的菜单、气泡卡片里的下拉),冒泡的话外层上的监听会收到内层的开关。
ptFocusvoid内部控件获得焦点
ptOpenvoid列表展开 **不冒泡**:弹层常互相嵌套(弹窗里的菜单、气泡卡片里的下拉),冒泡的话外层上的监听会收到内层的开关。

方法

方法说明
hide() => Promise<void>收起列表
refresh() => Promise<void>选项变动时重新同步(动态增删选项后调用)
setFocus(options?: FocusOptions) => Promise<void>
show() => Promise<void>展开列表

插槽

名称说明
(默认)`pt-option` 列表,可混放 `pt-option-group` 与 `pt-separator`

可定制的内部元素(::part())

part说明
base触发器(组件可见的外层控件,与 trigger 同一元素)
popup弹出的列表容器
trigger触发器

CSS 变量

变量说明
--pt-select-popup-max-height列表最大高度,默认 384px。窄屏抽屉形态下固定 60vh,不受它影响
--pt-select-radius触发器与弹层的圆角,默认 --pt-radius-md(sm 档触发器默认 --pt-radius-sm)

pt-option ​

属性

属性Attribute类型默认值说明
activeactivebooleanfalse键盘/指针当前高亮项。由所属的 pt-select / pt-combobox 维护,不要手动设置
disableddisabledbooleanfalse禁用:点击不选中,方向键与首字母跳转都会跳过它,并标注 aria-disabled
keywordskeywordsstring | undefined—额外的搜索关键词,空格分隔(如 `"production prod 线上"`)。 只存储、不影响渲染:给可搜索的下拉(pt-combobox)按别名、拼音、英文名匹配用, 这样搜「prod」也能命中文案是「生产」的选项(任一关键词包含查询即命中)。pt-select 的首字母跳转仍只看文案。
selectedselectedbooleanfalse由所属的 pt-select / pt-combobox 维护,不要手动设置
valuevaluestring | undefined—选项值。省略时取文案本身

插槽

名称说明
(默认)选项文案
start文案前的图标

可定制的内部元素(::part())

part说明
base选项行

pt-option-group ​

属性

属性Attribute类型默认值说明
labellabelstring | undefined—组标题。不可选、方向键跳过;同时是这一组的无障碍名称。不给时不渲染标题行

插槽

名称说明
(默认)这一组的 `pt-option`(可夹 `pt-separator`)

可定制的内部元素(::part())

part说明
base分组容器(role="group")
label组标题

Apache-2.0 协议开源