feat(kanban): prove accessible local reorder
req: client_local/013\nreq: accessibility/002\nreq: accessibility/003\nreq: accessibility/004\nreq: accessibility/006\nreq: milestone/001
This commit is contained in:
@@ -4,16 +4,35 @@ version.workspace = true
|
||||
edition.workspace = true
|
||||
publish = false
|
||||
|
||||
[features]
|
||||
default = ["server"]
|
||||
server = ["dep:axum", "dep:futures-util", "dep:hemx-axum", "dep:tokio"]
|
||||
client = ["hemx/client"]
|
||||
fixture = []
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[[bin]]
|
||||
name = "hemx-kanban-example"
|
||||
path = "src/main.rs"
|
||||
required-features = ["server"]
|
||||
|
||||
[[bin]]
|
||||
name = "client-fixture"
|
||||
path = "src/bin/client_fixture.rs"
|
||||
required-features = ["fixture"]
|
||||
|
||||
[dependencies]
|
||||
axum = "0.8"
|
||||
futures-util = "0.3"
|
||||
hemplate = { path = "../../../hemplate/hemplate" }
|
||||
axum = { version = "0.8", optional = true }
|
||||
futures-util = { version = "0.3", optional = true }
|
||||
hemx = { path = "../../hemx" }
|
||||
hemx-axum = { path = "../../hemx-axum" }
|
||||
tokio = { version = "1", features = ["macros", "net", "rt-multi-thread", "time"] }
|
||||
hemx-axum = { path = "../../hemx-axum", optional = true }
|
||||
tokio = { version = "1", features = ["macros", "net", "rt-multi-thread", "time"], optional = true }
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
hemplate = { path = "../../../hemplate/hemplate" }
|
||||
|
||||
[dev-dependencies]
|
||||
scraper = "0.23"
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
print!("{}", hemx_kanban_example::render_client_fixture());
|
||||
}
|
||||
@@ -1,6 +1,66 @@
|
||||
#[hemx::surface]
|
||||
pub mod ui {}
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
#[hemx::handler(client)]
|
||||
pub fn reorder_card(
|
||||
event: hemx::wasm::ClientEvent,
|
||||
state: hemx::wasm::ClientState,
|
||||
) -> impl hemx::IntoEffect {
|
||||
let card = event.value.unwrap_or_else(|| "1".to_owned());
|
||||
let order = state.encoded.split('|').collect::<Vec<_>>();
|
||||
let move_effect = if card == order.first().copied().unwrap_or("1") {
|
||||
ui::client_board::client_cards.move_to_end(card.clone())
|
||||
} else {
|
||||
ui::client_board::client_cards.move_before(
|
||||
card.clone(),
|
||||
order.first().copied().unwrap_or("1").to_owned(),
|
||||
)
|
||||
};
|
||||
vec![
|
||||
move_effect,
|
||||
ui::client_board::client_notice.text(format!("Moved {card} with {}", event.kind)),
|
||||
]
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "fixture", not(target_arch = "wasm32")))]
|
||||
mod fixture {
|
||||
use super::ui;
|
||||
use hemplate::Hemplate;
|
||||
use hemx::Html;
|
||||
|
||||
#[derive(Hemplate)]
|
||||
struct ClientBoard {
|
||||
cards: Vec<ClientCard>,
|
||||
}
|
||||
|
||||
#[derive(Hemplate)]
|
||||
struct ClientCard {
|
||||
id: u64,
|
||||
title: &'static str,
|
||||
}
|
||||
|
||||
pub fn render() -> Html {
|
||||
ui::client_board::page(&ClientBoard {
|
||||
cards: vec![
|
||||
ClientCard {
|
||||
id: 1,
|
||||
title: "First",
|
||||
},
|
||||
ClientCard {
|
||||
id: 2,
|
||||
title: "Second",
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "fixture", not(target_arch = "wasm32")))]
|
||||
pub fn render_client_fixture() -> hemx::Html {
|
||||
fixture::render()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::ui::{board, board_card};
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<select name="column" required="required">{+= self.options =+}</select>
|
||||
<button type="submit">Add card</button>
|
||||
</form>
|
||||
<p data-hemx-slot="notice">Ready</p>
|
||||
<p id="kanban-status" data-hemx-slot="notice" role="status" aria-live="polite">Ready</p>
|
||||
</header>
|
||||
|
||||
<div data-hemx-slot="board">{+= self.board =+}</div>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<section data-hemx-root="kanban_client" data-hemx-st="1|2" data-hemx-client-state-version="1" data-hemx-client-module="/kanban_client.js">
|
||||
<p id="kanban-status" data-hemx-slot="client_notice" role="status" aria-live="polite">Ready</p>
|
||||
<ul data-hemx-slot="client_cards">
|
||||
<template h-for="card in &self.cards" h-key="card.id">
|
||||
{+ card +}
|
||||
</template>
|
||||
</ul>
|
||||
<div data-hemx-handle="reorder_card" data-hemx-on="drop" data-hemx-client="reorder_card" data-hemx-client-event="drop" data-hemx-client-policy="latest">Drop card</div>
|
||||
</section>
|
||||
@@ -0,0 +1,4 @@
|
||||
<li class="card" +data-key="self.id" draggable="true" data-hemx-handle="client_card" data-hemx-on="dragstart">
|
||||
<span>{+ self.title +}</span>
|
||||
<button type="button" data-hemx-handle="client_move_right" data-hemx-on="click keydown" data-hemx-client="reorder_card" data-hemx-client-event="click keydown" data-hemx-client-policy="latest" +data-card-id="self.id" aria-describedby="kanban-status">Move right</button>
|
||||
</li>
|
||||
Reference in New Issue
Block a user