302 lines
10 KiB
Rust
302 lines
10 KiB
Rust
use ely_gpui_component::{
|
|
buttons::{
|
|
ActionBar, ActionSheet, BulkActionBar, Button, ButtonVariant, ConfirmButton, ConfirmMode,
|
|
CopyButton, FloatingActionButton, QuickAction, QuickActions, ShareButton, back_button,
|
|
close_button, more_button,
|
|
},
|
|
primitives::IconName,
|
|
theme::{ActiveTheme, ControlSize, Radius},
|
|
typography::Caption,
|
|
};
|
|
use gpui::{App, IntoElement, ParentElement, SharedString, Styled, Window, div, prelude::*, px};
|
|
|
|
use crate::{
|
|
probe::probe,
|
|
ui::{code, row, section, specimen, specimens},
|
|
};
|
|
|
|
pub fn later(cx: &App) -> impl IntoElement + use<> {
|
|
section(
|
|
"SplitButton / DropdownButton / MenuButton / LoadingButton",
|
|
"Built from parts in later chapters.",
|
|
cx,
|
|
)
|
|
.child(Caption::new(
|
|
"Split and dropdown buttons open a Menu: they land with Menus, chapter 8.",
|
|
))
|
|
.child(Caption::new(
|
|
"The loading state spins a Spinner: it lands with Loading, chapter 11.",
|
|
))
|
|
}
|
|
|
|
pub fn fab(cx: &App) -> impl IntoElement + use<> {
|
|
let theme = cx.theme();
|
|
section(
|
|
"FloatingActionButton",
|
|
"Round and raised for the screen's one main action. It rises in.",
|
|
cx,
|
|
)
|
|
.child(
|
|
div()
|
|
.relative()
|
|
.w(px(420.0))
|
|
.h(px(160.0))
|
|
.rounded(theme.radius(Radius::Lg))
|
|
.border_1()
|
|
.border_color(theme.colors.border)
|
|
.bg(theme.colors.sunken)
|
|
.child(
|
|
div()
|
|
.absolute()
|
|
.right_4()
|
|
.bottom_4()
|
|
.flex()
|
|
.items_center()
|
|
.gap_3()
|
|
.child(
|
|
FloatingActionButton::new("fab-compose", IconName::Pencil).label("Compose"),
|
|
)
|
|
.child(
|
|
FloatingActionButton::new("fab-add", IconName::Plus).tooltip("New item"),
|
|
),
|
|
),
|
|
)
|
|
}
|
|
|
|
pub fn confirm(cx: &App) -> impl IntoElement + use<> {
|
|
section(
|
|
"ConfirmButton / HoldToConfirm",
|
|
"Hold until the fill completes, or click twice within three seconds.",
|
|
cx,
|
|
)
|
|
.child(
|
|
specimens()
|
|
.child(specimen(
|
|
"hold",
|
|
probe(
|
|
"confirm-hold",
|
|
ConfirmButton::new("confirm-hold", "Hold to delete", ConfirmMode::Hold)
|
|
.on_confirm(|_, _| log::info!("gallery: held to delete")),
|
|
),
|
|
cx,
|
|
))
|
|
.child(specimen(
|
|
"twice",
|
|
probe(
|
|
"confirm-twice",
|
|
ConfirmButton::new("confirm-twice", "Discard draft", ConfirmMode::Twice)
|
|
.on_confirm(|_, _| log::info!("gallery: draft discarded")),
|
|
),
|
|
cx,
|
|
)),
|
|
)
|
|
}
|
|
|
|
pub fn small_buttons(cx: &App) -> impl IntoElement + use<> {
|
|
section(
|
|
"CopyButton / ShareButton / CloseButton / BackButton / MoreButton",
|
|
"Small, familiar verbs. Each names itself on hover.",
|
|
cx,
|
|
)
|
|
.child(
|
|
row()
|
|
.child(specimen(
|
|
"copy",
|
|
probe(
|
|
"copy-button",
|
|
CopyButton::new("copy-invite", "https://ely.dev/invite/7Q2"),
|
|
),
|
|
cx,
|
|
))
|
|
.child(specimen(
|
|
"share",
|
|
probe(
|
|
"share-button",
|
|
ShareButton::new("share-page")
|
|
.text("Ely, components for GPUI")
|
|
.url("https://github.com/ZacharyZhang-NY/Ely-GPUI-Components"),
|
|
),
|
|
cx,
|
|
))
|
|
.child(specimen("close", close_button("preset-close"), cx))
|
|
.child(specimen("back", back_button("preset-back"), cx))
|
|
.child(specimen("more", more_button("preset-more"), cx)),
|
|
)
|
|
.child(code(
|
|
"close_button(id), back_button(id), more_button(id)",
|
|
cx,
|
|
))
|
|
}
|
|
|
|
pub fn action_bar(cx: &App) -> impl IntoElement + use<> {
|
|
let theme = cx.theme();
|
|
section(
|
|
"ActionBar",
|
|
"Docked along a panel's foot, or floating as a pill.",
|
|
cx,
|
|
)
|
|
.child(
|
|
div()
|
|
.w(px(560.0))
|
|
.h(px(200.0))
|
|
.flex()
|
|
.flex_col()
|
|
.justify_end()
|
|
.items_center()
|
|
.overflow_hidden()
|
|
.rounded(theme.radius(Radius::Lg))
|
|
.border_1()
|
|
.border_color(theme.colors.border)
|
|
.bg(theme.colors.sunken)
|
|
.child(
|
|
div().pb_4().child(
|
|
ActionBar::new()
|
|
.floating()
|
|
.child(
|
|
Button::new("bar-reply", "Reply")
|
|
.variant(ButtonVariant::Ghost)
|
|
.icon(IconName::Reply),
|
|
)
|
|
.child(
|
|
Button::new("bar-forward", "Forward")
|
|
.variant(ButtonVariant::Ghost)
|
|
.icon(IconName::Forward),
|
|
)
|
|
.child(
|
|
Button::new("bar-archive", "Archive")
|
|
.primary()
|
|
.icon(IconName::Archive),
|
|
),
|
|
),
|
|
)
|
|
.child(
|
|
ActionBar::new()
|
|
.child(Button::new("bar-cancel", "Cancel").variant(ButtonVariant::Ghost))
|
|
.child(Button::new("bar-save", "Save changes").primary()),
|
|
),
|
|
)
|
|
}
|
|
|
|
pub fn bulk(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
|
let picked = window.use_keyed_state("bulk-picked", cx, |_, _| 0usize);
|
|
let count = *picked.read(cx);
|
|
let (add, clear) = (picked.clone(), picked);
|
|
section(
|
|
"BulkActionBar",
|
|
"Rises once rows are selected. The count rolls as it changes.",
|
|
cx,
|
|
)
|
|
.child(
|
|
row()
|
|
.child(probe(
|
|
"bulk-select",
|
|
Button::new("bulk-select", "Select one more")
|
|
.variant(ButtonVariant::Outline)
|
|
.on_click(move |_, _, cx| {
|
|
add.update(cx, |count, cx| {
|
|
*count += 1;
|
|
cx.notify();
|
|
})
|
|
}),
|
|
))
|
|
.child(Caption::new(format!("{count} selected"))),
|
|
)
|
|
.child(
|
|
div()
|
|
.h(cx.theme().control_height(ControlSize::Lg) * 1.5)
|
|
.child(
|
|
BulkActionBar::new("bulk-bar", count)
|
|
.action(
|
|
Button::new("bulk-move", "Move")
|
|
.variant(ButtonVariant::Ghost)
|
|
.icon(IconName::Folder),
|
|
)
|
|
.action(
|
|
Button::new("bulk-delete", "Delete")
|
|
.variant(ButtonVariant::Danger)
|
|
.icon(IconName::Trash2),
|
|
)
|
|
.on_clear(move |_, cx| {
|
|
clear.update(cx, |count, cx| {
|
|
*count = 0;
|
|
cx.notify();
|
|
})
|
|
}),
|
|
),
|
|
)
|
|
}
|
|
|
|
pub fn action_sheet(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
|
let open = window.use_keyed_state("sheet-shown", cx, |_, _| false);
|
|
let shown = *open.read(cx);
|
|
let (show, hide) = (open.clone(), open);
|
|
section(
|
|
"ActionSheet",
|
|
"A few choices from the bottom, and a separate way out.",
|
|
cx,
|
|
)
|
|
.child(probe(
|
|
"action-sheet-open",
|
|
Button::new("action-sheet-open", "Photo options")
|
|
.variant(ButtonVariant::Outline)
|
|
.on_click(move |_, _, cx| {
|
|
show.update(cx, |shown, cx| {
|
|
*shown = true;
|
|
cx.notify();
|
|
})
|
|
}),
|
|
))
|
|
.when(shown, |block| {
|
|
block.child(
|
|
ActionSheet::new("photo-sheet", move |_, cx| {
|
|
hide.update(cx, |shown, cx| {
|
|
*shown = false;
|
|
cx.notify();
|
|
})
|
|
})
|
|
.title("dunes.jpg")
|
|
.message("Taken at dusk. 4.2 MB.")
|
|
.action("Set as wallpaper", |_, _| log::info!("gallery: wallpaper"))
|
|
.action("Duplicate", |_, _| log::info!("gallery: duplicate"))
|
|
.destructive("Delete photo", |_, _| log::info!("gallery: delete photo")),
|
|
)
|
|
})
|
|
}
|
|
|
|
pub fn quick_actions(cx: &App) -> impl IntoElement + use<> {
|
|
let note = |label: &'static str| {
|
|
move |_: &mut Window, _: &mut App| log::info!("gallery: quick {label}")
|
|
};
|
|
section(
|
|
"QuickActions",
|
|
"Common moves with their keys. Arrows choose, Enter runs.",
|
|
cx,
|
|
)
|
|
.child(probe(
|
|
"quick",
|
|
div().w(px(420.0)).child(
|
|
QuickActions::new("quick-actions")
|
|
.action(
|
|
QuickAction::new(IconName::FilePlus, "New document", note("new"))
|
|
.note("Blank, or from a template")
|
|
.shortcut("cmd-n"),
|
|
)
|
|
.action(
|
|
QuickAction::new(IconName::FolderOpen, "Open…", note("open")).shortcut("cmd-o"),
|
|
)
|
|
.action(
|
|
QuickAction::new(IconName::Search, "Search everywhere", note("search"))
|
|
.note("Files, symbols, commands")
|
|
.shortcut("cmd-shift-p"),
|
|
)
|
|
.action(
|
|
QuickAction::new(IconName::Settings, "Settings", note("settings"))
|
|
.shortcut("cmd-,"),
|
|
),
|
|
),
|
|
))
|
|
.child(Caption::new(SharedString::from(
|
|
"Tab in, then use the arrows.",
|
|
)))
|
|
}
|