[fix] missing border on group shape when unlocked (#2075)
This PR fixes a bug where the indicator on a locked group (or any shape!) would not appear when the shape was unlocked. This happens because the `memo` equality checker filtered out changes to the shape's locked property if they did not effect any other properties. ![Kapture 2023-10-13 at 14 44 31](https://github.com/tldraw/tldraw/assets/23072548/c40442e0-8d18-4ed0-863c-c2b73da81f28) ### Change Type - [x] `patch` — Bug fix ### Release Notes - Fix case where indicator was not shown when unlocking groups
This commit is contained in:
parent
22955bb0ec
commit
ff9c1655f9
3 changed files with 20 additions and 28 deletions
|
@ -11,7 +11,11 @@ import { OptionalErrorBoundary } from './ErrorBoundary'
|
||||||
class ShapeWithPropsEquality {
|
class ShapeWithPropsEquality {
|
||||||
constructor(public shape: TLShape | undefined) {}
|
constructor(public shape: TLShape | undefined) {}
|
||||||
equals(other: ShapeWithPropsEquality) {
|
equals(other: ShapeWithPropsEquality) {
|
||||||
return this.shape?.props === other?.shape?.props && this.shape?.meta === other?.shape?.meta
|
return (
|
||||||
|
this.shape?.isLocked === other?.shape?.isLocked &&
|
||||||
|
this.shape?.props === other?.shape?.props &&
|
||||||
|
this.shape?.meta === other?.shape?.meta
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
|
import { useValue } from '@tldraw/state'
|
||||||
|
import { useEditor } from '../../../hooks/useEditor'
|
||||||
import { Box2d } from '../../../primitives/Box2d'
|
import { Box2d } from '../../../primitives/Box2d'
|
||||||
import { getPerfectDashProps } from '../shared/getPerfectDashProps'
|
import { getPerfectDashProps } from '../shared/getPerfectDashProps'
|
||||||
|
|
||||||
export function DashedOutlineBox({
|
export function DashedOutlineBox({ bounds, className }: { bounds: Box2d; className: string }) {
|
||||||
bounds,
|
const editor = useEditor()
|
||||||
zoomLevel,
|
|
||||||
className,
|
const zoomLevel = useValue('zoom level', () => editor.zoomLevel, [editor])
|
||||||
}: {
|
|
||||||
bounds: Box2d
|
|
||||||
zoomLevel: number
|
|
||||||
className: string
|
|
||||||
}) {
|
|
||||||
return (
|
return (
|
||||||
<g className={className} pointerEvents="none" strokeLinecap="round" strokeLinejoin="round">
|
<g className={className} pointerEvents="none" strokeLinecap="round" strokeLinejoin="round">
|
||||||
{bounds.sides.map((side, i) => {
|
{bounds.sides.map((side, i) => {
|
||||||
|
|
|
@ -49,15 +49,9 @@ export class GroupShapeUtil extends ShapeUtil<TLGroupShape> {
|
||||||
}
|
}
|
||||||
|
|
||||||
component(shape: TLGroupShape) {
|
component(shape: TLGroupShape) {
|
||||||
// Not a class component, but eslint can't tell that :(
|
const isErasing = this.editor.erasingShapeIds.includes(shape.id)
|
||||||
const {
|
|
||||||
erasingShapeIds,
|
|
||||||
currentPageState: { hintingShapeIds, focusedGroupId },
|
|
||||||
zoomLevel,
|
|
||||||
} = this.editor
|
|
||||||
|
|
||||||
const isErasing = erasingShapeIds.includes(shape.id)
|
|
||||||
|
|
||||||
|
const { hintingShapeIds } = this.editor.currentPageState
|
||||||
const isHintingOtherGroup =
|
const isHintingOtherGroup =
|
||||||
hintingShapeIds.length > 0 &&
|
hintingShapeIds.length > 0 &&
|
||||||
hintingShapeIds.some(
|
hintingShapeIds.some(
|
||||||
|
@ -66,12 +60,13 @@ export class GroupShapeUtil extends ShapeUtil<TLGroupShape> {
|
||||||
this.editor.isShapeOfType<TLGroupShape>(this.editor.getShape(id)!, 'group')
|
this.editor.isShapeOfType<TLGroupShape>(this.editor.getShape(id)!, 'group')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const isFocused = this.editor.currentPageState.focusedGroupId !== shape.id
|
||||||
|
|
||||||
if (
|
if (
|
||||||
// always show the outline while we're erasing the group
|
!isErasing && // always show the outline while we're erasing the group
|
||||||
!isErasing &&
|
|
||||||
// show the outline while the group is focused unless something outside of the group is being hinted
|
// show the outline while the group is focused unless something outside of the group is being hinted
|
||||||
// this happens dropping shapes from a group onto some outside group
|
// this happens dropping shapes from a group onto some outside group
|
||||||
(shape.id !== focusedGroupId || isHintingOtherGroup)
|
(isFocused || isHintingOtherGroup)
|
||||||
) {
|
) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -80,20 +75,15 @@ export class GroupShapeUtil extends ShapeUtil<TLGroupShape> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SVGContainer id={shape.id}>
|
<SVGContainer id={shape.id}>
|
||||||
<DashedOutlineBox className="tl-group" bounds={bounds} zoomLevel={zoomLevel} />
|
<DashedOutlineBox className="tl-group" bounds={bounds} />
|
||||||
</SVGContainer>
|
</SVGContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
indicator(shape: TLGroupShape) {
|
indicator(shape: TLGroupShape) {
|
||||||
// Not a class component, but eslint can't tell that :(
|
// Not a class component, but eslint can't tell that :(
|
||||||
const {
|
|
||||||
camera: { z: zoomLevel },
|
|
||||||
} = this.editor
|
|
||||||
|
|
||||||
const bounds = this.editor.getShapeGeometry(shape).bounds
|
const bounds = this.editor.getShapeGeometry(shape).bounds
|
||||||
|
return <DashedOutlineBox className="" bounds={bounds} />
|
||||||
return <DashedOutlineBox className="" bounds={bounds} zoomLevel={zoomLevel} />
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override onChildrenChange: TLOnChildrenChangeHandler<TLGroupShape> = (group) => {
|
override onChildrenChange: TLOnChildrenChangeHandler<TLGroupShape> = (group) => {
|
||||||
|
|
Loading…
Reference in a new issue