Compare commits

..

3 Commits
4.8.6 ... 4.8.7

Author SHA1 Message Date
Dhruwang Jariwala
74b679403d fix: multi-lang toggle covering arabic text (backport #7657) (#7660)
Co-authored-by: Johannes <johannes@formbricks.com>
2026-04-02 18:49:29 +05:30
Dhruwang Jariwala
4a5404557b fix: multilang button overflow (backport #7656) (#7659)
Co-authored-by: Niels Kaspers <kaspersniels@gmail.com>
2026-04-02 18:49:13 +05:30
Dhruwang Jariwala
fbb529d066 fix: prevent language switch from breaking survey orientation and resetting language on auto-save (backport #7654) (#7658) 2026-04-02 18:48:57 +05:30
5 changed files with 23 additions and 14 deletions

View File

@@ -346,8 +346,8 @@ export const MultipleChoiceElementForm = ({
</div>
<div className="mt-2">
<div className="mt-2 flex items-center justify-between space-x-2">
<div className="flex gap-2">
<div className="mt-2 flex flex-wrap items-center justify-between gap-2">
<div className="flex flex-wrap gap-2">
{specialChoices.map((specialChoice) => {
if (element.choices.some((c) => c.id === specialChoice.id)) return null;
return (

View File

@@ -48,7 +48,7 @@ export function LanguageIndicator({
<button
aria-expanded={showLanguageDropdown}
aria-haspopup="true"
className="relative z-20 flex max-w-[120px] items-center justify-center rounded-md bg-slate-900 p-1 px-2 text-xs text-white hover:bg-slate-700"
className="relative z-20 flex max-w-20 items-center justify-center rounded-md bg-slate-900 p-1 px-2 text-xs text-white hover:bg-slate-700"
onClick={toggleDropdown}
tabIndex={-1}
type="button">

View File

@@ -59,7 +59,7 @@ export function LanguageSwitch({
handleI18nLanguage(calculatedLanguageCode);
if (setDir) {
const calculateDir = isRTLLanguage(survey, calculatedLanguageCode) ? "rtl" : "auto";
const calculateDir = isRTLLanguage(survey, calculatedLanguageCode) ? "rtl" : "ltr";
setDir?.(calculateDir);
}

View File

@@ -9,12 +9,13 @@ export function RenderSurvey(props: SurveyContainerProps) {
const onFinishedTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const closeTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const isRTL = isRTLLanguage(props.survey, props.languageCode);
const [dir, setDir] = useState<"ltr" | "rtl" | "auto">(isRTL ? "rtl" : "auto");
const [dir, setDir] = useState<"ltr" | "rtl" | "auto">(isRTL ? "rtl" : "ltr");
useEffect(() => {
const isRTL = isRTLLanguage(props.survey, props.languageCode);
setDir(isRTL ? "rtl" : "auto");
}, [props.languageCode, props.survey]);
setDir(isRTL ? "rtl" : "ltr");
// eslint-disable-next-line react-hooks/exhaustive-deps -- Only recalculate direction when languageCode changes, not on survey auto-save
}, [props.languageCode]);
const close = () => {
if (onFinishedTimeoutRef.current) {

View File

@@ -1,20 +1,28 @@
import { ComponentChildren } from "preact";
import { useEffect } from "preact/hooks";
import { useEffect, useRef } from "preact/hooks";
import { I18nextProvider } from "react-i18next";
import i18n from "../../lib/i18n.config";
export const I18nProvider = ({ language, children }: { language: string; children?: ComponentChildren }) => {
const isFirstRender = useRef(true);
const prevLanguage = useRef(language);
// Set language synchronously on initial render so children get the correct translations immediately.
// This is safe because all translations are pre-loaded (bundled) in i18n.config.ts.
if (i18n.language !== language) {
i18n.changeLanguage(language);
}
// Handle language prop changes after initial render
useEffect(() => {
// On subsequent renders, skip this to avoid overriding language changes made by the user via LanguageSwitch.
if (isFirstRender.current) {
if (i18n.language !== language) {
i18n.changeLanguage(language);
}
isFirstRender.current = false;
}
// Only update language when the prop itself changes, not when i18n was changed internally by user action
useEffect(() => {
if (prevLanguage.current !== language) {
i18n.changeLanguage(language);
prevLanguage.current = language;
}
}, [language]);
// work around for react-i18next not supporting preact