@@ -811,34 +811,37 @@ export function useKonvaTransformer({
811811 lrNode ?. scaleY ( 1 ) ;
812812 const cur = id ? findObjectById ( getCurrentObjects ( ) , id ) : undefined ;
813813 const temporal = useLabelStore . temporal . getState ( ) ;
814- if ( lr . changed && id && cur && ! isGroup ( cur ) ) {
815- const cp = cur . props as { blockWidth ?: number ; blockLines ?: number ; blockHeight ?: number } ;
816- // ^TB collapses width + clip height; ^FB width + line count.
817- const secondAxis = lr . mode === "tb"
818- ? { blockHeight : cp . blockHeight }
819- : { blockLines : cp . blockLines } ;
820- const snapAxis = lr . mode === "tb"
821- ? { blockHeight : lr . snapshot . blockHeight }
822- : { blockLines : lr . snapshot . blockLines } ;
823- const final = {
824- x : cur . x ,
825- y : cur . y ,
826- props : { blockWidth : cp . blockWidth , ...secondAxis } ,
827- } ;
828- updateObject ( id , {
829- x : lr . snapshot . x ,
830- y : lr . snapshot . y ,
831- props : {
832- blockWidth : lr . snapshot . blockWidth ,
833- ...snapAxis ,
834- } ,
835- } ) ;
836- temporal . resume ( ) ;
837- updateObject ( id , final ) ;
838- } else {
814+ // try/finally so a throw can't leave undo paused (resume is idempotent).
815+ try {
816+ if ( lr . changed && id && cur && ! isGroup ( cur ) ) {
817+ const cp = cur . props as { blockWidth ?: number ; blockLines ?: number ; blockHeight ?: number } ;
818+ // ^TB collapses width + clip height; ^FB width + line count.
819+ const secondAxis = lr . mode === "tb"
820+ ? { blockHeight : cp . blockHeight }
821+ : { blockLines : cp . blockLines } ;
822+ const snapAxis = lr . mode === "tb"
823+ ? { blockHeight : lr . snapshot . blockHeight }
824+ : { blockLines : lr . snapshot . blockLines } ;
825+ const final = {
826+ x : cur . x ,
827+ y : cur . y ,
828+ props : { blockWidth : cp . blockWidth , ...secondAxis } ,
829+ } ;
830+ updateObject ( id , {
831+ x : lr . snapshot . x ,
832+ y : lr . snapshot . y ,
833+ props : {
834+ blockWidth : lr . snapshot . blockWidth ,
835+ ...snapAxis ,
836+ } ,
837+ } ) ;
838+ temporal . resume ( ) ;
839+ updateObject ( id , final ) ;
840+ }
841+ } finally {
839842 temporal . resume ( ) ;
843+ cleanupTransformState ( ) ;
840844 }
841- cleanupTransformState ( ) ;
842845 return ;
843846 }
844847 // Shape live reflow: same collapse-to-one-entry as the text block. Dims were
@@ -851,31 +854,34 @@ export function useKonvaTransformer({
851854 srNode ?. scaleY ( 1 ) ;
852855 const cur = id ? findObjectById ( getCurrentObjects ( ) , id ) : undefined ;
853856 const temporal = useLabelStore . temporal . getState ( ) ;
854- if ( sr . changed && id && cur && ! isGroup ( cur ) ) {
855- const sp = cur . props as { width : number ; height : number } ;
856- // Same snap/round/clamp contract as commitWidthHeightTransform, applied
857- // to the already-baked float dims.
858- const width = Math . max ( 1 , snap ( Math . round ( sp . width ) ) ) ;
859- const height = Math . max ( 1 , snap ( Math . round ( sp . height ) ) ) ;
860- // Pin the anchored edge: when dragging left/top, derive x/y from the
861- // snapped size so the opposite edge doesn't walk by the snap delta.
862- const edges = activeEdgesRef . current ;
863- const final = {
864- x : Math . round ( edges ?. left ? cur . x + sp . width - width : cur . x ) ,
865- y : Math . round ( edges ?. top ? cur . y + sp . height - height : cur . y ) ,
866- props : { width, height } ,
867- } ;
868- updateObject ( id , {
869- x : sr . snapshot . x ,
870- y : sr . snapshot . y ,
871- props : { width : sr . snapshot . width , height : sr . snapshot . height } ,
872- } ) ;
873- temporal . resume ( ) ;
874- updateObject ( id , final ) ;
875- } else {
857+ // try/finally so a throw can't leave undo paused (resume is idempotent).
858+ try {
859+ if ( sr . changed && id && cur && ! isGroup ( cur ) ) {
860+ const sp = cur . props as { width : number ; height : number } ;
861+ // Same snap/round/clamp contract as commitWidthHeightTransform, applied
862+ // to the already-baked float dims.
863+ const width = Math . max ( 1 , snap ( Math . round ( sp . width ) ) ) ;
864+ const height = Math . max ( 1 , snap ( Math . round ( sp . height ) ) ) ;
865+ // Pin the anchored edge: when dragging left/top, derive x/y from the
866+ // snapped size so the opposite edge doesn't walk by the snap delta.
867+ const edges = activeEdgesRef . current ;
868+ const final = {
869+ x : Math . round ( edges ?. left ? cur . x + sp . width - width : cur . x ) ,
870+ y : Math . round ( edges ?. top ? cur . y + sp . height - height : cur . y ) ,
871+ props : { width, height } ,
872+ } ;
873+ updateObject ( id , {
874+ x : sr . snapshot . x ,
875+ y : sr . snapshot . y ,
876+ props : { width : sr . snapshot . width , height : sr . snapshot . height } ,
877+ } ) ;
878+ temporal . resume ( ) ;
879+ updateObject ( id , final ) ;
880+ }
881+ } finally {
876882 temporal . resume ( ) ;
883+ cleanupTransformState ( ) ;
877884 }
878- cleanupTransformState ( ) ;
879885 return ;
880886 }
881887 if ( selectedIds . length !== 1 || ! selectedIds [ 0 ] || ! stageRef . current ) {
0 commit comments