windo/API/windo()
API ReferenceFactory

windo()

windo() is the authoring entry point. You call it once per *.windo.tsx file and return a single definition object — that object is the complete description of one canvas entry: what component renders, with which props, in what variants, under which contexts, and how its state evolves.

The factory

windo() does not come from a package import. defineWindoConfig() returns it bound to your project's groups and contexts, so the group field is checked against your configured slugs and the factory argument carries your context registry. You pass windo() a function; the function receives that argument and returns a WindoDefinition.

The function body runs once, at definition time — that is where static fields like title, group, and configurableProps are read. Every function-valued field below (defaultProps, component, actions, code, providers) runs later, at render time, with the live ctx. Don't close over render-time values in the outer body.

TSXbutton.windo.tsx
import { windo } from '../windo.config'
import { Button } from './Button'

export default windo(w => ({
title: 'Button',
group: w.groups.controls.slug,
defaultProps: { label: 'Save', variant: 'primary' },
component: props => <Button {...props} />,
}))

The two generics

windo<Props, State>(factory) carries two type parameters. Props is the component's prop type — it threads through defaultProps, variants, props, code, and component. State is the optional component-local state shape; it defaults to an empty object and types ctx.state, ctx.setState, and every WindoAction. Both are usually inferred, but you can name them when inference needs a hand — most often when a windo declares state and actions.

TSXtoast.windo.tsx
type ToastProps = { message: string }
type ToastState = { open: boolean }

export default windo<ToastProps, ToastState>(w => ({
title: 'Toast',
group: w.groups.feedback.slug,
state: { open: false },
actions: [{ label: 'Show', run: ctx => ctx.setState({ open: true }) }],
defaultProps: { message: 'Saved' },
component: (props, ctx) => <Toast {...props} open={ctx.state.open} />,
}))

WindoDefinition

The object your factory returns. Only title, group, defaultProps, and component are required; everything else is optional and unlocks one piece of canvas behaviour. Function-valued fields are marked — those receive the live ctx at render time.

FieldTypeDescription
titlestringRequired. Display name in the sidebar and chrome.
groupGroupSlugRequired. The slug of one configured group. Type-checked against your config's groups — reach for it via w.groups.<name>.slug.
tagsTag[]Tags this component carries, drawn from the config's declared tags. Type-checked against that list. Drives the sidebar's tag filter; a component can carry any number. Optional.
component(props: Props, ctx: WindoRenderContext<State>) => ReactNodeRequired. Renders the component. Runs at render time with the merged props (defaults plus editor overrides) and the live ctx.
defaultPropsProps | ((ctx: WindoRenderContext<State>) => Props)Required. The full prop set, including functions and JSX the schema cannot describe. May be a function of ctx. The JSON editor merges its overrides on top.
status'stable' | 'beta' | 'deprecated'Maturity badge in the sidebar. Optional.
descriptionstringOne-line summary shown in the chrome. Optional.
deprecationstringDeprecation notice copy. Pair with status: deprecated. Optional.
placementWindoPlacementWhere the component anchors in the canvas frame, e.g. 'center', 'fill', 'top-left'. Append -padding to inset from the edges. Optional.
configurablePropsz.ZodTypeA zod schema for the JSON-editable subset of props. Validates and parses live edits; z.output must be a subset of Props. Optional.
variantsWindoVariant<Props>[]Named prop patches ({ label, props }) shown in the gallery and click-to-apply. Optional.
propsWindoPropDoc[]An authored documentation table ({ name, type, default?, desc? }). Hand-written, not derived from the schema. Optional.
code(values: Props) => stringBuilds the snippet for the Code tab from the current prop values. Runs at render time. Optional.
usesstring[]Names of provider contexts this component opts into. Their providers wrap the component inside the iframe. Optional.
providersComponentType<{ children: ReactNode; ctx: WindoRenderContext<State> }>A local provider wrapping only this windo, in addition to any uses contexts. Optional.
stateStateInitial component-local state. Its shape is the State generic and seeds ctx.state. Optional.
actionsWindoAction<State>[]Out-of-band drivers of state: click actions become toolbar buttons, enter/exit/hover bind to the stage's pointer events. Each runs against the live ctx. Optional.

Required vs. optional, at a glance

The smallest valid windo is four fields: title, group, defaultProps, component. Each optional field maps to one surface in the chrome — configurableProps powers the live controls, variants the gallery, state and actions the toolbar, uses and providers the context wrappers, code and props the documentation tabs.