@ui5/webcomponents-base 1.0.0-rc.15 → 1.0.2
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.
- package/.eslintignore +2 -1
- package/CHANGELOG.md +53 -0
- package/README.md +26 -2
- package/bundle.esm.js +6 -2
- package/dist/CSP.js +59 -0
- package/dist/Device.js +5 -0
- package/dist/EventProvider.js +19 -25
- package/dist/FontFace.js +7 -95
- package/dist/InitialConfiguration.js +11 -7
- package/dist/Keys.js +9 -0
- package/dist/ManagedStyles.js +83 -0
- package/dist/Render.js +3 -1
- package/dist/StaticAreaItem.js +11 -9
- package/dist/SystemCSSVars.js +4 -25
- package/dist/UI5Element.js +43 -59
- package/dist/UI5ElementMetadata.js +9 -1
- package/dist/asset-registries/Icons.js +26 -8
- package/dist/asset-registries/Illustrations.js +10 -3
- package/dist/asset-registries/LocaleData.js +11 -2
- package/dist/assets-meta/IconCollectionsAlias.js +18 -0
- package/dist/config/Theme.js +14 -0
- package/dist/css/FontFace.css +45 -0
- package/dist/css/OverrideFontFace.css +32 -0
- package/dist/css/SystemCSSVars.css +17 -0
- package/dist/delegate/ItemNavigation.js +66 -0
- package/dist/generated/AssetParameters.js +1 -1
- package/dist/generated/css/FontFace.css.js +5 -0
- package/dist/generated/css/OverrideFontFace.css.js +5 -0
- package/dist/generated/css/SystemCSSVars.css.js +5 -0
- package/dist/i18nBundle.js +33 -2
- package/dist/renderer/LitRenderer.js +7 -4
- package/dist/renderer/directives/style-map.js +72 -0
- package/dist/resources/bundle.esm.js +19 -8
- package/dist/resources/bundle.esm.js.map +1 -1
- package/dist/sap/base/Log.js +2 -10
- package/dist/sap/base/assert.js +1 -5
- package/dist/test-resources/elements/WithStaticArea.js +2 -1
- package/dist/test-resources/pages/AllTestElements.html +3 -0
- package/dist/test-resources/pages/i18n.html +1 -3
- package/dist/test-resources/specs/ConfigurationChange.spec.js +9 -9
- package/dist/test-resources/specs/ConfigurationScript.spec.js +24 -24
- package/dist/test-resources/specs/ConfigurationURL.spec.js +33 -33
- package/dist/test-resources/specs/CustomTheme.spec.js +7 -7
- package/dist/test-resources/specs/EventProvider.spec.js +63 -0
- package/dist/test-resources/specs/StaticArea.spec.js +55 -13
- package/dist/test-resources/specs/Theming.spec.js +11 -11
- package/dist/test-resources/specs/UI5ElementInvalidation.js +29 -29
- package/dist/test-resources/specs/UI5ElementLifecycle.js +11 -11
- package/dist/test-resources/specs/UI5ElementListenForChildPropChanges.spec.js +11 -11
- package/dist/test-resources/specs/UI5ElementMetadataExt.js +8 -8
- package/dist/test-resources/specs/UI5ElementPropertyValidation.js +6 -6
- package/dist/test-resources/specs/UI5ElementPropsAndAttrs.spec.js +36 -36
- package/dist/test-resources/specs/UI5ElementShadowDOM.js +9 -9
- package/dist/test-resources/specs/UI5ElementSlots.js +9 -9
- package/dist/theming/CustomStyle.js +23 -3
- package/dist/theming/applyTheme.js +11 -10
- package/dist/theming/getEffectiveLinksHrefs.js +20 -0
- package/dist/theming/getStylesString.js +4 -2
- package/dist/theming/getThemeDesignerTheme.js +25 -5
- package/dist/theming/preloadLinks.js +23 -0
- package/dist/types/DataType.js +12 -0
- package/dist/types/Float.js +4 -0
- package/dist/types/Integer.js +4 -0
- package/dist/updateShadowRoot.js +8 -4
- package/dist/util/createLinkInHead.js +19 -0
- package/dist/util/encodeXML.js +35 -0
- package/dist/util/escapeRegex.js +10 -0
- package/dist/util/generateHighlightedMarkup.js +42 -0
- package/hash.txt +1 -1
- package/lib/generate-asset-parameters/index.js +0 -1
- package/lib/generate-styles/index.js +18 -0
- package/package-scripts.js +9 -6
- package/package.json +9 -11
- package/src/CSP.js +59 -0
- package/src/Device.js +5 -0
- package/src/EventProvider.js +19 -25
- package/src/FontFace.js +7 -95
- package/src/InitialConfiguration.js +11 -7
- package/src/Keys.js +9 -0
- package/src/ManagedStyles.js +83 -0
- package/src/Render.js +3 -1
- package/src/StaticAreaItem.js +11 -9
- package/src/SystemCSSVars.js +4 -25
- package/src/UI5Element.js +43 -59
- package/src/UI5ElementMetadata.js +9 -1
- package/src/asset-registries/Icons.js +26 -8
- package/src/asset-registries/Illustrations.js +10 -3
- package/src/asset-registries/LocaleData.js +11 -2
- package/src/assets-meta/IconCollectionsAlias.js +18 -0
- package/src/config/Theme.js +14 -0
- package/src/css/FontFace.css +45 -0
- package/src/css/OverrideFontFace.css +32 -0
- package/src/css/SystemCSSVars.css +17 -0
- package/src/delegate/ItemNavigation.js +66 -0
- package/src/i18nBundle.js +33 -2
- package/src/renderer/LitRenderer.js +7 -4
- package/src/renderer/directives/style-map.js +72 -0
- package/src/theming/CustomStyle.js +23 -3
- package/src/theming/applyTheme.js +11 -10
- package/src/theming/getEffectiveLinksHrefs.js +20 -0
- package/src/theming/getStylesString.js +4 -2
- package/src/theming/getThemeDesignerTheme.js +25 -5
- package/src/theming/preloadLinks.js +23 -0
- package/src/types/DataType.js +12 -0
- package/src/types/Float.js +4 -0
- package/src/types/Integer.js +4 -0
- package/src/updateShadowRoot.js +8 -4
- package/src/util/createLinkInHead.js +19 -0
- package/src/util/encodeXML.js +35 -0
- package/src/util/escapeRegex.js +10 -0
- package/src/util/generateHighlightedMarkup.js +42 -0
- package/dist/config/AssetsPath.js +0 -17
- package/dist/theming/createThemePropertiesStyleTag.js +0 -20
- package/src/config/AssetsPath.js +0 -17
- package/src/theming/createThemePropertiesStyleTag.js +0 -20
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import getSharedResource from "../getSharedResource.js";
|
|
2
|
+
import IconCollectionsAlias from "../assets-meta/IconCollectionsAlias.js";
|
|
3
|
+
import { isTheme } from "../config/Theme.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 =
|
|
51
|
+
collection = _getDefaultCollection();
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
const key = `${collection}/${name}`;
|
|
@@ -67,12 +68,16 @@ const _parseName = name => {
|
|
|
67
68
|
|
|
68
69
|
let collection;
|
|
69
70
|
[name, collection] = name.split("/").reverse();
|
|
70
|
-
collection = collection ||
|
|
71
|
-
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
collection = collection || _getDefaultCollection();
|
|
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
|
+
|
|
76
81
|
const registryKey = `${collection}/${name}`;
|
|
77
82
|
return { name, collection, registryKey };
|
|
78
83
|
};
|
|
@@ -108,9 +113,22 @@ const _getRegisteredNames = async () => {
|
|
|
108
113
|
// fetch one icon of each collection to trigger the bundle load
|
|
109
114
|
await getIconData("edit");
|
|
110
115
|
await getIconData("tnt/arrow");
|
|
116
|
+
await getIconData("business-suite/3d");
|
|
111
117
|
return Array.from(registry.keys());
|
|
112
118
|
};
|
|
113
119
|
|
|
120
|
+
const _getDefaultCollection = () => {
|
|
121
|
+
return isTheme("sap_horizon") ? "SAP-icons-v5" : "SAP-icons";
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const _normalizeCollection = collectionName => {
|
|
125
|
+
if (IconCollectionsAlias[collectionName]) {
|
|
126
|
+
return IconCollectionsAlias[collectionName];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return collectionName;
|
|
130
|
+
};
|
|
131
|
+
|
|
114
132
|
export {
|
|
115
133
|
registerIconBundle,
|
|
116
134
|
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
|
-
|
|
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 {
|
|
@@ -16,11 +16,20 @@ const M_ISO639_OLD_TO_NEW = {
|
|
|
16
16
|
"sh": "sr",
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
+
const DEV_MODE = false;
|
|
20
|
+
|
|
19
21
|
const _showAssetsWarningOnce = localeId => {
|
|
20
|
-
if (
|
|
22
|
+
if (warningShown) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (!DEV_MODE) {
|
|
21
27
|
console.warn(`[LocaleData] Supported locale "${localeId}" not configured, import the "Assets.js" module from the webcomponents package you are using.`); /* eslint-disable-line */
|
|
22
|
-
|
|
28
|
+
} else {
|
|
29
|
+
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
30
|
}
|
|
31
|
+
|
|
32
|
+
warningShown = true;
|
|
24
33
|
};
|
|
25
34
|
|
|
26
35
|
const calcLocale = (language, region, script) => {
|
|
@@ -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;
|
package/src/config/Theme.js
CHANGED
|
@@ -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,22 @@ 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`;
|
|
23
36
|
};
|
|
24
37
|
|
|
25
38
|
export {
|
|
26
39
|
getTheme,
|
|
27
40
|
setTheme,
|
|
41
|
+
isTheme,
|
|
28
42
|
};
|
|
@@ -0,0 +1,45 @@
|
|
|
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: "72Black";
|
|
40
|
+
font-style: bold;
|
|
41
|
+
font-weight: 900;
|
|
42
|
+
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");
|
|
45
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
isRight,
|
|
6
6
|
isHome,
|
|
7
7
|
isEnd,
|
|
8
|
+
isPageDown,
|
|
9
|
+
isPageUp,
|
|
8
10
|
} from "../Keys.js";
|
|
9
11
|
import getActiveElement from "../util/getActiveElement.js";
|
|
10
12
|
|
|
@@ -52,6 +54,7 @@ class ItemNavigation {
|
|
|
52
54
|
* - currentIndex: the index of the item that will be initially selected (from which navigation will begin)
|
|
53
55
|
* - navigationMode (Auto|Horizontal|Vertical): whether the items are displayed horizontally (Horizontal), vertically (Vertical) or as a matrix (Auto) meaning the user can navigate in both directions (up/down and left/right)
|
|
54
56
|
* - rowSize: tells how many items per row there are when the items are not rendered as a flat list but rather as a matrix. Relevant for navigationMode=Auto
|
|
57
|
+
* - skipItemsSize: tells how many items upon PAGE_UP and PAGE_DOWN should be skipped to applying the focus on the next item
|
|
55
58
|
* - behavior (Static|Cycling): tells what to do when trying to navigate beyond the first and last items
|
|
56
59
|
* Static means that nothing happens if the user tries to navigate beyond the first/last item.
|
|
57
60
|
* Cycling means that when the user navigates beyond the last item they go to the first and vice versa.
|
|
@@ -85,6 +88,7 @@ class ItemNavigation {
|
|
|
85
88
|
this._behavior = options.behavior || ItemNavigationBehavior.Static;
|
|
86
89
|
this._navigationMode = options.navigationMode || NavigationMode.Auto;
|
|
87
90
|
this._affectedPropertiesNames = options.affectedPropertiesNames || [];
|
|
91
|
+
this._skipItemsSize = options.skipItemsSize || null;
|
|
88
92
|
}
|
|
89
93
|
|
|
90
94
|
/**
|
|
@@ -142,6 +146,10 @@ class ItemNavigation {
|
|
|
142
146
|
this._handleHome();
|
|
143
147
|
} else if (isEnd(event)) {
|
|
144
148
|
this._handleEnd();
|
|
149
|
+
} else if (isPageUp(event)) {
|
|
150
|
+
this._handlePageUp();
|
|
151
|
+
} else if (isPageDown(event)) {
|
|
152
|
+
this._handlePageDown();
|
|
145
153
|
} else {
|
|
146
154
|
return; // if none of the supported keys is pressed, we don't want to prevent the event or update the item navigation
|
|
147
155
|
}
|
|
@@ -222,6 +230,64 @@ class ItemNavigation {
|
|
|
222
230
|
this._currentIndex += (homeEndRange - 1 - this._currentIndex % homeEndRange); // eslint-disable-line
|
|
223
231
|
}
|
|
224
232
|
|
|
233
|
+
_handlePageUp() {
|
|
234
|
+
if (this._rowSize > 1) {
|
|
235
|
+
// eslint-disable-next-line
|
|
236
|
+
// TODO: handle page up on matrix (grid) layout - ColorPalette, ProductSwitch.
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
this._handlePageUpFlat();
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
_handlePageDown() {
|
|
243
|
+
if (this._rowSize > 1) {
|
|
244
|
+
// eslint-disable-next-line
|
|
245
|
+
// TODO: handle page up on matrix (grid) layout - ColorPalette, ProductSwitch.
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
this._handlePageDownFlat();
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Handles PAGE_UP in a flat list-like structure, both vertically and horizontally.
|
|
253
|
+
*/
|
|
254
|
+
_handlePageUpFlat() {
|
|
255
|
+
if (this._skipItemsSize === null) {
|
|
256
|
+
// Move the focus to the very top (as Home).
|
|
257
|
+
this._currentIndex -= this._currentIndex;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (this._currentIndex + 1 > this._skipItemsSize) {
|
|
261
|
+
// When there are more than "skipItemsSize" number of items to the top,
|
|
262
|
+
// move the focus up/left with the predefined number.
|
|
263
|
+
this._currentIndex -= this._skipItemsSize;
|
|
264
|
+
} else {
|
|
265
|
+
// Otherwise, move the focus to the very top (as Home).
|
|
266
|
+
this._currentIndex -= this._currentIndex;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Handles PAGE_DOWN in a flat list-like structure, both vertically and horizontally.
|
|
272
|
+
*/
|
|
273
|
+
_handlePageDownFlat() {
|
|
274
|
+
if (this._skipItemsSize === null) {
|
|
275
|
+
// Move the focus to the very bottom (as End).
|
|
276
|
+
this._currentIndex = this._getItems().length - 1;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const currentToEndRange = this._getItems().length - this._currentIndex - 1;
|
|
280
|
+
|
|
281
|
+
if (currentToEndRange > this._skipItemsSize) {
|
|
282
|
+
// When there are more than "skipItemsSize" number of items until the bottom,
|
|
283
|
+
// move the focus down/right with the predefined number.
|
|
284
|
+
this._currentIndex += this._skipItemsSize;
|
|
285
|
+
} else {
|
|
286
|
+
// Otherwise, move the focus to the very bottom (as End).
|
|
287
|
+
this._currentIndex = this._getItems().length - 1;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
225
291
|
_applyTabIndex() {
|
|
226
292
|
const items = this._getItems();
|
|
227
293
|
for (let i = 0; i < items.length; i++) {
|
package/src/i18nBundle.js
CHANGED
|
@@ -3,6 +3,8 @@ import formatMessage from "./util/formatMessage.js";
|
|
|
3
3
|
|
|
4
4
|
const I18nBundleInstances = new Map();
|
|
5
5
|
|
|
6
|
+
let customGetI18nBundle;
|
|
7
|
+
|
|
6
8
|
/**
|
|
7
9
|
* @class
|
|
8
10
|
* @public
|
|
@@ -15,6 +17,7 @@ class I18nBundle {
|
|
|
15
17
|
/**
|
|
16
18
|
* Returns a text in the currently loaded language
|
|
17
19
|
*
|
|
20
|
+
* @public
|
|
18
21
|
* @param {Object|String} textObj key/defaultText pair or just the key
|
|
19
22
|
* @param params Values for the placeholders
|
|
20
23
|
* @returns {*}
|
|
@@ -38,7 +41,7 @@ class I18nBundle {
|
|
|
38
41
|
}
|
|
39
42
|
}
|
|
40
43
|
|
|
41
|
-
const
|
|
44
|
+
const getI18nBundleSync = packageName => {
|
|
42
45
|
if (I18nBundleInstances.has(packageName)) {
|
|
43
46
|
return I18nBundleInstances.get(packageName);
|
|
44
47
|
}
|
|
@@ -48,8 +51,36 @@ const getI18nBundle = packageName => {
|
|
|
48
51
|
return i18nBundle;
|
|
49
52
|
};
|
|
50
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Allows developers to provide a custom getI18nBundle implementation
|
|
56
|
+
* If this function is called, the custom implementation will be used for all components and will completely
|
|
57
|
+
* replace the default implementation.
|
|
58
|
+
*
|
|
59
|
+
* @public
|
|
60
|
+
* @param customGet the function to use instead of the standard getI18nBundle implementation
|
|
61
|
+
*/
|
|
62
|
+
const registerCustomI18nBundleGetter = customGet => {
|
|
63
|
+
customGetI18nBundle = customGet;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Fetches and returns the I18nBundle instance for the given package
|
|
68
|
+
*
|
|
69
|
+
* @public
|
|
70
|
+
* @param packageName
|
|
71
|
+
* @returns {Promise<I18nBundle>}
|
|
72
|
+
*/
|
|
73
|
+
const getI18nBundle = async packageName => {
|
|
74
|
+
if (customGetI18nBundle) {
|
|
75
|
+
return customGetI18nBundle(packageName);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
await fetchI18nBundle(packageName);
|
|
79
|
+
return getI18nBundleSync(packageName);
|
|
80
|
+
};
|
|
81
|
+
|
|
51
82
|
export {
|
|
52
83
|
registerI18nLoader,
|
|
53
|
-
fetchI18nBundle,
|
|
54
84
|
getI18nBundle,
|
|
85
|
+
registerCustomI18nBundleGetter,
|
|
55
86
|
};
|
|
@@ -5,9 +5,11 @@ import {
|
|
|
5
5
|
unsafeStatic,
|
|
6
6
|
} from "lit-html/static.js";
|
|
7
7
|
|
|
8
|
-
const litRender = (templateResult, domNode,
|
|
9
|
-
if (
|
|
10
|
-
templateResult = html`<style>${
|
|
8
|
+
const litRender = (templateResult, domNode, styleStrOrHrefsArr, { host } = {}) => {
|
|
9
|
+
if (typeof styleStrOrHrefsArr === "string") {
|
|
10
|
+
templateResult = html`<style>${styleStrOrHrefsArr}</style>${templateResult}`;
|
|
11
|
+
} else if (Array.isArray(styleStrOrHrefsArr) && styleStrOrHrefsArr.length) {
|
|
12
|
+
templateResult = html`${styleStrOrHrefsArr.map(href => html`<link type="text/css" rel="stylesheet" href="${href}">`)}${templateResult}`;
|
|
11
13
|
}
|
|
12
14
|
render(templateResult, domNode, { host });
|
|
13
15
|
};
|
|
@@ -25,7 +27,8 @@ export {
|
|
|
25
27
|
export { scopeTag };
|
|
26
28
|
export { repeat } from "lit-html/directives/repeat.js";
|
|
27
29
|
export { classMap } from "lit-html/directives/class-map.js";
|
|
28
|
-
export { styleMap } from "
|
|
30
|
+
export { styleMap } from "./directives/style-map.js";
|
|
31
|
+
export { ifDefined } from "lit-html/directives/if-defined.js";
|
|
29
32
|
export { unsafeHTML } from "lit-html/directives/unsafe-html.js";
|
|
30
33
|
|
|
31
34
|
export default litRender;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2018 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* This is the original style-map.js directive from lit-html 2 with the only difference that "render" is not called even for the first rendering (update is used instead)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { noChange } from 'lit-html';
|
|
12
|
+
import { directive, Directive, PartType, } from 'lit-html/directive.js';
|
|
13
|
+
class StyleMapDirective extends Directive {
|
|
14
|
+
constructor(partInfo) {
|
|
15
|
+
var _a;
|
|
16
|
+
super(partInfo);
|
|
17
|
+
if (partInfo.type !== PartType.ATTRIBUTE ||
|
|
18
|
+
partInfo.name !== 'style' ||
|
|
19
|
+
((_a = partInfo.strings) === null || _a === void 0 ? void 0 : _a.length) > 2) {
|
|
20
|
+
throw new Error('The `styleMap` directive must be used in the `style` attribute ' +
|
|
21
|
+
'and must be the only part in the attribute.');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
render(styleInfo) {
|
|
25
|
+
return "";
|
|
26
|
+
}
|
|
27
|
+
update(part, [styleInfo]) {
|
|
28
|
+
const { style } = part.element;
|
|
29
|
+
if (this._previousStyleProperties === undefined) {
|
|
30
|
+
this._previousStyleProperties = new Set();
|
|
31
|
+
for (const name in styleInfo) {
|
|
32
|
+
this._previousStyleProperties.add(name);
|
|
33
|
+
}
|
|
34
|
+
// return this.render(styleInfo);
|
|
35
|
+
}
|
|
36
|
+
// Remove old properties that no longer exist in styleInfo
|
|
37
|
+
// We use forEach() instead of for-of so that re don't require down-level
|
|
38
|
+
// iteration.
|
|
39
|
+
this._previousStyleProperties.forEach((name) => {
|
|
40
|
+
// If the name isn't in styleInfo or it's null/undefined
|
|
41
|
+
if (styleInfo[name] == null) {
|
|
42
|
+
this._previousStyleProperties.delete(name);
|
|
43
|
+
if (name.includes('-')) {
|
|
44
|
+
style.removeProperty(name);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
// Note reset using empty string (vs null) as IE11 does not always
|
|
48
|
+
// reset via null (https://developer.mozilla.org/en-US/docs/Web/API/ElementCSSInlineStyle/style#setting_styles)
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
50
|
+
style[name] = '';
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
// Add or update properties
|
|
55
|
+
for (const name in styleInfo) {
|
|
56
|
+
const value = styleInfo[name];
|
|
57
|
+
if (value != null) {
|
|
58
|
+
this._previousStyleProperties.add(name);
|
|
59
|
+
if (name.includes('-')) {
|
|
60
|
+
style.setProperty(name, value);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
64
|
+
style[name] = value;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return noChange;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export const styleMap = directive(StyleMapDirective);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { reRenderAllUI5Elements } from "../Render.js";
|
|
2
|
+
import getSharedResource from "../getSharedResource.js";
|
|
2
3
|
import EventProvider from "../EventProvider.js";
|
|
3
4
|
|
|
4
|
-
const eventProvider = new EventProvider();
|
|
5
|
+
const eventProvider = getSharedResource("CustomStyle.eventProvider", new EventProvider());
|
|
5
6
|
const CUSTOM_CSS_CHANGE = "CustomCSSChange";
|
|
6
7
|
|
|
7
8
|
const attachCustomCSSChange = listener => {
|
|
@@ -16,14 +17,33 @@ const fireCustomCSSChange = tag => {
|
|
|
16
17
|
return eventProvider.fireEvent(CUSTOM_CSS_CHANGE, tag);
|
|
17
18
|
};
|
|
18
19
|
|
|
19
|
-
const customCSSFor = {};
|
|
20
|
+
const customCSSFor = getSharedResource("CustomStyle.customCSSFor", {});
|
|
21
|
+
|
|
22
|
+
// Listen to the eventProvider, in case other copies of this CustomStyle module fire this
|
|
23
|
+
// event, and this copy would therefore need to reRender the ui5 webcomponents; but
|
|
24
|
+
// don't reRender if it was this copy that fired the event to begin with.
|
|
25
|
+
let skipRerender;
|
|
26
|
+
attachCustomCSSChange(tag => {
|
|
27
|
+
if (!skipRerender) {
|
|
28
|
+
reRenderAllUI5Elements({ tag });
|
|
29
|
+
}
|
|
30
|
+
});
|
|
20
31
|
|
|
21
32
|
const addCustomCSS = (tag, css) => {
|
|
22
33
|
if (!customCSSFor[tag]) {
|
|
23
34
|
customCSSFor[tag] = [];
|
|
24
35
|
}
|
|
25
36
|
customCSSFor[tag].push(css);
|
|
26
|
-
|
|
37
|
+
|
|
38
|
+
skipRerender = true;
|
|
39
|
+
try {
|
|
40
|
+
// The event is fired and the attached event listeners are all called synchronously
|
|
41
|
+
// The skipRerender flag will be used to avoid calling reRenderAllUI5Elements twice when it is this copy
|
|
42
|
+
// of CustomStyle.js which is firing the `CustomCSSChange` event.
|
|
43
|
+
fireCustomCSSChange(tag);
|
|
44
|
+
} finally {
|
|
45
|
+
skipRerender = false;
|
|
46
|
+
}
|
|
27
47
|
|
|
28
48
|
return reRenderAllUI5Elements({ tag });
|
|
29
49
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { getThemeProperties, getRegisteredPackages, isThemeRegistered } from "../asset-registries/Themes.js";
|
|
2
|
-
import
|
|
2
|
+
import { removeStyle, createOrUpdateStyle } from "../ManagedStyles.js";
|
|
3
3
|
import getThemeDesignerTheme from "./getThemeDesignerTheme.js";
|
|
4
4
|
import { fireThemeLoaded } from "./ThemeLoaded.js";
|
|
5
5
|
import { getFeature } from "../FeaturesRegistry.js";
|
|
6
6
|
|
|
7
|
-
const BASE_THEME_PACKAGE = "@ui5/webcomponents-
|
|
7
|
+
const BASE_THEME_PACKAGE = "@ui5/webcomponents-theming";
|
|
8
8
|
|
|
9
9
|
const isThemeBaseRegistered = () => {
|
|
10
10
|
const registeredPackages = getRegisteredPackages();
|
|
@@ -16,15 +16,14 @@ const loadThemeBase = async theme => {
|
|
|
16
16
|
return;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
const
|
|
20
|
-
|
|
19
|
+
const cssData = await getThemeProperties(BASE_THEME_PACKAGE, theme);
|
|
20
|
+
if (cssData) {
|
|
21
|
+
createOrUpdateStyle(cssData, "data-ui5-theme-properties", BASE_THEME_PACKAGE);
|
|
22
|
+
}
|
|
21
23
|
};
|
|
22
24
|
|
|
23
25
|
const deleteThemeBase = () => {
|
|
24
|
-
|
|
25
|
-
if (styleElement) {
|
|
26
|
-
styleElement.parentElement.removeChild(styleElement);
|
|
27
|
-
}
|
|
26
|
+
removeStyle("data-ui5-theme-properties", BASE_THEME_PACKAGE);
|
|
28
27
|
};
|
|
29
28
|
|
|
30
29
|
const loadComponentPackages = async theme => {
|
|
@@ -34,8 +33,10 @@ const loadComponentPackages = async theme => {
|
|
|
34
33
|
return;
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
const
|
|
38
|
-
|
|
36
|
+
const cssData = await getThemeProperties(packageName, theme);
|
|
37
|
+
if (cssData) {
|
|
38
|
+
createOrUpdateStyle(cssData, "data-ui5-theme-properties", packageName);
|
|
39
|
+
}
|
|
39
40
|
});
|
|
40
41
|
};
|
|
41
42
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getUrl } from "../CSP.js";
|
|
2
|
+
|
|
3
|
+
const flatten = arr => {
|
|
4
|
+
return arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flatten(val) : val), []);
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
const getEffectiveLinksHrefs = (ElementClass, forStaticArea = false) => {
|
|
8
|
+
let stylesData = ElementClass[forStaticArea ? "staticAreaStyles" : "styles"];
|
|
9
|
+
if (!stylesData) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (!Array.isArray(stylesData)) {
|
|
14
|
+
stylesData = [stylesData];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return flatten(stylesData).filter(data => !!data).map(data => getUrl(data.packageName, data.fileName));
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export default getEffectiveLinksHrefs;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
const getStylesString = styles => {
|
|
2
2
|
if (Array.isArray(styles)) {
|
|
3
|
-
return flatten(styles.filter(style => !!style)).
|
|
3
|
+
return flatten(styles.filter(style => !!style)).map(style => {
|
|
4
|
+
return typeof style === "string" ? style : style.content;
|
|
5
|
+
}).join(" ");
|
|
4
6
|
}
|
|
5
7
|
|
|
6
|
-
return styles;
|
|
8
|
+
return typeof styles === "string" ? styles : styles.content;
|
|
7
9
|
};
|
|
8
10
|
|
|
9
11
|
const flatten = arr => {
|