refactor: remove PinSelector component and associated styles

This commit is contained in:
David Montero Crespo 2026-04-21 11:16:11 -03:00
parent b152cb1919
commit 9ce4ad0147
3 changed files with 18 additions and 284 deletions

View File

@ -1,134 +0,0 @@
.pin-selector-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
}
.pin-selector {
position: relative;
background-color: #2d2d2d;
border: 1px solid #555;
border-radius: 8px;
padding: 20px;
min-width: 320px;
max-width: 400px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
}
.pin-selector-header {
margin-bottom: 15px;
border-bottom: 1px solid #444;
padding-bottom: 10px;
}
.pin-selector-header h4 {
margin: 0 0 5px 0;
color: #fff;
font-size: 16px;
}
.component-type-label {
font-size: 12px;
color: #888;
text-transform: capitalize;
}
.pin-group {
margin-bottom: 15px;
}
.pin-group-label {
font-size: 13px;
color: #aaa;
margin-bottom: 8px;
font-weight: 500;
}
.pin-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 6px;
}
.pin-button {
padding: 8px 4px;
background-color: #3d3d3d;
border: 1px solid #555;
border-radius: 4px;
color: #fff;
cursor: pointer;
font-size: 12px;
font-weight: 500;
transition: all 0.2s;
}
.pin-button:hover {
background-color: #4d4d4d;
border-color: #007acc;
}
.pin-button.selected {
background-color: #007acc;
border-color: #007acc;
color: #fff;
}
.pin-button.current {
background-color: #28a745;
border-color: #28a745;
color: #fff;
}
.pin-button.selected.current {
background-color: #007acc;
border-color: #007acc;
}
.pin-selector-footer {
display: flex;
justify-content: flex-end;
gap: 10px;
margin-top: 15px;
padding-top: 15px;
border-top: 1px solid #444;
}
.pin-selector-footer .btn {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
transition: all 0.2s;
}
.pin-selector-footer .btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.pin-selector-footer .btn-primary {
background-color: #007acc;
color: white;
}
.pin-selector-footer .btn-primary:hover:not(:disabled) {
background-color: #005a9e;
}
.pin-selector-footer .btn-secondary {
background-color: #6c757d;
color: white;
}
.pin-selector-footer .btn-secondary:hover {
background-color: #5a6268;
}

View File

@ -1,98 +0,0 @@
import { useState } from 'react';
import './PinSelector.css';
interface PinSelectorProps {
componentId: string;
componentType: string;
currentPin?: number;
onPinSelect: (componentId: string, pin: number) => void;
onClose: () => void;
position: { x: number; y: number };
}
// Arduino Uno pin groups
const PIN_GROUPS = [
{
label: 'Digital Pins',
pins: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
},
{
label: 'Analog Pins',
pins: [14, 15, 16, 17, 18, 19], // A0-A5
},
];
export const PinSelector = ({
componentId,
componentType,
currentPin,
onPinSelect,
onClose,
position,
}: PinSelectorProps) => {
const [selectedPin, setSelectedPin] = useState<number | undefined>(currentPin);
const handlePinClick = (pin: number) => {
setSelectedPin(pin);
};
const handleConfirm = () => {
if (selectedPin !== undefined) {
onPinSelect(componentId, selectedPin);
onClose();
}
};
const formatPinLabel = (pin: number): string => {
if (pin >= 14 && pin <= 19) {
return `A${pin - 14}`;
}
return `D${pin}`;
};
return (
<div className="pin-selector-overlay" onClick={onClose}>
<div
className="pin-selector"
onClick={(e) => e.stopPropagation()}
>
<div className="pin-selector-header">
<h4>Select Pin</h4>
<span className="component-type-label">{componentType}</span>
</div>
{PIN_GROUPS.map((group) => (
<div key={group.label} className="pin-group">
<div className="pin-group-label">{group.label}</div>
<div className="pin-grid">
{group.pins.map((pin) => (
<button
key={pin}
className={`pin-button ${selectedPin === pin ? 'selected' : ''} ${
currentPin === pin ? 'current' : ''
}`}
onClick={() => handlePinClick(pin)}
>
{formatPinLabel(pin)}
</button>
))}
</div>
</div>
))}
<div className="pin-selector-footer">
<button className="btn btn-secondary" onClick={onClose}>
Cancel
</button>
<button
className="btn btn-primary"
onClick={handleConfirm}
disabled={selectedPin === undefined}
>
Confirm
</button>
</div>
</div>
</div>
);
};

View File

@ -7,7 +7,6 @@ import { SensorControlPanel } from './SensorControlPanel';
import { SENSOR_CONTROLS } from '../../simulation/sensorControlConfig';
import { DynamicComponent, createComponentFromMetadata } from '../DynamicComponent';
import { ComponentRegistry } from '../../services/ComponentRegistry';
import { PinSelector } from './PinSelector';
import { getTabSessionId } from '../../simulation/Esp32Bridge';
import { WireLayer } from './WireLayer';
import type { SegmentHandle } from './WireLayer';
@ -107,8 +106,6 @@ export const SimulatorCanvas = () => {
// Component selection
const [selectedComponentId, setSelectedComponentId] = useState<string | null>(null);
const [showPinSelector, setShowPinSelector] = useState(false);
const [pinSelectorPos, setPinSelectorPos] = useState({ x: 0, y: 0 });
// Component property dialog
const [showPropertyDialog, setShowPropertyDialog] = useState(false);
@ -573,14 +570,18 @@ export const SimulatorCanvas = () => {
const boardId = touchId.slice('__board__:'.length);
useSimulatorStore.getState().setActiveBoardId(boardId);
} else if (touchId !== '__board__') {
// Short tap on component → open property dialog or sensor panel
// Short tap on component → open property dialog or sensor panel.
// While the simulator is running, components stay interactive —
// only sensor panels may open; property editing is disabled.
const component = componentsRef.current.find(
(c) => c.id === touchId
);
if (component) {
if (runningRef.current && SENSOR_CONTROLS[component.metadataId] !== undefined) {
setSensorControlComponentId(touchId);
setSensorControlMetadataId(component.metadataId);
if (runningRef.current) {
if (SENSOR_CONTROLS[component.metadataId] !== undefined) {
setSensorControlComponentId(touchId);
setSensorControlMetadataId(component.metadataId);
}
} else {
setPropertyDialogComponentId(touchId);
setPropertyDialogPosition({
@ -903,24 +904,6 @@ export const SimulatorCanvas = () => {
setShowComponentPicker(false);
};
// Component selection (double click to open pin selector)
const handleComponentDoubleClick = (componentId: string, event: React.MouseEvent) => {
event.stopPropagation();
setSelectedComponentId(componentId);
setPinSelectorPos({ x: event.clientX, y: event.clientY });
setShowPinSelector(true);
};
// Pin assignment
const handlePinSelect = (componentId: string, pin: number) => {
updateComponent(componentId, {
properties: {
...components.find((c) => c.id === componentId)?.properties,
pin,
},
} as any);
};
// Component rotation
const handleRotateComponent = (componentId: string) => {
const component = components.find((c) => c.id === componentId);
@ -937,7 +920,7 @@ export const SimulatorCanvas = () => {
// Component dragging handlers
const handleComponentMouseDown = (componentId: string, e: React.MouseEvent) => {
if (showPinSelector || showPropertyDialog) return;
if (showPropertyDialog) return;
e.stopPropagation();
const component = components.find((c) => c.id === componentId);
@ -1056,10 +1039,15 @@ export const SimulatorCanvas = () => {
} else if (draggedComponentId !== '__board__') {
const component = components.find((c) => c.id === draggedComponentId);
if (component) {
// During simulation: sensor components show the SensorControlPanel
if (running && SENSOR_CONTROLS[component.metadataId] !== undefined) {
setSensorControlComponentId(draggedComponentId);
setSensorControlMetadataId(component.metadataId);
if (running) {
// During simulation only sensor panels open on click — every
// other component is interactive (pushbutton, switch, pot, …)
// and must handle its own clicks, so we suppress the property
// dialog entirely.
if (SENSOR_CONTROLS[component.metadataId] !== undefined) {
setSensorControlComponentId(draggedComponentId);
setSensorControlMetadataId(component.metadataId);
}
} else {
setPropertyDialogComponentId(draggedComponentId);
setPropertyDialogPosition({
@ -1294,12 +1282,6 @@ export const SimulatorCanvas = () => {
onMouseDown={(e) => {
handleComponentMouseDown(component.id, e);
}}
onDoubleClick={(e) => {
// Only handle UI events when simulation is NOT running
if (!running) {
handleComponentDoubleClick(component.id, e);
}
}}
/>
{/* Pin overlay for wire creation - hide when running */}
@ -1595,22 +1577,6 @@ export const SimulatorCanvas = () => {
</div>
</div>
{/* Pin Selector Modal */}
{showPinSelector && selectedComponentId && (
<PinSelector
componentId={selectedComponentId}
componentType={
components.find((c) => c.id === selectedComponentId)?.metadataId || 'unknown'
}
currentPin={
components.find((c) => c.id === selectedComponentId)?.properties.pin as number | undefined
}
onPinSelect={handlePinSelect}
onClose={() => setShowPinSelector(false)}
position={pinSelectorPos}
/>
)}
{/* Component Property Dialog */}
{showPropertyDialog && propertyDialogComponentId && (() => {
const component = components.find((c) => c.id === propertyDialogComponentId);