RTL updates (#2416)
* Update a bunch of icons to be mirrored in RTL * Fix RTL layout issues in in zen mode and collaboration * Small change to the shortcuts dialog to make isRTL unnecessary * Tweaks to alignment in RTL
This commit is contained in:
parent
fec48060f7
commit
8d479ab238
@ -35,6 +35,8 @@ export const SelectedShapeActions = ({
|
|||||||
const isEditing = Boolean(appState.editingElement);
|
const isEditing = Boolean(appState.editingElement);
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
|
const isRTL = document.documentElement.getAttribute("dir") === "rtl";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="panelColumn">
|
<div className="panelColumn">
|
||||||
{renderAction("changeStrokeColor")}
|
{renderAction("changeStrokeColor")}
|
||||||
@ -88,9 +90,23 @@ export const SelectedShapeActions = ({
|
|||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{t("labels.align")}</legend>
|
<legend>{t("labels.align")}</legend>
|
||||||
<div className="buttonList">
|
<div className="buttonList">
|
||||||
|
{
|
||||||
|
// swap this order for RTL so the button positions always match their action
|
||||||
|
// (i.e. the leftmost button aligns left)
|
||||||
|
}
|
||||||
|
{isRTL ? (
|
||||||
|
<>
|
||||||
|
{renderAction("alignRight")}
|
||||||
|
{renderAction("alignHorizontallyCentered")}
|
||||||
|
{renderAction("alignLeft")}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
{renderAction("alignLeft")}
|
{renderAction("alignLeft")}
|
||||||
{renderAction("alignHorizontallyCentered")}
|
{renderAction("alignHorizontallyCentered")}
|
||||||
{renderAction("alignRight")}
|
{renderAction("alignRight")}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
{targetElements.length > 2 &&
|
{targetElements.length > 2 &&
|
||||||
renderAction("distributeHorizontally")}
|
renderAction("distributeHorizontally")}
|
||||||
<div className="iconRow">
|
<div className="iconRow">
|
||||||
|
@ -142,16 +142,24 @@
|
|||||||
transform: translate(-999px, 0);
|
transform: translate(-999px, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.App-menu_bottom--transition-left {
|
:root[dir="ltr"] &.App-menu_bottom--transition-left {
|
||||||
transform: translate(-92px, 0);
|
transform: translate(-92px, 0);
|
||||||
}
|
}
|
||||||
|
:root[dir="rtl"] &.App-menu_bottom--transition-left {
|
||||||
|
transform: translate(92px, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.disable-zen-mode {
|
.disable-zen-mode {
|
||||||
height: 30px;
|
height: 30px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 10px;
|
bottom: 10px;
|
||||||
|
[dir="ltr"] & {
|
||||||
right: 15px;
|
right: 15px;
|
||||||
|
}
|
||||||
|
[dir="rtl"] & {
|
||||||
|
left: 15px;
|
||||||
|
}
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
@ -12,8 +12,13 @@
|
|||||||
.RoomDialog-modalButton-collaborators {
|
.RoomDialog-modalButton-collaborators {
|
||||||
min-width: 1em;
|
min-width: 1em;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: -5px;
|
:root[dir="ltr"] & {
|
||||||
right: -5px;
|
right: -5px;
|
||||||
|
}
|
||||||
|
:root[dir="rtl"] & {
|
||||||
|
left: -5px;
|
||||||
|
}
|
||||||
|
bottom: -5px;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: $oc-green-6;
|
background-color: $oc-green-6;
|
||||||
@ -31,7 +36,7 @@
|
|||||||
color: var(--text-color-primary);
|
color: var(--text-color-primary);
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
margin-left: 1em;
|
margin-inline-start: 1em;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: none;
|
border: none;
|
||||||
@ -61,7 +66,7 @@
|
|||||||
appearance: none;
|
appearance: none;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
margin-left: 1em;
|
margin-inline-start: 1em;
|
||||||
height: 2.5rem;
|
height: 2.5rem;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
@ -37,7 +37,6 @@ const Shortcut = (props: {
|
|||||||
shortcuts: string[];
|
shortcuts: string[];
|
||||||
isOr: boolean;
|
isOr: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const isRTL = document.documentElement.getAttribute("dir") === "rtl";
|
|
||||||
return (
|
return (
|
||||||
<div className="ShorcutsDialog-shortcut">
|
<div className="ShorcutsDialog-shortcut">
|
||||||
<div
|
<div
|
||||||
@ -60,8 +59,7 @@ const Shortcut = (props: {
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
flex: "0 0 auto",
|
flex: "0 0 auto",
|
||||||
justifyContent: "flex-end",
|
justifyContent: "flex-end",
|
||||||
marginLeft: isRTL ? "0em" : "auto",
|
marginInlineStart: "auto",
|
||||||
marginRight: isRTL ? "auto" : "0em",
|
|
||||||
minWidth: "30%",
|
minWidth: "30%",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
// Icons are under the license https://fontawesome.com/license
|
// Icons are under the license https://fontawesome.com/license
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// Note: when adding new icons, review https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/RTL_Guidelines
|
||||||
|
// to determine whether or not the icons should be mirrored in right-to-left languages.
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import oc from "open-color";
|
import oc from "open-color";
|
||||||
@ -89,7 +92,6 @@ export const zoomOut = createIcon(
|
|||||||
|
|
||||||
export const done = createIcon(
|
export const done = createIcon(
|
||||||
"M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z",
|
"M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z",
|
||||||
{ mirror: true },
|
|
||||||
);
|
);
|
||||||
|
|
||||||
export const menu = createIcon(
|
export const menu = createIcon(
|
||||||
@ -135,7 +137,7 @@ export const BringForwardIcon = React.memo(
|
|||||||
strokeWidth="2"
|
strokeWidth="2"
|
||||||
/>
|
/>
|
||||||
</>,
|
</>,
|
||||||
{ width: 24 },
|
{ width: 24, mirror: true },
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -156,7 +158,7 @@ export const SendBackwardIcon = React.memo(
|
|||||||
strokeWidth="2"
|
strokeWidth="2"
|
||||||
/>
|
/>
|
||||||
</>,
|
</>,
|
||||||
{ width: 24 },
|
{ width: 24, mirror: true },
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -177,7 +179,7 @@ export const BringToFrontIcon = React.memo(
|
|||||||
strokeWidth="2"
|
strokeWidth="2"
|
||||||
/>
|
/>
|
||||||
</>,
|
</>,
|
||||||
{ width: 24 },
|
{ width: 24, mirror: true },
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -200,12 +202,15 @@ export const SendToBackIcon = React.memo(
|
|||||||
strokeWidth="2"
|
strokeWidth="2"
|
||||||
/>
|
/>
|
||||||
</>,
|
</>,
|
||||||
{ width: 24 },
|
{ width: 24, mirror: true },
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Align action icons created from scratch to match those of z-index actions
|
// Align action icons created from scratch to match those of z-index actions
|
||||||
|
// Note: vertical align icons are flipped so the larger item is always the
|
||||||
|
// first one the user sees. Horizontal align icons should not be flipped since
|
||||||
|
// that would make them lie about their function.
|
||||||
//
|
//
|
||||||
export const AlignTopIcon = React.memo(
|
export const AlignTopIcon = React.memo(
|
||||||
({ appearance }: { appearance: "light" | "dark" }) =>
|
({ appearance }: { appearance: "light" | "dark" }) =>
|
||||||
@ -225,7 +230,7 @@ export const AlignTopIcon = React.memo(
|
|||||||
strokeWidth="2"
|
strokeWidth="2"
|
||||||
/>
|
/>
|
||||||
</>,
|
</>,
|
||||||
{ width: 24 },
|
{ width: 24, mirror: true },
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -247,7 +252,7 @@ export const AlignBottomIcon = React.memo(
|
|||||||
strokeWidth="2"
|
strokeWidth="2"
|
||||||
/>
|
/>
|
||||||
</>,
|
</>,
|
||||||
{ width: 24 },
|
{ width: 24, mirror: true },
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -366,7 +371,7 @@ export const CenterVerticallyIcon = React.memo(
|
|||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
/>
|
/>
|
||||||
</>,
|
</>,
|
||||||
{ width: 24 },
|
{ width: 24, mirror: true },
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -398,6 +403,7 @@ export const users = createIcon(
|
|||||||
{ width: 640, height: 512, mirror: true },
|
{ width: 640, height: 512, mirror: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// not mirrored because it's inspired by a playback control, which is always RTL
|
||||||
export const start = createIcon(
|
export const start = createIcon(
|
||||||
"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm115.7 272l-176 101c-15.8 8.8-35.7-2.5-35.7-21V152c0-18.4 19.8-29.8 35.7-21l176 107c16.4 9.2 16.4 32.9 0 42z",
|
"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm115.7 272l-176 101c-15.8 8.8-35.7-2.5-35.7-21V152c0-18.4 19.8-29.8 35.7-21l176 107c16.4 9.2 16.4 32.9 0 42z",
|
||||||
);
|
);
|
||||||
@ -480,7 +486,7 @@ export const GroupIcon = React.memo(
|
|||||||
strokeWidth="6"
|
strokeWidth="6"
|
||||||
/>
|
/>
|
||||||
</>,
|
</>,
|
||||||
{ width: 182, height: 182 },
|
{ width: 182, height: 182, mirror: true },
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -555,7 +561,7 @@ export const UngroupIcon = React.memo(
|
|||||||
strokeWidth="6"
|
strokeWidth="6"
|
||||||
/>
|
/>
|
||||||
</>,
|
</>,
|
||||||
{ width: 182, height: 182 },
|
{ width: 182, height: 182, mirror: true },
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -672,7 +678,7 @@ export const SloppinessArchitectIcon = React.memo(
|
|||||||
strokeWidth={2}
|
strokeWidth={2}
|
||||||
fill="none"
|
fill="none"
|
||||||
/>,
|
/>,
|
||||||
{ width: 40, height: 20 },
|
{ width: 40, height: 20, mirror: true },
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -685,7 +691,7 @@ export const SloppinessArtistIcon = React.memo(
|
|||||||
strokeWidth={2}
|
strokeWidth={2}
|
||||||
fill="none"
|
fill="none"
|
||||||
/>,
|
/>,
|
||||||
{ width: 40, height: 20 },
|
{ width: 40, height: 20, mirror: true },
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -706,7 +712,7 @@ export const SloppinessCartoonistIcon = React.memo(
|
|||||||
fill="none"
|
fill="none"
|
||||||
/>
|
/>
|
||||||
</>,
|
</>,
|
||||||
{ width: 40, height: 20 },
|
{ width: 40, height: 20, mirror: true },
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -719,7 +725,7 @@ export const EdgeSharpIcon = React.memo(
|
|||||||
strokeWidth={2}
|
strokeWidth={2}
|
||||||
fill="none"
|
fill="none"
|
||||||
/>,
|
/>,
|
||||||
{ width: 40, height: 20 },
|
{ width: 40, height: 20, mirror: true },
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -732,6 +738,6 @@ export const EdgeRoundIcon = React.memo(
|
|||||||
strokeWidth={2}
|
strokeWidth={2}
|
||||||
fill="none"
|
fill="none"
|
||||||
/>,
|
/>,
|
||||||
{ width: 40, height: 20 },
|
{ width: 40, height: 20, mirror: true },
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -104,7 +104,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ToolIcon {
|
.ToolIcon {
|
||||||
margin: 0 8px 0 0;
|
margin: 0;
|
||||||
|
margin-inline-end: 8px;
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
outline: transparent;
|
outline: transparent;
|
||||||
@ -392,7 +393,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.zIndexButton {
|
.zIndexButton {
|
||||||
margin: 0 8px 0 0;
|
margin: 0;
|
||||||
|
margin-inline-end: 8px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user