Finalize EntityLink refactor

This commit is contained in:
Sam Becker 2023-12-14 16:16:25 -06:00
parent c12b1ca819
commit 6ce6ad7e92
7 changed files with 93 additions and 96 deletions

View File

@ -1,56 +1,45 @@
import { AiFillApple } from 'react-icons/ai';
import { cc } from '@/utility/css';
import Link from 'next/link';
import { pathForCamera } from '@/site/paths';
import { IoMdCamera } from 'react-icons/io';
import { Camera } from '.';
import EntityLink, { EntityLinkExternalProps } from '@/components/EntityLink';
export default function PhotoCamera({
camera,
showIcon = true,
hideApple = true,
hideAppleIcon = true,
type = 'icon-first',
badged,
dim,
countOnHover,
}: {
camera: Camera
showIcon?: boolean
hideApple?: boolean
hideAppleIcon?: boolean
countOnHover?: number
}) {
} & EntityLinkExternalProps) {
const isCameraApple = camera.make?.toLowerCase() === 'apple';
const showAppleIcon = !hideAppleIcon && isCameraApple;
return (
<span className="group">
<Link
href={pathForCamera(camera)}
className={cc(
'inline-flex items-center self-start',
'uppercase',
'hover:text-gray-900 dark:hover:text-gray-100',
)}
>
{showIcon && <>
<IoMdCamera
size={13}
className="text-icon translate-y-[-0.25px]"
/>
&nbsp;
</>}
{!(hideApple && camera.make?.toLowerCase() === 'apple') &&
<>
{camera.make?.toLowerCase() === 'apple'
? <AiFillApple
title="Apple"
className="text-icon translate-y-[-0.5px]"
size={14}
/>
: camera.make}
&nbsp;
</>}
<EntityLink
label={<>
{!isCameraApple && <>{camera.make}&nbsp;</>}
{camera.model}
</Link>
{countOnHover !== undefined &&
<span className="hidden group-hover:inline">
{' '}
{countOnHover}
</span>}
</span>
</>}
href={pathForCamera(camera)}
icon={showAppleIcon
? <AiFillApple
title="Apple"
className="text-icon translate-y-[-0.5px]"
size={14}
/>
: <IoMdCamera
size={13}
className="text-icon translate-y-[-0.25px]"
/>}
type={type}
badged={badged}
dim={dim}
hoverEntity={countOnHover}
/>
);
}

View File

@ -3,7 +3,11 @@ 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 interface EntityLinkExternalProps {
type?: 'icon-last' | 'icon-first' | 'icon-only' | 'text-only';
badged?: boolean
dim?: boolean
}
export default function EntityLink({
label,
@ -11,18 +15,20 @@ export default function EntityLink({
href,
icon,
title,
type = 'icon-last',
type = 'icon-first',
badged,
hoverEntity,
dim,
}: {
label: string
labelSmall?: string
label: ReactNode
labelSmall?: ReactNode
href: string
icon?: ReactNode
title?: string
type?: EntityType
badged?: boolean
hoverEntity?: ReactNode
dim?: boolean
}) {
const renderContent = () => <>
<span className="xs:hidden">
@ -34,27 +40,34 @@ export default function EntityLink({
</>;
return (
<span className="group h-6 inline-flex items-center gap-2">
<span className="group inline-flex items-center gap-3 overflow-hidden">
<Link
href={href}
title={title}
className="inline-flex items-center gap-1"
className={cc(
'inline-flex items-center gap-1',
!badged && 'text-main hover:text-gray-900 dark:hover:text-gray-100',
dim && 'text-dim',
)}
>
{type !== 'icon-only' && <>
{badged
? <Badge type="secondary" uppercase interactive>
{renderContent()}
</Badge>
: <span className="uppercase text-medium">
? <span className="h-6 inline-flex items-center">
<Badge type="secondary" uppercase interactive>
{renderContent()}
</Badge>
</span>
: <span className="uppercase">
{renderContent()}
</span>}
</>}
{icon && type !== 'text-only' && <span className={cc(
'translate-y-[-1px] text-dim',
type === 'icon-first' && 'order-first',
)}>
{icon}
</span>}
{icon && type !== 'text-only' &&
<span className={cc(
'text-dim inline-flex min-w-[1rem]',
type === 'icon-first' && 'order-first',
)}>
{icon}
</span>}
</Link>
{hoverEntity !== undefined &&
<span className="hidden group-hover:inline">

View File

@ -36,8 +36,9 @@ export default function PhotoGridSidebar({
<PhotoTag
key={tag}
tag={tag}
showIcon={false}
type="text-only"
countOnHover={count}
dim
/>)}
/>}
{cameras.length > 0 && <HeaderList
@ -52,9 +53,10 @@ export default function PhotoGridSidebar({
<PhotoCamera
key={cameraKey}
camera={camera}
showIcon={false}
type="text-only"
countOnHover={count}
hideApple
hideAppleIcon
dim
/>)}
/>}
{simulations.length > 0 && <HeaderList

View File

@ -83,8 +83,8 @@ export default function PhotoLarge({
<div className="space-y-0.5">
<PhotoCamera
camera={camera}
showIcon={false}
hideApple={false}
type="text-only"
hideAppleIcon={false}
/>
{showSimulation && photo.filmSimulation &&
<div className="translate-x-[-0.3rem]">

View File

@ -37,7 +37,7 @@ export default function PhotoSetHeader({
items={[<div
key="PhotosHeader"
className={cc(
'flex flex-col gap-y-0.5',
'flex flex-col gap-y-0.5 items-start',
'xs:grid grid-cols-2 sm:grid-cols-4 md:grid-cols-3 lg:grid-cols-4',
)}>
{entity}

View File

@ -2,19 +2,18 @@ import { labelForFilmSimulation } from '@/vendors/fujifilm';
import PhotoFilmSimulationIcon from './PhotoFilmSimulationIcon';
import { pathForFilmSimulation } from '@/site/paths';
import { FilmSimulation } from '.';
import EntityLink, { EntityType } from '@/components/EntityLink';
import EntityLink, { EntityLinkExternalProps } from '@/components/EntityLink';
export default function PhotoFilmSimulation({
simulation,
type = 'icon-last',
badged = true,
dim,
countOnHover,
}: {
simulation: FilmSimulation
type?: EntityType
badged?: boolean
countOnHover?: number
}) {
} & EntityLinkExternalProps) {
const { small, medium, large } = labelForFilmSimulation(simulation);
return (
@ -22,10 +21,14 @@ export default function PhotoFilmSimulation({
label={medium}
labelSmall={small}
href={pathForFilmSimulation(simulation)}
icon={<PhotoFilmSimulationIcon {...{ simulation }} />}
icon={<PhotoFilmSimulationIcon
simulation={simulation}
className="translate-y-[-1px]"
/>}
title={`Film Simulation: ${large}`}
type={type}
badged={badged}
dim={dim}
hoverEntity={countOnHover}
/>
);

View File

@ -1,44 +1,34 @@
import Link from 'next/link';
import { pathForTag } from '@/site/paths';
import { FaTag } from 'react-icons/fa';
import { cc } from '@/utility/css';
import { formatTag } from '.';
import EntityLink, { EntityLinkExternalProps } from '@/components/EntityLink';
export default function PhotoTag({
tag,
showIcon = true,
type,
badged,
dim,
countOnHover,
}: {
tag: string
showIcon?: boolean
countOnHover?: number
}) {
} & EntityLinkExternalProps) {
return (
<span className="group">
<Link
href={pathForTag(tag)}
<EntityLink
label={formatTag(tag)}
href={pathForTag(tag)}
icon={<FaTag
size={11}
className={cc(
'inline-flex items-center gap-x-1.5 self-start',
'hover:text-gray-900 dark:hover:text-gray-100',
'flex-shrink-0',
'text-icon translate-y-[0.5px]',
)}
>
{showIcon &&
<FaTag
size={11}
className={cc(
'flex-shrink-0',
'text-icon translate-y-[0.5px]',
)}
/>}
<span className="uppercase">
{formatTag(tag)}
</span>
</Link>
{countOnHover !== undefined &&
<span className="hidden group-hover:inline">
{' '}
{countOnHover}
</span>}
</span>
/>}
type={type}
badged={badged}
dim={dim}
hoverEntity={countOnHover}
/>
);
}