# Variable Conversion  

## Overview 

Conversion for Variables from Variables to px in Supportapp completed (`variableIgnore.js` && `pxParserPostcss.js` to be referred to), and px to custom variables through the new `variableModificationPlugin`. Error Log generation can also be converted on enabling


**Issue Fix**
# Issue fix done in `1.0.1`
- variable conversion for px and var(--) values in same declaration was not supported, now it is supported.

**Features:** 
# Features below are added from `0.0.1-beta.173`
1. variables are converted from px to custom variables ( options are consumed from `cssVariableReplacementOptions.json` present in source folder )
2. To enable the error log generation `errorLog` is to be made `true` in `cssVariableReplacementOptions.json` ( it will take a little longer than usual build time )
3. To enable the console display of errors that are generated, `errorInConsole` is to be made `true` in `cssVariableReplacementOptions.json`
4. To enable specific errors in the error log generation / error display on console, `DECLARATION_IGNORED`(for ignoring that particular line / declaration),`UNIT_ERROR` (when the Unit doesnt match the available units for the property),`RANGE_ERROR` (when the value does not fall within the range that is given for the property), `VARIABLE_PRESENT`(whether the value supposed to be in px for conversion sake is not converted from var() to px or if it's properly converted to px for conversion from px to var through our plugin) are to be individually made `true` in `cssVariableReplacementOptions.json`

# Features below are added form `0.0.1-beta.176`
  
* variables with -- are now supported due to the webpack plugin `VariableConversionCollector` that is generated for the same.
*  `DECIMAL_CHECK`, `DECIMAL_REJECT` are two new errors supported.
* support for text-indent, clip, flex, flex-basis, row-gap, column-gap, gap properties are now given.

# Features below are added form `0.0.1-beta.177`

* new Error `MULTIPLE_OCCURANCES` supported.
* In case css --variables are not assigned an error will be thrown and logged in `.cli/logs/unassignedVariables.log`. The unassigned variables can be manually assigned in `variableMapping.json` through two keys : 
  * `changes` : for the variables that have to be converted, manual values can be added ( eg. "--wms_height": "height" )
  * `ignore` : for the variables that do not have to be considered, they can be added as keys with some value in `ignore` key (eg. "--gc_widget_video_bg": "undefined"). These values will be ignored.
* strict mode can be enabled for checking --variables in `cssVariableReplacementOptions.strictMode`

For more information and reference, refer to `[details](https://zgit.csez.zohocorpin.com/zohodesk/react-cli/-/blob/2.0.0/docs/VariableConversion.md)

<!-- file paths :

# react - cli : 
src\postcss-plugins\variableModificationPlugin\index.js

# source folder : 
jsapps\supportapp\cssVariableReplacementOptions.json ( options json file )
jsapps\supportapp\plugins\pxParserPostcss.js ( px parsing as a process before plugin conversion to custom css variables in react -cli )
jsapps\supportapp\plugins\variableIgnore.js ( adding variable:ignore comment to ignore the line for any conversion beforehand to preserve the declaration )

-->

# Added support for Properties ( Cut 1 ) :  (0.0.1-beta.173)

* font-size
* margin 
* margin-top
* margin-bottom
* margin-left
* margin-right
* padding 
* padding-top
* padding-bottom
* padding-left
* padding-right
* top
* right
* bottom
* left
* width 
* min-width
* max-width
* height 
* min-height
* max-height

# Added support for Properties ( Cut 2 ) : (0.0.1-beta.176)

* text-indent 
* clip
* flex
* flex-basis 
* row-gap
* column-gap
* gap

# Css variable conversion consists of three steps : 

. addition of comment variable:ignore for the seperation of values to be considered for the conversion and the ones that are not to be considered for conversion. ( `variableIgnore.js` )
. conversion of the variable from current css variables to corresponding px value manually. ( `pxParserPostcss.js` )
. conversion of the resultant px values to custom variables present in settings ( `cssVariableReplacementOptions.json` )

`cssVariableReplacementOptions.json example` :

```json
{
    "errorLog": false,
    "errorInConsole": false,
    "errorsAllowed":{
      "DECLARATION_IGNORED": true,
      "UNIT_ERROR": true,
      "DECIMAL_CHECK": true,
      "DECIMAL_REJECT": true,
      "RANGE_ERROR": true,
      "VARIABLE_PRESENT": true,
      "MULTIPLE_OCCURANCES": false
    },
    "settings": {
      "font-size": {
        "allowed": [
          "px",
          "em",
          "%",
          "0",
          "vh",
          "initial"
        ],
        "replacements": {
          "px": "var(--zd_font_size$$)",
          "em": "var(--zd_font_size$$em)"
        },
        "range": {
          "start": 0,
          "end": 1650
        }
      },
      "margin": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      "margin-left": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      "margin-right": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      "margin-top": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      "margin-bottom": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      "padding": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      "padding-left": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      "padding-right": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      "padding-top": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      "padding-bottom": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      "height": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      "width": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      "min-width": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      "max-width": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      "min-height": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      "max-height": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      "top": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      "bottom": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      "left": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      "right": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      }
    }
  } 
```

Step 1 : Adding variable:ignore

use command `npm run variable:addignore` on source folder

before :
```css
.a{
    font-size: var(--zd_size14);
    margin: var(--zd_size12);
    padding: 12px;
}
```

after :

```css
/* explanation  : since padding has declaration in px instead of var, it is considered unique and thereby no conversion should take place, hence we add variable:ignore preceding the line  */
.a{
    font-size: var(--zd_size14);
    margin: var(--zd_size12);
    /*Variable:Ignore*/
    padding: 12px;
}
```

Step 2 : Converting vars to px 

use command `npm run variable:convert` on source folder 

before : 
```css
.a{
    font-size: var(--zd_size14);
    margin: var(--zd_size12);
    /*Variable:Ignore*/
    padding: 12px;
}
```

after : 
```css
/* explanation :  conversion from vars to px is done making the declarations convertable to custom variables further by the react-cli plugin*/
.a{
    font-size: 14px;
    margin: 12px;
    /*Variable:Ignore*/
    padding: 12px;
}
```

Step 3 : Conversion from px to custom variables present in settings

Things that are considered in the conversion : 
=> `allowed` is the allowed units that can be converted through the plugin
=> `replacements` are the conversion strings where `$$` will be converted to respective numbers
=> `range` is the starting and ending value within numbers will be allowed.

`variableModificationPlugin` in react-cli folder is where the conversion takes place.

and output would be as follows : 

before :

```css
/* explanation :  conversion from px to variable is allowed since, all the conditions for font-size and margin are satisfied, the numbers are within range and the unit is in the allowed array, replacements are thereby taken from the values in replacements and conversion is done to custom variables  */

/*
    "font-size": {
        "allowed": [
          "px",
          "em",
          "%",
          "0",
          "vh",
          "initial"
        ],
        "replacements": {
          "px": "var(--zd_font_size$$)",
          "em": "var(--zd_font_size$$em)"
        },
        "range": {
          "start": 0,
          "end": 1650
        }
      },
*/
/*

      "margin": {
        "allowed": [
          "px",
          "em",
          "fit-content",
          "auto",
          "%",
          "inherit",
          "-moz-fit-content",
          "vh",
          "0",
          "initial",
          "vw"
        ],
        "replacements": {
          "px": "var(--zd_size$$)"
        },
        "range": {
          "start": -1650,
          "end": 1650
        }
      },
      
*/
.a{
    font-size: 14px;
    margin: 12px;
    /*Variable:Ignore*/
    padding: 12px;
}
```

after : 

```css

.a{
    font-size: var(--zd_size14);
    margin: var(--zd_size12);
    /*Variable:Ignore*/
    padding: 12px;
}
```

Output configuration : 

Consider the below mentioned :
```json
    "errorLog": false,
    "errorInConsole": false,
    "errorsAllowed":{
      "DECLARATION_IGNORED" : true,
      "UNIT_ERROR" : true,
      "RANGE_ERROR" : true,
      "DECIMAL_CHECK":true,
      "DECIMAL_REJECT":true,
      "VARIABLE_PRESENT" : true
    },
```
. if an error log is necessary, a physical file `css_error.log` will be created in the source directory upon making `errorLog` true. will take generally more than usual time to write in the file, so delay in build is present.

. if error is needed to be seen in the console, `errorInConsole` should be enabled, all errors will be printed in the console.

. Individual errors can be enabled in `errorsAllowed` to collaboratively produce the error log file / errors in console. Here each of the errors mean the following : 

=> `DECLARATION_IGNORED` : Lines that succeed the /*Variable:Ignore*/ comment.
=> `UNIT_ERROR` : the units that are not present in the corresponding property's `allowed` array are used.
=> `RANGE_ERROR` : numerical values that are not present within the range of the corresponding property's `range` is used.
=> `DECIMAL_CHECK` : Decimal values containing . will be shown ( flex : 1.3 )
=> `DECIMAL_REJECT` : Decimal values such as .em which are to be rejected are shown ( font-size : 12.5px )
=> `VARIABLE_PRESENT` : conversion to px (Step 2) wasn't done properly and hence there are residues that contain `var` in it are found.
=> `MULTIPLE_OCCURANCES` : using --vars in multiple places ( using --zd_avatar_padding_left in left and right ), which results in confusion during conversion 

. --variables can be checked and debugged when the `strictMode` flag is enabled in `cssVariableReplacementOptions.json` file. The variables unassigned will be logged in the `unassignedVariable.log`. The manual assigning of all keys present will be split into `ignore` and `changes` for ignoring the variable and changing the variable respectively. 

* First two conversions are to be done manually by the use of the commands, `npm run variable:addignore` and `npm run variable:convert`
* Final conversion is done by react-cli on compilation of the source folder `npm run start --app:port=**** --app:domain=****`
