desktop version supports rtl

This commit is contained in:
MaysWind
2025-08-18 00:45:26 +08:00
parent 4eff3a337f
commit c00770201b
57 changed files with 502 additions and 371 deletions
+46 -3
View File
@@ -4,7 +4,16 @@ import 'moment-timezone/moment-timezone-utils';
import type { PartialRecord, NameValue, TypeAndName, TypeAndDisplayName, LocalizedSwitchOption } from '@/core/base.ts';
import { type LanguageInfo, type LanguageOption, ALL_LANGUAGES, DEFAULT_LANGUAGE } from '@/locales/index.ts';
import {
type LanguageInfo,
type LanguageOption,
ALL_LANGUAGES,
DEFAULT_LANGUAGE
} from '@/locales/index.ts';
import {
TextDirection
} from '@/core/text.ts';
import {
type DateFormat,
@@ -222,6 +231,24 @@ export function getI18nOptions(): object {
};
}
export function getRtlLocales(): Record<string, boolean> {
const rtlLocales: Record<string, boolean> = {};
for (const languageKey in ALL_LANGUAGES) {
if (!Object.prototype.hasOwnProperty.call(ALL_LANGUAGES, languageKey)) {
continue;
}
const languageInfo = ALL_LANGUAGES[languageKey];
if (languageInfo.textDirection === TextDirection.RTL) {
rtlLocales[languageKey] = true;
}
}
return rtlLocales;
}
export function useI18n() {
const { t, locale } = useVueI18n();
@@ -721,6 +748,11 @@ export function useI18n() {
return currentLanguageInfo.displayName;
}
function getCurrentLanguageTextDirection(): TextDirection {
const currentLanguageInfo = getCurrentLanguageInfo();
return currentLanguageInfo.textDirection;
}
function getDefaultCurrency(): string {
return t('default.currency');
}
@@ -1894,7 +1926,9 @@ export function useI18n() {
logger.info(`No specified language, use browser default language ${languageKey}`);
}
if (!getLanguageInfo(languageKey)) {
const languageInfo = getLanguageInfo(languageKey);
if (!languageInfo) {
languageKey = getDefaultLanguage();
logger.warn(`Not found language ${languageKey}, use browser default language ${languageKey}`);
}
@@ -1925,6 +1959,12 @@ export function useI18n() {
services.setLocale(languageKey);
document.querySelector('html')?.setAttribute('lang', languageKey);
if (languageInfo && languageInfo.textDirection === TextDirection.LTR) {
document.querySelector('html')?.removeAttribute('dir');
} else if (languageInfo && languageInfo.textDirection === TextDirection.RTL) {
document.querySelector('html')?.setAttribute('dir', 'rtl');
}
const defaultCurrency = getDefaultCurrency();
const defaultFirstDayOfWeekName = getDefaultFirstDayOfWeek();
let defaultFirstDayOfWeek = WeekDay.DefaultFirstDay.type;
@@ -1933,10 +1973,12 @@ export function useI18n() {
defaultFirstDayOfWeek = (WeekDay.parse(defaultFirstDayOfWeekName) as WeekDay).type;
}
return {
const localeDefaultSettings: LocaleDefaultSettings = {
currency: defaultCurrency,
firstDayOfWeek: defaultFirstDayOfWeek
};
return localeDefaultSettings;
}
function setTimeZone(timezone: string): void {
@@ -1987,6 +2029,7 @@ export function useI18n() {
getCurrentLanguageTag,
getCurrentLanguageInfo,
getCurrentLanguageDisplayName,
getCurrentLanguageTextDirection,
// get localization default type
getDefaultCurrency,
getDefaultFirstDayOfWeek,
+14
View File
@@ -11,12 +11,14 @@ import zhHans from './zh_Hans.json';
import zhHant from './zh_Hant.json';
import ptBR from './pt_BR.json';
import { TextDirection } from '@/core/text.ts';
export interface LanguageInfo {
readonly name: string;
readonly displayName: string;
readonly alternativeLanguageTag: string;
readonly aliases?: string[];
readonly textDirection: TextDirection;
readonly content: object;
}
@@ -34,60 +36,70 @@ export const ALL_LANGUAGES: Record<string, LanguageInfo> = {
name: 'German',
displayName: 'Deutsch',
alternativeLanguageTag: 'de-DE',
textDirection: TextDirection.LTR,
content: de
},
'en': {
name: 'English',
displayName: 'English',
alternativeLanguageTag: 'en-US',
textDirection: TextDirection.LTR,
content: en
},
'es': {
name: 'Spanish',
displayName: 'Español',
alternativeLanguageTag: 'es-ES',
textDirection: TextDirection.LTR,
content: es
},
'it': {
name: 'Italian',
displayName: 'Italiano',
alternativeLanguageTag: 'it-IT',
textDirection: TextDirection.LTR,
content: it
},
'ja': {
name: 'Japanese',
displayName: '日本語',
alternativeLanguageTag: 'ja-JP',
textDirection: TextDirection.LTR,
content: ja
},
'nl': {
name: 'Dutch',
displayName: 'Nederlands',
alternativeLanguageTag: 'nl-NL',
textDirection: TextDirection.LTR,
content: nl
},
'pt-BR': {
name: 'Portuguese (Brazil)',
displayName: 'Português (Brasil)',
alternativeLanguageTag: 'pt-BR',
textDirection: TextDirection.LTR,
content: ptBR
},
'ru': {
name: 'Russian',
displayName: 'Русский',
alternativeLanguageTag: 'ru-RU',
textDirection: TextDirection.LTR,
content: ru
},
'uk': {
name: 'Ukrainian',
displayName: 'Українська',
alternativeLanguageTag: 'uk-UA',
textDirection: TextDirection.LTR,
content: uk
},
'vi': {
name: 'Vietnamese',
displayName: 'Tiếng Việt',
alternativeLanguageTag: 'vi-VN',
textDirection: TextDirection.LTR,
content: vi
},
'zh-Hans': {
@@ -95,6 +107,7 @@ export const ALL_LANGUAGES: Record<string, LanguageInfo> = {
displayName: '中文 (简体)',
alternativeLanguageTag: 'zh-CN',
aliases: ['zh-CHS', 'zh-CN', 'zh-SG'],
textDirection: TextDirection.LTR,
content: zhHans
},
'zh-Hant': {
@@ -102,6 +115,7 @@ export const ALL_LANGUAGES: Record<string, LanguageInfo> = {
displayName: '中文 (繁體)',
alternativeLanguageTag: 'zh-TW',
aliases: ['zh-CHT', 'zh-TW', 'zh-HK', 'zh-MO'],
textDirection: TextDirection.LTR,
content: zhHant
},
};