Download
58 lines 1.9 KiBJavaScriptModified 2026-08-03 raw
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
// Date widget. Format: "Fri Jul 31" (optionally with year). Natural width —
// it only changes once per day. Click opens a month calendar pop-down.

import { createCalendarPopup } from "../lib/calendar-popup.js";

const DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
const MONTHS = [
  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
];

export default {
  name: "date",
  css: `
    .widget-date .text {
      text-align: center;
      font-family: var(--font-mono);
      font-weight: 600;
      font-variant-numeric: tabular-nums;
    }
  `,
  settings: [
    { key: "showYear", label: "Show year", type: "boolean", default: false },
  ],
  create({ options, listen }) {
    const el = document.createElement("div");
    el.className = "chip clickable widget-date";
    el.style.cursor = "pointer";
    const popup = createCalendarPopup({ anchor: el });
    el.addEventListener("click", () => popup.toggle());
    const textEl = document.createElement("span");
    textEl.className = "text";
    el.appendChild(textEl);

    // The date only changes at midnight; a minute-aligned tick keeps the
    // widget current with rare wakeups. The backend also pings resume
    // from suspend directly, so a sleep spanning midnight doesn't leave
    // yesterday's date up for the rest of the pending minute.
    let timer;
    const render = () => {
      clearTimeout(timer);
      const d = new Date();
      const year = options.showYear ? ` ${d.getFullYear()}` : "";
      textEl.textContent = `${DAYS[d.getDay()]} ${MONTHS[d.getMonth()]} ${d.getDate()}${year}`;
      timer = setTimeout(render, 60000 - d.getSeconds() * 1000 - d.getMilliseconds() + 20);
    };
    render();
    const unlisten = listen("divebar://resume", render);
    return {
      el,
      destroy() {
        clearTimeout(timer);
        unlisten.then((f) => f());
        popup.close();
      },
    };
  },
};