Skip to content

Commit bee1851

Browse files
gtm-nayantanhauhau
andauthored
[feat] |important modifier for style directive (#7489)
* important modifier for style directive * docs * Exclude third param if false third param for set_style is optional * Remove unused test Runtime test doesn't work because of weird behaviour of computed style the puppeteer test should cover it * remove unnecessary test Co-authored-by: tanhauhau <[email protected]>
1 parent ff6e1c3 commit bee1851

File tree

15 files changed

+153
-7
lines changed

15 files changed

+153
-7
lines changed

site/content/docs/03-template-syntax.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,9 @@ The `style:` directive provides a shorthand for setting multiple styles on an el
874874
875875
<!-- Multiple styles can be included -->
876876
<div style:color style:width="12rem" style:background-color={darkMode ? "black" : "white"}>...</div>
877+
878+
<!-- Styles can be marked as important -->
879+
<div style:color|important="red">...</div>
877880
```
878881

879882
---

src/compiler/compile/compiler_errors.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,5 +281,9 @@ export default {
281281
invalid_component_style_directive: {
282282
code: 'invalid-component-style-directive',
283283
message: 'Style directives cannot be used on components'
284-
}
284+
},
285+
invalid_style_directive_modifier: (valid: string) => ({
286+
code: 'invalid-style-directive-modifier',
287+
message: `Valid modifiers for style directives are: ${valid}`
288+
})
285289
};

src/compiler/compile/nodes/StyleDirective.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,42 @@
11
import { TemplateNode } from '../../interfaces';
2+
import list from '../../utils/list';
3+
import compiler_errors from '../compiler_errors';
24
import Component from '../Component';
35
import { nodes_to_template_literal } from '../utils/nodes_to_template_literal';
46
import Expression from './shared/Expression';
57
import Node from './shared/Node';
68
import TemplateScope from './shared/TemplateScope';
79

10+
const valid_modifiers = new Set(['important']);
11+
812
export default class StyleDirective extends Node {
913
type: 'StyleDirective';
1014
name: string;
15+
modifiers: Set<string>;
1116
expression: Expression;
1217
should_cache: boolean;
1318

14-
constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode) {
19+
constructor(
20+
component: Component,
21+
parent: Node,
22+
scope: TemplateScope,
23+
info: TemplateNode
24+
) {
1525
super(component, parent, scope, info);
1626

1727
this.name = info.name;
28+
this.modifiers = new Set(info.modifiers);
29+
30+
for (const modifier of this.modifiers) {
31+
if (!valid_modifiers.has(modifier)) {
32+
component.error(
33+
this,
34+
compiler_errors.invalid_style_directive_modifier(
35+
list([...valid_modifiers])
36+
)
37+
);
38+
}
39+
}
1840

1941
// Convert the value array to an expression so it's easier to handle
2042
// the StyleDirective going forward.
@@ -34,6 +56,9 @@ export default class StyleDirective extends Node {
3456
this.expression = new Expression(component, this, scope, raw_expression);
3557
this.should_cache = raw_expression.expressions.length > 0;
3658
}
59+
}
3760

61+
get important() {
62+
return this.modifiers.has('important');
3863
}
3964
}

src/compiler/compile/render_dom/wrappers/Element/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,7 +1100,7 @@ export default class ElementWrapper extends Wrapper {
11001100
add_styles(block: Block) {
11011101
const has_spread = this.node.attributes.some(attr => attr.is_spread);
11021102
this.node.styles.forEach((style_directive) => {
1103-
const { name, expression, should_cache } = style_directive;
1103+
const { name, expression, should_cache, important } = style_directive;
11041104

11051105
const snippet = expression.manipulate(block);
11061106
let cached_snippet: Identifier | undefined;
@@ -1109,7 +1109,7 @@ export default class ElementWrapper extends Wrapper {
11091109
block.add_variable(cached_snippet, snippet);
11101110
}
11111111

1112-
const updater = b`@set_style(${this.var}, "${name}", ${should_cache ? cached_snippet : snippet}, false)`;
1112+
const updater = b`@set_style(${this.var}, "${name}", ${should_cache ? cached_snippet : snippet}, ${important ? 1 : null})`;
11131113

11141114
block.chunks.hydrate.push(updater);
11151115

src/compiler/compile/render_ssr/handlers/Element.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ export default function (node: Element, renderer: Renderer, options: RenderOptio
4444
class_expression_list.reduce((lhs, rhs) => x`${lhs} + ' ' + ${rhs}`);
4545

4646
const style_expression_list = node.styles.map(style_directive => {
47-
const { name, expression: { node: expression } } = style_directive;
47+
let { name, important, expression: { node: expression } } = style_directive;
48+
if (important) {
49+
expression = x`${expression} + ' !important'`;
50+
}
4851
return p`"${name}": ${expression}`;
4952
});
5053

src/compiler/parse/state/tag.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ function read_attribute(parser: Parser, unique_names: Set<string>) {
395395
end,
396396
type,
397397
name: directive_name,
398+
modifiers,
398399
value
399400
};
400401
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<div style:color|important={myColor}></div>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"html": {
3+
"start": 0,
4+
"end": 43,
5+
"type": "Fragment",
6+
"children": [
7+
{
8+
"start": 0,
9+
"end": 43,
10+
"type": "Element",
11+
"name": "div",
12+
"attributes": [
13+
{
14+
"start": 5,
15+
"end": 36,
16+
"type": "StyleDirective",
17+
"name": "color",
18+
"modifiers": [
19+
"important"
20+
],
21+
"value": [
22+
{
23+
"start": 27,
24+
"end": 36,
25+
"type": "MustacheTag",
26+
"expression": {
27+
"type": "Identifier",
28+
"start": 28,
29+
"end": 35,
30+
"loc": {
31+
"start": {
32+
"line": 1,
33+
"column": 28
34+
},
35+
"end": {
36+
"line": 1,
37+
"column": 35
38+
}
39+
},
40+
"name": "myColor"
41+
}
42+
}
43+
]
44+
}
45+
],
46+
"children": []
47+
}
48+
]
49+
}
50+
}

test/parser/samples/attribute-style-directive-shorthand/output.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@
1515
"end": 16,
1616
"type": "StyleDirective",
1717
"name": "color",
18+
"modifiers": [],
1819
"value": true
1920
}
2021
],
2122
"children": []
2223
}
2324
]
2425
}
25-
}
26+
}

test/parser/samples/attribute-style-directive-string/output.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"end": 22,
1616
"type": "StyleDirective",
1717
"name": "color",
18+
"modifiers": [],
1819
"value": [
1920
{
2021
"start": 18,
@@ -45,6 +46,7 @@
4546
"start": 35,
4647
"end": 52,
4748
"type": "StyleDirective",
49+
"modifiers": [],
4850
"name": "color",
4951
"value": [
5052
{
@@ -77,6 +79,7 @@
7779
"end": 80,
7880
"type": "StyleDirective",
7981
"name": "color",
82+
"modifiers": [],
8083
"value": [
8184
{
8285
"start": 77,
@@ -108,6 +111,7 @@
108111
"end": 120,
109112
"type": "StyleDirective",
110113
"name": "color",
114+
"modifiers": [],
111115
"value": [
112116
{
113117
"start": 106,
@@ -160,6 +164,7 @@
160164
"end": 160,
161165
"type": "StyleDirective",
162166
"name": "color",
167+
"modifiers": [],
163168
"value": [
164169
{
165170
"start": 146,
@@ -212,6 +217,7 @@
212217
"end": 198,
213218
"type": "StyleDirective",
214219
"name": "color",
220+
"modifiers": [],
215221
"value": [
216222
{
217223
"start": 185,
@@ -264,6 +270,7 @@
264270
"end": 245,
265271
"type": "StyleDirective",
266272
"name": "color",
273+
"modifiers": [],
267274
"value": [
268275
{
269276
"start": 223,
@@ -352,4 +359,4 @@
352359
}
353360
]
354361
}
355-
}
362+
}

test/parser/samples/attribute-style-directive/output.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"end": 26,
1616
"type": "StyleDirective",
1717
"name": "color",
18+
"modifiers": [],
1819
"value": [
1920
{
2021
"start": 17,
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
export default {
2+
html: `
3+
<h1 class="svelte-szzkfu" style="background-color: red;">hello</h1>
4+
<h1 class="svelte-szzkfu" style="background-color: red !important;">hello</h1>
5+
`,
6+
7+
ssrHtml: `
8+
<h1 class="svelte-szzkfu" style="background-color: red;">hello</h1>
9+
<h1 class="svelte-szzkfu" style="background-color: red !important;">hello</h1>
10+
`,
11+
12+
test({ assert, target, window, component }) {
13+
const h1s = target.querySelectorAll('h1');
14+
15+
assert.equal(window.getComputedStyle(h1s[0])['backgroundColor'], 'rgb(0, 0, 255)');
16+
assert.equal(window.getComputedStyle(h1s[1])['backgroundColor'], 'rgb(255, 0, 0)');
17+
18+
component.color = 'yellow';
19+
assert.equal(window.getComputedStyle(h1s[0])['backgroundColor'], 'rgb(0, 0, 255)');
20+
assert.equal(window.getComputedStyle(h1s[1])['backgroundColor'], 'rgb(255, 255, 0)');
21+
}
22+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<script>
2+
export let color = 'red'
3+
</script>
4+
5+
<h1 style:background-color={color} >hello</h1>
6+
<h1 style:background-color|important="{color}">hello</h1>
7+
8+
<style>
9+
h1 {
10+
background-color: blue !important;
11+
}
12+
</style>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[{
2+
"message": "Valid modifiers for style directives are: important",
3+
"code": "invalid-style-directive-modifier",
4+
"start": {
5+
"line": 1,
6+
"column": 8,
7+
"character": 8
8+
},
9+
"end": {
10+
"line": 1,
11+
"column": 29,
12+
"character": 29
13+
},
14+
"pos": 8
15+
}]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<button style:color|bad='red'></button>

0 commit comments

Comments
 (0)