Biasing your business to producing value in a public manner

· Marketing · Patrick Smith

Some ancient 2011 advice from Patrick McKenzie:

Businesses create value with almost everything they do.  The lion’s share of the value is, like an iceberg, below the waterline: it cannot be seen from anywhere outside the business.  Create more value than you capture, certainly, but get the credit for doing so, both from Google and from everybody else.  This means biasing your business to producing value in a public manner.  Did you write software not core to  your line of business?  Great, OSS it.  Get the credit.  Have you learned something novel about your customers or industry?  Write about it.  Get the credit.  Are your business’ processes worthy of emulation?  Spread what you know.  Get the credit.

37Signals is amazing at this. You can do it, too.

Get good at SEO — You need more links. Create ways to justify people who aren’t in a commercial relationship with you linking to you anyway. My favorite way for doing this is getting the credit for things you do, as described above.

https://www.kalzumeus.com/2011/06/17/software-businesses-in-5-hours-a-week-microconf-2010-presentation-1-hour/

There are also slides for the talk.

My most used commands for front-end

· JavaScript, Workflow · Patrick Smith
# Create a new TypeScript library with TSDX
npx tsdx create <project-name>

# Create a new web app with Vite
npm init vite-app <project-name> # Vue by default
npm init vite-app <project-name> --template preact
npm init vite-app <project-name> --template react

# Measure HTTP response time
httpstat "https://example.org/"

# Run Google’s PageSpeed Insights
npx psi "https://example.org/" --strategy=mobile

# Optimize & minify SVG file
npx svgo <some-file.svg>

When a third party library schedules a focus via requestAnimationFrame() and blows all your tests up

· JavaScript, React, Testing · Patrick Smith

The Reach UI components are great. They offer accessible components that you’ll often need when building web apps — such as modals, menus, tabs and more. It’s also popular and therefore has been battled-tested to work with a range of clients.

However, needing to provide accessibility in any project, it sometimes has to make tradeoffs. One decision the @reach/menu-button package has is when to focus on the menu when opening. It’s not focused immediately — it’s asynchronously focused on the next frame.

  // When the menu is open, focus is placed on the menu itself so that
  // keyboard navigation is still possible.
  useEffect(() => {
    if (state.isExpanded) {
      // @ts-ignore
      window.__REACH_DISABLE_TOOLTIPS = true;
      window.requestAnimationFrame(() => {
        focus(menuRef.current);

This leads to errors when running Jest:

console.error
Warning: An update to PopoverImpl inside a test was not wrapped in act(…).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://fb.me/react-wrap-tests-with-act

We can’t change the implementation, so our tests are forced to come up with a solution.

We need to wait to the next frame. We can do this by running requestAnimationFrame() ourself.

However, when testing React we need to ensure anything that could change state is wrapped in act() so that it has rerendered. This function accepts a callback that returns a Promise (also known as an async function). So first we wrap requestAnimationFrame() in a Promise, then wrap that in act() — let’s call this waitForNextFrame() like so:

export function waitForNextFrame(): Promise<undefined> {
  return act(() => {
    return new Promise((resolve) => {
      requestAnimationFrame(() => resolve());
    });
  });
}

Now we can run this after clicking on our menu:

import { render, screen } from "@testing-library/react";
import user from "@testing-library/user-event";

beforeEach(async () => {
  render(<ComponentWithMenu />);
  user.click(screen.getByRole('button', { name: 'Open menu' });
  await waitForNextFrame();
});

We could also defensively run this after every test so any animation frame callbacks have been run:

afterEach(waitForNextFrame);

Useful React hooks for accessibility

import { useMemo } from 'react';
import { v4 as uuid } from 'uuid';

export function useLabelledBy(): readonly [
  string,
  { 'aria-labelledby': string }
] {
  const uniqueID = useMemo(uuid, [uuid]);
  return [uniqueID, { 'aria-labelledby': uniqueID }];
}

export function useDescribedBy(): readonly [
  string,
  { 'aria-describedby': string }
] {
  const uniqueID = useMemo(uuid, [uuid]);
  return [uniqueID, { 'aria-describedby': uniqueID }];
}

This allows us to create id/aria-labelledby pairs to add as attributes to the label and labelled. And another hook for descriptions with id/aria-describedby attributes.

interface ProductProps {
  name: string;
  description: string;
}
function Product({ name, description, price }: ProductProps) {
  const [labelID, labelledBy] = useLabelledBy();
  const [descriptionID, describedBy] = useDescribedBy();

  return (
    <article {...labelledBy} {...describedBy}>
      <h2 id={labelID}>{name}</h2>
      <p id={descriptionID}>{description}</h2>
      ...
    </article>
  );
}

And then for <dl> which are useful for presenting key-value pairs (e.g. attributes of a product, FAQ questions and answers). Here’s a helper that creates a <dt> and <dd> pair and associates them so they label one another.

import { visuallyHidden } from "./shared.css";

interface TermAndDefinitionProps {
  term: React.ReactNode;
  definition: React.ReactNode;
  termVisuallyHidden?: boolean;
}
function TermAndDefinition(props: TermAndDefinitionProps): JSX.Element {
  const [termID, labelledby] = useLabelledBy();  return (
    <>
      <dt
        id={termID}
        className={props.termVisuallyHidden ? visuallyHidden : undefined}
      >
        {props.term}
      </dt>
      <dd {...labelledby}>{props.definition}</dd>
    </>
  );
}

We could use it like so to present the price and color for our product:

interface ProductProps {
  name: string;
  description: string;
  price: string;
  color: string;
}
function Product({ name, description, price, color }: ProductProps) {
  const [labelID, labelledBy] = useLabelledBy();
  const [descriptionID, describedBy] = useDescribedBy();

  return (
    <article {...labelledBy} {...describedBy}>
      <h2 id={labelID}>{name}</h2>
      <p id={descriptionID}>{description}</h2>
      <dl>
        <TermAndDefinition term="Price:" definition={price} />
        <TermAndDefinition term="Color:" definition={color} />
      </dl>
    </article>
  );
}

This means in our tests we can look up the value for a specific key in the UI. We could use React Testing Library which offers looking elements up their accessible role.

The implicit role for a <dd> is definition, so we can look those up by their accessible name. We have wired the corresponding <dt> to be the label which becomes the accessible name. So testing becomes straightforward.

Say to assert that the price shown is $50:

expect(
  screen.getByRole('definition', { name: 'Price:' })
).toHaveTextContent('$50');

Or the color is red:

expect(
  screen.getByRole('definition', { name: 'Color:' })
).toHaveTextContent('Red');

A better alternative to TypeScript’s non-null assertive operator

· JavaScript · Patrick Smith

TypeScript supports using ! for telling the compiler that the value is not null or undefined. This is known as the non-null assertive operator.

user.type(document.activeElement!, "Some text");

However, it is simply stripped out when transpiling to JavaScript. No check is done at runtime. So, unlike the name suggests, we are not actually asserting anything. It would be better, if we are 100% confident that the value is not null/undefined, to have an additional runtime check that blows up if somehow we were mistaken.

This also solve eslint’s no-non-null-assertion rule, which might be enabled in your project by default if you use a preset pack of lint rules.

For Jest tests, you could implement it as:

export function assertDefined<T>(
  value: T | null | undefined
): asserts value is T {
  expect(value).not.toEqual(null);
}

For implementation code:

export function assertDefined<T>(
  value: T | null | undefined
): asserts value is T {
  if (value == null) {
    throw new Error(`Fatal error: value ${value} must not be null/undefined.`);
  }
}

We can now remove our usage of the non-null assertive operator, and replace it with our assertDefined() function. Here the first example of a Jest test:

assertDefined(document.activeElement);
user.type(document.activeElement, "Some text");