Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions crates/story/src/stories/data_table_story.rs
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,7 @@ pub struct DataTableStory {
num_extra_cols_input: Entity<InputState>,
stripe: bool,
refresh_data: bool,
group_by_enabled: bool,
size: Size,

_subscriptions: Vec<Subscription>,
Expand Down Expand Up @@ -841,6 +842,7 @@ impl DataTableStory {
num_extra_cols_input,
stripe: false,
refresh_data: false,
group_by_enabled: false,
size: Size::default(),
_subscriptions,
_load_task,
Expand Down Expand Up @@ -964,6 +966,22 @@ impl DataTableStory {
cx.notify();
}

fn toggle_group_by(&mut self, checked: &bool, _: &mut Window, cx: &mut Context<Self>) {
self.group_by_enabled = *checked;
self.table.update(cx, |table, cx| {
if *checked {
table
.delegate_mut()
.stocks
.sort_by(|a, b| a.counter.market.cmp(&b.counter.market));
table.set_group_by(&[1], cx);
} else {
table.set_group_by(&[], cx);
}
});
cx.notify();
}

fn on_change_size(&mut self, a: &ChangeSize, _: &mut Window, cx: &mut Context<Self>) {
self.size = a.0;
cx.notify();
Expand Down Expand Up @@ -1011,6 +1029,9 @@ impl DataTableStory {
TableEvent::ClearSelection => {
println!("Selection cleared");
}
TableEvent::ToggleGroup(key, expanded) => {
println!("Toggle group: {}, expanded={}", key, expanded);
}
}
}

Expand Down Expand Up @@ -1166,6 +1187,12 @@ impl Render for DataTableStory {
.label("Group Headers")
.checked(self.table.read(cx).delegate().show_group_headers)
.on_click(cx.listener(Self::toggle_group_headers)),
)
.child(
Checkbox::new("group-by-market")
.label("Group by Market")
.selected(self.group_by_enabled)
.on_click(cx.listener(Self::toggle_group_by)),
),
)
.child(
Expand Down
16 changes: 12 additions & 4 deletions crates/ui/src/table/data_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,10 @@ where
{
/// Create a new DataTable element with the given [`TableState`].
pub fn new(state: &Entity<TableState<D>>) -> Self {
Self { state: state.clone(), options: TableOptions::default() }
Self {
state: state.clone(),
options: TableOptions::default(),
}
}

/// Set to use stripe style of the table, default to false.
Expand All @@ -115,8 +118,11 @@ where

/// Set scrollbar visibility.
pub fn scrollbar_visible(mut self, vertical: bool, horizontal: bool) -> Self {
self.options.scrollbar_visible =
Edges { right: vertical, bottom: horizontal, ..Default::default() };
self.options.scrollbar_visible = Edges {
right: vertical,
bottom: horizontal,
..Default::default()
};
self
}
}
Expand Down Expand Up @@ -158,7 +164,9 @@ where
.on_action(window.listener_for(&self.state, TableState::action_select_page_down))
.bg(cx.theme().table)
.when(bordered, |this| {
this.rounded(cx.theme().radius).border_1().border_color(cx.theme().border)
this.rounded(cx.theme().radius)
.border_1()
.border_color(cx.theme().border)
})
.child(self.state)
}
Expand Down
37 changes: 37 additions & 0 deletions crates/ui/src/table/delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,41 @@ pub trait TableDelegate: Sized + 'static {
fn cell_text(&self, row_ix: usize, col_ix: usize, cx: &App) -> String {
String::new()
}

// ── Row Grouping ────────────────────────────────────────────────

/// Render the toggle icon (chevron) for a group header row.
///
/// The default implementation draws a `ChevronRight` / `ChevronDown`
/// icon. Override to customise the icon or spacing.
fn render_row_toggle(
&mut self,
is_expanded: bool,
_window: &mut Window,
cx: &mut Context<TableState<Self>>,
) -> impl IntoElement {
let icon = if is_expanded {
IconName::ChevronDown
} else {
IconName::ChevronRight
};
div()
.flex()
.items_center()
.justify_center()
.child(Icon::new(icon).size_3())
}

/// Render a group header row. Called for each group row
/// produced by [`TableState::group_by`].
///
/// The default renders a label showing the group value and count.
fn render_group_tr(
&mut self,
group: &crate::table::GroupInfo,
_window: &mut Window,
_cx: &mut Context<TableState<Self>>,
) -> Stateful<Div> {
div().id(group.key.clone()).child(group.label.clone())
}
}
Loading
Loading