Skip to main content

Overview

The @tempad-dev/plugins package exports several helper functions that make it easier to work with design nodes and build component trees:
  • h() - Hyperscript helper for building DevComponent trees
  • raw() - Create raw markup nodes
  • Query helpers - Find and filter design nodes (findChild, findChildren, findOne, findAll, queryAll, queryOne)

h()

Hyperscript helper to compose DevComponent trees from plugin code with a clean JSX-like syntax.

Signature

function h(name: string): DevComponent<Record<string, unknown>>

function h(
  name: string,
  children: (DevComponent | string)[] | DevComponent | string
): DevComponent<Record<string, unknown>>

function h<T extends object>(
  name: string,
  props: T,
  children?: (DevComponent | string)[] | DevComponent | string
): DevComponent<T>

Parameters

name
string
required
Component name or tag to render
props
object
Optional props object with component properties
children
(DevComponent | string)[] | DevComponent | string
Optional children - can be a single child, an array of children, or a string

Returns

DevComponent
DevComponent<T>
A dev component tree node ready for serialization

Examples

Simple text node:
const text = h('Text', 'Hello world')
Component with props:
const button = h('Button', { variant: 'primary' }, ['Submit'])
Nested component tree:
const preview = h('Container', { size: 'lg' }, [
  h('Heading', { level: 2 }, ['Button']),
  h('Button', { variant: 'primary' }, ['Submit'])
])

raw()

Helper to create a raw markup node. This allows you to inject HTML or other markup directly into the component tree.

Signature

function raw(
  content: string, 
  injectedProps?: Record<string, string>
): DevComponent

Parameters

content
string
required
The raw markup content to inject
injectedProps
Record<string, string>
Optional properties to inject into the markup

Returns

DevComponent
DevComponent
A dev component with name __tempad_raw__ containing the raw content

Example

import { raw, RAW_TAG_NAME } from '@tempad-dev/plugins'

const markup = raw('<div class="custom">Content</div>', { 
  'data-id': 'custom-div' 
})
The RAW_TAG_NAME constant ('__tempad_raw__') is exported for checking if a component is a raw node.

Query Helpers

These functions help you find and filter design nodes within a component tree. All query helpers accept a NodeQuery parameter which can be:
  • A property-based query: { type: 'TEXT', name: /title/i }
  • A predicate function: (node) => node.visible && node.name.startsWith('btn')

findChild()

Find the first direct child that matches the query.

Signature

function findChild<T extends DesignNode = DesignNode>(
  node: ContainerNode,
  query: NodeQuery
): T | null

Parameters

node
ContainerNode
required
Parent container to search
query
NodeQuery
required
Predicate or property query description

Returns

The first matching direct child or null when none found.

Example

const title = findChild(component, { type: 'TEXT', name: /title/i })

findChildren()

Find all direct children that match the query.

Signature

function findChildren<T extends DesignNode = DesignNode>(
  node: ContainerNode,
  query: NodeQuery
): T[]

Parameters

node
ContainerNode
required
Parent container to search
query
NodeQuery
required
Predicate or property query description

Returns

An array of matching direct children.

Example

const icons = findChildren(toolbar, { type: 'VECTOR' })

findOne()

Depth-first search for the first node that matches the query (searches recursively through all descendants).

Signature

function findOne<T extends DesignNode = DesignNode>(
  node: ContainerNode,
  query: NodeQuery
): T | null

Parameters

node
ContainerNode
required
Root container to search recursively
query
NodeQuery
required
Predicate or property query description

Returns

The first nested node that matches or null.

Example

const submitButton = findOne(frame, { name: 'Submit' })

findAll()

Depth-first search returning every node that matches the query (searches recursively through all descendants).

Signature

function findAll<T extends DesignNode = DesignNode>(
  node: ContainerNode,
  query: NodeQuery
): T[]

Parameters

node
ContainerNode
required
Root container to search recursively
query
NodeQuery
required
Predicate or property query description

Returns

All nodes within the subtree that satisfy the query.

Example

const texts = findAll(page, { type: 'TEXT', visible: true })

queryAll()

Execute a sequence of queries, returning the final node collection. This is useful for chaining multiple query operations.

Signature

function queryAll<T extends DesignNode = DesignNode>(
  node: ContainerNode,
  queries: (NodeQuery & { query: QueryType })[]
): T[]

Parameters

node
ContainerNode
required
Root container to start the pipeline from
queries
(NodeQuery & { query: QueryType })[]
required
Ordered list describing how each query step should behaveEach query object includes a query field specifying the query type:
  • 'child' - Use findChild for this step
  • 'children' - Use findChildren for this step
  • 'one' - Use findOne for this step
  • 'all' - Use findAll for this step

Returns

The collection of nodes produced by the final query step.

Example

const buttons = queryAll(frame, [
  { query: 'children', name: 'Footer' },
  { query: 'all', type: 'INSTANCE', name: /Button/ }
])

queryOne()

Execute a sequence of queries and return only the first match.

Signature

function queryOne<T extends DesignNode = DesignNode>(
  node: ContainerNode,
  queries: (NodeQuery & { query: QueryType })[]
): T | null

Parameters

node
ContainerNode
required
Root container to start the pipeline from
queries
(NodeQuery & { query: QueryType })[]
required
Ordered list describing how each query step should behave

Returns

The first node produced by the query sequence or null.

Example

const header = queryOne(page, [
  { query: 'children', name: 'Header' },
  { query: 'child', type: 'FRAME', name: /Top Bar/ }
])

NodeQuery Type

The NodeQuery type accepts either a property-based query or a predicate function:
type NodeQuery = 
  | RequireAtLeastOne<QueryableProperties> 
  | ((node: DesignNode) => boolean)

Property-Based Queries

Query by node properties with support for:
  • Exact match: { type: 'TEXT' }
  • Array of options: { name: ['Button', 'Submit'] }
  • Regular expression: { name: /button/i }
// Exact match
findOne(frame, { type: 'TEXT' })

// Array of options
findAll(page, { name: ['Header', 'Footer'] })

// Regular expression
findChildren(toolbar, { name: /icon/i })

// Multiple properties
findOne(frame, { type: 'INSTANCE', visible: true })

Predicate Functions

Use a custom function for complex matching logic:
const largeTitles = findAll(page, (node) => 
  node.type === 'TEXT' && 
  node.name.startsWith('Title') &&
  node.visible
)

See Also