Skip to content

Commit

Permalink
fix: directive
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <[email protected]>
  • Loading branch information
Innei committed Mar 16, 2024
1 parent 9906026 commit bb8093a
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 121 deletions.
99 changes: 0 additions & 99 deletions demo/app/(mdx)/advance/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -144,102 +144,3 @@ export const NestedModal = () => {
import { NestedModal } from "./demo.tsx"

<NestedModal />

## Best Practices for Imperative Invocation

The advantage of invoking Modal imperatively is that it's easy to encapsulate component logic. For example, we can quickly refactor and encapsulate a declarative Modal in scenarios where it is used multiple times.

```tsx
const MyModal = ({
open,
onOpenChange,
}: {
open: boolean
onOpenChange: (open: boolean) => void
}) => {
return (
<Modal
title="A declaratively modal"
open={open}
onOpenChange={onOpenChange}
>
<p>
This is a modal. You can put anything you want in here. And It can be
nested.
</p>
</Modal>
)
}
const Component1 = () => {
const [open, setOpen] = useState(false)
return (
<>
<Button
onClick={() => {
setOpen(true)
}}
>
Open Modal
</Button>

<MyModal open={open} onOpenChange={setOpen} />
</>
)
}

const Component2 = () => {
const [open, setOpen] = useState(false)
return (
<>
<Button
onClick={() => {
setOpen(true)
}}
>
Other biz button also use modal
</Button>

<MyModal open={open} onOpenChange={setOpen} />
</>
)
}
```

Refactoring into an imperative call Hook, so you no longer have to control the opening and closing state of the Modal within the component.

```tsx
const useMyModal = () => {
const { present } = useModalStack()
return useCallback(() => {
present({
title: "My Modal",
content: () => (
<p>
This is a modal. You can put anything you want in here. And It can be
nested.
</p>
),
})
}, [present])
}

const Component1 = () => {
const showModal = useMyModal()
return (
<>
<Button onClick={showModal}>Open Modal</Button>
</>
)
}

const Component2 = () => {
const showModal = useMyModal()
return (
<>
<Button onClick={showModal}>Other biz button also use modal</Button>
</>
)
}
```

Isn't it more concise and convenient to use?
98 changes: 98 additions & 0 deletions demo/app/(mdx)/best-practices/page.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
## Reusing components and abstractions

The advantage of invoking Modal imperatively is that it's easy to encapsulate component logic. For example, we can quickly refactor and encapsulate a declarative Modal in scenarios where it is used multiple times.

```tsx
const MyModal = ({
open,
onOpenChange,
}: {
open: boolean
onOpenChange: (open: boolean) => void
}) => {
return (
<Modal
title="A declaratively modal"
open={open}
onOpenChange={onOpenChange}
>
<p>
This is a modal. You can put anything you want in here. And It can be
nested.
</p>
</Modal>
)
}
const Component1 = () => {
const [open, setOpen] = useState(false)
return (
<>
<Button
onClick={() => {
setOpen(true)
}}
>
Open Modal
</Button>

<MyModal open={open} onOpenChange={setOpen} />
</>
)
}

const Component2 = () => {
const [open, setOpen] = useState(false)
return (
<>
<Button
onClick={() => {
setOpen(true)
}}
>
Other biz button also use modal
</Button>

<MyModal open={open} onOpenChange={setOpen} />
</>
)
}
```

Refactoring into an imperative call Hook, so you no longer have to control the opening and closing state of the Modal within the component.

```tsx
const useMyModal = () => {
const { present } = useModalStack()
return useCallback(() => {
present({
title: "My Modal",
content: () => (
<p>
This is a modal. You can put anything you want in here. And It can be
nested.
</p>
),
})
}, [present])
}

const Component1 = () => {
const showModal = useMyModal()
return (
<>
<Button onClick={showModal}>Open Modal</Button>
</>
)
}

const Component2 = () => {
const showModal = useMyModal()
return (
<>
<Button onClick={showModal}>Other biz button also use modal</Button>
</>
)
}
```

Isn't it more concise and convenient to use?
31 changes: 29 additions & 2 deletions demo/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import "@/styles/globals.css"

import { Metadata } from "next"
import { clsxm } from "~/lib/helper"
import { MobileDetector } from "rc-modal-sheet/src/helpers/mobile-detector"
import { ModalStackContainer } from "rc-modal-sheet/src/helpers/motion"
import { clsxm } from "~/lib/helper"

import "./index.css"

import type { SVGProps } from "react"
import Script from "next/script"
import { PresentSheet } from "~/sheet"

import { siteConfig } from "@/config/site"
import { LeftAside } from "@/components/layout/sidebar"
Expand Down Expand Up @@ -93,9 +97,15 @@ export default function RootLayout({ children }: RootLayoutProps) {
<LeftAside />
</div>

<main className="min-w-0 px-4 py-14 lg:px-2">
<main className="min-w-0 px-4 py-14 xl:px-2">
{children}
</main>

<PresentSheet content={<LeftAside asWeight />}>
<button className="fixed bottom-4 right-4 z-10 block rounded-full border border-zinc-200 bg-white p-2 text-black shadow xl:hidden dark:border-zinc-800 dark:bg-gray-950 dark:text-white">
<MaterialSymbolsMenuBookOutlineRounded />
</button>
</PresentSheet>
</div>
</div>
</div>
Expand All @@ -107,3 +117,20 @@ export default function RootLayout({ children }: RootLayoutProps) {
</>
)
}

function MaterialSymbolsMenuBookOutlineRounded(props: SVGProps<SVGSVGElement>) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 24 24"
{...props}
>
<path
fill="currentColor"
d="M6.5 16q1.175 0 2.288.263T11 17.05V7.2q-1.025-.6-2.175-.9T6.5 6q-.9 0-1.788.175T3 6.7v9.9q.875-.3 1.738-.45T6.5 16m6.5 1.05q1.1-.525 2.213-.787T17.5 16q.9 0 1.763.15T21 16.6V6.7q-.825-.35-1.713-.525T17.5 6q-1.175 0-2.325.3T13 7.2zm-1 2.425q-.35 0-.663-.087t-.587-.238q-.975-.575-2.05-.862T6.5 18q-1.05 0-2.062.275T2.5 19.05q-.525.275-1.012-.025T1 18.15V6.1q0-.275.138-.525T1.55 5.2q1.15-.6 2.4-.9T6.5 4q1.45 0 2.838.375T12 5.5q1.275-.75 2.663-1.125T17.5 4q1.3 0 2.55.3t2.4.9q.275.125.413.375T23 6.1v12.05q0 .575-.487.875t-1.013.025q-.925-.5-1.937-.775T17.5 18q-1.125 0-2.2.288t-2.05.862q-.275.15-.587.238t-.663.087m2-10.7q0-.225.163-.462T14.525 8q.725-.25 1.45-.375T17.5 7.5q.5 0 .988.063t.962.162q.225.05.388.25t.162.45q0 .425-.275.625t-.7.1q-.35-.075-.737-.112T17.5 9q-.65 0-1.275.125t-1.2.325q-.45.175-.737-.025T14 8.775m0 5.5q0-.225.163-.462t.362-.313q.725-.25 1.45-.375T17.5 13q.5 0 .988.063t.962.162q.225.05.388.25t.162.45q0 .425-.275.625t-.7.1q-.35-.075-.737-.112T17.5 14.5q-.65 0-1.275.113t-1.2.312q-.45.175-.737-.012T14 14.275m0-2.75q0-.225.163-.462t.362-.313q.725-.25 1.45-.375t1.525-.125q.5 0 .988.063t.962.162q.225.05.388.25t.162.45q0 .425-.275.625t-.7.1q-.35-.075-.737-.112t-.788-.038q-.65 0-1.275.125t-1.2.325q-.45.175-.737-.025t-.288-.65"
></path>
</svg>
)
}
22 changes: 11 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,19 @@
"require": "./dist/index.css"
},
"./motion": {
"type": "./dist/motion.d.ts",
"import": "./dist/motion.js",
"require": "./dist/motion.cjs"
"type": "./dist/helpers/motion.d.ts",
"import": "./dist/helpers/motion.js",
"require": "./dist/helpers/motion.cjs"
},
"./m": {
"type": "./dist/m.d.ts",
"import": "./dist/m.js",
"require": "./dist/m.cjs"
"type": "./dist/helpers/m.d.ts",
"import": "./dist/helpers/m.js",
"require": "./dist/helpers/m.cjs"
},
"./mobile-detector": {
"type": "./dist/mobile-detector.d.ts",
"import": "./dist/mobile-detector.js",
"require": "./dist/mobile-detector.cjs"
"type": "./dist/helpers/mobile-detector.d.ts",
"import": "./dist/helpers/mobile-detector.js",
"require": "./dist/helpers/mobile-detector.cjs"
}
}
},
Expand Down Expand Up @@ -90,7 +90,6 @@
"@vitejs/plugin-react": "4.2.1",
"dts-bundle-generator": "^9.3.1",
"esbuild": "0.20.2",
"foxact": "0.2.33",
"framer-motion": "11.0.13",
"husky": "9.0.11",
"lint-staged": "15.2.2",
Expand All @@ -99,6 +98,7 @@
"postcss-nested": "6.0.1",
"prettier": "3.2.5",
"react": "18.2.0",
"rollup-plugin-preserve-directives": "0.4.0",
"tailwindcss": "3.4.1",
"tsc-alias": "1.8.8",
"tslib": "2.6.2",
Expand All @@ -122,4 +122,4 @@
"tailwind-merge": "^2",
"vaul": "^0.9.0"
}
}
}
22 changes: 18 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions src/hooks/use-event-callback.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useCallback, useRef } from 'react'
import { useIsomorphicLayoutEffect } from 'foxact/use-isomorphic-layout-effect'
import { useCallback, useEffect, useLayoutEffect, useRef } from 'react'

const useIsomorphicLayoutEffect =
typeof window === 'undefined' ? useEffect : useLayoutEffect

export const useEventCallback = <T extends (...args: any[]) => any>(fn: T) => {
const ref = useRef<T>(fn)
Expand Down
2 changes: 2 additions & 0 deletions src/sheet/Sheet.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client'

import React, { useEffect, useMemo, useState } from 'react'
import { Drawer } from 'vaul'
import type { FC, PropsWithChildren, ReactNode } from 'react'
Expand Down
Loading

0 comments on commit bb8093a

Please sign in to comment.