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

primeng-tri-state-checkbox

v1.0.3

Published

A TypeScript utility library for tri-state checkbox functionality in Angular applications

Readme

primeng-tri-state-checkbox

A TypeScript utility library for tri-state checkbox functionality in Angular applications, specifically designed for PrimeNG 19+ and optimized for Tailwind CSS.

Features

  • 🔄 Tri-state cycling: null → true → false → null
  • 🎨 PrimeNG integration: Built specifically for PrimeNG p-checkbox component
  • 🎯 TypeScript support: Full type safety and IntelliSense
  • 🎨 Tailwind CSS utilities: Pre-built classes for visual feedback
  • 📦 Tree-shakeable: Import only what you need
  • 🚀 Zero dependencies: Lightweight and fast

Installation

npm install primeng-tri-state-checkbox

Peer Dependencies

npm install @angular/forms primeng

Basic Usage

1. Simple Import - One Function for Everything

import { turnToTriState } from 'primeng-tri-state-checkbox';
import { FormControl } from '@angular/forms';

// Create a form control with tri-state value
const formControl = new FormControl<boolean | null>(null);

// Use with form control directly - it will cycle the control's value
turnToTriState(formControl); // null → true → false → null

// Or use with direct values - it returns the next state
let currentValue: boolean | null = null;
currentValue = turnToTriState(currentValue); // returns true
currentValue = turnToTriState(currentValue); // returns false
currentValue = turnToTriState(currentValue); // returns null

2. Advanced Usage with Multiple Functions

import { 
  turnToTriState, 
  cycleTriState,
  getPrimeNGTriStateProps 
} from 'primeng-tri-state-checkbox';

// If you need more specific control, you can still use individual functions
const nextValue = cycleTriState(currentValue);
const primeNGProps = getPrimeNGTriStateProps(currentValue);

3. PrimeNG Integration

import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { turnToTriState } from 'primeng-tri-state-checkbox';

@Component({
  selector: 'app-example',
  template: `
    <form [formGroup]="form">
      <div class="flex items-center gap-2">
        <p-checkbox
          [value]="form.controls.hasFusing.value"
          inputId="hasFusing"
          name="hasFusing"
          [indeterminate]="form.controls.hasFusing.value === null"
          [binary]="true"
          (onChange)="turnToTriState(form.controls.hasFusing)" />
        <label class="whitespace-nowrap text-sm" for="hasFusing">
          Has Fusing?
        </label>
      </div>
    </form>
  `
})
export class ExampleComponent {
  form: FormGroup;

  constructor(private fb: FormBuilder) {
    this.form = this.fb.group({
      hasFusing: [null] // Start with indeterminate state
    });
  }

  // Make turnToTriState available in template
  turnToTriState = turnToTriState;
}

API Reference

Core Functions

cycleTriState(currentValue: boolean | null): boolean | null

Cycles through tri-state values: null → true → false → null

turnToTriState(formControl: TriStateFormControl): void

Cycles a FormControl through tri-state values

PrimeNG Utilities

getPrimeNGTriStateProps(value: boolean | null)

Returns props object for PrimeNG p-checkbox:

{
  value: boolean | null;
  indeterminate: boolean;
  binary: boolean;
}

handlePrimeNGTriStateChange(event: any, formControl: TriStateFormControl): void

Event handler for PrimeNG onChange events

generatePrimeNGTriStateTemplate(fieldName: string, config?: object): string

Generates complete HTML template for PrimeNG tri-state checkbox

Tailwind CSS Utilities

getTriStateTailwindClasses(value: boolean | null, customClasses?: object): string

Returns Tailwind CSS classes for visual feedback:

  • null: yellow theme (unknown/indeterminate)
  • true: green theme (positive)
  • false: red theme (negative)

getTriStateIcon(value: boolean | null, iconSet?: 'pi' | 'fa'): string

Returns icon classes for tri-state representation:

  • null: minus icon
  • true: check icon
  • false: times/x icon

Display Utilities

triStateToString(value: boolean | null): 'true' | 'false' | 'null'

Converts tri-state value to string

stringToTriState(value: string): boolean | null

Parses string to tri-state value

getTriStateLabel(value: boolean | null, labels?: object): string

Returns human-readable labels for each state

Advanced Examples

Custom Styling with Tailwind

import { getTriStateTailwindClasses, getTriStateIcon } from 'primeng-tri-state-checkbox';

@Component({
  template: `
    <div [class]="getStateClasses(form.controls.status.value)" 
         class="p-3 rounded-lg border">
      <i [class]="getStateIcon(form.controls.status.value)" class="mr-2"></i>
      {{ getStateLabel(form.controls.status.value) }}
    </div>
  `
})
export class CustomStyledComponent {
  getStateClasses(value: boolean | null): string {
    return getTriStateTailwindClasses(value, {
      null: 'bg-gray-100 border-gray-300 text-gray-700',
      true: 'bg-emerald-50 border-emerald-300 text-emerald-700',
      false: 'bg-rose-50 border-rose-300 text-rose-700'
    });
  }

  getStateIcon(value: boolean | null): string {
    return getTriStateIcon(value, 'pi');
  }
}

Multiple Tri-state Checkboxes

@Component({
  template: `
    <form [formGroup]="form" class="space-y-4">
      <div *ngFor="let field of triStateFields" 
           class="flex items-center gap-2">
        <p-checkbox
          [value]="form.controls[field.key].value"
          [inputId]="field.key"
          [name]="field.key"
          [indeterminate]="form.controls[field.key].value === null"
          [binary]="true"
          (onChange)="turnToTriState(form.controls[field.key])" />
        <label class="text-sm" [for]="field.key">
          {{ field.label }}
        </label>
        <span [class]="getTriStateTailwindClasses(form.controls[field.key].value)"
              class="px-2 py-1 rounded text-xs">
          {{ getTriStateLabel(form.controls[field.key].value) }}
        </span>
      </div>
    </form>
  `
})
export class MultiTriStateComponent {
  triStateFields = [
    { key: 'hasWarranty', label: 'Has Warranty?' },
    { key: 'isActive', label: 'Is Active?' },
    { key: 'isVerified', label: 'Is Verified?' }
  ];

  form = this.fb.group({
    hasWarranty: [null],
    isActive: [null], 
    isVerified: [null]
  });

  turnToTriState = turnToTriState;
  getTriStateTailwindClasses = getTriStateTailwindClasses;
  getTriStateLabel = getTriStateLabel;
}

TypeScript Types

interface TriStateFormControl {
  value: boolean | null;
  setValue(value: boolean | null): void;
}

type TriStateValue = boolean | null;
type TriStateString = 'true' | 'false' | 'null';

Development & Contributing

Automated Publishing Workflow

This package uses automated versioning and publishing through GitHub Actions. Contributors don't need to manually update versions or publish to NPM.

Commit Message Format

Use conventional commit messages to trigger automatic version bumps:

# For bug fixes (patch version: 1.0.0 → 1.0.1)
git commit -m "fix: resolve checkbox state issue"

# For new features (minor version: 1.0.0 → 1.1.0)  
git commit -m "feat: add new utility function"

# For breaking changes (major version: 1.0.0 → 2.0.0)
git commit -m "major: change API interface"
# OR
git commit -m "feat: new feature

BREAKING CHANGE: API has changed"

# Other commits (no version bump)
git commit -m "docs: update README"
git commit -m "chore: update dependencies"

Development Workflow

  1. Make your changes
  2. Commit with proper message format
  3. Push to main branch
  4. GitHub Actions automatically:
    • Runs tests and type checking
    • Bumps version based on commit message
    • Publishes to NPM
    • Creates git tags
# Example workflow
git add .
git commit -m "feat: add new tri-state utility"
git push origin main
# 🎉 Package automatically published!

Pull Request Workflow

For larger changes, use pull requests:

# Create feature branch
git checkout -b feature/new-functionality

# Make changes and commit
git commit -m "feat: add advanced tri-state features"

# Push and create PR
git push origin feature/new-functionality
# Create PR on GitHub → Merge → Automatic publish!

Browser Support

  • Modern browsers supporting ES2020+
  • Angular 19+
  • PrimeNG 19+

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License. See LICENSE file for details.

Links