Skip to content

Commit 02aa97f

Browse files
committed
Help admins choose tag colors with contrast
Add front-end soft validation to the TagAdmin form. This uses WCAG 2.2 guidelines to warn the administrator if a color choice is going to be low-contrast when compared to our text/background color of white. (The warning may be ignored.)
1 parent c0b0dc7 commit 02aa97f

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

media/commitfest/js/change_tag.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// An input validator for the color picker. Points out low-contrast tag color
2+
// choices.
3+
const input = document.getElementById("id_color");
4+
input.addEventListener("input", (event) => {
5+
// Don't do anything if the color code doesn't pass default validity.
6+
input.setCustomValidity("");
7+
if (!input.validity.valid) {
8+
return;
9+
}
10+
11+
// Break the #rrggbb color code into RGB components.
12+
color = parseInt(input.value.substr(1), 16);
13+
red = ((color & 0xFF0000) >> 16) / 255.;
14+
green = ((color & 0x00FF00) >> 8) / 255.;
15+
blue = (color & 0x0000FF) / 255.;
16+
17+
// Compare the contrast ratio against white. All the magic math comes from
18+
// Web Content Accessibility Guidelines (WCAG) 2.2, Technique G18:
19+
//
20+
// https://www.w3.org/WAI/WCAG22/Techniques/general/G18.html
21+
//
22+
function l(val) {
23+
if (val <= 0.04045) {
24+
return val / 12.92;
25+
}
26+
return ((val + 0.055) / 1.055) ** 2.4;
27+
}
28+
29+
lum = 0.2126 * l(red) + 0.7152 * l(green) + 0.0722 * l(blue);
30+
contrast = (1 + 0.05) / (lum + 0.05);
31+
32+
// Complain if we're below WCAG 2.2 recommendations.
33+
if (contrast < 4.5) {
34+
input.setCustomValidity(
35+
"Consider choosing a darker color. "
36+
+ "(Tag text is small and white.)\n\n"
37+
+ "Contrast ratio: " + (Math.trunc(contrast * 10) / 10) + " (< 4.5)"
38+
);
39+
40+
// The admin form uses novalidate, so manually display the browser's
41+
// validity popup. (The user can still ignore it if desired.)
42+
input.reportValidity();
43+
}
44+
});

pgcommitfest/commitfest/admin.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ class ColorInput(widgets.Input):
5151

5252

5353
class TagAdmin(admin.ModelAdmin):
54+
# Customize the Tag form with a color picker and soft validation.
55+
change_form_template = "change_tag_form.html"
5456
formfield_overrides = {
5557
ColorField: {"widget": ColorInput},
5658
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{% extends 'admin/change_form.html' %}
2+
{% load static %}
3+
4+
{% block admin_change_form_document_ready %}
5+
{{ block.super }}
6+
<script src="{% static 'commitfest/js/change_tag.js' %}" async></script>
7+
{% endblock %}

0 commit comments

Comments
 (0)