Code Explainers

Code explainers tagged #accessibility

typescript
import { Component, HostBinding, Input } from '@angular/core';
 
type ProgressVariant = 'success' | 'warning' | 'danger';
 

A CSS-driven progress ring in Angular

host-bindings css-custom-properties input-setters
Intermediate 8 steps
typescript
import { Component } from '@angular/core';
import { RouterLink, RouterLinkActive } from '@angular/router';
import { NgFor } from '@angular/common';
 

Building an active-route navbar in Angular

routing standalone-components accessibility
Intermediate 6 steps
javascript
const FOCUSABLE = [
  'a[href]',
  'button:not([disabled])',
  'input:not([disabled])',

How to trap keyboard focus in a dialog

accessibility dom event-handling
Intermediate 8 steps
javascript
function initCharacterCounter(textarea, options = {}) {
  const maxLength = options.maxLength ?? 280;
  const warnThreshold = options.warnThreshold ?? 0.9;
 

A live character counter for textareas

dom closures accessibility
Intermediate 7 steps
javascript
const zxcvbn = require('zxcvbn');
 
const STRENGTH_LABELS = ['Very weak', 'Weak', 'Fair', 'Strong', 'Very strong'];
const STRENGTH_COLORS = ['#d64545', '#e0803c', '#d9c94c', '#5aa84f', '#2f8f3a'];

Building a live password strength meter

debounce closures dom-events
Intermediate 8 steps
typescript
type RGB = { r: number; g: number; b: number };
 
type WCAGLevel = "AA" | "AAA";
type TextSize = "normal" | "large";

Checking WCAG color contrast in TypeScript

accessibility color-math type-safety
Intermediate 10 steps
javascript
import { useEffect, useRef } from "react";
import { useLocation } from "react-router-dom";
 
export function RouteFocus({ title, children }) {

Managing focus on route change in React

accessibility focus-management routing
Intermediate 6 steps
javascript
const STORAGE_KEY = "theme-preference";
 
function getSystemTheme() {
  return window.matchMedia("(prefers-color-scheme: dark)").matches

Building a dark-mode toggle that respects the OS

dark-mode localstorage matchmedia
Intermediate 8 steps
javascript
import { useState, useRef, useCallback } from "react";
 
export function MultiSelect({ options, value, onChange, placeholder = "Select…" }) {
  const [open, setOpen] = useState(false);

Building a keyboard-accessible MultiSelect in React

controlled-component accessibility keyboard-navigation
Intermediate 10 steps
javascript
class StarRating {
  constructor(container, { max = 5, value = 0, onChange } = {}) {
    this.container = container;
    this.max = max;

Building an accessible star-rating widget

dom event-handling accessibility
Intermediate 7 steps
javascript
const form = document.querySelector('#signup-form');
const password = form.querySelector('#password');
const confirm = form.querySelector('#confirm-password');
const submit = form.querySelector('button[type="submit"]');

Live password-match validation in the DOM

form-validation dom-events accessibility
Intermediate 6 steps
javascript
import { NavLink, useLocation } from 'react-router-dom';
 
const NAV_ITEMS = [
  { to: '/', label: 'Dashboard', end: true },

Building an accessible Sidebar in React

routing accessibility declarative-ui
Intermediate 6 steps
javascript
import { forwardRef, useImperativeHandle, useRef, useState } from 'react';
 
const TextField = forwardRef(function TextField(
  { label, error, onChange, ...props },

Exposing an imperative handle in React

forwardref useimperativehandle refs
Advanced 8 steps
javascript
import { createContext, useContext, useState, useId } from "react";
 
const AccordionContext = createContext(null);
const ItemContext = createContext(null);

Building a compound Accordion in React

context compound-components state-management
Intermediate 8 steps
javascript
import { useState, useRef, useEffect, useCallback } from 'react';
 
export function CopyButton({ text, label = 'Copy' }) {
  const [copied, setCopied] = useState(false);

A copy-to-clipboard button in React

clipboard-api hooks cleanup
Intermediate 7 steps
javascript
import { useState } from "react";
 
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
 

Building a validated signup form in React

form-validation controlled-components state-management
Intermediate 10 steps
javascript
import { useCallback, useEffect, useRef } from 'react';
import { createPortal } from 'react-dom';
 
const FOCUSABLE = 'a[href], button:not([disabled]), textarea, input, select, [tabindex]:not([tabindex="-1"])';

Building an accessible modal in React

focus-trap accessibility portals
Advanced 9 steps
javascript
import { useSearchParams } from "react-router-dom";
 
const TABS = [
  { id: "overview", label: "Overview" },

URL-driven tabs with React Router

url-state query-params accessibility
Intermediate 8 steps