Lip Gloss
GitHub概要
charmbracelet/lipgloss
Style definitions for nice terminal layouts 👄
スター9,305
ウォッチ35
フォーク259
作成日:2021年3月1日
言語:Go
ライセンス:MIT License
トピックス
cligogolanghacktoberfestlayoutstyletui
スター履歴
データ取得日時: 2025/7/25 11:09
Lip Gloss
Lip Glossは、Charmbraceletが開発したターミナルアプリケーション向けのスタイリングライブラリです。CSSに似た直感的なAPIで、ターミナルに美しいレイアウトとスタイルを適用できます。Bubble TeaやCharmエコシステムの一部として、多くのプロジェクトで使用されています。
特徴
CSSライクなスタイリング
- プロパティ: 色、パディング、マージン、ボーダー
- レイアウト: Flexbox風の配置、位置調整
- テキスト装飾: 太字、斜体、下線、取り消し線
- アニメーション: 点滅、フェード
高度な機能
- アダプティブカラー: ターミナルの能力に応じた色調整
- グラデーション: グラデーション背景
- レスポンシブ: ターミナルサイズに応じた調整
- スタイル継承: CSSのようなスタイル継承
ユーティリティ
- テーブルレンダリング: 美しいテーブル作成
- ジョイン機能: 要素の結合
- 折り返しと省略: テキスト処理
- カスタムレンダラー: 拡張可能な描画システム
パフォーマンス
- ゼロアロケーション: スタイルの再利用
- 効率的なレンダリング: 最小限のANSIコード
- キャッシュ: スタイル計算のキャッシュ
- 軽量: 最小限の依存関係
基本的な使用方法
インストール
go get github.com/charmbracelet/lipgloss
Hello World
package main
import (
"fmt"
"github.com/charmbracelet/lipgloss"
)
func main() {
// 基本的なスタイル
style := lipgloss.NewStyle().
Bold(true).
Foreground(lipgloss.Color("#FAFAFA")).
Background(lipgloss.Color("#7D56F4")).
PaddingTop(2).
PaddingLeft(4).
Width(22)
fmt.Println(style.Render("Hello, Lip Gloss!"))
}
スタイルの組み合わせ
package main
import (
"fmt"
"github.com/charmbracelet/lipgloss"
)
func main() {
// ベーススタイル
var baseStyle = lipgloss.NewStyle().
PaddingLeft(1).
PaddingRight(1)
// タイトルスタイル
titleStyle := baseStyle.Copy().
Bold(true).
Foreground(lipgloss.Color("#FF00FF")).
MarginTop(1).
MarginBottom(1)
// コンテンツスタイル
contentStyle := baseStyle.Copy().
Foreground(lipgloss.Color("#CCCCCC")).
Padding(1, 2)
// ボーダースタイル
borderStyle := lipgloss.NewStyle().
Border(lipgloss.RoundedBorder()).
BorderForeground(lipgloss.Color("62")).
Padding(1, 2)
// レンダリング
title := titleStyle.Render("ウェルカム")
content := contentStyle.Render("これはLip Glossでスタイルされた\nコンテンツです。")
// 結合
output := lipgloss.JoinVertical(lipgloss.Left, title, content)
fmt.Println(borderStyle.Render(output))
}
レイアウトと位置調整
package main
import (
"fmt"
"github.com/charmbracelet/lipgloss"
)
func main() {
// ターミナルサイズの取得
width := 80
height := 24
// ヘッダー
headerStyle := lipgloss.NewStyle().
Background(lipgloss.Color("62")).
Foreground(lipgloss.Color("230")).
Bold(true).
Align(lipgloss.Center).
Width(width).
Padding(0, 1)
header := headerStyle.Render("🌈 My Application")
// サイドバー
sidebarStyle := lipgloss.NewStyle().
Border(lipgloss.NormalBorder(), false, true, false, false).
BorderForeground(lipgloss.Color("240")).
Width(20).
Height(height - 4).
Padding(1)
sidebar := sidebarStyle.Render("Menu\n\n• Home\n• About\n• Contact")
// メインコンテンツ
mainStyle := lipgloss.NewStyle().
Width(width - 22).
Height(height - 4).
Padding(2).
Align(lipgloss.Center, lipgloss.Center)
main := mainStyle.Render("メインコンテンツエリア")
// フッター
footerStyle := lipgloss.NewStyle().
Background(lipgloss.Color("235")).
Foreground(lipgloss.Color("241")).
Align(lipgloss.Center).
Width(width)
footer := footerStyle.Render("Press q to quit")
// レイアウトの組み立て
body := lipgloss.JoinHorizontal(lipgloss.Top, sidebar, main)
doc := lipgloss.JoinVertical(lipgloss.Left, header, body, footer)
fmt.Println(doc)
}
テーブルの作成
package main
import (
"fmt"
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/lipgloss/table"
)
func main() {
// テーブルデータ
rows := [][]string{
{"ID", "Name", "Age", "City"},
{"1", "Alice", "30", "New York"},
{"2", "Bob", "25", "Los Angeles"},
{"3", "Charlie", "35", "Chicago"},
}
// テーブル作成
t := table.New().
Border(lipgloss.NormalBorder()).
BorderStyle(lipgloss.NewStyle().Foreground(lipgloss.Color("99")))
// ヘッダースタイル
headerStyle := lipgloss.NewStyle().
Bold(true).
Foreground(lipgloss.Color("230")).
Background(lipgloss.Color("63")).
Align(lipgloss.Center)
// 偶数行スタイル
evenRowStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("245"))
// 奇数行スタイル
oddRowStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("250"))
// テーブルにスタイル適用
t.Headers(rows[0]...).
StyleFunc(func(row, col int) lipgloss.Style {
if row == 0 {
return headerStyle
}
if row%2 == 0 {
return evenRowStyle
}
return oddRowStyle
})
// データ追加
for _, row := range rows[1:] {
t.Row(row...)
}
fmt.Println(t)
}
グラデーションとアニメーション
package main
import (
"fmt"
"github.com/charmbracelet/lipgloss"
)
func main() {
// グラデーションスタイル
gradientStyle := lipgloss.NewStyle().
Bold(true).
Foreground(lipgloss.Color("#FF00FF")).
Background(lipgloss.Color("#FFD700")).
Width(40).
Align(lipgloss.Center).
Margin(1)
// 点滅スタイル
blinkStyle := lipgloss.NewStyle().
Blink(true).
Foreground(lipgloss.Color("#FF0000")).
Bold(true)
// 下線スタイル
underlineStyle := lipgloss.NewStyle().
Underline(true).
UnderlineSpaces(true).
Foreground(lipgloss.Color("#00FF00"))
// リバーススタイル
reverseStyle := lipgloss.NewStyle().
Reverse(true).
Padding(0, 2)
fmt.Println(gradientStyle.Render("グラデーション背景"))
fmt.Println(blinkStyle.Render("点滅テキスト"))
fmt.Println(underlineStyle.Render("下線付きテキスト"))
fmt.Println(reverseStyle.Render("反転テキスト"))
}
高度な機能
アダプティブカラー
// ターミナルの能力に応じた色選択
adaptiveColor := lipgloss.AdaptiveColor{
Light: "#000000",
Dark: "#FFFFFF",
}
style := lipgloss.NewStyle().
Foreground(adaptiveColor)
カスタムボーダー
// カスタムボーダーの定義
customBorder := lipgloss.Border{
Top: "━",
Bottom: "━",
Left: "┃",
Right: "┃",
TopLeft: "┏",
TopRight: "┓",
BottomLeft: "┗",
BottomRight: "┛",
}
style := lipgloss.NewStyle().
Border(customBorder).
BorderForeground(lipgloss.Color("63"))
レスポンシブデザイン
func responsiveLayout(width int) string {
var style lipgloss.Style
if width < 40 {
// モバイルレイアウト
style = lipgloss.NewStyle().
Width(width).
Padding(1)
} else if width < 80 {
// タブレットレイアウト
style = lipgloss.NewStyle().
Width(width).
Padding(2).
Margin(1)
} else {
// デスクトップレイアウト
style = lipgloss.NewStyle().
Width(width / 2).
Padding(3).
Margin(2).
Border(lipgloss.NormalBorder())
}
return style.Render("コンテンツ")
}
コンポーネント化
// ボタンコンポーネント
func Button(label string, primary bool) string {
style := lipgloss.NewStyle().
Padding(0, 3).
Bold(true).
Border(lipgloss.RoundedBorder())
if primary {
style = style.
Foreground(lipgloss.Color("#FFFFFF")).
Background(lipgloss.Color("#7D56F4")).
BorderForeground(lipgloss.Color("#7D56F4"))
} else {
style = style.
Foreground(lipgloss.Color("#7D56F4")).
BorderForeground(lipgloss.Color("#7D56F4"))
}
return style.Render(label)
}
// カードコンポーネント
func Card(title, content string) string {
titleStyle := lipgloss.NewStyle().
Bold(true).
Foreground(lipgloss.Color("#FF00FF")).
MarginBottom(1)
contentStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("#CCCCCC"))
cardStyle := lipgloss.NewStyle().
Border(lipgloss.RoundedBorder()).
BorderForeground(lipgloss.Color("#666666")).
Padding(1, 2).
Width(40)
card := lipgloss.JoinVertical(
lipgloss.Left,
titleStyle.Render(title),
contentStyle.Render(content),
)
return cardStyle.Render(card)
}
エコシステム
Charmbraceletツール
- Bubble Tea: TUIフレームワーク
- Bubbles: TUIコンポーネント集
- Glamour: Markdownレンダラー
- Glow: Markdownビューア
採用例
- gh: GitHub CLI
- lazygit: Git TUI
- soft-serve: Gitサーバー
- mods: AIチャットCLI
利点
- 直感的: CSSライクなAPI
- 美しい: プロフェッショナルな見た目
- 柔軟: コンポーネント化が容易
- 効率的: パフォーマンスを重視
- 活発: Charmbraceletによる継続的な開発
制約事項
- スタイリング専用: インタラクティブ機能はなし
- フレームワーク依存: 単体でTUIアプリは作れない
- レイアウト制限: 複雑なレイアウトは手動計算
他のライブラリとの比較
項目 | Lip Gloss | tview | termui |
---|---|---|---|
用途 | スタイリング | 完全TUI | ダッシュボード |
API | CSSライク | ウィジェット | ウィジェット |
学習コスト | 低 | 低 | 中 |
柔軟性 | 非常に高 | 中 | 低 |
エコシステム | Charmbracelet | 独立 | 独立 |
まとめ
Lip Glossは、ターミナルアプリケーションに美しいスタイルを適用するための優れたライブラリです。CSSに似た直感的なAPIにより、開発者は簡単にプロフェッショナルな見た目のターミナルUIを作成できます。単体では完全なTUIアプリケーションを構築できませんが、Bubble Teaと組み合わせることで、最もモダンで美しいTUIアプリケーションを実現できます。