Skip to content

Commit

Permalink
feat: vaul in mobile
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <i@innei.in>
  • Loading branch information
Innei committed Nov 2, 2023
1 parent 180449e commit c919584
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 1 deletion.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
"socket.io-client": "4.7.2",
"tailwind-merge": "2.0.0",
"uniqolor": "1.1.0",
"vaul": "0.7.7",
"xss": "1.0.14"
},
"devDependencies": {
Expand Down
17 changes: 17 additions & 0 deletions pnpm-lock.yaml

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

4 changes: 3 additions & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,9 @@ export default async function RootLayout(props: Props) {
appConfig={themeConfig.config}
/>

<Root>{children}</Root>
<div data-theme>
<Root>{children}</Root>
</div>

<TocAutoScroll />
<SearchPanelWithHotKey />
Expand Down
87 changes: 87 additions & 0 deletions src/components/ui/sheet/Sheet.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import React, { useEffect, useMemo, useState } from 'react'
import { atom, useStore } from 'jotai'
import { Drawer } from 'vaul'
import type { FC, PropsWithChildren } from 'react'

export interface PresentSheetProps {
content: JSX.Element | FC
open?: boolean
onOpenChange?: (value: boolean) => void
title?: string
zIndex?: number
dismissible?: boolean
}

export const sheetStackAtom = atom([] as HTMLDivElement[])

export const PresentSheet: FC<PropsWithChildren<PresentSheetProps>> = (
props,
) => {
const { content, children, zIndex = 998, title, dismissible = true } = props
const nextRootProps = useMemo(() => {
const nextProps = {} as any
if (props.open !== undefined) {
nextProps.open = props.open
}

if (props.onOpenChange !== undefined) {
nextProps.onOpenChange = props.onOpenChange
}

return nextProps
}, [props])
const [holderRef, setHolderRef] = useState<HTMLDivElement | null>()
const store = useStore()

useEffect(() => {
const holder = holderRef
if (!holder) return
store.set(sheetStackAtom, (p) => {
return p.concat(holder)
})

return () => {
store.set(sheetStackAtom, (p) => {
return p.filter((item) => item !== holder)
})
}
}, [holderRef, store])

const Root = Drawer.Root

const overlayZIndex = zIndex - 1
const contentZIndex = zIndex

return (
<Root dismissible={dismissible} {...nextRootProps}>
<Drawer.Trigger asChild>{children}</Drawer.Trigger>
<Drawer.Portal>
<Drawer.Content
style={{
zIndex: contentZIndex,
}}
className="fixed bottom-0 left-0 right-0 mt-24 flex max-h-[95vh] flex-col rounded-t-[10px] bg-base-100 p-4"
>
{dismissible && (
<div className="mx-auto mb-8 h-1.5 w-12 flex-shrink-0 rounded-full bg-zinc-300 dark:bg-neutral-800" />
)}

{title && <Drawer.Title>{title}</Drawer.Title>}

{React.isValidElement(content)
? content
: typeof content === 'function'
? React.createElement(content)
: null}
<div ref={setHolderRef} />
</Drawer.Content>
<Drawer.Overlay
className="fixed inset-0 bg-neutral-800/40"
style={{
zIndex: overlayZIndex,
}}
/>
</Drawer.Portal>
</Root>
)
}
1 change: 1 addition & 0 deletions src/components/ui/sheet/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Sheet'
17 changes: 17 additions & 0 deletions src/providers/root/modal-stack-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ import { usePathname } from 'next/navigation'
import type { Target, Transition } from 'framer-motion'
import type { FC, PropsWithChildren, SyntheticEvent } from 'react'

import { useIsMobile } from '~/atoms'
import { CloseIcon } from '~/components/icons/close'
import { DialogOverlay } from '~/components/ui/dialog/DialogOverlay'
import { Divider } from '~/components/ui/divider'
import { PresentSheet, sheetStackAtom } from '~/components/ui/sheet'
import { microReboundPreset } from '~/constants/spring'
import { useIsClient } from '~/hooks/common/use-is-client'
import { useIsUnMounted } from '~/hooks/common/use-is-unmounted'
Expand Down Expand Up @@ -195,6 +197,21 @@ const Modal: Component<{
dismiss: close,
}

const isMobile = useIsMobile()

if (isMobile) {
const drawerLength = jotaiStore.get(sheetStackAtom).length

return (
<PresentSheet
open
zIndex={1000 + drawerLength}
onOpenChange={onClose}
content={createElement(content, ModalProps)}
/>
)
}

if (CustomModalComponent) {
return (
<Dialog.Root open onOpenChange={onClose}>
Expand Down

1 comment on commit c919584

@vercel
Copy link

@vercel vercel bot commented on c919584 Nov 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

shiro – ./

shiro-git-main-innei.vercel.app
shiro-innei.vercel.app
springtide.vercel.app
innei.in

Please sign in to comment.