WIP Restyle channel modal

Nate Butler and Mikayla Maki created

Co-Authored-By: Mikayla Maki <mikayla.c.maki@gmail.com>

Change summary

crates/collab_ui/src/collab_panel/channel_modal.rs | 15 +-
crates/theme/src/theme.rs                          |  2 
styles/src/component/input.ts                      | 26 ++++
styles/src/component/text_button.ts                |  9 +
styles/src/style_tree/channel_modal.ts             | 88 ++++-----------
5 files changed, 64 insertions(+), 76 deletions(-)

Detailed changes

crates/collab_ui/src/collab_panel/channel_modal.rs 🔗

@@ -175,19 +175,16 @@ impl View for ChannelModal {
                     this.set_mode(mode, cx);
                 }
             })
-            .with_cursor_style(if active {
-                CursorStyle::Arrow
-            } else {
-                CursorStyle::PointingHand
-            })
+            .with_cursor_style(CursorStyle::PointingHand)
             .into_any()
         }
 
         Flex::column()
-            .with_child(Label::new(
-                format!("#{}", channel.name),
-                theme.header.clone(),
-            ))
+            .with_child(
+                Label::new(format!("#{}", channel.name), theme.header.text.clone())
+                    .contained()
+                    .with_style(theme.header.container.clone()),
+            )
             .with_child(Flex::row().with_children([
                 render_mode_button::<InviteMembers>(
                     Mode::InviteMembers,

crates/theme/src/theme.rs 🔗

@@ -253,7 +253,7 @@ pub struct CollabPanel {
 pub struct ChannelModal {
     pub container: ContainerStyle,
     pub height: f32,
-    pub header: TextStyle,
+    pub header: ContainedText,
     pub mode_button: Toggleable<Interactive<ContainedText>>,
     pub picker: Picker,
     pub row_height: f32,

styles/src/component/input.ts 🔗

@@ -0,0 +1,26 @@
+import { useTheme } from "../common"
+import { background, border, text } from "../style_tree/components"
+
+export const input = () => {
+    const theme = useTheme()
+
+    return {
+        background: background(theme.highest),
+        corner_radius: 8,
+        min_width: 200,
+        max_width: 500,
+        placeholder_text: text(theme.highest, "mono", "disabled"),
+        selection: theme.players[0],
+        text: text(theme.highest, "mono", "default"),
+        border: border(theme.highest),
+        margin: {
+            right: 12,
+        },
+        padding: {
+            top: 3,
+            bottom: 3,
+            left: 12,
+            right: 8,
+        }
+    }
+}

styles/src/component/text_button.ts 🔗

@@ -13,6 +13,7 @@ interface TextButtonOptions {
     | Theme["lowest"]
     | Theme["middle"]
     | Theme["highest"]
+    variant?: "default" | "ghost"
     color?: keyof Theme["lowest"]
     margin?: Partial<Margin>
     text_properties?: TextProperties
@@ -23,6 +24,7 @@ type ToggleableTextButtonOptions = TextButtonOptions & {
 }
 
 export function text_button({
+    variant = "default",
     color,
     layer,
     margin,
@@ -59,7 +61,7 @@ export function text_button({
         },
         state: {
             default: {
-                background: background(layer ?? theme.lowest, color),
+                background: variant !== "ghost" ? background(layer ?? theme.lowest, color) : null,
                 color: foreground(layer ?? theme.lowest, color),
             },
             hovered: {
@@ -76,14 +78,15 @@ export function text_button({
 
 export function toggleable_text_button(
     theme: Theme,
-    { color, active_color, margin }: ToggleableTextButtonOptions
+    { variant, color, active_color, margin }: ToggleableTextButtonOptions
 ) {
     if (!color) color = "base"
 
     return toggleable({
         state: {
-            inactive: text_button({ color, margin }),
+            inactive: text_button({ variant, color, margin }),
             active: text_button({
+                variant,
                 color: active_color ? active_color : color,
                 margin,
                 layer: theme.middle,

styles/src/style_tree/channel_modal.ts 🔗

@@ -2,6 +2,8 @@ import { useTheme } from "../theme"
 import { interactive, toggleable } from "../element"
 import { background, border, foreground, text } from "./components"
 import picker from "./picker"
+import { input } from "../component/input"
+import { toggleable_text_button } from "../component/text_button"
 
 export default function channel_modal(): any {
     const theme = useTheme()
@@ -19,29 +21,10 @@ export default function channel_modal(): any {
     delete picker_style.shadow
     delete picker_style.border
 
-    const picker_input = {
-        background: background(theme.middle, "on"),
-        corner_radius: 6,
-        text: text(theme.middle, "mono"),
-        placeholder_text: text(theme.middle, "mono", "on", "disabled", {
-            size: "xs",
-        }),
-        selection: theme.players[0],
-        border: border(theme.middle),
-        padding: {
-            bottom: 8,
-            left: 8,
-            right: 8,
-            top: 4,
-        },
-        margin: {
-            left: side_margin,
-            right: side_margin,
-            bottom: 8,
-        },
-    }
+    const picker_input = input()
 
     return {
+        // This is used for the icons that are rendered to the right of channel Members in both UIs
         member_icon: {
             background: background(theme.middle),
             padding: {
@@ -53,6 +36,7 @@ export default function channel_modal(): any {
             width: 5,
             color: foreground(theme.middle, "accent"),
         },
+        // This is used for the icons that are rendered to the right of channel invites in both UIs
         invitee_icon: {
             background: background(theme.middle),
             padding: {
@@ -89,54 +73,32 @@ export default function channel_modal(): any {
             }
         },
         container: {
-            background: background(theme.lowest),
-            border: border(theme.lowest),
+            background: background(theme.middle),
+            border: border(theme.middle),
             shadow: theme.modal_shadow,
             corner_radius: 12,
             padding: {
-                bottom: 4,
-                left: 20,
-                right: 20,
-                top: 20,
+                bottom: 0,
+                left: 0,
+                right: 0,
+                top: 0,
             },
         },
         height: 400,
-        header: text(theme.middle, "sans", "on", { size: "lg" }),
-        mode_button: toggleable({
-            base: interactive({
-                base: {
-                    ...text(theme.middle, "sans", { size: "xs" }),
-                    border: border(theme.middle, "active"),
-                    corner_radius: 4,
-                    padding: {
-                        top: 3,
-                        bottom: 3,
-                        left: 7,
-                        right: 7,
-                    },
-
-                    margin: { left: 6, top: 6, bottom: 6 },
-                },
-                state: {
-                    hovered: {
-                        ...text(theme.middle, "sans", "default", { size: "xs" }),
-                        background: background(theme.middle, "hovered"),
-                        border: border(theme.middle, "active"),
-                    },
-                },
-            }),
-            state: {
-                active: {
-                    default: {
-                        color: foreground(theme.middle, "accent"),
-                    },
-                    hovered: {
-                        color: foreground(theme.middle, "accent", "hovered"),
-                    },
-                    clicked: {
-                        color: foreground(theme.middle, "accent", "pressed"),
-                    },
-                },
+        header: {
+            ...text(theme.middle, "sans", "on", { size: "lg" }),
+            padding: {
+                left: 6,
+            }
+        },
+        mode_button: toggleable_text_button(theme, {
+            variant: "ghost",
+            layer: theme.middle,
+            active_color: "accent",
+            margin: {
+                top: 8,
+                bottom: 8,
+                right: 4
             }
         }),
         picker: {