npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@afixt/a11y-calc

v0.1.3

Published

An accessible calculator React component with basic and scientific modes, styled after macOS Calculator.

Readme

@afixt/a11y-calc

An accessible calculator React component styled after the macOS built-in calculator, with basic and scientific modes. Built with accessibility as the primary design constraint.

Features

  • Basic mode — standard four-function calculator (add, subtract, multiply, divide, percent, sign toggle)
  • Scientific mode — trigonometric, logarithmic, exponential, power, root, and factorial functions, parentheses, constants (π, e), degree/radian toggle, and a "2nd" function key
  • Fully accessible — screen reader announcements, keyboard support, ARIA attributes, high-contrast and reduced-motion support
  • Themeable — all colors and sizes exposed as CSS custom properties and an optional theme prop

Installation

npm install @afixt/a11y-calc

Usage

import { Calculator } from '@afixt/a11y-calc';
import '@afixt/a11y-calc/style.css';

// Basic usage
<Calculator />

// Start in scientific mode
<Calculator initialMode="scientific" />

// Custom theme
<Calculator theme={{
  'calc-bg': '#1a1a2e',
  'btn-operator-bg': '#e94560',
  'btn-number-bg': '#16213e',
  'btn-number-text': '#eee',
  'display-bg': '#0f3460',
  'display-text': '#ffffff',
}} />

Props

| Prop | Type | Default | Description | | ------------- | ------------------------- | --------- | ----------------------------------- | | initialMode | 'basic' \| 'scientific' | 'basic' | Which mode the calculator starts in | | theme | CalculatorTheme | — | Partial theme override object |

Theming

Every visual property is exposed as a CSS custom property. You can override them globally in CSS or per-instance via the theme prop.

CSS Custom Properties

| Property | Default (dark) | Description | | ----------------------------- | -------------- | --------------------------------------- | | --calc-bg | #2a2a2a | Calculator body background | | --calc-radius | 12px | Border radius of the calculator | | --calc-width | 320px | Width in basic mode | | --calc-width-scientific | 720px | Width in scientific mode | | --display-bg | #1c1c1c | Display area background | | --display-text | #ffffff | Display text color | | --display-font-size | 3rem | Display number size | | --btn-size | 70px | Minimum button height | | --btn-font-size | 1.5rem | Button text size | | --btn-number-bg | #505050 | Number button background | | --btn-number-text | #ffffff | Number button text | | --btn-number-hover | #6a6a6a | Number button hover | | --btn-function-bg | #a5a5a5 | Function button (AC, %, +/-) background | | --btn-function-text | #000000 | Function button text | | --btn-operator-bg | #f09a36 | Operator button background | | --btn-operator-text | #ffffff | Operator button text | | --btn-operator-hover | #f5b04e | Operator button hover | | --btn-operator-pressed-bg | #ffffff | Active operator background | | --btn-operator-pressed-text | #f09a36 | Active operator text | | --btn-scientific-bg | #3a3a3a | Scientific button background | | --btn-scientific-text | #ffffff | Scientific button text | | --focus-ring-color | #58a6ff | Focus indicator color | | --focus-ring-width | 3px | Focus indicator width |

Example: global CSS override

.calculator {
  --calc-bg: #1a1a2e;
  --btn-operator-bg: #e94560;
  --btn-number-bg: #16213e;
}

The calculator also responds to prefers-color-scheme: light, prefers-contrast: more, and prefers-reduced-motion: reduce media queries automatically.

Accessibility

Conformance

The <Calculator> component targets WCAG 2.2 AA. Accessibility is verified at four layers:

  1. eslint-plugin-jsx-a11y at lint time
  2. @afixt/a11y-assert via Vitest against the rendered component
  3. @afixt/a11y-assert via Playwright against the running demo
  4. A dedicated accessibility GitHub Actions workflow on every PR

See ADR 0009 for the layering rationale. Known limitations are tracked as issues labeled a11y.

Semantic HTML

  • All buttons are native <button type="button"> elements
  • The display uses the <output> element
  • The calculator container uses role="application" with aria-roledescription="calculator" to allow keyboard passthrough in screen readers

ARIA Attributes

  • Every symbolic button has an explicit aria-label (e.g., ÷ is labeled "Divide", √x is "Square root")
  • Active operator buttons have aria-pressed="true"
  • A live region (aria-live="polite") announces every action in natural language:
    • Digit press: "5"
    • Operator: "plus"
    • Equals: "5 plus 3 equals 8"
    • Scientific: "square root of 9 equals 3"
    • Error: "Error, cannot divide by zero"
    • Clear: "All cleared, 0"

Keyboard Support

| Key | Action | | --------------- | ----------------------------- | | 09 | Input digit | | . | Decimal point | | + - * / | Operators | | Enter or = | Equals | | Escape | Clear all | | Backspace | Delete last digit | | % | Percent | | ^ | Power (scientific mode) | | ( ) | Parentheses (scientific mode) |

Visual Accessibility

  • Minimum 44px touch targets on all calculator buttons
  • Visible focus indicators (never suppressed)
  • Light/dark mode support (prefers-color-scheme)
  • High contrast support (prefers-contrast: more)
  • Reduced motion support (prefers-reduced-motion)
  • Font sizes use rem units

Scientific Mode Functions

| Button | Aria Label | Function | | ------------ | ----------------------------------------------- | --------------------------------- | | sin / asin | Sine / Arc sine | Trigonometric sine and inverse | | cos / acos | Cosine / Arc cosine | Trigonometric cosine and inverse | | tan / atan | Tangent / Arc tangent | Trigonometric tangent and inverse | | sinh / asinh | Hyperbolic sine / Inverse hyperbolic sine | Hyperbolic functions | | cosh / acosh | Hyperbolic cosine / Inverse hyperbolic cosine | Hyperbolic functions | | tanh / atanh | Hyperbolic tangent / Inverse hyperbolic tangent | Hyperbolic functions | | ln / log₁₀ | Natural log / Log base 10 | Logarithms | | x² / x³ | x squared / x cubed | Powers | | xⁿ | x to the power of n | Arbitrary power | | eˣ / 10ˣ | e to the power / 10 to the power | Exponentials | | √x / ∛x | Square root / Cube root | Roots | | 1/x | Reciprocal | Reciprocal | | x! | Factorial | Factorial | | π | Pi | 3.14159... | | e | Euler's number e | 2.71828... | | Rad/Deg | Switch angle mode | Toggle radians/degrees | | 2nd | Second function | Toggles alternate functions |

Development

First-time setup

git clone https://github.com/AFixt/a11y-calc.git
cd a11y-calc
bash scripts/bootstrap.sh    # installs every external scanner used by the hooks
npm ci

The bootstrap script installs trufflehog, lychee, semgrep, osv-scanner, codeql, dependency-check, and zap via Homebrew on macOS (with Linux/WSL release-binary hints for the rest). First run of dependency-check seeds the NVD mirror (~1 GB, 20–40 min — faster with an NVD API key).

Scripts

npm run dev            # Start demo dev server (vite)
npm run build          # Type-check and build library (dist/)
npm run build:demo     # Build the demo app (dist-demo/)
npm run preview        # Serve the built demo
npm run lint           # ESLint
npm run typecheck      # tsc --noEmit across all project references
npm test               # Unit tests (vitest)
npm run test:watch     # Tests in watch mode
npm run test:coverage  # Tests with coverage report
npm run test:e2e       # Build demo + run Playwright E2E tests
npm run size           # size-limit budgets
npm run lhci           # Lighthouse CI against the demo
npm run ai:context     # Print project summary (for AI sessions / new contribs)

Gates

  • npm run check — fast: lint + typecheck + stylelint + markdownlint + format check
  • npm run check:ci — CI target: adds tests, build, size, dupes, links, fast security scanners, license allowlist
  • npm run check:all — pre-push: full gate including CodeQL and OWASP Dependency-Check

npm run check:all runs automatically on git push via Husky.

Contributing

  1. Run bash scripts/bootstrap.sh and npm ci.
  2. Create a branch, commit with Conventional Commits (enforced by commitlint on commit-msg).
  3. Husky's pre-commit runs lint-staged + type check on staged files
    • TruffleHog secret scan (see ADR 0012). pre-push runs the full check:all.
  4. Open a PR targeting main. CI runs check:ci, Lighthouse CI, and the a11y workflow. Scheduled workflows (CodeQL, OWASP Dependency-Check, OWASP ZAP, lychee online) run weekly on main.
  5. Non-obvious engineering decisions get an ADR in docs/adr/ — see docs/templates/adr-template.md.

Tech Stack

License

MIT