Add Small, Large size support to Input and Dropdown and let them use same height. (#35)
- Add `Dropdown::string_list` to use `Vec<SharedString>` to create dropdown for easy use. - Add `input_px`, `input_py`, `input_h` trait methods to `Styled` element.
This commit is contained in:
parent
2b184ca8d5
commit
ce7c1a3a34
6 changed files with 237 additions and 56 deletions
|
|
@ -1,9 +1,11 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use gpui::{
|
||||
px, IntoElement, ParentElement, Render, Styled, View, ViewContext, VisualContext, WindowContext,
|
||||
};
|
||||
|
||||
use ui::{
|
||||
dropdown::{Dropdown, DropdownDelegate, DropdownItem},
|
||||
dropdown::{Dropdown, DropdownDelegate, DropdownItem, StringDropdownDelegate},
|
||||
h_flex,
|
||||
theme::ActiveTheme,
|
||||
v_flex, Selection,
|
||||
|
|
@ -20,7 +22,7 @@ impl Country {
|
|||
}
|
||||
}
|
||||
|
||||
impl DropdownItem for Country {
|
||||
impl DropdownItem for &Country {
|
||||
fn title(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
|
@ -36,6 +38,8 @@ struct FuritDelegate(Vec<String>);
|
|||
pub struct DropdownStory {
|
||||
country_dropdown: View<Dropdown<CounterDelegate>>,
|
||||
furit_dropdown: View<Dropdown<FuritDelegate>>,
|
||||
simple_dropdown1: View<Dropdown<StringDropdownDelegate>>,
|
||||
simple_dropdown2: View<Dropdown<StringDropdownDelegate>>,
|
||||
}
|
||||
|
||||
impl DropdownDelegate for CounterDelegate {
|
||||
|
|
@ -43,12 +47,8 @@ impl DropdownDelegate for CounterDelegate {
|
|||
self.0.len()
|
||||
}
|
||||
|
||||
fn get(&self, ix: usize) -> Option<&dyn DropdownItem> {
|
||||
if let Some(item) = self.0.get(ix) {
|
||||
Some(item)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
fn get(&self, ix: usize) -> Option<impl DropdownItem> {
|
||||
self.0.get(ix)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -57,12 +57,8 @@ impl DropdownDelegate for FuritDelegate {
|
|||
self.0.len()
|
||||
}
|
||||
|
||||
fn get(&self, ix: usize) -> Option<&dyn DropdownItem> {
|
||||
if let Some(item) = self.0.get(ix) {
|
||||
Some(item)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
fn get(&self, ix: usize) -> Option<impl DropdownItem> {
|
||||
self.0.get(ix)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -82,7 +78,8 @@ impl DropdownStory {
|
|||
Country::new("Ecuador", "EC"),
|
||||
]);
|
||||
|
||||
let country_dropdown = cx.new_view(|cx| Dropdown::new("dropdown-country", countries, cx));
|
||||
let country_dropdown =
|
||||
cx.new_view(|cx| Dropdown::new("dropdown-country", countries, Some(6), cx));
|
||||
|
||||
let furits = FuritDelegate(
|
||||
[
|
||||
|
|
@ -98,11 +95,39 @@ impl DropdownStory {
|
|||
.map(|s| s.to_string())
|
||||
.collect(),
|
||||
);
|
||||
let furit_dropdown = cx.new_view(|cx| Dropdown::new("dropdown-furits", furits, cx));
|
||||
let furit_dropdown = cx.new_view(|cx| Dropdown::new("dropdown-furits", furits, None, cx));
|
||||
|
||||
cx.new_view(|_| Self {
|
||||
cx.new_view(|cx| Self {
|
||||
country_dropdown,
|
||||
furit_dropdown,
|
||||
simple_dropdown1: cx.new_view(|cx| {
|
||||
Dropdown::string_list(
|
||||
"string-list1",
|
||||
Rc::new(vec![
|
||||
"QPUI".into(),
|
||||
"Iced".into(),
|
||||
"QT".into(),
|
||||
"Cocoa".into(),
|
||||
]),
|
||||
Some(0),
|
||||
cx,
|
||||
)
|
||||
.size(ui::Size::Small)
|
||||
}),
|
||||
simple_dropdown2: cx.new_view(|cx| {
|
||||
Dropdown::string_list(
|
||||
"string-list2",
|
||||
Rc::new(vec![
|
||||
"Rust".into(),
|
||||
"Go".into(),
|
||||
"C++".into(),
|
||||
"JavaScript".into(),
|
||||
]),
|
||||
None,
|
||||
cx,
|
||||
)
|
||||
.size(ui::Size::Small)
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -138,5 +163,13 @@ impl Render for DropdownStory {
|
|||
.gap_4()
|
||||
.child("This is other text."),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.items_center()
|
||||
.w_128()
|
||||
.gap_2()
|
||||
.child(self.simple_dropdown1.clone())
|
||||
.child(self.simple_dropdown2.clone()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ use gpui::{
|
|||
ParentElement as _, Render, Styled, View, ViewContext, VisualContext, WindowContext,
|
||||
};
|
||||
|
||||
use ui::{button::Button, h_flex, input::TextInput, v_flex, Clickable, FocusableCycle, IconName};
|
||||
use ui::{
|
||||
button::Button, h_flex, input::TextInput, v_flex, Clickable, FocusableCycle, IconName, Size,
|
||||
};
|
||||
|
||||
use crate::section;
|
||||
|
||||
|
|
@ -24,6 +26,8 @@ pub struct InputStory {
|
|||
prefix_input1: View<TextInput>,
|
||||
suffix_input1: View<TextInput>,
|
||||
both_input1: View<TextInput>,
|
||||
large_input: View<TextInput>,
|
||||
small_input: View<TextInput>,
|
||||
}
|
||||
|
||||
impl InputStory {
|
||||
|
|
@ -72,6 +76,16 @@ impl InputStory {
|
|||
input.set_disabled(true, cx);
|
||||
input
|
||||
}),
|
||||
large_input: cx.new_view(|cx| {
|
||||
TextInput::new(cx)
|
||||
.size(Size::Large)
|
||||
.placeholder("Large input")
|
||||
}),
|
||||
small_input: cx.new_view(|cx| {
|
||||
TextInput::new(cx)
|
||||
.size(Size::Small)
|
||||
.placeholder("Small input")
|
||||
}),
|
||||
prefix_input1,
|
||||
suffix_input1,
|
||||
both_input1,
|
||||
|
|
@ -135,6 +149,11 @@ impl Render for InputStory {
|
|||
.child(self.both_input1.clone())
|
||||
.child(self.suffix_input1.clone()),
|
||||
)
|
||||
.child(
|
||||
section("Input Size", cx)
|
||||
.child(self.large_input.clone())
|
||||
.child(self.small_input.clone()),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.items_center()
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use gpui::{
|
||||
actions, deferred, div, prelude::FluentBuilder as _, px, rems, AnyElement, AppContext,
|
||||
DismissEvent, Element, ElementId, EventEmitter, FocusHandle, FocusableView, InteractiveElement,
|
||||
|
|
@ -21,8 +23,9 @@ pub fn init(cx: &mut AppContext) {
|
|||
use crate::{
|
||||
h_flex,
|
||||
list::{self, List, ListDelegate, ListItem},
|
||||
styled_ext::Sizeful,
|
||||
theme::ActiveTheme,
|
||||
Icon, IconName, StyledExt,
|
||||
Icon, IconName, Size, StyledExt,
|
||||
};
|
||||
|
||||
/// A trait for items that can be displayed in a dropdown.
|
||||
|
|
@ -31,7 +34,7 @@ pub trait DropdownItem {
|
|||
fn value(&self) -> &str;
|
||||
}
|
||||
|
||||
impl DropdownItem for String {
|
||||
impl DropdownItem for &String {
|
||||
fn title(&self) -> &str {
|
||||
self
|
||||
}
|
||||
|
|
@ -41,18 +44,28 @@ impl DropdownItem for String {
|
|||
}
|
||||
}
|
||||
|
||||
impl DropdownItem for &SharedString {
|
||||
fn title(&self) -> &str {
|
||||
self.as_ref()
|
||||
}
|
||||
|
||||
fn value(&self) -> &str {
|
||||
self.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DropdownDelegate {
|
||||
fn len(&self) -> usize;
|
||||
fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
fn get(&self, ix: usize) -> Option<&dyn DropdownItem>;
|
||||
fn get(&self, ix: usize) -> Option<impl DropdownItem>;
|
||||
}
|
||||
|
||||
struct DropdownListDelegate<D: DropdownDelegate + 'static> {
|
||||
delegate: D,
|
||||
dropdown: WeakView<Dropdown<D>>,
|
||||
selected_index: usize,
|
||||
selected_index: Option<usize>,
|
||||
}
|
||||
|
||||
impl<D> ListDelegate for DropdownListDelegate<D>
|
||||
|
|
@ -66,7 +79,7 @@ where
|
|||
}
|
||||
|
||||
fn confirmed_index(&self) -> Option<usize> {
|
||||
Some(self.selected_index)
|
||||
self.selected_index
|
||||
}
|
||||
|
||||
fn render_item(
|
||||
|
|
@ -74,7 +87,10 @@ where
|
|||
ix: usize,
|
||||
_cx: &mut gpui::ViewContext<List<Self>>,
|
||||
) -> Option<Self::Item> {
|
||||
let selected = ix == self.selected_index;
|
||||
let selected = self
|
||||
.selected_index
|
||||
.map_or(false, |selected_index| selected_index == ix);
|
||||
|
||||
if let Some(item) = self.delegate.get(ix) {
|
||||
let list_item = ListItem::new(("list-item", ix))
|
||||
.check_icon(IconName::Check)
|
||||
|
|
@ -97,13 +113,15 @@ where
|
|||
}
|
||||
|
||||
fn confirm(&mut self, ix: Option<usize>, cx: &mut ViewContext<List<Self>>) {
|
||||
self.selected_index = ix.unwrap_or(0);
|
||||
self.selected_index = ix;
|
||||
|
||||
if let Some(view) = self.dropdown.upgrade() {
|
||||
cx.update_view(&view, |view, cx| {
|
||||
if let Some(item) = self.delegate.get(self.selected_index) {
|
||||
view.title = Some(item.title().to_string().into());
|
||||
view.value = Some(item.value().to_string().into());
|
||||
if let Some(ix) = self.selected_index {
|
||||
if let Some(item) = self.delegate.get(ix) {
|
||||
view.title = Some(item.title().to_string().into());
|
||||
view.value = Some(item.value().to_string().into());
|
||||
}
|
||||
}
|
||||
|
||||
view.open = false;
|
||||
|
|
@ -113,10 +131,25 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub struct StringDropdownDelegate {
|
||||
items: Rc<Vec<SharedString>>,
|
||||
}
|
||||
|
||||
impl DropdownDelegate for StringDropdownDelegate {
|
||||
fn len(&self) -> usize {
|
||||
self.items.len()
|
||||
}
|
||||
|
||||
fn get(&self, ix: usize) -> Option<impl DropdownItem> {
|
||||
self.items.get(ix)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Dropdown<D: DropdownDelegate + 'static> {
|
||||
id: ElementId,
|
||||
focus_handle: FocusHandle,
|
||||
list: View<List<DropdownListDelegate<D>>>,
|
||||
size: Size,
|
||||
open: bool,
|
||||
/// The value of the selected item.
|
||||
value: Option<SharedString>,
|
||||
|
|
@ -127,11 +160,30 @@ impl<D> Dropdown<D>
|
|||
where
|
||||
D: DropdownDelegate + 'static,
|
||||
{
|
||||
pub fn new(id: impl Into<ElementId>, delegate: D, cx: &mut ViewContext<Self>) -> Self {
|
||||
pub fn new(
|
||||
id: impl Into<ElementId>,
|
||||
delegate: D,
|
||||
selected_index: Option<usize>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Self {
|
||||
let delegate = DropdownListDelegate {
|
||||
delegate,
|
||||
dropdown: cx.view().downgrade(),
|
||||
selected_index: 0,
|
||||
selected_index,
|
||||
};
|
||||
|
||||
let (title, value) = if let Some(selected_index) = selected_index {
|
||||
let title: Option<SharedString> = delegate
|
||||
.delegate
|
||||
.get(selected_index)
|
||||
.map(|item| item.title().to_string().into());
|
||||
let value: Option<SharedString> = delegate
|
||||
.delegate
|
||||
.get(selected_index)
|
||||
.map(|item| item.value().to_string().into());
|
||||
(title, value)
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
|
||||
let list = cx.new_view(|cx| List::new(delegate, cx).no_query().max_h(rems(20.)));
|
||||
|
|
@ -139,17 +191,27 @@ where
|
|||
id: id.into(),
|
||||
focus_handle: cx.focus_handle(),
|
||||
list,
|
||||
size: Size::Medium,
|
||||
open: false,
|
||||
title: None,
|
||||
value: None,
|
||||
title,
|
||||
value,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn size(mut self, size: Size) -> Self {
|
||||
self.size = size;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_value(&mut self, value: impl Into<SharedString>, cx: &mut ViewContext<Self>) {
|
||||
self.value = Some(value.into());
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn value(&self) -> Option<SharedString> {
|
||||
self.value.clone()
|
||||
}
|
||||
|
||||
fn up(&mut self, _: &Up, cx: &mut ViewContext<Self>) {
|
||||
if !self.open {
|
||||
return;
|
||||
|
|
@ -199,6 +261,21 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl Dropdown<StringDropdownDelegate> {
|
||||
pub fn string_list(
|
||||
id: impl Into<ElementId>,
|
||||
items: Rc<Vec<SharedString>>,
|
||||
selected_index: Option<usize>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Self {
|
||||
let delegate = StringDropdownDelegate {
|
||||
items: items.clone(),
|
||||
};
|
||||
|
||||
Self::new(id, delegate, selected_index, cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D> EventEmitter<DismissEvent> for Dropdown<D> where D: DropdownDelegate + 'static {}
|
||||
impl<D> FocusableView for Dropdown<D>
|
||||
where
|
||||
|
|
@ -241,8 +318,9 @@ where
|
|||
.rounded(px(cx.theme().radius))
|
||||
.shadow_sm()
|
||||
.when(focused, |this| this.outline(cx))
|
||||
.px_3()
|
||||
.py_2()
|
||||
.input_px(self.size)
|
||||
.input_py(self.size)
|
||||
.input_h(self.size)
|
||||
.on_click(cx.listener(|this, _, cx| {
|
||||
this.open = !this.open;
|
||||
cx.notify();
|
||||
|
|
@ -254,8 +332,7 @@ where
|
|||
.justify_between()
|
||||
.child(div().flex_1().child(title))
|
||||
.child(
|
||||
Icon::new(IconName::ChevronsUpDown)
|
||||
.size_4()
|
||||
Icon::new(IconName::ChevronDown)
|
||||
.text_color(cx.theme().muted_foreground),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -5,11 +5,19 @@
|
|||
|
||||
use std::ops::Range;
|
||||
|
||||
use crate::event::InterativeElementExt as _;
|
||||
use crate::styled_ext::Sizeful;
|
||||
use crate::theme::ActiveTheme;
|
||||
use crate::StyledExt as _;
|
||||
use crate::{event::InterativeElementExt as _, Size};
|
||||
use blink_cursor::BlinkCursor;
|
||||
use gpui::*;
|
||||
use gpui::{
|
||||
actions, div, fill, point, prelude, px, relative, rems, size, AnyView, AppContext, Bounds,
|
||||
ClipboardItem, Context as _, Element, ElementId, ElementInputHandler, EventEmitter,
|
||||
FocusHandle, FocusableView, GlobalElementId, InteractiveElement as _, IntoElement, KeyBinding,
|
||||
KeyDownEvent, LayoutId, Model, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent,
|
||||
PaintQuad, ParentElement as _, Pixels, Point, Render, ShapedLine, SharedString, Style,
|
||||
Styled as _, TextRun, UnderlineStyle, View, ViewContext, ViewInputHandler, WindowContext,
|
||||
};
|
||||
use prelude::FluentBuilder as _;
|
||||
use unicode_segmentation::*;
|
||||
|
||||
|
|
@ -95,6 +103,7 @@ pub struct TextInput {
|
|||
disabled: bool,
|
||||
masked: bool,
|
||||
appearance: bool,
|
||||
size: Size,
|
||||
}
|
||||
|
||||
impl EventEmitter<TextEvent> for TextInput {}
|
||||
|
|
@ -119,6 +128,7 @@ impl TextInput {
|
|||
appearance: true,
|
||||
prefix: None,
|
||||
suffix: None,
|
||||
size: Size::Medium,
|
||||
};
|
||||
|
||||
// Observe the blink cursor to repaint the view when it changes.
|
||||
|
|
@ -186,6 +196,12 @@ impl TextInput {
|
|||
self
|
||||
}
|
||||
|
||||
/// Set the size of the input field.
|
||||
pub fn size(mut self, size: impl Into<Size>) -> Self {
|
||||
self.size = size.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Return the text of the input field.
|
||||
pub fn text(&self) -> SharedString {
|
||||
self.text.clone()
|
||||
|
|
@ -633,13 +649,14 @@ impl Element for TextElement {
|
|||
.unwrap();
|
||||
|
||||
let cursor_pos = line.x_for_index(cursor);
|
||||
let inset = px(0.5);
|
||||
let (selection, cursor) = if selected_range.is_empty() && input.show_cursor(cx) {
|
||||
(
|
||||
None,
|
||||
Some(fill(
|
||||
Bounds::new(
|
||||
point(bounds.left() + cursor_pos, bounds.top()),
|
||||
size(px(1.5), bounds.bottom() - bounds.top()),
|
||||
point(bounds.left() + cursor_pos, bounds.top() + inset),
|
||||
size(px(1.5), bounds.bottom() - bounds.top() - inset * 2),
|
||||
),
|
||||
crate::blue_500(),
|
||||
)),
|
||||
|
|
@ -739,8 +756,8 @@ impl Render for TextInput {
|
|||
.size_full()
|
||||
.line_height(rems(1.25))
|
||||
.text_size(rems(0.875))
|
||||
.py_2()
|
||||
.h_10()
|
||||
.input_py(self.size)
|
||||
.input_h(self.size)
|
||||
.when(self.appearance, |this| {
|
||||
this.bg(cx.theme().input)
|
||||
.border_color(cx.theme().input)
|
||||
|
|
@ -748,7 +765,7 @@ impl Render for TextInput {
|
|||
.rounded(px(cx.theme().radius))
|
||||
.shadow_sm()
|
||||
.when(focused, |this| this.outline(cx))
|
||||
.px_3()
|
||||
.input_px(self.size)
|
||||
.bg(if self.disabled {
|
||||
cx.theme().muted
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use crate::theme::{ActiveTheme, Colorize as _};
|
|||
use crate::{scroll::Scrollbar, v_flex};
|
||||
use crate::{Icon, IconName};
|
||||
use gpui::{
|
||||
actions, deferred, div, px, uniform_list, AppContext, FocusHandle, FocusableView,
|
||||
actions, div, px, uniform_list, AppContext, FocusHandle, FocusableView,
|
||||
InteractiveElement as _, IntoElement, KeyBinding, Length, ListSizingBehavior, MouseButton,
|
||||
ParentElement as _, Render, Styled as _, UniformListScrollHandle, View, ViewContext,
|
||||
VisualContext as _,
|
||||
|
|
@ -118,15 +118,12 @@ where
|
|||
return None;
|
||||
}
|
||||
|
||||
Some(
|
||||
deferred(Scrollbar::uniform_scroll(
|
||||
cx.view().clone(),
|
||||
self.scrollbar_state.clone(),
|
||||
self.vertical_scroll_handle.clone(),
|
||||
self.delegate.items_count(),
|
||||
))
|
||||
.with_priority(2),
|
||||
)
|
||||
Some(Scrollbar::uniform_scroll(
|
||||
cx.view().clone(),
|
||||
self.scrollbar_state.clone(),
|
||||
self.vertical_scroll_handle.clone(),
|
||||
self.delegate.items_count(),
|
||||
))
|
||||
}
|
||||
|
||||
fn scroll_to_selected_item(&mut self, _cx: &mut ViewContext<Self>) {
|
||||
|
|
@ -242,7 +239,6 @@ where
|
|||
.min_h(px(100.))
|
||||
.when_some(self.max_height, |this, h| this.max_h(h))
|
||||
.overflow_hidden()
|
||||
.children(self.render_scrollbar(cx))
|
||||
.child(
|
||||
uniform_list(view, "uniform-list", items_count, {
|
||||
move |list, visible_range, cx| {
|
||||
|
|
@ -275,7 +271,8 @@ where
|
|||
.with_sizing_behavior(sizing_behavior)
|
||||
.track_scroll(vertical_scroll_handle)
|
||||
.into_any_element(),
|
||||
),
|
||||
)
|
||||
.children(self.render_scrollbar(cx)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::theme::ActiveTheme;
|
||||
use gpui::{hsla, point, px, BoxShadow, FocusHandle, Pixels, Styled, WindowContext};
|
||||
use gpui::{hsla, point, px, rems, BoxShadow, FocusHandle, Pixels, Styled, WindowContext};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
pub enum ElevationIndex {
|
||||
|
|
@ -149,3 +149,41 @@ impl From<Pixels> for Size {
|
|||
Size::Size(size)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub trait Sizeful<T: Styled> {
|
||||
fn input_size(self, size: Size) -> Self;
|
||||
fn input_px(self, size: Size) -> Self;
|
||||
fn input_py(self, size: Size) -> Self;
|
||||
fn input_h(self, size: Size) -> Self;
|
||||
}
|
||||
|
||||
impl<T: Styled> Sizeful<T> for T {
|
||||
fn input_size(self, size: Size) -> Self {
|
||||
self.input_px(size).input_py(size).input_h(size)
|
||||
}
|
||||
|
||||
fn input_px(self, size: Size) -> Self {
|
||||
match size {
|
||||
Size::Large => self.px_5(),
|
||||
Size::Medium => self.px_3(),
|
||||
_ => self.px_2(),
|
||||
}
|
||||
}
|
||||
|
||||
fn input_py(self, size: Size) -> Self {
|
||||
match size {
|
||||
Size::Large => self.py_5(),
|
||||
Size::Medium => self.py_2(),
|
||||
_ => self.py_1(),
|
||||
}
|
||||
}
|
||||
|
||||
fn input_h(self, size: Size) -> Self {
|
||||
match size {
|
||||
Size::Large => self.h_11().text_size(rems(1.)),
|
||||
Size::Medium => self.h_8().text_size(rems(0.85)),
|
||||
_ => self.h(px(26.)).text_size(rems(0.8)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue