Add collapsible inspector sections with persisted state
This commit is contained in:
parent
c02b14649e
commit
bf64195c45
@ -1,6 +1,7 @@
|
||||
const GRID = 20;
|
||||
const SNAPSHOTS_KEY = "schemeta:snapshots:v2";
|
||||
const SCHEMA_URL = "/schemeta.schema.json";
|
||||
const INSPECTOR_SECTIONS_KEY = "schemeta:inspector-sections:v1";
|
||||
const NET_CLASSES = ["power", "ground", "signal", "analog", "differential", "clock", "bus"];
|
||||
const PIN_SIDES = ["left", "right", "top", "bottom"];
|
||||
const PIN_TYPES = ["power_in", "power_out", "input", "output", "bidirectional", "passive", "analog", "ground"];
|
||||
@ -53,9 +54,13 @@ const el = {
|
||||
compileStatus: document.getElementById("compileStatus"),
|
||||
selectedSummary: document.getElementById("selectedSummary"),
|
||||
componentEditor: document.getElementById("componentEditor"),
|
||||
componentSection: document.getElementById("componentSection"),
|
||||
symbolEditor: document.getElementById("symbolEditor"),
|
||||
symbolSection: document.getElementById("symbolSection"),
|
||||
pinEditor: document.getElementById("pinEditor"),
|
||||
pinSection: document.getElementById("pinSection"),
|
||||
netEditor: document.getElementById("netEditor"),
|
||||
netSection: document.getElementById("netSection"),
|
||||
instRefInput: document.getElementById("instRefInput"),
|
||||
instValueInput: document.getElementById("instValueInput"),
|
||||
instNotesInput: document.getElementById("instNotesInput"),
|
||||
@ -1653,6 +1658,33 @@ function sortKeysDeep(value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
function saveInspectorSectionState() {
|
||||
const stateObj = {
|
||||
component: Boolean(el.componentSection?.open),
|
||||
symbol: Boolean(el.symbolSection?.open),
|
||||
pin: Boolean(el.pinSection?.open),
|
||||
net: Boolean(el.netSection?.open)
|
||||
};
|
||||
localStorage.setItem(INSPECTOR_SECTIONS_KEY, JSON.stringify(stateObj));
|
||||
}
|
||||
|
||||
function loadInspectorSectionState() {
|
||||
try {
|
||||
const raw = localStorage.getItem(INSPECTOR_SECTIONS_KEY);
|
||||
if (!raw) {
|
||||
return;
|
||||
}
|
||||
const parsed = JSON.parse(raw);
|
||||
if (typeof parsed !== "object" || !parsed) {
|
||||
return;
|
||||
}
|
||||
if (el.componentSection) el.componentSection.open = parsed.component !== false;
|
||||
if (el.symbolSection) el.symbolSection.open = parsed.symbol !== false;
|
||||
if (el.pinSection) el.pinSection.open = parsed.pin !== false;
|
||||
if (el.netSection) el.netSection.open = parsed.net !== false;
|
||||
} catch {}
|
||||
}
|
||||
|
||||
async function loadSchemaText() {
|
||||
if (state.schemaText) {
|
||||
return state.schemaText;
|
||||
@ -1890,6 +1922,12 @@ function setupEvents() {
|
||||
});
|
||||
el.instanceList.addEventListener("scroll", renderInstances, { passive: true });
|
||||
el.netList.addEventListener("scroll", renderNets, { passive: true });
|
||||
[el.componentSection, el.symbolSection, el.pinSection, el.netSection].forEach((section) => {
|
||||
if (!section) {
|
||||
return;
|
||||
}
|
||||
section.addEventListener("toggle", saveInspectorSectionState);
|
||||
});
|
||||
|
||||
el.instanceList.addEventListener("click", (evt) => {
|
||||
const item = evt.target.closest("[data-ref-item]");
|
||||
@ -2869,6 +2907,7 @@ function setupEvents() {
|
||||
|
||||
(async function init() {
|
||||
setupEvents();
|
||||
loadInspectorSectionState();
|
||||
updateTransform();
|
||||
|
||||
const snapshots = JSON.parse(localStorage.getItem(SNAPSHOTS_KEY) ?? "[]");
|
||||
|
||||
@ -72,6 +72,8 @@
|
||||
<section>
|
||||
<h2>Selected</h2>
|
||||
<div id="selectedSummary" class="card">Click a component, net, or pin to inspect it.</div>
|
||||
<details id="componentSection" class="editorSection" open>
|
||||
<summary>Component</summary>
|
||||
<div id="componentEditor" class="editorCard hidden">
|
||||
<div class="editorGrid">
|
||||
<label>Ref <input id="instRefInput" type="text" /></label>
|
||||
@ -97,6 +99,9 @@
|
||||
<button id="isolateSelectedComponentBtn">Isolate</button>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
<details id="symbolSection" class="editorSection" open>
|
||||
<summary>Symbol</summary>
|
||||
<div id="symbolEditor" class="editorCard hidden">
|
||||
<div id="symbolMeta" class="hintText"></div>
|
||||
<div class="editorGrid">
|
||||
@ -111,6 +116,9 @@
|
||||
<div id="symbolValidation" class="hintText"></div>
|
||||
<div id="symbolPinsList" class="miniList"></div>
|
||||
</div>
|
||||
</details>
|
||||
<details id="pinSection" class="editorSection" open>
|
||||
<summary>Pin</summary>
|
||||
<div id="pinEditor" class="editorCard hidden">
|
||||
<div id="pinMeta" class="hintText"></div>
|
||||
<div class="editorGrid">
|
||||
@ -167,6 +175,9 @@
|
||||
</div>
|
||||
<div id="pinConnections" class="miniList"></div>
|
||||
</div>
|
||||
</details>
|
||||
<details id="netSection" class="editorSection" open>
|
||||
<summary>Net</summary>
|
||||
<div id="netEditor" class="editorCard hidden">
|
||||
<div class="editorGrid">
|
||||
<label>Name <input id="netNameInput" type="text" /></label>
|
||||
@ -195,6 +206,7 @@
|
||||
</div>
|
||||
<div id="netNodesList" class="miniList"></div>
|
||||
</div>
|
||||
</details>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
|
||||
@ -218,6 +218,31 @@ textarea {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.editorSection {
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 8px;
|
||||
margin-top: 8px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.editorSection > summary {
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
padding: 8px 10px;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 700;
|
||||
color: var(--ink);
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
.editorSection[open] > summary {
|
||||
border-bottom-color: var(--line);
|
||||
}
|
||||
|
||||
.editorSection > summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.editorGrid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user