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

feed-control

v1.0.5

Published

An implementation of the W3C Feed Pattern

Downloads

2

Readme

Feed Control

The JavaScript implementation of the W3C Feed Pattern.

This plugin is responsible for requesting the feed data from the server, interpreting pagination data to return the proper response, and setting up event handlers for keyboard navigation. There is no support for scroll-activated loading. Instead, this plugin configures a button that, when clicked, will request more items to be pushed onto the feed.

Templating must be handled separately. The usage instructions cover how to create the required element structure. The code snippets here include the necessary ARIA roles and attributes. I know it still requires a lot from you, but this will likely improve with time, development and the right libraries.

Wanna see how it works? Try it here.

Installation and Usage

Install the package as a dependency of your project using your preferred package manager.

npm install feed-control
yarn add feed-control

Then import the module.

const Feed = require('feed-control');

Now create an instance of Feed and give its constructor a string representing the id HTML attribute of the wrapper element we'll be creating. This is how we distinguish between multiple instances of a feed on the same page.

var feed = new Feed('feed');

So if we wanted two feeds, we would create two instances with unique id attributes, like this:

var oneFeed = new Feed('oneFeed');
var anotherFeed = new Feed('anotherFeed');

Run setup() to initialize it.

feed.setup();

That's it for the JavaScript part.

Creating the Feed element

We're going to need some CSS for the next step.

@import "~feed-control/css/feed.css";
  1. Create a wrapper element with an id attribute set to the one you defined on the constructor of the Feed class.
  2. Create some children elements that represent the screens (more on that later).
  3. Create the .feed-data element, which is where the data returned from the server is appended into.
<div id="feed">
  <div class="feed-loading-screen feed-collapsible feed-expanded"></div>
  <div class="feed-error-screen feed-collapsible"></div>
  <div class="feed-nothing-here-screen feed-collapsible"></div>

  <div role="feed" aria-busy="false" data-target="" class="feed-data" aria-label=""></div>
</div>

Don't forget to set data-target to the path that returns the feed data.

If the request has to be made to the current URL, omit it or set data-target to an empty string. If the current URL has a route parameter such as a slug or id, pass this parameter alone through data-target.

The request will also send a GET parameter named page. You should retrieve this parameter on the server to return the requested page.

Finally, set aria-label on the role="feed" element to describe the purpose of the feed. You can also use this to inform the user about the keyboard shortcuts they can use to navigate the feed:

| Keyboard shortcuts | Function | | ------------------------ | ------------------------------------- | | PAGE UP | Navigate to the previous item | | PAGE DOWN | Navigate to the next item | | CTRL + HOME | Go to the first item | | CTRL + END | Go to the last item |

Before we start building the Ajax response template, let me explain a few things.

Screens are overlays for the .feed-data element. They are used during the initial loading process, when the request fails very early, or when there are no results. In other words, screens are only used to announce the status of the initial request. Once the feed has loaded items, control labels kick in.

Control labels are used to announce the status of the feed button, whether it's loading or ready for a new request or if there's nothing else to show. They are only used after the initial request has completed successfully.

These types of elements exist so you can customize the responses given by the Feed. For example, you may want to set a min-height on the screens and center their contents, or maybe change the color scheme of a control label. In short, styling is completely up to you.

Creating the Ajax response template

The response received from the URL specified through data-target should contain a paginated collection of <article> elements. The last of them should be the .feed-control element, within which the feed button and all of its control labels are located. These are the requirements for all, except the .feed-control:

  • Provide the pagination metadata via data attributes.
  • Indicate the first <article> of the set by giving it the class .focus-me, which tells the plugin to focus this element as soon as it is loaded. This ensures the correct TAB sequence is maintained.
<article class="feed-new-item focus-me" tabindex="-1" data-number-of-results="" data-page-size="" data-last-page="" aria-labelledby=""></article>

| Data attribute | Description | | ------------------------ | --------------------------------------------- | | data-number-of-results | The absolute total number of items | | data-page-size | The number of items loaded per page | | data-last-page | The total number of pages |

aria-labelledby should point to a label for the current <article> element. This gives screen reader users a short title or description for each item while browsing the feed with the provided keyboard navigation commands.

Now we create the last <article>, which holds the feed button and all of its labels.

<article class="feed-control feed-new-item" tabindex="-1">
  <button class="feed-control-label-ready feed-control-label feed-button feed-collapsible" type="button" data-label="fcl-ready">
    <span id="fcl-ready">Ready</span>
  </button>

  <div class="feed-control-label-loading feed-control-label feed-collapsible" data-label="fcl-loading">
    <span id="fcl-loading">Loading</span>
  </div>

  <button class="feed-control-label-error feed-control-label feed-button feed-collapsible" type="button" data-label="fcl-error">
    <span id="fcl-error">Error</span>
  </button>

  <div class="feed-control-label-nothing-else feed-control-label feed-collapsible" data-label="fcl-nothing-else">
    <span id="fcl-nothing-else">Nothing Else</span>
  </div>
</article>

The .feed-control element needs a label that corresponds to the currently visible control label. Each control label contains the attribute data-label, which takes an id that will be used to set the aria-labelledby of the .feed-control element.

Phew! That's it. If you got this far, I'd like to thank you for trying my plugin! Feel free to open issues about your questions, suggestions or bugs you may have found. Contributions are welcome, especially if they help reduce the amount of work needed to set this up.

Now go see if it's working!