From e66c2e508c260f4c2ac65a884bd81d173df933b8 Mon Sep 17 00:00:00 2001 From: Jasper Van Date: Wed, 8 Apr 2026 21:40:41 -0400 Subject: [PATCH] feat(web): complete i18n coverage for UI primitives (#268) Replace hardcoded strings in dialog, sheet, and sidebar components with t() calls. Adds common.close, common.sidebar, common.sidebarDescription, and common.toggleSidebar keys to both en.json and zh.json. All 124 keys now have parity across locales. Agent-Profile: https://agent-kanban.dev/agents/b724a773425e397c --- packages/web/src/components/ui/dialog.tsx | 7 +- packages/web/src/components/ui/sheet.tsx | 4 +- packages/web/src/components/ui/sidebar.tsx | 14 +- packages/web/src/i18n/common-locale.test.ts | 142 ++++++++++++++++++++ packages/web/src/i18n/locales/en.json | 6 +- packages/web/src/i18n/locales/zh.json | 6 +- 6 files changed, 169 insertions(+), 10 deletions(-) create mode 100644 packages/web/src/i18n/common-locale.test.ts diff --git a/packages/web/src/components/ui/dialog.tsx b/packages/web/src/components/ui/dialog.tsx index bad0fd7b..89e04ce4 100644 --- a/packages/web/src/components/ui/dialog.tsx +++ b/packages/web/src/components/ui/dialog.tsx @@ -1,6 +1,7 @@ import { XIcon } from 'lucide-react' import { Dialog as DialogPrimitive } from 'radix-ui' import type * as React from 'react' +import { useTranslation } from 'react-i18next' import { Button } from '@/components/ui/button' import { cn } from '@/lib/utils' @@ -41,6 +42,7 @@ function DialogContent({ }: React.ComponentProps & { showCloseButton?: boolean }) { + const { t } = useTranslation() return ( @@ -59,7 +61,7 @@ function DialogContent({ className="absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4" > - Close + {t('common.close')} )} @@ -85,6 +87,7 @@ function DialogFooter({ }: React.ComponentProps<'div'> & { showCloseButton?: boolean }) { + const { t } = useTranslation() return (
- + )}
diff --git a/packages/web/src/components/ui/sheet.tsx b/packages/web/src/components/ui/sheet.tsx index f2b3f908..1f3dd535 100644 --- a/packages/web/src/components/ui/sheet.tsx +++ b/packages/web/src/components/ui/sheet.tsx @@ -3,6 +3,7 @@ import { XIcon } from 'lucide-react' import { Dialog as SheetPrimitive } from 'radix-ui' import type * as React from 'react' +import { useTranslation } from 'react-i18next' import { cn } from '@/lib/utils' @@ -45,6 +46,7 @@ function SheetContent({ side?: 'top' | 'right' | 'bottom' | 'left' showCloseButton?: boolean }) { + const { t } = useTranslation() return ( @@ -68,7 +70,7 @@ function SheetContent({ {showCloseButton && ( - Close + {t('common.close')} )} diff --git a/packages/web/src/components/ui/sidebar.tsx b/packages/web/src/components/ui/sidebar.tsx index 8fc08cdd..ba2def38 100644 --- a/packages/web/src/components/ui/sidebar.tsx +++ b/packages/web/src/components/ui/sidebar.tsx @@ -2,6 +2,7 @@ import { cva, type VariantProps } from 'class-variance-authority' import { PanelLeftIcon } from 'lucide-react' import { Slot } from 'radix-ui' import * as React from 'react' +import { useTranslation } from 'react-i18next' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Separator } from '@/components/ui/separator' @@ -144,6 +145,7 @@ function Sidebar({ collapsible?: 'offcanvas' | 'icon' | 'none' }) { const { isMobile, state, openMobile, setOpenMobile } = useSidebar() + const { t } = useTranslation() if (collapsible === 'none') { return ( @@ -173,8 +175,8 @@ function Sidebar({ side={side} > - Sidebar - Displays the mobile sidebar. + {t('common.sidebar')} + {t('common.sidebarDescription')}
{children}
@@ -232,6 +234,7 @@ function Sidebar({ function SidebarTrigger({ className, onClick, ...props }: React.ComponentProps) { const { toggleSidebar } = useSidebar() + const { t } = useTranslation() return ( ) } function SidebarRail({ className, ...props }: React.ComponentProps<'button'>) { const { toggleSidebar } = useSidebar() + const { t } = useTranslation() return (