helpers.go (3864B)
1 package tui 2 3 import ( 4 "strings" 5 6 "git.prime8.dev/moncheeta/prime8dev/internal/config" 7 "git.prime8.dev/moncheeta/prime8dev/internal/utils" 8 "github.com/charmbracelet/lipgloss" 9 ) 10 11 func wrapIndex(v int, size int) int { 12 if size == 0 { 13 return 0 14 } 15 for v < 0 { 16 v += size 17 } 18 return v % size 19 } 20 21 func fitRunes(s string, width int) string { 22 if width <= 0 { 23 return "" 24 } 25 26 r := []rune(s) 27 if len(r) <= width { 28 return s 29 } 30 31 if width == 1 { 32 return "…" 33 } 34 35 return string(r[:width-1]) + "…" 36 } 37 38 func fitRunesLeading(s string, width int) string { 39 if width <= 0 { 40 return "" 41 } 42 43 r := []rune(s) 44 if len(r) <= width { 45 return s 46 } 47 48 if width <= 3 { 49 return strings.Repeat(".", width) 50 } 51 52 return "..." + string(r[len(r)-(width-3):]) 53 } 54 55 func padRunesRight(s string, width int) string { 56 r := []rune(s) 57 if len(r) >= width { 58 return s 59 } 60 return s + strings.Repeat(" ", width-len(r)) 61 } 62 63 func renderKeyValueFixed(key string, value string, keyWidth int, valueWidth int, keyStyle lipgloss.Style, valueStyle lipgloss.Style) string { 64 keyText := padRunesRight(fitRunes(key, keyWidth), keyWidth) + ":" 65 valueText := padRunesRight(fitRunesLeading(value, valueWidth), valueWidth) 66 return keyStyle.Render(keyText) + " " + valueStyle.Render(valueText) 67 } 68 69 func renderKeyValueLine(key string, value string, totalWidth int, keyStyle lipgloss.Style, valueStyle lipgloss.Style) string { 70 keyLabel := key + ":" 71 valueWidth := max(totalWidth-len([]rune(keyLabel))-1, 1) 72 return keyStyle.Render(keyLabel) + " " + valueStyle.Render(fitRunesLeading(value, valueWidth)) 73 } 74 75 func clipLines(s string, width int, maxLines int) string { 76 if maxLines <= 0 || width <= 0 { 77 return "" 78 } 79 return lipgloss.NewStyle().MaxWidth(width).MaxHeight(maxLines).Render(s) 80 } 81 82 func renderPanelWithStyle(style lipgloss.Style, width int, totalHeight int, content string) string { 83 borderX := style.GetHorizontalBorderSize() 84 borderY := style.GetVerticalBorderSize() 85 paddingX := style.GetHorizontalPadding() 86 paddingY := style.GetVerticalPadding() 87 88 innerWidth := max(width-borderX-paddingX, 1) 89 innerHeight := max(totalHeight-borderY-paddingY, 1) 90 clipped := clipLines(content, innerWidth, innerHeight) 91 return style. 92 Width(max(width-borderX, 1)). 93 Height(max(totalHeight-borderY, 1)). 94 Render(clipped) 95 } 96 97 func panelStyleSharedRight(style lipgloss.Style) lipgloss.Style { 98 b := lipgloss.NormalBorder() 99 b.TopRight = "┬" 100 b.BottomRight = "┴" 101 return style.BorderStyle(b) 102 } 103 104 func panelStyleSharedLeft(style lipgloss.Style) lipgloss.Style { 105 b := lipgloss.NormalBorder() 106 b.TopLeft = "┬" 107 b.BottomLeft = "┴" 108 return style.BorderStyle(b) 109 } 110 111 func panelStyleSharedBottom(style lipgloss.Style) lipgloss.Style { 112 b := lipgloss.NormalBorder() 113 b.BottomLeft = "├" 114 b.BottomRight = "┤" 115 return style.BorderStyle(b) 116 } 117 118 func panelStyleSharedTop(style lipgloss.Style) lipgloss.Style { 119 b := lipgloss.NormalBorder() 120 b.TopLeft = "├" 121 b.TopRight = "┤" 122 return style.BorderStyle(b) 123 } 124 125 func panelStyleWithoutRight(style lipgloss.Style) lipgloss.Style { 126 return style.Border(lipgloss.NormalBorder(), true, false, true, true) 127 } 128 129 func panelStyleWithoutLeft(style lipgloss.Style) lipgloss.Style { 130 return style.Border(lipgloss.NormalBorder(), true, true, true, false) 131 } 132 133 func panelStyleWithoutBottom(style lipgloss.Style) lipgloss.Style { 134 return style.Border(lipgloss.NormalBorder(), true, true, false, true) 135 } 136 137 func panelStyleWithoutTop(style lipgloss.Style) lipgloss.Style { 138 return style.Border(lipgloss.NormalBorder(), false, true, true, true) 139 } 140 141 func utilsYearLabel(exp config.Experience) string { 142 if exp.Current { 143 return "now" 144 } 145 if exp.EndDate != nil { 146 return exp.EndDate.Format("2006") 147 } 148 return exp.StartDate.Format("2006") 149 } 150 151 func dateRangeLabel(exp config.Experience) string { 152 return utils.FormatMonthYear(exp.StartDate) + " -> " + utils.FormatEndDate(exp.EndDate, exp.Current) 153 }