Skip to content

Commit

Permalink
(feat): add object attribute for the UIDLElement to pass objects as p…
Browse files Browse the repository at this point in the history
…rops for components
  • Loading branch information
JayaKrishnaNamburu committed Sep 19, 2024
1 parent ed0d0df commit 64d958b
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
generateDynamicWindowImport,
addDynamicExpressionAttributeToJSXTag,
resolveObjectValue,
objectToObjectExpression,
} from '../../utils/ast-utils'
import { createJSXTag, createSelfClosingJSXTag } from '../../builders/ast-builders'
import { DEFAULT_JSX_OPTIONS } from './constants'
Expand Down Expand Up @@ -167,6 +168,19 @@ const addAttributesToJSXTag = (
)

break

case 'object': {
const content = attributeValue.content
if (typeof content !== 'object') {
return
}
const expression = objectToObjectExpression(content as Record<string, unknown>)
elementTag.openingElement.attributes.push(
types.jsxAttribute(types.jsxIdentifier(attrKey), types.jsxExpressionContainer(expression))
)
break
}

default:
throw new Error(
`generateElementNode could not generate code for attribute of type ${JSON.stringify(
Expand Down
15 changes: 12 additions & 3 deletions packages/teleport-plugin-html-base-component/src/node-handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,10 +339,15 @@ const generateComponentContent = async (
const combinedStates = { ...stateDefinitions, ...(componentClone?.stateDefinitions || {}) }
const statesForInstance = Object.keys(combinedStates).reduce(
(acc: Record<string, UIDLStateDefinition>, propKey) => {
if (attrs[propKey]) {
const attr = attrs[propKey]
if (attr.type === 'object') {
throw new Error(`Object attributes are not supported in html exports`)
}

if (attr) {
acc[propKey] = {
...combinedStates[propKey],
defaultValue: attrs[propKey]?.content || combinedStates[propKey]?.defaultValue,
defaultValue: attr?.content || combinedStates[propKey]?.defaultValue,
}
} else {
acc[propKey] = combinedStates[propKey]
Expand All @@ -359,6 +364,10 @@ const generateComponentContent = async (
// the component instance that we are using here.
for (const propKey of Object.keys(combinedProps)) {
const prop = attrs[propKey]
if (prop?.type === 'object') {
throw new Error(`Object attributes are not supported in html exports`)
}

if (prop?.type === 'element') {
propsForInstance[propKey] = {
...combinedProps[propKey],
Expand Down Expand Up @@ -394,7 +403,7 @@ const generateComponentContent = async (
} else if (prop) {
propsForInstance[propKey] = {
...combinedProps[propKey],
defaultValue: attrs[propKey]?.content || combinedProps[propKey]?.defaultValue,
defaultValue: prop?.content || combinedProps[propKey]?.defaultValue,
}
} else {
const propFromCurrentComponent = combinedProps[propKey]
Expand Down
7 changes: 6 additions & 1 deletion packages/teleport-shared/src/utils/uidl-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,11 @@ export const traverseNodes = (
const { attrs, children, style, abilities, referencedStyles } = node.content
if (attrs) {
Object.keys(attrs).forEach((attrKey) => {
traverseNodes(attrs[attrKey], fn, node)
const attr = attrs[attrKey]
if (attr.type === 'object') {
return
}
traverseNodes(attr, fn, node)
})
}

Expand Down Expand Up @@ -902,6 +906,7 @@ export const transformAttributesAssignmentsToJson = (
return acc
}

case 'object':
case 'element':
acc[key] = attributeContent as UIDLAttributeValue
return acc
Expand Down
6 changes: 6 additions & 0 deletions packages/teleport-types/src/uidl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,11 @@ export interface UIDLCMSItemNode {
content: UIDLCMSItemNodeContent
}

export interface UIDLObjectValue {
type: 'object'
content: unknown
}

export interface UIDLCMSMixedTypeNode {
type: 'cms-mixed-type'
content: {
Expand Down Expand Up @@ -547,6 +552,7 @@ export type UIDLAttributeValue =
| UIDLComponentStyleReference
| UIDLRawValue
| UIDLElementNode
| UIDLObjectValue

export type UIDLStyleValue = UIDLDynamicReference | UIDLStaticValue

Expand Down
3 changes: 3 additions & 0 deletions packages/teleport-uidl-resolver/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,9 @@ const resolveRepeat = (repeatContent: UIDLRepeatContent, parentNode: UIDLNode) =
if (dataSourceValue.type === 'element') {
throw new Error(`Dynamic data source for repeat cannot be an element`)
}
if (dataSourceValue.type === 'object') {
throw new Error(`Data source for repeat cannot be an object`)
}
repeatContent.dataSource = dataSourceValue
// remove original attribute so it is not added as a static/dynamic value on the node
delete parentElement.attrs[nodeDataSourceAttr]
Expand Down
10 changes: 9 additions & 1 deletion packages/teleport-uidl-validator/src/decoders/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
intersection,
withDefault,
anyJson,
unknownJson,
} from '@mojotech/json-type-validation'
import {
UIDLStaticValue,
Expand Down Expand Up @@ -93,6 +94,7 @@ import {
VUIDLCMSMixedTypeNode,
UIDLLocalFontAsset,
VUIDLPropDefinitions,
UIDLObjectValue,
} from '@teleporthq/teleport-types'
import {
isValidElementName,
Expand Down Expand Up @@ -507,7 +509,8 @@ export const attributeValueDecoder: Decoder<VUIDLAttributeValue> = union(
importReferenceDecoder,
rawValueDecoder,
lazy(() => uidlComponentStyleReference),
lazy(() => elementNodeDecoder)
lazy(() => elementNodeDecoder),
lazy(() => objectValueDecoder)
)

export const uidlComponentStyleReference: Decoder<UIDLComponentStyleReference> = object({
Expand Down Expand Up @@ -683,6 +686,11 @@ export const designTokensDecoder: Decoder<VUIDLDesignTokens> = dict(
union(staticValueDecoder, string(), number())
)

export const objectValueDecoder: Decoder<UIDLObjectValue> = object({
type: constant('object'),
content: unknownJson(),
})

export const elementDecoder: Decoder<VUIDLElement> = object({
elementType: string(),
semanticType: optional(string()),
Expand Down

0 comments on commit 64d958b

Please sign in to comment.