( render: (props: Props, ctx: WidgetContext<State>) => VNode, options?: DefineWidgetOptions, )
| 297 | * ``` |
| 298 | */ |
| 299 | export function defineWidget<Props extends WidgetPropsBase, State = void>( |
| 300 | render: (props: Props, ctx: WidgetContext<State>) => VNode, |
| 301 | options?: DefineWidgetOptions, |
| 302 | ): WidgetFactory<Props> { |
| 303 | const widgetKey = generateWidgetKey(options?.name); |
| 304 | const wrapperKind = options?.wrapper ?? "fragment"; |
| 305 | |
| 306 | return function widgetFactory(props: Props): VNode { |
| 307 | // Store render function and props for later execution |
| 308 | const renderFn = (ctx: WidgetContext<unknown>) => { |
| 309 | return render(props, ctx as WidgetContext<State>); |
| 310 | }; |
| 311 | |
| 312 | // Create a composite VNode that the runtime will detect and handle |
| 313 | // Use a container wrapper so runtime can reconcile the rendered child. |
| 314 | const baseVNode: VNode = { |
| 315 | kind: wrapperKind, |
| 316 | props: props.key !== undefined ? { key: props.key } : {}, |
| 317 | children: [], |
| 318 | }; |
| 319 | |
| 320 | const compositeVNode: CompositeVNode = { |
| 321 | ...baseVNode, |
| 322 | __composite: Object.freeze({ |
| 323 | widgetKey, |
| 324 | render: renderFn, |
| 325 | props, |
| 326 | key: props.key, |
| 327 | }), |
| 328 | }; |
| 329 | |
| 330 | return compositeVNode; |
| 331 | }; |
| 332 | } |
| 333 | |
| 334 | /* ========== Instance ID Scoping ========== */ |
| 335 |
no test coverage detected