feat: enhance typography and accessibility in design system

- Added new UI heading utility with specific styles in typography.css.
- Updated typography tests to include new UI heading role and ensure proper size and styling.
- Documented design system audit findings, focusing on accessibility improvements and component consistency.
- Introduced CalendarExamples component to demonstrate calendar functionality with habit tracking.
- Created a shared Field component for consistent labeling and hinting of form controls.
- Implemented comprehensive accessibility tests for calendar and editor components, ensuring proper focus management and keyboard navigation.
- Added structure tests for Field and Card components to verify correct ID generation and heading levels.
This commit is contained in:
syntaxbullet
2026-09-04 13:44:31 +02:00
parent bfa54851c2
commit dde5e77317
19 changed files with 1077 additions and 681 deletions

View File

@@ -1,4 +1,4 @@
import { useRef, type ReactNode } from "react";
import { useEffect, useRef, type ReactNode } from "react";
import { useLocation, useNavigate } from "react-router";
type SystemTab = { id: string; label: string; content: ReactNode };
@@ -7,7 +7,13 @@ export function DesignSystemTabs({ tabs }: { tabs: SystemTab[] }) {
const { hash } = useLocation();
const navigate = useNavigate();
const buttons = useRef<Array<HTMLButtonElement | null>>([]);
const selected = tabs.findIndex((tab) => hash === `#${tab.id}`);
// Keep bookmarks for retired preview sections useful without mounting them.
const replacementHash = hash === "#playground" ? "#calendar-states"
: hash === "#editing" || hash === "#views" ? "#foundations" : hash;
useEffect(() => {
if (replacementHash !== hash) navigate({ hash: replacementHash }, { replace: true });
}, [hash, replacementHash, navigate]);
const selected = tabs.findIndex((tab) => replacementHash === `#${tab.id}`);
const active = selected < 0 ? 0 : selected;
function select(index: number) {
@@ -44,7 +50,7 @@ export function DesignSystemTabs({ tabs }: { tabs: SystemTab[] }) {
</button>
))}
</div>
{/* Keep panels mounted so editors and examples retain their local state. */}
{/* Keep panels mounted so examples retain their local state. */}
{tabs.map((tab, index) => (
<div
key={tab.id}