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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@canonical/react-ds-global-form

v0.23.0

Published

Form components for the Pragma design system. This package provides a field system built on react-hook-form with two core patterns: a field switch for rendering different input types and middleware composition for extending field behavior.

Readme

@canonical/react-ds-global-form

Form components for the Pragma design system. This package provides a field system built on react-hook-form with two core patterns: a field switch for rendering different input types and middleware composition for extending field behavior.

Prerequisites

  • React 19 or higher

Installation

bun add @canonical/react-ds-global-form

The package builds on top of @canonical/react-ds-global.

Dependencies

The form system builds on two key libraries:

  • react-hook-form - Form state management, validation, and field registration. The Field component uses useFormContext internally, so forms must be wrapped in a FormProvider.
  • downshift - Powers the combobox field with accessible autocomplete behavior.

Usage

Wrap your form in a Form component and use Field for inputs:

import { Form, Field } from "@canonical/react-ds-global-form";

function ContactForm() {
  const onSubmit = (data) => console.log(data);

  return (
    <Form onSubmit={onSubmit}>
      <Field
        name="email"
        inputType="email"
        label="Email address"
        description="We'll never share your email."
      />
      <Field
        name="message"
        inputType="textarea"
        label="Message"
      />
      <button type="submit">Send</button>
    </Form>
  );
}

Field Switch Pattern

The Field component uses inputType to select the appropriate input component:

| inputType | Component | Description | |-----------|-----------|-------------| | text, email, password, number, tel, url | Text | Standard text inputs | | textarea | Textarea | Multi-line text | | checkbox | Checkbox | Boolean toggle | | range | Range | Slider input | | select | Select | Dropdown selection | | simple-choices | SimpleChoices | Radio buttons or checkboxes | | combobox | Combobox | Searchable dropdown | | hidden | Hidden | Hidden input | | custom | Your component | Pass via CustomComponent prop |

All fields are wrapped with withWrapper, which provides form registration, labels, descriptions, error display, and middleware support.

Custom Fields

For field types not covered by the built-ins, use inputType="custom":

import { Field } from "@canonical/react-ds-global-form";
import { MyColorPicker } from "./MyColorPicker";

<Field
  name="brandColor"
  inputType="custom"
  CustomComponent={MyColorPicker}
  label="Brand Color"
/>

Custom components must be wrapped with withWrapper. See docs/creating-custom-fields.md for the complete guide.

Middleware Pattern

Middleware are higher-order components that wrap fields to add functionality. They compose via the middleware prop:

<Field
  name="country"
  inputType="select"
  label="Country"
  middleware={[addRESTOptions("/api/countries")]}
/>

The middleware signature is (Component) => Component. Multiple middleware compose in array order, with the first middleware as the outermost wrapper.

Built-in Middleware

addRESTOptions - Fetches options from an API endpoint:

import { addRESTOptions } from "@canonical/react-ds-global-form";

<Field
  name="category"
  inputType="select"
  middleware={[
    addRESTOptions("/api/categories", {
      transformData: (data) => data.categories,
    }),
  ]}
/>

addRESTValidation - Validates field values against an API:

import { addRESTValidation } from "@canonical/react-ds-global-form";

<Field
  name="username"
  inputType="text"
  middleware={[
    addRESTValidation("/api/validate-username", {
      debounceWait: 300,
      minLength: 3,
    }),
  ]}
/>

See docs/creating-middleware.md for creating custom middleware.

Conditional Display

Fields can conditionally render based on other field values:

<Field
  name="company"
  inputType="text"
  label="Company"
  condition={[
    ["accountType"],
    ([type]) => type === "business",
  ]}
/>

The field only renders when the condition function returns true.

Storybook

cd packages/react/ds-global-form
bun run storybook

The Storybook configuration includes MSW integration for mocking backend responses.

Component Specifications

Form component specifications are defined in the Design System Ontology.