Skip to content

Instantly share code, notes, and snippets.

@otolab
Last active February 15, 2024 21:29
Show Gist options
  • Save otolab/0299481c14065dc9cc26ae9e481ccf36 to your computer and use it in GitHub Desktop.
Save otolab/0299481c14065dc9cc26ae9e481ccf36 to your computer and use it in GitHub Desktop.
"use strict";
const postcss = require('postcss');
const postcssModules = require('postcss-modules');
const posthtml = require('posthtml');
const matchHelper = require('posthtml-match-helper');
const parseAttrs = require('posthtml-attrs-parser');
function class_to_css_module_plugin(_options) {
let options = _options || {};
options.imports = options.imports || {};
return function classToCssModule(tree) {
const matcher = matchHelper('');
tree.match(matcher, function (node) {
const attrs = parseAttrs(node.attrs);
const classes = [];
if (!attrs.class) return node;
attrs.class.forEach(function (klass) {
if (options.imports[klass]) {
classes.push(options.imports[klass]);
}
else {
classes.push(klass);
}
});
attrs.class = classes;
node.attrs = attrs.compose();
return node;
});
}
}
module.exports = function (css, html) {
const output = {
css: null,
cssExports: null,
html: null
};
const cssPromise = postcss([
postcssModules({
getJSON: function(cssFileName, json) {
output.cssExports = json;
}
})
])
.process(css)
.then(function (result) {
output.css = result.css;
});
const htmlPromise = cssPromise.then(function () {
return posthtml([
class_to_css_module_plugin({
imports: output.cssExports
})
])
.process(html)
.then(function (result) {
output.html = result.html;
});
});
return htmlPromise.then(function () {
return output;
});
}
@otolab
Copy link
Author

otolab commented Aug 26, 2016

var convert = require('css-modules-auto-bind');

var p = convert(css, html);
p.then(function (result) {
  console.log(result.css, result.cssExports, result.html);
});

@otolab
Copy link
Author

otolab commented Aug 26, 2016

Input

CSS

.smallText {
  font-size: 0.7em;
}

.icon {
  composes: smallText;
  background-image: url(icon.png);
}

.content a i.icon {
  color: red;
}
.container :global(p.link) {
  color: white;
  background-color: black;
}

HTML

<div class="container karte-widget-container">
  <div class="content"><p class="link">test<a><i class="icon">&nbsp;</i>link</a></p></div>
  <component is="InnerComponent"></component>
</div>

Output

CSS

._smallText_o4ar1_2 {
  font-size: 0.7em;
}

._icon_o4ar1_6 {
  background-image: url(icon.png);
}

._content_o4ar1_11 a i._icon_o4ar1_6 {
  color: red;
}
._container_o4ar1_14 p.link {
  color: white;
  background-color: black;
}

CSS Module exports

{ smallText: '_smallText_o4ar1_2',
  icon: '_icon_o4ar1_6 _smallText_o4ar1_2',
  content: '_content_o4ar1_11',
  container: '_container_o4ar1_14' }

HTML

<div class="_container_o4ar1_14 karte-widget-container">
  <div class="_content_o4ar1_11"><p class="link">test<a><i class="_icon_o4ar1_6 _smallText_o4ar1_2">&nbsp;</i>link</a></p></div>
  <component is="InnerComponent"></component>
</div>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment