Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions docs/2-advanced/01-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ There are several configuration settings that affect all UI5 Web Components glob
| [secondaryCalendarType](#calendarType) | `Gregorian`, `Islamic`, `Buddhist`, `Japanese`, `Persian` | `undefined` | Default secondary calendar type to be used for date-related components | Date/time components (`ui5-date-picker`, etc.) |
| [noConflict](#noConflict) | `true`, `false` | `false` | When set to true, all events will be fired with a `ui5-` prefix only | Components that fire events (most do) |
| [formatSettings](#formatSettings) | See the [Format settings](#formatSettings) section below | `{}` | Allows to override locale-specific configuration | Date/time components (`ui5-date-picker`, etc.) |
| [loadBaseThemingCSSVariables](#loadBaseThemingCSSVariables) | `true`, `false` | `true` | Whether to load CSS variables from `@sap-theming/theming-base-content` package | Framework |
| [fetchDefaultLanguage](#fetchDefaultLanguage) | `true`, `false` | `false` | Whether to fetch assets even for the default language | Framework |
| [defaultFontLoading](#defaultFontLoading) | `true`, `false` | `true` | Whether to fetch default font faces | Framework |
| [enableDefaultTooltips](#enableDefaultTooltips) | `true`, `false` | `true` | Whether to display default tooltips | Components (Icon, Button, RatingIndicator, etc.) |
Expand Down Expand Up @@ -219,6 +220,23 @@ Example:
}
</script>
```

### loadBaseThemingCSSVariables
<a name="loadBaseThemingCSSVariables"></a>

This configuration option controls whether the framework should load the CSS variables from `@sap-theming/theming-base-content` package.

Typically, you would not need to modify this setting. However, if your application provides its **own** instance or version of `@sap-theming/theming-base-content` and you prefer the framework **not** to load the built-in base theming CSS variables, you can set `loadBaseThemingCSSVariables` to `false`.

Example:
```html
<script data-ui5-config type="application/json">
{
"loadBaseThemingCSSVariables": false
}
</script>
```

### defaultFontLoading
<a name="defaultFontLoading"></a>

Expand Down
8 changes: 8 additions & 0 deletions packages/base/src/InitialConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type InitialConfig = {
formatSettings: FormatSettings,
fetchDefaultLanguage: boolean,
defaultFontLoading: boolean,
loadBaseThemingCSSVariables: boolean,
enableDefaultTooltips: boolean,
};

Expand All @@ -40,6 +41,7 @@ let initialConfig: InitialConfig = {
formatSettings: {},
fetchDefaultLanguage: false,
defaultFontLoading: true,
loadBaseThemingCSSVariables: true,
enableDefaultTooltips: true,
};

Expand Down Expand Up @@ -94,6 +96,11 @@ const getDefaultFontLoading = () => {
return initialConfig.defaultFontLoading;
};

const getLoadBaseThemingCSSVariables = () => {
initConfiguration();
return initialConfig.loadBaseThemingCSSVariables;
};

const getEnableDefaultTooltips = () => {
initConfiguration();
return initialConfig.enableDefaultTooltips;
Expand Down Expand Up @@ -255,6 +262,7 @@ export {
getTimezone,
getFormatSettings,
getDefaultFontLoading,
getLoadBaseThemingCSSVariables,
resetConfiguration,
getEnableDefaultTooltips,
};
35 changes: 34 additions & 1 deletion packages/base/src/config/Theme.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getTheme as getConfiguredTheme } from "../InitialConfiguration.js";
import { getTheme as getConfiguredTheme, getLoadBaseThemingCSSVariables as getConfiguredLoadBaseThemingCSSVariables } from "../InitialConfiguration.js";
import { reRenderAllUI5Elements } from "../Render.js";
import applyTheme from "../theming/applyTheme.js";
import getThemeDesignerTheme from "../theming/getThemeDesignerTheme.js";
Expand All @@ -7,6 +7,7 @@ import { boot, isBooted } from "../Boot.js";
import { attachConfigurationReset } from "./ConfigurationReset.js";

let curTheme: string | undefined;
let loadBaseThemingCSSVariables: boolean | undefined;

attachConfigurationReset(() => {
curTheme = undefined;
Expand Down Expand Up @@ -57,6 +58,36 @@ const getDefaultTheme = (): string => {
return DEFAULT_THEME;
};

/**
* Returns the current configuration for loading base theming CSS variables.
*
* @public
* @since 2.17.0
* @returns {boolean}
*/
const getLoadBaseThemingCSSVariables = () => {
if (loadBaseThemingCSSVariables === undefined) {
loadBaseThemingCSSVariables = getConfiguredLoadBaseThemingCSSVariables();
}

return loadBaseThemingCSSVariables;
};

/**
* Configures whether to load base theming CSS variables.
*
* - When set to `true` (default), base theming CSS variables are loaded.
* - When set to `false`, base theming CSS variables are not loaded.
*
* **Note:** This method should be called before the boot process.
*
* @public
* @since 2.17.0
*/
const setLoadBaseThemingCSSVariables = (value: boolean) => {
loadBaseThemingCSSVariables = value;
};

/**
* Returns if the given theme name is the one currently applied.
* @private
Expand Down Expand Up @@ -98,4 +129,6 @@ export {
isLegacyThemeFamily,
isLegacyThemeFamilyAsync,
getDefaultTheme,
getLoadBaseThemingCSSVariables,
setLoadBaseThemingCSSVariables,
};
5 changes: 5 additions & 0 deletions packages/base/src/theming/applyTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { fireThemeLoaded } from "./ThemeLoaded.js";
import { attachCustomThemeStylesToHead, getThemeRoot } from "../config/ThemeRoot.js";
import { DEFAULT_THEME } from "../generated/AssetParameters.js";
import { getCurrentRuntimeIndex } from "../Runtimes.js";
import { getLoadBaseThemingCSSVariables } from "../config/Theme.js";

// eslint-disable-next-line
export let _lib = "ui5";
Expand Down Expand Up @@ -33,6 +34,10 @@ const loadComponentPackages = async (theme: string, externalThemeName?: string)
const registeredPackages = getRegisteredPackages();

const packagesStylesPromises = [...registeredPackages].map(async packageName => {
if (getLoadBaseThemingCSSVariables() !== true && packageName === `${BASE_THEME_PACKAGE}-raw`) {
return;
}

if (packageName === BASE_THEME_PACKAGE) {
return;
}
Expand Down
1 change: 0 additions & 1 deletion packages/compat/cypress/specs/Table.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,6 @@ describe("Table general interaction", () => {
cy.get("@popinChange")
.should(stub => {
expect(stub).to.have.been.calledTwice;
debugger
// @ts-ignore
expect(stub.args.slice(-1)[0][0].detail.poppedColumns.length).to.equal(2);
})
Expand Down
10 changes: 9 additions & 1 deletion packages/main/src/bundle.common.bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,13 @@ import { resetConfiguration } from "@ui5/webcomponents-base/dist/InitialConfigur
import { sanitizeHTML, URLListValidator } from "@ui5/webcomponents-base/dist/util/HTMLSanitizer.js";

import { getAnimationMode, setAnimationMode } from "@ui5/webcomponents-base/dist/config/AnimationMode.js";
import { getTheme, setTheme, isLegacyThemeFamily } from "@ui5/webcomponents-base/dist/config/Theme.js";
import {
getTheme,
setTheme,
isLegacyThemeFamily,
getLoadBaseThemingCSSVariables,
setLoadBaseThemingCSSVariables,
} from "@ui5/webcomponents-base/dist/config/Theme.js";
import { getThemeRoot, setThemeRoot } from "@ui5/webcomponents-base/dist/config/ThemeRoot.js";
import { getTimezone, setTimezone } from "@ui5/webcomponents-base/dist/config/Timezone.js";
import { getLanguage, setLanguage } from "@ui5/webcomponents-base/dist/config/Language.js";
Expand Down Expand Up @@ -104,6 +110,8 @@ const testAssets = {
getFirstDayOfWeek,
getTimezone,
setTimezone,
getLoadBaseThemingCSSVariables,
setLoadBaseThemingCSSVariables,
},
invisibleMessage: {
announce,
Expand Down
2 changes: 1 addition & 1 deletion packages/main/test/pages/Button.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

</head>

<body class="button1auto">
<body class="button1auto" style="background-color: var(--sapButton_Emphasized_Background);">
<ui5-button design="Negative" icon="decline">Reject</ui5-button>
<ui5-button design="Positive" icon="add">Add</ui5-button>
<ui5-button icon="home" id="icon-only-comment"><!----><!----></ui5-button>
Expand Down
21 changes: 21 additions & 0 deletions packages/main/test/pages/theming/Themes7.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<title>Theming</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<script data-ui5-config type="application/json">
{
"loadBaseThemingCSSVariables": true
}
</script>
<script src="../%VITE_BUNDLE_PATH%" type="module"></script>
</head>

<body style="background-color: var(--sapButton_Emphasized_Background);">
<ui5-button>Some content</ui5-button>
</body>

</html>
21 changes: 21 additions & 0 deletions packages/main/test/pages/theming/Themes8.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<title>Theming</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<script data-ui5-config type="application/json">
{
"loadBaseThemingCSSVariables": false
}
</script>
<script src="../%VITE_BUNDLE_PATH%" type="module"></script>
</head>

<body style="background-color: var(--sapButton_Emphasized_Background);">
<ui5-button>Some content</ui5-button>
</body>

</html>
6 changes: 5 additions & 1 deletion packages/theming/package-scripts.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ module.exports = {
src: `ui5nps-script "${TOOLS_LIB}copy-and-watch/index.js" "src/**/*.{json}" dist/`,
typescript: "tsc",
postcss: `ui5nps-script "${TOOLS_LIB}/css-processors/css-processor-themes.mjs"`,
jsonImports: `ui5nps-script "${jsonImportsScript}" src/themes src/generated/json-imports`,
jsonImports: {
default: "ui5nps build.jsonImports.scoped build.jsonImports.raw",
scoped: `ui5nps-script "${jsonImportsScript}" src/themes src/generated/json-imports`,
raw: `ui5nps-script "${jsonImportsScript}" src/themes src/generated/json-imports -raw`,
}
},
generateReport: `ui5nps-script "${generateReportScript}"`,
},
Expand Down
1 change: 1 addition & 0 deletions packages/theming/src/Assets-fetch.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
// The theming package provides theming assets only
import "./generated/json-imports/Themes-fetch.js";
import "./generated/json-imports/Themes-raw-fetch.js";
3 changes: 2 additions & 1 deletion packages/theming/src/Assets-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
*
* It serves as an alternative to the `Assets` and `Assets-fetch` modules and supports the
* `with: { type: 'json' }` import attribute for loading JSON files.
*
*
* This import attribute is required in some environments, such as Node.js with server-side rendering (SSR).
*
* Example usage:
* await import("../assets/themes/sap_horizon/parameters-bundle.css.json", { with: { type: 'json' } })
*/

import "./generated/json-imports/Themes-node.js";
import "./generated/json-imports/Themes-raw-node.js";
1 change: 1 addition & 0 deletions packages/theming/src/Assets.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
// The theming package provides theming assets only
import "./generated/json-imports/Themes.js";
import "./generated/json-imports/Themes-raw.js";
64 changes: 43 additions & 21 deletions packages/tools/lib/css-processors/css-processor-themes.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,28 @@ import { writeFileIfChanged, getFileContent } from "./shared.mjs";
import { scopeUi5Variables, scopeThemingVariables } from "./scope-variables.mjs";
import { pathToFileURL } from "url";

async function processThemingPackageFile(f) {
async function processThemingPackageFile(f, scope = true) {
const selector = ':root';
const newRule = postcss.rule({ selector });
const result = await postcss().process(f.text);

result.root.walkRules(selector, rule => {
for (const decl of rule.nodes) {
if (decl.type !== 'decl' ) {
if (decl.type !== 'decl') {
continue;
} else if (decl.prop.startsWith('--sapFontUrl')) {
continue;
} else if (!decl.prop.startsWith('--sap')) {
newRule.append(decl.clone());
} else {
const originalProp = decl.prop;
const originalValue = decl.value;

newRule.append(decl.clone({ prop: originalProp.replace("--sap", "--ui5-sap"), value: `var(${originalProp}, ${originalValue})` }));
if (scope) {
const originalProp = decl.prop;
const originalValue = decl.value;

newRule.append(decl.clone({ prop: originalProp.replace("--sap", "--ui5-sap"), value: `var(${originalProp}, ${originalValue})` }));
} else {
newRule.append(decl.clone());
}
}
}
});
Expand All @@ -43,6 +47,24 @@ async function processComponentPackageFile(f, packageJSON) {

return result;
}
async function writeProcessedContent(basePath, content, packageJSON, extension) {
const cssPath = basePath;
const jsonPath = basePath.replace(/dist[\/\\]css/, "dist/generated/assets").replace(".css", ".css.json");
const jsPath = basePath.replace(/dist[\/\\]css/, "src/generated/").replace(".css", extension);

// Write CSS file
await mkdir(path.dirname(cssPath), { recursive: true });
await writeFile(cssPath, content);

// Write JSON file
await mkdir(path.dirname(jsonPath), { recursive: true });
await writeFileIfChanged(jsonPath, JSON.stringify(content));

// Write JS/TS file
const jsContent = getFileContent(packageJSON.name, `\`${content}\``);
await mkdir(path.dirname(jsPath), { recursive: true });
await writeFileIfChanged(jsPath, jsContent);
}

async function generate(argv) {
const tsMode = process.env.UI5_TS === "true";
Expand All @@ -55,27 +77,27 @@ async function generate(argv) {
]);
const restArgs = argv.slice(2);

let scopingPlugin = {
const scopingPlugin = {
name: 'scoping',
setup(build) {
build.initialOptions.write = false;

build.onEnd(result => {
result.outputFiles.forEach(async f => {
let newText = f.path.includes("packages/theming") ? await processThemingPackageFile(f) : await processComponentPackageFile(f, packageJSON);

await mkdir(path.dirname(f.path), { recursive: true });
writeFile(f.path, newText);

// JSON
const jsonPath = f.path.replace(/dist[\/\\]css/, "dist/generated/assets").replace(".css", ".css.json");
await mkdir(path.dirname(jsonPath), { recursive: true });
writeFileIfChanged(jsonPath, JSON.stringify(newText));

// JS/TS
const jsPath = f.path.replace(/dist[\/\\]css/, "src/generated/").replace(".css", extension);
const jsContent = getFileContent(packageJSON.name, "\`" + newText + "\`");
writeFileIfChanged(jsPath, jsContent);
if (f.path.includes("packages/theming")) {
const scopedText = await processThemingPackageFile(f);
const originalText = await processThemingPackageFile(f, false);

// Write scoped version
await writeProcessedContent(f.path, scopedText, packageJSON, extension);

// Write raw version
const originalPath = f.path.replace(/parameters-bundle.css$/, "parameters-bundle-raw.css");
await writeProcessedContent(originalPath, originalText, packageJSON, extension);
} else {
const processedText = await processComponentPackageFile(f, packageJSON);
await writeProcessedContent(f.path, processedText, packageJSON, extension);
}
});
})
},
Expand Down
Loading
Loading