Add `ThemeSelector` component

Marshall Bowers created

Change summary

crates/storybook2/src/stories/components.rs                |  1 
crates/storybook2/src/stories/components/theme_selector.rs | 26 +++++
crates/storybook2/src/story_selector.rs                    |  2 
crates/ui2/src/components.rs                               |  2 
crates/ui2/src/components/theme_selector.rs                | 41 ++++++++
5 files changed, 72 insertions(+)

Detailed changes

crates/storybook2/src/stories/components/theme_selector.rs πŸ”—

@@ -0,0 +1,26 @@
+use std::marker::PhantomData;
+
+use ui::prelude::*;
+use ui::ThemeSelector;
+
+use crate::story::Story;
+
+#[derive(Element)]
+pub struct ThemeSelectorStory<S: 'static + Send + Sync + Clone> {
+    state_type: PhantomData<S>,
+}
+
+impl<S: 'static + Send + Sync + Clone> ThemeSelectorStory<S> {
+    pub fn new() -> Self {
+        Self {
+            state_type: PhantomData,
+        }
+    }
+
+    fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
+        Story::container(cx)
+            .child(Story::title_for::<_, ThemeSelector<S>>(cx))
+            .child(Story::label(cx, "Default"))
+            .child(ThemeSelector::new())
+    }
+}

crates/storybook2/src/story_selector.rs πŸ”—

@@ -53,6 +53,7 @@ pub enum ComponentStory {
     Tab,
     TabBar,
     Terminal,
+    ThemeSelector,
     TitleBar,
     Toast,
     Toolbar,
@@ -88,6 +89,7 @@ impl ComponentStory {
             Self::Tab => components::tab::TabStory::new().into_any(),
             Self::TabBar => components::tab_bar::TabBarStory::new().into_any(),
             Self::Terminal => components::terminal::TerminalStory::new().into_any(),
+            Self::ThemeSelector => components::theme_selector::ThemeSelectorStory::new().into_any(),
             Self::TitleBar => components::title_bar::TitleBarStory::new().into_any(),
             Self::Toast => components::toast::ToastStory::new().into_any(),
             Self::Toolbar => components::toolbar::ToolbarStory::new().into_any(),

crates/ui2/src/components.rs πŸ”—

@@ -21,6 +21,7 @@ mod status_bar;
 mod tab;
 mod tab_bar;
 mod terminal;
+mod theme_selector;
 mod title_bar;
 mod toast;
 mod toolbar;
@@ -50,6 +51,7 @@ pub use status_bar::*;
 pub use tab::*;
 pub use tab_bar::*;
 pub use terminal::*;
+pub use theme_selector::*;
 pub use title_bar::*;
 pub use toast::*;
 pub use toolbar::*;

crates/ui2/src/components/theme_selector.rs πŸ”—

@@ -0,0 +1,41 @@
+use std::marker::PhantomData;
+
+use crate::prelude::*;
+use crate::{OrderMethod, Palette, PaletteItem};
+
+#[derive(Element)]
+pub struct ThemeSelector<S: 'static + Send + Sync + Clone> {
+    state_type: PhantomData<S>,
+    scroll_state: ScrollState,
+}
+
+impl<S: 'static + Send + Sync + Clone> ThemeSelector<S> {
+    pub fn new() -> Self {
+        Self {
+            state_type: PhantomData,
+            scroll_state: ScrollState::default(),
+        }
+    }
+
+    fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
+        div().child(
+            Palette::new(self.scroll_state.clone())
+                .items(vec![
+                    PaletteItem::new("One Dark"),
+                    PaletteItem::new("RosΓ© Pine"),
+                    PaletteItem::new("RosΓ© Pine Moon"),
+                    PaletteItem::new("Sandcastle"),
+                    PaletteItem::new("Solarized Dark"),
+                    PaletteItem::new("Summercamp"),
+                    PaletteItem::new("Atelier Cave Light"),
+                    PaletteItem::new("Atelier Dune Light"),
+                    PaletteItem::new("Atelier Estuary Light"),
+                    PaletteItem::new("Atelier Forest Light"),
+                    PaletteItem::new("Atelier Heath Light"),
+                ])
+                .placeholder("Select Theme...")
+                .empty_string("No matches")
+                .default_order(OrderMethod::Ascending),
+        )
+    }
+}