-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from dalurness/jesse/add-dialogs-to-solution
Add Dialog to solution
- Loading branch information
Showing
14 changed files
with
631 additions
and
435 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { Modal, type ModalProps } from "./Modal"; | ||
|
||
export interface DialogProps extends ModalProps {} | ||
|
||
/** | ||
* Open a dialog popup that can be dimissed by clicking outside of it. | ||
* | ||
* This is opened programatically and the content is centered on the screen. | ||
*/ | ||
export function Dialog({ | ||
open = false, | ||
onToggle = () => {}, | ||
children, | ||
className = "", | ||
}: DialogProps) { | ||
return ( | ||
// For some reason TypeScript complains if these are possibly undefined, so set defaults above | ||
<Modal open={open} onToggle={onToggle} className={className}> | ||
{(args) => ( | ||
<div className="fixed inset-0 z-10 w-screen pointer-events-none"> | ||
<div className="flex min-h-full items-center justify-center p-4 sm:p-0"> | ||
<div className="relative rounded-lg overflow-hidden bg-yeti-light-1 shadow-xl pointer-events-auto w-full sm:my-8 sm:max-w-lg"> | ||
{typeof children === "function" ? children(args) : children} | ||
</div> | ||
</div> | ||
</div> | ||
)} | ||
</Modal> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { useEffect, useRef, type ReactNode } from "react"; | ||
import { twMerge } from "tailwind-merge"; | ||
|
||
export interface ModalProps { | ||
open?: boolean; | ||
onToggle?: (open: boolean) => void; | ||
button?: ReactNode | (({ isOpen }: { isOpen: boolean }) => ReactNode); | ||
children: | ||
| ReactNode | ||
| (({ | ||
isOpen, | ||
close, | ||
}: { | ||
isOpen: boolean; | ||
close: () => void; | ||
}) => ReactNode); | ||
className?: string; | ||
} | ||
|
||
/** | ||
* Open a modal popup that can be dimissed by clicking outside of it. | ||
* | ||
* This has a button that opens the modal and anything can be displayed inside. | ||
*/ | ||
export function Modal({ | ||
open, | ||
onToggle, | ||
button, | ||
children, | ||
className, | ||
}: ModalProps) { | ||
const details = useRef<HTMLDetailsElement>(null); | ||
const isOpen = details.current?.open === true; | ||
function close() { | ||
if (details.current) { | ||
details.current.open = false; | ||
} | ||
} | ||
|
||
useEffect(() => { | ||
function onToggleEvent() { | ||
onToggle?.(details.current!.open); | ||
} | ||
details.current?.addEventListener("toggle", onToggleEvent); | ||
|
||
return () => { | ||
details.current?.removeEventListener("toggle", onToggleEvent); | ||
}; | ||
}, [onToggle]); | ||
|
||
return ( | ||
<details ref={details} className={twMerge(className, "group")} open={open}> | ||
<summary | ||
// when no button, hide off-screen and make it so you can't tab to it | ||
className={twMerge("list-none", !button && "fixed -top-96 -left-96")} | ||
tabIndex={button ? undefined : -1} | ||
> | ||
{typeof button === "function" ? button({ isOpen }) : button} | ||
|
||
{/* fullscreen background element that you can click to close when it's open */} | ||
<div className="fixed inset-0 bg-yeti-dark-9/50 hidden group-open:block cursor-pointer"></div> | ||
</summary> | ||
|
||
{typeof children === "function" ? children({ isOpen, close }) : children} | ||
</details> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.