Closed thatsamsonkid closed 8 months ago
Let me revise this after seeing how combobox was made. Can probably reuse parts of that to build a select.
Really like this proposal! I'm also open to reimplementing the Command Dialog in a similar way instead of relying on a 3rd party library like we do now 👀
Ok yea awesome we can definitely take a look at that after the select. A lot of the same elements should probably be able to be reused between these 2
I think this is good if you want to take a first pass at implementing this!
Awesome yea meant to mention I started already, hoping to have an initial PR for this in next day or two!
As this i merged now could this also be released into the cli? Already waiting for this component but the cli isn't showing it in the latest version.
@badsgahhl I'll try to get a release out with this ASAP
Which scope/s are relevant/related to the feature request?
select
Information
Select
Deps
brn
API (Proposed)
1. brn-select - (Component)
Will be the primary parent component and will also be the point of contact for interfacing with the the underlying ngControl and other "input/form control" attributes that may need to be passed to the component. Radix and Shadcn have placeholder set on the select.value component but I think it's cleaner and more predictable to pass these things to the parent but I dont know would definitely like to hear from others.
Proposed Inputs
We can add anything else. I know looking at the mat-select they also include some eventEmitters we can also implement some of those if we think they would be useful. Maybe the emitting the open and close of select overlay would be useful as well.
2. brn-select-trigger - (Component)
Holds the button and will trigger open and closing the cdkOverlay.
Note: Reason why I believe we may need to use cdkOverlay over menu is I found cdkMenu to be a little limited especially when it came to allowing multi-selection. Maybe this something that can be changed I didnt find a way to keep it open after making a selection. I think mainly an issue with trying to use cdkMenuItem and cdkListboxOption at same time.
4. brn-select-value - (Component)
This component will simply display the current value for the select component. If no value we will display a provided placeholder text. User can also optionally exclude brn-select-value and instead pass there only template or html and can render the value using the formcontrol's value with either ngModel or reactive form group
5. brn-select-content (Directive)
Has cdkListbox as a host directive. Will listen for Listbox value changes and publish the value updates. Will also be responsible for setting additional attributes tot he cdkListbox such as a multiple and setting the focus on the cdkListbox when the overlay is opened. As well as setting aria label id's controlledBy and LabelledBy
6. brn-select-option (component)
CdkOption as a host directive, so this is a component primarily for holding the svg checkbox to show hide when an option is selected (Reason for component instead of directive). Not sure if you would want this to be more flexible in terms of being able to provide something custom
7. brn-select-separator (directive)
Unsure of this one, this may just be a helm since I dont believe there is any physical element or divider rendered just spacing from what I can tell
8. brn-select-scroll-up (directive)
Can probably just have a a mouseenter hostbinding to trigger and change the option focus on cdkList
9. brn-select-scroll-down (directive)
same as number 7
10. brn-select-service (Service)
With most of these component being passed as content children, much easier to manage all the state in a service. We can use a signal object like shown below.
We can have accessor's like this. Took inspiration for this from something I saw Joshua Morony do recently when using signals and some light state management. We can do this differently if needed just thought it would be interesting to try.
Reference: https://youtu.be/ol671CJnNjY?si=o5hYEJ_8dRzrvWJS
We also need a subject to emit changes from cdkListbox to the service and update the state in the service. All other components will just read the value from state signal.
hlm
We can have one for each brn component/directive to add associated styles with an addition to these
1. hlm-select-group (directive)
2. hlm-select-label (directive)
Aria
Label - User can pass a label within select parent and we can manually assign an id if one is not provided to the label element. If no label element then select component can generate one an invisible one based on placeholder. Can correct me but i believe its usually best practice to have some sort of label
we can generate id's for the select trigger and select content elements and provide controls and controlledBy + LabelledBy respectively.
Aria expanded on select-trigger and role of combobox
cdkList is taking care of all the Listbox ADA and keyboard navigation so no need to worry much about that.
Radix
Source
https://www.radix-ui.com/primitives/docs/components/select
Shadcn
Source
https://ui.shadcn.com/docs/components/select
Other Considerations
Since we are not making use of cdkMenu in this proposal and are instead using cdkOverlay directly we may need to handle some issue with opening up or down depending on space. Can probably just look at mat-select for an idea.
Describe any alternatives/workarounds you're currently using
No response
I would be willing to submit a PR to fix this issue