Extract inline icons to SVG iconset (#1262)

This commit is contained in:
Sascha Ißbrücker
2026-01-04 09:39:42 +01:00
committed by GitHub
parent 06048ee26f
commit 4d82fefa4e
15 changed files with 158 additions and 175 deletions

112
bookmarks/static/icons.svg Normal file
View File

@@ -0,0 +1,112 @@
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="plus"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
</symbol>
<symbol id="close"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M18 6l-12 12"></path>
<path d="M6 6l12 12"></path>
</symbol>
<symbol id="menu"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M4 6l16 0"/>
<path d="M4 12l16 0"/>
<path d="M4 18l16 0"/>
</symbol>
<symbol id="preferences" viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M4 10a2 2 0 1 0 4 0a2 2 0 0 0 -4 0"></path>
<path d="M6 4v4"></path>
<path d="M6 12v8"></path>
<path d="M10 16a2 2 0 1 0 4 0a2 2 0 0 0 -4 0"></path>
<path d="M12 4v10"></path>
<path d="M12 18v2"></path>
<path d="M16 7a2 2 0 1 0 4 0a2 2 0 0 0 -4 0"></path>
<path d="M18 4v1"></path>
<path d="M18 9v11"></path>
</symbol>
<symbol id="sort"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M3 9l4 -4l4 4m-4 -4v14"/>
<path d="M21 15l-4 4l-4 -4m4 4v-14"/>
</symbol>
<symbol id="bulk-edit"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"/>
<path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z"/>
<path d="M16 5l3 3"/>
</symbol>
<symbol id="unread" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M3 19a9 9 0 0 1 9 0a9 9 0 0 1 9 0"></path>
<path d="M3 6a9 9 0 0 1 9 0a9 9 0 0 1 9 0"></path>
<path d="M3 6l0 13"></path>
<path d="M12 6l0 13"></path>
<path d="M21 6l0 13"></path>
</symbol>
<symbol id="share" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M6 12m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0"></path>
<path d="M18 6m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0"></path>
<path d="M18 18m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0"></path>
<path d="M8.7 10.7l6.6 -3.4"></path>
<path d="M8.7 13.3l6.6 3.4"></path>
</symbol>
<symbol id="note" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M5 3m0 2a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2z"></path>
<path d="M9 7l6 0"></path>
<path d="M9 11l6 0"></path>
<path d="M9 15l4 0"></path>
</symbol>
<symbol id="drag"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M9 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"/>
<path d="M9 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"/>
<path d="M9 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"/>
<path d="M15 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"/>
<path d="M15 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"/>
<path d="M15 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"/>
</symbol>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -1,6 +1,4 @@
{% load static %}
{% load shared %}
{% load pagination %}
{% load static shared pagination %}
{% if bookmark_list.is_empty %}
{% include 'bookmarks/empty_bookmarks.html' %}
{% else %}
@@ -123,8 +121,8 @@
class="btn btn-link btn-sm btn-icon"
data-confirm
data-confirm-question="Mark as read?">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<use xlink:href="#ld-icon-unread"></use>
<svg width="16" height="16">
<use href="{% static 'icons.svg' %}?v={{ app_version }}#unread"></use>
</svg>
Unread
</button>
@@ -136,16 +134,16 @@
class="btn btn-link btn-sm btn-icon"
data-confirm
data-confirm-question="Unshare?">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<use xlink:href="#ld-icon-share"></use>
<svg width="16" height="16">
<use href="{% static 'icons.svg' %}?v={{ app_version }}#share"></use>
</svg>
Shared
</button>
{% endif %}
{% if bookmark_item.show_notes_button %}
<button type="button" class="btn btn-link btn-sm btn-icon toggle-notes">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<use xlink:href="#ld-icon-note"></use>
<svg width="16" height="16">
<use href="{% static 'icons.svg' %}?v={{ app_version }}#note"></use>
</svg>
Notes
</button>

View File

@@ -11,19 +11,8 @@
{% bookmark_search bookmark_list.search mode=bookmark_list.search_mode %}
{% if bookmark_list.bulk_edit_enabled %}
<button class="btn hide-sm ml-2 bulk-edit-active-toggle" title="Bulk edit">
<svg xmlns="http://www.w3.org/2000/svg"
width="20px"
height="20px"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1" />
<path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z" />
<path d="M16 5l3 3" />
<svg width="20px" height="20px">
<use href="{% static 'icons.svg' %}?v={{ app_version }}#bulk-edit"></use>
</svg>
</button>
{% endif %}

View File

@@ -1,22 +1,12 @@
{% load static %}
{% if not request.user_profile.hide_bundles %}
<section aria-labelledby="bundles-heading">
<div class="section-header no-wrap">
<h2 id="bundles-heading">Bundles</h2>
<ld-dropdown class="dropdown dropdown-right ml-auto">
<button class="btn btn-noborder dropdown-toggle" aria-label="Bundles menu">
<svg xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M4 6l16 0" />
<path d="M4 12l16 0" />
<path d="M4 18l16 0" />
<svg width="20" height="20">
<use href="{% static 'icons.svg' %}?v={{ app_version }}#menu"></use>
</svg>
</button>
<ul class="menu" role="list" tabindex="-1">

View File

@@ -23,8 +23,8 @@
href="{% url 'linkding:assets.read' details.latest_snapshot.id %}"
target="{{ details.profile.bookmark_link_target }}">
{% if details.show_link_icons %}
<svg class="favicon" xmlns="http://www.w3.org/2000/svg">
<use xlink:href="#ld-icon-unread"></use>
<svg class="favicon">
<use href="{% static 'icons.svg' %}?v={{ app_version }}#unread"></use>
</svg>
{% endif %}
<span>Reader mode</span>

View File

@@ -1,4 +1,4 @@
{% load widget_tweaks %}
{% load static widget_tweaks %}
<div class="search-container">
<form id="search" action="" method="get" role="search">
<ld-search-autocomplete input-name="q"
@@ -17,25 +17,8 @@
<button type="button"
aria-label="Search preferences"
class="btn dropdown-toggle{% if search.has_modified_preferences %} badge{% endif %}">
<svg xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M4 10a2 2 0 1 0 4 0a2 2 0 0 0 -4 0"></path>
<path d="M6 4v4"></path>
<path d="M6 12v8"></path>
<path d="M10 16a2 2 0 1 0 4 0a2 2 0 0 0 -4 0"></path>
<path d="M12 4v10"></path>
<path d="M12 18v2"></path>
<path d="M16 7a2 2 0 1 0 4 0a2 2 0 0 0 -4 0"></path>
<path d="M18 4v1"></path>
<path d="M18 9v11"></path>
<svg width="20" height="20">
<use href="{% static 'icons.svg' %}?v={{ app_version }}#preferences"></use>
</svg>
</button>
<div class="menu" tabindex="0">

View File

@@ -1,22 +1,12 @@
{% load static %}
<section aria-labelledby="tags-heading">
<div class="section-header no-wrap">
<h2 id="tags-heading">Tags</h2>
{% if user.is_authenticated %}
<ld-dropdown class="dropdown dropdown-right ml-auto">
<button class="btn btn-noborder dropdown-toggle" aria-label="Tags menu">
<svg xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M4 6l16 0" />
<path d="M4 12l16 0" />
<path d="M4 18l16 0" />
<svg width="20" height="20">
<use href="{% static 'icons.svg' %}?v={{ app_version }}#menu"></use>
</svg>
</button>
<ul class="menu" role="list" tabindex="-1">

View File

@@ -1,4 +1,5 @@
{% extends "shared/layout.html" %}
{% load static %}
{% block head %}
{% with page_title="Bundles - Linkding" %}{{ block.super }}{% endwith %}
{% endblock %}
@@ -26,23 +27,8 @@
<tr data-bundle-id="{{ bundle.id }}" draggable="true">
<td>
<div class="d-flex align-center">
<svg xmlns="http://www.w3.org/2000/svg"
class="text-secondary mr-1"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M9 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
<path d="M9 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
<path d="M9 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
<path d="M15 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
<path d="M15 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
<path d="M15 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
<svg class="text-secondary mr-1" width="16" height="16">
<use href="{% static 'icons.svg' %}?v={{ app_version }}#drag"></use>
</svg>
<span>{{ bundle.name }}</span>
</div>

View File

@@ -6,37 +6,6 @@
{% include 'shared/head.html' %}
{% endblock %}
<body>
<div class="d-none">
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="ld-icon-unread" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M3 19a9 9 0 0 1 9 0a9 9 0 0 1 9 0"></path>
<path d="M3 6a9 9 0 0 1 9 0a9 9 0 0 1 9 0"></path>
<path d="M3 6l0 13"></path>
<path d="M12 6l0 13"></path>
<path d="M21 6l0 13"></path>
</symbol>
</svg>
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="ld-icon-share" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M6 12m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0"></path>
<path d="M18 6m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0"></path>
<path d="M18 18m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0"></path>
<path d="M8.7 10.7l6.6 -3.4"></path>
<path d="M8.7 13.3l6.6 3.4"></path>
</symbol>
</svg>
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="ld-icon-note" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M5 3m0 2a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2z"></path>
<path d="M9 7l6 0"></path>
<path d="M9 11l6 0"></path>
<path d="M9 15l4 0"></path>
</symbol>
</svg>
</div>
<header class="container">
{% if has_toasts %}
<div class="message-list">

View File

@@ -1,21 +1,12 @@
{% load static %}
<div class="modal-header">
<h2 class="title">{{ title }}</h2>
<button type="button"
class="btn btn-noborder close"
aria-label="Close dialog"
data-close-modal>
<svg xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M18 6l-12 12"></path>
<path d="M6 6l12 12"></path>
<svg width="24" height="24">
<use href="{% static 'icons.svg' %}?v={{ app_version }}#close"></use>
</svg>
</button>
</div>

View File

@@ -1,4 +1,4 @@
{% load shared %}
{% load shared static %}
{% htmlmin %}
{# Basic menu list #}
<div class="hide-md">
@@ -57,26 +57,16 @@
<a href="{% url 'linkding:bookmarks.new' %}"
aria-label="Add bookmark"
class="btn btn-primary">
<svg xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
style="width: 24px;
height: 24px">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
<svg width="24" height="24">
<use href="{% static 'icons.svg' %}?v={{ app_version }}#plus"></use>
</svg>
</a>
<ld-dropdown class="dropdown dropdown-right">
<button class="btn btn-link dropdown-toggle"
aria-label="Navigation menu"
tabindex="0">
<svg xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
style="width: 24px;
height: 24px">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
<svg width="24" height="24">
<use href="{% static 'icons.svg' %}?v={{ app_version }}#menu"></use>
</svg>
</button>
<!-- menu component -->

View File

@@ -1,6 +1,5 @@
{% extends "shared/layout.html" %}
{% load shared %}
{% load pagination %}
{% load shared static pagination %}
{% block head %}
{% with page_title="Tags - Linkding" %}{{ block.super }}{% endwith %}
{% endblock %}
@@ -39,18 +38,8 @@
<label class="form-label text-assistive" for="sort">Sort by</label>
<div class="input-group">
<span class="input-group-addon text-secondary">
<svg xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M3 9l4 -4l4 4m-4 -4v14" />
<path d="M21 15l-4 4l-4 -4m4 4v-14" />
<svg width="20" height="20">
<use href="{% static 'icons.svg' %}?v={{ app_version }}#sort"></use>
</svg>
</span>
<select id="sort" name="sort" class="form-select" data-submit-on-change>

View File

@@ -22,6 +22,7 @@ def bookmark_search(context, search: BookmarkSearch, mode: str = ""):
)
return {
"request": context["request"],
"app_version": context["app_version"],
"search": search,
"search_form": search_form,
"preferences_form": preferences_form,

View File

@@ -13,6 +13,7 @@ from bookmarks.middlewares import LinkdingMiddleware
from bookmarks.models import Bookmark, BookmarkSearch, UserProfile, User
from bookmarks.tests.helpers import BookmarkFactoryMixin, HtmlTestMixin
from bookmarks.views import contexts
from bookmarks.utils import app_version
class BookmarkListTemplateTest(TestCase, BookmarkFactoryMixin, HtmlTestMixin):
@@ -214,10 +215,10 @@ class BookmarkListTemplateTest(TestCase, BookmarkFactoryMixin, HtmlTestMixin):
def assertNotesToggle(self, html: str, count=1):
self.assertInHTML(
"""
f"""
<button type="button" class="btn btn-link btn-sm btn-icon toggle-notes">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<use xlink:href="#ld-icon-note"></use>
<svg width="16" height="16">
<use href="/static/icons.svg?v={app_version}#note"></use>
</svg>
Notes
</button>
@@ -232,8 +233,8 @@ class BookmarkListTemplateTest(TestCase, BookmarkFactoryMixin, HtmlTestMixin):
<button type="submit" name="unshare" value="{bookmark.id}"
class="btn btn-link btn-sm btn-icon"
data-confirm data-confirm-question="Unshare?">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<use xlink:href="#ld-icon-share"></use>
<svg width="16" height="16">
<use href="/static/icons.svg?v={app_version}#share"></use>
</svg>
Shared
</button>
@@ -248,8 +249,8 @@ class BookmarkListTemplateTest(TestCase, BookmarkFactoryMixin, HtmlTestMixin):
<button type="submit" name="mark_as_read" value="{bookmark.id}"
class="btn btn-link btn-sm btn-icon"
data-confirm data-confirm-question="Mark as read?">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<use xlink:href="#ld-icon-unread"></use>
<svg width="16" height="16">
<use href="/static/icons.svg?v={app_version}#unread"></use>
</svg>
Unread
</button>

View File

@@ -3,6 +3,7 @@ from django.urls import reverse
from bookmarks.models import BookmarkBundle
from bookmarks.tests.helpers import BookmarkFactoryMixin
from bookmarks.utils import app_version
class BundleIndexViewTestCase(TestCase, BookmarkFactoryMixin):
@@ -28,15 +29,8 @@ class BundleIndexViewTestCase(TestCase, BookmarkFactoryMixin):
<tr data-bundle-id="{bundle.id}" draggable="true">
<td>
<div class="d-flex align-center">
<svg xmlns="http://www.w3.org/2000/svg" class="text-secondary mr-1" width="16" height="16" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M9 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"/>
<path d="M9 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"/>
<path d="M9 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"/>
<path d="M15 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"/>
<path d="M15 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"/>
<path d="M15 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"/>
<svg class="text-secondary mr-1" width="16" height="16">
<use href="/static/icons.svg?v={app_version}#drag"></use>
</svg>
<span>{ bundle.name }</span>
</div>