瀏覽代碼

fix: reset bounds action

Peng Xiao 3 年之前
父節點
當前提交
ddb794907d

+ 29 - 3
tldraw/apps/tldraw-logseq/src/components/ContextBar/contextBarActionFactory.tsx

@@ -16,6 +16,7 @@ import { tint } from 'polished'
 import type {
   BoxShape,
   EllipseShape,
+  HTMLShape,
   LineShape,
   LogseqPortalShape,
   PencilShape,
@@ -31,6 +32,7 @@ export const contextBarActionTypes = [
   'Edit',
   'Swatch',
   'NoFill',
+  'ResetBounds',
   'StrokeType',
   'ScaleLevel',
   'YoutubeLink',
@@ -47,7 +49,7 @@ const contextBarActionMapping = new Map<ContextBarActionType, React.FC>()
 type ShapeType = Shape['props']['type']
 
 const shapeMapping: Partial<Record<ShapeType, ContextBarActionType[]>> = {
-  'logseq-portal': ['Edit', 'LogseqPortalViewMode', 'ScaleLevel', 'OpenPage'],
+  'logseq-portal': ['Edit', 'LogseqPortalViewMode', 'ScaleLevel', 'OpenPage', 'ResetBounds'],
   youtube: ['YoutubeLink'],
   box: ['Swatch', 'NoFill', 'StrokeType'],
   ellipse: ['Swatch', 'NoFill', 'StrokeType'],
@@ -55,8 +57,8 @@ const shapeMapping: Partial<Record<ShapeType, ContextBarActionType[]>> = {
   line: ['Edit', 'Swatch', 'ArrowMode'],
   pencil: ['Swatch'],
   highlighter: ['Swatch'],
-  text: ['Edit', 'Swatch', 'ScaleLevel'],
-  html: ['ScaleLevel'],
+  text: ['Edit', 'Swatch', 'ScaleLevel', 'ResetBounds'],
+  html: ['ScaleLevel', 'ResetBounds'],
 }
 
 const noStrokeShapes = Object.entries(shapeMapping)
@@ -97,6 +99,29 @@ const EditAction = observer(() => {
   )
 })
 
+const ResetBoundsAction = observer(() => {
+  const app = useApp<Shape>()
+  const shapes = filterShapeByAction<LogseqPortalShape | TextShape | HTMLShape>(
+    app.selectedShapesArray,
+    'ResetBounds'
+  )
+
+  return (
+    <button
+      className="tl-contextbar-button"
+      type="button"
+      onClick={() => {
+        shapes.forEach(s => {
+          s.onResetBounds()
+        })
+        app.persist()
+      }}
+    >
+      <TablerIcon name="dimensions" />
+    </button>
+  )
+})
+
 const LogseqPortalViewModeAction = observer(() => {
   const app = useApp<Shape>()
   const shapes = filterShapeByAction<LogseqPortalShape>(
@@ -354,6 +379,7 @@ const ArrowModeAction = observer(() => {
 })
 
 contextBarActionMapping.set('Edit', EditAction)
+contextBarActionMapping.set('ResetBounds', ResetBoundsAction)
 contextBarActionMapping.set('LogseqPortalViewMode', LogseqPortalViewModeAction)
 contextBarActionMapping.set('ScaleLevel', ScaleLevelAction)
 contextBarActionMapping.set('OpenPage', OpenPageAction)

+ 17 - 11
tldraw/apps/tldraw-logseq/src/lib/shapes/HTMLShape.tsx

@@ -1,5 +1,5 @@
 /* eslint-disable @typescript-eslint/no-explicit-any */
-import { delay, TLBoxShape, TLBoxShapeProps } from '@tldraw/core'
+import { delay, TLBoxShape, TLBoxShapeProps, TLResetBoundsInfo } from '@tldraw/core'
 import { HTMLContainer, TLComponentProps, useApp } from '@tldraw/react'
 import Vec from '@tldraw/vec'
 import { action, computed } from 'mobx'
@@ -39,6 +39,7 @@ export class HTMLShape extends TLBoxShape<HTMLShapeProps> {
   canChangeAspectRatio = true
   canFlip = false
   canEdit = true
+  htmlAnchorRef = React.createRef<HTMLDivElement>()
 
   @computed get scaleLevel() {
     return this.props.scaleLevel ?? 'md'
@@ -58,6 +59,18 @@ export class HTMLShape extends TLBoxShape<HTMLShapeProps> {
     })
   }
 
+  onResetBounds = (info?: TLResetBoundsInfo) => {
+    if (this.htmlAnchorRef.current) {
+      this.update({
+        size: [
+          this.props.size[0],
+          Math.max(Math.min(this.htmlAnchorRef.current.offsetHeight || 400, 800), 10),
+        ],
+      })
+    }
+    return this
+  }
+
   ReactComponent = observer(({ events, isErasing, isEditing }: TLComponentProps) => {
     const {
       props: { html, scaleLevel },
@@ -78,18 +91,11 @@ export class HTMLShape extends TLBoxShape<HTMLShapeProps> {
       [tlEventsEnabled]
     )
 
-    const anchorRef = React.useRef<HTMLDivElement>(null)
-
     const scaleRatio = levelToScale[scaleLevel ?? 'md']
 
     React.useEffect(() => {
-      if (this.props.size[1] === 0 && anchorRef.current) {
-        this.update({
-          size: [
-            this.props.size[0],
-            Math.max(Math.min(anchorRef.current.offsetHeight || 400, 800), 10),
-          ],
-        })
+      if (this.props.size[1] === 0) {
+        this.onResetBounds()
         app.persist(true)
       }
     }, [])
@@ -117,7 +123,7 @@ export class HTMLShape extends TLBoxShape<HTMLShapeProps> {
           }}
         >
           <div
-            ref={anchorRef}
+            ref={this.htmlAnchorRef}
             className="tl-html-anchor"
             dangerouslySetInnerHTML={{ __html: html.trim() }}
           />

+ 25 - 17
tldraw/apps/tldraw-logseq/src/lib/shapes/LogseqPortalShape.tsx

@@ -1,5 +1,12 @@
 /* eslint-disable @typescript-eslint/no-explicit-any */
-import { delay, TLBoxShape, TLBoxShapeProps, TLResizeInfo, validUUID } from '@tldraw/core'
+import {
+  delay,
+  TLBoxShape,
+  TLBoxShapeProps,
+  TLResetBoundsInfo,
+  TLResizeInfo,
+  validUUID,
+} from '@tldraw/core'
 import { HTMLContainer, TLComponentProps, useApp } from '@tldraw/react'
 import Vec from '@tldraw/vec'
 import { action, computed, makeObservable } from 'mobx'
@@ -172,16 +179,16 @@ export class LogseqPortalShape extends TLBoxShape<LogseqPortalShapeProps> {
     return this.props.blockType === 'B' ? this.props.compact : this.props.collapsed
   }
 
-  @action setCollapsed = (collapsed: boolean) => {
+  @action setCollapsed = async (collapsed: boolean) => {
     if (this.props.blockType === 'B') {
       this.update({ compact: collapsed })
       this.canResize[1] = !collapsed
       if (!collapsed) {
         // this will also persist the state, so we can skip persist call
-        this.autoResizeHeight()
-      } else {
-        this.persist?.()
+        await delay()
+        this.onResetBounds()
       }
+      this.persist?.()
     } else {
       const originalHeight = this.props.size[1]
       this.canResize[1] = !collapsed
@@ -256,17 +263,15 @@ export class LogseqPortalShape extends TLBoxShape<LogseqPortalShapeProps> {
     return null
   }
 
-  autoResizeHeight(replace: boolean = false) {
-    setTimeout(() => {
-      const height = this.getAutoResizeHeight()
-      if (height !== null && Math.abs(height - this.props.size[1]) > AUTO_RESIZE_THRESHOLD) {
-        this.update({
-          size: [this.props.size[0], height],
-        })
-        this.persist?.(replace)
-        this.initialHeightCalculated = true
-      }
-    })
+  onResetBounds = (info?: TLResetBoundsInfo) => {
+    const height = this.getAutoResizeHeight()
+    if (height !== null && Math.abs(height - this.props.size[1]) > AUTO_RESIZE_THRESHOLD) {
+      this.update({
+        size: [this.props.size[0], height],
+      })
+      this.initialHeightCalculated = true
+    }
+    return this
   }
 
   onResize = (initialProps: any, info: TLResizeInfo): this => {
@@ -615,7 +620,10 @@ export class LogseqPortalShape extends TLBoxShape<LogseqPortalShapeProps> {
 
     React.useEffect(() => {
       if (!this.initialHeightCalculated) {
-        this.autoResizeHeight(true)
+        setTimeout(() => {
+          this.onResetBounds()
+          app.persist(true)
+        })
       }
     }, [this.initialHeightCalculated])
 

+ 1 - 1
tldraw/packages/core/src/lib/shapes/TLImageShape/TLImageShape.ts

@@ -38,7 +38,7 @@ export class TLImageShape<
     assetId: '',
   }
 
-  onResetBounds = (info: TLResetBoundsInfo<TLImageAsset>) => {
+  autoResize = (info: TLResetBoundsInfo<TLImageAsset>) => {
     const { clipping, size, point } = this.props
     if (clipping) {
       const [t, r, b, l] = Array.isArray(clipping)

+ 2 - 4
tldraw/packages/core/src/lib/shapes/TLShape/TLShape.tsx

@@ -57,9 +57,7 @@ export interface TLResizeInfo {
   transformOrigin: number[]
 }
 
-export interface TLResetBoundsInfo<T extends TLAsset> {
-  asset?: T
-}
+export interface TLResetBoundsInfo {}
 
 export interface TLHandleChangeInfo {
   id: string
@@ -306,7 +304,7 @@ export abstract class TLShape<P extends TLShapeProps = TLShapeProps, M = any> {
     return new this.constructor(this.serialized)
   }
 
-  onResetBounds = (info: TLResetBoundsInfo<any>) => {
+  onResetBounds = (info?: TLResetBoundsInfo) => {
     return this
   }
 

+ 2 - 2
tldraw/packages/core/src/lib/tools/TLSelectTool/states/HoveringSelectionHandleState.ts

@@ -77,7 +77,7 @@ export class HoveringSelectionHandleState<
           break
         }
         case TLTargetType.Selection: {
-          selectedShape.onResetBounds?.({})
+          selectedShape.autoResize?.({})
           if (this.app.selectedShapesArray.length === 1) {
             this.tool.transition('editingShape', {
               type: TLTargetType.Shape,
@@ -91,7 +91,7 @@ export class HoveringSelectionHandleState<
       const asset = selectedShape.props.assetId
         ? this.app.assets[selectedShape.props.assetId]
         : undefined
-      selectedShape.onResetBounds({ asset })
+      selectedShape.autoResize({ asset })
       this.tool.transition('idle')
     }
   }