Skip to content

Commit d52ce42

Browse files
authored
I18n: Add RTL support (#51376)
* Add rtl support * Upgrade Chakra ui and fix select indicator position * Support mirrored navbar * Fix dynamic lang change
1 parent cafe913 commit d52ce42

File tree

8 files changed

+643
-599
lines changed

8 files changed

+643
-599
lines changed

airflow-core/src/airflow/ui/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!doctype html>
2-
<html lang="en" style="height: 100%">
2+
<html style="height: 100%">
33
<head>
44
<meta charset="UTF-8" />
55
<base href="{{ backend_server_base_url }}" />

airflow-core/src/airflow/ui/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
},
1818
"dependencies": {
1919
"@chakra-ui/anatomy": "^2.3.4",
20-
"@chakra-ui/react": "^3.17.0",
20+
"@chakra-ui/react": "^3.20.0",
2121
"@codemirror/lang-json": "^6.0.1",
2222
"@emotion/react": "^11.14.0",
2323
"@tanstack/react-query": "^5.75.1",

airflow-core/src/airflow/ui/pnpm-lock.yaml

Lines changed: 615 additions & 588 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

airflow-core/src/airflow/ui/src/components/ui/Select/Trigger.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export const Trigger = forwardRef<HTMLButtonElement, Props>((props, ref) => {
3232
return (
3333
<ChakraSelect.Control {...rest}>
3434
<ChakraSelect.Trigger ref={ref}>{children}</ChakraSelect.Trigger>
35-
<ChakraSelect.IndicatorGroup>
35+
<ChakraSelect.IndicatorGroup _rtl={{ bottom: 0, left: 0, right: "auto", top: 0 }}>
3636
{clearable ? (
3737
<ChakraSelect.ClearTrigger asChild>
3838
<CloseButton

airflow-core/src/airflow/ui/src/layouts/BaseLayout.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616
* specific language governing permissions and limitations
1717
* under the License.
1818
*/
19-
import { Box } from "@chakra-ui/react";
19+
import { Box, LocaleProvider } from "@chakra-ui/react";
2020
import type { PropsWithChildren } from "react";
21+
import { useTranslation } from "react-i18next";
2122
import { Outlet } from "react-router-dom";
2223

2324
import { useConfig } from "src/queries/useConfig";
@@ -26,17 +27,18 @@ import { Nav } from "./Nav";
2627

2728
export const BaseLayout = ({ children }: PropsWithChildren) => {
2829
const instanceName = useConfig("instance_name");
30+
const { i18n } = useTranslation();
2931

3032
if (typeof instanceName === "string") {
3133
document.title = instanceName;
3234
}
3335

3436
return (
35-
<>
37+
<LocaleProvider locale={i18n.language}>
3638
<Nav />
37-
<Box display="flex" flexDirection="column" h="100vh" ml={20} p={3}>
39+
<Box _ltr={{ ml: 20 }} _rtl={{ mr: 20 }} display="flex" flexDirection="column" h="100vh" p={3}>
3840
{children ?? <Outlet />}
3941
</Box>
40-
</>
42+
</LocaleProvider>
4143
);
4244
};

airflow-core/src/airflow/ui/src/layouts/Nav/Nav.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,18 @@ export const Nav = () => {
4040

4141
return (
4242
<VStack
43+
_ltr={{
44+
left: 0,
45+
right: "auto",
46+
}}
47+
_rtl={{
48+
left: "auto",
49+
right: 0,
50+
}}
4351
alignItems="center"
4452
bg="blue.muted"
4553
height="100%"
4654
justifyContent="space-between"
47-
left={0}
4855
position="fixed"
4956
py={3}
5057
top={0}

airflow-core/src/airflow/ui/src/main.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,19 @@ axios.interceptors.response.use(
5858

5959
axios.interceptors.request.use(tokenHandler);
6060

61+
const html = document.documentElement;
62+
const updateHtml = (lng: string) => {
63+
html.setAttribute("dir", i18n.dir(lng));
64+
html.setAttribute("lang", lng);
65+
};
66+
67+
updateHtml(i18n.language);
68+
i18n.on("languageChanged", updateHtml);
69+
6170
createRoot(document.querySelector("#root") as HTMLDivElement).render(
6271
<StrictMode>
6372
<I18nextProvider i18n={i18n}>
64-
<ChakraProvider value={system}>
73+
<ChakraProvider i18nIsDynamicList={true} value={system}>
6574
<ColorModeProvider>
6675
<QueryClientProvider client={client}>
6776
<TimezoneProvider>

airflow-core/src/airflow/ui/src/pages/Dashboard/Health/HealthBadge.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,13 @@ export const HealthBadge = ({
5151
{": "}
5252
{translate(`health.${status}`)}
5353
</Text>
54-
<Text>
54+
<Text hidden={latestHeartbeat === undefined}>
5555
{translate("health.lastHeartbeat")}
5656
{": "}
5757
<Time datetime={latestHeartbeat} />
5858
</Text>
5959
</div>
6060
}
61-
disabled={!Boolean(latestHeartbeat)}
6261
>
6362
<StateBadge size="lg" state={state} variant="surface">
6463
{title}

0 commit comments

Comments
 (0)