diff options
Diffstat (limited to 'components')
-rw-r--r-- | components/BreadCrumbs/breadcrumbs.module.scss (renamed from components/Breadcrumbs/breadcrumbs.module.scss) | 0 | ||||
-rw-r--r-- | components/BreadCrumbs/index.tsx (renamed from components/Breadcrumbs/index.tsx) | 6 | ||||
-rw-r--r-- | components/PathCrumbs/index.tsx | 60 |
3 files changed, 63 insertions, 3 deletions
diff --git a/components/Breadcrumbs/breadcrumbs.module.scss b/components/BreadCrumbs/breadcrumbs.module.scss index 6facea4..6facea4 100644 --- a/components/Breadcrumbs/breadcrumbs.module.scss +++ b/components/BreadCrumbs/breadcrumbs.module.scss diff --git a/components/Breadcrumbs/index.tsx b/components/BreadCrumbs/index.tsx index d773b33..693a9d0 100644 --- a/components/Breadcrumbs/index.tsx +++ b/components/BreadCrumbs/index.tsx @@ -3,13 +3,13 @@ import Link from "next/link"; import styles from './breadcrumbs.module.scss'; import clsx from 'clsx'; -export type BreadcrumbsProps = { +export type BreadCrumbsProps = { className?: string; style?: object; children: React.ReactNode; }; -const Breadcrumbs : FC<BreadcrumbsProps> = ({children, className, ...props}) => ( +const BreadCrumbs : FC<BreadCrumbsProps> = ({children, className, ...props}) => ( <span className={clsx(styles.breadcrumbs, className)} {...props}> {Children.map(children, (child, index) => { return ( @@ -51,6 +51,6 @@ const LinkCrumb : FC<LinkCrumbProps> = ({children, href, ...props}) => ( export { Crumb, - Breadcrumbs, + BreadCrumbs, LinkCrumb }; diff --git a/components/PathCrumbs/index.tsx b/components/PathCrumbs/index.tsx new file mode 100644 index 0000000..1c87344 --- /dev/null +++ b/components/PathCrumbs/index.tsx @@ -0,0 +1,60 @@ +import React, { FC } from 'react'; + +import assert from '../../utils/assert'; +import { DISPLAY_DOMAIN } from '../../utils/env'; + +const urlPathComponents = (path : string): string[] => { + assert(path.length > 0, "empty path"); + + let canonicalizedPath = path[path.length - 1] === '/' ? + path.substr(0, path.length - 1) : path; + + if(canonicalizedPath.length === 0) { + return []; + } else { + canonicalizedPath = canonicalizedPath[0] == '/' ? + path.substr(1, path.length - 1) : path; + } + + return canonicalizedPath.split('/') +} + +const urlPathComponentsToFullPath = (urlPathComponents : string[]): string[] => { + const fullPaths = new Array<string>(urlPathComponents.length + 1); + + fullPaths[0] = ''; + + for(let i = 0; i < urlPathComponents.length; i++) { + fullPaths[i + 1] = fullPaths[i] + '/' + urlPathComponents[i]; + } + + fullPaths[0] = '/'; + + return fullPaths; +}; + +export type PathCrumbsProps = { + path: string +}; + +import { BreadCrumbs , LinkCrumb } from '../../components/BreadCrumbs'; + +const PathCrumbs: FC<PathCrumbsProps> = ({ path }) => { + + const pathComponents = urlPathComponents(path); + const fullPaths = urlPathComponentsToFullPath(pathComponents); + + const linksComponents = fullPaths.map((fullPath, i) => ( + <LinkCrumb href={fullPath} key={fullPath}> + { i === 0 ? DISPLAY_DOMAIN : pathComponents[i - 1] } + </LinkCrumb> + )); + + return ( + <BreadCrumbs> + {linksComponents} + </BreadCrumbs> + ); +}; + +export default PathCrumbs; |