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

Implement active filter button to open drilldown for specific filter

This commit is contained in:
Sage Abdullah 2024-01-23 23:58:15 +00:00 committed by Thibaud Colas
parent 2adda186a0
commit e8b34ededd
4 changed files with 72 additions and 5 deletions

View File

@ -7,6 +7,10 @@
}
&__remove {
@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;
@apply w-pr-3 w-py-1 w-rounded-r-xl w-border w-border-info-100 w-bg-info-100 w-text-white w-p-0 w-pl-2 w-flex w-items-center w-justify-center w-h-full;
}
button {
@apply hover:w-bg-info-125;
}
}

View File

@ -1,4 +1,6 @@
import { Controller } from '@hotwired/stimulus';
import { ActionController } from './ActionController';
import { DropdownController } from './DropdownController';
/**
* Drilldown menu interaction combined with URL-driven
@ -13,17 +15,44 @@ export class DrilldownController extends Controller<HTMLElement> {
countAttr: { default: '', type: String },
};
static outlets = [
// w-action outlet for submenu toggles that are outside the drilldown.
// We don't really use anything specific to ActionController, we just need
// a Stimulus controller to be able to use the outlet. As with toggle targets,
// these need to have aria-controls.
'w-action',
// w-dropdown outlet for the popup menu, to allow interacting with the
// DropdownController programmatically.
'w-dropdown',
];
declare activeSubmenuValue: string;
declare countAttrValue: string;
declare readonly countTargets: HTMLElement[];
declare readonly menuTarget: HTMLElement;
declare readonly toggleTargets: HTMLButtonElement[];
declare readonly hasWDropdownOutlet: boolean;
declare readonly wActionOutlets: ActionController[];
declare readonly wDropdownOutlet: DropdownController;
countTargetConnected() {
this.updateCount();
}
connect(): void {
this.open = this.open.bind(this);
}
wActionOutletConnected(_: ActionController, element: HTMLElement) {
element.addEventListener('click', this.open);
}
wActionOutletDisconnected(_: ActionController, element: HTMLElement) {
element.removeEventListener('click', this.open);
}
/**
* Update the count of items in the menu.
* This is done by counting the number of elements with the data attribute
@ -107,7 +136,33 @@ export class DrilldownController extends Controller<HTMLElement> {
}
}
/**
* Prevent clicks on the w-action outlets from closing the dropdown.
* Usage: data-action="w-dropdown:clickaway->w-drilldown#preventOutletClickaway"
*/
preventOutletClickaway(e: Event) {
const clickawayEvent = e as CustomEvent<{ target: HTMLElement }>;
const target = clickawayEvent.detail.target;
if (!target) return;
const controlledIds = this.toggleTargets.map((toggle) =>
toggle.getAttribute('aria-controls'),
);
const clickawayControl =
target.closest('button')?.getAttribute('aria-controls') || '';
if (controlledIds.includes(clickawayControl)) {
e.preventDefault();
}
}
toggle(expanded: boolean, toggle: HTMLButtonElement) {
// If we're expanding, the toggle may be inside the w-dropdown outlet while
// the dropdown is hidden (e.g. opening directly to a submenu from an
// overall collapsed state).
// Ensure that the dropdown is shown so Tippy renders the toggle in the DOM.
if (this.hasWDropdownOutlet && expanded) {
this.wDropdownOutlet.show();
}
const controls = toggle.getAttribute('aria-controls');
const content = this.element.querySelector<HTMLElement>(`#${controls}`);
if (!content) {

View File

@ -1,11 +1,11 @@
{% load i18n wagtailadmin_tags %}
<ul class="w-active-filters">
{% for filter in active_filters %}
<li class="w-pill" data-w-active-filter-name="{{ filter.auto_id }}">
<div class="w-pill__content">
<li class="w-pill">
<button class="w-pill__content" data-controller="w-action" data-w-active-filter-name="{{ filter.auto_id }}" aria-controls="drilldown-{{ filter.auto_id }}">
<span class="w-text-14">{{ filter.field_label }}:</span>
<b class="w-ml-1">{{ filter.value }}</b>
</div>
</button>
<button
data-controller="w-swap"
data-action="click->w-swap#replaceLazy"

View File

@ -79,7 +79,15 @@
{% endif %}
{% if filters %}
<div id="filters-drilldown" class="w-drilldown" data-controller="w-drilldown" data-action="w-swap:success@document->w-drilldown#updateParams w-dropdown:hide->w-drilldown#delayedClose" data-w-drilldown-count-attr-value="data-w-active-filter-name">
<div
id="filters-drilldown"
class="w-drilldown"
data-controller="w-drilldown"
data-action="w-swap:success@document->w-drilldown#updateParams w-dropdown:hide->w-drilldown#delayedClose w-dropdown:clickaway->w-drilldown#preventOutletClickaway"
data-w-drilldown-count-attr-value="data-w-active-filter-name"
data-w-drilldown-w-action-outlet="[data-w-active-filter-name][data-controller='w-action']"
data-w-drilldown-w-dropdown-outlet="#filters-drilldown [data-controller='w-dropdown']"
>
{% include "wagtailadmin/shared/headers/_filters.html" with filters=filters only %}
</div>
{% endif %}