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 { labelForFilmSimulation } from '@/vendors/fujifilm';
|
||||||
import PhotoFilmSimulationIcon from './PhotoFilmSimulationIcon';
|
import PhotoFilmSimulationIcon from './PhotoFilmSimulationIcon';
|
||||||
import Badge from '@/components/Badge';
|
|
||||||
import Link from 'next/link';
|
|
||||||
import { pathForFilmSimulation } from '@/site/paths';
|
import { pathForFilmSimulation } from '@/site/paths';
|
||||||
import { FilmSimulation } from '.';
|
import { FilmSimulation } from '.';
|
||||||
|
import EntityLink, { EntityType } from '@/components/EntityLink';
|
||||||
|
|
||||||
export default function PhotoFilmSimulation({
|
export default function PhotoFilmSimulation({
|
||||||
simulation,
|
simulation,
|
||||||
@ -13,46 +11,22 @@ export default function PhotoFilmSimulation({
|
|||||||
countOnHover,
|
countOnHover,
|
||||||
}: {
|
}: {
|
||||||
simulation: FilmSimulation
|
simulation: FilmSimulation
|
||||||
type?: 'icon-last' | 'icon-first' | 'icon-only' | 'text-only'
|
type?: EntityType
|
||||||
badged?: boolean
|
badged?: boolean
|
||||||
countOnHover?: number
|
countOnHover?: number
|
||||||
}) {
|
}) {
|
||||||
const { small, medium, large } = labelForFilmSimulation(simulation);
|
const { small, medium, large } = labelForFilmSimulation(simulation);
|
||||||
|
|
||||||
const renderContent = () => <>
|
|
||||||
<span className="xs:hidden">
|
|
||||||
{small}
|
|
||||||
</span>
|
|
||||||
<span className="hidden xs:inline-block">
|
|
||||||
{medium}
|
|
||||||
</span>
|
|
||||||
</>;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span className="group h-6 inline-flex items-center gap-2">
|
<EntityLink
|
||||||
<Link
|
label={medium}
|
||||||
href={pathForFilmSimulation(simulation)}
|
labelSmall={small}
|
||||||
title={`Film Simulation: ${large}`}
|
href={pathForFilmSimulation(simulation)}
|
||||||
className="inline-flex items-center gap-1"
|
icon={<PhotoFilmSimulationIcon {...{ simulation }} />}
|
||||||
>
|
title={`Film Simulation: ${large}`}
|
||||||
{type !== 'icon-only' && <>
|
type={type}
|
||||||
{badged
|
badged={badged}
|
||||||
? <Badge type="secondary" uppercase interactive>
|
hoverEntity={countOnHover}
|
||||||
{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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user