Week View

Calendar showing a week.

17–23 August 2026
Time Mon Tue Wed Thu Fri Sat Sun
9:00 Standup
10:00 Design review
11:00 Client call

html

<table class="wv" data-density="Comfortable" data-weekend="true" data-highlight="true">
  <caption class="wv__caption">17–23 August 2026</caption>
  <thead>
    <tr>
      <th scope="col" class="wv__th wv__th--time">Time</th>
      <th scope="col" class="wv__th" data-today="false">Mon <time datetime="2026-08-17">17</time></th>
      <th scope="col" class="wv__th" data-today="true">Tue <time datetime="2026-08-18">18</time></th>
      <th scope="col" class="wv__th" data-today="false">Wed <time datetime="2026-08-19">19</time></th>
      <th scope="col" class="wv__th" data-today="false">Thu <time datetime="2026-08-20">20</time></th>
      <th scope="col" class="wv__th" data-today="false">Fri <time datetime="2026-08-21">21</time></th>
      <th scope="col" class="wv__th" data-today="false">Sat <time datetime="2026-08-22">22</time></th>
      <th scope="col" class="wv__th" data-today="false">Sun <time datetime="2026-08-23">23</time></th>
    </tr>
  </thead>
  <tbody>
    <tr><th scope="row" class="wv__row-th">9:00</th>
      <td class="wv__td" data-today="false"></td>
      <td class="wv__td" data-today="true"><span class="wv__ev" style="background:#A8E6C1;">Standup</span></td>
      <td class="wv__td" data-today="false"></td>
      <td class="wv__td" data-today="false"></td>
      <td class="wv__td" data-today="false"></td>
      <td class="wv__td" data-today="false"></td>
      <td class="wv__td" data-today="false"></td>
    </tr>
    <tr><th scope="row" class="wv__row-th">10:00</th>
      <td class="wv__td" data-today="false"></td>
      <td class="wv__td" data-today="true"></td>
      <td class="wv__td" data-today="false"></td>
      <td class="wv__td" data-today="false"><span class="wv__ev" style="background:#A8E6C1;">Design review</span></td>
      <td class="wv__td" data-today="false"></td>
      <td class="wv__td" data-today="false"></td>
      <td class="wv__td" data-today="false"></td>
    </tr>
    <tr><th scope="row" class="wv__row-th">11:00</th>
      <td class="wv__td" data-today="false"></td>
      <td class="wv__td" data-today="true"></td>
      <td class="wv__td" data-today="false"></td>
      <td class="wv__td" data-today="false"></td>
      <td class="wv__td" data-today="false"><span class="wv__ev" style="background:#A8E6C1;">Client call</span></td>
      <td class="wv__td" data-today="false"></td>
      <td class="wv__td" data-today="false"></td>
    </tr>
  </tbody>
</table>
<style>
.wv { border-collapse: collapse; width: 560px; font: 12px/1.3 system-ui, sans-serif; color: #241430; background: #FAF7F2; table-layout: fixed; }
.wv__caption { text-align: left; font-weight: 700; font-size: 14px; padding-bottom: 10px; }
.wv th, .wv td { border: 1px solid #24143014; padding: 8px 4px; text-align: center; }
.wv__th { font-weight: 600; color: #24143099; }
.wv__th--time { width: 50px; }
.wv__row-th { font-weight: 500; color: #24143099; font-variant-numeric: tabular-nums; }
.wv[data-density="Compact"] th, .wv[data-density="Compact"] td { padding: 4px 4px; }
.wv[data-highlight="true"] th[data-today="true"] { font-weight: 800; color: #241430; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 3px; }
.wv[data-highlight="true"] td[data-today="true"] { background: #24143008; }
.wv[data-weekend="false"] th:nth-last-child(2), .wv[data-weekend="false"] td:nth-last-child(2),
.wv[data-weekend="false"] th:last-child, .wv[data-weekend="false"] td:last-child { display: none; }
.wv__ev { display: block; border-radius: 5px; padding: 3px 5px; font-weight: 700; color: #14351f; font-size: 11px; }
</style>

tailwind

<table class="border-collapse w-[560px] font-sans text-xs text-[#241430] bg-[#FAF7F2] wv-tw table-fixed" data-density="Comfortable" data-weekend="true" data-highlight="true">
  <caption class="text-left font-bold text-sm pb-2.5">17–23 August 2026</caption>
  <thead>
    <tr>
      <th scope="col" class="w-[50px] font-semibold text-[#241430]/60 border border-[#24143014] p-2 text-center">Time</th>
      <th scope="col" class="wvtw-th" data-today="false">Mon <time datetime="2026-08-17">17</time></th>
      <th scope="col" class="wvtw-th" data-today="true">Tue <time datetime="2026-08-18">18</time></th>
      <th scope="col" class="wvtw-th" data-today="false">Wed <time datetime="2026-08-19">19</time></th>
      <th scope="col" class="wvtw-th" data-today="false">Thu <time datetime="2026-08-20">20</time></th>
      <th scope="col" class="wvtw-th" data-today="false">Fri <time datetime="2026-08-21">21</time></th>
      <th scope="col" class="wvtw-th" data-today="false">Sat <time datetime="2026-08-22">22</time></th>
      <th scope="col" class="wvtw-th" data-today="false">Sun <time datetime="2026-08-23">23</time></th>
    </tr>
  </thead>
  <tbody>
    <tr><th scope="row" class="wvtw-row-th">9:00</th>
      <td class="wvtw-td" data-today="false"></td>
      <td class="wvtw-td" data-today="true"><span class="wvtw-ev" style="background:#A8E6C1;">Standup</span></td>
      <td class="wvtw-td" data-today="false"></td>
      <td class="wvtw-td" data-today="false"></td>
      <td class="wvtw-td" data-today="false"></td>
      <td class="wvtw-td" data-today="false"></td>
      <td class="wvtw-td" data-today="false"></td>
    </tr>
    <tr><th scope="row" class="wvtw-row-th">10:00</th>
      <td class="wvtw-td" data-today="false"></td>
      <td class="wvtw-td" data-today="true"></td>
      <td class="wvtw-td" data-today="false"></td>
      <td class="wvtw-td" data-today="false"><span class="wvtw-ev" style="background:#A8E6C1;">Design review</span></td>
      <td class="wvtw-td" data-today="false"></td>
      <td class="wvtw-td" data-today="false"></td>
      <td class="wvtw-td" data-today="false"></td>
    </tr>
    <tr><th scope="row" class="wvtw-row-th">11:00</th>
      <td class="wvtw-td" data-today="false"></td>
      <td class="wvtw-td" data-today="true"></td>
      <td class="wvtw-td" data-today="false"></td>
      <td class="wvtw-td" data-today="false"></td>
      <td class="wvtw-td" data-today="false"><span class="wvtw-ev" style="background:#A8E6C1;">Client call</span></td>
      <td class="wvtw-td" data-today="false"></td>
      <td class="wvtw-td" data-today="false"></td>
    </tr>
  </tbody>
</table>
<style>
.wv-tw th, .wv-tw td { border: 1px solid #24143014; padding: 8px 4px; text-align: center; }
.wvtw-th { font-weight: 600; color: #24143099; }
.wvtw-row-th { font-weight: 500; color: #24143099; font-variant-numeric: tabular-nums; }
.wv-tw[data-density="Compact"] th, .wv-tw[data-density="Compact"] td { padding-top: 4px; padding-bottom: 4px; }
.wv-tw[data-highlight="true"] th[data-today="true"] { font-weight: 800; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 3px; }
.wv-tw[data-highlight="true"] td[data-today="true"] { background: #24143008; }
.wv-tw[data-weekend="false"] th:nth-last-child(2), .wv-tw[data-weekend="false"] td:nth-last-child(2),
.wv-tw[data-weekend="false"] th:last-child, .wv-tw[data-weekend="false"] td:last-child { display: none; }
.wvtw-ev { display: block; border-radius: 5px; padding: 3px 5px; font-weight: 700; color: #14351f; font-size: 11px; }
</style>

react

export function WeekView({
  weekLabel = "17–23 August 2026",
  density = "Comfortable",
  showWeekend = true,
  highlightToday = true,
  accent = "#A8E6C1",
}) {
  const TODAY = "2026-08-18";
  const days = [{ wd: "Mon", num: 17, iso: "2026-08-17" }, { wd: "Tue", num: 18, iso: "2026-08-18" }, { wd: "Wed", num: 19, iso: "2026-08-19" }, { wd: "Thu", num: 20, iso: "2026-08-20" }, { wd: "Fri", num: 21, iso: "2026-08-21" }, { wd: "Sat", num: 22, iso: "2026-08-22" }, { wd: "Sun", num: 23, iso: "2026-08-23" }];
  const hours = ["9:00", "10:00", "11:00"];
  const events = [{ hi: 0, di: 1, label: "Standup" }, { hi: 1, di: 3, label: "Design review" }, { hi: 2, di: 4, label: "Client call" }];
  const visibleDays = showWeekend ? days : days.slice(0, 5);
  const pad = density === "Compact" ? "4px" : "8px 4px";
  const cellBorder = { border: "1px solid #24143014", padding: pad, textAlign: "center" };
  return (
    <table style={{ borderCollapse: "collapse", width: 560, font: "12px/1.3 system-ui, sans-serif", color: "#241430", background: "#FAF7F2", tableLayout: "fixed" }}>
      <caption style={{ textAlign: "left", fontWeight: 700, fontSize: 14, paddingBottom: 10 }}>{weekLabel}</caption>
      <thead>
        <tr>
          <th scope="col" style={{ ...cellBorder, width: 50, fontWeight: 600, color: "#24143099" }}>Time</th>
          {visibleDays.map((d) => {
            const isToday = d.iso === TODAY;
            return (
              <th key={d.iso} scope="col" style={{ ...cellBorder, fontWeight: highlightToday && isToday ? 800 : 600, color: highlightToday && isToday ? "#241430" : "#24143099", textDecoration: highlightToday && isToday ? "underline" : "none", textDecorationThickness: 2, textUnderlineOffset: 3 }}>
                {d.wd} <time dateTime={d.iso}>{d.num}</time>
              </th>
            );
          })}
        </tr>
      </thead>
      <tbody>
        {hours.map((hour, hi) => (
          <tr key={hour}>
            <th scope="row" style={{ ...cellBorder, fontWeight: 500, color: "#24143099", fontVariantNumeric: "tabular-nums" }}>{hour}</th>
            {visibleDays.map((d, di) => {
              const isToday = d.iso === TODAY;
              const ev = events.find((e) => e.hi === hi && e.di === di);
              return (
                <td key={d.iso} style={{ ...cellBorder, background: highlightToday && isToday ? "#24143008" : "transparent" }}>
                  {ev && <span style={{ display: "block", borderRadius: 5, padding: "3px 5px", fontWeight: 700, color: "#14351f", fontSize: 11, background: accent }}>{ev.label}</span>}
                </td>
              );
            })}
          </tr>
        ))}
      </tbody>
    </table>
  );
}