Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ui5-calendar): add tooltips to special dates #10335

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/main/src/Calendar.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
format-pattern="{{_formatPattern}}"
.selectedDates="{{_selectedDatesTimestamps}}"
.specialCalendarDates="{{_specialCalendarDates}}"
._calendarLegend="{{calendarLegend}}"
._hidden="{{_isDayPickerHidden}}"
.primaryCalendarType="{{_primaryCalendarType}}"
.secondaryCalendarType="{{_secondaryCalendarType}}"
Expand Down
1 change: 1 addition & 0 deletions packages/main/src/DayPicker.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
?data-sap-focus-ref="{{this.focusRef}}"
data-sap-timestamp="{{this.timestamp}}"
role="gridcell"
title="{{this.tooltip}}"
aria-selected="{{this.ariaSelected}}"
aria-label="{{this.ariaLabel}}"
aria-disabled="{{this.ariaDisabled}}"
Expand Down
23 changes: 20 additions & 3 deletions packages/main/src/DayPicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import CalendarUtils from "@ui5/webcomponents-localization/dist/CalendarUtils.js
import DateFormat from "@ui5/webcomponents-localization/dist/DateFormat.js";
import CalendarSelectionMode from "./types/CalendarSelectionMode.js";
import CalendarPart from "./CalendarPart.js";
import type CalendarLegend from "./CalendarLegend.js";
import type {
ICalendarPicker,
SpecialCalendarDateT,
Expand Down Expand Up @@ -72,6 +73,7 @@ type Day = {
selected: boolean,
_isSecondaryCalendarType: boolean,
classes: string,
tooltip?: string,
ariaLabel: string,
ariaSelected: string,
ariaDisabled: string | undefined,
Expand Down Expand Up @@ -168,6 +170,9 @@ class DayPicker extends CalendarPart implements ICalendarPicker {
@property({ type: Array })
_dayNames: Array<DayName> = [];

@property({ type: Array })
_calendarLegend!: Array<CalendarLegend>;

/**
* When set, the component will skip all work in onBeforeRendering and will not automatically set the focus on itself
* @private
Expand Down Expand Up @@ -218,6 +223,7 @@ class DayPicker extends CalendarPart implements ICalendarPicker {
const secondaryMonthsNames = this.hasSecondaryCalendarType ? localeData.getMonths("wide", this.secondaryCalendarType) as Array<string> : [];
const nonWorkingDayLabel = DayPicker.i18nBundle.getText(DAY_PICKER_NON_WORKING_DAY);
const todayLabel = DayPicker.i18nBundle.getText(DAY_PICKER_TODAY);
const calendarLegend = this._calendarLegend && this._calendarLegend[0];
const tempDate = this._getFirstDay(); // date that will be changed by 1 day 42 times
const todayDate = CalendarDate.fromLocalJSDate(UI5Date.getInstance(), this._primaryCalendarType); // current day date - calculate once
const calendarDate = this._calendarDate; // store the _calendarDate value as this getter is expensive and degrades IE11 perf
Expand All @@ -237,6 +243,8 @@ class DayPicker extends CalendarPart implements ICalendarPicker {

const specialCalendarDate = specialCalendarDates.find(specialDate => specialDate.specialDateTimestamp === timestamp);
const specialDayType = specialCalendarDate ? specialCalendarDate.type : "";
const calendarLegendItemText = calendarLegend?.items.find(item => item.type === specialDayType)?.text;
const unnamedCalendarTypeLabel = calendarLegendItemText && !this._isDefaultCalendarLegendType(specialDayType) ? calendarLegendItemText : "";

const isFocused = tempDate.getMonth() === calendarDate.getMonth() && tempDate.getDate() === calendarDate.getDate();
const isSelected = this._isDaySelected(timestamp);
Expand All @@ -247,16 +255,20 @@ class DayPicker extends CalendarPart implements ICalendarPicker {
const isToday = tempDate.isSame(todayDate);
const isFirstDayOfWeek = tempDate.getDay() === firstDayOfWeek;

const nonWorkingAriaLabel = isWeekend ? `${nonWorkingDayLabel} ` : "";
const nonWorkingAriaLabel = (isWeekend || specialDayType === "NonWorking") && specialDayType !== "Working"
? `${nonWorkingDayLabel} `
: "";
const todayAriaLabel = isToday ? `${todayLabel} ` : "";

const tempSecondDateNumber = tempSecondDate ? tempSecondDate.getDate() : "";
const tempSecondYearNumber = tempSecondDate ? tempSecondDate.getYear() : "";
const secondaryMonthsNamesString = secondaryMonthsNames.length > 0 ? secondaryMonthsNames[tempSecondDate!.getMonth()] : "";

const tooltip = `${todayAriaLabel}${nonWorkingAriaLabel}${unnamedCalendarTypeLabel}`;

const ariaLabel = this.hasSecondaryCalendarType
? `${todayAriaLabel}${nonWorkingAriaLabel}${monthsNames[tempDate.getMonth()]} ${tempDate.getDate()}, ${tempDate.getYear()}; ${secondaryMonthsNamesString} ${tempSecondDateNumber}, ${tempSecondYearNumber}`
: `${todayAriaLabel}${nonWorkingAriaLabel}${monthsNames[tempDate.getMonth()]} ${tempDate.getDate()}, ${tempDate.getYear()}`;
? `${monthsNames[tempDate.getMonth()]} ${tempDate.getDate()}, ${tempDate.getYear()}; ${secondaryMonthsNamesString} ${tempSecondDateNumber}, ${tempSecondYearNumber} ${tooltip} `
: `${monthsNames[tempDate.getMonth()]} ${tempDate.getDate()}, ${tempDate.getYear()} ${tooltip}`;

const day: Day = {
timestamp: timestamp.toString(),
Expand All @@ -267,6 +279,7 @@ class DayPicker extends CalendarPart implements ICalendarPicker {
secondDay: this.hasSecondaryCalendarType ? (tempSecondDate as CalendarDate).getDate() : undefined,
_isSecondaryCalendarType: this.hasSecondaryCalendarType,
classes: `ui5-dp-item ui5-dp-wday${dayOfTheWeek}`,
tooltip,
ariaLabel,
ariaSelected: String(isSelected || isSelectedBetween),
ariaDisabled: isDisabled || isOtherMonth ? "true" : undefined,
Expand Down Expand Up @@ -792,6 +805,10 @@ class DayPicker extends CalendarPart implements ICalendarPicker {
return (target.className.indexOf("ui5-dp-item") > -1) || (targetParent && targetParent.classList && targetParent.classList.contains("ui5-dp-item"));
}

_isDefaultCalendarLegendType(type: string): boolean {
return type === "NonWorking" || type === "Working" || type === "Today" || type === "Selected" || type === "None";
}

_getSecondaryDay(tempDate: CalendarDate): CalendarDate {
return new CalendarDate(tempDate, this.secondaryCalendarType);
}
Expand Down
1 change: 1 addition & 0 deletions packages/main/src/themes/DayPicker.css
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
font-size: var(--sapFontSize);
border: var(--_ui5_daypicker_item_border);
border-radius: var(--_ui5_daypicker_item_border_radius);
cursor: pointer;
}

.ui5-dp-item:hover {
Expand Down
Loading