Skip to content

Commit

Permalink
feat(b-calendar, b-form-datepicker): allow customization of in-compon…
Browse files Browse the repository at this point in the history
…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 85c7e75
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 7 deletions.
48 changes: 46 additions & 2 deletions src/components/calendar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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'`) |
Expand Down
25 changes: 22 additions & 3 deletions src/components/calendar/calendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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'
})
},
Expand Down
5 changes: 5 additions & 0 deletions src/components/calendar/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand Down
47 changes: 47 additions & 0 deletions src/components/form-datepicker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 13 additions & 2 deletions src/components/form-datepicker/form-datepicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
})
}
}
}
Expand Down Expand Up @@ -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_')
Expand Down Expand Up @@ -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() {
Expand Down
5 changes: 5 additions & 0 deletions src/components/form-datepicker/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand Down

0 comments on commit 85c7e75

Please sign in to comment.