Display UI in RTL languages correctly
This commit is contained in:
parent
a62a6ba295
commit
5ec54e2445
@ -18,6 +18,8 @@ import { useLayout, useSettings, useDiagram, useSelect } from "../../hooks";
|
||||
import TableInfo from "../EditorSidePanel/TablesTab/TableInfo";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { dbToTypes } from "../../data/datatypes";
|
||||
import { isRtl } from "../../i18n/utils/rtl";
|
||||
import i18n from "../../i18n/i18n";
|
||||
|
||||
export default function Table(props) {
|
||||
const [hoveredField, setHoveredField] = useState(-1);
|
||||
@ -84,6 +86,7 @@ export default function Table(props) {
|
||||
? "border-solid border-blue-500"
|
||||
: "border-zinc-500"
|
||||
}`}
|
||||
style={{ direction: "ltr" }}
|
||||
>
|
||||
<div
|
||||
className="h-[10px] w-full rounded-t-md"
|
||||
@ -190,7 +193,10 @@ export default function Table(props) {
|
||||
key={i}
|
||||
content={
|
||||
<div className="popover-theme">
|
||||
<div className="flex justify-between items-center pb-2">
|
||||
<div
|
||||
className="flex justify-between items-center pb-2"
|
||||
style={{ direction: "ltr" }}
|
||||
>
|
||||
<p className="me-4 font-bold">{e.name}</p>
|
||||
<p className="ms-4">
|
||||
{e.type +
|
||||
@ -235,6 +241,11 @@ export default function Table(props) {
|
||||
}
|
||||
position="right"
|
||||
showArrow
|
||||
style={
|
||||
isRtl(i18n.language)
|
||||
? { direction: "rtl" }
|
||||
: { direction: "ltr" }
|
||||
}
|
||||
>
|
||||
{field(e, i)}
|
||||
</Popover>
|
||||
|
@ -2,6 +2,7 @@ import { useState } from "react";
|
||||
import {
|
||||
IconCaretdown,
|
||||
IconChevronRight,
|
||||
IconChevronLeft,
|
||||
IconChevronUp,
|
||||
IconChevronDown,
|
||||
IconSaveStroked,
|
||||
@ -68,6 +69,7 @@ import { useTranslation } from "react-i18next";
|
||||
import { exportSQL } from "../../utils/exportSQL";
|
||||
import { databases } from "../../data/databases";
|
||||
import { jsonToMermaid } from "../../utils/exportAs/mermaid";
|
||||
import { isRtl } from "../../i18n/utils/rtl";
|
||||
|
||||
export default function ControlPanel({
|
||||
diagramId,
|
||||
@ -109,7 +111,7 @@ export default function ControlPanel({
|
||||
const { undoStack, redoStack, setUndoStack, setRedoStack } = useUndoRedo();
|
||||
const { selectedElement, setSelectedElement } = useSelect();
|
||||
const { transform, setTransform } = useTransform();
|
||||
const { t } = useTranslation();
|
||||
const { t, i18n } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const invertLayout = (component) =>
|
||||
@ -1374,7 +1376,10 @@ export default function ControlPanel({
|
||||
|
||||
function toolbar() {
|
||||
return (
|
||||
<div className="py-1.5 px-5 flex justify-between items-center rounded-xl my-1 sm:mx-1 xl:mx-6 select-none overflow-hidden toolbar-theme">
|
||||
<div
|
||||
className="py-1.5 px-5 flex justify-between items-center rounded-xl my-1 sm:mx-1 xl:mx-6 select-none overflow-hidden toolbar-theme"
|
||||
style={isRtl(i18n.language) ? { direction: "rtl" } : {}}
|
||||
>
|
||||
<div className="flex justify-start items-center">
|
||||
<LayoutDropdown />
|
||||
<Divider layout="vertical" margin="8px" />
|
||||
@ -1382,7 +1387,9 @@ export default function ControlPanel({
|
||||
style={{ width: "240px" }}
|
||||
position="bottomLeft"
|
||||
render={
|
||||
<Dropdown.Menu>
|
||||
<Dropdown.Menu
|
||||
style={isRtl(i18n.language) ? { direction: "rtl" } : {}}
|
||||
>
|
||||
<Dropdown.Item
|
||||
onClick={fitWindow}
|
||||
style={{ display: "flex", justifyContent: "space-between" }}
|
||||
@ -1562,7 +1569,10 @@ export default function ControlPanel({
|
||||
|
||||
function header() {
|
||||
return (
|
||||
<nav className="flex justify-between pt-1 items-center whitespace-nowrap">
|
||||
<nav
|
||||
className="flex justify-between pt-1 items-center whitespace-nowrap"
|
||||
style={isRtl(i18n.language) ? { direction: "rtl" } : {}}
|
||||
>
|
||||
<div className="flex justify-start items-center">
|
||||
<Link to="/">
|
||||
<img
|
||||
@ -1608,7 +1618,10 @@ export default function ControlPanel({
|
||||
<Dropdown
|
||||
key={category}
|
||||
position="bottomLeft"
|
||||
style={{ width: "240px" }}
|
||||
style={{
|
||||
width: "240px",
|
||||
direction: isRtl(i18n.language) ? "rtl" : "ltr",
|
||||
}}
|
||||
render={
|
||||
<Dropdown.Menu>
|
||||
{Object.keys(menu[category]).map((item, index) => {
|
||||
@ -1642,7 +1655,12 @@ export default function ControlPanel({
|
||||
onClick={menu[category][item].function}
|
||||
>
|
||||
{t(item)}
|
||||
<IconChevronRight />
|
||||
|
||||
{isRtl(i18n.language) ? (
|
||||
<IconChevronLeft />
|
||||
) : (
|
||||
<IconChevronRight />
|
||||
)}
|
||||
</Dropdown.Item>
|
||||
</Dropdown>
|
||||
);
|
||||
|
@ -7,6 +7,8 @@ import { Dropdown } from "@douyinfe/semi-ui";
|
||||
import { useFullscreen, useLayout } from "../../hooks";
|
||||
import { enterFullscreen, exitFullscreen } from "../../utils/fullscreen";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { isRtl } from "../../i18n/utils/rtl";
|
||||
import i18n from "../../i18n/i18n";
|
||||
|
||||
export default function LayoutDropdown() {
|
||||
const fullscreen = useFullscreen();
|
||||
@ -19,7 +21,10 @@ export default function LayoutDropdown() {
|
||||
return (
|
||||
<Dropdown
|
||||
position="bottomLeft"
|
||||
style={{ width: "180px" }}
|
||||
style={{
|
||||
width: "180px",
|
||||
direction: isRtl(i18n.language) ? "rtl" : "ltr",
|
||||
}}
|
||||
render={
|
||||
<Dropdown.Menu>
|
||||
<Dropdown.Item
|
||||
@ -48,9 +53,7 @@ export default function LayoutDropdown() {
|
||||
</Dropdown.Item>
|
||||
<Dropdown.Divider />
|
||||
<Dropdown.Item
|
||||
icon={
|
||||
fullscreen ? <IconCheckboxTick /> : <div className="px-2" />
|
||||
}
|
||||
icon={fullscreen ? <IconCheckboxTick /> : <div className="px-2" />}
|
||||
onClick={() => {
|
||||
if (fullscreen) {
|
||||
exitFullscreen();
|
||||
|
@ -37,6 +37,7 @@ import { githubLight } from "@uiw/codemirror-theme-github";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { importSQL } from "../../../utils/importSQL";
|
||||
import { databases } from "../../../data/databases";
|
||||
import { isRtl } from "../../../i18n/utils/rtl";
|
||||
|
||||
const languageExtension = {
|
||||
sql: [sql()],
|
||||
@ -53,7 +54,7 @@ export default function Modal({
|
||||
setExportData,
|
||||
importDb,
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const { t, i18n } = useTranslation();
|
||||
const { setTables, setRelationships, database, setDatabase } = useDiagram();
|
||||
const { setNotes } = useNotes();
|
||||
const { setAreas } = useAreas();
|
||||
@ -324,6 +325,7 @@ export default function Modal({
|
||||
|
||||
return (
|
||||
<SemiUIModal
|
||||
style={isRtl(i18n.language) ? { direction: "rtl" } : {}}
|
||||
title={getModalTitle(modal)}
|
||||
visible={modal !== MODAL.NONE}
|
||||
onOk={getModalOnOk}
|
||||
@ -362,7 +364,11 @@ export default function Modal({
|
||||
}}
|
||||
cancelText={t("cancel")}
|
||||
width={modal === MODAL.NEW || modal === MODAL.OPEN ? 740 : 600}
|
||||
bodyStyle={{ maxHeight: window.innerHeight - 280, overflow: "auto" }}
|
||||
bodyStyle={{
|
||||
maxHeight: window.innerHeight - 280,
|
||||
overflow: "auto",
|
||||
direction: "ltr",
|
||||
}}
|
||||
>
|
||||
{getModalBody()}
|
||||
</SemiUIModal>
|
||||
|
@ -11,6 +11,8 @@ import { useTranslation } from "react-i18next";
|
||||
import { useMemo } from "react";
|
||||
import { databases } from "../../data/databases";
|
||||
import EnumsTab from "./EnumsTab/EnumsTab";
|
||||
import { isRtl } from "../../i18n/utils/rtl";
|
||||
import i18n from "../../i18n/i18n";
|
||||
|
||||
export default function SidePanel({ width, resize, setResize }) {
|
||||
const { layout } = useLayout();
|
||||
@ -46,7 +48,7 @@ export default function SidePanel({ width, resize, setResize }) {
|
||||
});
|
||||
}
|
||||
|
||||
return tabs;
|
||||
return isRtl(i18n.language) ? tabs.reverse() : tabs;
|
||||
}, [t, database]);
|
||||
|
||||
return (
|
||||
@ -64,6 +66,7 @@ export default function SidePanel({ width, resize, setResize }) {
|
||||
setSelectedElement((prev) => ({ ...prev, currentTab: key }))
|
||||
}
|
||||
collapsible
|
||||
tabBarStyle={{ direction: "ltr" }}
|
||||
>
|
||||
{tabList.length &&
|
||||
tabList.map((tab) => (
|
||||
|
@ -22,6 +22,8 @@ import FloatingControls from "./FloatingControls";
|
||||
import { Modal } from "@douyinfe/semi-ui";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { databases } from "../data/databases";
|
||||
import { isRtl } from "../i18n/utils/rtl";
|
||||
import i18n from "../i18n/i18n";
|
||||
|
||||
export default function WorkSpace() {
|
||||
const [id, setId] = useState(0);
|
||||
@ -358,6 +360,7 @@ export default function WorkSpace() {
|
||||
// https://stackoverflow.com/a/70976017/1137077
|
||||
e.target.releasePointerCapture(e.pointerId);
|
||||
}}
|
||||
style={isRtl(i18n.language) ? { direction: "rtl" } : {}}
|
||||
>
|
||||
{layout.sidebar && (
|
||||
<SidePanel resize={resize} setResize={setResize} width={width} />
|
||||
|
2
src/i18n/utils/rtl.js
Normal file
2
src/i18n/utils/rtl.js
Normal file
@ -0,0 +1,2 @@
|
||||
const rtlLanguages = ["ar", "he", "fa", "ps", "ur"];
|
||||
export const isRtl = (language) => rtlLanguages.includes(language);
|
Loading…
Reference in New Issue
Block a user