ChunDe Claude Sonnet 4.5 commited on
Commit
56dd95f
·
1 Parent(s): aab4229

fix: Enable proper editing of layout text objects

Browse files

Mark layout text objects as modified when content or properties change:
- Text content changes now set isModified flag (Canvas.tsx:660)
- Font family changes mark as modified (App.tsx:1132)
- Bold/font weight changes mark as modified (App.tsx:1181)
- Italic changes mark as modified (App.tsx:1238)

This prevents layout text from being unexpectedly replaced during
layout switches and fixes MCP create_thumbnail text customization.

Fixes #text-editing-bug

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>

Files changed (2) hide show
  1. src/App.tsx +15 -6
  2. src/components/Canvas/Canvas.tsx +5 -2
src/App.tsx CHANGED
@@ -1128,6 +1128,9 @@ function App() {
1128
  onFontFamilyChange={(font) => {
1129
  const updatedObjects = objects.map((o: CanvasObject) => {
1130
  if (o.type === 'text' && selectedTextObjects.some(selected => selected.id === o.id)) {
 
 
 
1131
  // Recalculate text dimensions with new font
1132
  try {
1133
  const tempText = new Konva.Text({
@@ -1141,10 +1144,10 @@ function App() {
1141
  const newHeight = Math.max(40, tempText.height() + 10);
1142
 
1143
  tempText.destroy();
1144
- return { ...o, fontFamily: font, width: newWidth, height: newHeight };
1145
  } catch (error) {
1146
  console.error('Error recalculating text size:', error);
1147
- return { ...o, fontFamily: font };
1148
  }
1149
  }
1150
  return o;
@@ -1174,6 +1177,9 @@ function App() {
1174
  onBoldToggle={() => {
1175
  const updatedObjects = objects.map((o: CanvasObject) => {
1176
  if (o.type === 'text' && selectedTextObjects.some(selected => selected.id === o.id)) {
 
 
 
1177
  // Check if font supports BLACK weight
1178
  const supportsBlack = o.fontFamily === 'Source Sans 3';
1179
  const currentWeight = o.fontWeight || 'normal';
@@ -1215,10 +1221,10 @@ function App() {
1215
  const newHeight = Math.max(40, tempText.height() + 10);
1216
 
1217
  tempText.destroy();
1218
- return { ...o, bold: newBold, fontWeight: newWeight, width: newWidth, height: newHeight };
1219
  } catch (error) {
1220
  console.error('Error recalculating text size:', error);
1221
- return { ...o, bold: newBold, fontWeight: newWeight };
1222
  }
1223
  }
1224
  return o;
@@ -1228,6 +1234,9 @@ function App() {
1228
  onItalicToggle={() => {
1229
  const updatedObjects = objects.map((o: CanvasObject) => {
1230
  if (o.type === 'text' && selectedTextObjects.some(selected => selected.id === o.id)) {
 
 
 
1231
  const newItalic = !o.italic;
1232
  // Recalculate text dimensions with new italic state
1233
  try {
@@ -1242,10 +1251,10 @@ function App() {
1242
  const newHeight = Math.max(40, tempText.height() + 10);
1243
 
1244
  tempText.destroy();
1245
- return { ...o, italic: newItalic, width: newWidth, height: newHeight };
1246
  } catch (error) {
1247
  console.error('Error recalculating text size:', error);
1248
- return { ...o, italic: newItalic };
1249
  }
1250
  }
1251
  return o;
 
1128
  onFontFamilyChange={(font) => {
1129
  const updatedObjects = objects.map((o: CanvasObject) => {
1130
  if (o.type === 'text' && selectedTextObjects.some(selected => selected.id === o.id)) {
1131
+ // Mark layout objects as modified when font family changes
1132
+ const isModified = o.isFromLayout ? true : o.isModified;
1133
+
1134
  // Recalculate text dimensions with new font
1135
  try {
1136
  const tempText = new Konva.Text({
 
1144
  const newHeight = Math.max(40, tempText.height() + 10);
1145
 
1146
  tempText.destroy();
1147
+ return { ...o, fontFamily: font, width: newWidth, height: newHeight, isModified };
1148
  } catch (error) {
1149
  console.error('Error recalculating text size:', error);
1150
+ return { ...o, fontFamily: font, isModified };
1151
  }
1152
  }
1153
  return o;
 
1177
  onBoldToggle={() => {
1178
  const updatedObjects = objects.map((o: CanvasObject) => {
1179
  if (o.type === 'text' && selectedTextObjects.some(selected => selected.id === o.id)) {
1180
+ // Mark layout objects as modified when bold changes
1181
+ const isModified = o.isFromLayout ? true : o.isModified;
1182
+
1183
  // Check if font supports BLACK weight
1184
  const supportsBlack = o.fontFamily === 'Source Sans 3';
1185
  const currentWeight = o.fontWeight || 'normal';
 
1221
  const newHeight = Math.max(40, tempText.height() + 10);
1222
 
1223
  tempText.destroy();
1224
+ return { ...o, bold: newBold, fontWeight: newWeight, width: newWidth, height: newHeight, isModified };
1225
  } catch (error) {
1226
  console.error('Error recalculating text size:', error);
1227
+ return { ...o, bold: newBold, fontWeight: newWeight, isModified };
1228
  }
1229
  }
1230
  return o;
 
1234
  onItalicToggle={() => {
1235
  const updatedObjects = objects.map((o: CanvasObject) => {
1236
  if (o.type === 'text' && selectedTextObjects.some(selected => selected.id === o.id)) {
1237
+ // Mark layout objects as modified when italic changes
1238
+ const isModified = o.isFromLayout ? true : o.isModified;
1239
+
1240
  const newItalic = !o.italic;
1241
  // Recalculate text dimensions with new italic state
1242
  try {
 
1251
  const newHeight = Math.max(40, tempText.height() + 10);
1252
 
1253
  tempText.destroy();
1254
+ return { ...o, italic: newItalic, width: newWidth, height: newHeight, isModified };
1255
  } catch (error) {
1256
  console.error('Error recalculating text size:', error);
1257
+ return { ...o, italic: newItalic, isModified };
1258
  }
1259
  }
1260
  return o;
src/components/Canvas/Canvas.tsx CHANGED
@@ -656,9 +656,12 @@ export default function Canvas({
656
  const handleTextChange = (id: string, text: string, width: number, height: number) => {
657
  const updatedObjects = objects.map(obj => {
658
  if (obj.id === id && obj.type === 'text') {
659
- // Check if dimensions changed - if so, mark as modified
 
660
  const dimensionsChanged = obj.width !== width || obj.height !== height;
661
- const isModified = dimensionsChanged && obj.isFromLayout ? true : obj.isModified;
 
 
662
 
663
  return { ...obj, text, width, height, isModified };
664
  }
 
656
  const handleTextChange = (id: string, text: string, width: number, height: number) => {
657
  const updatedObjects = objects.map(obj => {
658
  if (obj.id === id && obj.type === 'text') {
659
+ // Mark as modified if: text changed OR dimensions changed (for layout objects)
660
+ const textChanged = obj.text !== text;
661
  const dimensionsChanged = obj.width !== width || obj.height !== height;
662
+ const isModified = obj.isFromLayout && (textChanged || dimensionsChanged)
663
+ ? true
664
+ : obj.isModified;
665
 
666
  return { ...obj, text, width, height, isModified };
667
  }