Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ Finally, you can use the plugin and add it to modules you want to use it with.

```js
variants: {
float: ['responsive', 'direction'],
margin: ['responsive', 'direction'],
padding: ['responsive', 'direction'],
float: ['responsive', 'direction'], // adds both rtl and ltr variants
margin: ['responsive', 'rtl'], // only adds rtl variant
padding: ['responsive', 'ltr'], // only adds ltr variant
},
```

Expand Down
47 changes: 28 additions & 19 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,42 @@
function addSelectors(container, modifierFunction) {
const rules = [];

container.walkRules(rule => {
const selectors = rule.selectors.map(selector => modifierFunction(selector.slice(1)));
container.walkRules((rule) => {
const selectors = rule.selectors.map((selector) => modifierFunction(selector.slice(1)));
rules.push(rule.clone({ selectors }));
});

return rules;
}

const RTL_VARIANT = 'rtl';
const LTR_VARIANT = 'ltr';

function generator({ addVariant, e }) {
addVariant('direction', ({ container, separator }) => {
const result = container.clone({ nodes: [] });

['ltr', 'rtl'].forEach(dir => {
result.nodes = result.nodes.concat(
addSelectors(container, className => {
return [
`[dir='${dir}'] .${dir}${e(separator)}${className}`,
`[dir='${dir}'].${dir}${e(separator)}${className}`,
];
})
);
});

return result;
});
addVariant('direction', variantGenerator([LTR_VARIANT, RTL_VARIANT]));
addVariant(LTR_VARIANT, variantGenerator([LTR_VARIANT]));
addVariant(RTL_VARIANT, variantGenerator([RTL_VARIANT]));

function variantGenerator(variants) {
return ({ container, separator }) => {
const result = container.clone({ nodes: [] });

variants.forEach((dir) => {
result.nodes = result.nodes.concat(
addSelectors(container, (className) => {
return [
`[dir='${dir}'] .${dir}${e(separator)}${className}`,
`[dir='${dir}'].${dir}${e(separator)}${className}`,
];
})
);
});

return result;
};
}
}

module.exports = function() {
module.exports = function () {
return generator;
};
77 changes: 71 additions & 6 deletions tests/variantGenerator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ const postcss = require('postcss');
const tailwindcss = require('tailwindcss');
const config = require('./config');

function expectMatch(input, output) {
return postcss([tailwindcss(config)])
.process(input, { from: undefined })
.then((result) => {
expect(result.css).toMatchCss(output);
expect(result.warnings().length).toBe(0);
});
}
test('it generates direction variants', () => {
const input = `
@variants direction {
Expand Down Expand Up @@ -40,10 +48,67 @@ test('it generates direction variants', () => {
}
`;

return postcss([tailwindcss(config)])
.process(input, { from: undefined })
.then(result => {
expect(result.css).toMatchCss(output);
expect(result.warnings().length).toBe(0);
});
return expectMatch(input, output);
});

test('it generates rtl variant', () => {
const input = `
@variants rtl {
.banana { color: yellow; }
.tomato { color: red; }
}
`;

const output = `
.banana {
color: yellow;
}

.tomato {
color: red;
}

[dir='rtl'] .rtl\\:banana,
[dir='rtl'].rtl\\:banana {
color: yellow;
}

[dir='rtl'] .rtl\\:tomato,
[dir='rtl'].rtl\\:tomato {
color: red;
}
`;

return expectMatch(input, output);
});

test('it generates ltr variant', () => {
const input = `
@variants ltr {
.banana { color: yellow; }
.tomato { color: red; }
}
`;

const output = `
.banana {
color: yellow;
}

.tomato {
color: red;
}

[dir='ltr'] .ltr\\:banana,
[dir='ltr'].ltr\\:banana {
color: yellow;
}

[dir='ltr'] .ltr\\:tomato,
[dir='ltr'].ltr\\:tomato {
color: red;
}
`;

return expectMatch(input, output);
});