Skip to content

Commit 64cf297

Browse files
authored
feat: Add internationalization support to MuxUploader (muxinc#1220)
Closes muxinc#1149 This PR adds the `locale` attribute to mux-uploader to specify the required language. **Supported locales:** - `'en'` (default if not set) - `'es'` (Spanish) - `'fr'` (French) - `'de'` (German) - `'pt'` (Portuguese) - `'it'` (Italian) - `'zh'` (Chinese) **Features:** - Automatic fallback to English for unsupported locales - Browser language detection when no locale is specified
1 parent 54f7793 commit 64cf297

25 files changed

+903
-22
lines changed

examples/nextjs-with-typescript/pages/MuxUploader.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Head from 'next/head';
22
import MuxUploader, { ProgressTypes } from '@mux/mux-uploader-react';
33
import type { MuxUploaderProps } from '@mux/mux-uploader-react';
4-
import { BooleanRenderer, EnumRenderer, NumberRenderer, URLRenderer } from '../components/renderers';
4+
import { BooleanRenderer, EnumRenderer, NumberRenderer, URLRenderer, TextRenderer } from '../components/renderers';
55
import ComponentCodeRenderer from '../components/ComponentCodeRenderer';
66
import URLPathRenderer from '../components/URLPathRenderer';
77
import { getLocationServerSideProps, usePageStateReducer } from '../app/page-state';
@@ -41,6 +41,7 @@ function MuxUploaderPage({ location }: Props) {
4141
noRetry={state.noRetry}
4242
pausable={state.pausable}
4343
type={state.type}
44+
locale={state.locale}
4445
dynamicChunkSize={state.dynamicChunkSize}
4546
useLargeFileWorkaround={state.useLargeFileWorkaround}
4647
maxFileSize={state.maxFileSize}
@@ -67,6 +68,7 @@ function MuxUploaderPage({ location }: Props) {
6768
<BooleanRenderer value={state.noRetry} name="noRetry" onChange={genericOnChange} />
6869
<BooleanRenderer value={state.pausable} name="pausable" onChange={genericOnChange} />
6970
<EnumRenderer value={state.type} values={ProgressTypesList} name="type" onChange={genericOnChange} />
71+
<TextRenderer value={state.locale} name="locale" onChange={genericOnChange} />
7072
<BooleanRenderer value={state.dynamicChunkSize} name="dynamicChunkSize" onChange={genericOnChange} />
7173
<BooleanRenderer
7274
value={state.useLargeFileWorkaround}

packages/mux-uploader-react/src/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export type MuxUploaderProps = {
3535
noStatus?: boolean;
3636
noRetry?: boolean;
3737
pausable?: boolean;
38+
locale?: string;
3839
style?: CSSProperties & {
3940
['--progress-bar-fill-color']?: CSSProperties['background'];
4041
['--progress-radial-fill-color']?: CSSProperties['stroke'];

packages/mux-uploader/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export * as constants from './constants';
2+
export { t } from './utils/i18n.js';
23
import MuxUploaderElement, { MuxUploaderElementEventMap } from './mux-uploader';
34
import MuxUploaderProgressElement from './mux-uploader-progress';
45
import MuxUploaderDropElement from './mux-uploader-drop';
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { TranslateDictionary } from './en.js';
2+
3+
export const De: TranslateDictionary = {
4+
'Drop a video file here to upload': 'Legen Sie hier eine Videodatei zum Hochladen ab',
5+
or: 'oder',
6+
'Upload complete!': 'Upload abgeschlossen!',
7+
Retry: 'Wiederholen',
8+
'Pausing...': 'Pausiere...',
9+
Resume: 'Fortsetzen',
10+
Pause: 'Pausieren',
11+
'Upload a video': 'Video hochladen',
12+
'No url or endpoint specified - cannot handle upload':
13+
'Keine URL oder Endpunkt angegeben - Upload kann nicht verarbeitet werden',
14+
};
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export const En = {
2+
'Drop a video file here to upload': 'Drop a video file here to upload',
3+
or: 'or',
4+
'Upload complete!': 'Upload complete!',
5+
Retry: 'Retry',
6+
'Pausing...': 'Pausing...',
7+
Resume: 'Resume',
8+
Pause: 'Pause',
9+
'Upload a video': 'Upload a video',
10+
'No url or endpoint specified - cannot handle upload': 'No url or endpoint specified - cannot handle upload',
11+
} as const;
12+
13+
export type TranslateKeys = keyof typeof En;
14+
15+
export type TranslateDictionary = {
16+
[key in TranslateKeys]: string;
17+
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { TranslateDictionary } from './en.js';
2+
3+
export const Es: TranslateDictionary = {
4+
'Drop a video file here to upload': 'Arrastra un archivo de video aquí para subir',
5+
or: 'o',
6+
'Upload complete!': '¡Subida completada!',
7+
Retry: 'Reintentar',
8+
'Pausing...': 'Pausando...',
9+
Resume: 'Reanudar',
10+
Pause: 'Pausar',
11+
'Upload a video': 'Subir un video',
12+
'No url or endpoint specified - cannot handle upload':
13+
'No se especificó URL o endpoint - no se puede manejar la subida',
14+
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { TranslateDictionary } from './en.js';
2+
3+
export const Fr: TranslateDictionary = {
4+
'Drop a video file here to upload': 'Déposez un fichier vidéo ici pour le télécharger',
5+
or: 'ou',
6+
'Upload complete!': 'Téléchargement terminé!',
7+
Retry: 'Réessayer',
8+
'Pausing...': 'En pause...',
9+
Resume: 'Reprendre',
10+
Pause: 'Pause',
11+
'Upload a video': 'Télécharger une vidéo',
12+
'No url or endpoint specified - cannot handle upload':
13+
'Aucune URL ou point de terminaison spécifié - impossible de gérer le téléchargement',
14+
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { TranslateDictionary } from './en.js';
2+
3+
export const It: TranslateDictionary = {
4+
'Drop a video file here to upload': 'Trascina qui un file video per caricarlo',
5+
or: 'o',
6+
'Upload complete!': 'Caricamento completato!',
7+
Retry: 'Riprova',
8+
'Pausing...': 'In pausa...',
9+
Resume: 'Riprendi',
10+
Pause: 'Pausa',
11+
'Upload a video': 'Carica un video',
12+
'No url or endpoint specified - cannot handle upload':
13+
'Nessun URL o endpoint specificato - impossibile gestire il caricamento',
14+
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { TranslateDictionary } from './en.js';
2+
3+
export const Pt: TranslateDictionary = {
4+
'Drop a video file here to upload': 'Arraste um arquivo de vídeo aqui para fazer o upload',
5+
or: 'ou',
6+
'Upload complete!': 'Upload completo!',
7+
Retry: 'Tentar novamente',
8+
'Pausing...': 'Pausando...',
9+
Resume: 'Retomar',
10+
Pause: 'Pausar',
11+
'Upload a video': 'Fazer upload de um vídeo',
12+
'No url or endpoint specified - cannot handle upload':
13+
'Nenhum URL ou endpoint especificado - não é possível processar o upload',
14+
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import type { TranslateDictionary } from './en.js';
2+
3+
export const Zh: TranslateDictionary = {
4+
'Drop a video file here to upload': '将视频文件拖放到此处以上传',
5+
or: '或',
6+
'Upload complete!': '上传完成!',
7+
Retry: '重试',
8+
'Pausing...': '暂停...',
9+
Resume: '继续',
10+
Pause: '暂停',
11+
'Upload a video': '上传视频',
12+
'No url or endpoint specified - cannot handle upload': '未指定 URL 或 endpoint - 无法处理上传',
13+
};

0 commit comments

Comments
 (0)