Skip to content

Commit

Permalink
"support different exported types: camelCase, camelCaseOnly, dashes, …
Browse files Browse the repository at this point in the history
…dashesOnly (#93)"
  • Loading branch information
allocenx committed Apr 13, 2020
1 parent dcb25fc commit 9a691e9
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 28 deletions.
27 changes: 10 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,26 +181,19 @@ postcss([
]);
```

### Camel cased classes
### localsConvention

If you need, you can pass the options `{ camelCase: true }` to transform classes:
Type: `String`
Default: `null`

CSS:
Style of exported classnames.

```css
.post-title {
color: red;
}
```

JSON:

```json
{
"post-title": "._post-title_116zl_1",
"postTitle": "._post-title_116zl_1"
}
```
| Name | Type | Description |
| :-------------------: | :--------: | :----------------------------------------------------------------------------------------------- |
| **`'camelCase'`** | `{String}` | Class names will be camelized, the original class name will not to be removed from the locals |
| **`'camelCaseOnly'`** | `{String}` | Class names will be camelized, the original class name will be removed from the locals |
| **`'dashes'`** | `{String}` | Only dashes in class names will be camelized |
| **`'dashesOnly'`** | `{String}` | Dashes in class names will be camelized, the original class name will be removed from the locals |

## Integration with templates

Expand Down
39 changes: 34 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ function isResultPlugin(plugin) {
return plugin.postcssPlugin !== PLUGIN_NAME;
}

function dashesCamelCase(string) {
return string.replace(/-+(\w)/g, (_, firstLetter) =>
firstLetter.toUpperCase()
);
}

module.exports = postcss.plugin(PLUGIN_NAME, (opts = {}) => {
const getJSON = opts.getJSON || saveJSON;

Expand All @@ -72,11 +78,34 @@ module.exports = postcss.plugin(PLUGIN_NAME, (opts = {}) => {
const out = loader.finalSource;
if (out) css.prepend(out);

if (opts.camelCase) {
Object.keys(parser.exportTokens).forEach(token => {
const camelCaseToken = camelCase(token);
parser.exportTokens[camelCaseToken] = parser.exportTokens[token];
});
if (opts.localsConvention) {
parser.exportTokens = Object.entries(parser.exportTokens).reduce(
(tokens, [className, value]) => {
switch (opts.localsConvention) {
case "camelCase":
tokens[className] = value;
tokens[camelCase(className)] = value;

break;
case "camelCaseOnly":
tokens[camelCase(className)] = value;

break;
case "dashes":
tokens[className] = value;
tokens[dashesCamelCase(className)] = value;

break;
case "dashesOnly":
tokens[dashesCamelCase(className)] = value;

break;
}

return tokens;
},
{}
);
}

result.messages.push({
Expand Down
8 changes: 8 additions & 0 deletions test/fixtures/in/camelCase.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
.camel-case {
background: red;
}

.camel-case-extra {
background: blue;
}

.FooBar {
background: green;
}
80 changes: 74 additions & 6 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,24 +91,92 @@ it("processes globalModulePaths option", async () => {
expect(result.css).toMatchSnapshot("processes globalModulePaths option");
});

it("processes camelCase option", async () => {
it("processes localsConvention with camelCase option", async () => {
const sourceFile = path.join(fixturesPath, "in", "camelCase.css");
const source = fs.readFileSync(sourceFile).toString();
const jsonFile = path.join(fixturesPath, "in", "camelCase.css.json");

if (fs.existsSync(jsonFile)) fs.unlinkSync(jsonFile);

await postcss([plugin({ generateScopedName, camelCase: true })]).process(
source,
{ from: sourceFile }
);
await postcss([
plugin({ generateScopedName, localsConvention: "camelCase" })
]).process(source, { from: sourceFile });

const json = fs.readFileSync(jsonFile).toString();
fs.unlinkSync(jsonFile);

expect(JSON.parse(json)).toMatchObject({
"camel-case": "_camelCase_camel-case",
camelCase: "_camelCase_camel-case",
"camel-case-extra": "_camelCase_camel-case-extra",
camelCaseExtra: "_camelCase_camel-case-extra",
FooBar: "_camelCase_FooBar",
fooBar: "_camelCase_FooBar"
});
});

it("processes localsConvention with camelCaseOnly option", async () => {
const sourceFile = path.join(fixturesPath, "in", "camelCase.css");
const source = fs.readFileSync(sourceFile).toString();
const jsonFile = path.join(fixturesPath, "in", "camelCase.css.json");

if (fs.existsSync(jsonFile)) fs.unlinkSync(jsonFile);

await postcss([
plugin({ generateScopedName, localsConvention: "camelCaseOnly" })
]).process(source, { from: sourceFile });

const json = fs.readFileSync(jsonFile).toString();
fs.unlinkSync(jsonFile);

expect(JSON.parse(json)).toMatchObject({
camelCase: "_camelCase_camel-case",
camelCaseExtra: "_camelCase_camel-case-extra",
fooBar: "_camelCase_FooBar"
});
});

it("processes localsConvention with dashes option", async () => {
const sourceFile = path.join(fixturesPath, "in", "camelCase.css");
const source = fs.readFileSync(sourceFile).toString();
const jsonFile = path.join(fixturesPath, "in", "camelCase.css.json");

if (fs.existsSync(jsonFile)) fs.unlinkSync(jsonFile);

await postcss([
plugin({ generateScopedName, localsConvention: "dashes" })
]).process(source, { from: sourceFile });

const json = fs.readFileSync(jsonFile).toString();
fs.unlinkSync(jsonFile);

expect(JSON.parse(json)).toMatchObject({
"camel-case": "_camelCase_camel-case",
camelCase: "_camelCase_camel-case",
"camel-case-extra": "_camelCase_camel-case-extra",
camelCaseExtra: "_camelCase_camel-case-extra",
FooBar: "_camelCase_FooBar"
});
});

it("processes localsConvention with dashes option", async () => {
const sourceFile = path.join(fixturesPath, "in", "camelCase.css");
const source = fs.readFileSync(sourceFile).toString();
const jsonFile = path.join(fixturesPath, "in", "camelCase.css.json");

if (fs.existsSync(jsonFile)) fs.unlinkSync(jsonFile);

await postcss([
plugin({ generateScopedName, localsConvention: "dashes" })
]).process(source, { from: sourceFile });

const json = fs.readFileSync(jsonFile).toString();
fs.unlinkSync(jsonFile);

expect(JSON.parse(json)).toMatchObject({
camelCase: "_camelCase_camel-case",
"camel-case": "_camelCase_camel-case"
camelCaseExtra: "_camelCase_camel-case-extra",
FooBar: "_camelCase_FooBar"
});
});

Expand Down

0 comments on commit 9a691e9

Please sign in to comment.