From 43d6c10c2f6cb84354f2b2c65ddc4c80dcd74b3d Mon Sep 17 00:00:00 2001 From: lerte smith Date: Tue, 12 Dec 2023 01:09:21 +0800 Subject: [PATCH] :feat: Accordion asChild --- .../AccordionContent/AccordionContent.tsx | 74 +++++++++++-------- .../AccordionHeader/AccordionHeader.tsx | 4 +- 2 files changed, 44 insertions(+), 34 deletions(-) diff --git a/packages/actify/src/components/Accordion/AccordionContent/AccordionContent.tsx b/packages/actify/src/components/Accordion/AccordionContent/AccordionContent.tsx index 97074106..43185d24 100644 --- a/packages/actify/src/components/Accordion/AccordionContent/AccordionContent.tsx +++ b/packages/actify/src/components/Accordion/AccordionContent/AccordionContent.tsx @@ -3,17 +3,14 @@ import { tv, VariantProps } from 'tailwind-variants' import { AccordionContext } from '../AccordionContext' -import React, { - useContext, - forwardRef, - cloneElement, - isValidElement -} from 'react' +import React, { useMemo, useContext, forwardRef } from 'react' + +import { Slot } from '@actify/Slot' const variants = tv({ base: 'transition-all duration-300 ease-in-out grid', variants: { - open: { + active: { true: 'grid-rows-[1fr]', false: 'grid-rows-[0fr]', undefined: 'grid-rows-[0fr]' @@ -21,39 +18,52 @@ const variants = tv({ } }) -export interface AccordionContentProps - extends VariantProps, - React.HTMLAttributes { +export type AccordionContentProps = { index?: number asChild?: boolean - children: React.ReactNode -} + children?: ((_?: any) => React.ReactNode) | React.ReactNode +} & VariantProps & + React.HTMLAttributes const AccordionContent: React.FC = forwardRef( (props, ref?: React.Ref) => { - const { index, style, className, asChild, children, ...rest } = props + const { index, style, className, asChild, ...rest } = props const { open } = useContext(AccordionContext) - // `asChild` allows the user to pass any element as the content - if (asChild && isValidElement(children)) { - return cloneElement(children, { - ref, - ...rest, - ...children.props, - className: variants({ className: children.props.className }) - }) - } + const active = useMemo(() => { + if (open !== undefined) { + return open[index as number] + } + }, [open, index]) - return ( -
-

{children}

-
- ) + if (asChild) { + return ( + + {typeof rest.children === 'function' + ? rest.children({ active }) + : rest.children} + + ) + } else { + return ( +
+

{rest.children}

+
+ ) + } } ) diff --git a/packages/actify/src/components/Accordion/AccordionHeader/AccordionHeader.tsx b/packages/actify/src/components/Accordion/AccordionHeader/AccordionHeader.tsx index c9406a85..6c0b1fdb 100644 --- a/packages/actify/src/components/Accordion/AccordionHeader/AccordionHeader.tsx +++ b/packages/actify/src/components/Accordion/AccordionHeader/AccordionHeader.tsx @@ -22,6 +22,7 @@ const variants = tv({ export type AccordionHeaderProps = { index?: number asChild?: boolean + children?: ((_?: any) => React.ReactNode) | React.ReactNode } & React.HTMLAttributes const AccordionHeader: React.FC = forwardRef( @@ -58,8 +59,7 @@ const AccordionHeader: React.FC = forwardRef( className={variants({ className })} > {typeof rest.children === 'function' - ? // @ts-expect-error - rest.children({ active }) + ? rest.children({ active }) : rest.children} )