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

API reference

The default surface is tng-datepicker. When you need custom markup, use createDatepickerController(...), bindTngDatepicker(...), and the datepicker helper directives instead of wiring keyboard, focus, and ARIA behavior by hand.

The wrapper intentionally sets a few opinionated defaults on top of the controller, notably closeOnSelect, trapFocus, and autoCommitView.

tng-datepicker (component)

Wrapper attachment

html
<tng-datepicker
  [defaultValue]="'2024-04-22'"
  [minDate]="'2024-04-01'"
  [maxDate]="'2026-03-31'"
  selectionMode="single"
  ariaLabel="Invoice date"
></tng-datepicker>

Selection and value

PropertyTypeDefaultDetails
defaultValueTngDateSelectionInput<TDate> | undefinedundefinedSets the uncontrolled initial selection.
valueTngDateSelectionInput<TDate> | undefinedundefinedControls the committed selection from the outside.
selectionMode'single' | 'range' | 'multiple''single'Changes the value model and selection behavior without changing the wrapper UI contract.
allowDeselectbooleanfalseLets a second click clear the current selection in single mode.
minDate / maxDateTngDateInputValue<TDate> | undefinedundefinedDisables out-of-range days, months, and years.
disableDate((date: TDate) => boolean) | nullnullDisables individual dates inside the otherwise valid range.
todayTngDateInputValue<TDate> | undefinedundefinedOverrides which date is marked as today in the grid.

Interaction and behavior

PropertyTypeDefaultDetails
allowManualInputbooleantrueAllows typing directly into the field and committing valid values.
autoCommitViewbooleanfalseControls whether the wrapper should auto-commit when drilling between year, month, and day views.
closeOnEscapebooleantrueCloses the popup when Escape is pressed.
closeOnOutsideClickbooleantrueDismisses the popup when pointer or focus moves outside.
closeOnSelectbooleantrueCloses after a committed date selection.
closeOthersOnOpenbooleanfalseAsks other registered datepickers to close when this one opens.
restoreFocusbooleantrueRestores focus to the trigger after the popup closes.
showOutsideDaysbooleantrueKeeps adjacent-month days visible in day view.
trapFocusbooleantrueKeeps focus inside the popup while it is open.
weekStartsOnTngWeekdayIndex0Overrides the locale-derived start of week.

Overlay and layout

PropertyTypeDefaultDetails
defaultOpenbooleanfalseSets the uncontrolled initial open state.
openboolean | undefinedundefinedControls the popup state from the outside.
placement'auto' | 'bottom' | 'top''auto'Auto-flips the popup when there is not enough room below the field.
overlayRuntimeTngOverlayRuntime | null | undefinedInternal runtimeLets advanced apps share an overlay layer registry across surfaces.
overlaySizenumber320Sets the popup width used by the wrapper overlay positioning logic.
yearPageSizenumber24Controls how many years are shown per year page.
direction'ltr' | 'rtl''ltr'Flips navigation semantics and keyboard movement for RTL flows.

Accessibility and presentation

PropertyTypeDefaultDetails
adapterTngDateAdapter<TDate> | undefinedDefault date adapterControls parsing, formatting, and visible month or period labels.
ariaDescribedBystring | nullnullForwards an external description id to the host.
ariaLabelstring | nullnullSets a root accessible name when no visible label is present.
ariaLabelledBystring | nullnullPoints the host at an external labeling element.
disabledbooleanfalseDisables the field, trigger, and all calendar interaction.
fullWidthbooleantrueMakes the host fill the available inline size.
idstring | nullnullSeeds the generated input id and overlay relationship ids.
inputAriaLabelstring'Date input'Labels the editable text input itself.
invalidbooleanfalseForces invalid styling in addition to manual input validation state.
localestringAngular LOCALE_IDDrives weekday names, month labels, and adapter locale defaults.
placeholderstring'MM-DD-YYYY'Changes the visible hint only. Parsing still comes from the adapter.
readonlybooleanfalseMakes the text field read-only while still allowing popup selection.

Outputs

OutputTypeDetails
valueChangeTngDateValue<TDate>Emits after click, keyboard commit, or a successful manual input commit.
openChangebooleanEmits whenever the popup opens or closes.
closedTngDatepickerCloseReasonReports escape, outside, programmatic, or select close reasons.
activeDateChangeTDateEmits as keyboard focus moves through the calendar model.
viewChange'day' | 'month' | 'year'Tracks the current visible panel.
monthChangeTDateEmits when the visible month block changes.
yearChangenumberEmits when the visible year page anchor changes.

Wrapper instance methods

MethodPurpose
clear()Clears the current selection for the active selection mode and returns the wrapper to day view.
close(reason?)Programmatically closes the popup with an optional close reason.
openDatepicker()Programmatically opens the popup.
showDaysPanel() / showMonthsPanel() / showYearsPanel()Drives the visible panel explicitly when the default drill-down flow is not enough.
toggleOpen()Toggles the popup state.

Headless binding layer

Controller + Angular binding

ts
import { bindTngDatepicker, createDatepickerController } from '@tailng-ui/primitives';

readonly controller = createDatepickerController<Date>({
  ownerDocument: document,
  value: '2024-04-22',
  today: '2024-04-18',
  minDate: '2024-04-01',
  maxDate: '2026-03-31',
  closeOnSelect: true,
  trapFocus: true,
});

readonly datepicker = bindTngDatepicker(this.controller);

Field + overlay wiring

html
<section [tngDatepickerHost]="controller">
  <div data-slot="datepicker-field">
    <div #anchorShell>
      <div
        data-slot="datepicker-input-shell"
        [attr.data-invalid]="datepicker.outputs().validationError !== null ? 'true' : null"
        [attr.data-open]="datepicker.outputs().getTriggerAttributes()['data-open']"
      >
        <input [tngDatepickerInput]="controller" type="text" placeholder="MM-DD-YYYY" />
        <button [tngDatepickerTrigger]="controller" type="button">Open</button>
      </div>

      <section [tngDatepickerOverlay]="controller" [tngDatepickerOverlayAnchor]="anchorShell">
        <button [tngDatepickerPrevButton]="controller" type="button">‹</button>
        <button [tngDatepickerPeriodButton]="controller" type="button">
          {{ datepicker.periodLabel() }}
        </button>
        <button [tngDatepickerNextButton]="controller" type="button">›</button>

        <div [tngDatepickerDayGrid]="controller">
          @for (cell of datepicker.outputs().cells; track cell.id) {
            <button [tngDatepickerDayCell]="cell" type="button">{{ cell.label }}</button>
          }
        </div>
      </section>
    </div>
  </div>
</section>
HelperPurpose
bindTngDatepicker(controller)Returns signals for outputs() and periodLabel() so Angular templates can stay declarative.
[tngDatepickerHost]Applies the public root attributes such as data-open, data-view, and ARIA labels.
[tngDatepickerInput] / [tngDatepickerTrigger]Forward manual input editing, trigger registration, and wrapper-grade open and keyboard behavior.
[tngDatepickerOverlay]Ports the popup to document.body, syncs public overlay attributes, and keeps focus and positioning aligned.
[tngDatepickerPrevButton] / [tngDatepickerNextButton] / [tngDatepickerPeriodButton]Own the standard navigation and drill-down flow without per-view branching in your component.
[tngDatepickerDayGrid] / [tngDatepickerDayCell]Forward day-grid keyboarding, click handling, hover range behavior, and the public day-cell state hooks.
[tngDatepickerMonthGrid] / [tngDatepickerMonthOption] / [tngDatepickerYearGrid] / [tngDatepickerYearOption]Handle month and year picker keyboarding and selection while preserving the public slot contract.

Advanced controller options

The wrapper covers the common surface. These options are available when you work with the controller directly.

OptionTypeDefaultDetails
initialView'day' | 'month' | 'year''day'Starts the controller on a different panel than the wrapper exposes by default.
overlayMode'overlay' | 'push' | 'side''overlay'Changes how the controller models overlay layout when you are fully headless.
position'start' | 'center' | 'end''start'Changes overlay alignment relative to the field in headless layouts.
focusStrategy'active-descendant' | 'roving''roving'Lets advanced compositions opt into a different grid focus model.
maxSelectionsnumber | nullnullCaps the number of selected values in multiple mode.
onPartialInputCommitbooleanfalseAllows partial manual input commits in advanced headless flows.
preserveViewOnOpenClosebooleantrueKeeps the current panel when reopening instead of always returning to day view.
skipDisabledbooleantrueControls whether keyboard movement jumps across disabled dates.

Controller methods

MethodPurpose
getOutputs() / getState()Read the live render model or the lower-level mutable state snapshot.
open() / close() / toggleOpen()Own popup visibility when you are not using the wrapper.
setInputText(...) / commitInputText() / parseInputText(...)Support manual editing with adapter validation and bound checks.
selectDate(...) / clear() / setValue(...)Own the committed selection state directly.
showYearsPanel() / showMonthsPanel() / showDaysPanel()Drive the visible panel explicitly.
setConfig(...)Reconfigures the controller after creation for advanced custom integrations.
subscribe(...)Exposes low-level controller events when the template bindings are not enough.