Skip to content

Calendar

Calendário standalone para seleção de datas. Suporta modos single, range e multi, visualização de dois meses, presets e marcação de eventos.

Uso

vue
<script setup lang="ts">
import { Calendar } from '@halfbyte/maka'
import { ref } from 'vue'

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

<template>
  <Calendar v-model="data" />
</template>

Exemplos

Single (padrão)

vue
<Calendar v-model="data" />

Range — dois meses

vue
<Calendar v-model="range" mode="range" :number-of-months="2" />

Multi (seleção descontínua)

vue
<Calendar v-model="dates" mode="multi" />

Com eventos

vue
<Calendar v-model="data" :events="['2026-05-10', '2026-05-20']" />

Com datas desabilitadas

vue
<!-- Array de strings -->
<Calendar :disabled-dates="['2024-12-25', '2024-12-26']" />

<!-- Ou função -->
<Calendar :disabled-dates="(d) => d.getDay() === 0" />

Min / Max

vue
<Calendar v-model="data" min-date="2026-01-01" max-date="2026-12-31" />

Tamanhos

vue
<Calendar size="sm" />
<Calendar size="md" />
<Calendar size="lg" />

Cores

vue
<Calendar color="blue" />
<Calendar color="lime" />
<Calendar color="black" />

Em superfície escura

vue
<Calendar v-model="range" mode="range" :dark="true" />

Range com presets

vue
<script setup lang="ts">
import { Calendar, type CalendarPreset } from '@halfbyte/maka'
import { ref } from 'vue'

const range = ref<string[]>([])
const t = () => new Date()

const presets: CalendarPreset[] = [
  { label: 'Hoje',           getValue: () => [t(), t()] },
  { label: 'Últimos 7 dias', getValue: () => [new Date(t().getTime() - 6 * 86400000), t()] },
  { label: 'Mês atual',      getValue: () => [new Date(t().getFullYear(), t().getMonth(), 1), new Date(t().getFullYear(), t().getMonth() + 1, 0)] },
  { label: 'Este trimestre', getValue: () => { const m = Math.floor(t().getMonth() / 3) * 3; return [new Date(t().getFullYear(), m, 1), new Date(t().getFullYear(), m + 3, 0)] } },
]
</script>

<template>
  <Calendar
    v-model="range"
    mode="range"
    :presets="presets"
  />
</template>

Props

PropTipoPadrãoDescrição
modelValuestring | string[]Data(s) selecionada(s) em formato YYYY-MM-DD
mode'single' | 'range' | 'multi''single'Modo de seleção
size'sm' | 'md' | 'lg''md'Tamanho das células (32 / 40 / 52px)
color'blue' | 'lime' | 'black''blue'Cor do estado selecionado
darkbooleanfalseAtiva variante para fundo escuro (seleção muda para lime)
numberOfMonthsnumber1Quantidade de meses exibidos (use 2 para range)
minDatestringData mínima selecionável (YYYY-MM-DD)
maxDatestringData máxima selecionável (YYYY-MM-DD)
disabledDatesstring[] | ((d: Date) => boolean)Datas indisponíveis
eventsstring[]Datas marcadas com ponto lime
showOutsideDaysbooleantrueExibe dias do mês adjacente para completar 6 linhas
localestring'pt-BR'Locale para formatação
presetsCalendarPreset[]Atalhos de range (exibe painel no rodapé)
ariaLabelstring'Calendário'Label para role="application"

Eventos

EventoPayloadDescrição
update:modelValuestring | string[]Emitido ao selecionar. Single → string, range/multi → string[]
update:monthstringEmitido ao navegar entre meses

Tipo CalendarPreset

ts
interface CalendarPreset {
  label:    string;
  getValue: () => [Date, Date];
}

Teclado

TeclaAção
/ Dia anterior / próximo
/ Semana anterior / próxima
HomePrimeiro dia da semana
EndÚltimo dia da semana
PgUpMês anterior
PgDnPróximo mês
Shift+PgUpAno anterior
Shift+PgDnPróximo ano
Enter / SpaceSeleciona o dia em foco
EscFecha popover (DatePicker)

Acessibilidade

  • role="application" no container com aria-label obrigatório
  • role="grid" + aria-labelledby no grid de cada mês
  • aria-current="date" no dia de hoje
  • aria-selected e aria-disabled gerenciados automaticamente pelo Ark UI
  • aria-live="polite" anuncia mudanças de mês para leitores de tela
  • Roving tabindex: apenas um dia tem tabindex=0 por vez
  • Respeita prefers-reduced-motion (sem animação de slide — apenas fade)

Date Picker

Input com calendário em popover para seleção de data. Suporta máscara DD/MM/AAAA, estados de erro, required e integração com formulários.

Uso

vue
<script setup lang="ts">
import { DatePicker } from '@halfbyte/maka'
import { ref } from 'vue'

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

<template>
  <DatePicker v-model="data" label="Data" aria-label="Selecione uma data" />
</template>

Exemplos

Padrão

vue
<DatePicker v-model="data" label="Padrão" aria-label="Data de nascimento" />

Com erro

vue
<DatePicker
  v-model="data"
  label="Data de vencimento"
  error="Data inválida"
  aria-label="Data de vencimento"
/>

Required

vue
<DatePicker v-model="data" label="Data" :required="true" aria-label="Data" />

Desabilitado

vue
<DatePicker v-model="data" label="Data" :disabled="true" aria-label="Data" />

Com limites

vue
<DatePicker
  v-model="data"
  label="Período"
  min-date="2026-01-01"
  max-date="2026-12-31"
  aria-label="Data dentro do período permitido"
/>

Props

PropTipoPadrãoDescrição
modelValuestringData em formato YYYY-MM-DD
labelstringRótulo visível acima do input
placeholderstring'DD/MM/AAAA'Placeholder do input
formatstring'dd/MM/yyyy'Formato de exibição (date-fns syntax)
requiredbooleanfalseMarca o campo como obrigatório
disabledbooleanfalseDesabilita o campo
errorstringMensagem de erro exibida abaixo do input
minDatestringData mínima selecionável (YYYY-MM-DD)
maxDatestringData máxima selecionável (YYYY-MM-DD)
localestring'pt-BR'Locale para formatação
namestringAtributo name do input (formulários)
ariaLabelstringaria-label do campo (obrigatório para a11y)

Eventos

EventoPayloadDescrição
update:modelValuestringEmitido ao selecionar a data (formato YYYY-MM-DD)

Acessibilidade

  • ariaLabel é obrigatório para leitores de tela
  • Teclado completo herdado do Calendar: setas, PgUp/Dn, Shift+PgUp/Dn
  • Esc fecha o popover sem alterar o valor
  • aria-invalid aplicado automaticamente quando error está preenchido