Обзор
<b-calendar>
совместим с WAI-ARIA, оптимизирован для управления с клавиатуры (arrow, page up/down, home и end keys). Также поддерживается интернационализация и по умолчанию используется языковой стандарт браузера или страницы, если языковой стандарт не указан.
Если вам нужен выбор даты в качестве ввода настраиваемого элемента управления формой, используйте вместо него компонент <b-form-datepicker>
.
<template>
<b-row>
<b-col md="auto">
<b-calendar v-model="value" @context="onContext" locale="ru"></b-calendar>
</b-col>
<b-col>
<p>Значение: <b>''</b></p>
<p class="mb-0">Контекст:</p>
<pre class="small"></pre>
</b-col>
</b-row>
</template>
<script>
export default {
data() {
return {
value: '',
context: null
}
},
methods: {
onContext(ctx) {
this.context = ctx
}
}
}
</script>
Возвращаемое значение v-model
По умолчанию <b-calendar>
возвращает даты в виде строки в формате YYYY-MM-DD
, который является тем же форматом, что и элементы управления нативного браузера <input type="date">
. Вместо этого вы можете заставить <b-calendar>
возвращать объект Date
(без временной части) в качестве значения v-model
установив свойство value-as-date
prop.
Если дата не выбрана, <b-calendar>
возвращает пустую строку ''
или возвращает null
, если задано свойство value-as-date
.
Обратите внимание, что когда свойство value-as-date
установлено, возвращаемый объект Date
будет в часовом поясе браузера по умолчанию.
Состояния: отключено и только для чтения
Установка свойства disabled
удалит всю интерактивность компонента <b-calendar>
.
Установка свойства readonly
отключит выбор даты, но сохранит интерактивность компонента, позволяя осуществлять навигацию по дате. v-model
не будет обновляться в состоянии только для чтения.
Чтобы отключить определенные даты или установить минимальные и максимальные пределы дат, обратитесь к разделу Ограничения даты.
<template>
<div>
<b-form-group label="Выберите интерактивное состояние календаря" v-slot="{ ariaDescribedby }">
<b-form-radio-group
v-model="state"
:aria-describedby="ariaDescribedby"
aria-controls="ex-disabled-readonly"
>
<b-form-radio value="disabled">Отключено</b-form-radio>
<b-form-radio value="readonly">Только чтение</b-form-radio>
<b-form-radio value="normal">Обычное</b-form-radio>
</b-form-radio-group>
</b-form-group>
<b-calendar
id="ex-disabled-readonly"
:disabled="disabled"
:readonly="readonly"
></b-calendar>
</div>
</template>
<script>
export default {
data() {
return {
state: 'disabled'
}
},
computed: {
disabled() {
return this.state === 'disabled'
},
readonly() {
return this.state === 'readonly'
}
}
}
</script>
Ограничения по дате
Минимальные и максимальные даты
Ограничьте диапазон календаря с помощью свойств min
и max
. Свойства принимают строку даты в формате YYYY-MM-DD
или объект Date
.
<template>
<div>
<b-calendar v-model="value" :min="min" :max="max" locale="ru"></b-calendar>
</div>
</template>
<script>
export default {
data() {
const now = new Date()
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
const minDate = new Date(today)
minDate.setMonth(minDate.getMonth() - 2)
minDate.setDate(15)
const maxDate = new Date(today)
maxDate.setMonth(maxDate.getMonth() + 2)
maxDate.setDate(15)
return {
value: '',
min: minDate,
max: maxDate
}
}
}
</script>
Отключение дат
Если вам нужно отключить определенные даты в календаре, укажите ссылку на функцию для свойства date-disabled-fn
. Функции передаются два аргумента:
ymd
Дата как строка YYYY-MM-DD
date
Дата как объект Date
Функция должна либо возвращать true
, если дата не может быть выбрана (отключена), либо false
, если дата может быть выбрана (включена). Обратите внимание, что функция не может быть асинхронной и должна возвращать значение как можно быстрее.
<template>
<div>
<b-calendar v-model="value" :date-disabled-fn="dateDisabled" locale="ru"></b-calendar>
</div>
</template>
<script>
export default {
data() {
return {
value: ''
}
},
methods: {
dateDisabled(ymd, date) {
const weekday = date.getDay()
const day = date.getDate()
return weekday === 0 || weekday === 6 || day === 13
}
}
}
</script>
Обратите внимание, что ограничения даты min
и max
оцениваются в первую очередь, перед date-disabled-fn
.
Стилизация
Варианты
Выбранная кнопка даты (цвет фона) по умолчанию соответствует 'primary'
варианту темы. Вы можете изменить это на любой из цветов варианта темы Bootstrap v4: 'secondary'
, 'success'
, 'danger'
, 'warning'
, 'info'
и т. д. с помощью свойства selected-variant
.
Сегодняшняя дата также будет выделена (цветом текста) с использованием того же варианта, что и выбранная дата по умолчанию. Чтобы указать другой цвет темы, который будет использоваться для сегодняшней даты, используйте свойство today-variant
.
Чтобы полностью отключить выделение сегодняшней даты, установите свойство no-highlight-today
.
Кнопки навигации по умолчанию относятся к 'secondary'
варианту темы. Вы можете изменить это с помощью свойства nav-button-variant
.
<template>
<b-calendar
selected-variant="success"
today-variant="info"
nav-button-variant="primary"
></b-calendar>
</template>
Ширина
<b-calendar>
отображается как встроенный блочный элемент с шириной по умолчанию 270px
(исключая любые отступы или границы, которые могут быть добавлены к нему). Эта ширина оптимизирована, чтобы соответствовать ширине небольших мобильных устройств.
Чтобы изменить ширину, установите для свойства width
любую допустимую ширину CSS (включая единицы измерения).
При желании, сделайте календарь полной шириной, установив свойство block
, которое заставит его расширяться, чтобы соответствовать ширине родительского элемента. Свойство width
не действует, когда установлен block
.
<template>
<b-calendar block locale="ru"></b-calendar>
</template>
Обратите внимание, что не рекомендуется устанавливать ширину ниже 260px
, в противном случае могут возникнуть проблемы с усечением и компоновкой компонента.
Начальная дата открытия календаря
По умолчанию, если дата не выбрана, в представлении календаря будет установлен текущий месяц (или min
или max
дата, если сегодняшняя дата находится вне диапазона min
или max
). Вы можете изменить это поведение, указав дату через свойство initial-date
. Свойство начальной даты будет использоваться для определения календарного месяца, который будет первоначально представлен пользователю. Он не устанавливает значение компонента.
Строковый формат даты
v2.6.0+
Чтобы изменить параметры формата отображаемого текста даты внутри компонента, например в заголовке установите опцию date-format-options
для объекта, содержащего запрошенные свойства формата для объекта Intl.DateTimeFormat
(смотрите также Интернационализация).
<template>
<div>
<p>Пользовательский формат даты:</p>
<b-calendar
:date-format-options="{ year: 'numeric', month: 'short', day: '2-digit', weekday: 'short' }"
locale="ru"
></b-calendar>
<p class="mt-3">Краткий формат даты:</p>
<b-calendar
:date-format-options="{ year: 'numeric', month: 'numeric', day: 'numeric' }"
locale="ru"
></b-calendar>
</div>
</template>
В следующей таблице приведены допустимые параметры для каждого свойства формата:
Свойство | Возможные значения |
year | 'numeric' , или '2-digit' |
month | 'numeric' , '2-digit' , 'long' , 'short' , или 'narrow' |
day | 'numeric' , или '2-digit' |
weekday | 'long' , 'short' , или 'narrow' |
Заметки:
- Отсутствие определенных параметров может повлиять на форматированную текстовую строку, например
weekday
- Отформатированное значение будет варьироваться в зависимости от разрешенного языкового стандарта. Некоторые языки могут не поддерживать
'narrow'
формат и будут использовать 'short'
или long'
формат (если 'short'
недоступен) - Всегда будут отображаться
year
, month
и day
. Если вам нужно не указывать значение, установите для свойства значение undefined
, хотя это крайне не рекомендуется по причинам доступности
Формат заголовка названия дня недели
2.12.0+
Формат заголовка имени дня недели календаря по умолчанию 'short'
, который обычно представляет собой трехсимвольное сокращение дня недели, хотя некоторые локали могут переопределить это. Форматом можно управлять с помощью свойства weekday-header-format
, которое принимает одно из трех значений:
'long'
- полное название дня недели (например, Вторник). Удобно при использовании календаря полной ширины. Избегайте использования с шириной календаря по умолчанию. 'short'
обычно представляет собой двух- или трехбуквенное сокращение названия дня недели, в зависимости от выбранного языка (например, "Вт"). 'narrow'
- это обычно односимвольное сокращение (например, В). Два будних дня могут иметь один и тот же узкий стиль для некоторых регионов (например, узкий стиль вторника В и четверга Ч). Это может быть удобно для тех языков, которые не поддерживают 'short'
формат, например для локалей 'ar'
и 'fa'
.
Скрытие верхнего выбранного заголовка даты
По умолчанию текущая выбранная дата будет отображаться в верхней части календарного компонента в формате, установленном на языке локали.
Вы можете скрыть этот заголовок с помощью свойства hide-header
. Обратите внимание, что это только визуально скрывает выбранную дату, сохраняя при этом доступность для пользователей программ чтения с экрана как область aria-live
.
Для примера использования смотрите Раздел интернационализации ниже.
Дополнительные кнопки навигации декады
Установите свойство show-decade-nav
, чтобы включить кнопки предыдущей и следующей декады на панели инструментов навигации по дате календаря.
Свойства label-prev-decade
и label-next-decade
могут использоваться для предоставления пользовательского текста метки для кнопок декады.
Для примера использования смотрите Раздел интернационализации ниже.
Граница и отступы
Хотите календарь с рамкой и отступом? Используйте классы-утилиты границ и отступов, чтобы добавить границы и отступы:
<template>
<b-calendar class="border rounded p-2" locale="ru"></b-calendar>
</template>
Слот по умолчанию
Предоставьте дополнительный контент в нижней части интерфейса календаря с помощью слота по умолчанию. В слот можно добавлять такие кнопки, как Select Today
или Reset
и т. д.
<template>
<b-calendar v-model="value" value-as-date locale="ru">
<div class="d-flex" dir="ltr">
<b-button
size="sm"
variant="outline-danger"
v-if="value"
@click="clearDate"
>
Очистить дату
</b-button>
<b-button
size="sm"
variant="outline-primary"
class="ml-auto"
@click="setToday"
>
Установить сегодня
</b-button>
</div>
</b-calendar>
</template>
<script>
export default {
data() {
return {
value: null
}
},
methods: {
setToday() {
const now = new Date()
this.value = new Date(now.getFullYear(), now.getMonth(), now.getDate())
},
clearDate() {
this.value = ''
}
}
}
</script>
Слоты для кнопок навигации по дате
2.12.0+
Чтобы изменить содержимое кнопок навигации по дате календаря, BootstrapVue предоставляет слоты с заданной областью для каждой кнопки:
'nav-prev-decade'
'nav-prev-year'
'nav-prev-month'
'nav-this-month'
(кнопка перехода к выбранному/сегодня) 'nav-next-month'
'nav-next-year'
'nav-next-decade'
Для всех семи слотов доступно одно и то же свойство с областью действия:
Свойство | Тип | Описание |
isRTL | Boolean | Будет иметь значение true , если панель навигации по дате отображается справа-налево |
Вы можете использовать рассмотренное свойство isRTL
, чтобы «перевернуть» содержимое кнопки назад и далее для обработки изменения ориентации слева направо на справа налево — т.е. кнопка предыдущего года будет справа, когда isRTL
имеет значение true
, а не слева.
Добавление классов CSS к определенным датам
Если вам нужно выделить конкретную дату или даты, установите свойство date-info-fn
на ссылку на функцию, которая возвращает строку класса CSS (или массив строк) для применения к ячейке даты. Функции передаются два аргумента:
ymd
Дата как строка YYYY-MM-DD
date
Дата как объект Date
Функция может возвращать строку или массив строк. Если не заданы классы, вы можете вернуть пустую строку (''
), пустой массив ([]
) или null
.
В этом примере мы используем классы цвета table-{variant}
для установки цвета фона в ячейке даты. Цветовые классы table-{variant}
работают хорошо, поскольку они являются приглушенными версиями цветов темы.
<template>
<div>
<b-calendar v-model="value" :date-info-fn="dateClass" locale="ru"></b-calendar>
</div>
</template>
<script>
export default {
data() {
return {
value: ''
}
},
methods: {
dateClass(ymd, date) {
const day = date.getDate()
return day >= 10 && day <= 20 ? 'table-info' : ''
}
}
}
</script>
Обратите внимание, что функция не будет вызываться для отключенных дат.
Примечание о доступности:
При использовании классов для передачи определенного значения дате вы должны включить дополнительный контекст вне календаря (или через слот по умолчанию) в отношении выделенных дат (например, в области aria-live
), особенно для программы чтения с экрана пользователей.
В будущем BootstrapVue может добавить функцию добавления текстовой заметки, удобной для чтения с экрана, для выделенной даты с помощью этой функции.
События
Событие 'input'
генерируется при обновлении v-model
. У события есть единственный аргумент - выбранная дата. По умолчанию значение представляет собой строку в формате YYYY-MM-DD
(или пустую строку, если дата не выбрана). Если свойство value-as-date
установлено, то первым аргументом вместо этого будет объект Date
(или null
, если дата не выбрана).
Если заданы свойства disabled
или readonly
, событие 'input'
не генерируется.
Событие selected
Событие 'selected'
генерируется, когда пользователь щелкает дату без отключения. Событие передает два аргумента:
ymd
Выбранная дата как строка YYYY-MM-DD
date
Выбранная дата как объект Date
Если пользователь щелкает по уже выбранной дате, событие selected
все равно будет генерироваться, в отличие от события 'input'
, которое не повторно генерирует уже выбранную дату.
Если заданы свойства disabled
или readonly
, событие 'selected'
не генерируется.
Событие context
Событие 'context'
генерируется всякий раз, когда пользователь выбирает дату или пользователь перемещается по календарю (либо с помощью клавиш курсора, клавиш вверх/вниз, клавиш домой или завершения, либо с помощью кнопок навигации календаря). Он также будет генерироваться при создании компонента (непосредственно перед вставкой в DOM) или при изменении разрешенного языкового стандарта.
Когда установлено свойство readonly
, событие все равно будет генерироваться, когда пользователь будет перемещаться по календарю. Он не будет генерироваться, если установлено свойство disabled
prop is set (за исключением начального испускания при создании календаря).
Событию 'context'
передается объект контекста как единственный аргумент со следующими свойствами:
Свойство | Описание |
selectedYMD | Выбранное значение даты (формат YYYY-MM-DD ) или пустая строка, если дата не выбрана |
selectedDate | Выбранное значение даты как объект Date или null , если дата не выбрана |
selectedFormatted | Выбранная дата отформатирована в текущем языковом стандарте. Если дата не выбрана, это будет значение свойства label-no-date-selected |
activeYMD | Текущая дата кнопки календарного дня, которая может получать фокус в виде строки (формат YYYY-MM-DD ) |
activeDate | Текущая дата кнопки календарного дня, которая может получать фокус как объект Date |
activeFormatted | Активная дата, отформатированная в текущем языковом стандарте. |
disabled | Будет true , если активная дата отключена, иначе false otherwise |
locale | Разрешенный языковой стандарт (может отличаться от запрошенного языкового стандарта) |
calendarLocale | Разрешенный языковой стандарт, используемый календарем, необязательно включая тип календаря (например, 'gregory'). Обычно это то же самое, что и locale , но может включать используемый тип календаря, например, fa-u-ca-gregory при выборе персидского языка ('fa' ) |
isRTL | Будет иметь значение true , если календарь имеет ориентацию RTL (справа налево). Будет false , если LTR (слева направо) |
При форматировании дат вручную с помощью Intl.DateTimeFormat
используйте значение свойства calendarLocale
вместо значения свойства locale
, чтобы убедиться, что вы используете то же соглашение календаря, которое использует <b-calendar>
. Это особенно верно для браузера IE 11, который не полностью реализует все функции Intl.DateTimeFormat
. Дополнительные сведения смотрите в разделе Интернационализации ниже.
Интернационализация
Интернационализация календаря обеспечивается через Intl.DateTimeFormat
, за исключением меток, применяемых к элементам управление календарем (aria-labels, выбранный статус и текст справки). Вы должны предоставить свои собственные переводы для этих этикеток. Доступные языковые стандарты будут зависеть от браузера (не все браузеры поддерживают все языковые стандарты)
По умолчанию <b-calendar>
будет использовать языковой стандарт браузера по умолчанию, но вы можете указать языковой стандарт (или языковые стандарты) для использования через свойство locale
. Свойство принимает либо одну строку языкового стандарта, либо массив строк языкового стандарта (перечисленных в порядке предпочтительного языкового стандарта).
В календаре неделя начинается в воскресенье. Это можно изменить, установив для свойства start-weekday
значение от 0
до 6
, где 0
означает воскресенье, 1
- понедельник, а 6
субботу.
Вызванное событие context
будет включать, какой языковой стандарт разрешен для календаря (который может отличаться от запрашиваемого языкового стандарта, в зависимости от поддерживаемых языковых стандартов Intl
).
<template>
<b-row>
<b-col cols="12" class="mb-3">
<label for="example-locales">Локаль:</label>
<b-form-select id="example-locales" v-model="locale" :options="locales"></b-form-select>
<label for="example-weekdays" class="mt-2">Начало рабочего дня:</label>
<b-form-select id="example-weekdays" v-model="weekday" :options="weekdays"></b-form-select>
<b-form-checkbox v-model="showDecadeNav" switch inline class="my-2">
Показать кнопки навигации по декаде
</b-form-checkbox>
<b-form-checkbox v-model="hideHeader" switch inline class="my-2">
Скрыть заголовок даты
</b-form-checkbox>
</b-col>
<b-col md="auto">
<b-calendar
v-model="value"
v-bind="labels[locale] || {}"
:locale="locale"
:start-weekday="weekday"
:hide-header="hideHeader"
:show-decade-nav="showDecadeNav"
@context="onContext"
></b-calendar>
</b-col>
<b-col>
<p>Значение: <b>''</b></p>
<p class="mb-0">Контекст:</p>
<pre class="small"></pre>
</b-col>
</b-row>
</template>
<script>
export default {
data() {
return {
value: '',
context: null,
showDecadeNav: false,
hideHeader: false,
locale: 'ru',
locales: [
{ value: 'ru', text: 'Русский (ru)' },
{ value: 'en-US', text: 'English US (en-US)' },
{ value: 'de', text: 'German (de)' },
{ value: 'ar-EG', text: 'Arabic Egyptian (ar-EG)' },
{ value: 'zh', text: 'Chinese (zh)' }
],
weekday: 0,
weekdays: [
{ value: 0, text: 'Воскресенье' },
{ value: 1, text: 'Понедельник' },
{ value: 6, text: 'Суббота' }
],
labels: {
'ru': {
labelPrevDecade: 'Предыдущее десятилетие',
labelPrevYear: 'Предыдущий год',
labelPrevMonth: 'Предыдущий месяц',
labelCurrentMonth: 'Текущий месяц',
labelNextMonth: 'Следующий месяц',
labelNextYear: 'В следующем году',
labelNextDecade: 'Следующее десятилетие',
labelToday: 'Сегодня',
labelSelected: 'Выбранная дата',
labelNoDateSelected: 'Дата не выбрана',
labelCalendar: 'Календарь',
labelNav: 'Навигация по календарю',
labelHelp: 'Используйте клавиши со стрелками для навигации по календарю'
},
de: {
labelPrevDecade: 'Vorheriges Jahrzehnt',
labelPrevYear: 'Vorheriges Jahr',
labelPrevMonth: 'Vorheriger Monat',
labelCurrentMonth: 'Aktueller Monat',
labelNextMonth: 'Nächster Monat',
labelNextYear: 'Nächstes Jahr',
labelNextDecade: 'Nächstes Jahrzehnt',
labelToday: 'Heute',
labelSelected: 'Ausgewähltes Datum',
labelNoDateSelected: 'Kein Datum gewählt',
labelCalendar: 'Kalender',
labelNav: 'Kalendernavigation',
labelHelp: 'Mit den Pfeiltasten durch den Kalender navigieren'
},
'ar-EG': {
weekdayHeaderFormat: 'narrow',
labelPrevDecade: 'العقد السابق',
labelPrevYear: 'العام السابق',
labelPrevMonth: 'الشهر السابق',
labelCurrentMonth: 'الشهر الحالي',
labelNextMonth: 'الشهر المقبل',
labelNextYear: 'العام المقبل',
labelNextDecade: 'العقد القادم',
labelToday: 'اليوم',
labelSelected: 'التاريخ المحدد',
labelNoDateSelected: 'لم يتم اختيار تاريخ',
labelCalendar: 'التقويم',
labelNav: 'الملاحة التقويم',
labelHelp: 'استخدم مفاتيح المؤشر للتنقل في التواريخ'
},
zh: {
weekdayHeaderFormat: 'narrow',
labelPrevDecade: '过去十年',
labelPrevYear: '上一年',
labelPrevMonth: '上个月',
labelCurrentMonth: '当前月份',
labelNextMonth: '下个月',
labelNextYear: '明年',
labelNextDecade: '下一个十年',
labelToday: '今天',
labelSelected: '选定日期',
labelNoDateSelected: '未选择日期',
labelCalendar: '日历',
labelNav: '日历导航',
labelHelp: '使用光标键浏览日期'
}
}
}
},
methods: {
onContext(ctx) {
this.context = ctx
}
}
}
</script>
В настоящее время <b-calendar>
поддерживает только Григорианский ('gregory'
) календарь.
По умолчанию <b-calendar>
автоматически определяет RTL и LTR через разрешенную локаль. Вы можете заставить календарь отображаться справа налево, установив свойство direction
в строку rtl
, или установив свойство direction
равной 'ltr'
, чтобы всегда отображать слева направо.
Вы можете прослушать событие context
, чтобы определить локаль и направленность, на которые настроен календарь.
Для рендеринга на стороне сервера (SSR) при использовании Node.js убедитесь, что среда выполнения Node.js, которую вы используете, поддерживает Intl
и локали, которые вы будете использовать. За подробностями обращайтесь к документации поддержки Node Intl
.
Доступность
<b-calendar>
предоставляет множество специальных возможностей, таких как aria-live
области, роли, метка арий, сочетания клавиш и полная навигация с клавиатуры для работы с большинством программ чтения с экрана.
Клавиатурная навигация:
- ArrowLeft перемещает на предыдущий день (или на следующий день в режиме RTL)
- ArrowRight перемещает на следующий день (или предыдущий день в режиме RTL)
- ArrowUp перемещается в тот же день на предыдущей неделе
- ArrowDown перемещается в тот же день на следующей неделе
- PageUp перемещается на тот же день предыдущего месяца
- PageDown перемещается в тот же день следующего месяца
- Alt+PageUp перемещается в тот же день и месяц в предыдущем году
- Alt+PageDown перемещает в тот же день и месяц следующего года
- Ctrl+Alt+PageUp перемещает в тот же день и месяц в предыдущей декаде
- Ctrl+Alt+PageDown перемещает к тому же дню и месяцу в следующем десятилетии
- Home перемещается на сегодняшнюю дату
- End перемещает к текущей выбранной дате или сегодня, если не выбрана дата
- Enter или Space выбирает текущий выделенный (сфокусированный) день
Некоторые свойства label-*
не видны на экране, но используются для обозначения различных элементов в календаре для пользователей программ чтения с экрана, например, свойство label-today
добавляется в ячейку, которая содержит сегодняшнюю дату: 'January 28, 2020 (Сегодня)'
, а свойство label-selected
добавляется в ячейку, содержащую выбранную дату 'January 28, 2020 (Выбранная дата)'
, а также добавлен в заголовок выбранной даты в виде текста sr-only
.
При интернационализации datepicker важно также обновить свойства label-*
, соответствующими переведенными строками, чтобы международные пользователи программ чтения с экрана слышали правильные подсказки и описания.
Функции и стиль <b-calendar>
намеренно сохранены в минималистичном стиле, чтобы обеспечить максимальную доступность для всех пользователей.
Замечания по реализации
<b-calendar>
использует классы-утилиты Bootstrap border
и flex
, а также классы кнопок (btn-*
) и form-control
. Пользовательский SCSS/CSS BootstrapVue также необходим для правильного стиля.
С точки зрения доступности мы решили не использовать grid
ролей ARIA для календаря, чтобы свести к минимуму многословие и обеспечить согласованность между различными программами чтения с экрана (NVDA при обнаружении роли grid
считывает выделенную ячейку как "выбранную", что вводит пользователя в заблуждение).
Смотрите также