Tag: React
23 posts
Replacing CSS Class Assertions with ARIA in Storybook
CSS classes break when Tailwind configs change. ARIA attributes are the semantic contract. Six rules for interaction tests that survive refactors.
Client-Side Tag Filtering Without Losing SEO URLs
One component renders Link for crawlable tag pages or button for instant client filtering. The same TagChipStrip serves both without duplicating code.
Correlating a Multi-Step Funnel with One sessionStorage ID
A timestamp and random suffix in sessionStorage ties scan, completion, email capture, and calendar booking into one GA4 funnel with zero backend state.
Upgrading cmdk Search with MiniSearch Field Boosting
cmdk does substring matching. Keeping its UI shell and swapping the filter engine for MiniSearch gives ranked, fuzzy results with match highlighting.
Cycling Theme Toggle: From Radio Group to Single Button
Replacing a three-button theme picker with a single cycling button and a keyboard shortcut reclaims nav space without losing discoverability.
Site Search Without a Server: Static Index and cmdk
A build-time search index and cmdk power Cmd+K search across 47 pages with zero API calls.
An 8-Second Timeout for Third-Party Iframes
An iframe that never loads looks like a broken page. An 8-second timeout and a direct booking link keep users moving instead of staring.
Tooltip aria-describedby Was on the Wrong Element
A Tooltip component passed every test but put aria-describedby on a wrapper div instead of the trigger. Screen readers never announced it.
Aligning Five Form Components Around aria-describedby
Five form components, five approaches to displaying errors. One aria-describedby pattern turns inconsistency into a shared accessibility contract.
Standardizing a Component Size Scale
A design system with five avatar sizes, no badge size, and three spinner sizes is a design system arguing with itself.
Mobile Nav Accessibility: The Bottom Sheet Dialog Pattern
A nav redesign passes code review but fails E2E tests on mobile. Here's what axe caught and how aria-hidden, inert, and proper dialog semantics fixed it.
Fixing Hydration Mismatches Without Suppressing Them
A three-line useSyncExternalStore hook helps server and client renders agree, no more suppressHydrationWarning.
Graceful Degradation for Third-Party Embeds
Adding a timeout-based fallback when a Calendly iframe gets blocked by ad blockers or network issues.
Z-Index Choreography for a Mobile Bottom Nav
The z-index choreography behind adding a fixed bottom bar without breaking scroll-to-top, table-of-contents, and bottom sheet overlays.
Making Data Tables Keyboard-Navigable
Adding scope, caption, clickable row keyboard support, and focus-visible to a Table component. The accessibility basics HTML tables need but rarely get.
Pause-on-Hover: Making Toast Notifications Respect the User
Adding aria-live regions and pause-on-hover to a Toast system. Screen readers and sighted users have conflicting timing needs.
Building an Accessible Dropdown Without a Library
Full ARIA menu semantics and keyboard navigation in ~150 lines of React, no Radix, no Headless UI, just the spec.
The Rule of Three in Design Systems
When to extract a repeated pattern into a shared abstraction, and when to leave it inline. A framework from auditing portfolio typography.
Removing focus-trap-react: Native Focus Management in Modals
Replacing a 15KB focus-trap dependency with native dialog behavior and manual focus management drops bundle size and simplifies the shared-ui library.
Building a Typography System for a Next.js Design System
Auditing three competing heading systems and consolidating them into a variant-based Heading/Text API that serves as a single typography source of truth.
Composing React Providers Without the Nesting Nightmare
A functional composition pattern that turns deeply nested provider trees into a flat, readable list. Includes automatic React DevTools display names.
From Wrapper Hell to One Source of Truth
Promoting kit wrappers into a shared-ui library with typography variants and layout primitives eliminates 2,000 lines of duplication.
Building an Auto-Generated Table of Contents with Scroll Spy
Extracting headings from rendered MDX, tracking reading position with IntersectionObserver, and adapting between a sticky sidebar and a mobile bottom sheet.