Skip to content

Commit 4fd9482

Browse files
Copilothuangyiirene
andcommitted
Fix code review issues: type safety, cursor logic, accessibility, and docs
Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
1 parent 79443fc commit 4fd9482

3 files changed

Lines changed: 28 additions & 28 deletions

File tree

packages/designer/DRAG_AND_RESIZE_GUIDE.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,6 @@ Planned features for future releases:
344344
- [ ] **Keyboard resize** (Arrow keys with Shift)
345345
- [ ] **Percentage-based constraints**
346346
- [ ] **Resize preview overlay** showing dimensions
347-
- [ ] **Undo/redo for resize operations** (currently works)
348347
- [ ] **Multi-select resize** (resize multiple components)
349348
- [ ] **Resize from center** (Alt+Drag)
350349

packages/designer/src/components/Canvas.tsx

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { useState, useCallback, useMemo, useEffect } from 'react';
22
import { SchemaRenderer } from '@object-ui/react';
3-
import { ComponentRegistry } from '@object-ui/core';
3+
import { ComponentRegistry, type SchemaNode } from '@object-ui/core';
44
import { useDesigner } from '../context/DesignerContext';
55
import { ContextMenu } from './ContextMenu';
66
import { ResizeHandles, ResizeDirection } from './ResizeHandle';
@@ -206,7 +206,8 @@ export const Canvas: React.FC<CanvasProps> = React.memo(({ className }) => {
206206
}
207207

208208
// Apply constraints from component config
209-
const config = ComponentRegistry.getConfig(schema.type);
209+
const currentNode = findNodeInSchema(schema, resizingNode.nodeId);
210+
const config = currentNode ? ComponentRegistry.getConfig(currentNode.type) : null;
210211
if (config?.resizeConstraints) {
211212
const constraints = config.resizeConstraints;
212213
if (constraints.minWidth) newWidth = Math.max(constraints.minWidth, newWidth);
@@ -232,25 +233,13 @@ export const Canvas: React.FC<CanvasProps> = React.memo(({ className }) => {
232233
const width = element.style.width;
233234
const height = element.style.height;
234235

235-
// Update node with new dimensions in className
236-
// We'll add custom width/height to the existing className
237-
const currentNode = findNodeInSchema(schema, resizingNode.nodeId);
238-
if (currentNode) {
239-
const existingClasses = currentNode.className || '';
240-
// Remove any existing width/height classes
241-
let newClassName = existingClasses
242-
.split(' ')
243-
.filter(c => !c.startsWith('w-') && !c.startsWith('h-') && !c.includes('width') && !c.includes('height'))
244-
.join(' ');
245-
246-
// Add inline style instead via data attribute for persistent sizing
247-
updateNode(resizingNode.nodeId, {
248-
style: {
249-
width,
250-
height
251-
}
252-
});
253-
}
236+
// Persist new dimensions via style on the node schema
237+
updateNode(resizingNode.nodeId, {
238+
style: {
239+
width,
240+
height
241+
}
242+
});
254243

255244
// Clear inline style after update
256245
element.style.width = '';
@@ -270,16 +259,18 @@ export const Canvas: React.FC<CanvasProps> = React.memo(({ className }) => {
270259
}, [resizingNode, setResizingNode, updateNode, schema]);
271260

272261
// Helper to find node in schema
273-
const findNodeInSchema = (node: any, targetId: string): any => {
262+
const findNodeInSchema = (node: SchemaNode, targetId: string): SchemaNode | null => {
274263
if (node.id === targetId) return node;
275264

276265
if (Array.isArray(node.body)) {
277266
for (const child of node.body) {
278-
const found = findNodeInSchema(child, targetId);
279-
if (found) return found;
267+
if (typeof child === 'object' && child !== null) {
268+
const found = findNodeInSchema(child as SchemaNode, targetId);
269+
if (found) return found;
270+
}
280271
}
281272
} else if (node.body && typeof node.body === 'object') {
282-
return findNodeInSchema(node.body, targetId);
273+
return findNodeInSchema(node.body as SchemaNode, targetId);
283274
}
284275

285276
return null;
@@ -480,7 +471,12 @@ export const Canvas: React.FC<CanvasProps> = React.memo(({ className }) => {
480471
/* Resizing state cursor override */
481472
${resizingNode ? `
482473
* {
483-
cursor: ${resizingNode.direction.includes('e') || resizingNode.direction.includes('w') ? 'ew-resize' : 'ns-resize'} !important;
474+
cursor: ${
475+
resizingNode.direction === 'ne' || resizingNode.direction === 'sw' ? 'nesw-resize' :
476+
resizingNode.direction === 'nw' || resizingNode.direction === 'se' ? 'nwse-resize' :
477+
resizingNode.direction.includes('e') || resizingNode.direction.includes('w') ? 'ew-resize' :
478+
'ns-resize'
479+
} !important;
484480
}
485481
486482
[data-obj-id="${resizingNode.nodeId}"] {

packages/designer/src/components/ComponentPalette.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,15 @@ export const ComponentPalette: React.FC<ComponentPaletteProps> = React.memo(({ c
138138
"group flex flex-col items-center justify-center gap-2 p-3 rounded-xl border-2 border-transparent hover:border-indigo-200 hover:bg-gradient-to-br hover:from-indigo-50 hover:to-purple-50 hover:shadow-lg cursor-grab active:cursor-grabbing transition-all duration-200 bg-white relative overflow-hidden",
139139
"h-24 hover:scale-105 active:scale-95"
140140
)}
141+
aria-label={`${config.label || type}${isResizable ? ' (resizable)' : ''}`}
141142
>
142143
{/* Resizable badge indicator */}
143144
{isResizable && (
144-
<div className="absolute top-1 right-1 w-2 h-2 bg-gradient-to-br from-emerald-400 to-green-500 rounded-full opacity-0 group-hover:opacity-100 transition-opacity shadow-sm ring-2 ring-white" title="Resizable"></div>
145+
<div
146+
className="absolute top-1 right-1 w-2 h-2 bg-gradient-to-br from-emerald-400 to-green-500 rounded-full opacity-0 group-hover:opacity-100 transition-opacity shadow-sm ring-2 ring-white"
147+
title="Resizable"
148+
aria-hidden="true"
149+
></div>
145150
)}
146151

147152
<div className="w-9 h-9 rounded-lg bg-gradient-to-br from-gray-50 to-gray-100 group-hover:from-indigo-100 group-hover:to-purple-100 flex items-center justify-center text-gray-600 group-hover:text-indigo-700 transition-all border border-gray-200 group-hover:border-indigo-300 group-hover:shadow-md">

0 commit comments

Comments
 (0)