Initial public release of Warp.

Repo-Sync-Origin: warpdotdev/warp-internal@12af1d983b
This commit is contained in:
David Stern
2026-04-28 08:43:33 -05:00
commit 0dbd3d567a
4982 changed files with 1431549 additions and 0 deletions
+190
View File
@@ -0,0 +1,190 @@
use std::borrow::Cow;
use warp_core::ui::Icon;
use warp_core::ui::appearance::Appearance;
use warpui::{fonts, keymap::Keystroke, prelude::stack};
use crate::{keyboard_shortcut, tooltip};
use super::Theme;
/// The parameters for rendering a button.
pub struct Params<'a> {
/// The content of the button.
pub content: Content,
/// The theme to use for the button.
pub theme: &'a dyn Theme,
/// The options for the button.
pub options: Options,
}
impl<'a> crate::Params for Params<'a> {
type Options<'b> = Options;
}
pub struct Options {
/// Whether or not the button is disabled.
///
/// Disabled buttons are rendered with a different theme and do not respond
/// to mouse events.
pub disabled: bool,
/// The size of the button.
pub size: Size,
/// The tooltip to show on hover, if any.
pub tooltip: Option<Tooltip>,
/// The keystroke to display, if any.
pub keystroke: Option<Keystroke>,
/// The callback to invoke when the button is clicked, if any.
pub on_click: Option<crate::MouseEventHandler>,
}
impl crate::Options for Options {
fn default(appearance: &Appearance) -> Self {
Self {
disabled: false,
size: Size::default(appearance),
tooltip: None,
keystroke: None,
on_click: None,
}
}
}
/// The content of the button.
pub enum Content {
/// A label-only button.
Label(Cow<'static, str>),
/// An icon-only button.
Icon(Icon),
/// A button with both an icon and a label.
IconAndLabel(Icon, Cow<'static, str>),
}
/// The size of the button.
pub enum Size {
Default,
Small,
Custom(Sizing),
}
impl crate::Options for Size {
fn default(_: &Appearance) -> Self {
Self::Default
}
}
impl Size {
pub(super) fn height(&self) -> f32 {
self.sizing().height
}
pub(super) fn icon_size(&self) -> f32 {
self.sizing().icon_size
}
pub(super) fn font_size(&self) -> f32 {
self.sizing().font_size
}
pub(super) fn font_properties(&self) -> fonts::Properties {
self.sizing().font_properties
}
pub(super) fn horizontal_padding(&self) -> f32 {
self.sizing().horizontal_padding
}
pub(super) fn inner_spacing(&self) -> f32 {
self.sizing().inner_spacing
}
pub(super) fn keyboard_shortcut_sizing(&self) -> keyboard_shortcut::Sizing {
self.sizing().keyboard_shortcut_sizing
}
fn sizing(&self) -> &Sizing {
match self {
Size::Default => &DEFAULT_SIZE,
Size::Small => &SMALL_SIZE,
Size::Custom(custom) => custom,
}
}
}
/// The set of properties that vary with button size.
pub struct Sizing {
pub height: f32,
pub font_size: f32,
pub icon_size: f32,
pub font_properties: fonts::Properties,
pub horizontal_padding: f32,
pub inner_spacing: f32,
pub keyboard_shortcut_sizing: keyboard_shortcut::Sizing,
}
/// Sizing for a default-sized button.
const DEFAULT_SIZE: Sizing = Sizing {
height: 32.,
font_size: 14.,
icon_size: 16.,
font_properties: fonts::Properties {
weight: fonts::Weight::Semibold,
style: fonts::Style::Normal,
},
horizontal_padding: 12.,
inner_spacing: 4.,
keyboard_shortcut_sizing: keyboard_shortcut::Sizing {
font_size: 12.,
padding: 2.,
},
};
/// Sizing for a small-sized button.
const SMALL_SIZE: Sizing = Sizing {
height: 24.,
font_size: 12.,
icon_size: 14.,
font_properties: fonts::Properties {
weight: fonts::Weight::Semibold,
style: fonts::Style::Normal,
},
horizontal_padding: 8.,
inner_spacing: 2.,
keyboard_shortcut_sizing: keyboard_shortcut::Sizing {
font_size: 10.,
padding: 2.,
},
};
/// The tooltip to show on hover, if any.
pub struct Tooltip {
pub params: tooltip::Params,
pub alignment: TooltipAlignment,
}
/// Alignment options for button tooltips.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum TooltipAlignment {
Left,
Center,
#[default]
Right,
}
impl TooltipAlignment {
pub fn parent_anchor(&self) -> stack::ParentAnchor {
match self {
Self::Left => stack::ParentAnchor::TopLeft,
Self::Center => stack::ParentAnchor::TopMiddle,
Self::Right => stack::ParentAnchor::TopRight,
}
}
pub fn child_anchor(&self) -> stack::ChildAnchor {
match self {
Self::Left => stack::ChildAnchor::BottomLeft,
Self::Center => stack::ChildAnchor::BottomMiddle,
Self::Right => stack::ChildAnchor::BottomRight,
}
}
}
+122
View File
@@ -0,0 +1,122 @@
use pathfinder_color::ColorU;
use warp_core::ui::{
appearance::Appearance, color::coloru_with_opacity, theme::Fill, theme::color::internal_colors,
};
/// Theming delegate for a button.
pub trait Theme {
/// The background fill for the button.
fn background(&self, button_state: super::State, appearance: &Appearance) -> Option<Fill>;
/// The color to use for text and icons, given the current background color.
fn text_color(&self, background: Option<Fill>, appearance: &Appearance) -> ColorU;
/// The border color for the button, if any.
fn border(&self, _: &Appearance) -> Option<ColorU> {
None
}
/// The border color for the keyboard shortcut, if any.
fn keyboard_shortcut_border(&self, _text_color: ColorU, _: &Appearance) -> Option<ColorU> {
None
}
/// The background color for the keyboard shortcut, if any.
fn keyboard_shortcut_background(&self, _: &Appearance) -> Option<ColorU> {
None
}
}
/// "Primary" buttons have a colorful fill.
///
/// [Figma spec](https://www.figma.com/design/chk9pwt35jTJhf9KnHmZyE/Components?node-id=3628-14344&t=GRYXipD0INVmDupA-0)
pub struct Primary;
impl Theme for Primary {
fn background(&self, button_state: super::State, appearance: &Appearance) -> Option<Fill> {
match button_state {
super::State::Default => Some(appearance.theme().accent()),
super::State::Hovered => Some(internal_colors::accent_overlay_4(appearance.theme())),
super::State::Pressed => Some(internal_colors::accent_overlay_3(appearance.theme())),
}
}
fn text_color(&self, background: Option<Fill>, appearance: &Appearance) -> ColorU {
let theme = appearance.theme();
let bg = background.unwrap_or_else(|| theme.accent()).into_solid();
theme.font_color(bg).into_solid()
}
fn keyboard_shortcut_border(&self, text_color: ColorU, _: &Appearance) -> Option<ColorU> {
Some(coloru_with_opacity(text_color, 60))
}
}
/// "Secondary" buttons have no fill and a border.
///
/// [Figma spec](https://www.figma.com/design/chk9pwt35jTJhf9KnHmZyE/Components?node-id=3628-14344&t=L1sS5Nxu1zzpWPYp-0)
pub struct Secondary;
impl Theme for Secondary {
fn background(&self, button_state: super::State, appearance: &Appearance) -> Option<Fill> {
match button_state {
super::State::Default => None,
super::State::Hovered => Some(internal_colors::fg_overlay_2(appearance.theme())),
super::State::Pressed => Some(internal_colors::fg_overlay_3(appearance.theme())),
}
}
fn text_color(&self, _background: Option<Fill>, appearance: &Appearance) -> ColorU {
appearance.theme().foreground().into()
}
fn border(&self, appearance: &Appearance) -> Option<ColorU> {
Some(internal_colors::neutral_4(appearance.theme()))
}
fn keyboard_shortcut_background(&self, appearance: &Appearance) -> Option<ColorU> {
Some(internal_colors::neutral_3(appearance.theme()))
}
}
/// "Disabled" buttons have a disabled fill and text color.
///
/// [Figma spec](https://www.figma.com/design/chk9pwt35jTJhf9KnHmZyE/Components?node-id=3628-14344&t=c27DwGHWevMlisVN-0)
pub struct Disabled;
impl Theme for Disabled {
fn background(&self, _button_state: super::State, _: &Appearance) -> Option<Fill> {
None
}
fn text_color(&self, _background: Option<Fill>, appearance: &Appearance) -> ColorU {
internal_colors::neutral_5(appearance.theme())
}
fn keyboard_shortcut_background(&self, appearance: &Appearance) -> Option<ColorU> {
Some(internal_colors::neutral_3(appearance.theme()))
}
}
/// "Naked" buttons have no fill or border by default, only their contents.
///
/// This is typically used for link-like or text-style actions.
pub struct Naked;
impl Theme for Naked {
fn background(&self, button_state: super::State, appearance: &Appearance) -> Option<Fill> {
match button_state {
super::State::Default => None,
super::State::Hovered => Some(internal_colors::fg_overlay_2(appearance.theme())),
super::State::Pressed => Some(internal_colors::fg_overlay_3(appearance.theme())),
}
}
fn text_color(&self, _background: Option<Fill>, appearance: &Appearance) -> ColorU {
appearance.theme().foreground().into_solid()
}
fn keyboard_shortcut_background(&self, appearance: &Appearance) -> Option<ColorU> {
Some(internal_colors::neutral_3(appearance.theme()))
}
}