dioxus icon indicating copy to clipboard operation
dioxus copied to clipboard

Placeholders in SVGs break rendering

Open xvlunar opened this issue 1 year ago • 3 comments

Problem

In the code below props.icon.child_elements() returns a Element from a rsx! macro. With just the 'web' feature this works fine, however with fullstack this causes the children_elements to render side by side the parent svg.

What is rendered in the html

<svg></svg>
<path></path>

What should be rendered in the html

<svg><path></path></svg>
#[allow(non_snake_case)]
pub fn Icon<T: IconShape + Clone + PartialEq + 'static>(props: IconProps<T>) -> Element {
    rsx!(
        svg {
            stroke_width: "0",
            class: "{props.class}",
            height: "{props.height}",
            width: "{props.width}",
            view_box: "{props.icon.view_box()}",
            xmlns: "{props.icon.xmlns()}",
            fill: "{props.fill}",
            stroke: "{props.fill}",
            if let Some(title_text) = props.title {
                title {
                    "{title_text}"
                }
            },
            {props.icon.child_elements()} // This is what returns a Element using rsx!{}
        }
    )
}

Steps To Reproduce use dioxus-free-icons and try to render one with fullstack. ( I think sometimes it works but rarely, so try a couple times)

Expected behavior Expect the path to be inside the svg

Environment:

  • Dioxus version: master
  • Rust version: 1.77.0
  • OS info: Linux Endeavor OS
  • App platform: Fullstack

Questionnaire

  • [ ] I'm interested in fixing this myself but don't know where to start
  • [ ] I would like to fix and I have a solution
  • [x] I don't have time to fix this right now, and I also have no clue how I would fix this

xvlunar avatar Apr 08 '24 16:04 xvlunar

This is caused by a <pre> tag dioxus renders as a placeholder for the if let Some(title_text) = props.title { statement. If you look at the network tab, dioxus renderes something like:

<svg ... data-node-hydration="0">
    <pre data-node-hydration=1></pre>
    <path d="..." data-node-hydration="2"></path>
</svg>

The browser transforms that invalid svg into:

<svg ... data-node-hydration="0"></svg>
<pre data-node-hydration=1></pre>
<path d="..." data-node-hydration="2"></path>

We might need to use a different element than <pre> for placeholders in svgs

ealmloff avatar Apr 08 '24 18:04 ealmloff

I think this is happening in my project as well, but it's inconsistent. Sometimes the tags are set properly and the svg is displayed without issues.

magikmw avatar Apr 18 '24 09:04 magikmw