| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- "use client";
- import React from "react";
- import { useRouter } from "next/navigation";
- import { Check, ChevronDown } from "lucide-react";
- import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuLabel,
- DropdownMenuSeparator,
- DropdownMenuTrigger,
- } from "@/components/ui/dropdown-menu";
- /**
- * SegmentDropdown
- *
- * A small dropdown trigger used next to breadcrumb segments to switch between
- * existing years/months/days.
- *
- * IMPORTANT:
- * - This component MUST be declared at module scope (not inside another component render),
- * otherwise React will treat it as a new component type on each render and warn/error.
- *
- * UX rule:
- * - All visible text is provided by the parent in German.
- *
- * @param {{
- * items: Array<{ value: string, label: string, href: string }>,
- * currentValue: string|null,
- * menuLabel: string,
- * triggerAriaLabel: string
- * }} props
- */
- export default function SegmentDropdown({
- items,
- currentValue,
- menuLabel,
- triggerAriaLabel,
- }) {
- const router = useRouter();
- if (!Array.isArray(items) || items.length === 0) return null;
- return (
- <DropdownMenu>
- <DropdownMenuTrigger asChild>
- <button
- type="button"
- className="ml-1 inline-flex h-7 w-7 items-center justify-center rounded-md border bg-background text-muted-foreground shadow-xs hover:bg-accent hover:text-foreground focus:outline-none focus:ring-2 focus:ring-ring/50"
- aria-label={triggerAriaLabel}
- title={triggerAriaLabel}
- >
- <ChevronDown className="h-4 w-4" aria-hidden="true" />
- </button>
- </DropdownMenuTrigger>
- <DropdownMenuContent align="start" className="max-h-72 overflow-auto">
- <DropdownMenuLabel>{menuLabel}</DropdownMenuLabel>
- <DropdownMenuSeparator />
- {items.map((it) => {
- const isActive =
- currentValue && String(it.value) === String(currentValue);
- return (
- <DropdownMenuItem
- key={it.href}
- className="cursor-pointer"
- onSelect={(e) => {
- // Radix fires onSelect for click + keyboard. Prevent default for consistent behavior.
- e.preventDefault();
- router.push(it.href);
- }}
- >
- <span className="flex items-center gap-2">
- {isActive ? (
- <Check className="h-4 w-4" aria-hidden="true" />
- ) : (
- <span className="h-4 w-4" aria-hidden="true" />
- )}
- <span>{it.label}</span>
- </span>
- </DropdownMenuItem>
- );
- })}
- </DropdownMenuContent>
- </DropdownMenu>
- );
- }
|