import { create, createEventRegistrar, dispatch, text, } from "@hesxenon/prelude/Dom.js"; import { pipe } from "@hesxenon/prelude/Function.js"; import * as Option from "@hesxenon/prelude/Option.js"; import { Idl } from "../entry"; import { Events } from "../events"; export const connectSelection = ( datepicker: UwcDatepickerElement, opts: { getLabel: (date: Date, format: "short" | "long") => string; disconnect: AbortController; addPages: (amount: number, toDate: Date) => Date; getStartOfPage: (date: Date) => Date; leapPages: number; }, ) => { const on = createEventRegistrar(datepicker, opts.disconnect); const appendPageButton = (part: "<<" | "<" | ">" | ">>") => { let anchorPageStart: Date; let targetStart: Date; let targetEnd: Date; const move = () => { switch (part) { case "<<": return opts.addPages(-opts.leapPages, anchorPageStart); case "<": return opts.addPages(-1, anchorPageStart); case ">": return opts.addPages(1, anchorPageStart); case ">>": return opts.addPages(opts.leapPages, anchorPageStart); } }; const isDisabled = () => { return part.startsWith("<") ? pipe( Option.fromNullable(datepicker.min), Option.map(Idl.asDate), Option.match( () => false, (min) => targetEnd < min || !datepicker.views.some( (view) => view.addOneUnit(min) < targetEnd, ), ), ) : pipe( Option.fromNullable(datepicker.max), Option.map(Idl.asDate), Option.match( () => false, (max) => targetStart > max || !datepicker.views.some( (view) => view.addOneUnit(targetStart) < max, ), ), ); }; const update = () => { anchorPageStart = opts.getStartOfPage(datepicker.anchorDate); targetStart = move(); targetEnd = opts.addPages(1, targetStart); pageButton.disabled = isDisabled(); }; const pageButton = create( "button", { part, onclick: () => { datepicker.anchorDate = move(); }, }, [text(part)], ); on( [Events.minChanged, Events.maxChanged, Events["anchor-dateChanged"]], update, ); update(); return selection.append(pageButton); }; const selection = create("div", { ariaLive: "true", part: "selection" }); appendPageButton("<<"); appendPageButton("<"); { const currentButton = create( "button", { part: "current", onclick: () => dispatch(datepicker, { type: Events.drillUp }), }, [], ); const update = () => { currentButton.textContent = opts.getLabel(datepicker.anchorDate, "long"); }; on([Events["anchor-dateChanged"]], update); update(); selection.append(currentButton); } appendPageButton(">"); appendPageButton(">>"); datepicker.append(selection); };