radix-ui / primitives

Radix Primitives is an open-source UI component library for building high-quality, accessible design systems and web apps. Maintained by @workos.
https://radix-ui.com/primitives
MIT License
15.91k stars 832 forks source link

[Collapsible][Accordion] Making collapsed content accessible with `hidden=until-found` #1660

Open yumin-chen opened 2 years ago

yumin-chen commented 2 years ago

Feature request

Making collapsed content accessible with hidden=until-found attribute.

Overview

As a new browser feature the attribute hidden=until-found should be used to indicate the content is hidden but searchable

https://chromestatus.com/feature/5400510406328320

Examples in other libraries

https://developer.chrome.com/articles/hidden-until-found/

Who does this impact? Who is this for?

SEO users -- Without this, SEO is impacted as the hidden content is not searchable.

Additional context

benoitgrelard commented 2 years ago

Hey @yumin-chen, yes that is a great suggestion we have discussed internally already. This is dependent on having options to keep the content mounted though (as discussed in #1155 or #855). I'll mark it as an enhancement.

Thanks!

valentinogagliardi commented 1 year ago

Would be super useful. Any news on this?

benoitgrelard commented 1 year ago

Nothing yet on that front, there's also a few dependencies as highlighted above.

pedrosousa13 commented 8 months ago

I managed to fix this issue with forceMount=true. Somehow the element height --radix-collapsible-content-height property gets lost when the elements are force mounted.

By using useResizeObserver on the Accordion.Content I managed to check for it's height in the dom and add that css variable on mount only once and let the accordion logic take over.

Example solution:

// _accordion.module.scss
 &[data-state='closed'] {
    height: 0;
  }
...
const [currentHeight, setCurrentHeight] = useState(0);

const ref = useRef(null);

const { height } = useElementSize(ref);

<AccordionPrimitive.Content
  ref={ref}
  className={classes}
  forceMount={true}
  onAnimationEnd={() => {
    height > 0 && !currentHeight && setCurrentHeight(Math.ceil(height));
  }}
  style={
    currentHeight > 0
      ? ({
          '--radix-collapsible-content-height': `${currentHeight}px`,
        } as CSSProperties)
      : {}
  }
  >
...