Skip to content
On this page

Datetime Picker

A date time picker bootstrap by VCalendar. Styled and aligned with your current theme & styles from vanilla components. This component is just a wrapper around the original component with a few tweaks to make it work with vanilla components & provide a smoother experience for daily usage So expect the same props, slots, events & more.

WARNING

This is NOT an official vanilla components component, a full-fledged date time picker takes a lot of effort, so we have just bootstrapped this one for now 😃 There are plans to port an official datetime picker. But meanwhile enjoy this amazing experience by V-Calendar!

Note: Please keep in mind for this case you must include the CSS file. Please check the theme

Install V-Calendar

Start by installing the VCalendar for this case we will be using the @next branch as it is the latest version and supports vue 3.

bash
pnpm add v-calendar@next
bash
yarn add v-calendar@next
bash
npm install v-calendar@next

Tailwind, Theme & Style

Because you cannot really use the full power of Vanilla Components here and name your classes, a CSS file must be included to match your styles. While you can do this on your own and use direct the v-calendar css file, we have prepared a small CSS file that you can use to match your theme, the same theme being used with your Vanilla Components setup, in case you are using Tailwind CSS, you can check the Tailwind CSS Configuration section for more info.

We leverage the colors.primary from TailwindCSS to match you current theme, same with the dark mode via class.

Create a file in your project and name it for ex: v-calendar.pcss or v-calendar.css and add the following content assuming you are using post-css & postcss-nesting:

css
/** Ex: styles/v-calendar.css */
@import 'v-calendar/dist/style.css';

.vc-base-select select{
    @apply border-0;
}

:root{
    --vc-color: theme('colors.gray.500');
    --vc-white: #ffffff;
    --vc-black: #000000;
    --vc-gray-50: theme('colors.gray.50');
    --vc-gray-100: theme('colors.gray.100');
    --vc-gray-200: theme('colors.gray.200');
    --vc-gray-300: theme('colors.gray.300');
    --vc-gray-400: theme('colors.gray.400');
    --vc-gray-500: theme('colors.gray.500');
    --vc-gray-600: theme('colors.gray.600');
    --vc-gray-700: theme('colors.gray.700');
    --vc-gray-800: theme('colors.gray.800');
    --vc-gray-900: theme('colors.gray.900');
}

.vc-indigo {
    --vc-color: theme('colors.gray.500');
    --vc-accent-50: theme('colors.primary.50');
    --vc-accent-100: theme('colors.primary.100');
    --vc-accent-200: theme('colors.primary.200');
    --vc-accent-300: theme('colors.primary.300');
    --vc-accent-400: theme('colors.primary.400');
    --vc-accent-500: theme('colors.primary.500');
    --vc-accent-600: theme('colors.primary.600');
    --vc-accent-700: theme('colors.primary.700');
    --vc-accent-800: theme('colors.primary.800');
    --vc-accent-900: theme('colors.primary.900');
}

Preview & Playground 🖼️

Here you may find a preview of the component, with error & possible variants.

🏄 Click to expand the code
vue
<script setup lang="ts">
import { DateTimeInput } from '@flavorly/vanilla-components'
import { ref } from 'vue'

const value = ref('2011-01-01 0:00:01')
const rangeValue = ref({})
const dragValue = ref(null)
const selectDragAttribute = {
  popover: {
    visibility: 'hover',
    isInteractive: false, // Defaults to true when using slot
  },
}
</script>

<template>
  <PreviewWrapper>
    <client-only>
      <div>
        <!-- Range -->
        <DateTimeInput
          v-model="rangeValue"
          :minute-increment="5"
          :is-required="false"
          :is-range="true"
          :inline="false"
          mode="dateTime"
          :select-attribute="selectDragAttribute"
          :drag-attribute="selectDragAttribute"
          placeholder="Please select your date range"
          @drag="dragValue = $event"
        >
          <template #day-popover="{ format }">
            <div>
              {{ format(dragValue ? dragValue.start : rangeValue.start, 'MMM D') }}
              -
              {{ format(dragValue ? dragValue.end : rangeValue.end, 'MMM D') }}
            </div>
          </template>
        </DateTimeInput>

        <div class="flex items-center justify-center mx-auto text-center mt-2">
          <pre class="text-xs">From: {{ JSON.stringify(rangeValue?.start) || '-' }} | To: {{ JSON.stringify(rangeValue?.end) || '-' }}</pre>
        </div>
      </div>

      <div class="mt-5">
        <!-- Simple -->
        <DateTimeInput
          v-model="value"
          :is-required="false"
          :inline="false"
          mode="date"
          errors="This field can also get an errors"
          placeholder="Please select your date"
        />

        <div class="flex items-center justify-center mx-auto text-center mt-2">
          <pre class="text-xs">{{ JSON.stringify(value) || '-' }}</pre>
        </div>
      </div>

      <div class="">
        <!-- Inline -->
        <div class="mt-5 flex items-center justify-center mx-auto">
          <DateTimeInput
            v-model="rangeValue"
            :inline="true"
            :is-range="true"
            mode="dateTime"
            is24hr
            placeholder="Please select your date"
            @drag="dragValue = $event"
          >
            <template #day-popover="{ format }">
              <div>
                {{ format(dragValue ? dragValue.start : rangeValue.start, 'MMM D') }}
                -
                {{ format(dragValue ? dragValue.end : rangeValue.end, 'MMM D') }}
              </div>
            </template>
          </DateTimeInput>
        </div>

        <div class="flex items-center justify-center mx-auto text-center mt-2">
          <pre class="text-xs">From: {{ JSON.stringify(rangeValue?.start) || '-' }} | To: {{ JSON.stringify(rangeValue?.end) || '-' }}</pre>
        </div>
      </div>
    </client-only>
  </PreviewWrapper>
</template>

Props 📥

Props available for this component extending the default variant & global props.

PropDescriptionAccepted ValuesDefault
modelValueThe value for the elementAnyundefined
optionsV-Calendar OptionsObjectundefined
typeType of inputString'text'

Slots 🧬

Current slots available for this component are the following:

All the default slots of VCalendar are available normally for usage. The default slot is pre-filled, please check Below.

Slot default

This is the default slot of the component, by default a Vanilla Text Input is used to display the value. But you are free to use whatever you want for this slot, the slot is also forwarded to the V-Calendar component.

AttributeDescriptionType
classNameClasses injectedString

Released under the MIT License.