Drei Auswahlfelder liessen sich gleichzeitig aufklappen
Jedes merkte sich nur seine eigene Liste. Nebeneinander geöffnet lagen sie übereinander, und keine wusste von den anderen. Ein Auswahlfeld ist ein Menü, und von denen ist höchstens eines offen — jetzt modulweit vermerkt, genau wie beim Kontextmenü. Escape schliesst zusätzlich von überall, nicht nur mit dem Fokus in der Liste. Dazu stand unter jeder Mediathek „0 Titel freigeben". Der Knopf wurde über `hidden` versteckt — das Attribut wirkt über `display: none` mit der Spezifität von Null, und `.btn` setzt `display: inline-flex`. Die Klasse `.hidden` trägt ein `!important` und setzt sich durch. Und das Favicon kommt jetzt aus `icon.png`, dem gerenderten App-Icon selbst. Meine nachgezeichnete Fassung war falsch: die Grafik füllt die Fläche, statt klein in der Mitte zu sitzen. Ein Icon, das dem echten nur ähnelt, driftet beim nächsten Entwurf wieder auseinander. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
8809b9f46f
commit
4b0323f955
+25
-1
@@ -28,6 +28,20 @@ export type Auswahlfeld = {
|
||||
setzen: (optionen: Option[]) => void;
|
||||
};
|
||||
|
||||
/** Das eine offene Auswahlfeld — oder keines.
|
||||
*
|
||||
* **Modulweit, nicht je Feld.** Vorher merkte sich jedes Feld nur seine
|
||||
* eigene Liste; drei Felder nebeneinander liessen sich alle drei aufklappen
|
||||
* und überlagerten einander. Ein Auswahlfeld ist ein Menü, und von denen ist
|
||||
* immer höchstens eines offen — genauso hält es das Kontextmenü.
|
||||
*/
|
||||
let offenesFeld: { schliessen: () => void } | null = null;
|
||||
|
||||
export function alleAuswahlenSchliessen(): void {
|
||||
offenesFeld?.schliessen();
|
||||
offenesFeld = null;
|
||||
}
|
||||
|
||||
export function auswahl(optionen: Option[], vorgabe = ''): Auswahlfeld {
|
||||
let liste = [...optionen];
|
||||
let wert = vorgabe;
|
||||
@@ -56,8 +70,11 @@ export function auswahl(optionen: Option[], vorgabe = ''): Auswahlfeld {
|
||||
offen?.remove();
|
||||
offen = null;
|
||||
knopf.setAttribute('aria-expanded', 'false');
|
||||
if (offenesFeld === steuerung) offenesFeld = null;
|
||||
}
|
||||
|
||||
const steuerung = { schliessen };
|
||||
|
||||
function waehlen(neu: string): void {
|
||||
const geaendert = neu !== wert;
|
||||
wert = neu;
|
||||
@@ -70,6 +87,10 @@ export function auswahl(optionen: Option[], vorgabe = ''): Auswahlfeld {
|
||||
function oeffnen(): void {
|
||||
if (offen) { schliessen(); return; }
|
||||
|
||||
// Erst das andere zu, dann dieses auf.
|
||||
alleAuswahlenSchliessen();
|
||||
offenesFeld = steuerung;
|
||||
|
||||
const box = document.createElement('div');
|
||||
box.className = 'auswahl-liste';
|
||||
box.setAttribute('role', 'listbox');
|
||||
@@ -172,8 +193,11 @@ export function auswahl(optionen: Option[], vorgabe = ''): Auswahlfeld {
|
||||
// Kontextmenü. Je Feld registriert und nicht global: es gibt wenige davon,
|
||||
// und beim Entfernen des Feldes gehen sie mit.
|
||||
document.addEventListener('click', e => {
|
||||
if (offen && !offen.contains(e.target as Node) && e.target !== knopf) schliessen();
|
||||
if (offen && !offen.contains(e.target as Node) && !knopf.contains(e.target as Node)) {
|
||||
schliessen();
|
||||
}
|
||||
});
|
||||
document.addEventListener('keydown', e => { if (e.key === 'Escape' && offen) schliessen(); });
|
||||
window.addEventListener('scroll', () => schliessen(), { passive: true, capture: true });
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user