diff --git a/frontend/src/lib/components/SortDropdown.svelte b/frontend/src/lib/components/SortDropdown.svelte
new file mode 100644
index 00000000..abc7012b
--- /dev/null
+++ b/frontend/src/lib/components/SortDropdown.svelte
@@ -0,0 +1,36 @@
+
+
+
+
+
+
diff --git a/frontend/src/lib/components/SortDropdown.svelte.spec.ts b/frontend/src/lib/components/SortDropdown.svelte.spec.ts
new file mode 100644
index 00000000..2c4282a8
--- /dev/null
+++ b/frontend/src/lib/components/SortDropdown.svelte.spec.ts
@@ -0,0 +1,36 @@
+import { render } from 'vitest-browser-svelte';
+import { describe, expect, it } from 'vitest';
+import { page } from '@vitest/browser/context';
+import SortDropdown from './SortDropdown.svelte';
+
+describe('SortDropdown', () => {
+ it('renders a select with all sort options', async () => {
+ render(SortDropdown, { sort: 'DATE', dir: 'desc' });
+ const select = page.getByRole('combobox');
+ await expect.element(select).toBeInTheDocument();
+ });
+
+ it('shows the current sort value as selected', async () => {
+ render(SortDropdown, { sort: 'TITLE', dir: 'asc' });
+ const select = page.getByRole('combobox');
+ await expect.element(select).toHaveValue('TITLE');
+ });
+
+ it('renders direction toggle button', async () => {
+ render(SortDropdown, { sort: 'DATE', dir: 'asc' });
+ const btn = page.getByRole('button');
+ await expect.element(btn).toBeInTheDocument();
+ });
+
+ it('direction button shows ↑ when dir is asc', async () => {
+ render(SortDropdown, { sort: 'DATE', dir: 'asc' });
+ const btn = page.getByRole('button');
+ await expect.element(btn).toHaveTextContent('↑');
+ });
+
+ it('direction button shows ↓ when dir is desc', async () => {
+ render(SortDropdown, { sort: 'DATE', dir: 'desc' });
+ const btn = page.getByRole('button');
+ await expect.element(btn).toHaveTextContent('↓');
+ });
+});