Skip to content
Permalink
Browse files
feat(b-calendar, b-form-datepicker): allow customization of in-compon…
…ent displayed date format (closes #4797) (#4835)

* feat(b-calendar): made date format to be configurable

* Added new prop `formatLong` that defaults to current layout
* Allows for better control on display (e.g. in combination with layouts defined in other components like vue-i18n)

* feat(b-form-datepicker): Added format option for display of formatted date string

* docs(b-calendar): Updated prop list

* docs(b-form-datepicker): Updated prop list

* Fixed prop default value

* fix(b-form-datepicker): prop default value

* docs(b-calendar): change prop name and referenced default format

* docs(b-form-datepicker): change prop name and referenced default format

* fix(b-calendar): rename prop and enforce gregorian calendar

* fix(b-form-datepicker): rename prop in component and in forwarding to b-calendar

* chore(b-calendar): file formating

* docs(b-calendar): add styling subsection on new prop

* Fixed referenced filename

* docs(b-form-datepicker): add styling subsection on new prop

* Removed fixed calendar type from prop dateFormatOptions

* Removed fixed calendar type from prop dateFormatOptions

* Update package.json

* Update package.json

* Update README.md

* Update README.md

* Update calendar.js

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Minor tweaks

* Enhance docs

Co-authored-by: Troy Morehouse <troymore@nbnet.nb.ca>
Co-authored-by: Jacob Müller <jacob.mueller.elz@gmail.com>
  • Loading branch information
3 people committed Feb 26, 2020
1 parent 14f7ea1 commit 85c7e759bc78d2ffb5b026cb5ee484b2567136aa
Showing 6 changed files with 138 additions and 7 deletions.
@@ -230,12 +230,56 @@ fit the width of the parent element. The `width` prop has no effect when `block`
Note it is _not recommended_ to set a width below `260px`, otherwise truncation and layout issues
with the component may occur.

### Date string format

<span class="badge badge-info small">v2.6.0+</span>

To change format options of the displayed date text inside the component, e.g. in the header, set
the `dateFormatOptions` prop to an object containing the requested format properties for the
`Intl.DateTimeFormat` object (see also [Internationalization](#internationalization)).

```html
<template>
<div>
<p>Custom date format:</p>
<b-calendar
:dateFormatOptions="{ year: 'numeric', month: 'short', day: '2-digit', weekday: 'short' }"
locale="en"
></b-calendar>
<p class="mt-3">Short date format:</p>
<b-calendar
:dateFormatOptions="{ year: 'numeric', month: 'numeric', day: 'numeric' }"
locale="en"
></b-calendar>
</div>
</template>

<!-- b-calendar-dateformat.vue -->
```

The following table summarizes the valid options for each format property:

| Property | Possible values |
| --------- | ------------------------------------------------------------ |
| `year` | `'numeric'`, or `'2-digit'` |
| `month` | `'numeric'`, `'2-digit'`, `'long'`, `'short'`, or `'narrow'` |
| `day` | `'numeric'`, or `'2-digit'` |
| `weekday` | `'long'`, `'short'`, or `'narrow'` |

Notes:

- Leaving out certain options may affect the formatted text string, e.g. the `weekday`
- The formatted value will vary according to the resolved locale. Some locales may not support the
`'narrow'` format and will fall back to `'short'` or `long'` (if `'short'` is not available)
- `year`, `month` and `day` will always be shown. If you need to leave out a value, set the property
to `undefined`, although this is highly discouraged for accessibility reasons

### Hiding the top selected date header

By default, the current selected date will be displayed at the top of the calendar component,
formatted in the locale's language.

You can hide this header via the `hide-header` prop. Note this only visually hides the selected
You can hide this header via the `hide-header` prop. Note this only _visually hides_ the selected
date, while keeping it available to screen reader users as an `aria-live` region.

### Border and padding
@@ -400,7 +444,7 @@ properties:
| `selectedFormatted` | The selected date formatted in the current locale. If no date is selected, this will be the value of the `label-no-date-selected` prop |
| `activeYMD` | The current date of the calendar day button that can receive focus as a string (`YYYY-MM-DD` format) |
| `activeDate` | The current date of the calendar day button that can receive focus as a `Date` object |
| `activeFormated` | The active date formatted in the current locale |
| `activeFormatted` | The active date formatted in the current locale |
| `disabled` | Will be `true` if active date is disabled, `false` otherwise |
| `locale` | The resolved locale (may not be the same as the requested locale) |
| `calendarLocale` | The resolved locale used by the calendar, optionally including the calendar type (i.e. 'gregory'). Usually this will be the same as `locale`, but may include the calendar type used, such as `fa-u-ca-gregory` when selecting the Persian locale (`'fa'`) |
@@ -224,6 +224,16 @@ export const BCalendar = Vue.extend({
labelHelp: {
type: String,
default: () => getComponentConfig(NAME, 'labelHelp')
},
dateFormatOptions: {
// `Intl.DateTimeFormat` object
type: Object,
default: () => ({
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long'
})
}
},
data() {
@@ -372,10 +382,19 @@ export const BCalendar = Vue.extend({
formatDateString() {
// Returns a date formatter function
return createDateFormatter(this.calendarLocale, {
// Ensure we have year, month, day shown for screen readers/ARIA
// If users really want to leave one of these out, they can
// pass `undefined` for the property value
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long',
month: '2-digit',
day: '2-digit',
// Merge in user supplied options
...this.dateFormatOptions,
// Ensure hours/minutes/seconds are not shown
hour: undefined,
minute: undefined,
second: undefined,
// Ensure calendar is gregorian
calendar: 'gregory'
})
},
@@ -135,6 +135,11 @@
{
"prop": "labelHelp",
"description": "Help text that appears at the bottom of the calendar grid"
},
{
"prop": "dateFormatOptions",
"version": "2.6.0",
"description": "Format object for displayed text string that is passed to `Intl.DateTimeFormat`"
}
],
"events": [
@@ -301,6 +301,53 @@ and usage of these props.
Want a fancy popup with a dark background instead of a light background? Set the `dark` prop to
`true` to enable the dark background.

### Date string format

<span class="badge badge-info small">v2.6.0+</span>

To change format options of the displayed date text inside the component, e.g. in the header or
placeholder, set the `date-format-options` prop to an object containing the requested format
properties for the `Intl.DateTimeFormat` object (see also
[Internationalization](#internationalization)).

```html
<template>
<div>
<label for="datepicker-dateformat1">Custom date format</label>
<b-form-datepicker
id="datepicker-dateformat1"
:dateFormatOptions="{ year: 'numeric', month: 'short', day: '2-digit', weekday: 'short' }"
locale="en"
></b-form-datepicker>
<label for="datepicker-dateformat2">Short date format</label>
<b-form-datepicker
id="datepicker-dateformat2"
:dateFormatOptions="{ year: 'numeric', month: 'numeric', day: 'numeric' }"
locale="en"
></b-form-datepicker>
</div>
</template>

<!-- b-form-datepicker-dateformat.vue -->
```

The following table summarizes the valid options for each format property:

| Property | Possible values |
| --------- | ------------------------------------------------------------ |
| `year` | `'numeric'`, or `'2-digit'` |
| `month` | `'numeric'`, `'2-digit'`, `'long'`, `'short'`, or `'narrow'` |
| `day` | `'numeric'`, or `'2-digit'` |
| `weekday` | `'long'`, `'short'`, or `'narrow'` |

Notes:

- Leaving out certain options may affect the formatted text string, e.g. the `weekday`
- The formatted value will vary according to the resolved locale. Some locales may not support the
`'narrow'` format and will fall back to `'short'` or `long'` (if `'short'` is not available)
- `year`, `month` and `day` will always be shown. If you need to leave out a value, set the property
to `undefined`, although this is highly discouraged for accessibility reasons

## Internationalization

Internationalization of the date picker's calendar is provided via
@@ -208,6 +208,16 @@ const propsMixin = {
dark: {
type: Boolean,
default: false
},
dateFormatOptions: {
// `Intl.DateTimeFormat` object
type: Object,
default: () => ({
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long'
})
}
}
}
@@ -248,7 +258,7 @@ export const BFormDatepicker = /*#__PURE__*/ Vue.extend({
return this.activeYMD.slice(0, -3)
},
calendarProps() {
// We alis `this` to `self` for better minification
// We alias `this` to `self` for better minification
const self = this
// TODO: Make the ID's computed props
const idLabel = self.safeId('_value_')
@@ -280,7 +290,8 @@ export const BFormDatepicker = /*#__PURE__*/ Vue.extend({
labelNoDateSelected: self.labelNoDateSelected,
labelCalendar: self.labelCalendar,
labelNav: self.labelNav,
labelHelp: self.labelHelp
labelHelp: self.labelHelp,
dateFormatOptions: self.dateFormatOptions
}
},
computedResetValue() {
@@ -208,6 +208,11 @@
{
"prop": "labelCloseButton",
"description": "Content for the optional `Close` button"
},
{
"prop": "dateFormatOptions",
"version": "2.6.0",
"description": "Format object for displayed text string that is passed to `Intl.DateTimeFormat`"
}
],
"events": [

0 comments on commit 85c7e75

Please sign in to comment.