packages/docusaurus-theme-classic/src/theme/DocCard/index.tsx (101 lines of code) (raw):

/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import React, {type ReactNode} from 'react'; import Link from '@docusaurus/Link'; import type { PropSidebarItemCategory, PropSidebarItemLink, } from '@docusaurus/plugin-content-docs'; import type {Props} from '@theme/DocCard'; import {findFirstCategoryLink, useDocById} from '@docusaurus/theme-common'; import clsx from 'clsx'; import styles from './styles.module.css'; import isInternalUrl from '@docusaurus/isInternalUrl'; import {translate} from '@docusaurus/Translate'; function CardContainer({ href, children, }: { href: string; children: ReactNode; }): JSX.Element { return ( <Link href={href} className={clsx('card padding--lg', styles.cardContainer)}> {children} </Link> ); } function CardLayout({ href, icon, title, description, }: { href: string; icon: ReactNode; title: string; description?: string; }): JSX.Element { return ( <CardContainer href={href}> <h2 className={clsx('text--truncate', styles.cardTitle)} title={title}> {icon} {title} </h2> {description && ( <p className={clsx('text--truncate', styles.cardDescription)} title={description}> {description} </p> )} </CardContainer> ); } function CardCategory({ item, }: { item: PropSidebarItemCategory; }): JSX.Element | null { const href = findFirstCategoryLink(item); // Unexpected: categories that don't have a link have been filtered upfront if (!href) { return null; } return ( <CardLayout href={href} icon="🗃️" title={item.label} description={translate( { message: '{count} items', id: 'theme.docs.DocCard.categoryDescription', description: 'The default description for a category card in the generated index about how many items this category includes', }, {count: item.items.length}, )} /> ); } function CardLink({item}: {item: PropSidebarItemLink}): JSX.Element { const icon = isInternalUrl(item.href) ? '📄️' : '🔗'; const doc = useDocById(item.docId ?? undefined); return ( <CardLayout href={item.href} icon={icon} title={item.label} description={doc?.description} /> ); } export default function DocCard({item}: Props): JSX.Element { 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)}`); } }