Skip to main content

fret_ui_headless/table/
cells.rs

1use std::sync::Arc;
2
3use super::ColumnDef;
4use super::RowKey;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct CellSnapshot {
8    pub id: Arc<str>,
9    pub column_id: Arc<str>,
10    pub is_grouped: bool,
11    pub is_placeholder: bool,
12    pub is_aggregated: bool,
13}
14
15/// A Rust-native equivalent of TanStack `cell.getContext()`.
16///
17/// This provides the stable ids/keys required to render a cell without requiring consumers to
18/// re-derive identity from strings.
19#[derive(Debug, Clone, PartialEq, Eq)]
20pub struct CellContextSnapshot {
21    pub id: Arc<str>,
22    pub row_id: super::RowId,
23    pub row_key: RowKey,
24    pub column_id: Arc<str>,
25}
26
27#[derive(Debug, Clone, PartialEq, Eq)]
28pub struct RowCellsSnapshot {
29    pub all: Vec<CellSnapshot>,
30    pub visible: Vec<CellSnapshot>,
31    pub left: Vec<CellSnapshot>,
32    pub center: Vec<CellSnapshot>,
33    pub right: Vec<CellSnapshot>,
34}
35
36pub fn snapshot_cells_for_row<TData>(
37    row_id: &str,
38    all_leaf_columns: &[&ColumnDef<TData>],
39    left_leaf_columns: &[&ColumnDef<TData>],
40    center_leaf_columns: &[&ColumnDef<TData>],
41    right_leaf_columns: &[&ColumnDef<TData>],
42    grouped_column_ids: &[Arc<str>],
43    row_grouping_column_id: Option<&str>,
44    row_has_sub_rows: bool,
45) -> RowCellsSnapshot {
46    let mk = |col: &ColumnDef<TData>| {
47        let column_id = col.id.clone();
48        let column_id_ref = column_id.as_ref();
49
50        let column_is_grouped = grouped_column_ids
51            .iter()
52            .any(|grouped| grouped.as_ref() == column_id_ref);
53        let is_grouped = column_is_grouped
54            && row_grouping_column_id
55                .is_some_and(|grouping_column| grouping_column == column_id_ref);
56        let is_placeholder = column_is_grouped && !is_grouped;
57        let is_aggregated = !is_grouped && !is_placeholder && row_has_sub_rows;
58
59        CellSnapshot {
60            id: Arc::<str>::from(format!("{}_{}", row_id, column_id_ref)),
61            column_id,
62            is_grouped,
63            is_placeholder,
64            is_aggregated,
65        }
66    };
67
68    let left: Vec<CellSnapshot> = left_leaf_columns.iter().copied().map(mk).collect();
69    let center: Vec<CellSnapshot> = center_leaf_columns.iter().copied().map(mk).collect();
70    let right: Vec<CellSnapshot> = right_leaf_columns.iter().copied().map(mk).collect();
71
72    let mut visible = Vec::new();
73    visible.extend(left.iter().cloned());
74    visible.extend(center.iter().cloned());
75    visible.extend(right.iter().cloned());
76
77    RowCellsSnapshot {
78        all: all_leaf_columns.iter().copied().map(mk).collect(),
79        visible,
80        left,
81        center,
82        right,
83    }
84}