aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/route-config.ts
blob: 9d308d4f6b5c46c885d1c83dc6c8337870adc47d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import type { ComponentType } from 'react'
import type { RouteObject } from 'react-router'
import HomeIcon from '@react-spectrum/s2/icons/Home'
import InfoCircleIcon from '@react-spectrum/s2/icons/InfoCircle'
import HelpCircleIcon from '@react-spectrum/s2/icons/HelpCircle'
import EditIcon from '@react-spectrum/s2/icons/Edit'
import AppsIcon from '@react-spectrum/s2/icons/Apps'
import Home from './page-home'
import About from './page-about'
import NotFound from './page-not-found'
import FormPage from './page-form'
import UIKitPage from './page-ui-kit'

interface ItemMetadata {
  id: string
  title: string
  Icon?: typeof HomeIcon
  hidden?: boolean
}

interface PageConfig extends ItemMetadata {
  path: string
  Component: ComponentType
  children?: never
}

interface GroupConfig extends ItemMetadata {
  children: NavigationItem[]
  defaultExpanded?: boolean
  path?: never
  Component?: never
}

export type NavigationItem = PageConfig | GroupConfig

export interface PageMetadata {
  id: string
  title: string
  path: string
}

// Menu groups organize navigation; page paths are absolute and independent of groups.
export const routeConfig: NavigationItem[] = [
  { id: 'home', title: 'Home', path: '/', Icon: HomeIcon, Component: Home },
  { id: 'form', title: '表单', path: '/form', Icon: EditIcon, Component: FormPage },
  { id: 'ui-kit', title: 'UI Kit', path: '/ui-kit', Icon: AppsIcon, Component: UIKitPage },
  {
    id: 'help',
    title: 'Help',
    Icon: HelpCircleIcon,
    defaultExpanded: true,
    children: [
      { id: 'about', title: 'About', path: '/about', Icon: InfoCircleIcon, Component: About },
    ],
  },
  { id: 'not-found', title: 'Page not found', path: '*', Component: NotFound, hidden: true },
]

function createPageRoutes(items: NavigationItem[]): RouteObject[] {
  return items.flatMap((item): RouteObject[] => {
    if (item.children) return createPageRoutes(item.children)
    const handle: PageMetadata = { id: item.id, title: item.title, path: item.path }
    return [{ id: item.id, path: item.path, Component: item.Component, handle }]
  })
}

function createMenuItems(items: NavigationItem[]): NavigationItem[] {
  return items.filter((item) => !item.hidden).map((item) =>
    item.children ? { ...item, children: createMenuItems(item.children) } : item,
  )
}

function getExpandedKeys(items: NavigationItem[]): string[] {
  return items.flatMap((item) => item.children
    ? [...(item.defaultExpanded ? [item.id] : []), ...getExpandedKeys(item.children)]
    : [],
  )
}

export const pageRoutes = createPageRoutes(routeConfig)
export const menuItems = createMenuItems(routeConfig)
export const defaultExpandedKeys = getExpandedKeys(menuItems)