Skip to content
Open
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
91 changes: 91 additions & 0 deletions docs/docusaurus/src/components/CollectionTable/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import React, { useState } from 'react';
import type { CollectionDetailData } from '../../data/collectionDetails';
import styles from './styles.module.css';

const maturityClass: Record<CollectionDetailData['maturity'], string> = {
Stable: styles.maturityStable,
Preview: styles.maturityPreview,
Experimental: styles.maturityExperimental,
};

/**
* CollectionTableWithDescriptions - A table component displaying HVE collections
* with hover tooltips showing detailed descriptions from collection files.
*
* Implements the feature request from issue #1266: adding collection description
* tooltips to the Docusaurus collections page.
*/
export default function CollectionTableWithDescriptions({
collections,
}: {
collections: CollectionDetailData[];
}): React.ReactElement {
const [expandedRow, setExpandedRow] = useState<string | null>(null);

const toggleRow = (name: string) => {
setExpandedRow(expandedRow === name ? null : name);
};

return (
<div className={styles.tableWrapper}>
<table className={styles.collectionTable}>
<thead>
<tr>
<th>Collection</th>
<th>Description</th>
<th>Artifacts</th>
<th>Maturity</th>
</tr>
</thead>
<tbody>
{collections.map((collection) => (
<React.Fragment key={collection.name}>
<tr
className={`${styles.tableRow} ${expandedRow === collection.name ? styles.expanded : ''}`}
onClick={() => toggleRow(collection.name)}
title={collection.detailedDescription}
>
<td>
<span className={styles.collectionName}>{collection.name}</span>
<span className={styles.expandIcon}>
{expandedRow === collection.name ? '▼' : '▶'}
</span>
</td>
<td>{collection.shortDescription}</td>
<td className={styles.artifacts}>{collection.artifacts}</td>
<td>
<span className={`${styles.maturityBadge} ${maturityClass[collection.maturity]}`}>
{collection.maturity}
</span>
</td>
</tr>
{expandedRow === collection.name && (
<tr className={styles.detailRow}>
<td colSpan={4}>
<div className={styles.detailContent}>
<h4>Detailed Description</h4>
<p>{collection.detailedDescription}</p>
{collection.includes && collection.includes.length > 0 && (
<div className={styles.includesSection}>
<h5>Key Features:</h5>
<ul>
{collection.includes.slice(0, 5).map((item, idx) => (
<li key={idx}>{item}</li>
))}
</ul>
</div>
)}
</div>
</td>
</tr>
)}
</React.Fragment>
))}
</tbody>
</table>
<p className={styles.hint}>
💡 Click on a row to expand and see more details, or hover over the collection name for a quick tooltip.
</p>
</div>
);
}
120 changes: 120 additions & 0 deletions docs/docusaurus/src/components/CollectionTable/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
.tableWrapper {
margin: 1rem 0;
}

.collectionTable {
width: 100%;
border-collapse: collapse;
margin-bottom: 0.5rem;
}

.collectionTable th {
padding: 0.75rem 1rem;
text-align: left;
background: var(--ifm-color-primary-contrast-background);
border-bottom: 2px solid var(--ifm-color-primary);
font-weight: 600;
}

.collectionTable td {
padding: 0.75rem 1rem;
border-bottom: 1px solid var(--ifm-color-emphasis-200);
}

.tableRow {
cursor: pointer;
transition: background-color 0.2s ease;
}

.tableRow:hover {
background: var(--ifm-color-emphasis-100);
}

.tableRow.expanded {
background: var(--ifm-color-emphasis-100);
}

.collectionName {
font-weight: 600;
color: var(--ifm-color-primary);
}

.expandIcon {
margin-left: 0.5rem;
font-size: 0.75rem;
color: var(--ifm-color-emphasis-600);
}

.artifacts {
text-align: center;
font-weight: 500;
}

.maturityBadge {
display: inline-block;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
padding: 0.25rem 0.5rem;
border-radius: 2px;
}

.maturityStable {
background: var(--ifm-color-success-contrast-background);
color: var(--ifm-color-success-dark);
}

.maturityPreview {
background: var(--ifm-color-warning-contrast-background);
color: var(--ifm-color-warning-dark);
}

.maturityExperimental {
background: var(--ifm-color-info-contrast-background);
color: var(--ifm-color-info-dark);
}

.detailRow {
background: var(--ifm-color-emphasis-50);
}

.detailContent {
padding: 1rem;
}

.detailContent h4 {
margin-top: 0;
margin-bottom: 0.75rem;
font-size: 1rem;
color: var(--ifm-color-primary);
}

.detailContent p {
margin-bottom: 1rem;
line-height: 1.6;
}

.includesSection h5 {
margin-bottom: 0.5rem;
font-size: 0.875rem;
color: var(--ifm-color-emphasis-700);
}

.includesSection ul {
margin: 0;
padding-left: 1.5rem;
list-style-type: disc;
}

.includesSection li {
margin-bottom: 0.25rem;
font-size: 0.875rem;
}

.hint {
font-size: 0.75rem;
color: var(--ifm-color-emphasis-600);
text-align: center;
margin-top: 0.5rem;
}
Loading