Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 32 additions & 3 deletions __tests__/avatarLocale.spec.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { describe, expect, it } from 'vitest'

import { normalizeAvatarLocale, translateAvatarText } from '../src/avatarLocale'
import { hasAvatarTranslation, normalizeAvatarLocale, translateAvatarText } from '../src/avatarLocale'
import { AVATAR_FACE_PRESETS } from '../src/avatarFacePresets'
import { AVATAR_ANIMAL_BREED_TEMPLATES } from '../src/avatarSpeciesBreeds'

describe('avatar locale', () => {
it('normalizes supported English and Simplified Chinese locale variants', () => {
it('normalizes supported English, Simplified Chinese, and French locale variants', () => {
expect(normalizeAvatarLocale('en')).toBe('en')
expect(normalizeAvatarLocale('zh-CN')).toBe('zh-Hans')
expect(normalizeAvatarLocale('zh-Hans')).toBe('zh-Hans')
expect(normalizeAvatarLocale('fr')).toBeNull()
expect(normalizeAvatarLocale('fr')).toBe('fr')
expect(normalizeAvatarLocale('fr-FR')).toBe('fr')
expect(normalizeAvatarLocale('de')).toBeNull()
})

it('translates known labels and preserves unknown text', () => {
Expand Down Expand Up @@ -88,6 +90,21 @@ describe('avatar locale', () => {
expect(translateAvatarText('zh-Hans', 'Custom animation name')).toBe('Custom animation name')
})

it('translates known labels to French and preserves unknown text', () => {
expect(translateAvatarText('fr', 'Effects')).toBe('Effets')
expect(translateAvatarText('fr', 'Download PNG')).toBe('Télécharger le PNG')
expect(translateAvatarText('fr', 'Transparent')).toBe('Transparent')
expect(translateAvatarText('fr', 'Bring your avatar to life')).toBe('Donnez vie à votre avatar')
expect(translateAvatarText('fr', 'Start creating')).toBe('Commencer à créer')
expect(translateAvatarText('fr', 'Dog')).toBe('Chien')
expect(translateAvatarText('fr', 'Fox')).toBe('Renard')
expect(translateAvatarText('fr', 'Fox types')).toBe('Types de renards')
expect(translateAvatarText('fr', 'Red Fox')).toBe('Renard roux')
expect(translateAvatarText('fr', 'Language')).toBe('Langue')
expect(translateAvatarText('fr', 'French')).toBe('Français')
expect(translateAvatarText('fr', 'Custom animation name')).toBe('Custom animation name')
})

it('provides Simplified Chinese labels for every face preset', () => {
for (const preset of AVATAR_FACE_PRESETS) {
expect(translateAvatarText('zh-Hans', preset.label)).not.toBe(preset.label)
Expand All @@ -99,4 +116,16 @@ describe('avatar locale', () => {
expect(translateAvatarText('zh-Hans', template.label)).not.toBe(template.label)
}
})

it('provides French labels for every face preset', () => {
for (const preset of AVATAR_FACE_PRESETS) {
expect(hasAvatarTranslation('fr', preset.label)).toBe(true)
}
})

it('provides French labels for every new animal breed', () => {
for (const template of AVATAR_ANIMAL_BREED_TEMPLATES) {
expect(hasAvatarTranslation('fr', template.label)).toBe(true)
}
})
})
2 changes: 1 addition & 1 deletion packages/react/src/renderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export type {
} from '@oneworks/avatar'

export type AvatarTheme = 'dark' | 'light' | 'system'
export type AvatarLocale = 'en' | 'zh-Hans'
export type AvatarLocale = 'en' | 'zh-Hans' | 'fr'
export type AvatarCaptureOptions = {
readonly background?: string | 'transparent'
readonly format: 'png' | 'svg'
Expand Down
2 changes: 1 addition & 1 deletion packages/vue/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ export const OneWorksAvatar = oneWorksAvatarComponent as typeof oneWorksAvatarCo
const editorProps = {
animationLibraries: { default: () => [], type: Array as PropType<readonly AvatarAnimationLibrary[]> },
definition: { default: undefined, type: Object as PropType<AvatarDefinition | undefined> },
locale: { default: 'en', type: String as PropType<'en' | 'zh-Hans'> },
locale: { default: 'en', type: String as PropType<'en' | 'zh-Hans' | 'fr'> },
theme: { default: 'system', type: String as PropType<AvatarTheme> }
}

Expand Down
2 changes: 1 addition & 1 deletion packages/web/src/elements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ export class OneWorksAvatarEditorElement extends HTMLElementBase {
return {
animationLibraries: this.#animationLibraries,
definition: this.#definition,
locale: locale === 'zh-Hans' ? locale : 'en',
locale: locale === 'zh-Hans' || locale === 'fr' ? locale : 'en',
theme: theme === 'dark' || theme === 'light' ? theme : 'system'
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/web/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export interface AvatarMountOptions {
export interface AvatarEditorMountOptions {
readonly animationLibraries?: readonly AvatarAnimationLibrary[]
readonly definition?: AvatarDefinition
readonly locale?: 'en' | 'zh-Hans'
readonly locale?: 'en' | 'zh-Hans' | 'fr'
readonly theme?: AvatarTheme
}

Expand Down
Loading