yew_hooks/hooks/
use_counter.rs1use std::fmt;
2use std::ops::Deref;
3use std::rc::Rc;
4
5use yew::prelude::*;
6
7enum CounterAction {
8 Increase,
9 IncreaseBy(i32),
10 Decrease,
11 DecreaseBy(i32),
12 Set(i32),
13 Reset,
14}
15
16struct UseCounterReducer {
17 value: i32,
18 default: i32,
19}
20
21impl Reducible for UseCounterReducer {
22 type Action = CounterAction;
23
24 fn reduce(self: Rc<Self>, action: Self::Action) -> Rc<Self> {
25 let next_value = match action {
26 CounterAction::Increase => self.value + 1,
27 CounterAction::IncreaseBy(delta) => self.value + delta,
28 CounterAction::Decrease => self.value - 1,
29 CounterAction::DecreaseBy(delta) => self.value - delta,
30 CounterAction::Set(value) => value,
31 CounterAction::Reset => self.default,
32 };
33
34 Self {
35 value: next_value,
36 default: self.default,
37 }
38 .into()
39 }
40}
41
42impl PartialEq for UseCounterReducer {
43 fn eq(&self, other: &Self) -> bool {
44 self.value == other.value
45 }
46}
47
48pub struct UseCounterHandle {
50 inner: UseReducerHandle<UseCounterReducer>,
51}
52
53impl UseCounterHandle {
54 pub fn increase(&self) {
56 self.inner.dispatch(CounterAction::Increase);
57 }
58
59 pub fn increase_by(&self, delta: i32) {
61 self.inner.dispatch(CounterAction::IncreaseBy(delta));
62 }
63
64 pub fn decrease(&self) {
66 self.inner.dispatch(CounterAction::Decrease);
67 }
68
69 pub fn decrease_by(&self, delta: i32) {
71 self.inner.dispatch(CounterAction::DecreaseBy(delta));
72 }
73
74 pub fn set(&self, value: i32) {
76 self.inner.dispatch(CounterAction::Set(value));
77 }
78
79 pub fn reset(&self) {
81 self.inner.dispatch(CounterAction::Reset);
82 }
83}
84
85impl fmt::Debug for UseCounterHandle {
86 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87 f.debug_struct("UseCounterHandle")
88 .field("value", &format!("{:?}", self.inner.value))
89 .field("default", &format!("{:?}", self.inner.default))
90 .finish()
91 }
92}
93
94impl Deref for UseCounterHandle {
95 type Target = i32;
96
97 fn deref(&self) -> &Self::Target {
98 &(*self.inner).value
99 }
100}
101
102impl Clone for UseCounterHandle {
103 fn clone(&self) -> Self {
104 Self {
105 inner: self.inner.clone(),
106 }
107 }
108}
109
110impl PartialEq for UseCounterHandle {
111 fn eq(&self, other: &Self) -> bool {
112 *self.inner == *other.inner
113 }
114}
115
116#[hook]
171pub fn use_counter(default: i32) -> UseCounterHandle {
172 let inner = use_reducer(move || UseCounterReducer {
173 value: default,
174 default,
175 });
176
177 UseCounterHandle { inner }
178}