From c0f57a871d73e5abb35c4c0f12cee79e5d4c6d3b Mon Sep 17 00:00:00 2001 From: Clemens Beese Date: Mon, 14 Sep 2026 17:26:47 +0200 Subject: [PATCH] =?UTF-8?q?SearchField=20ut=20av=20sidebar=20&=20sidebar?= =?UTF-8?q?=20er=20n=C3=A5=20sticky?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/SearchField.css | 30 +++++++++++++++++++++++++++ src/components/SearchField.tsx | 32 +++++++++++++++++++++++++++++ src/components/sidebar.css | 37 +++++++++------------------------- src/components/sidebar.tsx | 19 ++++------------- 4 files changed, 76 insertions(+), 42 deletions(-) create mode 100644 src/components/SearchField.css create mode 100644 src/components/SearchField.tsx diff --git a/src/components/SearchField.css b/src/components/SearchField.css new file mode 100644 index 0000000..74a72b7 --- /dev/null +++ b/src/components/SearchField.css @@ -0,0 +1,30 @@ +/* Skiller søkefeltet fra lenkene under. + padding-bottom er luft over streken, margin-bottom er luft under den. */ +.search-field { + padding-bottom: 24px; + margin-bottom: 24px; + border-bottom: 1px solid var(--border); +} + +.search-field input { + width: 100%; + font-size: 18px; + padding: 8px 12px; + box-sizing: border-box; /* padding regnes inn i bredden, så feltet ikke blir bredere enn sidebaren */ + border-radius: 10px; /* samme runding som filmkortene */ + border: 1px solid var(--border); +} + +/* Skjuler elementet visuelt uten å fjerne det fra DOM-en, + slik at skjermlesere fortsatt leser opp teksten (labelen over). */ +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} \ No newline at end of file diff --git a/src/components/SearchField.tsx b/src/components/SearchField.tsx new file mode 100644 index 0000000..e125767 --- /dev/null +++ b/src/components/SearchField.tsx @@ -0,0 +1,32 @@ +import './SearchField.css'; + +// value og onChange heter det samme som på et vanlig , med vilje: +// da leser som HTML folk kan fra før. +type SearchFieldProps = { + value: string; + onChange: (value: string) => void; +}; + +// Komponenten har ingen egen state. Teksten kommer inn som prop og sendes ut igjen +// via onChange - den som bruker komponenten (App) eier verdien. Det kalles et +// "kontrollert" felt, og er grunnen til at søket kan tømmes utenfra når man +// klikker på en lenke i sidebaren. +export function SearchField({ value, onChange }: SearchFieldProps) { + return ( +
+ {/* htmlFor må matche input-ens id. Det er koblingen som gjør at skjermlesere + vet hva feltet er til for, og at man kan klikke på labelen for å fokusere feltet. */} + + onChange(e.target.value)} + /> +
+ ); +} \ No newline at end of file diff --git a/src/components/sidebar.css b/src/components/sidebar.css index 7660d3d..9e17632 100644 --- a/src/components/sidebar.css +++ b/src/components/sidebar.css @@ -1,19 +1,3 @@ - - -/* Skjuler elementet visuelt uten å fjerne det fra DOM-en, - slik at skjermlesere fortsatt leser opp teksten (f.eks. labelen over). */ -.visually-hidden { - position: absolute; /* tar det ut av normal layout-flyt */ - width: 1px; - height: 1px; /* krymper det til nesten ingenting */ - padding: 0; - margin: -1px; /* trikser bort avrundingsproblemer i noen nettlesere */ - overflow: hidden; /* skjuler alt innhold som stikker utenfor 1x1px */ - clip: rect(0, 0, 0, 0); /* eldre metode for å "klippe bort" innholdet visuelt */ - white-space: nowrap; /* hindrer teksten fra å brekke og bli synlig */ - border: 0; -} - /* Gjør at #-lenker (som href="#populaere") scroller mykt i stedet for å hoppe brått. */ html { scroll-behavior: smooth; @@ -22,17 +6,16 @@ html { .sidebar { text-align: left; flex: 1 1 0; /* 2 del av 4 = 1/4 av siden */ -} - -.sidebar-search { - margin-bottom: 28px; /* luft mellom søkefelt og lenkene */ -} - -.sidebar-search input { - width: 100%; - font-size: 18px; - padding: 8px 12px; - box-sizing: border-box; + position: sticky; /*betyr at elementet oppfører seg helt normalt helt til man scroller forbi "top" grensen som man også setter */ + top: 24px; + /* + Tips fra claude her: + når dere gjør siden responsiv er overflow-x: hidden på body eller #root + et vanlig triks mot horisontal scroll, og det dreper sticky umiddelbart uten noen feilmelding. + Hvis sidebaren blir høyere enn skjermen (flere lenker, eller favoritter listet i sidebaren senere), + legg til max-height: 100vh; og overflow-y: auto; i samme regel. Da får sidebaren sin egen scroll i + stedet for at bunnen blir utilgjengelig. + */ } .sidebar-nav { diff --git a/src/components/sidebar.tsx b/src/components/sidebar.tsx index a2a3cf3..90b6ca1 100644 --- a/src/components/sidebar.tsx +++ b/src/components/sidebar.tsx @@ -1,5 +1,5 @@ import './sidebar.css'; - +import { SearchField } from './SearchField'; type SidebarProps = { onSearch?: (query: string) => void; @@ -18,18 +18,8 @@ export function Sidebar({onSearch, searchValue}: SidebarProps) { ); -} - +} \ No newline at end of file