From cc328d8756ac23afa26d4f5ca77a36e5216ca96b Mon Sep 17 00:00:00 2001 From: Vlad Grecu Date: Sun, 16 Feb 2025 15:25:42 +0200 Subject: [PATCH] feat/THQ-4151 Support Dynamic values and Expression as operand of a Conditional Element --- .../src/node-handlers/node-to-html/utils.ts | 16 +++++++++++- .../src/node-handlers/node-to-jsx/utils.ts | 25 ++++++++++++++++++- packages/teleport-types/src/uidl.ts | 2 +- .../src/decoders/utils.ts | 7 +++++- 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/packages/teleport-plugin-common/src/node-handlers/node-to-html/utils.ts b/packages/teleport-plugin-common/src/node-handlers/node-to-html/utils.ts index ddb21d8c0..83077cfd9 100644 --- a/packages/teleport-plugin-common/src/node-handlers/node-to-html/utils.ts +++ b/packages/teleport-plugin-common/src/node-handlers/node-to-html/utils.ts @@ -7,6 +7,8 @@ import { UIDLAttributeValue, UIDLEventHandlerStatement, UIDLElementNode, + UIDLExpressionValue, + UIDLDynamicReference, } from '@teleporthq/teleport-types' import { HTMLTemplateGenerationParams, HTMLTemplateSyntax } from './types' import { createHTMLNode } from '../../builders/hast-builders' @@ -195,7 +197,7 @@ const createConditional = ( const stringifyConditionalExpression = ( identifier: string, operation: string, - value: string | number | boolean + value: string | number | boolean | UIDLDynamicReference | UIDLExpressionValue ) => { if (typeof value === 'boolean') { return `${value ? '' : '!'}${identifier}` @@ -205,5 +207,17 @@ const stringifyConditionalExpression = ( return `${identifier} ${operation} '${value}'` } + if (typeof value === 'number') { + return `${identifier} ${operation} ${value}` + } + + if (value.type === 'dynamic') { + return `${identifier} ${operation} ${value.content.id}` + } + + if (value.type === 'expr') { + return `${identifier} ${operation} ${value.content}` + } + return `${identifier} ${operation} ${value}` } diff --git a/packages/teleport-plugin-common/src/node-handlers/node-to-jsx/utils.ts b/packages/teleport-plugin-common/src/node-handlers/node-to-jsx/utils.ts index b5c407fd2..0b13a3978 100644 --- a/packages/teleport-plugin-common/src/node-handlers/node-to-jsx/utils.ts +++ b/packages/teleport-plugin-common/src/node-handlers/node-to-jsx/utils.ts @@ -4,6 +4,7 @@ import { convertToBinaryOperator, convertToUnaryOperator, convertValueToLiteral, + getExpressionFromUIDLExpressionNode, } from '../../utils/ast-utils' import { StringUtils, UIDLUtils } from '@teleporthq/teleport-shared' import { @@ -284,7 +285,7 @@ export const createConditionalJSXExpression = ( export const createBinaryExpression = ( condition: { operation: string - operand?: string | number | boolean + operand?: string | number | boolean | UIDLDynamicReference | UIDLExpressionValue }, conditionalIdentifier: ConditionalIdentifier, t = types @@ -308,6 +309,28 @@ export const createBinaryExpression = ( } if (operand !== undefined) { + if (typeof operand === 'object' && 'type' in operand && operand.type === 'expr') { + const exprIdentifier = getExpressionFromUIDLExpressionNode(operand) + + return t.binaryExpression(convertToBinaryOperator(operation), identifier, exprIdentifier) + } + + if (typeof operand === 'object' && 'type' in operand && operand.type === 'dynamic') { + const dynamicValueIdentifier = createDynamicValueExpression(operand, { + dynamicReferencePrefixMap: { + prop: 'props', + state: '', + local: '', + }, + }) + + return t.binaryExpression( + convertToBinaryOperator(operation), + identifier, + dynamicValueIdentifier + ) + } + const stateValueIdentifier = convertValueToLiteral(operand, conditionalIdentifier.type) return t.binaryExpression(convertToBinaryOperator(operation), identifier, stateValueIdentifier) diff --git a/packages/teleport-types/src/uidl.ts b/packages/teleport-types/src/uidl.ts index 05d3c3e26..a09ff2f21 100755 --- a/packages/teleport-types/src/uidl.ts +++ b/packages/teleport-types/src/uidl.ts @@ -532,7 +532,7 @@ export interface UIDLConditionalNode { export interface UIDLConditionalExpression { conditions: Array<{ operation: string - operand?: string | boolean | number + operand?: string | boolean | number | UIDLDynamicReference | UIDLExpressionValue }> // In the code generation phase, we are only supporting 'all' or '||' // Maybe the type checking for this can be improved. diff --git a/packages/teleport-uidl-validator/src/decoders/utils.ts b/packages/teleport-uidl-validator/src/decoders/utils.ts index 5085df275..b698f24a5 100644 --- a/packages/teleport-uidl-validator/src/decoders/utils.ts +++ b/packages/teleport-uidl-validator/src/decoders/utils.ts @@ -784,7 +784,12 @@ export const conditionalNodeDecoder: Decoder = object({ condition: optional( object({ conditions: array( - object({ operation: string(), operand: optional(union(string(), number(), boolean())) }) + object({ + operation: string(), + operand: optional( + union(string(), number(), boolean(), dynamicValueDecoder, expressionValueDecoder) + ), + }) ), matchingCriteria: optional(string()), })