Skip to content

Latest commit

 

History

History
342 lines (321 loc) · 9 KB

migration.md

File metadata and controls

342 lines (321 loc) · 9 KB

Antd v5 Style Migration

  • Clone the source code of react-antd
git clone https://github.com/ant-design/ant-design.git

After cloning, the directory tree is as follows:

ant-design/
ant-design-blazor/
 ├── cssincs.json

ant-design: is the source code of the React project.
ant-design-blazor: is the source code of the Blazor project.

For stable version, please use the git tag version

  • Install the generator
dotnet tool install -g CssInCSharp.CommandLine
  • Create profile

Create a cssincs.json under the root path of the blazor project, as follows:

{
  "Converter": "Ts",
  "CsOptions": {
    "Usings": [
      "System",
      "AntDesign",
      "CssInCSharp",
      "CssInCSharp.Colors",
      "static AntDesign.GlobalStyle",
      "static AntDesign.Theme",
      "static AntDesign.StyleUtil",
      "static AntDesign.PresetColors",
      "Keyframes = CssInCSharp.Keyframe"
    ],
    "Namespace": "AntDesign.Styles",
    "NamePrefix": "{dir:../../}",
    "DefaultReturnType": "object",
    "DefaultParameterType": "object",
    "DefaultVariableType": "object",
    "DefaultExportType": "object",
    "DefaultExportClassName": "{dir:../../}Style",
    "DefaultExportMethodName": "{file}Default",
    "UsePascalCase": true,
    "UsePartialClass": true,
    "UseStaticMethod": true,
    "Replacements": [
      {
        "Pattern": "class ComponentToken",
        "Value": "class ComponentToken : TokenWithCommonCls"
      },
      {
        "Pattern": "FullToken(\\<\\w*\\>)?",
        "Value": "ComponentToken"
      },
      {
        "Pattern": "(?<!var) gen(\\w+)",
        "Value": " Gen$1"
      },
      {
        "Pattern": "prepare(\\w+)",
        "Value": "Prepare$1"
      },
      {
        "Pattern": "(?<!token.)Calc\\(",
        "Value": "calc("
      },
      {
        "Pattern": "_skip_check_",
        "Value": "SkipCheck"
      },
      {
        "Pattern": "= textEllipsis",
        "Value": "= TextEllipsis"
      },
      {
        "Pattern": "= AvatarSizeStyle",
        "Value": "= avatarSizeStyle"
      },
      {
        "Pattern": "= GetCompactBorderStyle",
        "Value": "= getCompactBorderStyle"
      },
      {
        "Pattern": "CSSObject\\[\\]",
        "Value": "CSSInterpolation[]"
      },
      {
        "Pattern": "ButtonVariantType variant",
        "Value": "string variant = null"
      },
      {
        "Pattern": "variant &&",
        "Value": "variant == null &&"
      },
      {
        "Pattern": "var genDisabledButtonStyle",
        "Value": "Func<ButtonToken, CSSObject> genDisabledButtonStyle"
      },
      {
        "Pattern": "= GenDisabledButtonStyle",
        "Value": "= genDisabledButtonStyle"
      },
      {
        "Pattern": "PresetColorKey",
        "Value": "string"
      },
      {
        "Pattern": "token\\[(\\$@\"[^\"]+\")\\]",
        "Value": "token[$1].ToString()"
      },
      {
        "Pattern": "Unitless = new GenOptions",
        "Value": "Unitless = new"
      },
      {
        "Pattern": "getCompactBorderStyle\\(\\)",
        "Value": "getCompactBorderStyle(false)"
      },
      {
        "Pattern": "CSSObject hoverStyle, CSSObject activeStyle",
        "Value": "CSSObject hoverStyle = null, CSSObject activeStyle = null"
      },
      {
        "Pattern": "getColumnsStyle;",
        "Value": "GetColumnsStyle;"
      }
    ]
  },
  "Include": [
    {
      "Src": "../ant-design/components/**/style/*.ts",
      "Dest": "./components"
    }
  ],
  "Exclude": [
    "../ant-design/components/style/*.ts",
    "../ant-design/components/qrcode/style/*.ts"
  ],
  "TypeInferences": [
    {
      "RuleName": "ObjectTypeInfer_CSSObject",
      "Expression": "Kind == \"ObjectType\" && ((HasIndexer && Properties == null) || HasAny(\"margin\", \"width\", \"display\", \"position\", \"color\", \"direction\", \"flex\", \"background\"))",
      "Actions": {
        "OnSuccess": {
          "Name": "OutputExpression",
          "Context": {
            "Expression": "\"CSSObject\""
          }
        }
      }
    },
    {
      "RuleName": "ObjectTypeInfer_PropertySkip",
      "Expression": "Kind == \"ObjectType\" && HasKey(\"_skip_check_\")",
      "Actions": {
        "OnSuccess": {
          "Name": "OutputExpression",
          "Context": {
            "Expression": "\"PropertySkip\""
          }
        }
      }
    },
    {
      "RuleName": "ObjectTypeInfer_GenOptions",
      "Expression": "Kind == \"ObjectType\" && HasAny(\"deprecatedTokens\", \"unitless\")",
      "Actions": {
        "OnSuccess": {
          "Name": "OutputExpression",
          "Context": {
            "Expression": "\"GenOptions\""
          }
        }
      }
    },
    {
      "RuleName": "ReturnTypeInfer_CSSInterpolation_Size",
      "Expression": "Kind == \"ReturnType\" && FunctionName.StartsWith(\"genSize\")",
      "Actions": {
        "OnSuccess": {
          "Name": "OutputExpression",
          "Context": {
            "Expression": "\"CSSInterpolation\""
          }
        }
      }
    },
    {
      "RuleName": "ReturnTypeInfer_CSSObject",
      "Expression": "Kind == \"ReturnType\" && FunctionName.EndsWith(\"Style\")",
      "Actions": {
        "OnSuccess": {
          "Name": "OutputExpression",
          "Context": {
            "Expression": "\"CSSObject\""
          }
        }
      }
    },
    {
      "RuleName": "ReturnTypeInfer_Token",
      "Expression": "Kind == \"ReturnType\" && FunctionName.StartsWith(\"pre\") && FunctionName.EndsWith(\"Token\")",
      "Actions": {
        "OnSuccess": {
          "Name": "OutputExpression",
          "Context": {
            "Expression": "CsOptions.NamePrefix + \"Token\""
          }
        }
      }
    },
    {
      "RuleName": "ReturnTypeInfer_UseComponentStyleResult",
      "Expression": "Kind == \"ReturnType\" && FunctionName.EndsWith(\"indexDefault\")",
      "Actions": {
        "OnSuccess": {
          "Name": "OutputExpression",
          "Context": {
            "Expression": "\"UseComponentStyleResult\""
          }
        }
      }
    },
    {
      "RuleName": "ReturnTypeInfer_CSSInterpolation",
      "Expression": "Kind == \"ReturnType\" && (FunctionName == \"genStyleHooks\" || FunctionName == \"genSubStyleComponent\") && ValueType == \"array\"",
      "Actions": {
        "OnSuccess": {
          "Name": "OutputExpression",
          "Context": {
            "Expression": "\"CSSInterpolation\""
          }
        }
      }
    },
    {
      "RuleName": "ParameterTypeInfer_Token",
      "Expression": "Kind == \"ParameterType\" && Name.EndsWith(\"token\")",
      "Actions": {
        "OnSuccess": {
          "Name": "OutputExpression",
          "Context": {
            "Expression": "FunctionName.EndsWith(\"ComponentToken\") ? \"GlobalToken\" : CsOptions.NamePrefix + \"Token\""
          }
        }
      }
    },
    {
      "RuleName": "ParameterTypeInfer_CalcColor",
      "Expression": "Kind == \"ParameterType\" && FunctionName == \"genPresetColor\"",
      "Actions": {
        "OnSuccess": {
          "Name": "OutputExpression",
          "Context": {
            "Expression": "Name.Contains(\"binding\") ? \"CalcColor\" : \"string\""
          }
        }
      }
    },
    {
      "RuleName": "ParameterTypeInfer_StringColor",
      "Expression": "Kind == \"ParameterType\" && Name.Contains(\"Color\")",
      "Actions": {
        "OnSuccess": {
          "Name": "OutputExpression",
          "Context": {
            "Expression": "\"string\""
          }
        }
      }
    },
    {
      "RuleName": "PropertyTypeInfer_String",
      "Expression": "Kind == \"PropertyType\" && UnionType != null",
      "Actions": {
        "OnSuccess": {
          "Name": "OutputExpression",
          "Context": {
            "Expression": "\"CSSProperties\""
          }
        }
      }
    }
  ]
}

Where Include and Exclude are relative to the path of the react project, if you clone with a different path, please modify this configuration.

  • Execute Convert Command

Execute the following command at the root path of the blazor project.

cssincs convert -c cssincs.json

After the command is executed, all .ts files will be converted to .cs files. If Dest specifies a folder instead of a file, the final file will be generated according to the directory of the source file.

Legacy ssues

  • Since C# doesn't support UnionType, like multiple inheritance or Pick<T>, Omit<T>, etc., are not possible.

To solve this problem, we plan to use a source generator to achieve the effect of Pick and Omit.

  • Antd-Style library is not implemented

Sample code:

var style = new
{
  container = new CSSObject
  {
    MaxWidth = 400,
    Width = '100%',
    Height = 180,
    Display = 'flex',
  },
  card = css(@"
    margin-bottom: 8px;
    cursor: pointer;
    &:hover {
      color: #DDD;
    }
  ")
}

<div class="@style.card"></div>
<div class="@cx('a-simple-create-style-demo-classname', styles.container)"></div>

To solve the above problems, you only need to implement a css() and cx() method. CssInCSharp already supports the serialization of a string or a CSSObject.