deephaven / deephaven-plugins

Deephaven Plugins
11 stars 15 forks source link

deephaven.ui Element plugins #491

Open mofojed opened 5 months ago

mofojed commented 5 months ago

As a developer, I want to add a custom deephaven.ui Element component and simply define the JS to take advantage of the deephaven.ui framework.

E.g. On the server, I want to simply define a component using deephaven.ui:

# In a package named `foo_deephaven_element`
from deephaven import ui

# The name of the component is derived from the declaration, e.g. `get_component_name`: https://github.com/deephaven/deephaven-plugins/blob/f2675721e6f6a408917c9d436349564260a371e3/plugins/ui/src/deephaven/ui/_internal/utils.py#L22
@ui.component
def counter():
    value, set_value = ui.use_state(0)

    return ui.button(f"Count is {value}", on_press=lambda: set_value(value + 1))

# Or define something with a `BaseElement` to just pass some props through, e.g.
def foo(*children: Any, default_value: str, on_change: Callable[[str], None]):
  return BaseElement('foo_deephaven_element.foo', *children, default_value=default_value, on_change=on_change)

And then on the JS side, I want to be able to register an Element/component:

// Not 100% sure how this part would actually work
import { registerElementPlugin } from '@deephaven/js-plugin-ui';

function FooCounter({ children }) {
  // You should be able to whatever you want here, with a custom react component
  return <MyCustomReactComponent>{children}</MyCustomReactComponent>;
}

// The name passed in should match the component name as determined on the Python side
registerElementPlugin('foo_deephaven_element.counter', FooCounter);

Finally, use it by installing the plugin, and then using it in your query:

from foo_deephaven_element import counter

my_counter = counter()
mofojed commented 5 months ago

Want some way to hook into the getComponentForType method: https://github.com/deephaven/deephaven-plugins/blob/df587a8cf88257324fd13ef69215d5224657c509/plugins/ui/src/js/src/widget/WidgetUtils.tsx#L64

We should also make sure it's easy to pass a table and use that viewport data from the UI. Write an example element component doing just that.

dsmmcken commented 3 months ago

I would also like to be able to easily pass our common props to a component, or like extend a component maybe?