JSFiddle - React, Tailwind, and code Playground

by mgiuffrida

HTML

<script>Polymer = {dom: 'shadow', lazyRegister: true, useNativeCSSProperties: true};</script>
<base href="https://polygit.org/*+:master/components/">
<link rel="import" href="polymer/polymer.html">

<dom-module id="x-child">
  <template>
    <style>
      span {
        font-family: monospace;
        /* --child-pretty has a color property. @apply will be replaced with
           color: var(--child-pretty_-_color); */ 
        @apply(--child-pretty);
        font-weight: bold;
      }
    </style>
    x-child's span: <span>This is a styled span</span>
  </template>
</dom-module>
<dom-module id="x-parent1">
  <template>
    <style>
      blah {
        --child-pretty: {
          font-size: 100px;
        };
      }
      x-child {
        /* --child-pretty first seen here, so its properties are ['color']. */
        --child-pretty: {
          /* Sets --child-pretty_-_color to green. */
          color: green;
        };
      }
    </style>
    <header>Parent 1:</header>
    <x-child></x-child>
  </template>
</dom-module>

<dom-module id="x-parent2">
  <template>
    <style>
      x-child {
        /* The properties used by --child-pretty have already been set. */
        --child-pretty: {
          /* No effect: property not supported. */
          text-decoration: underline;
          /* Fine: color is a known property. */
          color: red;
        }
      }
    </style>
    <header>Parent 2:</header>
    <x-child></x-child>
  </template>
</dom-module>

<div>
  <x-child></x-child>
  <x-parent1></x-parent1>
  <x-parent2></x-parent2>
</div>

CSS

body {
  color: grey;
}
body > div {
  display: flex;
  flex-direction: column;
}
body > div > * {
  margin: 10px;
}

JavaScript

// Parses x-parent1, finding and processing --child-pretty.
// Adds it to the global map with properties ['color'].
Polymer({is: 'x-parent1'});

// Parses x-child, finding and processing --child-pretty.
Polymer({is: 'x-child'});

// Parses x-parent2, finding and processing --child-pretty.
Polymer({is: 'x-parent2'});

function assert(cond) {
  if (!cond)
    throw new Error('Failed: ' + cond);
}

function checkMixins() {
  var mixins = new Map();
  var mixinPropRe = new RegExp(/[\s{};]\-\-([\w\-]+)_-_([\w\-]+)\s*:/g);
  var mixinAppliedPropRe = new RegExp(/[\s{};]([\w\-]+)\s*:\s*var\(\s*\-\-([\w\-]+)_-_\1\s*[,)]/g); 
  function parseStyle(style) {
    var match;
    while (match = mixinPropRe.exec(style.innerText)) {
      assert(match.length == 3);
      var mixinName = match[1];
      var mixinProp = match[2];
      if (!mixins.has(mixinName))
        mixins.set(mixinName, new Map());
      var mixin = mixins.get(mixinName);
      if (!mixin.has(mixinProp))
        mixin.set(mixinProp, {valueSet: true, applied: false});
      else
        mixin.get(mixinProp).valueSet = true;
    }
    while (match = mixinAppliedPropRe.exec(style.innerText)) {
      assert(match.length == 3);
      var mixinProp = match[1];
      var mixinName = match[2];
      if (!mixins.has(mixinName))
        mixins.set(mixinName, new Map());
      var mixin = mixins.get(mixinName);
      if (!mixin.has(mixinProp))
        mixin.set(mixinProp, {valueSet: false, applied: true});
      else
        mixin.get(mixinProp).applied = true;
    }
  }
  
  var styles = document.querySelectorAll('style, * /deep/ style');
  console.log('Processing ' + styles.length + ' styles...')
  styles.forEach(parseStyle);
  
  mixins.forEach(function(mixin, mixinName) {
    mixin.forEach(function(detail, mixinProp) {
      if (detail.valueSet && !detail.applied)
        console.warn('Property "' + mixinProp + '" set for --' + mixinName + ' but never applied');
      else if (!detail.valueSet)
       ...