Skip to content

Commit

Permalink
feat: implement grid-routes component
Browse files Browse the repository at this point in the history
  • Loading branch information
beeman committed Jan 9, 2024
1 parent b49a724 commit 2a2431d
Show file tree
Hide file tree
Showing 12 changed files with 192 additions and 46 deletions.
41 changes: 41 additions & 0 deletions apps/web/src/app/features/demo/demo-feature-grid-routes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { SimpleGrid } from '@mantine/core'
import { UiCard, UiGridRoutes } from '@pubkey-ui/core'

export function DemoFeatureGridRoutes() {
return (
<UiCard title="Grid Routes">
<UiGridRoutes
basePath="/demo/grid-routes"
routes={[
{
path: 'overview',
label: 'Overview',
element: (
<SimpleGrid cols={2} spacing="md">
<UiCard title="Overview">Overview</UiCard>
</SimpleGrid>
),
},
{
path: 'content',
label: 'Content',
element: (
<SimpleGrid cols={2} spacing="md">
<UiCard title="Content">Content</UiCard>
</SimpleGrid>
),
},
{
path: 'settings',
label: 'Settings',
element: (
<SimpleGrid cols={2} spacing="md">
<UiCard title="Settings">Settings</UiCard>
</SimpleGrid>
),
},
]}
/>
</UiCard>
)
}
27 changes: 4 additions & 23 deletions apps/web/src/app/features/demo/demo-feature.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { Grid, NavLink } from '@mantine/core'
import { UiNotFound, UiPage, UiStack } from '@pubkey-ui/core'
import { UiGridRoutes, UiPage } from '@pubkey-ui/core'
import { ReactNode } from 'react'
import { Link, Navigate, useLocation, useRoutes } from 'react-router-dom'
import { DemoFeatureAlerts } from './demo-feature-alerts'
import { DemoFeatureAnchor } from './demo-feature-anchor'
import { DemoFeatureBack } from './demo-feature-back'
Expand All @@ -10,6 +8,7 @@ import { DemoFeatureCopy } from './demo-feature-copy'
import { DemoFeatureDashboardGrid } from './demo-feature-dashboard-grid'
import { DemoFeatureDebug } from './demo-feature-debug'
import { DemoFeatureForm } from './demo-feature-form'
import { DemoFeatureGridRoutes } from './demo-feature-grid-routes'
import { DemoFeatureGroup } from './demo-feature-group'
import { DemoFeatureHeader } from './demo-feature-header'
import { DemoFeatureLoader } from './demo-feature-loader'
Expand All @@ -24,7 +23,6 @@ import { DemoFeatureTime } from './demo-feature-time'
import { DemoFeatureToast } from './demo-feature-toast'

export function DemoFeature() {
const { pathname } = useLocation()
const demos: {
path: string
label: string
Expand All @@ -38,6 +36,7 @@ export function DemoFeature() {
{ path: 'dashboard-grid', label: 'Dashboard Grid', element: <DemoFeatureDashboardGrid /> },
{ path: 'debug', label: 'Debug', element: <DemoFeatureDebug /> },
{ path: 'form', label: 'Form', element: <DemoFeatureForm /> },
{ path: 'grid-routes', label: 'Grid Routes', element: <DemoFeatureGridRoutes /> },
{ path: 'group', label: 'Group', element: <DemoFeatureGroup /> },
{ path: 'header', label: 'Header', element: <DemoFeatureHeader /> },
{ path: 'loader', label: 'Loader', element: <DemoFeatureLoader /> },
Expand All @@ -52,27 +51,9 @@ export function DemoFeature() {
{ path: 'toast', label: 'Toast', element: <DemoFeatureToast /> },
]

const routes = useRoutes([
{ index: true, element: <Navigate to={demos[0].path} replace /> },
...demos.map((demo) => ({ path: `${demo.path}/*`, element: demo.element })),
{ path: '*', element: <UiNotFound to="/demo" /> },
])

return (
<UiPage title="Demo">
<Grid>
<Grid.Col span={{ base: 12, sm: 2 }}>
{demos.map((demo) => {
const to = `/demo/${demo.path}`
return (
<NavLink active={pathname.startsWith(to)} component={Link} key={demo.path} label={demo.label} to={to} />
)
})}
</Grid.Col>
<Grid.Col span={{ base: 12, sm: 10 }}>
<UiStack gap="xl">{routes}</UiStack>
</Grid.Col>
</Grid>
<UiGridRoutes basePath="/demo" routes={demos} />
</UiPage>
)
}
1 change: 1 addition & 0 deletions packages/core/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export * from './ui-copy'
export * from './ui-dashboard-grid'
export * from './ui-debug'
export * from './ui-form'
export * from './ui-grid-routes'
export * from './ui-group'
export * from './ui-header'
export * from './ui-layout'
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/lib/ui-grid-routes/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ui-grid-routes'
48 changes: 48 additions & 0 deletions packages/core/src/lib/ui-grid-routes/ui-grid-routes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Grid, GridColProps, GridProps, NavLink } from '@mantine/core'
import { ReactNode, useMemo } from 'react'
import { Link, Navigate, useLocation, useRoutes } from 'react-router-dom'
import { UiNotFound } from '../ui-not-found'

export interface UiGridRoute {
path: string
label?: string
element: ReactNode
}
export interface UiGridRoutesProps extends GridProps {
basePath: string
routes: UiGridRoute[]
leftColProps?: GridColProps
rightColProps?: GridColProps
}

export function UiGridRoutes({ basePath, routes, leftColProps, rightColProps, ...props }: UiGridRoutesProps) {
const { pathname } = useLocation()

const links = useMemo(
() =>
routes
.filter((app) => app.label)
.map((app) => {
const to = `${basePath}/${app.path}`
return <NavLink active={pathname.startsWith(to)} component={Link} key={app.path} label={app.label} to={to} />
}),
[basePath, pathname, routes],
)

const router = useRoutes([
{ index: true, element: <Navigate to={routes[0].path} replace /> },
...routes.map((item) => ({ path: `${item.path}/*`, element: item.element })),
{ path: '*', element: <UiNotFound to={basePath} /> },
])

return (
<Grid {...props}>
<Grid.Col span={{ base: 12, sm: 2 }} {...rightColProps}>
{links}
</Grid.Col>
<Grid.Col span={{ base: 12, sm: 10 }} {...leftColProps}>
{router}
</Grid.Col>
</Grid>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface ComponentGeneratorSchema {
| 'dashboard-grid'
| 'debug'
| 'form'
| 'grid-routes'
| 'group'
| 'header'
| 'layout'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"dashboard-grid",
"debug",
"form",
"grid-routes",
"group",
"header",
"layout",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const componentTypes: ComponentGeneratorSchema['type'][] = [
'dashboard-grid',
'debug',
'form',
'grid-routes',
'group',
'header',
'layout',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Grid, GridColProps, GridProps, NavLink } from '@mantine/core'
import { ReactNode, useMemo } from 'react'
import { Link, Navigate, useLocation, useRoutes } from 'react-router-dom'
import { <%= prefix.className %>NotFound } from '../<%= prefix.fileName %>-not-found'

export interface <%= prefix.className %>GridRoute {
path: string
label?: string
element: ReactNode
}
export interface <%= prefix.className %>GridRoutesProps extends GridProps {
basePath: string
routes: <%= prefix.className %>GridRoute[]
leftColProps?: GridColProps
rightColProps?: GridColProps
}

export function <%= prefix.className %>GridRoutes({ basePath, routes, leftColProps, rightColProps, ...props }: <%= prefix.className %>GridRoutesProps) {
const { pathname } = useLocation()

const links = useMemo(
() =>
routes
.filter((app) => app.label)
.map((app) => {
const to = `${basePath}/${app.path}`
return <NavLink active={pathname.startsWith(to)} component={Link} key={app.path} label={app.label} to={to} />
}),
[basePath, pathname, routes],
)

const router = useRoutes([
{ index: true, element: <Navigate to={routes[0].path} replace /> },
...routes.map((item) => ({ path: `${item.path}/*`, element: item.element })),
{ path: '*', element: <<%= prefix.className %>NotFound to={basePath} /> },
])

return (
<Grid {...props}>
<Grid.Col span={{ base: 12, sm: 2 }} {...rightColProps}>
{links}
</Grid.Col>
<Grid.Col span={{ base: 12, sm: 10 }} {...leftColProps}>
{router}
</Grid.Col>
</Grid>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './<%= prefixFileName %>-grid-routes'
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { SimpleGrid } from '@mantine/core'
import { <%= prefix.className %>Card, <%= prefix.className %>GridRoutes } from '<%= uiImport %>'

export function DemoFeatureGridRoutes() {
return (
<<%= prefix.className %>Card title="Grid Routes">
<<%= prefix.className %>GridRoutes
basePath="/demo/grid-routes"
routes={[
{
path: 'overview',
label: 'Overview',
element: (
<SimpleGrid cols={2} spacing="md">
<<%= prefix.className %>Card title="Overview">Overview</<%= prefix.className %>Card>
</SimpleGrid>
),
},
{
path: 'content',
label: 'Content',
element: (
<SimpleGrid cols={2} spacing="md">
<<%= prefix.className %>Card title="Content">Content</<%= prefix.className %>Card>
</SimpleGrid>
),
},
{
path: 'settings',
label: 'Settings',
element: (
<SimpleGrid cols={2} spacing="md">
<<%= prefix.className %>Card title="Settings">Settings</<%= prefix.className %>Card>
</SimpleGrid>
),
},
]}
/>
</<%= prefix.className %>Card>
)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { Grid, NavLink } from '@mantine/core'
import { <%= prefix.className %>NotFound, <%= prefix.className %>Page, <%= prefix.className %>Stack } from '<%= uiImport %>'
import { <%= prefix.className %>GridRoutes, <%= prefix.className %>Page } from '<%= uiImport %>'
import { ReactNode } from 'react'
import { Link, Navigate, useLocation, useRoutes } from 'react-router-dom'
import { DemoFeatureAlerts } from './demo-feature-alerts'
import { DemoFeatureAnchor } from './demo-feature-anchor'
import { DemoFeatureBack } from './demo-feature-back'
Expand All @@ -10,6 +8,7 @@ import { DemoFeatureCopy } from './demo-feature-copy'
import { DemoFeatureDashboardGrid } from './demo-feature-dashboard-grid'
import { DemoFeatureDebug } from './demo-feature-debug'
import { DemoFeatureForm } from './demo-feature-form'
import { DemoFeatureGridRoutes } from './demo-feature-grid-routes'
import { DemoFeatureGroup } from './demo-feature-group'
import { DemoFeatureHeader } from './demo-feature-header'
import { DemoFeatureLoader } from './demo-feature-loader'
Expand All @@ -24,7 +23,6 @@ import { DemoFeatureTime } from './demo-feature-time'
import { DemoFeatureToast } from './demo-feature-toast'

export function DemoFeature() {
const { pathname } = useLocation()
const demos: {
path: string
label: string
Expand All @@ -38,6 +36,7 @@ export function DemoFeature() {
{ path: 'dashboard-grid', label: 'Dashboard Grid', element: <DemoFeatureDashboardGrid /> },
{ path: 'debug', label: 'Debug', element: <DemoFeatureDebug /> },
{ path: 'form', label: 'Form', element: <DemoFeatureForm /> },
{ path: 'grid-routes', label: 'Grid Routes', element: <DemoFeatureGridRoutes /> },
{ path: 'group', label: 'Group', element: <DemoFeatureGroup /> },
{ path: 'header', label: 'Header', element: <DemoFeatureHeader /> },
{ path: 'loader', label: 'Loader', element: <DemoFeatureLoader /> },
Expand All @@ -52,27 +51,9 @@ export function DemoFeature() {
{ path: 'toast', label: 'Toast', element: <DemoFeatureToast /> },
]

const routes = useRoutes([
{ index: true, element: <Navigate to={demos[0].path} replace /> },
...demos.map((demo) => ({ path: `${demo.path}/*`, element: demo.element })),
{ path: '*', element: <<%= prefix.className %>NotFound to="/demo" /> },
])

return (
<<%= prefix.className %>Page title="Demo">
<Grid>
<Grid.Col span={{ base: 12, sm: 2 }}>
{demos.map((demo) => {
const to = `/demo/${demo.path}`
return (
<NavLink active={pathname.startsWith(to)} component={Link} key={demo.path} label={demo.label} to={to} />
)
})}
</Grid.Col>
<Grid.Col span={{ base: 12, sm: 10 }}>
<<%= prefix.className %>Stack gap="xl">{routes}</<%= prefix.className %>Stack>
</Grid.Col>
</Grid>
<<%= prefix.className %>GridRoutes basePath="/demo" routes={demos} />
</<%= prefix.className %>Page>
)
}

0 comments on commit 2a2431d

Please sign in to comment.