How to Use UEFN Buttons and Text Blocks in Verse?

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())