feat(radix): bring checkbox_group/checkbox_cards to prop parity with radio_group/radio_cards

Merged
ST
6d ago
+251-2

All Submissions:

  • Have you followed the guidelines stated in CONTRIBUTING.md file?
  • Have you checked to ensure there aren't any other open Pull Requests for the desired changed?

Type of change

  • New feature (non-breaking change which adds functionality)

New Feature Submission:

  • Does your submission pass the tests?
  • Have you linted your code locally prior to submission?

Closes #7343

What

Adds the props of the Radix CheckboxGroupPrimitive that checkbox_group and checkbox_cards did not declare. radio_group and radio_cards already declare the same props for their own primitive.

Why

CheckboxGroup.Root and CheckboxCards.Root in @radix-ui/themes both wrap CheckboxGroupPrimitive.Root. Without value and on_value_change, neither component can be controlled from state. checkbox_cards.item had no props, so a card could not carry a value.

Reflex does not reject an undeclared prop. It renders it as a style, so rx.checkbox_group.root(..., disabled=True) gave css:({ ["disabled"] : true }) and the group stayed enabled.

How

  • checkbox_group.root: adds value, disabled, required, orientation, dir, loop, on_value_change.
  • checkbox_group.item: adds required.
  • checkbox_cards.root: adds default_value, value, name, disabled, required, orientation, dir, loop, on_value_change. Sets _is_form_control = True, like checkbox_group, radio_group and radio_cards, so a TypedDict on_submit handler sees its name.
  • checkbox_cards.item: adds value, disabled, required.

as_child is not added. Radix Themes removes it from both roots.

A root required makes Radix require every item, not one item. The field docs say this.

A form still submits only the last value of a repeated name, such as a checkbox group. #7386 fixes that (#7342); this PR does not change form submission.

Tests

tests/units/reflex_components_radix/themes/components/test_checkbox_group.py and test_checkbox_cards.py:

  • Every new prop renders, including the exact value binding and an onValueChange that passes the checked list to the handler.
  • checkbox_cards.root(name=...) satisfies a TypedDict on_submit field of that name, and a different name raises EventHandlerValueError. This test fails without _is_form_control.

Each prop was also checked in a running app: controlled values, server-side reset, root and item disabled, dir/orientation/loop keyboard navigation, and form submission with required.