-
Notifications
You must be signed in to change notification settings - Fork 0
/
theme.go
77 lines (66 loc) · 1.66 KB
/
theme.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// Content managed by Project Forge, see [projectforge.md] for details.
package theme
import (
"io"
"strings"
"golang.org/x/exp/slices"
"admini.dev/admini/app/util"
)
type Theme struct {
Key string `json:"-"`
Light *Colors `json:"light"`
Dark *Colors `json:"dark"`
css string
}
func (t *Theme) CSS(indent int) string {
if t.css != "" {
return t.css
}
sb := &strings.Builder{}
sb.WriteString("/* theme: " + t.Key + " */\n")
sb.WriteString(t.Light.CSS(":root", indent))
sb.WriteString(t.Light.CSS(".mode-light", indent))
sb.WriteString(t.Dark.CSS(".mode-dark", indent))
addLine(sb, "", indent)
addLine(sb, "@media (prefers-color-scheme: dark) {", indent)
sb.WriteString(t.Dark.CSS(":root", indent+1))
sb.WriteString(t.Light.CSS(".mode-light", indent+1))
sb.WriteString(t.Dark.CSS(".mode-dark", indent+1))
addLine(sb, "}", indent)
t.css = sb.String()
return t.css
}
func (t *Theme) Clone(key string) *Theme {
return &Theme{Key: key, Light: t.Light.Clone(), Dark: t.Dark.Clone()}
}
func (t *Theme) Equals(x *Theme) bool {
return t.Light.Equals(x.Light) && t.Dark.Equals(x.Dark)
}
type Themes []*Theme
func (t Themes) Sort() {
slices.SortFunc(t, func(l *Theme, r *Theme) bool {
if l.Key == ThemeDefault.Key {
return true
}
if r.Key == ThemeDefault.Key {
return false
}
return l.Key < r.Key
})
}
func (t Themes) Replace(n *Theme) Themes {
for idx, o := range t {
if o.Key == n.Key {
t[idx] = n
return t
}
}
ret := append(Themes{}, t...)
ret = append(ret, n)
ret.Sort()
return ret
}
func addLine(sb io.StringWriter, s string, indent int) {
indention := util.StringRepeat(" ", indent)
_, _ = sb.WriteString(indention + s + "\n")
}