widgetti / ipyreact

React for ipywidgets that just works. No webpack, no npm, no hassle
BSD 3-Clause "New" or "Revised" License
104 stars 8 forks source link

How to init class with parameter? #5

Closed kolibril13 closed 1 year ago

kolibril13 commented 1 year ago

Considering the following example:

import ipyreact

class MyExampleWidget(ipyreact.ReactWidget):
    name = "Hello World"
    _esm = f"""
    import * as React from "react";

    export default function Square() {{
        return <button> {name} </button> 
    }};"""
MyExampleWidget()

how can I add a parameter, so that I can call the widget like MyExampleWidget(name = "Hi there") ?

Here is a suggestion how this could look like:

import ipyreact

class MyExampleWidget(ipyreact.ReactWidget):
    def __init__(self, name):
        self.name = name
        print(self.name)

        self._esm = f"""
        import * as React from "react";

        export default function Square() {{
            return <button> {name} </button> 
        }};"""

MyExampleWidget(name = "Hi there")
maartenbreddels commented 1 year ago
import traitlets
import ipyreact

class MyExampleWidget(ipyreact.ReactWidget):
    myname = traitlets.Unicode("Hello World").tag(sync=True)
    _esm = """
    export default function Square({myname}) {
        return <button>{myname}</button> 
    };"""
w = MyExampleWidget()

This works, now you can mutate w.myname. Not that the name trait is 'taken' already, I am gonna change that in the next version, so we can use name freely.

kolibril13 commented 1 year ago

Nice! This code works!

import traitlets
import ipyreact

class MyExampleWidget(ipyreact.ReactWidget):
    myname = traitlets.Unicode("Hello World").tag(sync=True)
    _esm = """
    import * as React from "react";
    export default function Square({myname}) {
        return <button>{myname}</button> 
    };"""
w = MyExampleWidget()
w.myname = "foo"
w

but is there also a way so that I can set the parameter also already in the initialization step like MyExampleWidget(myname = "foo") ?

maartenbreddels commented 1 year ago

MyExampleWidget(myname="foo") :)

kolibril13 commented 1 year ago

That was too obvious :D I will soon contribute this as an example for the documentation:

import traitlets
import ipyreact

class MyExampleWidget(ipyreact.ReactWidget):
    myname = traitlets.Unicode("Hello World").tag(sync=True)
    _esm = """
    import * as React from "react";
    export default function Square({myname}) {
        return <button>{myname}</button> 
    };"""
w = MyExampleWidget(myname = "foo")
w

and is there any way one can still have an init function? If something like

class MyExampleWidget(ipyreact.ReactWidget):
    def __init__(self, name):
        self.name = name
         ....

was possible, we would get auto-completion:

image
maartenbreddels commented 1 year ago

Try:

import ipyreact
from traitlets import Any, Unicode, Int, observe, signature_has_traits

@signature_has_traits
class Tldraw(ipyreact.ReactWidget):
    ...
kolibril13 commented 1 year ago

Yess, that works!

image

Thank you so much for showing me all these concepts today!

maartenbreddels commented 1 year ago

Hoping to see great things!