Compare commits
No commits in common. "03579c9d119a1b3b875ebdb8971615d2c10e896a" and "b704a9c378962ff6cdda012f9e69a209079a1a05" have entirely different histories.
03579c9d11
...
b704a9c378
3 changed files with 12 additions and 89 deletions
|
|
@ -5931,37 +5931,7 @@ Rettet til `grid grid-cols-3` (samme mønster som `NumberPicker` allerede
|
|||
brukte). Alle FIRE andre `ChoiceRow`-bruk i filen (Kjønn,
|
||||
Statistikk-nivå × 2) har nøyaktig 3 valg fra før — visuelt uendret for
|
||||
dem, kun 6-alternativs-tilfellet endrer seg. Browserverifisert lys+mørk.
|
||||
Committet (`17e4793`), deployet 2026-08-11 sammen med tagging-runden
|
||||
(se ADR-063).
|
||||
|
||||
**Oppfølging 2026-08-11 — punkt 6 (ScrollFade) hadde TO reelle feil,
|
||||
brukeren rapporterte via skjermbilde av Retning-steget:** "Den
|
||||
sprettende ned-pilen fungerer ikke. Den ligger OPPÅ en annen nedpil."
|
||||
|
||||
1. `ResizeObserver` observerte scroll-BEHOLDEREN (`el`), ikke
|
||||
innholdet. Beholderens boks-størrelse er fast (`flex-1`, bundet av
|
||||
veiviserens layout) og endrer seg ALDRI når man bytter steg —
|
||||
observeren fyrte derfor aldri når et steg med reelt overflow ble
|
||||
vist, og `hasMore` ble stående på sin opprinnelige (ofte `false`)
|
||||
verdi. Hintet virket rett og slett ikke der det trengtes, nøyaktig
|
||||
det brukeren rapporterte. Rettet ved å observere en egen
|
||||
`contentRef`-div rundt `children` i stedet for beholderen selv.
|
||||
2. Fade-/piloverlayet er absolutt posisjonert over de siste 64px av
|
||||
scroll-området uten noen garanti om at ekte innhold ikke havner
|
||||
der. På Retning-steget (med fullt kølle-utvalg satt på testbrukeren
|
||||
for å reprodusere brukerens eksakte rutenett) landet nettopp
|
||||
"Kort"-knappens eget `ArrowDown`-ikon i den sonen — to piler oppå
|
||||
hverandre, akkurat som beskrevet. Rettet med en usynlig 64px-buffer
|
||||
(`SCROLL_FADE_HEIGHT_PX`) etter innholdet; `hasMore`-utregningen
|
||||
trekker fra samme høyde så bufferen selv aldri gir et falskt
|
||||
positivt hint på kort innhold.
|
||||
|
||||
Browserverifisert (samme reproduksjon: full kølle-liste for å tvinge
|
||||
frem overflow): hintet vises korrekt (`opacity: 1`) når steget faktisk
|
||||
overflower, forsvinner korrekt (`opacity: 0`) ved reell bunn, "Kort"
|
||||
fullt synlig og klar av overlay-sonen ved skrolling, lys+mørk, ingen
|
||||
konsollfeil. `tsc --noEmit` rent, 45/45 vitest grønt. Committet
|
||||
(`ee91d03`).
|
||||
Committet (`17e4793`), IKKE deployet ennå i skrivende stund.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
28
CHANGELOG.md
28
CHANGELOG.md
|
|
@ -10505,31 +10505,3 @@ Neste steg:
|
|||
tidligere upubliserte ChoiceRow-fiksen (`17e4793`). Ren omstart,
|
||||
ingen feil i containerloggene, ingen konsollfeil på
|
||||
`https://teecup.golf/logg-inn` etter omstart.
|
||||
|
||||
73. **Fiks: ScrollFade-scrollhintet (fra ADR-062 punkt 6) hadde to
|
||||
reelle feil — 2026-08-11, se oppfølgingsnotatet i ADR-062.**
|
||||
Bruker sendte skjermbilde: "Den sprettende ned-pilen fungerer
|
||||
ikke. Den ligger OPPÅ en annen nedpil."
|
||||
|
||||
To separate rotårsaker i samme `ScrollFade`-komponent
|
||||
(`round-detail.tsx`): (1) `ResizeObserver` observerte scroll-
|
||||
beholderen i stedet for innholdet — beholderens boksstørrelse er
|
||||
fast, så observeren fyrte aldri ved stegbytte i veiviseren, og
|
||||
hintet virket dermed rett og slett ikke på steg med reelt
|
||||
overflow-innhold (som Retning-steget). Rettet ved å observere en
|
||||
egen `contentRef`-div rundt innholdet i stedet for beholderen selv.
|
||||
(2) Fade-/piloverlayet (absolutt posisjonert, siste 64px av
|
||||
scroll-området) hadde ingen garanti mot å dekke ekte innhold —
|
||||
på Retning-steget landet "Kort"-knappens eget `ArrowDown`-ikon i
|
||||
akkurat den sonen, to piler oppå hverandre. Rettet med en usynlig
|
||||
64px-buffer etter innholdet (`hasMore`-utregningen trekker fra
|
||||
samme høyde for å unngå falske positiver på kort innhold).
|
||||
|
||||
**Verifisert:** Full scratch-stack, testbruker med fullt
|
||||
kølle-utvalg for å reprodusere nøyaktig samme rutenett som i
|
||||
brukerens skjermbilde. Bekreftet: hintet vises (`opacity: 1`) når
|
||||
steget faktisk overflower, forsvinner (`opacity: 0`) ved reell
|
||||
bunn, "Kort" fullt synlig og klar av overlay-sonen ved skrolling,
|
||||
lys+mørk, ingen konsollfeil. `tsc --noEmit` rent, 45/45 vitest
|
||||
grønt. `teecup_db` urørt (ren frontend-endring). Committet
|
||||
(`ee91d03`), **ikke rullet ut ennå**.
|
||||
|
|
|
|||
|
|
@ -6577,49 +6577,30 @@ function WizardSection({ title, children }: { title: string; children: React.Rea
|
|||
// finnes mer innhold under fold-linjen -- og skjuler seg av seg selv idet man
|
||||
// har scrollet helt ned. Fanger både resize og innholdsendringer (ulikt
|
||||
// stat_level/par gir ulik høyde) via en ResizeObserver på selve scrollboksen.
|
||||
// Høyden (px) på fade-/piloverlayet under -- MÅ matche spacer-diven sin
|
||||
// h-16 og trekkes fra i hasMore-utregningen, se begrunnelse der.
|
||||
const SCROLL_FADE_HEIGHT_PX = 64
|
||||
|
||||
function ScrollFade({ children, className }: { children: React.ReactNode; className?: string }) {
|
||||
const scrollRef = useRef<HTMLDivElement>(null)
|
||||
const contentRef = useRef<HTMLDivElement>(null)
|
||||
const ref = useRef<HTMLDivElement>(null)
|
||||
const [hasMore, setHasMore] = useState(false)
|
||||
useEffect(() => {
|
||||
const scrollEl = scrollRef.current
|
||||
const contentEl = contentRef.current
|
||||
if (!scrollEl || !contentEl) return
|
||||
const el = ref.current
|
||||
if (!el) return
|
||||
const update = () => {
|
||||
// Trekker fra spacer-divens egen høyde (samme SCROLL_FADE_HEIGHT_PX)
|
||||
// i tillegg til 4px slingring -- uten dette ville "hasMore" blitt
|
||||
// sant utelukkende fordi spaceren selv gjør scrollHeight større, selv
|
||||
// når ALT ekte innhold allerede er synlig (falskt positivt hint).
|
||||
setHasMore(scrollEl.scrollTop + scrollEl.clientHeight < scrollEl.scrollHeight - SCROLL_FADE_HEIGHT_PX - 4)
|
||||
// 4px slingring: unngår at en sub-piksel-rest holder hintet i live
|
||||
// når man i praksis ER nederst.
|
||||
setHasMore(el.scrollTop + el.clientHeight < el.scrollHeight - 4)
|
||||
}
|
||||
update()
|
||||
scrollEl.addEventListener("scroll", update, { passive: true })
|
||||
// Observerer INNHOLDS-diven, IKKE scroll-beholderen selv --
|
||||
// beholderens egen boks-størrelse er fast (flex-1, bundet av
|
||||
// veiviserens layout), den endrer seg ALDRI når man bytter steg. Uten
|
||||
// dette ble "hasMore" aldri regnet på nytt ved stegbytte -- den
|
||||
// sprettende pilen dukket rett og slett ikke opp på steg som faktisk
|
||||
// trengte scrolling (f.eks. "Retning"-steget med kølle-rutenett).
|
||||
el.addEventListener("scroll", update, { passive: true })
|
||||
const ro = new ResizeObserver(update)
|
||||
ro.observe(contentEl)
|
||||
ro.observe(el)
|
||||
return () => {
|
||||
scrollEl.removeEventListener("scroll", update)
|
||||
el.removeEventListener("scroll", update)
|
||||
ro.disconnect()
|
||||
}
|
||||
}, [])
|
||||
return (
|
||||
<div className="relative flex min-h-0 flex-1 flex-col">
|
||||
<div ref={scrollRef} className={className}>
|
||||
<div ref={contentRef}>{children}</div>
|
||||
{/* Usynlig buffer, SAMME høyde som fade-/piloverlayet -- garanterer at
|
||||
overlayet aldri dekker et ekte, interaktivt element (f.eks. en
|
||||
retningsknapp med sin egen pil-ikon nederst i steget). Uten denne
|
||||
kunne den sprettende pilen havne rett oppå en annen pil. */}
|
||||
<div aria-hidden="true" className="h-16 shrink-0" />
|
||||
<div ref={ref} className={className}>
|
||||
{children}
|
||||
</div>
|
||||
{/* Rent dekorativt -- selve scrollingen er fullt mulig uten dette. */}
|
||||
<div
|
||||
|
|
|
|||
Loading…
Reference in a new issue