Replies: 4 comments 6 replies
-
Looks good 👍 Also what would happen if I had a store for the items: const [options, setOptions] = createStore([
{
id: "apple",
textValue: "Apple",
label: "🍎 Apple",
disabled: false,
},
// ...
])
// and updated the displayed value
setOptions(0, "label", "🍎 Apple 🍎") would it mean diffing all the items to figure out what's changed? What would virtualization API look like? is it something that user does on his own, or would this be a part of the <Select.Content>
<Select.Listbox>{node => <Select.Item node={node} />}</Select.Listbox>
</Select.Content> Where I would expect: <Select.Content>
{(nodes, container) => (
<MyVirtualFor each={nodes()} container={container}>
{node => <Select.Item node={node} />}
</MyVirtualFor>
)}
</Select.Content> But I guess this is for the library to handle. Just how this could be done so that it's tree-shakeable? How do I listen for the value changes? I think that this {
getLabel: item => item.label
} could be replaced with this: <Select.Item node={node} label={node.label} /> Idk, it feels better to keep rendering/displaying parts in JSX rather than the data structure. Although keeping the label strings there is sound. shouldn't the Can't think of more things. Cheers :D |
Beta Was this translation helpful? Give feedback.
-
Looks good. +1 on separating out the source of truth for the data rather than building through registration. Couple of thoughts:
|
Beta Was this translation helpful? Give feedback.
-
Curious:
|
Beta Was this translation helpful? Give feedback.
-
Released in |
Beta Was this translation helpful? Give feedback.
-
Summary
Currently
Select.Root
is responsible for managing the selection state of the component, in order to do thatSelect.Root
needs to be aware of all it's childSelect.Item
.Motivation
Wille the current implementation has a good Developer eXperience in terms of "writing" the component, there are some drawbacks related to the way it's designed :
Select.Item
needs to be mounted and register themselves toSelect.Root
which lead to poor performance when using large dataset (ex: 2000 items).Select.Content
is always mounted even if the user never open theSelect
.Select
orSelect
with large collection of items in a page.Select.Root
needs to know everySelect.Item
but virtual list solution only render a part of the collection.Goal
Select.Content
keep unmounted when not opened.Detailed Design
The proposed solution is to provide an external "data source" as the single source of truth and not relying on the DOM and
Select.Item
registration to makeSelect.Root
aware of all items.API
Select.Root
will have the following props:T[] | () => T[]
An array of options to display as the available options.
string | (option: T) => string
Property name or getter function to use as the value of an option, defaults to the option itself when not defined.
string | (option: T) => string
Property name or getter function to use as the text value of an option for typeahead purpose, defaults to the option itself when not defined.
string | (option: T) => boolean
Property name or getter function to use as the disabled flag of an option, defaults to false when not defined.
string | (optGroup: T) => T[]
Property name or getter function that refers to the children options of option group.
Internally Kobalte will use the
options
prop to build a flatten array ofCollectionItem
which is an abstraction over user's provided option/group data.CollectionItem<T>
interface has the following properties:'item' | 'section'
The type of the item.
string
The unique key for the item.
string
The string value for the item, used for feature like typeahead.
boolean
Whether the item is disabled.
number
The level of depth the item is at (ex: when the item is built from an option part of an option group).
T
The option/group this item was created from.
Select.Listbox
will accept achildren
render prop which will give access to eachCollectionItem
.Usage
The following use case show how to deal with a data source containing a mix of plain and grouped options.
An option is described as an
object
structure, the final API will have equivalent for dealing withstring
based options.The
Select.Section
componentSelect.Section
is a syntactic sugar component used to render a presentational<li>
which is ignored by screen readers and keyboard navigation. The common use case will be for rendering the label of your option group.The
Select.Item
componentSelect.Item
is the component that represent a selectable option. It is visible by screen readers and support keyboard navigation.FAQs
Will Kobalte provide a built-in virtual scroll solution ?
Not in the initial release, however a port of React Aria Virtualizer is planned.
Will
Select
support nested option group ?No, Kobalte will follows the default html
<select>
behavior, meaning you can't nest<optgroup>
.Related Discussions
Appendix
Beta Was this translation helpful? Give feedback.
All reactions