Merge branch 'dev'
This commit is contained in:
commit
90b4426484
|
|
@ -137,6 +137,12 @@ class FolkCalendarView extends HTMLElement {
|
|||
private lunarOverlayExpanded = false;
|
||||
private _wheelTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
// Map resize state
|
||||
private mapPanelWidth = 400;
|
||||
private _isResizing = false;
|
||||
private _resizeStartX = 0;
|
||||
private _resizeStartWidth = 0;
|
||||
|
||||
// Transition state
|
||||
private _pendingTransition: 'nav-left' | 'nav-right' | 'zoom-in' | 'zoom-out' | null = null;
|
||||
private _ghostHtml: string | null = null;
|
||||
|
|
@ -196,6 +202,11 @@ class FolkCalendarView extends HTMLElement {
|
|||
this.boundKeyHandler = null;
|
||||
}
|
||||
if (this._wheelTimer) { clearTimeout(this._wheelTimer); this._wheelTimer = null; }
|
||||
if (this._isResizing) {
|
||||
this._isResizing = false;
|
||||
document.body.style.cursor = "";
|
||||
document.body.style.userSelect = "";
|
||||
}
|
||||
this._pointerCache = [];
|
||||
this._panStartX = this._panStartY = this._initialPinchDist = null;
|
||||
this._gestureMode = 'none';
|
||||
|
|
@ -861,16 +872,17 @@ class FolkCalendarView extends HTMLElement {
|
|||
|
||||
${this.renderSources()}
|
||||
|
||||
<div class="main-layout ${isDocked ? "main-layout--docked" : ""}">
|
||||
<div class="zoom-bar--top">${this.renderZoomController()}</div>
|
||||
|
||||
<div class="main-layout ${isDocked ? "main-layout--docked" : ""}" id="main-layout"${isDocked ? ` style="grid-template-columns: 1fr 6px ${this.mapPanelWidth}px"` : ""}>
|
||||
<div class="calendar-pane" id="calendar-pane">
|
||||
${this.renderCalendarContent()}
|
||||
</div>
|
||||
${isDocked ? `<div class="zoom-bar--middle">${this.renderZoomController()}</div>` : ""}
|
||||
${isDocked ? `<div class="resize-handle" id="resize-handle"></div>` : ""}
|
||||
${this.renderMapPanel()}
|
||||
</div>
|
||||
|
||||
<div class="bottom-bar">
|
||||
${!isDocked ? this.renderZoomController() : ""}
|
||||
${this.renderLunarOverlay()}
|
||||
<button class="bottom-bar__lunar-toggle ${this.showLunar ? "active" : ""}" id="toggle-lunar" title="Toggle lunar phases (l)">\u{1F319}</button>
|
||||
</div>
|
||||
|
|
@ -1883,6 +1895,62 @@ class FolkCalendarView extends HTMLElement {
|
|||
$("map-fab")?.addEventListener("click", () => { this.mapPanelState = "docked"; this.render(); });
|
||||
$("map-minimize")?.addEventListener("click", () => { this.mapPanelState = "minimized"; this.render(); });
|
||||
|
||||
// Resize handle drag
|
||||
const resizeHandle = $("resize-handle");
|
||||
const mainLayout = $("main-layout");
|
||||
if (resizeHandle && mainLayout) {
|
||||
const startResize = (startX: number) => {
|
||||
this._isResizing = true;
|
||||
this._resizeStartX = startX;
|
||||
this._resizeStartWidth = this.mapPanelWidth;
|
||||
resizeHandle.classList.add("active");
|
||||
document.body.style.cursor = "col-resize";
|
||||
document.body.style.userSelect = "none";
|
||||
};
|
||||
const doResize = (clientX: number) => {
|
||||
if (!this._isResizing) return;
|
||||
const delta = this._resizeStartX - clientX; // drag left = bigger map
|
||||
const newWidth = Math.max(200, Math.min(800, this._resizeStartWidth + delta));
|
||||
this.mapPanelWidth = newWidth;
|
||||
(mainLayout as HTMLElement).style.gridTemplateColumns = `1fr 6px ${newWidth}px`;
|
||||
};
|
||||
const endResize = () => {
|
||||
if (!this._isResizing) return;
|
||||
this._isResizing = false;
|
||||
resizeHandle.classList.remove("active");
|
||||
document.body.style.cursor = "";
|
||||
document.body.style.userSelect = "";
|
||||
if (this.leafletMap) this.leafletMap.invalidateSize();
|
||||
};
|
||||
|
||||
resizeHandle.addEventListener("mousedown", (e: Event) => {
|
||||
(e as MouseEvent).preventDefault();
|
||||
startResize((e as MouseEvent).clientX);
|
||||
const onMouseMove = (em: MouseEvent) => doResize(em.clientX);
|
||||
const onMouseUp = () => {
|
||||
document.removeEventListener("mousemove", onMouseMove);
|
||||
document.removeEventListener("mouseup", onMouseUp);
|
||||
endResize();
|
||||
};
|
||||
document.addEventListener("mousemove", onMouseMove);
|
||||
document.addEventListener("mouseup", onMouseUp);
|
||||
});
|
||||
|
||||
resizeHandle.addEventListener("touchstart", (e: Event) => {
|
||||
const te = e as TouchEvent;
|
||||
te.preventDefault();
|
||||
startResize(te.touches[0].clientX);
|
||||
const onTouchMove = (em: Event) => doResize((em as TouchEvent).touches[0].clientX);
|
||||
const onTouchEnd = () => {
|
||||
document.removeEventListener("touchmove", onTouchMove);
|
||||
document.removeEventListener("touchend", onTouchEnd);
|
||||
endResize();
|
||||
};
|
||||
document.addEventListener("touchmove", onTouchMove);
|
||||
document.addEventListener("touchend", onTouchEnd);
|
||||
}, { passive: false });
|
||||
}
|
||||
|
||||
// Zoom spectrum slider — click on track or tick labels
|
||||
const zoomTrack = $("zoom-track");
|
||||
if (zoomTrack) {
|
||||
|
|
@ -2452,17 +2520,23 @@ class FolkCalendarView extends HTMLElement {
|
|||
.src-badge:hover { filter: brightness(1.2); }
|
||||
.src-badge.filtered { opacity: 0.3; text-decoration: line-through; }
|
||||
|
||||
/* ── Zoom Bar Top ── */
|
||||
.zoom-bar--top { margin-bottom: 10px; padding: 8px 12px; background: var(--rs-bg-surface); border: 1px solid var(--rs-border-subtle); border-radius: 8px; }
|
||||
.zoom-bar--top .zoom-bar__track { min-width: 200px; }
|
||||
.zoom-bar--top .zoom-bar__row { gap: 12px; }
|
||||
.zoom-bar--top .zoom-bar__tick-label { font-size: 10px; }
|
||||
.zoom-bar--top .zoom-bar__label-end { font-size: 11px; }
|
||||
|
||||
/* ── Main Layout ── */
|
||||
.main-layout { position: relative; min-height: 400px; }
|
||||
.main-layout--docked { display: grid; grid-template-columns: 1fr auto 400px; gap: 0; min-height: 500px; }
|
||||
.main-layout--docked { display: grid; grid-template-columns: 1fr 6px 400px; gap: 0; min-height: 500px; }
|
||||
.calendar-pane { overflow: auto; min-width: 0; touch-action: pan-y; user-select: none; }
|
||||
.zoom-bar--middle { display: flex; flex-direction: column; justify-content: center; padding: 8px 2px; border-left: 1px solid var(--rs-border-subtle); border-right: 1px solid var(--rs-border-subtle); }
|
||||
.zoom-bar--middle .zoom-bar { padding: 0; }
|
||||
.zoom-bar--middle .zoom-bar__label-end { display: none; }
|
||||
.zoom-bar--middle .zoom-bar__track { min-width: 100px; }
|
||||
.zoom-bar--middle .zoom-bar__tick-label { font-size: 7px; }
|
||||
.zoom-bar--middle .coupling-btn { padding: 2px 6px; font-size: 10px; }
|
||||
.zoom-bar--middle .variant-indicator { display: none; }
|
||||
|
||||
/* ── Resize Handle ── */
|
||||
.resize-handle { width: 6px; cursor: col-resize; background: transparent; position: relative; z-index: 10; transition: background 0.15s; }
|
||||
.resize-handle:hover, .resize-handle.active { background: var(--rs-primary-hover); opacity: 0.5; }
|
||||
.resize-handle::before { content: ""; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 2px; height: 32px; border-radius: 1px; background: var(--rs-border-strong); opacity: 0.4; transition: opacity 0.15s; }
|
||||
.resize-handle:hover::before, .resize-handle.active::before { opacity: 0.8; }
|
||||
|
||||
/* ── Map Panel ── */
|
||||
.map-panel { background: var(--rs-bg-surface-sunken); border: 1px solid var(--rs-border-strong); border-radius: 12px; overflow: hidden; display: flex; flex-direction: column; }
|
||||
|
|
@ -2753,19 +2827,20 @@ class FolkCalendarView extends HTMLElement {
|
|||
|
||||
/* ── Tablet/Adaptive ── */
|
||||
@media (max-width: 1024px) {
|
||||
.main-layout--docked { grid-template-columns: 1fr auto 320px; }
|
||||
.main-layout--docked { grid-template-columns: 1fr 6px 320px; }
|
||||
}
|
||||
@media (max-width: 900px) and (min-width: 769px) {
|
||||
.main-layout--docked { grid-template-columns: 1fr; }
|
||||
.zoom-bar--middle { display: none; }
|
||||
.main-layout--docked { grid-template-columns: 1fr !important; }
|
||||
.resize-handle { display: none; }
|
||||
.ev-label { display: none; }
|
||||
.day { min-height: 64px; }
|
||||
.zoom-bar--top .zoom-bar__track { min-width: 140px; }
|
||||
}
|
||||
/* ── Mobile ── */
|
||||
@media (max-width: 768px) {
|
||||
:host { padding: 0.25rem; }
|
||||
.main-layout--docked { grid-template-columns: 1fr; }
|
||||
.zoom-bar--middle { display: none; }
|
||||
.main-layout--docked { grid-template-columns: 1fr !important; }
|
||||
.resize-handle { display: none; }
|
||||
.year-grid { grid-template-columns: repeat(3, 1fr); }
|
||||
.season-grid { grid-template-columns: 1fr; }
|
||||
.day { min-height: 52px; padding: 4px; }
|
||||
|
|
@ -2780,6 +2855,8 @@ class FolkCalendarView extends HTMLElement {
|
|||
.wd { font-size: 10px; padding: 3px; }
|
||||
.season-cities, .week-event-meta, .tl-event-desc, .yv-country { display: none; }
|
||||
.week-view { font-size: 10px; }
|
||||
.zoom-bar--top { padding: 6px 8px; margin-bottom: 6px; }
|
||||
.zoom-bar--top .zoom-bar__track { min-width: 120px; }
|
||||
.zoom-bar__track { min-width: 120px; }
|
||||
.zoom-bar__label-end { font-size: 9px; }
|
||||
.zoom-bar__tick-label { font-size: 8px; }
|
||||
|
|
|
|||
Loading…
Reference in New Issue