feat: add sidebar nav generator
This commit is contained in:
parent
ff42ed744b
commit
5ee17f85e9
277
src/_nav.js
277
src/_nav.js
@ -1,12 +1,10 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import CIcon from '@coreui/icons-react'
|
import CIcon from '@coreui/icons-react'
|
||||||
import { NavLink } from 'react-router-dom'
|
|
||||||
|
|
||||||
const _nav = [
|
const _nav = [
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
name: 'Dashboard',
|
||||||
anchor: 'Dashboard',
|
|
||||||
to: '/dashboard',
|
to: '/dashboard',
|
||||||
icon: <CIcon name="cil-speedometer" customClassName="nav-icon" />,
|
icon: <CIcon name="cil-speedometer" customClassName="nav-icon" />,
|
||||||
badge: {
|
badge: {
|
||||||
@ -15,210 +13,206 @@ const _nav = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavTitle',
|
component: 'CNavTitle',
|
||||||
anchor: 'Theme',
|
name: 'Theme',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
name: 'Colors',
|
||||||
anchor: 'Colors',
|
|
||||||
to: '/theme/colors',
|
to: '/theme/colors',
|
||||||
icon: <CIcon name="cil-drop" customClassName="nav-icon" />,
|
icon: <CIcon name="cil-drop" customClassName="nav-icon" />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
name: 'Typography',
|
||||||
anchor: 'Typography',
|
|
||||||
to: '/theme/typography',
|
to: '/theme/typography',
|
||||||
icon: <CIcon name="cil-pencil" customClassName="nav-icon" />,
|
icon: <CIcon name="cil-pencil" customClassName="nav-icon" />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavTitle',
|
component: 'CNavTitle',
|
||||||
anchor: 'Components',
|
name: 'Components',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavGroup',
|
component: 'CNavGroup',
|
||||||
as: NavLink,
|
name: 'Base',
|
||||||
anchor: 'Base',
|
to: '/base',
|
||||||
to: '/to',
|
icon: 'cil-puzzle',
|
||||||
icon: <CIcon name="cil-puzzle" customClassName="nav-icon" />,
|
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Accordion',
|
name: 'Accordion',
|
||||||
to: '/base/accordion',
|
to: '/base/accordion',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Breadcrumb',
|
name: 'Breadcrumb',
|
||||||
to: '/base/breadcrumbs',
|
to: '/base/breadcrumbs',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Cards',
|
name: 'Cards',
|
||||||
to: '/base/cards',
|
to: '/base/cards',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Carousel',
|
name: 'Carousel',
|
||||||
to: '/base/carousels',
|
to: '/base/carousels',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Collapse',
|
name: 'Collapse',
|
||||||
to: '/base/collapses',
|
to: '/base/collapses',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'List group',
|
name: 'List group',
|
||||||
to: '/base/list-groups',
|
to: '/base/list-groups',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Navs & Tabs',
|
name: 'Navs & Tabs',
|
||||||
to: '/base/navs',
|
to: '/base/navs',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Pagination',
|
name: 'Pagination',
|
||||||
to: '/base/paginations',
|
to: '/base/paginations',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Popovers',
|
name: 'Popovers',
|
||||||
to: '/base/popovers',
|
to: '/base/popovers',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Progress',
|
name: 'Progress',
|
||||||
to: '/base/progress',
|
to: '/base/progress',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Spinners',
|
name: 'Spinners',
|
||||||
to: '/base/spinners',
|
to: '/base/spinners',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Tables',
|
name: 'Tables',
|
||||||
to: '/base/tables',
|
to: '/base/tables',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Tooltips',
|
name: 'Tooltips',
|
||||||
to: '/base/tooltips',
|
to: '/base/tooltips',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavGroup',
|
component: 'CNavGroup',
|
||||||
anchor: 'Buttons',
|
name: 'Buttons',
|
||||||
icon: <CIcon name="cil-cursor" customClassName="nav-icon" />,
|
icon: <CIcon name="cil-cursor" customClassName="nav-icon" />,
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Buttons',
|
name: 'Buttons',
|
||||||
to: '/buttons/buttons',
|
to: '/buttons/buttons',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Buttons groups',
|
name: 'Buttons groups',
|
||||||
to: '/buttons/button-groups',
|
to: '/buttons/button-groups',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Dropdowns',
|
name: 'Dropdowns',
|
||||||
to: '/buttons/dropdowns',
|
to: '/buttons/dropdowns',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavGroup',
|
component: 'CNavGroup',
|
||||||
anchor: 'Forms',
|
name: 'Forms',
|
||||||
icon: <CIcon name="cil-notes" customClassName="nav-icon" />,
|
icon: <CIcon name="cil-notes" customClassName="nav-icon" />,
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Form Control',
|
name: 'Form Control',
|
||||||
to: '/forms/form-control',
|
to: '/forms/form-control',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Select',
|
name: 'Select',
|
||||||
to: '/forms/select',
|
to: '/forms/select',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Checks & Radios',
|
name: 'Checks & Radios',
|
||||||
to: '/forms/checks-radios',
|
to: '/forms/checks-radios',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Range',
|
name: 'Range',
|
||||||
to: '/forms/range',
|
to: '/forms/range',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Input Group',
|
name: 'Input Group',
|
||||||
to: '/forms/input-group',
|
to: '/forms/input-group',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Floating Labels',
|
name: 'Floating Labels',
|
||||||
to: '/forms/floating-labels',
|
to: '/forms/floating-labels',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Layout',
|
name: 'Layout',
|
||||||
to: '/forms/layout',
|
to: '/forms/layout',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Validation',
|
name: 'Validation',
|
||||||
to: '/forms/validation',
|
to: '/forms/validation',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
name: 'Charts',
|
||||||
anchor: 'Charts',
|
|
||||||
to: '/charts',
|
to: '/charts',
|
||||||
icon: <CIcon name="cil-chart-pie" customClassName="nav-icon" />,
|
icon: <CIcon name="cil-chart-pie" customClassName="nav-icon" />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavGroup',
|
component: 'CNavGroup',
|
||||||
anchor: 'Icons',
|
name: 'Icons',
|
||||||
icon: <CIcon name="cil-star" customClassName="nav-icon" />,
|
icon: <CIcon name="cil-star" customClassName="nav-icon" />,
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'CoreUI Free',
|
name: 'CoreUI Free',
|
||||||
to: '/icons/coreui-icons',
|
to: '/icons/coreui-icons',
|
||||||
badge: {
|
badge: {
|
||||||
color: 'success',
|
color: 'success',
|
||||||
@ -226,54 +220,53 @@ const _nav = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'CoreUI Flags',
|
name: 'CoreUI Flags',
|
||||||
to: '/icons/flags',
|
to: '/icons/flags',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'CoreUI Brands',
|
name: 'CoreUI Brands',
|
||||||
to: '/icons/brands',
|
to: '/icons/brands',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavGroup',
|
component: 'CNavGroup',
|
||||||
anchor: 'Notifications',
|
name: 'Notifications',
|
||||||
icon: <CIcon name="cil-bell" customClassName="nav-icon" />,
|
icon: <CIcon name="cil-bell" customClassName="nav-icon" />,
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Alerts',
|
name: 'Alerts',
|
||||||
to: '/notifications/alerts',
|
to: '/notifications/alerts',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Badges',
|
name: 'Badges',
|
||||||
to: '/notifications/badges',
|
to: '/notifications/badges',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Modal',
|
name: 'Modal',
|
||||||
to: '/notifications/modals',
|
to: '/notifications/modals',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Toasts',
|
name: 'Toasts',
|
||||||
to: '/notifications/toasts',
|
to: '/notifications/toasts',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
name: 'Widgets',
|
||||||
anchor: 'Widgets',
|
|
||||||
to: '/widgets',
|
to: '/widgets',
|
||||||
icon: <CIcon name="cil-calculator" customClassName="nav-icon" />,
|
icon: <CIcon name="cil-calculator" customClassName="nav-icon" />,
|
||||||
badge: {
|
badge: {
|
||||||
@ -282,36 +275,36 @@ const _nav = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavTitle',
|
component: 'CNavTitle',
|
||||||
anchor: 'Extras',
|
name: 'Extras',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavGroup',
|
component: 'CNavGroup',
|
||||||
anchor: 'Pages',
|
name: 'Pages',
|
||||||
icon: <CIcon name="cil-star" customClassName="nav-icon" />,
|
icon: <CIcon name="cil-star" customClassName="nav-icon" />,
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Login',
|
name: 'Login',
|
||||||
to: '/login',
|
to: '/login',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Register',
|
name: 'Register',
|
||||||
to: '/register',
|
to: '/register',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Error 404',
|
name: 'Error 404',
|
||||||
to: '/404',
|
to: '/404',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_component: 'CNavItem',
|
component: 'CNavItem',
|
||||||
as: NavLink,
|
|
||||||
anchor: 'Error 500',
|
name: 'Error 500',
|
||||||
to: '/500',
|
to: '/500',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { useSelector, useDispatch } from 'react-redux'
|
import { useSelector, useDispatch } from 'react-redux'
|
||||||
|
|
||||||
import {
|
import { CSidebar, CSidebarBrand, CSidebarNav, CSidebarToggler } from '@coreui/react'
|
||||||
CSidebar,
|
|
||||||
CSidebarBrand,
|
import { AppSidebarNav } from './AppSidebarNav'
|
||||||
CSidebarNav,
|
|
||||||
CSidebarToggler,
|
|
||||||
CCreateNavItem,
|
|
||||||
} from '@coreui/react'
|
|
||||||
|
|
||||||
import CIcon from '@coreui/icons-react'
|
import CIcon from '@coreui/icons-react'
|
||||||
|
|
||||||
@ -27,7 +23,7 @@ const AppSidebar = () => {
|
|||||||
position="fixed"
|
position="fixed"
|
||||||
selfHiding="md"
|
selfHiding="md"
|
||||||
unfoldable={unfoldable}
|
unfoldable={unfoldable}
|
||||||
show={sidebarShow}
|
visible={sidebarShow}
|
||||||
onShow={() => console.log('show')}
|
onShow={() => console.log('show')}
|
||||||
onHide={() => {
|
onHide={() => {
|
||||||
dispatch({ type: 'set', sidebarShow: false })
|
dispatch({ type: 'set', sidebarShow: false })
|
||||||
@ -39,7 +35,7 @@ const AppSidebar = () => {
|
|||||||
</CSidebarBrand>
|
</CSidebarBrand>
|
||||||
<CSidebarNav>
|
<CSidebarNav>
|
||||||
<SimpleBar>
|
<SimpleBar>
|
||||||
<CCreateNavItem items={navigation} />
|
<AppSidebarNav items={navigation} />
|
||||||
</SimpleBar>
|
</SimpleBar>
|
||||||
</CSidebarNav>
|
</CSidebarNav>
|
||||||
<CSidebarToggler
|
<CSidebarToggler
|
||||||
|
70
src/components/AppSidebarNav.js
Normal file
70
src/components/AppSidebarNav.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { NavLink, useLocation } from 'react-router-dom'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
|
import { CBadge, CNavGroup, CNavGroupItems, CNavItem, CNavLink, CNavTitle } from '@coreui/react'
|
||||||
|
import CIcon from '@coreui/icons-react'
|
||||||
|
|
||||||
|
export const AppSidebarNav = ({ items }) => {
|
||||||
|
const components = { CNavGroup, CNavGroupItems, CNavItem, CNavLink, CNavTitle }
|
||||||
|
const location = useLocation()
|
||||||
|
|
||||||
|
const navLink = (name, icon, badge) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{icon && typeof icon === 'string' ? <CIcon name={icon} customClassName="nav-icon" /> : icon}
|
||||||
|
{name && name}
|
||||||
|
{badge && (
|
||||||
|
<CBadge color={badge.color} className="ms-auto">
|
||||||
|
{badge.text}
|
||||||
|
</CBadge>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const navItem = (item, index) => {
|
||||||
|
const { component, name, badge, icon, ...rest } = item
|
||||||
|
const Component = components[component] || component
|
||||||
|
return (
|
||||||
|
<Component
|
||||||
|
{...(component === 'CNavItem' && {
|
||||||
|
component: NavLink,
|
||||||
|
activeClassName: 'active',
|
||||||
|
})}
|
||||||
|
key={index}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
{navLink(name, icon, badge)}
|
||||||
|
</Component>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
const navGroup = (item, index) => {
|
||||||
|
const { component, name, icon, items, to, ...rest } = item
|
||||||
|
const Component = components[component] || component
|
||||||
|
return (
|
||||||
|
<Component
|
||||||
|
toggler={navLink(name, icon)}
|
||||||
|
visible={location.pathname.startsWith(to)}
|
||||||
|
idx={String(index)}
|
||||||
|
key={index}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
{item.items.map((item, index) =>
|
||||||
|
item.items ? navGroup(item, index) : navItem(item, index),
|
||||||
|
)}
|
||||||
|
</Component>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
{items &&
|
||||||
|
items.map((item, index) => (item.items ? navGroup(item, index) : navItem(item, index)))}
|
||||||
|
</React.Fragment>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
AppSidebarNav.propTypes = {
|
||||||
|
items: PropTypes.arrayOf(PropTypes.any).isRequired,
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user