leap: portalled menu for less dupe

This commit is contained in:
Hunter Miller 2021-08-16 10:59:52 -05:00
parent d89cfc7291
commit edde5e3ec4

View File

@ -1,4 +1,5 @@
import { DialogContent } from '@radix-ui/react-dialog'; import { DialogContent } from '@radix-ui/react-dialog';
import * as Portal from '@radix-ui/react-portal';
import classNames from 'classnames'; import classNames from 'classnames';
import React, { import React, {
ChangeEvent, ChangeEvent,
@ -80,8 +81,11 @@ export const Nav: FunctionComponent<NavProps> = ({ menu = 'closed' }) => {
const { push } = useHistory(); const { push } = useHistory();
const location = useLocation(); const location = useLocation();
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
const navRef = useRef<HTMLDivElement>(null);
const dialogNavRef = useRef<HTMLDivElement>(null);
const { searchInput, setSearchInput, selection, select } = useNavStore(); const { searchInput, setSearchInput, selection, select } = useNavStore();
const [systemMenuOpen, setSystemMenuOpen] = useState(false); const [systemMenuOpen, setSystemMenuOpen] = useState(false);
const [delayedOpen, setDelayedOpen] = useState(false);
const isOpen = menu !== 'closed'; const isOpen = menu !== 'closed';
const eitherOpen = isOpen || systemMenuOpen; const eitherOpen = isOpen || systemMenuOpen;
@ -90,8 +94,11 @@ export const Nav: FunctionComponent<NavProps> = ({ menu = 'closed' }) => {
(event: Event) => { (event: Event) => {
event.preventDefault(); event.preventDefault();
setDelayedOpen(true);
if (menu === 'search' && inputRef.current) { if (menu === 'search' && inputRef.current) {
inputRef.current.focus(); setTimeout(() => {
inputRef.current?.focus();
}, 0);
} }
}, },
[menu] [menu]
@ -119,6 +126,7 @@ export const Nav: FunctionComponent<NavProps> = ({ menu = 'closed' }) => {
const onDialogClose = useCallback((open: boolean) => { const onDialogClose = useCallback((open: boolean) => {
if (!open) { if (!open) {
select(null); select(null);
setDelayedOpen(false);
push('/'); push('/');
} }
}, []); }, []);
@ -156,48 +164,12 @@ export const Nav: FunctionComponent<NavProps> = ({ menu = 'closed' }) => {
}, []); }, []);
return ( return (
<menu className="w-full max-w-3xl my-6 px-4 text-gray-400 font-semibold"> <>
<div className={classNames('flex space-x-2', isOpen && 'invisible')}> <Portal.Root containerRef={delayedOpen ? dialogNavRef : navRef} className="flex space-x-2">
{!isOpen && (
<SystemMenu
showOverlay
open={systemMenuOpen}
setOpen={setSystemMenuOpen}
className={classNames(
'relative z-50 flex-none',
eitherOpen ? 'bg-white' : 'bg-gray-100'
)}
/>
)}
<Link
to="/leap/notifications"
className="relative z-50 flex-none circle-button bg-blue-400 text-white default-ring"
>
3
</Link>
<input
onClick={toggleSearch}
onFocus={onFocus}
type="text"
className="relative z-50 rounded-full w-full pl-4 h4 bg-gray-100 default-ring"
placeholder="Search Landscape"
/>
</div>
<Dialog open={isOpen} onOpenChange={onDialogClose}>
<DialogContent
onOpenAutoFocus={onOpen}
className="fixed top-0 left-[calc(50%-7.5px)] w-[calc(100%-15px)] max-w-3xl px-4 text-gray-400 -translate-x-1/2 outline-none"
>
<div tabIndex={-1} onKeyDown={onDialogKey} role="presentation">
<header className="flex my-6 space-x-2">
<SystemMenu <SystemMenu
open={systemMenuOpen} open={systemMenuOpen}
setOpen={setSystemMenuOpen} setOpen={setSystemMenuOpen}
className={classNames( className={classNames('relative z-50 flex-none', eitherOpen ? 'bg-white' : 'bg-gray-100')}
'relative z-50 flex-none',
eitherOpen ? 'bg-white' : 'bg-gray-100'
)}
/> />
<Link <Link
to="/leap/notifications" to="/leap/notifications"
@ -205,7 +177,13 @@ export const Nav: FunctionComponent<NavProps> = ({ menu = 'closed' }) => {
> >
3 3
</Link> </Link>
<div className="relative z-50 flex items-center w-full px-2 rounded-full bg-white default-ring focus-within:ring-4"> <form
className={classNames(
'relative z-50 flex items-center w-full px-2 rounded-full bg-white default-ring focus-within:ring-4',
!isOpen && 'bg-gray-100'
)}
onSubmit={() => {}}
>
<label <label
htmlFor="leap" htmlFor="leap"
className={classNames( className={classNames(
@ -239,8 +217,22 @@ export const Nav: FunctionComponent<NavProps> = ({ menu = 'closed' }) => {
<span className="sr-only">Close</span> <span className="sr-only">Close</span>
</Link> </Link>
)} )}
</div> </form>
</header> </Portal.Root>
<menu
ref={navRef}
className={classNames(
'w-full max-w-3xl my-6 px-4 text-gray-400 font-semibold',
delayedOpen && 'h-12'
)}
/>
<Dialog open={isOpen} onOpenChange={onDialogClose}>
<DialogContent
onOpenAutoFocus={onOpen}
className="fixed top-0 left-[calc(50%-7.5px)] w-[calc(100%-15px)] max-w-3xl px-4 text-gray-400 -translate-x-1/2 outline-none"
>
<div tabIndex={-1} onKeyDown={onDialogKey} role="presentation">
<header ref={dialogNavRef} className="my-6" />
<div <div
id="leap-items" id="leap-items"
className="grid grid-rows-[fit-content(calc(100vh-7.5rem))] bg-white rounded-3xl overflow-hidden" className="grid grid-rows-[fit-content(calc(100vh-7.5rem))] bg-white rounded-3xl overflow-hidden"
@ -256,6 +248,6 @@ export const Nav: FunctionComponent<NavProps> = ({ menu = 'closed' }) => {
</div> </div>
</DialogContent> </DialogContent>
</Dialog> </Dialog>
</menu> </>
); );
}; };