Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions modules/svg/svg.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"html/template"
"path"
"sort"
"strings"
"sync"

Expand Down Expand Up @@ -78,6 +79,16 @@ func MockIcon(icon string) func() {
}
}

// DiscoveredIconNames returns the sorted list of all discovered SVG icon names
func DiscoveredIconNames() []string {
names := make([]string, 0, len(svgIcons))
for name := range svgIcons {
names = append(names, name)
}
sort.Strings(names)
return names
}

// RenderHTML renders icons - arguments icon name (string), size (int), class (string)
func RenderHTML(icon string, others ...any) template.HTML {
result, _ := renderHTML(icon, others...)
Expand Down
18 changes: 18 additions & 0 deletions routers/web/devtest/devtest.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/badge"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/svg"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/context"
Expand Down Expand Up @@ -180,6 +181,21 @@ func prepareMockDataRelativeTime(ctx *context.Context) {
ctx.Data["TimeFuture1y"] = now.Add(366 * 24 * time.Hour)
}

func prepareMockDataIconGallery(ctx *context.Context) {
allNames := svg.DiscoveredIconNames()
grouped := map[string][]string{}
for _, name := range allNames {
prefix := "other"
if before, _, ok := strings.Cut(name, "-"); ok {
prefix = before
}
grouped[prefix] = append(grouped[prefix], name)
}
ctx.Data["IconGroups"] = grouped
ctx.Data["IconGroupOrder"] = []string{"octicon", "gitea", "fontawesome", "material", "other"}
ctx.Data["IconCount"] = len(allNames)
}

func prepareMockData(ctx *context.Context) {
switch ctx.Req.URL.Path {
case "/devtest/gitea-ui":
Expand All @@ -190,6 +206,8 @@ func prepareMockData(ctx *context.Context) {
prepareMockDataBadgeActionsSvg(ctx)
case "/devtest/relative-time":
prepareMockDataRelativeTime(ctx)
case "/devtest/icon-gallery":
prepareMockDataIconGallery(ctx)
}
}

Expand Down
45 changes: 45 additions & 0 deletions templates/devtest/icon-gallery.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{{template "devtest/devtest-header"}}
<div class="page-content devtest ui container">
<h1>Icon Gallery</h1>
<p>All <strong>{{.IconCount}}</strong> SVG icons available in templates.</p>
<p>
<input id="icon-search" type="text" placeholder="Filter icons..." class="ui input" style="width: 300px">
<label class="gt-checkbox tw-ml-4"><input id="icon-size-toggle" type="checkbox"> Large (24px)</label>
</p>

<script>
document.addEventListener('DOMContentLoaded', () => {
const search = document.getElementById('icon-search');
const sizeToggle = document.getElementById('icon-size-toggle');
search.addEventListener('input', () => {
const q = search.value.toLowerCase();
for (const card of document.querySelectorAll('.icon-card')) {
card.style.display = card.getAttribute('data-name').includes(q) ? '' : 'none';
}
});
sizeToggle.addEventListener('change', () => {
const size = sizeToggle.checked ? '24' : '16';
for (const icon of document.querySelectorAll('.icon-card svg')) {
icon.setAttribute('width', size);
icon.setAttribute('height', size);
}
});
});
</script>

{{range $prefix := .IconGroupOrder}}
{{$icons := index $.IconGroups $prefix}}
{{if $icons}}
<h2 id="group-{{$prefix}}">{{$prefix}} <span class="ui grey label">{{len $icons}}</span></h2>
<div class="tw-flex tw-flex-wrap tw-gap-2 tw-mb-4">
{{range $name := $icons}}
<div class="icon-card tw-flex tw-flex-col tw-items-center tw-gap-1 tw-p-2 tw-border tw-border-secondary tw-rounded" style="width: 120px" data-name="{{$name}}" title="{{$name}}">
<div class="tw-flex tw-items-center tw-justify-center" style="height: 32px">{{svg $name 16}}</div>
<code class="gt-ellipsis" style="max-width: 108px; font-size: 10px">{{$name}}</code>
</div>
{{end}}
</div>
{{end}}
{{end}}
</div>
{{template "devtest/devtest-footer"}}