Skip to content

Commit f451d62

Browse files
committed
refactor: improve typings
1 parent 57b0f90 commit f451d62

File tree

8 files changed

+50
-44
lines changed

8 files changed

+50
-44
lines changed

packages/coreui-react/src/components/carousel/CCarouselItem.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export const CCarouselItem = forwardRef<HTMLDivElement, CCarouselItemProps>(
2929
const carouselItemRef = useRef<HTMLDivElement>(null)
3030
const forkedRef = useForkedRef(ref, carouselItemRef)
3131

32-
const prevActive = useRef<boolean>()
32+
const prevActive = useRef<boolean>(undefined)
3333
const [directionClassName, setDirectionClassName] = useState<string>()
3434
const [orderClassName, setOrderClassName] = useState<string>()
3535
const [activeClassName, setActiveClassName] = useState(active && 'active')
@@ -101,15 +101,15 @@ export const CCarouselItem = forwardRef<HTMLDivElement, CCarouselItemProps>(
101101
activeClassName,
102102
directionClassName,
103103
orderClassName,
104-
className,
104+
className
105105
)}
106106
ref={forkedRef}
107107
{...rest}
108108
>
109109
{children}
110110
</div>
111111
)
112-
},
112+
}
113113
)
114114

115115
CCarouselItem.propTypes = {

packages/coreui-react/src/components/dropdown/CDropdown.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ export interface CDropdownProps extends HTMLAttributes<HTMLDivElement | HTMLLIEl
171171

172172
interface ContextProps extends CDropdownProps {
173173
// eslint-disable-next-line @typescript-eslint/no-explicit-any
174-
dropdownToggleRef: RefObject<any | undefined>
175-
dropdownMenuRef: RefObject<HTMLDivElement | HTMLUListElement | undefined>
174+
dropdownToggleRef: RefObject<any | null>
175+
dropdownMenuRef: RefObject<HTMLDivElement | HTMLUListElement | null>
176176
setVisible: React.Dispatch<React.SetStateAction<boolean | undefined>>
177177
portal: boolean
178178
}

packages/coreui-react/src/components/sidebar/CSidebarNav.tsx

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ import React, {
1010
import PropTypes from 'prop-types'
1111
import 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'
1316
import { PolymorphicRefForwardingComponent } from '../../helpers'
1417

1518
export interface CSidebarNavProps extends HTMLAttributes<HTMLUListElement> {
@@ -32,35 +35,37 @@ interface ContextProps {
3235

3336
export 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+
3550
const 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
})

packages/coreui-react/src/components/tabs/CTabPane.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export interface CTabPaneProps extends HTMLAttributes<HTMLDivElement> {
3232

3333
export const CTabPane = forwardRef<HTMLDivElement, CTabPaneProps>(
3434
({ children, className, onHide, onShow, transition = true, visible, ...rest }, ref) => {
35-
const tabPaneRef = useRef()
35+
const tabPaneRef = useRef(null)
3636
const forkedRef = useForkedRef(ref, tabPaneRef)
3737

3838
return (

packages/coreui-react/src/components/tabs/CTabPanel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export const CTabPanel = forwardRef<HTMLDivElement, CTabPanelProps>(
3838
({ children, className, itemKey, onHide, onShow, transition = true, visible, ...rest }, ref) => {
3939
const { _activeItemKey, id } = useContext(TabsContext)
4040

41-
const tabPaneRef = useRef()
41+
const tabPaneRef = useRef(null)
4242
const forkedRef = useForkedRef(ref, tabPaneRef)
4343

4444
const [_visible, setVisible] = useState(visible || _activeItemKey === itemKey)

packages/coreui-react/src/components/toast/CToast.tsx

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,12 @@ export const CToast = forwardRef<HTMLDivElement, CToastProps>(
8282
onShow,
8383
...rest
8484
},
85-
ref,
85+
ref
8686
) => {
87-
const toastRef = useRef()
87+
const toastRef = useRef(null)
8888
const forkedRef = useForkedRef(ref, toastRef)
8989
const [_visible, setVisible] = useState(false)
90-
const timeout = useRef<number>()
90+
const timeout = useRef<number>(undefined)
9191

9292
useEffect(() => {
9393
setVisible(visible)
@@ -135,7 +135,7 @@ export const CToast = forwardRef<HTMLDivElement, CToastProps>(
135135
'show showing': state === 'entering' || state === 'exiting',
136136
show: state === 'entered',
137137
},
138-
className,
138+
className
139139
)}
140140
aria-live="assertive"
141141
aria-atomic="true"
@@ -152,7 +152,7 @@ export const CToast = forwardRef<HTMLDivElement, CToastProps>(
152152
)}
153153
</Transition>
154154
)
155-
},
155+
}
156156
)
157157

158158
CToast.propTypes = {
@@ -163,10 +163,7 @@ CToast.propTypes = {
163163
color: colorPropType,
164164
delay: PropTypes.number,
165165
index: PropTypes.number,
166-
innerKey: PropTypes.oneOfType([
167-
PropTypes.number,
168-
PropTypes.string
169-
]),
166+
innerKey: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
170167
onClose: PropTypes.func,
171168
onShow: PropTypes.func,
172169
visible: PropTypes.bool,

packages/coreui-react/src/components/toast/CToaster.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import PropTypes from 'prop-types'
33
import classNames from 'classnames'
44
import { CConditionalPortal } from '../conditional-portal'
55

6+
import type { CToastProps } from './CToast'
7+
68
export interface CToasterProps extends HTMLAttributes<HTMLDivElement> {
79
/**
810
* A string of all className you want applied to the base component.
@@ -27,20 +29,22 @@ export interface CToasterProps extends HTMLAttributes<HTMLDivElement> {
2729
/**
2830
* Adds new `CToast` to `CToaster`.
2931
*/
30-
push?: ReactElement
32+
push?: ReactElement<CToastProps>
3133
}
3234

3335
export const CToaster = forwardRef<HTMLDivElement, CToasterProps>(
3436
({ children, className, placement, push, ...rest }, ref) => {
35-
const [toasts, setToasts] = useState<ReactElement[]>([])
37+
const [toasts, setToasts] = useState<ReactElement<CToastProps>[]>([])
3638
const index = useRef<number>(0)
3739

3840
useEffect(() => {
3941
index.current++
40-
push && addToast(push)
42+
if (push) {
43+
addToast(push)
44+
}
4145
}, [push])
4246

43-
const addToast = (push: ReactElement) => {
47+
const addToast = (push: ReactElement<CToastProps>) => {
4448
setToasts((state) => [
4549
...state,
4650
React.cloneElement(push, {
@@ -67,18 +71,18 @@ export const CToaster = forwardRef<HTMLDivElement, CToasterProps>(
6771
'start-50 translate-middle-x': placement && placement.includes('center'),
6872
'end-0': placement && placement.includes('end'),
6973
},
70-
className,
74+
className
7175
)}
7276
{...rest}
7377
ref={ref}
7478
>
7579
{children}
76-
{toasts.map((toast) => React.cloneElement(toast, { visible: true }))}
80+
{toasts.map((toast, index) => React.cloneElement(toast, { visible: true, key: index }))}
7781
</div>
7882
) : null}
7983
</CConditionalPortal>
8084
)
81-
},
85+
}
8286
)
8387

8488
CToaster.propTypes = {

packages/coreui-react/src/hooks/usePopper.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ interface UsePopperOutput {
1010
}
1111

1212
export const usePopper = (): UsePopperOutput => {
13-
const _popper = useRef<Instance>()
14-
const el = useRef<HTMLElement>()
13+
const _popper = useRef<Instance>(undefined)
14+
const el = useRef<HTMLElement>(null)
1515

1616
const initPopper = (reference: HTMLElement, popper: HTMLElement, options: Partial<Options>) => {
1717
_popper.current = createPopper(reference, popper, options)

0 commit comments

Comments
 (0)