T06f forms other: signature pad, code and JSON inputs, font, icon and emoji pickers, language, country and currency comboboxes

This commit is contained in:
ZacharyZhang-NY committed 2026-09-25 09:41:29 -04:00
1 parent ffd634dab6
commit 0ca1ff65c7
18 files changed
+1692 -24

No files matched your search

+60
View File
@@ -4,6 +4,7 @@ mod dates;
mod files;
mod formats;
mod numbers;
mod other;
mod pickers;
mod rich;
mod text;
@@ -244,6 +245,60 @@ const SCRIPT: &[Step] = &[
Step::CancelPanel,
Step::Wait(600),
Step::Shot("files"),
Step::DownAt("signature", 40.0, 100.0),
Step::DragTo("signature", 70.0, 50.0),
Step::DragTo("signature", 100.0, 110.0),
Step::DragTo("signature", 130.0, 55.0),
Step::DragTo("signature", 160.0, 105.0),
Step::DragTo("signature", 210.0, 60.0),
Step::DragTo("signature", 250.0, 100.0),
Step::DragTo("signature", 320.0, 80.0),
Step::UpAt("signature", 320.0, 80.0),
Step::Wait(300),
Step::Shot("signature"),
Step::Click("code"),
Step::Key("secondary-a"),
Step::Type("let total = price(3) * 1.2; // tax"),
Step::Click("json"),
Step::Key("secondary-a"),
Step::Type("{\"name\": \"Ely\", \"size\": 3,"),
Step::Wait(300),
Step::Shot("code-json"),
Step::DownAt("font", 100.0, 14.0),
Step::UpAt("font", 100.0, 14.0),
Step::Key("secondary-a"),
Step::Type("mono"),
Step::Wait(300),
Step::Shot("font"),
Step::Key("enter"),
Step::Wait(300),
Step::DownAt("icons", 100.0, 14.0),
Step::UpAt("icons", 100.0, 14.0),
Step::Key("secondary-a"),
Step::Type("arrow"),
Step::Key("down"),
Step::Key("right"),
Step::Key("down"),
Step::Wait(300),
Step::Shot("icons"),
Step::Key("enter"),
Step::DownAt("emoji", 100.0, 14.0),
Step::UpAt("emoji", 100.0, 14.0),
Step::Key("secondary-a"),
Step::Type("heart"),
Step::Key("down"),
Step::Key("right"),
Step::Wait(300),
Step::Shot("emoji"),
Step::Key("enter"),
Step::Wait(300),
Step::Click("country"),
Step::Key("secondary-a"),
Step::Type("jap"),
Step::Wait(300),
Step::Shot("country"),
Step::Key("enter"),
Step::Wait(300),
Step::Rest,
];
@@ -291,5 +346,10 @@ fn render(window: &mut Window, cx: &mut App) -> AnyElement {
.child(colors::swatches(window, cx))
.child(colors::gradient(window, cx))
.child(files::files(window, cx))
.child(other::signature(window, cx))
.child(other::code(window, cx))
.child(other::font(window, cx))
.child(other::glyphs(window, cx))
.child(other::regional(window, cx))
.into_any_element()
}
+206
View File
@@ -0,0 +1,206 @@
use ely_gpui_component::{
forms::{
CodeInput, Combobox, EmojiPicker, FontPicker, IconPicker, JsonInput, NumberInput,
SignaturePad, Stroke, code_highlights, json_highlights,
},
primitives::IconName,
theme::ActiveTheme,
};
use gpui::{App, IntoElement, ParentElement, SharedString, Styled, Window, div, px};
use super::{
choices::{keep, set},
text::field,
};
use crate::{
probe::probe,
ui::{section, specimen, specimens},
};
pub fn signature(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
let strokes = keep("signature-strokes", Vec::<Stroke>::new, window, cx);
let now = strokes.read(cx).clone();
section(
"SignaturePad",
"Sign with the pointer. A stroke lands when the pen lifts; Clear starts over.",
cx,
)
.child(specimen(
match now.len() {
1 => "1 stroke".to_string(),
count => format!("{count} strokes"),
},
probe(
"signature",
div().w(px(420.0)).child(
SignaturePad::new("signature", now)
.on_change(move |next, _, cx| set(&strokes, next.to_vec(), cx)),
),
),
cx,
))
}
pub fn code(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
let line = field("input-code", window, cx, |input| {
input
.placeholder("cargo run --example gallery")
.highlighter(code_highlights)
});
let json = field("input-json", window, cx, |input| {
input
.multi_line(4, 8)
.placeholder("{ \"name\": \"Ely\" }")
.highlighter(json_highlights)
});
section(
"CodeInput / JsonInput",
"One line of code, colored the way most languages read. JSON is checked as you type.",
cx,
)
.child(
specimens()
.child(specimen(
"code",
probe("code", div().w(px(420.0)).child(CodeInput::new(&line))),
cx,
))
.child(specimen(
"json",
probe("json", div().w(px(420.0)).child(JsonInput::new(&json))),
cx,
)),
)
}
pub fn font(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
let search = field("input-font", window, cx, |input| {
input.placeholder("Search fonts")
});
let ui = cx.theme().font_family.clone();
let family = keep("font-family", move || ui, window, cx);
let now = family.read(cx).clone();
section(
"FontPicker",
"Every family the system knows, and a line set in the chosen one.",
cx,
)
.child(probe(
"font",
div().w(px(420.0)).child(
FontPicker::new("font-picker", &search)
.selected(now)
.on_change(move |next, _, cx| set(&family, next.clone(), cx)),
),
))
}
pub fn glyphs(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
let icon = keep("icon-picked", || IconName::Sparkles, window, cx);
let emoji = keep("emoji-picked", || SharedString::from("✨"), window, cx);
let (icon_now, emoji_now) = (*icon.read(cx), emoji.read(cx).clone());
section(
"IconPicker / EmojiPicker",
"Type to narrow. Down moves into the grid, arrows walk it, Enter picks.",
cx,
)
.child(
specimens()
.child(specimen(
icon_now.name(),
probe(
"icons",
IconPicker::new("icon-picker")
.selected(icon_now)
.on_change(move |next, _, cx| set(&icon, next, cx)),
),
cx,
))
.child(specimen(
emoji_now.clone(),
probe(
"emoji",
EmojiPicker::new("emoji-picker")
.selected(emoji_now)
.on_change(move |next, _, cx| {
set(&emoji, SharedString::from(next.to_string()), cx)
}),
),
cx,
)),
)
}
pub fn regional(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
let language = field("input-language", window, cx, |input| {
input.placeholder("Language")
});
let country = field("input-country", window, cx, |input| {
input.placeholder("Country")
});
let currency = field("input-currency", window, cx, |input| {
input.placeholder("Currency")
});
let spoken = keep("regional-language", || SharedString::from("zh"), window, cx);
let land = keep("regional-country", || SharedString::from("CN"), window, cx);
let money = keep(
"regional-currency",
|| SharedString::from("CNY"),
window,
cx,
);
let amount = keep("regional-amount", || 1280.0, window, cx);
let (spoken_now, land_now, money_now, amount_now) = (
spoken.read(cx).clone(),
land.read(cx).clone(),
money.read(cx).clone(),
*amount.read(cx),
);
section(
"LanguageSelect / CountrySelect / CurrencySelect",
"Languages under their own names, countries with flags, currencies by ISO 4217. Type a name or a code.",
cx,
)
.child(
specimens()
.child(specimen(
spoken_now.clone(),
div().w(px(260.0)).child(
Combobox::languages("language-select", &language)
.selected(spoken_now)
.on_change(move |next, _, cx| set(&spoken, next.clone(), cx)),
),
cx,
))
.child(specimen(
land_now.clone(),
probe(
"country",
div().w(px(260.0)).child(
Combobox::countries("country-select", &country)
.selected(land_now)
.on_change(move |next, _, cx| set(&land, next.clone(), cx)),
),
),
cx,
))
.child(specimen(
money_now.clone(),
div().w(px(260.0)).child(
Combobox::currencies("currency-select", &currency)
.selected(money_now.clone())
.on_change(move |next, _, cx| set(&money, next.clone(), cx)),
),
cx,
)),
)
.child(specimen(
format!("an amount in {money_now}"),
div().w(px(260.0)).child(
NumberInput::new("regional-amount", amount_now)
.currency(&money_now)
.on_change(move |next, _, cx| set(&amount, next, cx)),
),
cx,
))
}