diff --git a/site/content/docs/03-template-syntax.md b/site/content/docs/03-template-syntax.md
index 5d84827494..9afe399469 100644
--- a/site/content/docs/03-template-syntax.md
+++ b/site/content/docs/03-template-syntax.md
@@ -874,6 +874,9 @@ The `style:` directive provides a shorthand for setting multiple styles on an el
...
+
+
+...
```
---
diff --git a/src/compiler/compile/compiler_errors.ts b/src/compiler/compile/compiler_errors.ts
index c1a7d8bc5c..e4d4ffddad 100644
--- a/src/compiler/compile/compiler_errors.ts
+++ b/src/compiler/compile/compiler_errors.ts
@@ -281,5 +281,9 @@ export default {
invalid_component_style_directive: {
code: 'invalid-component-style-directive',
message: 'Style directives cannot be used on components'
- }
+ },
+ invalid_style_directive_modifier: (valid: string) => ({
+ code: 'invalid-style-directive-modifier',
+ message: `Valid modifiers for style directives are: ${valid}`
+ })
};
diff --git a/src/compiler/compile/nodes/StyleDirective.ts b/src/compiler/compile/nodes/StyleDirective.ts
index ea340cf2dc..01af8cc62e 100644
--- a/src/compiler/compile/nodes/StyleDirective.ts
+++ b/src/compiler/compile/nodes/StyleDirective.ts
@@ -1,20 +1,42 @@
import { TemplateNode } from '../../interfaces';
+import list from '../../utils/list';
+import compiler_errors from '../compiler_errors';
import Component from '../Component';
import { nodes_to_template_literal } from '../utils/nodes_to_template_literal';
import Expression from './shared/Expression';
import Node from './shared/Node';
import TemplateScope from './shared/TemplateScope';
+const valid_modifiers = new Set(['important']);
+
export default class StyleDirective extends Node {
type: 'StyleDirective';
name: string;
+ modifiers: Set;
expression: Expression;
should_cache: boolean;
- constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode) {
+ constructor(
+ component: Component,
+ parent: Node,
+ scope: TemplateScope,
+ info: TemplateNode
+ ) {
super(component, parent, scope, info);
this.name = info.name;
+ this.modifiers = new Set(info.modifiers);
+
+ for (const modifier of this.modifiers) {
+ if (!valid_modifiers.has(modifier)) {
+ component.error(
+ this,
+ compiler_errors.invalid_style_directive_modifier(
+ list([...valid_modifiers])
+ )
+ );
+ }
+ }
// Convert the value array to an expression so it's easier to handle
// the StyleDirective going forward.
@@ -34,6 +56,9 @@ export default class StyleDirective extends Node {
this.expression = new Expression(component, this, scope, raw_expression);
this.should_cache = raw_expression.expressions.length > 0;
}
+ }
+ get important() {
+ return this.modifiers.has('important');
}
}
diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts
index 97984748c3..8d0429879e 100644
--- a/src/compiler/compile/render_dom/wrappers/Element/index.ts
+++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts
@@ -1100,7 +1100,7 @@ export default class ElementWrapper extends Wrapper {
add_styles(block: Block) {
const has_spread = this.node.attributes.some(attr => attr.is_spread);
this.node.styles.forEach((style_directive) => {
- const { name, expression, should_cache } = style_directive;
+ const { name, expression, should_cache, important } = style_directive;
const snippet = expression.manipulate(block);
let cached_snippet: Identifier | undefined;
@@ -1109,7 +1109,7 @@ export default class ElementWrapper extends Wrapper {
block.add_variable(cached_snippet, snippet);
}
- const updater = b`@set_style(${this.var}, "${name}", ${should_cache ? cached_snippet : snippet}, false)`;
+ const updater = b`@set_style(${this.var}, "${name}", ${should_cache ? cached_snippet : snippet}, ${important ? 1 : null})`;
block.chunks.hydrate.push(updater);
diff --git a/src/compiler/compile/render_ssr/handlers/Element.ts b/src/compiler/compile/render_ssr/handlers/Element.ts
index 081988b567..f1dd86dd2b 100644
--- a/src/compiler/compile/render_ssr/handlers/Element.ts
+++ b/src/compiler/compile/render_ssr/handlers/Element.ts
@@ -44,7 +44,10 @@ export default function (node: Element, renderer: Renderer, options: RenderOptio
class_expression_list.reduce((lhs, rhs) => x`${lhs} + ' ' + ${rhs}`);
const style_expression_list = node.styles.map(style_directive => {
- const { name, expression: { node: expression } } = style_directive;
+ let { name, important, expression: { node: expression } } = style_directive;
+ if (important) {
+ expression = x`${expression} + ' !important'`;
+ }
return p`"${name}": ${expression}`;
});
diff --git a/src/compiler/parse/state/tag.ts b/src/compiler/parse/state/tag.ts
index bf50c6c774..9d1bf5e5c2 100644
--- a/src/compiler/parse/state/tag.ts
+++ b/src/compiler/parse/state/tag.ts
@@ -395,6 +395,7 @@ function read_attribute(parser: Parser, unique_names: Set) {
end,
type,
name: directive_name,
+ modifiers,
value
};
}
diff --git a/test/parser/samples/attribute-style-directive-modifiers/input.svelte b/test/parser/samples/attribute-style-directive-modifiers/input.svelte
new file mode 100644
index 0000000000..1ec740107d
--- /dev/null
+++ b/test/parser/samples/attribute-style-directive-modifiers/input.svelte
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/test/parser/samples/attribute-style-directive-modifiers/output.json b/test/parser/samples/attribute-style-directive-modifiers/output.json
new file mode 100644
index 0000000000..3c607fb5ea
--- /dev/null
+++ b/test/parser/samples/attribute-style-directive-modifiers/output.json
@@ -0,0 +1,50 @@
+{
+ "html": {
+ "start": 0,
+ "end": 43,
+ "type": "Fragment",
+ "children": [
+ {
+ "start": 0,
+ "end": 43,
+ "type": "Element",
+ "name": "div",
+ "attributes": [
+ {
+ "start": 5,
+ "end": 36,
+ "type": "StyleDirective",
+ "name": "color",
+ "modifiers": [
+ "important"
+ ],
+ "value": [
+ {
+ "start": 27,
+ "end": 36,
+ "type": "MustacheTag",
+ "expression": {
+ "type": "Identifier",
+ "start": 28,
+ "end": 35,
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 28
+ },
+ "end": {
+ "line": 1,
+ "column": 35
+ }
+ },
+ "name": "myColor"
+ }
+ }
+ ]
+ }
+ ],
+ "children": []
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/test/parser/samples/attribute-style-directive-shorthand/output.json b/test/parser/samples/attribute-style-directive-shorthand/output.json
index ac658408e6..80fb4f741f 100644
--- a/test/parser/samples/attribute-style-directive-shorthand/output.json
+++ b/test/parser/samples/attribute-style-directive-shorthand/output.json
@@ -15,6 +15,7 @@
"end": 16,
"type": "StyleDirective",
"name": "color",
+ "modifiers": [],
"value": true
}
],
@@ -22,4 +23,4 @@
}
]
}
-}
\ No newline at end of file
+}
diff --git a/test/parser/samples/attribute-style-directive-string/output.json b/test/parser/samples/attribute-style-directive-string/output.json
index e81e7be3c9..505e9333e1 100644
--- a/test/parser/samples/attribute-style-directive-string/output.json
+++ b/test/parser/samples/attribute-style-directive-string/output.json
@@ -15,6 +15,7 @@
"end": 22,
"type": "StyleDirective",
"name": "color",
+ "modifiers": [],
"value": [
{
"start": 18,
@@ -45,6 +46,7 @@
"start": 35,
"end": 52,
"type": "StyleDirective",
+ "modifiers": [],
"name": "color",
"value": [
{
@@ -77,6 +79,7 @@
"end": 80,
"type": "StyleDirective",
"name": "color",
+ "modifiers": [],
"value": [
{
"start": 77,
@@ -108,6 +111,7 @@
"end": 120,
"type": "StyleDirective",
"name": "color",
+ "modifiers": [],
"value": [
{
"start": 106,
@@ -160,6 +164,7 @@
"end": 160,
"type": "StyleDirective",
"name": "color",
+ "modifiers": [],
"value": [
{
"start": 146,
@@ -212,6 +217,7 @@
"end": 198,
"type": "StyleDirective",
"name": "color",
+ "modifiers": [],
"value": [
{
"start": 185,
@@ -264,6 +270,7 @@
"end": 245,
"type": "StyleDirective",
"name": "color",
+ "modifiers": [],
"value": [
{
"start": 223,
@@ -352,4 +359,4 @@
}
]
}
-}
\ No newline at end of file
+}
diff --git a/test/parser/samples/attribute-style-directive/output.json b/test/parser/samples/attribute-style-directive/output.json
index f36ce6b01e..d80d61bddb 100644
--- a/test/parser/samples/attribute-style-directive/output.json
+++ b/test/parser/samples/attribute-style-directive/output.json
@@ -15,6 +15,7 @@
"end": 26,
"type": "StyleDirective",
"name": "color",
+ "modifiers": [],
"value": [
{
"start": 17,
diff --git a/test/runtime-puppeteer/samples/inline-style-directive-important/_config.js b/test/runtime-puppeteer/samples/inline-style-directive-important/_config.js
new file mode 100644
index 0000000000..d6323b82e3
--- /dev/null
+++ b/test/runtime-puppeteer/samples/inline-style-directive-important/_config.js
@@ -0,0 +1,22 @@
+export default {
+ html: `
+ hello
+ hello
+ `,
+
+ ssrHtml: `
+ hello
+ hello
+ `,
+
+ test({ assert, target, window, component }) {
+ const h1s = target.querySelectorAll('h1');
+
+ assert.equal(window.getComputedStyle(h1s[0])['backgroundColor'], 'rgb(0, 0, 255)');
+ assert.equal(window.getComputedStyle(h1s[1])['backgroundColor'], 'rgb(255, 0, 0)');
+
+ component.color = 'yellow';
+ assert.equal(window.getComputedStyle(h1s[0])['backgroundColor'], 'rgb(0, 0, 255)');
+ assert.equal(window.getComputedStyle(h1s[1])['backgroundColor'], 'rgb(255, 255, 0)');
+ }
+};
diff --git a/test/runtime-puppeteer/samples/inline-style-directive-important/main.svelte b/test/runtime-puppeteer/samples/inline-style-directive-important/main.svelte
new file mode 100644
index 0000000000..e869a9a473
--- /dev/null
+++ b/test/runtime-puppeteer/samples/inline-style-directive-important/main.svelte
@@ -0,0 +1,12 @@
+
+
+hello
+hello
+
+
\ No newline at end of file
diff --git a/test/validator/samples/style-directive-modifiers-invalid/errors.json b/test/validator/samples/style-directive-modifiers-invalid/errors.json
new file mode 100644
index 0000000000..245dfc63a8
--- /dev/null
+++ b/test/validator/samples/style-directive-modifiers-invalid/errors.json
@@ -0,0 +1,15 @@
+[{
+ "message": "Valid modifiers for style directives are: important",
+ "code": "invalid-style-directive-modifier",
+ "start": {
+ "line": 1,
+ "column": 8,
+ "character": 8
+ },
+ "end": {
+ "line": 1,
+ "column": 29,
+ "character": 29
+ },
+ "pos": 8
+}]
diff --git a/test/validator/samples/style-directive-modifiers-invalid/input.svelte b/test/validator/samples/style-directive-modifiers-invalid/input.svelte
new file mode 100644
index 0000000000..5fd7b1b1b5
--- /dev/null
+++ b/test/validator/samples/style-directive-modifiers-invalid/input.svelte
@@ -0,0 +1 @@
+
\ No newline at end of file