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

@flexzap/form

v1.1.1

Published

All the form components that makes part of the flexzap library

Readme

@flexzap/form

Comprehensive form components and services for Angular applications, providing reusable form controls, validation utilities, and form management solutions. Part of the FlexZap Library ecosystem.

Installation

npm install @flexzap/form

Peer Dependencies

This library requires the following peer dependencies:

npm install @angular/common@^21.0.0 @angular/core@^21.0.0

Usage

1. Native HTML Validation (Simple)

This approach relies on standard HTML attributes like required, minlength, maxlength, and pattern. The form automatically detects these constraints.

import { Component } from '@angular/core';
import { ZapFormFieldset, ZapFormGroup, ZapFormField, ZapFormInput, ZapFormRow } from '@flexzap/form';
import { ZapButton } from '@flexzap/buttons';

@Component({
  imports: [ZapFormFieldset, ZapFormGroup, ZapFormField, ZapFormInput, ZapFormRow, ZapButton],
  template: `
    <!-- Validation happens on 'blur' (when user leaves the field) -->
    <form ZapFormGroup #myForm="ZapForm" [ZapFormValidationStrategy]="'blur'" (ZapFormSubmit)="onSubmit($event)">
      <zap-form-fieldset [title]="'User Info'" [description]="'Enter your basic details.'">
        <zap-form-row>
          <zap-form-field [label]="'Username'">
            <input ZapFormInput type="text" name="username" required minlength="3" />
          </zap-form-field>
        </zap-form-row>

        <zap-form-row>
          <zap-form-field [label]="'Email'">
            <input ZapFormInput type="email" name="email" required />
          </zap-form-field>
        </zap-form-row>
      </zap-form-fieldset>

      <zap-button [type]="'submit'" [disabled]="!myForm.isFormValid()"> Submit </zap-button>
    </form>
  `
})
export class SimpleFormComponent {
  onSubmit(data: Record<string, FormDataEntryValue | FormDataEntryValue[]>) {
    console.log(JSON.stringify(data, null, 2));
  }
}

2. Custom Validators (Advanced)

Use ZapFormValidators for more complex logic or when you need custom error messages. Custom validators take precedence over native attributes.

import { Component } from '@angular/core';
import {
  ZapFormFieldset,
  ZapFormGroup,
  ZapFormField,
  ZapFormInput,
  ZapFormRow,
  ZapFormValidators
} from '@flexzap/form';
import { ZapButton } from '@flexzap/buttons';

@Component({
  imports: [ZapFormFieldset, ZapFormGroup, ZapFormField, ZapFormInput, ZapFormRow, ZapButton],
  template: `
    <!-- Validation happens only on 'submit' -->
    <form ZapFormGroup #myForm="ZapForm" [ZapFormValidationStrategy]="'submit'" (ZapFormSubmit)="onSubmit($event)">
      <zap-form-fieldset [title]="'Security'" [description]="'Setup your security credentials.'">
        <zap-form-row>
          <zap-form-field
            [label]="'Password'"
            [validators]="[
              validators.required('Password is mandatory'),
              validators.minLength(8, 'Password must be at least 8 chars')
            ]"
          >
            <input ZapFormInput type="password" name="password" />
          </zap-form-field>
        </zap-form-row>

        <zap-form-row>
          <zap-form-field
            [label]="'Custom Code'"
            [validators]="[validators.pattern(/^[A-Z]{3}-\d{3}$/, 'Format must be ABC-123')]"
          >
            <input ZapFormInput type="text" name="code" />
          </zap-form-field>
        </zap-form-row>
      </zap-form-fieldset>

      <zap-button [type]="'submit'" [disabled]="!myForm.isFormValid()"> Submit </zap-button>
    </form>
  `
})
export class AdvancedFormComponent {
  readonly validators = ZapFormValidators;

  onSubmit(data: Record<string, FormDataEntryValue | FormDataEntryValue[]>) {
    console.log(JSON.stringify(data, null, 2));
  }
}

3. Selection Controls

Work with radio buttons and checkboxes using the dedicated components zap-form-radio and zap-form-checkbox.

import { Component } from '@angular/core';
import {
  ZapFormFieldset,
  ZapFormGroup,
  ZapFormField,
  ZapFormRadio,
  ZapFormCheckbox,
  ZapFormRow,
  ZapFormInput,
  ZapFormValidators
} from '@flexzap/form';
import { ZapButton } from '@flexzap/buttons';

@Component({
  imports: [
    ZapFormFieldset,
    ZapFormGroup,
    ZapFormField,
    ZapFormRadio,
    ZapFormCheckbox,
    ZapFormRow,
    ZapFormInput,
    ZapButton
  ],
  template: `
    <form ZapFormGroup #myForm="ZapForm" (ZapFormSubmit)="onSubmit($event)">
      <zap-form-fieldset [title]="'Preferences'" [description]="'Choose your settings.'">
        <zap-form-row>
          <zap-form-field [label]="'Notifications'" [validators]="[validators.required('Please select an option')]">
            <zap-form-radio [label]="'Email'">
              <input ZapFormInput type="radio" name="notifications" value="email" />
            </zap-form-radio>
            <zap-form-radio [label]="'SMS'">
              <input ZapFormInput type="radio" name="notifications" value="sms" />
            </zap-form-radio>
          </zap-form-field>
        </zap-form-row>

        <zap-form-row>
          <zap-form-field [label]="'Terms'">
            <zap-form-checkbox [label]="'I agree to terms'">
              <input ZapFormInput type="checkbox" name="terms" required />
            </zap-form-checkbox>
          </zap-form-field>
        </zap-form-row>
      </zap-form-fieldset>

      <zap-button [type]="'submit'" [disabled]="!myForm.isFormValid()"> Submit </zap-button>
    </form>
  `
})
export class SelectionFormComponent {
  readonly validators = ZapFormValidators;

  onSubmit(data: Record<string, FormDataEntryValue | FormDataEntryValue[]>) {
    console.log(JSON.stringify(data, null, 2));
  }
}

API Reference

ZapFormGroup

A directive that manages the state of a form, including validation and submission.

Inputs

| Property | Type | Default | Description | | --------------------------- | ------------------------------------------ | ---------- | ------------------------------------------- | | ZapFormValidationStrategy | 'blur' \| 'change' \| 'submit' \| 'none' | 'submit' | Determines when validation errors are shown |

Outputs

| Event | Type | Description | | --------------- | ------------------------------------------------------------ | -------------------------------------------- | | ZapFormSubmit | Record<string, FormDataEntryValue \| FormDataEntryValue[]> | Emitted when the form is valid and submitted |

Properties

| Property | Type | Description | | ------------- | ------------------------- | ------------------------------------------------------ | | isFormValid | Signal<boolean> | Computed signal indicating if the entire form is valid | | onReset | (event?: Event) => void | Method to reset the form state and controls |

ZapFormFieldset

A structural component to group related form fields with a title and optional description.

Inputs

| Property | Type | Default | Description | | ------------- | -------- | ----------- | ------------------------------ | | title | string | Required | The main title of the fieldset | | description | string | undefined | Optional description text |

ZapFormRow

A layout component used to wrap form fields for consistent spacing and alignment.

Usage

<zap-form-row>
  <zap-form-field [label]="'Name'">...</zap-form-field>
</zap-form-row>

Data Normalization

The ZapFormGroup automatically normalizes form data output to ensure consistency:

  • Missing Fields: Fields that are typically excluded from FormData when unchecked (like radio buttons and checkboxes) are automatically included in the output with an empty string value ("").
  • Consistency: This ensures that every registered control in your form has a corresponding key in the submitted data object, matching the behavior of empty text inputs.

ZapFormField

A component that wraps a form input and handles label, validation messages, and error states.

Inputs

| Property | Type | Default | Description | | ------------ | ---------------------- | ----------- | ----------------------------------------------- | | label | string | Required | The label text for the control | | message | string | undefined | Helper text to display when there are no errors | | validators | ZapFormValidatorFn[] | [] | Array of custom validator functions |

ZapFormInput

A directive applied to native input elements to integrate them with the FlexZap form system.

Usage

<input ZapFormInput type="text" name="username" required />

ZapFormRadio

A component to style and wrap a native radio input.

Inputs

| Property | Type | Default | Description | | -------- | -------- | -------- | ---------------------------- | | label | string | Required | The label text for the radio |

ZapFormCheckbox

A component to style and wrap a native checkbox input.

Inputs

| Property | Type | Default | Description | | -------- | -------- | -------- | ------------------------------- | | label | string | Required | The label text for the checkbox |

ZapFormControl

An interface that all form controls (like ZapFormField) implement to participate in the ZapFormGroup validation and state management.

Interface

interface ZapFormControl {
  validate(showError?: boolean): boolean;
  reset(): void;
  readonly controlNames?: () => string[];
}

ZapFormValidators

A utility class providing common validator functions.

  • required(errorMessage?): Checks if value is present
  • minLength(length, errorMessage?): Checks minimum length
  • maxLength(length, errorMessage?): Checks maximum length
  • pattern(regex, errorMessage?): Checks against a regex pattern

Testing

This library uses Jest for unit testing with zoneless Angular configuration.

Running Tests

# From the monorepo root
npm run form:test            # Run all unit tests with coverage
npm run form:test:watch      # Run tests in watch mode (no coverage)

Test Configuration

  • Framework: Jest with jest-preset-angular
  • Environment: jsdom
  • Configuration: Zoneless Angular (mandatory)
  • Coverage: Reports generated at coverage/flexzap/form/

Development

Building the Library

# From the monorepo root
npm run form:build       # Build with version bump
ng build @flexzap/form   # Build directly

Code Scaffolding

To generate new components within this library:

ng generate component [component-name] --project @flexzap/form

Publishing

Build for Publication

# From the monorepo root
npm run form:build

Publish to NPM

cd dist/flexzap/form
npm publish --access public

Contributing

This library is part of the FlexZap Library monorepo. Please refer to the main repository for contribution guidelines.

Development Guidelines

  • Use standalone components (default behavior)
  • Use input() and output() functions instead of decorators
  • Set changeDetection: ChangeDetectionStrategy.OnPush
  • Write comprehensive tests with Jest (zoneless configuration)
  • Follow semantic versioning for releases

License

MIT License - see the LICENSE file for details.

Links