2 Commits

Author SHA1 Message Date
Hadi 39d2b852a8 add components
Signed-off-by: Hadi <112569860+anotherhadi@users.noreply.github.com>
2026-05-26 16:23:51 +02:00
Hadi 47ed1886a9 change default colors
Signed-off-by: Hadi <112569860+anotherhadi@users.noreply.github.com>
2026-05-26 16:07:40 +02:00
4 changed files with 119 additions and 22 deletions
+76
View File
@@ -0,0 +1,76 @@
package ilovetui
import (
"strings"
"charm.land/bubbles/v2/help"
"charm.land/bubbles/v2/textarea"
"charm.land/bubbles/v2/viewport"
"charm.land/lipgloss/v2"
)
// NewHelp returns a help.Model styled with the active theme.
func NewHelp() help.Model {
h := help.New()
h.Styles.ShortKey = lipgloss.NewStyle().Foreground(S.Primary)
h.Styles.ShortDesc = lipgloss.NewStyle().Foreground(S.Muted)
h.Styles.ShortSeparator = lipgloss.NewStyle().Foreground(S.Subtle)
h.Styles.FullKey = lipgloss.NewStyle().Foreground(S.Primary)
h.Styles.FullDesc = lipgloss.NewStyle().Foreground(S.Muted)
h.Styles.FullSeparator = lipgloss.NewStyle().Foreground(S.Subtle)
h.Styles.Ellipsis = lipgloss.NewStyle().Foreground(S.Subtle)
return h
}
// NewTextarea returns a textarea.Model styled with the active theme.
// Set showLineNumbers to true to display line numbers in the gutter.
func NewTextarea(showLineNumbers bool) textarea.Model {
ta := textarea.New()
ta.Prompt = ""
ta.ShowLineNumbers = showLineNumbers
ta.CharLimit = 0
ta.EndOfBufferCharacter = '~'
ts := ta.Styles()
ts.Focused.Base = lipgloss.NewStyle()
ts.Blurred.Base = lipgloss.NewStyle()
ts.Focused.Text = lipgloss.NewStyle().Foreground(S.Text)
ts.Focused.CursorLine = lipgloss.NewStyle().Background(S.Selection).Foreground(S.Text)
ts.Focused.CursorLineNumber = lipgloss.NewStyle().Background(S.Selection).Foreground(S.Primary).Bold(true)
ts.Focused.LineNumber = lipgloss.NewStyle().Foreground(S.Subtle)
ts.Focused.Placeholder = lipgloss.NewStyle().Foreground(S.Subtle)
ts.Focused.EndOfBuffer = lipgloss.NewStyle().Foreground(S.SubtleBg)
ts.Blurred.Text = lipgloss.NewStyle().Foreground(S.Muted)
ts.Blurred.LineNumber = lipgloss.NewStyle().Foreground(S.SubtleBg)
ts.Blurred.Placeholder = lipgloss.NewStyle().Foreground(S.Subtle)
ts.Blurred.EndOfBuffer = lipgloss.NewStyle().Foreground(S.SubtleBg)
ta.SetStyles(ts)
return ta
}
// NewViewport returns a viewport.Model with mouse wheel disabled.
func NewViewport() viewport.Model {
vp := viewport.New()
vp.MouseWheelEnabled = false
return vp
}
// ViewportView renders the viewport and appends a subtle scroll indicator
// on the last visible line when the user has not reached the bottom.
func ViewportView(vp *viewport.Model) string {
v := vp.View()
if vp.AtBottom() {
return v
}
lines := strings.Split(v, "\n")
if len(lines) == 0 {
return v
}
arrow := lipgloss.NewStyle().Foreground(S.Subtle).Render("↓")
arrowW := lipgloss.Width(arrow)
inner := vp.Width() - 2*arrowW
if inner < 0 {
inner = 0
}
lines[len(lines)-1] = arrow + strings.Repeat(" ", inner) + arrow
return strings.Join(lines, "\n")
}
+16 -16
View File
@@ -1,19 +1,19 @@
# ilovetui default theme
# Copy to ~/.config/ilovetui/config.yaml and edit to customize.
colors:
base00: "#1e1e2e" # Background
base01: "#181825" # Lighter Background / Status Bars
base02: "#313244" # Selection Background
base03: "#45475a" # Comments / Invisibles
base04: "#585b70" # Dark Foreground / Status Bars
base05: "#cdd6f4" # Default Foreground
base06: "#f5f5f5" # Light Foreground
base07: "#b4befe" # Light Background
base08: "#f38ba8" # Variables / Errors / Diff Deleted
base09: "#fab387" # Integers / Constants / Booleans
base0a: "#f9e2af" # Classes / Warnings / Search Background
base0b: "#a6e3a1" # Strings / Success / Diff Inserted
base0c: "#94e2d5" # Support / Regex / Escape Characters
base0d: "#89b4fa" # Functions / Methods / Headings / Accent
base0e: "#cba6f7" # Keywords / Storage / Diff Changed
base0f: "#f2cdcd" # Embedded / Misc
base00: "#110F12" # Background
base01: "#1C1920" # Lighter Background / Status Bars
base02: "#1D1A26" # Selection Background
base03: "#514D63" # Comments / Invisibles
base04: "#8E8AA0" # Dark Foreground / Status Bars
base05: "#C2BED6" # Default Foreground
base06: "#D8D5EA" # Light Foreground
base07: "#EAE7F7" # Light Background
base08: "#E07080" # Variables / Errors / Diff Deleted
base09: "#D49070" # Integers / Constants / Booleans
base0a: "#C4B060" # Classes / Warnings / Search Background
base0b: "#80B880" # Strings / Success / Diff Inserted
base0c: "#70B8C0" # Support / Regex / Escape Characters
base0d: "#9E97F8" # Functions / Methods / Headings / Accent
base0e: "#C090E8" # Keywords / Storage / Diff Changed
base0f: "#D080A0" # Embedded / Misc
+5 -2
View File
@@ -3,16 +3,19 @@ module github.com/anotherhadi/ilovetui
go 1.25.8
require (
charm.land/bubbles/v2 v2.1.0
charm.land/glamour/v2 v2.0.0
charm.land/lipgloss/v2 v2.0.3
gopkg.in/yaml.v3 v3.0.1
)
require (
charm.land/bubbletea/v2 v2.0.2 // indirect
github.com/alecthomas/chroma/v2 v2.14.0 // indirect
github.com/atotto/clipboard v0.1.4 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
github.com/charmbracelet/colorprofile v0.4.3 // indirect
github.com/charmbracelet/ultraviolet v0.0.0-20251205161215-1948445e3318 // indirect
github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8 // indirect
github.com/charmbracelet/x/ansi v0.11.7 // indirect
github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf // indirect
github.com/charmbracelet/x/term v0.2.2 // indirect
@@ -31,7 +34,7 @@ require (
github.com/yuin/goldmark v1.7.8 // indirect
github.com/yuin/goldmark-emoji v1.0.5 // indirect
golang.org/x/net v0.39.0 // indirect
golang.org/x/sync v0.18.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.43.0 // indirect
golang.org/x/text v0.24.0 // indirect
)
+22 -4
View File
@@ -1,17 +1,33 @@
charm.land/bubbles/v2 v2.1.0 h1:YSnNh5cPYlYjPxRrzs5VEn3vwhtEn3jVGRBT3M7/I0g=
charm.land/bubbles/v2 v2.1.0/go.mod h1:l97h4hym2hvWBVfmJDtrEHHCtkIKeTEb3TTJ4ZOB3wY=
charm.land/bubbletea/v2 v2.0.2 h1:4CRtRnuZOdFDTWSff9r8QFt/9+z6Emubz3aDMnf/dx0=
charm.land/bubbletea/v2 v2.0.2/go.mod h1:3LRff2U4WIYXy7MTxfbAQ+AdfM3D8Xuvz2wbsOD9OHQ=
charm.land/glamour/v2 v2.0.0 h1:IDBoqLEy7Hdpb9VOXN+khLP/XSxtJy1VsHuW/yF87+U=
charm.land/glamour/v2 v2.0.0/go.mod h1:kjq9WB0s8vuUYZNYey2jp4Lgd9f4cKdzAw88FZtpj/w=
charm.land/lipgloss/v2 v2.0.3 h1:yM2zJ4Cf5Y51b7RHIwioil4ApI/aypFXXVHSwlM6RzU=
charm.land/lipgloss/v2 v2.0.3/go.mod h1:7myLU9iG/3xluAWzpY/fSxYYHCgoKTie7laxk6ATwXA=
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
github.com/alecthomas/assert/v2 v2.7.0 h1:QtqSACNS3tF7oasA8CU6A6sXZSBDqnm7RfpLl9bZqbE=
github.com/alecthomas/assert/v2 v2.7.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
github.com/alecthomas/chroma/v2 v2.14.0 h1:R3+wzpnUArGcQz7fCETQBzO5n9IMNi13iIs46aU4V9E=
github.com/alecthomas/chroma/v2 v2.14.0/go.mod h1:QolEbTfmUHIMVpBqxeDnNBj2uoeI4EbYP4i6n68SG4I=
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/aymanbagabas/go-udiff v0.4.1 h1:OEIrQ8maEeDBXQDoGCbbTTXYJMYRCRO1fnodZ12Gv5o=
github.com/aymanbagabas/go-udiff v0.4.1/go.mod h1:0L9PGwj20lrtmEMeyw4WKJ/TMyDtvAoK9bf2u/mNo3w=
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
github.com/charmbracelet/colorprofile v0.4.3 h1:QPa1IWkYI+AOB+fE+mg/5/4HRMZcaXex9t5KX76i20Q=
github.com/charmbracelet/colorprofile v0.4.3/go.mod h1:/zT4BhpD5aGFpqQQqw7a+VtHCzu+zrQtt1zhMt9mR4Q=
github.com/charmbracelet/ultraviolet v0.0.0-20251205161215-1948445e3318 h1:OqDqxQZliC7C8adA7KjelW3OjtAxREfeHkNcd66wpeI=
github.com/charmbracelet/ultraviolet v0.0.0-20251205161215-1948445e3318/go.mod h1:Y6kE2GzHfkyQQVCSL9r2hwokSrIlHGzZG+71+wDYSZI=
github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8 h1:eyFRbAmexyt43hVfeyBofiGSEmJ7krjLOYt/9CF5NKA=
github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8/go.mod h1:SQpCTRNBtzJkwku5ye4S3HEuthAlGy2n9VXZnWkEW98=
github.com/charmbracelet/x/ansi v0.11.7 h1:kzv1kJvjg2S3r9KHo8hDdHFQLEqn4RBCb39dAYC84jI=
github.com/charmbracelet/x/ansi v0.11.7/go.mod h1:9qGpnAVYz+8ACONkZBUWPtL7lulP9No6p1epAihUZwQ=
github.com/charmbracelet/x/exp/golden v0.0.0-20250806222409-83e3a29d542f h1:pk6gmGpCE7F3FcjaOEKYriCvpmIN4+6OS/RD0vm4uIA=
github.com/charmbracelet/x/exp/golden v0.0.0-20250806222409-83e3a29d542f/go.mod h1:IfZAMTHB6XkZSeXUqriemErjAWCCzT0LwjKFYCZyw0I=
github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf h1:rLG0Yb6MQSDKdB52aGX55JT1oi0P0Kuaj7wi1bLUpnI=
github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf/go.mod h1:B3UgsnsBZS/eX42BlaNiJkD1pPOUa+oF1IYC6Yd2CEU=
github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk=
@@ -28,6 +44,8 @@ github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxK
github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/lucasb-eyer/go-colorful v1.4.0 h1:UtrWVfLdarDgc44HcS7pYloGHJUjHV/4FwW4TvVgFr4=
github.com/lucasb-eyer/go-colorful v1.4.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-runewidth v0.0.23 h1:7ykA0T0jkPpzSvMS5i9uoNn2Xy3R383f9HDx3RybWcw=
@@ -49,8 +67,8 @@ golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=