Web: Kategorie-Auswahlfeld zeigt Oberkategorien der gewaehlten Kategorie

Im geschlossenen Feld stand nur das Blatt (z.B. "Fruechte") - bei mehreren
gleichnamigen Kategorien war unklar, welche gemeint ist. Jetzt steht der volle
Pfad drin, Oberkategorien klein/subtil davor (z.B. "TK -> Fruechte"), das Blatt
normal - ohne das Dropdown oeffnen zu muessen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-07-27 21:38:16 +02:00
parent 10a948df15
commit c28ac7d7dd

View File

@@ -1,6 +1,7 @@
import { useEffect, useLayoutEffect, useRef, useState } from "react"; import { useEffect, useLayoutEffect, useRef, useState } from "react";
import { createPortal } from "react-dom"; import { createPortal } from "react-dom";
import Icon from "./Icon"; import Icon from "./Icon";
import CategoryPathLabel from "./CategoryPathLabel";
/** /**
* Aufklappbarer Kategorie-Baum als Auswahlfeld Ersatz für die früheren, mit * Aufklappbarer Kategorie-Baum als Auswahlfeld Ersatz für die früheren, mit
@@ -39,6 +40,23 @@ export default function CategorySelect({
const selectedId = !isRoot && !extra ? value : null; const selectedId = !isRoot && !extra ? value : null;
const label = isRoot ? rootLabel : extra ? extra.label : nameById[selectedId] ?? rootLabel; const label = isRoot ? rootLabel : extra ? extra.label : nameById[selectedId] ?? rootLabel;
// Voller Pfad der gewählten Kategorie (Oberkategorien → Blatt), damit im
// geschlossenen Feld sichtbar bleibt, WELCHE „Früchte" gemeint sind (z.B.
// „TK → Früchte" statt nur „Früchte").
function pathPartsFor(id) {
const parts = [];
let cur = id;
const gesehen = new Set();
while (cur != null && idset.has(cur) && !gesehen.has(cur)) {
gesehen.add(cur);
parts.unshift(nameById[cur]);
cur = parentById[cur];
}
return parts;
}
const selectedParts = selectedId != null && nameById[selectedId] != null
? pathPartsFor(selectedId) : null;
function place() { function place() {
const r = btnRef.current?.getBoundingClientRect(); const r = btnRef.current?.getBoundingClientRect();
if (r) setPos({ left: r.left, top: r.bottom + 4, width: r.width }); if (r) setPos({ left: r.left, top: r.bottom + 4, width: r.width });
@@ -108,7 +126,9 @@ export default function CategorySelect({
aria-expanded={open} aria-expanded={open}
onClick={() => setOpen((o) => !o)} onClick={() => setOpen((o) => !o)}
> >
<span className={isRoot ? "muted" : ""}>{label}</span> <span className={isRoot ? "muted" : ""}>
{selectedParts ? <CategoryPathLabel parts={selectedParts} /> : label}
</span>
<Icon name="chevronRight" size={13} className={`caret ${open ? "open" : ""}`} /> <Icon name="chevronRight" size={13} className={`caret ${open ? "open" : ""}`} />
</button> </button>