prime8dev

prime8dev
git clone https://git.prime8.dev/prime8dev.git
Log | Files | Refs | README | LICENSE

helpers.go (3162B)


      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 padRunesRight(s string, width int) string {
     39 	r := []rune(s)
     40 	if len(r) >= width {
     41 		return s
     42 	}
     43 	return s + strings.Repeat(" ", width-len(r))
     44 }
     45 
     46 func clipLines(s string, width int, maxLines int) string {
     47 	if maxLines <= 0 || width <= 0 {
     48 		return ""
     49 	}
     50 	return lipgloss.NewStyle().MaxWidth(width).MaxHeight(maxLines).Render(s)
     51 }
     52 
     53 func renderPanelWithStyle(style lipgloss.Style, width int, totalHeight int, content string) string {
     54 	borderX := style.GetHorizontalBorderSize()
     55 	borderY := style.GetVerticalBorderSize()
     56 	paddingX := style.GetHorizontalPadding()
     57 	paddingY := style.GetVerticalPadding()
     58 
     59 	innerWidth := max(width-borderX-paddingX, 1)
     60 	innerHeight := max(totalHeight-borderY-paddingY, 1)
     61 	clipped := clipLines(content, innerWidth, innerHeight)
     62 	return style.
     63 		Width(max(width-borderX, 1)).
     64 		Height(max(totalHeight-borderY, 1)).
     65 		Render(clipped)
     66 }
     67 
     68 func panelStyleSharedLeft(style lipgloss.Style) lipgloss.Style {
     69 	b := lipgloss.NormalBorder()
     70 	b.TopLeft = "┬"
     71 	b.BottomLeft = "┴"
     72 	return style.BorderStyle(b)
     73 }
     74 
     75 func panelStyleSharedTop(style lipgloss.Style) lipgloss.Style {
     76 	b := lipgloss.NormalBorder()
     77 	b.TopLeft = "├"
     78 	b.TopRight = "┤"
     79 	return style.BorderStyle(b)
     80 }
     81 
     82 // panelStyleSharedRight draws a full border whose right edge is the divider
     83 // shared with a pane to its right (which then omits its left border).
     84 func panelStyleSharedRight(style lipgloss.Style) lipgloss.Style {
     85 	b := lipgloss.NormalBorder()
     86 	b.TopRight = "┬"
     87 	b.BottomRight = "┴"
     88 	return style.BorderStyle(b)
     89 }
     90 
     91 // panelStyleSharedBottom draws a full border whose bottom edge is the divider
     92 // shared with a pane below it (which then omits its top border).
     93 func panelStyleSharedBottom(style lipgloss.Style) lipgloss.Style {
     94 	b := lipgloss.NormalBorder()
     95 	b.BottomLeft = "├"
     96 	b.BottomRight = "┤"
     97 	return style.BorderStyle(b)
     98 }
     99 
    100 func panelStyleWithoutLeft(style lipgloss.Style) lipgloss.Style {
    101 	return style.Border(lipgloss.NormalBorder(), true, true, true, false)
    102 }
    103 
    104 func panelStyleWithoutTop(style lipgloss.Style) lipgloss.Style {
    105 	return style.Border(lipgloss.NormalBorder(), false, true, true, true)
    106 }
    107 
    108 func panelStyleWithoutRight(style lipgloss.Style) lipgloss.Style {
    109 	return style.Border(lipgloss.NormalBorder(), true, false, true, true)
    110 }
    111 
    112 func panelStyleWithoutBottom(style lipgloss.Style) lipgloss.Style {
    113 	return style.Border(lipgloss.NormalBorder(), true, true, false, true)
    114 }
    115 
    116 // dateRangeLabel is "oct 2024 – feb 2026 · 1 yr 5 mo".
    117 func dateRangeLabel(exp config.Experience) string {
    118 	return utils.FormatRange(exp.StartDate, exp.EndDate, exp.Current) + " · " +
    119 		utils.FormatDurationShort(exp.StartDate, exp.EndDate, exp.Current)
    120 }