37 lines
1.1 KiB
TypeScript
37 lines
1.1 KiB
TypeScript
import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';
|
|
import { cn } from '@/lib/utils';
|
|
|
|
export const DISCLOSURE_ENTER_MS = 240;
|
|
export const DISCLOSURE_EXIT_MS = 180;
|
|
|
|
export interface DisclosureContentProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
open: boolean;
|
|
children: ReactNode;
|
|
innerClassName?: string;
|
|
}
|
|
|
|
/**
|
|
* A shared, interruptible-feeling disclosure surface. The content stays in
|
|
* the tree so reversing a toggle can retarget the same transition instead of
|
|
* snapping from a newly mounted node.
|
|
*/
|
|
export const DisclosureContent = forwardRef<HTMLDivElement, DisclosureContentProps>(
|
|
function DisclosureContent({ open, children, className, innerClassName, ...props }, ref) {
|
|
return (
|
|
<div
|
|
{...props}
|
|
ref={ref}
|
|
aria-hidden={!open || undefined}
|
|
data-state={open ? 'open' : 'closed'}
|
|
className={cn('codex-disclosure', className)}
|
|
>
|
|
<div className={cn('codex-disclosure-inner', innerClassName)}>
|
|
{children}
|
|
</div>
|
|
</div>
|
|
);
|
|
},
|
|
);
|
|
|
|
DisclosureContent.displayName = 'DisclosureContent';
|