Skip to main content

FormSelect

Function FormSelect 

Source
pub fn FormSelect<T, L>(props: FormSelectProps<T, L>) -> impl IntoView
where T: Clone + PartialEq + Send + Sync + 'static, L: AsRef<str> + Send + Sync + 'static,
Expand description

下拉选择框组件(自定义弹层,全主题化)。

原生 <select> 的弹出列表由 OS/浏览器渲染,无法跟随主题(暗色下是白底 系统菜单),故用 button[aria-haspopup=listbox] + 绝对定位面板重写:

  • 面板从触发器下方展开(snappy 弹簧,0.98 → 1),视口下方不够时向上展开;
  • 焦点留在触发器,键盘经 aria-activedescendant 高亮(↑↓ 循环、 Enter/Space 选中、Esc 关闭、Home/End 跳首尾、Tab 关闭并自然流转焦点);
  • 选项多于 8 个时面板顶部出现筛选框,打开即聚焦,键盘规则相同,Esc 把焦点还给触发器;
  • disabled_options 中的项保留但变淡,并在下方写明原因,键盘与点击都跳过;
  • 透明遮罩拦截外部点击关闭;选项 mousedown 阻止默认行为,点击不夺走焦点;
  • 泛型值绑定:onchange 直接回传选中项的 T,无需字符串反查。

触发器与选项的内部 id(form-select-N-opt-I 等)在挂载后由客户端计数分配, 原因见 use_instance_prefix;需要与 label 关联时显式传 id。

Props:

  • id:触发器 id,用于与 label 关联(缺省挂载后用内部计数器生成)
  • value:当前选中项(受控,可传信号)
  • options:可选项 (值, 标签) 列表(Vec 或返回它的闭包 / 信号)
  • disabled_options:不可用的项及原因 (值, 原因)
  • onchange:选中变化回调,回传新选中项的值
  • trigger_class:触发器外观(缺省全宽 field;工具栏传 FORM_SELECT_COMPACT_CLASS)
  • aria_label:触发器无障碍标签;可见文本不足以表意时传入

value / onchange 的类型参数要能从 options 或 onchange 闭包的参数类型推断; 传裸信号且闭包参数无标注时,给闭包写类型(move |v: Foo| ..)。

§Required Props

§Optional Props

  • id: impl Into<MaybeProp<String>>
  • disabled_options: [impl Into<Signal<Vec<(T, &'static str)>>>](Signal<Vec<(T, &’static str)>>)
  • trigger_class: [&'static str]
  • aria_label: [&'static str]