mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 05:42:19 +00:00
The workout, values, score, and medication detail pages each hand-rolled the same ghost Button + Link + ArrowLeft back-nav block. Fold it into a single BackLink (href + label + optional data-slot) so the affordance reads identically — same hit area, icon, and left-bleed alignment — on every page and lives in one place. Each page passes its existing label translation, so no new i18n keys are introduced and the markup stays byte-identical.
48 lines
1.5 KiB
TypeScript
48 lines
1.5 KiB
TypeScript
import Link from "next/link";
|
|
import { ArrowLeft } from "lucide-react";
|
|
|
|
import { Button } from "@/components/ui/button";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
/**
|
|
* v1.16.16 — shared back-navigation control.
|
|
*
|
|
* The detail / sub-page surfaces (`/insights/workouts/[id]`,
|
|
* `/insights/values/[type]`, `/insights/scores/[metric]`,
|
|
* `/medications/[id]`) each hand-rolled the identical
|
|
* `Button(ghost, sm, -ml-2 w-fit) > Link > ArrowLeft + label` block. This
|
|
* folds that into one component so the back-nav reads the same — same hit
|
|
* area, same icon, same left-bleed alignment — on every page, and a future
|
|
* change to the affordance lives in one place.
|
|
*
|
|
* The label travels in from the caller (each page already owns its own
|
|
* translation key, e.g. `insights.workouts.detail.backToList`), so this
|
|
* component adds no new i18n surface.
|
|
*/
|
|
export interface BackLinkProps {
|
|
/** Internal href the back-nav points at. */
|
|
href: string;
|
|
/** Already-translated label text. */
|
|
label: string;
|
|
/** Optional per-surface `data-slot` for e2e/visual targeting. */
|
|
dataSlot?: string;
|
|
className?: string;
|
|
}
|
|
|
|
export function BackLink({ href, label, dataSlot, className }: BackLinkProps) {
|
|
return (
|
|
<Button
|
|
asChild
|
|
variant="ghost"
|
|
size="sm"
|
|
data-slot={dataSlot}
|
|
className={cn("-ml-2 w-fit", className)}
|
|
>
|
|
<Link href={href}>
|
|
<ArrowLeft className="size-4" aria-hidden="true" />
|
|
{label}
|
|
</Link>
|
|
</Button>
|
|
);
|
|
}
|