@@ -10,6 +10,9 @@ import React, {
1010import PropTypes from 'prop-types'
1111import classNames from 'classnames'
1212
13+ import type { CNavGroupProps } from '../nav/CNavGroup'
14+ import type { CNavLinkProps } from '../nav/CNavLink'
15+ import type { CNavItemProps } from '../nav/CNavItem'
1316import { PolymorphicRefForwardingComponent } from '../../helpers'
1417
1518export interface CSidebarNavProps extends HTMLAttributes < HTMLUListElement > {
@@ -32,35 +35,37 @@ interface ContextProps {
3235
3336export const CNavContext = createContext ( { } as ContextProps )
3437
38+ const isNavElement = (
39+ child : ReactNode
40+ ) : child is ReactElement < CNavGroupProps | CNavLinkProps | CNavItemProps > => {
41+ if ( ! React . isValidElement ( child ) ) return false
42+ const type = child . type as { displayName ?: string }
43+ return (
44+ type . displayName === 'CNavGroup' ||
45+ type . displayName === 'CNavLink' ||
46+ type . displayName === 'CNavItem'
47+ )
48+ }
49+
3550const recursiveClone = ( children : ReactNode , id ?: string , updateId ?: boolean ) : ReactNode => {
36- return React . Children . map ( children , ( child : ReactNode , index : number ) => {
37- if (
38- ! React . isValidElement ( child ) ||
39- // @ts -expect-error the `children` exist in each component. TODO: resolve
40- ( child . type . displayName !== 'CNavGroup' &&
41- // @ts -expect-error the `children` exist in each component. TODO: resolve
42- child . type . displayName !== 'CNavLink' &&
43- // @ts -expect-error the `children` exist in each component. TODO: resolve
44- child . type . displayName !== 'CNavItem' )
45- ) {
51+ return React . Children . map ( children , ( child , index ) => {
52+ if ( ! isNavElement ( child ) ) {
4653 return child
4754 }
4855
4956 const _id = id ? ( updateId ? `${ id } .${ index } ` : `${ id } ` ) : `${ index } `
5057
51- if ( child . props && child . props . children ) {
52- return React . cloneElement ( child as ReactElement < any > , {
58+ if ( child . props . children ) {
59+ const type = child . type as { displayName ?: string }
60+ const shouldUpdateId = type . displayName !== 'CNavItem'
61+
62+ return React . cloneElement ( child , {
5363 idx : _id ,
54- children : recursiveClone (
55- child . props . children ,
56- _id ,
57- // @ts -expect-error the `displayName` exist in each component. TODO: resolve
58- child . type . displayName === 'CNavItem' ? false : true ,
59- ) ,
64+ children : recursiveClone ( child . props . children , _id , shouldUpdateId ) ,
6065 } )
6166 }
6267
63- return React . cloneElement ( child as ReactElement < any > , {
68+ return React . cloneElement ( child , {
6469 idx : _id ,
6570 } )
6671 } )
0 commit comments