DioxusLabs / DioxusLabs/dioxus

State management with dynamic rendering inside contenteditable divs

Open
#1,962 4 comments 0 reactions 0 assignees View on GitHub
bug help wanted
Dominant language
Rust
Stars
39.1k
Forks
1.9k
Avg merge
4d 10h
Merged PRs (30d)
4

Description

**State isn't synced properly when user deletes children nodes in contentetitable div**

the user can delete elements by using the backspace inside contentetitable elements. Video below.

I also have a question regarding the event listeners of the child elements. Why they aren't triggered at all? Only the parent element event listeners are called.

**Steps To Reproduce**

Code:
```rust

#![allow(non_snake_case)]
// import the prelude to get access to the `rsx!` macro and the `Scope` and `Element` types
use dioxus::prelude::*;
use dioxus_desktop::{tao::event_loop::EventLoop, use_window, LogicalSize, WindowBuilder};
use uuid::Uuid;

fn main() {
// launch the dioxus app in a webview
dioxus_desktop::launch_cfg(
App,
dioxus_desktop::Config::new()
.with_custom_head(
r#"



"#
.to_string(),
)
.with_window(
WindowBuilder::new()
.with_title("Desktop App")
.with_inner_size(LogicalSize {
width: 400.0,
height: 400.0,
})
.with_min_inner_size(LogicalSize {
width: 400.0,
height: 400.0,
})
.with_transparent(true),
),
)
}

enum Blocks {
ParagraphBlock(Uuid)
}

pub fn Paragraph(cx: Scope) -> Element {
let inner_text = use_state(cx, || "".to_string());

cx.render(rsx! {
div {
class: "border-solid border-2 border-indigo-300 p-4 rounded-lg some-block",
onkeydown: move |e| {println!("Inner State (onkeydown) {:?}", e.key().to_string());},
oninput : move |e| {println!("Inner State (oninput) {:?}", e.data.value.clone()); inner_text.set(e.data.value.clone())},
p{
class: "text-xs font-semibold text-gray-600 uppercase some-block-header",
"contenteditable": "false",
"Paragraph"
},
p {
class: "text-base text-gray-800 empty:before:content-[attr(data-placeholder)] empty:before:text-gray-300 whitespace-pre-wrap selectable-area",
"data-placeholder" : "Write text here ..",
inner_text.as_str()

}

}
}
)
}

fn App(cx: Scope) -> Element {
let window = use_window(&cx);

let some_blocks = use_ref(cx, Vec::::new);
if some_blocks.read().is_empty() {
some_blocks
.write()
.push(Blocks::ParagraphBlock(Uuid::new_v4()));

some_blocks
.write()
.push(Blocks::ParagraphBlock(Uuid::new_v4()));

some_blocks
.write()
.push(Blocks::ParagraphBlock(Uuid::new_v4()));
}

let binding = some_blocks.read();
let blocks_rendered = binding
.iter()
.map(|block| match block {
Blocks::ParagraphBlock(id) => rsx! {Paragraph{key: "{id}"}},
});

cx.render(rsx! {
div {
class: "h-screen w-screen flex bg-pink-100 p-4 rounded-lg flex-col space-y-4 overflow-auto",
"contenteditable" : "true",
onkeydown: move |_e| { println!("Number of blocks: {:?} ", some_blocks.read().len()) },
onmousedown: move |_| {window.drag()},
blocks_rendered
}
})
}

```

**Expected behavior**

State should be maintained and synced

**Screenshots**

![dioxus-bug](https://github.com/DioxusLabs/dioxus/assets/57562898/d5fd2be6-e31d-42c4-98e5-996b39f2e36a)

**Environment:**
- Dioxus version: 0.4.3
- Rust version: rustc 1.76.0
- OS info: Windows 10
- App platform: desktop

**Questionnaire**

- [x] I'm interested in fixing this myself but don't know where to start
- [ ] I would like to fix and I have a solution
- [ ] I don't have time to fix this right now, but maybe later

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.