mirror of
https://github.com/charmbracelet/lipgloss.git
synced 2024-09-11 14:07:21 +03:00
Finish up example
This commit is contained in:
parent
34d6f0c73b
commit
8a4bf146ce
220
example/main.go
220
example/main.go
@ -11,14 +11,20 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
columnWidth = 30
|
||||
// In real life situations we'd adjust the document to fit the width we've
|
||||
// detected. In the case of this example we're hardcoding the width, and
|
||||
// later using the detected width only to truncate in order to avoid jaggy
|
||||
// wrapping.
|
||||
width = 96
|
||||
|
||||
historyA = "The Romans learned from the Greeks that quinces slowly cooked with honey would “set” when cool. The Apicius gives a recipe for preserving whole quinces, stems and leaves attached, in a bath of honey diluted with defrutum—Roman marmalade. Preserves of quince and lemon appear (along with rose, apple, plum and pear) in the Book of ceremonies of the Byzantine Emperor Constantine VII Porphyrogennetos."
|
||||
historyB = "Medieval quince preserves, which went by the French name cotignac, produced in a clear version and a fruit pulp version, began to lose their medieval seasoning of spices in the 16th century. In the 17th century, La Varenne provided recipes for both thick and clear cotignac."
|
||||
historyC = "In 1524, Henry VIII, King of England, received a “box of marmalade” from Mr. Hull of Exeter. This was probably marmelada, a solid quince paste from Portugal, still made and sold in southern Europe today. It became a favourite treat of Anne Boleyn and her ladies in waiting."
|
||||
columnWidth = 30
|
||||
)
|
||||
|
||||
// Style definitions
|
||||
var (
|
||||
|
||||
// General
|
||||
|
||||
subtle = lipgloss.AdaptiveColor{Light: "#D9DCCF", Dark: "#383838"}
|
||||
accent = lipgloss.AdaptiveColor{Light: "#43BF6D", Dark: "#73F59F"}
|
||||
|
||||
@ -80,13 +86,24 @@ var (
|
||||
SetString("Lip Gloss")
|
||||
|
||||
descStyle = lipgloss.NewStyle().
|
||||
MarginTop(1).
|
||||
MarginTop(1)
|
||||
|
||||
infoStyle = lipgloss.NewStyle().
|
||||
BorderStyle(lipgloss.NormalBorder()).
|
||||
BorderBottom(true).
|
||||
BorderTop(true).
|
||||
BorderForegroundColor(subtle)
|
||||
|
||||
// Dialog
|
||||
|
||||
dialogBoxStyle = lipgloss.NewStyle().
|
||||
Border(lipgloss.RoundedBorder()).
|
||||
BorderForegroundColor(lipgloss.Color("#874BFD")).
|
||||
Padding(1, 0).
|
||||
BorderTop(true).
|
||||
BorderLeft(true).
|
||||
BorderRight(true).
|
||||
BorderBottom(true)
|
||||
|
||||
buttonStyle = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("#FFF7DB")).
|
||||
Background(lipgloss.Color("#888B7E")).
|
||||
@ -104,7 +121,9 @@ var (
|
||||
list = lipgloss.NewStyle().
|
||||
Border(lipgloss.NormalBorder(), false, true, false, false).
|
||||
BorderForegroundColor(subtle).
|
||||
Height(8)
|
||||
MarginRight(2).
|
||||
Height(8).
|
||||
Width(columnWidth + 1)
|
||||
|
||||
listHeader = lipgloss.NewStyle().
|
||||
BorderStyle(lipgloss.NormalBorder()).
|
||||
@ -120,37 +139,58 @@ var (
|
||||
PaddingRight(1).
|
||||
String()
|
||||
|
||||
listDone = lipgloss.NewStyle().
|
||||
listDone = func(s string) string {
|
||||
return checkMark + lipgloss.NewStyle().
|
||||
Strikethrough(true).
|
||||
Foreground(lipgloss.AdaptiveColor{Light: "", Dark: "#696969"}).
|
||||
Render
|
||||
Render(s)
|
||||
}
|
||||
|
||||
// Paragraphs
|
||||
// Paragraphs/History
|
||||
|
||||
historyStyle = lipgloss.NewStyle().
|
||||
Align(lipgloss.Left).
|
||||
Foreground(lipgloss.Color("#7E51D6")).
|
||||
Background(lipgloss.AdaptiveColor{Light: "#888B7E", Dark: "#F6FFFD"}).
|
||||
Foreground(lipgloss.Color("#874BFD")).
|
||||
Background(lipgloss.AdaptiveColor{Light: "#F1F3EA", Dark: "#f1f1f1"}).
|
||||
Margin(1, 3, 0, 0).
|
||||
Padding(1, 2).
|
||||
Height(18).
|
||||
Height(19).
|
||||
Width(columnWidth)
|
||||
|
||||
helloStyle = lipgloss.NewStyle().
|
||||
Border(lipgloss.RoundedBorder()).
|
||||
BorderForegroundColor(lipgloss.Color("#874BFD")).
|
||||
Padding(1, 0).
|
||||
BorderTop(true).
|
||||
BorderLeft(true).
|
||||
BorderRight(true).
|
||||
BorderBottom(true)
|
||||
// Status Bar
|
||||
|
||||
docStyle = lipgloss.NewStyle().Padding(1, 2, 0, 2)
|
||||
statusNugget = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("#FFFDF5")).
|
||||
Padding(0, 1)
|
||||
|
||||
statusBarStyle = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.AdaptiveColor{Light: "#343433", Dark: "#C1C6B2"}).
|
||||
Background(lipgloss.AdaptiveColor{Light: "#D9DCCF", Dark: "#353533"})
|
||||
|
||||
statusStyle = lipgloss.NewStyle().
|
||||
Inherit(statusBarStyle).
|
||||
Foreground(lipgloss.Color("#FFFDF5")).
|
||||
Background(lipgloss.Color("#FF5F87")).
|
||||
Padding(0, 1).
|
||||
MarginRight(1)
|
||||
|
||||
encodingStyle = statusNugget.Copy().
|
||||
Background(lipgloss.Color("#A550DF")).
|
||||
Align(lipgloss.Right)
|
||||
|
||||
statusText = lipgloss.NewStyle().
|
||||
Inherit(statusBarStyle)
|
||||
|
||||
fishCakeStyle = statusNugget.Copy().
|
||||
Background(lipgloss.Color("#6124DF"))
|
||||
|
||||
// Page
|
||||
|
||||
docStyle = lipgloss.NewStyle().Padding(1, 2, 1, 2)
|
||||
)
|
||||
|
||||
func main() {
|
||||
physicalWidth, _, _ := terminal.GetSize(int(os.Stdout.Fd()))
|
||||
width := min(94, max(120, physicalWidth))
|
||||
|
||||
var doc strings.Builder
|
||||
|
||||
@ -164,7 +204,7 @@ func main() {
|
||||
tab.Render("Mascara"),
|
||||
tab.Render("Foundation"),
|
||||
)
|
||||
gap := tabGap.Render(strings.Repeat(" ", max(0, width-lipgloss.Width(row))))
|
||||
gap := tabGap.Render(strings.Repeat(" ", max(0, width-lipgloss.Width(row)-2)))
|
||||
row = lipgloss.JoinHorizontal(lipgloss.Bottom, row, gap)
|
||||
doc.WriteString(row + "\n\n")
|
||||
}
|
||||
@ -185,8 +225,8 @@ func main() {
|
||||
}
|
||||
|
||||
desc := lipgloss.JoinVertical(lipgloss.Left,
|
||||
descStyle.Render("Style Definitions for Terminal-Based Layouts"),
|
||||
"From Charm"+divider+url("https://github.com/charmbracelet/lipgloss"),
|
||||
descStyle.Render("Style Definitions for Nice Terminal Layouts"),
|
||||
infoStyle.Render("From Charm"+divider+url("https://github.com/charmbracelet/lipgloss")),
|
||||
)
|
||||
|
||||
row := lipgloss.JoinHorizontal(lipgloss.Top, title.String(), desc)
|
||||
@ -194,7 +234,6 @@ func main() {
|
||||
}
|
||||
|
||||
// Dialog
|
||||
var dialog string
|
||||
{
|
||||
okButton := activeButtonStyle.Render("Yes")
|
||||
cancelButton := buttonStyle.Render("Maybe")
|
||||
@ -203,48 +242,23 @@ func main() {
|
||||
buttons := lipgloss.JoinHorizontal(lipgloss.Top, okButton, cancelButton)
|
||||
ui := lipgloss.JoinVertical(lipgloss.Center, question, buttons)
|
||||
|
||||
dialog = lipgloss.JoinVertical(lipgloss.Center, question, buttons)
|
||||
dialog := lipgloss.JoinVertical(lipgloss.Center, question, buttons)
|
||||
dialog = lipgloss.Place(width, 9,
|
||||
lipgloss.Center, lipgloss.Center,
|
||||
helloStyle.Render(ui),
|
||||
dialogBoxStyle.Render(ui),
|
||||
lipgloss.WithWhitespaceChars("猫咪"),
|
||||
lipgloss.WithWhitespaceForeground(subtle),
|
||||
)
|
||||
|
||||
doc.WriteString(dialog + "\n\n")
|
||||
}
|
||||
doc.WriteString(dialog + "\n\n")
|
||||
|
||||
// Color grid
|
||||
grid := func() string {
|
||||
x0y0, _ := colorful.Hex("#F25D94")
|
||||
x1y0, _ := colorful.Hex("#EDFF82")
|
||||
x0y1, _ := colorful.Hex("#874BFD")
|
||||
x1y1, _ := colorful.Hex("#14F9D5")
|
||||
|
||||
const xSteps = 10
|
||||
const ySteps = 8
|
||||
|
||||
x0 := make([]colorful.Color, ySteps)
|
||||
for i := range x0 {
|
||||
x0[i] = x0y0.BlendLuv(x0y1, float64(i)/float64(ySteps))
|
||||
}
|
||||
|
||||
x1 := make([]colorful.Color, ySteps)
|
||||
for i := range x1 {
|
||||
x1[i] = x1y0.BlendLuv(x1y1, float64(i)/float64(ySteps))
|
||||
}
|
||||
|
||||
grid := make([][]string, ySteps)
|
||||
for x := 0; x < ySteps; x++ {
|
||||
y0 := x0[x]
|
||||
grid[x] = make([]string, xSteps)
|
||||
for y := 0; y < xSteps; y++ {
|
||||
grid[x][y] = y0.BlendLuv(x1[x], float64(y)/float64(xSteps)).Hex()
|
||||
}
|
||||
}
|
||||
colors := colorGrid(14, 8)
|
||||
|
||||
b := strings.Builder{}
|
||||
for _, x := range grid {
|
||||
for _, x := range colors {
|
||||
for _, y := range x {
|
||||
s := lipgloss.NewStyle().SetString(" ").Background(lipgloss.Color(y))
|
||||
b.WriteString(s.String())
|
||||
@ -255,32 +269,83 @@ func main() {
|
||||
return b.String()
|
||||
}()
|
||||
|
||||
fruits := lipgloss.JoinVertical(lipgloss.Left,
|
||||
listHeader("Citrus Fruits to Try"),
|
||||
checkMark+listDone("Quince"),
|
||||
checkMark+listDone("Yuzu"),
|
||||
listItem("Citron"),
|
||||
listItem("Kumquat"),
|
||||
listItem("Pomelo"),
|
||||
lists := lipgloss.JoinHorizontal(lipgloss.Top,
|
||||
list.Render(
|
||||
lipgloss.JoinVertical(lipgloss.Left,
|
||||
listHeader("Citrus Fruits to Try"),
|
||||
listDone("Quince"),
|
||||
listDone("Yuzu"),
|
||||
listItem("Citron"),
|
||||
listItem("Kumquat"),
|
||||
listItem("Pomelo"),
|
||||
),
|
||||
),
|
||||
list.Copy().Width(columnWidth).Render(
|
||||
lipgloss.JoinVertical(lipgloss.Left,
|
||||
listHeader("Actual Lip Gloss Vendors"),
|
||||
listItem("Glossier"),
|
||||
listItem("Claire‘s Boutique"),
|
||||
listDone("Nyx"),
|
||||
listItem("Mac"),
|
||||
listDone("Milk"),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
doc.WriteString(lipgloss.JoinHorizontal(lipgloss.Top, fruits, grid))
|
||||
doc.WriteString(lipgloss.JoinHorizontal(lipgloss.Top, lists, grid))
|
||||
|
||||
doc.WriteString(lipgloss.JoinHorizontal(
|
||||
lipgloss.Top,
|
||||
historyStyle.Copy().Align(lipgloss.Right).Render(historyA),
|
||||
historyStyle.Copy().Align(lipgloss.Center).Render(historyB),
|
||||
historyStyle.Copy().MarginRight(0).Render(historyC),
|
||||
))
|
||||
doc.WriteString("\n\n")
|
||||
// Marmalade history
|
||||
{
|
||||
const (
|
||||
historyA = "The Romans learned from the Greeks that quinces slowly cooked with honey would “set” when cool. The Apicius gives a recipe for preserving whole quinces, stems and leaves attached, in a bath of honey diluted with defrutum: Roman marmalade. Preserves of quince and lemon appear (along with rose, apple, plum and pear) in the Book of ceremonies of the Byzantine Emperor Constantine VII Porphyrogennetos."
|
||||
historyB = "Medieval quince preserves, which went by the French name cotignac, produced in a clear version and a fruit pulp version, began to lose their medieval seasoning of spices in the 16th century. In the 17th century, La Varenne provided recipes for both thick and clear cotignac."
|
||||
historyC = "In 1524, Henry VIII, King of England, received a “box of marmalade” from Mr. Hull of Exeter. This was probably marmelada, a solid quince paste from Portugal, still made and sold in southern Europe today. It became a favourite treat of Anne Boleyn and her ladies in waiting."
|
||||
)
|
||||
|
||||
fmt.Println(docStyle.MaxWidth(physicalWidth).Render(doc.String()))
|
||||
doc.WriteString(lipgloss.JoinHorizontal(
|
||||
lipgloss.Top,
|
||||
historyStyle.Copy().Align(lipgloss.Right).Render(historyA),
|
||||
historyStyle.Copy().Align(lipgloss.Center).Render(historyB),
|
||||
historyStyle.Copy().MarginRight(0).Render(historyC),
|
||||
))
|
||||
|
||||
doc.WriteString("\n\n")
|
||||
}
|
||||
|
||||
// Status bar
|
||||
{
|
||||
w := lipgloss.Width
|
||||
|
||||
statusKey := statusStyle.Render("STATUS")
|
||||
encoding := encodingStyle.
|
||||
Render("UTF-8")
|
||||
fishCake := fishCakeStyle.Render("🍥 Fish Cake")
|
||||
statusVal := statusText.Copy().
|
||||
Width(width - w(statusKey) - w(encoding) - w(fishCake)).
|
||||
Render("Ravishing")
|
||||
|
||||
bar := lipgloss.JoinHorizontal(lipgloss.Top,
|
||||
statusKey,
|
||||
statusVal,
|
||||
encoding,
|
||||
fishCake,
|
||||
)
|
||||
|
||||
doc.WriteString(statusBarStyle.Width(width).Render(bar))
|
||||
}
|
||||
|
||||
if physicalWidth > 0 {
|
||||
docStyle = docStyle.MaxWidth(physicalWidth)
|
||||
}
|
||||
|
||||
// Print it
|
||||
fmt.Println(docStyle.Render(doc.String()))
|
||||
}
|
||||
|
||||
func colorGrid(xSteps, ySteps int) [][]string {
|
||||
x0y0, _ := colorful.Hex("#F25D94")
|
||||
x1y0, _ := colorful.Hex("#EDFF82")
|
||||
x0y1, _ := colorful.Hex("#874BFD")
|
||||
x0y1, _ := colorful.Hex("#643AFF")
|
||||
x1y1, _ := colorful.Hex("#14F9D5")
|
||||
|
||||
x0 := make([]colorful.Color, ySteps)
|
||||
@ -305,13 +370,6 @@ func colorGrid(xSteps, ySteps int) [][]string {
|
||||
return grid
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
|
Loading…
Reference in New Issue
Block a user