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

@akreid/ampm-timepicker

v1.2.7

Published

A custom web component timepicker supporting AM/PM and 24-hour formats.

Readme

Note: This document has been translated using AI.

ampmTimepicker.js Usage Guide

🇰🇷 한국어 버전

npm version npm downloads npm total downloads License: MIT

js

⚠️ v1.2.0 Update Notice (Styling Changes) Starting from this update, the component now inherits fonts and colors from its parent element and supports automatic dark mode. As a result, its appearance might look slightly different when updating from older versions. However, it will now blend much more naturally with your default website styles without requiring manual CSS tweaks.

<time-picker> is a zero-dependency, vanilla JavaScript timepicker implemented as a native Custom Web Component. It works seamlessly in any environment without frameworks like React or Vue. It supports both AM/PM 12-hour and 24-hour formats and includes an intuitive UI with built-in keyboard accessibility (arrow keys and tab navigation).

Demo

https://akreid.github.io/ampmTimepicker/

1. Using ES Module (Recommended)

If your project supports ES modules, it's best to install it via npm and import it.

# Install via npm
npm install @akreid/ampm-timepicker
# or via yarn
yarn add @akreid/ampm-timepicker
<!DOCTYPE html>
<html>
<head>
  <title>AmPmTimePicker Demo</title>
  <!-- Import the component as a module -->
  <script type="module" src="https://cdn.jsdelivr.net/npm/@akreid/[email protected]/ampmTimepicker.js"></script>
</head>
<body>
  <!-- Usage example -->
  <time-picker use-ampm="true" interval="15"></time-picker>
</body>
</html>

2. Using CDN (Quick Start)

You can use it immediately by adding a <script> tag to your HTML file. It is recommended to use a file path that includes the version number.

<!-- Include script (Version: 1.2.7) -->
<script src="https://cdn.jsdelivr.net/npm/@akreid/[email protected]/ampmTimepicker.js"></script>

<!-- Basic usage -->
<time-picker></time-picker>

⚙️ Attributes

You can control the picker's behavior and display format by adding attributes to the component tag.

| Attribute | Type | Default | Description | |---|---|---|---| | use-ampm | boolean | false | When set to true, it operates in an AM/PM 12-hour format. (Defaults to 24-hour format if not set) | | interval | number | 1 | Sets the minute selection interval. (e.g., 5, 10, 15) | | start-time | string | 00:00 | The minimum selectable time (Format: HH:mm, based on 24-hour format) | | end-time | string | 23:59 | The maximum selectable time (Format: HH:mm, based on 24-hour format) | | margin-right| string | 0px | Sets the right margin. (e.g., 10px) | | hide-button | boolean| false | When set to true, hides the dropdown toggle (arrow) button on the right. | | hour-label | string | null | The label displayed at the top of the Hour column in the dropdown | | min-label | string | null | The label displayed at the top of the Minute column in the dropdown | | ampm-label | string | null | The label displayed at the top of the AM/PM column in the dropdown | | disabled | boolean| false | When set to true, the component is disabled and interaction is blocked | | readonly | boolean| false | When set to true, the value cannot be changed by the user | | required | boolean| false | When set to true, the field must be filled before submitting a form | | required-message | string | null | Custom validation error message when the required condition is not met. If not provided, the browser's default localized message is used. | | name | string | null | The name of the element used for form submission | | value | string | null | The initial time value (Format: HH:mm) | | dropdown-class | string | null | A custom class name injected directly into the dynamically appended dropdown element for scoped styling |

HTML Example

<time-picker 
  use-ampm="true" 
  interval="10" 
  start-time="09:00" 
  end-time="18:30" 
  hour-label="Hour" 
  min-label="Min" 
  ampm-label="AM/PM"
  margin-right="8px">
</time-picker>

Global / Batch Configuration (JS)

If you have multiple timepickers on a single page, you can apply common attributes globally using JavaScript instead of repeating them in your HTML.

<!-- Add a common class to your timepickers -->
<time-picker class="common-time"></time-picker>
<!-- Override specific attributes directly in HTML if needed -->
<time-picker class="common-time" interval="30"></time-picker>

<script type="module">
  document.addEventListener('DOMContentLoaded', () => {
    const defaultOptions = {
      'use-ampm': 'true',
      'interval': '15',
      'hour-label': 'Hour',
      'min-label': 'Min',
      'ampm-label': 'AM/PM'
    };

    document.querySelectorAll('.common-time').forEach(picker => {
      Object.entries(defaultOptions).forEach(([key, value]) => {
        // Apply default value only if not explicitly set in HTML
        if (!picker.hasAttribute(key)) {
          picker.setAttribute(key, value);
        }
      });
    });
  });
</script>

🎨 Styling & Theming

<time-picker> natively supports Automatic Dark Mode synchronized with the OS and browser settings. Its default styles adapt naturally to the parent container's theme using native CSS System Colors.

1. CSS Custom Properties

You can override the default colors using the following CSS variables. (Old variable names are still supported, but --ampm- prefix is recommended to prevent conflicts.)

| Variable Name | Default Value | Description | |---|---|---| | --ampm-width | 165px | The total width of the input form | | --ampm-height | 42px | The total height of the input form | | --ampm-border-radius| 8px | The border-radius for all corners | | --ampm-primary-color| #007bff / #4da3ff (Dark) | Outline color on focus and active list item (hover/focus) color |

2. Internal Element & State Control (::part, Attribute Selectors)

For more granular control (like the toggle button styling) or overriding specific states (disabled, readonly), combine ::part() with attribute selectors.

  • part="container": The main wrapper container
  • part="input": The internal text input
  • part="toggle-btn": The dropdown toggle button
/* 1. Customizing the toggle button's border and icon */
time-picker::part(toggle-btn) {
  border-left: 2px dashed #ccc;
  background-image: url('custom-icon.svg');
}

/* 2. Forcing a custom background color when disabled (without using variables) */
time-picker[disabled]::part(container) {
  background-color: #ffe6e6;
  border-color: #ff0000;
}

3. Dropdown Scoped Styling Guide

The dropdown list is dynamically appended to the bottom of document.body to prevent clipping issues. For custom styling, refer to the internal DOM structure of the dropdown below:

🏗️ Dropdown DOM Structure Tree

div.ampm-timepicker-dropdown
├── div.ampm-col-wrapper
│   ├── div.ampm-header (AM/PM Header)
│   └── div.ampm-column.ampm-period-column
│       ├── div.ampm-item.ampm-active ("AM")
│       └── div.ampm-item ("PM")
├── div.ampm-col-wrapper
│   ├── div.ampm-header (Hour Header)
│   └── div.ampm-column.ampm-hour-column
│       ├── div.ampm-item ("12")
│       └── ...
└── div.ampm-col-wrapper
    ├── div.ampm-header (Minute Header)
    └── div.ampm-column.ampm-minute-column
        ├── div.ampm-item ("00")
        └── ...

Because it is appended globally, custom classes applied directly to the component do not automatically affect the dropdown. To solve this, we provide two powerful synchronization options:

1) Explicit Custom Class (dropdown-class attribute)

If you want to style the dropdown of a specific time picker instance, use the dropdown-class attribute. The class you provide will be injected directly into the dynamically created dropdown element.

<time-picker dropdown-class="my-pink-theme"></time-picker>
/* Target this specific dropdown safely in your global CSS */
.my-pink-theme { border: 2px solid pink; }
.my-pink-theme .ampm-header { background-color: #ffe6e6; }

2) Vue/Svelte Scoped CSS Auto-Support (data-* Syncing)

When using <style scoped> in frameworks like Vue or Svelte, the framework injects a unique hash (e.g., data-v-1a2b3c) into your elements. AmPmTimePicker automatically syncs all data- attributes from the <time-picker> tag directly to the appended dropdown. Therefore, framework developers can use scoped CSS seamlessly without any extra configuration!

4. ⚠️ Deprecated CSS Variables

The following highly specific CSS variables are scheduled to be completely removed in the next major version (v2.0) for optimization and standard compliance. While they will continue to work for now (via fallback), it is highly recommended to migrate your styles using the ::part() selector approach explained above.

| Deprecated Variable | Migration Guide (Recommended Alternative) | | :--- | :--- | | --ampm-bg-color | Use time-picker::part(container) { background-color: ... } | | --ampm-font-color | Use time-picker { color: ... } | | --ampm-border-color | Use time-picker::part(container) { border-color: ... } | | --ampm-toggle-border-left | Use time-picker::part(toggle-btn) { border-left: ... } | | --ampm-toggle-icon-url | Use time-picker::part(toggle-btn) { background-image: ... } | | --ampm-toggle-icon-size | Use time-picker::part(toggle-btn) { background-size: ... } | | --ampm-invalid-color | Use time-picker:invalid::part(container) { border-color: ... } | | --ampm-disabled-bg | Use time-picker[disabled]::part(container) { background-color: ... } | | --ampm-disabled-opacity | Use time-picker[disabled] { opacity: ... } | | --ampm-readonly-bg | Use time-picker[readonly]::part(container) { background-color: ... } | | --ampm-dropdown-bg--ampm-dropdown-text-color--ampm-dropdown-border-color | Use global class:.ampm-timepicker-dropdown { background-color: ...; color: ...; border-color: ...; } | | --ampm-bg-hover--ampm-dropdown-hover-bg | Use .ampm-timepicker-dropdown .ampm-item:hover { background-color: ... } | | --ampm-dropdown-header-bg | Use .ampm-timepicker-dropdown .ampm-header { background-color: ... } | | --ampm-dropdown-divider-color | Use .ampm-timepicker-dropdown .ampm-column { border-right-color: ... }.ampm-timepicker-dropdown .ampm-header { border-bottom-color: ... } | | --ampm-dropdown-scrollbar-thumb | Use .ampm-timepicker-dropdown .ampm-column::-webkit-scrollbar-thumb { background: ... } |

Note: If you want to disable automatic dark mode and force a light theme, add :root { --ampm-bg-color: #ffffff; --ampm-font-color: #333333; } to your global stylesheet.

💻 JavaScript API

1. Properties

You can get the selected time or change it dynamically through the value property.

💡 Note: The input/output format of the value is always a 24-hour HH:mm string.

const picker = document.querySelector('time-picker');

// Set a value
picker.value = '14:30'; 

// Get the current value
console.log(picker.value); // "14:30"

2. Events

change event is triggered whenever the time changes. You can check the selected value in e.detail.value.

const picker = document.querySelector('time-picker');

picker.addEventListener('change', (e) => {
  const selectedTime = e.detail.value;
  console.log('Selected time:', selectedTime); // e.g., "09:00"
});

3. Dynamic Attributes

You can dynamically modify attributes like start-time, end-time, disabled, readonly, etc., using standard DOM APIs. The component will react immediately.

const startPicker = document.getElementById('start-picker');
const endPicker = document.getElementById('end-picker');

// Create a paired constraint dynamically
startPicker.addEventListener('change', (e) => {
  if (e.detail.value) endPicker.setAttribute('start-time', e.detail.value);
  else endPicker.removeAttribute('start-time');
});

4. Form Integration

Since it supports ElementInternals, you can use it directly inside a <form> tag like a native input.

<form id="scheduleForm">
  <time-picker name="setTime"></time-picker>
  <time-picker name="startTime" start-time="08:30" value="09:00" interval="10"></time-picker>
</form>

<script>
  const scheduleForm = document.getElementById('scheduleForm');
  scheduleForm.addEventListener('submit', (e) => {
    e.preventDefault();
    
    // Use the native FormData API to easily extract values
    const formData = new FormData(scheduleForm);
    const setTime = formData.get('setTime');
    const startTime = formData.get('startTime');
    
    alert(`Selected Time: ${setTime}\nStart Work: ${startTime}`);

    // Tip: When sending to a server via fetch or axios:
    // axios.post('/api/save', Object.fromEntries(formData));
  });
</script>

⌨️ Accessibility and UX

This component is designed to be fully operable using a keyboard, in addition to a mouse.

  • Smart Typing Input: Typing numbers into the input field automatically auto-corrects to the specified format.
  • Arrow Key Navigation (Input): While the input is focused, pressing the (Up) or (Down) keys will increment/decrement the time by the interval unit.
  • Dropdown Navigation:
    • When the dropdown is open, pressing the or keys will switch focus between the AM/PM, Hour, and Minute columns.
    • Within each column, use the or keys to navigate through the values.
  • Tab Focus Control: Pressing the Tab key within the dropdown smoothly moves the focus to the next element. Logic is applied to prevent the browser address bar from capturing the focus (a common Shadow DOM focus trap issue).
  • Mobile Touch Optimization: On touch devices, the virtual keyboard is automatically disabled (inputmode="none") upon focus, preventing the screen from being obscured and allowing for a comfortable dropdown scrolling experience.
  • Screen Scroll Synchronization: Scrolling the browser window while the dropdown is open will automatically close the dropdown and commit the currently selected value.

📝 Changelog

Detailed changes for each release are documented in the CHANGELOG.md.