Add subtle transitions to sidebars (#344)

This commit is contained in:
Frank Noirot
2023-08-31 08:17:52 -04:00
committed by GitHub
parent 3507da7b39
commit 2693a5609b
2 changed files with 163 additions and 119 deletions

View File

@ -1,10 +1,11 @@
import { Popover } from '@headlessui/react' import { Popover, Transition } from '@headlessui/react'
import { ActionButton } from './ActionButton' import { ActionButton } from './ActionButton'
import { faHome } from '@fortawesome/free-solid-svg-icons' import { faHome } from '@fortawesome/free-solid-svg-icons'
import { ProjectWithEntryPointMetadata, paths } from '../Router' import { ProjectWithEntryPointMetadata, paths } from '../Router'
import { isTauri } from '../lib/isTauri' import { isTauri } from '../lib/isTauri'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import { ExportButton } from './ExportButton' import { ExportButton } from './ExportButton'
import { Fragment } from 'react'
const ProjectSidebarMenu = ({ const ProjectSidebarMenu = ({
project, project,
@ -34,7 +35,7 @@ const ProjectSidebarMenu = ({
) : ( ) : (
<Popover className="relative"> <Popover className="relative">
<Popover.Button <Popover.Button
className="border-0 px-1 pr-2 pl-0 flex items-center gap-4 focus:outline-none focus:ring-2 focus:ring-energy-50" className="border-0 p-0.5 pr-2 flex items-center gap-4 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-energy-50"
data-testid="project-sidebar-toggle" data-testid="project-sidebar-toggle"
> >
<img <img
@ -46,54 +47,77 @@ const ProjectSidebarMenu = ({
{isTauri() && project?.name ? project.name : 'KittyCAD Modeling App'} {isTauri() && project?.name ? project.name : 'KittyCAD Modeling App'}
</span> </span>
</Popover.Button> </Popover.Button>
<Popover.Overlay className="fixed z-20 inset-0 bg-chalkboard-110/50" /> <Transition
enter="duration-200 ease-out"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="duration-100 ease-in"
leaveFrom="opacity-100"
leaveTo="opacity-0"
as={Fragment}
>
<Popover.Overlay className="fixed z-20 inset-0 bg-chalkboard-110/50" />
</Transition>
<Popover.Panel className="fixed inset-0 right-auto z-30 w-64 bg-chalkboard-10 dark:bg-chalkboard-100 border border-energy-100 shadow-md rounded-r-lg overflow-hidden"> <Transition
<div className="flex items-center gap-4 px-4 py-3 bg-energy-100"> enter="duration-100 ease-out"
<img enterFrom="opacity-0 -translate-x-1/4"
src="/kitt-8bit-winking.svg" enterTo="opacity-100 translate-x-0"
alt="KittyCAD App" leave="duration-75 ease-in"
className="h-9 w-auto" leaveFrom="opacity-100 translate-x-0"
/> leaveTo="opacity-0 -translate-x-4"
as={Fragment}
>
<Popover.Panel className="fixed inset-0 right-auto z-30 w-64 bg-chalkboard-10 dark:bg-chalkboard-100 border border-energy-100 dark:border-energy-100/50 shadow-md rounded-r-lg overflow-hidden">
<div className="flex items-center gap-4 px-4 py-3 bg-energy-100">
<img
src="/kitt-8bit-winking.svg"
alt="KittyCAD App"
className="h-9 w-auto"
/>
<div> <div>
<p <p
className="m-0 text-energy-10 text-mono" className="m-0 text-energy-10 text-mono"
data-testid="projectName" data-testid="projectName"
> >
{project?.name ? project.name : 'KittyCAD Modeling App'} {project?.name ? project.name : 'KittyCAD Modeling App'}
</p>
{project?.entrypoint_metadata && (
<p className="m-0 text-energy-40 text-xs" data-testid="createdAt">
Created{' '}
{project?.entrypoint_metadata.createdAt.toLocaleDateString()}
</p> </p>
{project?.entrypoint_metadata && (
<p
className="m-0 text-energy-40 text-xs"
data-testid="createdAt"
>
Created{' '}
{project?.entrypoint_metadata.createdAt.toLocaleDateString()}
</p>
)}
</div>
</div>
<div className="p-4 flex flex-col gap-2">
<ExportButton
className={{
button:
'border-transparent dark:border-transparent dark:hover:border-energy-60',
}}
>
Export Model
</ExportButton>
{isTauri() && (
<ActionButton
Element="link"
to={paths.HOME}
icon={{
icon: faHome,
}}
className="border-transparent dark:border-transparent dark:hover:border-energy-60"
>
Go to Home
</ActionButton>
)} )}
</div> </div>
</div> </Popover.Panel>
<div className="p-4 flex flex-col gap-2"> </Transition>
<ExportButton
className={{
button:
'border-transparent dark:border-transparent dark:hover:border-energy-60',
}}
>
Export Model
</ExportButton>
{isTauri() && (
<ActionButton
Element="link"
to={paths.HOME}
icon={{
icon: faHome,
}}
className="border-transparent dark:border-transparent dark:hover:border-energy-60"
>
Go to Home
</ActionButton>
)}
</div>
</Popover.Panel>
</Popover> </Popover>
) )
} }

View File

@ -1,9 +1,9 @@
import { Popover } from '@headlessui/react' import { Popover, Transition } from '@headlessui/react'
import { ActionButton } from './ActionButton' import { ActionButton } from './ActionButton'
import { faBars, faGear, faSignOutAlt } from '@fortawesome/free-solid-svg-icons' import { faBars, faGear, faSignOutAlt } from '@fortawesome/free-solid-svg-icons'
import { faGithub } from '@fortawesome/free-brands-svg-icons' import { faGithub } from '@fortawesome/free-brands-svg-icons'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import { useState } from 'react' import { Fragment, useState } from 'react'
import { paths } from '../Router' import { paths } from '../Router'
import makeUrlPathRelative from '../lib/makeUrlPathRelative' import makeUrlPathRelative from '../lib/makeUrlPathRelative'
import { Models } from '@kittycad/lib' import { Models } from '@kittycad/lib'
@ -61,82 +61,102 @@ const UserSidebarMenu = ({ user }: { user?: User }) => {
Menu Menu
</ActionButton> </ActionButton>
)} )}
<Popover.Overlay className="fixed z-20 inset-0 bg-chalkboard-110/50" /> <Transition
enter="duration-200 ease-out"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="duration-100 ease-in"
leaveFrom="opacity-100"
leaveTo="opacity-0"
as={Fragment}
>
<Popover.Overlay className="fixed z-20 inset-0 bg-chalkboard-110/50" />
</Transition>
<Popover.Panel className="fixed inset-0 left-auto z-30 w-64 bg-chalkboard-10 dark:bg-chalkboard-100 border border-liquid-100 shadow-md rounded-l-lg overflow-hidden"> <Transition
{({ close }) => ( enter="duration-100 ease-out"
<> enterFrom="opacity-0 translate-x-1/4"
{user && ( enterTo="opacity-100 translate-x-0"
<div className="flex items-center gap-4 px-4 py-3 bg-liquid-100"> leave="duration-75 ease-in"
{user.image && !imageLoadFailed && ( leaveFrom="opacity-100 translate-x-0"
<div className="rounded-full shadow-inner overflow-hidden"> leaveTo="opacity-0 translate-x-4"
<img as={Fragment}
src={user.image} >
alt={user.name || ''} <Popover.Panel className="fixed inset-0 left-auto z-30 w-64 bg-chalkboard-10 dark:bg-chalkboard-100 border border-liquid-100 dark:border-liquid-100/50 shadow-md rounded-l-lg overflow-hidden">
className="h-8 w-8" {({ close }) => (
referrerPolicy="no-referrer" <>
onError={() => setImageLoadFailed(true)} {user && (
/> <div className="flex items-center gap-4 px-4 py-3 bg-liquid-100">
</div> {user.image && !imageLoadFailed && (
)} <div className="rounded-full shadow-inner overflow-hidden">
<img
<div> src={user.image}
<p alt={user.name || ''}
className="m-0 text-liquid-10 text-mono" className="h-8 w-8"
data-testid="username" referrerPolicy="no-referrer"
> onError={() => setImageLoadFailed(true)}
{displayedName || ''} />
</p> </div>
{displayedName !== user.email && (
<p
className="m-0 text-liquid-40 text-xs"
data-testid="email"
>
{user.email}
</p>
)} )}
<div>
<p
className="m-0 text-liquid-10 text-mono"
data-testid="username"
>
{displayedName || ''}
</p>
{displayedName !== user.email && (
<p
className="m-0 text-liquid-40 text-xs"
data-testid="email"
>
{user.email}
</p>
)}
</div>
</div> </div>
)}
<div className="p-4 flex flex-col gap-2">
<ActionButton
Element="button"
icon={{ icon: faGear }}
className="border-transparent dark:border-transparent dark:hover:border-liquid-60"
onClick={() => {
// since /settings is a nested route the sidebar doesn't close
// automatically when navigating to it
close()
navigate(makeUrlPathRelative(paths.SETTINGS))
}}
>
Settings
</ActionButton>
<ActionButton
Element="link"
to="https://github.com/KittyCAD/modeling-app/discussions"
icon={{ icon: faGithub }}
className="border-transparent dark:border-transparent dark:hover:border-liquid-60"
>
Request a feature
</ActionButton>
<ActionButton
Element="button"
onClick={() => send('Log out')}
icon={{
icon: faSignOutAlt,
bgClassName: 'bg-destroy-80',
iconClassName:
'text-destroy-20 group-hover:text-destroy-10 hover:text-destroy-10',
}}
className="border-transparent dark:border-transparent hover:border-destroy-40 dark:hover:border-destroy-60"
>
Sign out
</ActionButton>
</div> </div>
)} </>
<div className="p-4 flex flex-col gap-2"> )}
<ActionButton </Popover.Panel>
Element="button" </Transition>
icon={{ icon: faGear }}
className="border-transparent dark:border-transparent dark:hover:border-liquid-60"
onClick={() => {
// since /settings is a nested route the sidebar doesn't close
// automatically when navigating to it
close()
navigate(makeUrlPathRelative(paths.SETTINGS))
}}
>
Settings
</ActionButton>
<ActionButton
Element="link"
to="https://github.com/KittyCAD/modeling-app/discussions"
icon={{ icon: faGithub }}
className="border-transparent dark:border-transparent dark:hover:border-liquid-60"
>
Request a feature
</ActionButton>
<ActionButton
Element="button"
onClick={() => send('Log out')}
icon={{
icon: faSignOutAlt,
bgClassName: 'bg-destroy-80',
iconClassName:
'text-destroy-20 group-hover:text-destroy-10 hover:text-destroy-10',
}}
className="border-transparent dark:border-transparent hover:border-destroy-40 dark:hover:border-destroy-60"
>
Sign out
</ActionButton>
</div>
</>
)}
</Popover.Panel>
</Popover> </Popover>
) )
} }