various ui improvements, including a new sequence nav component and a new kabbalah detail view

This commit is contained in:
2026-05-28 18:19:13 -07:00
parent c423f1191d
commit 1433ec1495
17 changed files with 2274 additions and 120 deletions
+74 -3
View File
@@ -21,6 +21,7 @@
monthRefsByPlanetId: new Map(),
cubePlacementsByPlanetId: new Map()
};
let detailNavigator = null;
function normalizePlanetToken(value) {
return String(value || "")
@@ -80,12 +81,16 @@
function getElements() {
return {
planetSectionEl: document.getElementById("planet-section"),
planetCardListEl: document.getElementById("planet-card-list"),
planetSearchInputEl: document.getElementById("planet-search-input"),
planetSearchClearEl: document.getElementById("planet-search-clear"),
planetCountEl: document.getElementById("planet-card-count"),
planetDetailNameEl: document.getElementById("planet-detail-name"),
planetDetailTypeEl: document.getElementById("planet-detail-type"),
planetDetailPrevEl: document.getElementById("planet-detail-prev"),
planetDetailPositionEl: document.getElementById("planet-detail-position"),
planetDetailNextEl: document.getElementById("planet-detail-next"),
planetDetailSummaryEl: document.getElementById("planet-detail-summary"),
planetDetailFactsEl: document.getElementById("planet-detail-facts"),
planetDetailAtmosphereEl: document.getElementById("planet-detail-atmosphere"),
@@ -156,11 +161,14 @@
if (!state.filteredEntries.some((entry) => entry.id === state.selectedId)) {
if (state.filteredEntries.length > 0) {
selectById(state.filteredEntries[0].id, elements);
} else {
syncDetailNavigation(elements);
}
return;
}
updateSelection(elements);
syncDetailNavigation(elements);
}
function clearChildren(element) {
@@ -434,6 +442,68 @@
});
}
function getSequenceState() {
const total = state.filteredEntries.length;
const currentIndex = state.filteredEntries.findIndex((entry) => entry.id === state.selectedId);
return {
total,
currentIndex,
previousId: currentIndex > 0 ? state.filteredEntries[currentIndex - 1].id : "",
nextId: currentIndex >= 0 && currentIndex < total - 1 ? state.filteredEntries[currentIndex + 1].id : ""
};
}
function getDetailNavigator() {
if (detailNavigator || typeof window.TarotSequenceNav?.createSequenceNavigator !== "function") {
return detailNavigator;
}
detailNavigator = window.TarotSequenceNav.createSequenceNavigator({
getElements,
isActive: (elements) => Boolean(elements?.planetSectionEl && elements.planetSectionEl.hidden === false),
getSequenceState,
getPrevButton: (elements) => elements?.planetDetailPrevEl,
getNextButton: (elements) => elements?.planetDetailNextEl,
getPositionEl: (elements) => elements?.planetDetailPositionEl,
formatPositionText: ({ total, currentIndex }) => {
if (total > 0 && currentIndex >= 0) {
const suffix = state.searchQuery ? " shown" : "";
return `${currentIndex + 1} of ${total}${suffix}`;
}
return total > 0 ? `${total} bodies` : "No bodies";
},
selectTarget: (targetId, elements) => {
selectById(targetId, elements);
return true;
},
afterSelect: (targetId, elements) => {
scrollEntryIntoView(targetId, elements);
}
});
return detailNavigator;
}
function syncDetailNavigation(elements) {
getDetailNavigator()?.sync(elements);
}
function scrollEntryIntoView(id, elements) {
elements?.planetCardListEl
?.querySelector(`[data-planet-id="${id}"]`)
?.scrollIntoView({ block: "nearest" });
}
function selectAdjacentEntry(offset, elements) {
return getDetailNavigator()?.step(offset, elements) === true;
}
function bindKeyboardNavigation(elements) {
getDetailNavigator()?.bind(elements);
}
function selectById(id, elements) {
const entry = state.entries.find((planet) => planet.id === id);
if (!entry) {
@@ -443,6 +513,7 @@
state.selectedId = entry.id;
updateSelection(elements);
renderDetail(entry, elements);
syncDetailNavigation(elements);
}
function renderList(elements) {
@@ -580,6 +651,8 @@
});
}
bindKeyboardNavigation(elements);
state.initialized = true;
}
@@ -594,9 +667,7 @@
);
if (!entry) return;
selectById(entry.id, el);
el.planetCardListEl
?.querySelector(`[data-planet-id="${entry.id}"]`)
?.scrollIntoView({ block: "nearest" });
scrollEntryIntoView(entry.id, el);
}
window.PlanetSectionUi = {