SAP / ui5-webcomponents

UI5 Web Components - the enterprise-flavored sugar on top of native APIs! Build SAP Fiori user interfaces with the technology of your choice.
https://sap.github.io/ui5-webcomponents/
Apache License 2.0
1.5k stars 260 forks source link

Theme: can not be set #7998

Closed kamiyubidan closed 9 months ago

kamiyubidan commented 9 months ago

Bug Description

This may be a duplicate of #7970, where the theme is not being set correctly.

However, I am also using importmaps (https://github.com/WICG/import-maps) and no build step, which may be partially causing the first error.

I tried to trace the code and found the sap.ui.require function but could not find a corresponding import statement to account for the 'dynamically imported module' in the MIME type checking error. I was guessing it might be resolved with an extension check and import assert.

Error 1:

import '@ui5/webcomponents/dist/Assets.js'
import { setTheme } from '@ui5/webcomponents-base/dist/config/Theme.js'
setTheme('sap_fiori_3_dark')

image

Error 2:

import { setTheme } from '@ui5/webcomponents-base/dist/config/Theme.js'
setTheme('sap_fiori_3_dark')

image

Thanks for your time.

Affected Component

Theme

Expected Behaviour

No response

Isolated Example

No response

Steps to Reproduce

No response

Log Output, Stack Trace or Screenshots

No response

Priority

Low

UI5 Web Components Version

1.20.1

Browser

Chrome

Operating System

Windows

Additional Context

No response

Organization

No response

Declaration

pskelin commented 9 months ago

Hi @kamiyubidan , the .json imports which are coming from the import '@ui5/webcomponents/dist/Assets.js' are meant to be handled by a bundler, like for example vitejs that we have documented in our getting started guide.

I have a workaround for import maps, but this use case is really meant more for development where not all features are expected. I suggest you switch to a bundler, it's really easy.

Now to the issue, as the .json files cannot be imported (vitejs creates a .js file with the content), we have provided the same styles as a .js files like here: https://unpkg.com/@ui5/webcomponents-theming@1.20.1/dist/generated/themes/sap_horizon/parameters-bundle.css.js

Now you can import this file to get the styles, but you have to register them manually. This is done by calling registerThemePropertiesLoader and providing a function that returns the result (you can put a dynamic import in this function).

here is the full example:

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>Button</title>
</head>

<body class="button1auto">
    <ui5-button>Hello</ui5-button>
    <script type="importmap">
        {
            "imports": {
            "@ui5/webcomponents/": "https://unpkg.com/@ui5/webcomponents@1.20.1/",
            "@ui5/webcomponents-base/": "https://unpkg.com/@ui5/webcomponents-base@1.20.1/",
            "@ui5/webcomponents-localization/": "https://unpkg.com/@ui5/webcomponents-localization@1.20.1/",
            "@ui5/webcomponents-theming/": "https://unpkg.com/@ui5/webcomponents-theming@1.20.1/",
            "@ui5/webcomponents-icons/": "https://unpkg.com/@ui5/webcomponents-icons@1.20.1/",
            "lit-html": "https://unpkg.com/lit-html#@2.0.1",
            "lit-html/directives/repeat.js": "https://unpkg.com/lit-html@2.0.1/directives/repeat.js",
            "lit-html/directives/class-map.js": "https://unpkg.com/lit-html@2.0.1/directives/class-map.js",
            "lit-html/directives/if-defined.js": "https://unpkg.com/lit-html@2.0.1/directives/if-defined.js",
            "lit-html/directives/unsafe-html.js": "https://unpkg.com/lit-html@2.0.1/directives/unsafe-html.js",
            "lit-html/directive.js": "https://unpkg.com/lit-html@2.0.1/directive.js"
            }
        }
    </script>
    <script type="module">
        import { setTheme } from '@ui5/webcomponents-base/dist/config/Theme.js'
        import { registerThemePropertiesLoader} from "@ui5/webcomponents-base/dist/asset-registries/Themes.js"

        // import .css content as .js modules
        import styles from "@ui5/webcomponents-theming/dist/generated/themes/sap_fiori_3_dark/parameters-bundle.css.js"
        import stylesMain from "@ui5/webcomponents/dist/generated/themes/sap_fiori_3_dark/parameters-bundle.css.js"

        // tell the framework which styles to use for each package/theme combination
        registerThemePropertiesLoader("@ui5/webcomponents-theming", "sap_fiori_3_dark", () => { return styles; });
        registerThemePropertiesLoader("@ui5/webcomponents", "sap_fiori_3_dark", () => { return stylesMain; });

        import "@ui5/webcomponents/dist/Button.js";
        setTheme('sap_fiori_3_dark')
    </script>
</body>
</html>

You will also need to set the background of the page, you can use this:

background-color: var(--sapBackgroundColor);

You will have to do this for all themes and languages for each package and for the icons as well. All of these imports are generated and used with a bundler when you import Assets.js.

pskelin commented 9 months ago

One more thing, we have considered adding an import assertion for json files, but this is not supported everywhere yet.

It will look like this:

const jsonModule = await import('./foo.json', {
  assert: { type: 'json' }
});

and will work for Chrome and Edge. Unfortunately it doesn't work for the other browsers yet. https://caniuse.com/mdn-javascript_statements_import_import_attribues_assert_type_json

kamiyubidan commented 9 months ago

@pskelin Thank you very much for taking the time to provide a complete, working solution. I really appreciate it.