woocraft 0.4.5

GPUI components lib for Woocraft design system.
Documentation
use gpui::{
  App, AppContext, Application, Bounds, Context, Entity, IntoElement, ParentElement, Render,
  Size as GpuiSize, Styled, Window, WindowBounds, WindowOptions, div, px,
};
use woocraft::{
  ActiveTheme, Button, ContextMenuExt as _, DropdownMenu as _, IconName, PopupMenuItem,
  StyledExt as _, ThemeMode, h_flex, v_flex, window_border,
};

#[derive(Default)]
struct MenuWindow {
  selected: String,
  checked: bool,
}

impl MenuWindow {
  fn view(cx: &mut App) -> Entity<Self> {
    cx.new(|_| Self {
      selected: "None".to_string(),
      checked: true,
    })
  }
}

impl Render for MenuWindow {
  fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
    let view = cx.entity().clone();

    let menu_trigger = Button::new("menu-trigger")
      .label("Open Menu")
      .dropdown_menu(move |menu, _, _| {
        let view = view.clone();
        let view_refresh = view.clone();
        let view_pin = view.clone();
        menu
          .item(
            PopupMenuItem::new("Refresh")
              .icon(IconName::ArrowSync)
              .on_click(move |_, _, cx| {
                view_refresh.update(cx, |state, cx| {
                  state.selected = "Refresh".to_string();
                  cx.notify();
                });
              }),
          )
          .item(
            PopupMenuItem::new("Pinned")
              .checked(true)
              .on_click(move |_, _, cx| {
                view_pin.update(cx, |state, cx| {
                  state.selected = "Pinned".to_string();
                  state.checked = !state.checked;
                  cx.notify();
                });
              }),
          )
          .item(PopupMenuItem::new("Disabled Item").disabled(true))
          .separator()
          .item(PopupMenuItem::link(
            "Open Project",
            "https://github.com/Reverier-Xu/woocraft",
          ))
      });

    let view_for_context = cx.entity().clone();
    let context_area = div()
      .w(px(360.))
      .h(px(180.))
      .rounded(cx.theme().radius_container)
      .border_1()
      .border_color(cx.theme().border)
      .bg(cx.theme().card)
      .text_color(cx.theme().card_foreground)
      .items_center()
      .justify_center()
      .child("Right click this area")
      .context_menu(move |menu, _, _| {
        let view = view_for_context.clone();
        let view_copy = view.clone();
        let view_inspect = view.clone();
        menu
          .item(PopupMenuItem::new("Copy").on_click(move |_, _, cx| {
            view_copy.update(cx, |state, cx| {
              state.selected = "Copy".to_string();
              cx.notify();
            });
          }))
          .item(PopupMenuItem::new("Inspect").on_click(move |_, _, cx| {
            view_inspect.update(cx, |state, cx| {
              state.selected = "Inspect".to_string();
              cx.notify();
            });
          }))
      });

    window_border().child(
      v_flex()
        .size_full()
        .p_6()
        .gap_4()
        .bg(cx.theme().background)
        .text_color(cx.theme().foreground)
        .child(
          div()
            .text_xl()
            .font_semibold()
            .child("Woocraft Menu Example"),
        )
        .child(
          h_flex().gap_3().child(menu_trigger).child(
            Button::new("theme-toggle")
              .label("Toggle Theme")
              .on_click(|_, _, cx| {
                let mode = if cx.theme().mode.is_dark() {
                  ThemeMode::Light
                } else {
                  ThemeMode::Dark
                };
                woocraft::Theme::set_mode(mode, cx);
              }),
          ),
        )
        .child(
          div()
            .text_sm()
            .text_color(cx.theme().muted_foreground)
            .child(format!("Last selected: {}", self.selected)),
        )
        .child(context_area),
    )
  }
}

fn main() {
  let app = Application::new().with_assets(woocraft::Assets);

  app.run(|cx: &mut App| {
    woocraft::init(cx);
    cx.activate(true);

    let bounds = Bounds::centered(None, GpuiSize::new(px(920.), px(640.)), cx);
    let window = cx
      .open_window(
        WindowOptions {
          window_bounds: Some(WindowBounds::Windowed(bounds)),
          ..Default::default()
        },
        |_window, cx| MenuWindow::view(cx),
      )
      .expect("open menu demo window failed");

    window
      .update(cx, |_, window, _| {
        window.activate_window();
        window.set_window_title("Woocraft Menu Example");
      })
      .expect("update menu demo window failed");
  });
}