Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs-site/src/css/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ html {
--gusto-code-block-bg: #f7f7f8;
--gusto-body-text-color: rgba(27, 27, 29, 0.82);

--ifm-heading-color: #000000;

--docusaurus-highlighted-code-line-bg: rgba(241, 94, 73, 0.1);
}

Expand Down Expand Up @@ -89,6 +91,8 @@ html {
--gusto-code-block-bg: #2a2a2d;
--gusto-body-text-color: rgba(255, 255, 255, 0.72);

--ifm-heading-color: #ffffff;

--docusaurus-highlighted-code-line-bg: rgba(241, 94, 73, 0.15);
}

Expand Down
21 changes: 21 additions & 0 deletions docs-site/src/theme/DocCard/Description/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React, { type ReactNode } from 'react'
import clsx from 'clsx'
import { ThemeClassNames } from '@docusaurus/theme-common'
import type { Props } from '@theme/DocCard/Description'

import styles from './styles.module.css'

export default function DocCardDescription({ description }: Props): ReactNode {
return (
<p
className={clsx(
'text--truncate',
ThemeClassNames.docs.docCard.description,
styles.cardDescription,
)}
title={description}
>
{description}
</p>
)
}
10 changes: 10 additions & 0 deletions docs-site/src/theme/DocCard/Description/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.cardDescription {
font-size: 0.95rem;
line-height: 1.6;
color: #525860;
margin: 0;
}

[data-theme='dark'] .cardDescription {
color: rgba(255, 255, 255, 0.65);
}
12 changes: 12 additions & 0 deletions docs-site/src/theme/DocCard/Heading/Icon/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React, { type ReactNode } from 'react'
import clsx from 'clsx'
import { ThemeClassNames } from '@docusaurus/theme-common'
import type { Props } from '@theme/DocCard/Heading/Icon'

import styles from './styles.module.css'

export default function DocCardHeadingIcon({ icon }: Props): ReactNode {
return (
<span className={clsx(ThemeClassNames.docs.docCard.icon, styles.cardTitleIcon)}>{icon}</span>
)
}
4 changes: 4 additions & 0 deletions docs-site/src/theme/DocCard/Heading/Icon/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.cardTitleIcon {
font-size: 1.6rem;
margin-right: 0.6rem;
}
21 changes: 21 additions & 0 deletions docs-site/src/theme/DocCard/Heading/Text/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React, { type ReactNode } from 'react'
import clsx from 'clsx'
import { ThemeClassNames } from '@docusaurus/theme-common'
import type { Props } from '@theme/DocCard/Heading/Text'

import styles from './styles.module.css'

export default function DocCardHeadingText({ title }: Props): ReactNode {
return (
<span
className={clsx(
'text--truncate',

ThemeClassNames.docs.docCard.title,
styles.cardTitleText,
)}
>
{title}
</span>
)
}
10 changes: 10 additions & 0 deletions docs-site/src/theme/DocCard/Heading/Text/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.cardTitleText {
font-size: 1.25rem;
font-weight: 600;
letter-spacing: -0.01em;
color: #1b1b1d;
}

[data-theme='dark'] .cardTitleText {
color: #ffffff;
}
22 changes: 22 additions & 0 deletions docs-site/src/theme/DocCard/Heading/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React, { type ReactNode } from 'react'
import clsx from 'clsx'
import { ThemeClassNames } from '@docusaurus/theme-common'
import Heading from '@theme/Heading'
import Icon from '@theme/DocCard/Heading/Icon'
import Text from '@theme/DocCard/Heading/Text'
import type { Props } from '@theme/DocCard/Heading'

import styles from './styles.module.css'

export default function DocCardHeading({ item, title, icon }: Props): ReactNode {
return (
<Heading
as="h2"
className={clsx(ThemeClassNames.docs.docCard.heading, styles.cardTitle)}
title={title}
>
{icon && <Icon item={item} icon={icon} />}
<Text item={item} title={title} />
</Heading>
)
}
5 changes: 5 additions & 0 deletions docs-site/src/theme/DocCard/Heading/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.cardTitle {
display: inline-flex;
align-items: center;
margin: 0 0 0.5rem 0;
}
49 changes: 49 additions & 0 deletions docs-site/src/theme/DocCard/Layout/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React, { type ReactNode } from 'react'
import clsx from 'clsx'
import Link from '@docusaurus/Link'
import { ThemeClassNames } from '@docusaurus/theme-common'
import Heading from '@theme/DocCard/Heading'
import Description from '@theme/DocCard/Description'
import type { Props } from '@theme/DocCard/Layout'

import styles from './styles.module.css'

function Container({
className,
href,
children,
}: {
className?: string
href: string
children: ReactNode
}): ReactNode {
return (
<Link
href={href}
className={clsx(
'card padding--lg',
ThemeClassNames.docs.docCard.container,
styles.cardContainer,
className,
)}
>
{children}
</Link>
)
}

export default function DocCardLayout({
item,
className,
href,
icon,
title,
description,
}: Props): ReactNode {
return (
<Container href={href} className={className}>
<Heading item={item} icon={icon} title={title} />
{description && <Description item={item} description={description} />}
</Container>
)
}
36 changes: 36 additions & 0 deletions docs-site/src/theme/DocCard/Layout/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.cardContainer {
--ifm-link-color: var(--ifm-color-emphasis-800);
--ifm-link-hover-color: var(--ifm-color-emphasis-700);
--ifm-link-hover-decoration: none;

display: block;
height: 100%;
padding: 2rem;
background-color: #ffffff;
border: 1px solid #ebedf0;
border-radius: 16px;
box-shadow: none;
color: inherit;
text-decoration: none;
transition: border-color 0.15s ease;
}

.cardContainer:hover {
border-color: #d0d3d8;
box-shadow: none;
text-decoration: none;
color: inherit;
}

[data-theme='dark'] .cardContainer {
background-color: rgba(255, 255, 255, 0.03);
border-color: rgba(255, 255, 255, 0.1);
}

[data-theme='dark'] .cardContainer:hover {
border-color: rgba(255, 255, 255, 0.22);
}

.cardContainer *:last-child {
margin-bottom: 0;
}
73 changes: 73 additions & 0 deletions docs-site/src/theme/DocCard/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React, { type ReactNode } from 'react'
import { useDocById, findFirstSidebarItemLink } from '@docusaurus/plugin-content-docs/client'
import {
extractLeadingEmoji,
useDocCardDescriptionCategoryItemsPlural,
} from '@docusaurus/theme-common/internal'
import isInternalUrl from '@docusaurus/isInternalUrl'
import Layout from '@theme/DocCard/Layout'

import type { Props } from '@theme/DocCard'
import type { PropSidebarItemCategory, PropSidebarItemLink } from '@docusaurus/plugin-content-docs'

function getFallbackEmojiIcon(item: PropSidebarItemLink | PropSidebarItemCategory): string {
if (item.type === 'category') {
return '🗃'
}
return isInternalUrl(item.href) ? '📄️' : '🔗'
}

function getIconTitleProps(item: PropSidebarItemLink | PropSidebarItemCategory): {
icon: ReactNode
title: string
} {
const extracted = extractLeadingEmoji(item.label)
const emoji = extracted.emoji ?? getFallbackEmojiIcon(item)
return {
icon: emoji,
title: extracted.rest.trim(),
}
}

function CardCategory({ item }: { item: PropSidebarItemCategory }): ReactNode {
const href = findFirstSidebarItemLink(item)
const categoryItemsPlural = useDocCardDescriptionCategoryItemsPlural()

// Unexpected: categories that don't have a link have been filtered upfront
if (!href) {
return null
}
return (
<Layout
item={item}
className={item.className}
href={href}
description={item.description ?? categoryItemsPlural(item.items.length)}
{...getIconTitleProps(item)}
/>
)
}

function CardLink({ item }: { item: PropSidebarItemLink }): ReactNode {
const doc = useDocById(item.docId ?? undefined)
return (
<Layout
item={item}
className={item.className}
href={item.href}
description={item.description ?? doc?.description}
{...getIconTitleProps(item)}
/>
)
}

export default function DocCard({ item }: Props): ReactNode {
switch (item.type) {
case 'link':
return <CardLink item={item} />
case 'category':
return <CardCategory item={item} />
default:
throw new Error(`unknown item type ${JSON.stringify(item)}`)
}
}
37 changes: 37 additions & 0 deletions docs-site/src/theme/DocCardList/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React, { type ComponentProps, type ReactNode } from 'react'
import clsx from 'clsx'
import {
useCurrentSidebarSiblings,
filterDocCardListItems,
} from '@docusaurus/plugin-content-docs/client'
import DocCard from '@theme/DocCard'
import type { Props } from '@theme/DocCardList'
import styles from './styles.module.css'

function DocCardListForCurrentSidebarCategory({ className }: Props) {
const items = useCurrentSidebarSiblings()
return <DocCardList items={items} className={className} />
}

function DocCardListItem({ item }: { item: ComponentProps<typeof DocCard>['item'] }) {
return (
<article className={clsx(styles.docCardListItem, 'col col--6')}>
<DocCard item={item} />
</article>
)
}

export default function DocCardList(props: Props): ReactNode {
const { items, className } = props
if (!items) {
return <DocCardListForCurrentSidebarCategory {...props} />
}
const filteredItems = filterDocCardListItems(items)
return (
<section className={clsx('row', className)}>
{filteredItems.map((item, index) => (
<DocCardListItem key={index} item={item} />
))}
</section>
)
}
7 changes: 7 additions & 0 deletions docs-site/src/theme/DocCardList/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.docCardListItem {
margin-bottom: 2rem;
}

.docCardListItem > * {
height: 100%;
}
Loading