diff --git a/desktop/src/components/browser/BrowserAddressBar.test.tsx b/desktop/src/components/browser/BrowserAddressBar.test.tsx
new file mode 100644
index 00000000..c82beed7
--- /dev/null
+++ b/desktop/src/components/browser/BrowserAddressBar.test.tsx
@@ -0,0 +1,37 @@
+import { fireEvent, render, screen } from '@testing-library/react'
+import { describe, expect, it, vi } from 'vitest'
+import '@testing-library/jest-dom'
+import { BrowserAddressBar } from './BrowserAddressBar'
+
+const baseProps = {
+ url: 'http://localhost:5173/', canGoBack: false, canGoForward: false,
+ onNavigate: vi.fn(), onBack: vi.fn(), onForward: vi.fn(), onReload: vi.fn(),
+}
+
+describe('BrowserAddressBar', () => {
+ it('shows the current url in the input', () => {
+ render()
+ expect(screen.getByRole('textbox')).toHaveValue('http://localhost:5173/')
+ })
+
+ it('submits the edited url via onNavigate', () => {
+ const onNavigate = vi.fn()
+ render()
+ const input = screen.getByRole('textbox')
+ fireEvent.change(input, { target: { value: 'http://localhost:3000/x' } })
+ fireEvent.submit(input.closest('form')!)
+ expect(onNavigate).toHaveBeenCalledWith('http://localhost:3000/x')
+ })
+
+ it('disables back when cannot go back', () => {
+ render()
+ expect(screen.getByLabelText('后退')).toBeDisabled()
+ })
+
+ it('enables back and fires onBack when canGoBack', () => {
+ const onBack = vi.fn()
+ render()
+ fireEvent.click(screen.getByLabelText('后退'))
+ expect(onBack).toHaveBeenCalled()
+ })
+})
diff --git a/desktop/src/components/browser/BrowserAddressBar.tsx b/desktop/src/components/browser/BrowserAddressBar.tsx
new file mode 100644
index 00000000..37776bc6
--- /dev/null
+++ b/desktop/src/components/browser/BrowserAddressBar.tsx
@@ -0,0 +1,33 @@
+import { useEffect, useState } from 'react'
+import { ArrowLeft, ArrowRight, RotateCw } from 'lucide-react'
+
+type Props = {
+ url: string
+ canGoBack: boolean
+ canGoForward: boolean
+ onNavigate: (url: string) => void
+ onBack: () => void
+ onForward: () => void
+ onReload: () => void
+}
+
+export function BrowserAddressBar({ url, canGoBack, canGoForward, onNavigate, onBack, onForward, onReload }: Props) {
+ const [draft, setDraft] = useState(url)
+ useEffect(() => { setDraft(url) }, [url])
+
+ return (
+
+ )
+}