Add loading status to all entity links
This commit is contained in:
parent
8548fee089
commit
95e11c70bc
@ -9,7 +9,7 @@ import EntityLink, {
|
||||
export default function PhotoCamera({
|
||||
camera,
|
||||
hideAppleIcon,
|
||||
type = 'icon-first',
|
||||
type,
|
||||
badged,
|
||||
contrast,
|
||||
prefetch,
|
||||
@ -36,7 +36,7 @@ export default function PhotoCamera({
|
||||
size={12}
|
||||
className="translate-x-[-1px]"
|
||||
/>}
|
||||
type={showAppleIcon && isCameraApple ? 'icon-first' : type}
|
||||
type={type}
|
||||
badged={badged}
|
||||
contrast={contrast}
|
||||
prefetch={prefetch}
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
'use client';
|
||||
|
||||
import { ReactNode } from 'react';
|
||||
import LabeledIcon, { LabeledIconType } from './LabeledIcon';
|
||||
import Badge from '../Badge';
|
||||
import { clsx } from 'clsx/lite';
|
||||
import LinkWithStatus from '../LinkWithStatus';
|
||||
import Spinner from '../Spinner';
|
||||
|
||||
export interface EntityLinkExternalProps {
|
||||
type?: LabeledIconType
|
||||
@ -18,7 +22,7 @@ export default function EntityLink({
|
||||
type,
|
||||
badged,
|
||||
contrast = 'medium',
|
||||
href,
|
||||
href = '', // Make link optional for debugging purposes
|
||||
prefetch,
|
||||
title,
|
||||
hoverEntity,
|
||||
@ -59,43 +63,53 @@ export default function EntityLink({
|
||||
</>;
|
||||
|
||||
return (
|
||||
<span className={clsx(
|
||||
'group inline-flex gap-2 w-full',
|
||||
className,
|
||||
)}>
|
||||
<LabeledIcon {...{
|
||||
icon,
|
||||
iconWide,
|
||||
href,
|
||||
prefetch,
|
||||
title,
|
||||
type,
|
||||
className: clsx(
|
||||
classForContrast(),
|
||||
href && !badged && 'hover:text-gray-900 dark:hover:text-gray-100',
|
||||
),
|
||||
debug,
|
||||
}}>
|
||||
{badged
|
||||
? <Badge
|
||||
type="small"
|
||||
highContrast={contrast === 'high'}
|
||||
className='translate-y-[-0.5px]'
|
||||
uppercase
|
||||
interactive
|
||||
>
|
||||
{renderLabel()}
|
||||
</Badge>
|
||||
: <span className={clsx(
|
||||
truncate && 'inline-flex max-w-full [&>*]:truncate',
|
||||
)}>
|
||||
{renderLabel()}
|
||||
</span>}
|
||||
</LabeledIcon>
|
||||
{hoverEntity !== undefined &&
|
||||
<span className="hidden group-hover:inline">
|
||||
{hoverEntity}
|
||||
</span>}
|
||||
<span className="group inline-flex w-full">
|
||||
<LinkWithStatus
|
||||
href={href}
|
||||
className={clsx(
|
||||
'inline-flex items-center gap-2',
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{({ isLoading }) => <>
|
||||
<LabeledIcon {...{
|
||||
icon,
|
||||
iconWide,
|
||||
href,
|
||||
prefetch,
|
||||
title,
|
||||
type,
|
||||
className: clsx(
|
||||
classForContrast(),
|
||||
href && !badged && 'hover:text-gray-900 dark:hover:text-gray-100',
|
||||
),
|
||||
debug,
|
||||
}}>
|
||||
{badged
|
||||
? <Badge
|
||||
type="small"
|
||||
highContrast={contrast === 'high'}
|
||||
className='translate-y-[-0.5px]'
|
||||
uppercase
|
||||
interactive
|
||||
>
|
||||
{renderLabel()}
|
||||
</Badge>
|
||||
: <span className={clsx(
|
||||
truncate && 'inline-flex max-w-full [&>*]:truncate',
|
||||
)}>
|
||||
{renderLabel()}
|
||||
</span>}
|
||||
</LabeledIcon>
|
||||
{!isLoading && hoverEntity !== undefined &&
|
||||
<span className="hidden group-hover:inline text-dim">
|
||||
{hoverEntity}
|
||||
</span>}
|
||||
{isLoading && <Spinner className={clsx(
|
||||
badged && 'translate-y-[0.5px]',
|
||||
)} />}
|
||||
</>}
|
||||
</LinkWithStatus>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { ComponentProps, ReactNode } from 'react';
|
||||
import { ReactNode } from 'react';
|
||||
import Icon from './Icon';
|
||||
import { clsx } from 'clsx/lite';
|
||||
import Link from 'next/link';
|
||||
|
||||
export type LabeledIconType =
|
||||
'icon-first' |
|
||||
@ -15,8 +14,6 @@ export default function LabeledIcon({
|
||||
className: classNameProp,
|
||||
children,
|
||||
iconWide,
|
||||
href,
|
||||
prefetch,
|
||||
debug,
|
||||
}: {
|
||||
icon?: ReactNode,
|
||||
@ -25,36 +22,28 @@ export default function LabeledIcon({
|
||||
children: ReactNode,
|
||||
iconWide?:boolean,
|
||||
debug?: boolean,
|
||||
} & Partial<ComponentProps<typeof Link>>) {
|
||||
const className = clsx(
|
||||
'inline-flex gap-x-1 md:gap-x-1.5 min-w-0',
|
||||
classNameProp,
|
||||
debug && 'border border-green-500 m-[-1px]',
|
||||
}) {
|
||||
return (
|
||||
<span className={ clsx(
|
||||
'inline-flex gap-x-1 md:gap-x-1.5 min-w-0',
|
||||
classNameProp,
|
||||
debug && 'border border-green-500 m-[-1px]',
|
||||
)}>
|
||||
{icon && type !== 'text-only' &&
|
||||
<Icon {...{
|
||||
className: clsx(type === 'icon-last' && 'order-1'),
|
||||
wide: iconWide,
|
||||
debug,
|
||||
}}>
|
||||
{icon}
|
||||
</Icon>}
|
||||
{children && type !== 'icon-only' &&
|
||||
<span className={clsx(
|
||||
'uppercase overflow-hidden',
|
||||
debug && 'bg-gray-300 dark:bg-gray-700',
|
||||
)}>
|
||||
{children}
|
||||
</span>}
|
||||
</span>
|
||||
);
|
||||
|
||||
const renderContent = () => <>
|
||||
{icon && type !== 'text-only' &&
|
||||
<Icon {...{
|
||||
className: clsx(type === 'icon-last' && 'order-1'),
|
||||
wide: iconWide,
|
||||
debug,
|
||||
}}>
|
||||
{icon}
|
||||
</Icon>}
|
||||
{children && type !== 'icon-only' &&
|
||||
<span className={clsx(
|
||||
'uppercase overflow-hidden',
|
||||
debug && 'bg-gray-300 dark:bg-gray-700',
|
||||
)}>
|
||||
{children}
|
||||
</span>}
|
||||
</>;
|
||||
|
||||
return href
|
||||
? <Link {...{ href, prefetch, className }}>
|
||||
{renderContent()}
|
||||
</Link>
|
||||
: <div {...{ className }}>
|
||||
{renderContent()}
|
||||
</div>;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user