github manzt/anywidget @anywidget/types@0.4.0

latest release: @anywidget/vue@0.1.2
5 hours ago

Minor Changes

  • Allow initialize to return an exports object (#974)

    initialize can now return a plain object to expose a programmatic API for the widget. This API is accessible to parent widgets via host.getWidget().

    export default {
      initialize({ model }) {
        return {
          getValue: () => model.get("value"),
          setValue: (v) => {
            model.set("value", v);
            model.save_changes();
          },
        };
      },
      render({ model, el }) {
        /* ... */
      },
    };

    The return type is distinguished by typeof: functions are treated as cleanup callbacks (existing behavior), objects are treated as exports, and void means neither.

  • Add signal (AbortSignal) to initialize and render props for lifecycle cleanup (#974)

    Both initialize and render now receive an AbortSignal via the signal prop. The signal is aborted when the widget is destroyed (or during HMR). This is the preferred way to manage cleanup going forward — it composes with the broader web platform (addEventListener, fetch, child widgets) and avoids the need to manually track teardown logic.

    The previous callback-based pattern continues to work but is no longer recommended:

    // before
    export default {
      render({ model, el }) {
        let handler = () => { /* ... */ };
        model.on("change:value", handler);
        return () => model.off("change:value", handler);
      },
    };
    
    // after
    export default {
      render({ model, el, signal }) {
        let handler = () => { /* ... */ };
        model.on("change:value", handler);
        signal.addEventListener("abort", () => model.off("change:value", handler));
      },
    };

    signal also works with addEventListener and fetch directly:

    export default {
      render({ model, el, signal }) {
        el.addEventListener(
          "click",
          () => {
            /* ... */
          },
          { signal }
        );
      },
    };
  • Add host.getWidget and host.getModel for widget composition (#974)

    render now receives a host prop with methods to resolve child widgets by reference, enabling one anywidget to render another inside its DOM.

    export default {
      async render({ model, el, signal, host }) {
        let child = await host.getWidget(model.get("slider"));
        await child.render({ el, signal });
      },
    };

    On the Python side, widget references are serialized as "anywidget:<model_id>" strings. A new WidgetTrait traitlet validates anywidget-compatible objects, and a Widget type alias is provided for annotations:

    import anywidget
    
    class Dashboard(anywidget.AnyWidget):
        _esm = "dashboard.js"
        slider = anywidget.WidgetTrait().tag(sync=True)
    
    Dashboard(slider=Slider())

    host.getWidget(ref) returns { exports, render } where exports is the object returned from the child's initialize, and render({ el, signal }) mounts the child's view. host.getModel(ref) returns the raw model for lower-level access.

Don't miss a new anywidget release

NewReleases is sending notifications on new releases.