-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support non-DOM widgets? #388
Comments
In the same vein than Anywidget's DOM widget, from the user point of view I could imagine a non-DOM anywidget look like this: import anywidget
import traitlets
# below I use the name `anywidget.AnyPureWidget` for non-DOM widgets
# would have been great to use `anywidget.AnyWidget` vs. `anywidget.AnyDOMWidget`!
class CounterWidget(anywidget.AnyPureWidget):
_esm = """
export default function (model) {
let getCount = () => model.get("count");
model.on("change:count", () => {
console.log("count is ${getCount()}");
});
}
"""
count = traitlets.Int(0).tag(sync=True)
counter = CounterWidget()
counter.count = 42 # shows message in JS console
counter # shows Python repr (plain text) Where the default exported function in the user-defined module would be called in the widget's If DOM widgets are used for 99% of the uses cases and non-DOM widgets for the remaining 1% that may simply be not worth having the latter available in Anywidget after all :-). Feel free to close this issue if you think this is not relevant. |
Thanks for sharing the use case! I see the usage but need to look into how Widgets without views end up getting displayed with a plain-text repr in the front end (rather than loading the JS-view). As a workaround for now, you could do something like display the widget plain text in a pre tag: import anywidget
import traitlets
# BaseClass
class Widget(anywidget.AnyWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.add_traits(_str_repr=traitlets.Unicode(repr(self)).tag(sync=True))
# "Headless widget"
class HeadlessWidget(Widget):
_esm = """
export function render({ model, el }) {
console.log({ model })
el.innerHTML = `<pre>${model.get("_str_repr")}</pre>`
}
"""
value = traitlets.Int(0).tag(sync=True)
HeadlessWidget() you just need to remember to add the last line at the end of the "render" func.
If nothing is set to |
Thanks for the workaround. I guess that the JS
I think that for an |
Ah ok I see, I think this could be related to In the MVC framework used by Jupyter Widgets, right now anywidget treats Python as the sole source-of-truth for defining the model and only supports rendering "views" of the current model. We don't have an API to setup some initial front-end model listeners/state. I have been toying with some ideas for APIs (as mentioned in that issue), but the main concern is how this could play with HMR (as you've mentioned above). However, I could imagine that if an anywidget module doesn't export |
Ah yes indeed this is quite related to #266! For a viewless widget we would only need a
I guess this could be handled in a similar way than for DOM widgets with no view to clean-up? I.e., load the updated esm, remove all event listeners and re-call
For a truly viewless (any)widget, I'm wondering if on the Python side the widget type must be a subclass of Having two distinct classes |
In hindsight I think I agree, but I'm not willing to introduce a breaking change for naming. Please see #395. With that API, you can "opt out" of of creating a view and use a |
It seems that Anywidget currently only supports DOM widgets by wrapping ipywidgets'
DOMWidget
/DOMWidgetModel
. Could it also expose wrappers forWidget
/WidgetModel
as well?DOM widgets likely cover 95% of the use cases but there are a few interesting applications that don't really require DOM elements like interacting with the Web audio API (ipytone) or the Web MIDI API.
Maybe we could just create empty DOM elements for those applications? This feels a bit hacky, though.
There is still the possibility of using ipywidgets directly but I really enjoy the anywidget layer for developing custom widgets :). Not sure if/how HMR would work and it is likely that non-browser front-ends won't work for the applications mentioned above, but I guess that using anywidgets would still make things easier for prototyping and packaging.
The text was updated successfully, but these errors were encountered: