Fortura/apps/www/content/docs/headless/disclosure.mdx
2025-08-20 04:12:49 -06:00

99 lines
2.6 KiB
Plaintext

---
title: Disclosure
description: A simple, accessible foundation for building custom UIs that show and hide content, like togglable accordion panels.
author:
name: imskyleen
url: https://github.com/imskyleen
---
<ComponentPreview name="headless-disclosure-demo" />
## Installation
<ComponentInstallation name="headless-disclosure" />
## Usage
```tsx
<Disclosure>
<DisclosureButton>Disclosure Button</DisclosureButton>
<DisclosurePanel>Disclosure Panel</DisclosurePanel>
</Disclosure>
```
## Props
<div className="flex flex-row gap-x-3">
<ExternalLink href="https://headlessui.com/react/disclosure" text="Docs" />
<ExternalLink
href="https://headlessui.com/react/disclosure#component-api"
text="API Reference"
/>
</div>
### Animate UI props
#### DisclosurePanel
<TypeTable
type={{
transition: {
description: 'The transition of the disclosure panel',
type: 'Transition',
required: false,
default: "{ type: 'spring', stiffness: 150, damping: 22 }",
},
}}
/>
## Don't delete from the DOM
The choice made is the same as Headless UI, i.e. to remove the element from the DOM for accessibility and performance reasons. However, this may pose a problem for SEO. If you want your Disclosure content to be taken into account by Google, please **replace the DisclosurePanel component with**:
```tsx title="components/animate-ui/headless-disclosure.tsx"
const DisclosurePanel = React.forwardRef<HTMLDivElement, DisclosurePanelProps>(
(
{
className,
children,
transition = { type: 'spring', stiffness: 150, damping: 17 },
as = React.Fragment,
...props
},
ref,
) => {
const { isOpen } = useDisclosure();
return (
<DisclosurePanelPrimitive static as={as} {...props}>
{(bag) => (
<motion.div
initial={false}
animate={
isOpen
? { height: 'auto', opacity: 1, '--mask-stop': '100%' }
: { height: 0, opacity: 0, '--mask-stop': '0%' }
}
transition={transition}
style={{
maskImage:
'linear-gradient(black var(--mask-stop), transparent var(--mask-stop))',
WebkitMaskImage:
'linear-gradient(black var(--mask-stop), transparent var(--mask-stop))',
}}
className={cn('overflow-hidden', className)}
ref={ref}
>
{typeof children === 'function' ? children(bag) : children}
</motion.div>
)}
</DisclosurePanelPrimitive>
);
},
);
```
## Credits
- We use [Headless UI](https://headlessui.com/react/disclosure) for the disclosure component.