-
Notifications
You must be signed in to change notification settings - Fork 840
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[EUI+] Implement Breadcrumbs design changes (#7885)
- Loading branch information
Showing
14 changed files
with
851 additions
and
4 deletions.
There are no files selected for viewing
30 changes: 30 additions & 0 deletions
30
packages/docusaurus-theme/src/theme/DocBreadcrumbs/Items/Home/index.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,30 @@ | ||
import React from 'react'; | ||
import Link from '@docusaurus/Link'; | ||
import useBaseUrl from '@docusaurus/useBaseUrl'; | ||
import { translate } from '@docusaurus/Translate'; | ||
import { EuiIcon, useEuiMemoizedStyles } from '@elastic/eui'; | ||
|
||
import { getItemStyles } from '../item.styles'; | ||
|
||
export default function HomeBreadcrumbItem(): JSX.Element { | ||
const homeHref = useBaseUrl('/'); | ||
|
||
const styles = useEuiMemoizedStyles(getItemStyles); | ||
|
||
return ( | ||
<li className="breadcrumbs__item" css={styles.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="breadcrumbs__link" | ||
href={homeHref} | ||
> | ||
EUI | ||
</Link> | ||
<EuiIcon type="arrowRight" size="s" css={styles.icon} /> | ||
</li> | ||
); | ||
} |
35 changes: 35 additions & 0 deletions
35
packages/docusaurus-theme/src/theme/DocBreadcrumbs/Items/item.styles.ts
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,35 @@ | ||
import { css } from '@emotion/react'; | ||
import { UseEuiTheme } from '@elastic/eui'; | ||
|
||
export const getItemStyles = ({ euiTheme }: UseEuiTheme) => ({ | ||
item: css` | ||
--ifm-breadcrumb-item-background: transparent; | ||
--ifm-breadcrumb-item-background-active: transparent; | ||
// overwrite global styles | ||
&.breadcrumbs__item:not(:last-child):after { | ||
content: none; | ||
} | ||
.breadcrumbs__link { | ||
padding: 0 ${euiTheme.size.m}; | ||
font-size: var(--eui-font-size-xs); | ||
line-height: var(--eui-line-height-m); | ||
} | ||
a.breadcrumbs__link { | ||
color: ${euiTheme.colors.link}; | ||
font-weight: ${euiTheme.font.weight.bold}; | ||
text-decoration: underline; | ||
} | ||
&.breadcrumbs__item--active .breadcrumbs__link { | ||
color: ${euiTheme.colors.text}; | ||
} | ||
`, | ||
icon: css` | ||
block-size: ${euiTheme.size.s}; | ||
inline-size: ${euiTheme.size.s}; | ||
fill: ${euiTheme.colors.text}; | ||
`, | ||
}); |
138 changes: 138 additions & 0 deletions
138
packages/docusaurus-theme/src/theme/DocBreadcrumbs/index.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,138 @@ | ||
import React, { type ReactNode } from 'react'; | ||
import clsx from 'clsx'; | ||
import { css } from '@emotion/react'; | ||
import { ThemeClassNames } from '@docusaurus/theme-common'; | ||
import { | ||
useSidebarBreadcrumbs, | ||
useHomePageRoute, | ||
} from '@docusaurus/theme-common/internal'; | ||
import Link from '@docusaurus/Link'; | ||
import { translate } from '@docusaurus/Translate'; | ||
import { EuiIcon, useEuiMemoizedStyles, UseEuiTheme } from '@elastic/eui'; | ||
|
||
import HomeBreadcrumbItem from './Items/Home'; | ||
import { getItemStyles } from './Items/item.styles'; | ||
|
||
// converted from css modules to Emotion | ||
const getStyles = ({ euiTheme }: UseEuiTheme) => ({ | ||
breadcrumbsContainer: css` | ||
--ifm-breadcrumb-size-multiplier: 0.8; | ||
// align breadcrumb items with content | ||
margin-inline-start: -${euiTheme.size.m}; | ||
`, | ||
}); | ||
|
||
// TODO move to design system folder | ||
function BreadcrumbsItemLink({ | ||
children, | ||
href, | ||
isLast, | ||
}: { | ||
children: ReactNode; | ||
href: string | undefined; | ||
isLast: boolean; | ||
}): JSX.Element { | ||
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> | ||
); | ||
} | ||
|
||
function BreadcrumbsItem({ | ||
children, | ||
active, | ||
index, | ||
addMicrodata, | ||
}: { | ||
children: ReactNode; | ||
active?: boolean; | ||
index: number; | ||
addMicrodata: boolean; | ||
}): JSX.Element { | ||
const styles = useEuiMemoizedStyles(getItemStyles); | ||
|
||
return ( | ||
<li | ||
{...(addMicrodata && { | ||
itemScope: true, | ||
itemProp: 'itemListElement', | ||
itemType: 'https://schema.org/ListItem', | ||
})} | ||
className={clsx('breadcrumbs__item', { | ||
'breadcrumbs__item--active': active, | ||
})} | ||
css={styles.item} | ||
> | ||
{children} | ||
<meta itemProp="position" content={String(index + 1)} /> | ||
{!active && <EuiIcon type="arrowRight" css={styles.icon} />} | ||
</li> | ||
); | ||
} | ||
|
||
export default function DocBreadcrumbs(): JSX.Element | null { | ||
const breadcrumbs = useSidebarBreadcrumbs(); | ||
const homePageRoute = useHomePageRoute(); | ||
|
||
const styles = useEuiMemoizedStyles(getStyles); | ||
|
||
if (!breadcrumbs) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<nav | ||
className={clsx(ThemeClassNames.docs.docBreadcrumbs)} | ||
aria-label={translate({ | ||
id: 'theme.docs.breadcrumbs.navAriaLabel', | ||
message: 'Breadcrumbs', | ||
description: 'The ARIA label for the breadcrumbs', | ||
})} | ||
css={styles.breadcrumbsContainer} | ||
> | ||
<ul | ||
className="breadcrumbs" | ||
itemScope | ||
itemType="https://schema.org/BreadcrumbList" | ||
> | ||
{homePageRoute && <HomeBreadcrumbItem />} | ||
{breadcrumbs.map((item, idx) => { | ||
const isLast = idx === breadcrumbs.length - 1; | ||
const href = | ||
item.type === 'category' && item.linkUnlisted | ||
? undefined | ||
: item.href; | ||
return ( | ||
<BreadcrumbsItem | ||
key={idx} | ||
active={isLast} | ||
index={idx} | ||
addMicrodata={!!href} | ||
> | ||
<BreadcrumbsItemLink href={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
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
53 changes: 53 additions & 0 deletions
53
packages/docusaurus-theme/src/theme/DocRoot/Layout/Main/index.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 @@ | ||
import React from 'react'; | ||
import clsx from 'clsx'; | ||
import { css } from '@emotion/react'; | ||
import { useDocsSidebar } from '@docusaurus/theme-common/internal'; | ||
import type { Props } from '@theme-original/DocRoot/Layout/Main'; | ||
|
||
// converted from css modules to Emotion | ||
const styles = { | ||
docMainContainer: css` | ||
display: flex; | ||
width: 100%; | ||
@media (min-width: 997px) { | ||
flex-grow: 1; | ||
max-width: calc(100% - var(--doc-sidebar-width)); | ||
} | ||
`, | ||
docMainContainerEnhanced: css` | ||
@media (min-width: 997px) { | ||
max-width: calc(100% - var(--doc-sidebar-hidden-width)); | ||
} | ||
`, | ||
docItemWrapperEnhanced: css` | ||
@media (min-width: 997px) { | ||
max-width: calc( | ||
var(--ifm-container-width) + var(--doc-sidebar-width) | ||
) !important; | ||
} | ||
`, | ||
}; | ||
|
||
export default function DocRootLayoutMain({ | ||
hiddenSidebarContainer, | ||
children, | ||
}: any): JSX.Element { | ||
const sidebar = useDocsSidebar(); | ||
return ( | ||
<main | ||
className={clsx(styles.docMainContainer)} | ||
css={[ | ||
styles.docMainContainer, | ||
(hiddenSidebarContainer || !sidebar) && styles.docMainContainerEnhanced, | ||
]} | ||
> | ||
<div | ||
className="container padding-top--md padding-bottom--lg" | ||
css={[hiddenSidebarContainer && styles.docItemWrapperEnhanced]} | ||
> | ||
{children} | ||
</div> | ||
</main> | ||
); | ||
} |
60 changes: 60 additions & 0 deletions
60
packages/docusaurus-theme/src/theme/DocRoot/Layout/Sidebar/ExpandButton/index.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,60 @@ | ||
import React from 'react'; | ||
import { css } from '@emotion/react'; | ||
import { translate } from '@docusaurus/Translate'; | ||
import IconArrow from '@theme-original/Icon/Arrow'; | ||
|
||
import type { Props } from '@theme-original/DocRoot/Layout/Sidebar/ExpandButton'; | ||
|
||
// converted from css modules to Emotion | ||
const styles = { | ||
expandButton: css` | ||
@media (min-width: 997px) { | ||
position: absolute; | ||
top: 0; | ||
right: 0; | ||
width: 100%; | ||
height: 100%; | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
transition: background-color var(--ifm-transition-fast) ease; | ||
background-color: var(--docusaurus-collapse-button-bg); | ||
&:hover, | ||
&:focus { | ||
background-color: var(--docusaurus-collapse-button-bg-hover); | ||
} | ||
} | ||
`, | ||
expandButtonIcon: css` | ||
transform: rotate(0); | ||
`, | ||
}; | ||
|
||
export default function DocRootLayoutSidebarExpandButton({ | ||
toggleSidebar, | ||
}: Props): JSX.Element { | ||
return ( | ||
<div | ||
css={styles.expandButton} | ||
title={translate({ | ||
id: 'theme.docs.sidebar.expandButtonTitle', | ||
message: 'Expand sidebar', | ||
description: | ||
'The ARIA label and title attribute for expand button of doc sidebar', | ||
})} | ||
aria-label={translate({ | ||
id: 'theme.docs.sidebar.expandButtonAriaLabel', | ||
message: 'Expand sidebar', | ||
description: | ||
'The ARIA label and title attribute for expand button of doc sidebar', | ||
})} | ||
tabIndex={0} | ||
role="button" | ||
onKeyDown={toggleSidebar} | ||
onClick={toggleSidebar} | ||
> | ||
<IconArrow css={styles.expandButtonIcon} /> | ||
</div> | ||
); | ||
} |
Oops, something went wrong.