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

@edux-design/forms

v0.0.13

Published

React form primitives that share a common context so every label, control, and validation message stays connected and accessible. The package powers the `Field`, `Label`, `Input`, `Textarea`, `Checkbox`, `Radio`, `Switch`, and `Feedback` components used a

Readme

@edux-design/forms

React form primitives that share a common context so every label, control, and validation message stays connected and accessible. The package powers the Field, Label, Input, Textarea, Checkbox, Radio, Switch, and Feedback components used across the Edux design system.

  • Accessible by default – the FieldProvider wires htmlFor, aria-describedby, and live regions automatically.
  • Composable – mix any primitives inside <Field> and re-export Field.Feedback for colocated messaging.
  • Design-token aware – components rely on the shared utility cx helper plus the Edux tokens for borders, colors, spacing, and focus rings.
  • Feature complete inputs – variants, start/end icons, clear buttons, and controlled/uncontrolled support ship in every text control.

Installation

npm install @edux-design/forms @edux-design/utils @edux-design/icons
# or
pnpm add @edux-design/forms @edux-design/utils @edux-design/icons

Peer dependencies:

  • react ^19.1.0
  • react-dom ^19.1.0

After installing, ensure your build pipeline can consume both ESM and CJS outputs (generated via tsup). The published bundle exposes /dist/index.{js,mjs} plus type declarations.


Quick Start

import { Field, Label, Input, Textarea, Checkbox, Radio } from "@edux-design/forms";

export function SignupForm() {
  return (
    <form className="flex flex-col gap-8 w-full max-w-md">
      <Field>
        <Label hint="required" description="We’ll only email account alerts.">
          Email address
        </Label>
        <Input
          type="email"
          placeholder="[email protected]"
          variant="primary"
          clearable
        />
        <Field.Feedback tone="error">
          This email is already registered.
        </Field.Feedback>
      </Field>

      <Field>
        <Label hint="optional">Bio</Label>
        <Textarea rows={5} placeholder="Tell us about yourself…" />
      </Field>

      <Field>
        <Label>Contact me</Label>
        <Radio />
      </Field>

      <Field>
        <Label hint="required">Terms</Label>
        <Checkbox aria-label="Agree to the terms and conditions" />
        <Field.Feedback tone="corrective">
          Agreeing is required before continuing.
        </Field.Feedback>
      </Field>
    </form>
  );
}

Every Field instance mounts a internal context. Label, Input, Textarea, Radio, and Field.Feedback consume that context so they stay synchronized even if rendered in separate components.


Components

<Field>

  • Provides layout (flex, gap-8) and context wiring.
  • Accepts any children; typically wraps Label, a control (Input, Textarea, Radio), and optional Field.Feedback.
  • Set orientation="horizontal" when you need inline layouts (e.g., Switch + label) without affecting other form groups.
  • Use justify="between" with orientation="horizontal" to align left labels and right controls across a column.
  • Re-exports Field.Feedback for ergonomic composition.

<Label>

  • Consumes the field context and sets htmlFor.
  • Supports hint="required" | "optional" and a description prop rendered beneath the main label.
  • Pass hidden to visually hide the label while keeping it accessible.

<Input>

  • Extends standard <input> props and forwards refs.
  • Variants: primary, error, corrective, success, inactive.
  • Optional startIcon, endIcon, and clearable button (uses the Close icon).
  • When clearable is set, clicking the clear button dispatches onChange with an empty value, so controlled inputs update seamlessly.
  • Honors aria-invalid, aria-disabled, and disables itself for the inactive variant.

<Textarea>

  • Mirrors the Input API while targeting multiline content.
  • Supports rows, startIcon, endIcon, clearable, and the same variants.
  • Uses resize-y by default; pass inline styles to opt into both-axis resizing.

<Radio>

  • Minimal radio control bound to the surrounding Field context.
  • Implements hover, focus, and checked states with Tailwind utility classes.
  • Currently exposes a single style; future work will add “active” token colors (see FIXME in source).

<Checkbox>

  • Square control that mirrors native checkbox behavior while layering on design-token driven states (hover, focus, pressed, inactive, and error).
  • Supports the same variants as text inputs plus an indeterminate appearance for tri-state flows.
  • Automatically shares IDs and aria-describedby references with the wrapping Field, so helper text and validation copy are announced.
  • Pairs well with <Label> for field titles; pass aria-label or wrap inline helper text next to the component when you need per-option copy.

<Switch>

  • Toggle-style checkbox that maps the native input to Edux track and thumb visuals, complete with iconography that switches between the Close and Check glyphs.
  • Variants mirror the checkbox control (primary, success, corrective, error, inactive) so validation states stay consistent.
  • Integrates with the Field context to automatically sync id, focus management, and aria-describedby strings built from registered feedback messages.
  • Disables itself automatically when variant="inactive" and exposes hover, focus, pressed, and checked states for every other variant.

<Field.Feedback>

  • Semantic messaging component with tones: info, success, warning, error, corrective.
  • Registers its id with the parent Field, so any controls automatically receive aria-describedby.
  • tone="error" switches to role="alert" / aria-live="assertive"; other tones stay aria-live="polite".
  • Includes a circular icon container that colors itself based on the selected tone.

Accessibility Model

  1. Context-generated IDsFieldProvider assigns a unique labelHTMLForId; the same ID drives <label htmlFor> and the child control’s id.
  2. Description registryField.Feedback registers/unregisters its identifier so inputs build the aria-describedby string automatically, even if multiple feedback blocks mount.
  3. Live regions – error messages announce immediately via role="alert", while neutral/success tones fall back to polite announcements.
  4. Focus styling – every interactive element shares the branded focus:shadow-focus utility, ensuring visible focus outlines without extra work.

To enforce the contract, hooks throw if you render any primitive outside <Field>, making misconfigurations obvious during development.


Theming & Variants

Variants map directly to semantic tokens defined in @edux-design/design-tokens and consumed via Tailwind utility classes:

| Variant | Border / Background intent | | ------------ | -------------------------------------------------------------- | | primary | Default border; highlights on hover/focus with primary color. | | error | Danger border + subtle danger background for immediate errors. | | corrective | Soft highlight for “nudge” messages without blocking input. | | success | Success border for confirmed entries. | | inactive | Muted border/background, disables the control automatically. |

Apply variants per control to reflect validation state. Combine with Field.Feedback to reinforce messaging.


Building & Contributing

  • pnpm build (or npm run build) bundles the package via tsup into dist/.
  • pnpm dev starts tsup in watch mode.
  • pnpm lint and pnpm check-types keep code quality high.

Stories live under src/demos/*.stories.jsx; use them as references for new component states and to manually verify visual behavior.


Roadmap / Known Gaps

  • Radio buttons need dedicated “active” token colors (tracked via FIXME in Radio.jsx).
  • Feedback icons currently reuse the Close glyph for all tones; alternative glyphs per tone may improve clarity.
  • Clear button animations exist, but the components still rely on manually passing value for controlled usage—add tests to prevent regressions.

Contributions should follow the existing Tailwind utility conventions and rely on the shared tokens/utilities package to stay consistent with the broader system.