Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 3 additions & 1 deletion packages/app/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,9 @@ function ResolvedDraftRoute(props: { draft: DraftTab }) {
function UiI18nBridge(props: ParentProps) {
const language = useLanguage()
return (
<I18nProvider value={{ locale: language.intl, t: language.t, plural: language.plural }}>
<I18nProvider
value={{ locale: language.intl, layoutLocale: language.layoutLocale, t: language.t, plural: language.plural }}
>
{props.children}
</I18nProvider>
)
Expand Down
49 changes: 34 additions & 15 deletions packages/app/src/components/debug-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function Cell(props: {
label: string
tip: string
value: string
wide?: boolean
span?: 2 | 3
}) {
const content = () => (
<div
Expand All @@ -69,7 +69,8 @@ function Cell(props: {
"min-h-[20px] w-fit justify-start px-1.5 py-0.5 text-left": !!props.inline,
"justify-center text-center": !props.inline,
"min-h-[42px] w-full flex-col rounded-[8px] px-0.5 py-1": !props.inline,
"col-span-2": !!props.wide && !props.inline,
"col-span-2": props.span === 2 && !props.inline,
"col-span-3": props.span === 3 && !props.inline,
}}
>
<div
Expand Down Expand Up @@ -116,11 +117,18 @@ function Cell(props: {
)
}

function FocusCell(props: { active: boolean; inline?: boolean; onClick: () => void }) {
function ToggleCell(props: {
active: boolean
inline?: boolean
label: string
onClick: () => void
tip: string
value: string
}) {
const content = () => (
<button
type="button"
aria-label="Force focus styles on all interactive elements"
aria-label={props.tip}
aria-pressed={props.active}
classList={{
"flex min-w-0 items-center font-mono uppercase hover:bg-surface-raised-base focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-border-focus": true,
Expand All @@ -137,26 +145,22 @@ function FocusCell(props: { active: boolean; inline?: boolean; onClick: () => vo
"flex-col items-center": !props.inline,
}}
>
<span class="text-[10px] leading-none font-black tracking-[0.04em] opacity-70">FOCUS</span>
<span
classList={{ "leading-none font-bold": true, "text-[11px]": !!props.inline, "text-[13px]": !props.inline }}
>
{props.active ? "ON" : "OFF"}
</span>
<span class="text-[10px] leading-none font-black tracking-[0.04em] opacity-70">{props.label}</span>
<span class="text-[11px] leading-none font-bold">{props.value}</span>
</span>
</button>
)

if (props.inline) {
return (
<TooltipV2 value="Force focus styles on all interactive elements" placement="top">
<TooltipV2 value={props.tip} placement="top">
{content()}
</TooltipV2>
)
}

return (
<Tooltip value="Force focus styles on all interactive elements" placement="top">
<Tooltip value={props.tip} placement="top">
{content()}
</Tooltip>
)
Expand Down Expand Up @@ -475,7 +479,7 @@ export function DebugBar(props: { inline?: boolean } = {}) {
"gap-[9px]": !!props.inline,
"gap-px": !props.inline,
"flex w-full flex-nowrap items-center justify-start": !!props.inline,
"grid-cols-5": !props.inline,
"grid-cols-4": !props.inline,
grid: !props.inline,
}}
>
Expand Down Expand Up @@ -557,10 +561,25 @@ export function DebugBar(props: { inline?: boolean } = {}) {
bad={bad(heap(), 0.8)}
dim={state.heap.used === undefined}
inline={props.inline}
wide={!platform.setForceFocus}
span={platform.setForceFocus ? 2 : 3}
/>
<ToggleCell
active={language.direction() === "rtl"}
inline={props.inline}
label={language.t("debugBar.direction.label")}
tip={language.t("debugBar.direction.tip")}
value={language.t(`debugBar.direction.${language.direction()}`)}
onClick={() => language.setDirection(language.direction() === "rtl" ? "ltr" : "rtl")}
/>
{platform.setForceFocus && (
<FocusCell active={state.focus} inline={props.inline} onClick={() => void toggleFocus()} />
<ToggleCell
active={state.focus}
inline={props.inline}
label={language.t("debugBar.focus.label")}
tip={language.t("debugBar.focus.tip")}
value={language.t(state.focus ? "debugBar.focus.on" : "debugBar.focus.off")}
onClick={() => void toggleFocus()}
/>
)}
</div>
</aside>
Expand Down
19 changes: 18 additions & 1 deletion packages/app/src/context/language.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,14 @@ import {
} from "@/i18n/desktop-native"

export type Locale = DesktopNativeLocale
export type Direction = "ltr" | "rtl"

const RTL_LOCALES: ReadonlySet<Locale> = new Set(["ar", "ur", "pa"])

function localeDirection(locale: Locale): Direction {
return RTL_LOCALES.has(locale) ? "rtl" : "ltr"
}

type RawDictionary = typeof en & typeof uiEn
type Dictionary = i18n.Flatten<RawDictionary>
type PluralKey =
Expand Down Expand Up @@ -242,6 +247,13 @@ export const { use: useLanguage, provider: LanguageProvider } = createSimpleCont

const locale = createMemo<Locale>(() => normalizeLocale(store.locale))
const intl = createMemo(() => INTL[locale()])
const [layout, setLayout] = createStore({ direction: undefined as Direction | undefined })
const direction = createMemo(() => layout.direction ?? localeDirection(locale()))
const layoutLocale = createMemo(() => {
if (!layout.direction) return intl()
// Kobalte derives menu direction from locale rather than accepting a direction override.
return layout.direction === "rtl" ? "ar" : "en"
})

const [dict] = createResource(locale, loadDict, {
initialValue: dicts.get(initial) ?? base,
Expand Down Expand Up @@ -270,7 +282,7 @@ export const { use: useLanguage, provider: LanguageProvider } = createSimpleCont
if (typeof document !== "object") return
const value = locale()
document.documentElement.lang = value
document.documentElement.dir = RTL_LOCALES.has(value) ? "rtl" : "ltr"
document.documentElement.dir = direction()
document.cookie = cookie(value)
})

Expand All @@ -287,13 +299,18 @@ export const { use: useLanguage, provider: LanguageProvider } = createSimpleCont
ready,
locale,
intl,
direction,
layoutLocale,
locales: LOCALES,
label,
t,
plural,
setLocale(next: Locale) {
setStore("locale", normalizeLocale(next))
},
setDirection(next: Direction) {
setLayout("direction", next === localeDirection(locale()) ? undefined : next)
},
}
},
})
8 changes: 8 additions & 0 deletions packages/app/src/i18n/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1124,6 +1124,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "كومة JS المستخدمة مقابل حد الكومة. Chromium فقط.",
"debugBar.mem.tip": "كومة JS المستخدمة مقابل حد الكومة. {{used}} من {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "فرض أنماط التركيز على جميع العناصر التفاعلية",
"debugBar.focus.on": "تشغيل",
"debugBar.focus.off": "إيقاف",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "فرض اتجاه التخطيط على التطبيق بالكامل دون تغيير اللغة المحددة",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Shift",
Expand Down
8 changes: 8 additions & 0 deletions packages/app/src/i18n/az.ts
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "İstifadə olunmuş JS yığını və yığın limiti. Yalnız Chromium.",
"debugBar.mem.tip": "İstifadə olunmuş JS yığını və yığın limiti. {{used}} və {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Bütün interaktiv elementlərə fokus üslublarını məcburi tətbiq et",
"debugBar.focus.on": "AÇIQ",
"debugBar.focus.off": "QAPALI",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Seçilmiş dili dəyişmədən bütün tətbiq üçün tərtibat istiqamətini məcburi təyin et",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"app.name.desktop": "OpenCode Desktop",
"settings.section.desktop": "Masaüstü",
"settings.section.server": "Server",
Expand Down
8 changes: 8 additions & 0 deletions packages/app/src/i18n/br.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1134,6 +1134,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Heap JS usado vs limite de heap. Apenas Chromium.",
"debugBar.mem.tip": "Heap JS usado vs limite de heap. {{used}} de {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Forçar estilos de foco em todos os elementos interativos",
"debugBar.focus.on": "LIGADO",
"debugBar.focus.off": "DESLIGADO",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Forçar a direção do layout de todo o aplicativo sem alterar o idioma selecionado",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Shift",
Expand Down
8 changes: 8 additions & 0 deletions packages/app/src/i18n/bs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1210,6 +1210,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Korišteni JS heap naspram limita heapa. Samo Chromium.",
"debugBar.mem.tip": "Korišteni JS heap naspram limita heapa. {{used}} od {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Prisilno primijeni stilove fokusa na sve interaktivne elemente",
"debugBar.focus.on": "UKLJUČENO",
"debugBar.focus.off": "ISKLJUČENO",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Prisilno postavi smjer rasporeda cijele aplikacije bez promjene odabranog jezika",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Shift",
Expand Down
8 changes: 8 additions & 0 deletions packages/app/src/i18n/da.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1084,6 +1084,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Brugt JS-heap sammenholdt med heapgrænsen. Kun Chromium.",
"debugBar.mem.tip": "Brugt JS-heap sammenholdt med heapgrænsen. {{used}} af {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Gennemtving fokusstile for alle interaktive elementer",
"debugBar.focus.on": "TIL",
"debugBar.focus.off": "FRA",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Gennemtving layoutretningen for hele appen uden at ændre det valgte sprog",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Shift",
Expand Down
8 changes: 8 additions & 0 deletions packages/app/src/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Belegter JS-Heap im Verhältnis zum Heap-Limit. Nur Chromium.",
"debugBar.mem.tip": "Belegter JS-Heap im Verhältnis zum Heap-Limit. {{used}} von {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Fokusstile für alle interaktiven Elemente erzwingen",
"debugBar.focus.on": "EIN",
"debugBar.focus.off": "AUS",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Layoutrichtung für die gesamte App erzwingen, ohne die ausgewählte Sprache zu ändern",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Strg",
"common.key.alt": "Alt",
"common.key.shift": "Umschalt",
Expand Down
8 changes: 8 additions & 0 deletions packages/app/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Used JS heap vs heap limit. Chromium only.",
"debugBar.mem.tip": "Used JS heap vs heap limit. {{used}} of {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Force focus styles on all interactive elements",
"debugBar.focus.on": "ON",
"debugBar.focus.off": "OFF",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Force the full app layout direction without changing the selected language",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",

"app.name.desktop": "OpenCode Desktop",

Expand Down
8 changes: 8 additions & 0 deletions packages/app/src/i18n/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1218,6 +1218,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Heap JS usado vs límite de heap. Solo Chromium.",
"debugBar.mem.tip": "Heap JS usado vs límite de heap. {{used}} de {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Forzar los estilos de foco en todos los elementos interactivos",
"debugBar.focus.on": "SÍ",
"debugBar.focus.off": "NO",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Forzar la dirección del diseño de toda la aplicación sin cambiar el idioma seleccionado",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Mayús",
Expand Down
8 changes: 8 additions & 0 deletions packages/app/src/i18n/fi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Käytetty JS-keko suhteessa keon rajaan. Vain Chromium.",
"debugBar.mem.tip": "Käytetty JS-keko suhteessa keon rajaan. {{used}} / {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Pakota kohdistustyylit kaikkiin vuorovaikutteisiin elementteihin",
"debugBar.focus.on": "KÄYTÖSSÄ",
"debugBar.focus.off": "EI KÄYTÖSSÄ",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Pakota koko sovelluksen asettelun suunta valittua kieltä muuttamatta",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"app.name.desktop": "OpenCode Desktop",
"settings.section.desktop": "Työpöytä",
"settings.section.server": "Palvelin",
Expand Down
8 changes: 8 additions & 0 deletions packages/app/src/i18n/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Tas JS utilisé vs limite de tas. Chromium uniquement.",
"debugBar.mem.tip": "Tas JS utilisé vs limite de tas. {{used}} sur {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Forcer les styles de focus sur tous les éléments interactifs",
"debugBar.focus.on": "ACTIVÉ",
"debugBar.focus.off": "DÉSACTIVÉ",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Forcer le sens de disposition de toute l’application sans changer la langue sélectionnée",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Maj",
Expand Down
8 changes: 8 additions & 0 deletions packages/app/src/i18n/hi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "उपयोग किया गया JS हीप बनाम हीप सीमा। केवल Chromium।",
"debugBar.mem.tip": "उपयोग किया गया JS हीप बनाम हीप सीमा। {{limit}} में से {{used}}।",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "सभी इंटरैक्टिव एलिमेंट पर फ़ोकस स्टाइल ज़बरदस्ती लागू करें",
"debugBar.focus.on": "चालू",
"debugBar.focus.off": "बंद",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "चुनी गई भाषा बदले बिना पूरे ऐप की लेआउट दिशा ज़बरदस्ती सेट करें",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"app.name.desktop": "OpenCode Desktop",
"settings.section.desktop": "डेस्कटॉप",
"settings.section.server": "सर्वर",
Expand Down
8 changes: 8 additions & 0 deletions packages/app/src/i18n/id.ts
Original file line number Diff line number Diff line change
Expand Up @@ -963,6 +963,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Heap JS terpakai vs batas heap. Khusus Chromium.",
"debugBar.mem.tip": "Heap JS terpakai vs batas heap. {{used}} dari {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Paksa gaya fokus pada semua elemen interaktif",
"debugBar.focus.on": "AKTIF",
"debugBar.focus.off": "NONAKTIF",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Paksa arah tata letak seluruh aplikasi tanpa mengubah bahasa yang dipilih",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",

"app.name.desktop": "OpenCode Desktop",

Expand Down
8 changes: 8 additions & 0 deletions packages/app/src/i18n/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Heap JS utilizzato rispetto al limite dell'heap. Solo Chromium.",
"debugBar.mem.tip": "Heap JS utilizzato rispetto al limite dell'heap. {{used}} di {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Forza gli stili di focus su tutti gli elementi interattivi",
"debugBar.focus.on": "ON",
"debugBar.focus.off": "OFF",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Forza la direzione del layout dell’intera app senza cambiare la lingua selezionata",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"app.name.desktop": "OpenCode Desktop",
"settings.section.desktop": "Desktop",
"settings.section.server": "Server",
Expand Down
8 changes: 8 additions & 0 deletions packages/app/src/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1116,6 +1116,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "使用中の JS ヒープ対ヒープ制限。Chromium のみ。",
"debugBar.mem.tip": "使用中の JS ヒープ対ヒープ制限。{{limit}} 中 {{used}}。",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "すべてのインタラクティブ要素にフォーカススタイルを強制適用",
"debugBar.focus.on": "オン",
"debugBar.focus.off": "オフ",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "選択中の言語を変更せずに、アプリ全体のレイアウト方向を強制設定",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Shift",
Expand Down
Loading
Loading