+ Close button doesn't work becayse inside the story we use the{" "}
+ isOpen control.
+
+
+
+ )
+ },
+}
diff --git a/packages/wethegit-components/src/components/modal/modal.tsx b/packages/wethegit-components/src/components/modal/modal.tsx
new file mode 100644
index 00000000..9425c57f
--- /dev/null
+++ b/packages/wethegit-components/src/components/modal/modal.tsx
@@ -0,0 +1,58 @@
+"use client"
+
+import { Modal as WTCModal, ModalContent, ModalBackdrop } from "@wethegit/react-modal"
+import type { ModalProps as WTCModalProps } from "@wethegit/react-modal"
+import { useAnimatePresence, useUserPrefs } from "@wethegit/react-hooks"
+
+import { classnames } from "@local/utilities"
+
+import styles from "./modal.module.scss"
+
+export interface ModalProps extends WTCModalProps {
+ /**
+ * Whether the modal is open or not.
+ */
+ isOpen: boolean
+ /**
+ * A function that toggles the modal.
+ */
+ toggle: () => void
+ /**
+ * The modal content.
+ */
+ children?: React.ReactNode
+}
+
+/**
+ * Wrapper around the `@wethegit/react-modal` component that adds a trigger and takes care of reducing motion.
+ * For more information, see the [modal documentation](https://github.com/wethegit/react-modal).
+ */
+export function Modal({ children, isOpen, toggle, ...props }: ModalProps) {
+ const { prefersReducedMotion } = useUserPrefs()
+ const { render, animate, currentDuration } = useAnimatePresence({
+ isVisible: isOpen,
+ duration: prefersReducedMotion ? 0 : 500,
+ })
+
+ const stylesVars = {
+ "--duration": `${currentDuration}ms`,
+ } as React.CSSProperties
+
+ if (!render) return null
+
+ return (
+
+
+
+
+ {children}
+
+
+ )
+}
diff --git a/packages/wethegit-components/src/components/modal/readme.stories.mdx b/packages/wethegit-components/src/components/modal/readme.stories.mdx
new file mode 100644
index 00000000..bd737f24
--- /dev/null
+++ b/packages/wethegit-components/src/components/modal/readme.stories.mdx
@@ -0,0 +1,57 @@
+import { Meta } from "@storybook/blocks"
+
+
+
+# modal
+
+The `` component is a wrapper around [@wethegit/react-modal](https://github.com/wethegit/react-modal) with some default styles including animation.
+
+### Install
+
+```bash
+npx @wethegit/components-cli add modal
+```
+
+### Usage
+
+First, import the global modal styles from `@wethegit/react-modal` into your global stylesheet or root layout:
+
+```scss
+@import "@wethegit/react-modal/style.css";
+```
+
+The `` component takes a `trigger` prop that is a function which receives a `toggle` function as its only argument and should return the element that will trigger the modal.
+
+It also handles reduced motion by default and because of that you are required to make sure that the modal component renders inside the [UserPreferencesProvider](https://wethegit.github.io/react-hooks/user-preferences-provider).
+
+```tsx
+import { useRef } from "react"
+import { useModal } from "@wethegit/react-modal"
+import { UserPreferencesProvider } from "@wethegit/react-hooks"
+
+import { Modal } from "@local/components"
+
+function Page() {
+ const triggerRef = useRef(null)
+ const props = useModal({
+ triggerRef,
+ })
+
+ return (
+ <>
+
+
+
+
Modal Content
+
+ Pariatur occaecat quis aliquip excepteur adipisicing minim ipsum qui proident
+ qui voluptate ut sunt.
+