Files
apparel-designer/client/src/components/properties/PropertiesPanel.jsx
Khalid A 2acf674aaa Phase 3: Sidebar & Properties Panel
- Three-column layout (sidebar/canvas/properties)
- Sidebar with tabs: Upload, Stickers, Text
- Upload tab with drag-and-drop and click-to-upload
- Stickers tab with 6 categories (40+ emojis)
- Text tab with font selector, size slider, color picker
- Properties panel with position, size, rotation controls
- Delete button for selected element
- Responsive layout for mobile

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 01:17:47 -05:00

110 lines
3.4 KiB
JavaScript

export function PropertiesPanel({ selectedElement, onUpdate, onDelete }) {
if (!selectedElement) {
return (
<div className="properties-panel">
<h3>Properties</h3>
<div className="no-selection">
<p>Select an element to edit its properties</p>
</div>
</div>
);
}
const handlePositionChange = (axis, value) => {
onUpdate(selectedElement.id, { [axis]: Number(value) });
};
const handleSizeChange = (dimension, value) => {
onUpdate(selectedElement.id, { [dimension]: Number(value) });
};
const handleRotationChange = (value) => {
onUpdate(selectedElement.id, { rotation: Number(value) });
};
const getIcon = () => {
if (selectedElement.type === 'image') return '🖼️';
if (selectedElement.type === 'text') return 'T';
if (selectedElement.type === 'sticker') return '😊';
return '📦';
};
return (
<div className="properties-panel">
<h3>Properties</h3>
<div className="element-header">
<span className="element-icon">{getIcon()}</span>
<span className="element-name">
{selectedElement.type === 'text'
? selectedElement.text?.substring(0, 20) || 'Text'
: `${selectedElement.type}`}
</span>
</div>
<div className="property-group">
<label>Position</label>
<div className="property-row">
<div className="property-input">
<span className="property-label">X</span>
<input
type="number"
value={Math.round(selectedElement.x)}
onChange={(e) => handlePositionChange('x', e.target.value)}
/>
</div>
<div className="property-input">
<span className="property-label">Y</span>
<input
type="number"
value={Math.round(selectedElement.y)}
onChange={(e) => handlePositionChange('y', e.target.value)}
/>
</div>
</div>
</div>
<div className="property-group">
<label>Size</label>
<div className="property-row">
<div className="property-input">
<span className="property-label">W</span>
<input
type="number"
value={Math.round(selectedElement.width || selectedElement.fontSize || 0)}
onChange={(e) =>
handleSizeChange(selectedElement.text ? 'fontSize' : 'width', e.target.value)
}
/>
</div>
{selectedElement.type !== 'text' && (
<div className="property-input">
<span className="property-label">H</span>
<input
type="number"
value={Math.round(selectedElement.height || 0)}
onChange={(e) => handleSizeChange('height', e.target.value)}
/>
</div>
)}
</div>
</div>
<div className="property-group">
<label>Rotation: {Math.round(selectedElement.rotation || 0)}°</label>
<input
type="range"
min="0"
max="360"
value={selectedElement.rotation || 0}
onChange={(e) => handleRotationChange(e.target.value)}
className="rotation-slider"
/>
</div>
<button className="delete-btn" onClick={() => onDelete(selectedElement.id)}>
Delete Element
</button>
</div>
);
}