refactor(ui): unify low-level controls and expand design system
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 2m57s

This commit is contained in:
2026-03-03 15:50:15 +01:00
parent 9a43980412
commit db7a0cef96
47 changed files with 1404 additions and 711 deletions

View File

@@ -0,0 +1,52 @@
'use client';
import { ReactNode, useId, useState } from 'react';
interface DisclosureProps {
title: ReactNode;
subtitle?: ReactNode;
defaultOpen?: boolean;
className?: string;
children: ReactNode;
}
export function Disclosure({
title,
subtitle,
defaultOpen = false,
className = '',
children,
}: DisclosureProps) {
const [isOpen, setIsOpen] = useState(defaultOpen);
const contentId = useId();
return (
<div className={`rounded-lg border border-border bg-card-hover ${className}`}>
<button
type="button"
onClick={() => setIsOpen((prev) => !prev)}
aria-expanded={isOpen}
aria-controls={contentId}
className="flex w-full items-center justify-between px-4 py-2.5 text-left transition-colors hover:bg-card"
>
<div className="min-w-0">
<div className="text-sm font-semibold text-foreground">{title}</div>
{subtitle && <div className="text-xs text-muted">{subtitle}</div>}
</div>
<svg
className={`h-4 w-4 shrink-0 text-muted transition-transform ${isOpen ? 'rotate-180' : ''}`}
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</button>
{isOpen && (
<div id={contentId} className="border-t border-border px-4 py-3">
{children}
</div>
)}
</div>
);
}