adospace / reactorui-maui

MauiReactor is a MVU UI framework built on top of .NET MAUI
MIT License
552 stars 45 forks source link

What is the best way to initialize method component before it can be render #240

Open cris-m opened 3 weeks ago

cris-m commented 3 weeks ago

How can I initialize the following component with text. Before render there is default text in the Entry

static VisualNode RenderMudEntry(string label, Action<string> textChangedAction)
    => Render<(bool IsFocused, bool IsFilled)>(state =>
    {
        MauiControls.Entry _entryRef = null;
        // state.Set(s => (s.IsFocused = true, s.IsFilled = true)); // create issue in component like BottomSheet

        return Grid("Auto", "*",
            Entry(entryRef => _entryRef = entryRef)
                .OnAfterTextChanged(text =>
                {
                    state.Set(s => (s.IsFocused, IsFilled: !string.IsNullOrWhiteSpace(text)));
                    textChangedAction?.Invoke(text);
                })
                .VCenter()
                .OnFocused(()=>state.Set(s => (IsFocused: true, s.IsFilled)))
                .OnUnfocused(()=>state.Set(s => (IsFocused: false, s.IsFilled))),

            Label(label)
                .OnTapped(() =>_entryRef?.Focus())
                .Margin(5,0)
                .HStart()
                .VCenter()
                .TranslationY(state.Value.IsFocused || state.Value.IsFilled ? -20 : 0)
                .ScaleX(state.Value.IsFocused || state.Value.IsFilled ? 0.8 : 1.0)
                .AnchorX(0)
                .TextColor(!state.Value.IsFocused || !state.Value.IsFilled ? Colors.Gray : Colors.Red)
                .WithAnimation(duration: 200),
        )
        .VCenter();
    });

I try to initialize It like this state.Set(s => (s.IsFocused = true, s.IsFilled = true)); but the component is render twice on the view in third party component like BottomSheet. If the BottomSheet contains a CollectionView, the app will throw an the following exception:

Exception has occurred: System.ArgumentOutOfRangeException
Index must be within the bounds of the List. (Parameter 'index')
adospace commented 2 weeks ago

Hi, seems you're reporting more than one issue. 1) Do you want to initialize the entry with a custom text? if so, have you tried to use the Text("...") method on the entry?

2) Can you show the code that causes the exception CollectionView inside a BottomSheet?

cris-m commented 2 weeks ago

If I put customer text, IsFilled or IsFocused will be initially to false. I wanted to add initially hasError property to the entry which can be control by a boolean state but I initialize as following:

state.Set(s => (s.IsFocused = true, s.IsFilled = true, s.HasError = hasError)); // hasError is parameter pass to the controller function

This create a conflict when I rendered the entry controller on The49 bottom sheet. The entry is rendered twice.

adospace commented 1 week ago

Can you please create a small repro project that shows the problem?

cris-m commented 1 week ago

I have established a repository that reproduces the issue. The problem manifests as follows:

The RenderMudEntry component is rendered twice on the bottom sheet.

You can find the repository at this link.