@ui5/webcomponents-base 0.0.0-cf069fb29 → 0.0.0-cf50976ce

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/.eslintignore +0 -1
  2. package/CHANGELOG.md +173 -0
  3. package/README.md +28 -6
  4. package/bundle.esm.js +7 -9
  5. package/dist/Boot.js +3 -5
  6. package/dist/CustomElementsRegistry.js +1 -1
  7. package/dist/CustomElementsScope.js +20 -98
  8. package/dist/CustomElementsScopeUtils.js +108 -0
  9. package/dist/Device.js +5 -0
  10. package/dist/Keys.js +24 -0
  11. package/dist/StaticAreaItem.js +1 -1
  12. package/dist/UI5Element.js +24 -2
  13. package/dist/UI5ElementMetadata.js +1 -1
  14. package/dist/asset-registries/Icons.js +4 -8
  15. package/dist/asset-registries/LocaleData.js +7 -2
  16. package/dist/asset-registries/Themes.js +6 -2
  17. package/dist/asset-registries/i18n.js +3 -1
  18. package/dist/assets/bundle.esm.83f057b4.js +43 -0
  19. package/dist/config/Icons.js +52 -0
  20. package/dist/config/Theme.js +11 -0
  21. package/dist/css/BusyIndicator.css +80 -0
  22. package/dist/css/FontFace.css +31 -10
  23. package/dist/delegate/ItemNavigation.js +9 -4
  24. package/dist/features/F6Navigation.js +4 -0
  25. package/dist/features/OpenUI5Enablement.js +119 -0
  26. package/dist/generated/AssetParameters.js +1 -1
  27. package/dist/generated/VersionInfo.js +3 -3
  28. package/dist/generated/css/BusyIndicator.css.js +5 -0
  29. package/dist/generated/css/FontFace.css.js +1 -1
  30. package/dist/i18nBundle.js +1 -1
  31. package/dist/renderer/LitRenderer.js +29 -11
  32. package/dist/renderer/executeTemplate.js +19 -2
  33. package/dist/sap/ui/thirdparty/caja-html-sanitizer.js +1 -1
  34. package/dist/theming/getEffectiveLinksHrefs.js +7 -0
  35. package/dist/theming/getEffectiveStyle.js +9 -0
  36. package/dist/types/DOMReference.js +24 -0
  37. package/dist/updateShadowRoot.js +2 -3
  38. package/dist/util/AriaLabelHelper.js +2 -4
  39. package/dist/util/Caret.js +1 -14
  40. package/dist/util/ColorConversion.js +30 -2
  41. package/dist/util/InvisibleMessage.js +20 -9
  42. package/dist/util/TabbableElements.js +4 -0
  43. package/dist/util/getEffectiveScrollbarStyle.js +5 -0
  44. package/dist/util/getNormalizedTarget.js +16 -0
  45. package/dist/util/isDefaultSlotProvided.js +11 -0
  46. package/hash.txt +1 -1
  47. package/lib/generate-asset-parameters/index.js +8 -4
  48. package/lib/generate-styles/index.js +17 -9
  49. package/lib/generate-version-info/index.js +18 -13
  50. package/package-scripts.js +16 -27
  51. package/package.json +7 -6
  52. package/src/Boot.js +3 -5
  53. package/src/CustomElementsRegistry.js +1 -1
  54. package/src/CustomElementsScope.js +20 -98
  55. package/src/CustomElementsScopeUtils.js +108 -0
  56. package/src/Device.js +5 -0
  57. package/src/Keys.js +24 -0
  58. package/src/StaticAreaItem.js +1 -1
  59. package/src/UI5Element.js +24 -2
  60. package/src/UI5ElementMetadata.js +1 -1
  61. package/src/asset-registries/Icons.js +4 -8
  62. package/src/asset-registries/LocaleData.js +7 -2
  63. package/src/asset-registries/Themes.js +6 -2
  64. package/src/asset-registries/i18n.js +3 -1
  65. package/src/config/Icons.js +52 -0
  66. package/src/config/Theme.js +11 -0
  67. package/src/css/BusyIndicator.css +80 -0
  68. package/src/css/FontFace.css +31 -10
  69. package/src/delegate/ItemNavigation.js +9 -4
  70. package/src/features/F6Navigation.js +4 -0
  71. package/src/features/OpenUI5Enablement.js +119 -0
  72. package/src/i18nBundle.js +1 -1
  73. package/src/renderer/LitRenderer.js +29 -11
  74. package/src/renderer/executeTemplate.js +19 -2
  75. package/src/theming/getEffectiveLinksHrefs.js +7 -0
  76. package/src/theming/getEffectiveStyle.js +9 -0
  77. package/src/types/DOMReference.js +24 -0
  78. package/src/updateShadowRoot.js +2 -3
  79. package/src/util/AriaLabelHelper.js +2 -4
  80. package/src/util/Caret.js +1 -14
  81. package/src/util/ColorConversion.js +30 -2
  82. package/src/util/InvisibleMessage.js +20 -9
  83. package/src/util/TabbableElements.js +4 -0
  84. package/src/util/getEffectiveScrollbarStyle.js +5 -0
  85. package/src/util/getNormalizedTarget.js +16 -0
  86. package/src/util/isDefaultSlotProvided.js +11 -0
  87. package/config/.eslintrc.js +0 -3
  88. package/config/rollup.config.js +0 -1
  89. package/dist/isLegacyBrowser.js +0 -3
  90. package/dist/resources/bundle.esm.js +0 -37
  91. package/dist/resources/bundle.esm.js.map +0 -1
  92. package/dist/test-resources/assets/Themes.js +0 -17
  93. package/dist/test-resources/elements/Child.js +0 -35
  94. package/dist/test-resources/elements/Generic.js +0 -84
  95. package/dist/test-resources/elements/GenericExt.js +0 -26
  96. package/dist/test-resources/elements/NoShadowDOM.js +0 -13
  97. package/dist/test-resources/elements/Parent.js +0 -41
  98. package/dist/test-resources/elements/WithStaticArea.js +0 -77
  99. package/dist/test-resources/pages/AllTestElements.html +0 -42
  100. package/dist/test-resources/pages/Configuration.html +0 -18
  101. package/dist/test-resources/pages/ConfigurationScript.html +0 -34
  102. package/dist/test-resources/pages/assets/messagebundle_de.properties +0 -1
  103. package/dist/test-resources/pages/assets/messagebundle_en.properties +0 -1
  104. package/dist/test-resources/pages/assets/messagebundle_es.properties +0 -1
  105. package/dist/test-resources/pages/assets/messagebundle_fr.properties +0 -1
  106. package/dist/test-resources/pages/i18n.html +0 -33
  107. package/dist/test-resources/specs/ConfigurationChange.spec.js +0 -27
  108. package/dist/test-resources/specs/ConfigurationScript.spec.js +0 -63
  109. package/dist/test-resources/specs/ConfigurationURL.spec.js +0 -93
  110. package/dist/test-resources/specs/CustomTheme.spec.js +0 -27
  111. package/dist/test-resources/specs/EventProvider.spec.js +0 -63
  112. package/dist/test-resources/specs/StaticArea.spec.js +0 -78
  113. package/dist/test-resources/specs/Theming.spec.js +0 -33
  114. package/dist/test-resources/specs/UI5ElementInvalidation.js +0 -242
  115. package/dist/test-resources/specs/UI5ElementLifecycle.js +0 -98
  116. package/dist/test-resources/specs/UI5ElementListenForChildPropChanges.spec.js +0 -75
  117. package/dist/test-resources/specs/UI5ElementMetadataExt.js +0 -42
  118. package/dist/test-resources/specs/UI5ElementPropertyValidation.js +0 -14
  119. package/dist/test-resources/specs/UI5ElementPropsAndAttrs.spec.js +0 -67
  120. package/dist/test-resources/specs/UI5ElementShadowDOM.js +0 -24
  121. package/dist/test-resources/specs/UI5ElementSlots.js +0 -36
  122. package/dist/util/findNodeOwner.js +0 -35
  123. package/src/isLegacyBrowser.js +0 -3
  124. package/src/util/findNodeOwner.js +0 -35
@@ -1,6 +1,6 @@
1
1
  import getSharedResource from "../getSharedResource.js";
2
2
  import IconCollectionsAlias from "../assets-meta/IconCollectionsAlias.js";
3
- import { isTheme } from "../config/Theme.js";
3
+ import { getEffectiveDefaultIconCollection } from "../config/Icons.js";
4
4
 
5
5
  const loaders = new Map();
6
6
  const registry = getSharedResource("SVGIcons.registry", new Map());
@@ -36,7 +36,7 @@ const _fillRegistry = bundleData => {
36
36
  const iconData = bundleData.data[iconName];
37
37
 
38
38
  registerIcon(iconName, {
39
- pathData: iconData.path,
39
+ pathData: iconData.path || iconData.paths,
40
40
  ltr: iconData.ltr,
41
41
  accData: iconData.acc,
42
42
  collection: bundleData.collection,
@@ -48,7 +48,7 @@ const _fillRegistry = bundleData => {
48
48
  // set
49
49
  const registerIcon = (name, { pathData, ltr, accData, collection, packageName } = {}) => { // eslint-disable-line
50
50
  if (!collection) {
51
- collection = _getDefaultCollection();
51
+ collection = getEffectiveDefaultIconCollection();
52
52
  }
53
53
 
54
54
  const key = `${collection}/${name}`;
@@ -68,7 +68,7 @@ const _parseName = name => {
68
68
 
69
69
  let collection;
70
70
  [name, collection] = name.split("/").reverse();
71
- collection = collection || _getDefaultCollection();
71
+ collection = collection || getEffectiveDefaultIconCollection();
72
72
 
73
73
  // Normalize collection name.
74
74
  // - resolve `SAP-icons-TNT` to `tnt`.
@@ -117,10 +117,6 @@ const _getRegisteredNames = async () => {
117
117
  return Array.from(registry.keys());
118
118
  };
119
119
 
120
- const _getDefaultCollection = () => {
121
- return isTheme("sap_horizon") ? "SAP-icons-v5" : "SAP-icons";
122
- };
123
-
124
120
  const _normalizeCollection = collectionName => {
125
121
  if (IconCollectionsAlias[collectionName]) {
126
122
  return IconCollectionsAlias[collectionName];
@@ -13,7 +13,6 @@ const M_ISO639_OLD_TO_NEW = {
13
13
  "iw": "he",
14
14
  "ji": "yi",
15
15
  "in": "id",
16
- "sh": "sr",
17
16
  };
18
17
 
19
18
  const DEV_MODE = false;
@@ -48,6 +47,12 @@ const calcLocale = (language, region, script) => {
48
47
  }
49
48
  }
50
49
 
50
+ // Special case 3: for Serbian, there are cyrillic and latin scripts, "sh" and "sr-latn" map to "latin", "sr" maps to cyrillic.
51
+ if (language === "sh" || (language === "sr" && script === "Latn")) {
52
+ language = "sr";
53
+ region = "Latn";
54
+ }
55
+
51
56
  // try language + region
52
57
  let localeId = `${language}_${region}`;
53
58
  if (SUPPORTED_LOCALES.includes(localeId)) {
@@ -142,7 +147,7 @@ const registerLocaleDataLoader = (localeId, loader) => {
142
147
 
143
148
  // register default loader for "en" from ui5 CDN (dev workflow without assets)
144
149
  registerLocaleDataLoader("en", async runtimeLocaleId => {
145
- return (await fetch(`https://ui5.sap.com/1.60.2/resources/sap/ui/core/cldr/en.json`)).json();
150
+ return (await fetch(`https://sdk.openui5.org/1.103.0/resources/sap/ui/core/cldr/en.json`)).json();
146
151
  });
147
152
 
148
153
  // When the language changes dynamically (the user calls setLanguage),
@@ -38,10 +38,14 @@ const getThemeProperties = async (packageName, themeName) => {
38
38
 
39
39
  if (!registeredThemes.has(themeName)) {
40
40
  const regThemesStr = [...registeredThemes.values()].join(", ");
41
- console.warn(`You have requested a non-registered theme - falling back to ${DEFAULT_THEME}. Registered themes are: ${regThemesStr}`); /* eslint-disable-line */
42
- return themeStyles.get(`${packageName}_${DEFAULT_THEME}`);
41
+ console.warn(`You have requested a non-registered theme ${themeName} - falling back to ${DEFAULT_THEME}. Registered themes are: ${regThemesStr}`); /* eslint-disable-line */
42
+ return _getThemeProperties(packageName, DEFAULT_THEME);
43
43
  }
44
44
 
45
+ return _getThemeProperties(packageName, themeName);
46
+ };
47
+
48
+ const _getThemeProperties = async (packageName, themeName) => {
45
49
  const loader = loaders.get(`${packageName}/${themeName}`);
46
50
  if (!loader) {
47
51
  // no themes for package
@@ -14,10 +14,12 @@ const bundlePromises = new Map();
14
14
  const loaders = new Map();
15
15
 
16
16
  /**
17
+ * Registers i18n loader function for given package and locale.
17
18
  *
19
+ * @public
18
20
  * @param {string} packageName for which package this loader can fetch data
21
+ * @param {string} localeId locale that this loader can handle
19
22
  * @param {function} loader async function that will be passed a localeId and should return a JSON object
20
- * @param {Array} localeIds Array of locale IDs that this loader can handle
21
23
  */
22
24
  const registerI18nLoader = (packageName, localeId, loader) => {
23
25
  // register loader by key
@@ -0,0 +1,52 @@
1
+ import { getTheme, isThemeFamily } from "./Theme.js";
2
+
3
+ const IconCollectionConfiguration = new Map();
4
+
5
+ /**
6
+ * Sets the default icon collection (v4 or v5) per theme,
7
+ * which will be applied in case icon collection is not specified.
8
+ *
9
+ * Note: by default SAP-icons-v5 is used in SAP Horizon and SAP-icons-v4 for all the rest.
10
+ * @param {String} theme
11
+ * @param {String} collectionName
12
+ */
13
+ const setDefaultIconCollection = (theme, collectionName) => {
14
+ if (collectionName === "horizon") {
15
+ collectionName = "SAP-icons-v5";
16
+ }
17
+
18
+ IconCollectionConfiguration.set(theme, collectionName);
19
+ };
20
+
21
+ /**
22
+ * Returns the default icon collection (v4 or v5) for given theme,
23
+ * that is configured.
24
+ *
25
+ * @param {String} theme
26
+ * @returns {String}
27
+ */
28
+ const getDefaultIconCollection = theme => {
29
+ return IconCollectionConfiguration.get(theme);
30
+ };
31
+
32
+ /**
33
+ * Returns the effective icon collection that will be applied for icon web components
34
+ * whenever namespace is not specified.
35
+ * @returns {String}
36
+ */
37
+ const getEffectiveDefaultIconCollection = () => {
38
+ const currentTheme = getTheme();
39
+ const currentThemeConfiguration = IconCollectionConfiguration.get(currentTheme);
40
+
41
+ if (currentThemeConfiguration) {
42
+ return currentThemeConfiguration;
43
+ }
44
+
45
+ return isThemeFamily("sap_horizon") ? "SAP-icons-v5" : "SAP-icons";
46
+ };
47
+
48
+ export {
49
+ setDefaultIconCollection,
50
+ getDefaultIconCollection,
51
+ getEffectiveDefaultIconCollection,
52
+ };
@@ -35,8 +35,19 @@ const isTheme = _theme => {
35
35
  return currentTheme === _theme || currentTheme === `${_theme}_exp`;
36
36
  };
37
37
 
38
+ /**
39
+ * Returns if the current theme is part of given theme family
40
+ * @private
41
+ * @param {String} the theme family
42
+ * @returns {boolean}
43
+ */
44
+ const isThemeFamily = _theme => {
45
+ return getTheme().startsWith(_theme);
46
+ };
47
+
38
48
  export {
39
49
  getTheme,
40
50
  setTheme,
41
51
  isTheme,
52
+ isThemeFamily,
42
53
  };
@@ -0,0 +1,80 @@
1
+ .busy-indicator-wrapper {
2
+ position: relative;
3
+ height: 100%;
4
+ width: 100%;
5
+ }
6
+
7
+ .busy-indicator-overlay {
8
+ display: var(--ui5_web_components_busy_indicator_display);
9
+ position: absolute;
10
+ inset: 0;
11
+ background: var(--ui5_web_components_busy_indicator_background-color);
12
+ z-index: 99;
13
+ }
14
+
15
+ .busy-indicator-busy-area {
16
+ display: var(--ui5_web_components_busy_indicator_display);
17
+ position: absolute;
18
+ z-index: 99;
19
+ inset: 0;
20
+ justify-content: center;
21
+ align-items: center;
22
+ background-color: inherit;
23
+ flex-direction: column;
24
+ color: var(--_ui5_busy_indicator_color);
25
+ }
26
+
27
+ :host([__is-busy]) .busy-indicator-wrapper > :not(.busy-indicator-busy-area):not(.busy-indicator-overlay):not([busy-indicator-before-span]) {
28
+ --ui5_web_components_busy_indicator_display: none;
29
+ }
30
+
31
+ .busy-indicator-busy-area:focus {
32
+ outline: var(--_ui5_busy_indicator_focus_outline);
33
+ outline-offset: -.125rem;
34
+ }
35
+
36
+ .busy-indicator-circle {
37
+ width: 1rem;
38
+ height: 1rem;
39
+ display: inline-block;
40
+ background-color: currentColor;
41
+ border-radius: 50%;
42
+ }
43
+
44
+ .circle-animation-0 {
45
+ animation: grow 1.6s infinite cubic-bezier(0.32, 0.06, 0.85, 1.11);
46
+ }
47
+
48
+ .circle-animation-1 {
49
+ animation: grow 1.6s infinite cubic-bezier(0.32, 0.06, 0.85, 1.11);
50
+ animation-delay: 200ms;
51
+ }
52
+
53
+ .circle-animation-2 {
54
+ animation: grow 1.6s infinite cubic-bezier(0.32, 0.06, 0.85, 1.11);
55
+ animation-delay: 400ms;
56
+ }
57
+
58
+ .sapUiLocalBusy {
59
+ --ui5_web_components_busy_indicator_display: none;
60
+ }
61
+
62
+ .busy-indicator-wrapper [ui5-busy-indicator] {
63
+ display: none;
64
+ }
65
+
66
+ @keyframes grow {
67
+ 0%, 50%, 100% {
68
+ -webkit-transform: scale(0.5);
69
+ -moz-transform: scale(0.5);
70
+ -ms-transform: scale(0.5);
71
+ transform: scale(0.5);
72
+ }
73
+
74
+ 25% {
75
+ -webkit-transform: scale(1);
76
+ -moz-transform: scale(1);
77
+ -ms-transform: scale(1);
78
+ transform: scale(1);
79
+ }
80
+ }
@@ -3,8 +3,7 @@
3
3
  font-style: normal;
4
4
  font-weight: 400;
5
5
  src: local("72"),
6
- url(https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Regular.woff2?ui5-webcomponents) format("woff2"),
7
- url(https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Regular.woff?ui5-webcomponents) format("woff");
6
+ url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Regular.woff2?ui5-webcomponents) format("woff2");
8
7
  }
9
8
 
10
9
  @font-face {
@@ -12,8 +11,7 @@
12
11
  font-style: normal;
13
12
  font-weight: 400;
14
13
  src: local('72-full'),
15
- url(https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Regular-full.woff2?ui5-webcomponents) format("woff2"),
16
- url(https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Regular-full.woff?ui5-webcomponents) format("woff");
14
+ url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Regular-full.woff2?ui5-webcomponents) format("woff2");
17
15
 
18
16
  }
19
17
 
@@ -22,8 +20,7 @@
22
20
  font-style: normal;
23
21
  font-weight: 700;
24
22
  src: local('72-Bold'),
25
- url(https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold.woff2?ui5-webcomponents) format("woff2"),
26
- url(https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold.woff?ui5-webcomponents) format("woff");
23
+ url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold.woff2?ui5-webcomponents) format("woff2");
27
24
  }
28
25
 
29
26
  @font-face {
@@ -31,8 +28,33 @@
31
28
  font-style: normal;
32
29
  font-weight: 700;
33
30
  src: local('72-Bold-full'),
34
- url(https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold-full.woff2?ui5-webcomponents) format("woff2"),
35
- url(https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold-full.woff?ui5-webcomponents) format("woff");
31
+ url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold-full.woff2?ui5-webcomponents) format("woff2");
32
+ }
33
+
34
+ @font-face {
35
+ font-family: '72-Bold';
36
+ font-style: normal;
37
+ src: local('72-Bold'),
38
+ url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold.woff2?ui5-webcomponents) format("woff2");
39
+ }
40
+
41
+ @font-face {
42
+ font-family: '72-Boldfull';
43
+ font-style: normal;
44
+ src: url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold-full.woff2?ui5-webcomponents) format("woff2");
45
+ }
46
+
47
+ @font-face {
48
+ font-family: '72-Light';
49
+ font-style: normal;
50
+ src: local('72-Light'),
51
+ url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Light.woff2?ui5-webcomponents) format("woff2");
52
+ }
53
+
54
+ @font-face {
55
+ font-family: '72-Lightfull';
56
+ font-style: normal;
57
+ src: url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Light-full.woff2?ui5-webcomponents) format("woff2");
36
58
  }
37
59
 
38
60
  @font-face {
@@ -40,6 +62,5 @@
40
62
  font-style: bold;
41
63
  font-weight: 900;
42
64
  src: local('72Black'),
43
- url(https://openui5nightly.hana.ondemand.com/resources/sap/ui/core/themes/sap_horizon/fonts/72-Black.woff2?ui5-webcomponents) format("woff2"),
44
- url(https://openui5nightly.hana.ondemand.com/resources/sap/ui/core/themes/sap_horizon/fonts/72-Black.woff?ui5-webcomponents) format("woff");
65
+ url(https://sdk.openui5.org/resources/sap/ui/core/themes/sap_horizon/fonts/72-Black.woff2?ui5-webcomponents) format("woff2");
45
66
  }
@@ -133,15 +133,20 @@ class ItemNavigation {
133
133
 
134
134
  const horizontalNavigationOn = this._navigationMode === NavigationMode.Horizontal || this._navigationMode === NavigationMode.Auto;
135
135
  const verticalNavigationOn = this._navigationMode === NavigationMode.Vertical || this._navigationMode === NavigationMode.Auto;
136
+ const isRTL = this.rootWebComponent.effectiveDir === "rtl";
136
137
 
137
- if (isUp(event) && verticalNavigationOn) {
138
- this._handleUp();
139
- } else if (isDown(event) && verticalNavigationOn) {
140
- this._handleDown();
138
+ if (isRTL && isLeft(event) && horizontalNavigationOn) {
139
+ this._handleRight();
140
+ } else if (isRTL && isRight(event) && horizontalNavigationOn) {
141
+ this._handleLeft();
141
142
  } else if (isLeft(event) && horizontalNavigationOn) {
142
143
  this._handleLeft();
143
144
  } else if (isRight(event) && horizontalNavigationOn) {
144
145
  this._handleRight();
146
+ } else if (isUp(event) && verticalNavigationOn) {
147
+ this._handleUp();
148
+ } else if (isDown(event) && verticalNavigationOn) {
149
+ this._handleDown();
145
150
  } else if (isHome(event)) {
146
151
  this._handleHome();
147
152
  } else if (isEnd(event)) {
@@ -21,6 +21,8 @@ class F6Navigation {
21
21
  return;
22
22
  }
23
23
 
24
+ event.preventDefault();
25
+
24
26
  const nextIndex = this.groups.indexOf(this.selectedGroup);
25
27
  let nextElement = null;
26
28
 
@@ -44,6 +46,8 @@ class F6Navigation {
44
46
  return;
45
47
  }
46
48
 
49
+ event.preventDefault();
50
+
47
51
  const nextIndex = this.groups.indexOf(this.selectedGroup);
48
52
  let nextElement = null;
49
53
 
@@ -0,0 +1,119 @@
1
+ import { registerFeature } from "../FeaturesRegistry.js";
2
+ import BusyIndicatorStyles from "../generated/css/BusyIndicator.css.js";
3
+ import merge from "../thirdparty/merge.js";
4
+ import {
5
+ isTabPrevious,
6
+ } from "../Keys.js";
7
+
8
+ const busyIndicatorMetadata = {
9
+ properties: {
10
+ __isBusy: {
11
+ type: Boolean,
12
+ },
13
+ },
14
+ };
15
+
16
+ const getBusyIndicatorStyles = () => {
17
+ return BusyIndicatorStyles;
18
+ };
19
+
20
+ const wrapTemplateResultInBusyMarkup = (html, host, templateResult) => {
21
+ if (host.isOpenUI5Component && host.__isBusy) {
22
+ templateResult = html`
23
+ <div class="busy-indicator-wrapper">
24
+ <span tabindex="0" busy-indicator-before-span @focusin=${host.__suppressFocusIn}></span>
25
+ ${templateResult}
26
+ <div class="busy-indicator-overlay"></div>
27
+ <div busy-indicator
28
+ class="busy-indicator-busy-area"
29
+ tabindex="0"
30
+ role="progressbar"
31
+ @keydown=${host.__suppressFocusBack}
32
+ aria-valuemin="0"
33
+ aria-valuemax="100"
34
+ aria-valuetext="Busy">
35
+ <div>
36
+ <div class="busy-indicator-circle circle-animation-0"></div>
37
+ <div class="busy-indicator-circle circle-animation-1"></div>
38
+ <div class="busy-indicator-circle circle-animation-2"></div>
39
+ </div>
40
+ </div>
41
+ </div>`;
42
+ }
43
+
44
+ return templateResult;
45
+ };
46
+
47
+ const enrichBusyIndicatorMetadata = UI5Element => {
48
+ UI5Element.metadata = merge(UI5Element.metadata, busyIndicatorMetadata);
49
+ };
50
+
51
+ const enrichBusyIndicatorMethods = UI5ElementPrototype => {
52
+ Object.defineProperties(UI5ElementPrototype, {
53
+ "__redirectFocus": { value: true, writable: true },
54
+ "__suppressFocusBack": {
55
+ get() {
56
+ const that = this;
57
+
58
+ return {
59
+ handleEvent: e => {
60
+ if (isTabPrevious(e)) {
61
+ const beforeElem = that.shadowRoot.querySelector("[busy-indicator-before-span]");
62
+ that.__redirectFocus = false;
63
+ beforeElem.focus();
64
+ that.__redirectFocus = true;
65
+ }
66
+ },
67
+ capture: true,
68
+ passive: false,
69
+ };
70
+ },
71
+ },
72
+ "isOpenUI5Component": { get: () => { return true; } },
73
+ });
74
+
75
+ UI5ElementPrototype.__suppressFocusIn = function handleFocusIn() {
76
+ const busyIndicator = this.shadowRoot.querySelector("[busy-indicator]");
77
+ if (busyIndicator && this.__redirectFocus) {
78
+ busyIndicator.focus();
79
+ }
80
+ };
81
+
82
+ UI5ElementPrototype.getDomRef = function getDomRef() {
83
+ // If a component set _getRealDomRef to its children, use the return value of this function
84
+ if (typeof this._getRealDomRef === "function") {
85
+ return this._getRealDomRef();
86
+ }
87
+
88
+ if (!this.shadowRoot || this.shadowRoot.children.length === 0) {
89
+ return;
90
+ }
91
+
92
+ const children = [...this.shadowRoot.children].filter(child => !["link", "style"].includes(child.localName));
93
+
94
+ if (children.length !== 1) {
95
+ console.warn(`The shadow DOM for ${this.constructor.getMetadata().getTag()} does not have a top level element, the getDomRef() method might not work as expected`); // eslint-disable-line
96
+ }
97
+
98
+ if (this.__isBusy) {
99
+ return children[0].querySelector(".busy-indicator-wrapper > :not([busy-indicator-before-span]):not(.busy-indicator-overlay):not(.busy-indicator-busy-area)");
100
+ }
101
+
102
+ return children[0];
103
+ };
104
+ };
105
+
106
+ const enrichBusyIndicatorSettings = UI5Element => {
107
+ enrichBusyIndicatorMetadata(UI5Element);
108
+ enrichBusyIndicatorMethods(UI5Element.prototype);
109
+ };
110
+
111
+ const OpenUI5Enablement = {
112
+ enrichBusyIndicatorSettings,
113
+ wrapTemplateResultInBusyMarkup,
114
+ getBusyIndicatorStyles,
115
+ };
116
+
117
+ export default OpenUI5Enablement;
118
+
119
+ registerFeature("OpenUI5Enablement", OpenUI5Enablement);
package/src/i18nBundle.js CHANGED
@@ -37,7 +37,7 @@ class I18nBundle {
37
37
  }
38
38
  const messageText = bundle && bundle[textObj.key] ? bundle[textObj.key] : (textObj.defaultText || textObj.key);
39
39
 
40
- return formatMessage(messageText, params);
40
+ return params.length ? formatMessage(messageText, params) : messageText;
41
41
  }
42
42
  }
43
43
 
@@ -1,28 +1,46 @@
1
- import { render } from "lit-html";
2
1
  import {
2
+ render,
3
3
  html,
4
4
  svg,
5
- unsafeStatic,
6
- } from "lit-html/static.js";
5
+ } from "lit-html";
6
+ import { getFeature } from "../FeaturesRegistry.js";
7
+
8
+ const effectiveHtml = (...args) => {
9
+ const LitStatic = getFeature("LitStatic");
10
+ const fn = LitStatic ? LitStatic.html : html;
11
+ return fn(...args);
12
+ };
13
+
14
+ const effectiveSvg = (...args) => {
15
+ const LitStatic = getFeature("LitStatic");
16
+ const fn = LitStatic ? LitStatic.svg : svg;
17
+ return fn(...args);
18
+ };
19
+
20
+ const litRender = (templateResult, domNode, styleStrOrHrefsArr, forStaticArea, { host } = {}) => {
21
+ const OpenUI5Enablement = getFeature("OpenUI5Enablement");
22
+ if (OpenUI5Enablement && !forStaticArea) {
23
+ templateResult = OpenUI5Enablement.wrapTemplateResultInBusyMarkup(effectiveHtml, host, templateResult);
24
+ }
7
25
 
8
- const litRender = (templateResult, domNode, styleStrOrHrefsArr, { host } = {}) => {
9
26
  if (typeof styleStrOrHrefsArr === "string") {
10
- templateResult = html`<style>${styleStrOrHrefsArr}</style>${templateResult}`;
27
+ templateResult = effectiveHtml`<style>${styleStrOrHrefsArr}</style>${templateResult}`;
11
28
  } else if (Array.isArray(styleStrOrHrefsArr) && styleStrOrHrefsArr.length) {
12
- templateResult = html`${styleStrOrHrefsArr.map(href => html`<link type="text/css" rel="stylesheet" href="${href}">`)}${templateResult}`;
29
+ templateResult = effectiveHtml`${styleStrOrHrefsArr.map(href => effectiveHtml`<link type="text/css" rel="stylesheet" href="${href}">`)}${templateResult}`;
13
30
  }
14
31
  render(templateResult, domNode, { host });
15
32
  };
16
33
 
17
34
  const scopeTag = (tag, tags, suffix) => {
18
- const resultTag = suffix && (tags || []).includes(tag) ? `${tag}-${suffix}` : tag;
19
- return unsafeStatic(resultTag);
35
+ const LitStatic = getFeature("LitStatic");
36
+ if (LitStatic) {
37
+ return LitStatic.unsafeStatic((tags || []).includes(tag) ? `${tag}-${suffix}` : tag);
38
+ }
20
39
  };
21
40
 
22
41
  export {
23
- html,
24
- svg,
25
- unsafeStatic,
42
+ effectiveHtml as html,
43
+ effectiveSvg as svg,
26
44
  };
27
45
  export { scopeTag };
28
46
  export { repeat } from "lit-html/directives/repeat.js";
@@ -1,4 +1,4 @@
1
- import { getCustomElementsScopingSuffix, shouldScopeCustomElement } from "../CustomElementsScope.js";
1
+ import { getCustomElementsScopingSuffix, shouldScopeCustomElement } from "../CustomElementsScopeUtils.js";
2
2
 
3
3
  /**
4
4
  * Runs a component's template with the component's current state, while also scoping HTML
@@ -9,9 +9,26 @@ import { getCustomElementsScopingSuffix, shouldScopeCustomElement } from "../Cus
9
9
  * @returns {*}
10
10
  */
11
11
  const executeTemplate = (template, component) => {
12
- const tagsToScope = component.constructor.getUniqueDependencies().map(dep => dep.getMetadata().getPureTag()).filter(shouldScopeCustomElement);
12
+ const tagsToScope = getTagsToScope(component);
13
13
  const scope = getCustomElementsScopingSuffix();
14
14
  return template(component, tagsToScope, scope);
15
15
  };
16
16
 
17
+ /**
18
+ * Returns all tags, used inside component's template subject to scoping.
19
+ * @param component - the component
20
+ * @returns {Array[]}
21
+ * @private
22
+ */
23
+ const getTagsToScope = component => {
24
+ const componentTag = component.constructor.getMetadata().getPureTag();
25
+ const tagsToScope = component.constructor.getUniqueDependencies().map(dep => dep.getMetadata().getPureTag()).filter(shouldScopeCustomElement);
26
+
27
+ if (shouldScopeCustomElement(componentTag)) {
28
+ tagsToScope.push(componentTag);
29
+ }
30
+
31
+ return tagsToScope;
32
+ };
33
+
17
34
  export default executeTemplate;
@@ -1,4 +1,5 @@
1
1
  import { getUrl } from "../CSP.js";
2
+ import { getFeature } from "../FeaturesRegistry.js";
2
3
 
3
4
  const flatten = arr => {
4
5
  return arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flatten(val) : val), []);
@@ -6,6 +7,8 @@ const flatten = arr => {
6
7
 
7
8
  const getEffectiveLinksHrefs = (ElementClass, forStaticArea = false) => {
8
9
  let stylesData = ElementClass[forStaticArea ? "staticAreaStyles" : "styles"];
10
+ const OpenUI5Enablement = getFeature("OpenUI5Enablement");
11
+
9
12
  if (!stylesData) {
10
13
  return;
11
14
  }
@@ -14,6 +17,10 @@ const getEffectiveLinksHrefs = (ElementClass, forStaticArea = false) => {
14
17
  stylesData = [stylesData];
15
18
  }
16
19
 
20
+ if (OpenUI5Enablement) {
21
+ stylesData.push(OpenUI5Enablement.getBusyIndicatorStyles());
22
+ }
23
+
17
24
  return flatten(stylesData).filter(data => !!data).map(data => getUrl(data.packageName, data.fileName));
18
25
  };
19
26
 
@@ -1,5 +1,6 @@
1
1
  import { getCustomCSS, attachCustomCSSChange } from "./CustomStyle.js";
2
2
  import getStylesString from "./getStylesString.js";
3
+ import { getFeature } from "../FeaturesRegistry.js";
3
4
 
4
5
  const effectiveStyleMap = new Map();
5
6
 
@@ -10,9 +11,15 @@ attachCustomCSSChange(tag => {
10
11
  const getEffectiveStyle = (ElementClass, forStaticArea = false) => {
11
12
  const tag = ElementClass.getMetadata().getTag();
12
13
  const key = `${tag}_${forStaticArea ? "static" : "normal"}`;
14
+ const OpenUI5Enablement = getFeature("OpenUI5Enablement");
13
15
 
14
16
  if (!effectiveStyleMap.has(key)) {
15
17
  let effectiveStyle;
18
+ let busyIndicatorStyles = "";
19
+
20
+ if (OpenUI5Enablement) {
21
+ busyIndicatorStyles = getStylesString(OpenUI5Enablement.getBusyIndicatorStyles());
22
+ }
16
23
 
17
24
  if (forStaticArea) {
18
25
  effectiveStyle = getStylesString(ElementClass.staticAreaStyles);
@@ -21,6 +28,8 @@ const getEffectiveStyle = (ElementClass, forStaticArea = false) => {
21
28
  const builtInStyles = getStylesString(ElementClass.styles);
22
29
  effectiveStyle = `${builtInStyles} ${customStyle}`;
23
30
  }
31
+
32
+ effectiveStyle = `${effectiveStyle} ${busyIndicatorStyles}`;
24
33
  effectiveStyleMap.set(key, effectiveStyle);
25
34
  }
26
35