-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathContextCounterComponent.java
More file actions
87 lines (76 loc) · 2.95 KB
/
Copy pathContextCounterComponent.java
File metadata and controls
87 lines (76 loc) · 2.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package rsp.app.counters;
import rsp.component.ComponentView;
import rsp.component.StateUpdater;
import rsp.component.definitions.ContextStateComponent;
import java.util.Objects;
import java.util.function.Function;
/**
* A counter component synchronized with the address bar (URL path or query parameters).
* <p>
* <strong>Usage examples:</strong>
* <ul>
* <li>URL path element: {@code /100/1001} → counter 1 = 100, counter 2 = 1001</li>
* <li>URL query parameter: {@code ?c4=27} → counter 4 = 27</li>
* </ul>
*
* @see ContextStateComponent for state-to-context synchronization
* @see CountersView for the counter's UI definition and events handlers logic
* @see CountersMainComponent for the counters group UI
*/
public class ContextCounterComponent extends ContextStateComponent<Integer, CountersView.CounterIntent> {
private final String name;
/**
* Creates a context-synced counter for the given name.
* <p>
* The name is used as:
* <ul>
* <li>Context attribute key (to retrieve state value from URL)</li>
* <li>Counter label in the UI</li>
* <li>HTML element ID prefix for event binding</li>
* </ul>
*
* @param name the counter identifier (e.g., \"c1\", \"c2\", \"c4\")
*/
public ContextCounterComponent(final String name) {
super(name);
this.name = Objects.requireNonNull(name);
}
@Override
protected Function<ContextValue, Integer> contextValueToStateFunction() {
return contextValue -> {
if (contextValue instanceof ContextValue.StringValue(String value)) {
return Integer.parseInt(value);
} else {
return 0;
}
};
}
@Override
protected Function<Integer, ContextValue> stateToContextValueFunction() {
return value -> new ContextValue.StringValue(value.toString());
}
/**
* Provides the view implementation for this counter.
* <p>
* This overrides the abstract {@link rsp.component.definitions.Component#componentView() componentView()}
* method, allowing subclasses to specify their own view logic while inheriting state management
* behavior from the base class.
* <p>
* The view reuses {@link CountersView}, which can be shared across multiple counter components
* with different state synchronization strategies.
*
* @return a new CountersView instance configured for this counter's name
*
* @see CountersView for the UI implementation
*/
@Override
public ComponentView<Integer, CountersView.CounterIntent> componentView() {
return new CountersView(this.name);
}
@Override
protected void onIntent(final CountersView.CounterIntent intent,
final Integer state,
final StateUpdater<Integer> stateUpdater) {
stateUpdater.setState(intent == CountersView.CounterIntent.INCREMENT ? state + 1 : state - 1);
}
}