diff --git a/docuilib/sidebars.js b/docuilib/sidebars.js
index 3a041c11ad..2cdaa086a8 100644
--- a/docuilib/sidebars.js
+++ b/docuilib/sidebars.js
@@ -64,6 +64,10 @@ module.exports = {
type: 'category',
label: componentsCategories[category],
collapsed: true,
+ link: {
+ type: 'generated-index',
+ keywords: [category]
+ },
items: [
{
type: 'autogenerated',
diff --git a/docuilib/src/theme/DocCard/index.tsx b/docuilib/src/theme/DocCard/index.tsx
new file mode 100644
index 0000000000..18ed8956fe
--- /dev/null
+++ b/docuilib/src/theme/DocCard/index.tsx
@@ -0,0 +1,54 @@
+import React, {type ReactNode} from 'react';
+import clsx from 'clsx';
+import Link from '@docusaurus/Link';
+import {findFirstSidebarItemLink} from '@docusaurus/plugin-content-docs/client';
+
+import type {Props} from '@theme/DocCard';
+import Heading from '@theme/Heading';
+import type {PropSidebarItemCategory, PropSidebarItemLink} from '@docusaurus/plugin-content-docs';
+
+import styles from './styles.module.css';
+
+function CardContainer({href, children}: {href: string; children: ReactNode}): JSX.Element {
+ return (
+
+ {children}
+
+ );
+}
+
+function CardLayout({href, title}: {href: string; title: string}): JSX.Element {
+ return (
+
+
+ {title}
+
+
+ );
+}
+
+function CardCategory({item}: {item: PropSidebarItemCategory}): JSX.Element | null {
+ const href = findFirstSidebarItemLink(item);
+
+ // Unexpected: categories that don't have a link have been filtered upfront
+ if (!href) {
+ return null;
+ }
+
+ return ;
+}
+
+function CardLink({item}: {item: PropSidebarItemLink}): JSX.Element {
+ return ;
+}
+
+export default function DocCard({item}: Props): JSX.Element {
+ switch (item.type) {
+ case 'link':
+ return ;
+ case 'category':
+ return ;
+ default:
+ throw new Error(`unknown item type ${JSON.stringify(item)}`);
+ }
+}
diff --git a/docuilib/src/theme/DocCard/styles.module.css b/docuilib/src/theme/DocCard/styles.module.css
new file mode 100644
index 0000000000..4f7ad27f40
--- /dev/null
+++ b/docuilib/src/theme/DocCard/styles.module.css
@@ -0,0 +1,27 @@
+.cardContainer {
+ --ifm-link-color: var(--ifm-color-emphasis-800);
+ --ifm-link-hover-color: var(--ifm-color-emphasis-700);
+ --ifm-link-hover-decoration: none;
+
+ box-shadow: 0 1.5px 3px 0 rgb(0 0 0 / 15%);
+ border: 1px solid var(--ifm-color-emphasis-200);
+ transition: all var(--ifm-transition-fast) ease;
+ transition-property: border, box-shadow;
+}
+
+.cardContainer:hover {
+ border-color: var(--ifm-color-primary);
+ box-shadow: 0 3px 6px 0 rgb(0 0 0 / 20%);
+}
+
+.cardContainer *:last-child {
+ margin-bottom: 0;
+}
+
+.cardTitle {
+ font-size: 1.2rem;
+}
+
+.cardDescription {
+ font-size: 0.8rem;
+}