ui-kit
ui-kit copied to clipboard
[RFC] Select component library
Problem statement
In order to implement upcoming features such as the Time Range Picker and the Filters we’ll require to use a Select component, we’ll need to decide whether implementing the Select component ourselves or using a third party library.
Requirements
The Select component should include the next set of features
- It should be Accessibility rich
- It should be usable by keyboard
- It should be a lightweight library
- It should be a well maintained library
- It should be highly customizable
- It should allow autocompletion
- It should allow multi-select
Implementing component ourselves
Implementing the Select component by ourselves will require that we fulfill the requirements that would mostly be already fulfilled by a third party library, it provides the advantage that we would have fully control around the component and any related bug would be in our hands to fix.
This would imply implementing by ourselves at least
- Customization
- Accessibility
- Autocompletion
- Multi-select
Customization
Ideally we would expose our customers with an API to fully customize the Select component’s styles, using a third party library would make this process a lot easy since we can expose the library’s API to our customers similar to what we do with Chart.js, implementing this ourselves would require:
- Defining a customization API for the component
- Allow customizing every part of the component
- Colors
- Text and fonts
- Focus indicators
- Option selected state
- Providing customers with a primitive version of the component so they can style from scratch
- The component should respond to browser preferences
- Upon customization the component will require to update ARIA attributes accordingly
Accessibility
The component will require providing with full accessibility support
- The component should be readable by a screen reader
- The component should be usable only with the keyboard
- The component should be fully responsive and work on mobile devices
- The component should include the correct ARIA attributes
- The component should ensure customization does not affect accessibility
Autocompletion
The component will require support for autocompletion
- The API should allow enabling/disabling autocompletion
- Typing in the input should filter the available options
Multi-select
The component will require support for selecting multiple options
- The API should allow enabling/disabling auto-select
- Selection an option should include the option value in the input
- The input view for multiple options should be customizable
Using a third-party library
Radix
- [x] It should be Accessibility rich ✅
- [x] It should be usable by keyboard ✅
- [x] It should be a lightweight library (428 kB) ✅
- [ ] It should be a well maintained library (⚠️ Last commit 4 months ago)
- [x] It should be highly customizable ✅
- [ ] It should allow autocompletion (⚠️ Doable but not built-in supported)
- [x] It should allow multi-select ✅
Pros | Cons |
---|---|
Radix is a popular library (13k stars on Github) | Radix doesn’t support autocompletion, although they plan to implement a ComboBox which is similar to our use case |
Radix provides a low-level customization by having a different component for each piece of the Select | Radix primitives have not been maintained since 4 months ago, which makes more unlikely that we’ll get the ComboBox component shortly |
Radix allows installing only its Select dependency which makes it more lightweight for our use case | Even if we make our own autocomplete on top of Radix that would sacrifice part of the Accessibility |
Radix contains other components that we could use for future use cases | Radix’s learning curve is pronounced since it’s necessary to use all of the sub components together and style each of them |
React-select
- [x] It should be Accessibility rich ✅
- [x] It should be usable by keyboard ✅
- [x] It should be a lightweight library (723 kB) ✅
- [ ] It should be a well maintained library (⚠️ Last commit 2 months ago)
- [x] It should be highly customizable ✅
- [x] It should allow autocompletion ✅
- [x] It should allow multi-select ✅
Pros | Cons |
---|---|
React-select is a popular library (26.9k stars on Github) | React-select has 296 unresolved issues on GitHub |
React-select provides built-in default autocompletion which is easy to disable | React-select could be an overkill for our use case |
React-select enables easy customization of each of the internal component’s CSS and enables to create a wrapper for each of the internal components | React-select’s last commit was 2 months ago |
React-select’s documentation is extensive | React-select does not contain other components that we could use for future use cases |
Material-UI
- [x] It should be Accessibility rich ✅
- [x] It should be usable by keyboard ✅
- [ ] It should be a lightweight library (10.3 MB) ❌
- [x] It should be a well maintained library (✅ Last commit less than a day ago)
- [x] It should be highly customizable ✅
- [x] It should allow autocompletion ✅
- [x] It should allow multi-select ✅
Note: Base-UI is a more modern and lightweight version of Material-UI that also allows better customization, it’s maintained by Material-UI and could be a better option to consider
Pros | Cons |
---|---|
Material-UI is a popular library (90.3k stars on Github) | It requires installing the entire library to use the Select component |
Only 111 open issues related to Select on Github | Material-UI is not a lightweight library |
Material-UI provides a Base-UI library which provides a basic set of components that are more customizable and lightweight (2.94 MB) This library also doesn’t require to install emotion. | Base-UI is currently in beta. |
Material-UI contains other components that we could use for future use cases | Material-UI requires installing emotion, which would add more weight to the bundle size |
Comparison
Requirement | Radix | React-select | MUI |
---|---|---|---|
Accessibility | ✅ | ✅ | ✅ |
Keyboard | ✅ | ✅ | ✅ |
Lightweight | ✅ | ✅ | ❌ |
Well maintained | ⚠️ | ⚠️ | ✅ |
Customizable | ✅ | ✅ | ✅ |
Autocompletion | ⚠️ | ✅ | ✅ |
Multi-select | ✅ | ✅ | ✅ |
Candidate stats
Lib | GitHub starts | Open issues | Closed issues* | Opened issues* | Contributors |
---|---|---|---|---|---|
https://github.com/mantinedev/mantine | 22.9k | 46 | 48 | 13 | 475 |
https://github.com/shoelace-style/shoelace | 10.8k | 37 | 5 | 11 | 132 |
https://github.com/mui/material-ui | 90.3k | 1.5k | 89 | 88 | 2887 |
https://github.com/radix-ui/primitives | 13.1k | 365 | 14 | 29 | 45 |
*- for the past month
Notes
- January 2024: We decided to use Base-UI as it provides the best balance within our requirements, and the bundle size can be addressed with tree-shaking