input: Add appearance option to NumberInput, Dropdown, DatePicker to render without style. (#1054)
<img width="1100" height="935" alt="image" src="https://github.com/user-attachments/assets/b213c778-eef0-4d63-8d07-b68da9a078b1" />
This commit is contained in:
parent
867b4ff3a6
commit
6508927e7f
9 changed files with 223 additions and 45 deletions
|
|
@ -1,12 +1,12 @@
|
||||||
use chrono::{Datelike, Days, Duration, Utc};
|
use chrono::{Datelike, Days, Duration, Utc};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
px, App, AppContext, Context, Entity, Focusable, IntoElement, ParentElement as _, Render,
|
div, px, App, AppContext, Context, Entity, Focusable, IntoElement, ParentElement as _, Render,
|
||||||
Styled as _, Subscription, Window,
|
Styled as _, Subscription, Window,
|
||||||
};
|
};
|
||||||
use gpui_component::{
|
use gpui_component::{
|
||||||
calendar,
|
calendar,
|
||||||
date_picker::{DatePicker, DatePickerEvent, DatePickerState, DateRangePreset},
|
date_picker::{DatePicker, DatePickerEvent, DatePickerState, DateRangePreset},
|
||||||
v_flex, Sizable as _,
|
v_flex, ActiveTheme as _, Sizable as _,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::section;
|
use crate::section;
|
||||||
|
|
@ -19,6 +19,7 @@ pub struct DatePickerStory {
|
||||||
date_picker_value: Option<String>,
|
date_picker_value: Option<String>,
|
||||||
date_range_picker: Entity<DatePickerState>,
|
date_range_picker: Entity<DatePickerState>,
|
||||||
default_range_mode_picker: Entity<DatePickerState>,
|
default_range_mode_picker: Entity<DatePickerState>,
|
||||||
|
without_appearance_picker: Entity<DatePickerState>,
|
||||||
_subscriptions: Vec<Subscription>,
|
_subscriptions: Vec<Subscription>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,6 +96,8 @@ impl DatePickerStory {
|
||||||
|
|
||||||
let default_range_mode_picker = cx.new(|cx| DatePickerState::range(window, cx));
|
let default_range_mode_picker = cx.new(|cx| DatePickerState::range(window, cx));
|
||||||
|
|
||||||
|
let without_appearance_picker = cx.new(|cx| DatePickerState::new(window, cx));
|
||||||
|
|
||||||
let _subscriptions = vec![
|
let _subscriptions = vec![
|
||||||
cx.subscribe(&date_picker, |this, _, ev, _| match ev {
|
cx.subscribe(&date_picker, |this, _, ev, _| match ev {
|
||||||
DatePickerEvent::Change(date) => {
|
DatePickerEvent::Change(date) => {
|
||||||
|
|
@ -120,6 +123,7 @@ impl DatePickerStory {
|
||||||
data_picker_custom,
|
data_picker_custom,
|
||||||
date_range_picker,
|
date_range_picker,
|
||||||
default_range_mode_picker,
|
default_range_mode_picker,
|
||||||
|
without_appearance_picker,
|
||||||
date_picker_value: None,
|
date_picker_value: None,
|
||||||
_subscriptions,
|
_subscriptions,
|
||||||
}
|
}
|
||||||
|
|
@ -133,7 +137,7 @@ impl Focusable for DatePickerStory {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for DatePickerStory {
|
impl Render for DatePickerStory {
|
||||||
fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
|
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
let presets = vec![
|
let presets = vec![
|
||||||
DateRangePreset::single(
|
DateRangePreset::single(
|
||||||
"Yesterday",
|
"Yesterday",
|
||||||
|
|
@ -216,5 +220,15 @@ impl Render for DatePickerStory {
|
||||||
format!("Date picker value: {:?}", self.date_picker_value).into_element(),
|
format!("Date picker value: {:?}", self.date_picker_value).into_element(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
.child(
|
||||||
|
section("Without Appearance").max_w_128().child(
|
||||||
|
div().w_full().bg(cx.theme().secondary).child(
|
||||||
|
DatePicker::new(&self.without_appearance_picker)
|
||||||
|
.appearance(false)
|
||||||
|
.placeholder("Without appearance")
|
||||||
|
.cleanable(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,5 @@
|
||||||
use gpui::{
|
use gpui::*;
|
||||||
px, App, AppContext, Context, Entity, Focusable, InteractiveElement, IntoElement, KeyBinding,
|
use gpui_component::{button::*, checkbox::*, divider::*, dropdown::*, input::*, *};
|
||||||
ParentElement, Render, SharedString, Styled, Window,
|
|
||||||
};
|
|
||||||
|
|
||||||
use gpui_component::{
|
|
||||||
checkbox::Checkbox,
|
|
||||||
dropdown::{Dropdown, DropdownEvent, DropdownItem, DropdownState, SearchableVec},
|
|
||||||
h_flex, v_flex, ActiveTheme, FocusableCycle, IconName, Sizable,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::section;
|
use crate::section;
|
||||||
use crate::{Tab, TabPrev};
|
use crate::{Tab, TabPrev};
|
||||||
|
|
@ -58,6 +50,8 @@ pub struct DropdownStory {
|
||||||
simple_dropdown2: Entity<DropdownState<SearchableVec<SharedString>>>,
|
simple_dropdown2: Entity<DropdownState<SearchableVec<SharedString>>>,
|
||||||
simple_dropdown3: Entity<DropdownState<Vec<SharedString>>>,
|
simple_dropdown3: Entity<DropdownState<Vec<SharedString>>>,
|
||||||
disabled_dropdown: Entity<DropdownState<Vec<SharedString>>>,
|
disabled_dropdown: Entity<DropdownState<Vec<SharedString>>>,
|
||||||
|
appearance_dropdown: Entity<DropdownState<Vec<SharedString>>>,
|
||||||
|
input_state: Entity<InputState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl super::Story for DropdownStory {
|
impl super::Story for DropdownStory {
|
||||||
|
|
@ -97,6 +91,21 @@ impl DropdownStory {
|
||||||
];
|
];
|
||||||
|
|
||||||
let country_dropdown = cx.new(|cx| DropdownState::new(countries, Some(6), window, cx));
|
let country_dropdown = cx.new(|cx| DropdownState::new(countries, Some(6), window, cx));
|
||||||
|
let appearance_dropdown = cx.new(|cx| {
|
||||||
|
DropdownState::new(
|
||||||
|
vec![
|
||||||
|
"CN".into(),
|
||||||
|
"US".into(),
|
||||||
|
"HK".into(),
|
||||||
|
"JP".into(),
|
||||||
|
"KR".into(),
|
||||||
|
],
|
||||||
|
Some(0),
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
let input_state = cx.new(|cx| InputState::new(window, cx).placeholder("Your phone number"));
|
||||||
|
|
||||||
let fruits = SearchableVec::new(vec![
|
let fruits = SearchableVec::new(vec![
|
||||||
"Apple".into(),
|
"Apple".into(),
|
||||||
|
|
@ -156,6 +165,8 @@ impl DropdownStory {
|
||||||
.new(|cx| DropdownState::new(Vec::<SharedString>::new(), None, window, cx)),
|
.new(|cx| DropdownState::new(Vec::<SharedString>::new(), None, window, cx)),
|
||||||
disabled_dropdown: cx
|
disabled_dropdown: cx
|
||||||
.new(|cx| DropdownState::new(Vec::<SharedString>::new(), None, window, cx)),
|
.new(|cx| DropdownState::new(Vec::<SharedString>::new(), None, window, cx)),
|
||||||
|
appearance_dropdown,
|
||||||
|
input_state,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -276,6 +287,41 @@ impl Render for DropdownStory {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
.child(
|
||||||
|
section("Appearance false with TextInput")
|
||||||
|
.max_w_128()
|
||||||
|
.child(
|
||||||
|
h_flex()
|
||||||
|
.border_1()
|
||||||
|
.border_color(cx.theme().input)
|
||||||
|
.rounded_lg()
|
||||||
|
.text_color(cx.theme().secondary_foreground)
|
||||||
|
.w_full()
|
||||||
|
.gap_1()
|
||||||
|
.child(
|
||||||
|
div().w(px(140.)).child(
|
||||||
|
Dropdown::new(&self.appearance_dropdown)
|
||||||
|
.appearance(false)
|
||||||
|
.py_2()
|
||||||
|
.pl_3(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(Divider::vertical())
|
||||||
|
.child(
|
||||||
|
div().flex_1().child(
|
||||||
|
TextInput::new(&self.input_state)
|
||||||
|
.appearance(false)
|
||||||
|
.pr_3()
|
||||||
|
.py_2(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.p_2()
|
||||||
|
.child(Button::new("send").small().ghost().label("Send")),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
.child(
|
.child(
|
||||||
section("Selected Values").max_w_lg().child(
|
section("Selected Values").max_w_lg().child(
|
||||||
v_flex()
|
v_flex()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use gpui::{
|
use gpui::{
|
||||||
div, prelude::FluentBuilder as _, App, AppContext, Axis, Context, Entity, Focusable,
|
div, prelude::FluentBuilder as _, px, App, AppContext, Axis, Context, Entity, Focusable,
|
||||||
InteractiveElement, IntoElement, ParentElement as _, Render, Styled, Window,
|
InteractiveElement, IntoElement, ParentElement as _, Render, Styled, Window,
|
||||||
};
|
};
|
||||||
use gpui_component::{
|
use gpui_component::{
|
||||||
|
|
@ -8,14 +8,16 @@ use gpui_component::{
|
||||||
color_picker::{ColorPicker, ColorPickerState},
|
color_picker::{ColorPicker, ColorPickerState},
|
||||||
date_picker::{DatePicker, DatePickerState},
|
date_picker::{DatePicker, DatePickerState},
|
||||||
divider::Divider,
|
divider::Divider,
|
||||||
|
dropdown::{Dropdown, DropdownState},
|
||||||
form::{form_field, v_form},
|
form::{form_field, v_form},
|
||||||
h_flex,
|
h_flex,
|
||||||
input::{InputState, TextInput},
|
input::{InputState, TextInput},
|
||||||
switch::Switch,
|
switch::Switch,
|
||||||
v_flex, AxisExt, FocusableCycle, Selectable, Sizable, Size,
|
v_flex, ActiveTheme, AxisExt, FocusableCycle, Selectable, Sizable, Size,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct FormStory {
|
pub struct FormStory {
|
||||||
|
name_prefix_state: Entity<DropdownState<Vec<String>>>,
|
||||||
name_input: Entity<InputState>,
|
name_input: Entity<InputState>,
|
||||||
email_input: Entity<InputState>,
|
email_input: Entity<InputState>,
|
||||||
bio_input: Entity<InputState>,
|
bio_input: Entity<InputState>,
|
||||||
|
|
@ -50,6 +52,20 @@ impl FormStory {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||||
|
let name_prefix_state = cx.new(|cx| {
|
||||||
|
DropdownState::new(
|
||||||
|
vec![
|
||||||
|
"Mr.".to_string(),
|
||||||
|
"Mrs.".to_string(),
|
||||||
|
"Ms.".to_string(),
|
||||||
|
"Dr.".to_string(),
|
||||||
|
],
|
||||||
|
Some(0),
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
let name_input = cx.new(|cx| InputState::new(window, cx).default_value("Jason Lee"));
|
let name_input = cx.new(|cx| InputState::new(window, cx).default_value("Jason Lee"));
|
||||||
let color_state = cx.new(|cx| ColorPickerState::new(window, cx));
|
let color_state = cx.new(|cx| ColorPickerState::new(window, cx));
|
||||||
|
|
||||||
|
|
@ -64,6 +80,7 @@ impl FormStory {
|
||||||
let date = cx.new(|cx| DatePickerState::new(window, cx));
|
let date = cx.new(|cx| DatePickerState::new(window, cx));
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
name_prefix_state,
|
||||||
name_input,
|
name_input,
|
||||||
email_input,
|
email_input,
|
||||||
bio_input,
|
bio_input,
|
||||||
|
|
@ -158,9 +175,23 @@ impl Render for FormStory {
|
||||||
.layout(self.layout)
|
.layout(self.layout)
|
||||||
.with_size(self.size)
|
.with_size(self.size)
|
||||||
.child(
|
.child(
|
||||||
form_field()
|
form_field().label_fn(|_, _| "Name").child(
|
||||||
.label_fn(|_, _| "Name")
|
h_flex()
|
||||||
.child(TextInput::new(&self.name_input)),
|
.gap_2()
|
||||||
|
.border_1()
|
||||||
|
.border_color(cx.theme().border)
|
||||||
|
.rounded(cx.theme().radius)
|
||||||
|
.child(
|
||||||
|
div().w(px(90.)).child(
|
||||||
|
Dropdown::new(&self.name_prefix_state)
|
||||||
|
.pr_0()
|
||||||
|
.appearance(false),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(div().flex_1().child(
|
||||||
|
TextInput::new(&self.name_input).pl_0().appearance(false),
|
||||||
|
)),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
form_field()
|
form_field()
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,7 @@ use gpui::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{section, Tab, TabPrev};
|
use crate::{section, Tab, TabPrev};
|
||||||
use gpui_component::{
|
use gpui_component::{button::*, input::*, *};
|
||||||
button::{Button, ButtonVariants as _},
|
|
||||||
input::{InputEvent, InputState, MaskPattern, TextInput},
|
|
||||||
v_flex, ContextModal, FocusableCycle, Icon, IconName, Sizable,
|
|
||||||
};
|
|
||||||
|
|
||||||
const CONTEXT: &str = "InputStory";
|
const CONTEXT: &str = "InputStory";
|
||||||
|
|
||||||
|
|
@ -271,5 +267,26 @@ impl Render for InputStory {
|
||||||
window.focused_input(cx).map(|input| input.read(cx).value())
|
window.focused_input(cx).map(|input| input.read(cx).value())
|
||||||
))),
|
))),
|
||||||
)
|
)
|
||||||
|
.child(
|
||||||
|
section("Appearance false").max_w_md().child(
|
||||||
|
div()
|
||||||
|
.border_1()
|
||||||
|
.px_6()
|
||||||
|
.py_5()
|
||||||
|
.rounded_lg()
|
||||||
|
.bg(if cx.theme().is_dark() {
|
||||||
|
yellow_950()
|
||||||
|
} else {
|
||||||
|
yellow_50()
|
||||||
|
})
|
||||||
|
.text_color(if cx.theme().is_dark() {
|
||||||
|
yellow_100()
|
||||||
|
} else {
|
||||||
|
yellow_900()
|
||||||
|
})
|
||||||
|
.w_full()
|
||||||
|
.child(TextInput::new(&self.input1).appearance(false)),
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use gpui::{
|
use gpui::{
|
||||||
App, AppContext as _, Context, Entity, FocusHandle, Focusable, InteractiveElement, IntoElement,
|
div, App, AppContext as _, Context, Entity, FocusHandle, Focusable, InteractiveElement,
|
||||||
KeyBinding, ParentElement as _, Render, Styled, Subscription, Window,
|
IntoElement, KeyBinding, ParentElement as _, Render, Styled, Subscription, Window,
|
||||||
};
|
};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
|
|
@ -8,7 +8,7 @@ use crate::{section, Tab, TabPrev};
|
||||||
use gpui_component::{
|
use gpui_component::{
|
||||||
button::{Button, ButtonVariants},
|
button::{Button, ButtonVariants},
|
||||||
input::{InputEvent, InputState, MaskPattern, NumberInput, NumberInputEvent, StepAction},
|
input::{InputEvent, InputState, MaskPattern, NumberInput, NumberInputEvent, StepAction},
|
||||||
v_flex, FocusableCycle, IconName, Sizable,
|
v_flex, ActiveTheme, FocusableCycle, IconName, Sizable,
|
||||||
};
|
};
|
||||||
|
|
||||||
const CONTEXT: &str = "NumberInputStory";
|
const CONTEXT: &str = "NumberInputStory";
|
||||||
|
|
@ -27,6 +27,8 @@ pub struct NumberInputStory {
|
||||||
number_input2_value: u64,
|
number_input2_value: u64,
|
||||||
number_input3: Entity<InputState>,
|
number_input3: Entity<InputState>,
|
||||||
number_input3_value: f64,
|
number_input3_value: f64,
|
||||||
|
number_input4: Entity<InputState>,
|
||||||
|
number_input4_value: f64,
|
||||||
|
|
||||||
_subscriptions: Vec<Subscription>,
|
_subscriptions: Vec<Subscription>,
|
||||||
}
|
}
|
||||||
|
|
@ -77,6 +79,15 @@ impl NumberInputStory {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let number_input4 = cx.new(|cx| {
|
||||||
|
InputState::new(window, cx)
|
||||||
|
.placeholder("Number Input without appearance")
|
||||||
|
.mask_pattern(MaskPattern::Number {
|
||||||
|
separator: Some(','),
|
||||||
|
fraction: Some(2),
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
let _subscriptions = vec![
|
let _subscriptions = vec![
|
||||||
cx.subscribe_in(&number_input1, window, Self::on_input_event),
|
cx.subscribe_in(&number_input1, window, Self::on_input_event),
|
||||||
cx.subscribe_in(&number_input1, window, Self::on_number_input_event),
|
cx.subscribe_in(&number_input1, window, Self::on_number_input_event),
|
||||||
|
|
@ -84,6 +95,8 @@ impl NumberInputStory {
|
||||||
cx.subscribe_in(&number_input2, window, Self::on_number_input_event),
|
cx.subscribe_in(&number_input2, window, Self::on_number_input_event),
|
||||||
cx.subscribe_in(&number_input3, window, Self::on_input_event),
|
cx.subscribe_in(&number_input3, window, Self::on_input_event),
|
||||||
cx.subscribe_in(&number_input3, window, Self::on_number_input_event),
|
cx.subscribe_in(&number_input3, window, Self::on_number_input_event),
|
||||||
|
cx.subscribe_in(&number_input4, window, Self::on_input_event),
|
||||||
|
cx.subscribe_in(&number_input4, window, Self::on_number_input_event),
|
||||||
];
|
];
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -93,6 +106,8 @@ impl NumberInputStory {
|
||||||
number_input2_value: 0,
|
number_input2_value: 0,
|
||||||
number_input3,
|
number_input3,
|
||||||
number_input3_value: 0.0,
|
number_input3_value: 0.0,
|
||||||
|
number_input4,
|
||||||
|
number_input4_value: 0.0,
|
||||||
_subscriptions,
|
_subscriptions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -162,6 +177,11 @@ impl NumberInputStory {
|
||||||
this.update(cx, |input, cx| {
|
this.update(cx, |input, cx| {
|
||||||
input.set_value(self.number_input3_value.to_string(), window, cx);
|
input.set_value(self.number_input3_value.to_string(), window, cx);
|
||||||
});
|
});
|
||||||
|
} else if this == &self.number_input4 {
|
||||||
|
self.number_input4_value = self.number_input4_value - 1.0;
|
||||||
|
this.update(cx, |input, cx| {
|
||||||
|
input.set_value(self.number_input4_value.to_string(), window, cx);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StepAction::Increment => {
|
StepAction::Increment => {
|
||||||
|
|
@ -180,6 +200,11 @@ impl NumberInputStory {
|
||||||
this.update(cx, |input, cx| {
|
this.update(cx, |input, cx| {
|
||||||
input.set_value(self.number_input3_value.to_string(), window, cx);
|
input.set_value(self.number_input3_value.to_string(), window, cx);
|
||||||
});
|
});
|
||||||
|
} else if this == &self.number_input4 {
|
||||||
|
self.number_input4_value = self.number_input4_value + 1.0;
|
||||||
|
this.update(cx, |input, cx| {
|
||||||
|
input.set_value(self.number_input4_value.to_string(), window, cx);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -225,5 +250,14 @@ impl Render for NumberInputStory {
|
||||||
.max_w_md()
|
.max_w_md()
|
||||||
.child(NumberInput::new(&self.number_input3)),
|
.child(NumberInput::new(&self.number_input3)),
|
||||||
)
|
)
|
||||||
|
.child(
|
||||||
|
section("Without appearance").max_w_md().child(
|
||||||
|
div()
|
||||||
|
.w_full()
|
||||||
|
.bg(cx.theme().secondary)
|
||||||
|
.rounded_md()
|
||||||
|
.child(NumberInput::new(&self.number_input4).appearance(false)),
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -264,6 +264,7 @@ pub struct Dropdown<D: DropdownDelegate + 'static> {
|
||||||
empty: Option<AnyElement>,
|
empty: Option<AnyElement>,
|
||||||
menu_width: Length,
|
menu_width: Length,
|
||||||
disabled: bool,
|
disabled: bool,
|
||||||
|
appearance: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SearchableVec<T> {
|
pub struct SearchableVec<T> {
|
||||||
|
|
@ -533,6 +534,7 @@ where
|
||||||
empty: None,
|
empty: None,
|
||||||
menu_width: Length::Auto,
|
menu_width: Length::Auto,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
appearance: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -581,6 +583,12 @@ where
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the appearance of the dropdown, if false the dropdown input will no border, background.
|
||||||
|
pub fn appearance(mut self, appearance: bool) -> Self {
|
||||||
|
self.appearance = appearance;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the title element for the dropdown input.
|
/// Returns the title element for the dropdown input.
|
||||||
fn display_title(&self, _: &Window, cx: &App) -> impl IntoElement {
|
fn display_title(&self, _: &Window, cx: &App) -> impl IntoElement {
|
||||||
let default_title = div()
|
let default_title = div()
|
||||||
|
|
@ -714,17 +722,25 @@ where
|
||||||
.flex()
|
.flex()
|
||||||
.items_center()
|
.items_center()
|
||||||
.justify_between()
|
.justify_between()
|
||||||
.bg(cx.theme().background)
|
.when(self.appearance, |this| {
|
||||||
.border_1()
|
this.bg(cx.theme().background)
|
||||||
.border_color(cx.theme().input)
|
.border_1()
|
||||||
.rounded(cx.theme().radius)
|
.border_color(cx.theme().input)
|
||||||
.when(cx.theme().shadow, |this| this.shadow_xs())
|
.rounded(cx.theme().radius)
|
||||||
.map(|this| if self.disabled { this } else { this })
|
.when(cx.theme().shadow, |this| this.shadow_xs())
|
||||||
|
})
|
||||||
|
.map(|this| {
|
||||||
|
if self.disabled {
|
||||||
|
this.shadow_none()
|
||||||
|
} else {
|
||||||
|
this
|
||||||
|
}
|
||||||
|
})
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.input_text_size(self.size)
|
|
||||||
.when(outline_visible, |this| this.focused_border(cx))
|
|
||||||
.input_size(self.size)
|
.input_size(self.size)
|
||||||
|
.input_text_size(self.size)
|
||||||
.refine_style(&self.style)
|
.refine_style(&self.style)
|
||||||
|
.when(outline_visible, |this| this.focused_border(cx))
|
||||||
.when(allow_open, |this| {
|
.when(allow_open, |this| {
|
||||||
this.on_click(window.listener_for(&self.state, DropdownState::toggle_menu))
|
this.on_click(window.listener_for(&self.state, DropdownState::toggle_menu))
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ pub struct NumberInput {
|
||||||
size: Size,
|
size: Size,
|
||||||
prefix: Option<AnyElement>,
|
prefix: Option<AnyElement>,
|
||||||
suffix: Option<AnyElement>,
|
suffix: Option<AnyElement>,
|
||||||
|
appearance: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NumberInput {
|
impl NumberInput {
|
||||||
|
|
@ -40,6 +41,7 @@ impl NumberInput {
|
||||||
placeholder: SharedString::default(),
|
placeholder: SharedString::default(),
|
||||||
prefix: None,
|
prefix: None,
|
||||||
suffix: None,
|
suffix: None,
|
||||||
|
appearance: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,6 +76,12 @@ impl NumberInput {
|
||||||
self.suffix = Some(suffix.into_any_element());
|
self.suffix = Some(suffix.into_any_element());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the appearance of the number input, if false will no border and background.
|
||||||
|
pub fn appearance(mut self, appearance: bool) -> Self {
|
||||||
|
self.appearance = appearance;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputState {
|
impl InputState {
|
||||||
|
|
@ -128,10 +136,12 @@ impl RenderOnce for NumberInput {
|
||||||
.flex_1()
|
.flex_1()
|
||||||
.input_size(self.size)
|
.input_size(self.size)
|
||||||
.px(self.size.input_px() / 2.)
|
.px(self.size.input_px() / 2.)
|
||||||
.bg(cx.theme().background)
|
.when(self.appearance, |this| {
|
||||||
.border_color(cx.theme().input)
|
this.bg(cx.theme().background)
|
||||||
.border_1()
|
.border_color(cx.theme().input)
|
||||||
.rounded(cx.theme().radius)
|
.border_1()
|
||||||
|
.rounded(cx.theme().radius)
|
||||||
|
})
|
||||||
.when(focused, |this| this.focused_border(cx))
|
.when(focused, |this| this.focused_border(cx))
|
||||||
.child(
|
.child(
|
||||||
Button::new("minus")
|
Button::new("minus")
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ impl TextInput {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the appearance of the input field.
|
/// Set the appearance of the input field, if false the input field will no border, background.
|
||||||
pub fn appearance(mut self, appearance: bool) -> Self {
|
pub fn appearance(mut self, appearance: bool) -> Self {
|
||||||
self.appearance = appearance;
|
self.appearance = appearance;
|
||||||
self
|
self
|
||||||
|
|
|
||||||
|
|
@ -238,6 +238,7 @@ pub struct DatePicker {
|
||||||
size: Size,
|
size: Size,
|
||||||
number_of_months: usize,
|
number_of_months: usize,
|
||||||
presets: Option<Vec<DateRangePreset>>,
|
presets: Option<Vec<DateRangePreset>>,
|
||||||
|
appearance: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sizable for DatePicker {
|
impl Sizable for DatePicker {
|
||||||
|
|
@ -275,6 +276,7 @@ impl DatePicker {
|
||||||
style: StyleRefinement::default(),
|
style: StyleRefinement::default(),
|
||||||
number_of_months: 2,
|
number_of_months: 2,
|
||||||
presets: None,
|
presets: None,
|
||||||
|
appearance: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -301,6 +303,12 @@ impl DatePicker {
|
||||||
self.number_of_months = number_of_months;
|
self.number_of_months = number_of_months;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set appearance of the date picker, if false, the date picker will be in a minimal style.
|
||||||
|
pub fn appearance(mut self, appearance: bool) -> Self {
|
||||||
|
self.appearance = appearance;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderOnce for DatePicker {
|
impl RenderOnce for DatePicker {
|
||||||
|
|
@ -337,14 +345,16 @@ impl RenderOnce for DatePicker {
|
||||||
.flex()
|
.flex()
|
||||||
.items_center()
|
.items_center()
|
||||||
.justify_between()
|
.justify_between()
|
||||||
.bg(cx.theme().background)
|
.when(self.appearance, |this| {
|
||||||
.border_1()
|
this.bg(cx.theme().background)
|
||||||
.border_color(cx.theme().input)
|
.border_1()
|
||||||
.rounded(cx.theme().radius)
|
.border_color(cx.theme().input)
|
||||||
.when(cx.theme().shadow, |this| this.shadow_xs())
|
.rounded(cx.theme().radius)
|
||||||
|
.when(cx.theme().shadow, |this| this.shadow_xs())
|
||||||
|
.when(is_focused, |this| this.focused_border(cx))
|
||||||
|
})
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.input_text_size(self.size)
|
.input_text_size(self.size)
|
||||||
.when(is_focused, |this| this.focused_border(cx))
|
|
||||||
.input_size(self.size)
|
.input_size(self.size)
|
||||||
.when(!state.open, |this| {
|
.when(!state.open, |this| {
|
||||||
this.on_click(
|
this.on_click(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue