Skip to content

Commit 1fe814b

Browse files
committed
fixed examples
1 parent a6d31d2 commit 1fe814b

File tree

6 files changed

+273
-1
lines changed

6 files changed

+273
-1
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ all-features = true
1515

1616
[dependencies]
1717
leptos = { version = "0.8" }
18-
leptos-struct-table-macro = { version = "0.14" }
18+
leptos-struct-table-macro = { version = "0.14.1" }
1919
leptos-use = { version = "0.18", default-features = false, features = [
2020
"element",
2121
"use_debounce_fn",
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[package]
2+
name = "custom_renderers_svg"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
leptos = { version = "0.8", features = ["csr"] }
8+
leptos-struct-table = { path = "../.." }
9+
console_error_panic_hook = "0.1"
10+
console_log = "1"
11+
log = "0.4"
12+
13+
[dev-dependencies]
14+
wasm-bindgen = "0.2"
15+
wasm-bindgen-test = "0.3.0"
16+
web-sys = "0.3"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
### Example that shows how use custom renderers to render the table as SVG.
2+
3+
To make this example work, you must download / fork the whole repo because this is in the Cargo.toml: `leptos-struct-table = { path = "../.." }`.
4+
5+
If you don't have it installed already, install [Trunk](https://trunkrs.dev/)
6+
as well as the wasm32-unknown-unknown target:
7+
8+
```bash
9+
cargo install trunk
10+
rustup target add wasm32-unknown-unknown
11+
```
12+
13+
Then, to run this example, execute in a terminal:
14+
15+
```bash
16+
trunk serve --open
17+
```
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head></head>
4+
<body></body>
5+
</html>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
mod renderers;
2+
3+
use renderers::*;
4+
5+
use leptos::prelude::*;
6+
use leptos_struct_table::*;
7+
8+
// This generates the component BookTable
9+
#[derive(TableRow, Clone)]
10+
#[table(thead_cell_renderer = "SvgHeadCellRenderer", impl_vec_data_provider)]
11+
pub struct Form {
12+
#[table(renderer = "SvgTextCellRenderer")]
13+
pub name: String,
14+
#[table(renderer = "SvgPathCellRenderer")]
15+
pub path: String,
16+
}
17+
18+
fn main() {
19+
_ = console_log::init_with_level(log::Level::Debug);
20+
console_error_panic_hook::set_once();
21+
22+
mount_to_body(|| {
23+
let rows = vec![
24+
Form {
25+
name: "Heart".to_string(),
26+
path: "M12.82 5.58l-.82.822l-.824-.824a5.375 5.375 0 1 0-7.601 7.602l7.895 7.895a.75.75 0 0 0 1.06 0l7.902-7.897a5.376 5.376 0 0 0-.001-7.599a5.38 5.38 0 0 0-7.611 0zm6.548 6.54L12 19.485L4.635 12.12a3.875 3.875 0 1 1 5.48-5.48l1.358 1.357a.75.75 0 0 0 1.073-.012L13.88 6.64a3.88 3.88 0 0 1 5.487 5.48z".to_string(),
27+
},
28+
Form {
29+
name: "Bell".to_string(),
30+
path: "M12 1.996a7.49 7.49 0 0 1 7.496 7.25l.004.25v4.097l1.38 3.156a1.249 1.249 0 0 1-1.145 1.75L15 18.502a3 3 0 0 1-5.995.177L9 18.499H4.275a1.251 1.251 0 0 1-1.147-1.747L4.5 13.594V9.496c0-4.155 3.352-7.5 7.5-7.5zM13.5 18.5l-3 .002a1.5 1.5 0 0 0 2.993.145l.007-.147zM12 3.496c-3.32 0-6 2.674-6 6v4.41L4.656 17h14.697L18 13.907V9.509l-.003-.225A5.988 5.988 0 0 0 12 3.496z".to_string(),
31+
},
32+
Form {
33+
name: "Star".to_string(),
34+
path: "M10.788 3.102c.495-1.003 1.926-1.003 2.421 0l2.358 4.778l5.273.766c1.107.16 1.549 1.522.748 2.303l-3.816 3.719l.901 5.25c.19 1.104-.968 1.945-1.959 1.424l-4.716-2.48l-4.715 2.48c-.99.52-2.148-.32-1.96-1.423l.901-5.251l-3.815-3.72c-.801-.78-.359-2.141.748-2.302L8.43 7.88l2.358-4.778zm1.21.937L9.74 8.614a1.35 1.35 0 0 1-1.016.739l-5.05.734l3.654 3.562c.318.31.463.757.388 1.195l-.862 5.029l4.516-2.375a1.35 1.35 0 0 1 1.257 0l4.516 2.375l-.862-5.03a1.35 1.35 0 0 1 .388-1.194l3.654-3.562l-5.05-.734a1.35 1.35 0 0 1-1.016-.739L11.998 4.04z".to_string(),
35+
},
36+
];
37+
38+
view! {
39+
<svg style="font-family: sans-serif;">
40+
<TableContent
41+
rows
42+
row_renderer=SvgRowRenderer
43+
loading_row_renderer=SvgLoadingRowRenderer
44+
error_row_renderer=SvgErrorRowRenderer
45+
thead_row_renderer=GRenderer
46+
thead_renderer=GRenderer
47+
tbody_renderer=SvgTbodyRenderer
48+
scroll_container="html"
49+
/>
50+
</svg>
51+
}
52+
})
53+
}
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
use crate::Form;
2+
use leptos::prelude::*;
3+
use leptos::web_sys;
4+
use leptos_struct_table::*;
5+
6+
const ROW_HEIGHT: usize = 30;
7+
const ROW_HEIGHT_HALF: usize = ROW_HEIGHT / 2;
8+
9+
wrapper_render_fn!(
10+
/// g
11+
GRenderer,
12+
g,
13+
);
14+
15+
#[allow(non_snake_case)]
16+
pub fn SvgTbodyRenderer(
17+
content: impl IntoView,
18+
class: Signal<String>,
19+
body_ref: BodyRef,
20+
) -> impl IntoView {
21+
view! { <g class=class use:body_ref>{content}</g> }
22+
}
23+
24+
#[allow(unused_variables, non_snake_case)]
25+
pub fn SvgRowRenderer(
26+
class: Signal<String>,
27+
row: RwSignal<Form>,
28+
index: usize,
29+
selected: Signal<bool>,
30+
on_select: EventHandler<web_sys::MouseEvent>,
31+
// Columns to show and their order.
32+
columns: RwSignal<Vec<usize>>,
33+
) -> impl IntoView {
34+
let transform = y_transform_from_index(index);
35+
36+
view! {
37+
<g
38+
class=class
39+
transform=transform
40+
on:click=move |mouse_event| on_select.run(mouse_event)
41+
>
42+
<line
43+
x1="5"
44+
y1="0"
45+
x2="150"
46+
y2="0"
47+
stroke-width="1px"
48+
stroke="black"
49+
opacity="0.1"
50+
></line>
51+
{TableRow::render_row(row, index, columns)}
52+
</g>
53+
}
54+
}
55+
56+
fn y_transform_from_index(index: usize) -> String {
57+
format!("translate(0, {})", (index + 1) * ROW_HEIGHT)
58+
}
59+
60+
#[allow(non_snake_case)]
61+
pub fn SvgErrorRowRenderer(err: String, index: usize, _col_count: usize) -> impl IntoView {
62+
let transform = y_transform_from_index(index);
63+
64+
view! {
65+
<g transform=transform>
66+
<text x="0" y=ROW_HEIGHT_HALF dominant-baseline="central">
67+
{err}
68+
</text>
69+
</g>
70+
}
71+
}
72+
73+
#[allow(non_snake_case, unstable_name_collisions)]
74+
pub fn SvgLoadingRowRenderer(
75+
class: Signal<String>,
76+
_get_cell_class: Callback<(usize,), String>,
77+
get_inner_cell_class: Callback<(usize,), String>,
78+
index: usize,
79+
_col_count: usize,
80+
) -> impl IntoView {
81+
let transform = y_transform_from_index(index);
82+
83+
view! {
84+
<g class=class transform=transform>
85+
<text x="0" y=ROW_HEIGHT_HALF class=get_inner_cell_class.run((0,)) dominant-baseline="central">
86+
Loading...
87+
</text>
88+
</g>
89+
}
90+
}
91+
92+
#[component]
93+
#[allow(unused_variables)]
94+
pub fn SvgHeadCellRenderer<F, Column>(
95+
/// The class attribute for the head element. Generated by the classes provider.
96+
#[prop(into)]
97+
class: Signal<String>,
98+
/// The class attribute for the inner element. Generated by the classes provider.
99+
#[prop(into)]
100+
inner_class: String,
101+
/// The index of the column. Starts at 0 for the first column. The order of the columns is the same as the order of the fields in the struct.
102+
index: usize,
103+
/// The sort priority of the column. `None` if the column is not sorted. `0` means the column is the primary sort column.
104+
#[prop(into)]
105+
sort_priority: Signal<Option<usize>>,
106+
/// The sort direction of the column. See [`ColumnSort`].
107+
#[prop(into)]
108+
sort_direction: Signal<ColumnSort>,
109+
/// The event handler for the click event. Has to be called with [`TableHeadEvent`].
110+
on_click: F,
111+
children: Children,
112+
/// unused here
113+
drag_state: DragStateRwSignal<Column>,
114+
drag_handler: HeadDragHandler<Column>,
115+
columns: RwSignal<Vec<Column>>,
116+
) -> impl IntoView
117+
where
118+
F: Fn(TableHeadEvent<usize>) + 'static,
119+
{
120+
let style = default_th_sorting_style(sort_priority, sort_direction);
121+
122+
let transform = transform_from_index(index, 0);
123+
124+
view! {
125+
<g
126+
class=class
127+
transform=transform
128+
on:click=move |mouse_event| on_click(TableHeadEvent {
129+
index,
130+
mouse_event,
131+
})
132+
133+
style=style
134+
>
135+
<text x="0" y=ROW_HEIGHT_HALF class=inner_class dominant-baseline="central">
136+
{children()}
137+
</text>
138+
</g>
139+
}
140+
}
141+
142+
#[component]
143+
#[allow(unused_variables)]
144+
pub fn SvgTextCellRenderer<T>(
145+
class: String,
146+
value: Signal<T>,
147+
row: RwSignal<Form>,
148+
index: usize,
149+
) -> impl IntoView
150+
where
151+
T: IntoView + Clone + Send + Sync + 'static,
152+
{
153+
let x = x_from_index(index);
154+
155+
view! {
156+
<text x=x y=ROW_HEIGHT_HALF class=class dominant-baseline="central">
157+
{value}
158+
</text>
159+
}
160+
}
161+
162+
#[component]
163+
#[allow(unused_variables)]
164+
pub fn SvgPathCellRenderer(
165+
#[prop(into)] class: String,
166+
value: Signal<String>,
167+
row: RwSignal<Form>,
168+
index: usize,
169+
) -> impl IntoView {
170+
let transform = transform_from_index(index, 3);
171+
172+
view! { <path transform=transform class=class d=value></path> }
173+
}
174+
175+
fn transform_from_index(index: usize, y: usize) -> String {
176+
format!("translate({}, {y})", x_from_index(index))
177+
}
178+
179+
fn x_from_index(index: usize) -> usize {
180+
5 + index * 100
181+
}

0 commit comments

Comments
 (0)