@isthatuzii/create-nano-app
Version:
Desktop application scaffolding tool for the Nano Framework
218 lines (204 loc) • 6.64 kB
JSX
import { createSignal, onMount } from "solid-js";
import {
Settings,
Info,
Eye,
EyeOff,
Edit,
Save,
ChevronDown,
ChevronRight
} from "lucide-solid";
import "./PropertiesPanel.css";
import { createPropertiesPanelFunctions } from "./PropertiesPanel.functions.js";
function PropertiesPanel(props) {
const [state, setState] = createSignal({
selectedItem: null,
expandedSections: new Set(['details', 'properties']),
editingProperty: null
});
const functions = createPropertiesPanelFunctions(
state,
setState,
props
);
onMount(() => {
functions.initialize();
});
const PropertySection = ({ id, title, children, collapsible = true }) => {
const isExpanded = () => state().expandedSections.has(id);
return (
<div class="property-section">
<div
class="section-header"
classList={{ collapsible }}
onClick={() => collapsible && functions.toggleSection(id)}
>
{collapsible && (
<div class="section-toggle">
{isExpanded() ?
<ChevronDown class="icon size-sm" /> :
<ChevronRight class="icon size-sm" />
}
</div>
)}
<span class="section-title">{title}</span>
<div class="section-controls">
<Eye class="icon size-sm" />
</div>
</div>
{(!collapsible || isExpanded()) && (
<div class="section-content">
{children}
</div>
)}
</div>
);
};
const PropertyRow = ({ label, value, type = 'text', editable = false }) => {
const isEditing = () => state().editingProperty === label;
return (
<div class="property-row">
<div class="property-label">{label}</div>
<div class="property-value-container">
{isEditing() ? (
<div class="property-edit">
<input
type={type}
value={value}
class="property-input"
onBlur={() => functions.stopEditing()}
onKeyDown={(e) => {
if (e.key === 'Enter') functions.stopEditing();
if (e.key === 'Escape') functions.stopEditing();
}}
autofocus
/>
<button class="edit-action" onClick={() => functions.stopEditing()}>
<Save class="icon size-sm" />
</button>
</div>
) : (
<div class="property-display">
<span class="property-value" classList={{ [type]: true }}>
{value}
</span>
{editable && (
<button
class="edit-action"
onClick={() => functions.startEditing(label)}
>
<Edit class="icon size-sm" />
</button>
)}
</div>
)}
</div>
</div>
);
};
return (
<div class="properties-panel">
<div class="panel-header">
<div class="header-title">
<Settings class="icon size-sm" />
<span>Properties</span>
</div>
<div class="header-controls">
<button class="panel-control" title="Panel Settings">
<Settings class="icon size-sm" />
</button>
</div>
</div>
<div class="panel-content">
{state().selectedItem ? (
<>
<PropertySection id="details" title="Item Details">
<PropertyRow
label="Name"
value={state().selectedItem.name}
editable={true}
/>
<PropertyRow
label="Type"
value={state().selectedItem.type}
type="code"
/>
<PropertyRow
label="Path"
value={state().selectedItem.path || 'N/A'}
type="path"
/>
<PropertyRow
label="GUID"
value={state().selectedItem.guid || 'N/A'}
type="code"
/>
</PropertySection>
<PropertySection id="properties" title="Entity Properties">
<PropertyRow
label="Bioselection"
value="False"
type="boolean"
editable={true}
/>
<PropertyRow
label="Category"
value="Default.large"
editable={true}
/>
<PropertyRow
label="Icon"
value="Default.large"
editable={true}
/>
<PropertyRow
label="Invisible"
value="False"
type="boolean"
editable={true}
/>
</PropertySection>
<PropertySection id="components" title="Components">
<div class="component-list">
<div class="component-item">
<span class="component-name">StaticEntityClassData</span>
<Eye class="icon size-sm component-visibility" />
</div>
<div class="component-item">
<span class="component-name">Tags</span>
<Eye class="icon size-sm component-visibility" />
</div>
</div>
</PropertySection>
<PropertySection id="metadata" title="Metadata">
<PropertyRow
label="Created"
value="2023-08-15 14:30:25"
type="datetime"
/>
<PropertyRow
label="Modified"
value="2024-01-20 09:15:42"
type="datetime"
/>
<PropertyRow
label="Size"
value="2.4 KB"
type="size"
/>
</PropertySection>
</>
) : (
<div class="no-selection">
<Info class="icon size-lg no-selection-icon" />
<p class="no-selection-text">
Select an item to view its properties
</p>
</div>
)}
</div>
</div>
);
}
export default PropertiesPanel;