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

@libs-ui/components-datetime-input

v0.2.356-1

Published

> **Version**: 0.2.355-15

Readme

Datetime Input Component

Version: 0.2.355-15

Component nhập giờ phút với hỗ trợ single time và time range, tự động format và validation.

Tính năng

  • Single Time Input: Nhập giờ phút đơn giản (HH:mm)
  • Time Range Input: Nhập khoảng thời gian (From - To)
  • Auto Format: Tự động format thành HH:mm khi blur
  • Auto Focus: Tự động chuyển focus giữa hours và minutes
  • Validation: Hỗ trợ validation required và compare time
  • Real-time Emit: Emit data real-time khi nhập
  • Keyboard Support: Hỗ trợ đầy đủ keyboard navigation
  • FunctionsControl: Điều khiển component từ bên ngoài

Khi nào sử dụng

  • Khi cần nhập giờ phút đơn giản (HH:mm)
  • Khi cần nhập khoảng thời gian (From - To)
  • Khi cần validation cho time input (required, compare time)
  • Khi cần so sánh thời gian bắt đầu và kết thúc
  • Khi cần format time input tự động
  • Khi cần emit data real-time trong quá trình nhập

Important Notes

⚠️ ISelectedMultiTime sử dụng WritableSignal — phải tạo bằng signal() khi truyền vào [selectedTime]

⚠️ Mặc định [ignoreAllowEqualTime]="true" — From và To bằng nhau sẽ bị coi là lỗi khi dùng isCheckErrorTimeEndGreaterTimeStart

⚠️ Auto Focus tự động chuyển focus: hours → minutes → toHours → toMinutes khi nhập đủ ký tự

⚠️ Component tự động format thành HH:mm khi blur (vd: nhập "9" → hiển thị "09")

⚠️ Validation chỉ chạy khi không ở trạng thái disable hoặc readonly

Installation

npm install @libs-ui/components-datetime-input

Usage

Basic Single Time

import { Component } from '@angular/core';
import { LibsUiComponentsDatetimeInputComponent, ISelectedTimeInput } from '@libs-ui/components-datetime-input';

@Component({
  selector: 'app-example',
  standalone: true,
  imports: [LibsUiComponentsDatetimeInputComponent],
  template: `
    <libs_ui-components-datetime-input
      [labelConfig]="{ labelLeft: 'Chọn giờ' }"
      (outEmitSingleTime)="onTimeSelected($event)" />
  `,
})
export class ExampleComponent {
  onTimeSelected(event: ISelectedTimeInput) {
    console.log('Time:', event); // { hours: 9, minute: 30 }
  }
}

Time Range

import { Component } from '@angular/core';
import { LibsUiComponentsDatetimeInputComponent, ISelectedMultiTime } from '@libs-ui/components-datetime-input';

@Component({
  selector: 'app-example',
  standalone: true,
  imports: [LibsUiComponentsDatetimeInputComponent],
  template: `
    <libs_ui-components-datetime-input
      [multiTime]="true"
      [labelConfig]="{ labelLeft: 'Khoảng giờ' }"
      (outEmitMultiTime)="onTimeRangeSelected($event)" />
  `,
})
export class ExampleComponent {
  onTimeRangeSelected(event: ISelectedMultiTime) {
    console.log('From:', event.from?.());
    console.log('To:', event.to?.());
  }
}

With Preset Value

import { Component, signal } from '@angular/core';
import { ISelectedMultiTime } from '@libs-ui/components-datetime-input';

@Component({
  // ...
  template: `
    <libs_ui-components-datetime-input
      [multiTime]="true"
      [selectedTime]="selectedTime()"
      [labelConfig]="{ labelLeft: 'Giờ làm việc' }"
      (outEmitMultiTime)="onTimeRangeSelected($event)" />
  `,
})
export class ExampleComponent {
  // ⚠️ from và to PHẢI là WritableSignal
  readonly selectedTime = signal<ISelectedMultiTime>({
    from: signal({ hours: 9, minute: 30 }),
    to: signal({ hours: 17, minute: 0 }),
  });

  onTimeRangeSelected(event: ISelectedMultiTime) {
    console.log('Time range:', event);
  }
}

With Validation

import { Component } from '@angular/core';

@Component({
  // ...
  template: `
    <libs_ui-components-datetime-input
      [multiTime]="true"
      [validRequired]="{ message: 'Vui lòng nhập giờ' }"
      [validCompareTime]="{
        message: 'Giờ kết thúc phải lớn hơn giờ bắt đầu',
        isCheckErrorTimeEndGreaterTimeStart: true,
      }"
      (outEmitMultiTime)="onTimeRangeSelected($event)"
      (outEmitValid)="onValidChange($event)" />
  `,
})
export class ExampleComponent {
  onTimeRangeSelected(event: ISelectedMultiTime) {
    console.log('Time range:', event);
  }

  onValidChange(valid: { validRequired: boolean; validCompare: boolean }) {
    console.log('Validation:', valid);
  }
}

FunctionsControl

import { Component, signal } from '@angular/core';
import { IDateTimeInputFunctionControlEvent } from '@libs-ui/components-datetime-input';

@Component({
  // ...
  template: `
    <libs_ui-components-datetime-input
      [multiTime]="true"
      [validRequired]="{ message: 'Vui lòng nhập giờ' }"
      (outFunctionsControl)="controls.set($event)"
    />
  `,
})
export class ExampleComponent {
  controls = signal<IDateTimeInputFunctionControlEvent | null>(null);

  async validate() {
    const isValid = await this.controls()?.checkIsValid();
    console.log('Valid:', isValid);
  }

  async setError() {
    await this.controls()?.setMessageError('Thời gian không hợp lệ');
  }

  async resetError() {
    await this.controls()?.resetError();
  }
}

API

Inputs

| Property | Type | Default | Description | | ---------------------------------------- | -------------------------------- | ----------------- | ------------------------------------------------------------------------------- | | [classDatePickerInput] | string | undefined | CSS class cho date picker input | | [classIncludeBetweenTime] | string | undefined | CSS class cho phần between time (dấu -) | | [classIncludeInput] | string | libs-ui-font-h5r| CSS class cho input element | | [defaultHeight] | number | 28 | Chiều cao mặc định của input (px) | | [disable] | boolean | false | Disable input | | [emitDataSingleDataWhenUseMultiTime] | boolean | false | Emit data riêng từng phần khi dùng multiTime | | [fromAndToDateLabel] | { from?: string; to?: string } | undefined | Label cho From và To | | [ignoreAllowEqualTime] | boolean | true | Khi true, From = To bị coi là lỗi (với isCheckErrorTimeEndGreaterTimeStart) | | [ignoreBorder] | boolean | false | Ẩn border của input | | [ignoreCheckValidWhenInput] | boolean | false | Bỏ qua validate khi nhập từ bàn phím | | [ignoreMultiIcon] | boolean | false | Ẩn icon giữa 2 time range | | [ignoreShowValid] | boolean | false | Ẩn hiển thị lỗi validation | | [ignoreWithDefault] | boolean | false | Bỏ qua giá trị default | | [isEmitRealTime] | boolean | false | Emit data real-time khi nhập (mỗi keystroke) | | [labelConfig] | ILabel | undefined | Cấu hình label (labelLeft, required, ...) | | [multiTime] | boolean | false | Chế độ chọn time range (From - To) | | [readonly] | boolean | false | Readonly mode | | [resetInput] | boolean | true | Cho phép reset input | | [selectedTime] | ISelectedMultiTime | undefined | Giá trị time được set sẵn (sử dụng WritableSignal) | | [showBorderError] | boolean | false | Hiển thị border error state | | [validCompareTime] | IValidCompare | undefined | Cấu hình validation so sánh time | | [validRequired] | IMessageTranslate | undefined | Cấu hình validation required |

Outputs

| Property | Type | Description | | ----------------------- | --------------------------------------------------- | ------------------------------------------------------ | | (outClickButtonLabel) | IButton | Event khi click button trên label | | (outEmitMultiTime) | ISelectedMultiTime | Event khi chọn time range (cả from và to) | | (outEmitRealTime) | ISelectedMultiTime | Event emit real-time khi nhập (mỗi keystroke) | | (outEmitSingleTime) | ISelectedTimeInput | Event khi chọn single time | | (outEmitValid) | { validRequired: boolean; validCompare: boolean } | Event trạng thái validation | | (outFunctionsControl) | IDateTimeInputFunctionControlEvent | Emit functions để điều khiển component từ bên ngoài | | (outLabelRightClick) | boolean | Event khi click label bên phải | | (outResetTime) | ISelectedMultiTime \| undefined | Event khi reset time | | (outSwitchEventLabel) | ISwitchEvent | Event khi switch trên label thay đổi |

FunctionsControl Methods

| Method | Description | | ----------------------------- | -------------------------------------------------- | | checkIsValid() | Kiểm tra validation và trả về Promise<boolean> | | resetError(resetAll?) | Reset tất cả trạng thái lỗi | | setMessageError(message) | Đặt message lỗi tùy chỉnh (undefined để xóa) |

Types

ISelectedTimeInput

export interface ISelectedTimeInput {
  hours?: string | number;
  minute?: string | number;
}

ISelectedMultiTime

export interface ISelectedMultiTime {
  from?: WritableSignal<ISelectedTimeInput>;
  to?: WritableSignal<ISelectedTimeInput>;
}

IValidCompare

export interface IValidCompare extends IMessageTranslate {
  isCheckErrorTimeEndGreaterTimeStart?: boolean;
  isCheckErrorTimeDuplicate?: boolean;
}

IDateTimeInputFunctionControlEvent

export interface IDateTimeInputFunctionControlEvent {
  checkIsValid: () => Promise<boolean>;
  resetError: (resetAll?: boolean) => Promise<void>;
  setMessageError: (message: string | undefined) => Promise<void>;
}

Hidden Logic

Signal Auto-Unwrapping trong selectedTime

Khi truyền [selectedTime], component sử dụng effect() để watch thay đổi. Giá trị from/toWritableSignal, component sẽ gọi .() để unwrap. Nếu truyền plain object thay vì signal sẽ gây lỗi.

Backspace Navigation

Khi nhấn Backspace ở ô trống, component tự động focus về ô trước đó (toMinutes → toHours → fromMinutes → fromHours). Cần nhấn Backspace 2 lần: lần 1 xóa giá trị, lần 2 chuyển focus.

Input Dependencies — ignoreCheckValidWhenInput

Khi [ignoreCheckValidWhenInput]="true", validation sẽ KHÔNG chạy ngay khi nhập từ bàn phím, chỉ chạy khi gọi checkIsValid() từ FunctionsControl.

Demo

Test

nx test components-datetime-input

License

MIT