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

retil-issues

v0.28.4

Published

Super-powers for validation with React.

Downloads

62

Readme

Getting Started

yarn add retil-issues
import { useIssues, useValidator } from 'retil-issues'

2-minute primer

The useIssues() hook manages a list of issues related to a data object.

const [issues, addIssues, clearIssues] = useIssues({ email, password })

With this line, you now have a access to a list of your form's issues:

// Log any issues with the email field to the console
console.log(issues)

But where do these issues come from? You may have guessed that it has something to do with that addIssues variable. But in fact, there are two different ways that you add issues: validation, and server responses.

useValidator()

The first, and simplest, is to use the useValidator hook. This hook accepts an addIssues function (as returned by useIssues) as its first argument, and a validator function as its second argument. It returns a tuple with a function to trigger validation, and a a function to remove any issues.

The validator function is simple - it takes the data to be validated, and returns an object mapping paths to arrays of issues.

const [validate, clear] = useValidator(addIssues, ({ email, password }) => ({
  email: [
    !email && "Please enter your email",
    !isValidEmail(email) && "That doesn't look like a valid email",
  ],
  password: [
    !password && "Please enter your password",
  ]
}))

The returned validate function can be called to run the validator and add any resulting issues to your issues object. This function returns a promise to a boolean, which will resolve to true if the data looks good and issue-free.

This is great for form handlers, where you'll want validate your data before hitting the server.

const handleSubmit = async () => {
  const isValid = await validate()
  if (isValid) {
    // ...
  }
}

Of course, you don't always want to wait until your form is submitted to help your user out with a validation hint. That's why the validate function optionally accepts a path which you'd like to validate.

This makes it perfect for use in the onBlur handler or an input -- it allows you to validate a field as soon as the user taps out of it.

const input = (
  <input
    // Validate just the `email` field whenever focus moves somewhere else
    onBlur={() => validate('email')}
    onChange={event => setEmail(event.target.value)}
    value={email}
  >
)

addIssues()

Not all issues with user input can be detected client side. For example, say you're building a sign-up form with an email field. While you can detect missing emails on the client, what you can't detect is duplicate emails.

If your server returns a message saying "that email has already been used", then you'll want to display it the user -- but you'll also want to clean it up once the user changes the email. This is easy to achieve by calling addIssues() directly:

const handleSubmit = async () => {
  // Note that `validate` only validates the form -- it doesn't check for
  // issues added from a previous submit.
  if (await validate()) {
    clearIssues()

    const serverIssues = await submitToServer(data)

    // Add the issues returned from the server. They'll be automatically removed
    // as the relevant input data changes.
    addIssues(serverIssues)
  }
}