@redocly/theme
Version:
Shared UI components lib
192 lines • 9.25 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CatalogClassicVirtualizedGroups = CatalogClassicVirtualizedGroups;
const react_1 = __importStar(require("react"));
const react_virtual_1 = require("@tanstack/react-virtual");
const styled_components_1 = __importDefault(require("styled-components"));
const hooks_1 = require("../../core/hooks");
const CatalogClassicCard_1 = require("../../components/CatalogClassic/CatalogClassicCard");
const CounterTag_1 = require("../../components/Tags/CounterTag");
const SpinnerLoader_1 = require("../../components/Loaders/SpinnerLoader");
const GAP_SIZE = 32;
const ESTIMATED_HEADER_HEIGHT = 43;
const ESTIMATED_CARD_HEIGHT = 194 + GAP_SIZE;
const CARD_MIN_WIDTH_VAR = '--catalog-classic-card-min-width';
const VIRTUALIZATION_THRESHOLD = 20; // Don't virtualize below this number of items
function CatalogClassicVirtualizedGroups({ groups, filters, filterTerm, }) {
const [isClient, setIsClient] = (0, react_1.useState)(false);
const [size, parentRef] = (0, hooks_1.useElementSize)({ delay: 50, detectSizes: 'width' });
(0, react_1.useEffect)(() => {
setIsClient(true);
}, []);
const totalItemCount = (0, react_1.useMemo)(() => {
return groups.reduce((total, group) => total + group.items.length, 0);
}, [groups]);
const shouldVirtualize = totalItemCount >= VIRTUALIZATION_THRESHOLD;
const columnCount = (0, react_1.useMemo)(() => {
if (!size.width)
return 4;
const cardMinWidth = parseInt(getComputedStyle(document.documentElement).getPropertyValue(CARD_MIN_WIDTH_VAR), 10);
return Math.max(1, Math.floor((size.width + GAP_SIZE) / (cardMinWidth + GAP_SIZE)));
}, [size.width]);
const flatRows = (0, react_1.useMemo)(() => {
if (!shouldVirtualize || !isClient) {
return groups.flatMap((group) => [
{
type: 'header',
groupTitle: group.title,
groupCount: group.items.length,
key: `header-${group.title}`,
},
{
type: 'cardRow',
groupTitle: group.title,
items: group.items,
key: `${group.title}-cards`,
},
]);
}
const rows = [];
groups.forEach((group) => {
rows.push({
type: 'header',
groupTitle: group.title,
groupCount: group.items.length,
key: `header-${group.title}`,
});
const numRows = Math.ceil(group.items.length / columnCount);
for (let rowIndex = 0; rowIndex < numRows; rowIndex++) {
const startIndex = rowIndex * columnCount;
const rowItems = group.items.slice(startIndex, startIndex + columnCount);
rows.push({
type: 'cardRow',
groupTitle: group.title,
items: rowItems,
key: `${group.title}-row-${rowIndex}`,
});
}
});
return rows;
}, [groups, columnCount, isClient, shouldVirtualize]);
const virtualizer = (0, react_virtual_1.useWindowVirtualizer)({
count: flatRows.length,
estimateSize: (index) => {
const row = flatRows[index];
if (row.type === 'header')
return ESTIMATED_HEADER_HEIGHT;
return ESTIMATED_CARD_HEIGHT;
},
overscan: 5,
enabled: shouldVirtualize,
});
(0, react_1.useEffect)(() => {
if (!size.width || !shouldVirtualize) {
return;
}
virtualizer.measure();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [filters, filterTerm, size.width, shouldVirtualize]);
const renderRow = (rowData) => {
if (rowData.type === 'header') {
return (react_1.default.createElement(SSRHeaderRow, { key: rowData.key },
react_1.default.createElement(CatalogSeparatorLabel, null, rowData.groupTitle),
react_1.default.createElement(CounterTag_1.CounterTag, { borderless: true }, rowData.groupCount)));
}
return (react_1.default.createElement(SSRGridRow, { key: rowData.key }, rowData.items.map((item) => (react_1.default.createElement(CatalogClassicCard_1.CatalogClassicCard, { key: item.link, item: item })))));
};
if (!isClient) {
return (react_1.default.createElement("div", { ref: parentRef, "data-component-name": "CatalogClassic/CatalogClassicVirtualizedGroups" },
flatRows.slice(0, 15).map((rowData) => renderRow(rowData)),
react_1.default.createElement(LoadingWrapper, null,
react_1.default.createElement(SpinnerLoader_1.SpinnerLoader, { color: "var(--catalog-classic-description-text-color)", size: "20px" }))));
}
if (!shouldVirtualize) {
return (react_1.default.createElement("div", { ref: parentRef, "data-component-name": "CatalogClassic/CatalogClassicVirtualizedGroups" }, flatRows.map((rowData) => renderRow(rowData))));
}
return (react_1.default.createElement("div", { ref: parentRef, "data-component-name": "CatalogClassic/CatalogClassicVirtualizedGroups" },
react_1.default.createElement("div", { style: {
position: 'relative',
height: `${virtualizer.getTotalSize()}px`,
} }, virtualizer.getVirtualItems().map((virtualRow) => {
const rowData = flatRows[virtualRow.index];
if (rowData.type === 'header') {
return (react_1.default.createElement(HeaderRow, { key: rowData.key, ref: virtualizer.measureElement, "data-index": virtualRow.index, style: { transform: `translateY(${virtualRow.start}px)` } },
react_1.default.createElement(CatalogSeparatorLabel, null, rowData.groupTitle),
react_1.default.createElement(CounterTag_1.CounterTag, { borderless: true }, rowData.groupCount)));
}
return (react_1.default.createElement(GridRow, { key: rowData.key, ref: virtualizer.measureElement, "data-index": virtualRow.index, style: { transform: `translateY(${virtualRow.start}px)` } }, rowData.items.map((item) => (react_1.default.createElement(CatalogClassicCard_1.CatalogClassicCard, { key: item.link, item: item })))));
}))));
}
const SSRHeaderRow = styled_components_1.default.div `
width: 100%;
display: flex;
align-items: center;
padding: var(--catalog-classic-separator-padding);
border-top: 1px solid var(--catalog-classic-separator-border-color);
padding-bottom: calc(4px * 4);
color: var(--catalog-classic-separator-color);
font-size: var(--catalog-classic-separator-font-size);
font-weight: var(--catalog-classic-separator-font-weight);
`;
const SSRGridRow = styled_components_1.default.div `
width: 100%;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(var(--catalog-classic-card-min-width), 1fr));
gap: var(--catalog-classic-cards-group-gap, 32px);
padding-bottom: var(--catalog-classic-cards-group-gap, 32px);
`;
const HeaderRow = (0, styled_components_1.default)(SSRHeaderRow) `
position: absolute;
left: 0;
will-change: transform;
`;
const GridRow = (0, styled_components_1.default)(SSRGridRow) `
position: absolute;
left: 0;
will-change: transform;
`;
const CatalogSeparatorLabel = styled_components_1.default.div `
margin: var(--catalog-classic-separator-label-margin);
`;
const LoadingWrapper = styled_components_1.default.div `
display: flex;
justify-content: center;
align-items: center;
`;
//# sourceMappingURL=CatalogClassicVirtualizedGroups.js.map