tpa-style-webpack-plugin
TypeScript icon, indicating that this package has built-in type declarations

1.4.13 • Public • Published

tpa-style-webpack-plugin

Build Status NPM version code style: prettier

A Webpack plugin that handles wix tpa styles, it extracts the dynamic css from the static css and injects it back to the bundle.

Requirements

  • Node.js v8 or above
  • Webpack 4.x

Installation

$ npm install --save-dev tpa-style-webpack-plugin

Usage

Add the plugin to your webpack config.

// webpack.config.js
const TpaStyleWebpackPlugin = require('tpa-style-webpack-plugin');

module.exports = {
  module: {
  ...
  },
  plugins: [
    new MiniCssExtractPlugin({filename: '[name].[chunkhash].css'}),
    new TpaStyleWebpackPlugin()
  ]
};

getProcessedCss

import getProcessedCss function from plugins runtime in your production code.

import {getProcessedCss} from 'tpa-style-webpack-plugin/runtime';
import {addStyles} from 'tpa-style-webpack-plugin/addStyles';

const dynamicCss = getProcessedCss(
  {styleParams, siteColors, siteTextPresets},
  {isRTL: false, prefixSelector: '.style-id', strictMode: true}
);
addStyles(dynamicCss, 'tag-id');

getProcessedCss Options

Name Type Default Description
isRTL {Boolean} false Defines id the direction replacers will work on ltr/rtl mode.
prefixSelector {String} '' Prefix of each selector in the css
strictMode {Boolean} true Defines if the function should throw on invalid css or invalid values.

Supported Css Functions

.my-selector {
    --my-font: "font(Body-M)";                                              /* define a custom variable with a default value */
    --my-font2: "font({theme: 'Body-M', size: '10px', lineHeight: '2em', weight: 'bold', style:'italic'})"     /* will use Body-M as base font and override the given attributes */
    --default-width: "number(42)";                                          /* define a numeric custom var */
    font: "font({theme: 'var-from-settings', size: '32px', lineHeight: '40px'})"; /* will use var-from-settings as base font and override the given attributes */
    font: "font(--my-font)";                                                /* assign a dynamic font value from a custom var */
    width: calc(100% - '"unit(--default-width, px)"');                      /* assign a dynamic numeric value from a custom var */
    width: calc(100% / "number(--default-width)" + 0px);                    /* assign a dynamic numeric value from a custom var */
    color: "color(color-8)";                                                /* assign a color from the site's palette */
    background-color: "join(opacity(color-1, 0.5), opacity(color-8, 0.5))"; /* blends 2 colors */
    color: "opacity(color-8, 0.3)";                                         /* add opacity to a site palette color */
    color: "withoutOpacity(opacity(color-8, 0.3))";                         /* will remove the opacity of site palette color */
    color: "darken(color-8, 0.3)";                                          /* make a darken version of site palette color */
    color: "whiten(color-8, 0.3)";                                          /* make a whiten version of site palette color - Mix the color with pure white, from 0 to 100 */
    color: "lighten(color-8, 0.3)";                                         /* make a lighten version of site palette color - from 0 to 100. Providing 100 will always return white */
    font: "font(--my-font2)";                                               /* will use the overridden default unless it was defined in settings  */
    border-width: "unit(--var-from-settings, px)";                          /* will produce border-width: 42px */
    color: "fallback(color(--var-from-settings), color(color-8))";          /* will return the first none falsy value from left to right */
}

Direction support

Expression RTL LTR
START right left
END left right
STARTSIGN '' '-'
ENDSIGN '-' ''
DEG-START 180 0
DEG-END 0 180
DIR rtl ltr
.my-selector {
  padding-start: 9px; /* START will be replaced with left / right, given rtl = false / true */
  float: START; /* Same as above, applied to the value */
  padding-end: 9px; /* END will be replaced with left / right, given rtl = true / false */
  direction: DIR; /* DIR will be replaced with ltr / rtl, given rtl = false / true */
  margin: STARTSIGN5px; /* STARTSIGN will be replaced with -, given rtl = false, and will be removed for rtl = true */
  margin: ENDSIGN5px; /* ENDSIGN will be replaced with -, given rtl = true, and will be removed for rtl = false */
  transform: rotate(DEG-STARTdeg);
  transform: rotate(DEG-ENDdeg);
}

You can check out an example project.

getStaticCss

Use it to inject the static css content to your .js bundle

Comparison to wix-style-processor

This plugin was written in order to add support for SSR to Wix tpa dynamic styles as part of OOI project.

It uses the same syntax as wix-style-proccesor but it works completely different, instead of searching the DOM for style tags with special syntax, it extracts the special syntax css, prepare all the data-structure that is needed at build-time and then exposes a function that given site params (colors, settings etc...) at run-time returns the css as a string.

You can use a built in method to inject it as a style tag or use your framework to render the style tag.

Usage example (React)

import React from "react";
import {getProcessedCss} from "tpa-style-webpack-plugin/runtime";

export const withStyles = (Component, options) => {
  return function WithStyles(props) {
    const {isRTL, siteStyles, styleId} = props;

    const dynamicCss = getProcessedCss(siteStyles, {
      prefixSelector: styleId ? `.${styleId}` : "",
      isRTL: !!isRTL,
      strictMode: !!options.strictMode,
    });

    return (
      <div className={styleId}>
        <style dangerouslySetInnerHTML={{__html: dynamicCss}} />
        <Component {...props} />
      </div>
    );
  };
};

⚠️ Caveats

  • If you use cssnano to minify CSS, be aware of the following limitations:

    • Don't mix static and dynamic values inside of border shorthand declaration (see the issue):

      .my-selector {
        /* DON'T */
        border: "unit(--var-from-settings, px)" solid "color(color-1)"; /* `cssnano` will remove the dynamic values, and it will become "border: solid;" */
      
        /* DO */
        border-width: "unit(--var-from-settings, px)";
        border-style: solid;
        border-color: "color(color-1)";
      }
    • If you use percentages and dynamic values together inside of calc, you need to have mixed units in order to opt out of calc minification:

      .my-selector {
        /* DON'T */
        width: calc(100% / "number(4)"); /* `reduce-css-calc` (used by `cssnano`) will transform it to "calc(1 / 4)" */
      
        /* DO */
        width: calc(100% / "number(4)" + 0px); /* notice 0px here */
      }
  • Currently there is no support for usage of style-loader, coming soon.

Package Sidebar

Install

npm i tpa-style-webpack-plugin

Weekly Downloads

163

Version

1.4.13

License

MIT

Unpacked Size

178 kB

Total Files

58

Last publish

Collaborators

  • arielh
  • falconci
  • yurynix
  • itai.benda
  • wix-ci
  • wix-ambassador
  • shahata
  • netanelgilad
  • wix-ci-publisher
  • wix-bi-publisher