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 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-aria-announcer

v1.1.0

Published

This lightweight package allows you to broadcast `aria-live` messages to screen-readers from anywhere within your React application.

Downloads

4

Readme

react-aria-announcer

This lightweight package allows you to broadcast aria-live messages to screen-readers from anywhere within your React application.

This package was created to try and solve the problems that I faced when building an online accessible editor. Historically, online editors are known for being not very accessible. Using this package I was able to broadcast announcements such as "text block has been added" or an "image block has been deleted", which normally would not have been detected by a screenreader, but would have been visible on the screen.

Unlike other packages that also solve this issue, react-aria-announcer allows you to pre-define acceptable aria-live announcements. It also, takes advantage of HOCs, allowing for cleaner, more readable code.

Using react-aria-announcer you can broadcast these important announcements from any component in your application.

Installation


npm install react-aria-announcer

or

yarn add react-aria-announcer

Usage



The library exports 3 components and one react context.

HiddenMessages


This component contains your aria-live div.

import React, { Component } from 'react';
import { HiddenMessages } from 'react-aria-announcer';

class MyAccessibleApp extends Component {
  state = {
    message: '',
    timeStamp: '',
  }

  render() {
    return (
      <HiddenMessages 
        message={this.state.message} 
        timeStamp={this.state.timeStamp} 
      />
    )
  }
}

The props:

  • message - required (must receive the state value)
  • timeStamp - required (must receive the state value)
  • manner - optional values: 'assertive' or 'polite' (default: 'polite')

connectAriaAnnouncementProvider


This higher order component receives your app or a section of your app, where any number of it's ancestors might want to make an announcement.

import React, { Component } from 'react';
import { HiddenMessages, connectAriaAnnouncementProvider } from 'react-aria-announcer';
import ariaMessages from './ariaMessages';

function SearchableDashboard(props) {
  return (
    <div>
      ...lots of components within here!
    </div>
  )
}

const AccessibleSearchableDashboard = connectAriaAnnouncementProvider(SearchableDashboard)

class MyAccessibleApp extends Component {
  constructor(props) {
    super(props)
    this.state = {
      message: '',
      timeStamp: '',
    }
  }

  render() {
    return (
      <div>
      <HiddenMessages 
        message={this.state.message} 
        timeStamp={this.state.timeStamp} 
        manner='assertive'
      />
      <AccessibleSearchableDashboard
        announce={(message, timeStamp) => this.setState({ message, timeStamp })} 
        ariaMessages={ariaMessages}
        {...props}
      />
      </div>
    )
  }
}

The new component must receive 2 props: This new component must receive a function that calls the setState belonging to the component that holds the state; message and timestamp.

  • announce - {function} with two parameters, message and timeStamp and must call the setState method that belongs to the component that holds the state; message and timestamp. i.e.
(message, timeStamp) => this.setState({ message, timeStamp })
  • ariaMessages - {object}
    • keys: actions e.g. addBlock
    • values: {functions} - can take as many arguments as needed, but must return a string

e.g.

const ariaMessages = {
  onToggleButton: () => 'Press shift enter to open toolbar, and navigate using tab ',
  addBlockGuide: type => `Press shift enter to add a new ${type} block`,
  blockAction: (type, action) => `${type} block ${action}`,
  moveBlock: (type, position) => `${type} block has moved to ${position}`,
  entered: (type) => `You are now in the ${type} block`,
  filter: (type, resultNumber) => `Now viewing ${resultNumber} of ${type} blocks`
};

Connecting to the Announcer


There are 2 ways to connect to the announcer:

  • {connectAriaAnnouncementConsumer} this is a higher order component
  • {AnnounceMessageContext} this is a react context object, allowing you to use react hooks

connectAriaAnnouncementConsumer


This higher order component receives your component that might handle important visual changes and actions etc.

import React from 'react';
import { HiddenMessages, connectAriaAnnouncementConsumer } from 'react-aria-announcer';

function FilterByBlockButton({ announce, type }) {
  function handleClick() {
    fnFiltersDataBy(type)
      .then((res) => {
        announce('filter', type, res.length)
      })
    
  }

  return (
    <button onClick={() => handleClick()}>
      filter by {type}
    </button>
  )
}

const AccessibleFilterByBlock = connectAriaAnnouncementConsumer(FilterByBlockButton)

function MyAccessibleAppSectionChild() {
  return (
    <div>
      other components
      <AccessibleFilterByBlock type='text' />
      <AccessibleFilterByBlock type='headline' />
      <AccessibleFilterByBlock type='image' />
      even more components
    </div>
  )
}

Your component will receive a prop announce.

  • announce - {function} - the first argument will be a key, as defined in your ariaMessages. Any additional arguments will correspond to the keys value and any arguments that you defined that function to take.

AnnounceMessageContext


This context object allows you to take advantage of react hooks. It's behaviour is then exactly the same as connectAriaAnnouncementConsumer

import React from 'react';
import { HiddenMessages, AnnounceMessageContext } from 'react-aria-announcer';

function FilterByBlockButton({ type }) {
  const announce = React.useContext(AnnounceMessageContext);
  function handleClick() {
    fnFiltersDataBy(type)
      .then((res) => {
        announce('filter', type, res.length)
      })
    
  }

  return (
    <button onClick={() => handleClick()}>
      filter by {type}
    </button>
  )
}

const AccessibleFilterByBlock = connectAriaAnnouncementConsumer(FilterByBlockButton)

function MyAccessibleAppSectionChild() {
  return (
    <div>
      other components
      <AccessibleFilterByBlock type='text' />
      <AccessibleFilterByBlock type='headline' />
      <AccessibleFilterByBlock type='image' />
      even more components
    </div>
  )
}

Your component will receive a prop announce.

  • announce - {function} - the first argument will be a key, as defined in your ariaMessages. Any additional arguments will correspond to the keys value and any arguments that you defined that function to take.

Contributing to react-aria-announcer

Thank you for taking the time to contribute.

The community is a safe place for people to collaborate.

Please read the CODE of CONDUCT.


All contributions are welcome

...from typos in documentation to coding new features. If you require any help or have any questions please do not hesitate to ask, we are friendly and aim to reply within 48hours.