src/components/form-timepicker/README.md
<b-form-timepicker>is a BootstrapVue custom time picker input form control, which provides full WAI-ARIA compliance and internationalization support.
As a form control wrapper component for the <b-time> component, it
provides additional validation state presentation and a compact interface. Native HTML5 time inputs
vary in presentation, accessibility, and in some instances are not supported by all browsers.
<b-form-timepicker> provides a consistent and accessible interface across all browser platforms
and devices.
<template>
<div>
<b-form-timepicker v-model="value" locale="en"></b-form-timepicker>
<div class="mt-2">Value: '{{ value }}'</div>
</div>
</template>
<script>
export default {
data() {
return {
value: ''
}
}
}
</script>
<!-- b-form-timepicker.vue -->
v-model return value<b-form-timepicker> always returns a string in the format of 'HH:mm:ss' which is the same format
returned by native browser <input type="time"> controls. The value will be in the range of
'00:00:00' up to '23:59:59' (24-hour clock using the 'h23' hour cycle syntax).
If no time is selected, then <b-form-timepicker> returns an empty string ('').
Setting the disabled prop will remove all interactivity of the <b-form-timepicker> component.
Setting the readonly prop will disable selecting a time, but will keep the component interactive,
allowing for tabbing between spinbuttons. The v-model will not be updated in the readonly state.
<template>
<div>
<b-form-group
label="Select time picker interactive state"
v-slot="{ ariaDescribedby }"
>
<b-form-radio-group
v-model="state"
:aria-describedby="ariaDescribedby"
aria-controls="ex-disabled-readonly"
>
<b-form-radio value="disabled">Disabled</b-form-radio>
<b-form-radio value="readonly">Readonly</b-form-radio>
<b-form-radio value="normal">Normal</b-form-radio>
</b-form-radio-group>
</b-form-group>
<b-form-timepicker
id="ex-disabled-readonly"
:disabled="disabled"
:readonly="readonly"
></b-form-timepicker>
</div>
</template>
<script>
export default {
data() {
return {
state: 'disabled'
}
},
computed: {
disabled() {
return this.state === 'disabled'
},
readonly() {
return this.state === 'readonly'
}
}
}
</script>
<!-- b-form-timepicker-disabled-readonly.vue -->
<b-form-timepicker> supports invalid and valid styling via the boolean state prop. Setting
state to boolean false will style the input as invalid, while setting it to boolean true will
style it as valid. Setting state to null will not show any validation state styling (the default).
<template>
<div>
<label for="timepicker-invalid">Choose a time (invalid style)</label>
<b-form-timepicker id="datepicker-invalid" :state="false" class="mb-2"></b-form-timepicker>
<label for="timepicker-valid">Choose a time (valid style)</label>
<b-form-timepicker id="datepicker-valid" :state="true"></b-form-timepicker>
</div>
</template>
<!-- b-form-timepicker-validation.vue -->
Note that native browser validation is not available with <b-form-timepicker>.
By default, the seconds spinbutton is not shown. To enable the section of seconds, set the
show-seconds prop to true to enable the seconds selection spinbutton. When show-seconds is
false (or not provided), the returned value will always have the seconds portion of the time string
set to 00.
<template>
<div>
<b-form-timepicker v-model="value" show-seconds locale="en"></b-form-timepicker>
<div class="mt-2">Value: '{{ value }}'</div>
</div>
</template>
<script>
export default {
data() {
return {
value: ''
}
}
}
</script>
<!-- b-form-timepicker-show-seconds.vue -->
Fancy a smaller or larger <b-form-timepicker> control? Set the size prop to 'sm' for a smaller
form control, or 'lg' for a larger form form control. Note this does not affect the size of the
popup time selection dialog.
<template>
<div>
<label for="timepicker-sm">Small time picker</label>
<b-form-timepicker id="timepicker-sm" size="sm" locale="en" class="mb-2"></b-form-timepicker>
<label for="timepicker-lg">Large time picker</label>
<b-form-timepicker id="timepicker-lg" size="lg" locale="en"></b-form-timepicker>
</div>
</template>
<!-- b-form-timepicker-control-size.vue -->
Add custom placeholder text to the control, when no date is selected, via the placeholder prop. If
a placeholder is not provided, the value of the label-no-time-selected prop is used.
<template>
<div>
<label for="timepicker-placeholder">Time picker with placeholder</label>
<b-form-timepicker id="timepicker-placeholder" placeholder="Choose a time" locale="en"></b-form-timepicker>
</div>
</template>
<!-- b-form-timepicker-placeholder.vue -->
Add optional control buttons to the bottom of the calendar popup via the props now-button or
reset-button. The default close button can be removed via the no-close-button prop.
reset-value (if provided)<template>
<div>
<label for="timepicker-buttons">Time picker with optional footer buttons</label>
<b-form-timepicker
id="timepicker-buttons"
now-button
reset-button
locale="en"
></b-form-timepicker>
</div>
</template>
<!-- b-form-timepicker-footer-buttons.vue -->
The text for the optional buttons can be set via the label-now-button, label-reset-button, and
the label-close-button props. Due to the limited width of the footer section, it is recommended to
keep these labels short.
Use the dropdown props right, dropup, dropright, dropleft, no-flip, and offset to
control the positioning of the popup calendar.
Refer to the <b-dropdown> positioning section for details
on the effects and usage of these props.
<span class="badge badge-info small">v2.7.0+</span>
Fancy just a button that launches the timepicker dialog, or want to provide your own optional text
input field? Use the button-only prop to render the timepicker as a dropdown button. The formatted
time label will be rendered with the class sr-only (available only to screen readers).
In the following simple example, we are placing the timepicker (button only mode) as an append to a
<b-input-group>:
<template>
<div>
<label for="example-input">Choose a time</label>
<b-input-group class="mb-3">
<b-form-input
id="example-input"
v-model="value"
type="text"
placeholder="HH:mm:ss"
></b-form-input>
<b-input-group-append>
<b-form-timepicker
v-model="value"
button-only
right
show-seconds
locale="en"
aria-controls="example-input"
></b-form-timepicker>
</b-input-group-append>
</b-input-group>
<p>Value: '{{ value }}'</p>
</div>
</template>
<script>
export default {
data() {
return {
value: ''
}
}
}
</script>
<!-- b-form-timepicker-button-only.vue -->
Control the size of the button via the size prop, and the button variant via the button-variant
prop.
Internationalization of the time interface is provided via
Intl.DateTimeFormat
and
Intl.NumberFormat,
except for the labels applied to elements of the time control (aria-labels, selected status, etc.).
You must provide your own translations for these labels. The available locales will be browser
dependent (not all browsers support all locales).
By default <b-form-timepicker> will use the browser's default locale, but you can specify the
locale (or locales) to use via the locale prop. The prop accepts either a single locale string, or
an array of locale strings (listed in order of most preferred locale to least preferred).
The emitted 'context' event will include which locale the time control has resolved to (which may
not be the same locale as requested, depending on the supported locales of Intl).
For server side rendering (SSR) when using Node.js, ensure that the Node.js runtime you are using
supports Intl and the locales you will be using. Refer to the
Node Intl support documentation for details.
<template>
<b-row>
<b-col cols="12" class="mb-3">
<label for="example-locales">Locale:</label>
<b-form-select id="example-locales" v-model="locale" :options="locales"></b-form-select>
</b-col>
<b-col md="6">
<b-form-timepicker
v-model="value"
v-bind="labels[locale] || {}"
:locale="locale"
show-seconds
@context="onContext"
></b-form-timepicker>
</b-col>
<b-col>
<p>Value: <b>'{{ value }}'</b></p>
<p class="mb-0">Context:</p>
<pre class="small">{{ context }}</pre>
</b-col>
</b-row>
</template>
<script>
export default {
data() {
return {
value: '',
context: null,
locale: 'en-US',
locales: [
{ 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)' }
],
labels: {
de: {
labelHours: 'Stunden',
labelMinutes: 'Minuten',
labelSeconds: 'Sekunden',
labelIncrement: 'Erhöhen',
labelDecrement: 'Verringern',
labelSelected: 'Ausgewählte Zeit',
labelNoTimeSelected: 'Keine Zeit ausgewählt',
labelCloseButton: 'Schließen'
},
'ar-EG': {
labelHours: 'ساعات',
labelMinutes: 'الدقائق',
labelSeconds: 'ثواني',
labelAmpm: 'صباحا مساء',
labelAm: 'ص',
labelPm: 'م',
labelIncrement: 'زيادة',
labelDecrement: 'إنقاص',
labelSelected: 'الوقت المحدد',
labelNoTimeSelected: 'لا وقت المختار',
labelCloseButton: 'قريب'
},
zh: {
labelHours: '小时',
labelMinutes: '分钟',
labelSeconds: '秒',
labelAmpm: '上午下午',
labelAm: '上午',
labelPm: '下午',
labelIncrement: '增量',
labelDecrement: '减量',
labelSelected: '选定时间',
labelNoTimeSelected: '没有选择时间',
labelCloseButton: '关'
}
}
}
},
methods: {
onContext(ctx) {
this.context = ctx
}
}
}
</script>
<!-- b-form-time-i18n.vue -->
hourCycleThere are 2 main types of time keeping conventions (clocks) used around the world: the 12-hour clock
and the 24-hour clock. The hourCycle property allows you to access the clock type used by a
particular locale. The hour cycle type can have several different values, which are listed in the
table below. The hourCycle signals how the time '00:00:00' (the start of the day) should be
presented/formatted to a user of a particular locale. The 'context' event includes the resolved
hourCycle value.
hourCycle | Description |
|---|---|
'h12' | Hour system using 1–12. The 12 hour clock, with midnight starting at 12:00 am |
'h23' | Hour system using 0–23. The 24 hour clock, with midnight starting at 0:00 |
'h11' | Hour system using 0–11. The 12 hour clock, with midnight starting at 0:00 am |
'h24' | Hour system using 1–24. The 24 hour clock, with midnight starting at 24:00 |
Native HTML5 <input type="date"> returns the time value in the 'h23' format, and
<b-form-timepicker> also returns the v-model in the 'h23' format. This value may differ from
what is presented to the user via the GUI (spin buttons) of the <b-form-timepicker> component,
dependent upon the locale selected.
Note: IE 11 does not support resolving the hourCycle value of a locale, so we assume either
h12 or h23 based on the resolved hour12 value.
12-hour versus 24-hour input is determined by the client browsers default locale (or the locale
resolved from the locale prop). To force a 12-hour user interface, set the prop hour12 to
true. To force a 24-hour user interface, set the prop hour12 to false. The default for prop
hour12 is null which uses the resolved locale to determine which interface to use.
The setting of the hour12 prop will affect which hourCycle is
resolved for formatting the hours spinbutton. Note that while this may affect the format of the hour
spinbutton, but the formatted time string result may show the 'h12 or 'h23' format due to
limitations in the client Intl.DateTimeFormat support for a particular locale. It is therefore
recommended to leave the hour12 prop set to null (default), so show the locale default
time/hour formatting.
The popup time supports the same keyboard controls as
<b-time>, along with the following:
When internationalizing the timepicker, it is important to also update the label-* props with
appropriate translated strings, so that international screen reader users will hear the correct
prompts and descriptions.
Refer to the <b-time> documentation for additional details.
<b-form-timepicker> is based upon the components <b-time> and
<b-dropdown>.
<b-form-timepicker> uses Bootstrap's border and flex utility classes, along with button (btn-*)
classes, dropdown (dropdown*) classes, and the form-control* (plus validation) classes.
BootstrapVue's Custom SCSS/CSS is also required for proper styling of the time picker and popup.