Sitelet https://github.com/Cynthion/ngx-formidable
Skip to content

Latest commit

 

History

381 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ngx-formidable

Angular form fields you can actually theme, configure and customize. Validated by whatever you already use.

Created with ❤️ by Cynthion

npm version Deploy Live Studio Angular ^22 MIT License GitHub Stars

Demonstration of how to style the ngx-formidable fields.

Eleven form fields, one decorator that puts labels, prefixes, suffixes, hints and messages around them, and around two hundred CSS custom properties to make them look like your product instead of like a component library. The fields bind to Signal Forms, reactive forms and template-driven forms alike; the model and the rules stay with your forms API, and the rules can be Angular's own, Vest, Zod, or none at all.

  • Studio: a live form of every field. Theme it to your brand, configure the fields, and take away the CSS and the Signal Forms component.
  • Specimen: every field, one change at a time, covering every state, every label position, every adornment and every panel, under any preset or your own theme.
  • Docs: the guides and references below, rendered in the browser from the same files. .documentation/ holds them, plus the design notes for maintainers.

Table Of Contents

Features

  • 🧩 Eleven Fields, One Decorator: input, textarea, select, dropdown, autocomplete, radio and checkbox group, date, time, toggle, slider. <formidable-field-decorator> puts the label, prefixes, suffixes, hints, the required marker and the messages around any of them, in six label positions.
  • 🔌 Every Angular Forms API: Signal Forms, reactive forms and template-driven forms, through [formField], [formControl], formControlName or ngModel. No value accessor, no form directive of its own, no store.
  • ✅ Bring Your Own Validator: Angular's own rules, Vest or Zod through Standard Schema, or none. The library renders the messages, decides when they appear, and marks what is required.
  • 🎨 Themeable To The Corner: ~200 CSS custom properties and no design system in your bundle. Rebrand from one variable; no SCSS hooks, no theme to initialise.
  • 🧠 Typed End To End: Signal Forms types every [formField] path from your model, so a typo in a model key fails the build.
  • ⌨️ Accessible By Default: full keyboard handling, managed focus, combobox, listbox, switch and group roles, and messages in an aria-live region.
  • 🛡️ Masking, Dates And Panels: ngx-mask on text fields, one token string for parsing and formatting a date or time, and panels that flip when there is no room and become a sheet on phones.
  • 🛠️ Extensible: BaseField makes a field of your own bind, decorate and theme like a built-in one.
  • 🎛️ Studio: build the theme and the form against the real components in the browser, then copy out the CSS and the Signal Forms component, template and schema.

When To Pick This Over Angular Material

Material is a design system with a form library in it. This is a form library with no design opinion. That is the whole difference, and it cuts both ways.

You Want Pick
Fields that look like your brand, themed from CSS variables only ngx-formidable
Masking, hints, six label positions and clickable adornments built in ngx-formidable
A form library that adds no design system to your bundle ngx-formidable
Material Design, and to look like it Angular Material
Components beyond forms: tables, dialogs, menus, navigation Angular Material
The CDK: overlays, drag and drop, virtual scroll, a11y utilities Angular Material
A large ecosystem, many maintainers and a long support horizon Angular Material

Installation

npm i @cynthion/ngx-formidable date-fns ngx-mask pikaday

The library does not validate, so it brings no validation library. Add one only if you want it (npm i vest or npm i zod), or validate with Angular's own rules and add nothing.

Full instructions, including what each peer dependency is for: Getting Started.

Setup

// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideNgxFormidable } from '@cynthion/ngx-formidable';

export const appConfig: ApplicationConfig = {
  providers: [...provideNgxFormidable()]
};

It takes an optional config, including app-wide defaults for what every template would otherwise repeat: the label position, the adornment alignment, the panel position, when messages appear and whether required markers show. See Getting Started.

Then the stylesheet, which is imported separately because it is a stylesheet and not a provider:

// styles.scss
@use '@cynthion/ngx-formidable/styles/ngx-formidable';

That is the whole default theme. Redeclare whatever you want to change in your own :root afterwards:

:root {
  --formidable-color-field-border-focus: #0f766e; // rebrand from this one variable
  --formidable-field-height: 50px;
}

Your First Form

Declare the model, its initial value and its rules in one *.form.ts. This one validates with Angular's own rules:

// user.form.ts
import { required, schema } from '@angular/forms/signals';

export interface UserModel {
  name: string;
  birthdate: Date | null;
}

export const initialUserModel: UserModel = { name: '', birthdate: null };

export const userSchema = schema<UserModel>((path) => {
  required(path.name, { message: 'Name is required.' });
});

The component holds the model and the form over it:

// user-form.ts
import { Component, signal } from '@angular/core';
import { form, FormField, FormRoot } from '@angular/forms/signals';
import { DateField, FieldDecorator, FieldHint, FieldLabel, InputField } from '@cynthion/ngx-formidable';
import { initialUserModel, UserModel, userSchema } from './user.form';

@Component({
  selector: 'app-user-form',
  templateUrl: './user-form.html',
  imports: [FormRoot, FormField, DateField, FieldDecorator, FieldHint, FieldLabel, InputField]
})
export class UserForm {
  readonly model = signal<UserModel>(initialUserModel);
  readonly form = form(this.model, userSchema);
}

Then the template:

<!-- user-form.html -->
<form [formRoot]="form">
  <formidable-field-decorator>
    <formidable-input-field [formField]="form.name" />
    <div formidableFieldLabel>Name</div>
    <div formidableFieldHint>As it appears on your passport</div>
  </formidable-field-decorator>

  <formidable-field-decorator>
    <formidable-date-field
      [unicodeTokenFormat]="'dd.MM.yyyy'"
      [formField]="form.birthdate" />
    <div
      formidableFieldLabel
      [position]="'border'">
      Birthdate
    </div>
  </formidable-field-decorator>
</form>

required() marks the name required and checks it, and its message appears once the user has left the field. Vest and Zod plug into the same schema(), and reactive and template-driven forms bind the same fields: Validation, Forms.

The whole walkthrough, with submission and where each piece goes: Getting Started.

What's In The Box

The full API (every input, output, type and token) is in the Component Catalogue.

Category Component Value
Text <formidable-input-field> string
<formidable-textarea-field> string
Options <formidable-select-field> string | null
<formidable-dropdown-field> string | null
<formidable-autocomplete-field> string | null
Option Groups <formidable-radio-group-field> string | null
<formidable-checkbox-group-field> string[]
Date & Time <formidable-date-field> Date | null
<formidable-time-field> Date | null
Values <formidable-toggle-field> boolean
<formidable-slider-field> number
Structural <formidable-field-decorator>
<formidable-field-option>
<formidable-field-errors>
Category Directives And Tokens
Decoration formidableFieldLabel, formidableFieldLabelAdornment, formidableFieldPrefix, formidableFieldSuffix, formidableFieldHint, formidableFieldToggleIcon
Configuration provideNgxFormidable(), FORMIDABLE_DEFAULTS, FORMIDABLE_ERROR_MESSAGE

Documentation

Guides teach a topic; references list what it accepts.

Guide Covers
Getting Started Install, wiring, the stylesheet, a first form
Forms How the fields meet Signal Forms, reactive forms and template-driven forms
Fields Options, panels, keyboard, dates and times, masking, focus
Decoration Labels, adornments, prefixes, suffixes, hints, required marker
Validation Angular's rules, Vest, Zod or none; messages and their reveal
Theming The default theme, what to override, worked examples
Studio Building a theme and a form in the browser, and exporting both
Custom Fields Building a field or an option of your own
Reference Lists
Components Every component, directive, token, type and interface
Theme Reference Every overridable --formidable-* custom property

Design notes for maintainers live in .documentation/tech/, and the repo's own conventions in .documentation/impl/.

Contributing

Contributions are welcome, see CONTRIBUTING.md.

License

Everything in this repository is licensed under the MIT License unless otherwise specified.

In plain English: use it commercially, modify it, ship it inside a closed-source product, sublicense it. Nothing has to be published back. The one condition is that the copyright notice and the license text travel with any copy or substantial portion of the code. It comes with no warranty and no liability.

Every runtime peer dependency is permissive too (MIT, 0BSD or Apache-2.0, no copyleft anywhere), so adding this library puts no obligation on you beyond MIT's own notice.

Copyright (c) 2025 - present Christian Lüthold

About

A powerful Angular component library for building rich, validated forms.

Topics

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages