mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-13 11:05:46 +02:00
Merge 8f6f30c1cedff3aca172c2f9c6fcb4d605741847 into ce089f498bce32305b2d9e8c6adfd8cb7c82f88f
This commit is contained in:
commit
0d7d2a5fc9
@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"path"
|
"path"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@ -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)
|
// RenderHTML renders icons - arguments icon name (string), size (int), class (string)
|
||||||
func RenderHTML(icon string, others ...any) template.HTML {
|
func RenderHTML(icon string, others ...any) template.HTML {
|
||||||
result, _ := renderHTML(icon, others...)
|
result, _ := renderHTML(icon, others...)
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/badge"
|
"code.gitea.io/gitea/modules/badge"
|
||||||
"code.gitea.io/gitea/modules/charset"
|
"code.gitea.io/gitea/modules/charset"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
|
"code.gitea.io/gitea/modules/svg"
|
||||||
"code.gitea.io/gitea/modules/indexer/code"
|
"code.gitea.io/gitea/modules/indexer/code"
|
||||||
"code.gitea.io/gitea/modules/templates"
|
"code.gitea.io/gitea/modules/templates"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
@ -182,6 +183,21 @@ func prepareMockDataRelativeTime(ctx *context.Context) {
|
|||||||
ctx.Data["TimeFuture1y"] = now.Add(366 * 24 * time.Hour)
|
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) {
|
func prepareMockData(ctx *context.Context) {
|
||||||
switch ctx.Req.URL.Path {
|
switch ctx.Req.URL.Path {
|
||||||
case "/devtest/gitea-ui":
|
case "/devtest/gitea-ui":
|
||||||
@ -192,6 +208,8 @@ func prepareMockData(ctx *context.Context) {
|
|||||||
prepareMockDataBadgeActionsSvg(ctx)
|
prepareMockDataBadgeActionsSvg(ctx)
|
||||||
case "/devtest/relative-time":
|
case "/devtest/relative-time":
|
||||||
prepareMockDataRelativeTime(ctx)
|
prepareMockDataRelativeTime(ctx)
|
||||||
|
case "/devtest/icon-gallery":
|
||||||
|
prepareMockDataIconGallery(ctx)
|
||||||
case "/devtest/toast-and-message":
|
case "/devtest/toast-and-message":
|
||||||
prepareMockDataToastAndMessage(ctx)
|
prepareMockDataToastAndMessage(ctx)
|
||||||
case "/devtest/unicode-escape":
|
case "/devtest/unicode-escape":
|
||||||
|
|||||||
25
templates/devtest/icon-gallery.tmpl
Normal file
25
templates/devtest/icon-gallery.tmpl
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{{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 icon-gallery-search">
|
||||||
|
<label class="gt-checkbox tw-ml-4"><input id="icon-size-toggle" type="checkbox"> Large (24px)</label>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{{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 icon-gallery-card tw-flex tw-flex-col tw-items-center tw-gap-1 tw-p-2 tw-border tw-border-secondary tw-rounded" data-name="{{$name}}" title="{{$name}}">
|
||||||
|
<div class="icon-gallery-preview tw-flex tw-items-center tw-justify-center">{{svg $name 16}}</div>
|
||||||
|
<code class="gt-ellipsis icon-gallery-name">{{$name}}</code>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
{{template "devtest/devtest-footer"}}
|
||||||
@ -18,3 +18,20 @@ h1, h2 {
|
|||||||
.fetch-action-demo-forms .form-fetch-action {
|
.fetch-action-demo-forms .form-fetch-action {
|
||||||
border: 1px red dashed; /* show the border for demo purpose */
|
border: 1px red dashed; /* show the border for demo purpose */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-gallery-search {
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-gallery-card {
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-gallery-preview {
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-gallery-name {
|
||||||
|
max-width: 108px;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|||||||
@ -9,6 +9,25 @@ import {showGlobalErrorMessage} from './errors.ts';
|
|||||||
type LevelMap = Record<string, (message: string) => Toast | null>;
|
type LevelMap = Record<string, (message: string) => Toast | null>;
|
||||||
|
|
||||||
function initDevtestPage() {
|
function initDevtestPage() {
|
||||||
|
const iconSearch = document.querySelector<HTMLInputElement>('#icon-search');
|
||||||
|
const iconSizeToggle = document.querySelector<HTMLInputElement>('#icon-size-toggle');
|
||||||
|
if (iconSearch && iconSizeToggle) {
|
||||||
|
iconSearch.addEventListener('input', () => {
|
||||||
|
const query = iconSearch.value.toLowerCase();
|
||||||
|
for (const card of document.querySelectorAll<HTMLElement>('.icon-card')) {
|
||||||
|
card.style.display = card.getAttribute('data-name')!.includes(query) ? '' : 'none';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
iconSizeToggle.addEventListener('change', () => {
|
||||||
|
const size = iconSizeToggle.checked ? '24' : '16';
|
||||||
|
for (const icon of document.querySelectorAll<SVGElement>('.icon-card svg')) {
|
||||||
|
icon.setAttribute('width', size);
|
||||||
|
icon.setAttribute('height', size);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const toastButtons = document.querySelectorAll('.toast-test-button');
|
const toastButtons = document.querySelectorAll('.toast-test-button');
|
||||||
if (toastButtons.length) {
|
if (toastButtons.length) {
|
||||||
const levelMap: LevelMap = {info: showInfoToast, warning: showWarningToast, error: showErrorToast};
|
const levelMap: LevelMap = {info: showInfoToast, warning: showWarningToast, error: showErrorToast};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user