From 8c5e709af0fbd3a2ba00ad03b96ac2d1ead07bee Mon Sep 17 00:00:00 2001 From: Grant Wong Date: Mon, 10 Mar 2025 16:50:48 +1100 Subject: [PATCH] Throw error if css function call used inside object in unsupported way --- .../babel-plugin/src/utils/css-builders.ts | 14 +++++++++++++- .../babel-plugin/src/utils/is-compiled.ts | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/babel-plugin/src/utils/css-builders.ts b/packages/babel-plugin/src/utils/css-builders.ts index aa8a98f1d..36b2e31e6 100644 --- a/packages/babel-plugin/src/utils/css-builders.ts +++ b/packages/babel-plugin/src/utils/css-builders.ts @@ -17,6 +17,7 @@ import { isCompiledCSSTaggedTemplateExpression, isCompiledKeyframesCallExpression, isCompiledKeyframesTaggedTemplateExpression, + isCompiledStyleCall, } from './is-compiled'; import { isEmptyValue } from './is-empty'; import { @@ -591,7 +592,7 @@ const extractObjectExpression = (node: t.ObjectExpression, meta: Metadata): CSSO if (t.isArrowFunctionExpression(propValue)) { /* - Given statments like: + Given statements like: fontWeight: (props) => props.isBold ? 'bold': 'normal', marginTop: (props) => `${props.isLast ? 5 : 10}px`, @@ -647,6 +648,17 @@ const extractObjectExpression = (node: t.ObjectExpression, meta: Metadata): CSSO return; } + if (isCompiledStyleCall(propValue, updatedMeta.state)) { + throw new Error( + "You can't use Compiled APIs like this within an object.\n\n" + + `This is the invalid code: ${generate(node).code}\n\n` + + "Usually this happens because you're referencing some styles using syntax like `styles['someString']`. We don't support this for `css` function calls. Instead, you should either:\n" + + '- change it to not use square brackets, like `styles.hello`\n' + + '- if you need to use square brackets (e.g. you are styling something like `styles[someKey]`), use the cssMap API instead -- https://compiledcssinjs.com/docs/api-cssmap\n\n' + + 'If you triggered this error through another way, we want to know about it! Please report this error message and your code to us, either (for Atlassian employees) on #help-compiled or (non-employees) on GitHub.' + ); + } + const { expression, variableName } = getVariableDeclaratorValueForOwnPath( propValue, updatedMeta diff --git a/packages/babel-plugin/src/utils/is-compiled.ts b/packages/babel-plugin/src/utils/is-compiled.ts index 6bf3145fc..54a251164 100644 --- a/packages/babel-plugin/src/utils/is-compiled.ts +++ b/packages/babel-plugin/src/utils/is-compiled.ts @@ -135,3 +135,22 @@ export const isCompiledStyledTaggedTemplateExpression = ( t.isTaggedTemplateExpression(node) && (isCompiledStyledMemberExpression(node.tag, state) || isCompiledStyledCompositionCallExpression(node.tag, state)); + +/** Returns true if and only if the current node is one of the following: + * - A usage of the `css` API from Compiled + * - A usage + * - A usage of the `styled` API from Compiled + * - IS NOT a usage of the `keyframes` API from Compiled + */ +export const isCompiledStyleCall = (node: t.Expression, state: State): boolean => { + const checkers = [ + isCompiledCSSCallExpression, + isCompiledCSSTaggedTemplateExpression, + isCompiledCSSMapCallExpression, + isCompiledStyledCompositionCallExpression, + isCompiledStyledCallExpression, + isCompiledStyledTaggedTemplateExpression, + ]; + + return checkers.some((checker) => checker(node, state)); +};