In my opinion it’s far worse than this: it’s not just a considerably less ambitious component, it’s a component currently completely unfit for any purpose. Most significantly, it’s inaccessible due to semantic abuse and missing ARIA support (role=listbox, aria-controls, aria-expanded, aria-selected, &c. &c.). Even as a sighted user that doesn’t need to use accessibility tech (AT; screen readers are the best known example), I would hate to encounter a page using this, because it misses valuable functionality like type-ahead. Users that depend on AT will be left high and dry, presented with just a read-only text box and no idea what to do with it.
All up, it’s just like so many others, a bad reimplementation of half of what the browser already provides with <select>. About the only thing it adds to that is support for an image per option, and perhaps some more exotic styling aspects (which you hopefully don’t want anyway).
Mind you, I do find Headless UI generally bloated, mostly just suffering from being overly flexible, and it does end up with a moderate amount of code bloat attributable to the particular frameworks’ designs (though not as much as some I’ve seen), but the comparison is just unreasonable. If they think it’s fair to say “With React: 2.5k lines; with Nue: 200 lines”, then I respond: “With HTML: 0 lines”, and insist that <select> is better than the result of those 200 lines.
There are more problems with it, too, whereas I suppose Headless UI will be a pretty high-quality implementation. Examples of problems I found immediately, without having tried to actually run it, but which I presume Headless UI will be free of: it uses <menu> for the options and wraps each option’s label with <strong>, which are both semantic sins; some of the code sharing with combo boxes leads to obvious minor inefficiency (filtering, which can’t actually happen); Escape detection happens on keyup instead of keydown; clicking outside the listbox popup won’t close it if the target or an ancestor matches .open, which is very plausible, e.g. when within a modal dialog (and because it’s ad hoc, it’s certain to interact badly with things like clicking outside modals—any concept of potentially-nestable modality needs to be managed more than that, in one of a few ways but I’ve already rambled enough); after pressing Escape to close the popup, pressing Tab will reopen it as well as moving to the next focusable.
Hopefully the problems with this will be sorted out, but at present I think it’d be best to just remove the comparison, because it portrays a false picture, and suggests that the listbox is ready for use, whereas I hope that the author would agree it’s not.
Totally agree with "HTML: 0 lines" is the best pick in most, if not all situations. For example the Headless UI radio group component [1], can be implemented with just HTML and CSS — and they made it a huge JS component.
All up, it’s just like so many others, a bad reimplementation of half of what the browser already provides with <select>. About the only thing it adds to that is support for an image per option, and perhaps some more exotic styling aspects (which you hopefully don’t want anyway).
Mind you, I do find Headless UI generally bloated, mostly just suffering from being overly flexible, and it does end up with a moderate amount of code bloat attributable to the particular frameworks’ designs (though not as much as some I’ve seen), but the comparison is just unreasonable. If they think it’s fair to say “With React: 2.5k lines; with Nue: 200 lines”, then I respond: “With HTML: 0 lines”, and insist that <select> is better than the result of those 200 lines.
There are more problems with it, too, whereas I suppose Headless UI will be a pretty high-quality implementation. Examples of problems I found immediately, without having tried to actually run it, but which I presume Headless UI will be free of: it uses <menu> for the options and wraps each option’s label with <strong>, which are both semantic sins; some of the code sharing with combo boxes leads to obvious minor inefficiency (filtering, which can’t actually happen); Escape detection happens on keyup instead of keydown; clicking outside the listbox popup won’t close it if the target or an ancestor matches .open, which is very plausible, e.g. when within a modal dialog (and because it’s ad hoc, it’s certain to interact badly with things like clicking outside modals—any concept of potentially-nestable modality needs to be managed more than that, in one of a few ways but I’ve already rambled enough); after pressing Escape to close the popup, pressing Tab will reopen it as well as moving to the next focusable.
Hopefully the problems with this will be sorted out, but at present I think it’d be best to just remove the comparison, because it portrays a false picture, and suggests that the listbox is ready for use, whereas I hope that the author would agree it’s not.