-
-
Notifications
You must be signed in to change notification settings - Fork 298
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(docs): start adding layout docs and example projects
- Loading branch information
Showing
31 changed files
with
1,255 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
"use client"; | ||
import { rmdConfig } from "@/constants/rmdConfig.jsx"; | ||
import { CoreProviders } from "@react-md/core/CoreProviders"; | ||
import { type ReactElement, type ReactNode } from "react"; | ||
|
||
export interface RootProvidersProps { | ||
children: ReactNode; | ||
} | ||
|
||
export function RootProviders(props: RootProvidersProps): ReactElement { | ||
const { children } = props; | ||
|
||
return <CoreProviders {...rmdConfig}>{children}</CoreProviders>; | ||
} |
53 changes: 53 additions & 0 deletions
53
apps/docs/src/app/(layout-examples)/layout-example/[layout]/ExpandableLayoutExample.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
"use client"; | ||
import { AppBar } from "@react-md/core/app-bar/AppBar"; | ||
import { AppBarTitle } from "@react-md/core/app-bar/AppBarTitle"; | ||
import { Button } from "@react-md/core/button/Button"; | ||
import { LayoutNav } from "@react-md/core/layout/LayoutNav"; | ||
import { Main } from "@react-md/core/layout/Main"; | ||
import { | ||
useExpandableLayout, | ||
type ExpandableLayoutOptions, | ||
} from "@react-md/core/layout/useExpandableLayout"; | ||
import { Sheet } from "@react-md/core/sheet/Sheet"; | ||
import { usePathname } from "next/navigation.js"; | ||
import { type ReactElement } from "react"; | ||
import { Navigation } from "./Navigation.jsx"; | ||
import { type ExampleLayoutProps } from "./layouts.js"; | ||
|
||
export interface ExpandableLayoutExampleProps | ||
extends ExampleLayoutProps, | ||
Omit<ExpandableLayoutOptions, "pathname"> {} | ||
|
||
export function ExpandableLayoutExample( | ||
props: ExpandableLayoutExampleProps | ||
): ReactElement { | ||
const { layout, children, ...options } = props; | ||
|
||
const pathname = usePathname(); | ||
const { | ||
temporary, | ||
temporaryNavProps, | ||
navToggleProps, | ||
appBarProps, | ||
mainProps, | ||
expandableNavProps, | ||
} = useExpandableLayout({ pathname, ...options }); | ||
|
||
return ( | ||
<> | ||
<AppBar {...appBarProps}> | ||
<Button {...navToggleProps} /> | ||
<AppBarTitle>Expandable Layout Example</AppBarTitle> | ||
</AppBar> | ||
<LayoutNav {...expandableNavProps}> | ||
<Navigation layout={layout} /> | ||
</LayoutNav> | ||
{temporary && ( | ||
<Sheet {...temporaryNavProps}> | ||
<Navigation layout={layout} /> | ||
</Sheet> | ||
)} | ||
<Main {...mainProps}>{children}</Main> | ||
</> | ||
); | ||
} |
9 changes: 9 additions & 0 deletions
9
...s/src/app/(layout-examples)/layout-example/[layout]/FullHeightExpandableLayoutExample.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { type ReactElement } from "react"; | ||
import { type ExampleLayoutProps } from "./layouts.js"; | ||
import { ExpandableLayoutExample } from "./ExpandableLayoutExample.js"; | ||
|
||
export function FullHeightExpandableLayoutExample( | ||
props: ExampleLayoutProps | ||
): ReactElement { | ||
return <ExpandableLayoutExample {...props} fullHeightNav defaultExpanded />; | ||
} |
9 changes: 9 additions & 0 deletions
9
apps/docs/src/app/(layout-examples)/layout-example/[layout]/FullHeightLayoutExample.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { type ReactElement } from "react"; | ||
import { type ExampleLayoutProps } from "./layouts.js"; | ||
import { ExpandableLayoutExample } from "./ExpandableLayoutExample.jsx"; | ||
|
||
export function FullHeightLayoutExample( | ||
props: ExampleLayoutProps | ||
): ReactElement { | ||
return <ExpandableLayoutExample {...props} fullHeightNav="static" />; | ||
} |
9 changes: 9 additions & 0 deletions
9
...cs/src/app/(layout-examples)/layout-example/[layout]/FullHeightResizableLayoutExample.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { type ReactElement } from "react"; | ||
import { type ExampleLayoutProps } from "./layouts.js"; | ||
import { ResizableLayoutExample } from "./ResizableLayoutExample.jsx"; | ||
|
||
export function FullHeightResizableLayoutExample( | ||
props: ExampleLayoutProps | ||
): ReactElement { | ||
return <ResizableLayoutExample {...props} fullHeightNav="static" />; | ||
} |
44 changes: 44 additions & 0 deletions
44
apps/docs/src/app/(layout-examples)/layout-example/[layout]/LayoutIcon.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import ForestIcon from "@react-md/material-icons/ForestIcon"; | ||
import AllOutIcon from "node_modules/@react-md/material-icons/src/AllOutIcon.jsx"; | ||
import DensityLargeIcon from "node_modules/@react-md/material-icons/src/DensityLargeIcon.jsx"; | ||
import ExpandIcon from "node_modules/@react-md/material-icons/src/ExpandIcon.jsx"; | ||
import FullscreenIcon from "node_modules/@react-md/material-icons/src/FullscreenIcon.jsx"; | ||
import MenuOpenIcon from "node_modules/@react-md/material-icons/src/MenuOpenIcon.jsx"; | ||
import OpenInFullIcon from "node_modules/@react-md/material-icons/src/OpenInFullIcon.jsx"; | ||
import { type ComponentType, type ReactElement } from "react"; | ||
import { type LayoutType } from "./layouts.js"; | ||
import { type SVGIconProps } from "@react-md/core/icon/SVGIcon"; | ||
|
||
export interface LayoutIconProps extends SVGIconProps { | ||
layout: LayoutType; | ||
} | ||
|
||
export function LayoutIcon(props: LayoutIconProps): ReactElement { | ||
const { layout, ...remaining } = props; | ||
let Component: ComponentType<SVGIconProps>; | ||
switch (layout) { | ||
case "temporary": | ||
Component = MenuOpenIcon; | ||
break; | ||
case "expandable": | ||
Component = ExpandIcon; | ||
break; | ||
case "resizable": | ||
Component = OpenInFullIcon; | ||
break; | ||
case "full-height": | ||
Component = FullscreenIcon; | ||
break; | ||
case "full-height-expandable": | ||
Component = DensityLargeIcon; | ||
break; | ||
case "full-height-resizable": | ||
Component = AllOutIcon; | ||
break; | ||
case "tree": | ||
Component = ForestIcon; | ||
break; | ||
} | ||
|
||
return <Component {...remaining} />; | ||
} |
63 changes: 63 additions & 0 deletions
63
apps/docs/src/app/(layout-examples)/layout-example/[layout]/Navigation.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { pascalCase } from "@/utils/strings.js"; | ||
import { cssUtils } from "@react-md/core/cssUtils"; | ||
import { Divider } from "@react-md/core/divider/Divider"; | ||
import { List } from "@react-md/core/list/List"; | ||
import { ListSubheader } from "@react-md/core/list/ListSubheader"; | ||
import HomeIcon from "@react-md/material-icons/HomeIcon"; | ||
import StarIcon from "@react-md/material-icons/StarIcon"; | ||
import ExitToAppIcon from "node_modules/@react-md/material-icons/src/ExitToAppIcon.jsx"; | ||
import FavoriteIcon from "node_modules/@react-md/material-icons/src/FavoriteIcon.jsx"; | ||
import { type ReactElement } from "react"; | ||
import { LayoutIcon } from "./LayoutIcon.jsx"; | ||
import { SimpleNavItem } from "./SimpleNavItem.jsx"; | ||
import { LAYOUT_TYPES, type LayoutType } from "./layouts.js"; | ||
|
||
export interface NavigationProps { | ||
layout: LayoutType; | ||
} | ||
|
||
export function Navigation(props: NavigationProps): ReactElement { | ||
const { layout } = props; | ||
|
||
return ( | ||
<List className={cssUtils({ textOverflow: "ellipsis" })}> | ||
<SimpleNavItem | ||
href={`/layout-example/${layout}`} | ||
leftAddon={<HomeIcon />} | ||
> | ||
Home | ||
</SimpleNavItem> | ||
<SimpleNavItem | ||
href={`/layout-example/${layout}/page-1`} | ||
leftAddon={<StarIcon />} | ||
> | ||
Page 1 | ||
</SimpleNavItem> | ||
<SimpleNavItem | ||
href={`/layout-example/${layout}/page-2`} | ||
leftAddon={<FavoriteIcon />} | ||
> | ||
Page 2 | ||
</SimpleNavItem> | ||
<Divider /> | ||
<ListSubheader>Layout Types</ListSubheader> | ||
{LAYOUT_TYPES.map((layoutType) => ( | ||
<SimpleNavItem | ||
key={layoutType} | ||
active={layout === layoutType} | ||
href={`/layout-example/${layoutType}`} | ||
leftAddon={<LayoutIcon layout={layoutType} />} | ||
> | ||
{pascalCase(layoutType, " ")} | ||
</SimpleNavItem> | ||
))} | ||
<Divider /> | ||
<SimpleNavItem | ||
href={`/getting-started/layout#${layout}-navigation-layout`} | ||
leftAddon={<ExitToAppIcon />} | ||
> | ||
Back to layout docs | ||
</SimpleNavItem> | ||
</List> | ||
); | ||
} |
145 changes: 145 additions & 0 deletions
145
apps/docs/src/app/(layout-examples)/layout-example/[layout]/NavigationTree.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
"use client"; | ||
import { ButtonStyledLink } from "@/components/ButtonStyledLink.jsx"; | ||
import { LinkUnstyled } from "@/components/LinkUnstyled.jsx"; | ||
import { pascalCase } from "@/utils/strings.js"; | ||
import { box } from "@react-md/core/box/styles"; | ||
import { useLayoutTree } from "@react-md/core/layout/useLayoutTree"; | ||
import { Tree } from "@react-md/core/tree/Tree"; | ||
import { type TreeData, type TreeItemSorter } from "@react-md/core/tree/types"; | ||
import ExitToAppIcon from "@react-md/material-icons/ExitToAppIcon"; | ||
import HomeIcon from "@react-md/material-icons/HomeIcon"; | ||
import { cnb } from "cnbuilder"; | ||
import { usePathname } from "next/navigation.js"; | ||
import FavoriteIcon from "node_modules/@react-md/material-icons/src/FavoriteIcon.jsx"; | ||
import StarIcon from "node_modules/@react-md/material-icons/src/StarIcon.jsx"; | ||
import { useMemo, type ReactElement } from "react"; | ||
import { LayoutIcon } from "./LayoutIcon.jsx"; | ||
import { LAYOUT_TYPES, type LayoutType } from "./layouts.js"; | ||
import { cssUtils } from "@react-md/core/cssUtils"; | ||
|
||
const PATH_PREFIX = "/layout-example/"; | ||
const TYPE_SUFFIX = "-type"; | ||
|
||
const sort: TreeItemSorter = (items) => { | ||
if (items.length !== LAYOUT_TYPES.length) { | ||
return items; | ||
} | ||
const sorted = [...items]; | ||
sorted.sort((a, b) => { | ||
const aType = a.itemId.substring( | ||
PATH_PREFIX.length, | ||
a.itemId.length - TYPE_SUFFIX.length | ||
); | ||
const bType = b.itemId.substring( | ||
PATH_PREFIX.length, | ||
b.itemId.length - TYPE_SUFFIX.length | ||
); | ||
|
||
return ( | ||
LAYOUT_TYPES.indexOf(bType as LayoutType) - | ||
LAYOUT_TYPES.indexOf(aType as LayoutType) | ||
); | ||
}); | ||
sorted.reverse(); | ||
|
||
return sorted; | ||
}; | ||
|
||
export interface NavigationTreeProps { | ||
layout: LayoutType; | ||
} | ||
|
||
export function NavigationTree(props: NavigationTreeProps): ReactElement { | ||
const { layout } = props; | ||
|
||
const pathname = usePathname(); | ||
const navItems = useMemo<TreeData>(() => { | ||
const homeHref = `${PATH_PREFIX}${layout}`; | ||
const layouts = LAYOUT_TYPES.reduce<TreeData>((result, layoutType) => { | ||
const href = `${PATH_PREFIX}${layoutType}`; | ||
result[`${href}${TYPE_SUFFIX}`] = { | ||
href, | ||
itemId: `${href}${TYPE_SUFFIX}`, | ||
children: pascalCase(layoutType, " "), | ||
parentId: "layouts", | ||
leftAddon: <LayoutIcon layout={layoutType} />, | ||
contentClassName: cnb( | ||
layout === layoutType && "rmd-tree-item__content--selected" | ||
), | ||
}; | ||
|
||
return result; | ||
}, {}); | ||
|
||
return { | ||
pages: { | ||
itemId: "pages", | ||
parentId: null, | ||
children: "Pages", | ||
}, | ||
layouts: { | ||
itemId: "layouts", | ||
parentId: null, | ||
children: "Layout Types", | ||
}, | ||
[homeHref]: { | ||
href: homeHref, | ||
itemId: homeHref, | ||
parentId: "pages", | ||
children: "Home", | ||
leftAddon: <HomeIcon />, | ||
}, | ||
[`${homeHref}/page-1`]: { | ||
href: `${homeHref}/page-1`, | ||
itemId: `${homeHref}/page-1`, | ||
parentId: "pages", | ||
children: "Page 1", | ||
leftAddon: <StarIcon />, | ||
}, | ||
[`${homeHref}/page-2`]: { | ||
href: `${homeHref}/page-2`, | ||
itemId: `${homeHref}/page-2`, | ||
parentId: "pages", | ||
children: "Page 2", | ||
leftAddon: <FavoriteIcon />, | ||
}, | ||
...layouts, | ||
}; | ||
}, [layout]); | ||
const tree = useLayoutTree({ | ||
navItems, | ||
pathname, | ||
defaultExpandedIds: ["layouts", "pages"], | ||
}); | ||
|
||
return ( | ||
<> | ||
<Tree | ||
aria-label="Navigation" | ||
{...tree} | ||
sort={sort} | ||
linkComponent={LinkUnstyled} | ||
/> | ||
<footer | ||
className={box({ | ||
justify: "stretch", | ||
fullWidth: true, | ||
disableWrap: true, | ||
className: cssUtils({ textOverflow: "ellipsis" }), | ||
})} | ||
> | ||
<ButtonStyledLink | ||
style={{ flex: "1 1 auto", justifyContent: "flex-start" }} | ||
href={`/getting-started/layout#${layout}-navigation-layout`} | ||
theme="secondary" | ||
themeType="contained" | ||
> | ||
<ExitToAppIcon /> | ||
<span className={cssUtils({ textOverflow: "ellipsis" })}> | ||
Back to layout docs | ||
</span> | ||
</ButtonStyledLink> | ||
</footer> | ||
</> | ||
); | ||
} |
3 changes: 3 additions & 0 deletions
3
.../docs/src/app/(layout-examples)/layout-example/[layout]/NavigationTreeExample.module.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.navigation { | ||
grid-template-rows: 1fr min-content; | ||
} |
Oops, something went wrong.