refactor(#81): replace nudge button with always-visible count badge
Show the discussion count badge on every state (including 0) instead of a separate nudge button. Simpler, less intrusive, and works without needing an extra element near the panel. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -107,7 +107,7 @@ function handleCountChange(count: number) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="fixed relative right-0 bottom-0 left-0 z-30 flex flex-col border-t border-line bg-surface shadow-[0_-4px_16px_rgba(0,0,0,0.08)]"
|
class="fixed right-0 bottom-0 left-0 z-30 flex flex-col border-t border-line bg-surface shadow-[0_-4px_16px_rgba(0,0,0,0.08)]"
|
||||||
style="height: {panelHeight}px"
|
style="height: {panelHeight}px"
|
||||||
data-testid="bottom-panel"
|
data-testid="bottom-panel"
|
||||||
>
|
>
|
||||||
@@ -126,15 +126,6 @@ function handleCountChange(count: number) {
|
|||||||
<div class="h-1 w-12 rounded-full bg-line"></div>
|
<div class="h-1 w-12 rounded-full bg-line"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if !open && discussionCount === 0}
|
|
||||||
<button
|
|
||||||
data-testid="discussion-nudge"
|
|
||||||
onclick={() => openTab('discussion')}
|
|
||||||
class="absolute -top-7 left-1/2 -translate-x-1/2 rounded-full border border-line bg-surface px-3 py-1 font-sans text-xs whitespace-nowrap text-ink-3 shadow-sm transition-colors hover:text-ink"
|
|
||||||
>{m.comment_start_discussion()}</button
|
|
||||||
>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<!-- Tab bar -->
|
<!-- Tab bar -->
|
||||||
<div class="flex shrink-0 items-center border-b border-line bg-surface px-4">
|
<div class="flex shrink-0 items-center border-b border-line bg-surface px-4">
|
||||||
{#each tabs as tab (tab.id)}
|
{#each tabs as tab (tab.id)}
|
||||||
@@ -146,7 +137,7 @@ function handleCountChange(count: number) {
|
|||||||
aria-pressed={activeTab === tab.id && open}
|
aria-pressed={activeTab === tab.id && open}
|
||||||
>
|
>
|
||||||
{tab.label()}
|
{tab.label()}
|
||||||
{#if tab.id === 'discussion' && discussionCount > 0}
|
{#if tab.id === 'discussion'}
|
||||||
<span
|
<span
|
||||||
data-testid="discussion-count-badge"
|
data-testid="discussion-count-badge"
|
||||||
class="ml-1.5 inline-flex h-4 min-w-4 items-center justify-center rounded-full bg-primary px-1 font-sans text-[10px] font-bold text-white"
|
class="ml-1.5 inline-flex h-4 min-w-4 items-center justify-center rounded-full bg-primary px-1 font-sans text-[10px] font-bold text-white"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { describe, it, expect, afterEach } from 'vitest';
|
import { describe, it, expect, afterEach } from 'vitest';
|
||||||
import { cleanup, render } from 'vitest-browser-svelte';
|
import { cleanup, render } from 'vitest-browser-svelte';
|
||||||
import { page, userEvent } from 'vitest/browser';
|
import { page } from 'vitest/browser';
|
||||||
import DocumentBottomPanel from './DocumentBottomPanel.svelte';
|
import DocumentBottomPanel from './DocumentBottomPanel.svelte';
|
||||||
import type { Comment } from '$lib/types';
|
import type { Comment } from '$lib/types';
|
||||||
|
|
||||||
@@ -30,45 +30,18 @@ const baseProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
describe('DocumentBottomPanel – discussion badge', () => {
|
describe('DocumentBottomPanel – discussion badge', () => {
|
||||||
it('shows a badge with comment count on the Discussion tab when comments exist', async () => {
|
it('always shows a badge on the Discussion tab', async () => {
|
||||||
|
render(DocumentBottomPanel, { ...baseProps, comments: [], open: true });
|
||||||
|
await expect.element(page.getByTestId('discussion-count-badge')).toBeInTheDocument();
|
||||||
|
await expect.element(page.getByTestId('discussion-count-badge')).toHaveTextContent('0');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows the correct count when comments exist', async () => {
|
||||||
render(DocumentBottomPanel, {
|
render(DocumentBottomPanel, {
|
||||||
...baseProps,
|
...baseProps,
|
||||||
comments: [makeComment('c-1'), makeComment('c-2')],
|
comments: [makeComment('c-1'), makeComment('c-2')],
|
||||||
open: true
|
open: true
|
||||||
});
|
});
|
||||||
await expect.element(page.getByTestId('discussion-count-badge')).toBeInTheDocument();
|
|
||||||
await expect.element(page.getByTestId('discussion-count-badge')).toHaveTextContent('2');
|
await expect.element(page.getByTestId('discussion-count-badge')).toHaveTextContent('2');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not show badge when there are no comments', async () => {
|
|
||||||
render(DocumentBottomPanel, { ...baseProps, comments: [], open: true });
|
|
||||||
await expect.element(page.getByTestId('discussion-count-badge')).not.toBeInTheDocument();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('DocumentBottomPanel – start discussion nudge', () => {
|
|
||||||
it('shows nudge above drag handle when panel is closed and no comments', async () => {
|
|
||||||
render(DocumentBottomPanel, { ...baseProps, comments: [], open: false });
|
|
||||||
await expect.element(page.getByTestId('discussion-nudge')).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not show nudge when panel is closed but comments exist', async () => {
|
|
||||||
render(DocumentBottomPanel, {
|
|
||||||
...baseProps,
|
|
||||||
comments: [makeComment('c-1')],
|
|
||||||
open: false
|
|
||||||
});
|
|
||||||
await expect.element(page.getByTestId('discussion-nudge')).not.toBeInTheDocument();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not show nudge when panel is open', async () => {
|
|
||||||
render(DocumentBottomPanel, { ...baseProps, comments: [], open: true });
|
|
||||||
await expect.element(page.getByTestId('discussion-nudge')).not.toBeInTheDocument();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('opens the discussion tab when the nudge is clicked', async () => {
|
|
||||||
render(DocumentBottomPanel, { ...baseProps, comments: [], open: false });
|
|
||||||
await userEvent.click(page.getByTestId('discussion-nudge'));
|
|
||||||
await expect.element(page.getByTestId('bottom-panel-content')).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user