diff --git a/docs/app/views/docs/combobox.rb b/docs/app/views/docs/combobox.rb index 2fd1d422f..afb460361 100644 --- a/docs/app/views/docs/combobox.rb +++ b/docs/app/views/docs/combobox.rb @@ -123,6 +123,49 @@ def view_template RUBY end + render Docs::VisualCodeExample.new(title: "Required Checkbox", context: self) do + <<~RUBY + form(class: "flex flex-col gap-2 w-96") do + FormField do + FormFieldLabel { "Pick at least one" } + + Combobox term: "things" do + ComboboxTrigger placeholder: "Pick value" + + ComboboxPopover do + ComboboxSearchInput(placeholder: "Pick value or type anything") + + ComboboxList do + ComboboxEmptyState { "No result" } + + CheckboxGroup(data_required: true) do + ComboboxItem do + ComboboxCheckbox(name: "food[]", value: "apple", data: {value_missing: "Pick at least one option"}) + span { "Apple" } + end + + ComboboxItem do + ComboboxCheckbox(name: "food[]", value: "banana", data: {value_missing: "Pick at least one option"}) + span { "Banana" } + end + + ComboboxItem do + ComboboxCheckbox(name: "food[]", value: "carrot", data: {value_missing: "Pick at least one option"}) + span { "Carrot" } + end + end + end + end + end + + FormFieldError() + end + + Button(type: "submit") { "Submit" } + end + RUBY + end + render Docs::VisualCodeExample.new(title: "Disabled", context: self) do <<~RUBY div(class: "w-96") do diff --git a/gem/lib/ruby_ui/combobox/combobox_checkbox.rb b/gem/lib/ruby_ui/combobox/combobox_checkbox.rb index 141c432d6..a659ca29d 100644 --- a/gem/lib/ruby_ui/combobox/combobox_checkbox.rb +++ b/gem/lib/ruby_ui/combobox/combobox_checkbox.rb @@ -19,7 +19,14 @@ def default_attrs ], data: { ruby_ui__combobox_target: "input", - action: "ruby-ui--combobox#inputChanged" + ruby_ui__checkbox_group_target: "checkbox", + ruby_ui__form_field_target: "input", + action: %w[ + ruby-ui--combobox#inputChanged + change->ruby-ui--checkbox-group#onChange + change->ruby-ui--form-field#onInput + invalid->ruby-ui--form-field#onInvalid + ] } } end diff --git a/gem/test/ruby_ui/combobox_test.rb b/gem/test/ruby_ui/combobox_test.rb index a660b7164..800ce6c0f 100644 --- a/gem/test/ruby_ui/combobox_test.rb +++ b/gem/test/ruby_ui/combobox_test.rb @@ -92,6 +92,15 @@ def test_combobox_checkbox_renders_styled_input assert_match(/checked:bg-primary/, output) end + def test_combobox_checkbox_wires_checkbox_group_and_form_field + output = phlex { RubyUI.ComboboxCheckbox(name: "x", value: "1") } + assert_match(/data-ruby-ui--checkbox-group-target="checkbox"/, output) + assert_match(/data-ruby-ui--form-field-target="input"/, output) + assert_match(/change->ruby-ui--checkbox-group#onChange/, output) + assert_match(/change->ruby-ui--form-field#onInput/, output) + assert_match(/invalid->ruby-ui--form-field#onInvalid/, output) + end + def test_combobox_item_indicator_renders_check_svg output = phlex { RubyUI.ComboboxItemIndicator() } assert_match(/peer-checked:opacity-100/, output) diff --git a/mcp/data/registry.json b/mcp/data/registry.json index a2a49683d..53ec88270 100644 --- a/mcp/data/registry.json +++ b/mcp/data/registry.json @@ -935,7 +935,7 @@ }, { "path": "combobox_checkbox.rb", - "content": "# frozen_string_literal: true\n\nmodule RubyUI\n class ComboboxCheckbox < Base\n def view_template\n input(type: \"checkbox\", **attrs)\n end\n\n private\n\n def default_attrs\n {\n class: [\n \"peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background accent-primary\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n \"checked:bg-primary checked:text-primary-foreground\",\n \"aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:pointer-events-none\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n ],\n data: {\n ruby_ui__combobox_target: \"input\",\n action: \"ruby-ui--combobox#inputChanged\"\n }\n }\n end\n end\nend\n" + "content": "# frozen_string_literal: true\n\nmodule RubyUI\n class ComboboxCheckbox < Base\n def view_template\n input(type: \"checkbox\", **attrs)\n end\n\n private\n\n def default_attrs\n {\n class: [\n \"peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background accent-primary\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n \"checked:bg-primary checked:text-primary-foreground\",\n \"aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:pointer-events-none\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n ],\n data: {\n ruby_ui__combobox_target: \"input\",\n ruby_ui__checkbox_group_target: \"checkbox\",\n ruby_ui__form_field_target: \"input\",\n action: %w[\n ruby-ui--combobox#inputChanged\n change->ruby-ui--checkbox-group#onChange\n change->ruby-ui--form-field#onInput\n invalid->ruby-ui--form-field#onInvalid\n ]\n }\n }\n end\n end\nend\n" }, { "path": "combobox_clear_button.rb",