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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use crate::RatingInjection;
use leptos::{either::Either, prelude::*};
use thaw_components::{If, Then};
use thaw_utils::class_list;
#[component]
pub fn RatingItem(value: u8) -> impl IntoView {
let rating = RatingInjection::expect_context();
let icon_fill_width = Memo::new(move |_| {
let displayed_rating_value = rating
.hovered_value
.get()
.unwrap_or_else(|| (rating.value.get().unwrap_or_default() * 2.0).round() / 2.0);
let value = f32::from(value);
if displayed_rating_value >= value {
1.0
} else if displayed_rating_value >= value - 0.5 {
0.5
} else {
0.0
}
});
let half = Signal::derive(move || rating.step.get() == 0.5);
view! {
<span class=class_list![
"thaw-rating-item",
("thaw-rating-item--filled", !rating.interactive),
("thaw-rating-item--half", move || half.get() && icon_fill_width.get() == 0.5),
move || format!("thaw-rating-item--{}", rating.color.get().as_str()),
move || format!("thaw-rating-item--{}", rating.size.get().as_str())
]>
{if rating.interactive {
Either::Left(
view! {
<If cond=half>
<Then slot>
<input
type="radio"
name=rating.name
aria-label=f32::from(value) - 0.5
class="thaw-rating-item__half-value-input"
value=f32::from(value) - 0.5
/>
</Then>
</If>
<input
type="radio"
name=rating.name
aria-label=value
class="thaw-rating-item__full-value-input"
value=value
/>
},
)
} else {
Either::Right(())
}} <If cond=Signal::derive(move || icon_fill_width.get() < 1.0)>
<Then slot>
<div aria-hidden="true" class="thaw-rating-item__unselected-icon">
{if rating.interactive {
Either::Left(
view! {
<svg
fill="currentColor"
aria-hidden="true"
width="1em"
height="1em"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M9.1 2.9a1 1 0 0 1 1.8 0l1.93 3.91 4.31.63a1 1 0 0 1 .56 1.7l-3.12 3.05.73 4.3a1 1 0 0 1-1.45 1.05L10 15.51l-3.86 2.03a1 1 0 0 1-1.45-1.05l.74-4.3L2.3 9.14a1 1 0 0 1 .56-1.7l4.31-.63L9.1 2.9Zm.9.44L8.07 7.25a1 1 0 0 1-.75.55L3 8.43l3.12 3.04a1 1 0 0 1 .3.89l-.75 4.3 3.87-2.03a1 1 0 0 1 .93 0l3.86 2.03-.74-4.3a1 1 0 0 1 .29-.89L17 8.43l-4.32-.63a1 1 0 0 1-.75-.55L10 3.35Z"
fill="currentColor"
></path>
</svg>
},
)
} else {
Either::Right(
view! {
<svg
fill="currentColor"
aria-hidden="true"
width="1em"
height="1em"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M9.1 2.9a1 1 0 0 1 1.8 0l1.93 3.91 4.31.63a1 1 0 0 1 .56 1.7l-3.12 3.05.73 4.3a1 1 0 0 1-1.45 1.05L10 15.51l-3.86 2.03a1 1 0 0 1-1.45-1.05l.74-4.3L2.3 9.14a1 1 0 0 1 .56-1.7l4.31-.63L9.1 2.9Z"
fill="currentColor"
></path>
</svg>
},
)
}}
</div>
</Then>
</If> <If cond=Signal::derive(move || icon_fill_width.get() > 0.0)>
<Then slot>
<div aria-hidden="true" class="thaw-rating-item__selected-icon">
<svg
fill="currentColor"
aria-hidden="true"
width="1em"
height="1em"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M9.1 2.9a1 1 0 0 1 1.8 0l1.93 3.91 4.31.63a1 1 0 0 1 .56 1.7l-3.12 3.05.73 4.3a1 1 0 0 1-1.45 1.05L10 15.51l-3.86 2.03a1 1 0 0 1-1.45-1.05l.74-4.3L2.3 9.14a1 1 0 0 1 .56-1.7l4.31-.63L9.1 2.9Z"
fill="currentColor"
></path>
</svg>
</div>
</Then>
</If>
</span>
}
}