Files

80 lines
2.6 KiB
TypeScript

'use client'
import React, { type ComponentProps } from "react";
import { MARK_HEIGHT, type PartnerLogo } from "@/lib/constants/partner-logos";
import { View, XStack } from '@hanzo/ui'
/**
* A row of marks, centred, wrapping until there is room for one line.
*
* NO TAILWIND. What a caller used to say through `className` it says as gui
* props — the row IS an `XStack`, so it takes an XStack's props and a caller
* states `columnGap` or `opacity` directly instead of naming a utility this
* component would have to pass through untouched.
*
* A MARK RESTS AT 70% AND COMES TO FULL ON APPROACH: `opacity` and
* `hoverStyle` on the cell that holds it, so the rest and the hover are one
* gui style and neither out-ranks the other. Its height is DATA, because
* Techstars' glyphs fill a third of their viewBox and a literal height match
* renders them tiny beside a wordmark, so lib/constants/partner-logos.ts
* carries a px value per logo and this reads it.
*
* The marks are drawn black. `invert` turns them white always; `invert="dark"`
* only on the dark theme, so a reader who picks light keeps them black.
*
* FLEX, NOT GRID, and deliberately: this row WRAPS below `$md` and grid's
* auto-flow has no wrap — a track list would put nine marks on one line and
* overflow a phone. Grid is the site's default for a row of a known width;
* a row that reflows is still flex's job.
*/
interface PartnerLogoRowProps extends ComponentProps<typeof XStack> {
logos: PartnerLogo[];
invert?: boolean | 'dark';
}
const PartnerLogoRow: React.FC<PartnerLogoRowProps> = ({
logos,
invert = false,
...rest
}) => {
return (
<XStack
flexWrap="wrap"
justify="center"
items="center"
columnGap={32}
rowGap={16}
{...rest}
>
{logos.map((logo) => {
const img = (
<View
render={<img src={logo.src} alt={`${logo.name} logo`} loading="lazy" />}
display="inline"
height={logo.height ?? MARK_HEIGHT}
width="auto"
filter={invert === true ? 'invert(1)' : undefined}
/>
);
return (
<XStack
key={logo.name}
items="center"
justify="center"
opacity={0.7}
hoverStyle={{ opacity: 1 }}
$theme-dark={invert === 'dark' ? { filter: 'invert(1)' } : undefined}
transition="quickest"
>
{logo.href ? (
<a href={logo.href} target="_blank" rel="noopener noreferrer">{img}</a>
) : img}
</XStack>
);
})}
</XStack>
);
};
export default PartnerLogoRow;