diff --git a/src/admin/AdminNavClient.tsx b/src/admin/AdminNavClient.tsx
index 240ab4e1..3acc5e8d 100644
--- a/src/admin/AdminNavClient.tsx
+++ b/src/admin/AdminNavClient.tsx
@@ -1,5 +1,6 @@
'use client';
+import LinkWithLoader from '@/components/LinkWithLoader';
import LinkWithStatus from '@/components/LinkWithStatus';
import Note from '@/components/Note';
import SiteGrid from '@/components/SiteGrid';
@@ -73,11 +74,11 @@ export default function AdminNavClient({
key={label}
href={href}
className={clsx(
+ 'flex gap-0.5',
checkPathPrefix(pathname, href) ? 'font-bold' : 'text-dim',
'px-1 py-0.5 rounded-md',
)}
loadingClassName="bg-dim"
- contentClassName="flex gap-0.5"
prefetch={false}
>
{label}
@@ -85,19 +86,19 @@ export default function AdminNavClient({
({count})}
)}
- }
+ loader={}
>
-
+
{shouldShowBanner &&
}>
diff --git a/src/components/LinkWithLoader.tsx b/src/components/LinkWithLoader.tsx
new file mode 100644
index 00000000..af01c50b
--- /dev/null
+++ b/src/components/LinkWithLoader.tsx
@@ -0,0 +1,31 @@
+import { ComponentProps, ReactNode } from 'react';
+import LinkWithStatus from './LinkWithStatus';
+import clsx from 'clsx/lite';
+import Link from 'next/link';
+
+export default function LinkWithLoader({
+ loader,
+ children,
+ ...props
+}: ComponentProps & {
+ loader: ReactNode
+}) {
+ return (
+
+ {({ isLoading }) => <>
+
+ {children}
+
+ {isLoading &&
+ {loader}
+ }
+ >}
+
+ );
+}
diff --git a/src/components/LinkWithStatus.tsx b/src/components/LinkWithStatus.tsx
index 6b00bf2c..a2ddf0a9 100644
--- a/src/components/LinkWithStatus.tsx
+++ b/src/components/LinkWithStatus.tsx
@@ -20,18 +20,14 @@ const MAX_LOADING_DURATION = 15_000;
export type LinkWithStatusProps = Omit<
ComponentProps, 'children'
> & {
- loadingElement?: ReactNode
loadingClassName?: string
- contentClassName?: string
children: ReactNode | ((props: {
isLoading: boolean
}) => ReactNode)
}
export default function LinkWithStatus({
- loadingElement,
loadingClassName,
- contentClassName,
href,
className,
onClick,
@@ -93,7 +89,10 @@ export default function LinkWithStatus({
{...props }
href={href}
className={clsx(
- 'relative transition-colors',
+ 'relative flex transition-[colors,opacity]',
+ (loadingClassName || isControlled)
+ ? 'opacity-100'
+ : isLoading ? 'opacity-50' : 'opacity-100',
className,
isLoading && loadingClassName,
)}
@@ -116,24 +115,8 @@ export default function LinkWithStatus({
onClick?.(e);
}}
>
-
- {typeof children === 'function'
- ? children({ isLoading })
- : children}
-
- {isLoading && loadingElement &&
- {loadingElement}
- }
+ {typeof children === 'function'
+ ? children({ isLoading })
+ : children}
;
}
diff --git a/src/components/SwitcherItem.tsx b/src/components/SwitcherItem.tsx
index eb1b70be..87c01783 100644
--- a/src/components/SwitcherItem.tsx
+++ b/src/components/SwitcherItem.tsx
@@ -1,8 +1,8 @@
import { clsx } from 'clsx/lite';
import { SHOULD_PREFETCH_ALL_LINKS } from '@/site/config';
-import { JSX, ReactNode } from 'react';
-import LinkWithStatus from './LinkWithStatus';
+import { JSX } from 'react';
import Spinner from './Spinner';
+import LinkWithLoader from './LinkWithLoader';
export default function SwitcherItem({
icon,
@@ -37,23 +37,23 @@ export default function SwitcherItem({
: 'hover:text-gray-700 dark:hover:text-gray-400',
);
- const renderContent = (content: ReactNode) => noPadding
- ? content
+ const renderIcon = () => noPadding
+ ? icon
:
- {content}
+ {icon}
;
return (
href
- ? ,
+ loader: ,
}}>
- {renderContent(icon)}
-
- : {renderContent(icon)}
+ {renderIcon()}
+
+ : {renderIcon()}
);
};