Files
LazyPM/internal/utils/truncate/trunc.go
Robin Olsen 7facfb6afe Merge pull request #73 from LazyBachelor/LPM-138
LPM-138 Refactor Tui with composable modals and use canvas

Refactors the TUI (dashboard + kanban) to use a shared, composable modal system with canvas-based overlay rendering, while consolidating styling into internal/style and expanding issue interactions (e.g., comments).

Changes:

Introduces a new pkg/tui/modal system (manager/stack + multiple modal types) and overlays modals using Lipgloss compositor layers.
Refactors dashboard/kanban views and input handling to use the modal manager + focus manager instead of per-modal boolean state.
Consolidates TUI styling by moving from pkg/tui/styles to internal/style and updates components to use the new style package; adds a shared footer renderer.
2026-03-20 16:28:10 +01:00

44 lines
932 B
Go

package truncate
import "charm.land/lipgloss/v2"
// TruncateToWidth trims the given text so that its rendered width does not
// exceed maxWidth. If truncation occurs and there is room, an ellipsis is
// appended to indicate that the text was shortened.
func TruncateToWidth(text string, maxWidth int) string {
if maxWidth <= 0 {
return ""
}
if lipgloss.Width(text) <= maxWidth {
return text
}
const ellipsis = "…"
ellipsisWidth := lipgloss.Width(ellipsis)
if ellipsisWidth > maxWidth {
runes := []rune(text)
if len(runes) > 0 {
firstChar := string(runes[0])
if lipgloss.Width(firstChar) <= maxWidth {
return firstChar
}
}
return ""
}
runes := []rune(text)
lastSafe := 0
for i := range runes {
candidate := string(runes[:i+1])
if lipgloss.Width(candidate)+ellipsisWidth > maxWidth {
break
}
lastSafe = i + 1
}
current := string(runes[:lastSafe])
return current + ellipsis
}