diff --git a/src/css/common.css b/src/css/common.css index 415b13efb..1a8ba0b34 100644 --- a/src/css/common.css +++ b/src/css/common.css @@ -218,6 +218,11 @@ label:hover .checkbox:not([disabled]) { .checkbox[disabled] ~ span { filter: var(--checkbox-disabled-filter); } +.checkbox.partial > input[type="checkbox"]:checked + svg { + background-color: var(--surface-1); + border-color: var(--checkbox-checked-ink); + stroke: var(--checkbox-checked-ink); + } .radio { --margin-end: calc(var(--font-size) * 0.75); diff --git a/src/js/3p-filters.js b/src/js/3p-filters.js index 98fc477dd..2f1cd92cd 100644 --- a/src/js/3p-filters.js +++ b/src/js/3p-filters.js @@ -400,9 +400,10 @@ const toggleFilterList = (elem, on, ui = false) => { const updateListNode = listNode => { if ( listNode === null ) { return; } if ( listNode.dataset.role !== 'node' ) { return; } - const listLeaves = qsa$(listNode, '.listEntry[data-role="leaf"].checked'); + const checkedListLeaves = qsa$(listNode, '.listEntry[data-role="leaf"].checked'); + const allListLeaves = qsa$(listNode, '.listEntry[data-role="leaf"]'); dom.text(qs$(listNode, '.nodestats'), - renderNodeStats(listLeaves.length, qsa$(listNode, '.listEntry[data-role="leaf"]').length) + renderNodeStats(checkedListLeaves.length, allListLeaves.length) ); dom.cl.toggle(listNode, 'searchMatch', qs$(listNode, ':scope > .listEntries > .listEntry.searchMatch') !== null @@ -413,7 +414,7 @@ const updateListNode = listNode => { let isCached = false; let isObsolete = false; let writeTime = 0; - for ( const listLeaf of listLeaves ) { + for ( const listLeaf of checkedListLeaves ) { const listkey = listLeaf.dataset.key; const listDetails = listsetDetails.available[listkey]; usedFilterCount += listDetails.off ? 0 : listDetails.entryUsedCount || 0; @@ -423,8 +424,15 @@ const updateListNode = listNode => { isObsolete = isObsolete || dom.cl.has(listLeaf, 'obsolete'); writeTime = Math.max(writeTime, assetCache.writeTime || 0); } - dom.cl.toggle(listNode, 'checked', listLeaves.length !== 0); - dom.prop(qs$(listNode, ':scope > .detailbar input'), 'checked', listLeaves.length !== 0); + dom.cl.toggle(listNode, 'checked', checkedListLeaves.length !== 0); + dom.cl.toggle(qs$(listNode, ':scope > .detailbar .checkbox'), + 'partial', + checkedListLeaves.length !== allListLeaves.length + ); + dom.prop(qs$(listNode, ':scope > .detailbar input'), + 'checked', + checkedListLeaves.length !== 0 + ); dom.text(qs$(listNode, '.leafstats'), renderLeafStats(usedFilterCount, totalFilterCount) );