diff --git a/README.md b/README.md index b3209a5..0870047 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,8 @@ Custom Home Assistant card displaying a responsive overview of multiple days wit | `legendToggle` | boolean | false | `false` \| `true` | Toggle calendars by clicking on the legend | 1.11.0 | | `columns` | object | optional | See [Columns](#columns) | Configuration to override the number of columns | 1.11.0 | | `showNavigation` | boolean | false | `false` \| `true` | Show navigational arrows to traverse additional dates on calendar. | 1.12.0 | +| `showNavigationLabel` | boolean | true | `false` \| `true` | Show or hide the navigation label | 1.14.0 | +| `navigationLabelFormat` | string | `MMMM` | See [Luxon format](https://moment.github.io/luxon/#/formatting?id=table-of-tokens) | Format of the navigation label. Supports range templates using `{start: ...}` and `{end: ...}`. When these tokens are present, the left token formats the start date and the right token formats the inclusive end date. If omitted, the value is applied to the start date only. Example: `{start: MMM, dd} - {end: MMM, dd yyyy}` → `OCT, 27 - NOV, 09 2025`. | 1.14.0 | ### Calendars @@ -317,3 +319,25 @@ calendars: - calendar.my_calendar_1 dayFormat: '''''d'' ''MMMM''''' ``` + +### Navigation label single-date formatting + +```yaml +type: custom:week-planner-card +calendars: + - entity: calendar.my_calendar_1 +showNavigation: true +showNavigationLabel: true +navigationLabelFormat: 'MMM, dd yyyy' +``` + +### Navigation label range formatting + +```yaml +type: custom:week-planner-card +calendars: + - entity: calendar.my_calendar_1 +showNavigation: true +showNavigationLabel: true +navigationLabelFormat: '{start: MMM, dd} - {end: MMM, dd yyyy}' +``` diff --git a/src/card.js b/src/card.js index 4e2fa21..2fbdc5d 100644 --- a/src/card.js +++ b/src/card.js @@ -89,6 +89,7 @@ export class WeekPlannerCard extends LitElement { _showNavigation; _navigationOffset = 0; _updateEventsTimeouts = []; + _showNavigationLabel; /** * Get config element @@ -174,6 +175,8 @@ export class WeekPlannerCard extends LitElement { this._dayFormat = config.dayFormat ?? null; this._dateFormat = config.dateFormat ?? 'cccc d LLLL yyyy'; this._timeFormat = config.timeFormat ?? 'HH:mm'; + this._showNavigationLabel = config.showNavigationLabel ?? true; + this._navigationLabelFormat = config.navigationLabelFormat ?? 'MMMM'; this._locationLink = config.locationLink ?? 'https://www.google.com/maps/search/?api=1&query='; this._showTitle = config.showTitle ?? true; this._showDescription = config.showDescription ?? false; @@ -365,11 +368,51 @@ export class WeekPlannerCard extends LitElement {
  • -
    ${this._startDate.toFormat('MMMM')}
    + ${this._showNavigationLabel ? + html`
    ${this._getNavigationLabel()}
    ` : + '' + } `; } + _getNavigationLabel() { + if (this._showNavigationLabel) { + const template = this._navigationLabelFormat; + + // Support explicit start/end templates like "{start: MMM} - {end: MMM yyyy}" + if (template?.includes('{')) { + return this._formatNavigationLabel(template); + } + + // Default: single-date formatting + return this._startDate.toFormat(template); + } + return ''; + } + + _formatNavigationLabel(template) { + const startInclusive = this._startDate; + let endInclusive; + + if (this._numberOfDaysIsMonth) { + // Show the visual end of the month + endInclusive = startInclusive.endOf('month'); + } else { + // End is exclusive in calculations; make inclusive for display + endInclusive = startInclusive.plus({ days: this._numberOfDays }).minus({ days: 1 }); + } + + return template.replace(/\{(start|end):([^}]+)\}/g, (match, which, fmt) => { + const date = which === 'start' ? startInclusive : endInclusive; + try { + return date.toFormat(fmt.trim()); + } catch (e) { + return match; + } + }); + } + _renderDays() { if (!this._days) { return html``; diff --git a/src/editor.js b/src/editor.js index 0efe4f0..61c3332 100644 --- a/src/editor.js +++ b/src/editor.js @@ -117,6 +117,8 @@ export class WeekPlannerCardEditor extends LitElement { ${this.addBooleanField('hideTodayWithoutEvents', 'Also hide today without events')} ${this.addTextField('maxDayEvents', 'Maximum number of events per day (0 is no maximum)', 'number', 0)} ${this.addBooleanField('showNavigation', 'Show navigation')} + ${this.addBooleanField('showNavigationLabel', 'Show navigation label', true)} + ${this.addTextField('navigationLabelFormat', 'Navigation label format (Luxon)', 'text', 'MMMM')} ` )} ${this.addExpansionPanel(