mirror of
https://github.com/pretix/pretix.git
synced 2026-05-09 15:54:03 +00:00
[A11y] Fix sneak-peek for cart (#5076)
This commit is contained in:
committed by
GitHub
parent
2b735bec0b
commit
7472564c26
@@ -13,7 +13,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<aside aria-label="{% trans "Your cart" %}">
|
<aside aria-label="{% trans "Your cart" %}">
|
||||||
<details class="panel panel-default cart{% if "open_cart" not in request.GET %} sneak-peek{% endif %}" {% if "open_cart" in request.GET %}open{% endif %}>
|
<details class="panel panel-default cart sneak-peek-container" open>
|
||||||
<summary class="panel-heading">
|
<summary class="panel-heading">
|
||||||
<h2 class="panel-title">
|
<h2 class="panel-title">
|
||||||
<span>
|
<span>
|
||||||
@@ -33,11 +33,15 @@
|
|||||||
</summary>
|
</summary>
|
||||||
{% if "open_cart" not in request.GET %}
|
{% if "open_cart" not in request.GET %}
|
||||||
<p class="sneak-peek-trigger">
|
<p class="sneak-peek-trigger">
|
||||||
<button type="button" class="btn btn-default">{% trans "Show full cart" %}</button>
|
<button type="button" class="btn btn-default" aria-controls="cart-foldable-container">{% trans "Show full cart" %}</button>
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div>
|
<div>
|
||||||
|
{% if "open_cart" not in request.GET %}
|
||||||
|
<div class="panel-body sneak-peek-content" id="cart-foldable-container">
|
||||||
|
{% else %}
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
|
{% endif %}
|
||||||
{% include "pretixpresale/event/fragment_cart.html" with cart=cart event=request.event %}
|
{% include "pretixpresale/event/fragment_cart.html" with cart=cart event=request.event %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,39 +2,56 @@
|
|||||||
|
|
||||||
setup_collapsible_details = function (el) {
|
setup_collapsible_details = function (el) {
|
||||||
|
|
||||||
el.find('details.sneak-peek:not([open])').each(function() {
|
el.find('.sneak-peek-trigger').each(function() {
|
||||||
this.open = true;
|
var trigger = this;
|
||||||
var $elements = $("> :not(summary)", this).show().filter(':not(.sneak-peek-trigger)');
|
var button = this.querySelector('button');
|
||||||
var container = this;
|
var content = document.getElementById(button.getAttribute('aria-controls'));
|
||||||
|
if (content.scrollHeight < 200) {
|
||||||
if (Array.prototype.reduce.call($elements, function (h, e) {
|
trigger.remove();
|
||||||
return h + $(e).outerHeight();
|
content.classList.remove('sneak-peek-content');
|
||||||
}, 0) < 200) {
|
|
||||||
$(".sneak-peek-trigger", this).remove();
|
|
||||||
$(container).removeClass('sneak-peek');
|
|
||||||
container.style.removeProperty('height');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
content.setAttribute('aria-hidden', 'true');
|
||||||
|
button.setAttribute('aria-expanded', 'false');
|
||||||
|
button.addEventListener('click', function (e) {
|
||||||
|
button.setAttribute('aria-expanded', 'true');
|
||||||
|
content.setAttribute('aria-hidden', 'false');
|
||||||
|
|
||||||
$elements.attr('aria-hidden', 'true');
|
content.addEventListener('transitionend', function() {
|
||||||
|
content.classList.remove('sneak-peek-content');
|
||||||
var trigger = $('summary, .sneak-peek-trigger button', container);
|
content.style.removeProperty('height');
|
||||||
function onclick(e) {
|
// we need to keep the trigger/button in the DOM to not irritate screenreaders toggling visibility
|
||||||
e.preventDefault();
|
trigger.classList.add('sr-only');
|
||||||
|
|
||||||
container.addEventListener('transitionend', function() {
|
|
||||||
$(container).removeClass('sneak-peek');
|
|
||||||
container.style.removeProperty('height');
|
|
||||||
}, {once: true});
|
}, {once: true});
|
||||||
container.style.height = container.scrollHeight + 'px';
|
content.style.height = content.scrollHeight + 'px';
|
||||||
$('.sneak-peek-trigger', container).fadeOut(function() {
|
|
||||||
$(this).remove();
|
|
||||||
});
|
|
||||||
$elements.removeAttr('aria-hidden');
|
|
||||||
|
|
||||||
trigger.off('click', onclick);
|
button.addEventListener('click', function (e) {
|
||||||
|
// this will be called by screenreader users if they kept focus on the button after expanding
|
||||||
|
// we need to keep the trigger/button in the DOM to not irritate screenreaders toggling visibility
|
||||||
|
var expanded = button.getAttribute('aria-expanded') == 'true';
|
||||||
|
button.setAttribute('aria-expanded', !expanded);
|
||||||
|
content.setAttribute('aria-hidden', expanded);
|
||||||
|
});
|
||||||
|
button.addEventListener('blur', function (e) {
|
||||||
|
// if content is visible and the user leaves the button, we can safely remove the trigger/button
|
||||||
|
if (button.getAttribute('aria-expanded') == 'true') {
|
||||||
|
trigger.remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, { once: true });
|
||||||
|
|
||||||
|
var container = this.closest('details.sneak-peek-container');
|
||||||
|
if (container) {
|
||||||
|
function removeSneekPeakWhenClosed(e) {
|
||||||
|
if (e.newState == "closed") {
|
||||||
|
container.removeEventListener("toggle", removeSneekPeakWhenClosed);
|
||||||
|
trigger.remove();
|
||||||
|
content.removeAttribute('aria-hidden');
|
||||||
|
content.classList.remove('sneak-peek-content');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
container.addEventListener("toggle", removeSneekPeakWhenClosed);
|
||||||
}
|
}
|
||||||
trigger.on('click', onclick);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
|
var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
|
||||||
@@ -43,10 +60,6 @@ setup_collapsible_details = function (el) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
var $details = $(this).closest("details");
|
var $details = $(this).closest("details");
|
||||||
if ($details.hasClass('sneak-peek')) {
|
|
||||||
// if sneak-peek is active, needs to be handled differently
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
var isOpen = $details.prop("open");
|
var isOpen = $details.prop("open");
|
||||||
var $detailsNotSummary = $details.children(':not(summary)');
|
var $detailsNotSummary = $details.children(':not(summary)');
|
||||||
if ($detailsNotSummary.is(':animated')) {
|
if ($detailsNotSummary.is(':animated')) {
|
||||||
@@ -70,11 +83,6 @@ setup_collapsible_details = function (el) {
|
|||||||
if (32 == event.keyCode || (13 == event.keyCode && !isOpera)) {
|
if (32 == event.keyCode || (13 == event.keyCode && !isOpera)) {
|
||||||
// Space or Enter is pressed — trigger the `click` event on the `summary` element
|
// Space or Enter is pressed — trigger the `click` event on the `summary` element
|
||||||
// Opera already seems to trigger the `click` event when Enter is pressed
|
// Opera already seems to trigger the `click` event when Enter is pressed
|
||||||
var $details = $(this).closest("details");
|
|
||||||
if ($details.hasClass('sneak-peek')) {
|
|
||||||
// if sneak-peek is active, needs to be handled differently
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
$(this).click();
|
$(this).click();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -521,12 +521,17 @@ details summary {
|
|||||||
transform: rotate(-90deg);
|
transform: rotate(-90deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
details.sneak-peek {
|
.sneak-peek-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 11em;
|
}
|
||||||
|
.sneak-peek-content {
|
||||||
|
height: 8em;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: height .5s;
|
transition: height .5s;
|
||||||
}
|
}
|
||||||
|
.nojs .sneak-peek-content {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
.sneak-peek-trigger {
|
.sneak-peek-trigger {
|
||||||
display: grid;
|
display: grid;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -540,6 +545,14 @@ details.sneak-peek {
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity .5s;
|
||||||
|
}
|
||||||
|
.nojs .sneak-peek-trigger {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.sneak-peek-trigger:has(button[aria-expanded="true"]) {
|
||||||
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
form.download-btn-form {
|
form.download-btn-form {
|
||||||
|
|||||||
Reference in New Issue
Block a user