prime8dev

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

commit b12defe0b9080a02a6dadce99d0253727a25e7aa
parent 492e5ced59d40a6bbd78c10114506422ba43a812
Author: Damian Myrda <damian@prime8.dev>
Date:   Wed, 21 Oct 2026 02:51:16 +0000

feat: dwm-style tab bar (web + tui)

Diffstat:
Minternal/tui/styles.go | 2+-
Minternal/tui/view.go | 4++--
Minternal/web/styles/header.css | 29+++++++++++++++++------------
Minternal/web/templates/partials/header.gohtml | 2+-
4 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/internal/tui/styles.go b/internal/tui/styles.go @@ -46,7 +46,7 @@ var ( promptCmdStyle = lipgloss.NewStyle().Foreground(colorFg) selectedRowStyle = lipgloss.NewStyle().Foreground(colorAccent).Bold(true) - tabActiveStyle = selectedRowStyle + tabActiveStyle = lipgloss.NewStyle().Background(colorAccent).Foreground(lipgloss.Color("0")).Bold(true) rowStyle = lipgloss.NewStyle().Foreground(colorFg) dimStyle = lipgloss.NewStyle().Foreground(colorDim) titleStyle = lipgloss.NewStyle().Foreground(colorAccent).Bold(true) diff --git a/internal/tui/view.go b/internal/tui/view.go @@ -133,7 +133,7 @@ func (m portfolioModel) renderBoot(width int, height int) string { func (m portfolioModel) renderHeader(width int) string { parts := make([]string, 0, len(tabLabels)) for i, label := range tabLabels { - t := fmt.Sprintf("[%d] %s", i+1, label) + t := fmt.Sprintf(" %d %s ", i+1, label) if i == m.activeTab { t = tabActiveStyle.Render(t) } else { @@ -142,7 +142,7 @@ func (m portfolioModel) renderHeader(width int) string { parts = append(parts, t) } - left := strings.Join(parts, " ") + left := strings.Join(parts, "") right := "" if width >= 96 { right = dimStyle.Render("▲ ▼ ◀ ▶ navigate · tab cycle · ? help") diff --git a/internal/web/styles/header.css b/internal/web/styles/header.css @@ -18,16 +18,19 @@ .tab-nav { display: flex; - align-items: center; - gap: 4px; + align-items: stretch; + align-self: stretch; + margin-left: -12px; } +/* dwm-style tags: flush cells, the selected one filled */ .tab { - padding: 6px 12px; + display: flex; + align-items: center; + padding: 0 10px; color: var(--fg-dim); cursor: pointer; - border-bottom: 2px solid transparent; - transition: color 0.15s, border-color 0.15s; + text-decoration: none; } .tab:hover { @@ -35,8 +38,9 @@ } .tab.active { - color: var(--accent); - border-bottom-color: var(--accent); + background: var(--accent); + color: var(--bg); + font-weight: bold; } .tab-spacer { @@ -82,18 +86,19 @@ flex-wrap: wrap; height: auto; min-height: 36px; - padding: 8px 12px; - gap: 8px; + padding: 0; + gap: 0; } .tab-nav { width: 100%; - justify-content: space-between; - gap: 0; + margin-left: 0; } .tab { - padding: 6px 8px; + justify-content: center; + min-height: 36px; + padding: 0 8px; font-size: var(--fs-12); flex: 1; text-align: center; diff --git a/internal/web/templates/partials/header.gohtml b/internal/web/templates/partials/header.gohtml @@ -3,7 +3,7 @@ <nav class="tab-nav" aria-label="main navigation" preload="preload:init" preload-images="true"> {{range .Tabs}} <a href="{{tabPath .ID}}" class="tab{{if eq .ID $.ActiveTab}} active{{end}}" data-tab="{{.ID}}" data-label="{{.ID}}" hx-get="{{tabPath .ID}}" hx-target="#content" hx-push-url="true"> - <span class="tab-num">[{{.Num}}] </span>{{.ID}} + <span class="tab-num">{{.Num}}&nbsp;</span>{{.ID}} </a> {{end}} </nav>