Example #1
0
def Input(
    callback: Callable[[str], None],
    type: str,
    value: str = "",
    attributes: Optional[Dict[str, Any]] = None,
    cast: Optional[Callable[[str], Any]] = None,
    ignore_empty: bool = True,
) -> VdomDict:
    """Utility for making an ``<input/>`` with a callback"""
    attrs = attributes or {}
    value, set_value = idom.hooks.use_state(value)

    events = idom.Events()

    @events.on("change")
    def on_change(event: Dict[str, Any]) -> None:
        value = event["value"]
        set_value(value)
        if not value and ignore_empty:
            return
        callback(value if cast is None else cast(value))

    return html.input({
        "type": type,
        "value": value,
        **attrs
    },
                      event_handlers=events)
Example #2
0
    async def DivInDiv(self):
        inner_events = idom.Events()
        inner_events.on("Click", stop_propagation=True)

        async def outer_click_is_not_triggered():
            assert False

        inner = idom.html.div(
            {
                "style": {
                    "height": "30px",
                    "width": "30px",
                    "backgroundColor": "blue"
                },
                "id": "inner",
            },
            event_handlers=inner_events,
        )
        outer = idom.html.div(
            {
                "style": {
                    "height": "35px",
                    "width": "35px",
                    "backgroundColor": "red"
                },
                "onClick": outer_click_is_not_triggered,
                "id": "outer",
            },
            [inner],
        )
        return outer
Example #3
0
def GameLoop(grid_size, block_scale, set_game_state):
    # we `use_ref` here to capture the latest direction press without any delay
    direction = idom.hooks.use_ref(Direction.ArrowRight.value)

    snake, set_snake = idom.hooks.use_state([(grid_size // 2 - 1,
                                              grid_size // 2 - 1)])
    food, set_food = use_snake_food(grid_size, snake)

    grid = create_grid(grid_size, block_scale)
    grid_events = grid["eventHandlers"] = idom.Events()

    @grid_events.on("KeyDown", prevent_default=True)
    async def on_direction_change(event):
        if hasattr(Direction, event["key"]):
            maybe_new_direction = Direction[event["key"]].value
            direction_vector_sum = tuple(
                map(sum, zip(direction.current, maybe_new_direction)))
            if direction_vector_sum != (0, 0):
                direction.current = maybe_new_direction

    assign_grid_block_color(grid, food, "blue")

    for location in snake:
        assign_grid_block_color(grid, location, "white")

    new_game_state = None
    if snake[-1] in snake[:-1]:
        assign_grid_block_color(grid, snake[-1], "red")
        new_game_state = GameState.lost
    elif len(snake) == grid_size**2:
        assign_grid_block_color(grid, snake[-1], "yellow")
        new_game_state = GameState.won

    interval = use_interval(0.5)

    @idom.hooks.use_effect
    async def animate():
        if new_game_state is not None:
            await asyncio.sleep(1)
            set_game_state(new_game_state)
            return

        await interval

        new_snake_head = (
            # grid wraps due to mod op here
            (snake[-1][0] + direction.current[0]) % grid_size,
            (snake[-1][1] + direction.current[1]) % grid_size,
        )

        if snake[-1] == food:
            set_food()
            new_snake = snake + [new_snake_head]
        else:
            new_snake = snake[1:] + [new_snake_head]

        set_snake(new_snake)

    return grid
Example #4
0
def test_simple_events_object():
    events = idom.Events()

    @events.on("Click")
    async def click_handler():
        pass

    @events.on("keyPress")
    async def key_press_handler():
        pass

    assert isinstance(events["onClick"], EventHandler)
    assert isinstance(events["onKeyPress"], EventHandler)
Example #5
0
def test_simple_events():
    events = idom.Events()

    @events.on("Click")
    def click_handler():
        pass

    @events.on("keyPress")
    def key_press_handler():
        pass

    assert events == {"onClick": click_handler, "onKeyPress": key_press_handler}

    assert isinstance(events["onClick"], EventHandler)
    assert isinstance(events["onKeyPress"], EventHandler)
Example #6
0
def Grid(grid_size, block_size):
    return idom.html.div(
        [
            idom.html.div(
                [Block("white", block_size) for i in range(grid_size)],
                style={"height": block_size},
            ) for i in range(grid_size)
        ],
        style={
            "height": f"{block_size * grid_size}px",
            "width": f"{block_size * grid_size}px",
        },
        eventHandlers=idom.Events(),
        tabIndex=-1,
    )
Example #7
0
async def test_register_multiple_handlers_to_same_event():
    events = idom.Events()

    calls = []

    @events.on("change")
    async def handler_1():
        calls.append(1)

    @events.on("change")
    async def handler_2():
        calls.append(2)

    await events["onChange"]([])

    assert calls == [1, 2]
Example #8
0
def Grid(grid_size, block_size):
    return idom.html.div(
        {
            "style": {
                "height": f"{block_size * grid_size}px",
                "width": f"{block_size * grid_size}px",
            },
            "tabIndex": -1,
        },
        [
            idom.html.div(
                {"style": {"height": block_size}},
                [Block("white", block_size) for i in range(grid_size)],
            )
            for i in range(grid_size)
        ],
        event_handlers=idom.Events(),
    )
Example #9
0
import pytest

import idom
from idom.core.vdom import make_vdom_constructor

fake_events = idom.Events()


@fake_events.on("Click")
async def handler(event):
    pass


@pytest.mark.parametrize(
    "actual, expected",
    [
        (
            idom.vdom("div", [idom.vdom("div")]),
            {
                "tagName": "div",
                "children": [{
                    "tagName": "div"
                }]
            },
        ),
        (
            idom.vdom("div", {"style": {
                "backgroundColor": "red"
            }}),
            {
                "tagName": "div",
Example #10
0
        (
            # lists and tuples passed to children are flattened
            idom.nodes.div([idom.nodes.div(), 1], (idom.nodes.div(), 2)),
            {
                "tagName": "div",
                "children": [{"tagName": "div"}, 1, {"tagName": "div"}, 2],
            },
        ),
        (
            # keywords become attributes
            idom.nodes.div(style={"backgroundColor": "blue"}),
            {"tagName": "div", "attributes": {"style": {"backgroundColor": "blue"}}},
        ),
        (
            # eventHandlers is popped from attributes and made a top level field
            idom.nodes.div(eventHandlers=idom.Events()),
            {"tagName": "div", "eventHandlers": idom.Events()},
        ),
    ],
)
def test_simple_node_construction(actual, expected):
    assert actual == expected


def test_node_constructor_factory():
    elmt = node_constructor("some-tag")

    assert elmt(elmt(), data=1) == {
        "tagName": "some-tag",
        "children": [{"tagName": "some-tag"}],
        "attributes": {"data": 1},