import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
import { CheckIcon, PlusIcon } from '@radix-ui/react-icons'
import * as React from 'react'
import { FormattedMessage, useIntl } from 'react-intl'
import { Divider } from '~components/Primitives/Divider'
import { DMContent } from '~components/Primitives/DropdownMenu'
import { RowButton } from '~components/Primitives/RowButton'
import { SmallIcon } from '~components/Primitives/SmallIcon'
import { ToolButton } from '~components/Primitives/ToolButton'
import { useTldrawApp } from '~hooks'
import { styled } from '~styles'
import type { TDSnapshot } from '~types'
import { PageOptionsDialog } from '../PageOptionsDialog'
const sortedSelector = (s: TDSnapshot) =>
Object.values(s.document.pages).sort((a, b) => (a.childIndex || 0) - (b.childIndex || 0))
const currentPageNameSelector = (s: TDSnapshot) => s.document.pages[s.appState.currentPageId].name
const currentPageIdSelector = (s: TDSnapshot) => s.document.pages[s.appState.currentPageId].id
export function PageMenu() {
const app = useTldrawApp()
const intl = useIntl()
const rIsOpen = React.useRef(false)
const [isOpen, setIsOpen] = React.useState(false)
React.useEffect(() => {
if (rIsOpen.current !== isOpen) {
rIsOpen.current = isOpen
}
}, [isOpen])
const handleClose = React.useCallback(() => {
setIsOpen(false)
}, [setIsOpen])
const handleOpenChange = React.useCallback(
(isOpen: boolean) => {
if (rIsOpen.current !== isOpen) {
setIsOpen(isOpen)
}
},
[setIsOpen]
)
const currentPageName = app.useStore(currentPageNameSelector)
return (
{currentPageName || intl.formatMessage({ id: 'page' })}
{isOpen && }
)
}
function PageMenuContent({ onClose }: { onClose: () => void }) {
const app = useTldrawApp()
const intl = useIntl()
const sortedPages = app.useStore(sortedSelector)
const currentPageId = app.useStore(currentPageIdSelector)
const defaultPageName = intl.formatMessage({ id: 'page' })
const handleCreatePage = React.useCallback(() => {
const pageName =
defaultPageName + ' ' + (Object.keys(app.document.pages).length + 1)
app.createPage(undefined, pageName)
}, [app])
const handleChangePage = React.useCallback(
(id: string) => {
onClose()
app.changePage(id)
},
[app]
)
const [dragId, setDragId] = React.useState(null)
const [dropIndex, setDropIndex] = React.useState(null)
const handleDragStart = React.useCallback((ev: React.DragEvent) => {
setDragId(ev.currentTarget.id)
setDropIndex(sortedPages.findIndex((p) => p.id === ev.currentTarget.id))
ev.dataTransfer.effectAllowed = 'move'
}, [])
const handleDrag = React.useCallback(
(ev: React.DragEvent) => {
ev.preventDefault()
let dropIndex = sortedPages.findIndex((p) => p.id === ev.currentTarget.id)
const rect = ev.currentTarget.getBoundingClientRect()
const ny = (ev.clientY - rect.top) / rect.height
dropIndex = ny < 0.5 ? dropIndex : dropIndex + 1
setDropIndex(dropIndex)
},
[dragId, sortedPages]
)
const handleDrop = React.useCallback(() => {
if (dragId !== null && dropIndex !== null) {
app.movePage(dragId, dropIndex)
}
setDragId(null)
setDropIndex(null)
}, [dragId, dropIndex])
return (
<>
{sortedPages.map((page, i) => (
{page.name || defaultPageName}
))}
>
)
}
const ButtonWithOptions = styled('div', {
position: 'relative',
display: 'grid',
gridTemplateColumns: '1fr auto',
gridAutoFlow: 'column',
margin: 0,
'& > *[data-shy="true"]': {
opacity: 0,
},
'&:hover > *[data-shy="true"]': {
opacity: 1,
},
variants: {
isDropAbove: {
true: {
'&::after': {
content: '',
display: 'block',
position: 'absolute',
top: 0,
width: '100%',
height: '1px',
backgroundColor: '$selected',
zIndex: 999,
pointerEvents: 'none',
},
},
},
isDropBelow: {
true: {
'&::after': {
content: '',
display: 'block',
position: 'absolute',
width: '100%',
height: '1px',
top: '100%',
backgroundColor: '$selected',
zIndex: 999,
pointerEvents: 'none',
},
},
},
},
})
export const PageButton = styled(RowButton, {
minWidth: 128,
})