Skip to content
On this page

Slot Content ​

Default slot ​

When a default slot is used with VDatePicker, that content will display instead of the calendar picker.

Value:10/15/2023, 8:04:27 PM (Date)
vue
<template>
  <VDatePicker v-model="date">
    <template #default="{ togglePopover }">
      <button
        class="px-3 py-2 bg-blue-500 text-sm text-white font-semibold rounded-md"
        @click="togglePopover"
      >
        Select date
      </button>
    </template>
  </VDatePicker>
</template>

In this simple example, we display a <button /> as the default slot, and use one of the slot props provided to toggle the calendar popover.

Slot props ​

The full date picker context is bound to the default slot. Here are a few props that might be useful for you.

ts
interface DatePickerContext {
  // Value to bind to input element(s)
  inputValue: string | { start: string; end: string }; 
  // Events to bind to input element(s)
  inputEvents: object;
  // Popover show/hide methods
  showPopover: (opts?: Partial<PopoverOptions>) => void;
  hidePopover: (opts?: Partial<PopoverOptions>) => void;
  togglePopover: (opts: Partial<PopoverOptions>) => void;
  // ...,
}

Input element ​

To support date text entry, provide a custom input element as the default slot. VDatePicker provides formatting, parsing and event handling out of the box via the following slot props:

  • inputValue: The is the value you should bind to your input. This value will update as new dates are assigned and validated by the component.
  • inputEvents: These events include handlers for events that manage debounce, value updates and showing/hiding the popover (as specified via the popover prop).
Popover events

To exclude popover events from inputEvents, assign a falsy value to the popover prop.

Value:10/15/2023, 8:04:27 PM (Date)
vue
<template>
  <VDatePicker v-model="date">
    <template #default="{ inputValue, inputEvents }">
      <BaseInput :value="inputValue" v-on="inputEvents" />
    </template>
  </VDatePicker>
</template>

<script setup>
import { ref } from 'vue';
const date = ref(new Date());
</script>

Range Inputs ​

When binding to a date range and providing custom input elements, the inputValue and inputEvents are split into separate start and end sub-properties.

Start:10/12/2020, 12:00:00 AM (date)
End:10/16/2020, 12:00:00 AM (date)
vue
<template>
  <VDatePicker v-model="range" is-range>
    <template #default="{ inputValue, inputEvents }">
      <div class="flex justify-center items-center">
        <BaseInput :value="inputValue.start" v-on="inputEvents.start" />
        <IconArrowRight />
        <BaseInput :value="inputValue.end" v-on="inputEvents.end" />
      </div>
    </template>
  </VDatePicker>
</template>

<script setup>
import { ref } from 'vue';

const range = ref({
  start: new Date(2020, 9, 12),
  end: new Date(2020, 9, 16),
});
</script>

Debounce ​

Use the input-debounce prop (in milliseconds) to set a custom debounce duration. This example makes the input a little more responsive to text input by using a debounce of 500ms rather than the default 1000ms.

Value:10/15/2023, 8:04:27 PM (Date)
vue
<template>
  <VDatePicker v-model="date" :input-debounce="500">
    <template #default="{ inputValue, inputEvents }">
      <BaseInput :value="inputValue" v-on="inputEvents" />
    </template>
  </VDatePicker>
</template>

<script setup>
import { ref } from 'vue';
const date = ref(new Date());
</script>

Disable Update On Input ​

To completely disable value updates as the user types, set the update-on-input prop to false. This will defer updates until the input's change event occurs.

Value:10/15/2023, 8:04:27 PM (Date)
vue
<template>
  <VDatePicker v-model="date" :update-on-input="false">
    <template v-slot="{ inputValue, inputEvents }">
      <BaseInput :value="inputValue" v-on="inputEvents" />
    </template>
  </VDatePicker>
</template>

<script setup>
import { ref } from 'vue';
const date = ref(new Date());
</script>

Input Format ​

Locale ​

By default, the browser's detected locale will be used to format and parse the input text.

However, a locale prop can be provided to override this setting. This could be helpful if you store your user's locale in a database or want to force all user's to a specific locale.

Value:10/15/2023, 8:04:27 PM (Date)
vue
<template>
  <VDatePicker v-model="date" :locale="locale">
    <template v-slot="{ inputValue, inputEvents }">
      <BaseInput :value="inputValue" v-on="inputEvents" />
    </template>
  </VDatePicker>
</template>

<script setup>
import { ref } from 'vue';

const date = ref(new Date());
const locale = ref(null);

// Fetch user's locale using custom API (eg. 'en-ZA')
locale.value = await api.getUserLocale();
</script>

Mask ​

Alternatively, if you wish to keep the locale, but just override the locale's input format, provide a custom mask via the masks.input prop.

Value:10/15/2023, 8:04:27 PM (Date)
vue
<template>
  <VDatePicker v-model="date" :masks="masks">
    <template v-slot="{ inputValue, inputEvents }">
      <BaseInput :value="inputValue" v-on="inputEvents" />
    </template>
  </VDatePicker>
</template>

<script setup>
import { ref } from 'vue';
const date = ref(new Date());
const masks = ref({
  input: 'YYYY-MM-DD',
});
</script>

Please reference the masks section for a complete list of available mask tokens.

Popover ​

The popover prop determines how popover events are generated in the inputEvents slot prop.

ts
type PopoverProp = boolean | Partial<PopoverOptions>;

interface PopoverOptions {
  visibility: PopoverVisibility; // When the popover appears
  placement: Placement; // Where the popover appears
  autoHide: boolean; // Auto-hide popover based on visibility
  showDelay: number; // Delay (ms) before popover is shown
  hideDelay: number; // Delay (ms) before popover is hidden
}

type PopoverVisibility = 'click' | 'hover' | 'hover-focus' | 'focus';

Default behavior ​

The popover prop is true by default, which means that the events will use the following default settings.

json
{
  visibility: 'hover-focus',
  autoHide: true,
  placement: 'bottom-start',
  showDelay: 0,
  hideDelay: 110,
}

Now, if the inputEvents have been properly bound to an input element, then the popover will display as the user interacts with the input popover.

Value:10/15/2023, 8:04:27 PM (Date)
vue
<template>
  <VDatePicker v-model="date" :popover="popover">
    <template #default="{ inputValue, inputEvents }">
      <BaseInput :value="inputValue" v-on="inputEvents" />
    </template>
  </VDatePicker>
</template>

<script setup>
import { ref } from 'vue';

const date = ref(new Date());
const popover = ref(true);
</script>

Custom behavior ​

To customize this behavior, provide a custom PopoverOptions object.

Value:10/15/2023, 8:04:27 PM (Date)
vue
<template>
  <VDatePicker v-model="date" :popover="popover">
    <template #default="{ inputValue, inputEvents }">
      <BaseInput :value="inputValue" v-on="inputEvents" />
    </template>
  </VDatePicker>
</template>

<script setup>
import { ref } from 'vue';

const date = ref(new Date());
const popover = ref({
  visibility: 'click',
  placement: 'right',
});
</script>

Manual Control ​

You may choose to not bind popover behavior to the inputEvents, or you may not be using an input element at all. In that case, you can manually show/hide the popover by using the provided slot prop functions.

  1. Assign a falsy value to the popover prop to unbind popover events from inputEvents.
  2. Extract the relevant popover methods needed (togglePopover, showPopover, hidePopover) to show/hide the popover manually.
Value:10/15/2023, 8:04:27 PM (Date)
vue
<template>
  <VDatePicker v-model="date" :popover="false">
    <template #default="{ togglePopover, inputValue, inputEvents }">
      <div
        class="flex rounded-lg border border-gray-300 dark:border-gray-600 overflow-hidden"
      >
        <button
          class="flex justify-center items-center px-2 bg-accent-100 hover:bg-accent-200 text-accent-700 border-r border-gray-300 dark:bg-gray-700 dark:text-accent-300 dark:border-gray-600 dark:hover:bg-gray-600"
          @click="() => togglePopover()"
        >
          <IconCalendar class="w-5 h-5" />
        </button>
        <input
          :value="inputValue"
          v-on="inputEvents"
          class="flex-grow px-2 py-1 bg-white dark:bg-gray-700"
        />
      </div>
    </template>
  </VDatePicker>
</template>

<script setup>
import { ref } from 'vue';

const date = ref(new Date());
</script>
Tip

See the date picker examples for more guidance on using these slot variables.

Released under the MIT License.