feat(core): format handles for templates
Implement Display for generated Handle<T> values and migrate example view data to carry handles directly instead of raw handle id numbers for dynamic handle attributes. req: public_api/001 req: public_api/002
This commit is contained in:
@@ -4,7 +4,7 @@ use axum::routing::get;
|
|||||||
use axum::Router;
|
use axum::Router;
|
||||||
use futures_util::{stream, StreamExt};
|
use futures_util::{stream, StreamExt};
|
||||||
use hemplate::Hemplate;
|
use hemplate::Hemplate;
|
||||||
use slhx::{IntoEffect, SafeHtml};
|
use slhx::{Handle, IntoEffect, SafeHtml};
|
||||||
use slhx_axum::{runtime_js, sse, DispatchRejection, EffectResponse, HandlerRegistry, InteractionForm, PageRequest};
|
use slhx_axum::{runtime_js, sse, DispatchRejection, EffectResponse, HandlerRegistry, InteractionForm, PageRequest};
|
||||||
use slhx_kanban_example::ui;
|
use slhx_kanban_example::ui;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
@@ -51,9 +51,9 @@ struct BoardColumn {
|
|||||||
struct BoardCard {
|
struct BoardCard {
|
||||||
id: u64,
|
id: u64,
|
||||||
title: String,
|
title: String,
|
||||||
left_handle: u32,
|
left_handle: Handle<()>,
|
||||||
right_handle: u32,
|
right_handle: Handle<()>,
|
||||||
delete_handle: u32,
|
delete_handle: Handle<()>,
|
||||||
left_disabled: bool,
|
left_disabled: bool,
|
||||||
right_disabled: bool,
|
right_disabled: bool,
|
||||||
}
|
}
|
||||||
@@ -292,9 +292,9 @@ fn render_card(card: &Card) -> BoardCard {
|
|||||||
BoardCard {
|
BoardCard {
|
||||||
id: card.id,
|
id: card.id,
|
||||||
title: card.title.clone(),
|
title: card.title.clone(),
|
||||||
left_handle: ui::board::handles::move_left.id().id,
|
left_handle: ui::board::handles::move_left,
|
||||||
right_handle: ui::board::handles::move_right.id().id,
|
right_handle: ui::board::handles::move_right,
|
||||||
delete_handle: ui::board::handles::delete_card.id().id,
|
delete_handle: ui::board::handles::delete_card,
|
||||||
left_disabled: card.column == 0,
|
left_disabled: card.column == 0,
|
||||||
right_disabled: card.column + 1 == COLUMNS.len(),
|
right_disabled: card.column + 1 == COLUMNS.len(),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use axum::routing::get;
|
|||||||
use axum::Router;
|
use axum::Router;
|
||||||
use futures_util::{stream, StreamExt};
|
use futures_util::{stream, StreamExt};
|
||||||
use hemplate::Hemplate;
|
use hemplate::Hemplate;
|
||||||
use slhx::{CssClass, CssClasses, IntoEffect, SafeHtml};
|
use slhx::{CssClass, CssClasses, Handle, IntoEffect, SafeHtml};
|
||||||
use slhx_axum::{
|
use slhx_axum::{
|
||||||
runtime_js, sse, DispatchRejection, EffectResponse, HandlerRegistry, InteractionForm,
|
runtime_js, sse, DispatchRejection, EffectResponse, HandlerRegistry, InteractionForm,
|
||||||
PageRequest,
|
PageRequest,
|
||||||
@@ -102,7 +102,7 @@ struct Shared {
|
|||||||
struct IssueLane {
|
struct IssueLane {
|
||||||
class: CssClass,
|
class: CssClass,
|
||||||
lane_id: &'static str,
|
lane_id: &'static str,
|
||||||
move_handle: u32,
|
move_handle: Handle<()>,
|
||||||
title: &'static str,
|
title: &'static str,
|
||||||
description: &'static str,
|
description: &'static str,
|
||||||
cards: Vec<IssueCard>,
|
cards: Vec<IssueCard>,
|
||||||
@@ -116,9 +116,9 @@ struct IssueCard {
|
|||||||
title: String,
|
title: String,
|
||||||
stage: &'static str,
|
stage: &'static str,
|
||||||
impact_style: String,
|
impact_style: String,
|
||||||
spotlight_handle: u32,
|
spotlight_handle: Handle<()>,
|
||||||
advance_handle: u32,
|
advance_handle: Handle<()>,
|
||||||
delete_handle: u32,
|
delete_handle: Handle<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Hemplate)]
|
#[derive(Hemplate)]
|
||||||
@@ -454,7 +454,7 @@ fn render_board(demo: &DemoState) -> SafeHtml {
|
|||||||
.map(|(idx, (lane_id, title, description))| IssueLane {
|
.map(|(idx, (lane_id, title, description))| IssueLane {
|
||||||
class: ui::control_center::classes::lane,
|
class: ui::control_center::classes::lane,
|
||||||
lane_id,
|
lane_id,
|
||||||
move_handle: ui::control_center::handles::move_to_lane.id().id,
|
move_handle: ui::control_center::handles::move_to_lane,
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
cards: demo
|
cards: demo
|
||||||
@@ -483,9 +483,9 @@ fn issue_card(item: &WorkItem, selected: bool) -> IssueCard {
|
|||||||
title: item.title.clone(),
|
title: item.title.clone(),
|
||||||
stage: item.stage.label(),
|
stage: item.stage.label(),
|
||||||
impact_style: format!("width:{}%", item.impact as usize * 11),
|
impact_style: format!("width:{}%", item.impact as usize * 11),
|
||||||
spotlight_handle: ui::control_center::handles::spotlight_work.id().id,
|
spotlight_handle: ui::control_center::handles::spotlight_work,
|
||||||
advance_handle: ui::control_center::handles::advance_work.id().id,
|
advance_handle: ui::control_center::handles::advance_work,
|
||||||
delete_handle: ui::control_center::handles::delete_work.id().id,
|
delete_handle: ui::control_center::handles::delete_work,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -896,6 +896,12 @@ impl<I> Handle<I> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<I> core::fmt::Display for Handle<I> {
|
||||||
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
self.id.id.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait FormValue {}
|
pub trait FormValue {}
|
||||||
|
|
||||||
impl<T> FormValue for T where T: std::str::FromStr {}
|
impl<T> FormValue for T where T: std::str::FromStr {}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use slhx_core::{
|
use slhx_core::{
|
||||||
event, navigate, redirect, replace, Atom, AtomSnapshot, AtomState, BuildFingerprint,
|
event, navigate, redirect, replace, Atom, AtomSnapshot, AtomState, BuildFingerprint,
|
||||||
CssClass, CssClasses, Effect, EffectBatch, Form, IntoEffect, KeyedSlot, NavigateMode, Payload,
|
CssClass, CssClasses, Effect, EffectBatch, Form, Handle, IntoEffect, KeyedSlot, NavigateMode,
|
||||||
ResourceKind, SafeHtml, ScopeKey, Slot,
|
Payload, ResourceKind, SafeHtml, ScopeKey, Slot,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -93,6 +93,12 @@ fn slot_html_requires_explicit_safe_html() {
|
|||||||
assert_eq!(payload, Payload::Html(String::from("<strong>ok</strong>")));
|
assert_eq!(payload, Payload::Html(String::from("<strong>ok</strong>")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn generated_handles_format_for_hemplate_dynamic_handle_attrs() {
|
||||||
|
// req: public_api/001 req: public_api/002
|
||||||
|
assert_eq!(Handle::<()>::new(42).to_string(), "42");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn generated_css_classes_join_for_hemplate_dynamic_class_attrs() {
|
fn generated_css_classes_join_for_hemplate_dynamic_class_attrs() {
|
||||||
// req: style/003
|
// req: style/003
|
||||||
|
|||||||
Reference in New Issue
Block a user