diff --git a/packages/localization/package.json b/packages/localization/package.json index 556e5500ae86..221042266a73 100644 --- a/packages/localization/package.json +++ b/packages/localization/package.json @@ -39,7 +39,7 @@ "resolve": "^1.20.0" }, "dependencies": { - "@types/openui5": "^1.113.0", + "@types/openui5": "^1.146.0", "@ui5/webcomponents-base": "2.22.0-rc.0" } } diff --git a/packages/localization/src/DateFormat.ts b/packages/localization/src/DateFormat.ts index da6649603374..5596e83b7f92 100644 --- a/packages/localization/src/DateFormat.ts +++ b/packages/localization/src/DateFormat.ts @@ -1,8 +1,42 @@ import type DateFormatT from "sap/ui/core/format/DateFormat"; // @ts-ignore import DateFormatNative from "./sap/ui/core/format/DateFormat.js"; +import getLocale from "@ui5/webcomponents-base/dist/locale/getLocale.js"; +import LocaleWrapped from "./Locale.js"; +import type CalendarWeekNumbering from "sap/base/i18n/date/CalendarWeekNumbering"; +import type CalendarType from "sap/base/i18n/date/CalendarType"; + +type DateFormatOptions = { + calendarWeekNumbering?: CalendarWeekNumbering | keyof typeof CalendarWeekNumbering; + firstDayOfWeek?: int; + minimalDaysInFirstWeek?: int; + format?: string; + pattern?: string; + style?: string; + strictParsing?: boolean; + relative?: boolean; + relativeRange?: int[]; + relativeScale?: string; + relativeStyle?: string; + interval?: boolean; + intervalDelimiter?: string; + singleIntervalValue?: boolean; + UTC?: boolean; + calendarType?: CalendarType | keyof typeof CalendarType; +}; const DateFormatWrapped = DateFormatNative as typeof DateFormatT; -class DateFormat extends DateFormatWrapped {} + +class DateFormat extends DateFormatWrapped { + static getDateInstance(oFormatOptions?: DateFormatOptions, oLocale?: LocaleWrapped): DateFormat; + static getDateInstance(oLocale?: LocaleWrapped): DateFormat; + static getDateInstance(oFormatOptionsOrLocale?: DateFormatOptions | LocaleWrapped, oLocale?: LocaleWrapped): DateFormat { + if (oFormatOptionsOrLocale instanceof LocaleWrapped) { + return DateFormatWrapped.getDateInstance(undefined, oFormatOptionsOrLocale); + } + const nativeLocale = oLocale ?? new LocaleWrapped(getLocale().toString()); + return DateFormatWrapped.getDateInstance(oFormatOptionsOrLocale, nativeLocale); + } +} export default DateFormat; diff --git a/packages/localization/src/Locale.ts b/packages/localization/src/Locale.ts new file mode 100644 index 000000000000..79a0b1dc0f12 --- /dev/null +++ b/packages/localization/src/Locale.ts @@ -0,0 +1,8 @@ +import type LocaleOpenUI5T from "sap/ui/core/Locale"; +// @ts-ignore +import LocaleNative from "./sap/ui/core/Locale.js"; + +const LocaleWrapped = LocaleNative as typeof LocaleOpenUI5T; +class Locale extends LocaleWrapped { } + +export default Locale; diff --git a/packages/localization/src/dates/convertMonthNumbersToMonthNames.ts b/packages/localization/src/dates/convertMonthNumbersToMonthNames.ts index 21c79a55115a..40b2fd16f9d1 100644 --- a/packages/localization/src/dates/convertMonthNumbersToMonthNames.ts +++ b/packages/localization/src/dates/convertMonthNumbersToMonthNames.ts @@ -15,8 +15,8 @@ import getCachedLocaleDataInstance from "../getCachedLocaleDataInstance.js"; const convertMonthNumbersToMonthNames = (firstMonth: number, lastMonth: number, calendarType?: `${CalendarType}`) => { const localeData = getCachedLocaleDataInstance(getLocale()); const pattern = localeData.getIntervalPattern(""); - const secondaryMonthsNames = localeData.getMonthsStandAlone("abbreviated", calendarType) as Array; - const secondaryMonthsNamesWide = localeData.getMonthsStandAlone("wide", calendarType) as Array; + const secondaryMonthsNames = localeData.getMonthsStandAlone("abbreviated", calendarType); + const secondaryMonthsNamesWide = localeData.getMonthsStandAlone("wide", calendarType); if (firstMonth === lastMonth) { return { diff --git a/packages/localization/src/getCachedLocaleDataInstance.ts b/packages/localization/src/getCachedLocaleDataInstance.ts index 169b4d6c2dba..38542ca57107 100644 --- a/packages/localization/src/getCachedLocaleDataInstance.ts +++ b/packages/localization/src/getCachedLocaleDataInstance.ts @@ -6,6 +6,8 @@ const cache = new Map(); const getCachedLocaleDataInstance = (locale: Locale) => { if (!cache.has(locale)) { + // @ts-expect-error - The LocaleData constructor expects a LocaleT, but we are passing a Locale. This is a known issue and can be ignored for now. + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument cache.set(locale, new LocaleData(locale as unknown as LocaleT)); } diff --git a/packages/localization/src/locale/getLocaleData.ts b/packages/localization/src/locale/getLocaleData.ts index 437c0a1c1056..6e2ac429ac26 100644 --- a/packages/localization/src/locale/getLocaleData.ts +++ b/packages/localization/src/locale/getLocaleData.ts @@ -19,6 +19,8 @@ const getLocaleData = async (lang: string): Promise => { if (!instances.has(localeLang)) { await fetchCldr(locale.getLanguage(), locale.getRegion(), locale.getScript()); + // @ts-expect-error - The LocaleData constructor expects a LocaleT, but we are passing a Locale. This is a known issue and can be ignored for now. + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument instances.set(localeLang, new LocaleData(locale as unknown as LocaleT)); } diff --git a/packages/localization/src/sap/base/i18n/Formatting.ts b/packages/localization/src/sap/base/i18n/Formatting.ts index 812e7105c4d9..23a868956a11 100644 --- a/packages/localization/src/sap/base/i18n/Formatting.ts +++ b/packages/localization/src/sap/base/i18n/Formatting.ts @@ -1,8 +1,8 @@ import { getLegacyDateCalendarCustomizing } from "@ui5/webcomponents-base/dist/config/FormatSettings.js"; -import { getLanguage } from "@ui5/webcomponents-base/dist/config/Language.js"; import { getCalendarType } from "@ui5/webcomponents-base/dist/config/CalendarType.js"; +import getLocale from "@ui5/webcomponents-base/dist/locale/getLocale.js"; -const emptyFn = () => {}; +const emptyFn = () => { }; /** * OpenUI5 Formatting Shim @@ -10,7 +10,7 @@ const emptyFn = () => {}; const Formatting = { getABAPDateFormat: emptyFn, getCustomIslamicCalendarData: getLegacyDateCalendarCustomizing, - getLanguageTag: () => getLanguage() || "en", + getLanguageTag: () => getLocale().toString(), getCalendarType, getTrailingCurrencyCode: () => true, getCustomLocaleData: () => ({}), diff --git a/packages/localization/src/sap/base/i18n/Localization.ts b/packages/localization/src/sap/base/i18n/Localization.ts index 518ae14c0ffc..3625ed49054c 100644 --- a/packages/localization/src/sap/base/i18n/Localization.ts +++ b/packages/localization/src/sap/base/i18n/Localization.ts @@ -1,5 +1,5 @@ -import { getLanguage } from "@ui5/webcomponents-base/dist/config/Language.js"; import { getTimezone as getConfigTimezone } from "@ui5/webcomponents-base/dist/config/Timezone.js"; +import getLocale from "@ui5/webcomponents-base/dist/locale/getLocale.js"; const M_ISO639_OLD_TO_NEW = { "iw": "he", @@ -12,7 +12,7 @@ const getModernLanguage = (sLanguage: string) => { const Localization = { getModernLanguage, - getLanguageTag: () => getLanguage() || "en", + getLanguageTag: () => getLocale().toString(), getTimezone: () => getConfigTimezone() || Intl.DateTimeFormat().resolvedOptions().timeZone, setTimezone: () => {}, }; diff --git a/packages/main/src/DayPicker.ts b/packages/main/src/DayPicker.ts index 6fad0fa4e087..affaeaaca9a5 100644 --- a/packages/main/src/DayPicker.ts +++ b/packages/main/src/DayPicker.ts @@ -233,8 +233,8 @@ class DayPicker extends CalendarPart implements ICalendarPicker { const firstDayOfWeek = this._getFirstDayOfWeek(); const specialCalendarDates = this._specialCalendarDates; - const monthsNames = localeData.getMonths("wide", this._primaryCalendarType) as Array; - const secondaryMonthsNames = this.hasSecondaryCalendarType ? localeData.getMonths("wide", this.secondaryCalendarType) as Array : []; + const monthsNames = localeData.getMonths("wide", this._primaryCalendarType); + const secondaryMonthsNames = this.hasSecondaryCalendarType ? localeData.getMonths("wide", this.secondaryCalendarType) : []; const nonWorkingDayLabel = DayPicker.i18nBundle.getText(DAY_PICKER_NON_WORKING_DAY); const todayLabel = DayPicker.i18nBundle.getText(DAY_PICKER_TODAY); const tempDate = this._getFirstDay(); // date that will be changed by 1 day 42 times @@ -385,12 +385,12 @@ class DayPicker extends CalendarPart implements ICalendarPicker { let dayOfTheWeek; - const aDayNamesWide = localeData.getDays("wide", this._primaryCalendarType) as Array; - let aDayNamesAbbreviated = localeData.getDays("abbreviated", this._primaryCalendarType) as Array; + const aDayNamesWide = localeData.getDays("wide", this._primaryCalendarType); + let aDayNamesAbbreviated = localeData.getDays("abbreviated", this._primaryCalendarType); let dayName; if (this.namesTooLong(aDayNamesAbbreviated)) { - aDayNamesAbbreviated = localeData.getDays("narrow", this._primaryCalendarType) as Array; + aDayNamesAbbreviated = localeData.getDays("narrow", this._primaryCalendarType); } this._dayNames = []; diff --git a/packages/main/src/MonthPicker.ts b/packages/main/src/MonthPicker.ts index 881ab8d9bdc9..63a514d75b27 100644 --- a/packages/main/src/MonthPicker.ts +++ b/packages/main/src/MonthPicker.ts @@ -46,7 +46,7 @@ type Month = { selected: boolean, ariaSelected: boolean, name: string, - nameInSecType: string, + nameInSecType: string | undefined, disabled: boolean, ariaDisabled: boolean | undefined, classes: string, @@ -191,7 +191,7 @@ class MonthPicker extends CalendarPart implements ICalendarPicker { selected: isSelected || isSelectedBetween, ariaSelected: isSelected || isSelectedBetween, name: monthsNames[i], - nameInSecType: this.hasSecondaryCalendarType && this._getDisplayedSecondaryMonthText(timestamp).text, + nameInSecType: this.hasSecondaryCalendarType ? this._getDisplayedSecondaryMonthText(timestamp).text : undefined, disabled: isDisabled, ariaDisabled: isDisabled, classes: "ui5-mp-item", diff --git a/packages/main/src/YearPicker.ts b/packages/main/src/YearPicker.ts index c487eb23daf6..4780c867b0c4 100644 --- a/packages/main/src/YearPicker.ts +++ b/packages/main/src/YearPicker.ts @@ -2,7 +2,6 @@ import customElement from "@ui5/webcomponents-base/dist/decorators/customElement import property from "@ui5/webcomponents-base/dist/decorators/property.js"; import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js"; import i18n from "@ui5/webcomponents-base/dist/decorators/i18n.js"; -import type LocaleT from "sap/ui/core/Locale"; import DateFormat from "@ui5/webcomponents-localization/dist/DateFormat.js"; import { isEnter, @@ -18,7 +17,6 @@ import { isPageUp, isPageDown, } from "@ui5/webcomponents-base/dist/Keys.js"; -import getLocale from "@ui5/webcomponents-base/dist/locale/getLocale.js"; import transformDateToSecondaryType from "@ui5/webcomponents-localization/dist/dates/transformDateToSecondaryType.js"; import CalendarDate from "@ui5/webcomponents-localization/dist/dates/CalendarDate.js"; import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js"; @@ -161,9 +159,8 @@ class YearPicker extends CalendarPart implements ICalendarPicker { _buildYears() { const pageSize = this._getPageSize(); - const locale = getLocale() as unknown as LocaleT; - const oYearFormat = DateFormat.getDateInstance({ format: "y", calendarType: this._primaryCalendarType }, locale); - const oYearFormatInSecType = DateFormat.getDateInstance({ format: "y", calendarType: this.secondaryCalendarType }, locale); + const oYearFormat = DateFormat.getDateInstance({ format: "y", calendarType: this._primaryCalendarType }); + const oYearFormatInSecType = DateFormat.getDateInstance({ format: "y", calendarType: this.secondaryCalendarType }); const calendarDate = this._calendarDate; // store the value of the expensive getter const minDate = this._minDate; // store the value of the expensive getter diff --git a/packages/main/src/YearRangePicker.ts b/packages/main/src/YearRangePicker.ts index 6494deb8a3ca..713865f1daa3 100644 --- a/packages/main/src/YearRangePicker.ts +++ b/packages/main/src/YearRangePicker.ts @@ -2,7 +2,6 @@ import customElement from "@ui5/webcomponents-base/dist/decorators/customElement import property from "@ui5/webcomponents-base/dist/decorators/property.js"; import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js"; import i18n from "@ui5/webcomponents-base/dist/decorators/i18n.js"; -import type LocaleT from "sap/ui/core/Locale"; import DateFormat from "@ui5/webcomponents-localization/dist/DateFormat.js"; import { isEnter, @@ -145,7 +144,7 @@ class YearRangePicker extends CalendarPart implements ICalendarPicker { } _shouldShowOneColumn() { - const locale = getLocale() as unknown as LocaleT; + const locale = getLocale(); const language = locale.getLanguage(); const longLanguages = ["zh", "ja", "ko", "bg", "mk", "ru"]; @@ -200,9 +199,8 @@ class YearRangePicker extends CalendarPart implements ICalendarPicker { } _getYearRanges() { - const locale = getLocale() as unknown as LocaleT; - const yearFormat = DateFormat.getDateInstance({ format: "y", calendarType: this._primaryCalendarType }, locale); - const yearFormatInSecType = DateFormat.getDateInstance({ format: "y", calendarType: this._secondaryCalendarType }, locale); + const yearFormat = DateFormat.getDateInstance({ format: "y", calendarType: this._primaryCalendarType }); + const yearFormatInSecType = DateFormat.getDateInstance({ format: "y", calendarType: this._secondaryCalendarType }); const pageSize = this._getPageSize(); const rowSize = this._getRowSize(); diff --git a/yarn.lock b/yarn.lock index e3d9aec34a2a..81a7a99047cb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6847,12 +6847,12 @@ __metadata: languageName: node linkType: hard -"@types/jquery@npm:*": - version: 3.5.16 - resolution: "@types/jquery@npm:3.5.16" +"@types/jquery@npm:~3.5.13": + version: 3.5.34 + resolution: "@types/jquery@npm:3.5.34" dependencies: "@types/sizzle": "npm:*" - checksum: 10c0/f40f6528f91e52e2cf5c08ad9d0ed7aad4392b366e3b4228cd3e57d4e0d82c850f0694a9c2779065acb2353e372d337e2fb1dc6861c8c5849bd6538ce2f002e8 + checksum: 10c0/c85eec82531912cc497c34daad3509cf54875a0457c64d82b4fe17a4a27a313150c0882b7dd345b7e98c9116e0bae64c3942b7a76f6edcd664efa701cd1f2d81 languageName: node linkType: hard @@ -7047,13 +7047,13 @@ __metadata: languageName: node linkType: hard -"@types/openui5@npm:^1.113.0": - version: 1.115.1 - resolution: "@types/openui5@npm:1.115.1" +"@types/openui5@npm:^1.146.0": + version: 1.146.0 + resolution: "@types/openui5@npm:1.146.0" dependencies: - "@types/jquery": "npm:*" - "@types/qunit": "npm:*" - checksum: 10c0/4ca4c412cc363e66e9a7a180e5d9e9d31a0734e2c26ea818bc534adbb1e8dc6f6d464bb84872ee237ecc04a41e002284daef2e3ab8b8e99efac7415ab28debea + "@types/jquery": "npm:~3.5.13" + "@types/qunit": "npm:^2.5.4" + checksum: 10c0/c6b0a5c9d91ea5ce545a8b9acdbe963e0088f4957d3dd1abbedc20a6cca5dfc8f00e467e9f5495a9724ab2296928cb2b2e7a5ec3a583615cc37b272591ef5bc2 languageName: node linkType: hard @@ -7092,10 +7092,10 @@ __metadata: languageName: node linkType: hard -"@types/qunit@npm:*": - version: 2.19.6 - resolution: "@types/qunit@npm:2.19.6" - checksum: 10c0/9c36a1ab9007ee4da5e04e635aea6b03cc35b09fe38fff4fd2f97a1725c567072fe69604ff5a17e09091b389d3d4d9162e25a44207430276f0b9f14475378548 +"@types/qunit@npm:^2.5.4": + version: 2.19.13 + resolution: "@types/qunit@npm:2.19.13" + checksum: 10c0/47f31282083f5f278bf0e4e49522f382f10161358363c8bd309fae8f926a4732c456d4c77aedd25a33c4bcc7da86cea87fd7a96531806adb85ce01b4f38eae4a languageName: node linkType: hard @@ -7772,7 +7772,7 @@ __metadata: "@babel/generator": "npm:^7.24.6" "@babel/parser": "npm:^7.24.6" "@openui5/sap.ui.core": "npm:1.146.0" - "@types/openui5": "npm:^1.113.0" + "@types/openui5": "npm:^1.146.0" "@ui5/webcomponents-base": "npm:2.22.0-rc.0" "@ui5/webcomponents-tools": "npm:2.22.0-rc.0" babel-plugin-amd-to-esm: "npm:^2.0.3"