Tenon’s accessible React components – Coming soon to an NPM repo near you.

Update: Since this post was published, these components have been released as Tenon-UI. Examples now reflect the current state of our UI library.

There’s a lot cooking in the Tenon.io kitchen these days! While the details must remain a surprise for now, we are updating our website to be more modern and much faster while still remaining extremely accessible.

Being an accessibility company, it may come as a surprise that we are using React to build the interactive parts of our web application. However, we embrace modern tooling, as long as it doesn’t stand in the way of accessibility. Used correctly, tools like React can expedite the creation of complex applications by making codebases highly maintainable and easily testable while accelerating productivity through the reuse of solid, accessible components.

When modern web applications fail on the accessibility front, it is almost always because of incorrect tool use or by employing third party components that are not accessible. In fact, accessible UI elements are pretty hard to find out there; you know, things like form elements, buttons, tab controls and so on. That’s why we decided to build our own.

TL;DR: In the very near future you will be able to build your React websites using the very same accessible building blocks we use!

We present to you: Tenon UI.

Accessibility built in

Even though accessibility is second nature to us, this does not mean that we like to write the same code over and over and that includes accessibility code. Instead, we believe that using solid, tested bits of accessibility code allow you to hit the mark quicker. It also saves a ton on testing and maintenance.

That is where the power of something like React comes in. Such bits of code translate to components in the React world and these can be independently created by our experts and tested by our gurus.

When you have accessibility built into your building blocks, the result is far more likely to be accessible.

Tenon UI

But enough jibbajabba™, let’s go and explore what will soon be coming your way!

Oh and by the way, we guarantee that all of these components will play nice with screen readers, or we owe you (and ourselves) a bugfix!

Accessible forms become a cinch

Not everyone likes creating HTML forms. Yet, very few websites exist without some sort of input form or the other. Hey Login Screen, I am looking at you!

Making forms accessible is not rocket science once you know how, but it still requires quite a bit of effort to check every form element you create. Miss one ID and your entire form could become unusable to a large number of people!

So what if  this could be managed for you? We’re talking about accessible labels, exposing error messages to screen readers, easy validation, the works! Well, meet Tenon UI’s form elements:

Tenon Ui's form elements with validation block.

You can see it in action on them forms demo of Tenon-UI.

Packed to the brim with features, such as automatic element ID management to avoid ID clashes, these controls combine ease of use with full on accessibility power.

You simply use the bundled controller and view components:

    <InputController
    name="password"
    validators={[
        validator(
            isRequired,
            'A password is required`
        )
    ]}
    >
    {props => (
        <Input
            {...props}
            required="required"
            labelText="Password"
        />
    )}
    </InputController>

It also automatically adds all the needed ARIA states and properties to your HTML elements.

And if you don’t like the view component that ships with Tenon UI you can easily inject your own inside the child render function! Tenon UI employs advanced prop getter functions to give you real time access to all the accessibility props your form elements need. This pattern also allows you to easily override any of the standard prop values.

As if that is not exciting enough, Tenon UI also contains a form component that will manage your entire form state and data submission event handling for you!

Here we owe thanks to Paypal Downshift and Kent C. Dodds for prop getter inspiration.

Painless headings

Did you know that the heading structure of a web page acts as the table of contents? The <h1><h6> structure needs to remain properly ordered without skipping levels or switching the order.

In large applications, especially ones that use components, this can be a total pain!

No longer! Tenon UI provides you with a supercharged heading component that will auto calculate the correct level to render:

    <h1>An h1</h1>
    <Heading.LevelBoundary>
       <Heading.H>
           Automatically renders as an h2
       </Heading.H>
       <Heading.LevelBoundary>
           <Heading.H>
               Automatically renders as an h3
           </Heading.H>
       </Heading.LevelBoundary>
       <Heading.H>
           Automatically renders as an h2
       </Heading.H>
    </Heading.LevelBoundary>

When you refactor the code or add another code that implements this component, the headings will automatically calculate the correct levels saving you time and bugs!

Credit is given where it’s due and this one comes straight from Sophie Alpert of the React Core team as described in a recent blog post by Heydon Pickering.

Tremendous tabs

Tabbed interfaces show up a lot on the web. It would be an exaggeration to say that there are as many implementations out there as occurrences but the truth is that it can be tricky to hit the mark with a tabbed control. In fact, tabs should ideally conform to the WAI-ARIA design patterns for a tabbed interface, as clearly described in an article about tabbed interfaces on the Inclusive Components blog.

Those are a lot of things to to think about when coding this and it definitely is something you only want to build once. Or even better, let someone else build it for you:

Tenon Ui's WAI-ARIA tabbed control showing focussed tab

Check it out on the tabbed interface page of Tenon-UI.

This control is a joy to use, allowing you full control to customize the content of both the tab toggles as well as the tab panels while letting the component do the heavy ARIA lifting for you. Things such as keyboard arrow key interaction and ensuring that only the active tab sits in the TAB order of the page.

And you get all of that by writing this:

    <Tabs>
        <Tabs.Tab
            title="Panel 1"
        >
            <p>
                You are on the first panel
            </p>
        </Tabs.Tab>
        <Tabs.Tab
            title="Panel 2"
        >
            <p>
                You are on the second panel
            </p>
        </Tabs.Tab>
        <Tabs.Tab
            title="Panel 3"
        >
            <p>
                You are on the third panel
            </p>
        </Tabs.Tab>
        <Tabs.Tab
            title="Panel 4"
        >
            <p>
                You are on the fourth panel
            </p>
        </Tabs.Tab>
    </Tabs>

Spinning around

Informing users when your application is busy is very important. However, this is often done in ways that are confusing or blocking, especially to screen reader users.

With this in mind, Tenon UI provides two components to make your life easier.

An SVG spinner component

One would expect that that putting a spinning SVG loader on a website should be easy enough, but you have to ensure that screen reader users can also experience it.

That is where our Tenon UI spinner comes in and gives you a properly titled SVG spinner! And no, you won’t see this title in the screen capture, but it’s there just waiting for a screen reader to come along.

To code it, all you have to write is this:

    <Spinner title="Working"/>

See it in action on the animated spinner page of Tenon-UI.

Action button with busy spinner

Async actions, such as saving form data, are often triggered by clicking a button. You can avoid modal, application blocking busy spinners by using the Tenon UI spinner button!

Tenon-UI's spinner button

You can test the full function of this control on the spinner button page of Tenon-UI.

The button also triggers an event when users attempt to click on it when it’s in the spinning state. This makes it super easy to notify people that the action is not complete.

    <SpinnerButton
        onClick={this.onClickHandler}
        onBusyClick={this.onNotifyBusyHandler}
        busyText="Still saving"
        isBusy={this.state.showSpinner}
    >
        Save your information
    </SpinnerButton>

Notifying everyone

Important application notifications shouldn’t just exist for visual users. Everyone deserves to know when something important has happened.

Tenon UI’s notification component wraps your own notification view code in an ARIA live region that tells non visual users what is going on.

    <Notification
        isActive={this.state.showInfoMessage}
        type="info"
    >
        <span>
            You have new messages.
        </span>
        <button
            type="button"
            onClick={this.onDismissHandler}
        >
            Dismiss
        </button>
    </Notification>

With two settings for information and error messages your users will never miss another important application update again!

Share your code with everyone

So you want to share some code with the world? This is can be easier said than done. And when you finally have it on screen the job only starts. You have to ensure that the code contrast is good enough and that users can easily select the code with mouse, keyboard or any input device. That’s no small task, just ask the developer who built this thing!

Rather use Tenon UI’s code block:

    <CodeBlock
        file="codeExample.js"
    />

Or just plug in a code string and see the magic happen!

    <CodeBlock
        codeString={this.state.codeText}
    />

Built-in XHR will automatically fetch the file you specify and display its contents, ensuring that your examples can easily be kept up to date.

Want to know how it looks? Every code block on this page is rendered with that component!

When can I have this?

If you read this far, we are sure that you cannot wait to get started with our shiny new library. Unfortunately you will need to wait just a little longer as we make sure that our first public release meets our own high standards.

We promise it won’t be long. Hey, we are already starting to use these components in-house and they are working like little steam engines!

Keep your eyes on this blog and all social media channels where Tenon is active so that you will be the first to know.

The road ahead

Rome was not built in a day and neither is a UI library. But unlike Rome, you can start using our UI library even though it is still far from complete. More components need to be added and the ones we already have need to be extended to cover even more use cases. But this is a journey we would like to take with you.

We will also be sharing our updates and ideas with you. And if you like to get technical, you can look forward to some more blog articles about the components above which will dive into what makes them tick, and how.

And we want to hear your ideas and comments.

If you already have some ideas and wishes after reading this post, get in touch with us. The best ideas win a place on our magical Jira backlog.

We all hope that this is the start of a long and productive journey with you, dear React developer!

Start your free trial of Tenon today!