Skip to content

Commit cad7851

Browse files
committed
Make AppSidebar a typescript component
1 parent 6eba59b commit cad7851

File tree

11 files changed

+162
-23
lines changed

11 files changed

+162
-23
lines changed

REFERENCES.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,11 @@ http://bit.ly/2E3uMER
99
https://gumroad.com/l/UAxnr
1010

1111

12+
### Materials
13+
14+
https://www.carlrippon.com/react-forwardref-typescript/
15+
16+
17+
18+
1219

package-lock.json

Lines changed: 49 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"@material-ui/lab": "^4.0.0-alpha.58",
2727
"@rehooks/component-size": "^1.0.3",
2828
"@types/lodash": "^4.14.168",
29+
"@types/react-router-dom": "^5.1.7",
2930
"@types/uuid": "^8.3.0",
3031
"axios": "^0.21.1",
3132
"axios-mock-adapter": "^1.19.0",

src-ts/_common/AppSidebar/AppSidebar.js renamed to src-ts/_common/AppSidebar/AppSidebar.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React from 'react'
2-
import PropTypes from 'prop-types'
32
import { makeStyles } from '@material-ui/core/styles'
43

54
import { Link } from 'react-router-dom'
@@ -9,7 +8,11 @@ import Typography from '@material-ui/core/Typography'
98
import Logo from '_common/BaseLogo/BaseLogo'
109
import SidebarNav from './SidebarNav'
1110

12-
const Sidebar = (props) => {
11+
export interface ISidebarProps {
12+
isCollapsed?: boolean
13+
}
14+
15+
const Sidebar: React.FC<ISidebarProps> = (props) => {
1316
const { isCollapsed } = props
1417

1518
const classes = useStyles(props)
@@ -43,9 +46,9 @@ Sidebar.defaultProps = {
4346
isCollapsed: false,
4447
}
4548

46-
Sidebar.propTypes = {
47-
isCollapsed: PropTypes.bool,
48-
}
49+
// Sidebar.propTypes = {
50+
// isCollapsed: PropTypes.bool,
51+
// }
4952

5053
const useStyles = makeStyles((theme) => ({
5154
sidebar: {
@@ -95,7 +98,7 @@ const useStyles = makeStyles((theme) => ({
9598
color: theme.palette.primary.main,
9699
zIndex: 10,
97100
},
98-
title: (props) => ({
101+
title: (props: ISidebarProps) => ({
99102
position: 'relative',
100103
overflow: 'visible',
101104
marginLeft: '5px',

src-ts/_common/AppSidebar/SidebarNav/NavItem.js renamed to src-ts/_common/AppSidebar/SidebarNav/NavItem.tsx

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useLayoutEffect } from 'react'
1+
import React, { useLayoutEffect, MouseEvent } from 'react'
22
import clsx from 'clsx'
33

44
import { makeStyles, createStyles } from '@material-ui/core/styles'
@@ -15,11 +15,30 @@ import IconExpandLess from '@material-ui/icons/ExpandLess'
1515
import IconExpandMore from '@material-ui/icons/ExpandMore'
1616
import IconSpacer from '@material-ui/icons/FiberManualRecord'
1717

18+
import { ISidebarNavItem } from './SidebarNav'
19+
1820
import NavItemComponent from './NavItemComponent'
1921

2022
// ----------------------------------------------------------------------
2123

22-
const NavItemCollapsed = (props) => {
24+
export interface INavItemCollapsedProps {
25+
name: string
26+
link?: string
27+
Icon?: any
28+
IconStyles?: object
29+
IconClassName?: string
30+
isCollapsed?: boolean
31+
className?: string
32+
nestingLevel?: number
33+
nestingOffset?: number
34+
isNested?: boolean
35+
items?: ISidebarNavItem[]
36+
isOpen?: boolean
37+
style?: any
38+
onClick?: () => void
39+
}
40+
41+
const NavItemCollapsed: React.FC<INavItemCollapsedProps> = (props) => {
2342
const {
2443
name,
2544
link,
@@ -36,11 +55,12 @@ const NavItemCollapsed = (props) => {
3655
const itemsAll = getItemsAll(items)
3756
const hasChildrenAndIsActive =
3857
hasChildren &&
39-
itemsAll.filter((item) => `#${item.link}` === window.location.hash).length > 0
58+
itemsAll.filter((item: ISidebarNavItem) => `#${item.link}` === window.location.hash)
59+
.length > 0
4060

41-
const [anchorEl, setAnchorEl] = React.useState(null)
61+
const [anchorEl, setAnchorEl] = React.useState<HTMLAnchorElement>()
4262

43-
const handlePopoverOpen = (event) => {
63+
const handlePopoverOpen = (event: MouseEvent<HTMLAnchorElement>) => {
4464
if (!hasChildren) {
4565
return false
4666
}
@@ -49,7 +69,7 @@ const NavItemCollapsed = (props) => {
4969
}
5070

5171
const handlePopoverClose = () => {
52-
setAnchorEl(null)
72+
setAnchorEl(undefined)
5373
}
5474

5575
const open = Boolean(anchorEl)
@@ -152,7 +172,23 @@ const NavItemCollapsed = (props) => {
152172
)
153173
}
154174

155-
const NavItemDefault = (props) => {
175+
export interface INavItemDefaultProps {
176+
name: string
177+
link?: string
178+
Icon?: any
179+
IconStyles?: object
180+
IconClassName?: string
181+
isCollapsed?: boolean
182+
className?: string
183+
nestingLevel?: number
184+
nestingOffset?: number
185+
style?: any
186+
items?: ISidebarNavItem[]
187+
isOpen?: boolean
188+
onClick?: () => void
189+
}
190+
191+
const NavItemDefault: React.FC<INavItemDefaultProps> = (props) => {
156192
const {
157193
name,
158194
link,
@@ -257,7 +293,7 @@ const NavItemDefault = (props) => {
257293
)
258294
}
259295

260-
const NavItem = (props) => {
296+
const NavItem: React.FC<INavItemCollapsedProps | INavItemDefaultProps> = (props) => {
261297
if (props.isCollapsed) {
262298
return <NavItemCollapsed {...props} />
263299
} else {
@@ -344,8 +380,8 @@ const useStyles = makeStyles((theme) =>
344380
// ----------------------
345381

346382
// Flattened array of all children
347-
function getItemsAll(items) {
348-
return items.reduce((allItems, item) => {
383+
function getItemsAll(items: ISidebarNavItem[]): ISidebarNavItem[] {
384+
return items.reduce((allItems: ISidebarNavItem[], item: ISidebarNavItem) => {
349385
// let res = allItems.concat([item])
350386

351387
if (item.items && item.items.length) {

src-ts/_common/AppSidebar/SidebarNav/NavItemComponent.js renamed to src-ts/_common/AppSidebar/SidebarNav/NavItemComponent.tsx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,34 @@
1-
import React, { forwardRef } from 'react'
1+
import React, { forwardRef, MouseEvent } from 'react'
22
import clsx from 'clsx'
33

44
import ListItem from '@material-ui/core/ListItem'
55
import { makeStyles, createStyles } from '@material-ui/core/styles'
66

7-
import { NavLink } from 'react-router-dom'
7+
import { NavLink, NavLinkProps } from 'react-router-dom'
88

9-
export const NavItemLink = forwardRef((props, ref) => (
9+
export const NavItemLink = forwardRef<HTMLAnchorElement, NavLinkProps>((props, ref) => (
1010
<NavLink exact {...props} innerRef={ref} />
1111
))
1212

13+
export interface INavItemComponent {
14+
link?: string
15+
className?: string
16+
isCollapsed?: boolean
17+
style?: any
18+
onClick(e: MouseEvent): void
19+
}
20+
1321
// Can be a link, or button
14-
export const NavItemComponent = forwardRef((props, ref) => {
22+
export const NavItemComponent = forwardRef<
23+
HTMLDivElement,
24+
React.PropsWithChildren<INavItemComponent>
25+
>((props, ref) => {
1526
const { isCollapsed, ...newProps } = props
1627
const classes = useStyles()
1728

1829
const component =
1930
typeof props.link === 'string' ? (
20-
<ListItem {...newProps} button component={NavItemLink} to={props.link} />
31+
<ListItem {...newProps} component={NavItemLink} to={props.link} />
2132
) : (
2233
<ListItem {...newProps} button />
2334
)

src-ts/_common/AppSidebar/SidebarNav/NavList.js renamed to src-ts/_common/AppSidebar/SidebarNav/NavList.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,15 @@ import React from 'react'
22

33
import NavItem from './NavItem'
44

5-
const AppSidebarNavList = (props) => {
5+
import { ISidebarNavItem } from './SidebarNav'
6+
7+
export interface IAppSidebarNavList {
8+
isNested?: boolean
9+
isCollapsed?: boolean
10+
items: ISidebarNavItem[]
11+
}
12+
13+
const AppSidebarNavList: React.FC<IAppSidebarNavList> = (props) => {
614
const { items = [], isCollapsed = false, isNested = false } = props
715
// const classes = useStyles()
816

src-ts/_common/AppSidebar/SidebarNav/SidebarNav.js renamed to src-ts/_common/AppSidebar/SidebarNav/SidebarNav.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,19 @@ import IconPreson from '@material-ui/icons/Person' //
1515

1616
import NavList from './NavList'
1717

18-
const SidebarNav = (props) => {
18+
export interface ISidebarNavItem {
19+
name: string
20+
link?: string
21+
Icon?: any
22+
IconClassName?: string
23+
items?: ISidebarNavItem[]
24+
}
25+
26+
export interface ISidebarNavProps {
27+
isCollapsed?: boolean
28+
}
29+
30+
const SidebarNav: React.FC<ISidebarNavProps> = (props) => {
1931
const { isCollapsed } = props
2032
const classes = useStyles()
2133

0 commit comments

Comments
 (0)