Wrap services grid-combine or grid-preserve

This commit is contained in:
lukylix 2023-07-10 14:45:10 +02:00
parent 5c78a1f00a
commit 1c6e5a18c9

View File

@ -1,6 +1,7 @@
import classNames from "classnames"; import classNames from "classnames";
import Item from "components/services/item"; import Item from "components/services/item";
import { useEffect, useRef, useState } from "react";
const columnMap = [ const columnMap = [
"grid-cols-1 md:grid-cols-1 lg:grid-cols-1", "grid-cols-1 md:grid-cols-1 lg:grid-cols-1",
@ -17,37 +18,117 @@ const columnMap = [
const subcolumnMap = [ const subcolumnMap = [
"grid-cols-1", "grid-cols-1",
"grid-cols-1", "grid-cols-1",
"grid-cols-1 @[11rem]:grid-cols-2", "grid-cols-1 @[18rem]:grid-cols-2",
"grid-cols-1 @[9rem]:grid-cols-2 @[18rem]:grid-cols-3", "grid-cols-1 @[16rem]:grid-cols-2 @[24rem]:grid-cols-3",
"grid-cols-1 @[7rem]:grid-cols-2 @[14rem]:grid-cols-3 @[21rem]:grid-cols-4", "grid-cols-1 @[14rem]:grid-cols-2 @[21rem]:grid-cols-3 @[28rem]:grid-cols-4",
"grid-cols-1 @[7rem]:grid-cols-2 @[14rem]:grid-cols-3 @[21rem]:grid-cols-4 @[28rem]:grid-cols-5", "grid-cols-1 @[14rem]:grid-cols-2 @[21rem]:grid-cols-3 @[28rem]:grid-cols-4 @[35rem]:grid-cols-5",
"grid-cols-1 @[7rem]:grid-cols-2 @[14rem]:grid-cols-3 @[21rem]:grid-cols-4 @[28rem]:grid-cols-5 @[35rem]:grid-cols-6", "grid-cols-1 @[14rem]:grid-cols-2 @[21rem]:grid-cols-3 @[28rem]:grid-cols-4 @[35rem]:grid-cols-5 @[42rem]:grid-cols-6",
"grid-cols-1 @[7rem]:grid-cols-2 @[14rem]:grid-cols-3 @[21rem]:grid-cols-4 @[28rem]:grid-cols-5 @[35rem]:grid-cols-6 @[42rem]:grid-cols-7", "grid-cols-1 @[14rem]:grid-cols-2 @[21rem]:grid-cols-3 @[28rem]:grid-cols-4 @[35rem]:grid-cols-5 @[42rem]:grid-cols-6 [49rem]:grid-cols-7",
"grid-cols-1 @[7rem]:grid-cols-2 @[14rem]:grid-cols-3 @[21rem]:grid-cols-4 @[28rem]:grid-cols-5 @[35rem]:grid-cols-6 @[42rem]:grid-cols-7 @[49rem]:grid-cols-8", "grid-cols-1 @[14rem]:grid-cols-2 @[21rem]:grid-cols-3 @[28rem]:grid-cols-4 @[35rem]:grid-cols-5 @[42rem]:grid-cols-6 [49rem]:grid-cols-7 [56rem]:grid-cols-8",
]; ];
const itemRemSizeMap = [1, 1, 9, 8, 7, 7, 7, 7, 7];
export default function List({ group, services, layout, isGroup = false }) { export default function List({ group, services, layout, isGroup = false }) {
const containerRef = useRef(null);
const [childrensToSlice, setChildrensToSlice] = useState(0);
const numberOfServices = services.filter((e) => e).length;
const servicesTopRows = services.filter((v) => v).slice(0, numberOfServices - childrensToSlice);
const servicesBottomRows = services.filter((v) => v).slice(numberOfServices - childrensToSlice);
if (servicesBottomRows.length > 0) console.log(servicesBottomRows);
let gridClassName = isGroup ? subcolumnMap[layout.columns] : columnMap[layout?.columns];
let gridClassNameBottom = isGroup
? subcolumnMap[servicesBottomRows?.length]
: servicesBottomRows[servicesTopRows?.length];
if (gridClassName) gridClassName = ` grid auto-rows-max ${gridClassName} gap-x-2`;
if (gridClassNameBottom) gridClassNameBottom = ` grid auto-rows-max ${gridClassNameBottom} gap-x-2`;
if (!gridClassName) gridClassName = " flex flex-wrap gap-x-2";
if (!gridClassNameBottom) gridClassNameBottom = " flex flex-wrap gap-x-2";
useEffect(() => {
const resizeObserver = new ResizeObserver((entries) => {
for (let i = 0; i < entries.length; i += 1) {
const entry = entries[i];
const { width } = entry.contentRect;
const remSize = parseFloat(getComputedStyle(document.documentElement).fontSize);
const itemRemSize = itemRemSizeMap[parseInt(layout?.columns, 10)];
const remWidth = width / remSize;
const maxChildrenFit = Math.floor(remWidth / itemRemSize);
if (numberOfServices < maxChildrenFit) return setChildrensToSlice(0);
const toSlice =
remWidth / itemRemSize > 1 && numberOfServices > Math.min(maxChildrenFit, layout.columns)
? numberOfServices % Math.min(maxChildrenFit, layout.columns)
: 0;
setChildrensToSlice(toSlice);
}
return true;
});
if (containerRef.current) {
resizeObserver.observe(containerRef.current);
}
return () => {
resizeObserver.disconnect();
};
}, [numberOfServices]);
return ( return (
<ul <ul
className={classNames( className={classNames(
layout?.style === "row" layout?.style === "row" ? gridClassName : "flex flex-col",
? `grid auto-rows-max ${isGroup ? subcolumnMap[layout?.columns] : columnMap[layout?.columns]} gap-x-2` isGroup ? undefined : "mt-3",
: "flex flex-col", "@container"
isGroup ? undefined : "mt-3"
)} )}
ref={containerRef}
> >
{services.map((service) => {servicesTopRows.length > 0 &&
service.type === "grouped-service" ? ( servicesTopRows.map((service) =>
<List service.type === "grouped-service" ? (
key={service.name} <List
group={group} key={service.name}
services={service.services} group={service.name}
layout={{ columns: parseInt(service.name, 10) || service.services.length, style: "row" }} services={service.services}
isGroup layout={{
/> columns: parseInt(service.name, 10) || 1,
) : ( style: "row",
<Item key={service.container ?? service.app ?? service.name} service={service} group={group} /> }}
) isGroup
/>
) : (
<Item key={service.container ?? service.app ?? service.name} service={service} group={group} />
)
)}
{servicesBottomRows.length > 0 && (
<ul
className={classNames(
layout?.style === "row" ? gridClassNameBottom : "flex flex-col",
isGroup ? undefined : "mt-3",
"col-span-full"
)}
>
{servicesBottomRows.map((service) =>
service.type === "grouped-service" ? (
<List
key={service.name}
group={service.name}
services={service.services}
layout={{
columns: service.services?.length,
style: "row",
}}
isGroup
/>
) : (
<Item key={service.container ?? service.app ?? service.name} service={service} group={group} />
)
)}
</ul>
)} )}
</ul> </ul>
); );