diff --git a/docs/schema/app.js b/docs/schema/app.js index fd80d08..cffeec4 100644 --- a/docs/schema/app.js +++ b/docs/schema/app.js @@ -302,6 +302,11 @@ async function _ingestParsed(parsed, studioComps = [], boardId = null) { isWip: (n.nodes || []).length <= 1, })); + // Sort globally once per ingestion using natural (BOM) collation order + const naturalCollator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }); + S.components.sort((a, b) => naturalCollator.compare(a.ref, b.ref)); + S.nets.sort((a, b) => naturalCollator.compare(a.name, b.name)); + S.hasData = true; S.selectedComp = null; S.selectedNet = null; diff --git a/docs/schema/interaction.js b/docs/schema/interaction.js index b7c19a7..b37f6a1 100644 --- a/docs/schema/interaction.js +++ b/docs/schema/interaction.js @@ -527,6 +527,45 @@ export function initInteraction(saveComponentLayout, saveViewport) { if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return; _hideContextMenu(); + if (e.key === 'ArrowUp' || e.key === 'ArrowDown') { + const isUp = e.key === 'ArrowUp'; + const naturalCollator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }); + + if (S.selectedComp) { + e.preventDefault(); + const idx = S.components.findIndex(c => c.id === S.selectedComp); + if (idx !== -1) { + const nextIdx = isUp ? idx - 1 : idx + 1; + if (nextIdx >= 0 && nextIdx < S.components.length) { + const nextComp = S.components[nextIdx]; + S.selectedComp = nextComp.id; + showProperties(nextComp); + updateSidePanels(); + render(); + document.querySelector('.comp-item.selected')?.scrollIntoView({ block: 'nearest' }); + } + } + return; + } + + if (S.selectedNet) { + e.preventDefault(); + const idx = S.nets.findIndex(n => n.name === S.selectedNet); + if (idx !== -1) { + const nextIdx = isUp ? idx - 1 : idx + 1; + if (nextIdx >= 0 && nextIdx < S.nets.length) { + const nextNet = S.nets[nextIdx]; + S.selectedNet = nextNet.name; + showNetProperties(nextNet); + updateSidePanels(); + render(); + document.querySelector('.net-item.selected')?.scrollIntoView({ block: 'nearest' }); + } + } + return; + } + } + if ((e.key === 'z' || e.key === 'Z') && (e.ctrlKey || e.metaKey)) { undo(); return; }