Skip to content

Commit c7d372c

Browse files
authored
Merge pull request #1695 from sveltejs/class-shortcut
Adds class directive shortcut and encapsulate styles
2 parents 3c9d4b2 + fb734a3 commit c7d372c

File tree

4 files changed

+40
-8
lines changed

4 files changed

+40
-8
lines changed

src/compile/nodes/Element.ts

+16-7
Original file line numberDiff line numberDiff line change
@@ -855,8 +855,8 @@ export default class Element extends Node {
855855
const { expression } = action;
856856
let snippet, dependencies;
857857
if (expression) {
858-
snippet = action.expression.snippet;
859-
dependencies = action.expression.dependencies;
858+
snippet = expression.snippet;
859+
dependencies = expression.dependencies;
860860
}
861861

862862
const name = block.getUniqueName(
@@ -889,14 +889,22 @@ export default class Element extends Node {
889889

890890
addClasses(block: Block) {
891891
this.classes.forEach(classDir => {
892-
const { expression: { snippet, dependencies}, name } = classDir;
892+
const { expression, name } = classDir;
893+
let snippet, dependencies;
894+
if (expression) {
895+
snippet = expression.snippet;
896+
dependencies = expression.dependencies;
897+
} else {
898+
snippet = `ctx${quotePropIfNecessary(name)}`;
899+
dependencies = [name];
900+
}
893901
const updater = `@toggleClass(${this.var}, "${name}", ${snippet});`;
894902

895903
block.builders.hydrate.addLine(updater);
896904

897905
if ((dependencies && dependencies.size > 0) || this.classDependencies.length) {
898906
const allDeps = this.classDependencies.concat(...dependencies);
899-
const deps = allDeps.map(dependency => `changed.${dependency}`).join(' || ');
907+
const deps = allDeps.map(dependency => `changed${quotePropIfNecessary(dependency)}`).join(' || ');
900908
const condition = allDeps.length > 1 ? `(${deps})` : deps;
901909

902910
block.builders.update.addConditional(
@@ -978,7 +986,8 @@ export default class Element extends Node {
978986
}
979987

980988
const classExpr = this.classes.map((classDir: Class) => {
981-
const { expression: { snippet }, name } = classDir;
989+
const { expression, name } = classDir;
990+
const snippet = expression ? expression.snippet : `ctx${quotePropIfNecessary(name)}`;
982991
return `${snippet} ? "${name}" : ""`;
983992
}).join(', ');
984993

@@ -1026,15 +1035,15 @@ export default class Element extends Node {
10261035
openingTag += '${' + attribute.chunks[0].snippet + ' ? " ' + attribute.name + '" : "" }';
10271036
} else if (attribute.name === 'class' && classExpr) {
10281037
addClassAttribute = false;
1029-
openingTag += ` class="\${ [\`${attribute.stringifyForSsr()}\`, ${classExpr} ].join(' ') }"`;
1038+
openingTag += ` class="\${ [\`${attribute.stringifyForSsr()}\`, ${classExpr} ].join(' ').trim() }"`;
10301039
} else {
10311040
openingTag += ` ${attribute.name}="${attribute.stringifyForSsr()}"`;
10321041
}
10331042
});
10341043
}
10351044

10361045
if (addClassAttribute) {
1037-
openingTag += ` class="\${ [${classExpr}].join(' ') }"`;
1046+
openingTag += ` class="\${ [${classExpr}].join(' ').trim() }"`;
10381047
}
10391048

10401049
openingTag += '>';

src/css/Selector.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ function applySelector(stylesheet: Stylesheet, blocks: Block[], node: Node, stac
157157
}
158158

159159
if (selector.type === 'ClassSelector') {
160-
if (!attributeMatches(node, 'class', selector.name, '~=', false)) return false;
160+
if (!attributeMatches(node, 'class', selector.name, '~=', false) && !classMatches(node, selector.name)) return false;
161161
}
162162

163163
else if (selector.type === 'IdSelector') {
@@ -258,6 +258,12 @@ function attributeMatches(node: Node, name: string, expectedValue: string, opera
258258
return false;
259259
}
260260

261+
function classMatches(node, name: string) {
262+
return node.classes.some(function(classDir) {
263+
return classDir.name === name;
264+
});
265+
}
266+
261267
function isDynamic(value: Node) {
262268
return value.length > 1 || value[0].type !== 'Text';
263269
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export default {
2+
data: {
3+
"is-active": true,
4+
isSelected: true,
5+
myClass: 'one two'
6+
},
7+
html: `<div class="one two is-active isSelected"></div>`,
8+
9+
test ( assert, component, target, window ) {
10+
component.set({ "is-active": false });
11+
12+
assert.htmlEqual( target.innerHTML, `
13+
<div class="one two isSelected"></div>
14+
` );
15+
}
16+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<div class="{ myClass }" class:is-active class:isSelected class:not-used></div>

0 commit comments

Comments
 (0)