Skip to content

Commit

Permalink
chore: csr example
Browse files Browse the repository at this point in the history
  • Loading branch information
brofrain committed Oct 26, 2023
1 parent 021156c commit d020b38
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 51 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
dist
target

# Editor directories and files
Expand Down
1 change: 1 addition & 0 deletions examples/csr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ rand = "0.8.5"

[lints.clippy]
pedantic = "warn"
module-name-repetitions = "allow"
9 changes: 9 additions & 0 deletions examples/csr/Trunk.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[serve]
address = "127.0.0.1"
port = 8080
open = false
no_autoreload = false

[watch]
watch = ["index.html", "src"]
ignore = []
2 changes: 2 additions & 0 deletions examples/csr/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<title>CSR example</title>

<link data-trunk rel="tailwind-css" href="src/tailwind.css" />
</head>
</html>
10 changes: 10 additions & 0 deletions examples/csr/src/button.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use leptos::{component, view, Children, IntoView};

#[component]
pub fn Button(children: Children) -> impl IntoView {
view! {
<button class="rounded px-4 py-1
bg-purple-500 hover:bg-purple-600 transition
cursor-pointer select-none">{children()}</button>
}
}
17 changes: 17 additions & 0 deletions examples/csr/src/circle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use leptos::{component, view, Children, IntoView, MaybeProp};

#[component]
pub fn Circle(
children: Children,
#[prop(optional, into)] class: MaybeProp<String>,
) -> impl IntoView {
let class = move || {
[
"rounded-full flex items-center justify-center".to_owned(),
class().unwrap_or_default(),
]
.join(" ")
};

view! { <div class=class>{children()}</div> }
}
158 changes: 107 additions & 51 deletions examples/csr/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
mod button;
mod circle;

use leptos::{
component,
mount_to_body,
Expand All @@ -8,96 +11,149 @@ use leptos::{
RwSignal,
SignalUpdate,
StoredValue,
View,
};
use leptos_animated_for::AnimatedFor;
use rand::{seq::SliceRandom, thread_rng, Rng};

use crate::{button::Button, circle::Circle};

#[derive(Clone)]
struct Item {
id: usize,
view: View,
}

const INITIAL_ITEM_COUNT: usize = 20;
const INITIAL_ITEM_COUNT: usize = 40;

#[allow(clippy::too_many_lines)]
#[component]
fn App() -> impl IntoView {
let last_added_item_id = StoredValue::new(INITIAL_ITEM_COUNT);
let items = RwSignal::new(
(1..INITIAL_ITEM_COUNT)
.map(|id| Item { id })
.collect::<Vec<_>>(),
);
let last_added_item_id = StoredValue::new(0);

let rng = StoredValue::new(thread_rng());

let create_new_item = Callback::new(move |()| {
let id = last_added_item_id();
last_added_item_id.set_value(id + 1);
Item { id }

let mut circle = None;
let mut bg_color_class = None;

rng.update_value(|rng| {
circle = Some(matches!(rng.gen_range(0..=1), 0));

bg_color_class = Some(match rng.gen_range(0..=2) {
0 => "bg-red-500/70",
1 => "bg-green-500/70",
_ => "bg-blue-500/70",
});
});

let view = if circle.unwrap() {
view! { <Circle class=bg_color_class.unwrap()>{id}</Circle> }
.into_view()
} else {
view! {
<div class=["rounded flex items-center justify-center", bg_color_class.unwrap()]
.join(" ")>{id}</div>
}
.into_view()
};

Item { id, view }
});

let shuffle = move || {
let items = RwSignal::new(
(0..INITIAL_ITEM_COUNT)
.map(|_| create_new_item(()))
.collect::<Vec<_>>(),
);

let shuffle = move |_| {
items.update(|items| {
rng.update_value(|rng| {
items.shuffle(rng);
});
});
};

let add_start = {
move || {
update!(|items| {
items.insert(0, create_new_item(()));
});
}
let add_start = move |_| {
update!(|items| {
items.insert(0, create_new_item(()));
});
};

let add_end = {
move || {
update!(|items| {
items.push(create_new_item(()));
});
}
let add_end = move |_| {
update!(|items| {
items.push(create_new_item(()));
});
};

let add_random = {
move || {
items.update(|items| {
rng.update_value(|rng| {
items.insert(
rng.gen_range(0..items.len()),
create_new_item(()),
);
});
let add_random = move |_| {
items.update(|items| {
let item = create_new_item(());
rng.update_value(|rng| {
items.insert(rng.gen_range(0..items.len()), item);
});
}
});
};

let remove_start = {
move || {
update!(|items| {
items.remove(0);
});
}
let remove_start = move |_| {
update!(|items| {
if items.is_empty() {
return;
}

items.remove(0);
});
};

let remove_end = {
move || {
update!(|items| {
items.pop();
});
}
let remove_end = move |_| {
update!(|items| {
items.pop();
});
};

let remove_random = {
move || {
items.update(|items| {
rng.update_value(|rng| {
items.remove(rng.gen_range(0..items.len()));
});
let remove_random = move |_| {
items.update(|items| {
if items.is_empty() {
return;
}

rng.update_value(|rng| {
items.remove(rng.gen_range(0..items.len()));
});
}
});
};

view! { <div></div> }
view! {
<div class="min-h-screen py-8 bg-gray-800 font-bold text-white">
<div class="flex flex-wrap gap-2 justify-center">
<Button on:click=add_start>{"Add start"}</Button>
<Button on:click=add_end>{"Add end"}</Button>
<Button on:click=add_random>{"Add random"}</Button>
<Button on:click=remove_start>{"Remove start"}</Button>
<Button on:click=remove_end>{"Remove end"}</Button>
<Button on:click=remove_random>{"Remove random"}</Button>
<Button on:click=shuffle>{"Shuffle"}</Button>
</div>

<div class="mt-4 grid grid-cols-[repeat(5,auto)] gap-2 justify-center text-xl [&>*]:w-16 [&>*]:h-16">
<AnimatedFor
each=items
key=|item| item.id
children=|item| item.view
enter_from_class="opacity-0"
enter_class="duration-1000"
move_class="duration-1000"
leave_class="opacity-0 duration-1000"
appear=true
/>

</div>
</div>
}
}

fn main() {
Expand Down
3 changes: 3 additions & 0 deletions examples/csr/src/tailwind.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
11 changes: 11 additions & 0 deletions examples/csr/tailwind.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/** @type { import('tailwindcss').Config } */

module.exports = {
content: {
files: ["src/**/*.rs"],
},
theme: {
extend: {},
},
plugins: [],
};

0 comments on commit d020b38

Please sign in to comment.