init go project
This commit is contained in:
commit
5dde43e409
85 changed files with 16720 additions and 0 deletions
195
internal/ui/components/calendar/calendar.templ
Normal file
195
internal/ui/components/calendar/calendar.templ
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
// templui component calendar - version: v0.101.0 installed by templui v0.101.0
|
||||
// 📚 Documentation: https://templui.io/docs/components/calendar
|
||||
package calendar
|
||||
|
||||
import (
|
||||
"git.juancwu.dev/juancwu/budgething/internal/ui/components/icon"
|
||||
"git.juancwu.dev/juancwu/budgething/internal/utils"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type LocaleTag string
|
||||
|
||||
var (
|
||||
LocaleDefaultTag = LocaleTag("en-US")
|
||||
LocaleTagChinese = LocaleTag("zh-CN")
|
||||
LocaleTagFrench = LocaleTag("fr-FR")
|
||||
LocaleTagGerman = LocaleTag("de-DE")
|
||||
LocaleTagItalian = LocaleTag("it-IT")
|
||||
LocaleTagJapanese = LocaleTag("ja-JP")
|
||||
LocaleTagPortuguese = LocaleTag("pt-PT")
|
||||
LocaleTagSpanish = LocaleTag("es-ES")
|
||||
)
|
||||
|
||||
type Day int
|
||||
|
||||
var (
|
||||
Sunday = Day(0)
|
||||
Monday = Day(1)
|
||||
Tuesday = Day(2)
|
||||
Wednesday = Day(3)
|
||||
Thursday = Day(4)
|
||||
Friday = Day(5)
|
||||
Saturday = Day(6)
|
||||
)
|
||||
|
||||
type Props struct {
|
||||
ID string
|
||||
Class string
|
||||
LocaleTag LocaleTag
|
||||
Value *time.Time
|
||||
Name string
|
||||
InitialMonth int // Optional: 0-11 (Default: current or from Value). Controls the initially displayed month view.
|
||||
InitialYear int // Optional: (Default: current or from Value). Controls the initially displayed year view.
|
||||
StartOfWeek *Day // Optional: 0-6 [Sun-Sat] (Default: 1).
|
||||
RenderHiddenInput bool // Optional: Whether to render the hidden input (Default: true). Set to false when used inside DatePicker.
|
||||
}
|
||||
|
||||
templ Calendar(props ...Props) {
|
||||
{{
|
||||
var p Props
|
||||
if len(props) > 0 {
|
||||
p = props[0]
|
||||
}
|
||||
if p.ID == "" {
|
||||
p.ID = utils.RandomID() + "-calendar"
|
||||
}
|
||||
if p.Name == "" {
|
||||
// Should be provided by parent (e.g., DatePicker or in standalone usage)
|
||||
p.Name = p.ID + "-value" // Fallback name
|
||||
}
|
||||
if p.LocaleTag == "" {
|
||||
p.LocaleTag = LocaleDefaultTag
|
||||
}
|
||||
// Default to rendering hidden input unless explicitly set to false
|
||||
if p.RenderHiddenInput == false && len(props) > 0 {
|
||||
// Only respect false if it was explicitly passed
|
||||
p.RenderHiddenInput = props[0].RenderHiddenInput
|
||||
} else {
|
||||
p.RenderHiddenInput = true
|
||||
}
|
||||
|
||||
initialStartOfWeek := Monday
|
||||
if p.StartOfWeek != nil {
|
||||
initialStartOfWeek = *p.StartOfWeek
|
||||
}
|
||||
|
||||
initialView := time.Now()
|
||||
if p.Value != nil {
|
||||
initialView = *p.Value
|
||||
}
|
||||
|
||||
initialMonth := p.InitialMonth
|
||||
initialYear := p.InitialYear
|
||||
|
||||
// Use year from initialView if InitialYear prop is invalid/unset (<= 0)
|
||||
if initialYear <= 0 {
|
||||
initialYear = initialView.Year()
|
||||
}
|
||||
|
||||
// Use month from initialView if InitialMonth prop is invalid OR
|
||||
// if InitialMonth is default 0 AND InitialYear was also defaulted (meaning neither was likely set explicitly)
|
||||
if (initialMonth < 0 || initialMonth > 11) || (initialMonth == 0 && p.InitialYear <= 0) {
|
||||
initialMonth = int(initialView.Month()) - 1 // time.Month is 1-12
|
||||
}
|
||||
|
||||
initialSelectedISO := ""
|
||||
if p.Value != nil {
|
||||
initialSelectedISO = p.Value.Format("2006-01-02")
|
||||
}
|
||||
|
||||
// For SelectBox display
|
||||
currentMonth := initialMonth
|
||||
currentYear := initialYear
|
||||
|
||||
// Generate short month names (English only, JS will update with localized)
|
||||
monthNames := []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
|
||||
}}
|
||||
<div class={ p.Class } id={ p.ID + "-wrapper" } data-tui-calendar-wrapper="true">
|
||||
if p.RenderHiddenInput {
|
||||
<input
|
||||
type="hidden"
|
||||
name={ p.Name }
|
||||
value={ initialSelectedISO }
|
||||
id={ p.ID + "-hidden" }
|
||||
data-tui-calendar-hidden-input
|
||||
/>
|
||||
}
|
||||
<div
|
||||
id={ p.ID }
|
||||
data-tui-calendar-container="true"
|
||||
data-tui-calendar-locale-tag={ string(p.LocaleTag) }
|
||||
data-tui-calendar-initial-month={ strconv.Itoa(initialMonth) }
|
||||
data-tui-calendar-initial-year={ strconv.Itoa(initialYear) }
|
||||
data-tui-calendar-selected-date={ initialSelectedISO }
|
||||
data-tui-calendar-start-of-week={ int(initialStartOfWeek) }
|
||||
>
|
||||
<!-- Calendar Header -->
|
||||
<div class="flex items-center gap-2 mb-4">
|
||||
<button
|
||||
type="button"
|
||||
data-tui-calendar-prev
|
||||
class="inline-flex items-center justify-center rounded-md text-sm font-medium h-7 w-7 hover:bg-accent hover:text-accent-foreground focus:outline-none disabled:opacity-50 shrink-0"
|
||||
>
|
||||
@icon.ChevronLeft()
|
||||
</button>
|
||||
<div class="flex gap-2 flex-1 min-w-0">
|
||||
<!-- Month Select -->
|
||||
<div class="relative flex-1 has-[:focus]:border-ring border border-input shadow-xs has-[:focus]:ring-ring/50 has-[:focus]:ring-[3px] rounded-md">
|
||||
<select
|
||||
id={ p.ID + "-month-select" }
|
||||
data-tui-calendar-month-select
|
||||
class="absolute inset-0 opacity-0 cursor-pointer w-full"
|
||||
aria-label="Choose the Month"
|
||||
>
|
||||
for i := 0; i < 12; i++ {
|
||||
<option value={ strconv.Itoa(i) } selected?={ i == currentMonth } data-tui-calendar-month-index={ strconv.Itoa(i) }>
|
||||
{ monthNames[i] }
|
||||
</option>
|
||||
}
|
||||
</select>
|
||||
<span class="select-none font-medium rounded-md px-2 flex items-center justify-center gap-1 text-sm h-7 pointer-events-none" aria-hidden="true">
|
||||
<span id={ p.ID + "-month-value" }>{ monthNames[currentMonth] }</span>
|
||||
@icon.ChevronDown(icon.Props{Size: 14, Class: "text-muted-foreground"})
|
||||
</span>
|
||||
</div>
|
||||
<!-- Year Select -->
|
||||
<div class="relative flex-1 has-[:focus]:border-ring border border-input shadow-xs has-[:focus]:ring-ring/50 has-[:focus]:ring-[3px] rounded-md">
|
||||
<select
|
||||
id={ p.ID + "-year-select" }
|
||||
data-tui-calendar-year-select
|
||||
class="absolute inset-0 opacity-0 cursor-pointer w-full"
|
||||
aria-label="Choose the Year"
|
||||
>
|
||||
for year := 2100; year >= 1900; year-- {
|
||||
<option value={ strconv.Itoa(year) } selected?={ year == currentYear }>
|
||||
{ strconv.Itoa(year) }
|
||||
</option>
|
||||
}
|
||||
</select>
|
||||
<span class="select-none font-medium rounded-md px-2 flex items-center justify-center gap-1 text-sm h-7 pointer-events-none" aria-hidden="true">
|
||||
<span id={ p.ID + "-year-value" }>{ strconv.Itoa(currentYear) }</span>
|
||||
@icon.ChevronDown(icon.Props{Size: 14, Class: "text-muted-foreground"})
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
data-tui-calendar-next
|
||||
class="inline-flex items-center justify-center rounded-md text-sm font-medium h-7 w-7 hover:bg-accent hover:text-accent-foreground focus:outline-none disabled:opacity-50 shrink-0"
|
||||
>
|
||||
@icon.ChevronRight()
|
||||
</button>
|
||||
</div>
|
||||
<!-- Weekday Headers -->
|
||||
<div data-tui-calendar-weekdays class="grid grid-cols-7 gap-1 mb-1 place-items-center"></div>
|
||||
<!-- Calendar Day Grid -->
|
||||
<div data-tui-calendar-days class="grid grid-cols-7 gap-1 place-items-center"></div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
templ Script() {
|
||||
<script defer nonce={ templ.GetNonce(ctx) } src={ "/assets/js/calendar.min.js?v=" + utils.ScriptVersion }></script>
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue