import * as _ContextMenu from '@radix-ui/react-context-menu' import styled from 'styles' import { IconWrapper, IconButton as _IconButton, RowButton, } from 'components/shared' import { commandKey, deepCompareArrays, getSelectedShapes, isMobile, } from 'utils/utils' import state, { useSelector } from 'state' import { AlignType, DistributeType, MoveType, ShapeType, StretchType, } from 'types' import React, { useRef } from 'react' import { ChevronRightIcon, AlignBottomIcon, AlignCenterHorizontallyIcon, AlignCenterVerticallyIcon, AlignLeftIcon, AlignRightIcon, AlignTopIcon, SpaceEvenlyHorizontallyIcon, SpaceEvenlyVerticallyIcon, StretchHorizontallyIcon, StretchVerticallyIcon, } from '@radix-ui/react-icons' function alignTop() { state.send('ALIGNED', { type: AlignType.Top }) } function alignCenterVertical() { state.send('ALIGNED', { type: AlignType.CenterVertical }) } function alignBottom() { state.send('ALIGNED', { type: AlignType.Bottom }) } function stretchVertically() { state.send('STRETCHED', { type: StretchType.Vertical }) } function distributeVertically() { state.send('DISTRIBUTED', { type: DistributeType.Vertical }) } function alignLeft() { state.send('ALIGNED', { type: AlignType.Left }) } function alignCenterHorizontal() { state.send('ALIGNED', { type: AlignType.CenterHorizontal }) } function alignRight() { state.send('ALIGNED', { type: AlignType.Right }) } function stretchHorizontally() { state.send('STRETCHED', { type: StretchType.Horizontal }) } function distributeHorizontally() { state.send('DISTRIBUTED', { type: DistributeType.Horizontal }) } export default function ContextMenu({ children, }: { children: React.ReactNode }): JSX.Element { const selectedShapes = useSelector( (s) => getSelectedShapes(s.data), deepCompareArrays ) const rContent = useRef(null) const hasGroupSelectd = selectedShapes.some((s) => s.type === ShapeType.Group) const hasTwoOrMore = selectedShapes.length > 1 const hasThreeOrMore = selectedShapes.length > 2 return ( <_ContextMenu.Root> <_ContextMenu.Trigger>{children} {selectedShapes.length ? ( <> {/* */} {hasGroupSelectd || (hasTwoOrMore && ( <> {hasGroupSelectd && ( )} {hasTwoOrMore && ( )} ))} {hasTwoOrMore && ( )} ) : ( <> )} ) } const StyledContent = styled(_ContextMenu.Content, { position: 'relative', backgroundColor: '$panel', borderRadius: '4px', overflow: 'hidden', pointerEvents: 'all', userSelect: 'none', zIndex: 200, padding: 3, boxShadow: '0px 2px 4px rgba(0,0,0,.2)', minWidth: 128, '& kbd': { marginLeft: '32px', fontSize: '$1', fontFamily: '$ui', }, '& kbd > span': { display: 'inline-block', width: '12px', }, variants: { isMobile: { true: { '& kbd': { display: 'none', }, }, }, }, }) const StyledDivider = styled(_ContextMenu.Separator, { backgroundColor: '$hover', height: 1, margin: '3px -3px', }) function Button({ onSelect, children, disabled = false, }: { onSelect: () => void disabled?: boolean children: React.ReactNode }) { return ( <_ContextMenu.Item as={RowButton} disabled={disabled} bp={{ '@initial': 'mobile', '@sm': 'small' }} onSelect={onSelect} > {children} ) } function IconButton({ onSelect, children, disabled = false, }: { onSelect: () => void disabled?: boolean children: React.ReactNode }) { return ( <_ContextMenu.Item as={_IconButton} bp={{ '@initial': 'mobile', '@sm': 'small' }} disabled={disabled} onSelect={onSelect} > {children} ) } function SubMenu({ children, label, }: { label: string children: React.ReactNode }) { return ( <_ContextMenu.Root> <_ContextMenu.TriggerItem as={RowButton} bp={{ '@initial': 'mobile', '@sm': 'small' }} > {label} {children} ) } function AlignDistributeSubMenu({ hasThreeOrMore, }: { hasTwoOrMore: boolean hasThreeOrMore: boolean }) { return ( <_ContextMenu.Root> <_ContextMenu.TriggerItem as={RowButton} bp={{ '@initial': 'mobile', '@sm': 'small' }} > Align / Distribute {hasThreeOrMore && ( )} {hasThreeOrMore && ( )} ) } const StyledGrid = styled(StyledContent, { display: 'grid', variants: { selectedStyle: { threeOrMore: { gridTemplateColumns: 'repeat(5, auto)', }, twoOrMore: { gridTemplateColumns: 'repeat(4, auto)', }, }, }, }) function MoveToPageMenu() { const documentPages = useSelector((s) => s.data.document.pages) const currentPageId = useSelector((s) => s.data.currentPageId) if (!documentPages[currentPageId]) return null const sorted = Object.values(documentPages) .sort((a, b) => a.childIndex - b.childIndex) .filter((a) => a.id !== currentPageId) if (sorted.length === 0) return null return ( <_ContextMenu.Root> <_ContextMenu.TriggerItem as={RowButton} bp={{ '@initial': 'mobile', '@sm': 'small' }} > Move To Page {sorted.map(({ id, name }) => ( ))} ) } const StyledArrow = styled(_ContextMenu.Arrow, { fill: 'white', })