diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/AbstractUpdateImports.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/AbstractUpdateImports.java
index 135d973d582..48a4760e1a8 100644
--- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/AbstractUpdateImports.java
+++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/AbstractUpdateImports.java
@@ -71,14 +71,15 @@ abstract class AbstractUpdateImports implements Runnable {
+ " document.head[before ? 'insertBefore' : 'appendChild'](tpl.content, document.head.firstChild);\n"
+ "};";
- private static final String CSS_IMPORT = "import $css_%d from '%s';";
+ private static final String CSS_IMPORT = "import $cssFromFile_%d from '%s';%n" //
+ + "const $css_%1$d = typeof $cssFromFile_%1$d === 'string' ? unsafeCSS($cssFromFile_%1$d) : $cssFromFile_%1$d;";
private static final String CSS_PRE = CSS_IMPORT + "%n" + "addCssBlock(`";
private static final String CSS_POST = "`);";
private static final String CSS_BASIC_TPL = CSS_PRE
- + "" + CSS_POST;
- private static final String THEMABLE_MIXIN_IMPORT = "import { css, registerStyles } from '@vaadin/vaadin-themable-mixin';";
+ + "" + CSS_POST;
+ private static final String THEMABLE_MIXIN_IMPORT = "import { css, unsafeCSS, registerStyles } from '@vaadin/vaadin-themable-mixin';";
private static final String REGISTER_STYLES_FOR_TEMPLATE = CSS_IMPORT + "%n"
- + "registerStyles('%s', css`${$css_%d}`%s);";
+ + "registerStyles('%s', $css_%1$d%s);";
private static final String IMPORT_TEMPLATE = "import '%s';";
@@ -513,13 +514,13 @@ private boolean addCssLines(Collection lines, CssData cssData,
? cssData.getThemefor()
: "";
addLines(lines, String.format(REGISTER_STYLES_FOR_TEMPLATE, i,
- cssImport, themeFor, i, optionals));
+ cssImport, themeFor, optionals));
} else {
String include = cssData.getInclude() != null
? " include=\"" + cssData.getInclude() + "\""
: "";
addLines(lines,
- String.format(CSS_BASIC_TPL, i, cssImport, include, i));
+ String.format(CSS_BASIC_TPL, i, cssImport, include));
}
return found;
}
diff --git a/flow-server/src/test/java/com/vaadin/flow/server/frontend/AbstractNodeUpdateImportsTest.java b/flow-server/src/test/java/com/vaadin/flow/server/frontend/AbstractNodeUpdateImportsTest.java
index 3f200cb5607..adc90c169b1 100644
--- a/flow-server/src/test/java/com/vaadin/flow/server/frontend/AbstractNodeUpdateImportsTest.java
+++ b/flow-server/src/test/java/com/vaadin/flow/server/frontend/AbstractNodeUpdateImportsTest.java
@@ -122,27 +122,26 @@ public void generateImportsFile_fileContainsThemeLinesAndExpectedImportsAndCssIm
expectedLines.add("import 'unresolved/component';");
expectedLines.add(
- "import $css_0 from '@vaadin/vaadin-mixed-component/bar.css'");
- expectedLines.add("import $css_1 from 'Frontend/foo.css';");
- expectedLines.add("import $css_2 from 'Frontend/foo.css';");
- expectedLines.add("import $css_3 from 'Frontend/foo.css';");
- expectedLines.add("import $css_4 from 'Frontend/foo.css';");
- expectedLines.add("import $css_5 from 'Frontend/foo.css';");
- expectedLines.add("import $css_6 from 'Frontend/foo.css';");
+ "import $cssFromFile_0 from '@vaadin/vaadin-mixed-component/bar.css'");
+ expectedLines.add("import $cssFromFile_1 from 'Frontend/foo.css';");
+ expectedLines.add("import $cssFromFile_2 from 'Frontend/foo.css';");
+ expectedLines.add("import $cssFromFile_3 from 'Frontend/foo.css';");
+ expectedLines.add("import $cssFromFile_4 from 'Frontend/foo.css';");
+ expectedLines.add("import $cssFromFile_5 from 'Frontend/foo.css';");
+ expectedLines.add("import $cssFromFile_6 from 'Frontend/foo.css';");
expectedLines.add(
- "import { css, registerStyles } from '@vaadin/vaadin-themable-mixin';");
+ "import { css, unsafeCSS, registerStyles } from '@vaadin/vaadin-themable-mixin';");
expectedLines.add("addCssBlock(``);");
expectedLines.add("addCssBlock(``);");
expectedLines.add(
"addCssBlock(``);");
- expectedLines
- .add("registerStyles('', css`${$css_3}`, {moduleId: 'baz'});");
+ expectedLines.add("registerStyles('', $css_3, {moduleId: 'baz'});");
expectedLines.add(
- "registerStyles('', css`${$css_4}`, {include: 'bar', moduleId: 'baz'});");
+ "registerStyles('', $css_4, {include: 'bar', moduleId: 'baz'});");
expectedLines.add(
- "registerStyles('foo-bar', css`${$css_5}`, {moduleId: 'flow_css_mod'});");
+ "registerStyles('foo-bar', $css_5, {moduleId: 'flow_css_mod'});");
expectedLines.add(
- "registerStyles('foo-bar', css`${$css_6}`, {include: 'bar', moduleId: 'flow_css_mod'});");
+ "registerStyles('foo-bar', $css_6, {include: 'bar', moduleId: 'flow_css_mod'});");
assertFalse(importsFile.exists());
diff --git a/flow-server/src/test/java/com/vaadin/flow/server/frontend/AbstractUpdateImportsTest.java b/flow-server/src/test/java/com/vaadin/flow/server/frontend/AbstractUpdateImportsTest.java
index ca5add6696b..021b5cd65eb 100644
--- a/flow-server/src/test/java/com/vaadin/flow/server/frontend/AbstractUpdateImportsTest.java
+++ b/flow-server/src/test/java/com/vaadin/flow/server/frontend/AbstractUpdateImportsTest.java
@@ -308,25 +308,24 @@ public void generateLines_resultingLinesContainsThemeLinesAndExpectedImportsAndC
expectedLines.add("import 'unresolved/component';");
expectedLines.add(
- "import $css_0 from '@vaadin/vaadin-mixed-component/bar.css';");
- expectedLines.add("import $css_1 from 'Frontend/foo.css';");
- expectedLines.add("import $css_2 from 'Frontend/foo.css';");
- expectedLines.add("import $css_3 from 'Frontend/foo.css';");
- expectedLines.add("import $css_4 from 'Frontend/foo.css';");
- expectedLines.add("import $css_5 from 'Frontend/foo.css';");
- expectedLines.add("import $css_6 from 'Frontend/foo.css';");
+ "import $cssFromFile_0 from '@vaadin/vaadin-mixed-component/bar.css';");
+ expectedLines.add("import $cssFromFile_1 from 'Frontend/foo.css';");
+ expectedLines.add("import $cssFromFile_2 from 'Frontend/foo.css';");
+ expectedLines.add("import $cssFromFile_3 from 'Frontend/foo.css';");
+ expectedLines.add("import $cssFromFile_4 from 'Frontend/foo.css';");
+ expectedLines.add("import $cssFromFile_5 from 'Frontend/foo.css';");
+ expectedLines.add("import $cssFromFile_6 from 'Frontend/foo.css';");
expectedLines.add("addCssBlock(``);");
expectedLines.add("addCssBlock(``);");
expectedLines.add(
"addCssBlock(``);");
- expectedLines
- .add("registerStyles('', css`${$css_3}`, {moduleId: 'baz'});");
+ expectedLines.add("registerStyles('', $css_3, {moduleId: 'baz'});");
expectedLines.add(
- "registerStyles('', css`${$css_4}`, {include: 'bar', moduleId: 'baz'});");
+ "registerStyles('', $css_4, {include: 'bar', moduleId: 'baz'});");
expectedLines.add(
- "registerStyles('foo-bar', css`${$css_5}`, {moduleId: 'flow_css_mod'});");
+ "registerStyles('foo-bar', $css_5, {moduleId: 'flow_css_mod'});");
expectedLines.add(
- "registerStyles('foo-bar', css`${$css_6}`, {include: 'bar', moduleId: 'flow_css_mod'});");
+ "registerStyles('foo-bar', $css_6, {include: 'bar', moduleId: 'flow_css_mod'});");
expectedLines.add("import 'generated-modules-foo';");
expectedLines.add("import 'generated-modules-bar';");
diff --git a/flow-server/src/test/java/com/vaadin/flow/server/frontend/NodeUpdateImportsTest.java b/flow-server/src/test/java/com/vaadin/flow/server/frontend/NodeUpdateImportsTest.java
index 8c486c8e8dc..ba0e514986b 100644
--- a/flow-server/src/test/java/com/vaadin/flow/server/frontend/NodeUpdateImportsTest.java
+++ b/flow-server/src/test/java/com/vaadin/flow/server/frontend/NodeUpdateImportsTest.java
@@ -148,14 +148,14 @@ Logger log() {
// Contains CSS import lines
MatcherAssert.assertThat(mainContent, CoreMatchers.containsString(
- "import $css_0 from '@vaadin/vaadin-mixed-component/bar.css';"));
+ "import $cssFromFile_0 from '@vaadin/vaadin-mixed-component/bar.css';"));
MatcherAssert.assertThat(mainContent, CoreMatchers
.containsString("addCssBlock(``);"));
- MatcherAssert.assertThat(mainContent, CoreMatchers
- .containsString("import $css_5 from 'Frontend/foo.css';"));
MatcherAssert.assertThat(mainContent, CoreMatchers.containsString(
- "registerStyles('foo-bar', css`${$css_5}`, {moduleId: 'flow_css_mod'});"));
+ "import $cssFromFile_5 from 'Frontend/foo.css';"));
+ MatcherAssert.assertThat(mainContent, CoreMatchers.containsString(
+ "registerStyles('foo-bar', $css_5, {moduleId: 'flow_css_mod'});"));
// Contains theme imports
MatcherAssert.assertThat(mainContent, CoreMatchers.containsString(
@@ -201,17 +201,17 @@ Logger log() {
// Does not contains CSS import lines
MatcherAssert.assertThat(fallBackContent,
CoreMatchers.not(CoreMatchers.containsString(
- "import $css_0 from '@vaadin/vaadin-mixed-component/bar.css';")));
+ "import $cssFromFile_0 from '@vaadin/vaadin-mixed-component/bar.css';")));
// Contain lines to import exported modules from main file
MatcherAssert.assertThat(fallBackContent, CoreMatchers.containsString(
"export const addCssBlock = function(block, before = false) {"));
// Contains CSS import lines from CP not discovered by byte scanner
- MatcherAssert.assertThat(fallBackContent, CoreMatchers
- .containsString("import $css_0 from 'Frontend/b-css.css';"));
MatcherAssert.assertThat(fallBackContent, CoreMatchers.containsString(
- "registerStyles('extra-foo', css`${$css_2}`, {include: 'extra-bar', moduleId: 'fallback_flow_css_mod'});"));
+ "import $cssFromFile_0 from 'Frontend/b-css.css';"));
+ MatcherAssert.assertThat(fallBackContent, CoreMatchers.containsString(
+ "registerStyles('extra-foo', $css_2, {include: 'extra-bar', moduleId: 'fallback_flow_css_mod'});"));
// Does not contains JS module imports
MatcherAssert.assertThat(fallBackContent, CoreMatchers.not(CoreMatchers
@@ -303,10 +303,10 @@ Logger log() {
// Contains CSS import lines from CP not discovered by byte
// scanner
- MatcherAssert.assertThat(fallBackContent, CoreMatchers
- .containsString("import $css_0 from 'Frontend/foo.css';"));
MatcherAssert.assertThat(fallBackContent, CoreMatchers.containsString(
- "registerStyles('', css`${$css_0}`, {include: 'bar', moduleId: 'baz'});"));
+ "import $cssFromFile_0 from 'Frontend/foo.css';"));
+ MatcherAssert.assertThat(fallBackContent, CoreMatchers.containsString(
+ "registerStyles('', $css_0, {include: 'bar', moduleId: 'baz'});"));
// Contains JS module imports
MatcherAssert.assertThat(fallBackContent, CoreMatchers.containsString(
diff --git a/flow-tests/test-application-theme/test-theme-component-live-reload/src/main/java/com/vaadin/flow/uitest/ui/ComponentThemeLiveReloadView.java b/flow-tests/test-application-theme/test-theme-component-live-reload/src/main/java/com/vaadin/flow/uitest/ui/ComponentThemeLiveReloadView.java
index e1160d0d58d..1d0cf14ed70 100644
--- a/flow-tests/test-application-theme/test-theme-component-live-reload/src/main/java/com/vaadin/flow/uitest/ui/ComponentThemeLiveReloadView.java
+++ b/flow-tests/test-application-theme/test-theme-component-live-reload/src/main/java/com/vaadin/flow/uitest/ui/ComponentThemeLiveReloadView.java
@@ -23,6 +23,7 @@
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.uitest.servlet.ViewTestLayout;
+import com.vaadin.flow.uitest.ui.dependencies.ThemableTextField;
@Route(value = "com.vaadin.flow.uitest.ui.ComponentThemeLiveReloadView", layout = ViewTestLayout.class)
public class ComponentThemeLiveReloadView extends Div {
@@ -35,7 +36,7 @@ public class ComponentThemeLiveReloadView extends Div {
private final Span attachIdLabel = new Span();
public ComponentThemeLiveReloadView() {
- TestThemedTextField testThemedTextField = new TestThemedTextField();
+ ThemableTextField testThemedTextField = new ThemableTextField();
testThemedTextField.withId(THEMED_COMPONENT_ID);
add(testThemedTextField);
diff --git a/flow-tests/test-frontend/vite-basics/frontend/cssimport-textfield.css b/flow-tests/test-frontend/vite-basics/frontend/cssimport-textfield.css
new file mode 100644
index 00000000000..2348e1905fd
--- /dev/null
+++ b/flow-tests/test-frontend/vite-basics/frontend/cssimport-textfield.css
@@ -0,0 +1,3 @@
+:host {
+ background: rgb(173, 216, 230);
+}
diff --git a/flow-tests/test-frontend/vite-basics/frontend/cssimport.css b/flow-tests/test-frontend/vite-basics/frontend/cssimport.css
new file mode 100644
index 00000000000..a0e63db4a85
--- /dev/null
+++ b/flow-tests/test-frontend/vite-basics/frontend/cssimport.css
@@ -0,0 +1,3 @@
+body {
+ background: rgb(211, 211, 211);
+}
diff --git a/flow-tests/test-frontend/vite-basics/package.json b/flow-tests/test-frontend/vite-basics/package.json
index 4446788546b..13f5406b430 100644
--- a/flow-tests/test-frontend/vite-basics/package.json
+++ b/flow-tests/test-frontend/vite-basics/package.json
@@ -10,13 +10,15 @@
"@vaadin/flow-frontend": "./target/flow-frontend",
"@vaadin/router": "1.7.4",
"@vaadin/vaadin-lumo-styles": "22.0.0-alpha9",
+ "@vaadin/vaadin-text-field": "22.0.0-alpha9",
"construct-style-sheets-polyfill": "3.0.4",
"copy-to-clipboard": "^3.3.1",
- "lit": "2.0.0",
+ "lit": "2.1.4",
"package-outside-npm": "file:package-outside-npm",
"package2-outside-npm": "./package2-outside-npm"
},
"devDependencies": {
+ "@rollup/plugin-replace": "3.1.0",
"@vaadin/application-theme-plugin": "./target/plugins/application-theme-plugin",
"@vaadin/build-status-plugin": "./target/plugins/build-status-plugin",
"@vaadin/theme-live-reload-plugin": "./target/plugins/theme-live-reload-plugin",
@@ -37,10 +39,12 @@
"@vaadin/common-frontend": "0.0.17",
"@vaadin/router": "1.7.4",
"@vaadin/vaadin-lumo-styles": "22.0.0-alpha9",
+ "@vaadin/vaadin-text-field": "22.0.0-alpha9",
"construct-style-sheets-polyfill": "3.0.4",
- "lit": "2.0.0"
+ "lit": "2.1.4"
},
"devDependencies": {
+ "@rollup/plugin-replace": "3.1.0",
"glob": "7.1.6",
"mkdirp": "1.0.4",
"rollup-plugin-brotli": "3.1.0",
@@ -51,6 +55,30 @@
"workbox-core": "6.4.2",
"workbox-precaching": "6.4.2"
},
- "hash": "1fbd15f1fc5035e3b4c52bd7b61168316b3b8ea359e30c73c01d39373962b5da"
+ "hash": "a7eca1c52a990494443679351b12088160f1fb9f37356bbfe42416b751e63a60"
+ },
+ "overrides": {
+ "@polymer/polymer": "$@polymer/polymer",
+ "@testscope/all": "$@testscope/all",
+ "@testscope/button": "$@testscope/button",
+ "@vaadin/bundles": "$@vaadin/bundles",
+ "@vaadin/common-frontend": "$@vaadin/common-frontend",
+ "@vaadin/router": "$@vaadin/router",
+ "@vaadin/vaadin-lumo-styles": "$@vaadin/vaadin-lumo-styles",
+ "construct-style-sheets-polyfill": "$construct-style-sheets-polyfill",
+ "copy-to-clipboard": "$copy-to-clipboard",
+ "lit": "$lit",
+ "package-outside-npm": "$package-outside-npm",
+ "package2-outside-npm": "$package2-outside-npm",
+ "glob": "$glob",
+ "mkdirp": "$mkdirp",
+ "rollup-plugin-brotli": "$rollup-plugin-brotli",
+ "typescript": "$typescript",
+ "vite": "$vite",
+ "vite-plugin-checker": "$vite-plugin-checker",
+ "workbox-build": "$workbox-build",
+ "workbox-core": "$workbox-core",
+ "workbox-precaching": "$workbox-precaching",
+ "@rollup/plugin-replace": "$@rollup/plugin-replace"
}
}
diff --git a/flow-tests/test-frontend/vite-basics/src/main/java/com/vaadin/viteapp/views/empty/MainView.java b/flow-tests/test-frontend/vite-basics/src/main/java/com/vaadin/viteapp/views/empty/MainView.java
index 405d0849bcd..ac14f30ae3f 100644
--- a/flow-tests/test-frontend/vite-basics/src/main/java/com/vaadin/viteapp/views/empty/MainView.java
+++ b/flow-tests/test-frontend/vite-basics/src/main/java/com/vaadin/viteapp/views/empty/MainView.java
@@ -1,10 +1,9 @@
package com.vaadin.viteapp.views.empty;
import com.vaadin.experimental.FeatureFlags;
-import com.vaadin.flow.component.Component;
-import com.vaadin.flow.component.Html;
import com.vaadin.flow.component.HtmlComponent;
import com.vaadin.flow.component.UI;
+import com.vaadin.flow.component.dependency.CssImport;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.H2;
@@ -12,12 +11,15 @@
import com.vaadin.flow.component.html.NativeButton;
import com.vaadin.flow.component.html.Paragraph;
import com.vaadin.flow.router.Route;
+import com.vaadin.flow.uitest.ui.dependencies.ThemableTextField;
@Route("")
@JsModule("./jsonloader.js")
@JsModule("package-outside-npm/index.js")
@JsModule("package2-outside-npm/index.js")
@JsModule("./testscopebuttonloader.js")
+@CssImport(value = "./cssimport-textfield.css", themeFor = "vaadin-text-field")
+@CssImport(value = "./cssimport.css")
public class MainView extends Div {
public static final String LOAD_AND_SHOW_JSON = "loadAndShowJson";
@@ -75,6 +77,9 @@ public MainView() {
add(outsideStatus);
add(new HtmlComponent("testscope-button"));
+ ThemableTextField textField = new ThemableTextField();
+ textField.setId("themedfield");
+ add(textField);
}
}
diff --git a/flow-tests/test-frontend/vite-basics/src/test/java/com/vaadin/viteapp/ThemeIT.java b/flow-tests/test-frontend/vite-basics/src/test/java/com/vaadin/viteapp/ThemeIT.java
index 398cc7967a2..b1723cac803 100644
--- a/flow-tests/test-frontend/vite-basics/src/test/java/com/vaadin/viteapp/ThemeIT.java
+++ b/flow-tests/test-frontend/vite-basics/src/test/java/com/vaadin/viteapp/ThemeIT.java
@@ -24,4 +24,18 @@ public void themeStylesShouldNotBeAddedToHead() {
Assert.assertEquals("Theme rule should not have been added to ",
0, styleTagsWithString.size());
}
+
+ @Test
+ public void cssImportAnnotation() {
+ String bodyBackground = (String) executeScript(
+ "return getComputedStyle(document.body).backgroundColor");
+ Assert.assertEquals("rgb(211, 211, 211)", bodyBackground);
+ }
+
+ @Test
+ public void cssImportAnnotationForComponent() {
+ String fieldBackground = (String) executeScript(
+ "return getComputedStyle(document.querySelector('#themedfield')).backgroundColor");
+ Assert.assertEquals("rgb(173, 216, 230)", fieldBackground);
+ }
}
diff --git a/flow-tests/test-frontend/vite-test-assets/pom.xml b/flow-tests/test-frontend/vite-test-assets/pom.xml
index a58e4876528..9ecb0cfe69c 100644
--- a/flow-tests/test-frontend/vite-test-assets/pom.xml
+++ b/flow-tests/test-frontend/vite-test-assets/pom.xml
@@ -59,6 +59,11 @@
com.vaadin
flow-html-components-testbench
+
+ com.vaadin
+ flow-test-resources
+ ${project.version}
+
com.vaadin
addon-with-templates
diff --git a/flow-tests/test-application-theme/test-theme-component-live-reload/src/main/java/com/vaadin/flow/uitest/ui/TestThemedTextField.java b/flow-tests/test-resources/src/main/java/com/vaadin/flow/uitest/ui/dependencies/ThemableTextField.java
similarity index 83%
rename from flow-tests/test-application-theme/test-theme-component-live-reload/src/main/java/com/vaadin/flow/uitest/ui/TestThemedTextField.java
rename to flow-tests/test-resources/src/main/java/com/vaadin/flow/uitest/ui/dependencies/ThemableTextField.java
index 89145e685d8..ec56d8b8ad3 100644
--- a/flow-tests/test-application-theme/test-theme-component-live-reload/src/main/java/com/vaadin/flow/uitest/ui/TestThemedTextField.java
+++ b/flow-tests/test-resources/src/main/java/com/vaadin/flow/uitest/ui/dependencies/ThemableTextField.java
@@ -13,22 +13,20 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
-package com.vaadin.flow.uitest.ui;
+package com.vaadin.flow.uitest.ui.dependencies;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.dependency.NpmPackage;
-import com.vaadin.flow.uitest.ui.dependencies.TestVersion;
-
/**
- * Custom vaadin text field for testing component theming live reload.
+ * Custom vaadin text field for testing component theming.
*/
@JsModule("@vaadin/vaadin-text-field/vaadin-text-field.js")
@Tag("vaadin-text-field")
@NpmPackage(value = "@vaadin/vaadin-text-field", version = TestVersion.VAADIN)
-public class TestThemedTextField extends Component {
+public class ThemableTextField extends Component {
/**
* Set the component id.