import { Link, NavLink, useTransition } from 'remix'; import { Fragment, useEffect, useMemo, useState } from 'react'; import classNames from 'classnames'; import { Menu, Transition } from '@headlessui/react'; import DotsVerticalIcon from '@heroicons/react/solid/DotsVerticalIcon'; import MenuIcon from '@heroicons/react/solid/MenuIcon'; import { Config, getFolder } from '~/utils'; import { ThemeButton } from '../ThemeButton'; import { useConfig } from '../ConfigProvider'; import { useNavOpen } from '../UiStateProvider'; function ActionMenu({ actions }: { actions?: Config['site']['actions'] }) { if (!actions || actions.length === 0) return null; return (
Open Menu
{actions?.map((action) => ( {({ active }) => ( {action.title} )} ))}
); } /** * Show a loading progess bad if the load takes more than 150ms */ function useLoading() { const transitionState = useTransition().state; const ref = useMemo<{ start?: NodeJS.Timeout; finish?: NodeJS.Timeout }>( () => ({}), [], ); const [showLoading, setShowLoading] = useState(false); useEffect(() => { if (transitionState === 'loading') { ref.start = setTimeout(() => { setShowLoading(true); }, 150); } else { if (ref.start) { // We have stoped loading in <150ms clearTimeout(ref.start); delete ref.start; setShowLoading(false); return; } ref.finish = setTimeout(() => { setShowLoading(false); }, 150); } return () => { if (ref.start) { clearTimeout(ref.start); delete ref.start; } if (ref.finish) { clearTimeout(ref.finish); delete ref.finish; } }; }, [transitionState]); return { showLoading, isLoading: transitionState === 'loading' }; } export function TopNav() { const [open, setOpen] = useNavOpen(); const config = useConfig(); const { logo, logoText, sections, actions, name } = config?.site ?? {}; const { isLoading, showLoading } = useLoading(); return (
{showLoading && (
)}
); }