Create EntityLink component for tags, cameras, films
This commit is contained in:
parent
2f88388d9f
commit
e4812ce540
65
src/components/EntityLink.tsx
Normal file
65
src/components/EntityLink.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
@ -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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user