-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Brand styling for pagination and breadcrumbs
- Loading branch information
Showing
8 changed files
with
263 additions
and
2 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
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
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,111 @@ | ||
import React from 'react'; | ||
import clsx from 'clsx'; | ||
import { ThemeClassNames } from '@docusaurus/theme-common'; | ||
import { | ||
useSidebarBreadcrumbs, | ||
useHomePageRoute, | ||
} from '@docusaurus/theme-common/internal'; | ||
import Link from '@docusaurus/Link'; | ||
import useBaseUrl from '@docusaurus/useBaseUrl'; | ||
import { translate } from '@docusaurus/Translate'; | ||
import IconHome from '@theme/Icon/Home'; | ||
import styles from './styles.module.css'; | ||
// TODO move to design system folder | ||
function BreadcrumbsItemLink({ children, href, isLast }) { | ||
const className = 'breadcrumbs__link'; | ||
if (isLast) { | ||
return ( | ||
<span className={className} itemProp="name"> | ||
{children} | ||
</span> | ||
); | ||
} | ||
return href ? ( | ||
<Link className={className} href={href} itemProp="item"> | ||
<span itemProp="name">{children}</span> | ||
</Link> | ||
) : ( | ||
// TODO Google search console doesn't like breadcrumb items without href. | ||
// The schema doesn't seem to require `id` for each `item`, although Google | ||
// insist to infer one, even if it's invalid. Removing `itemProp="item | ||
// name"` for now, since I don't know how to properly fix it. | ||
// See https://github.com/facebook/docusaurus/issues/7241 | ||
<span className={className}>{children}</span> | ||
); | ||
} | ||
// TODO move to design system folder | ||
function BreadcrumbsItem({ children, active, index, addMicrodata }) { | ||
return ( | ||
<li | ||
{...(addMicrodata && { | ||
itemScope: true, | ||
itemProp: 'itemListElement', | ||
itemType: 'https://schema.org/ListItem', | ||
})} | ||
className={clsx('breadcrumbs__item', { | ||
'breadcrumbs__item--active': active, | ||
})}> | ||
{children} | ||
<meta itemProp="position" content={String(index + 1)} /> | ||
</li> | ||
); | ||
} | ||
function HomeBreadcrumbItem() { | ||
const homeHref = useBaseUrl('/'); | ||
return ( | ||
<li className={clsx( | ||
"breadcrumbs__item" | ||
)}> | ||
<Link | ||
aria-label={translate({ | ||
id: 'theme.docs.breadcrumbs.home', | ||
message: 'Home page', | ||
description: 'The ARIA label for the home page in the breadcrumbs', | ||
})} | ||
className={clsx('breadcrumbs__link', styles.breadcrumbsItemLink)} | ||
href={homeHref}> | ||
<IconHome className={styles.breadcrumbHomeIcon} /> | ||
</Link> | ||
</li> | ||
); | ||
} | ||
export default function DocBreadcrumbs() { | ||
const breadcrumbs = useSidebarBreadcrumbs(); | ||
const homePageRoute = useHomePageRoute(); | ||
if (!breadcrumbs) { | ||
return null; | ||
} | ||
return ( | ||
<nav | ||
className={clsx( | ||
ThemeClassNames.docs.docBreadcrumbs, | ||
'pt-4' | ||
)} | ||
aria-label={translate({ | ||
id: 'theme.docs.breadcrumbs.navAriaLabel', | ||
message: 'Breadcrumbs', | ||
description: 'The ARIA label for the breadcrumbs', | ||
})}> | ||
<ul | ||
className="breadcrumbs" | ||
itemScope | ||
itemType="https://schema.org/BreadcrumbList"> | ||
{homePageRoute && <HomeBreadcrumbItem />} | ||
{breadcrumbs.map((item, idx) => { | ||
const isLast = idx === breadcrumbs.length - 1; | ||
return ( | ||
<BreadcrumbsItem | ||
key={idx} | ||
active={isLast} | ||
index={idx} | ||
addMicrodata={!!item.href}> | ||
<BreadcrumbsItemLink href={item.href} isLast={isLast}> | ||
{item.label} | ||
</BreadcrumbsItemLink> | ||
</BreadcrumbsItem> | ||
); | ||
})} | ||
</ul> | ||
</nav> | ||
); | ||
} |
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,8 @@ | ||
.breadcrumbHomeIcon { | ||
position: relative; | ||
top: 1px; | ||
vertical-align: top; | ||
height: 1.5rem; | ||
width: 1.6rem; | ||
color: var(--ifm-color-primary); | ||
} |
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,11 @@ | ||
import React from 'react'; | ||
import {useDoc} from '@docusaurus/theme-common/internal'; | ||
import DocPaginator from '@theme/DocPaginator'; | ||
/** | ||
* This extra component is needed, because <DocPaginator> should remain generic. | ||
* DocPaginator is used in non-docs contexts too: generated-index pages... | ||
*/ | ||
export default function DocItemPaginator() { | ||
const {metadata} = useDoc(); | ||
return <DocPaginator previous={metadata.previous} next={metadata.next} />; | ||
} |
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,41 @@ | ||
import React from 'react'; | ||
import Translate, { translate } from '@docusaurus/Translate'; | ||
import PaginatorNavLink from '@theme/PaginatorNavLink'; | ||
export default function DocPaginator(props) { | ||
const { previous, next } = props; | ||
return ( | ||
<nav | ||
className="pagination-nav docusaurus-mt-lg" | ||
aria-label={translate({ | ||
id: 'theme.docs.paginator.navAriaLabel', | ||
message: 'Docs pages navigation', | ||
description: 'The ARIA label for the docs pagination', | ||
})}> | ||
{previous && ( | ||
<PaginatorNavLink | ||
{...previous} | ||
subLabel={ | ||
<Translate | ||
id="theme.docs.paginator.previous" | ||
description="The label used to navigate to the previous doc"> | ||
Previous | ||
</Translate> | ||
} | ||
/> | ||
)} | ||
{next && ( | ||
<PaginatorNavLink | ||
{...next} | ||
subLabel={ | ||
<Translate | ||
id="theme.docs.paginator.next" | ||
description="The label used to navigate to the next doc"> | ||
Next | ||
</Translate> | ||
} | ||
isNext | ||
/> | ||
)} | ||
</nav> | ||
); | ||
} |
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
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,85 @@ | ||
import React from 'react'; | ||
import clsx from 'clsx'; | ||
import Link from '@docusaurus/Link'; | ||
import { motion, useMotionTemplate, useMotionValue } from 'framer-motion' | ||
import { GridPattern } from '../../components/GridPattern'; | ||
|
||
export default function PaginatorNavLink(props) { | ||
const { permalink, title, subLabel, isNext } = props; | ||
|
||
let mouseX = useMotionValue(0) | ||
let mouseY = useMotionValue(0) | ||
|
||
function onMouseMove({ currentTarget, clientX, clientY }) { | ||
let { left, top } = currentTarget.getBoundingClientRect() | ||
mouseX.set(clientX - left) | ||
mouseY.set(clientY - top) | ||
} | ||
|
||
let pattern = { | ||
y: 48, | ||
squares: isNext ? [ | ||
[-1, 0], | ||
[0, -1], | ||
[-2, -1], | ||
] : [ | ||
[2, 0], | ||
[0, 1], | ||
[-1, 0], | ||
], | ||
}; | ||
|
||
return ( | ||
<Link | ||
onMouseMove={onMouseMove} | ||
className={clsx( | ||
'pagination-nav__link', | ||
'group relative', | ||
'bg-zinc-50', | ||
'transition-shadow shadow-lg hover:shadow-lg hover:shadow-zinc-900/5', | ||
'display-inline', | ||
isNext ? 'pagination-nav__link--next' : 'pagination-nav__link--prev', | ||
)} | ||
to={permalink}> | ||
<FeaturePattern {...pattern} mouseX={mouseX} mouseY={mouseY} /> | ||
{subLabel && <div className="pagination-nav__sublabel">{subLabel}</div>} | ||
<div className="pagination-nav__label">{title}</div> | ||
</Link> | ||
); | ||
} | ||
|
||
|
||
function FeaturePattern({ mouseX, mouseY, ...gridProps }) { | ||
let maskImage = useMotionTemplate`radial-gradient(180px at ${mouseX}px ${mouseY}px, white, transparent)` | ||
let style = { maskImage, WebkitMaskImage: maskImage } | ||
|
||
return ( | ||
<div className="pointer-events-none"> | ||
<div className="absolute inset-0 rounded-2xl transition duration-300 [mask-image:linear-gradient(white,transparent)] group-hover:opacity-50"> | ||
<GridPattern | ||
width={72} | ||
height={56} | ||
x="50%" | ||
className="absolute inset-x-0 inset-y-[-30%] h-[160%] w-full skew-y-[-18deg] fill-black/[0.02] stroke-black/5" | ||
{...gridProps} | ||
/> | ||
</div> | ||
<motion.div | ||
className="absolute inset-0 rounded-2xl bg-gradient-to-r from-[#d7e6ed] to-[#e0e8f6] opacity-0 transition duration-300 group-hover:opacity-100" | ||
style={style} | ||
/> | ||
<motion.div | ||
className="absolute inset-0 transition duration-300 opacity-0 rounded-2xl mix-blend-overlay group-hover:opacity-100" | ||
style={style} | ||
> | ||
<GridPattern | ||
width={72} | ||
height={56} | ||
x="50%" | ||
className="absolute inset-x-0 inset-y-[-30%] h-[160%] w-full skew-y-[-18deg] fill-black/50 stroke-black/70" | ||
{...gridProps} | ||
/> | ||
</motion.div> | ||
</div> | ||
) | ||
} |