Getting StartedInstallation and setup guides 6
FormInput and selection components 26
LayoutWorkflow and structural layout components 10
NavigationMenu surfaces and hierarchical actions 7
OverlayModal and floating layer surfaces 3
FeedbackStatus, empty, progress, and loading placeholder patterns 6
UtilityGeneral-purpose interface utilities 7

API reference

<tng-number-range> is the single component entry point for dual numeric range input. All configuration is done through Angular signal inputs and outputs.

<tng-number-range> (component)

A standalone Angular component that renders a min/max numeric input group. The snippet below is ready to paste into a standalone Angular component.

doc-cmp-nr-api-example.component.ts

ts
import { Component, signal } from '@angular/core';
import { TngNumberRangeComponent } from '@tailng-ui/components';
import type { TngNumberRangeValue, TngNumberRangeChangeEvent } from '@tailng-ui/primitives';

@Component({
  selector: 'app-doc-cmp-nr-api-example',
  standalone: true,
  imports: [TngNumberRangeComponent],
  template: `
    <tng-number-range
      [min]="0"
      [max]="1000"
      [step]="10"
      [value]="range()"
      minPlaceholder="Min price"
      maxPlaceholder="Max price"
      ariaLabel="Price range"
      minAriaLabel="Minimum price"
      maxAriaLabel="Maximum price"
      (valueChange)="range.set($event)"
      (rangeChange)="onRangeChange($event)"
    ></tng-number-range>
  `,
})
export class DocCmpNrApiExampleComponent {
  protected readonly range = signal<TngNumberRangeValue>({ min: 100, max: 500 });

  protected onRangeChange(event: TngNumberRangeChangeEvent): void {
    console.log(event.source, event.value, event.valid);
  }
}

Inputs reference

InputTypeDefaultDetails
valueTngNumberRangeValue | nullnullControlled value. When provided, drives the displayed min/max values. Both fields can independently be null to represent an empty input.
defaultValueTngNumberRangeValue | nullnullInitial value for uncontrolled usage. Applied once at initialization; not tracked thereafter.
minnumber | string | nullnullLower bound for both inputs. Forwarded as the native min attribute and used for built-in validity checking. Accepts string input which is normalized to a number.
maxnumber | string | nullnullUpper bound for both inputs. Forwarded as the native max attribute and used for built-in validity checking.
stepnumber | string | nullnullStep interval for both inputs. Forwarded as the native step attribute. Pass "any" to allow any decimal value.
disabledboolean | stringfalseDisables both inputs. Legacy Angular forms can also set this through the explicit adapter.
readonlyboolean | stringfalseMarks both inputs as read-only. Reflects data-readonly to the host and group.
requiredboolean | stringfalseForwards the required attribute to both native inputs.
invalidboolean | stringfalseExplicitly forces the invalid visual state regardless of computed validity.
minPlaceholderstring''Placeholder text for the min input.
maxPlaceholderstring''Placeholder text for the max input.
separatorstring'—'Text rendered between the min and max inputs. Can be any string or symbol.
ariaLabelstring | nullnullAccessible label for the outer role="group" container.
ariaLabelledbystring | nullnullID of an external element that labels the group. Alternative to ariaLabel.
minAriaLabelstring'Minimum'Accessible label for the min input. Override for more descriptive screen-reader text.
maxAriaLabelstring'Maximum'Accessible label for the max input. Override for more descriptive screen-reader text.
slotPartial<Record<TngNumberRangeSlots, string>>{}Additional CSS class names to merge onto internal slot elements. Keys: root, group, minInput, separator, maxInput.

The [slot] input lets you attach extra classes to any internal element:

Slot class customization

html
<tng-number-range
  ariaLabel="Price range"
  [slot]="{
    root: 'my-range-root',
    group: 'my-range-group',
    minInput: 'my-range-min',
    separator: 'my-range-sep',
    maxInput: 'my-range-max'
  }"
></tng-number-range>

Outputs reference

OutputTypeDetails
valueChangeoutput<TngNumberRangeValue>Emits on every input event from either field with the current { min, max } value object. Use for two-way binding or controlled state updates.
rangeChangeoutput<TngNumberRangeChangeEvent>Emits the full change event including the updated value, the source field ('min' or 'max'), and the computed valid boolean.

Angular Signal Forms bind the component directly through its value model. Legacy Angular forms require the explicit tngAngularForms adapter marker.

Forms featureDetails
Angular formsSignal Forms use [formField]. Template-driven (ngModel) and reactive forms (formControlName, formControl) use tngAngularForms.
Value typeTngNumberRangeValue{ min: number | null; max: number | null }
Disabled stateControlled by the component input or the optional legacy forms adapter.

Types reference

All types are exported from @tailng-ui/primitives.

Exported types

ts
/** The value object held and emitted by the component. */
type TngNumberRangeValue = {
  min: number | null;
  max: number | null;
};

/** Which input triggered the change. */
type TngNumberRangeSource = 'min' | 'max';

/** Full change event including source and validity. */
type TngNumberRangeChangeEvent = {
  value: TngNumberRangeValue;
  source: TngNumberRangeSource;
  valid: boolean;
};

/** CSS class override targets. */
type TngNumberRangeSlots = 'root' | 'group' | 'minInput' | 'separator' | 'maxInput';

Host state attributes

AttributeLocationWhen present
data-disabledHost element & inner groupWhen disabled is true or the legacy form control is disabled.
data-readonlyHost element & inner groupWhen readonly is true.
data-invalidHost element & inner groupWhen the range fails built-in validity checks or [invalid]="true" is set.