From e14d9d5042aff9191d2e382464d7085c5528a7a9 Mon Sep 17 00:00:00 2001 From: Dogfather Date: Mon, 31 Aug 2026 12:14:18 +0200 Subject: [PATCH] Wissen: Kategoriewahl und Filter ohne Systemmenue Filipe: "wieso sieht das so scheisse aus?" -- zum aufgeklappten Auswahlmenue der Kategorie. Er hat recht, und die Ursache ist dieselbe wie bei der Rollenwahl: Ein AUFGEKLAPPTES . Der Grund ist derselbe wie bei der + Rollenwahl: Ein AUFGEKLAPPTES Systemmenue laesst sich nicht + gestalten -- es kam als weisses Windows-Menue mitten in der dunklen + Oberflaeche. Bei zwanzig Kategorien kam dazu, dass man in so einer + Liste nichts findet. + + Hier stehen dieselben sechs Welten und dieselben Farben wie auf den + Kacheln der Seite: Man waehlt aus demselben Regal, in dem man sonst + stoebert. + =================================================================== */ + +.katwahl { display: grid; gap: 14px; margin-top: 4px; } + +.katwahl__welt { --w: var(--akzent); } +.katwahl__welt[data-welt="tiktok"] { --w: #3fbdf5; } +.katwahl__welt[data-welt="aufbau"] { --w: #8a76ff; } +.katwahl__welt[data-welt="bildton"] { --w: #5fc99a; } +.katwahl__welt[data-welt="technik"] { --w: #e8b877; } +.katwahl__welt[data-welt="inhalt"] { --w: #e88fb4; } +.katwahl__welt[data-welt="hilfe"] { --w: #8e9cb0; } + +.katwahl__weltname { + margin: 0 0 6px; font-size: .7rem; font-weight: 700; + letter-spacing: .08em; text-transform: uppercase; + color: color-mix(in srgb, var(--w) 55%, #ffffff); +} +.katwahl__reihe { display: flex; gap: 6px; flex-wrap: wrap; } + +.katwahl__knopf { + display: inline-flex; align-items: center; gap: 8px; + padding: 8px 13px; cursor: pointer; text-align: left; + background: linear-gradient(#1a2230, #151c28); + border: 1px solid var(--rand); border-radius: 10px; + color: var(--text-leise); font: inherit; font-size: .83rem; + transition: border-color .16s ease, background .16s ease, color .16s ease; +} +.katwahl__knopf:hover { color: var(--text); border-color: color-mix(in srgb, var(--w) 45%, transparent); } +.katwahl__knopf:focus-visible { + outline: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--w) 32%, transparent); +} +.katwahl__knopf[data-an="ja"] { + color: #fff; font-weight: 600; + border-color: color-mix(in srgb, var(--w) 65%, transparent); + background: linear-gradient(color-mix(in srgb, var(--w) 20%, #1a2230), + color-mix(in srgb, var(--w) 11%, #151c28)); + box-shadow: 0 4px 14px -9px var(--w); +} +.katwahl__symbol { + width: 17px; height: 17px; flex: none; + fill: none; stroke: var(--w); stroke-width: 1.7; + stroke-linecap: round; stroke-linejoin: round; +} +.katwahl__name { white-space: nowrap; } + +/* ---------- Filterschalter ------------------------------------------------ */ + +.filterreihe { display: inline-flex; gap: 4px; } +.filterreihe__knopf { + padding: 7px 12px; cursor: pointer; + background: rgba(255, 255, 255, .04); + border: 1px solid var(--rand); border-radius: 8px; + color: var(--text-still); font: inherit; font-size: .82rem; + transition: color .16s ease, border-color .16s ease, background .16s ease; +} +.filterreihe__knopf:hover { color: var(--text); border-color: rgba(255, 255, 255, .22); } +.filterreihe__knopf[data-an="ja"] { + color: #fff; font-weight: 600; + border-color: rgba(63, 189, 245, .55); + background: rgba(63, 189, 245, .16); +} +.filterreihe__knopf:focus-visible { + outline: none; box-shadow: 0 0 0 3px rgba(63, 189, 245, .3); +} + +@media (max-width: 620px) { + .katwahl__knopf { flex: 1 1 100%; } + .filterreihe { flex-wrap: wrap; } +} +@media (prefers-reduced-motion: reduce) { + .katwahl__knopf, .filterreihe__knopf { transition: none; } +} diff --git a/workspace/assets/js/wissen.js b/workspace/assets/js/wissen.js index 86b61c8d..2b730f88 100644 --- a/workspace/assets/js/wissen.js +++ b/workspace/assets/js/wissen.js @@ -284,28 +284,44 @@ let filterGefuellt = false; function fuelleFilter() { const z = zustand(); - const setz = (id, eintraege, wert) => { + /* Stufe und Geraet als Schalterreihe: zwei bis vier Werte, die sich + nie aendern -- dafuer ein Auswahlmenue zu oeffnen ist ein Klick zu + viel, und aufgeklappt liesse es sich ohnehin nicht gestalten. */ + const reihe = (id, eintraege, wert, feldname) => { const f = $(id); f.textContent = ''; - const alle = document.createElement('option'); - alle.value = ''; alle.textContent = 'Alle'; - f.append(alle); - for (const [w, name] of eintraege) { - const o = document.createElement('option'); - o.value = w; o.textContent = name; - f.append(o); + for (const [w, name] of [['', 'Alle'], ...eintraege]) { + const b = el('button', 'filterreihe__knopf', name); + b.type = 'button'; + b.setAttribute('role', 'radio'); + const an = (wert || '') === w; + b.setAttribute('aria-checked', an ? 'true' : 'false'); + if (an) b.dataset.an = 'ja'; + if (w) b.dataset.wert = w; + b.addEventListener('click', () => setzeZustand({ [feldname]: w })); + f.append(b); } - f.value = wert || ''; }; - setz('f-stufe', Object.entries(aufbau.stufen), z.stufe); - setz('f-geraet', [['pc', 'PC'], ['handy', 'Handy']], z.geraet); - setz('f-tag', aufbau.tags.map((t) => [t, '#' + t]), z.tag); + reihe('f-stufe', Object.entries(aufbau.stufen), z.stufe, 'stufe'); + reihe('f-geraet', [['pc', 'PC'], ['handy', 'Handy']], z.geraet, 'geraet'); + + /* Die Tags wachsen mit dem Bestand -- dafuer bleibt ein Auswahlfeld + richtig, eine Schalterreihe waere irgendwann zwei Zeilen lang. */ + const f = $('f-tag'); + f.textContent = ''; + const alle = document.createElement('option'); + alle.value = ''; alle.textContent = 'Alle'; + f.append(alle); + for (const tg of aufbau.tags) { + const o = document.createElement('option'); + o.value = tg; o.textContent = '#' + tg; + f.append(o); + } + f.value = z.tag || ''; $('q').value = z.q; if (filterGefuellt) return; filterGefuellt = true; - $('f-stufe').addEventListener('change', () => setzeZustand({ stufe: $('f-stufe').value })); - $('f-geraet').addEventListener('change', () => setzeZustand({ geraet: $('f-geraet').value })); $('f-tag').addEventListener('change', () => setzeZustand({ tag: $('f-tag').value })); $('f-weg').addEventListener('click', () => setzeZustand({ k: '', q: '', stufe: '', geraet: '', tag: '' })); let warte = null; @@ -317,6 +333,24 @@ window.addEventListener('popstate', laden_); + /* ---------- Kategoriewahl ------------------------------------------------ */ + + function setzeKategorie(schluessel) { + for (const b of document.querySelectorAll('.katwahl__knopf')) { + const an = b.dataset.kategorie === schluessel; + if (an) b.dataset.an = 'ja'; else delete b.dataset.an; + b.setAttribute('aria-checked', an ? 'true' : 'false'); + } + const hinweis = $('n-kat-hinweis'); + if (hinweis) { + const k = aufbau?.kategorien.find((x) => x.schluessel === schluessel); + hinweis.textContent = k ? k.beschreibung : 'Noch keine Kategorie gewählt.'; + } + } + + const gewaehlteKategorie = () => + document.querySelector('.katwahl__knopf[data-an="ja"]')?.dataset.kategorie || ''; + /* ---------- Formular ------------------------------------------------------ */ function formularOeffnen(eintrag) { @@ -335,7 +369,7 @@ nicht bewusst aendert, merkt es nicht. Vorbelegt wird nur, wenn man aus EINER Kategorie heraus hochlaedt -- dann ist es eine informierte Annahme, keine geratene. */ - $('n-kategorie').value = eintrag ? eintrag.kategorie : (zustand().k || ''); + setzeKategorie(eintrag ? eintrag.kategorie : (zustand().k || '')); $('n-stufe').value = eintrag ? eintrag.stufe : 'einsteiger'; $('n-geraet').value = eintrag ? eintrag.geraet : 'egal'; $('n-tags').value = eintrag ? eintrag.tags.join(', ') : ''; @@ -366,25 +400,32 @@ f.append(o); } }; - /* Nach Welten gruppiert -- dieselbe Gliederung wie auf der Seite. - Zwanzig Eintraege in einer flachen Liste findet man nicht. */ + /* Nach Welten gruppiert -- dieselbe Gliederung und dieselben Farben + wie die Kacheln auf der Seite. Man waehlt aus demselben Regal, in + dem man sonst stoebert. */ const kf = $('n-kategorie'); kf.textContent = ''; - const platzhalter = document.createElement('option'); - platzhalter.value = ''; - platzhalter.textContent = '— Kategorie wählen —'; - platzhalter.disabled = true; - kf.append(platzhalter); for (const welt of aufbau.welten) { - const gruppe = document.createElement('optgroup'); - gruppe.label = welt.name; - for (const k of aufbau.kategorien.filter((x) => x.welt === welt.schluessel)) { - const o = document.createElement('option'); - o.value = k.schluessel; - o.textContent = k.name; - gruppe.append(o); + const kats = aufbau.kategorien.filter((x) => x.welt === welt.schluessel); + if (!kats.length) continue; + const gruppe = el('div', 'katwahl__welt'); + gruppe.dataset.welt = welt.schluessel; + gruppe.append(el('p', 'katwahl__weltname', welt.name)); + const reihe = el('div', 'katwahl__reihe'); + for (const k of kats) { + const b = el('button', 'katwahl__knopf'); + b.type = 'button'; + b.dataset.kategorie = k.schluessel; + b.setAttribute('role', 'radio'); + b.setAttribute('aria-checked', 'false'); + b.title = k.beschreibung; + b.append(symbol(k.symbol, 'katwahl__symbol')); + b.append(el('span', 'katwahl__name', k.name)); + b.addEventListener('click', () => setzeKategorie(k.schluessel)); + reihe.append(b); } - if (gruppe.children.length) kf.append(gruppe); + gruppe.append(reihe); + kf.append(gruppe); } setz('n-stufe', Object.entries(aufbau.stufen)); setz('n-geraet', Object.entries(aufbau.geraete)); @@ -466,7 +507,7 @@ const angaben = { titel: $('n-titel').value.trim(), beschreibung: $('n-beschreibung').value.trim(), - kategorie: $('n-kategorie').value, + kategorie: gewaehlteKategorie(), stufe: $('n-stufe').value, geraet: $('n-geraet').value, tags: $('n-tags').value, @@ -476,7 +517,8 @@ if (angaben.titel.length < 3) { $('n-fehler').textContent = 'Der Titel fehlt.'; return; } if (!angaben.kategorie) { $('n-fehler').textContent = 'Wähle die Kategorie aus, in der die Anleitung stehen soll.'; - $('n-kategorie').focus(); + $('n-kategorie').scrollIntoView({ block: 'center', behavior: 'smooth' }); + $('n-kategorie').querySelector('.katwahl__knopf')?.focus(); return; } diff --git a/workspace/aufgaben.html b/workspace/aufgaben.html index 6df1696a..a9524b79 100644 --- a/workspace/aufgaben.html +++ b/workspace/aufgaben.html @@ -7,9 +7,9 @@ - - - + + + @@ -134,7 +134,7 @@ - - + + diff --git a/workspace/bereich.html b/workspace/bereich.html index 84ba228e..d4ca697f 100644 --- a/workspace/bereich.html +++ b/workspace/bereich.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -98,7 +98,7 @@ - - + + diff --git a/workspace/calls.html b/workspace/calls.html index 49ca3a2f..3fe73390 100644 --- a/workspace/calls.html +++ b/workspace/calls.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -49,8 +49,8 @@ - - - + + + diff --git a/workspace/dateien.html b/workspace/dateien.html index 07995d1c..c577b777 100644 --- a/workspace/dateien.html +++ b/workspace/dateien.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -88,7 +88,7 @@ - - + + diff --git a/workspace/index.html b/workspace/index.html index e96c66eb..427b5021 100644 --- a/workspace/index.html +++ b/workspace/index.html @@ -25,7 +25,7 @@ type="image/webp" media="(max-width: 899px)" /> - + @@ -143,6 +143,6 @@

- + diff --git a/workspace/kalender.html b/workspace/kalender.html index e6539b9b..401584cf 100644 --- a/workspace/kalender.html +++ b/workspace/kalender.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -94,7 +94,7 @@ - - + + diff --git a/workspace/personen.html b/workspace/personen.html index e535041f..01edc1bf 100644 --- a/workspace/personen.html +++ b/workspace/personen.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -93,7 +93,7 @@ - - + + diff --git a/workspace/profil.html b/workspace/profil.html index 7954e238..7f88fd60 100644 --- a/workspace/profil.html +++ b/workspace/profil.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -127,7 +127,7 @@ - - + + diff --git a/workspace/report.html b/workspace/report.html index 13b1c322..18322137 100644 --- a/workspace/report.html +++ b/workspace/report.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -86,8 +86,8 @@ - - - + + + diff --git a/workspace/scouting.html b/workspace/scouting.html index 3089af1b..12864fc1 100644 --- a/workspace/scouting.html +++ b/workspace/scouting.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -124,7 +124,7 @@ - - + + diff --git a/workspace/start.html b/workspace/start.html index 87d42d58..a1160587 100644 --- a/workspace/start.html +++ b/workspace/start.html @@ -7,8 +7,8 @@ - - + + @@ -56,7 +56,7 @@

- - + + diff --git a/workspace/startcheck.html b/workspace/startcheck.html index ab5d3143..c774b44a 100644 --- a/workspace/startcheck.html +++ b/workspace/startcheck.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -65,8 +65,8 @@ - - - + + + diff --git a/workspace/wissen.html b/workspace/wissen.html index 9dc9ec2b..26cb7284 100644 --- a/workspace/wissen.html +++ b/workspace/wissen.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -79,10 +79,10 @@
- - - - + Stufe +
+ Gerät +
@@ -119,8 +119,13 @@
- - + Hauptkategorie + +
+

Noch keine Kategorie gewählt.

@@ -165,7 +170,7 @@ - - + +