How to Use UEFN Buttons and Text Blocks in Verse?

I created a UI in UEFN and placed a button and a text block. I want to implement functionality using Verse so that clicking the button inputs text into the adjacent text block.

I have reviewed the official tutorials and believe I understand the basics, but the tutorials do not explain how to bring UI elements like buttons and text blocks into Verse.
Could you please explain how to import these UI elements into Verse or provide guidance on how to implement this functionality?


This is my UI

Would Start With Some Base Object Like This

using { /UnrealEngine.com/Temporary/UI }
using { /Fortnite.com/UI }
using { /Verse.org/Colors }

button_text_block := struct:
    TextBlock : text_block
    Button : text_button_base

(ButtonTextBlock:button_text_block).ClickedEvent():listenable(widget_message)=
    return ButtonTextBlock.Button.OnClick()

ConstructButtonTextBlock(ButtonText:string, DefaultText:string):button_text_block=
    TextBlock := text_block:
        DefaultTextColor := color{R := 1.0, G := 1.0, B := 1.0}
        DefaultText := DefaultText.ToMessage()

    Button := button_loud:
        DefaultText := ButtonText.ToMessage()

    ButtonTextBlock := button_text_block:
        TextBlock := TextBlock
        Button := Button
        
    return ButtonTextBlock

(ButtonTextBlock:button_text_block).ToStackBoxSlot():stack_box_slot=
    StackBox := stack_box:
        Orientation := orientation.Horizontal

    Slots := array:
        stack_box_slot{Widget := ButtonTextBlock.Button}
        stack_box_slot{Widget := ButtonTextBlock.TextBlock}

    for(Slot:Slots){StackBox.AddWidget(Slot)}
        
    OutStackBoxSlot := stack_box_slot{Widget := StackBox}
        
    return OutStackBoxSlot

(ButtonTextBlock:button_text_block).ClickTask(ExitEvent:listenable(widget_message))<suspends>:void=
    var Clicks : int = 0
    race:
        block:
            ExitEvent.Await()
        block:
            loop:
                ButtonTextBlock.ClickedEvent().Await()
                set Clicks += 1
                ButtonTextBlock.TextBlock.SetText("{Clicks}".ToMessage())
                Sleep(0.0) # You can remove this if you want

Would then make some base class for ui

StringToMessage<localizes>(String:string):message="{String}"
(String:string).ToMessage():message={return StringToMessage(String)}

player_ui_base := class:

    Owner : player
    MainOverlay : overlay = overlay{}
    ContainsButtons : logic

    Show():void=
        InputMode := player_ui_slot{InputMode := if(ContainsButtons?){ui_input_mode.All} else{ui_input_mode.None}}
        if(PlayerUI := GetPlayerUI[Owner]):
            PlayerUI.AddWidget(MainOverlay,  InputMode)
    
    Hide():void=
        if(PlayerUI := GetPlayerUI[Owner]):
            PlayerUI.RemoveWidget(MainOverlay)

    Initialize():void=
        block{}

Finally you could make some sub class that has buttons and build out the ui / use the object i created above

button_text_ui_test := class(player_ui_base):

    NumBlocks : int

    var ButtonTextBlocks : []button_text_block = array{}

    ContainsButtons <override> : logic = true

    ExitButton : text_button_base = button_loud{}

    ExitEvent():listenable(widget_message)={return ExitButton.OnClick()}

    Initialize<override>():void=
        for(i := 0..NumBlocks):
            ButtonTextBlock := ConstructButtonTextBlock("Button {i}", "")
            set ButtonTextBlocks += array{ButtonTextBlock}

        HorizontalSlots := for(ButtonTextBlock:ButtonTextBlocks){ButtonTextBlock.ToStackBoxSlot()}

        MainStackBox := stack_box{Orientation := orientation.Vertical}

        for(Slot:HorizontalSlots){MainStackBox.AddWidget(Slot)}

        OverlaySlot := overlay_slot{Widget := MainStackBox}

        ExitButton.SetText("EXIT".ToMessage())
        ExitButtonSlot := overlay_slot{Widget := ExitButton}

        MainOverlay.AddWidget(ExitButtonSlot)
        MainOverlay.AddWidget(OverlaySlot)

    ButtonTask()<suspends>:void=
        Show()
        for(ButtonTextBlock:ButtonTextBlocks):
            spawn{ButtonTextBlock.ClickTask(ExitEvent())}
        ExitEvent().Await()
        Hide()

But most importantly you can really just pass a button / text_block into a method that has an exit condition, wait for the button to be clicked and then set the text on it however you’d like

you could really just do

(Button:text_button_base).AwaitInteraction(TextBlock:text_block, ExitEvent:listenable(widget_message))<suspends>:void=
    race:
        block:
            ExitEvent.Await()
        block:
            loop:
                Button.OnClick().Await()
                TextBlock.SetText("SomeText".ToMessage())