Skip to content

Commit af0bc9f

Browse files
jaygeorgeclaudejasonvarga
authored
[6.x] Filters can only be removed by clicking cross (#14220)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Jason Varga <jason@pixelfear.com>
1 parent 3d3dfbe commit af0bc9f

File tree

1 file changed

+57
-26
lines changed

1 file changed

+57
-26
lines changed

resources/js/components/ui/Listing/Filters.vue

Lines changed: 57 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
Stack,
1010
} from '@ui';
1111
import { injectListingContext } from '../Listing/Listing.vue';
12+
import { dateFormatter } from '@/api';
1213
import { computed, ref, watch, nextTick } from 'vue';
1314
import FieldFilter from './FieldFilter.vue';
1415
import DataListFilter from './Filter.vue';
@@ -39,6 +40,27 @@ function removeFieldFilter(filterHandle, fieldHandle) {
3940
setFilter(filterHandle, fields);
4041
}
4142
43+
function getFieldFilterBadgeLabel(handle, badge) {
44+
if (handle === 'date') {
45+
const df = dateFormatter.options('date');
46+
const parts = [badge.field, badge.translatedOperator];
47+
48+
if (badge.operator === 'between') {
49+
parts.push(df.date(badge.value.start), __('and'), df.date(badge.value.end));
50+
} else {
51+
parts.push(df.date(badge.value));
52+
}
53+
54+
return parts.filter(Boolean).join(' ');
55+
}
56+
57+
return badge;
58+
}
59+
60+
function getClearFilterLabel(label) {
61+
return __('Clear :filter', { filter: label });
62+
}
63+
4264
function isActive(handle) {
4365
return activeFilters.value.hasOwnProperty(handle);
4466
}
@@ -172,38 +194,47 @@ function handleStackClosed() {
172194
</Stack>
173195

174196
<Button
197+
as="div"
198+
variant="filled"
175199
v-for="({ filter, handle, badge }, index) in fieldFilterBadges"
176200
:key="`${filter}-${handle}`"
177-
variant="filled"
178-
:icon-append="reorderable ? null : 'x'"
179-
:disabled="reorderable"
180-
class="last:me-12"
181-
@click="removeFieldFilter(filter, handle)"
201+
class="cursor-default ps-4 gap-1 text-gray-900 dark:text-gray-200 last:me-12 hover:bg-gray-950/5 dark:hover:bg-white/4"
202+
:class="reorderable ? 'pe-4 text-gray-400 dark:text-gray-600' : 'pe-2'"
182203
>
183-
<template v-if="handle == 'date'">
184-
{{ badge.field }}
185-
{{ badge.translatedOperator }}
186-
<template v-if="badge.operator === 'between'">
187-
<date-time :of="badge.value.start" options="date" />
188-
{{ __('and') }}
189-
<date-time :of="badge.value.end" options="date" />
190-
</template>
191-
<date-time v-else :of="badge.value" options="date" />
192-
</template>
193-
194-
<template v-else>
195-
{{ badge }}
196-
</template>
204+
<span class="whitespace-nowrap" v-text="getFieldFilterBadgeLabel(handle, badge)" />
205+
206+
<Button
207+
v-if="!reorderable"
208+
variant="ghost"
209+
size="xs"
210+
icon="x"
211+
iconOnly
212+
inset
213+
class="opacity-100 [&_svg]:size-4"
214+
:aria-label="getClearFilterLabel(getFieldFilterBadgeLabel(handle, badge))"
215+
@click="removeFieldFilter(filter, handle)"
216+
/>
197217
</Button>
198218
<Button
219+
as="div"
220+
variant="filled"
199221
v-for="(badge, handle, index) in standardBadges"
200222
:key="handle"
201-
variant="filled"
202-
:icon-append="reorderable ? null : 'x'"
203-
:text="badge"
204-
:disabled="reorderable"
205-
class="last:me-12"
206-
@click="setFilter(handle, null)"
207-
/>
223+
class="cursor-default ps-4 gap-1 text-gray-900 dark:text-gray-200 last:me-12 hover:bg-gray-950/5 dark:hover:bg-white/4"
224+
:class="reorderable ? 'pe-4 text-gray-400 dark:text-gray-600' : 'pe-2'"
225+
>
226+
<span class="whitespace-nowrap">{{ badge }}</span>
227+
<Button
228+
v-if="!reorderable"
229+
variant="ghost"
230+
size="xs"
231+
icon="x"
232+
iconOnly
233+
inset
234+
class="opacity-100 [&_svg]:size-4"
235+
:aria-label="getClearFilterLabel(badge)"
236+
@click="setFilter(handle, null)"
237+
/>
238+
</Button>
208239
</div>
209240
</template>

0 commit comments

Comments
 (0)