Skip to content

Commit f4f5af5

Browse files
authored
Merge branch 'main' into calendar-acc-improvements
2 parents 912245d + 4e18756 commit f4f5af5

13 files changed

Lines changed: 183 additions & 31 deletions

File tree

packages/main/cypress/specs/Calendar.cy.tsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import YearRangePicker from "../../src/YearRangePicker.js";
66
import YearPicker from "../../src/YearPicker.js";
77
import "@ui5/webcomponents-localization/dist/features/calendar/Islamic.js";
88
import "@ui5/webcomponents-localization/dist/features/calendar/Gregorian.js";
9+
import { resetConfiguration } from "@ui5/webcomponents-base/dist/InitialConfiguration.js";
10+
import { getFirstDayOfWeek } from "@ui5/webcomponents-base/dist/config/FormatSettings.js";
911

1012
const getDefaultCalendar = (date: Date) => {
1113
const calDate = new Date(date);
@@ -1434,3 +1436,40 @@ describe("Day Picker Tests", () => {
14341436
});
14351437
});
14361438
});
1439+
1440+
describe("Calendar Global Configuration", () => {
1441+
it("Should respect firstDayOfWeek from global formatSettings configuration", () => {
1442+
const configurationObject = {
1443+
"formatSettings": {
1444+
"firstDayOfWeek": 6 // Saturday
1445+
}
1446+
};
1447+
1448+
cy.window()
1449+
.then($el => {
1450+
const scriptElement = $el.document.createElement("script");
1451+
scriptElement.type = "application/json";
1452+
scriptElement.setAttribute("data-ui5-config", "true");
1453+
scriptElement.innerHTML = JSON.stringify(configurationObject);
1454+
$el.document.head.appendChild(scriptElement);
1455+
});
1456+
1457+
cy.wrap({ resetConfiguration })
1458+
.invoke("resetConfiguration", true);
1459+
1460+
cy.wrap({ getFirstDayOfWeek })
1461+
.invoke("getFirstDayOfWeek")
1462+
.should("equal", 6);
1463+
1464+
const date = new Date(Date.UTC(2023, 0, 1, 0, 0, 0)); // January 1, 2023
1465+
cy.mount(<Calendar id="calendar1" timestamp={date.valueOf() / 1000} calendarWeekNumbering="Default" />);
1466+
1467+
cy.get<Calendar>("#calendar1")
1468+
.shadow()
1469+
.find("[ui5-daypicker]")
1470+
.shadow()
1471+
.find(".ui5-dp-firstday")
1472+
.first()
1473+
.should("have.text", "Sat");
1474+
});
1475+
});

packages/main/cypress/specs/TableCustomAnnouncement.cy.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,15 @@ describe("Cell Custom Announcement - More details", () => {
148148
cy.realPress("ArrowRight"); // Row actions cell
149149
checkAnnouncement(Table.i18nBundle.getText(MULTIPLE_ACTIONS, 2));
150150
cy.focused().should("have.attr", "aria-colindex", "6")
151-
.should("have.attr", "role", "gridcell");
151+
.should("have.attr", "role", "gridcell")
152+
.then($rowActionsCell => {
153+
const rowActionsCell = $rowActionsCell[0];
154+
const invisibleText = document.getElementById("ui5-table-invisible-text");
155+
expect(rowActionsCell.ariaLabelledByElements[0]).to.equal(invisibleText);
156+
rowActionsCell.blur();
157+
expect(rowActionsCell.ariaLabelledByElements).to.equal(null);
158+
rowActionsCell.focus();
159+
});
152160

153161
cy.get("#row1-edit-action").invoke("remove");
154162
checkAnnouncement(ONE_ROW_ACTION, true);

packages/main/cypress/specs/TimePicker.cy.tsx

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,77 @@ describe("Validation inside a form", () => {
545545
});
546546
});
547547

548+
describe("Icon Tooltip Tests", () => {
549+
it("TimePicker icon tooltip changes when toggling picker", () => {
550+
cy.mount(<TimePicker />);
551+
552+
cy.get<TimePicker>("[ui5-time-picker]")
553+
.as("timePicker");
554+
555+
cy.get<TimePicker>("@timePicker")
556+
.should("not.have.attr", "open");
557+
558+
cy.get<TimePicker>("@timePicker")
559+
.shadow()
560+
.find("ui5-icon")
561+
.as("icon")
562+
.should("have.attr", "accessible-name", "Open Picker");
563+
564+
cy.get<TimePicker>("@timePicker")
565+
.ui5TimePickerValueHelpIconPress();
566+
567+
cy.get<TimePicker>("@timePicker")
568+
.should("have.attr", "open");
569+
570+
cy.get("@icon")
571+
.should("have.attr", "accessible-name", "Close Picker");
572+
573+
cy.get<TimePicker>("@timePicker")
574+
.ui5TimePickerValueHelpIconPress();
575+
576+
cy.get<TimePicker>("@timePicker")
577+
.should("not.have.attr", "open");
578+
579+
cy.get("@icon")
580+
.should("have.attr", "accessible-name", "Open Picker");
581+
});
582+
583+
it("TimePicker icon tooltip changes when using keyboard shortcuts", () => {
584+
cy.mount(<TimePicker />);
585+
586+
cy.get<TimePicker>("[ui5-time-picker]")
587+
.as("timePicker")
588+
.ui5TimePickerGetInnerInput()
589+
.as("input")
590+
.realClick()
591+
.should("be.focused");
592+
593+
cy.get<TimePicker>("@timePicker")
594+
.shadow()
595+
.find("ui5-icon")
596+
.as("icon")
597+
.should("have.attr", "accessible-name", "Open Picker");
598+
599+
cy.get("@input")
600+
.realPress("F4");
601+
602+
cy.get<TimePicker>("@timePicker")
603+
.should("have.attr", "open");
604+
605+
cy.get("@icon")
606+
.should("have.attr", "accessible-name", "Close Picker");
607+
608+
cy.get("@input")
609+
.realPress(["Alt", "ArrowUp"]);
610+
611+
cy.get<TimePicker>("@timePicker")
612+
.should("not.have.attr", "open");
613+
614+
cy.get("@icon")
615+
.should("have.attr", "accessible-name", "Open Picker");
616+
});
617+
});
618+
548619
describe("CSS Parts", () => {
549620
it("TimePicker exposes input CSS part through DateTimeInput", () => {
550621
cy.mount(<TimePicker />);

packages/main/src/DayPicker.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
isPageDownAlt,
3232
isPageDownShiftCtrl,
3333
} from "@ui5/webcomponents-base/dist/Keys.js";
34+
import { getFirstDayOfWeek } from "@ui5/webcomponents-base/dist/config/FormatSettings.js";
3435
import CalendarDate from "@ui5/webcomponents-localization/dist/dates/CalendarDate.js";
3536
import CalendarType from "@ui5/webcomponents-base/dist/types/CalendarType.js";
3637
import UI5Date from "@ui5/webcomponents-localization/dist/dates/UI5Date.js";
@@ -853,10 +854,23 @@ class DayPicker extends CalendarPart implements ICalendarPicker {
853854
}
854855

855856
_getFirstDayOfWeek(): number {
857+
const localeData = getCachedLocaleDataInstance(getLocale());
858+
let firstDayOfWeek;
859+
const configurationFirstDayOfWeek = getFirstDayOfWeek();
860+
861+
if (configurationFirstDayOfWeek !== undefined) {
862+
firstDayOfWeek = configurationFirstDayOfWeek;
863+
} else {
864+
firstDayOfWeek = localeData.getFirstDayOfWeek();
865+
}
866+
856867
const result = CalendarUtils.getWeekConfigurationValues(this.calendarWeekNumbering);
857868

858-
const localeData = getCachedLocaleDataInstance(getLocale());
859-
return result?.firstDayOfWeek ? result.firstDayOfWeek : localeData.getFirstDayOfWeek();
869+
if (result?.firstDayOfWeek !== undefined && this.calendarWeekNumbering !== "Default") {
870+
return result.firstDayOfWeek;
871+
}
872+
873+
return firstDayOfWeek;
860874
}
861875

862876
get styles() {

packages/main/src/TableCustomAnnouncement.ts

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,37 +23,32 @@ import {
2323
} from "./generated/i18n/i18n-defaults.js";
2424

2525
let invisibleText: HTMLElement;
26-
const i18nBundle = new I18nBundle("@ui5/webcomponents/main");
26+
const i18nBundle = new I18nBundle("@ui5/webcomponents");
2727

2828
const checkVisibility = (element: HTMLElement): boolean => {
2929
return element.checkVisibility() || getComputedStyle(element).display === "contents";
3030
};
3131

32-
const updateInvisibleText = (element: HTMLElement, text: string | string[] = []) => {
33-
const invisibleTextId = "ui5-table-invisible-text";
32+
const updateInvisibleText = (element: any, text: string | string[] = []) => {
3433
if (!invisibleText || !invisibleText.isConnected) {
3534
invisibleText = document.createElement("span");
36-
invisibleText.id = invisibleTextId;
35+
invisibleText.id = "ui5-table-invisible-text";
3736
invisibleText.ariaHidden = "true";
3837
invisibleText.style.display = "none";
3938
document.body.appendChild(invisibleText);
4039
}
4140

42-
let ariaLabelledBy = (element.getAttribute("aria-labelledby") || "").split(" ").filter(Boolean);
43-
const invisibleTextAssociated = ariaLabelledBy.includes(invisibleTextId);
44-
41+
const ariaLabelledByElements = [...(element.ariaLabelledByElements || [])];
42+
const invisibleTextIndex = ariaLabelledByElements.indexOf(invisibleText);
4543
text = Array.isArray(text) ? text.filter(Boolean).join(" . ").trim() : text.trim();
46-
if (text && !invisibleTextAssociated) {
47-
ariaLabelledBy.push(invisibleTextId);
48-
} else if (!text && invisibleTextAssociated) {
49-
ariaLabelledBy = ariaLabelledBy.filter(id => id !== invisibleTextId);
50-
}
51-
5244
invisibleText.textContent = text;
53-
if (ariaLabelledBy.length > 0) {
54-
element.setAttribute("aria-labelledby", ariaLabelledBy.join(" "));
55-
} else {
56-
element.removeAttribute("aria-labelledby");
45+
46+
if (text && invisibleTextIndex === -1) {
47+
ariaLabelledByElements.unshift(invisibleText);
48+
element.ariaLabelledByElements = ariaLabelledByElements;
49+
} else if (!text && invisibleTextIndex > -1) {
50+
ariaLabelledByElements.splice(invisibleTextIndex, 1);
51+
element.ariaLabelledByElements = ariaLabelledByElements.length ? ariaLabelledByElements : null;
5752
}
5853
};
5954

packages/main/src/Text.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,25 +22,25 @@ import styles from "./generated/themes/Text.css.js";
2222
/**
2323
* @class
2424
*
25-
* <h3>Overview</h3>
25+
* ### Overview
2626
*
2727
* The `ui5-text` component displays text that can be used in any content area of an application.
2828
*
29-
* <h3>Usage</h3>
29+
* ### Usage
3030
*
3131
* - Use the `ui5-text` if you want to display text inside a form, table, or any other content area.
3232
* - Do not use the `ui5-text` if you need to reference input type of components (use ui5-label).
3333
*
34-
* <h3>Responsive behavior</h3>
34+
* ### Responsive behavior
3535
*
3636
* The `ui5-text` component is fully adaptive to all screen sizes.
3737
* By default, the text will wrap when the space is not enough.
38-
* In addition, the component supports truncation via the <code>max-lines</code> property,
38+
* In addition, the component supports truncation via the `max-lines` property,
3939
* by defining the number of lines the text should wrap before start truncating.
4040
*
41-
* <h3>ES6 Module Import</h3>
41+
* ### ES6 Module Import
4242
*
43-
* <code>import "@ui5/webcomponents/dist/Text";</code>
43+
* `import "@ui5/webcomponents/dist/Text";`
4444
*
4545
* @constructor
4646
* @extends UI5Element

packages/main/src/TimePicker.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ import {
5959
VALUE_STATE_WARNING,
6060
TIMEPICKER_VALUE_MISSING,
6161
TIMEPICKER_PATTERN_MISSMATCH,
62+
TIMEPICKER_OPEN_ICON_TITLE_OPENED,
63+
TIMEPICKER_OPEN_ICON_TITLE,
6264
} from "./generated/i18n/i18n-defaults.js";
6365

6466
// Styles
@@ -487,6 +489,14 @@ class TimePicker extends UI5Element implements IFormInputElement {
487489
this.tempValue = e.detail.value; // every time the user changes the time selection -> update tempValue
488490
}
489491

492+
get openIconTitle() {
493+
if (this.open) {
494+
return TimePicker.i18nBundle.getText(TIMEPICKER_OPEN_ICON_TITLE_OPENED);
495+
}
496+
497+
return TimePicker.i18nBundle.getText(TIMEPICKER_OPEN_ICON_TITLE);
498+
}
499+
490500
_togglePicker() {
491501
this.open = !this.open;
492502
if (this._isMobileDevice) {

packages/main/src/TimePickerTemplate.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export default function TimePickerTemplate(this: TimePicker) {
4040
name={timeEntryRequest}
4141
tabindex={-1}
4242
showTooltip={true}
43+
accessibleName={this.openIconTitle}
4344
mode={this._iconMode}
4445
onClick={this._togglePicker}
4546
class={{

packages/main/src/i18n/messagebundle.properties

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,12 @@ TIMEPICKER_INPUTS_ENTER_MINUTES=Please enter minutes
549549
#XACT: Time Picker Inputs tooltip/aria-label for Seconds input
550550
TIMEPICKER_INPUTS_ENTER_SECONDS=Please enter seconds
551551

552+
#XACT: Time Picker 'Open Picker' icon title
553+
TIMEPICKER_OPEN_ICON_TITLE=Open Picker
554+
555+
#XACT: Time Picker 'Open Picker' icon title when the picker is opened
556+
TIMEPICKER_OPEN_ICON_TITLE_OPENED=Close Picker
557+
552558
TIMEPICKER_VALUE_MISSING=Fill in the time value in the format: {0}.
553559

554560
TIMEPICKER_PATTERN_MISSMATCH=This format is not supported. Fill in the time value in the format: {0}.

packages/main/test/pages/Calendar.html

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,18 @@
1010
// delete Document.prototype.adoptedStyleSheets;
1111
</script>
1212

13-
<script data-ui5-config type="application/json">
13+
<!-- <script data-ui5-config type="application/json">
1414
{
1515
"language": "EN"
1616
}
17+
</script> -->
18+
<script data-id="sap-ui-config" type="application/json">
19+
{
20+
"rtl": false,
21+
"formatSettings": {
22+
"firstDayOfWeek": 0
23+
}
24+
}
1725
</script>
1826

1927
<script src="%VITE_BUNDLE_PATH%" type="module"></script>

0 commit comments

Comments
 (0)