unovue / radix-vue

Vue port of Radix UI Primitives. An open-source UI component library for building high-quality, accessible design systems and web apps.
https://radix-vue.com
MIT License
3.7k stars 230 forks source link

[Feature]: Unify Select and Combobox by adding "multiple" selection to Select #716

Closed maelp closed 2 weeks ago

maelp commented 8 months ago

Describe the feature

It seems weird that Combobox allows multiple selection but not Select, could we add the same feature there?

Additional information

kilobyte2007 commented 7 months ago

Why is this closed? Seems like a reasonable feature request and #696 doesn't really solve it.

zernonia commented 2 weeks ago

Released on reka-ui@latest. Now Select supports multiple modelValue 😁

maelp commented 2 weeks ago

@zernonia really cool! are you moving shadcn-vue to reka-ui ? Will it be also possible to "unify" Dialog and Alert? They are mostly the same except one can be closed with "esc" and clicking outside and not the other, so sometimes we want to add features "on top of them" and let the user choose whether he wants it "modal" or not, see https://github.com/unovue/radix-vue/issues/720

cyyynthia commented 2 weeks ago

The distinction between the AlertDialog and the Dialog is very important, as they serve very different purposes (even though based upon the same primitive UI object). Unifying them is not a good idea and both should be used when appropriate.

Specifically, AlertDialog are specifically for interrupting the user about something important that requires a clear answer and cannot be dismissed (as this would mean no answer). The WAI-ARIA Authoring Practices Guide makes a clear distinction between the two and states that assistive technologies may treat alert dialog differently (e.g. by playing a specific sound)

See the WAI-ARIA APG Dialog (Modal) Pattern and Alert and Message Dialogs Pattern, and the WAI-ARIA 1.2 dialog and alertdialog definition.

Note that it is trivial to reproduce the AlertDialog from the Dialog primitive itself: see AlertDialogRoot.vue and AlertDialogContent.vue.

maelp commented 2 weeks ago

I understand they serve different purposes but it doesn't mean that switching from one to the other in code should be complicated...

For instance if I want to build a ShowSomeModal component, and then I want to let the library end user decide whether this should be shown has a Dialog or an AlertDialog, currently I have to develop my component twice (although the code is close to identical, just the element names change), which creates duplicate code

If there was just a property useAsModal in the code that I could switch to on/off to use the proper ARIA and everything, it would be much easier to share code

Again: my point is not that there should be a unique way to display information to the user, it's important to keep the distinction, but it should be just a flag/toggle/field in the element rather than a completely different set of tags, which forces libraries to duplicate their code in a "Alert" version and an "AlertDialog" version when they want to let the end user choose which one he wants to use

For instance, imagine you want to build and "auto-dialog" feature looking a bit like the "auto-form" of shadcn, where you can specify to the end-user a few inputs to be filled, and it generates a dialog/alert for you and gives you back the value (or undefined if it was dismissed). Right now you have to duplicate all the code to have an Alert version and an AlertDialog version, although you would want from a user perspective to be able to do const values = await showMyForm(mode="alert")

cyyynthia commented 2 weeks ago

As I pointed out, it is trivial to make an AlertDialog from the Dialog primitive; you can apply the properties on your own in your implementation to achieve the desired result; AlertDialog is mostly a convenience wrapper over the actual Dialog primitive with little to no behavior on top that is trivial to "build at home" should you want to do so.

It remains two very distinct elements that I'm strongly unconvinced is relevant to merge/unify together as they serve very different purposes (FWIW, the difference is not "just" the modal-ness: Dialog are modal by default). Keeping them separate is a strong indicator from the library that they should not be treated as equivalent which is a good way to prevent misuse at the conception layer.

Higher level UI libraries may also elect to put content restrictions by design on AlertDialog, such as encouraging the use of concise messages and limit the amount of input required from the user to the strict necessary (generally none besides the action buttons, eventually a text field for delete operations, or a checkbox; but not a full form). This abstraction can then be used by higher level tools such as an "auto-modal" tool.

Chances are, if duplicated code exists, unless you have a very strict definition of "duplicate code" I'm more inclined to think there is possibly missed reuse opportunities (such as using a composable), or an insufficient hierarchy of components (an auto-modal is very high level; it seems relevant to me to make the component rely on lower level components without dropping as low as the primitive Radix-Vue/Reka components. Note that this is what shadcn-vue AutoForm does, along with leveraging Vue dynamic components (docs)