mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-25 02:41:07 +01:00
Floating sidebar
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import classnames from 'classnames';
|
||||
import { motion } from 'framer-motion';
|
||||
import type { ReactNode } from 'react';
|
||||
import { Portal } from '../Portal';
|
||||
import { Overlay } from '../Overlay';
|
||||
import { IconButton } from './IconButton';
|
||||
import { HStack, VStack } from './Stacks';
|
||||
|
||||
@@ -25,43 +25,38 @@ export function Dialog({
|
||||
description,
|
||||
}: Props) {
|
||||
return (
|
||||
<Portal name="dialog">
|
||||
{open && (
|
||||
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }}>
|
||||
<div
|
||||
aria-hidden
|
||||
onClick={() => onOpenChange(false)}
|
||||
className="fixed inset-0 bg-gray-600/60 dark:bg-black/50"
|
||||
/>
|
||||
<div>
|
||||
<div
|
||||
className={classnames(
|
||||
className,
|
||||
'absolute top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%] bg-gray-100',
|
||||
'w-[20rem] max-h-[80vh] p-5 rounded-lg overflow-auto',
|
||||
'dark:border border-gray-200 shadow-md shadow-black/10',
|
||||
wide && 'w-[80vw] max-w-[50rem]',
|
||||
)}
|
||||
>
|
||||
<IconButton
|
||||
onClick={() => onOpenChange(false)}
|
||||
title="Close dialog"
|
||||
aria-label="Close"
|
||||
icon="x"
|
||||
size="sm"
|
||||
className="ml-auto absolute right-1 top-1"
|
||||
/>
|
||||
<VStack space={3}>
|
||||
<HStack alignItems="center" className="pb-3">
|
||||
<div className="text-xl font-semibold">{title}</div>
|
||||
</HStack>
|
||||
{description && <div>{description}</div>}
|
||||
<div>{children}</div>
|
||||
</VStack>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</Portal>
|
||||
<Overlay open={open} onClick={() => onOpenChange(false)} portalName="dialog">
|
||||
<div className="absolute inset-0 flex items-center justify-center pointer-events-none">
|
||||
<div className="pointer-events-auto">
|
||||
<motion.div
|
||||
initial={{ top: 5, scale: 0.97 }}
|
||||
animate={{ top: 0, scale: 1 }}
|
||||
className={classnames(
|
||||
className,
|
||||
'relative bg-gray-100 pointer-events-auto',
|
||||
'w-[20rem] max-h-[80vh] p-5 rounded-lg overflow-auto',
|
||||
'dark:border border-gray-200 shadow-md shadow-black/10',
|
||||
wide && 'w-[80vw] max-w-[50rem]',
|
||||
)}
|
||||
>
|
||||
<IconButton
|
||||
onClick={() => onOpenChange(false)}
|
||||
title="Close dialog"
|
||||
aria-label="Close"
|
||||
icon="x"
|
||||
size="sm"
|
||||
className="ml-auto absolute right-1 top-1"
|
||||
/>
|
||||
<VStack space={3}>
|
||||
<HStack alignItems="center" className="pb-3">
|
||||
<div className="text-xl font-semibold">{title}</div>
|
||||
</HStack>
|
||||
{description && <div>{description}</div>}
|
||||
<div>{children}</div>
|
||||
</VStack>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</Overlay>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -161,8 +161,8 @@ function Menu({ className, items, onClose, triggerRect }: MenuProps) {
|
||||
<Portal name="dropdown">
|
||||
<button aria-hidden title="close" className="fixed inset-0" onClick={onClose} />
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: -10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
initial={{ opacity: 0, y: -5, scale: 0.98 }}
|
||||
animate={{ opacity: 1, y: 0, scale: 1 }}
|
||||
role="menu"
|
||||
aria-orientation="vertical"
|
||||
dir="ltr"
|
||||
|
||||
Reference in New Issue
Block a user