feat(sidebar): refine active connection filter indicator

This commit is contained in:
zipg authored and GitHub committed 2026-08-26 00:25:10 +08:00
1 parent 1c2e5bb07c
commit 2a2357e2f1
2 files changed
+15 -10

No files matched your search

@@ -1,7 +1,6 @@
<script setup lang="ts">
import { useId } from "vue";
import { useI18n } from "vue-i18n";
import { CircleDot } from "@lucide/vue";
import LightTooltip from "@/components/ui/LightTooltip.vue";
defineProps<{
@@ -29,8 +28,12 @@ const activeConnectionStatusId = useId();
:aria-pressed="pressed"
@click="emit('toggle')"
>
<CircleDot data-active-connection-filter-icon class="h-3.5 w-3.5" />
<span v-if="activeConnectionCount > 0" data-active-connection-badge class="pointer-events-none absolute right-0.5 top-0.5 h-1.5 w-1.5 rounded-full bg-green-500 ring-1 ring-background" aria-hidden="true" />
<span
data-active-connection-filter-icon
class="pointer-events-none absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full border-[1.5px] transition-[width,height,border-color,background-color] duration-200 ease-out"
:class="activeConnectionCount > 0 ? 'h-1.5 w-1.5 border-green-500 bg-green-500' : 'h-3 w-3 border-current bg-transparent'"
aria-hidden="true"
/>
<span :id="activeConnectionStatusId" class="sr-only" aria-live="polite" aria-atomic="true">{{ t("sidebar.activeConnectionsStatus", { count: activeConnectionCount }) }}</span>
</button>
</LightTooltip>
@@ -71,23 +71,25 @@ afterEach(() => {
});
describe("ActiveConnectionFilterButton", () => {
it("keeps the filter icon stable while the active connection status changes from 0 to 1 to 0", async () => {
it("morphs the centered indicator as the active connection status changes from 0 to 1 to 0", async () => {
const { button, state } = await mountFilter(0);
expect(button.querySelector("[data-active-connection-filter-icon]")).not.toBeNull();
expect(button.querySelector("[data-active-connection-badge]")).toBeNull();
const indicator = button.querySelector("[data-active-connection-filter-icon]");
expect(indicator).not.toBeNull();
expect(indicator?.className).toContain("left-1/2 top-1/2");
expect(indicator?.className).toContain("h-3 w-3 border-current bg-transparent");
expect(describedStatus(button).textContent).toBe("Active connections: 0");
state.activeConnectionCount = 1;
await nextTick();
expect(button.querySelector("[data-active-connection-filter-icon]")).not.toBeNull();
expect(button.querySelector("[data-active-connection-badge]")).not.toBeNull();
expect(button.querySelector("[data-active-connection-filter-icon]")).toBe(indicator);
expect(indicator?.className).toContain("h-1.5 w-1.5 border-green-500 bg-green-500");
expect(describedStatus(button).textContent).toBe("Active connections: 1");
state.activeConnectionCount = 0;
await nextTick();
expect(button.querySelector("[data-active-connection-filter-icon]")).not.toBeNull();
expect(button.querySelector("[data-active-connection-badge]")).toBeNull();
expect(button.querySelector("[data-active-connection-filter-icon]")).toBe(indicator);
expect(indicator?.className).toContain("h-3 w-3 border-current bg-transparent");
expect(describedStatus(button).textContent).toBe("Active connections: 0");
});