我们需要研究如何将选择/组合框的 API 想象成 Web 组件世界中的样子。
选择框或组合框可能是同一个组件,但也许我们想将它们分开。 这还没有定论。
将不同的组件库/设计系统方法与组合框/选择组件进行比较,并提出可行的 API 建议。
一些潜在资源:
请记住,选项的虚拟化将是必须的。 这是我们应该在 Web 组件层上处理的事情,还是我们的消费者在潜在的框架层上处理的事情。
使用虚拟滚动选项在 Angular 设置中使用上述 Web 组件之一进行测试和研究。
尝试在 Web 组件中使用 React 和虚拟化。
如果我们决定自己处理这个问题 - 构建一个模板机制,为创建的选项设置上下文是我们需要做的事情。
有关如何实现此类目标的一些资源可能是microsoft-graph-toolkit
这个问题的结果应该是我们的选择和优缺点的概述,以便我们就如何继续前进做出明智的决定。
与@heartdisease同步关于组合框的 API 想法。 他正在改进我们当前的 Angular 实验版本
我测试了microsoft-graph-toolkit TemplateHelper以生成具有给定上下文和插槽中提供的模板的组合框项。 这正如我们希望的那样工作,也适用于模板中的嵌套元素。
我将测试上传到这个 repo
因此,我们应该将项目列表和(可选)模板传递给组合框,并在实际渲染项目之前“仅”添加虚拟化以仅渲染 x 个项目,具体取决于滚动位置和高度覆盖容器。
目前, TemplateHelper.renderTemplate()
方法接受一个 HTMLElement 作为根节点、一个模板和一个上下文(以及一个可选的附加上下文)。 它根据给定的模板创建所有节点并将它们附加到根节点。
最好改变这种行为,让该方法只接受一个模板和一个上下文,并返回编译后的模板,然后能够直接在组件的 lit-template 中输出返回的 HTML。
你怎么认为?
ToDo
加载微调器应该显示在哪里?聚焦时,组合框应在点击Enter
、 ArrowUp
或ArrowDown
键或用户开始在输入字段中输入过滤器时打开。
打开时,用户应该能够使用ArrowUp
/ ArrowDown
键从现有选项中进行选择。 输入过滤器的焦点应保留在输入字段中,选项不应为选项卡式。 应使用aria-selected
属性指示选项的选择状态。
应使用Enter
键提交选择。
按Tab
或Escape
键应该会关闭覆盖层,并且不应更改所选项目。
键入过滤器然后跳出输入字段时,应重置过滤器并显示先前选择的项目。
用户必须提供模板部件的开始和结束字符串。 这应该可以在全局或每个组件级别上实现(尚未决定)。
默认为{{
和}}
。
_WIP_
ComboBox 应该分为主要的FluidComboBox
组件、 FluidComboBoxOptionsList
组件和FluidComboBoxOption
组件。
包含一个FluidComboBoxOptionsList
,它又包含FluidComboBoxOption
s。
处理覆盖和覆盖定位的打开和关闭。
接受一个模板作为接受基HTMLElement
的子元素。
提供模板时,必须设置用于模板绑定的开始和结束字符串。
| 姓名 | 计划用于 | 类型 | 默认 | 说明 |
| -------------- | ----------- | -------- | ------- | -------------------------------------------------- ------------------------------ |
| 选项| MVP | 数组 | [] | 在FluidComboBoxOptionsList
显示的选项数组 |
| 过滤器Fn | MVP | (option: T) => boolean
| null
| 用于过滤选项的函数 |
| renderOptionFn | MVP | (option: T) => string
| null
| 用于自动完成面板中的渲染选项的函数 |
| 占位符| MVP | 字符串 | '' | 未选择任何选项时在输入字段中显示的占位符 |
| 禁用 | MVP | 布尔值 | 假| Boolean 判断组合框是否被禁用 |
| 加载 | MVP | 布尔值 | 假| 布尔判断是否显示加载指示器|
| 选择 | MVP | 任何 | 空| 要预选的项目 |
| 多选 | v2 | 布尔值 | 假| 布尔判断是否可以同时选择多个选项|
| 姓名 | 计划用于 | 类型 | 说明 |
| ---------------- | ----------- | --------------------------------- | -------------------------------------------------- ---- |
| 改变 | MVP | FluidComboBoxChangeEvent | 值更改时触发的事件 |
| 过滤器变化| MVP | FluidComboBoxFilterChangeEvent | 当用户输入过滤值时触发的事件 |
| 选择-改变| MVP | FluidComboBoxSelectionChangeEvent | 所选选项更改时触发的事件 |
作为 FluidComboBox 的先决条件,我们需要先实现一个可重用的加载微调组件。
ToDo
向 UX 询问新加载微调器的 L&F(或者是否可以重新使用旧设计)。
作为 FluidComboBox 的先决条件,我们需要实现一个可复用的组件,实现虚拟滚动
为了能够使用带有大量项目的组合框。
也可以看看:
https://github.com/WICG/virtual-scroller/blob/master/README.md
https://www.sitepen.com/blog/next-generation-virtual-scrolling/
https://dev.to/adamklein/build-your-own-virtual-scroll-part-i-11ib
https://blog.logrocket.com/virtual-scrolling-core-principles-and-basic-implementation-in-react/
作为FluidComboBox的先决条件,我们需要实现一个可复用的popover组件,可以放置
完美地位于组合框的输入元素下方。
这个库应该用于实现该组件:
https://popper.js.org/docs/v2/
关于模板,我有一些担忧,因为开发人员只有文本替换不是很灵活和广泛。 考虑通过函数或简单条件进行文本转换,例如 if 那是不可能的,但我认为是必需的。
我的方法是编写返回一个 HTML 字符串的函数,该字符串可以放入 DocumentFragment 中,然后可以附加。
使用写入函数,您将获得转换或条件的完全灵活性。
为了提供一个简单的出口,我们可以利用类似于 JSX htm 的东西,它可以呈现为字符串,因此不需要编译。 它还具有我们所说的约 700 字节的非常小的占用空间。
然后可以以某种方式使用它,例如:
<script type="text/template">
html`
<span>${text}</span>
{count > 0
<span>occurrences ${count}</span>
}
</div>
`;
</script>
import { render } from "preact-render-to-string";
const template = document.createElement('template');
template.innerHTML = render(option); // option is the script that can be passed via slot or input
const fragment = temp.content;
或者,我们可以使用标记模板https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_templates。
这可能是更小的解决方案。
我做了一些测试,不幸的是,Angular 从模板中删除了所有脚本标签。 关于在模板中声明脚本,我只需 2 美分。
也许让我们采用函数优先的方法,以便组合框有一个输入,您可以在其中提供有关如何呈现模板的函数。
是否可以在 LitElements 上提供一个函数作为属性? 因为那样我会将渲染传递给消费者,他在此功能中拥有 javascript 的所有灵活性。 该函数已声明参数(模板的输入)并且必须返回一个字符串。
默认实现可以这样完成:
_defaultTemplate<T>(display: string, value: T): string {
return `<option>${display}</option>`
}
正如#1513 中所讨论的,我们需要正确处理弹出窗口。
我不确定这是否是讨论组合框组件一部分的输入的正确地方 - 但由于输入在焦点上增长,我认为扩展输入组件的框以占据最大状态的空间是有意义的拥有。
目前,一旦聚焦,输入的宽度就会增加 16 像素。 所以我建议让标签 + 输入移动 8 的填充。这意味着如果多个控件(输入、选择、...)处于垂直表单布局中,则任何控件的所有标签都需要对齐。 也许一个表单控件是有意义的,它负责统一标签 + 输入的间距。
我想修改提案,添加一个新的输入来呈现当前选择选项的显示字符串:
| 姓名 | 计划用于 | 类型 | 默认 | 说明 |
| -------------- | ----------- | -------- | ------- | -------------------------------------------------- ------------------------------ |
| 显示名称Fn | MVP | (option: T) => string
| (option) => `${option}` | 返回给定选项的显示字符串(不允许 HTML)的函数。 |
这也将为这个问题提供一个简单的解决方案:#1527
我认为很重要的一些小事:当前的 DtCombobox 使用选项的value
作为默认的“选定选项”显示文本。 我认为使用选项的textContent
更有意义。
1) textContent
总是一个 UI 友好的值( value
只是有时一个 UI 友好的值)
2)使用textContent
是标准select
的做法
我们将关闭这个问题,因为 Web 组件不是我们希望在未来创建组件的方式,这与团队中优先级的转变有关。
最有用的评论
要求
后续步骤要求
ToDo
加载微调器应该显示在哪里?无障碍
聚焦时,组合框应在点击
Enter
、ArrowUp
或ArrowDown
键或用户开始在输入字段中输入过滤器时打开。打开时,用户应该能够使用
ArrowUp
/ArrowDown
键从现有选项中进行选择。 输入过滤器的焦点应保留在输入字段中,选项不应为选项卡式。 应使用aria-selected
属性指示选项的选择状态。应使用
Enter
键提交选择。按
Tab
或Escape
键应该会关闭覆盖层,并且不应更改所选项目。键入过滤器然后跳出输入字段时,应重置过滤器并显示先前选择的项目。
自定义模板语法
用户必须提供模板部件的开始和结束字符串。 这应该可以在全局或每个组件级别上实现(尚未决定)。
默认为
{{
和}}
。API 提案
_WIP_
ComboBox 应该分为主要的
FluidComboBox
组件、FluidComboBoxOptionsList
组件和FluidComboBoxOption
组件。流体组合框
包含一个
FluidComboBoxOptionsList
,它又包含FluidComboBoxOption
s。处理覆盖和覆盖定位的打开和关闭。
接受一个模板作为接受基
HTMLElement
的子元素。提供模板时,必须设置用于模板绑定的开始和结束字符串。
输入
| 姓名 | 计划用于 | 类型 | 默认 | 说明 |
| -------------- | ----------- | -------- | ------- | -------------------------------------------------- ------------------------------ |
| 选项| MVP | 数组 | [] | 在
FluidComboBoxOptionsList
显示的选项数组 || 过滤器Fn | MVP |
(option: T) => boolean
|null
| 用于过滤选项的函数 || renderOptionFn | MVP |
(option: T) => string
|null
| 用于自动完成面板中的渲染选项的函数 || 占位符| MVP | 字符串 | '' | 未选择任何选项时在输入字段中显示的占位符 |
| 禁用 | MVP | 布尔值 | 假| Boolean 判断组合框是否被禁用 |
| 加载 | MVP | 布尔值 | 假| 布尔判断是否显示加载指示器|
| 选择 | MVP | 任何 | 空| 要预选的项目 |
| 多选 | v2 | 布尔值 | 假| 布尔判断是否可以同时选择多个选项|
输出
| 姓名 | 计划用于 | 类型 | 说明 |
| ---------------- | ----------- | --------------------------------- | -------------------------------------------------- ---- |
| 改变 | MVP | FluidComboBoxChangeEvent | 值更改时触发的事件 |
| 过滤器变化| MVP | FluidComboBoxFilterChangeEvent | 当用户输入过滤值时触发的事件 |
| 选择-改变| MVP | FluidComboBoxSelectionChangeEvent | 所选选项更改时触发的事件 |
流体加载旋转器
作为 FluidComboBox 的先决条件,我们需要先实现一个可重用的加载微调组件。
ToDo
向 UX 询问新加载微调器的 L&F(或者是否可以重新使用旧设计)。流体虚拟滚动器
作为 FluidComboBox 的先决条件,我们需要实现一个可复用的组件,实现虚拟滚动
为了能够使用带有大量项目的组合框。
也可以看看:
https://github.com/WICG/virtual-scroller/blob/master/README.md
https://www.sitepen.com/blog/next-generation-virtual-scrolling/
https://dev.to/adamklein/build-your-own-virtual-scroll-part-i-11ib
https://blog.logrocket.com/virtual-scrolling-core-principles-and-basic-implementation-in-react/
流体爆裂
作为FluidComboBox的先决条件,我们需要实现一个可复用的popover组件,可以放置
完美地位于组合框的输入元素下方。
这个库应该用于实现该组件:
https://popper.js.org/docs/v2/