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

@bw-ui/datepicker-accessibility

v1.1.4

Published

Accessibility plugin - Keyboard nav, ARIA, focus trap, screen readers

Readme

@bw-ui/datepicker-accessibility

Accessibility plugin for BW DatePicker - Full keyboard navigation, ARIA support, focus trap, and screen reader announcements.

Version License Size

Live DemoDocumentationCore Package

✨ Features

  • ⌨️ Full Keyboard Navigation - Navigate with arrow keys, shortcuts
  • 🔒 Focus Trap - Keep focus inside picker when open
  • 📢 Screen Reader Announcements - ARIA live regions
  • 🏷️ ARIA Labels - Proper roles and labels
  • 🎯 High Contrast Mode - Support for high contrast themes
  • 🔄 Auto Focus - Smart initial focus on open

📦 Installation

npm install @bw-ui/datepicker @bw-ui/datepicker-accessibility

⚠️ Peer Dependency: Requires @bw-ui/datepicker core package

🚀 Quick Start

ES Modules

import { BWDatePicker } from '@bw-ui/datepicker';
import { AccessibilityPlugin } from '@bw-ui/datepicker-accessibility';

const picker = new BWDatePicker('#date-input', {
  mode: 'popup',
}).use(AccessibilityPlugin);

CDN

<link
  rel="stylesheet"
  href="https://unpkg.com/@bw-ui/datepicker/dist/bw-datepicker.min.css"
/>
<link
  rel="stylesheet"
  href="https://unpkg.com/@bw-ui/datepicker-accessibility/dist/bw-accessibility.min.css"
/>

<script src="https://unpkg.com/@bw-ui/datepicker/dist/bw-datepicker.min.js"></script>
<script src="https://unpkg.com/@bw-ui/datepicker-accessibility/dist/bw-accessibility.min.js"></script>

<script>
  const picker = new BW.BWDatePicker('#date-input').use(
    BWAccessibility.AccessibilityPlugin
  );
</script>

⚙️ Options

.use(BWAccessibility.AccessibilityPlugin, {
  // Keyboard Navigation
  enableKeyboard: true,       // Enable keyboard navigation

  // Focus Management
  enableFocusTrap: true,      // Trap focus inside picker
  autoFocus: true,            // Auto focus on open
  returnFocus: true,          // Return focus to input on close

  // Screen Reader
  enableAnnouncer: true,      // Enable screen reader announcements
  announcerDelay: 100,        // Delay before announcements (ms)

  // ARIA
  enableAria: true,           // Add ARIA attributes

  // High Contrast
  enableHighContrast: true,   // Support high contrast mode
})

Options Reference

| Option | Type | Default | Description | | -------------------- | --------- | ------- | ----------------------------------------- | | enableKeyboard | boolean | true | Enable/disable keyboard navigation | | enableFocusTrap | boolean | true | Trap focus inside picker when open | | autoFocus | boolean | true | Automatically focus first element on open | | returnFocus | boolean | true | Return focus to trigger element on close | | enableAnnouncer | boolean | true | Enable screen reader announcements | | announcerDelay | number | 100 | Milliseconds delay before announcement | | enableAria | boolean | true | Add ARIA roles and attributes | | enableHighContrast | boolean | true | Support high contrast mode |

Examples

Minimal (keyboard only):

.use(BWAccessibility.AccessibilityPlugin, {
  enableFocusTrap: false,
  enableAnnouncer: false,
})

Full accessibility (default):

.use(BWAccessibility.AccessibilityPlugin)
// All options enabled by default

Custom announcer delay:

.use(BWAccessibility.AccessibilityPlugin, {
  announcerDelay: 200,  // Slower announcements
})

Disable auto focus:

.use(BWAccessibility.AccessibilityPlugin, {
  autoFocus: false,  // Don't auto focus on open
})

⌨️ Keyboard Shortcuts

Day Navigation

| Key | Action | | ------ | ------------------------ | | | Previous day | | | Next day | | | Previous week (same day) | | | Next week (same day) | | Home | First day of month | | End | Last day of month |

Month/Year Navigation

| Key | Action | | ------------------ | -------------- | | PageUp | Previous month | | PageDown | Next month | | Shift + PageUp | Previous year | | Shift + PageDown | Next year |

Selection & Control

| Key | Action | | ------------- | ------------------------- | | Enter | Select focused date | | Space | Select focused date | | Escape | Close picker | | Tab | Navigate between elements | | Shift + Tab | Navigate backwards |

🔧 What It Does

1. Keyboard Navigation (enableKeyboard)

Enables full keyboard control of the datepicker:

// User can navigate entirely with keyboard
// Arrow keys move between days
// PageUp/Down changes months
// Enter selects, Escape closes

2. Focus Trap (enableFocusTrap)

Keeps focus inside the picker when open:

// When picker opens:
// - Focus moves to selected date (or today, or first day)
// - Tab cycles through picker elements only
// - Focus doesn't escape to page behind

3. Auto Focus (autoFocus)

Smart initial focus when picker opens:

Priority order:
1. Previously selected date
2. Today's date
3. First available day

4. Return Focus (returnFocus)

Returns focus to input when picker closes:

// User presses Escape or selects date
// Focus returns to the input field

5. Screen Reader Announcements (enableAnnouncer)

Announces changes to screen readers:

// Announces:
// - "Calendar opened"
// - "Calendar closed"
// - "December 2025" (on month change)
// - Date labels when navigating

6. ARIA Attributes (enableAria)

Adds proper ARIA roles and labels:

<!-- Grid structure -->
<div role="grid" aria-label="December 2025">
  <div role="row">
    <button
      role="gridcell"
      aria-label="Sunday, December 25, 2025"
      aria-selected="true"
      tabindex="0"
    >
      25
    </button>
  </div>
</div>

7. High Contrast Support (enableHighContrast)

Respects user's high contrast preferences:

@media (prefers-contrast: high) {
  /* Enhanced borders and focus indicators */
}

📡 Events

The plugin emits no additional events but responds to core events:

// Plugin listens to:
picker.on('picker:opened', () => {
  // Activates keyboard nav, focus trap, announces "Calendar opened"
});

picker.on('picker:closed', () => {
  // Deactivates focus trap, announces "Calendar closed"
});

picker.on('nav:monthChanged', ({ month, year }) => {
  // Announces new month/year to screen readers
});

🎯 Accessibility Compliance

This plugin helps achieve:

  • WCAG 2.1 Level AA compliance
  • Section 508 compliance
  • WAI-ARIA 1.2 design patterns

Checklist

| Requirement | Status | | --------------------- | ------ | | Keyboard accessible | ✅ | | Focus visible | ✅ | | Focus trapped | ✅ | | Screen reader support | ✅ | | ARIA labels | ✅ | | High contrast support | ✅ | | No keyboard traps | ✅ |

🔌 Combining with Other Plugins

Works great with other BW DatePicker plugins:

import { BWDatePicker } from '@bw-ui/datepicker';
import { ThemingPlugin } from '@bw-ui/datepicker-theming';
import { AccessibilityPlugin } from '@bw-ui/datepicker-accessibility';
import { PositioningPlugin } from '@bw-ui/datepicker-positioning';

const picker = new BWDatePicker('#date-input')
  .use(BWTheming.ThemingPlugin, { theme: 'dark' })
  .use(BWAccessibility.AccessibilityPlugin) // Add accessibility
  .use(BWPositioning.PositioningPlugin);

Recommended Plugin Order

.use(BWTheming.ThemingPlugin)        // 1. Theming first
.use(BWAccessibility.AccessibilityPlugin)  // 2. Accessibility second
.use(BWPositioning.PositioningPlugin)    // 3. Positioning last

🧪 Testing Accessibility

Manual Testing

  1. Keyboard Only: Unplug mouse, navigate with keyboard only
  2. Screen Reader: Test with NVDA, VoiceOver, or JAWS
  3. High Contrast: Enable Windows High Contrast mode

Automated Testing

# Using axe-core
npm install axe-core

# In your tests
import axe from 'axe-core';

axe.run(document.querySelector('.bw-datepicker'))
  .then(results => {
    console.log(results.violations); // Should be empty
  });

📁 What's Included

dist/
├── bw-accessibility.min.js      # IIFE build (for <script>)
├── bw-accessibility.esm.min.js  # ESM build (for import)
└── bw-accessibility.min.css     # Styles (focus indicators, etc.)

🔗 Related Packages

| Package | Description | | ------------------------------------------------------------------------------------------------ | ---------------- | | @bw-ui/datepicker | Core (required) | | @bw-ui/datepicker-theming | Dark mode | | @bw-ui/datepicker-positioning | Auto-positioning | | @bw-ui/datepicker-mobile | Touch support | | @bw-ui/datepicker-input-handler | Input masking | | @bw-ui/datepicker-date-utils | Date utilities |

📄 License

MIT © BW UI

🐛 Issues

Found a bug? Report it here