wip

Ben Kunkle created

wip

Change summary

Cargo.lock                                    |   1 
crates/settings_ui/Cargo.toml                 |   1 
crates/settings_ui/src/keybindings.rs         | 130 --------
crates/settings_ui/src/settings_ui.rs         |   1 
crates/settings_ui/src/ui_components/mod.rs   |   1 
crates/settings_ui/src/ui_components/table.rs | 314 +++++++++++++++++++++
crates/ui/src/components.rs                   |   2 
crates/ui/src/components/table.rs             | 271 ------------------
crates/workspace/src/theme_preview.rs         |   4 
9 files changed, 326 insertions(+), 399 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -14567,6 +14567,7 @@ name = "settings_ui"
 version = "0.1.0"
 dependencies = [
  "command_palette_hooks",
+ "component",
  "db",
  "editor",
  "feature_flags",

crates/settings_ui/Cargo.toml 🔗

@@ -13,6 +13,7 @@ path = "src/settings_ui.rs"
 
 [dependencies]
 command_palette_hooks.workspace = true
+component.workspace = true
 db.workspace = true
 editor.workspace = true
 feature_flags.workspace = true

crates/settings_ui/src/keybindings.rs 🔗

@@ -15,7 +15,7 @@ use ui::{
 };
 use workspace::{Item, SerializableItem, Workspace, register_serializable_item};
 
-use crate::keybindings::persistence::KEYBINDING_EDITORS;
+use crate::{keybindings::persistence::KEYBINDING_EDITORS, ui_components::table::Table};
 
 actions!(zed, [OpenKeymapEditor]);
 
@@ -391,7 +391,8 @@ impl Render for KeymapEditor {
             px(0.)
         };
 
-        let table = Table::new(self.processed_bindings.len());
+        let row_count = self.processed_bindings.len();
+        let table = Table::new(row_count);
 
         let theme = cx.theme();
         let headers = ["Command", "Keystrokes", "Context"].map(Into::into);
@@ -412,7 +413,6 @@ impl Render for KeymapEditor {
             }))
             .child(
                 table
-                    .render()
                     .h_full()
                     .v_flex()
                     .child(table.render_header(headers, cx))
@@ -424,10 +424,9 @@ impl Render for KeymapEditor {
                             .overflow_hidden()
                             .child(
                                 uniform_list(
-                                    cx.entity(),
                                     "keybindings",
-                                    table.row_count,
-                                    move |this, range, _, cx| {
+                                    row_count,
+                                    cx.processor(move |this, range, _, cx| {
                                         range
                                             .map(|index| {
                                                 let binding = &this.processed_bindings[index];
@@ -443,7 +442,7 @@ impl Render for KeymapEditor {
                                                 table.render_row(index, row, cx)
                                             })
                                             .collect()
-                                    },
+                                    }),
                                 )
                                 .size_full()
                                 .flex_grow()
@@ -518,123 +517,6 @@ impl Render for KeymapEditor {
     }
 }
 
-/// A table component
-#[derive(Clone, Copy)]
-pub struct Table<const COLS: usize> {
-    striped: bool,
-    width: Length,
-    row_count: usize,
-}
-
-impl<const COLS: usize> Table<COLS> {
-    /// Create a new table with a column count equal to the
-    /// number of headers provided.
-    pub fn new(row_count: usize) -> Self {
-        Table {
-            striped: false,
-            width: Length::Auto,
-            row_count,
-        }
-    }
-
-    /// Enables row striping.
-    pub fn striped(mut self) -> Self {
-        self.striped = true;
-        self
-    }
-
-    /// Sets the width of the table.
-    pub fn width(mut self, width: impl Into<Length>) -> Self {
-        self.width = width.into();
-        self
-    }
-
-    fn base_cell_style(cx: &App) -> Div {
-        div()
-            .px_1p5()
-            .flex_1()
-            .justify_start()
-            .text_ui(cx)
-            .whitespace_nowrap()
-            .text_ellipsis()
-            .overflow_hidden()
-    }
-
-    pub fn render_row(&self, row_index: usize, items: [TableCell; COLS], cx: &App) -> AnyElement {
-        let is_last = row_index == self.row_count - 1;
-        let bg = if row_index % 2 == 1 && self.striped {
-            Some(cx.theme().colors().text.opacity(0.05))
-        } else {
-            None
-        };
-        div()
-            .w_full()
-            .flex()
-            .flex_row()
-            .items_center()
-            .justify_between()
-            .px_1p5()
-            .py_1()
-            .when_some(bg, |row, bg| row.bg(bg))
-            .when(!is_last, |row| {
-                row.border_b_1().border_color(cx.theme().colors().border)
-            })
-            .children(items.into_iter().map(|cell| match cell {
-                TableCell::String(s) => Self::base_cell_style(cx).child(s),
-                TableCell::Element(e) => Self::base_cell_style(cx).child(e),
-            }))
-            .into_any_element()
-    }
-
-    fn render_header(&self, headers: [SharedString; COLS], cx: &mut App) -> impl IntoElement {
-        div()
-            .flex()
-            .flex_row()
-            .items_center()
-            .justify_between()
-            .w_full()
-            .p_2()
-            .border_b_1()
-            .border_color(cx.theme().colors().border)
-            .children(headers.into_iter().map(|h| {
-                Self::base_cell_style(cx)
-                    .font_weight(FontWeight::SEMIBOLD)
-                    .child(h.clone())
-            }))
-    }
-
-    fn render(&self) -> Div {
-        div().w(self.width).overflow_hidden()
-    }
-}
-
-/// Represents a cell in a table.
-pub enum TableCell {
-    /// A cell containing a string value.
-    String(SharedString),
-    /// A cell containing a UI element.
-    Element(AnyElement),
-}
-
-/// Creates a `TableCell` containing a string value.
-pub fn string_cell(s: impl Into<SharedString>) -> TableCell {
-    TableCell::String(s.into())
-}
-
-/// Creates a `TableCell` containing an element.
-pub fn element_cell(e: impl Into<AnyElement>) -> TableCell {
-    TableCell::Element(e.into())
-}
-
-impl<E> From<E> for TableCell
-where
-    E: Into<SharedString>,
-{
-    fn from(e: E) -> Self {
-        TableCell::String(e.into())
-    }
-}
-
 impl SerializableItem for KeymapEditor {
     fn serialized_item_kind() -> &'static str {
         "KeymapEditor"

crates/settings_ui/src/settings_ui.rs 🔗

@@ -21,6 +21,7 @@ use workspace::{Workspace, with_active_or_new_workspace};
 use crate::appearance_settings_controls::AppearanceSettingsControls;
 
 pub mod keybindings;
+pub mod ui_components;
 
 pub struct SettingsUiFeatureFlag;
 

crates/settings_ui/src/ui_components/table.rs 🔗

@@ -0,0 +1,314 @@
+use std::ops::Range;
+
+use db::smol::stream::iter;
+use gpui::{Entity, FontWeight, Length, uniform_list};
+use ui::{
+    ActiveTheme as _, AnyElement, App, Button, ButtonCommon as _, ButtonStyle, Color, Component,
+    ComponentScope, Div, ElementId, FixedWidth as _, FluentBuilder as _, Indicator, IntoElement,
+    ParentElement, RegisterComponent, RenderOnce, Styled, StyledTypography, Window, div,
+    example_group_with_title, px, single_example, v_flex,
+};
+
+struct UniformListData {
+    render_item_fn: Box<dyn Fn(Range<usize>, &mut Window, &mut App) -> Vec<AnyElement>>,
+    element_id: ElementId,
+    row_count: usize,
+}
+
+enum TableContents<const COLS: usize> {
+    Vec(Vec<[AnyElement; COLS]>),
+    UniformList(UniformListData),
+}
+
+impl<const COLS: usize> TableContents<COLS> {
+    fn rows_mut(&mut self) -> Option<&mut Vec<[AnyElement; COLS]>> {
+        match self {
+            TableContents::Vec(rows) => Some(rows),
+            TableContents::UniformList(_) => None,
+        }
+    }
+
+    fn len(&self) -> usize {
+        match self {
+            TableContents::Vec(rows) => rows.len(),
+            TableContents::UniformList(data) => data.row_count,
+        }
+    }
+}
+
+/// A table component
+#[derive(RegisterComponent, IntoElement)]
+pub struct Table<const COLS: usize = 3> {
+    striped: bool,
+    width: Length,
+    headers: Option<[AnyElement; COLS]>,
+    rows: TableContents<COLS>,
+}
+
+impl<const COLS: usize> Table<COLS> {
+    pub fn uniform_list(
+        id: impl Into<ElementId>,
+        row_count: usize,
+        render_item_fn: impl Fn(Range<usize>, &mut Window, &mut App) -> Vec<AnyElement> + 'static,
+    ) -> Self {
+        Table {
+            striped: false,
+            width: Length::Auto,
+            headers: None,
+            rows: TableContents::UniformList(UniformListData {
+                element_id: id.into(),
+                row_count: row_count,
+                render_item_fn: Box::new(render_item_fn),
+            }),
+        }
+    }
+
+    /// Create a new table with a column count equal to the
+    /// number of headers provided.
+    pub fn new() -> Self {
+        Table {
+            striped: false,
+            width: Length::Auto,
+            headers: None,
+            rows: TableContents::Vec(Vec::new()),
+        }
+    }
+
+    /// Enables row striping.
+    pub fn striped(mut self) -> Self {
+        self.striped = true;
+        self
+    }
+
+    /// Sets the width of the table.
+    pub fn width(mut self, width: impl Into<Length>) -> Self {
+        self.width = width.into();
+        self
+    }
+
+    pub fn header(mut self, headers: [impl IntoElement; COLS]) -> Self {
+        self.headers = Some(headers.map(IntoElement::into_any_element));
+        self
+    }
+
+    pub fn row(mut self, items: [impl IntoElement; COLS]) -> Self {
+        if let Some(rows) = self.rows.rows_mut() {
+            rows.push(items.map(IntoElement::into_any_element));
+        }
+        self
+    }
+
+    pub fn render_row(&self, items: [impl IntoElement; COLS], cx: &mut App) -> AnyElement {
+        return render_row(0, items, self.rows.len(), self.striped, cx);
+    }
+
+    pub fn render_header(
+        &self,
+        headers: [impl IntoElement; COLS],
+        cx: &mut App,
+    ) -> impl IntoElement {
+        render_header(headers, cx)
+    }
+}
+
+fn base_cell_style(cx: &App) -> Div {
+    div()
+        .px_1p5()
+        .flex_1()
+        .justify_start()
+        .text_ui(cx)
+        .whitespace_nowrap()
+        .text_ellipsis()
+        .overflow_hidden()
+}
+
+pub fn render_row<const COLS: usize>(
+    row_index: usize,
+    items: [impl IntoElement; COLS],
+    row_count: usize,
+    striped: bool,
+    cx: &App,
+) -> AnyElement {
+    let is_last = row_index == row_count - 1;
+    let bg = if row_index % 2 == 1 && striped {
+        Some(cx.theme().colors().text.opacity(0.05))
+    } else {
+        None
+    };
+    div()
+        .w_full()
+        .flex()
+        .flex_row()
+        .items_center()
+        .justify_between()
+        .px_1p5()
+        .py_1()
+        .when_some(bg, |row, bg| row.bg(bg))
+        .when(!is_last, |row| {
+            row.border_b_1().border_color(cx.theme().colors().border)
+        })
+        .children(
+            items
+                .map(IntoElement::into_any_element)
+                .map(|cell| base_cell_style(cx).child(cell)),
+        )
+        .into_any_element()
+}
+
+pub fn render_header<const COLS: usize>(
+    headers: [impl IntoElement; COLS],
+    cx: &mut App,
+) -> impl IntoElement {
+    div()
+        .flex()
+        .flex_row()
+        .items_center()
+        .justify_between()
+        .w_full()
+        .p_2()
+        .border_b_1()
+        .border_color(cx.theme().colors().border)
+        .children(headers.into_iter().map(|h| {
+            base_cell_style(cx)
+                .font_weight(FontWeight::SEMIBOLD)
+                .child(h)
+        }))
+}
+
+impl<const COLS: usize> RenderOnce for Table<COLS> {
+    fn render(mut self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
+        // match self.ro
+        let row_count = self.rows.len();
+        div()
+            .w(self.width)
+            .overflow_hidden()
+            .when_some(self.headers.take(), |this, headers| {
+                this.child(render_header(headers, cx))
+            })
+            .map(|div| match self.rows {
+                TableContents::Vec(items) => div.children(
+                    items
+                        .into_iter()
+                        .enumerate()
+                        .map(|(index, row)| render_row(index, row, row_count, self.striped, cx)),
+                ),
+                TableContents::UniformList(uniform_list_data) => div.child(uniform_list(
+                    uniform_list_data.element_id,
+                    uniform_list_data.row_count,
+                    uniform_list_data.render_item_fn,
+                )),
+            })
+    }
+}
+
+impl Component for Table<3> {
+    fn scope() -> ComponentScope {
+        ComponentScope::Layout
+    }
+
+    fn description() -> Option<&'static str> {
+        Some("A table component for displaying data in rows and columns with optional styling.")
+    }
+
+    fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
+        Some(
+            v_flex()
+                .gap_6()
+                .children(vec![
+                    example_group_with_title(
+                        "Basic Tables",
+                        vec![
+                            single_example(
+                                "Simple Table",
+                                Table::new()
+                                    .width(px(400.))
+                                    .header(["Name", "Age", "City"])
+                                    .row(["Alice", "28", "New York"])
+                                    .row(["Bob", "32", "San Francisco"])
+                                    .row(["Charlie", "25", "London"])
+                                    .into_any_element(),
+                            ),
+                            single_example(
+                                "Two Column Table",
+                                Table::new()
+                                    .header(["Category", "Value"])
+                                    .width(px(300.))
+                                    .row(["Revenue", "$100,000"])
+                                    .row(["Expenses", "$75,000"])
+                                    .row(["Profit", "$25,000"])
+                                    .into_any_element(),
+                            ),
+                        ],
+                    ),
+                    example_group_with_title(
+                        "Styled Tables",
+                        vec![
+                            single_example(
+                                "Default",
+                                Table::new()
+                                    .width(px(400.))
+                                    .header(["Product", "Price", "Stock"])
+                                    .row(["Laptop", "$999", "In Stock"])
+                                    .row(["Phone", "$599", "Low Stock"])
+                                    .row(["Tablet", "$399", "Out of Stock"])
+                                    .into_any_element(),
+                            ),
+                            single_example(
+                                "Striped",
+                                Table::new()
+                                    .width(px(400.))
+                                    .striped()
+                                    .header(["Product", "Price", "Stock"])
+                                    .row(["Laptop", "$999", "In Stock"])
+                                    .row(["Phone", "$599", "Low Stock"])
+                                    .row(["Tablet", "$399", "Out of Stock"])
+                                    .row(["Headphones", "$199", "In Stock"])
+                                    .into_any_element(),
+                            ),
+                        ],
+                    ),
+                    example_group_with_title(
+                        "Mixed Content Table",
+                        vec![single_example(
+                            "Table with Elements",
+                            Table::new()
+                                .width(px(840.))
+                                .header(["Status", "Name", "Priority", "Deadline", "Action"])
+                                .row([
+                                    Indicator::dot().color(Color::Success).into_any_element(),
+                                    "Project A".into_any_element(),
+                                    "High".into_any_element(),
+                                    "2023-12-31".into_any_element(),
+                                    Button::new("view_a", "View")
+                                        .style(ButtonStyle::Filled)
+                                        .full_width()
+                                        .into_any_element(),
+                                ])
+                                .row([
+                                    Indicator::dot().color(Color::Warning).into_any_element(),
+                                    "Project B".into_any_element(),
+                                    "Medium".into_any_element(),
+                                    "2024-03-15".into_any_element(),
+                                    Button::new("view_b", "View")
+                                        .style(ButtonStyle::Filled)
+                                        .full_width()
+                                        .into_any_element(),
+                                ])
+                                .row([
+                                    Indicator::dot().color(Color::Error).into_any_element(),
+                                    "Project C".into_any_element(),
+                                    "Low".into_any_element(),
+                                    "2024-06-30".into_any_element(),
+                                    Button::new("view_c", "View")
+                                        .style(ButtonStyle::Filled)
+                                        .full_width()
+                                        .into_any_element(),
+                                ])
+                                .into_any_element(),
+                        )],
+                    ),
+                ])
+                .into_any_element(),
+        )
+    }
+}

crates/ui/src/components.rs 🔗

@@ -32,7 +32,6 @@ mod settings_group;
 mod stack;
 mod tab;
 mod tab_bar;
-mod table;
 mod toggle;
 mod tooltip;
 
@@ -73,7 +72,6 @@ pub use settings_group::*;
 pub use stack::*;
 pub use tab::*;
 pub use tab_bar::*;
-pub use table::*;
 pub use toggle::*;
 pub use tooltip::*;
 

crates/ui/src/components/table.rs 🔗

@@ -1,271 +0,0 @@
-use crate::{Indicator, prelude::*};
-use gpui::{AnyElement, FontWeight, IntoElement, Length, div};
-
-/// A table component
-#[derive(IntoElement, RegisterComponent)]
-pub struct Table {
-    column_headers: Vec<SharedString>,
-    rows: Vec<Vec<TableCell>>,
-    column_count: usize,
-    striped: bool,
-    width: Length,
-}
-
-impl Table {
-    /// Create a new table with a column count equal to the
-    /// number of headers provided.
-    pub fn new(headers: Vec<impl Into<SharedString>>) -> Self {
-        let column_count = headers.len();
-
-        Table {
-            column_headers: headers.into_iter().map(Into::into).collect(),
-            column_count,
-            rows: Vec::new(),
-            striped: false,
-            width: Length::Auto,
-        }
-    }
-
-    /// Adds a row to the table.
-    ///
-    /// The row must have the same number of columns as the table.
-    pub fn row(mut self, items: Vec<impl Into<TableCell>>) -> Self {
-        if items.len() == self.column_count {
-            self.rows.push(items.into_iter().map(Into::into).collect());
-        } else {
-            log::error!("Row length mismatch");
-        }
-        self
-    }
-
-    /// Adds multiple rows to the table.
-    ///
-    /// Each row must have the same number of columns as the table.
-    /// Rows that don't match the column count are ignored.
-    pub fn rows(mut self, rows: Vec<Vec<impl Into<TableCell>>>) -> Self {
-        for row in rows {
-            self = self.row(row);
-        }
-        self
-    }
-
-    fn base_cell_style(cx: &mut App) -> Div {
-        div()
-            .px_1p5()
-            .flex_1()
-            .justify_start()
-            .text_ui(cx)
-            .whitespace_nowrap()
-            .text_ellipsis()
-            .overflow_hidden()
-    }
-
-    /// Enables row striping.
-    pub fn striped(mut self) -> Self {
-        self.striped = true;
-        self
-    }
-
-    /// Sets the width of the table.
-    pub fn width(mut self, width: impl Into<Length>) -> Self {
-        self.width = width.into();
-        self
-    }
-}
-
-impl RenderOnce for Table {
-    fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
-        let header = div()
-            .flex()
-            .flex_row()
-            .items_center()
-            .justify_between()
-            .w_full()
-            .p_2()
-            .border_b_1()
-            .border_color(cx.theme().colors().border)
-            .children(self.column_headers.into_iter().map(|h| {
-                Table::base_cell_style(cx)
-                    .font_weight(FontWeight::SEMIBOLD)
-                    .child(h.clone())
-            }));
-
-        let row_count = self.rows.len();
-        let rows = self.rows.into_iter().enumerate().map(|(ix, row)| {
-            let is_last = ix == row_count - 1;
-            let bg = if ix % 2 == 1 && self.striped {
-                Some(cx.theme().colors().text.opacity(0.05))
-            } else {
-                None
-            };
-            div()
-                .w_full()
-                .flex()
-                .flex_row()
-                .items_center()
-                .justify_between()
-                .px_1p5()
-                .py_1()
-                .when_some(bg, |row, bg| row.bg(bg))
-                .when(!is_last, |row| {
-                    row.border_b_1().border_color(cx.theme().colors().border)
-                })
-                .children(row.into_iter().map(|cell| match cell {
-                    TableCell::String(s) => Self::base_cell_style(cx).child(s),
-                    TableCell::Element(e) => Self::base_cell_style(cx).child(e),
-                }))
-        });
-
-        div()
-            .w(self.width)
-            .overflow_hidden()
-            .child(header)
-            .children(rows)
-    }
-}
-
-/// Represents a cell in a table.
-pub enum TableCell {
-    /// A cell containing a string value.
-    String(SharedString),
-    /// A cell containing a UI element.
-    Element(AnyElement),
-}
-
-/// Creates a `TableCell` containing a string value.
-pub fn string_cell(s: impl Into<SharedString>) -> TableCell {
-    TableCell::String(s.into())
-}
-
-/// Creates a `TableCell` containing an element.
-pub fn element_cell(e: impl Into<AnyElement>) -> TableCell {
-    TableCell::Element(e.into())
-}
-
-impl<E> From<E> for TableCell
-where
-    E: Into<SharedString>,
-{
-    fn from(e: E) -> Self {
-        TableCell::String(e.into())
-    }
-}
-
-impl Component for Table {
-    fn scope() -> ComponentScope {
-        ComponentScope::Layout
-    }
-
-    fn description() -> Option<&'static str> {
-        Some("A table component for displaying data in rows and columns with optional styling.")
-    }
-
-    fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
-        Some(
-            v_flex()
-                .gap_6()
-                .children(vec![
-                    example_group_with_title(
-                        "Basic Tables",
-                        vec![
-                            single_example(
-                                "Simple Table",
-                                Table::new(vec!["Name", "Age", "City"])
-                                    .width(px(400.))
-                                    .row(vec!["Alice", "28", "New York"])
-                                    .row(vec!["Bob", "32", "San Francisco"])
-                                    .row(vec!["Charlie", "25", "London"])
-                                    .into_any_element(),
-                            ),
-                            single_example(
-                                "Two Column Table",
-                                Table::new(vec!["Category", "Value"])
-                                    .width(px(300.))
-                                    .row(vec!["Revenue", "$100,000"])
-                                    .row(vec!["Expenses", "$75,000"])
-                                    .row(vec!["Profit", "$25,000"])
-                                    .into_any_element(),
-                            ),
-                        ],
-                    ),
-                    example_group_with_title(
-                        "Styled Tables",
-                        vec![
-                            single_example(
-                                "Default",
-                                Table::new(vec!["Product", "Price", "Stock"])
-                                    .width(px(400.))
-                                    .row(vec!["Laptop", "$999", "In Stock"])
-                                    .row(vec!["Phone", "$599", "Low Stock"])
-                                    .row(vec!["Tablet", "$399", "Out of Stock"])
-                                    .into_any_element(),
-                            ),
-                            single_example(
-                                "Striped",
-                                Table::new(vec!["Product", "Price", "Stock"])
-                                    .width(px(400.))
-                                    .striped()
-                                    .row(vec!["Laptop", "$999", "In Stock"])
-                                    .row(vec!["Phone", "$599", "Low Stock"])
-                                    .row(vec!["Tablet", "$399", "Out of Stock"])
-                                    .row(vec!["Headphones", "$199", "In Stock"])
-                                    .into_any_element(),
-                            ),
-                        ],
-                    ),
-                    example_group_with_title(
-                        "Mixed Content Table",
-                        vec![single_example(
-                            "Table with Elements",
-                            Table::new(vec!["Status", "Name", "Priority", "Deadline", "Action"])
-                                .width(px(840.))
-                                .row(vec![
-                                    element_cell(
-                                        Indicator::dot().color(Color::Success).into_any_element(),
-                                    ),
-                                    string_cell("Project A"),
-                                    string_cell("High"),
-                                    string_cell("2023-12-31"),
-                                    element_cell(
-                                        Button::new("view_a", "View")
-                                            .style(ButtonStyle::Filled)
-                                            .full_width()
-                                            .into_any_element(),
-                                    ),
-                                ])
-                                .row(vec![
-                                    element_cell(
-                                        Indicator::dot().color(Color::Warning).into_any_element(),
-                                    ),
-                                    string_cell("Project B"),
-                                    string_cell("Medium"),
-                                    string_cell("2024-03-15"),
-                                    element_cell(
-                                        Button::new("view_b", "View")
-                                            .style(ButtonStyle::Filled)
-                                            .full_width()
-                                            .into_any_element(),
-                                    ),
-                                ])
-                                .row(vec![
-                                    element_cell(
-                                        Indicator::dot().color(Color::Error).into_any_element(),
-                                    ),
-                                    string_cell("Project C"),
-                                    string_cell("Low"),
-                                    string_cell("2024-06-30"),
-                                    element_cell(
-                                        Button::new("view_c", "View")
-                                            .style(ButtonStyle::Filled)
-                                            .full_width()
-                                            .into_any_element(),
-                                    ),
-                                ])
-                                .into_any_element(),
-                        )],
-                    ),
-                ])
-                .into_any_element(),
-        )
-    }
-}

crates/workspace/src/theme_preview.rs 🔗

@@ -5,8 +5,8 @@ use theme::all_theme_colors;
 use ui::{
     AudioStatus, Avatar, AvatarAudioStatusIndicator, AvatarAvailabilityIndicator, ButtonLike,
     Checkbox, CheckboxWithLabel, CollaboratorAvailability, ContentGroup, DecoratedIcon,
-    ElevationIndex, Facepile, IconDecoration, Indicator, KeybindingHint, Switch, Table, TintColor,
-    Tooltip, element_cell, prelude::*, string_cell, utils::calculate_contrast_ratio,
+    ElevationIndex, Facepile, IconDecoration, Indicator, KeybindingHint, Switch, TintColor,
+    Tooltip, prelude::*, utils::calculate_contrast_ratio,
 };
 
 use crate::{Item, Workspace};