For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to any URL or sending an Accept: text/markdown header. An agent skill is available at /.well-known/agent-skills/site-skill.md.
/
3
Sponsor

Getting Started

Learn how to set up and use maccn in your GPUI project.

Installation

This guide assumes a working GPUI project. For upstream setup details, see the gpui-component repository.

Add maccn and its GPUI dependencies to your Cargo.toml:

[dependencies]
maccn = { git = "https://github.com/shadcn-labs/maccn" }
gpui = { git = "https://github.com/zed-industries/zed" }
gpui_platform = { git = "https://github.com/zed-industries/zed", features = ["font-kit"] }

Quick Start

Here's a minimal example to get started:

use gpui::*;
use maccn::{MacButton, theme::ThemeExt as _};
 
pub struct HelloWorld;
 
impl Render for HelloWorld {
    fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
        div()
            .flex()
            .flex_col()
            .gap_2()
            .size_full()
            .items_center()
            .justify_center()
            .child("Hello, World!")
            .child(
                MacButton::new("ok")
                    .child("Let's Go!")
                    .on_click(|_, _, _| println!("Clicked!")),
            )
    }
}
 
fn main() {
    gpui_platform::application().run(move |cx: &mut App| {
        // This must be called before using any maccn features.
        maccn::init(cx);
 
        cx.open_window(WindowOptions::default(), |_, cx| {
            cx.new(|_| HelloWorld)
        })
        .expect("Failed to open window");
    });
}

Basic Concepts

Stateless Elements

maccn components are stateless RenderOnce elements. State lives in your view, which makes components predictable and easy to compose.

struct MyView;
 
impl Render for MyView {
    fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
        div()
            .flex()
            .flex_col()
            .gap_2()
            .child(MacButton::new("btn").child("Click me"))
            .child(MacSwitch::new("sw").checked(true))
    }
}

Stateful Components

Some components need an Entity state object, such as text fields (InputState) and sliders (SliderState). Create the entity in your view and pass a reference to the component.

use gpui_base::input::InputState;
use maccn::MacTextField;
 
struct MyView {
    input: Entity<InputState>,
}
 
impl MyView {
    fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
        let input = cx.new(|cx| {
            InputState::new(window, cx)
                .placeholder("Server name")
                .default_value("")
        });
        Self { input }
    }
}
 
impl Render for MyView {
    fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
        MacTextField::new("field", &self.input)
    }
}

Theming

Components read colors from the global [MaccnTheme]. Access it through the ThemeExt trait:

use maccn::theme::ThemeExt as _;
 
let theme = cx.theme();
let label = theme.label;
let accent = theme.accent;

Sizing

Every interactive control supports the five macOS control sizes:

use maccn::MacControlSize;
 
MacButton::new("xl").size(MacControlSize::ExtraLarge)
MacButton::new("l").size(MacControlSize::Large)
MacButton::new("r") // Regular (default)
MacButton::new("s").size(MacControlSize::Small)
MacButton::new("m").size(MacControlSize::Mini)

Variants

Buttons offer several visual variants:

use maccn::ButtonVariant;
 
MacButton::new("default").child("Default")
MacButton::new("prominent")
    .variant(ButtonVariant::Prominent)
    .child("Prominent")
MacButton::new("destructive")
    .variant(ButtonVariant::Destructive)
    .child("Delete")

Icons & Assets

maccn does not rely on external icon assets. All control glyphs (check marks, chevrons, magnifiers, etc.) are rendered as inline SVG images from the crate itself, so there is no asset setup step.

Running the Showcase

The repository includes an interactive showcase. Run it natively:

cargo run -p maccn --example showcase

Open a specific component:

cargo run -p maccn --example showcase -- switch

Or build the WebAssembly demo for the docs site:

make -C crates/maccn/examples/wasm build
pnpm install
pnpm dev

Next Steps

Browse the component docs to learn more about each control: