Skip to main content
The getComponentData function extracts the underlying component data from a child builder function by inspecting its AST structure. It unwraps modifiers to find the core component and returns its name and props.
getComponentData(child: () => Component): ComponentData

Parameters

  • child - A function that returns a component

Returns

Returns a ComponentData object containing:
interface ComponentData {
  name: string | null;    // The name of the component, or null if not found
  props: Record<string, any>;  // The props of the component
}

Usage

Extract component information

const body = () => {
  const data = getComponentData(() => Text("Hello World"))

  // data = { name: "Text", props: { text: "Hello World" } }

  return VStack([
    Text(`Component name: ${data.name}`),
    Text(`Component props: ${JSON.stringify(data.props)}`)
  ])
}

Inspect modified components

The function unwraps modifiers like ModifiedComponent or DOMIdentifiable to find the core component:
const body = () => {
  const data = getComponentData(() =>
    Text("Styled Text")
      .foregroundStyle(Color("blue"))
      .font(18)
      .bold()
  )

  // data = { name: "Text", props: { text: "Styled Text" } }
  // Modifiers are unwrapped to get the base component

  return Text(`Found component: ${data.name}`)
}

Conditional rendering based on component type

const body = (props, children) => {
  const childData = getComponentData(() => children[0])

  if (childData.name === "Image") {
    return VStack([
      Text("Image detected"),
      children[0]
    ])
  } else if (childData.name === "Video") {
    return VStack([
      Text("Video detected"),
      children[0]
    ])
  } else {
    return children[0]
  }
}

Validating child component types

const ImageCard = (props, children) => {
  const childData = getComponentData(() => children[0])

  if (childData.name !== "Image") {
    console.warn(`ImageCard expects an Image child, but received: ${childData.name}`)
  }

  return VStack([
    Text(props.title),
    children[0]
  ])
    .padding(16)
    .background(Color("white"))
    .cornerRadius(8)
}

Creating wrapper components with introspection

const SmartContainer = (props, children) => {
  // Analyze all children to determine layout
  const childTypes = children.map(child => {
    const data = getComponentData(() => child)
    return data.name
  })

  const hasImages = childTypes.some(type => type === "Image")
  const hasVideos = childTypes.some(type => type === "Video")

  // Apply different layouts based on content type
  if (hasImages || hasVideos) {
    return VStack({ spacing: 20 }, children)
  } else {
    return VStack({ spacing: 10 }, children)
  }
}

Extracting props for debugging

const DebugWrapper = (props, children) => {
  const data = getComponentData(() => children[0])

  return VStack([
    Text(`Component: ${data.name}`)
      .font(12)
      .foregroundStyle(Color("gray")),
    Text(`Props: ${JSON.stringify(data.props, null, 2)}`)
      .font(10)
      .monospaced(),
    Divider(),
    children[0]
  ])
    .padding(8)
    .border({ style: Color("gray"), width: 1 })
}

Notes

  • The function inspects the component’s AST structure to retrieve information
  • Modifiers are automatically unwrapped to find the core component
  • If the component cannot be identified, name will be null
  • The returned props are the direct props passed to the component, not computed values
  • This is useful for creating wrapper components that need to inspect their children
  • The function does not execute the component, it only analyzes its structure
  • Custom components defined with defineComponent will return their registered name
  • Built-in components return their standard names (e.g., “Text”, “Image”, “VStack”)