forked from CGM_Public/pretix_original
[A11y] Fix sneak-peek for cart (#5076)
This commit is contained in:
committed by
GitHub
parent
2b735bec0b
commit
7472564c26
@@ -13,7 +13,7 @@
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<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">
|
||||
<h2 class="panel-title">
|
||||
<span>
|
||||
@@ -33,11 +33,15 @@
|
||||
</summary>
|
||||
{% if "open_cart" not in request.GET %}
|
||||
<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>
|
||||
{% endif %}
|
||||
<div>
|
||||
{% if "open_cart" not in request.GET %}
|
||||
<div class="panel-body sneak-peek-content" id="cart-foldable-container">
|
||||
{% else %}
|
||||
<div class="panel-body">
|
||||
{% endif %}
|
||||
{% include "pretixpresale/event/fragment_cart.html" with cart=cart event=request.event %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,39 +2,56 @@
|
||||
|
||||
setup_collapsible_details = function (el) {
|
||||
|
||||
el.find('details.sneak-peek:not([open])').each(function() {
|
||||
this.open = true;
|
||||
var $elements = $("> :not(summary)", this).show().filter(':not(.sneak-peek-trigger)');
|
||||
var container = this;
|
||||
|
||||
if (Array.prototype.reduce.call($elements, function (h, e) {
|
||||
return h + $(e).outerHeight();
|
||||
}, 0) < 200) {
|
||||
$(".sneak-peek-trigger", this).remove();
|
||||
$(container).removeClass('sneak-peek');
|
||||
container.style.removeProperty('height');
|
||||
el.find('.sneak-peek-trigger').each(function() {
|
||||
var trigger = this;
|
||||
var button = this.querySelector('button');
|
||||
var content = document.getElementById(button.getAttribute('aria-controls'));
|
||||
if (content.scrollHeight < 200) {
|
||||
trigger.remove();
|
||||
content.classList.remove('sneak-peek-content');
|
||||
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');
|
||||
|
||||
var trigger = $('summary, .sneak-peek-trigger button', container);
|
||||
function onclick(e) {
|
||||
e.preventDefault();
|
||||
|
||||
container.addEventListener('transitionend', function() {
|
||||
$(container).removeClass('sneak-peek');
|
||||
container.style.removeProperty('height');
|
||||
content.addEventListener('transitionend', function() {
|
||||
content.classList.remove('sneak-peek-content');
|
||||
content.style.removeProperty('height');
|
||||
// we need to keep the trigger/button in the DOM to not irritate screenreaders toggling visibility
|
||||
trigger.classList.add('sr-only');
|
||||
}, {once: true});
|
||||
container.style.height = container.scrollHeight + 'px';
|
||||
$('.sneak-peek-trigger', container).fadeOut(function() {
|
||||
$(this).remove();
|
||||
});
|
||||
$elements.removeAttr('aria-hidden');
|
||||
content.style.height = content.scrollHeight + 'px';
|
||||
|
||||
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]';
|
||||
@@ -43,10 +60,6 @@ setup_collapsible_details = function (el) {
|
||||
return true;
|
||||
}
|
||||
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 $detailsNotSummary = $details.children(':not(summary)');
|
||||
if ($detailsNotSummary.is(':animated')) {
|
||||
@@ -70,11 +83,6 @@ setup_collapsible_details = function (el) {
|
||||
if (32 == event.keyCode || (13 == event.keyCode && !isOpera)) {
|
||||
// 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
|
||||
var $details = $(this).closest("details");
|
||||
if ($details.hasClass('sneak-peek')) {
|
||||
// if sneak-peek is active, needs to be handled differently
|
||||
return true;
|
||||
}
|
||||
event.preventDefault();
|
||||
$(this).click();
|
||||
}
|
||||
|
||||
@@ -521,12 +521,17 @@ details summary {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
details.sneak-peek {
|
||||
.sneak-peek-container {
|
||||
position: relative;
|
||||
height: 11em;
|
||||
}
|
||||
.sneak-peek-content {
|
||||
height: 8em;
|
||||
overflow: hidden;
|
||||
transition: height .5s;
|
||||
}
|
||||
.nojs .sneak-peek-content {
|
||||
height: auto;
|
||||
}
|
||||
.sneak-peek-trigger {
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
@@ -540,6 +545,14 @@ details.sneak-peek {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user