primitives icon indicating copy to clipboard operation
primitives copied to clipboard

How can I read component internal state

Open michaltaberski opened this issue 1 year ago • 1 comments

Hi,

I wonder what's the desired pattern to read the internal state of the primitives. It's possible to style components conditionally because of the state is exposed to DOM through data-attributes.

That's cool, but what is the pattern for following scenario:

Preconditions

  1. Build radio cards
  2. Option can have different look for "checked" and "unchecked" state. eg:
// not a real example but it represents the idea
options = [{ selectedLabel: 'Select me', unselectedLabel: 'I am not selected' }]

I would look for something to be able to do:

const isSelected = // how to get this value?
return <>{isSelected ? option.selectedLabel : option.unselectedLabel}</>

So far I couldn't find a better approach than a hack component:

const RenderProps = forwardRef(({ children, ...props }, ref) => {
  return children({ ...props, ref });
});

// usage
<RadixRadioGroup.Item value={value} asChild>
  <RenderProps>
    {({ 'aria-checked': isSelected }) => (
      <>{isSelected ? option.selectedLabel : option.unselectedLabel}</>
    )}
  </RenderProps>
<RadixRadioGroup.Item/>

However this is obvious hack - surly I am not getting something from the library philosophy.

michaltaberski avatar May 16 '24 13:05 michaltaberski

you can use the parent's data attribute to style the child via css only. as I usually use tailwind I would use the group modifier

joaom00 avatar May 18 '24 22:05 joaom00

You can't "read" the internal state of the components, but you can create your own controlled components and use that state as the source of truth. In the case of radio group items, you'd also need to pass down the current value from root to the items via React context.

For example, see the Segmented Control component in Radix Themes which is built on top of the Toggle Group primitive. Instead of "reading" the primitive state, it bases its state on the value props and passes them down to the primitive.

https://github.com/radix-ui/themes/blob/616a66fb37d8d92e8ee5b02abf798ab405ae247e/packages/radix-ui-themes/src/components/segmented-control.tsx

vladmoroz avatar Jun 05 '24 07:06 vladmoroz