Footer.jsx
2.7 kB · jsx · 62 lines
1import site from "../../site.json";2import { CATEGORIES, DOCS, FILES, FOOT_COLUMNS, SHOP, SITE } from "../config/shop.ts";3import { useMediaQuery } from "../lib/hooks.ts";4import { collectionUrl } from "../lib/shop.ts";5import { Icon } from "./Icon.jsx";67function pack(groups, count) {8 const columns = Array.from({ length: Math.min(count, groups.length) }, () => ({ height: 0, groups: [] }));9 for (const group of [...groups].sort((a, b) => b.links.length - a.links.length)) {10 const column = columns.reduce((low, one) => (one.height < low.height ? one : low));11 column.groups.push(group);12 column.height += group.links.length + 2;13 }14 for (const column of columns) column.groups.sort((a, b) => groups.indexOf(a) - groups.indexOf(b));15 return columns.filter((one) => one.groups.length).sort((a, b) => groups.indexOf(a.groups[0]) - groups.indexOf(b.groups[0]));16}1718export function Footer({ catalog = [], now = 0 }) {19 const year = new Date(now || Date.now()).getUTCFullYear();20 const wide = useMediaQuery("(min-width: 1024px)");21 const shop = CATEGORIES.map(([slug, name]) => ({ slug, name, href: `${SHOP}${slug}/`, links: catalog.filter((row) => row.category === slug).map((row) => ({ name: row.title, href: collectionUrl(row.handle) })) })).filter((one) => one.links.length);22 const groups = [23 ...shop,24 { slug: "site", name: "Site", links: SITE },25 { slug: "help", name: "Help", links: DOCS },26 { slug: "files", name: "Files", links: FILES },27 { slug: "socials", name: "Socials", links: site.socials, rel: "me noopener" },28 ];29 return (30 <footer className="foot">31 <div className="wrap">32 <nav className="catalog" aria-label="Site">33 {pack(groups, FOOT_COLUMNS).map((column, i) => (34 <div key={i} className="col">35 {column.groups.map((group) => (36 <details key={group.slug} className="drop" open={wide} style={{ order: groups.indexOf(group) }}>37 <summary>38 {group.href ? <a href={group.href}>{group.name}</a> : <span>{group.name}</span>}39 <Icon name="expand_more" extra="small" />40 </summary>41 <ul>42 {group.links.map((one) => (43 <li key={one.href}>44 <a href={one.href} rel={group.rel}>45 {one.name}46 </a>47 </li>48 ))}49 </ul>50 </details>51 ))}52 </div>53 ))}54 </nav>55 <div className="rule"></div>56 <div className="legal">57 <p className="copy">{`Copyright © ${site.since}-${year} ${site.owner}. All rights reserved.`}</p>58 </div>59 </div>60 </footer>61 );62}