import * as React from 'react' import * as Dialog from '@radix-ui/react-alert-dialog' import { MixerVerticalIcon, Pencil1Icon } from '@radix-ui/react-icons' import type { TDSnapshot, TDPage } from '~types' import { useTldrawApp } from '~hooks' import { RowButton, RowButtonProps } from '~components/Primitives/RowButton' import { styled } from '~styles' import { Divider } from '~components/Primitives/Divider' import { IconButton } from '~components/Primitives/IconButton/IconButton' import { SmallIcon } from '~components/Primitives/SmallIcon' import { breakpoints } from '~components/breakpoints' import { TextField } from '~components/Primitives/TextField' import { FormattedMessage, useIntl } from 'react-intl' const canDeleteSelector = (s: TDSnapshot) => { return Object.keys(s.document.pages).length > 1 } interface PageOptionsDialogProps { page: TDPage onOpen?: () => void onClose?: () => void } export function PageOptionsDialog({ page, onOpen, onClose }: PageOptionsDialogProps) { const app = useTldrawApp() const intl = useIntl() const [isOpen, setIsOpen] = React.useState(false) const [pageName, setPageName] = React.useState(page.name || 'Page') const canDelete = app.useStore(canDeleteSelector) const rInput = React.useRef(null) const handleDuplicate = React.useCallback(() => { app.duplicatePage(page.id) onClose?.() }, [app]) const handleDelete = React.useCallback(() => { if (window.confirm(`Are you sure you want to delete this page?`)) { app.deletePage(page.id) onClose?.() } }, [app]) const handleOpenChange = React.useCallback( (isOpen: boolean) => { setIsOpen(isOpen) if (isOpen) { onOpen?.() return } }, [app] ) const close = React.useCallback(() => setIsOpen(false), []) function stopPropagation(e: React.KeyboardEvent) { e.stopPropagation() } // TODO: Replace with text input function handleRename(event: React.ChangeEvent) { setPageName(event.target.value) app.renamePage(page.id, event.target.value || page.name || 'Page') } React.useEffect(() => { if (isOpen) { requestAnimationFrame(() => { const elm = rInput.current if (elm) { elm.focus() elm.select() } }) } }, [isOpen]) return ( } /> ) } /* -------------------------------------------------- */ /* Dialog */ /* -------------------------------------------------- */ export const StyledDialogContent = styled(Dialog.Content, { position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', minWidth: 240, maxWidth: 'fit-content', maxHeight: '85vh', marginTop: '-5vh', pointerEvents: 'all', backgroundColor: '$panel', padding: '$0', borderRadius: '$2', font: '$ui', '&:focus': { outline: 'none', }, }) export const StyledDialogOverlay = styled(Dialog.Overlay, { backgroundColor: 'rgba(0, 0, 0, .15)', position: 'fixed', pointerEvents: 'all', inset: 0, }) function DialogAction({ onSelect, ...rest }: RowButtonProps & { onSelect: (e: React.SyntheticEvent) => void }) { return ( ) }