Skip to content

Commit 542c0b4

Browse files
authored
Merge 3026b5e into a1b61a0
2 parents a1b61a0 + 3026b5e commit 542c0b4

20 files changed

+6031
-62
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## [3.6.0] - 2022-04-09
4+
5+
- Added a new diff mode to output only flipped rules with the intention of using them in a separate stylesheet file to override the main stylesheet
6+
37
## [3.5.4] - 2022-03-26
48

59
- Build the package bundle using rollup and created an ESM version of the package

README.md

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# PostCSS RTLCSS
22

3-
[PostCSS] plugin to build Cascading Style Sheets (CSS) with Left-To-Right (LTR) and Right-To-Left (RTL) rules using [RTLCSS]
3+
[PostCSS] plugin to build Cascading Style Sheets (CSS) with Left-To-Right (LTR) and Right-To-Left (RTL) rules using [RTLCSS]. RTLCSS allows one to flip an entire CSS file with the intention of using the original CSS for one direction and the new generated one for the other. What PostcCSS RTLCSS does, is to create a single CSS file with both directions or to create a minimal CSS file only with the flipped rules with the intention of overriding the main one.
44

55
[![Build Status](https://travis-ci.com/elchininet/postcss-rtlcss.svg?branch=master)](https://app.travis-ci.com/elchininet/postcss-rtlcss)   [![Coverage Status](https://coveralls.io/repos/github/elchininet/postcss-rtlcss/badge.svg?branch=master)](https://coveralls.io/github/elchininet/postcss-rtlcss?branch=master)   [![npm version](https://badge.fury.io/js/postcss-rtlcss.svg)](https://badge.fury.io/js/postcss-rtlcss)
66

77
[PostCSS]: https://github.com/postcss/postcss
88
[RTLCSS]: https://rtlcss.com/
99

10-
Demo
10+
Playground Demo
1111
---
1212

1313
https://elchininet.github.io/postcss-rtlcss/
@@ -131,7 +131,7 @@ Examples
131131

132132
#### Output using the combined mode (default)
133133

134-
This is the recommended method, it will generate more CSS code but each direction will have their specific CSS declarations and there is not need to override properties.
134+
This is the recommended method, it will generate more CSS code but each direction will have their specific CSS declarations and there is no need of overriding properties.
135135

136136
```css
137137
.test1, .test2 {
@@ -172,7 +172,7 @@ This is the recommended method, it will generate more CSS code but each directio
172172

173173
#### Output using the override mode
174174

175-
This is the alternative method, it will generate less code because it lets the main rule intact and generates a shorter specific rule to override the properties that are affected by the direction of the text.
175+
This is one of the alternative methods to override. It will generate less code because it lets the main rule intact and generates a shorter specific rule to override the properties that are affected by the direction of the text.
176176

177177
```css
178178
.test1, .test2 {
@@ -206,12 +206,30 @@ This is the alternative method, it will generate less code because it lets the m
206206
}
207207
```
208208

209-
But this method has a disadvantage:
209+
#### Output using the diff mode
210210

211-
<details><summary>Disadvantage of the override method</summary>
211+
This is the second alternative method to override. It generates the minimum amount of code because it only outputs the rules that have been flipped and without prefixing them. The intention of this method is to generate a separate stylesheet file that will be loaded on top of the original one to override those rules that need to be flipped in certain direction.
212+
213+
```css
214+
.test1, .test2 {
215+
border-radius: 2px 0 8px 0;
216+
padding-right: 0;
217+
padding-left: 20px;
218+
text-align: right;
219+
transform: translate(50%, 50%);
220+
}
221+
222+
.test3 {
223+
direction: rtl;
224+
}
225+
```
226+
227+
But the two methods to override have a disadvantage:
228+
229+
<details><summary>Disadvantage of the methods to override</summary>
212230
<p>
213231

214-
Use this method carefully. It can override a property that is coming from another class if multiple classes are used at the same time. Take a look at the next `HTML` and `CSS` codes:
232+
Use these methods carefully. They can override a property that is coming from another class if multiple classes are used at the same time. Take a look at the next `HTML` and `CSS` codes:
215233

216234
```html
217235
<div class="test1 test2">
@@ -231,7 +249,7 @@ Use this method carefully. It can override a property that is coming from anothe
231249
}
232250
```
233251

234-
Using the combined method, the generated code will be the next one:
252+
Using the `combined` method, the generated code will be the next one:
235253

236254
```css
237255
.test1 {
@@ -249,9 +267,9 @@ Using the combined method, the generated code will be the next one:
249267
}
250268
```
251269

252-
So, the `div` will have a padding of `20px 10px 20px 20px` in `LTR` and `20px 20px 20px 10px` in `RTL`.
270+
So, the `div` will have a padding of `20px 10px 20px 20px` in `LTR` and `20px 20px 20px 10px` in `RTL`. Everything will work as expected here.
253271

254-
However, using the override method the generated code will be the next one:
272+
However, using the `override` method the generated code will be the next one:
255273

256274
```css
257275
.test1 {
@@ -270,7 +288,16 @@ However, using the override method the generated code will be the next one:
270288
}
271289
```
272290

273-
Now the `div` has a padding of `20px 10px 20px 20px` in `LTR` and `20px 0 20px 10px` in `RTL`, because the override of the class `test2` doesn't take into account that this class could be used with `test1` having the same properties. The solution, in this case, is to provide the property that has been inherited:
291+
And using the `diff` method the generated code will be the next one:
292+
293+
```css
294+
.test2 {
295+
padding-right: 0;
296+
padding-left: 10px;
297+
}
298+
```
299+
300+
Now the `div` has a padding of `20px 10px 20px 20px` in `LTR` and `20px 0 20px 10px` in `RTL`, because when the class `test2` is overriden, it is not taken into account that it could be used with `test1` having the same properties. The solution, in this case, is to provide the property that has been inherited:
274301

275302
```css
276303
.test1 {
@@ -285,7 +312,7 @@ Now the `div` has a padding of `20px 10px 20px 20px` in `LTR` and `20px 0 20px 1
285312
}
286313
```
287314

288-
So, the generated code will be:
315+
So, using the `override` method the generated code will be:
289316

290317
```css
291318
.test1 {
@@ -305,6 +332,15 @@ So, the generated code will be:
305332
}
306333
```
307334

335+
And using the `diff` method the generated code will be:
336+
337+
```css
338+
.test2 {
339+
padding-right: 20px;
340+
padding-left: 10px;
341+
}
342+
```
343+
308344
</p>
309345
</details>
310346

src/@types/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { Rule, AtRule } from 'postcss';
22

33
export enum Mode {
44
combined = 'combined',
5-
override = 'override'
5+
override = 'override',
6+
diff = 'diff'
67
}
78

89
export enum Source {

src/data/store.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Rule } from 'postcss';
1+
import { Rule, AtRule } from 'postcss';
22
import {
33
PluginOptions,
44
PluginOptionsNormalized,
@@ -24,10 +24,12 @@ import {
2424
interface Store {
2525
options: PluginOptionsNormalized;
2626
keyframes: AtRulesObject[];
27+
keyframesToRemove: AtRule[];
2728
keyframesStringMap: AtRulesStringMap;
2829
keyframesRegExp: RegExp;
2930
rules: RulesObject[];
3031
rulesAutoRename: Rule[];
32+
rulesToRemove: Rule[];
3133
rulesPrefixRegExp: RegExp;
3234
}
3335

@@ -146,10 +148,12 @@ const defaultOptions = (): PluginOptionsNormalized => ({
146148
const store: Store = {
147149
options: {...defaultOptions()},
148150
keyframes: [],
151+
keyframesToRemove: [],
149152
keyframesStringMap: {},
150153
keyframesRegExp: defaultRegExp,
151154
rules: [],
152155
rulesAutoRename: [],
156+
rulesToRemove: [],
153157
rulesPrefixRegExp: defaultRegExp
154158
};
155159

@@ -215,10 +219,12 @@ const normalizeOptions = (options: PluginOptions): PluginOptionsNormalized => {
215219
const initStore = (options: PluginOptions): void => {
216220
store.options = normalizeOptions(options);
217221
store.keyframes = [];
222+
store.keyframesToRemove = [];
218223
store.keyframesStringMap = {};
219224
store.keyframesRegExp = defaultRegExp;
220225
store.rules = [];
221226
store.rulesAutoRename = [];
227+
store.rulesToRemove = [];
222228
store.rulesPrefixRegExp = createRulesPrefixesRegExp(store.options);
223229
};
224230

src/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ import { PluginOptions } from '@types';
33
import { initStore } from '@data/store';
44
import { parseKeyFrames, parseAtRules } from '@parsers/atrules';
55
import { parseRules } from '@parsers/rules';
6-
import { appendRules, appendKeyFrames, appendAutorenameRules } from '@utilities/rules';
6+
import {
7+
appendRules,
8+
appendKeyFrames,
9+
appendAutorenameRules
10+
} from '@utilities/rules';
11+
import { clean } from '@utilities/clean';
712

813
function postcssRTLCSS (options: PluginOptions = {}): Plugin {
914
return ({
@@ -16,6 +21,7 @@ function postcssRTLCSS (options: PluginOptions = {}): Plugin {
1621
appendRules();
1722
appendKeyFrames();
1823
appendAutorenameRules();
24+
clean(css);
1925
}
2026
});
2127
};

src/parsers/atrules.ts

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1-
import postcss, { Root, Container, Node, AtRule, Comment } from 'postcss';
1+
import postcss, {
2+
Root,
3+
Container,
4+
Node,
5+
AtRule,
6+
Comment
7+
} from 'postcss';
28
import rtlcss from 'rtlcss';
39
import {
410
Source,
5-
ControlDirective
11+
ControlDirective,
12+
Mode
613
} from '@types';
714
import {
815
AT_RULE_TYPE,
@@ -62,6 +69,12 @@ export const parseAtRules = (container: Container): void => {
6269

6370
};
6471

72+
const addToIgnoreKeyframesInDiffMode = (node: Node): void => {
73+
if (store.options.mode === Mode.diff) {
74+
store.keyframesToRemove.push(node as AtRule);
75+
}
76+
};
77+
6578
export const parseKeyFrames = (css: Root): void => {
6679

6780
const { source, processUrls, useCalc, stringMap, processKeyFrames } = store.options;
@@ -87,19 +100,27 @@ export const parseKeyFrames = (css: Root): void => {
87100
(node: Node): void => {
88101

89102
if ( checkDirective(controlDirectives, CONTROL_DIRECTIVE.IGNORE) ) {
103+
addToIgnoreKeyframesInDiffMode(node);
90104
return;
91105
}
92106

93-
if (node.type !== AT_RULE_TYPE) return;
107+
if (node.type !== AT_RULE_TYPE) {
108+
return;
109+
}
94110

95111
const atRule = node as AtRule;
96112

97-
if (vendor.unprefixed(atRule.name) !== KEYFRAMES_NAME) return;
113+
if (vendor.unprefixed(atRule.name) !== KEYFRAMES_NAME) {
114+
return;
115+
}
98116

99117
const atRuleString = atRule.toString();
100118
const atRuleFlippedString = rtlcss.process(atRuleString, { processUrls, useCalc, stringMap });
101119

102-
if (atRuleString === atRuleFlippedString) return;
120+
if (atRuleString === atRuleFlippedString) {
121+
addToIgnoreKeyframesInDiffMode(atRule);
122+
return;
123+
}
103124

104125
const rootFlipped = postcss.parse(atRuleFlippedString);
105126
const atRuleFlipped = rootFlipped.first as AtRule;

0 commit comments

Comments
 (0)