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

@archpublicwebsite/rangepicker

v1.0.14

Published

Custom date range picker component for PBA Hotel Apps

Readme

@archpublicwebsite/rangepicker

Custom, lightweight date range picker component for Vue 3 with Tailwind CSS prefix support.

Features

  • 🎨 Vue 3 Composition API - Built with modern Vue 3 and TypeScript
  • 📦 CSS Prefix Support - All Tailwind classes prefixed with arch- to prevent conflicts with Vuetify/Bootstrap
  • 📅 Dayjs Integration - Powerful date manipulation without moment.js bloat
  • 🎨 Themeable - Easy color customization via props (HEX colors)
  • 📱 Mobile Responsive - Touch-friendly with bottom sheet on mobile
  • 🎯 Smart Positioning - Auto-adjusts based on available viewport space
  • Accessible - Keyboard navigation and screen reader support
  • 🚀 SSR Compatible - Works perfectly with Nuxt 3
  • 🪶 Lightweight - ~49KB CSS (gzipped: 5.3KB), ~40KB JS (gzipped: 9.4KB)

Installation

npm install @archpublicwebsite/rangepicker
# or
pnpm add @archpublicwebsite/rangepicker
# or
yarn add @archpublicwebsite/rangepicker

Quick Start

Important: You must import both the component AND the CSS file.

<script setup>
import { ref } from 'vue'
import { RangepickerInput } from '@archpublicwebsite/rangepicker'
import '@archpublicwebsite/rangepicker/style.css' // Required!

const dates = ref('')
</script>

<template>
  <RangepickerInput
    v-model="dates"
    primary-color="#3b82f6"
    placeholder="Check in / Check out"
  />
</template>

TypeScript Support

Full TypeScript support with exported types for type-safe development:

<script setup lang="ts">
import { ref } from 'vue'
import {
  RangepickerInput,
  type RangepickerProps,
  type DateRange
} from '@archpublicwebsite/rangepicker'
import '@archpublicwebsite/rangepicker/style.css'

// Type-safe date range
const dates = ref<DateRange>({ startDate: '', endDate: '' })

// Type-safe props configuration
const pickerOptions: Partial<RangepickerProps> = {
  format: 'DD/MM/YYYY',
  autoApply: true,
  minDays: 2,
  maxDays: 30,
  showTooltip: true
}
</script>

<template>
  <RangepickerInput
    v-model="dates"
    v-bind="pickerOptions"
    primary-color="#3b82f6"
    placeholder="Check in / Check out"
  />
</template>

Why separate CSS import?

  • Better performance (CSS cached independently)
  • Smaller JS bundle
  • No Flash of Unstyled Content (FOUC)
  • Industry standard (like Vuetify, Element Plus, etc.)

Tailwind CSS Prefix: All Tailwind utility classes are prefixed with arch- to prevent conflicts with other CSS frameworks like Vuetify or Bootstrap. Your existing styles won't be affected!

Color Customization

Customize colors easily by passing HEX color values as props. Each rangepicker instance can have its own color scheme:

<script setup>
import { ref } from 'vue'
import { RangepickerInput } from '@archpublicwebsite/rangepicker'
import '@archpublicwebsite/rangepicker/style.css'

const dates1 = ref('')
const dates2 = ref('')
const dates3 = ref('')
</script>

<template>
  <!-- Blue theme -->
  <RangepickerInput
    v-model="dates1"
    primary-color="#3b82f6"
    secondary-color="#60a5fa"
    placeholder="Blue theme"
  />

  <!-- Purple theme -->
  <RangepickerInput
    v-model="dates2"
    primary-color="#8b5cf6"
    secondary-color="#a78bfa"
    placeholder="Purple theme"
  />

  <!-- Red theme -->
  <RangepickerInput
    v-model="dates3"
    primary-color="#ef4444"
    secondary-color="#f87171"
    placeholder="Red theme"
  />
</template>

Color Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | primary-color | string | - | Main color for selected dates and buttons (HEX format, e.g., #3b82f6) | | secondary-color | string | - | Color for hover states and secondary elements (HEX format, optional) |

Features:

  • Scoped per instance - Multiple pickers can have different colors simultaneously
  • No global state - Colors don't conflict between instances
  • HEX format - Standard 3 or 6 digit HEX colors (e.g., #3b82f6, #fff)
  • Auto-conversion - Automatically converts HEX to RGB for CSS variables
  • Optional - Falls back to default theme if not provided

Framework Compatibility

This package is designed to work seamlessly with any Vue 3 framework:

  • Vuetify - No CSS conflicts thanks to arch- prefix
  • Bootstrap - Works alongside Bootstrap utilities
  • Element Plus - Fully compatible
  • Quasar - No issues
  • Plain Vue 3 - Works great standalone
  • Nuxt 3 - SSR compatible

The arch- prefix on all Tailwind classes ensures zero conflicts with other CSS frameworks.

Usage

With Vuetify (Recommended)

<script setup>
import { ref } from 'vue'
import { RangepickerInput } from '@archpublicwebsite/rangepicker'
import '@archpublicwebsite/rangepicker/style.css'
import '@archpublicwebsite/rangepicker/style.css'

const dates = ref('')
const options = {
  autoApply: true,
  minDate: new Date(),
  format: 'DD MMM YYYY',
  numberOfColumns: 2,
  numberOfMonths: 2,
}
</script>

<template>
  <v-container>
    <RangepickerInput
      v-model="dates"
      :options="options"
      primary-color="#1976d2"
      placeholder="Check in / Check out"
      class="my-custom-input"
    />
  </v-container>
</template>

Basic Usage

<script setup lang="ts">
import { ref, computed } from 'vue'
import { Rangepicker, type DateRange } from '@archpublicwebsite/rangepicker'
import '@archpublicwebsite/rangepicker/style.css'

const triggerRef = ref<HTMLElement | null>(null)
const isOpen = ref(false)
const dateRange = ref<DateRange>({ startDate: '', endDate: '' })

const dateRangeText = computed(() => {
  if (!dateRange.value.startDate || !dateRange.value.endDate) return ''
  return `${dateRange.value.startDate} - ${dateRange.value.endDate}`
})
</script>

<template>
  <div>
    <input
      ref="triggerRef"
      type="text"
      :value="dateRangeText"
      placeholder="Select dates"
      readonly
      @click="isOpen = true"
    />

    <Rangepicker
      v-model="dateRange"
      v-model:is-open="isOpen"
      :trigger-element="triggerRef"
      :value-of-months="2"
      format="DD MMM YYYY"
    />
  </div>
</template>

Using the Composable

<script setup lang="ts">
import { ref } from 'vue'
import {
  Rangepicker,
  useRangepicker,
  type RangepickerProps
} from '@archpublicwebsite/rangepicker'
import '@archpublicwebsite/rangepicker/style.css'

const triggerRef = ref<HTMLElement | null>(null)

// Type-safe composable options
const options: Partial<RangepickerProps> = {
  valueOfMonths: 2,
  format: 'DD MMM YYYY',
  minDays: 1,
  autoApply: true
}

const { isOpen, dateRange, open, close, toggle } = useRangepicker(triggerRef, options)
</script>

<template>
  <div>
    <button ref="triggerRef" @click="toggle">
      {{ dateRange.startDate && dateRange.endDate
        ? `${dateRange.startDate} - ${dateRange.endDate}`
        : 'Select dates' }}
    </button>

    <Rangepicker
      v-model="dateRange"
      v-model:is-open="isOpen"
      :trigger-element="triggerRef"
      v-bind="options"
    />
  </div>
</template>

Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | modelValue | { startDate?: string \| Date \| Dayjs, endDate?: string \| Date \| Dayjs } | {} | Selected date range | | isOpen | boolean | false | Controls picker visibility | | variant | 'desktop' \| 'mobile' | 'desktop' | Display variant | | primaryColor | string | - | Primary color in HEX format (e.g., #3b82f6) | | secondaryColor | string | - | Secondary color in HEX format (e.g., #60a5fa) | | minDate | string \| Date \| Dayjs | - | Minimum selectable date | | maxDate | string \| Date \| Dayjs | - | Maximum selectable date | | minDays | number | - | Minimum number of days in range | | maxDays | number | - | Maximum number of days in range | | valueOfMonths | number | 2 | Number of months to display | | valueOfColumns | number | 2 | Grid columns for months | | disabledDates | (string \| Date)[] | [] | Array of disabled dates | | holidays | (string \| Date)[] | [] | Array of holiday dates | | format | string | 'YYYY-MM-DD' | Date format | | delimiter | string | ' - ' | Delimiter between dates | | placeholder | string | 'Select dates' | Placeholder text | | label | string | - | Label for the picker | | showTooltip | boolean | true | Show night count tooltip | | autoApply | boolean | false | Auto-apply selection | | position | 'auto' \| 'top' \| 'bottom' | 'auto' | Positioning strategy | | triggerElement | HTMLElement \| null | - | Trigger element for positioning |

Events

| Event | Payload | Description | |-------|---------|-------------| | update:modelValue | { startDate: string, endDate: string } | Emitted when date range changes | | update:isOpen | boolean | Emitted when picker opens/closes | | dateSelected | Dayjs | Emitted when a date is clicked | | rangeSelected | { start: Dayjs, end: Dayjs } | Emitted when range is complete |

TypeScript Support

This package is built with TypeScript and provides full type definitions. All types are automatically exported for your convenience.

Available Types

import type {
  RangepickerProps,    // Component props interface
  RangepickerEmits,    // Event emitter interface
  DateRange,           // Date range object type
  CalendarDay,         // Internal calendar day type
  CalendarMonth        // Internal calendar month type
} from '@archpublicwebsite/rangepicker'

Type Definitions

RangepickerProps

Complete props interface with JSDoc documentation. All props are optional with sensible defaults:

interface RangepickerProps {
  modelValue?: { startDate?: string | Date | Dayjs; endDate?: string | Date | Dayjs }
  isOpen?: boolean
  variant?: 'desktop' | 'mobile'
  minDate?: string | Date | Dayjs
  maxDate?: string | Date | Dayjs
  minDays?: number
  maxDays?: number
  close?: boolean
  valueOfMonths?: number  // default: 2
  valueOfColumns?: number // default: 2
  disabledDates?: (string | Date)[]
  holidays?: (string | Date)[]
  format?: string         // default: 'YYYY-MM-DD'
  delimiter?: string      // default: ' - '
  placeholder?: string
  label?: string
  showTooltip?: boolean   // default: true
  autoApply?: boolean     // default: false
  position?: 'auto' | 'top' | 'bottom'
  triggerElement?: HTMLElement | null
  colorStyles?: Record<string, string>
}

DateRange

Type for the v-model binding:

interface DateRange {
  startDate: string
  endDate: string
}

RangepickerEmits

Event emitter types for type-safe event handling:

interface RangepickerEmits {
  'update:modelValue': [value: { startDate: string; endDate: string }]
  'update:isOpen': [value: boolean]
  'dateSelected': [date: Dayjs]
  'rangeSelected': [start: Dayjs, end: Dayjs]
}

Usage Examples

Type-Safe Component Props

import type { RangepickerProps } from '@archpublicwebsite/rangepicker'

// Define props with autocomplete support
const config: Partial<RangepickerProps> = {
  format: 'DD/MM/YYYY',
  minDays: 2,
  maxDays: 30,
  autoApply: true,
  showTooltip: true
}

Type-Safe Event Handlers

import type { Dayjs } from 'dayjs'

function handleDateSelected(date: Dayjs) {
  console.log('Selected:', date.format('YYYY-MM-DD'))
}

function handleRangeSelected(start: Dayjs, end: Dayjs) {
  const nights = end.diff(start, 'day')
  console.log(`Booking: ${nights} nights`)
}

Type-Safe Refs

import { ref } from 'vue'
import type { DateRange } from '@archpublicwebsite/rangepicker'

const dateRange = ref<DateRange>({ startDate: '', endDate: '' })
const holidays = ref<string[]>(['2025-12-25', '2025-01-01'])
const disabledDates = ref<Date[]>([new Date('2025-12-24')])

IDE Support

With the exported types, you'll get:

  • Autocomplete - IntelliSense for all props and events
  • Type Checking - Compile-time error detection
  • Documentation - Hover tooltips with prop descriptions and default values
  • Refactoring - Safe rename and refactor operations
  • Error Prevention - Catch typos and incorrect prop usage before runtime

Development

# Install dependencies
pnpm install

# Start dev server with demo
pnpm dev

# Build package
pnpm build

# Type check
pnpm type-check

# Preview build
pnpm preview

CSS Architecture

The component uses Tailwind CSS with arch- prefix to prevent conflicts with other frameworks:

Why the prefix?

  • Zero conflicts with Vuetify, Bootstrap, Element Plus, etc.
  • Safe to use alongside any CSS framework
  • All utilities prefixed: .arch-flex, .arch-text-sm, .arch-bg-white, etc.
  • Custom classes untouched: .rangepicker-* classes remain unprefixed

Styling Options

  1. Color Props (Easiest):
<RangepickerInput
  primary-color="#3b82f6"
  secondary-color="#60a5fa"
/>
  1. CSS Variables (Global):
:root {
  --color-primary: 59 130 246;      /* RGB format */
  --color-secondary: 148 163 184;
}
  1. Custom CSS Overrides:
/* Override component styles */
.rangepicker-day-selected {
  background-color: purple !important;
}

Troubleshooting

Styles not showing

Make sure you imported the CSS:

import '@archpublicwebsite/rangepicker/style.css'

CSS conflicts with Vuetify

This should NOT happen thanks to the arch- prefix. If you see conflicts, please open an issue.

TypeScript errors

Ensure vue is installed as a dependency in your project.

Browser Support

  • Chrome/Edge (latest 2 versions)
  • Firefox (latest 2 versions)
  • Safari (latest 2 versions)
  • Mobile Safari (iOS 14+)
  • Chrome for Android (latest)

Contributing

See the main repository README for contribution guidelines.

License

MIT © Archipelago International