Use icons instead of Unicode symbols for buttons

Fixes #26.
This commit is contained in:
Jonas Schäfer
2021-01-18 17:25:38 +01:00
parent 16f990f475
commit c1dbec51ab
17 changed files with 333 additions and 49 deletions

View File

@@ -1,5 +1,5 @@
{% extends "admin_app.html" %}
{% from "library.j2" import box %}
{% from "library.j2" import box, form_button, standard_button %}
{% block content %}
<h1>{% trans user_name=target_user.localpart %}Delete user {{ user_name }}{% endtrans %}</h1>
<div class="form layout-expanded"><form method="POST">
@@ -20,8 +20,8 @@
<p>The user and their data will be deleted irrevocably, permanently and immediately upon pushing thre below button. <strong>There is no way back!</strong></p>
{% endcall %}
<div class="f-bbox">
<a class="button secondary" href="{{ url_for('.users') }}">Back</a>
{{ form.action_delete(class="primary danger") }}
{%- call standard_button("back", url_for(".index"), class="secondary") %}{% trans %}Back{% endtrans %}{% endcall -%}
{%- call form_button("remove", form.action_delete, class="primary danger") %}{% endcall -%}
</div>
</form></div>
{% endblock %}

View File

@@ -1,5 +1,5 @@
{% extends "admin_app.html" %}
{% from "library.j2" import showuri %}
{% from "library.j2" import showuri, form_button, standard_button %}
{% block head_lead %}
{{ super() }}
{% include "copy-snippet.html" %}
@@ -18,11 +18,10 @@
<dd>{% call showuri(invite.landing_page) %}{% endcall %}</dd>
</dl>
<div class="f-bbox">
{#- -#}
{{ form.action_revoke(class="button secondary danger") }}
{#- -#}
<a href="{{ url_for(".invitations") }}" class="button primary">{% trans %}Back{% endtrans %}</a>
{#- -#}
{%- call form_button("remove_link", form.action_revoke, class="secondary danger") %}{% endcall -%}
{%- call standard_button("back", url_for(".invitations"), class="primary") %}
{% trans %}Back{% endtrans %}
{%- endcall %}
</div>
</div>
</form>

View File

@@ -1,4 +1,5 @@
{% extends "admin_app.html" %}
{% from "library.j2" import action_button, icon, clipboard_button, form_button, custom_form_button %}
{% block head_lead %}
{{ super() }}
{% include "copy-snippet.html" %}
@@ -10,7 +11,7 @@
<h2 class="form-title">{% trans %}Create new invitation{% endtrans %}</h2>
<p class="form-descr weak">{% trans %}Create a new invitation link to invite more users to your Snikket instance by clicking the button below.{% endtrans %}</p>
<div class="f-bbox">
{{ form.action_create_invite(class="primary") }}
{%- call form_button("create_link", form.action_create_invite, class="primary") %}{% endcall -%}
</div>
</div>
<h2>{% trans %}Pending invitations{% endtrans %}</h2>
@@ -32,13 +33,15 @@
<td>{{ invite.created_at | format_date }}</td>
<td>{{ (invite.expires - now) | format_timedelta(add_direction=True) }}</td>
<td style="white-space: nowrap;">
{#- -#}
<a href="{{ url_for(".edit_invite", id_=invite.id_) }}" class="button secondary btn-more" title="{% trans %}Show invite details{% endtrans %}"><span class="a11y-only">{% trans %}Show invite details{% endtrans %}</span></a>
{#- -#}
<a class="button primary" title="{% trans %}Copy invite link to clipboard{% endtrans %}" aria-label="{% trans %}Copy invite link to clipboard{% endtrans %}" data-cliptext="{{ invite.landing_page }}" onclick="copy_to_clipboard(this); return false;"><span>📋</span></a>
{#- -#}
<button type="submit" class="secondary danger btn-delete" name="{{ form.action_revoke.name }}" value="{{ invite.id_ }}"><span class="a11y-only">{% trans %}Delete invitation{% endtrans %}</span></button>
{#- -#}
{%- call action_button("more", url_for(".edit_invite", id_=invite.id_), class="secondary") -%}
{% trans %}Show invite details{% endtrans %}
{%- endcall -%}
{%- call clipboard_button(invite.landing_page, class="primary") -%}
{% trans %}Copy invite link to clipboard{% endtrans %}
{%- endcall -%}
{%- call custom_form_button("remove_link", form.action_revoke.name, invite.id_, class="secondary danger", slim=True) -%}
{% trans %}Delete invitation{% endtrans %}
{%- endcall -%}
</td>
</tr>
{% endfor %}

View File

@@ -1,4 +1,5 @@
{% extends "admin_app.html" %}
{% from "library.j2" import icon %}
{% macro value_or_hint(v, caller=None) %}
{%- if v is not none -%}
{{- v -}}
@@ -26,7 +27,7 @@
<td class="collapsible">{% call value_or_hint(user.email) %}{% endcall %}</td>
<td class="collapsible">{% call value_or_hint(user.phone) %}{% endcall %}</td>
<td>
{#- -#}<a class="button secondary btn-delete" href="{{ url_for(".delete_user", localpart=user.localpart) }}" title="{% trans user_name=user.localpart %}Delete user {{ user_name }}{% endtrans %}"><span class="a11y-only">{% trans user_name=user.localpart %}Delete user {{ user_name }}{% endtrans %}</span></a>
{#- -#}<a class="button secondary btn-delete" href="{{ url_for(".delete_user", localpart=user.localpart) }}">{% call icon("remove") %}{% trans user_name=user.localpart %}Delete user {{ user_name }}{% endtrans %}{% endcall %}</a>
{#- -#}
</td>
</tr>

View File

@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="{{ lang }}">
<html lang="{{ lang }}" xmlns:xlink="http://www.w3.org/1999/xlink">
<head>
<meta charset="utf-8">
{% block head_lead %}{% endblock %}

View File

@@ -73,6 +73,50 @@ var copy_to_clipboard = function(el) {
});
};
var get_current_icon = function(svg_el) {
var use_el = svg_el.firstChild;
// dont ask. I hate js.
var tmp = "" + use_el.getAttribute("xlink:href");
return tmp.split("#")[1].split("-")[1];
}
var change_icon = function(svg_el, new_icon) {
var use_el = svg_el.firstChild;
// dont ask. I hate js.
var tmp = "" + use_el.getAttribute("xlink:href");
var base_url = tmp.split("#")[0];
use_el.setAttributeNS(
"http://www.w3.org/1999/xlink", "xlink:href",
base_url + "#icon-" + new_icon
);
}
var copy_to_clipboard_btn = function(el) {
var text = el.dataset.cliptext;
if (!text) {
console.error('copy_to_clipboard used on element without text to copy');
}
copyTextToClipboard(text, el, function(success) {
var existing_result_el = document.getElementById("clipboard-result");
if (existing_result_el !== null) {
existing_result_el.parentNode.removeChild(existing_result_el);
}
var icon = "done";
var label = "{% trans %}Copied to clipboard{% endtrans %}";
if (!success) {
icon = "cancel";
label = "{% trans %}Copy operation failed{% endtrans %}";
}
var icon_bak = get_current_icon(el.firstChild);
change_icon(el.firstChild, icon);
setTimeout(function() {
change_icon(el.firstChild, icon_bak);
el.blur();
}, 1500);
});
};
window.addEventListener('load', function() {
document.body.classList.remove("no-copy");
});

View File

@@ -1,5 +1,5 @@
{% extends "base.html" %}
{% from "library.j2" import box %}
{% from "library.j2" import box, icon %}
{% set body_id = "no-lines" %}
{% block head_lead %}
<title>Theme Demo Snikket Web Portal</title>
@@ -238,5 +238,22 @@
{% endfor %}
#}
</form></div>
<h2>Icons</h2>
<p>Icons can be used in a variety of ways. For example in an enumeration:</p>
<ul>
<li>{% call icon("add") %}{% endcall %} Yaycon</li>
<li>{% call icon("remove") %}{% endcall %} Naycon</li>
</ul>
<p>Or, more importantly, on buttons:</p>
<div class="form layout-expanded">
<h3 class="form-title">Do the thing?</h3>
<div class="f-bbox">
{#- -#}
<a class="button secondary">{% call icon("cancel") %}{% endcall %}No</a>
{#- -#}
<a class="button primary">{% call icon("done") %}{% endcall %}Yes</a>
{#- -#}
</div>
</div>
{% endblock %}

View File

@@ -10,16 +10,65 @@
{%- endif -%}
{%- endmacro %}
{% macro clipboard_button(label=_("Copy link"), caller=None) -%}
{%- set text = caller() -%}
<a title="{% trans content=text %}Copy &quot;{{ content }}&quot; to clipboard{% endtrans %}" aria-label="{% trans content=text %}Copy &quot;{{ content }}&quot; to clipboard{% endtrans %}" class="copy-to-clipboard" onclick="copy_to_clipboard(this); return false;" data-cliptext="{{ text }}" href="#">{{ label }}</a>
{%- endmacro %}
{% macro showuri(uri, caller=None) %}
{%- if uri is none -%}
<em>—</em>
{%- else -%}
<div><input type="text" readonly="readonly" value="{{ uri }}"></div>
<div>{% call clipboard_button() %}{{ uri }}{% endcall %}</div>
<div>{% call clipboard_button(uri, show_label=True) %}{% trans %}Copy link{% endtrans %}{% endcall %}</div>
{%- endif -%}
{% endmacro %}
{% macro icon(name, caller=None) -%}
{%- set alt = "" if caller is none else caller() -%}
{%- if alt %}<span class="a11y-only">{{ alt }}</span>{% endif %}<svg class="icon icon-{{ name }}" aria-hidden="true"><use xlink:href="{{ url_for('static', filename='img/icons.svg' )}}#icon-{{ name }}"></use></svg>
{%- endmacro %}
{% macro standard_button(icon_name, href, caller=None, class=None) -%}
{%- set label = caller() -%}
<a href="{{ href }}" class="button {% if class %}{{ class }}{% endif %}" aria-label="{{ a11y }}" title="{{ a11y }}">{% call icon(icon_name) %}{% endcall %}<span>{{ label }}</span></a>
{%- endmacro %}
{% macro form_button(icon_name, button_obj, caller=None, class=None) -%}
<button {% if class %}class="{{ class }}"{% endif %} id="{{ button_obj.id }}" name="{{ button_obj.name }}" type="submit" value="{{ button_obj.data or 'true' }}">{% call icon(icon_name) %}{% endcall %}<span>{{ button_obj.label.text }}</span></button>
{%- endmacro %}
{% macro custom_form_button(icon_name, name, value, caller=None, slim=False, class=None) -%}
{%- set text = caller() -%}
<button
{% if class %}class="{{ class }}"{% endif %}
{% if name %}name="{{ name }}"{% endif %}
type="submit"
{% if value %} value="{{ value }}"{% endif %}
{% if slim %}
aria-label="{{ text }}"
title="{{ text }}"
{% endif %}
>
{%- call icon(icon_name) %}{% endcall -%}
{%- if not slim -%}
<span>{{ text }}</span>
{%- endif -%}
</button>
{%- endmacro %}
{% macro action_button(icon_name, href, caller=None, class=None) -%}
{%- set a11y = caller() -%}
<a href="{{ href }}" class="button {% if class %}{{ class }}{% endif %}" aria-label="{{ a11y }}" title="{{ a11y }}">{% call icon(icon_name) %}{% endcall %}</a>
{%- endmacro %}
{% macro clipboard_button(data, show_label=False, caller=None, class=None) -%}
{%- set label = caller() -%}
<a class="button{% if class %} {{ class }}{% endif %}"
{% if not show_label %}
aria-label="{{ label }}"
title="{{ label }}"
{% endif %}
data-cliptext="{{ data }}"
onclick="copy_to_clipboard_btn(this); return false;">
{%- call icon("copy") %}{% endcall -%}
{%- if show_label %}
<span>{{ label }}</span>
{% endif -%}
</a>
{%- endmacro %}

View File

@@ -1,5 +1,5 @@
{% extends "base.html" %}
{% from "library.j2" import box %}
{% from "library.j2" import box, icon %}
{% set body_id = "login" %}
{% block head_lead %}
<title>{{ _("Snikket Login") }}</title>
@@ -28,7 +28,7 @@
{{ form.password(placeholder=form.password.label.text) }}
</div>
<div class="f-bbox">
<button type="submit" class="primary">{{ _("Log in") }}</button>
<button type="submit" class="primary">{% call icon("login") %}{% endcall %}{{ _("Log in") }}</button>
</div>
</from>
</div></main></div>

View File

@@ -1,4 +1,5 @@
{% extends "app.html" %}
{% from "library.j2" import icon %}
{% block head_lead %}
<title>Snikket Web Portal</title>
{% endblock %}
@@ -9,9 +10,9 @@
{{ form.csrf_token }}
<div class="f-bbox">
{#- -#}
<a href="{{ url_for('user.index') }}" class="button secondary">{% trans %}Back{% endtrans %}</a>
<a href="{{ url_for('user.index') }}" class="button secondary">{% call icon("back") %}{% endcall %}{% trans %}Back{% endtrans %}</a>
{#- -#}
<button type="submit" class="primary">{% trans %}Sign out{% endtrans %}</button>
<button type="submit" class="primary">{% call icon("logout") %}{% endcall %}{% trans %}Sign out{% endtrans %}</button>
{#- -#}
</div>
</form></div>

View File

@@ -1,4 +1,5 @@
{% extends "app.html" %}
{% from "library.j2" import standard_button, custom_form_button %}
{% block head_lead %}
<title>Snikket Web Portal</title>
{% endblock %}
@@ -36,8 +37,10 @@
<p>{% trans %}After changing your password, you will have to enter the new password on all of your devices.{% endtrans %}</p>
</div>
<div class="f-bbox">
<a href="{{ url_for('.index') }}" class="button secondary">{% trans %}Back{% endtrans %}</a>
<button type="submit" class="primary">{% trans %}Change password{% endtrans %}</button>
{%- call standard_button("back", url_for('.index'), class="secondary") %}{% trans %}Back{% endtrans %}{% endcall -%}
{%- call custom_form_button("done", "", "", class="primary") -%}
{% trans %}Change password{% endtrans %}
{%- endcall -%}
</div>
</form></div>
{% endblock %}

View File

@@ -1,4 +1,5 @@
{% extends "app.html" %}
{% from "library.j2" import standard_button, form_button %}
{% block head_lead %}
<title>Snikket Web Portal</title>
{% endblock %}
@@ -21,7 +22,8 @@
{{ form.profile_access_model }}
</div>
<div class="f-bbox">
<a href="{{ url_for('user.index') }}" class="button secondary">{% trans %}Back{% endtrans %}</a><button type="submit" class="primary">{% trans %}Apply{% endtrans %}</button>
{%- call standard_button("back", url_for('.index'), class="secondary") %}{% trans %}Back{% endtrans %}{% endcall -%}
{%- call form_button("done", form.action_save, class="primary") %}{% endcall -%}
</div>
</form></div>
{% endblock %}