| 175 | } |
| 176 | |
| 177 | pub(crate) fn use_single_selectable_value<T: Clone + PartialEq + 'static>( |
| 178 | controlled_value: Option<ReadSignal<Option<T>>>, |
| 179 | default_value: Option<T>, |
| 180 | on_change: Callback<Option<T>>, |
| 181 | component_name: &'static str, |
| 182 | ) -> (Memo<Vec<RcPartialEqValue>>, Callback<RcPartialEqValue>) { |
| 183 | let mut internal_value: Signal<Option<T>> = use_signal(|| default_value.clone()); |
| 184 | let value = use_memo(move || match controlled_value { |
| 185 | Some(value) => value.cloned(), |
| 186 | None => internal_value.cloned(), |
| 187 | }); |
| 188 | let values = use_memo(move || value().map(RcPartialEqValue::new).into_iter().collect()); |
| 189 | let set_value = use_callback(move |incoming: RcPartialEqValue| { |
| 190 | let value = incoming |
| 191 | .as_ref::<T>() |
| 192 | .unwrap_or_else(|| panic!("{component_name} and option value types must match")) |
| 193 | .clone(); |
| 194 | internal_value.set(Some(value.clone())); |
| 195 | on_change.call(Some(value)); |
| 196 | }); |
| 197 | |
| 198 | (values, set_value) |
| 199 | } |
| 200 | |
| 201 | pub(crate) fn use_selectable_root( |
| 202 | values: Memo<Vec<RcPartialEqValue>>, |