perspective_viewer/components/style_controls/number_string_format/
digits_section.rs1use std::rc::Rc;
14
15use itertools::Itertools;
16use perspective_client::config::ColumnType;
17use yew::html;
18
19use super::CustomNumberFormat;
20use crate::components::style_controls::CustomNumberFormatMsg;
21use crate::config::{
22 ROUNDING_INCREMENTS, RoundingIncrement, RoundingMode, RoundingPriority, TrailingZeroDisplay,
23};
24use crate::ui::{
25 NumberField, NumberRangeField, OptionalField, Select, SelectEnumField, SelectItem,
26};
27
28impl CustomNumberFormat {
29 pub fn digits_section(&self, ctx: &yew::prelude::Context<Self>) -> yew::prelude::Html {
30 let is_float = matches!(ctx.props().view_type, ColumnType::Float);
31 html! {
32 <>
33 <NumberField
34 label="minimum-integer-digits"
35 min=1.
36 max=21.
37 step=1.
38 default={ctx.props().defaults.minimum_integer_digits}
39 current_value={self.config.minimum_integer_digits}
40 on_change={ctx.link().callback(CustomNumberFormatMsg::MinimumIntegerDigits)}
41 />
42 if is_float { { self.float_section(ctx) } } else { { self.rounding_increment(ctx) } }
43 </>
44 }
45 }
46
47 fn rounding_increment(&self, ctx: &yew::prelude::Context<Self>) -> yew::prelude::Html {
48 let values = ROUNDING_INCREMENTS
50 .iter()
51 .map(|val| RoundingIncrement::Custom(*val))
52 .map(SelectItem::Option)
53 .collect_vec();
54
55 let values = Rc::new([vec![SelectItem::Option(RoundingIncrement::Auto)], values].concat());
56 let on_check = ctx
57 .link()
58 .callback(|_| CustomNumberFormatMsg::RoundingIncrement(RoundingIncrement::default()));
59
60 let selected = self
61 .config
62 .rounding_increment
63 .map(RoundingIncrement::Custom)
64 .unwrap_or_default();
65
66 html! {
67 <div class="row">
68 <OptionalField
69 label="rounding-increment"
70 {on_check}
71 checked={self.config.rounding_increment.is_some()}
73 >
74 <Select<RoundingIncrement>
75 {values}
76 {selected}
77 on_select={ctx.link().callback(CustomNumberFormatMsg::RoundingIncrement)}
78 />
79 </OptionalField>
80 </div>
81 }
82 }
83
84 fn float_section(&self, ctx: &yew::prelude::Context<Self>) -> yew::prelude::Html {
85 let defaults = &ctx.props().defaults;
86 let fractional_value = Some((
87 self.config
88 .minimum_fraction_digits
89 .unwrap_or(defaults.fraction.0),
90 self.config
91 .maximum_fraction_digits
92 .unwrap_or(defaults.fraction.1),
93 ));
94
95 let significant_value = Some((
96 self.config
97 .minimum_significant_digits
98 .unwrap_or(defaults.significant.0),
99 self.config
100 .maximum_significant_digits
101 .unwrap_or(defaults.significant.1),
102 ));
103
104 html! {
105 <>
106 <div class="row">
107 <NumberRangeField
108 label="fractional-digits"
109 min=0.
110 max=20.
111 step=1.
112 default={defaults.fraction}
113 current_value={fractional_value}
114 on_change={ctx.link().callback(CustomNumberFormatMsg::FracChange)}
115 />
116 </div>
117 <div class="row">
118 <NumberRangeField
119 label="significant-digits"
120 min=1.
121 max=21.
122 step=1.
123 default={defaults.significant}
124 current_value={significant_value}
125 on_change={ctx.link().callback(CustomNumberFormatMsg::SigChange)}
126 />
127 </div>
128 { self.rounding_increment(ctx) }
129 <SelectEnumField<RoundingPriority>
130 label="rounding-priority"
131 current_value={self.config.rounding_priority.unwrap_or(defaults.rounding_priority)}
132 default_value={defaults.rounding_priority}
133 on_change={ctx.link().callback(CustomNumberFormatMsg::RoundingPriority)}
134 />
135 <SelectEnumField<RoundingMode>
136 label="rounding-mode"
137 current_value={self.config.rounding_mode.unwrap_or(defaults.rounding_mode)}
138 default_value={defaults.rounding_mode}
139 on_change={ctx.link().callback(CustomNumberFormatMsg::RoundingMode)}
140 />
141 <SelectEnumField<TrailingZeroDisplay>
142 label="trailing-zero-display"
143 current_value={self.config.trailing_zero_display.unwrap_or(defaults.trailing_zero_display)}
144 default_value={defaults.trailing_zero_display}
145 on_change={ctx.link().callback(CustomNumberFormatMsg::TrailingZero)}
146 />
147 </>
148 }
149 }
150}