import * as React from 'react' ; import { composeRefs } from '@radix-ui/react-compose-refs' ; interface SlotProps extends React . HTMLAttributes < HTMLElement > { children ? : React . ReactNode ; } const Slot = React . forwardRef < HTMLElement , SlotProps > ( ( props , forwardedRef ) => { const { children , ... slotProps } = props ; if ( React . Children . toArray ( children ) . some ( isSlottable ) ) { return ( < > { React . Children . map ( children , ( child ) => { return isSlottable ( child ) ? ( < SlotClone { ... slotProps } ref = { forwardedRef } > { child . props . children } < /SlotClone>) : (child); } ) } < />); } return ( < SlotClone { ... slotProps } ref = { forwardedRef } > { children } < /SlotClone>); } ) ; Slot . displayName = 'Slot' ; interface SlotCloneProps { children : React . ReactNode ; } const SlotClone = React . forwardRef < any , SlotCloneProps > ( ( props , forwardedRef ) => { const { children , ... slotProps } = props ; if ( React . isValidElement ( children ) ) { return React . cloneElement ( children , { ... mergeProps ( slotProps , children . props ) , ref : composeRefs ( forwardedRef , ( children as any ) . ref ) , } ) ; } return React . Children . count ( children ) > 1 ? React . Children . only ( null ) : null ; } ) ; SlotClone . displayName = 'SlotClone' ; const Slottable = ( { children } ) => { return < > { children } < />; } ; type AnyProps = Record < string , any > ; function isSlottable ( child ) { return React . isValidElement ( child ) && child . type === Slottable ; } function mergeProps ( slotProps , childProps ) { const overrideProps = { ... childProps } ; for ( const propName in childProps ) { const slotPropValue = slotProps [ propName ] ; const childPropValue = childProps [ propName ] ; const isHandler = /^on[A-Z]/ . test ( propName ) ; if ( isHandler ) { overrideProps [ propName ] = ( ... args ) => { childPropValue ?. ( ... args ) ; slotPropValue ?. ( ... args ) ; } ; } else if ( propName === 'style' ) { overrideProps [ propName ] = { ... slotPropValue , ... childPropValue } ; } else if ( propName === 'className' ) { overrideProps [ propName ] = [ slotPropValue , childPropValue ] . filter ( Boolean ) . join ( ' ' ) ; } } return { ... slotProps , ... overrideProps } ; } const Root = Slot ; export { Slot , Slottable , Root , } ; export type { SlotProps } ;