@ui5/webcomponents-base 0.0.0-2c7615fe9 → 0.0.0-3236d56be

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 (147) hide show
  1. package/.eslintignore +3 -2
  2. package/CHANGELOG.md +199 -0
  3. package/README.md +26 -2
  4. package/bundle.esm.js +3 -2
  5. package/dist/Boot.js +34 -18
  6. package/dist/CSP.js +59 -0
  7. package/dist/CustomElementsRegistry.js +60 -4
  8. package/dist/CustomElementsScope.js +20 -98
  9. package/dist/CustomElementsScopeUtils.js +108 -0
  10. package/dist/Device.js +20 -1
  11. package/dist/EventProvider.js +5 -2
  12. package/dist/FeaturesRegistry.js +4 -1
  13. package/dist/FontFace.js +7 -95
  14. package/dist/InitialConfiguration.js +11 -7
  15. package/dist/Keys.js +47 -0
  16. package/dist/ManagedStyles.js +83 -0
  17. package/dist/Render.js +3 -1
  18. package/dist/Runtimes.js +107 -0
  19. package/dist/StaticAreaItem.js +4 -10
  20. package/dist/SystemCSSVars.js +4 -25
  21. package/dist/UI5Element.js +31 -24
  22. package/dist/UI5ElementMetadata.js +17 -1
  23. package/dist/asset-registries/Icons.js +21 -14
  24. package/dist/asset-registries/Illustrations.js +10 -3
  25. package/dist/asset-registries/LocaleData.js +17 -3
  26. package/dist/assets-meta/IconCollectionsAlias.js +18 -0
  27. package/dist/config/Icons.js +52 -0
  28. package/dist/config/Theme.js +25 -0
  29. package/dist/css/BusyIndicator.css +76 -0
  30. package/dist/css/FontFace.css +75 -0
  31. package/dist/css/OverrideFontFace.css +32 -0
  32. package/dist/css/SystemCSSVars.css +17 -0
  33. package/dist/features/F6Navigation.js +108 -0
  34. package/dist/features/OpenUI5Enablement.js +119 -0
  35. package/dist/generated/AssetParameters.js +1 -1
  36. package/dist/generated/VersionInfo.js +10 -0
  37. package/dist/generated/css/BusyIndicator.css.js +5 -0
  38. package/dist/generated/css/FontFace.css.js +5 -0
  39. package/dist/generated/css/OverrideFontFace.css.js +5 -0
  40. package/dist/generated/css/SystemCSSVars.css.js +5 -0
  41. package/dist/i18nBundle.js +33 -2
  42. package/dist/renderer/LitRenderer.js +32 -12
  43. package/dist/renderer/directives/style-map.js +72 -0
  44. package/dist/renderer/executeTemplate.js +19 -2
  45. package/dist/resources/bundle.esm.js +14 -8
  46. package/dist/resources/bundle.esm.js.map +1 -1
  47. package/dist/sap/base/Log.js +2 -10
  48. package/dist/sap/base/assert.js +1 -5
  49. package/dist/sap/base/security/encodeCSS.js +14 -0
  50. package/dist/sap/base/security/encodeXML.js +23 -0
  51. package/dist/sap/base/strings/toHex.js +8 -0
  52. package/dist/sap/ui/thirdparty/caja-html-sanitizer.js +1 -1
  53. package/dist/test-resources/pages/i18n.html +1 -3
  54. package/dist/test-resources/specs/ConfigurationChange.spec.js +9 -9
  55. package/dist/test-resources/specs/ConfigurationScript.spec.js +24 -24
  56. package/dist/test-resources/specs/ConfigurationURL.spec.js +33 -33
  57. package/dist/test-resources/specs/CustomTheme.spec.js +7 -7
  58. package/dist/test-resources/specs/EventProvider.spec.js +63 -0
  59. package/dist/test-resources/specs/StaticArea.spec.js +35 -35
  60. package/dist/test-resources/specs/Theming.spec.js +11 -11
  61. package/dist/test-resources/specs/UI5ElementInvalidation.js +29 -29
  62. package/dist/test-resources/specs/UI5ElementLifecycle.js +11 -11
  63. package/dist/test-resources/specs/UI5ElementListenForChildPropChanges.spec.js +11 -11
  64. package/dist/test-resources/specs/UI5ElementMetadataExt.js +8 -8
  65. package/dist/test-resources/specs/UI5ElementPropertyValidation.js +6 -6
  66. package/dist/test-resources/specs/UI5ElementPropsAndAttrs.spec.js +36 -36
  67. package/dist/test-resources/specs/UI5ElementShadowDOM.js +9 -9
  68. package/dist/test-resources/specs/UI5ElementSlots.js +9 -9
  69. package/dist/theming/CustomStyle.js +23 -3
  70. package/dist/theming/applyTheme.js +11 -10
  71. package/dist/theming/getEffectiveLinksHrefs.js +27 -0
  72. package/dist/theming/getEffectiveStyle.js +9 -0
  73. package/dist/theming/getStylesString.js +4 -2
  74. package/dist/theming/getThemeDesignerTheme.js +25 -5
  75. package/dist/theming/preloadLinks.js +23 -0
  76. package/dist/updateShadowRoot.js +8 -4
  77. package/dist/util/FocusableElements.js +8 -6
  78. package/dist/util/InvisibleMessage.js +11 -9
  79. package/dist/util/TabbableElements.js +4 -0
  80. package/dist/util/createLinkInHead.js +19 -0
  81. package/dist/util/escapeRegex.js +10 -0
  82. package/dist/util/generateHighlightedMarkup.js +42 -0
  83. package/dist/util/getNormalizedTarget.js +16 -0
  84. package/dist/util/isNodeHidden.js +1 -1
  85. package/lib/generate-asset-parameters/index.js +8 -5
  86. package/lib/generate-styles/index.js +26 -0
  87. package/lib/generate-version-info/index.js +32 -0
  88. package/package-scripts.js +12 -16
  89. package/package.json +10 -12
  90. package/src/Boot.js +34 -18
  91. package/src/CSP.js +59 -0
  92. package/src/CustomElementsRegistry.js +60 -4
  93. package/src/CustomElementsScope.js +20 -98
  94. package/src/CustomElementsScopeUtils.js +108 -0
  95. package/src/Device.js +20 -1
  96. package/src/EventProvider.js +5 -2
  97. package/src/FeaturesRegistry.js +4 -1
  98. package/src/FontFace.js +7 -95
  99. package/src/InitialConfiguration.js +11 -7
  100. package/src/Keys.js +47 -0
  101. package/src/ManagedStyles.js +83 -0
  102. package/src/Render.js +3 -1
  103. package/src/Runtimes.js +107 -0
  104. package/src/StaticAreaItem.js +4 -10
  105. package/src/SystemCSSVars.js +4 -25
  106. package/src/UI5Element.js +31 -24
  107. package/src/UI5ElementMetadata.js +17 -1
  108. package/src/asset-registries/Icons.js +21 -14
  109. package/src/asset-registries/Illustrations.js +10 -3
  110. package/src/asset-registries/LocaleData.js +17 -3
  111. package/src/assets-meta/IconCollectionsAlias.js +18 -0
  112. package/src/config/Icons.js +52 -0
  113. package/src/config/Theme.js +25 -0
  114. package/src/css/BusyIndicator.css +76 -0
  115. package/src/css/FontFace.css +75 -0
  116. package/src/css/OverrideFontFace.css +32 -0
  117. package/src/css/SystemCSSVars.css +17 -0
  118. package/src/features/F6Navigation.js +108 -0
  119. package/src/features/OpenUI5Enablement.js +119 -0
  120. package/src/i18nBundle.js +33 -2
  121. package/src/renderer/LitRenderer.js +32 -12
  122. package/src/renderer/directives/style-map.js +72 -0
  123. package/src/renderer/executeTemplate.js +19 -2
  124. package/src/theming/CustomStyle.js +23 -3
  125. package/src/theming/applyTheme.js +11 -10
  126. package/src/theming/getEffectiveLinksHrefs.js +27 -0
  127. package/src/theming/getEffectiveStyle.js +9 -0
  128. package/src/theming/getStylesString.js +4 -2
  129. package/src/theming/getThemeDesignerTheme.js +25 -5
  130. package/src/theming/preloadLinks.js +23 -0
  131. package/src/updateShadowRoot.js +8 -4
  132. package/src/util/FocusableElements.js +8 -6
  133. package/src/util/InvisibleMessage.js +11 -9
  134. package/src/util/TabbableElements.js +4 -0
  135. package/src/util/createLinkInHead.js +19 -0
  136. package/src/util/escapeRegex.js +10 -0
  137. package/src/util/generateHighlightedMarkup.js +42 -0
  138. package/src/util/getNormalizedTarget.js +16 -0
  139. package/src/util/isNodeHidden.js +1 -1
  140. package/used-modules.txt +4 -1
  141. package/dist/config/AssetsPath.js +0 -17
  142. package/dist/theming/createThemePropertiesStyleTag.js +0 -20
  143. package/dist/util/encodeCSS.js +0 -24
  144. package/hash.txt +0 -1
  145. package/src/config/AssetsPath.js +0 -17
  146. package/src/theming/createThemePropertiesStyleTag.js +0 -20
  147. package/src/util/encodeCSS.js +0 -24
@@ -1,11 +1,12 @@
1
1
  import getSharedResource from "../getSharedResource.js";
2
+ import IconCollectionsAlias from "../assets-meta/IconCollectionsAlias.js";
3
+ import { getEffectiveDefaultIconCollection } from "../config/Icons.js";
2
4
 
3
5
  const loaders = new Map();
4
6
  const registry = getSharedResource("SVGIcons.registry", new Map());
5
7
  const iconCollectionPromises = getSharedResource("SVGIcons.promises", new Map());
6
8
 
7
9
  const ICON_NOT_FOUND = "ICON_NOT_FOUND";
8
- const DEFAULT_COLLECTION = "SAP-icons";
9
10
 
10
11
  /**
11
12
  * @deprecated
@@ -47,7 +48,7 @@ const _fillRegistry = bundleData => {
47
48
  // set
48
49
  const registerIcon = (name, { pathData, ltr, accData, collection, packageName } = {}) => { // eslint-disable-line
49
50
  if (!collection) {
50
- collection = DEFAULT_COLLECTION;
51
+ collection = getEffectiveDefaultIconCollection();
51
52
  }
52
53
 
53
54
  const key = `${collection}/${name}`;
@@ -67,18 +68,16 @@ const _parseName = name => {
67
68
 
68
69
  let collection;
69
70
  [name, collection] = name.split("/").reverse();
70
- collection = collection || DEFAULT_COLLECTION;
71
- // hardcoded alias in case icon explorer is used, resolve `SAP-icons-TNT` to `tnt`
72
- // aliases can be made a feature in the future if more collections need it or more aliases are needed.
73
- if (collection === "SAP-icons-TNT") {
74
- collection = "tnt";
75
- }
76
- // hardcoded alias in case icon explorer is used, resolve `BusinessSuiteInAppSymbols` to `business-suite`
77
- // aliases can be made a feature in the future if more collections need it or more aliases are needed.
78
- if (collection === "BusinessSuiteInAppSymbols") {
79
- collection = "business-suite";
80
- name = name.replace("icon-", "");
81
- }
71
+ collection = collection || getEffectiveDefaultIconCollection();
72
+
73
+ // Normalize collection name.
74
+ // - resolve `SAP-icons-TNT` to `tnt`.
75
+ // - resolve `BusinessSuiteInAppSymbols` to `business-suite`.
76
+ // - resolve `horizon` to `SAP-icons-v5`,
77
+ // Note: aliases can be made as a feature, if more collections need it or more aliases are needed.
78
+ collection = _normalizeCollection(collection);
79
+ name = name.replace("icon-", "");
80
+
82
81
  const registryKey = `${collection}/${name}`;
83
82
  return { name, collection, registryKey };
84
83
  };
@@ -118,6 +117,14 @@ const _getRegisteredNames = async () => {
118
117
  return Array.from(registry.keys());
119
118
  };
120
119
 
120
+ const _normalizeCollection = collectionName => {
121
+ if (IconCollectionsAlias[collectionName]) {
122
+ return IconCollectionsAlias[collectionName];
123
+ }
124
+
125
+ return collectionName;
126
+ };
127
+
121
128
  export {
122
129
  registerIconBundle,
123
130
  registerIconLoader,
@@ -3,8 +3,8 @@ import getSharedResource from "../getSharedResource.js";
3
3
  const registry = getSharedResource("SVGIllustration.registry", new Map());
4
4
  const ILLUSTRATION_NOT_FOUND = "ILLUSTRATION_NOT_FOUND";
5
5
 
6
- const registerIllustration = (name, { dialogSvg, sceneSvg, spotSvg, title, subtitle } = {}) => { // eslint-disable-line
7
- registry.set(name, {
6
+ const registerIllustration = (name, { dialogSvg, sceneSvg, spotSvg, set, title, subtitle } = {}) => { // eslint-disable-line
7
+ registry.set(`${set}/${name}`, {
8
8
  dialogSvg,
9
9
  sceneSvg,
10
10
  spotSvg,
@@ -14,7 +14,14 @@ const registerIllustration = (name, { dialogSvg, sceneSvg, spotSvg, title, subti
14
14
  };
15
15
 
16
16
  const getIllustrationDataSync = nameProp => {
17
- return registry.get(nameProp) || ILLUSTRATION_NOT_FOUND;
17
+ let set = "fiori";
18
+
19
+ if (nameProp.startsWith("Tnt")) {
20
+ set = "tnt";
21
+ nameProp = nameProp.replace(/^Tnt/, "");
22
+ }
23
+
24
+ return registry.get(`${set}/${nameProp}`) || ILLUSTRATION_NOT_FOUND;
18
25
  };
19
26
 
20
27
  export {
@@ -13,14 +13,22 @@ 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
 
18
+ const DEV_MODE = false;
19
+
19
20
  const _showAssetsWarningOnce = localeId => {
20
- if (!warningShown) {
21
+ if (warningShown) {
22
+ return;
23
+ }
24
+
25
+ if (!DEV_MODE) {
21
26
  console.warn(`[LocaleData] Supported locale "${localeId}" not configured, import the "Assets.js" module from the webcomponents package you are using.`); /* eslint-disable-line */
22
- warningShown = true;
27
+ } else {
28
+ console.warn(`[LocaleData] Note: in dev mode, CLDR assets might be disabled for performance reasons. Try running "ENABLE_CLDR=1 yarn start" to test CLDR assets.`); /* eslint-disable-line */
23
29
  }
30
+
31
+ warningShown = true;
24
32
  };
25
33
 
26
34
  const calcLocale = (language, region, script) => {
@@ -39,6 +47,12 @@ const calcLocale = (language, region, script) => {
39
47
  }
40
48
  }
41
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
+
42
56
  // try language + region
43
57
  let localeId = `${language}_${region}`;
44
58
  if (SUPPORTED_LOCALES.includes(localeId)) {
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Supported icon collection names and aliases.
3
+ *
4
+ * Users might specify a collection, using both the key and the value in the following key-value pairs,
5
+ * e.g the following pairs are completely exchangeable:
6
+ * "SAP-icons-TNT/actor" and "tnt/actor", "BusinessSuiteInAppSymbols/3d" and "business-suite/3d",
7
+ * "SAP-icons-v5/accept" and "horizon/accept".
8
+ *
9
+ * Note: technically, in the code we maintain the collections under the "value" name - "tnt", "business-suite",
10
+ * SAP-icons-v5" and "SAP-icons"(which does not have an alias).
11
+ */
12
+ const IconCollectionsAlias = {
13
+ "SAP-icons-TNT": "tnt",
14
+ "BusinessSuiteInAppSymbols": "business-suite",
15
+ "horizon": "SAP-icons-v5",
16
+ };
17
+
18
+ export default IconCollectionsAlias;
@@ -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
+ };
@@ -1,4 +1,5 @@
1
1
  import { getTheme as getConfiguredTheme } from "../InitialConfiguration.js";
2
+ import { reRenderAllUI5Elements } from "../Render.js";
2
3
  import applyTheme from "../theming/applyTheme.js";
3
4
 
4
5
  let theme;
@@ -20,9 +21,33 @@ const setTheme = async newTheme => {
20
21
 
21
22
  // Update CSS Custom Properties
22
23
  await applyTheme(theme);
24
+ await reRenderAllUI5Elements({ themeAware: true });
25
+ };
26
+
27
+ /**
28
+ * Returns if the given theme name is the one currently applied.
29
+ * @private
30
+ * @param {String}
31
+ * @returns {boolean}
32
+ */
33
+ const isTheme = _theme => {
34
+ const currentTheme = getTheme();
35
+ return currentTheme === _theme || currentTheme === `${_theme}_exp`;
36
+ };
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);
23
46
  };
24
47
 
25
48
  export {
26
49
  getTheme,
27
50
  setTheme,
51
+ isTheme,
52
+ isThemeFamily,
28
53
  };
@@ -0,0 +1,76 @@
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
+ @keyframes grow {
63
+ 0%, 50%, 100% {
64
+ -webkit-transform: scale(0.5);
65
+ -moz-transform: scale(0.5);
66
+ -ms-transform: scale(0.5);
67
+ transform: scale(0.5);
68
+ }
69
+
70
+ 25% {
71
+ -webkit-transform: scale(1);
72
+ -moz-transform: scale(1);
73
+ -ms-transform: scale(1);
74
+ transform: scale(1);
75
+ }
76
+ }
@@ -0,0 +1,75 @@
1
+ @font-face {
2
+ font-family: "72";
3
+ font-style: normal;
4
+ font-weight: 400;
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");
8
+ }
9
+
10
+ @font-face {
11
+ font-family: "72full";
12
+ font-style: normal;
13
+ font-weight: 400;
14
+ 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");
17
+
18
+ }
19
+
20
+ @font-face {
21
+ font-family: "72";
22
+ font-style: normal;
23
+ font-weight: 700;
24
+ 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");
27
+ }
28
+
29
+ @font-face {
30
+ font-family: "72full";
31
+ font-style: normal;
32
+ font-weight: 700;
33
+ 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");
36
+ }
37
+
38
+ @font-face {
39
+ font-family: '72-Bold';
40
+ font-style: normal;
41
+ src: local('72-Bold'),
42
+ url(https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold.woff2?ui5-webcomponents) format("woff2"),
43
+ url(https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold.woff?ui5-webcomponents) format("woff");
44
+ }
45
+
46
+ @font-face {
47
+ font-family: '72-Boldfull';
48
+ font-style: normal;
49
+ src: url(https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold-full.woff2?ui5-webcomponents) format("woff2"),
50
+ url(https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Bold-full.woff?ui5-webcomponents) format("woff");
51
+ }
52
+
53
+ @font-face {
54
+ font-family: '72-Light';
55
+ font-style: normal;
56
+ src: local('72-Light'),
57
+ url(https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Light.woff2?ui5-webcomponents) format("woff2"),
58
+ url(https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Light.woff?ui5-webcomponents) format("woff");
59
+ }
60
+
61
+ @font-face {
62
+ font-family: '72-Lightfull';
63
+ font-style: normal;
64
+ src: url(https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Light-full.woff2?ui5-webcomponents) format("woff2"),
65
+ url(https://ui5.sap.com/sdk/resources/sap/ui/core/themes/sap_fiori_3/fonts/72-Light-full.woff?ui5-webcomponents) format("woff");
66
+ }
67
+
68
+ @font-face {
69
+ font-family: "72Black";
70
+ font-style: bold;
71
+ font-weight: 900;
72
+ src: local('72Black'),
73
+ url(https://openui5nightly.hana.ondemand.com/resources/sap/ui/core/themes/sap_horizon/fonts/72-Black.woff2?ui5-webcomponents) format("woff2"),
74
+ url(https://openui5nightly.hana.ondemand.com/resources/sap/ui/core/themes/sap_horizon/fonts/72-Black.woff?ui5-webcomponents) format("woff");
75
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Some diacritics are supported by the 72 font:
3
+ * * Grave
4
+ * * Acute
5
+ * * Circumflex
6
+ * * Tilde
7
+ *
8
+ * However, the following diacritics and the combination of multiple diacritics (including the supported ones) are not supported:
9
+ * * Breve
10
+ * * Horn
11
+ * * Dot below
12
+ * * Hook above
13
+ *
14
+ *
15
+ * Override for the characters that aren't covered by the '72' font to other system fonts
16
+ *
17
+ * U+0102-0103: A and a with Breve
18
+ * U+01A0-01A1: O and o with Horn
19
+ * U+01AF-01B0: U and u with Horn
20
+ * U+1EA0-1EB7: A and a with diacritics that are not supported by the font and combination of multiple diacritics
21
+ * U+1EB8-1EC7: E and e with diacritics that are not supported by the font and combination of multiple diacritics
22
+ * U+1EC8-1ECB: I and i with diacritics that are not supported by the font and combination of multiple diacritics
23
+ * U+1ECC-1EE3: O and o with diacritics that are not supported by the font and combination of multiple diacritics
24
+ * U+1EE4-1EF1: U and u with diacritics that are not supported by the font and combination of multiple diacritics
25
+ * U+1EF4-1EF7: Y and y with diacritics that are not supported by the font and combination of multiple diacritics
26
+ *
27
+ */
28
+ @font-face {
29
+ font-family: '72override';
30
+ unicode-range: U+0102-0103, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EB7, U+1EB8-1EC7, U+1EC8-1ECB, U+1ECC-1EE3, U+1EE4-1EF1, U+1EF4-1EF7;
31
+ src: local('Arial'), local('Helvetica'), local('sans-serif');
32
+ }
@@ -0,0 +1,17 @@
1
+ :root {
2
+ --_ui5_content_density:cozy;
3
+ }
4
+
5
+ [data-ui5-compact-size],
6
+ .ui5-content-density-compact,
7
+ .sapUiSizeCompact {
8
+ --_ui5_content_density:compact;
9
+ }
10
+
11
+ [dir="rtl"] {
12
+ --_ui5_dir:rtl;
13
+ }
14
+
15
+ [dir="ltr"] {
16
+ --_ui5_dir:ltr;
17
+ }
@@ -0,0 +1,108 @@
1
+ import { registerFeature } from "../FeaturesRegistry.js";
2
+ import { isF6Next, isF6Previous } from "../Keys.js";
3
+ import { getFirstFocusableElement } from "../util/FocusableElements.js";
4
+
5
+ class F6Navigation {
6
+ init() {
7
+ this.keydownHandler = this._keydownHandler.bind(this);
8
+ this.attachEventListeners();
9
+ this.selectedGroup = null;
10
+ this.groups = [];
11
+ }
12
+
13
+ attachEventListeners() {
14
+ document.addEventListener("keydown", this.keydownHandler);
15
+ }
16
+
17
+ async _keydownHandler(event) {
18
+ event.preventDefault();
19
+
20
+ if (isF6Next(event)) {
21
+ this.updateGroups();
22
+ if (this.groups.length < 1) {
23
+ return;
24
+ }
25
+
26
+ const nextIndex = this.groups.indexOf(this.selectedGroup);
27
+ let nextElement = null;
28
+
29
+ if (nextIndex > -1) {
30
+ if (nextIndex + 1 >= this.groups.length) {
31
+ nextElement = this.groups[0];
32
+ } else {
33
+ nextElement = this.groups[nextIndex + 1];
34
+ }
35
+ } else {
36
+ nextElement = this.groups[0];
37
+ }
38
+
39
+ const elementToFocus = await getFirstFocusableElement(nextElement.isUI5Element ? nextElement.getDomRef() : nextElement, true);
40
+ elementToFocus.focus();
41
+ }
42
+
43
+ if (isF6Previous(event)) {
44
+ this.updateGroups();
45
+ if (this.groups.length < 1) {
46
+ return;
47
+ }
48
+
49
+ const nextIndex = this.groups.indexOf(this.selectedGroup);
50
+ let nextElement = null;
51
+
52
+ if (nextIndex > -1) {
53
+ if (nextIndex - 1 < 0) {
54
+ nextElement = this.groups[this.groups.length - 1];
55
+ } else {
56
+ // Handle the situation where the first focusable element of two neighbor groups is the same
57
+ // For example:
58
+ // <ui5-flexible-column-layout>
59
+ // <ui5-list>
60
+ // <ui5-li>List Item</ui5-li>
61
+ // </ui5-list>
62
+ // </ui5-flexible-column-layout>
63
+ // Here for both FCL & List the firstFoccusableElement is the same (the ui5-li)
64
+
65
+ const firstFocusable = await getFirstFocusableElement(this.groups[nextIndex - 1], true);
66
+ const shouldSkipParent = firstFocusable === await getFirstFocusableElement(this.groups[nextIndex], true);
67
+
68
+ nextElement = this.groups[shouldSkipParent ? nextIndex - 2 : nextIndex - 1];
69
+ }
70
+ } else {
71
+ nextElement = this.groups[this.groups.length - 1];
72
+ }
73
+
74
+ const elementToFocus = await getFirstFocusableElement(nextElement.isUI5Element ? nextElement.getDomRef() : nextElement, true);
75
+ elementToFocus.focus();
76
+ }
77
+ }
78
+
79
+ removeEventListeners() {
80
+ document.removeEventListener("keydown", this.keydownHandler);
81
+ }
82
+
83
+ updateGroups() {
84
+ this.setSelectedGroup(document.activeElement);
85
+ this.setGroups();
86
+ }
87
+
88
+ setGroups() {
89
+ this.groups = Array.from(document.querySelectorAll("[data-sap-ui-fastnavgroup='true']")).filter(group => group.clientWidth && window.getComputedStyle(group).visibility !== "hidden");
90
+ }
91
+
92
+ setSelectedGroup(element) {
93
+ while (element && element.getAttribute("data-sap-ui-fastnavgroup") !== "true" && element !== document.querySelector("html")) {
94
+ element = element.parentElement ? element.parentNode : element.parentNode.host;
95
+ }
96
+
97
+ this.selectedGroup = element;
98
+ }
99
+
100
+ destroy() {
101
+ this.removeEventListeners();
102
+ }
103
+ }
104
+
105
+ const F6HelperInstance = new F6Navigation();
106
+ registerFeature("F6Navigation", F6HelperInstance);
107
+
108
+ export default F6Navigation;
@@ -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);