- Added `SkipLink` component to allow keyboard users to bypass navigation. - Updated `Home`, `About`, and `Contact` pages to include `id="main-content"` target. - Added translation strings for English and German. - Added unit tests for `SkipLink`. - Verified with Playwright. Co-authored-by: ragusa-it <196988693+ragusa-it@users.noreply.github.com>
16 lines
2.0 KiB
Markdown
16 lines
2.0 KiB
Markdown
## 2024-05-24 - Accessible Input Validation
|
|
**Learning:** React 19 renders `aria-invalid={false}` as `aria-invalid="false"`, unlike older versions which might have omitted it. Explicitly handling this in tests is crucial. Also, ensuring DOM cleanup (`cleanup()`) in `afterEach` is vital when testing similar components with same labels across tests to avoid "finding the wrong element" false positives/negatives.
|
|
**Action:** Always include `afterEach(() => cleanup())` in `vitest` setup for DOM tests, and expect `aria-invalid="false"` (or explicitly handle `undefined` if omission is desired) when testing valid states in React 19.
|
|
|
|
## 2024-05-24 - Accessible Loading Buttons
|
|
**Learning:** Replacing button text with a spinner destroys the accessible name.
|
|
**Action:** Use `aria-busy="true"`, keep children in DOM (visually hidden via opacity/class), and overlay spinner absolutely. Ensure wrapper element replicates flex layout (gap/alignment) to prevent layout shifts.
|
|
|
|
## 2024-05-24 - Enhancing Inputs Safely
|
|
**Learning:** Adding features like character counters to generic input components must handle both controlled and uncontrolled states. Assuming a component is controlled (using `props.value`) can break uncontrolled usage by showing stale data (e.g., sticking at 0/100).
|
|
**Action:** When enhancing generic components, detect uncontrolled state (e.g., `props.value === undefined`) and either implement internal state tracking or gracefully degrade (hide the feature) to avoid misleading UX.
|
|
|
|
## 2025-02-23 - Robust Skip Links
|
|
**Learning:** For "Skip to Content" links to work reliably with SPA routers and all browsers, the target element needs `tabIndex={-1}` to be programmatically focusable. Using `transform: translateY(-100%)` for hiding is performant but requires `z-index` management to ensure visibility on focus.
|
|
**Action:** Always add `id="main-content"`, `tabIndex={-1}`, and `outline: 'none'` (to prevent focus ring on container) to the target `<main>` element when implementing skip links.
|