use gpui::{AnyElement, App, ElementId, SharedString, Window, div, prelude::*, px};
use theme::{TextStyle, Theme, Typeset};
pub(crate) const CODE_PADDING_X: f32 = 12.0;
pub(crate) const CODE_PADDING_Y: f32 = 10.0;
pub fn fence_panel(theme: &Theme) -> gpui::Div {
div()
.rounded(px(Theme::panel_radius()))
.bg(theme.ink(0.035))
.border_1()
.border_color(theme.border)
.overflow_hidden()
.relative()
}
pub const NOTE_SELECTOR: &str = "fence-note";
pub fn fence_note(note: SharedString, theme: &Theme) -> AnyElement {
div()
.debug_selector(|| NOTE_SELECTOR.into())
.flex()
.flex_col()
.px(px(CODE_PADDING_X))
.py(px(CODE_PADDING_Y))
.border_t_1()
.border_color(theme.border)
.text_color(theme.danger)
.font_family(theme.font_mono.clone())
.text_style(TextStyle::Subheadline)
.children(
note.lines()
.map(|line| SharedString::from(line.to_string()))
.collect::<Vec<_>>(),
)
.into_any_element()
}
pub fn fence_band(theme: &Theme) -> gpui::Div {
div()
.relative()
.flex()
.flex_row()
.items_center()
.px(px(CODE_PADDING_X))
.py(px(5.0))
.border_b_1()
.border_color(theme.border)
.bg(theme.ink(0.02))
.text_style(TextStyle::Subheadline)
}
pub(crate) fn copy_button(
code: &str,
ix: usize,
theme: &Theme,
window: &mut Window,
cx: &mut App,
) -> AnyElement {
let copied = window.use_keyed_state(ElementId::named_usize("md-copied", ix), cx, |_, _| false);
let showing = *copied.read(cx);
let text: SharedString = code.to_string().into();
div()
.id(ElementId::named_usize("md-copy", ix))
.absolute()
.top(px(3.0))
.right(px(5.0))
.h(px(20.0))
.px(px(6.0))
.rounded(px(5.0))
.flex()
.items_center()
.cursor_pointer()
.text_style(TextStyle::Caption)
.text_color(theme.text_muted)
.hover(|el| el.bg(theme.element_hover))
.child(if showing { "Copied" } else { "Copy" })
.on_click({
let copied = copied.clone();
move |_, _, cx| {
cx.write_to_clipboard(gpui::ClipboardItem::new_string(text.to_string()));
copied.update(cx, |state, cx| {
*state = true;
cx.notify();
});
}
})
.on_hover(move |hovering, _, cx| {
if !*hovering && *copied.read(cx) {
copied.update(cx, |state, cx| {
*state = false;
cx.notify();
});
}
})
.into_any_element()
}