init go project
This commit is contained in:
commit
5dde43e409
85 changed files with 16720 additions and 0 deletions
193
internal/ui/components/rating/rating.templ
Normal file
193
internal/ui/components/rating/rating.templ
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
// templui component rating - version: v0.101.0 installed by templui v0.101.0
|
||||
// 📚 Documentation: https://templui.io/docs/components/rating
|
||||
package rating
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.juancwu.dev/juancwu/budgething/internal/ui/components/icon"
|
||||
"git.juancwu.dev/juancwu/budgething/internal/utils"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Style string
|
||||
|
||||
const (
|
||||
StyleStar Style = "star"
|
||||
StyleHeart Style = "heart"
|
||||
StyleEmoji Style = "emoji"
|
||||
)
|
||||
|
||||
type Props struct {
|
||||
ID string
|
||||
Class string
|
||||
Attributes templ.Attributes
|
||||
Value float64
|
||||
ReadOnly bool
|
||||
Precision float64
|
||||
Name string
|
||||
Form string
|
||||
OnlyInteger bool
|
||||
}
|
||||
|
||||
type GroupProps struct {
|
||||
ID string
|
||||
Class string
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
type ItemProps struct {
|
||||
ID string
|
||||
Class string
|
||||
Attributes templ.Attributes
|
||||
Value int
|
||||
Style Style
|
||||
}
|
||||
|
||||
templ Rating(props ...Props) {
|
||||
{{ var p Props }}
|
||||
if len(props) > 0 {
|
||||
{{ p = props[0] }}
|
||||
}
|
||||
{{ p.setDefaults() }}
|
||||
<div
|
||||
if p.ID != "" {
|
||||
id={ p.ID }
|
||||
}
|
||||
data-tui-rating-component
|
||||
data-tui-rating-initial-value={ fmt.Sprintf("%.2f", p.Value) }
|
||||
data-tui-rating-precision={ fmt.Sprintf("%.2f", p.Precision) }
|
||||
data-tui-rating-readonly={ strconv.FormatBool(p.ReadOnly) }
|
||||
if p.Name != "" {
|
||||
data-tui-rating-name={ p.Name }
|
||||
}
|
||||
data-tui-rating-onlyinteger={ strconv.FormatBool(p.OnlyInteger) }
|
||||
class={
|
||||
utils.TwMerge(
|
||||
"flex flex-col items-start gap-1",
|
||||
p.Class,
|
||||
),
|
||||
}
|
||||
{ p.Attributes... }
|
||||
>
|
||||
{ children... }
|
||||
if p.Name != "" {
|
||||
<input
|
||||
type="hidden"
|
||||
name={ p.Name }
|
||||
value={ fmt.Sprintf("%.2f", p.Value) }
|
||||
if p.Form != "" {
|
||||
form={ p.Form }
|
||||
}
|
||||
data-tui-rating-input
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
templ Group(props ...GroupProps) {
|
||||
{{ var p GroupProps }}
|
||||
if len(props) > 0 {
|
||||
{{ p = props[0] }}
|
||||
}
|
||||
<div
|
||||
if p.ID != "" {
|
||||
id={ p.ID }
|
||||
}
|
||||
class={ utils.TwMerge("flex flex-row items-center gap-1", p.Class) }
|
||||
{ p.Attributes... }
|
||||
>
|
||||
{ children... }
|
||||
</div>
|
||||
}
|
||||
|
||||
templ Item(props ...ItemProps) {
|
||||
{{ var p ItemProps }}
|
||||
if len(props) > 0 {
|
||||
{{ p = props[0] }}
|
||||
}
|
||||
{{ p.setDefaults() }}
|
||||
<div
|
||||
if p.ID != "" {
|
||||
id={ p.ID }
|
||||
}
|
||||
data-tui-rating-item
|
||||
data-tui-rating-value={ strconv.Itoa(p.Value) }
|
||||
class={
|
||||
utils.TwMerge(
|
||||
"relative",
|
||||
colorClass(p.Style),
|
||||
"transition-opacity",
|
||||
"cursor-pointer", // Default cursor
|
||||
p.Class,
|
||||
),
|
||||
}
|
||||
{ p.Attributes... }
|
||||
>
|
||||
<div class="opacity-30">
|
||||
@ratingIcon(p.Style, false, float64(p.Value))
|
||||
</div>
|
||||
<div
|
||||
class="absolute inset-0 overflow-hidden w-0"
|
||||
data-tui-rating-item-foreground
|
||||
>
|
||||
@ratingIcon(p.Style, true, float64(p.Value))
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
func colorClass(style Style) string {
|
||||
switch style {
|
||||
case StyleHeart:
|
||||
return "text-destructive"
|
||||
case StyleEmoji:
|
||||
return "text-yellow-500"
|
||||
default:
|
||||
return "text-yellow-400"
|
||||
}
|
||||
}
|
||||
|
||||
func ratingIcon(style Style, filled bool, value float64) templ.Component {
|
||||
if style == StyleEmoji {
|
||||
if filled {
|
||||
switch {
|
||||
case value <= 1:
|
||||
return icon.Angry()
|
||||
case value <= 2:
|
||||
return icon.Frown()
|
||||
case value <= 3:
|
||||
return icon.Meh()
|
||||
case value <= 4:
|
||||
return icon.Smile()
|
||||
default:
|
||||
return icon.Laugh()
|
||||
}
|
||||
}
|
||||
return icon.Meh()
|
||||
}
|
||||
iconProps := icon.Props{}
|
||||
if filled {
|
||||
iconProps.Fill = "currentColor"
|
||||
}
|
||||
switch style {
|
||||
case StyleHeart:
|
||||
return icon.Heart(iconProps)
|
||||
default:
|
||||
return icon.Star(iconProps)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *ItemProps) setDefaults() {
|
||||
if p.Style == "" {
|
||||
p.Style = StyleStar
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Props) setDefaults() {
|
||||
if p.Precision <= 0 {
|
||||
p.Precision = 1.0
|
||||
}
|
||||
}
|
||||
|
||||
templ Script() {
|
||||
<script defer nonce={ templ.GetNonce(ctx) } src={ "/assets/js/rating.min.js?v=" + utils.ScriptVersion }></script>
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue