2026-10-14 22:55:12 +04:00

45 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Fragment, useRef, type PointerEvent, type RefObject } from "react";
import { COLW, GRID } from "../constants.ts";
import { dateText, dateTitle, type DateCol } from "../layout/layout.ts";
// липкая полоса подписей дат над доской: сдвиг — как у горизонтальной прокрутки доски; ручка границы меняет ширину колонки
export function DatesBar({ cols, width, scrollLeft, inRef, onColWidth }: {
cols: DateCol[]; width: number; scrollLeft: number; inRef: RefObject<HTMLDivElement | null>;
onColWidth(date: string, w: number | null): void;
}) {
const raf = useRef(0);
const down = (ev: PointerEvent<HTMLDivElement>, c: DateCol) => {
ev.preventDefault();
const handle = ev.currentTarget, x0 = ev.clientX;
handle.classList.add("on"); inRef.current?.classList.add("resizing");
let last = c.w;
const apply = (w: number) => onColWidth(c.date, w <= COLW ? null : Math.round(w / GRID) * GRID);
const move = (e: globalThis.PointerEvent) => {
last = Math.max(COLW, c.w + e.clientX - x0);
if (!raf.current) raf.current = requestAnimationFrame(() => { raf.current = 0; apply(last); });
};
const stop = () => {
window.removeEventListener("pointermove", move); window.removeEventListener("pointerup", stop); window.removeEventListener("pointercancel", stop);
handle.classList.remove("on"); inRef.current?.classList.remove("resizing");
apply(last);
};
window.addEventListener("pointermove", move); window.addEventListener("pointerup", stop); window.addEventListener("pointercancel", stop);
};
const cls = (c: DateCol) => (c.cls ? " " + c.cls : "");
return (
<div className="dates-bar">
<div className="dates-in" ref={inRef}>
<div className="dates-track" style={{ width, transform: `translateX(${-scrollLeft}px)` }}>
{cols.map((c) => (
<Fragment key={c.date}>
<span className={"dlabel" + cls(c)} style={{ left: c.x0 + 8 }} title={dateTitle(c)}>{dateText(c)}<span className="n">{c.count}</span></span>
<div className="dsplit" style={{ left: c.x0 + c.w }} title="Тянуть — ширина колонки; двойной щелчок — автоматическая"
onPointerDown={(e) => down(e, c)} onDoubleClick={() => onColWidth(c.date, null)} />
</Fragment>
))}
</div>
</div>
</div>
);
}