From 7508d32ebd9e80eac4905bbfaf205185c4442cb4 Mon Sep 17 00:00:00 2001 From: Brijesh Bittu Date: Fri, 27 Dec 2024 10:31:24 +0530 Subject: [PATCH] Implement evaluateExpression --- packages/pigment-css-utils/package.json | 6 +- .../pigment-css-utils/src/base-processor.ts | 9 +- .../src/utils/evaluateExpresions.ts | 11 ++ packages/pigment-css-utils/src/utils/index.ts | 1 + .../src/utils/processStyle.ts | 35 +++--- pnpm-lock.yaml | 109 +++++++++++++----- 6 files changed, 117 insertions(+), 54 deletions(-) create mode 100644 packages/pigment-css-utils/src/utils/evaluateExpresions.ts diff --git a/packages/pigment-css-utils/package.json b/packages/pigment-css-utils/package.json index 8bc44e5d..e9c879d6 100644 --- a/packages/pigment-css-utils/package.json +++ b/packages/pigment-css-utils/package.json @@ -31,10 +31,10 @@ "typescript": "tsc --noEmit -p ." }, "dependencies": { - "@babel/types": "^7.26.0", - "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.3", + "@babel/parser": "^7.26.3", "@emotion/unitless": "0.10.0", - "@emotion/serialize": "^1.3.2", + "@emotion/serialize": "^1.3.3", "@pigment-css/theme": "workspace:*", "@wyw-in-js/processor-utils": "^0.5.5", "@wyw-in-js/shared": "^0.5.5", diff --git a/packages/pigment-css-utils/src/base-processor.ts b/packages/pigment-css-utils/src/base-processor.ts index 205c48f1..efcbd626 100644 --- a/packages/pigment-css-utils/src/base-processor.ts +++ b/packages/pigment-css-utils/src/base-processor.ts @@ -4,11 +4,4 @@ import { BaseProcessor as WywBaseProcessor } from '@wyw-in-js/processor-utils'; * This is going to be expanded when the react package comes into picture. * Right now, it only has the bare mimimum. */ -export default abstract class BaseProcessor extends WywBaseProcessor { - abstract getBaseClass(): string | undefined; - - get asSelector(): string { - const baseClass = this.getBaseClass(); - return `.${baseClass ?? this.className}`; - } -} +export default abstract class BaseProcessor extends WywBaseProcessor {} diff --git a/packages/pigment-css-utils/src/utils/evaluateExpresions.ts b/packages/pigment-css-utils/src/utils/evaluateExpresions.ts new file mode 100644 index 00000000..c7290654 --- /dev/null +++ b/packages/pigment-css-utils/src/utils/evaluateExpresions.ts @@ -0,0 +1,11 @@ +/** + * Slightly unsafe but way faster way to evaluate JS code than using babel transforms. + * + * @param expressionString The JS code expression to evaluate + */ +export function evaluateClassNameArg(expressionString: string): T { + // Create sandbox context + const context = Object.create(null); + const safeEval = new Function('context', `with(context) { return ${expressionString}; }`); + return safeEval(context); +} diff --git a/packages/pigment-css-utils/src/utils/index.ts b/packages/pigment-css-utils/src/utils/index.ts index 2d38cfce..e1c3f79d 100644 --- a/packages/pigment-css-utils/src/utils/index.ts +++ b/packages/pigment-css-utils/src/utils/index.ts @@ -1,3 +1,4 @@ export * from './processStyle'; export * from './valueToLiteral'; export * from './parseExpressions'; +export * from './evaluateExpresions'; diff --git a/packages/pigment-css-utils/src/utils/processStyle.ts b/packages/pigment-css-utils/src/utils/processStyle.ts index 2613eafa..7d4b1029 100644 --- a/packages/pigment-css-utils/src/utils/processStyle.ts +++ b/packages/pigment-css-utils/src/utils/processStyle.ts @@ -26,12 +26,17 @@ export type ProcessStyleReturn = { variables: Record; }; +export type ClassNameOptions = + | { + variantName: string; + variantValue: string; + } + | { + isCv: true; + }; + export type ProcessStyleObjectsOptions = ProcessStyleOptions & { - getClassName: ( - variantName: string | undefined, - variantValue: string | undefined, - isCv?: boolean, - ) => string; + getClassName: (opts?: ClassNameOptions) => string; }; export type StyleObjectReturn = { @@ -138,7 +143,7 @@ function getCss( if (typeof style === 'string') { result.base.push({ cssText: serializeStyles([style]).styles, - className: cssesc(getClassName(undefined, undefined)), + className: cssesc(getClassName()), variables: {}, serializables: {}, }); @@ -152,7 +157,7 @@ function getCss( const { result: baseObj, variables } = processStyle(style, { getVariableName }); const cssText = serializeStyles([baseObj as any]).styles; result.base.push({ - className: getClassName(undefined, undefined), + className: getClassName(), cssText, variables, serializables: {}, @@ -163,7 +168,10 @@ function getCss( const variantData = variants[variantName]; Object.keys(variantData).forEach((variantValue) => { const cssObjOrStr = variantData[variantValue]; - const className = getClassName(variantName, variantValue); + const className = getClassName({ + variantName, + variantValue, + }); const serializables = { [variantName]: variantValue, }; @@ -190,7 +198,7 @@ function getCss( } if (compoundVariants && compoundVariants.length > 0) { compoundVariants.forEach(({ css, ...rest }, cvIndex) => { - const className = `${getClassName(undefined, undefined, true)}-cv${cvIndex ? `-${cvIndex}` : ''}`; + const className = `${getClassName({ isCv: true })}-cv${cvIndex ? `-${cvIndex}` : ''}`; const serializables = rest; if (typeof css === 'string') { result.compoundVariants.push({ @@ -231,12 +239,9 @@ export function processStyleObjects( styles.reduce((acc, style, index) => { const res = getCss(style, { ...options, - getClassName: ( - variantName: string | undefined, - variantValue: string | undefined, - isCv?: boolean, - ) => { - const base = options.getClassName(variantName, variantValue); + getClassName: (opts?: ClassNameOptions) => { + const isCv = opts && 'isCv' in opts && opts.isCv; + const base = options.getClassName(opts); if (index > 0) { return `${base}${isCv ? '-cv' : ''}-${index}`; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ab5f71ed..964d9918 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -652,14 +652,14 @@ importers: packages/pigment-css-utils: dependencies: '@babel/parser': - specifier: ^7.26.2 - version: 7.26.2 + specifier: ^7.26.3 + version: 7.26.3 '@babel/types': specifier: ^7.26.0 version: 7.26.0 '@emotion/serialize': - specifier: ^1.3.2 - version: 1.3.2 + specifier: ^1.3.3 + version: 1.3.3 '@emotion/unitless': specifier: 0.10.0 version: 0.10.0 @@ -766,6 +766,10 @@ packages: resolution: {integrity: sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==} engines: {node: '>=6.9.0'} + '@babel/generator@7.26.3': + resolution: {integrity: sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==} + engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.25.9': resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} engines: {node: '>=6.9.0'} @@ -869,6 +873,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.26.3': + resolution: {integrity: sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9': resolution: {integrity: sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==} engines: {node: '>=6.9.0'} @@ -1341,6 +1350,10 @@ packages: resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==} engines: {node: '>=6.9.0'} + '@babel/traverse@7.26.4': + resolution: {integrity: sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==} + engines: {node: '>=6.9.0'} + '@babel/types@7.26.0': resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} engines: {node: '>=6.9.0'} @@ -1418,6 +1431,9 @@ packages: '@emotion/serialize@1.3.2': resolution: {integrity: sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==} + '@emotion/serialize@1.3.3': + resolution: {integrity: sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==} + '@emotion/sheet@1.4.0': resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==} @@ -1442,6 +1458,9 @@ packages: '@emotion/utils@1.4.1': resolution: {integrity: sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA==} + '@emotion/utils@1.4.2': + resolution: {integrity: sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==} + '@emotion/weak-memoize@0.4.0': resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} @@ -8995,7 +9014,15 @@ snapshots: '@babel/generator@7.26.2': dependencies: - '@babel/parser': 7.26.2 + '@babel/parser': 7.26.3 + '@babel/types': 7.26.0 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.0.2 + + '@babel/generator@7.26.3': + dependencies: + '@babel/parser': 7.26.3 '@babel/types': 7.26.0 '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 @@ -9007,7 +9034,7 @@ snapshots: '@babel/helper-builder-binary-assignment-operator-visitor@7.25.9': dependencies: - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.4 '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color @@ -9028,7 +9055,7 @@ snapshots: '@babel/helper-optimise-call-expression': 7.25.9 '@babel/helper-replace-supers': 7.25.9(@babel/core@7.26.0) '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.4 semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -9053,7 +9080,7 @@ snapshots: '@babel/helper-member-expression-to-functions@7.25.9': dependencies: - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.4 '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color @@ -9070,7 +9097,7 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-module-imports': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.4 transitivePeerDependencies: - supports-color @@ -9085,7 +9112,7 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-annotate-as-pure': 7.25.9 '@babel/helper-wrap-function': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.4 transitivePeerDependencies: - supports-color @@ -9094,20 +9121,20 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-member-expression-to-functions': 7.25.9 '@babel/helper-optimise-call-expression': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.4 transitivePeerDependencies: - supports-color '@babel/helper-simple-access@7.25.9': dependencies: - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.4 '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.25.9': dependencies: - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.4 '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color @@ -9121,7 +9148,7 @@ snapshots: '@babel/helper-wrap-function@7.25.9': dependencies: '@babel/template': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.4 '@babel/types': 7.26.0 transitivePeerDependencies: - supports-color @@ -9145,11 +9172,15 @@ snapshots: dependencies: '@babel/types': 7.26.0 + '@babel/parser@7.26.3': + dependencies: + '@babel/types': 7.26.0 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.4 transitivePeerDependencies: - supports-color @@ -9176,7 +9207,7 @@ snapshots: dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.4 transitivePeerDependencies: - supports-color @@ -9230,7 +9261,7 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.26.0) - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.4 transitivePeerDependencies: - supports-color @@ -9276,7 +9307,7 @@ snapshots: '@babel/helper-compilation-targets': 7.25.9 '@babel/helper-plugin-utils': 7.25.9 '@babel/helper-replace-supers': 7.25.9(@babel/core@7.26.0) - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.4 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -9340,7 +9371,7 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-compilation-targets': 7.25.9 '@babel/helper-plugin-utils': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.4 transitivePeerDependencies: - supports-color @@ -9387,7 +9418,7 @@ snapshots: '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) '@babel/helper-plugin-utils': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.4 transitivePeerDependencies: - supports-color @@ -9731,14 +9762,26 @@ snapshots: '@babel/template@7.25.9': dependencies: '@babel/code-frame': 7.26.2 - '@babel/parser': 7.26.2 + '@babel/parser': 7.26.3 '@babel/types': 7.26.0 '@babel/traverse@7.25.9': dependencies: '@babel/code-frame': 7.26.2 '@babel/generator': 7.26.2 - '@babel/parser': 7.26.2 + '@babel/parser': 7.26.3 + '@babel/template': 7.25.9 + '@babel/types': 7.26.0 + debug: 4.3.7(supports-color@8.1.1) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/traverse@7.26.4': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.3 + '@babel/parser': 7.26.3 '@babel/template': 7.25.9 '@babel/types': 7.26.0 debug: 4.3.7(supports-color@8.1.1) @@ -9797,7 +9840,7 @@ snapshots: '@babel/runtime': 7.26.0 '@emotion/hash': 0.9.2 '@emotion/memoize': 0.9.0 - '@emotion/serialize': 1.3.2 + '@emotion/serialize': 1.3.3 babel-plugin-macros: 3.1.0 convert-source-map: 1.9.0 escape-string-regexp: 4.0.0 @@ -9873,6 +9916,14 @@ snapshots: '@emotion/utils': 1.4.1 csstype: 3.1.3 + '@emotion/serialize@1.3.3': + dependencies: + '@emotion/hash': 0.9.2 + '@emotion/memoize': 0.9.0 + '@emotion/unitless': 0.10.0 + '@emotion/utils': 1.4.2 + csstype: 3.1.3 + '@emotion/sheet@1.4.0': {} '@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1)': @@ -9917,6 +9968,8 @@ snapshots: '@emotion/utils@1.4.1': {} + '@emotion/utils@1.4.2': {} + '@emotion/weak-memoize@0.4.0': {} '@esbuild/aix-ppc64@0.21.5': @@ -10617,7 +10670,7 @@ snapshots: dependencies: '@babel/runtime': 7.26.0 '@emotion/cache': 11.13.1 - '@emotion/serialize': 1.3.2 + '@emotion/serialize': 1.3.3 '@emotion/sheet': 1.4.0 csstype: 3.1.3 prop-types: 15.8.1 @@ -10630,7 +10683,7 @@ snapshots: dependencies: '@babel/runtime': 7.26.0 '@emotion/cache': 11.13.1 - '@emotion/serialize': 1.3.2 + '@emotion/serialize': 1.3.3 '@emotion/sheet': 1.4.0 csstype: 3.1.3 prop-types: 15.8.1 @@ -11450,7 +11503,7 @@ snapshots: '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.26.2 + '@babel/parser': 7.26.3 '@babel/types': 7.26.0 '@types/babel__traverse@7.20.5': @@ -13700,7 +13753,7 @@ snapshots: estree-to-babel@3.2.1: dependencies: - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.4 '@babel/types': 7.26.0 c8: 7.14.0 transitivePeerDependencies: @@ -14914,7 +14967,7 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: '@babel/core': 7.26.0 - '@babel/parser': 7.26.2 + '@babel/parser': 7.26.3 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1