React Hook Form – Form Validation Hook based on Uncontrolled Components

Now this is an interesting approach, building further upon Uncontrolled Components:

The React Hook Form (react-hook-form) library provides a new form validation mechanism which embraces uncontrolled form validation and support controlled components.

The core idea is to register HTML input’s ref into the custom hook and therefore subscribe to its input value, validate and evaluate the form submission.

I guess this one makes more sense to many as it immediately gives you a values object containing all form values. Validation is also built-in

import React from "react";
import useForm from "react-hook-form";

const Example = () => {
  const { handleSubmit, register, errors } = useForm();
  const onSubmit = values => {
    console.log(values);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        name="email"
        ref={register({
          required: 'Required',
          pattern: {
            value: /^[A-Z0-9._%+-][email protected][A-Z0-9.-]+\.[A-Z]{2,4}$/i,
            message: "invalid email address"
          }
        })}
      />
      {errors.email && errors.email.message}

      <input
        name="username"
        ref={register({
          validate: value => value !== "admin" || "Nice try!"
        })}
      />
      {errors.username && errors.username.message}

      <button type="submit">Submit</button>
    </form>
  );
};

React Hook Form Presentation (Twitter Thread) →
React Hook Form →

💡 The React Hook Form Twitter Thread was compiled from its origin tweet to one single page using Threader

Made with WebAssembly

After several Twitter threads on highlighting use cases, projects, and companies in production using WebAssembly, myself and a few other Wasm communitty members thought it’d be a great idea to have a dedicated place to find projects using WebAssembly, and highlight what WebAssembly can be used for!

Some interesting stuff to find in there, like Diablo 1 or Soundation Studio

Made with WebAssembly →

The deadly race to the South Pole

From the “Vox Darkroom” series:

Robert Falcon Scott was a British explorer who dreamed of being the first person to reach the South Pole. In 1912, he reached the Pole only to learn that his Norwegian rival, Roald Amundsen, had beat him to it. Caught by freakish weather and a string of bad luck, his entire party died trying to get back.

🔗 Another “Vox Darkroom” entry: Why the Soviets doctored this iconic photo

Run Lighthouse in a CI Pipeline using lighthouse-ci

Lighthouse CI is a set of commands that make continuously running, asserting, saving, and retrieving Lighthouse results as easy as possible.

npm install -g @lhci/[email protected]
lhci autorun --upload.target=temporary-public-storage || echo "LHCI failed!"

Comes with default configurations for Travis, GitHub Actions, Circle CI, GitLab CI, and Jenkins.

lighthouse-ci

Upgrade to PHP 7.4 with Homebrew on Mac

Brent has done a writeup on how to upgrade your Homebrew-installed PHP version to PHP 7.4. Since the php formula now contains that 7.4 version (instead of 7.3 before), all you need to do is make sure brew is up-to-date and then upgrade the php formula itself:

# make sure brew is up-to-date
brew update

# upgrade the php formula to its latest version
brew upgrade php

Upgrade to PHP 7.4 with Homebrew on Mac →

💁‍♂️ Don’t forget to upgrade Valet too, while you’re at it:

# stop current valet
valet stop

# update global packages
composer global update

# Make Valet do its housekeeping
valet install

Turn a Twitter thread into an ad-free, single page with @threader_app

Now this is darn handy:

The tweet below for example …

… becomes this page:

All media added to tweets are also embedded 🙂

Embeddable CanIUse Images

Ire Aderinokun, author of the CanIUse Embed, has added an extra option where you can embed static images of features as mentioned on CanIUse.com. The images are generated using Puppeteer, are stored on Cloudinary, and are updated daily using Heroku Scheduler.

What I wanted to do was have a URL linking to an image (hosted on Cloudinary) that I would periodically update with the support table for that feature. For example, to get the latest image of CSS Grid support, anyone could use this URL: https://caniuse.bitsofco.de/image/css-grid.png

A detailed writeup on how she created those images (and how she updates) takes you through the whole process.

How I created 488 “live images” →

Making a Better Custom Select Element

24ways – the advent calendar for web geeks – is back! First post is “Making a Better Custom Select Element” in which Julie Grundy tries to create an accessible Custom Select Element:

Sometimes, I can’t recommend the select input. We want a way for someone to choose an item from a list of options, but it’s more complicated than just that. We want autocomplete options. We want to put images in there, not just text. The optgroup element is ugly, hard to style, and not announced by screen readers. The focus styles are low contrast. I had high hopes for the datalist element, but although it works well with screen readers, it’s no good for people with low vision who zoom or use high contrast themes.

Here’s a pen with the result:

Making a Better Custom Select Element →

Passing Elements as Props in React

I like this nuanced post by David Barral in which he goes over all the options on how to configure a Confirm component: what exactly do you pass in as props.

In this story we are going to see a simple technique that allows you to write friendly customizable components with simple APIs, just by using the basic React building blocks: the element.

The result finds the middle ground between “props explosion” (one prop per customisable part) and render props:

// Component
const Confirm = ({
  children,
  onAccept,
  onReject,
  acceptButton = <Button>Ok</Button>,
  rejectButton = <Button>Cancel</Button>,
}) => (
  <div className="confirm">
    <div className="confirm-header">
      <h1>Confirm</h1>
    </div>
    <div className="confirm-content">{children}</div>
    <div className="confirm-footer">
      {React.cloneElement(acceptButton, { className: "accept-btn", onClick: onAccept })}
      {React.cloneElement(rejectButton, { className: "reject-btn", onClick: onReject })}
    </div>
  </div>
);

// Usage
<Confirm
  acceptButton={<Button>Yep</Button>}
  rejectButton={<Button>Nope</Button>}
  onAccept={() => {}}
  onReject={() => {}}
>
  You sure?
</Confirm>

Passing Elements as Props in React →