Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xilem_web: An example using AnyDomView would be super helpful #459

Open
casey opened this issue Jul 28, 2024 · 6 comments
Open

xilem_web: An example using AnyDomView would be super helpful #459

casey opened this issue Jul 28, 2024 · 6 comments
Labels

Comments

@casey
Copy link
Contributor

casey commented Jul 28, 2024

I'm trying to make a <li> which can have one of two types, either a button or text node, depending on the state.

I tried to do something like:

fn bar(state: &mut bool) -> impl HtmlLiElement<State> {
  html::li(if *state {
    Box::new(html::button("button")) as Box<AnyDomView<State>>
  } else {
    Box::new("not a button") as Box<AnyDomView<State>>
  })
}

But got a bunch of errors:

rustc output
    Checking library-viewer v0.0.0 (/Users/rodarmor/src/gossamer/crates/library-viewer)
error: could not compile `library-viewer` (bin "library-viewer") due to 3 previous errors; 3 warnings emitted
error[E0277]: the trait bound `ViewCtx: OrphanView<&'static str, State, ()>` is not satisfied
   --> crates/library-viewer/src/main.rs:117:5
    |
117 |     Box::new("not a button") as Box<AnyDomView<State>>
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `OrphanView<&'static str, State, ()>` is not implemented for `ViewCtx`, which is required by `&str: AnyView<State, (), ViewCtx, Pod<DynNode, Box<(dyn Any + 'static)>>>`
    |
    = help: the following other types implement trait `OrphanView<V, State, Action, Message>`:
              <ViewCtx as OrphanView<&'static str, State, Action, Box<(dyn xilem_web::Message + 'static)>>>
              <ViewCtx as OrphanView<BezPath, State, Action, Box<(dyn xilem_web::Message + 'static)>>>
              <ViewCtx as OrphanView<Cow<'static, str>, State, Action, Box<(dyn xilem_web::Message + 'static)>>>
              <ViewCtx as OrphanView<f32, State, Action, Box<(dyn xilem_web::Message + 'static)>>>
              <ViewCtx as OrphanView<f64, State, Action, Box<(dyn xilem_web::Message + 'static)>>>
              <ViewCtx as OrphanView<i16, State, Action, Box<(dyn xilem_web::Message + 'static)>>>
              <ViewCtx as OrphanView<i32, State, Action, Box<(dyn xilem_web::Message + 'static)>>>
              <ViewCtx as OrphanView<i64, State, Action, Box<(dyn xilem_web::Message + 'static)>>>
            and 12 others
    = note: required for `&str` to implement `View<State, (), ViewCtx>`
    = note: required for `&str` to implement `AnyView<State, (), ViewCtx, Pod<DynNode, Box<(dyn Any + 'static)>>>`
    = note: required for the cast from `Box<&str>` to `Box<(dyn AnyView<State, (), ViewCtx, Pod<DynNode, Box<(dyn Any + 'static)>>> + 'static)>`

error[E0277]: the trait bound `Box<dyn AnyView<State, (), ViewCtx, Pod<DynNode, Box<(dyn Any + 'static)>>>>: ViewSequence<_, _, ViewCtx, Pod<DynNode, Box<(dyn Any + 'static)>>, _, Box<(dyn xilem_web::Message + 'static)>>` is not satisfied
   --> crates/library-viewer/src/main.rs:114:12
    |
114 |     html::li(if *state {
    |  ___--------_^
    | |   |
    | |   required by a bound introduced by this call
115 | |     Box::new(html::button("button")) as Box<AnyDomView<State>>
116 | |   } else {
117 | |     Box::new("not a button") as Box<AnyDomView<State>>
118 | |   })
    | |___^ the trait `ViewSequence<_, _, ViewCtx, Pod<DynNode, Box<(dyn Any + 'static)>>, _, Box<(dyn xilem_web::Message + 'static)>>` is not implemented for `Box<dyn AnyView<State, (), ViewCtx, Pod<DynNode, Box<(dyn Any + 'static)>>>>`
    |
    = help: the following other types implement trait `ViewSequence<State, Action, Context, Element, Marker, Message>`:
              <() as ViewSequence<State, Action, Context, Element, (), Message>>
              <(Seq,) as ViewSequence<State, Action, Context, Element, (Marker,), Message>>
              <(Seq0, Seq1) as ViewSequence<State, Action, Context, Element, (M0, M1), Message>>
              <(Seq0, Seq1, Seq2) as ViewSequence<State, Action, Context, Element, (M0, M1, M2), Message>>
              <(Seq0, Seq1, Seq2, Seq3) as ViewSequence<State, Action, Context, Element, (M0, M1, M2, M3), Message>>
              <(Seq0, Seq1, Seq2, Seq3, Seq4) as ViewSequence<State, Action, Context, Element, (M0, M1, M2, M3, M4), Message>>
              <(Seq0, Seq1, Seq2, Seq3, Seq4, Seq5) as ViewSequence<State, Action, Context, Element, (M0, M1, M2, M3, M4, M5), Message>>
              <(Seq0, Seq1, Seq2, Seq3, Seq4, Seq5, Seq6) as ViewSequence<State, Action, Context, Element, (M0, M1, M2, M3, M4, M5, M6), Message>>
            and 12 others
note: required by a bound in `xilem_web::elements::html::li`
   --> /Users/rodarmor/src/xilem/xilem_web/src/elements.rs:484:5
    |
484 | /     define_elements!(
485 | |         // the order is copied from
486 | |         // https://developer.mozilla.org/en-US/docs/Web/HTML/Element
487 | |         // DOM interfaces copied from https://html.spec.whatwg.org/multipage/grouping-content....
...   |
516 | |         (Li, li, HtmlLiElement),
    | |              -- required by a bound in this function
...   |
606 | |         (Template, template, HtmlTemplateElement),
607 | |     );
    | |_____^ required by this bound in `li`
    = note: this error originates in the macro `define_element` which comes from the expansion of the macro `define_elements` (in Nightly builds, run with -Z macro-backtrace for more info)

[Finished running. Exit status: 101]

I took a look at the examples, but didn't find any usage of AnyDomView. Am I trying using AnyDomView in the right way here, or is another approach required?

By the way, so far having a lot of fun with xilem_web, so thanks for putting it out there!

Philipp-M added a commit to Philipp-M/xilem that referenced this issue Jul 28, 2024
@Philipp-M
Copy link
Contributor

Philipp-M commented Jul 28, 2024

Hmm we really have to work on the error messages...

I just discovered that we don't currently have the .boxed() combinator of xilem, should be added with the fix in #460...
So with that method it would be just html::button("button").boxed() for either of those children. Anyway impl HtmlLiElement is not possible with an AnyDomView, this needs to be either Box<AnyDomView<State>> or impl DomView<State>.

You're right, we should probably add a simple example that shows the use of AnyView (and probably also describes the advantages and limitations of it).

In your case an Either would make sense, checkout e.g. the short example of #452, that allows retaining the intersection of the element type (or in other words the common DOM interface of these views).

By the way, so far having a lot of fun with xilem_web, so thanks for putting it out there!

Good to hear :)

@Philipp-M
Copy link
Contributor

Hmm I don't think #460 fixes this, I'll keep it open until we have a small example for AnyDomView...

@Philipp-M
Copy link
Contributor

Anyway impl HtmlLiElement is not possible with an AnyDomView, this needs to be either Box<AnyDomView> or impl DomView.

Whoops forget about that, I missed the li element that's surrounding the view...

@casey
Copy link
Contributor Author

casey commented Jul 28, 2024

Yah my code is definitely wrong 😅

I just tried #460, and it works perfectly. With that PR, my actual code is:

        ul(
          state
            .packages
            .iter()
            .map(|(hash, manifest)| {
              li(
                if let Some(handler) = state.handlers.get(&manifest.ty().into()) {
                  html::button(manifest.name.clone()).boxed()
                } else {
                  manifest.name.clone().boxed()
                },
              )
            })
            .collect::<Vec<_>>(),
        ),

@DJMcNab
Copy link
Member

DJMcNab commented Jul 29, 2024

@Philipp-M what's the status of this issue now? You set #460 to not auto-close this, so I presume there must still be follow-up needed?

@Philipp-M
Copy link
Contributor

I wanted to add the AnyDomView somewhere in an example, so that the actual title of this issue is "fixed", maybe a new one generally showing Either/OneOf and AnyDomView and explaining the strengths and weaknesses of each or something like that

@flosse flosse added the web label Aug 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants