Skip to content

Conversation

@stephannv
Copy link
Contributor

@stephannv stephannv commented Nov 29, 2024

EDIT:
After some problems with combobox dialog we are keeping the floating-ui popover. I spent 2 days trying to make it work with anchor-positioning polyfill but I got no success due to some anchor-name/position-anchor property strange behavior. Other update: We are using radio/checkbox to control combobox inputs instead of a hidden select.

Screen.Recording.2024-12-04.at.14.51.56.mov

ORIGINAL:
@cirdes asked me to build a combobox with multiselect. I started building a new component (Multiselect) inspired by how <select multiple> behaves on mobile browsers, which opens a dialog with options instead a dropdown widget. But after some discussions, Cirdes and I agreed that we should build the new component as an evolution of current combobox. We read some texts and docs and got inspiration from OpenUI combobox proposal: https://open-ui.org/components/combobox.explainer. Floating-ui was removed in favor of native dialog component.

Demo:

Combobox(multiple: true, term: "frameworks") do
  ComboboxInput(name: "multiple")

  ComboboxTrigger placeholder: "Select your framework"

  ComboboxDialog do
    ComboboxSearchInput(placeholder: "Type the framework name")

    ComboboxDatalist do
      ComboboxEmptyState { "No results" }

      ComboboxOptgroup label: "Ruby" do
        ComboboxOption(value: "rails") { "Rails" }
        ComboboxOption(value: "hanami") { "Hanami" }
      end

      ComboboxOptgroup label: "Crystal" do
        ComboboxOption(value: "lucky", selected: true) { "Lucky" }
        ComboboxOption(value: "kemal") { "Kemal" }
      end

      ComboboxOptgroup label: "Others" do
        ComboboxOption(value: "django",) { "Django" }
        ComboboxOption(value: "laravel") { "Laravel" }
      end


      ComboboxOption(value: "spring",) { "Spring" }
      ComboboxOption(value: "vraptor") { "VRaptor" }
    end
  end
end
Screen.Recording.2024-11-29.at.13.57.40.mov

@stephannv stephannv self-assigned this Nov 29, 2024

combobox:
js_packages:
- "@floating-ui/dom"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's great not to have to use any dependencies for dialogs!

class ComboboxInput < Base
def view_template
input(**attrs)
select(**attrs)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that is a great idea to use a hidden select to hold the values and submit the options

}

this.datalistOptionTargets.forEach((datalistOption) => {
const selectOption = document.createElement("option")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wondering if this would work if the combobox components were loaded using Turbo/async. Relying on JavaScript to create elements might be risky.

@stephannv stephannv requested a review from cirdes December 4, 2024 17:59

def default_attrs
{
class: "peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 accent-primary",
Copy link
Contributor

@pierry01 pierry01 Dec 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have a good syntax for classes with big strings
classes | focus-visible classes | disabled classes

Suggested change
class: "peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 accent-primary",
class: [
"peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background accent-primary",
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
"disabled:cursor-not-allowed disabled:opacity-50"
]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boa, acho que vai ajudar bastante mesmo a manter organizado.

Copy link
Contributor

@pierry01 pierry01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

insane!

Copy link
Collaborator

@cirdes cirdes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Congratulations, @stephannv! It’s incredible to see that the combobox now supports multiple items.

@stephannv stephannv marked this pull request as draft December 9, 2024 13:28
@stephannv
Copy link
Contributor Author

Converting to draft while we apply the new combobox on a real application.
To do:
[ ] Jean's suggestions
[ ] Add flip() to popover.

@sethhorsley
Copy link
Member

Wow this is great!!

@stephannv stephannv marked this pull request as ready for review December 11, 2024 15:43
@stephannv stephannv merged commit d29fac6 into main Dec 11, 2024
2 checks passed
@sethhorsley sethhorsley deleted the new_combobox branch October 6, 2025 18:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants