From 89414e1c3c4a7db19683234685c2b3a6f490756c Mon Sep 17 00:00:00 2001
From: xda <150917089+xda2023@users.noreply.github.com>
Date: Mon, 23 Sep 2024 12:58:16 +0900
Subject: [PATCH] table: Toggle stripe and number of rows in Table Story (#259)

---
crates/story/src/table_story.rs | 88 ++++++++++++++++++++++++++++++---
crates/ui/src/table.rs | 5 ++
2 files changed, 87 insertions(+), 6 deletions(-)
diff --git a/crates/story/src/table_story.rs b/crates/story/src/table_story.rs
index a1c5edb2..068d58a5 100644
--- a/crates/story/src/table_story.rs
+++ b/crates/story/src/table_story.rs
@@ -9,6 +9,7 @@ use ui::{
checkbox::Checkbox,
h_flex,
indicator::Indicator,
+ input::{InputEvent, TextInput},
label::Label,
prelude::FluentBuilder as _,
table::{ColSort, Table, TableDelegate, TableEvent},
@@ -121,6 +122,12 @@ impl CustomerTableDelegate {
is_eof: false,
}
}
+
+ fn update_customers(&mut self, size: usize) {
+ self.customers = randome_customers(size);
+ self.is_eof = false;
+ self.loading = false;
+ }
}
impl TableDelegate for CustomerTableDelegate {
@@ -360,6 +367,8 @@ impl TableDelegate for CustomerTableDelegate {
pub struct TableStory {
table: View
>,
+ num_customers_input: View,
+ stripe: bool,
}
impl super::Story for TableStory {
@@ -388,12 +397,49 @@ impl TableStory {
}
fn new(cx: &mut ViewContext) -> Self {
+ // Create the number input field with validation for positive integers
+ let num_customers_input = cx.new_view(|cx| {
+ let mut input = TextInput::new(cx)
+ .placeholder("Enter number of customers")
+ .validate(|s| s.parse::().is_ok());
+ input.set_text("5000", cx);
+ input
+ });
+
let delegate = CustomerTableDelegate::new(5000);
let table = cx.new_view(|cx| Table::new(delegate, cx));
cx.subscribe(&table, Self::on_table_event).detach();
+ cx.subscribe(&num_customers_input, Self::on_num_customers_input_change)
+ .detach();
- Self { table }
+ Self {
+ table,
+ num_customers_input,
+ stripe: false,
+ }
+ }
+
+ // Event handler for changes in the number input field
+ fn on_num_customers_input_change(
+ &mut self,
+ _: View,
+ event: &InputEvent,
+ cx: &mut ViewContext,
+ ) {
+ match event {
+ // Update when the user presses Enter or the input loses focus
+ InputEvent::PressEnter | InputEvent::Blur => {
+ let text = self.num_customers_input.read(cx).text().to_string();
+ if let Ok(num) = text.parse::() {
+ self.table.update(cx, |table, _| {
+ table.delegate_mut().update_customers(num);
+ });
+ cx.notify();
+ }
+ }
+ _ => {}
+ }
}
fn toggle_loop_selection(&mut self, checked: &bool, cx: &mut ViewContext) {
@@ -436,6 +482,16 @@ impl TableStory {
});
}
+ fn toggle_stripe(&mut self, checked: &bool, cx: &mut ViewContext) {
+ self.stripe = *checked;
+ let stripe = self.stripe;
+ let table = self.table.clone();
+ table.update(cx, |table, cx| {
+ table.set_stripe(stripe, cx);
+ cx.notify();
+ });
+ }
+
fn on_table_event(
&mut self,
_: View>,
@@ -493,11 +549,31 @@ impl Render for TableStory {
.selected(delegate.col_selection)
.on_click(cx.listener(Self::toggle_col_selection)),
)
- .when(delegate.loading, |this| {
- this.child(h_flex().gap_1().child(Indicator::new()).child("Loading..."))
- })
- .child(format!("Total Rows: {}", delegate.rows_count()))
- .when(delegate.is_eof, |this| this.child("Is loaded all data.")),
+ .child(
+ Checkbox::new("stripe")
+ .label("Stripe")
+ .selected(self.stripe)
+ .on_click(cx.listener(Self::toggle_stripe)),
+ ),
+ )
+ .child(
+ h_flex().items_center().gap_2().child(
+ h_flex()
+ .items_center()
+ .gap_1()
+ .child(Label::new("Number of Customers:"))
+ .child(
+ h_flex()
+ .min_w_32()
+ .child(self.num_customers_input.clone())
+ .into_any_element(),
+ )
+ .when(delegate.loading, |this| {
+ this.child(h_flex().gap_1().child(Indicator::new()).child("Loading..."))
+ })
+ .child(format!("Total Rows: {}", delegate.rows_count()))
+ .when(delegate.is_eof, |this| this.child("All data loaded.")),
+ ),
)
.child(self.table.clone())
}
diff --git a/crates/ui/src/table.rs b/crates/ui/src/table.rs
index 71f45798..70add161 100644
--- a/crates/ui/src/table.rs
+++ b/crates/ui/src/table.rs
@@ -262,6 +262,11 @@ where
self
}
+ pub fn set_stripe(&mut self, stripe: bool, cx: &mut ViewContext) {
+ self.stripe = stripe;
+ cx.notify();
+ }
+
/// Set to use border style of the table, default to true.
pub fn border(mut self, border: bool) -> Self {
self.border = border;