# Typed components and recursive children
Build a component with createElement, group its children in a Fragment, and render textual children.

## APIs demonstrated

- [createElement](/reference/functions/create-element/) from `@pibbl/core`
- [Fragment](/reference/overview/) from `@pibbl/core`
- [PibblComponent](/reference/types/elements-components/) from `@pibbl/core`
- [PibblElement](/reference/types/elements-components/) from `@pibbl/core`
- [PibblElementType](/reference/types/elements-components/) from `@pibbl/core`
- [PibblKey](/reference/types/elements-components/) from `@pibbl/core`
- [PibblNode](/reference/types/elements-components/) from `@pibbl/core`
- [PibblNodeInput](/reference/types/elements-components/) from `@pibbl/core`
- [PibblContainerChild](/reference/types/elements-components/) from `@pibbl/core`
- [PibblEmptyNode](/reference/types/elements-components/) from `@pibbl/core`
- [PibblTextChild](/reference/types/elements-components/) from `@pibbl/core`
- [PibblTextInput](/reference/types/elements-components/) from `@pibbl/core`
- [PibblRenderResult](/reference/types/elements-components/) from `@pibbl/core`

## Complete example

[Plain source](/minimal/lifecycle/elements.tsx). Run as a browser module after the document body exists. TSX uses `jsx: "react-jsx"` and `jsxImportSource: "@pibbl/core"`.

```tsx
/** @jsxImportSource @pibbl/core */
import {
  pibbl,
  createElement,
  Fragment,
  Text,
  type PibblComponent,
  type PibblElement,
  type PibblElementType,
  type PibblKey,
  type PibblNode,
  type PibblNodeInput,
  type PibblContainerChild,
  type PibblEmptyNode,
  type PibblTextChild,
  type PibblTextInput,
  type PibblRenderResult,
} from "@pibbl/core";

const canvas = document.createElement("canvas");
canvas.width = 320;
canvas.height = 120;
document.body.append(canvas);
const Label: PibblComponent<{ value: string }> = ({ value }): PibblRenderResult => {
  const words: PibblTextChild = ["Hello ", value];
  const text: PibblTextInput = words;
  return (
    <Text
      style={{ left: 20, top: 50, font: "24px sans-serif", fill: "#267d7c" }}
    >
      {text}
    </Text>
  );
};
const component: PibblElementType<{ value: string }> = Label;
const key: PibblKey = "greeting";
const element: PibblElement<{ value: string }> = createElement(component, {
  value: "Pibbl",
  key,
});
const empty: PibblEmptyNode = null;
const nodes: PibblNode = [element, empty];
const input: PibblNodeInput = nodes;
const children: PibblContainerChild = input;
const controller = pibbl(canvas, <Fragment>{children}</Fragment>);
window.addEventListener("pagehide", () => controller.dispose(), { once: true });

```

## Usage notes

- Textual values belong inside Text; arbitrary strings are not general scene nodes. Components are synchronous and createElement is equivalent to automatic JSX.

## Documentation version

Documentation built with @pibbl/core 0.0.2, revision 272a94a. ALPHA — NOT FOR PRODUCTION USE.
