feat(charts): drop the explanatory line under day-linked charts

This commit is contained in:
Marc-André Bombeck committed 2026-10-11 13:39:20 +02:00
1 parent 3c4e053dcd
commit b7eef0dff4
15 files changed
+13 -119

No files matched your search

@@ -52,11 +52,10 @@ describe("<HealthChart> day links", () => {
vi.resetModules();
});
it("a metric page's chart opens its days: plot, caption and table", async () => {
it("a metric page's chart opens its days: plot and table", async () => {
const html = await renderChart({ dayLinks: true, showDataTable: true });
expect(html).toContain('data-day-links="true"');
expect(html).toContain('data-slot="chart-day-caption"');
expect(html).toContain("Click a point to open its day.");
expect(html).not.toContain('data-slot="chart-day-caption"');
const links = html.match(/data-slot="day-link"/g) ?? [];
expect(links).toHaveLength(10);
expect(html).toMatch(/href="[^"]*\?day=\d{4}-\d{2}-\d{2}"/);
@@ -1,6 +1,5 @@
"use client";
import { ChartDayCaption } from "@/components/day/chart-day";
import { dayAnchor } from "@/components/day/chart-day-links";
import { OPEN_DAY_CELL, useHeatmapDay } from "@/components/day/heatmap-day";
import { useCalendarDate } from "@/hooks/use-calendar-date";
@@ -368,7 +367,6 @@ export function ComplianceHeatmap({
</div>
{activeCells.length > 0 ? (
<>
<ChartDayCaption coarse={heatmapDay.coarse} mark="cell" rug={false} />
{/* The keyboard and screen-reader way to each active day's doses,
and to the day itself. */}
<ChartDataTable
+1 -5
View File
@@ -1,6 +1,5 @@
"use client";
import { ChartDayCaption, useCoarsePointer } from "@/components/day/chart-day";
import { dayAnchor } from "@/components/day/chart-day-links";
import { OPEN_DAY_CELL, useHeatmapDay } from "@/components/day/heatmap-day";
import { useCalendarDate } from "@/hooks/use-calendar-date";
@@ -102,14 +101,13 @@ export function MoodHeatmapBody({
/**
* The loading shape of the stretched heatmap, at exactly the height the
* painted heatmap takes: the reserved grid box, the legend line, the day
* caption and the data-table toggle. `days` is the window when it is already
* data-table toggle. `days` is the window when it is already
* known; without it the shape assumes a window short enough to reach the cell
* ceiling on every width down to 360 px (eight weeks), the height most
* calendars settle at.
*/
export function MoodHeatmapSkeleton({ days = 56 }: { days?: number }) {
const timeZone = useDisplayTimezone();
const coarse = useCoarsePointer();
return (
<div
data-slot="mood-heatmap-skeleton"
@@ -120,7 +118,6 @@ export function MoodHeatmapSkeleton({ days = 56 }: { days?: number }) {
<div className="bg-muted/50 h-full w-full animate-pulse rounded-md motion-reduce:animate-none" />
</MoodHeatmapBody>
<div className="mt-2 h-4" />
<ChartDayCaption coarse={coarse} mark="cell" rug={false} />
<div className="border-border mt-3 border-t pt-3">
<div className="min-h-11" />
</div>
@@ -411,7 +408,6 @@ export function MoodHeatmap({
</div>
{loggedCells.length > 0 ? (
<>
<ChartDayCaption coarse={heatmapDay.coarse} mark="cell" rug={false} />
{/* The keyboard and screen-reader way to each logged day's value,
and to the day itself. */}
<ChartDataTable
@@ -173,7 +173,6 @@ export function NutrientDailyBarChart({
links={chartDays}
points={points.map((p) => ({ timestamp: dayAnchor(p.day) }))}
axis="band"
mark="bar"
// The y axis (44) on the left, the margin (12) on the right.
insetLeft={44}
insetRight={12}
+9 -16
View File
@@ -6,12 +6,10 @@ import type { DateKey } from "@/lib/day/contract";
import { prefersReducedMotion } from "@/lib/charts/reduced-motion";
import {
ChartDayCaption,
DayRug,
TooltipDayAction,
useCoarsePointer,
type ChartDayAxis,
type ChartDayMark,
} from "./chart-day";
import { openDay, useOpenDay, type DayFocus } from "./day-layer-controller";
import { isOpenableDay } from "./day-url";
@@ -35,7 +33,7 @@ import { useTodayKey } from "./use-today-key";
* days by accident;
* - the open day is marked with `OPEN_DAY_LINE` (a dashed vertical line)
* at `openIndex`;
* - `ChartDayFooter` draws the row of day dots and the one-line caption.
* - `ChartDayFooter` draws the row of day dots.
*
* The caller says, per drawn point and in data order, which calendar day the
* point stands for, or `null` when it stands for none (a week or month
@@ -190,7 +188,7 @@ export function useChartDayLinks({
}
/**
* The row of day dots and the caption under a day-linked chart. Nothing when
* The row of day dots under a day-linked chart. Nothing when
* the chart is not day-linked or draws no points.
*/
export function ChartDayFooter({
@@ -199,7 +197,6 @@ export function ChartDayFooter({
axis = "index",
insetLeft,
insetRight,
mark = "point",
}: {
links: Pick<ChartDayLinks, "active" | "coarse"> &
Partial<Pick<ChartDayLinks, "days">>;
@@ -208,20 +205,16 @@ export function ChartDayFooter({
axis?: ChartDayAxis;
insetLeft: number;
insetRight: number;
mark?: ChartDayMark;
}) {
if (!links.active || points.length === 0) return null;
return (
<>
<DayRug
points={points}
pointDays={links.days}
axis={axis}
insetLeft={insetLeft}
insetRight={insetRight}
/>
<ChartDayCaption coarse={links.coarse} mark={mark} />
</>
<DayRug
points={points}
pointDays={links.days}
axis={axis}
insetLeft={insetLeft}
insetRight={insetRight}
/>
);
}
-38
View File
@@ -257,41 +257,3 @@ export function DayRug({
</div>
);
}
/**
* What a day-linked surface is made of, which names the thing to click in
* the caption: a point on a line, a bar, or a cell of a calendar.
*/
export type ChartDayMark = "point" | "bar" | "cell";
const HINT_KEYS: Record<ChartDayMark, { fine: string; coarse: string }> = {
point: { fine: "day.chartHint", coarse: "day.chartHintTouch" },
bar: { fine: "day.chartHintBar", coarse: "day.chartHintTouchBar" },
cell: { fine: "day.chartHintCell", coarse: "day.chartHintTouchCell" },
};
/**
* The one line under a day-linked chart: what the dots mean (when the chart
* has the row of dots), and the click.
*/
export function ChartDayCaption({
coarse,
mark = "point",
rug = true,
}: {
coarse: boolean;
mark?: ChartDayMark;
rug?: boolean;
}) {
const { t } = useTranslations();
const hint = HINT_KEYS[mark];
return (
<p
data-slot="chart-day-caption"
className="text-muted-foreground mt-1 flex flex-wrap justify-between gap-x-4 gap-y-1 text-xs"
>
{rug ? <span>{t("day.rugLegend")}</span> : null}
<span>{coarse ? t(hint.coarse) : t(hint.fine)}</span>
</p>
);
}
@@ -606,7 +606,6 @@ export function SleepStageStackedBar({ breakdown }: SleepStageStackedBarProps) {
: 0,
}))}
axis="band"
mark="bar"
// The plot's margin (8) + the y axis (60) on the left, the
// margin (16) on the right.
insetLeft={8 + 60}