mirror of
https://github.com/block/buzz.git
synced 2026-10-27 04:30:52 +00:00
feat(desktop): show selected community in rail (#5000)
## Summary - add a persistent vertical pill beside the active community - keep the selected state visually distinct from unread dots and mention badges - preserve the existing `aria-current` selection semantics ## Screenshot  ## Test plan - `pnpm exec biome check src/features/sidebar/ui/CommunityRail.tsx tests/e2e/community-rail.spec.ts` - `pnpm test` (4,387 passed) - `pnpm build:e2e && pnpm exec playwright test tests/e2e/community-rail.spec.ts --project=smoke` (20 passed) - pre-push hooks: desktop check and 4,387 desktop tests passed on `c1e80c66d12f73c4eb5c03a19e932439b14caf2d` Signed-off-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
This commit is contained in:
@@ -133,10 +133,17 @@ function CommunityButton({
|
|||||||
{...dragAttributes}
|
{...dragAttributes}
|
||||||
{...dragListeners}
|
{...dragListeners}
|
||||||
>
|
>
|
||||||
|
{isActive ? (
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
className="absolute -left-2.5 h-5 w-1 rounded-r-full bg-primary"
|
||||||
|
data-testid={`community-rail-active-${community.id}`}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
<span
|
<span
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex h-9 w-9 items-center justify-center overflow-hidden rounded-xl bg-sidebar-accent/60 text-xs font-semibold text-sidebar-foreground/80 outline-2 outline-offset-2 outline-primary/0 transition-[outline-color]",
|
"flex h-9 w-9 items-center justify-center overflow-hidden rounded-xl bg-sidebar-accent/60 text-xs font-semibold text-sidebar-foreground/80 outline-2 outline-offset-2 outline-primary/0 transition-[outline-color]",
|
||||||
isActive ? "outline-primary" : "hover:outline-primary/50",
|
!isActive && "hover:outline-primary/50",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{iconUrl ? (
|
{iconUrl ? (
|
||||||
|
|||||||
@@ -66,13 +66,21 @@ test.describe("community rail", () => {
|
|||||||
await expect(buttonA).toBeVisible();
|
await expect(buttonA).toBeVisible();
|
||||||
await expect(buttonB).toBeVisible();
|
await expect(buttonB).toBeVisible();
|
||||||
|
|
||||||
// The active community is marked via aria-current.
|
// The active community is marked semantically and with a persistent rail.
|
||||||
await expect(buttonA).toHaveAttribute("aria-current", "true");
|
await expect(buttonA).toHaveAttribute("aria-current", "true");
|
||||||
await expect(buttonB).not.toHaveAttribute("aria-current", "true");
|
await expect(buttonB).not.toHaveAttribute("aria-current", "true");
|
||||||
await expect(buttonA.locator(":scope > span").first()).toHaveCSS(
|
const activeIndicator = page.getByTestId(
|
||||||
"opacity",
|
`community-rail-active-${COMMUNITY_A.id}`,
|
||||||
"1",
|
|
||||||
);
|
);
|
||||||
|
await expect(activeIndicator).toBeVisible();
|
||||||
|
await expect(
|
||||||
|
page.getByTestId(`community-rail-active-${COMMUNITY_B.id}`),
|
||||||
|
).toHaveCount(0);
|
||||||
|
await expect(activeIndicator).toHaveCSS("height", "20px");
|
||||||
|
await expect(activeIndicator).toHaveCSS("width", "4px");
|
||||||
|
await expect(
|
||||||
|
buttonA.locator(":scope > span:not([data-testid])").first(),
|
||||||
|
).toHaveCSS("opacity", "1");
|
||||||
await expect(buttonB.locator(":scope > span").first()).toHaveCSS(
|
await expect(buttonB.locator(":scope > span").first()).toHaveCSS(
|
||||||
"opacity",
|
"opacity",
|
||||||
"1",
|
"1",
|
||||||
@@ -80,7 +88,7 @@ test.describe("community rail", () => {
|
|||||||
const [activeStyle, inactiveStyle] = await Promise.all(
|
const [activeStyle, inactiveStyle] = await Promise.all(
|
||||||
[buttonA, buttonB].map((button) =>
|
[buttonA, buttonB].map((button) =>
|
||||||
button
|
button
|
||||||
.locator(":scope > span")
|
.locator(":scope > span:not([data-testid])")
|
||||||
.first()
|
.first()
|
||||||
.evaluate((element) => {
|
.evaluate((element) => {
|
||||||
const style = getComputedStyle(element);
|
const style = getComputedStyle(element);
|
||||||
@@ -88,6 +96,7 @@ test.describe("community rail", () => {
|
|||||||
backgroundColor: style.backgroundColor,
|
backgroundColor: style.backgroundColor,
|
||||||
borderRadius: style.borderRadius,
|
borderRadius: style.borderRadius,
|
||||||
color: style.color,
|
color: style.color,
|
||||||
|
outlineColor: style.outlineColor,
|
||||||
outlineStyle: style.outlineStyle,
|
outlineStyle: style.outlineStyle,
|
||||||
outlineWidth: style.outlineWidth,
|
outlineWidth: style.outlineWidth,
|
||||||
};
|
};
|
||||||
@@ -98,6 +107,7 @@ test.describe("community rail", () => {
|
|||||||
expect(activeStyle.borderRadius).toBe(inactiveStyle.borderRadius);
|
expect(activeStyle.borderRadius).toBe(inactiveStyle.borderRadius);
|
||||||
expect(activeStyle.borderRadius).toBe("12px");
|
expect(activeStyle.borderRadius).toBe("12px");
|
||||||
expect(activeStyle.color).toBe(inactiveStyle.color);
|
expect(activeStyle.color).toBe(inactiveStyle.color);
|
||||||
|
expect(activeStyle.outlineColor).toBe(inactiveStyle.outlineColor);
|
||||||
expect(activeStyle.outlineStyle).toBe("solid");
|
expect(activeStyle.outlineStyle).toBe("solid");
|
||||||
expect(activeStyle.outlineWidth).toBe("2px");
|
expect(activeStyle.outlineWidth).toBe("2px");
|
||||||
expect(inactiveStyle.outlineStyle).toBe("solid");
|
expect(inactiveStyle.outlineStyle).toBe("solid");
|
||||||
|
|||||||
Reference in New Issue
Block a user