Skip to content

Commit

Permalink
Merge pull request #1695 from sveltejs/class-shortcut
Browse files Browse the repository at this point in the history
Adds class directive shortcut and encapsulate styles
  • Loading branch information
Rich-Harris authored Aug 28, 2018
2 parents 3c9d4b2 + fb734a3 commit c7d372c
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 8 deletions.
23 changes: 16 additions & 7 deletions src/compile/nodes/Element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -855,8 +855,8 @@ export default class Element extends Node {
const { expression } = action;
let snippet, dependencies;
if (expression) {
snippet = action.expression.snippet;
dependencies = action.expression.dependencies;
snippet = expression.snippet;
dependencies = expression.dependencies;
}

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

addClasses(block: Block) {
this.classes.forEach(classDir => {
const { expression: { snippet, dependencies}, name } = classDir;
const { expression, name } = classDir;
let snippet, dependencies;
if (expression) {
snippet = expression.snippet;
dependencies = expression.dependencies;
} else {
snippet = `ctx${quotePropIfNecessary(name)}`;
dependencies = [name];
}
const updater = `@toggleClass(${this.var}, "${name}", ${snippet});`;

block.builders.hydrate.addLine(updater);

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

block.builders.update.addConditional(
Expand Down Expand Up @@ -978,7 +986,8 @@ export default class Element extends Node {
}

const classExpr = this.classes.map((classDir: Class) => {
const { expression: { snippet }, name } = classDir;
const { expression, name } = classDir;
const snippet = expression ? expression.snippet : `ctx${quotePropIfNecessary(name)}`;
return `${snippet} ? "${name}" : ""`;
}).join(', ');

Expand Down Expand Up @@ -1026,15 +1035,15 @@ export default class Element extends Node {
openingTag += '${' + attribute.chunks[0].snippet + ' ? " ' + attribute.name + '" : "" }';
} else if (attribute.name === 'class' && classExpr) {
addClassAttribute = false;
openingTag += ` class="\${ [\`${attribute.stringifyForSsr()}\`, ${classExpr} ].join(' ') }"`;
openingTag += ` class="\${ [\`${attribute.stringifyForSsr()}\`, ${classExpr} ].join(' ').trim() }"`;
} else {
openingTag += ` ${attribute.name}="${attribute.stringifyForSsr()}"`;
}
});
}

if (addClassAttribute) {
openingTag += ` class="\${ [${classExpr}].join(' ') }"`;
openingTag += ` class="\${ [${classExpr}].join(' ').trim() }"`;
}

openingTag += '>';
Expand Down
8 changes: 7 additions & 1 deletion src/css/Selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ function applySelector(stylesheet: Stylesheet, blocks: Block[], node: Node, stac
}

if (selector.type === 'ClassSelector') {
if (!attributeMatches(node, 'class', selector.name, '~=', false)) return false;
if (!attributeMatches(node, 'class', selector.name, '~=', false) && !classMatches(node, selector.name)) return false;
}

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

function classMatches(node, name: string) {
return node.classes.some(function(classDir) {
return classDir.name === name;
});
}

function isDynamic(value: Node) {
return value.length > 1 || value[0].type !== 'Text';
}
Expand Down
16 changes: 16 additions & 0 deletions test/runtime/samples/class-shortcut/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export default {
data: {
"is-active": true,
isSelected: true,
myClass: 'one two'
},
html: `<div class="one two is-active isSelected"></div>`,

test ( assert, component, target, window ) {
component.set({ "is-active": false });

assert.htmlEqual( target.innerHTML, `
<div class="one two isSelected"></div>
` );
}
};
1 change: 1 addition & 0 deletions test/runtime/samples/class-shortcut/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div class="{ myClass }" class:is-active class:isSelected class:not-used></div>

0 comments on commit c7d372c

Please sign in to comment.