Fix Studio toast close-button positioning (#7142)

* Fix Studio toast close-button positioning

* Use UTF-8 for locale regression test

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Harden toast close-button positioning

* Limit language menu height

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Michael Han 2026-07-15 07:43:40 -07:00 committed by GitHub
commit 300b5f9b41
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 48 additions and 16 deletions

View file

@ -90,7 +90,7 @@ const Toaster = ({ ...props }: ToasterProps) => {
// Pin the close button inside the toast's top-right corner.
// Sonner defaults to the left/outside edge, so keep the horizontal
// override here and the top offset in index.css.
"--toast-close-button-start": "unset",
"--toast-close-button-start": "auto",
"--toast-close-button-end": "8px",
"--toast-close-button-transform": "none",
} as React.CSSProperties

View file

@ -35,7 +35,11 @@ export function LanguageSelect() {
>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectContent
style={{
maxHeight: "min(18rem, var(--radix-select-content-available-height))",
}}
>
<SelectItem value={AUTO_LOCALE}>
{t("settings.appearance.language.autoDetect")}
</SelectItem>

View file

@ -98,7 +98,6 @@ function writeStoredPreference(preference: LocalePreference): void {
function syncDocumentLang(locale: Locale): void {
if (typeof document === "undefined") return;
document.documentElement.lang = locale;
document.documentElement.dir = LOCALES[locale].dir;
}
function notifySubscribers(): void {

View file

@ -15,19 +15,18 @@ import { de } from "./locales/de";
import { ko } from "./locales/ko";
import type { InterpolationValues, MessageKey } from "./types";
// dir sets documentElement.dir; Arabic stays ltr (CSS still physical-direction) but renders rtl via bidi.
export const LOCALES = {
en: { label: "English", nativeLabel: "English", dir: "ltr" },
"zh-CN": { label: "Chinese (Simplified)", nativeLabel: "简体中文", dir: "ltr" },
ja: { label: "Japanese", nativeLabel: "日本語", dir: "ltr" },
ko: { label: "Korean", nativeLabel: "한국어", dir: "ltr" },
es: { label: "Spanish", nativeLabel: "Español", dir: "ltr" },
"pt-BR": { label: "Portuguese (Brazil)", nativeLabel: "Português (Brasil)", dir: "ltr" },
fr: { label: "French", nativeLabel: "Français", dir: "ltr" },
de: { label: "German", nativeLabel: "Deutsch", dir: "ltr" },
ru: { label: "Russian", nativeLabel: "Русский", dir: "ltr" },
hi: { label: "Hindi", nativeLabel: "हिन्दी", dir: "ltr" },
ar: { label: "Arabic", nativeLabel: "العربية", dir: "ltr" },
en: { label: "English", nativeLabel: "English" },
"zh-CN": { label: "Chinese (Simplified)", nativeLabel: "简体中文" },
ja: { label: "Japanese", nativeLabel: "日本語" },
ko: { label: "Korean", nativeLabel: "한국어" },
es: { label: "Spanish", nativeLabel: "Español" },
"pt-BR": { label: "Portuguese (Brazil)", nativeLabel: "Português (Brasil)" },
fr: { label: "French", nativeLabel: "Français" },
de: { label: "German", nativeLabel: "Deutsch" },
ru: { label: "Russian", nativeLabel: "Русский" },
hi: { label: "Hindi", nativeLabel: "हिन्दी" },
ar: { label: "Arabic", nativeLabel: "العربية" },
} as const;
export type Locale = keyof typeof LOCALES;
@ -105,4 +104,4 @@ export function isSupportedLocale(value: unknown): value is Locale {
typeof value === "string" &&
Object.prototype.hasOwnProperty.call(LOCALES, value)
);
}
}

View file

@ -0,0 +1,30 @@
"""Regression guard for locale changes affecting the entire Studio layout."""
from pathlib import Path
REPO = Path(__file__).resolve().parents[2]
LOCALE_STORE = REPO / "studio/frontend/src/i18n/locale-store.ts"
MESSAGES = REPO / "studio/frontend/src/i18n/messages.ts"
SONNER = REPO / "studio/frontend/src/components/ui/sonner.tsx"
def test_locale_changes_do_not_force_document_direction():
src = LOCALE_STORE.read_text(encoding = "utf-8")
assert "document.documentElement.lang = locale" in src
assert "document.documentElement.dir" not in src, (
"locale changes must not force the root direction; html[dir] changes "
"third-party component layout, including Sonner close-button positioning"
)
def test_locale_metadata_does_not_advertise_unused_layout_direction():
src = MESSAGES.read_text(encoding = "utf-8")
locales_block = src[src.index("export const LOCALES") : src.index("export type Locale")]
assert "dir:" not in locales_block
def test_toast_close_position_does_not_inherit_root_direction():
src = SONNER.read_text(encoding = "utf-8")
assert '"--toast-close-button-start": "auto"' in src
assert '"--toast-close-button-start": "unset"' not in src