Create EntityLink component for tags, cameras, films

This commit is contained in:
Sam Becker 2023-12-12 20:43:34 -06:00
parent 2f88388d9f
commit e4812ce540
2 changed files with 77 additions and 38 deletions

View File

@ -0,0 +1,65 @@
import Link from 'next/link';
import { ReactNode } from 'react';
import Badge from './Badge';
import { cc } from '@/utility/css';
export type EntityType = 'icon-last' | 'icon-first' | 'icon-only' | 'text-only';
export default function EntityLink({
label,
labelSmall,
href,
icon,
title,
type = 'icon-last',
badged,
hoverEntity,
}: {
label: string
labelSmall?: string
href: string
icon?: ReactNode
title?: string
type?: EntityType
badged?: boolean
hoverEntity?: ReactNode
}) {
const renderContent = () => <>
<span className="xs:hidden">
{labelSmall ?? label}
</span>
<span className="hidden xs:inline-block">
{label}
</span>
</>;
return (
<span className="group h-6 inline-flex items-center gap-2">
<Link
href={href}
title={title}
className="inline-flex items-center gap-1"
>
{type !== 'icon-only' && <>
{badged
? <Badge type="secondary" uppercase interactive>
{renderContent()}
</Badge>
: <span className="uppercase text-medium">
{renderContent()}
</span>}
</>}
{icon && type !== 'text-only' && <span className={cc(
'translate-y-[-1px] text-dim',
type === 'icon-first' && 'order-first',
)}>
{icon}
</span>}
</Link>
{hoverEntity !== undefined &&
<span className="hidden group-hover:inline">
{hoverEntity}
</span>}
</span>
);
}

View File

@ -1,10 +1,8 @@
import { cc } from '@/utility/css';
import { labelForFilmSimulation } from '@/vendors/fujifilm';
import PhotoFilmSimulationIcon from './PhotoFilmSimulationIcon';
import Badge from '@/components/Badge';
import Link from 'next/link';
import { pathForFilmSimulation } from '@/site/paths';
import { FilmSimulation } from '.';
import EntityLink, { EntityType } from '@/components/EntityLink';
export default function PhotoFilmSimulation({
simulation,
@ -13,46 +11,22 @@ export default function PhotoFilmSimulation({
countOnHover,
}: {
simulation: FilmSimulation
type?: 'icon-last' | 'icon-first' | 'icon-only' | 'text-only'
type?: EntityType
badged?: boolean
countOnHover?: number
}) {
const { small, medium, large } = labelForFilmSimulation(simulation);
const renderContent = () => <>
<span className="xs:hidden">
{small}
</span>
<span className="hidden xs:inline-block">
{medium}
</span>
</>;
return (
<span className="group h-6 inline-flex items-center gap-2">
<Link
href={pathForFilmSimulation(simulation)}
title={`Film Simulation: ${large}`}
className="inline-flex items-center gap-1"
>
{type !== 'icon-only' && <>
{badged
? <Badge type="secondary" uppercase interactive>
{renderContent()}
</Badge>
: <span className="uppercase text-medium">{renderContent()}</span>}
</>}
{type !== 'text-only' && <span className={cc(
'translate-y-[-1px] text-dim',
type === 'icon-first' && 'order-first',
)}>
<PhotoFilmSimulationIcon {...{ simulation }} />
</span>}
</Link>
{countOnHover !== undefined &&
<span className="hidden group-hover:inline">
{countOnHover}
</span>}
</span>
<EntityLink
label={medium}
labelSmall={small}
href={pathForFilmSimulation(simulation)}
icon={<PhotoFilmSimulationIcon {...{ simulation }} />}
title={`Film Simulation: ${large}`}
type={type}
badged={badged}
hoverEntity={countOnHover}
/>
);
}