| 1 |
import React from "react"; |
| 2 |
|
| 3 |
// Loading skeleton that mirrors the real tree-table / tag-list layout. |
| 4 |
// variant="tree" renders the connector + chevron column (Doc Categories); |
| 5 |
// variant="flat" omits them (Doc Tags). Structural classes are reused from |
| 6 |
// _tree-table.scss so the skeleton aligns pixel-for-pixel with the loaded UI. |
| 7 |
|
| 8 |
const ROW_COUNT = 6; |
| 9 |
|
| 10 |
// Varied widths keep the shimmer from looking like a uniform grid |
| 11 |
const TITLE_WIDTHS = ["46%", "34%", "52%", "40%", "30%", "48%"]; |
| 12 |
const META_WIDTHS = ["62%", "70%", "55%", "66%", "58%", "72%"]; |
| 13 |
|
| 14 |
const SkeletonRow = ({ variant, index }) => ( |
| 15 |
<div className="bd-dc-row bd-dc-row--skel"> |
| 16 |
<span className="bd-dc-grip" aria-hidden="true"> |
| 17 |
<span className="bd-dc-skel bd-dc-skel-grip" /> |
| 18 |
</span> |
| 19 |
<span className="bd-dc-skel bd-dc-skel-check" /> |
| 20 |
|
| 21 |
{variant === "tree" && ( |
| 22 |
<> |
| 23 |
<span className="bd-dc-skel-connector" aria-hidden="true" /> |
| 24 |
<span className="bd-dc-skel bd-dc-skel-chevron" /> |
| 25 |
</> |
| 26 |
)} |
| 27 |
|
| 28 |
<span className="bd-dc-cell-name"> |
| 29 |
<span |
| 30 |
className="bd-dc-skel bd-dc-skel-line bd-dc-skel-line--title" |
| 31 |
style={{ width: TITLE_WIDTHS[index % TITLE_WIDTHS.length] }} |
| 32 |
/> |
| 33 |
<span |
| 34 |
className="bd-dc-skel bd-dc-skel-line bd-dc-skel-line--meta" |
| 35 |
style={{ width: META_WIDTHS[index % META_WIDTHS.length] }} |
| 36 |
/> |
| 37 |
</span> |
| 38 |
|
| 39 |
<span className="bd-dc-cell-count"> |
| 40 |
<span className="bd-dc-skel bd-dc-skel-count" /> |
| 41 |
</span> |
| 42 |
|
| 43 |
<span className="bd-dc-cell-actions"> |
| 44 |
<span className="bd-dc-skel bd-dc-skel-action" /> |
| 45 |
<span className="bd-dc-skel bd-dc-skel-action" /> |
| 46 |
{variant === "tree" && <span className="bd-dc-skel bd-dc-skel-action" />} |
| 47 |
</span> |
| 48 |
</div> |
| 49 |
); |
| 50 |
|
| 51 |
const TableSkeleton = ({ variant = "flat" }) => { |
| 52 |
const isTree = variant === "tree"; |
| 53 |
return ( |
| 54 |
<> |
| 55 |
{/* Toolbar lives outside the card (sibling above it) */} |
| 56 |
<div className="bd-dc-toolbar" aria-busy="true"> |
| 57 |
<div className="bd-dc-toolbar-left"> |
| 58 |
<span className="bd-dc-skel bd-dc-skel-toolbar-chip" /> |
| 59 |
</div> |
| 60 |
<div className="bd-dc-toolbar-right"> |
| 61 |
<span className="bd-dc-skel bd-dc-skel-toolbar-select" /> |
| 62 |
<span className="bd-dc-skel bd-dc-skel-toolbar-apply" /> |
| 63 |
</div> |
| 64 |
</div> |
| 65 |
|
| 66 |
<div className="bd-dc-tree-card" aria-busy="true" aria-live="polite"> |
| 67 |
{/* Header */} |
| 68 |
<div className={`bd-dc-table-header${isTree ? " bd-dc-table-header--tree" : ""}`}> |
| 69 |
{isTree && <span className="bd-dc-grip-spacer" aria-hidden="true" />} |
| 70 |
<span className="bd-dc-skel bd-dc-skel-check" /> |
| 71 |
<span className="bd-dc-col-name" /> |
| 72 |
<span className="bd-dc-col-count" /> |
| 73 |
<span className="bd-dc-col-actions" /> |
| 74 |
</div> |
| 75 |
|
| 76 |
{/* Rows */} |
| 77 |
<div className="bd-dc-table-body"> |
| 78 |
{Array.from({ length: ROW_COUNT }).map((_, i) => ( |
| 79 |
<SkeletonRow key={i} variant={variant} index={i} /> |
| 80 |
))} |
| 81 |
</div> |
| 82 |
</div> |
| 83 |
</> |
| 84 |
); |
| 85 |
}; |
| 86 |
|
| 87 |
export default TableSkeleton; |
| 88 |
|