0
0
mirror of https://github.com/wagtail/wagtail.git synced 2024-11-25 05:02:57 +01:00

Clean up unfinished aspects of DrilldownController

This commit is contained in:
Thibaud Colas 2024-01-23 09:47:35 +01:00 committed by Sage Abdullah
parent 7ba218a094
commit f1520bfcdd
No known key found for this signature in database
GPG Key ID: EB1A33CC51CC0217
6 changed files with 29 additions and 51 deletions

View File

@ -62,6 +62,7 @@
.w-drilldown__submenu .w-field__label {
@apply w-label-1;
// Align with the submenus back button.
margin-top: theme('spacing.2');
margin-bottom: theme('spacing.3');
}
@ -76,8 +77,10 @@
font-weight: theme('fontWeight.bold');
border-radius: theme('borderRadius.full');
background-color: theme('colors.info.100');
border: 1px solid theme('colors.info.100');
color: theme('colors.white.DEFAULT');
// Reuse the same count component as a button badge.
.w-filter-button & {
position: absolute;
top: calc(-0.5 * #{$badge-size});

View File

@ -3,10 +3,10 @@
min-height: theme('spacing[6.5]');
&__content {
@apply w-pl-3 w-py-1 w-rounded-l-xl w-bg-info-100 hover:w-bg-info-125 w-p-0 w-text-white hover:w-text-white w-pr-2 w-text-14 w-flex w-items-center w-border-r w-border-white-15 w-h-full;
@apply w-pl-3 w-py-1 w-rounded-l-xl w-bg-info-100 w-p-0 w-text-white w-pr-2 w-text-14 w-flex w-items-center w-border w-border-info-100 w-border-r-white-15 w-h-full;
}
&__remove {
@apply w-pr-3 w-py-1 w-rounded-r-xl w-bg-info-100 hover:w-bg-info-125 w-text-white hover:w-text-white w-p-0 w-pl-2 w-flex w-items-center w-justify-center w-h-full;
@apply w-pr-3 w-py-1 w-rounded-r-xl w-border w-border-info-100 w-bg-info-100 hover:w-bg-info-125 w-text-white hover:w-text-white w-p-0 w-pl-2 w-flex w-items-center w-justify-center w-h-full;
}
}

View File

@ -1,19 +1,27 @@
import { Controller } from '@hotwired/stimulus';
/**
* Drilldown menu interaction combined with URL-driven
* state management for listing filters.
*/
export class DrilldownController extends Controller<HTMLElement> {
static targets = ['menu', 'toggle'];
static targets = ['count', 'menu', 'toggle'];
static values = {
// Default: main menu.
activeSubmenu: { default: '', type: String },
};
declare activeSubmenuValue: string;
declare readonly countTarget: HTMLElement;
declare readonly menuTarget: HTMLElement;
declare readonly toggleTargets: HTMLButtonElement[];
connect() {
this.updateToggleCounts();
const filteredParams = new URLSearchParams(window.location.search);
this.countTarget.hidden = filteredParams.size === 0;
this.countTarget.textContent = filteredParams.size.toString();
}
updateParamsCount(e: Event) {
@ -29,9 +37,12 @@ export class DrilldownController extends Controller<HTMLElement> {
filteredParams.append(key, value);
}
});
const queryString = '?' + filteredParams.toString();
this.updateToggleCounts();
const queryString = `?${filteredParams.toString()}`;
window.history.replaceState(null, '', queryString);
// Update the drilldowns count badge based on remaining filter parameters.
this.countTarget.hidden = filteredParams.size === 0;
this.countTarget.textContent = filteredParams.size.toString();
}
}
@ -44,9 +55,12 @@ export class DrilldownController extends Controller<HTMLElement> {
close() {
this.activeSubmenuValue = '';
this.updateToggleCounts();
}
/**
* Derive the components targets based on the state,
* so the drilldown state can be controlled externally more easily.
*/
activeSubmenuValueChanged(activeSubmenu: string, prevActiveSubmenu?: string) {
if (prevActiveSubmenu) {
const toggle = document.querySelector(
@ -72,7 +86,6 @@ export class DrilldownController extends Controller<HTMLElement> {
toggle.setAttribute('aria-expanded', expanded.toString());
content.hidden = !expanded;
this.menuTarget.hidden = expanded;
this.element.classList.toggle('w-drilldown--active', expanded);
if (expanded) {
content.focus();
@ -80,37 +93,4 @@ export class DrilldownController extends Controller<HTMLElement> {
toggle.focus();
}
}
/**
* Placeholder function until this is more correctly set up with the backend.
*/
updateToggleCounts() {
let sum = 0;
this.toggleTargets.forEach((toggle) => {
const content = this.element.querySelector<HTMLElement>(
`#${toggle.getAttribute('aria-controls')}`,
);
const counter = toggle.querySelector<HTMLElement>('.w-drilldown__count');
if (!content || !counter) {
return;
}
// Hack to detect fields with a non-default value.
const nbActiveFields = content.querySelectorAll(
'[type="checkbox"]:checked, [type="radio"]:checked:not([id$="_0"]), option:checked:not(:first-child), input:not([type="checkbox"], [type="radio"]):not(:placeholder-shown)',
).length;
counter.hidden = nbActiveFields === 0;
counter.textContent = nbActiveFields.toString();
sum += nbActiveFields;
});
const sumCounter = this.element.querySelector<HTMLElement>(
'.w-drilldown__count',
);
if (!sumCounter) {
return;
}
sumCounter.hidden = sum === 0;
sumCounter.textContent = sum.toString();
}
}

View File

@ -2,10 +2,10 @@
<ul class="w-active-filters">
{% for filter in active_filters %}
<li class="w-pill">
<button data-a11y-dialog-show="filters-dialog" class="w-pill__content">
<div class="w-pill__content">
<span class="w-text-14">{{ filter.field_label }}:</span>
<b class="w-ml-1">{{ filter.value }}</b>
</button>
</div>
<button
data-controller="w-swap"
data-action="click->w-swap#replaceLazy"

View File

@ -81,17 +81,16 @@
{% if filters %}
<div class="w-drilldown" data-controller="w-drilldown" data-action="w-swap:success@document->w-drilldown#updateParamsCount">
{% fragment as toggle_suffix %}
<span class="w-drilldown__count" hidden></span>
<span class="w-drilldown__count" data-w-drilldown-target="count" hidden></span>
{% endfragment %}
{% dropdown theme="drilldown" toggle_icon="sliders" toggle_classname="w-filter-button" toggle_aria_label=_("Show filters") toggle_suffix=toggle_suffix %}
<div class="w-drilldown__contents">
<div class="w-drilldown__menu" data-w-drilldown-target="menu">
<h2 class="w-help-text w-pl-5 w-py-2.5 w-my-0">{% trans "Filter by" %}</h2>
{% for field in filters.form %}
<button class="w-drilldown__toggle" data-w-drilldown-target="toggle" data-action="click->w-drilldown#open" type="button" class="w-flex w-justify-between" aria-expanded="false" aria-controls="drilldown-{{field.auto_id}}">
<button class="w-drilldown__toggle" type="button" aria-expanded="false" aria-controls="drilldown-{{field.auto_id}}" data-w-drilldown-target="toggle" data-action="click->w-drilldown#open">
{{ field.label }}
<div class="w-flex w-items-center w-gap-2">
<span class="w-drilldown__count" hidden></span>
{% icon name="arrow-right" %}
</div>
</button>
@ -99,7 +98,7 @@
</div>
{% for field in filters.form %}
<div class="w-drilldown__submenu" id="drilldown-{{field.auto_id}}" hidden tabindex="-1">
<button class="w-drilldown__back" type="button" data-action="click->w-drilldown#close" aria-label="{% trans 'Back' %}">
<button class="w-drilldown__back" type="button" aria-label="{% trans 'Back' %}" data-action="click->w-drilldown#close">
{% icon name="arrow-left" %}
</button>
{% formattedfield field %}

View File

@ -57,10 +57,6 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
clear_button = soup.select_one(".w-active-filters .w-pill__remove")
self.assertIsNotNone(active_filter)
self.assertEqual(active_filter.get_text(separator=" ", strip=True), text)
self.assertEqual(
active_filter.attrs.get("data-a11y-dialog-show"),
"filters-dialog",
)
self.assertIsNotNone(clear_button)
self.assertNotIn(param, clear_button.attrs.get("data-w-swap-src-value"))