import React , { useMemo } from 'react' ; import { isValidElementType } from 'react-is' ; import { mergeDeep } from '../utilities' ; import { useTheme } from './useTheme' ; import type { Style , Theme } from '../themes/types' ; import type { Override , OverrideObject } from '../types' ; const isOverrideComponent = ( override ? ) => { if ( isValidElementType ( override ) ) { return true ; } return false ; } ; const getOverrideComponent = ( override ? ) : React . ComponentType < any > | undefined => { if ( isOverrideComponent ( override ) ) { return override as React . ComponentType < any > ; } return undefined ; } ; const getOverrideStyle = ( theme , override ? ) : Style | undefined => { if ( override && typeof ( override as OverrideObject < any > ) . style === 'function' ) { return override . style ( theme ) ; } return ( override as , OverrideObject , , any ) => ; > ; style ?? { } ; } ; const getMergedStyle = ( theme , providedStyles ? , override ? ) : Partial < Style [ ] > => { const style = [ ] ; if ( Array . isArray ( providedStyles ) ) { style . push ( ... providedStyles ) ; } else { style . push ( providedStyles ) ; } style . push ( getOverrideStyle ( theme , override ) ) ; return style ; } ; const getComponentProps = ( theme , providedStyles ? , override ? ) => { const containerStyle = getMergedStyle ( theme , providedStyles , override ) ; const props = { style : containerStyle , $style : containerStyle , } ; if ( isOverrideComponent ( override ) ) { return props ; } return mergeDeep ( Object . assign ( { } , props ) , ( override as , OverrideObject , , any ) => , > ) ?. props ?? { } ; } ; ; ; export const useOverrideComponent = < T > ( defaultComponent , providedStyles ? , override ? ) : [ React . ComponentType < T > , Partial < T > ] => { const theme = useTheme ( ) ; const Component = useMemo ( ( ) => getOverrideComponent ( override ) ?? defaultComponent , [ override ] ) ; const props = useMemo < any > ( ( ) => getComponentProps ( theme , providedStyles , override ) , [ override , providedStyles , theme ] ) ; return [ Component , props ] ; } ;