Files
Ely-GPUI-Components/examples/gallery/pages/forms/numbers.rs
T

134 lines
4.2 KiB
Rust

use ely_gpui_component::forms::{NumberInput, ScrubInput, UnitInput};
use gpui::{App, Entity, IntoElement, ParentElement, SharedString, Styled, Window, div, px};
use crate::{
probe::probe,
ui::{code, section, specimen, specimens},
};
fn number(key: &'static str, initial: f64, window: &mut Window, cx: &mut App) -> Entity<f64> {
window.use_keyed_state(key, cx, move |_, _| initial)
}
fn store(state: Entity<f64>) -> impl Fn(f64, &mut Window, &mut App) + 'static {
move |value, _, cx| {
state.update(cx, |state, cx| {
*state = value;
cx.notify();
})
}
}
pub fn number_input(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
let seats = number("number-seats", 4.0, window, cx);
let now = *seats.read(cx);
section(
"NumberInput",
"Arrow keys or the stepper move it; drag the grip sideways to scrub.",
cx,
)
.child(probe(
"number",
div().w(px(220.0)).child(
NumberInput::new("seats", now)
.range(1.0, 99.0)
.on_change(store(seats)),
),
))
}
pub fn scrub(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
let x = number("scrub-x", 120.0, window, cx);
let opacity = number("scrub-opacity", 0.8, window, cx);
let (x_now, opacity_now) = (*x.read(cx), *opacity.read(cx));
section(
"ScrubInput",
"Drag the label sideways, as in a design tool. The field still types.",
cx,
)
.child(probe(
"scrub",
div()
.flex()
.flex_col()
.gap_2()
.w(px(260.0))
.child(
ScrubInput::new("scrub-x", "X", x_now)
.range(-2000.0, 2000.0)
.on_change(store(x)),
)
.child(
ScrubInput::new("scrub-opacity", "Opacity", opacity_now)
.range(0.0, 1.0)
.step(0.01)
.precision(2)
.on_change(store(opacity)),
),
))
}
pub fn money(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
let price = number("number-price", 1249.5, window, cx);
let tax = number("number-tax", 8.0, window, cx);
let gap = number("number-gap", 16.0, window, cx);
let unit = window.use_keyed_state("number-unit", cx, |_, _| SharedString::from("px"));
let (price_now, tax_now, gap_now, unit_now) = (
*price.read(cx),
*tax.read(cx),
*gap.read(cx),
unit.read(cx).clone(),
);
section(
"CurrencyInput / PercentInput / UnitInput",
"The same number field with a symbol, a percent, or a unit you click through.",
cx,
)
.child(
specimens()
.child(specimen(
"currency",
div().w(px(200.0)).child(
NumberInput::new("price", price_now)
.currency("USD")
.range(0.0, 1_000_000.0)
.on_change(store(price)),
),
cx,
))
.child(specimen(
"percent",
div().w(px(160.0)).child(
NumberInput::new("tax", tax_now)
.percent()
.range(0.0, 100.0)
.on_change(store(tax)),
),
cx,
))
.child(specimen(
"unit",
probe(
"unit",
div().w(px(180.0)).child(
UnitInput::new("gap", gap_now, ["px", "%", "em"], unit_now)
.range(0.0, 400.0)
.on_change(store(gap))
.on_unit(move |next, _, cx| {
let next = next.clone();
unit.update(cx, |unit, cx| {
*unit = next;
cx.notify();
})
}),
),
),
cx,
)),
)
.child(code(
"NumberInput::new(id, value).currency(\"USD\") and .percent()",
cx,
))
}