diff --git a/packages/plugin-postcss/package.json b/packages/plugin-postcss/package.json
index fa8a94c8b..252601b1a 100644
--- a/packages/plugin-postcss/package.json
+++ b/packages/plugin-postcss/package.json
@@ -32,6 +32,7 @@
"postcss-preset-env": "^7.0.1"
},
"devDependencies": {
- "@greenwood/cli": "^0.31.0-alpha.1"
+ "@greenwood/cli": "^0.31.0-alpha.1",
+ "@spectrum-css/typography": "^6.2.0"
}
}
diff --git a/packages/plugin-postcss/src/index.js b/packages/plugin-postcss/src/index.js
index 25e9bc241..05bde0f0d 100644
--- a/packages/plugin-postcss/src/index.js
+++ b/packages/plugin-postcss/src/index.js
@@ -35,7 +35,6 @@ class PostCssResource extends ResourceInterface {
async shouldPreIntercept(url, request, response) {
return url.protocol === 'file:'
- && url.pathname.split('.').pop() === this.extensions[0]
&& (request?.headers?.get('Content-Type')?.includes('text/css') || response?.headers?.get('Content-Type')?.includes('text/css'));
}
@@ -47,7 +46,11 @@ class PostCssResource extends ResourceInterface {
? (await postcss(plugins).process(body, { from: normalizePathnameForWindows(url) })).css
: body;
- return new Response(css);
+ // preserve original headers (content type / accept)
+ // since this could be used in JS or CSS contexts
+ return new Response(css, {
+ headers: response.headers
+ });
}
}
diff --git a/packages/plugin-postcss/test/cases/loaders-default.import-attributes/greenwood.config.js b/packages/plugin-postcss/test/cases/loaders-default.import-attributes/greenwood.config.js
new file mode 100644
index 000000000..8180684f6
--- /dev/null
+++ b/packages/plugin-postcss/test/cases/loaders-default.import-attributes/greenwood.config.js
@@ -0,0 +1,8 @@
+import { greenwoodPluginPostCss } from '../../../src/index.js';
+
+export default {
+ prerender: true,
+ plugins: [
+ greenwoodPluginPostCss()
+ ]
+};
\ No newline at end of file
diff --git a/packages/plugin-postcss/test/cases/loaders-default.import-attributes/loaders-default.import-attributes.spec.js b/packages/plugin-postcss/test/cases/loaders-default.import-attributes/loaders-default.import-attributes.spec.js
new file mode 100644
index 000000000..2f1562e86
--- /dev/null
+++ b/packages/plugin-postcss/test/cases/loaders-default.import-attributes/loaders-default.import-attributes.spec.js
@@ -0,0 +1,89 @@
+/*
+ * Use Case
+ * Run Greenwood with default PostCSS config when using Import Attributes.
+ *
+ * User Result
+ * Should generate a bare bones Greenwood build with the user's CSS file correctly minified.
+ *
+ * User Command
+ * greenwood build
+ *
+ * User Config
+ * const pluginPostCss = require('@greenwood/plugin-postcss');
+ *
+ * {
+ * plugins: [
+ * pluginPostCss()
+ * ]
+ * }
+ *
+ * User Workspace
+ * src/
+ * components/
+ * header/
+ * header.js
+ * header.css
+ * pages/
+ * index.html
+ * styles/
+ * theme.css
+ */
+import chai from 'chai';
+import fs from 'fs';
+import glob from 'glob-promise';
+import path from 'path';
+import { runSmokeTest } from '../../../../../test/smoke-test.js';
+import { getOutputTeardownFiles } from '../../../../../test/utils.js';
+import { Runner } from 'gallinago';
+import { fileURLToPath, URL } from 'url';
+
+const expect = chai.expect;
+
+describe('Build Greenwood With: ', function() {
+ const LABEL = 'Default PostCSS configuration and CSS Import Attributes';
+ const cliPath = path.join(process.cwd(), 'packages/cli/src/index.js');
+ const outputPath = fileURLToPath(new URL('.', import.meta.url));
+ let runner;
+
+ before(function() {
+ this.context = {
+ publicDir: path.join(outputPath, 'public')
+ };
+ runner = new Runner(false, true);
+ });
+
+ describe(LABEL, function() {
+
+ before(function() {
+ runner.setup(outputPath);
+ runner.runCommand(cliPath, 'build');
+ });
+
+ runSmokeTest(['public', 'index'], LABEL);
+
+ describe('Page referencing external nested CSS file', function() {
+ it('should output correctly processed nested CSS as non nested', function() {
+ const expectedCss = 'body{color:red}h1{color:blue}';
+ const cssFiles = glob.sync(path.join(this.context.publicDir, 'styles', '*.css'));
+ const css = fs.readFileSync(cssFiles[0], 'utf-8');
+
+ expect(cssFiles.length).to.equal(1);
+ expect(css).to.equal(expectedCss);
+ });
+
+ it('should output correctly processed import attributes in header.js bundle output', function() {
+ const headerFiles = glob.sync(path.join(this.context.publicDir, 'header.*.js'));
+ const js = fs.readFileSync(headerFiles[0], 'utf-8');
+
+ expect(headerFiles.length).to.equal(1);
+ expect(js.indexOf('import e from"/styles/theme.1126086472.css"with{type:"css"};') >= 0).to.equal(true);
+ expect(js.indexOf('import t from"/header.CaS9Xrom.css"with{type:"css"};') >= 0).to.equal(true);
+ expect(js.indexOf('const s=new CSSStyleSheet;s.replaceSync(\'.spectrum{--spectrum-font-family-ar:myriad-arabic') >= 0).to.equal(true);
+ });
+ });
+ });
+
+ after(function() {
+ runner.teardown(getOutputTeardownFiles(outputPath));
+ });
+});
\ No newline at end of file
diff --git a/packages/plugin-postcss/test/cases/loaders-default.import-attributes/src/components/header/header.css b/packages/plugin-postcss/test/cases/loaders-default.import-attributes/src/components/header/header.css
new file mode 100644
index 000000000..eadfef754
--- /dev/null
+++ b/packages/plugin-postcss/test/cases/loaders-default.import-attributes/src/components/header/header.css
@@ -0,0 +1,3 @@
+header {
+ background-color: aqua;
+}
\ No newline at end of file
diff --git a/packages/plugin-postcss/test/cases/loaders-default.import-attributes/src/components/header/header.js b/packages/plugin-postcss/test/cases/loaders-default.import-attributes/src/components/header/header.js
new file mode 100644
index 000000000..567206531
--- /dev/null
+++ b/packages/plugin-postcss/test/cases/loaders-default.import-attributes/src/components/header/header.js
@@ -0,0 +1,24 @@
+import themeSheet from '../../styles/theme.css' with { type: 'css' };
+import headerSheet from './header.css' with { type: 'css' };
+import SpectrumTypography from '@spectrum-css/typography' with { type: 'css' };
+
+export default class Header extends HTMLElement {
+ connectedCallback() {
+ if (!this.shadowRoot) {
+ const template = document.createElement('template');
+
+ template.innerHTML = `
+