diff --git a/.changeset/eight-comics-tell.md b/.changeset/eight-comics-tell.md new file mode 100644 index 0000000000..fa506aba46 --- /dev/null +++ b/.changeset/eight-comics-tell.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +feat: add support for `` diff --git a/packages/svelte/messages/compile-errors/template.md b/packages/svelte/messages/compile-errors/template.md index 4e24714647..7920329c8b 100644 --- a/packages/svelte/messages/compile-errors/template.md +++ b/packages/svelte/messages/compile-errors/template.md @@ -324,7 +324,7 @@ HTML restricts where certain elements can appear. In case of a violation the bro ## svelte_options_invalid_attribute_value -> Valid values are %list% +> Value must be %list%, if specified ## svelte_options_invalid_customelement diff --git a/packages/svelte/src/compiler/errors.js b/packages/svelte/src/compiler/errors.js index 0b91336ee0..958c86a817 100644 --- a/packages/svelte/src/compiler/errors.js +++ b/packages/svelte/src/compiler/errors.js @@ -1275,13 +1275,13 @@ export function svelte_options_invalid_attribute(node) { } /** - * Valid values are %list% + * Value must be %list%, if specified * @param {null | number | NodeLike} node * @param {string} list * @returns {never} */ export function svelte_options_invalid_attribute_value(node, list) { - e(node, "svelte_options_invalid_attribute_value", `Valid values are ${list}`); + e(node, "svelte_options_invalid_attribute_value", `Value must be ${list}, if specified`); } /** diff --git a/packages/svelte/src/compiler/phases/1-parse/read/options.js b/packages/svelte/src/compiler/phases/1-parse/read/options.js index 751fe5f672..7c83946336 100644 --- a/packages/svelte/src/compiler/phases/1-parse/read/options.js +++ b/packages/svelte/src/compiler/phases/1-parse/read/options.js @@ -175,6 +175,17 @@ export default function read_options(node) { break; } + case 'css': { + const value = get_static_value(attribute); + + if (value === 'injected') { + component_options.css = value; + } else { + e.svelte_options_invalid_attribute_value(attribute, `"injected"`); + } + + break; + } case 'immutable': { component_options.immutable = get_boolean_value(attribute); break; diff --git a/packages/svelte/src/compiler/types/template.d.ts b/packages/svelte/src/compiler/types/template.d.ts index ee6315a98c..373822a873 100644 --- a/packages/svelte/src/compiler/types/template.d.ts +++ b/packages/svelte/src/compiler/types/template.d.ts @@ -75,6 +75,7 @@ export interface SvelteOptions { accessors?: boolean; preserveWhitespace?: boolean; namespace?: Namespace; + css?: 'injected'; customElement?: { tag: string; shadow?: 'open' | 'none'; diff --git a/packages/svelte/tests/server-side-rendering/samples/css-injected-options-nested/Nested.svelte b/packages/svelte/tests/server-side-rendering/samples/css-injected-options-nested/Nested.svelte new file mode 100644 index 0000000000..81243bf114 --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/css-injected-options-nested/Nested.svelte @@ -0,0 +1,9 @@ + + +
bar
+ + diff --git a/packages/svelte/tests/server-side-rendering/samples/css-injected-options-nested/_config.js b/packages/svelte/tests/server-side-rendering/samples/css-injected-options-nested/_config.js new file mode 100644 index 0000000000..286454e931 --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/css-injected-options-nested/_config.js @@ -0,0 +1,7 @@ +import { test } from '../../test'; + +export default test({ + compileOptions: { + css: 'external' + } +}); diff --git a/packages/svelte/tests/server-side-rendering/samples/css-injected-options-nested/_expected.css b/packages/svelte/tests/server-side-rendering/samples/css-injected-options-nested/_expected.css new file mode 100644 index 0000000000..bddefdd00c --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/css-injected-options-nested/_expected.css @@ -0,0 +1,4 @@ + +.foo.svelte-sg04hs { + color: red; +} diff --git a/packages/svelte/tests/server-side-rendering/samples/css-injected-options-nested/_expected.html b/packages/svelte/tests/server-side-rendering/samples/css-injected-options-nested/_expected.html new file mode 100644 index 0000000000..1f0b2b95fe --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/css-injected-options-nested/_expected.html @@ -0,0 +1 @@ +
bar
foo
\ No newline at end of file diff --git a/packages/svelte/tests/server-side-rendering/samples/css-injected-options-nested/_expected_head.html b/packages/svelte/tests/server-side-rendering/samples/css-injected-options-nested/_expected_head.html new file mode 100644 index 0000000000..806f6c2db2 --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/css-injected-options-nested/_expected_head.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/packages/svelte/tests/server-side-rendering/samples/css-injected-options-nested/main.svelte b/packages/svelte/tests/server-side-rendering/samples/css-injected-options-nested/main.svelte new file mode 100644 index 0000000000..a2b9f38de3 --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/css-injected-options-nested/main.svelte @@ -0,0 +1,13 @@ + + + + +
foo
+ + diff --git a/packages/svelte/tests/server-side-rendering/samples/css-injected-options/_config.js b/packages/svelte/tests/server-side-rendering/samples/css-injected-options/_config.js new file mode 100644 index 0000000000..286454e931 --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/css-injected-options/_config.js @@ -0,0 +1,7 @@ +import { test } from '../../test'; + +export default test({ + compileOptions: { + css: 'external' + } +}); diff --git a/packages/svelte/tests/server-side-rendering/samples/css-injected-options/_expected.css b/packages/svelte/tests/server-side-rendering/samples/css-injected-options/_expected.css new file mode 100644 index 0000000000..8882c6ec7e --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/css-injected-options/_expected.css @@ -0,0 +1,4 @@ + + .foo.svelte-sg04hs { + color: red; + } diff --git a/packages/svelte/tests/server-side-rendering/samples/css-injected-options/_expected.html b/packages/svelte/tests/server-side-rendering/samples/css-injected-options/_expected.html new file mode 100644 index 0000000000..8ebe1ad73e --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/css-injected-options/_expected.html @@ -0,0 +1 @@ +
foo
\ No newline at end of file diff --git a/packages/svelte/tests/server-side-rendering/samples/css-injected-options/_expected_head.html b/packages/svelte/tests/server-side-rendering/samples/css-injected-options/_expected_head.html new file mode 100644 index 0000000000..7281935646 --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/css-injected-options/_expected_head.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/packages/svelte/tests/server-side-rendering/samples/css-injected-options/main.svelte b/packages/svelte/tests/server-side-rendering/samples/css-injected-options/main.svelte new file mode 100644 index 0000000000..7387067b9b --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/css-injected-options/main.svelte @@ -0,0 +1,9 @@ + + +
foo
+ + diff --git a/packages/svelte/tests/validator/samples/namespace-invalid/errors.json b/packages/svelte/tests/validator/samples/namespace-invalid/errors.json index ae98ee7e25..bcd2dc1d9c 100644 --- a/packages/svelte/tests/validator/samples/namespace-invalid/errors.json +++ b/packages/svelte/tests/validator/samples/namespace-invalid/errors.json @@ -1,7 +1,7 @@ [ { "code": "svelte_options_invalid_attribute_value", - "message": "Valid values are \"html\", \"mathml\", \"svg\" or \"foreign\"", + "message": "Value must be \"html\", \"mathml\", \"svg\" or \"foreign\", if specified", "start": { "line": 1, "column": 16 diff --git a/packages/svelte/tests/validator/samples/namespace-non-literal/errors.json b/packages/svelte/tests/validator/samples/namespace-non-literal/errors.json index 439dbd032b..d7d637fbb1 100644 --- a/packages/svelte/tests/validator/samples/namespace-non-literal/errors.json +++ b/packages/svelte/tests/validator/samples/namespace-non-literal/errors.json @@ -1,7 +1,7 @@ [ { "code": "svelte_options_invalid_attribute_value", - "message": "Valid values are \"html\", \"mathml\", \"svg\" or \"foreign\"", + "message": "Value must be \"html\", \"mathml\", \"svg\" or \"foreign\", if specified", "start": { "line": 1, "column": 16 diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts index 8ba68e1d2d..8212c52cc0 100644 --- a/packages/svelte/types/index.d.ts +++ b/packages/svelte/types/index.d.ts @@ -1533,6 +1533,7 @@ declare module 'svelte/compiler' { accessors?: boolean; preserveWhitespace?: boolean; namespace?: Namespace; + css?: 'injected'; customElement?: { tag: string; shadow?: 'open' | 'none';