1.4.13 • Published 3 years ago

tpa-style-webpack-plugin v1.4.13

Weekly downloads
771
License
MIT
Repository
github
Last release
3 years ago

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

NameTypeDefaultDescription
isRTL{Boolean}falseDefines id the direction replacers will work on ltr/rtl mode.
prefixSelector{String}''Prefix of each selector in the css
strictMode{Boolean}trueDefines 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

ExpressionRTLLTR
STARTrightleft
ENDleftright
STARTSIGN'''-'
ENDSIGN'-'''
DEG-START1800
DEG-END0180
DIRrtlltr
.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.

1.4.13

3 years ago

1.4.12

3 years ago

1.4.11

3 years ago

1.4.10

3 years ago

1.4.6

3 years ago

1.4.9

3 years ago

1.4.8

3 years ago

1.4.7

3 years ago

1.4.5

3 years ago

1.4.4

3 years ago

1.4.3

3 years ago

1.4.2

3 years ago

1.4.1

3 years ago

1.4.0

3 years ago

1.3.18

3 years ago

1.3.19

3 years ago

1.3.17

4 years ago

1.3.16

4 years ago

1.3.15

4 years ago

1.3.14

4 years ago

1.3.13

4 years ago

1.3.12

4 years ago

1.3.11

5 years ago

1.3.10

5 years ago

1.3.9

5 years ago

1.3.8

5 years ago

1.3.7

5 years ago

1.3.6

5 years ago

1.3.5

5 years ago

1.3.4

5 years ago

1.3.3

5 years ago

1.3.2

5 years ago

1.3.1

5 years ago

1.3.0

5 years ago

1.2.2

5 years ago

1.2.1

5 years ago

1.2.0

5 years ago

1.1.3

5 years ago

1.1.2

5 years ago

1.1.1

5 years ago

1.1.0

5 years ago

1.0.5

5 years ago

1.0.4

5 years ago

1.0.3

5 years ago

1.0.2

6 years ago

1.0.1

6 years ago

1.0.0

6 years ago

0.1.6

6 years ago

0.1.5

6 years ago

0.1.4

6 years ago

0.1.3

6 years ago

0.1.2

6 years ago

0.1.1

6 years ago

0.1.0

6 years ago

0.0.2

6 years ago

0.0.1

6 years ago