feat(ui): add framework-neutral localization support
- add a lightweight UI i18n provider with translation and locale contexts\n- localize accessibility labels across breadcrumb, carousel, dialog, pagination, sheet, sidebar, spinner, and toast components\n- integrate calendar locale data without coupling UI components to Lingui\n- publish tree-shakeable catalogs for eight common locales
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
export const uiCatalogLocales = [
|
||||
"de",
|
||||
"en",
|
||||
"es",
|
||||
"fr",
|
||||
"ja",
|
||||
"ko",
|
||||
"zh-Hans",
|
||||
"zh-Hant",
|
||||
] as const
|
||||
|
||||
export const uiMessageIds = [
|
||||
"ui.breadcrumb.label",
|
||||
"ui.carousel.nextSlide",
|
||||
"ui.carousel.previousSlide",
|
||||
"ui.common.close",
|
||||
"ui.common.loading",
|
||||
"ui.common.more",
|
||||
"ui.pagination.label",
|
||||
"ui.pagination.more",
|
||||
"ui.pagination.next",
|
||||
"ui.pagination.nextPage",
|
||||
"ui.pagination.previous",
|
||||
"ui.pagination.previousPage",
|
||||
"ui.sidebar.description",
|
||||
"ui.sidebar.title",
|
||||
"ui.sidebar.toggle",
|
||||
"ui.toast.close",
|
||||
] as const
|
||||
|
||||
export type UiCatalogLocale = (typeof uiCatalogLocales)[number]
|
||||
export type UiMessageId = (typeof uiMessageIds)[number]
|
||||
export type UiMessageCatalog = Readonly<Record<UiMessageId, string>>
|
||||
@@ -0,0 +1,25 @@
|
||||
export { de as calendarLocale } from "react-day-picker/locale/de"
|
||||
|
||||
import type { UiMessageCatalog } from "../catalogs"
|
||||
|
||||
export const locale = "de"
|
||||
export const languageTag = "de-DE"
|
||||
|
||||
export const messages = {
|
||||
"ui.breadcrumb.label": "Breadcrumb-Navigation",
|
||||
"ui.carousel.nextSlide": "Nächste Folie",
|
||||
"ui.carousel.previousSlide": "Vorherige Folie",
|
||||
"ui.common.close": "Schließen",
|
||||
"ui.common.loading": "Wird geladen",
|
||||
"ui.common.more": "Mehr",
|
||||
"ui.pagination.label": "Seitennavigation",
|
||||
"ui.pagination.more": "Weitere Seiten",
|
||||
"ui.pagination.next": "Weiter",
|
||||
"ui.pagination.nextPage": "Zur nächsten Seite",
|
||||
"ui.pagination.previous": "Zurück",
|
||||
"ui.pagination.previousPage": "Zur vorherigen Seite",
|
||||
"ui.sidebar.description": "Zeigt die mobile Seitenleiste an.",
|
||||
"ui.sidebar.title": "Seitenleiste",
|
||||
"ui.sidebar.toggle": "Seitenleiste umschalten",
|
||||
"ui.toast.close": "Benachrichtigung schließen",
|
||||
} as const satisfies UiMessageCatalog
|
||||
@@ -0,0 +1,25 @@
|
||||
export { enUS as calendarLocale } from "react-day-picker/locale/en-US"
|
||||
|
||||
import type { UiMessageCatalog } from "../catalogs"
|
||||
|
||||
export const locale = "en"
|
||||
export const languageTag = "en-US"
|
||||
|
||||
export const messages = {
|
||||
"ui.breadcrumb.label": "Breadcrumb",
|
||||
"ui.carousel.nextSlide": "Next slide",
|
||||
"ui.carousel.previousSlide": "Previous slide",
|
||||
"ui.common.close": "Close",
|
||||
"ui.common.loading": "Loading",
|
||||
"ui.common.more": "More",
|
||||
"ui.pagination.label": "Pagination",
|
||||
"ui.pagination.more": "More pages",
|
||||
"ui.pagination.next": "Next",
|
||||
"ui.pagination.nextPage": "Go to next page",
|
||||
"ui.pagination.previous": "Previous",
|
||||
"ui.pagination.previousPage": "Go to previous page",
|
||||
"ui.sidebar.description": "Displays the mobile sidebar.",
|
||||
"ui.sidebar.title": "Sidebar",
|
||||
"ui.sidebar.toggle": "Toggle sidebar",
|
||||
"ui.toast.close": "Close notification",
|
||||
} as const satisfies UiMessageCatalog
|
||||
@@ -0,0 +1,25 @@
|
||||
export { es as calendarLocale } from "react-day-picker/locale/es"
|
||||
|
||||
import type { UiMessageCatalog } from "../catalogs"
|
||||
|
||||
export const locale = "es"
|
||||
export const languageTag = "es-ES"
|
||||
|
||||
export const messages = {
|
||||
"ui.breadcrumb.label": "Ruta de navegación",
|
||||
"ui.carousel.nextSlide": "Diapositiva siguiente",
|
||||
"ui.carousel.previousSlide": "Diapositiva anterior",
|
||||
"ui.common.close": "Cerrar",
|
||||
"ui.common.loading": "Cargando",
|
||||
"ui.common.more": "Más",
|
||||
"ui.pagination.label": "Paginación",
|
||||
"ui.pagination.more": "Más páginas",
|
||||
"ui.pagination.next": "Siguiente",
|
||||
"ui.pagination.nextPage": "Ir a la página siguiente",
|
||||
"ui.pagination.previous": "Anterior",
|
||||
"ui.pagination.previousPage": "Ir a la página anterior",
|
||||
"ui.sidebar.description": "Muestra la barra lateral móvil.",
|
||||
"ui.sidebar.title": "Barra lateral",
|
||||
"ui.sidebar.toggle": "Alternar barra lateral",
|
||||
"ui.toast.close": "Cerrar notificación",
|
||||
} as const satisfies UiMessageCatalog
|
||||
@@ -0,0 +1,25 @@
|
||||
export { fr as calendarLocale } from "react-day-picker/locale/fr"
|
||||
|
||||
import type { UiMessageCatalog } from "../catalogs"
|
||||
|
||||
export const locale = "fr"
|
||||
export const languageTag = "fr-FR"
|
||||
|
||||
export const messages = {
|
||||
"ui.breadcrumb.label": "Fil d’Ariane",
|
||||
"ui.carousel.nextSlide": "Diapositive suivante",
|
||||
"ui.carousel.previousSlide": "Diapositive précédente",
|
||||
"ui.common.close": "Fermer",
|
||||
"ui.common.loading": "Chargement",
|
||||
"ui.common.more": "Plus",
|
||||
"ui.pagination.label": "Pagination",
|
||||
"ui.pagination.more": "Plus de pages",
|
||||
"ui.pagination.next": "Suivant",
|
||||
"ui.pagination.nextPage": "Aller à la page suivante",
|
||||
"ui.pagination.previous": "Précédent",
|
||||
"ui.pagination.previousPage": "Aller à la page précédente",
|
||||
"ui.sidebar.description": "Affiche la barre latérale mobile.",
|
||||
"ui.sidebar.title": "Barre latérale",
|
||||
"ui.sidebar.toggle": "Afficher ou masquer la barre latérale",
|
||||
"ui.toast.close": "Fermer la notification",
|
||||
} as const satisfies UiMessageCatalog
|
||||
@@ -0,0 +1,25 @@
|
||||
export { ja as calendarLocale } from "react-day-picker/locale/ja"
|
||||
|
||||
import type { UiMessageCatalog } from "../catalogs"
|
||||
|
||||
export const locale = "ja"
|
||||
export const languageTag = "ja-JP"
|
||||
|
||||
export const messages = {
|
||||
"ui.breadcrumb.label": "パンくずリスト",
|
||||
"ui.carousel.nextSlide": "次のスライド",
|
||||
"ui.carousel.previousSlide": "前のスライド",
|
||||
"ui.common.close": "閉じる",
|
||||
"ui.common.loading": "読み込み中",
|
||||
"ui.common.more": "その他",
|
||||
"ui.pagination.label": "ページネーション",
|
||||
"ui.pagination.more": "その他のページ",
|
||||
"ui.pagination.next": "次へ",
|
||||
"ui.pagination.nextPage": "次のページへ移動",
|
||||
"ui.pagination.previous": "前へ",
|
||||
"ui.pagination.previousPage": "前のページへ移動",
|
||||
"ui.sidebar.description": "モバイルサイドバーを表示します。",
|
||||
"ui.sidebar.title": "サイドバー",
|
||||
"ui.sidebar.toggle": "サイドバーを切り替える",
|
||||
"ui.toast.close": "通知を閉じる",
|
||||
} as const satisfies UiMessageCatalog
|
||||
@@ -0,0 +1,25 @@
|
||||
export { ko as calendarLocale } from "react-day-picker/locale/ko"
|
||||
|
||||
import type { UiMessageCatalog } from "../catalogs"
|
||||
|
||||
export const locale = "ko"
|
||||
export const languageTag = "ko-KR"
|
||||
|
||||
export const messages = {
|
||||
"ui.breadcrumb.label": "이동 경로",
|
||||
"ui.carousel.nextSlide": "다음 슬라이드",
|
||||
"ui.carousel.previousSlide": "이전 슬라이드",
|
||||
"ui.common.close": "닫기",
|
||||
"ui.common.loading": "불러오는 중",
|
||||
"ui.common.more": "더 보기",
|
||||
"ui.pagination.label": "페이지 탐색",
|
||||
"ui.pagination.more": "더 많은 페이지",
|
||||
"ui.pagination.next": "다음",
|
||||
"ui.pagination.nextPage": "다음 페이지로 이동",
|
||||
"ui.pagination.previous": "이전",
|
||||
"ui.pagination.previousPage": "이전 페이지로 이동",
|
||||
"ui.sidebar.description": "모바일 사이드바를 표시합니다.",
|
||||
"ui.sidebar.title": "사이드바",
|
||||
"ui.sidebar.toggle": "사이드바 전환",
|
||||
"ui.toast.close": "알림 닫기",
|
||||
} as const satisfies UiMessageCatalog
|
||||
@@ -0,0 +1,25 @@
|
||||
export { zhCN as calendarLocale } from "react-day-picker/locale/zh-CN"
|
||||
|
||||
import type { UiMessageCatalog } from "../catalogs"
|
||||
|
||||
export const locale = "zh-Hans"
|
||||
export const languageTag = "zh-CN"
|
||||
|
||||
export const messages = {
|
||||
"ui.breadcrumb.label": "面包屑导航",
|
||||
"ui.carousel.nextSlide": "下一张",
|
||||
"ui.carousel.previousSlide": "上一张",
|
||||
"ui.common.close": "关闭",
|
||||
"ui.common.loading": "正在加载",
|
||||
"ui.common.more": "更多",
|
||||
"ui.pagination.label": "分页导航",
|
||||
"ui.pagination.more": "更多页面",
|
||||
"ui.pagination.next": "下一页",
|
||||
"ui.pagination.nextPage": "前往下一页",
|
||||
"ui.pagination.previous": "上一页",
|
||||
"ui.pagination.previousPage": "前往上一页",
|
||||
"ui.sidebar.description": "显示移动端侧栏。",
|
||||
"ui.sidebar.title": "侧栏",
|
||||
"ui.sidebar.toggle": "切换侧栏",
|
||||
"ui.toast.close": "关闭通知",
|
||||
} as const satisfies UiMessageCatalog
|
||||
@@ -0,0 +1,25 @@
|
||||
export { zhTW as calendarLocale } from "react-day-picker/locale/zh-TW"
|
||||
|
||||
import type { UiMessageCatalog } from "../catalogs"
|
||||
|
||||
export const locale = "zh-Hant"
|
||||
export const languageTag = "zh-TW"
|
||||
|
||||
export const messages = {
|
||||
"ui.breadcrumb.label": "麵包屑導覽",
|
||||
"ui.carousel.nextSlide": "下一張",
|
||||
"ui.carousel.previousSlide": "上一張",
|
||||
"ui.common.close": "關閉",
|
||||
"ui.common.loading": "載入中",
|
||||
"ui.common.more": "更多",
|
||||
"ui.pagination.label": "分頁導覽",
|
||||
"ui.pagination.more": "更多頁面",
|
||||
"ui.pagination.next": "下一頁",
|
||||
"ui.pagination.nextPage": "前往下一頁",
|
||||
"ui.pagination.previous": "上一頁",
|
||||
"ui.pagination.previousPage": "前往上一頁",
|
||||
"ui.sidebar.description": "顯示行動版側欄。",
|
||||
"ui.sidebar.title": "側欄",
|
||||
"ui.sidebar.toggle": "切換側欄",
|
||||
"ui.toast.close": "關閉通知",
|
||||
} as const satisfies UiMessageCatalog
|
||||
Reference in New Issue
Block a user