mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 14:32:03 +00:00
fix(ui): catalog loading/error truth, info-popover dedupe, touch sweep
Metric catalog page painted every metric as "Not tracked yet" (with Connect CTAs) while its four availability probes were still in flight, and stayed there forever on a failed batch — a load failure indistinguishable from an honest absence. Gate rows on the probes' aggregate loading/error state: row skeletons while loading, a QueryErrorCard with retry on failure. Repoint ComplianceInfoTip onto InfoPopover instead of carrying a verbatim structural copy (adds icon/align/data-slot override props to the shared primitive); migrate the cycle log-sheet's FieldInfo off a hover Tooltip onto the same click-opened InfoPopover, since a hover trigger never opens reliably on the sheet's thumb-first touch surface. Lift ViewToggle/SegmentedToggle off their stale 40px tap floor onto the 44px/36px floor the sibling intake and history-rail controls already carry, and correct the docstrings to match. Restore the dropped safe-area-inset-top term in /coach/conversations' height calc so it matches /coach on notched devices. Bring the coach history rail's off-scale spacing and sub-floor timestamp text onto the standard scale.
This commit is contained in:
1 parent
1d559d7ed0
commit
a977df24a0
14 files changed
+152
-93
No files matched your search
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { Info } from "lucide-react";
|
||||
import { Info, type LucideIcon } from "lucide-react";
|
||||
|
||||
import {
|
||||
Popover,
|
||||
@@ -43,6 +43,18 @@ export interface InfoPopoverProps {
|
||||
*/
|
||||
label?: string;
|
||||
className?: string;
|
||||
/**
|
||||
* Trigger glyph. Defaults to `Info` (h-3.5 w-3.5); the compliance-tip
|
||||
* wrapper passes `HelpCircle` at `h-3 w-3` to keep its pre-merge look.
|
||||
*/
|
||||
icon?: LucideIcon;
|
||||
iconClassName?: string;
|
||||
/** Popover alignment relative to the trigger. Defaults to `"end"`. */
|
||||
align?: "start" | "center" | "end";
|
||||
/** `data-slot` override for the trigger button. */
|
||||
triggerDataSlot?: string;
|
||||
/** `data-slot` override for the popover body. */
|
||||
bodyDataSlot?: string;
|
||||
}
|
||||
|
||||
export function InfoPopover({
|
||||
@@ -50,6 +62,11 @@ export function InfoPopover({
|
||||
link,
|
||||
label,
|
||||
className,
|
||||
icon: Icon = Info,
|
||||
iconClassName = "h-3.5 w-3.5",
|
||||
align = "end",
|
||||
triggerDataSlot = "info-popover-trigger",
|
||||
bodyDataSlot = "info-popover-body",
|
||||
}: InfoPopoverProps) {
|
||||
const { t } = useTranslations();
|
||||
const [open, setOpen] = useState(false);
|
||||
@@ -59,7 +76,7 @@ export function InfoPopover({
|
||||
<PopoverTrigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
data-slot="info-popover-trigger"
|
||||
data-slot={triggerDataSlot}
|
||||
aria-label={label ?? t("common.moreInfo")}
|
||||
aria-expanded={open}
|
||||
className={cn(
|
||||
@@ -70,12 +87,12 @@ export function InfoPopover({
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<Info className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
<Icon className={iconClassName} aria-hidden="true" />
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
data-slot="info-popover-body"
|
||||
align="end"
|
||||
data-slot={bodyDataSlot}
|
||||
align={align}
|
||||
sideOffset={6}
|
||||
className="max-w-xs space-y-1.5"
|
||||
>
|
||||
|
||||
@@ -25,9 +25,10 @@ export interface ViewToggleProps<T extends string> {
|
||||
* two-segment control: the active segment carries the filled surface, the
|
||||
* inactive one stays ghost. `aria-pressed` announces the state per segment;
|
||||
* the group is named for screen readers. Segments keep the 44-px mobile tap
|
||||
* floor (`size-11` via `size-10` + the `sm:size-8` desktop step), shrinking
|
||||
* to the standard 36-px control height on desktop like a neighbouring Add
|
||||
* button.
|
||||
* floor (`size-11`), shrinking to the 36-px control height on desktop
|
||||
* (`sm:size-9`) like a neighbouring Add button — the same floor the intake
|
||||
* kebab and history-rail delete controls raised in this release window
|
||||
* (L3, `.planning/audits/2026-07-18-qa-ui.md`).
|
||||
*
|
||||
* Previously forked between the medications module
|
||||
* (`medications/medication-view-toggle.tsx`) and the Vorsorge/Illness/Labs
|
||||
@@ -62,7 +63,7 @@ export function ViewToggle<T extends string>({
|
||||
title={label}
|
||||
data-slot={`${dataSlotPrefix}-${value}`}
|
||||
className={cn(
|
||||
"focus-visible:ring-ring inline-flex size-10 items-center justify-center rounded-[5px] transition-colors focus-visible:ring-2 focus-visible:outline-none motion-reduce:transition-none sm:size-8",
|
||||
"focus-visible:ring-ring inline-flex size-11 items-center justify-center rounded-[5px] transition-colors focus-visible:ring-2 focus-visible:outline-none motion-reduce:transition-none sm:size-9",
|
||||
active
|
||||
? "bg-secondary text-secondary-foreground shadow-sm"
|
||||
: "text-muted-foreground hover:text-foreground",
|
||||
|
||||
Reference in new issue
Block a user