[fix] current style and selected style (#298)
* Fix selectedStyles from being new on each update * Fix again * Update TldrawApp.ts * Fix log around current style and selected style * Add stub test, move style menu into folder * Cleanup repo * cleanup context menu
This commit is contained in:
parent
e0b607e512
commit
eb20f1c816
76 changed files with 210 additions and 187 deletions
|
@ -1,11 +0,0 @@
|
||||||
import * as React from 'react'
|
|
||||||
import { ContextMenuItem } from '@radix-ui/react-context-menu'
|
|
||||||
import { ToolButton, ToolButtonProps } from '~components/ToolButton'
|
|
||||||
|
|
||||||
export function CMIconButton({ onSelect, ...rest }: ToolButtonProps): JSX.Element {
|
|
||||||
return (
|
|
||||||
<ContextMenuItem dir="ltr" onSelect={onSelect} asChild>
|
|
||||||
<ToolButton {...rest} />
|
|
||||||
</ContextMenuItem>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
import * as React from 'react'
|
|
||||||
import { ContextMenuItem } from '@radix-ui/react-context-menu'
|
|
||||||
import { RowButton, RowButtonProps } from '~components/RowButton'
|
|
||||||
|
|
||||||
export const CMRowButton = ({ ...rest }: RowButtonProps) => {
|
|
||||||
return (
|
|
||||||
<ContextMenuItem asChild>
|
|
||||||
<RowButton {...rest} />
|
|
||||||
</ContextMenuItem>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
import * as React from 'react'
|
|
||||||
import { ContextMenuTriggerItem } from '@radix-ui/react-context-menu'
|
|
||||||
import { RowButton, RowButtonProps } from '~components/RowButton'
|
|
||||||
|
|
||||||
interface CMTriggerButtonProps extends RowButtonProps {
|
|
||||||
isSubmenu?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CMTriggerButton = ({ isSubmenu, ...rest }: CMTriggerButtonProps) => {
|
|
||||||
return (
|
|
||||||
<ContextMenuTriggerItem asChild>
|
|
||||||
<RowButton hasArrow={isSubmenu} {...rest} />
|
|
||||||
</ContextMenuTriggerItem>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -15,20 +15,13 @@ import {
|
||||||
StretchHorizontallyIcon,
|
StretchHorizontallyIcon,
|
||||||
StretchVerticallyIcon,
|
StretchVerticallyIcon,
|
||||||
} from '@radix-ui/react-icons'
|
} from '@radix-ui/react-icons'
|
||||||
import { CMRowButton } from './CMRowButton'
|
import { Divider } from '~components/Primitives/Divider'
|
||||||
import { CMIconButton } from './CMIconButton'
|
import { MenuContent } from '~components/Primitives/MenuContent'
|
||||||
import { CMTriggerButton } from './CMTriggerButton'
|
import { RowButton, RowButtonProps } from '~components/Primitives/RowButton'
|
||||||
import { Divider } from '~components/Divider'
|
import { ToolButton, ToolButtonProps } from '~components/Primitives/ToolButton'
|
||||||
import { MenuContent } from '~components/MenuContent'
|
|
||||||
|
|
||||||
const has1SelectedIdsSelector = (s: TDSnapshot) => {
|
const numberOfSelectedIdsSelector = (s: TDSnapshot) => {
|
||||||
return s.document.pageStates[s.appState.currentPageId].selectedIds.length > 0
|
return s.document.pageStates[s.appState.currentPageId].selectedIds.length
|
||||||
}
|
|
||||||
const has2SelectedIdsSelector = (s: TDSnapshot) => {
|
|
||||||
return s.document.pageStates[s.appState.currentPageId].selectedIds.length > 1
|
|
||||||
}
|
|
||||||
const has3SelectedIdsSelector = (s: TDSnapshot) => {
|
|
||||||
return s.document.pageStates[s.appState.currentPageId].selectedIds.length > 2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const isDebugModeSelector = (s: TDSnapshot) => {
|
const isDebugModeSelector = (s: TDSnapshot) => {
|
||||||
|
@ -50,9 +43,7 @@ interface ContextMenuProps {
|
||||||
|
|
||||||
export const ContextMenu = ({ onBlur, children }: ContextMenuProps): JSX.Element => {
|
export const ContextMenu = ({ onBlur, children }: ContextMenuProps): JSX.Element => {
|
||||||
const app = useTldrawApp()
|
const app = useTldrawApp()
|
||||||
const hasSelection = app.useStore(has1SelectedIdsSelector)
|
const numberOfSelectedIds = app.useStore(numberOfSelectedIdsSelector)
|
||||||
const hasTwoOrMore = app.useStore(has2SelectedIdsSelector)
|
|
||||||
const hasThreeOrMore = app.useStore(has3SelectedIdsSelector)
|
|
||||||
const isDebugMode = app.useStore(isDebugModeSelector)
|
const isDebugMode = app.useStore(isDebugModeSelector)
|
||||||
const hasGroupSelected = app.useStore(hasGroupSelectedSelector)
|
const hasGroupSelected = app.useStore(hasGroupSelectedSelector)
|
||||||
|
|
||||||
|
@ -122,6 +113,10 @@ export const ContextMenu = ({ onBlur, children }: ContextMenuProps): JSX.Element
|
||||||
app.redo()
|
app.redo()
|
||||||
}, [app])
|
}, [app])
|
||||||
|
|
||||||
|
const hasSelection = numberOfSelectedIds > 0
|
||||||
|
const hasTwoOrMore = numberOfSelectedIds > 1
|
||||||
|
const hasThreeOrMore = numberOfSelectedIds > 2
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RadixContextMenu.Root dir="ltr">
|
<RadixContextMenu.Root dir="ltr">
|
||||||
<RadixContextMenu.Trigger dir="ltr">{children}</RadixContextMenu.Trigger>
|
<RadixContextMenu.Trigger dir="ltr">{children}</RadixContextMenu.Trigger>
|
||||||
|
@ -216,6 +211,8 @@ export const ContextMenu = ({ onBlur, children }: ContextMenuProps): JSX.Element
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---------- Align and Distribute Sub Menu --------- */
|
||||||
|
|
||||||
function AlignDistributeSubMenu({
|
function AlignDistributeSubMenu({
|
||||||
hasThreeOrMore,
|
hasThreeOrMore,
|
||||||
}: {
|
}: {
|
||||||
|
@ -268,7 +265,7 @@ function AlignDistributeSubMenu({
|
||||||
<RadixContextMenu.Root dir="ltr">
|
<RadixContextMenu.Root dir="ltr">
|
||||||
<CMTriggerButton isSubmenu>Align / Distribute</CMTriggerButton>
|
<CMTriggerButton isSubmenu>Align / Distribute</CMTriggerButton>
|
||||||
<RadixContextMenu.Content asChild sideOffset={2} alignOffset={-2}>
|
<RadixContextMenu.Content asChild sideOffset={2} alignOffset={-2}>
|
||||||
<StyledGridContent selectedStyle={hasThreeOrMore ? 'threeOrMore' : 'twoOrMore'}>
|
<StyledGridContent numberOfSelected={hasThreeOrMore ? 'threeOrMore' : 'twoOrMore'}>
|
||||||
<CMIconButton onClick={alignLeft}>
|
<CMIconButton onClick={alignLeft}>
|
||||||
<AlignLeftIcon />
|
<AlignLeftIcon />
|
||||||
</CMIconButton>
|
</CMIconButton>
|
||||||
|
@ -313,7 +310,7 @@ function AlignDistributeSubMenu({
|
||||||
const StyledGridContent = styled(MenuContent, {
|
const StyledGridContent = styled(MenuContent, {
|
||||||
display: 'grid',
|
display: 'grid',
|
||||||
variants: {
|
variants: {
|
||||||
selectedStyle: {
|
numberOfSelected: {
|
||||||
threeOrMore: {
|
threeOrMore: {
|
||||||
gridTemplateColumns: 'repeat(5, auto)',
|
gridTemplateColumns: 'repeat(5, auto)',
|
||||||
},
|
},
|
||||||
|
@ -324,7 +321,7 @@ const StyledGridContent = styled(MenuContent, {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
/* ------------------ Move to Page ------------------ */
|
/* -------------- Move to Page Sub Menu ------------- */
|
||||||
|
|
||||||
const currentPageIdSelector = (s: TDSnapshot) => s.appState.currentPageId
|
const currentPageIdSelector = (s: TDSnapshot) => s.appState.currentPageId
|
||||||
const documentPagesSelector = (s: TDSnapshot) => s.document.pages
|
const documentPagesSelector = (s: TDSnapshot) => s.document.pages
|
||||||
|
@ -387,3 +384,37 @@ export function ContextMenuSubMenu({ children, label }: ContextMenuSubMenuProps)
|
||||||
const CMArrow = styled(RadixContextMenu.ContextMenuArrow, {
|
const CMArrow = styled(RadixContextMenu.ContextMenuArrow, {
|
||||||
fill: '$panel',
|
fill: '$panel',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/* ------------------- IconButton ------------------- */
|
||||||
|
|
||||||
|
function CMIconButton({ onSelect, ...rest }: ToolButtonProps): JSX.Element {
|
||||||
|
return (
|
||||||
|
<RadixContextMenu.ContextMenuItem dir="ltr" onSelect={onSelect} asChild>
|
||||||
|
<ToolButton {...rest} />
|
||||||
|
</RadixContextMenu.ContextMenuItem>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------- RowButton ------------------- */
|
||||||
|
|
||||||
|
const CMRowButton = ({ ...rest }: RowButtonProps) => {
|
||||||
|
return (
|
||||||
|
<RadixContextMenu.ContextMenuItem asChild>
|
||||||
|
<RowButton {...rest} />
|
||||||
|
</RadixContextMenu.ContextMenuItem>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------- Trigger Button ----------------- */
|
||||||
|
|
||||||
|
interface CMTriggerButtonProps extends RowButtonProps {
|
||||||
|
isSubmenu?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CMTriggerButton = ({ isSubmenu, ...rest }: CMTriggerButtonProps) => {
|
||||||
|
return (
|
||||||
|
<RadixContextMenu.ContextMenuTriggerItem asChild>
|
||||||
|
<RowButton hasArrow={isSubmenu} {...rest} />
|
||||||
|
</RadixContextMenu.ContextMenuTriggerItem>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { DotFilledIcon } from '@radix-ui/react-icons'
|
import { DotFilledIcon } from '@radix-ui/react-icons'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { IconButton } from '~components/IconButton/IconButton'
|
import { IconButton } from '~components/Primitives/IconButton/IconButton'
|
||||||
import { styled } from '~styles'
|
import { styled } from '~styles'
|
||||||
|
|
||||||
interface FocusButtonProps {
|
interface FocusButtonProps {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { CheckboxItem } from '@radix-ui/react-dropdown-menu'
|
import { CheckboxItem } from '@radix-ui/react-dropdown-menu'
|
||||||
import { RowButton, RowButtonProps } from '~components/RowButton'
|
import { RowButton, RowButtonProps } from '~components/Primitives/RowButton'
|
||||||
import { preventEvent } from '~components/preventEvent'
|
import { preventEvent } from '~components/preventEvent'
|
||||||
|
|
||||||
interface DMCheckboxItemProps {
|
interface DMCheckboxItemProps {
|
|
@ -1,7 +1,7 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { Content } from '@radix-ui/react-dropdown-menu'
|
import { Content } from '@radix-ui/react-dropdown-menu'
|
||||||
import { styled } from '~styles/stitches.config'
|
import { styled } from '~styles/stitches.config'
|
||||||
import { MenuContent } from '~components/MenuContent'
|
import { MenuContent } from '~components/Primitives/MenuContent'
|
||||||
import { stopPropagation } from '~components/stopPropagation'
|
import { stopPropagation } from '~components/stopPropagation'
|
||||||
|
|
||||||
export interface DMContentProps {
|
export interface DMContentProps {
|
|
@ -1,6 +1,6 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { Item } from '@radix-ui/react-dropdown-menu'
|
import { Item } from '@radix-ui/react-dropdown-menu'
|
||||||
import { RowButton, RowButtonProps } from '~components/RowButton'
|
import { RowButton, RowButtonProps } from '~components/Primitives/RowButton'
|
||||||
|
|
||||||
export function DMItem({
|
export function DMItem({
|
||||||
onSelect,
|
onSelect,
|
|
@ -1,7 +1,7 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { Root, TriggerItem, Content, Arrow } from '@radix-ui/react-dropdown-menu'
|
import { Root, TriggerItem, Content, Arrow } from '@radix-ui/react-dropdown-menu'
|
||||||
import { RowButton } from '~components/RowButton'
|
import { RowButton } from '~components/Primitives/RowButton'
|
||||||
import { MenuContent } from '~components/MenuContent'
|
import { MenuContent } from '~components/Primitives/MenuContent'
|
||||||
|
|
||||||
export interface DMSubMenuProps {
|
export interface DMSubMenuProps {
|
||||||
label: string
|
label: string
|
|
@ -1,6 +1,6 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { Trigger } from '@radix-ui/react-dropdown-menu'
|
import { Trigger } from '@radix-ui/react-dropdown-menu'
|
||||||
import { ToolButton, ToolButtonProps } from '~components/ToolButton'
|
import { ToolButton, ToolButtonProps } from '~components/Primitives/ToolButton'
|
||||||
|
|
||||||
interface DMTriggerIconProps extends ToolButtonProps {
|
interface DMTriggerIconProps extends ToolButtonProps {
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
|
@ -2,8 +2,8 @@ import { ItemIndicator } from '@radix-ui/react-dropdown-menu'
|
||||||
import { ChevronRightIcon, CheckIcon } from '@radix-ui/react-icons'
|
import { ChevronRightIcon, CheckIcon } from '@radix-ui/react-icons'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { breakpoints } from '~components/breakpoints'
|
import { breakpoints } from '~components/breakpoints'
|
||||||
import { Kbd } from '~components/Kbd'
|
import { Kbd } from '~components/Primitives/Kbd'
|
||||||
import { SmallIcon } from '~components/SmallIcon'
|
import { SmallIcon } from '~components/Primitives/SmallIcon'
|
||||||
import { styled } from '~styles'
|
import { styled } from '~styles'
|
||||||
|
|
||||||
export interface RowButtonProps {
|
export interface RowButtonProps {
|
|
@ -1,6 +1,6 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { breakpoints } from '~components/breakpoints'
|
import { breakpoints } from '~components/breakpoints'
|
||||||
import { Tooltip } from '~components/Tooltip'
|
import { Tooltip } from '~components/Primitives/Tooltip'
|
||||||
import { useTldrawApp } from '~hooks'
|
import { useTldrawApp } from '~hooks'
|
||||||
import { styled } from '~styles'
|
import { styled } from '~styles'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as RadixTooltip from '@radix-ui/react-tooltip'
|
import * as RadixTooltip from '@radix-ui/react-tooltip'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { Kbd } from '~components/Kbd'
|
import { Kbd } from '~components/Primitives/Kbd'
|
||||||
import { styled } from '~styles'
|
import { styled } from '~styles'
|
||||||
|
|
||||||
/* -------------------------------------------------- */
|
/* -------------------------------------------------- */
|
|
@ -1,5 +1,5 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { Tooltip } from '~components/Tooltip/Tooltip'
|
import { Tooltip } from '~components/Primitives/Tooltip/Tooltip'
|
||||||
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
||||||
import { useTldrawApp } from '~hooks'
|
import { useTldrawApp } from '~hooks'
|
||||||
import { styled } from '~styles'
|
import { styled } from '~styles'
|
||||||
|
@ -28,10 +28,10 @@ import {
|
||||||
StretchVerticallyIcon,
|
StretchVerticallyIcon,
|
||||||
BoxIcon,
|
BoxIcon,
|
||||||
} from '@radix-ui/react-icons'
|
} from '@radix-ui/react-icons'
|
||||||
import { DMContent } from '~components/DropdownMenu'
|
import { DMContent } from '~components/Primitives/DropdownMenu'
|
||||||
import { Divider } from '~components/Divider'
|
import { Divider } from '~components/Primitives/Divider'
|
||||||
import { TrashIcon } from '~components/icons'
|
import { TrashIcon } from '~components/Primitives/icons'
|
||||||
import { ToolButton } from '~components/ToolButton'
|
import { ToolButton } from '~components/Primitives/ToolButton'
|
||||||
|
|
||||||
const selectedShapesCountSelector = (s: TDSnapshot) =>
|
const selectedShapesCountSelector = (s: TDSnapshot) =>
|
||||||
s.document.pageStates[s.appState.currentPageId].selectedIds.length
|
s.document.pageStates[s.appState.currentPageId].selectedIds.length
|
||||||
|
|
|
@ -2,8 +2,8 @@ import * as React from 'react'
|
||||||
import { styled } from '~styles'
|
import { styled } from '~styles'
|
||||||
import type { TDSnapshot } from '~types'
|
import type { TDSnapshot } from '~types'
|
||||||
import { useTldrawApp } from '~hooks'
|
import { useTldrawApp } from '~hooks'
|
||||||
import { RowButton } from '~components/RowButton'
|
import { RowButton } from '~components/Primitives/RowButton'
|
||||||
import { MenuContent } from '~components/MenuContent'
|
import { MenuContent } from '~components/Primitives/MenuContent'
|
||||||
|
|
||||||
const isEmptyCanvasSelector = (s: TDSnapshot) =>
|
const isEmptyCanvasSelector = (s: TDSnapshot) =>
|
||||||
Object.keys(s.document.pages[s.appState.currentPageId].shapes).length > 0 &&
|
Object.keys(s.document.pages[s.appState.currentPageId].shapes).length > 0 &&
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { Tooltip } from '~components/Tooltip'
|
import { Tooltip } from '~components/Primitives/Tooltip'
|
||||||
import { useTldrawApp } from '~hooks'
|
import { useTldrawApp } from '~hooks'
|
||||||
import { ToolButton } from '~components/ToolButton'
|
import { ToolButton } from '~components/Primitives/ToolButton'
|
||||||
import { TrashIcon } from '~components/icons'
|
import { TrashIcon } from '~components/Primitives/icons'
|
||||||
|
|
||||||
export function DeleteButton(): JSX.Element {
|
export function DeleteButton(): JSX.Element {
|
||||||
const app = useTldrawApp()
|
const app = useTldrawApp()
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { LockClosedIcon, LockOpen1Icon } from '@radix-ui/react-icons'
|
import { LockClosedIcon, LockOpen1Icon } from '@radix-ui/react-icons'
|
||||||
import { Tooltip } from '~components/Tooltip'
|
import { Tooltip } from '~components/Primitives/Tooltip'
|
||||||
import { useTldrawApp } from '~hooks'
|
import { useTldrawApp } from '~hooks'
|
||||||
import { ToolButton } from '~components/ToolButton'
|
import { ToolButton } from '~components/Primitives/ToolButton'
|
||||||
import type { TDSnapshot } from '~types'
|
import type { TDSnapshot } from '~types'
|
||||||
|
|
||||||
const isToolLockedSelector = (s: TDSnapshot) => s.appState.isToolLocked
|
const isToolLockedSelector = (s: TDSnapshot) => s.appState.isToolLocked
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
||||||
import { Panel } from '~components/Panel'
|
import { Panel } from '~components/Primitives/Panel'
|
||||||
import { ToolButton } from '~components/ToolButton'
|
import { ToolButton } from '~components/Primitives/ToolButton'
|
||||||
import { TDShapeType, TDToolType } from '~types'
|
import { TDShapeType, TDToolType } from '~types'
|
||||||
import { useTldrawApp } from '~hooks'
|
import { useTldrawApp } from '~hooks'
|
||||||
import { Pencil1Icon } from '@radix-ui/react-icons'
|
import { Pencil1Icon } from '@radix-ui/react-icons'
|
||||||
import { Tooltip } from '~components/Tooltip'
|
import { Tooltip } from '~components/Primitives/Tooltip'
|
||||||
|
|
||||||
interface ShapesMenuProps {
|
interface ShapesMenuProps {
|
||||||
activeTool: TDToolType
|
activeTool: TDToolType
|
||||||
|
|
|
@ -8,10 +8,10 @@ import {
|
||||||
} from '@radix-ui/react-icons'
|
} from '@radix-ui/react-icons'
|
||||||
import { TDSnapshot, TDShapeType } from '~types'
|
import { TDSnapshot, TDShapeType } from '~types'
|
||||||
import { useTldrawApp } from '~hooks'
|
import { useTldrawApp } from '~hooks'
|
||||||
import { ToolButtonWithTooltip } from '~components/ToolButton'
|
import { ToolButtonWithTooltip } from '~components/Primitives/ToolButton'
|
||||||
import { Panel } from '~components/Panel'
|
import { Panel } from '~components/Primitives/Panel'
|
||||||
import { ShapesMenu } from './ShapesMenu'
|
import { ShapesMenu } from './ShapesMenu'
|
||||||
import { EraserIcon } from '~components/icons'
|
import { EraserIcon } from '~components/Primitives/icons'
|
||||||
|
|
||||||
const activeToolSelector = (s: TDSnapshot) => s.appState.activeTool
|
const activeToolSelector = (s: TDSnapshot) => s.appState.activeTool
|
||||||
const toolLockedSelector = (s: TDSnapshot) => s.appState.isToolLocked
|
const toolLockedSelector = (s: TDSnapshot) => s.appState.isToolLocked
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
||||||
import { Panel } from '~components/Panel'
|
import { Panel } from '~components/Primitives/Panel'
|
||||||
import { ToolButton } from '~components/ToolButton'
|
import { ToolButton } from '~components/Primitives/ToolButton'
|
||||||
import { TDShapeType, TDToolType } from '~types'
|
import { TDShapeType, TDToolType } from '~types'
|
||||||
import { useTldrawApp } from '~hooks'
|
import { useTldrawApp } from '~hooks'
|
||||||
import { SquareIcon, CircleIcon } from '@radix-ui/react-icons'
|
import { SquareIcon, CircleIcon } from '@radix-ui/react-icons'
|
||||||
import { Tooltip } from '~components/Tooltip'
|
import { Tooltip } from '~components/Primitives/Tooltip'
|
||||||
|
|
||||||
interface ShapesMenuProps {
|
interface ShapesMenuProps {
|
||||||
activeTool: TDToolType
|
activeTool: TDToolType
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
export function HelpMenu() {
|
|
||||||
return <div />
|
|
||||||
}
|
|
|
@ -2,11 +2,17 @@ import * as React from 'react'
|
||||||
import { ExitIcon, GitHubLogoIcon, HamburgerMenuIcon, TwitterLogoIcon } from '@radix-ui/react-icons'
|
import { ExitIcon, GitHubLogoIcon, HamburgerMenuIcon, TwitterLogoIcon } from '@radix-ui/react-icons'
|
||||||
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
||||||
import { useTldrawApp } from '~hooks'
|
import { useTldrawApp } from '~hooks'
|
||||||
import { PreferencesMenu } from './PreferencesMenu'
|
import { PreferencesMenu } from '../PreferencesMenu'
|
||||||
import { DMItem, DMContent, DMDivider, DMSubMenu, DMTriggerIcon } from '~components/DropdownMenu'
|
import {
|
||||||
import { SmallIcon } from '~components/SmallIcon'
|
DMItem,
|
||||||
|
DMContent,
|
||||||
|
DMDivider,
|
||||||
|
DMSubMenu,
|
||||||
|
DMTriggerIcon,
|
||||||
|
} from '~components/Primitives/DropdownMenu'
|
||||||
|
import { SmallIcon } from '~components/Primitives/SmallIcon'
|
||||||
import { useFileSystemHandlers } from '~hooks'
|
import { useFileSystemHandlers } from '~hooks'
|
||||||
import { HeartIcon } from '~components/icons/HeartIcon'
|
import { HeartIcon } from '~components/Primitives/icons/HeartIcon'
|
||||||
import { preventEvent } from '~components/preventEvent'
|
import { preventEvent } from '~components/preventEvent'
|
||||||
|
|
||||||
interface MenuProps {
|
interface MenuProps {
|
0
packages/tldraw/src/components/TopPanel/Menu/index.ts
Normal file
0
packages/tldraw/src/components/TopPanel/Menu/index.ts
Normal file
|
@ -2,9 +2,9 @@ import * as React from 'react'
|
||||||
import { CheckIcon, ClipboardIcon } from '@radix-ui/react-icons'
|
import { CheckIcon, ClipboardIcon } from '@radix-ui/react-icons'
|
||||||
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
||||||
import { useTldrawApp } from '~hooks'
|
import { useTldrawApp } from '~hooks'
|
||||||
import { DMItem, DMContent, DMDivider, DMTriggerIcon } from '~components/DropdownMenu'
|
import { DMItem, DMContent, DMDivider, DMTriggerIcon } from '~components/Primitives/DropdownMenu'
|
||||||
import { SmallIcon } from '~components/SmallIcon'
|
import { SmallIcon } from '~components/Primitives/SmallIcon'
|
||||||
import { MultiplayerIcon } from '~components/icons'
|
import { MultiplayerIcon } from '~components/Primitives/icons'
|
||||||
import type { TDSnapshot } from '~types'
|
import type { TDSnapshot } from '~types'
|
||||||
import { TLDR } from '~state/TLDR'
|
import { TLDR } from '~state/TLDR'
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './MultiplayerMenu'
|
|
@ -1,14 +1,14 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
||||||
import { PlusIcon, CheckIcon } from '@radix-ui/react-icons'
|
import { PlusIcon, CheckIcon } from '@radix-ui/react-icons'
|
||||||
import { PageOptionsDialog } from './PageOptionsDialog'
|
import { PageOptionsDialog } from '../PageOptionsDialog'
|
||||||
import { styled } from '~styles'
|
import { styled } from '~styles'
|
||||||
import { useTldrawApp } from '~hooks'
|
import { useTldrawApp } from '~hooks'
|
||||||
import type { TDSnapshot } from '~types'
|
import type { TDSnapshot } from '~types'
|
||||||
import { DMContent, DMDivider } from '~components/DropdownMenu'
|
import { DMContent, DMDivider } from '~components/Primitives/DropdownMenu'
|
||||||
import { SmallIcon } from '~components/SmallIcon'
|
import { SmallIcon } from '~components/Primitives/SmallIcon'
|
||||||
import { RowButton } from '~components/RowButton'
|
import { RowButton } from '~components/Primitives/RowButton'
|
||||||
import { ToolButton } from '~components/ToolButton'
|
import { ToolButton } from '~components/Primitives/ToolButton'
|
||||||
|
|
||||||
const sortedSelector = (s: TDSnapshot) =>
|
const sortedSelector = (s: TDSnapshot) =>
|
||||||
Object.values(s.document.pages).sort((a, b) => (a.childIndex || 0) - (b.childIndex || 0))
|
Object.values(s.document.pages).sort((a, b) => (a.childIndex || 0) - (b.childIndex || 0))
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './PageMenu'
|
|
@ -3,11 +3,11 @@ import * as Dialog from '@radix-ui/react-alert-dialog'
|
||||||
import { MixerVerticalIcon } from '@radix-ui/react-icons'
|
import { MixerVerticalIcon } from '@radix-ui/react-icons'
|
||||||
import type { TDSnapshot, TDPage } from '~types'
|
import type { TDSnapshot, TDPage } from '~types'
|
||||||
import { useTldrawApp } from '~hooks'
|
import { useTldrawApp } from '~hooks'
|
||||||
import { RowButton, RowButtonProps } from '~components/RowButton'
|
import { RowButton, RowButtonProps } from '~components/Primitives/RowButton'
|
||||||
import { styled } from '~styles'
|
import { styled } from '~styles'
|
||||||
import { Divider } from '~components/Divider'
|
import { Divider } from '~components/Primitives/Divider'
|
||||||
import { IconButton } from '~components/IconButton/IconButton'
|
import { IconButton } from '~components/Primitives/IconButton/IconButton'
|
||||||
import { SmallIcon } from '~components/SmallIcon'
|
import { SmallIcon } from '~components/Primitives/SmallIcon'
|
||||||
import { breakpoints } from '~components/breakpoints'
|
import { breakpoints } from '~components/breakpoints'
|
||||||
|
|
||||||
const canDeleteSelector = (s: TDSnapshot) => {
|
const canDeleteSelector = (s: TDSnapshot) => {
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './PageOptionsDialog'
|
|
@ -1,5 +1,5 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { DMCheckboxItem, DMDivider, DMSubMenu } from '~components/DropdownMenu'
|
import { DMCheckboxItem, DMDivider, DMSubMenu } from '~components/Primitives/DropdownMenu'
|
||||||
import { useTldrawApp } from '~hooks'
|
import { useTldrawApp } from '~hooks'
|
||||||
import type { TDSnapshot } from '~types'
|
import type { TDSnapshot } from '~types'
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './PreferencesMenu'
|
|
@ -0,0 +1,4 @@
|
||||||
|
describe('the style menu', () => {
|
||||||
|
test.todo('Correctly sets the style properties when shapes are selected')
|
||||||
|
test.todo('Correctly sets the style properties when nothing is selected')
|
||||||
|
})
|
|
@ -1,8 +1,13 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
||||||
import { strokes, fills } from '~state/shapes/shared/shape-styles'
|
import { strokes, fills, defaultStyle } from '~state/shapes/shared/shape-styles'
|
||||||
import { useTldrawApp } from '~hooks'
|
import { useTldrawApp } from '~hooks'
|
||||||
import { DMCheckboxItem, DMContent, DMRadioItem, DMTriggerIcon } from '~components/DropdownMenu'
|
import {
|
||||||
|
DMCheckboxItem,
|
||||||
|
DMContent,
|
||||||
|
DMRadioItem,
|
||||||
|
DMTriggerIcon,
|
||||||
|
} from '~components/Primitives/DropdownMenu'
|
||||||
import {
|
import {
|
||||||
CircleIcon,
|
CircleIcon,
|
||||||
DashDashedIcon,
|
DashDashedIcon,
|
||||||
|
@ -12,24 +17,28 @@ import {
|
||||||
SizeLargeIcon,
|
SizeLargeIcon,
|
||||||
SizeMediumIcon,
|
SizeMediumIcon,
|
||||||
SizeSmallIcon,
|
SizeSmallIcon,
|
||||||
} from '~components/icons'
|
} from '~components/Primitives/icons'
|
||||||
import { ToolButton } from '~components/ToolButton'
|
import { ToolButton } from '~components/Primitives/ToolButton'
|
||||||
import { TDSnapshot, ColorStyle, DashStyle, SizeStyle } from '~types'
|
import { TDSnapshot, ColorStyle, DashStyle, SizeStyle, ShapeStyles } from '~types'
|
||||||
import { styled } from '~styles'
|
import { styled } from '~styles'
|
||||||
import { breakpoints } from '~components/breakpoints'
|
import { breakpoints } from '~components/breakpoints'
|
||||||
import { Divider } from '~components/Divider'
|
import { Divider } from '~components/Primitives/Divider'
|
||||||
import { preventEvent } from '~components/preventEvent'
|
import { preventEvent } from '~components/preventEvent'
|
||||||
|
|
||||||
const selectedStyleSelector = (s: TDSnapshot) => s.appState.selectedStyle
|
const currentStyleSelector = (s: TDSnapshot) => s.appState.currentStyle
|
||||||
|
const selectedIdsSelector = (s: TDSnapshot) =>
|
||||||
|
s.document.pageStates[s.appState.currentPageId].selectedIds
|
||||||
|
|
||||||
const dashes = {
|
const STYLE_KEYS = Object.keys(defaultStyle) as (keyof ShapeStyles)[]
|
||||||
|
|
||||||
|
const DASHES = {
|
||||||
[DashStyle.Draw]: <DashDrawIcon />,
|
[DashStyle.Draw]: <DashDrawIcon />,
|
||||||
[DashStyle.Solid]: <DashSolidIcon />,
|
[DashStyle.Solid]: <DashSolidIcon />,
|
||||||
[DashStyle.Dashed]: <DashDashedIcon />,
|
[DashStyle.Dashed]: <DashDashedIcon />,
|
||||||
[DashStyle.Dotted]: <DashDottedIcon />,
|
[DashStyle.Dotted]: <DashDottedIcon />,
|
||||||
}
|
}
|
||||||
|
|
||||||
const sizes = {
|
const SIZES = {
|
||||||
[SizeStyle.Small]: <SizeSmallIcon />,
|
[SizeStyle.Small]: <SizeSmallIcon />,
|
||||||
[SizeStyle.Medium]: <SizeMediumIcon />,
|
[SizeStyle.Medium]: <SizeMediumIcon />,
|
||||||
[SizeStyle.Large]: <SizeLargeIcon />,
|
[SizeStyle.Large]: <SizeLargeIcon />,
|
||||||
|
@ -42,7 +51,53 @@ export const StyleMenu = React.memo(function ColorMenu(): JSX.Element {
|
||||||
|
|
||||||
const theme = app.useStore(themeSelector)
|
const theme = app.useStore(themeSelector)
|
||||||
|
|
||||||
const style = app.useStore(selectedStyleSelector)
|
const currentStyle = app.useStore(currentStyleSelector)
|
||||||
|
const selectedIds = app.useStore(selectedIdsSelector)
|
||||||
|
|
||||||
|
const [displayedStyle, setDisplayedStyle] = React.useState(currentStyle)
|
||||||
|
const rDisplayedStyle = React.useRef(currentStyle)
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const {
|
||||||
|
appState: { currentStyle },
|
||||||
|
page,
|
||||||
|
selectedIds,
|
||||||
|
} = app
|
||||||
|
|
||||||
|
let commonStyle = {} as ShapeStyles
|
||||||
|
|
||||||
|
if (selectedIds.length <= 0) {
|
||||||
|
commonStyle = currentStyle
|
||||||
|
} else {
|
||||||
|
const overrides = new Set<string>([])
|
||||||
|
|
||||||
|
app.selectedIds
|
||||||
|
.map((id) => page.shapes[id])
|
||||||
|
.forEach((shape) => {
|
||||||
|
STYLE_KEYS.forEach((key) => {
|
||||||
|
if (overrides.has(key)) return
|
||||||
|
if (commonStyle[key] === undefined) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
commonStyle[key] = shape.style[key]
|
||||||
|
} else {
|
||||||
|
if (commonStyle[key] === shape.style[key]) return
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
commonStyle[key] = shape.style[key]
|
||||||
|
overrides.add(key)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Until we can work out the correct logic for deciding whether or not to
|
||||||
|
// update the selected style, do a string comparison. Yuck!
|
||||||
|
if (JSON.stringify(commonStyle) !== JSON.stringify(rDisplayedStyle.current)) {
|
||||||
|
rDisplayedStyle.current = commonStyle
|
||||||
|
setDisplayedStyle(commonStyle)
|
||||||
|
}
|
||||||
|
}, [currentStyle, selectedIds])
|
||||||
|
|
||||||
const handleToggleFilled = React.useCallback((checked: boolean) => {
|
const handleToggleFilled = React.useCallback((checked: boolean) => {
|
||||||
app.style({ isFilled: checked })
|
app.style({ isFilled: checked })
|
||||||
|
@ -61,13 +116,17 @@ export const StyleMenu = React.memo(function ColorMenu(): JSX.Element {
|
||||||
<DMTriggerIcon>
|
<DMTriggerIcon>
|
||||||
<OverlapIcons
|
<OverlapIcons
|
||||||
style={{
|
style={{
|
||||||
color: strokes[theme][style.color as ColorStyle],
|
color: strokes[theme][displayedStyle.color as ColorStyle],
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{style.isFilled && (
|
{displayedStyle.isFilled && (
|
||||||
<CircleIcon size={16} stroke="none" fill={fills[theme][style.color as ColorStyle]} />
|
<CircleIcon
|
||||||
|
size={16}
|
||||||
|
stroke="none"
|
||||||
|
fill={fills[theme][displayedStyle.color as ColorStyle]}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
{dashes[style.dash]}
|
{DASHES[displayedStyle.dash]}
|
||||||
</OverlapIcons>
|
</OverlapIcons>
|
||||||
</DMTriggerIcon>
|
</DMTriggerIcon>
|
||||||
<DMContent>
|
<DMContent>
|
||||||
|
@ -78,13 +137,17 @@ export const StyleMenu = React.memo(function ColorMenu(): JSX.Element {
|
||||||
<DropdownMenu.Item key={colorStyle} onSelect={preventEvent} asChild>
|
<DropdownMenu.Item key={colorStyle} onSelect={preventEvent} asChild>
|
||||||
<ToolButton
|
<ToolButton
|
||||||
variant="icon"
|
variant="icon"
|
||||||
isActive={style.color === colorStyle}
|
isActive={displayedStyle.color === colorStyle}
|
||||||
onClick={() => app.style({ color: colorStyle as ColorStyle })}
|
onClick={() => app.style({ color: colorStyle as ColorStyle })}
|
||||||
>
|
>
|
||||||
<CircleIcon
|
<CircleIcon
|
||||||
size={18}
|
size={18}
|
||||||
strokeWidth={2.5}
|
strokeWidth={2.5}
|
||||||
fill={style.isFilled ? fills.light[colorStyle as ColorStyle] : 'transparent'}
|
fill={
|
||||||
|
displayedStyle.isFilled
|
||||||
|
? fills.light[colorStyle as ColorStyle]
|
||||||
|
: 'transparent'
|
||||||
|
}
|
||||||
stroke={strokes.light[colorStyle as ColorStyle]}
|
stroke={strokes.light[colorStyle as ColorStyle]}
|
||||||
/>
|
/>
|
||||||
</ToolButton>
|
</ToolButton>
|
||||||
|
@ -95,16 +158,16 @@ export const StyleMenu = React.memo(function ColorMenu(): JSX.Element {
|
||||||
<Divider />
|
<Divider />
|
||||||
<StyledRow>
|
<StyledRow>
|
||||||
Dash
|
Dash
|
||||||
<StyledGroup dir="ltr" value={style.dash} onValueChange={handleDashChange}>
|
<StyledGroup dir="ltr" value={displayedStyle.dash} onValueChange={handleDashChange}>
|
||||||
{Object.values(DashStyle).map((dashStyle) => (
|
{Object.values(DashStyle).map((dashStyle) => (
|
||||||
<DMRadioItem
|
<DMRadioItem
|
||||||
key={dashStyle}
|
key={dashStyle}
|
||||||
isActive={dashStyle === style.dash}
|
isActive={dashStyle === displayedStyle.dash}
|
||||||
value={dashStyle}
|
value={dashStyle}
|
||||||
onSelect={preventEvent}
|
onSelect={preventEvent}
|
||||||
bp={breakpoints}
|
bp={breakpoints}
|
||||||
>
|
>
|
||||||
{dashes[dashStyle as DashStyle]}
|
{DASHES[dashStyle as DashStyle]}
|
||||||
</DMRadioItem>
|
</DMRadioItem>
|
||||||
))}
|
))}
|
||||||
</StyledGroup>
|
</StyledGroup>
|
||||||
|
@ -112,22 +175,22 @@ export const StyleMenu = React.memo(function ColorMenu(): JSX.Element {
|
||||||
<Divider />
|
<Divider />
|
||||||
<StyledRow>
|
<StyledRow>
|
||||||
Size
|
Size
|
||||||
<StyledGroup dir="ltr" value={style.size} onValueChange={handleSizeChange}>
|
<StyledGroup dir="ltr" value={displayedStyle.size} onValueChange={handleSizeChange}>
|
||||||
{Object.values(SizeStyle).map((sizeStyle) => (
|
{Object.values(SizeStyle).map((sizeStyle) => (
|
||||||
<DMRadioItem
|
<DMRadioItem
|
||||||
key={sizeStyle}
|
key={sizeStyle}
|
||||||
isActive={sizeStyle === style.size}
|
isActive={sizeStyle === displayedStyle.size}
|
||||||
value={sizeStyle}
|
value={sizeStyle}
|
||||||
onSelect={preventEvent}
|
onSelect={preventEvent}
|
||||||
bp={breakpoints}
|
bp={breakpoints}
|
||||||
>
|
>
|
||||||
{sizes[sizeStyle as SizeStyle]}
|
{SIZES[sizeStyle as SizeStyle]}
|
||||||
</DMRadioItem>
|
</DMRadioItem>
|
||||||
))}
|
))}
|
||||||
</StyledGroup>
|
</StyledGroup>
|
||||||
</StyledRow>
|
</StyledRow>
|
||||||
<Divider />
|
<Divider />
|
||||||
<DMCheckboxItem checked={!!style.isFilled} onCheckedChange={handleToggleFilled}>
|
<DMCheckboxItem checked={!!displayedStyle.isFilled} onCheckedChange={handleToggleFilled}>
|
||||||
Fill
|
Fill
|
||||||
</DMCheckboxItem>
|
</DMCheckboxItem>
|
||||||
</DMContent>
|
</DMContent>
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './StyleMenu'
|
|
@ -1,10 +1,10 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { Menu } from './Menu'
|
import { Menu } from './Menu/Menu'
|
||||||
import { styled } from '~styles'
|
import { styled } from '~styles'
|
||||||
import { PageMenu } from './PageMenu'
|
import { PageMenu } from './PageMenu'
|
||||||
import { ZoomMenu } from './ZoomMenu'
|
import { ZoomMenu } from './ZoomMenu'
|
||||||
import { StyleMenu } from './StyleMenu'
|
import { StyleMenu } from './StyleMenu'
|
||||||
import { Panel } from '~components/Panel'
|
import { Panel } from '~components/Primitives/Panel'
|
||||||
|
|
||||||
interface TopPanelProps {
|
interface TopPanelProps {
|
||||||
readOnly: boolean
|
readOnly: boolean
|
||||||
|
|
|
@ -3,8 +3,8 @@ import { useTldrawApp } from '~hooks'
|
||||||
import type { TDSnapshot } from '~types'
|
import type { TDSnapshot } from '~types'
|
||||||
import { styled } from '~styles'
|
import { styled } from '~styles'
|
||||||
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
||||||
import { DMItem, DMContent } from '~components/DropdownMenu'
|
import { DMItem, DMContent } from '~components/Primitives/DropdownMenu'
|
||||||
import { ToolButton } from '~components/ToolButton'
|
import { ToolButton } from '~components/Primitives/ToolButton'
|
||||||
import { preventEvent } from '~components/preventEvent'
|
import { preventEvent } from '~components/preventEvent'
|
||||||
|
|
||||||
const zoomSelector = (s: TDSnapshot) => s.document.pageStates[s.appState.currentPageId].camera.zoom
|
const zoomSelector = (s: TDSnapshot) => s.document.pageStates[s.appState.currentPageId].camera.zoom
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './ZoomMenu'
|
|
@ -735,44 +735,6 @@ export class TLDR {
|
||||||
TLDR.updateParents(data, pageId, parentToUpdateIds)
|
TLDR.updateParents(data, pageId, parentToUpdateIds)
|
||||||
}
|
}
|
||||||
|
|
||||||
static getSelectedStyle(data: TDSnapshot, pageId: string): ShapeStyles | false {
|
|
||||||
const { currentStyle } = data.appState
|
|
||||||
|
|
||||||
const page = data.document.pages[pageId]
|
|
||||||
const pageState = data.document.pageStates[pageId]
|
|
||||||
|
|
||||||
if (pageState.selectedIds.length === 0) {
|
|
||||||
return currentStyle
|
|
||||||
}
|
|
||||||
|
|
||||||
const shapeStyles = pageState.selectedIds.map((id) => page.shapes[id].style)
|
|
||||||
|
|
||||||
const commonStyle = {} as ShapeStyles
|
|
||||||
|
|
||||||
const overrides = new Set<string>([])
|
|
||||||
|
|
||||||
for (const shapeStyle of shapeStyles) {
|
|
||||||
const styles = Object.keys(currentStyle) as (keyof ShapeStyles)[]
|
|
||||||
|
|
||||||
styles.forEach((key) => {
|
|
||||||
if (overrides.has(key)) return
|
|
||||||
if (commonStyle[key] === undefined) {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore
|
|
||||||
commonStyle[key] = shapeStyle[key]
|
|
||||||
} else {
|
|
||||||
if (commonStyle[key] === shapeStyle[key]) return
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore
|
|
||||||
commonStyle[key] = currentStyle[key]
|
|
||||||
overrides.add(key)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return commonStyle
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------- */
|
/* -------------------------------------------------- */
|
||||||
/* Bindings */
|
/* Bindings */
|
||||||
/* -------------------------------------------------- */
|
/* -------------------------------------------------- */
|
||||||
|
|
|
@ -247,7 +247,11 @@ export class TldrawApp extends StateManager<TDSnapshot> {
|
||||||
* @protected
|
* @protected
|
||||||
* @returns The final state
|
* @returns The final state
|
||||||
*/
|
*/
|
||||||
protected cleanup = (state: TDSnapshot, prev: TDSnapshot): TDSnapshot => {
|
protected cleanup = (
|
||||||
|
state: TDSnapshot,
|
||||||
|
prev: TDSnapshot,
|
||||||
|
patch: Patch<TDSnapshot>
|
||||||
|
): TDSnapshot => {
|
||||||
const next = { ...state }
|
const next = { ...state }
|
||||||
|
|
||||||
// Remove deleted shapes and bindings (in Commands, these will be set to undefined)
|
// Remove deleted shapes and bindings (in Commands, these will be set to undefined)
|
||||||
|
@ -415,17 +419,6 @@ export class TldrawApp extends StateManager<TDSnapshot> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply selected style change, if any
|
|
||||||
|
|
||||||
const newSelectedStyle = TLDR.getSelectedStyle(next, currentPageId)
|
|
||||||
|
|
||||||
if (newSelectedStyle) {
|
|
||||||
next.appState = {
|
|
||||||
...next.appState,
|
|
||||||
selectedStyle: newSelectedStyle,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Temporary block on editing pages while in readonly mode.
|
// Temporary block on editing pages while in readonly mode.
|
||||||
// This is a broad solution but not a very good one: the UX
|
// This is a broad solution but not a very good one: the UX
|
||||||
// for interacting with a readOnly document will be more nuanced.
|
// for interacting with a readOnly document will be more nuanced.
|
||||||
|
@ -2855,7 +2848,6 @@ export class TldrawApp extends StateManager<TDSnapshot> {
|
||||||
currentPageId: 'page',
|
currentPageId: 'page',
|
||||||
pages: [{ id: 'page', name: 'page', childIndex: 1 }],
|
pages: [{ id: 'page', name: 'page', childIndex: 1 }],
|
||||||
currentStyle: defaultStyle,
|
currentStyle: defaultStyle,
|
||||||
selectedStyle: defaultStyle,
|
|
||||||
isToolLocked: false,
|
isToolLocked: false,
|
||||||
isStyleOpen: false,
|
isStyleOpen: false,
|
||||||
isEmptyCanvas: false,
|
isEmptyCanvas: false,
|
||||||
|
|
|
@ -92,7 +92,6 @@ export interface TDSnapshot {
|
||||||
showCloneHandles: boolean
|
showCloneHandles: boolean
|
||||||
}
|
}
|
||||||
appState: {
|
appState: {
|
||||||
selectedStyle: ShapeStyles
|
|
||||||
currentStyle: ShapeStyles
|
currentStyle: ShapeStyles
|
||||||
currentPageId: string
|
currentPageId: string
|
||||||
pages: Pick<TLPage<TDShape, TDBinding>, 'id' | 'name' | 'childIndex'>[]
|
pages: Pick<TLPage<TDShape, TDBinding>, 'id' | 'name' | 'childIndex'>[]
|
||||||
|
|
Loading…
Reference in a new issue