diff --git a/.changeset/rare-poems-happen.md b/.changeset/rare-poems-happen.md new file mode 100644 index 000000000..d80d07393 --- /dev/null +++ b/.changeset/rare-poems-happen.md @@ -0,0 +1,9 @@ +--- +"@logto/experience": patch +"@logto/demo-app": patch +"@logto/elements": patch +"@logto/console": patch +"@logto/core": patch +--- + +improve RTL language support diff --git a/packages/console/src/App.tsx b/packages/console/src/App.tsx index c5f3a5022..d24380d6c 100644 --- a/packages/console/src/App.tsx +++ b/packages/console/src/App.tsx @@ -123,6 +123,7 @@ function Providers() { // hook will cause a re-render following some bugs here. This still works for the // initial render, so we're good for now. Consider refactoring this in the future. lang: i18next.language, + dir: i18next.dir(), }} /> diff --git a/packages/console/src/cloud/pages/Main/InvitationList/index.module.scss b/packages/console/src/cloud/pages/Main/InvitationList/index.module.scss index 3f223613f..d5032092e 100644 --- a/packages/console/src/cloud/pages/Main/InvitationList/index.module.scss +++ b/packages/console/src/cloud/pages/Main/InvitationList/index.module.scss @@ -43,7 +43,7 @@ } .tag { - margin-left: _.unit(-2); + margin-inline-start: _.unit(-2); } } diff --git a/packages/console/src/components/AppError/index.module.scss b/packages/console/src/components/AppError/index.module.scss index 8f6a541ef..df3de2080 100644 --- a/packages/console/src/components/AppError/index.module.scss +++ b/packages/console/src/components/AppError/index.module.scss @@ -36,7 +36,7 @@ .expander { display: inline-flex; align-items: center; - margin-left: _.unit(2); + margin-inline-start: _.unit(2); margin-top: _.unit(2); color: var(--color-primary); cursor: pointer; diff --git a/packages/console/src/components/AuditLogTable/components/EventName/index.module.scss b/packages/console/src/components/AuditLogTable/components/EventName/index.module.scss index 86794a94c..42118ea01 100644 --- a/packages/console/src/components/AuditLogTable/components/EventName/index.module.scss +++ b/packages/console/src/components/AuditLogTable/components/EventName/index.module.scss @@ -8,7 +8,7 @@ .icon { flex-shrink: 0; - margin-right: _.unit(1); + margin-inline-end: _.unit(1); width: 24px; height: 24px; diff --git a/packages/console/src/components/AuditLogTable/index.module.scss b/packages/console/src/components/AuditLogTable/index.module.scss index 46645153a..98e268152 100644 --- a/packages/console/src/components/AuditLogTable/index.module.scss +++ b/packages/console/src/components/AuditLogTable/index.module.scss @@ -12,11 +12,11 @@ .eventSelector { width: 300px; - margin-left: _.unit(2); + margin-inline-start: _.unit(2); } .applicationSelector { width: 250px; - margin-left: _.unit(2); + margin-inline-start: _.unit(2); } } diff --git a/packages/console/src/components/ConnectorForm/BasicForm/index.module.scss b/packages/console/src/components/ConnectorForm/BasicForm/index.module.scss index 8bea1b809..c35747433 100644 --- a/packages/console/src/components/ConnectorForm/BasicForm/index.module.scss +++ b/packages/console/src/components/ConnectorForm/BasicForm/index.module.scss @@ -15,10 +15,7 @@ border-radius: 8px; display: flex; align-items: center; - - .icon { - margin-right: _.unit(3); - } + gap: _.unit(3); .content { span { @@ -26,7 +23,7 @@ } > ul { - padding-left: _.unit(3); + padding-inline-start: _.unit(3); } } } diff --git a/packages/console/src/components/ConnectorForm/BasicForm/index.tsx b/packages/console/src/components/ConnectorForm/BasicForm/index.tsx index 0711588a6..027744620 100644 --- a/packages/console/src/components/ConnectorForm/BasicForm/index.tsx +++ b/packages/console/src/components/ConnectorForm/BasicForm/index.tsx @@ -103,9 +103,7 @@ function BasicForm({ isAllowEditTarget, isStandard, conflictConnectorName }: Pro {conflictConnectorName && (
-
- -
+
} + icon={ + + + + } className={styles.link} > diff --git a/packages/console/src/components/DetailsPage/DetailsPageHeader/index.tsx b/packages/console/src/components/DetailsPage/DetailsPageHeader/index.tsx index d72e741f6..154431509 100644 --- a/packages/console/src/components/DetailsPage/DetailsPageHeader/index.tsx +++ b/packages/console/src/components/DetailsPage/DetailsPageHeader/index.tsx @@ -105,12 +105,13 @@ function DetailsPageHeader({ additionalCustomElement, actionMenuItems, }: Props) { - const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); + const { t, i18n } = useTranslation(undefined, { keyPrefix: 'admin_console' }); const [showIcon, setShowIcon] = useState(true); const [isCompact, setIsCompact] = useState(false); const [showAdditionalCustomElement, setShowAdditionalCustomElement] = useState(true); const identifierRef = useRef(null); const operationRef = useRef(null); + const isRtl = i18n.dir() === 'rtl'; useWindowResize(() => { if (!identifierRef.current || !operationRef.current) { @@ -119,37 +120,45 @@ function DetailsPageHeader({ // Dynamically handle the visibility of the icon and action button styles. Sources: // https://www.figma.com/file/hqAWH3Di8gkiV5TXAt6juO/%F0%9F%8C%B9-%5BAC%5D-Layout-UI-Optimization?type=design&node-id=896-75673 - const { right: identifierRightEdge, width: identifierWidth } = - identifierRef.current.getBoundingClientRect(); - const operationLeftEdge = operationRef.current.getBoundingClientRect().left; + const { + left: identifierLeftEdge, + right: identifierRightEdge, + width: identifierWidth, + } = identifierRef.current.getBoundingClientRect(); + + const { left: operationLeftEdge, right: operationRightEdge } = + operationRef.current.getBoundingClientRect(); + + const identifierEdge = isRtl ? identifierLeftEdge : identifierRightEdge; + const operationEdge = isRtl ? operationRightEdge : operationLeftEdge; // When the operation buttons are in regular form, and the gap between the operation area and the identifier copy box is // only 24px. This means the window is shrinking and reaching the 1st breakpoint. Set operation buttons to compact form. - if (!isCompact && operationLeftEdge - identifierRightEdge <= 24) { + if (!isCompact && Math.abs(operationEdge - identifierEdge) <= 24) { setIsCompact(true); } // When the operation buttons are compact, and the gap between the operation area and the identifier copy box is only 24px. // This means the window keeps shrinking and reaching the 2nd breakpoint. Hide the main icon on the very left. - if (isCompact && showIcon && operationLeftEdge - identifierRightEdge <= 24) { + if (isCompact && showIcon && Math.abs(operationEdge - identifierEdge) <= 24) { setShowIcon(false); } // When the identifier copy box is 50px, and the gap between the operation area and the identifier copy box is only 24px. // This is when the page header is extremely narrow and barely has space to hold the identifier. Hide the additional custom element. - if (identifierWidth <= 50 && operationLeftEdge - identifierRightEdge <= 24) { + if (identifierWidth <= 50 && Math.abs(operationEdge - identifierEdge) <= 24) { setShowAdditionalCustomElement(false); } // When the gap between the operation buttons and the identifier copy box is greater than 80px, show the additional custom element. - if (!showAdditionalCustomElement && operationLeftEdge - identifierRightEdge > 80) { + if (!showAdditionalCustomElement && Math.abs(operationEdge - identifierEdge) > 80) { setShowAdditionalCustomElement(true); } // When the operation buttons are compact, icon is hidden, and the operation area is 120px away from the identifier copy box. // This means the window is enlarging and there is enough room to hold the icon. Show the icon. // 120px is a bit greater than the space required to hold the icon (60px + 24px padding), in order to avoid jittering. - if (isCompact && !showIcon && operationLeftEdge - identifierRightEdge > 120) { + if (isCompact && !showIcon && Math.abs(operationEdge - identifierEdge) > 120) { setShowIcon(true); } @@ -160,7 +169,7 @@ function DetailsPageHeader({ if ( isCompact && showIcon && - operationLeftEdge - identifierRightEdge > (additionalCustomElement ? 240 : 180) + Math.abs(operationEdge - identifierEdge) > (additionalCustomElement ? 240 : 180) ) { setIsCompact(false); } diff --git a/packages/console/src/components/DetailsPage/Skeleton/index.module.scss b/packages/console/src/components/DetailsPage/Skeleton/index.module.scss index d7a86f5d7..311aa5ad3 100644 --- a/packages/console/src/components/DetailsPage/Skeleton/index.module.scss +++ b/packages/console/src/components/DetailsPage/Skeleton/index.module.scss @@ -16,12 +16,12 @@ padding: _.unit(6); border-radius: 16px; background-color: var(--color-layer-1); + gap: _.unit(6); .icon { width: 60px; height: 60px; border-radius: 12px; - margin-right: _.unit(6); @include _.shimmering-animation; } diff --git a/packages/console/src/components/DetailsPage/index.tsx b/packages/console/src/components/DetailsPage/index.tsx index 2f4f86774..0d3d6384a 100644 --- a/packages/console/src/components/DetailsPage/index.tsx +++ b/packages/console/src/components/DetailsPage/index.tsx @@ -6,6 +6,7 @@ import { type To } from 'react-router-dom'; import Back from '@/assets/icons/back.svg?react'; import type DangerousRaw from '@/ds-components/DangerousRaw'; import DynamicT from '@/ds-components/DynamicT'; +import FlipOnRtl from '@/ds-components/FlipOnRtl'; import TextLink from '@/ds-components/TextLink'; import type { RequestError } from '@/hooks/use-api'; @@ -35,7 +36,15 @@ function DetailsPage({ }: Props) { return (
- } className={styles.backLink}> + + + + } + className={styles.backLink} + > {typeof backLinkTitle === 'string' ? : backLinkTitle} {isLoading ? ( diff --git a/packages/console/src/components/EntitiesTransfer/components/EntityItem/index.module.scss b/packages/console/src/components/EntitiesTransfer/components/EntityItem/index.module.scss index 78c459c72..50b1ae8d4 100644 --- a/packages/console/src/components/EntitiesTransfer/components/EntityItem/index.module.scss +++ b/packages/console/src/components/EntitiesTransfer/components/EntityItem/index.module.scss @@ -10,10 +10,10 @@ flex: 1 1 0; font: var(--font-body-2); @include _.text-ellipsis; - margin-left: _.unit(2); + margin-inline-start: _.unit(2); max-width: fit-content; } .suspended { - margin-left: _.unit(1); + margin-inline-start: _.unit(1); } diff --git a/packages/console/src/components/EntitiesTransfer/components/SourceEntityItem/index.module.scss b/packages/console/src/components/EntitiesTransfer/components/SourceEntityItem/index.module.scss index 1f4ccdfe2..5c84462b1 100644 --- a/packages/console/src/components/EntitiesTransfer/components/SourceEntityItem/index.module.scss +++ b/packages/console/src/components/EntitiesTransfer/components/SourceEntityItem/index.module.scss @@ -17,12 +17,12 @@ flex: 1 1 0; font: var(--font-body-2); @include _.text-ellipsis; - margin-left: _.unit(2); + margin-inline-start: _.unit(2); max-width: fit-content; } .suspended { - margin-left: _.unit(1); + margin-inline-start: _.unit(1); } &:hover { diff --git a/packages/console/src/components/EntitiesTransfer/components/TargetEntityItem/index.module.scss b/packages/console/src/components/EntitiesTransfer/components/TargetEntityItem/index.module.scss index 0c01be48e..7b530b14e 100644 --- a/packages/console/src/components/EntitiesTransfer/components/TargetEntityItem/index.module.scss +++ b/packages/console/src/components/EntitiesTransfer/components/TargetEntityItem/index.module.scss @@ -22,7 +22,7 @@ flex: 1 1 0; font: var(--font-body-2); @include _.text-ellipsis; - margin-left: _.unit(2); + margin-inline-start: _.unit(2); max-width: fit-content; } diff --git a/packages/console/src/components/Guide/GuideCard/index.module.scss b/packages/console/src/components/Guide/GuideCard/index.module.scss index bf6890d33..e591bd63d 100644 --- a/packages/console/src/components/Guide/GuideCard/index.module.scss +++ b/packages/console/src/components/Guide/GuideCard/index.module.scss @@ -58,12 +58,12 @@ display: flex; align-items: flex-start; // align name and the feature tag to the top justify-content: space-between; + gap: _.unit(1); } .name { font: var(--font-label-2); color: var(--color-text); - margin-right: _.unit(1); } .description { diff --git a/packages/console/src/components/Guide/ModalFooter/index.module.scss b/packages/console/src/components/Guide/ModalFooter/index.module.scss index 39754a73f..df83cab2b 100644 --- a/packages/console/src/components/Guide/ModalFooter/index.module.scss +++ b/packages/console/src/components/Guide/ModalFooter/index.module.scss @@ -15,12 +15,12 @@ justify-content: space-between; max-width: dim.$guide-main-content-max-width; margin: 0 auto; + gap: _.unit(3); } .text { font: var(--font-body-2); color: var(--color-text); - margin-right: _.unit(3); @include _.multi-line-ellipsis(2); } } diff --git a/packages/console/src/components/Guide/ModalHeader/index.module.scss b/packages/console/src/components/Guide/ModalHeader/index.module.scss index 0309365dc..0c4667ee5 100644 --- a/packages/console/src/components/Guide/ModalHeader/index.module.scss +++ b/packages/console/src/components/Guide/ModalHeader/index.module.scss @@ -1,11 +1,11 @@ @use '@/scss/underscore' as _; .requestSdkButton { - margin-right: _.unit(15); + margin-inline-end: _.unit(15); } @media screen and (max-width: 918px) { .requestSdkButton { - margin-right: 0; + margin-inline-end: 0; } } diff --git a/packages/console/src/components/Guide/StepsSkeleton/index.module.scss b/packages/console/src/components/Guide/StepsSkeleton/index.module.scss index e9c657a4a..b0d079265 100644 --- a/packages/console/src/components/Guide/StepsSkeleton/index.module.scss +++ b/packages/console/src/components/Guide/StepsSkeleton/index.module.scss @@ -9,12 +9,12 @@ background-color: var(--color-layer-1); max-width: dim.$guide-main-content-max-width; margin: 0 auto; + gap: _.unit(4); .index { width: 28px; height: 28px; border-radius: 50%; - margin-right: _.unit(4); @include _.shimmering-animation; } diff --git a/packages/console/src/components/Guide/index.module.scss b/packages/console/src/components/Guide/index.module.scss index f386e683d..0617fc8be 100644 --- a/packages/console/src/components/Guide/index.module.scss +++ b/packages/console/src/components/Guide/index.module.scss @@ -88,8 +88,7 @@ max-width: dim.$guide-main-content-max-width; > button { - margin-right: 0; - margin-left: auto; + margin-inline: auto 0; } } } diff --git a/packages/console/src/components/ItemPreview/index.module.scss b/packages/console/src/components/ItemPreview/index.module.scss index 292e43bf9..8d5d17d8e 100644 --- a/packages/console/src/components/ItemPreview/index.module.scss +++ b/packages/console/src/components/ItemPreview/index.module.scss @@ -10,11 +10,11 @@ } > div:not(:first-child) { - margin-left: _.unit(3); + margin-inline-start: _.unit(3); } .content { - padding-right: _.unit(4); + padding-inline-end: _.unit(4); overflow: hidden; display: flex; align-items: center; @@ -22,7 +22,7 @@ margin-top: _.unit(-1); > div:not(:last-child) { - margin-right: _.unit(2); + margin-inline-end: _.unit(2); } .meta { @@ -56,7 +56,7 @@ align-items: baseline; .title { - margin-right: _.unit(1); + margin-inline-end: _.unit(1); } } } diff --git a/packages/console/src/components/LivePreviewButton/index.tsx b/packages/console/src/components/LivePreviewButton/index.tsx index c773cfaac..82720c31f 100644 --- a/packages/console/src/components/LivePreviewButton/index.tsx +++ b/packages/console/src/components/LivePreviewButton/index.tsx @@ -7,6 +7,7 @@ import ExternalLinkIcon from '@/assets/icons/external-link.svg?react'; import { AppDataContext } from '@/contexts/AppDataProvider'; import type { Props as ButtonProps, ButtonType } from '@/ds-components/Button'; import Button from '@/ds-components/Button'; +import FlipOnRtl from '@/ds-components/FlipOnRtl'; import { Tooltip } from '@/ds-components/Tip'; import styles from './index.module.scss'; @@ -29,12 +30,14 @@ function LivePreviewButton({ size, type, isDisabled }: Props) { disabled={isDisabled} title="sign_in_exp.preview.live_preview" trailingIcon={ - + + + } onClick={() => { window.open(new URL('/demo-app', tenantEndpoint), '_blank'); diff --git a/packages/console/src/components/Markdown/index.module.scss b/packages/console/src/components/Markdown/index.module.scss index 4e7b22169..98ab4872f 100644 --- a/packages/console/src/components/Markdown/index.module.scss +++ b/packages/console/src/components/Markdown/index.module.scss @@ -77,7 +77,7 @@ color: var(--color-text); padding: _.unit(3); border-bottom: 1px solid var(--color-divider); - text-align: left; + text-align: start; } } diff --git a/packages/console/src/components/MfaFactorTitle/index.module.scss b/packages/console/src/components/MfaFactorTitle/index.module.scss index 0973142c4..928f7305b 100644 --- a/packages/console/src/components/MfaFactorTitle/index.module.scss +++ b/packages/console/src/components/MfaFactorTitle/index.module.scss @@ -8,9 +8,9 @@ .factorIcon { color: var(--color-text-secondary); - margin-right: _.unit(3); + margin-inline-end: _.unit(3); } .factorTip { - margin-left: _.unit(1); + margin-inline-start: _.unit(1); } diff --git a/packages/console/src/components/MultiOptionInput/index.module.scss b/packages/console/src/components/MultiOptionInput/index.module.scss index 933e08bc0..6bd7d31b9 100644 --- a/packages/console/src/components/MultiOptionInput/index.module.scss +++ b/packages/console/src/components/MultiOptionInput/index.module.scss @@ -57,7 +57,7 @@ .delete { width: 20px; height: 20px; - margin-right: _.unit(-0.5); + margin-inline-end: _.unit(-0.5); } input { diff --git a/packages/console/src/components/MultiTextInputField/index.module.scss b/packages/console/src/components/MultiTextInputField/index.module.scss index 715b900b3..e5f7cfb8b 100644 --- a/packages/console/src/components/MultiTextInputField/index.module.scss +++ b/packages/console/src/components/MultiTextInputField/index.module.scss @@ -1,5 +1,5 @@ @use '@/scss/underscore' as _; .headlineWithMultiInputs { - padding-right: _.unit(9); + padding-inline-end: _.unit(9); } diff --git a/packages/console/src/components/OpenExternalLink/index.tsx b/packages/console/src/components/OpenExternalLink/index.tsx index 649fbde7f..d2fd66ff1 100644 --- a/packages/console/src/components/OpenExternalLink/index.tsx +++ b/packages/console/src/components/OpenExternalLink/index.tsx @@ -1,6 +1,7 @@ import { useTranslation } from 'react-i18next'; import ExternalLinkIcon from '@/assets/icons/external-link.svg?react'; +import FlipOnRtl from '@/ds-components/FlipOnRtl'; import IconButton from '@/ds-components/IconButton'; import { Tooltip } from '@/ds-components/Tip'; @@ -18,7 +19,9 @@ function OpenExternalLink({ link }: Props) { window.open(link, '_blank'); }} > - + + + ); diff --git a/packages/console/src/components/PermissionsTable/index.module.scss b/packages/console/src/components/PermissionsTable/index.module.scss index 147a324bd..9419074be 100644 --- a/packages/console/src/components/PermissionsTable/index.module.scss +++ b/packages/console/src/components/PermissionsTable/index.module.scss @@ -11,7 +11,7 @@ align-items: center; .createButton { - margin-left: _.unit(2); + margin-inline-start: _.unit(2); } } @@ -25,6 +25,6 @@ } .actionColumn { - text-align: right; + text-align: end; } } diff --git a/packages/console/src/components/Region/index.module.scss b/packages/console/src/components/Region/index.module.scss index 569beaf3f..73727b5e2 100644 --- a/packages/console/src/components/Region/index.module.scss +++ b/packages/console/src/components/Region/index.module.scss @@ -4,7 +4,7 @@ font: var(--font-label-2); .comingSoon { - margin-left: _.unit(1); + margin-inline-start: _.unit(1); font: var(--font-body-2); color: var(--color-text-secondary); } diff --git a/packages/console/src/components/RoleScopesTransfer/components/ResourceItem/index.module.scss b/packages/console/src/components/RoleScopesTransfer/components/ResourceItem/index.module.scss index d9f39526a..ea63e6f78 100644 --- a/packages/console/src/components/RoleScopesTransfer/components/ResourceItem/index.module.scss +++ b/packages/console/src/components/RoleScopesTransfer/components/ResourceItem/index.module.scss @@ -16,7 +16,7 @@ overflow: hidden; .caret { - margin-right: _.unit(2); + margin-inline-end: _.unit(2); } .name { @@ -28,7 +28,7 @@ flex-shrink: 0; font: var(--font-body-2); color: var(--color-text-secondary); - margin-left: _.unit(2); + margin-inline-start: _.unit(2); } } } diff --git a/packages/console/src/components/RolesTransfer/TargetRolesBox/TargetRoleItem/index.module.scss b/packages/console/src/components/RolesTransfer/TargetRolesBox/TargetRoleItem/index.module.scss index 3936a0fdc..e4908d3f9 100644 --- a/packages/console/src/components/RolesTransfer/TargetRolesBox/TargetRoleItem/index.module.scss +++ b/packages/console/src/components/RolesTransfer/TargetRolesBox/TargetRoleItem/index.module.scss @@ -12,6 +12,6 @@ } .closeIcon { - margin-left: _.unit(1); + margin-inline-start: _.unit(1); } } diff --git a/packages/console/src/components/RolesTransfer/components/RoleInformation/index.module.scss b/packages/console/src/components/RolesTransfer/components/RoleInformation/index.module.scss index 1ddd688fa..e1b0e9b6a 100644 --- a/packages/console/src/components/RolesTransfer/components/RoleInformation/index.module.scss +++ b/packages/console/src/components/RolesTransfer/components/RoleInformation/index.module.scss @@ -13,13 +13,13 @@ // Todo @xiaoyijun Remove this `count` style together with the dev feature flag .count { flex-shrink: 0; - margin-left: _.unit(2); + margin-inline-start: _.unit(2); color: var(--color-text-secondary); } .flag { flex-shrink: 0; - margin-left: _.unit(2); + margin-inline-start: _.unit(2); color: var(--color-text-secondary); display: flex; align-items: center; diff --git a/packages/console/src/components/SignInExperiencePreview/index.module.scss b/packages/console/src/components/SignInExperiencePreview/index.module.scss index c8d4d83a7..3a30c6daa 100644 --- a/packages/console/src/components/SignInExperiencePreview/index.module.scss +++ b/packages/console/src/components/SignInExperiencePreview/index.module.scss @@ -22,7 +22,7 @@ width: _screenSize.$web-iframe-width; height: _screenSize.$web-iframe-height; transform: scaleX(_screenSize.$web-scale-x) scaleY(_screenSize.$web-scale-y); - margin-left: _screenSize.$web-to-wrapper-offset-x; + margin-inline-start: _screenSize.$web-to-wrapper-offset-x; margin-top: _screenSize.$web-to-wrapper-offset-y; } } @@ -79,7 +79,7 @@ width: _screenSize.$mobile-iframe-width; height: _screenSize.$mobile-iframe-height; transform: scaleX(_screenSize.$mobile-scale-x) scaleY(_screenSize.$mobile-scale-y); - margin-left: _screenSize.$mobile-to-wrapper-offset-x; + margin-inline-start: _screenSize.$mobile-to-wrapper-offset-x; margin-top: _screenSize.$mobile-to-wrapper-offset-y; } } diff --git a/packages/console/src/components/SubmitFormChangesActionBar/index.module.scss b/packages/console/src/components/SubmitFormChangesActionBar/index.module.scss index cd88d406c..6a98680b6 100644 --- a/packages/console/src/components/SubmitFormChangesActionBar/index.module.scss +++ b/packages/console/src/components/SubmitFormChangesActionBar/index.module.scss @@ -19,10 +19,7 @@ border-radius: 12px 12px 0 0; transform: translateY(100%); transition: transform 0.3s ease-out; - - > button + button { - margin-left: _.unit(3); - } + gap: _.unit(3); } &.active { diff --git a/packages/console/src/components/Topbar/ContactModal/index.module.scss b/packages/console/src/components/Topbar/ContactModal/index.module.scss index cfb97e140..9efeda57b 100644 --- a/packages/console/src/components/Topbar/ContactModal/index.module.scss +++ b/packages/console/src/components/Topbar/ContactModal/index.module.scss @@ -9,7 +9,7 @@ padding: _.unit(3) _.unit(4); .icon { - margin-right: _.unit(6); + margin-inline-end: _.unit(6); } &:not(:last-child) { diff --git a/packages/console/src/components/Topbar/TenantSelector/TenantDropdownItem/index.module.scss b/packages/console/src/components/Topbar/TenantSelector/TenantDropdownItem/index.module.scss index e7e739bf1..6e902a625 100644 --- a/packages/console/src/components/Topbar/TenantSelector/TenantDropdownItem/index.module.scss +++ b/packages/console/src/components/Topbar/TenantSelector/TenantDropdownItem/index.module.scss @@ -20,7 +20,7 @@ .info { display: flex; flex-direction: column; - margin-right: _.unit(4); + margin-inline-end: _.unit(4); .meta { display: flex; diff --git a/packages/console/src/components/Topbar/TenantSelector/index.module.scss b/packages/console/src/components/Topbar/TenantSelector/index.module.scss index 512d64d2a..4d9b72540 100644 --- a/packages/console/src/components/Topbar/TenantSelector/index.module.scss +++ b/packages/console/src/components/Topbar/TenantSelector/index.module.scss @@ -11,8 +11,8 @@ $dropdown-item-height: 40px; display: flex; align-items: center; padding: _.unit(1); - padding-left: _.unit(2); - margin-left: _.unit(4); + padding-inline-start: _.unit(2); + margin-inline-start: _.unit(4); max-width: 500px; border-radius: _.unit(2); transition: background-color 0.2s ease-in-out; @@ -62,6 +62,13 @@ $dropdown-item-height: 40px; pointer-events: none; cursor: default; } + + &.rtl { + &::before { + left: unset; + right: _.unit(-3); + } + } } .dropdown { diff --git a/packages/console/src/components/Topbar/TenantSelector/index.tsx b/packages/console/src/components/Topbar/TenantSelector/index.tsx index f882a351f..3b11c599d 100644 --- a/packages/console/src/components/Topbar/TenantSelector/index.tsx +++ b/packages/console/src/components/Topbar/TenantSelector/index.tsx @@ -1,4 +1,5 @@ import { OrganizationInvitationStatus } from '@logto/schemas'; +import classNames from 'classnames'; import { useContext, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; @@ -20,7 +21,7 @@ import TenantInvitationDropdownItem from './TenantInvitationDropdownItem'; import styles from './index.module.scss'; export default function TenantSelector() { - const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); + const { t, i18n } = useTranslation(undefined, { keyPrefix: 'admin_console' }); const { tenants, prependTenant, @@ -44,7 +45,7 @@ export default function TenantSelector() {
{ setShowDropdown(true); diff --git a/packages/console/src/components/Topbar/UserInfo/SubMenu/index.module.scss b/packages/console/src/components/Topbar/UserInfo/SubMenu/index.module.scss index 380ff74ee..55775b8f7 100644 --- a/packages/console/src/components/Topbar/UserInfo/SubMenu/index.module.scss +++ b/packages/console/src/components/Topbar/UserInfo/SubMenu/index.module.scss @@ -8,6 +8,7 @@ font: var(--font-body-2); border-radius: _.unit(2); cursor: pointer; + gap: _.unit(4); &:hover { background: var(--color-hover); @@ -22,7 +23,6 @@ .title { font: var(--font-body-2); - margin-left: _.unit(4); } .menu { @@ -38,6 +38,11 @@ &.visible { visibility: visible; } + + &.rtl { + right: unset; + left: calc(100% + 5px); + } } .menuOption { @@ -55,4 +60,13 @@ left: 8px; top: 10px; } + + &.rtl { + padding: _.unit(2.5) _.unit(8) _.unit(2.5) _.unit(5.5); + + .tick { + left: unset; + right: 8px; + } + } } diff --git a/packages/console/src/components/Topbar/UserInfo/SubMenu/index.tsx b/packages/console/src/components/Topbar/UserInfo/SubMenu/index.tsx index 415ac6664..ffb38069b 100644 --- a/packages/console/src/components/Topbar/UserInfo/SubMenu/index.tsx +++ b/packages/console/src/components/Topbar/UserInfo/SubMenu/index.tsx @@ -1,11 +1,13 @@ import type { AdminConsoleKey } from '@logto/phrases'; import classNames from 'classnames'; import { type ReactNode, useCallback, useState, useRef } from 'react'; +import { useTranslation } from 'react-i18next'; import ArrowRight from '@/assets/icons/arrow-right.svg?react'; import Tick from '@/assets/icons/tick.svg?react'; import { DropdownItem } from '@/ds-components/Dropdown'; import DynamicT from '@/ds-components/DynamicT'; +import FlipOnRtl from '@/ds-components/FlipOnRtl'; import OverlayScrollbar from '@/ds-components/OverlayScrollbar'; import type { Option } from '@/ds-components/Select'; import Spacer from '@/ds-components/Spacer'; @@ -42,6 +44,7 @@ function SubMenu({ const mouseEnterTimeoutRef = useRef(0); const mouseLeaveTimeoutRef = useRef(0); const [menuHeight, setMenuHeight] = useState(); + const { i18n } = useTranslation(); const calculateDropdownHeight = useCallback(() => { if (anchorRef.current) { @@ -90,9 +93,11 @@ function SubMenu({ - + + + {options.map(({ value, title }) => { @@ -104,7 +109,8 @@ function SubMenu({ className={classNames( styles.menuOption, selected && styles.selected, - menuItemClassName + menuItemClassName, + styles[i18n.dir()] )} onClick={() => { onItemClick(value); diff --git a/packages/console/src/components/Topbar/UserInfo/UserInfoSkeleton/index.module.scss b/packages/console/src/components/Topbar/UserInfo/UserInfoSkeleton/index.module.scss index 105793633..d13f743cb 100644 --- a/packages/console/src/components/Topbar/UserInfo/UserInfoSkeleton/index.module.scss +++ b/packages/console/src/components/Topbar/UserInfo/UserInfoSkeleton/index.module.scss @@ -4,13 +4,13 @@ display: flex; align-items: center; padding: _.unit(2); - margin-left: _.unit(4); + margin-inline-start: _.unit(4); border-radius: 8px; .image { width: 36px; height: 36px; - margin-right: _.unit(2); + margin-inline-end: _.unit(2); border-radius: 6px; @include _.shimmering-animation; } diff --git a/packages/console/src/components/Topbar/UserInfo/index.module.scss b/packages/console/src/components/Topbar/UserInfo/index.module.scss index 2d2582a01..5429bd3ec 100644 --- a/packages/console/src/components/Topbar/UserInfo/index.module.scss +++ b/packages/console/src/components/Topbar/UserInfo/index.module.scss @@ -57,6 +57,6 @@ } .spinner { - margin-left: _.unit(6); + margin-inline-start: _.unit(6); } } diff --git a/packages/console/src/components/Topbar/UserInfo/index.tsx b/packages/console/src/components/Topbar/UserInfo/index.tsx index 81519b3bf..42bfed860 100644 --- a/packages/console/src/components/Topbar/UserInfo/index.tsx +++ b/packages/console/src/components/Topbar/UserInfo/index.tsx @@ -15,6 +15,7 @@ import UserInfoCard from '@/components/UserInfoCard'; import { isCloud } from '@/consts/env'; import Divider from '@/ds-components/Divider'; import Dropdown, { DropdownItem } from '@/ds-components/Dropdown'; +import FlipOnRtl from '@/ds-components/FlipOnRtl'; import Spacer from '@/ds-components/Spacer'; import { Ring as Spinner } from '@/ds-components/Spinner'; import useCurrentUser from '@/hooks/use-current-user'; @@ -90,7 +91,9 @@ function UserInfo() { {t('menu.profile')}
- + + +
@@ -132,7 +135,11 @@ function UserInfo() { } + icon={ + + + + } onClick={(event) => { event.stopPropagation(); diff --git a/packages/console/src/components/Topbar/index.module.scss b/packages/console/src/components/Topbar/index.module.scss index 0de21ef48..5a743f086 100644 --- a/packages/console/src/components/Topbar/index.module.scss +++ b/packages/console/src/components/Topbar/index.module.scss @@ -37,7 +37,7 @@ user-select: none; outline: none; cursor: pointer; - margin-left: _.unit(-1); + margin-inline-start: _.unit(-1); text-decoration: none; gap: _.unit(1); font: var(--font-label-2); @@ -71,5 +71,5 @@ height: 8px; border-radius: 50%; background-color: var(--color-error); - margin-left: _.unit(0.5); + margin-inline-start: _.unit(0.5); } diff --git a/packages/console/src/components/UserAccountInformation/index.module.scss b/packages/console/src/components/UserAccountInformation/index.module.scss index 4a5884ab7..c17bc9d8c 100644 --- a/packages/console/src/components/UserAccountInformation/index.module.scss +++ b/packages/console/src/components/UserAccountInformation/index.module.scss @@ -20,11 +20,11 @@ .infoContent { font: var(--font-label-2); - padding-left: _.unit(1); + padding-inline-start: _.unit(1); } .operation { - padding-left: _.unit(1); + padding-inline-start: _.unit(1); } .eyeIcon { diff --git a/packages/console/src/components/UserAvatar/index.module.scss b/packages/console/src/components/UserAvatar/index.module.scss index 7e8dbd60a..a9d0a0c56 100644 --- a/packages/console/src/components/UserAvatar/index.module.scss +++ b/packages/console/src/components/UserAvatar/index.module.scss @@ -45,7 +45,11 @@ width: 48px; height: 48px; object-fit: cover; - transform-origin: 0 0; + transform-origin: top left; + + &.rtl { + transform-origin: top right; + } &.micro { transform: scale(0.416); @@ -90,6 +94,6 @@ .value { // Fixed font color should used in Tooltip component as the color does not change when theme changes. color: #f7f8f8; - margin-left: _.unit(1); + margin-inline-start: _.unit(1); } } diff --git a/packages/console/src/components/UserAvatar/index.tsx b/packages/console/src/components/UserAvatar/index.tsx index 71c7c9df0..e085ca01c 100644 --- a/packages/console/src/components/UserAvatar/index.tsx +++ b/packages/console/src/components/UserAvatar/index.tsx @@ -46,7 +46,8 @@ function UserInfoTipContent({ user }: { readonly user: Partial }) { } function UserAvatar({ className, size = 'medium', user, hasTooltip = false }: Props) { - const avatarClassName = classNames(styles.avatar, styles[size]); + const { i18n } = useTranslation(); + const avatarClassName = classNames(styles.avatar, styles[size], styles[i18n.dir()]); const wrapperClassName = classNames(styles.wrapper, styles[size], className); const defaultColorPalette = [ '#E74C3C', diff --git a/packages/console/src/components/UserInfoCard/index.module.scss b/packages/console/src/components/UserInfoCard/index.module.scss index 058b95d7f..d78d257d7 100644 --- a/packages/console/src/components/UserInfoCard/index.module.scss +++ b/packages/console/src/components/UserInfoCard/index.module.scss @@ -5,12 +5,12 @@ align-items: center; user-select: none; cursor: default; + gap: _.unit(3); } .nameWrapper { display: flex; flex-direction: column; - margin-left: _.unit(3); .name { font: var(--font-label-2); diff --git a/packages/console/src/components/UserName/index.module.scss b/packages/console/src/components/UserName/index.module.scss index bd9461ce4..bdd63abca 100644 --- a/packages/console/src/components/UserName/index.module.scss +++ b/packages/console/src/components/UserName/index.module.scss @@ -11,7 +11,7 @@ @include _.text-ellipsis; span { - margin-left: _.unit(2); + margin-inline-start: _.unit(2); } } diff --git a/packages/console/src/components/VerificationCodeInput/index.module.scss b/packages/console/src/components/VerificationCodeInput/index.module.scss index acec145ea..c7c0aa14e 100644 --- a/packages/console/src/components/VerificationCodeInput/index.module.scss +++ b/packages/console/src/components/VerificationCodeInput/index.module.scss @@ -33,6 +33,6 @@ .errorMessage { font: var(--font-body-2); color: var(--color-error); - margin-left: _.unit(0.5); + margin-inline-start: _.unit(0.5); margin-top: _.unit(1); } diff --git a/packages/console/src/containers/ConsoleContent/Sidebar/components/Item/index.module.scss b/packages/console/src/containers/ConsoleContent/Sidebar/components/Item/index.module.scss index 696e6ea77..207071337 100644 --- a/packages/console/src/containers/ConsoleContent/Sidebar/components/Item/index.module.scss +++ b/packages/console/src/containers/ConsoleContent/Sidebar/components/Item/index.module.scss @@ -13,6 +13,11 @@ background: none; border: none; width: calc(100% - _.unit(10)); + gap: _.unit(4); + + &.rtl { + margin: _.unit(1) _.unit(4) _.unit(1) _.unit(6); + } .icon { height: _.unit(5); @@ -38,10 +43,6 @@ } } - > div + div { - margin-left: _.unit(4); - } - .title { font: var(--font-label-2); } diff --git a/packages/console/src/containers/ConsoleContent/Sidebar/components/Item/index.tsx b/packages/console/src/containers/ConsoleContent/Sidebar/components/Item/index.tsx index 641d1e1c9..a8afad73c 100644 --- a/packages/console/src/containers/ConsoleContent/Sidebar/components/Item/index.tsx +++ b/packages/console/src/containers/ConsoleContent/Sidebar/components/Item/index.tsx @@ -18,7 +18,7 @@ type Props = { }; function Item({ icon, titleKey, modal, externalLink, isActive = false }: Props) { - const { t } = useTranslation(undefined, { + const { t, i18n } = useTranslation(undefined, { keyPrefix: 'admin_console.tabs', }); const [isOpen, setIsOpen] = useState(false); @@ -37,7 +37,7 @@ function Item({ icon, titleKey, modal, externalLink, isActive = false }: Props) return ( <> ); }; diff --git a/packages/experience/src/components/Button/SocialLinkButton.module.scss b/packages/experience/src/components/Button/SocialLinkButton.module.scss index 1f0a5a148..3ad6b73f0 100644 --- a/packages/experience/src/components/Button/SocialLinkButton.module.scss +++ b/packages/experience/src/components/Button/SocialLinkButton.module.scss @@ -24,7 +24,7 @@ .name { flex: 1; overflow: hidden; - margin-left: _.unit(-6); + margin-inline-start: _.unit(-6); @include _.flex-row; height: 100%; diff --git a/packages/experience/src/components/Button/index.module.scss b/packages/experience/src/components/Button/index.module.scss index 770ec64ca..c04342b40 100644 --- a/packages/experience/src/components/Button/index.module.scss +++ b/packages/experience/src/components/Button/index.module.scss @@ -31,7 +31,7 @@ } &.iconVisible { - padding-left: _.unit(7); + padding-inline-start: _.unit(7); .icon { left: 0; diff --git a/packages/experience/src/components/Checkbox/index.module.scss b/packages/experience/src/components/Checkbox/index.module.scss index 1db103ef5..6aa3ea7f4 100644 --- a/packages/experience/src/components/Checkbox/index.module.scss +++ b/packages/experience/src/components/Checkbox/index.module.scss @@ -6,7 +6,7 @@ align-items: center; .icon { - margin-right: _.unit(2); + margin-inline-end: _.unit(2); width: 18px; height: 18px; diff --git a/packages/experience/src/components/ConfirmModal/Acmodal.module.scss b/packages/experience/src/components/ConfirmModal/Acmodal.module.scss index 46e9daa00..bfa9207b5 100644 --- a/packages/experience/src/components/ConfirmModal/Acmodal.module.scss +++ b/packages/experience/src/components/ConfirmModal/Acmodal.module.scss @@ -56,7 +56,7 @@ } > button:first-child { - margin-right: _.unit(3); + margin-inline-end: _.unit(3); } } diff --git a/packages/experience/src/components/ConfirmModal/MobileModal.module.scss b/packages/experience/src/components/ConfirmModal/MobileModal.module.scss index 9a3e7e640..59ef2035f 100644 --- a/packages/experience/src/components/ConfirmModal/MobileModal.module.scss +++ b/packages/experience/src/components/ConfirmModal/MobileModal.module.scss @@ -45,7 +45,7 @@ } > button:first-child { - margin-right: _.unit(2); + margin-inline-end: _.unit(2); } } diff --git a/packages/experience/src/components/Divider/index.module.scss b/packages/experience/src/components/Divider/index.module.scss index 964739418..8d806dfc9 100644 --- a/packages/experience/src/components/Divider/index.module.scss +++ b/packages/experience/src/components/Divider/index.module.scss @@ -13,11 +13,11 @@ &.withLabel { &:first-child { - margin-right: _.unit(4); + margin-inline-end: _.unit(4); } &:last-child { - margin-left: _.unit(4); + margin-inline-start: _.unit(4); } } } diff --git a/packages/experience/src/components/FlipOnRtl/index.module.scss b/packages/experience/src/components/FlipOnRtl/index.module.scss new file mode 100644 index 000000000..c7d735b82 --- /dev/null +++ b/packages/experience/src/components/FlipOnRtl/index.module.scss @@ -0,0 +1,3 @@ +.flip { + transform: scaleX(-1); +} diff --git a/packages/experience/src/components/FlipOnRtl/index.tsx b/packages/experience/src/components/FlipOnRtl/index.tsx new file mode 100644 index 000000000..c39698a02 --- /dev/null +++ b/packages/experience/src/components/FlipOnRtl/index.tsx @@ -0,0 +1,38 @@ +import classNames from 'classnames'; +import { cloneElement, isValidElement, type ReactElement } from 'react'; +import { useTranslation } from 'react-i18next'; + +import styles from './index.module.scss'; + +type Props = { + readonly children: ReactElement; +}; + +/** + * This component flips its child element horizontally if the browser's text direction is RTL (right-to-left). + * + * @component + * @example + * ```tsx + * + * + * + * ``` + * + * @param {React.ReactNode} children - The SVG or other HTML content to render and flip if RTL. + * @returns {JSX.Element} The flipped content. + */ +function FlipOnRtl({ children }: Props) { + const { i18n } = useTranslation(); + const isRtl = i18n.dir() === 'rtl'; + + if (!isValidElement(children)) { + return children; + } + + return cloneElement(children, { + className: classNames(children.props.className, isRtl && styles.flip), + }); +} + +export default FlipOnRtl; diff --git a/packages/experience/src/components/IdentifierRegisterForm/index.module.scss b/packages/experience/src/components/IdentifierRegisterForm/index.module.scss index 8fa4bbd9a..d5091e5c5 100644 --- a/packages/experience/src/components/IdentifierRegisterForm/index.module.scss +++ b/packages/experience/src/components/IdentifierRegisterForm/index.module.scss @@ -19,7 +19,7 @@ } .formErrors { - margin-left: _.unit(0.5); + margin-inline-start: _.unit(0.5); margin-top: _.unit(-3); } diff --git a/packages/experience/src/components/IdentifierSignInForm/index.module.scss b/packages/experience/src/components/IdentifierSignInForm/index.module.scss index eead6c389..fb44b438a 100644 --- a/packages/experience/src/components/IdentifierSignInForm/index.module.scss +++ b/packages/experience/src/components/IdentifierSignInForm/index.module.scss @@ -19,7 +19,7 @@ } .formErrors { - margin-left: _.unit(0.5); + margin-inline-start: _.unit(0.5); margin-top: _.unit(-3); } diff --git a/packages/experience/src/components/InputFields/InputField/NotchedBorder/index.module.scss b/packages/experience/src/components/InputFields/InputField/NotchedBorder/index.module.scss index e063b0cfe..b8d676b0d 100644 --- a/packages/experience/src/components/InputFields/InputField/NotchedBorder/index.module.scss +++ b/packages/experience/src/components/InputFields/InputField/NotchedBorder/index.module.scss @@ -7,7 +7,7 @@ .border, .outline { - text-align: left; + text-align: start; position: absolute; inset: -10px 0 -0.5px; border: _.border(var(--color-line-border)); @@ -22,7 +22,7 @@ display: inline-block; visibility: hidden; // To keep the label in the middle of the empty space - margin-left: 1px; + margin-inline-start: 1px; padding: 0; // fix to the label font height to keep space for the input container height: 20px; @@ -88,6 +88,12 @@ } } +.container.rtl { + .label { + left: unset; + right: _.unit(3.5); + } +} .container.danger { .border { diff --git a/packages/experience/src/components/InputFields/InputField/NotchedBorder/index.tsx b/packages/experience/src/components/InputFields/InputField/NotchedBorder/index.tsx index f8e097e47..133a20071 100644 --- a/packages/experience/src/components/InputFields/InputField/NotchedBorder/index.tsx +++ b/packages/experience/src/components/InputFields/InputField/NotchedBorder/index.tsx @@ -1,4 +1,5 @@ import classNames from 'classnames'; +import { useTranslation } from 'react-i18next'; import styles from './index.module.scss'; @@ -26,6 +27,8 @@ type Props = { * */ const NotchedBorder = ({ label, isActive, isDanger, isFocused }: Props) => { + const { i18n } = useTranslation(); + return (
{ isDanger && styles.danger, isActive && styles.active, isFocused && styles.focused, - !label && styles.noLabel + !label && styles.noLabel, + styles[i18n.dir()] )} >
diff --git a/packages/experience/src/components/InputFields/InputField/index.module.scss b/packages/experience/src/components/InputFields/InputField/index.module.scss index a63504c1f..0f195d777 100644 --- a/packages/experience/src/components/InputFields/InputField/index.module.scss +++ b/packages/experience/src/components/InputFields/InputField/index.module.scss @@ -57,7 +57,7 @@ .suffix { position: absolute; - right: _.unit(2); + inset-inline-end: _.unit(2); top: 50%; transform: translateY(-50%); width: _.unit(8); @@ -68,7 +68,7 @@ &.isSuffixFocusVisible:focus-within { input { - padding-right: _.unit(10); + padding-inline-end: _.unit(10); } .suffix { @@ -110,7 +110,7 @@ .errorMessage { margin-top: _.unit(1); - margin-left: _.unit(0.5); + margin-inline-start: _.unit(0.5); } diff --git a/packages/experience/src/components/InputFields/InputField/index.tsx b/packages/experience/src/components/InputFields/InputField/index.tsx index 345a1e73c..407036cdb 100644 --- a/packages/experience/src/components/InputFields/InputField/index.tsx +++ b/packages/experience/src/components/InputFields/InputField/index.tsx @@ -10,6 +10,7 @@ import { useEffect, useCallback, } from 'react'; +import { useTranslation } from 'react-i18next'; import ErrorMessage from '@/components/ErrorMessage'; @@ -47,6 +48,7 @@ const InputField = ( }: Props, reference: Ref> ) => { + const { i18n } = useTranslation(); const innerRef = useRef(null); useImperativeHandle(reference, () => innerRef.current); @@ -94,7 +96,8 @@ const InputField = ( className={classNames( styles.inputField, isSuffixFocusVisible && styles.isSuffixFocusVisible, - inputFieldClassName + inputFieldClassName, + styles[i18n.dir()] )} > {prefix} diff --git a/packages/experience/src/components/InputFields/SmartInputField/CountryCodeSelector/CountryCodeDropdown/index.module.scss b/packages/experience/src/components/InputFields/SmartInputField/CountryCodeSelector/CountryCodeDropdown/index.module.scss index 5bc8098d7..ed66a7cc1 100644 --- a/packages/experience/src/components/InputFields/SmartInputField/CountryCodeSelector/CountryCodeDropdown/index.module.scss +++ b/packages/experience/src/components/InputFields/SmartInputField/CountryCodeSelector/CountryCodeDropdown/index.module.scss @@ -27,7 +27,7 @@ margin-bottom: _.unit(2); input { - padding-left: _.unit(2); + padding-inline-start: _.unit(2); } svg { @@ -48,12 +48,12 @@ cursor: pointer; > svg { - margin-right: _.unit(1); + margin-inline-end: _.unit(1); } &.active { color: var(--color-type-link); - padding-left: calc(_.unit(7) - _.unit(6)); + padding-inline-start: calc(_.unit(7) - _.unit(6)); } &.selected { @@ -114,7 +114,7 @@ } .innerInputFiled { - padding-left: _.unit(4); + padding-inline-start: _.unit(4); } } } diff --git a/packages/experience/src/components/InputFields/SmartInputField/CountryCodeSelector/index.module.scss b/packages/experience/src/components/InputFields/SmartInputField/CountryCodeSelector/index.module.scss index 1cac34a3d..aefdd77f3 100644 --- a/packages/experience/src/components/InputFields/SmartInputField/CountryCodeSelector/index.module.scss +++ b/packages/experience/src/components/InputFields/SmartInputField/CountryCodeSelector/index.module.scss @@ -9,8 +9,7 @@ background: none; position: relative; height: 100%; - padding-right: _.unit(1); - padding-left: _.unit(4); + padding-inline: _.unit(4) _.unit(1); @include _.flex-row; overflow: hidden; white-space: nowrap; @@ -30,7 +29,7 @@ > svg { flex-shrink: 0; color: var(--color-type-secondary); - margin-left: _.unit(1); + margin-inline-start: _.unit(1); width: 16px; height: 16px; } @@ -41,7 +40,7 @@ font: var(--font-body-2); > svg { - margin-left: _.unit(2); + margin-inline-start: _.unit(2); width: 20px; height: 20px; } diff --git a/packages/experience/src/components/InputFields/SmartInputField/index.tsx b/packages/experience/src/components/InputFields/SmartInputField/index.tsx index e0e631a28..543967082 100644 --- a/packages/experience/src/components/InputFields/SmartInputField/index.tsx +++ b/packages/experience/src/components/InputFields/SmartInputField/index.tsx @@ -50,8 +50,8 @@ const SmartInputField = ( }); const isPrefixVisible = identifierType === SignInIdentifier.Phone; - const { paddingLeft } = useSpring({ - paddingLeft: isPrefixVisible ? 4 : 16, + const { paddingInlineStart } = useSpring({ + paddingInlineStart: isPrefixVisible ? 4 : 16, config: { ...config.default, clamp: true }, }); @@ -68,7 +68,7 @@ const SmartInputField = ( {...rest} ref={innerRef} isSuffixFocusVisible={Boolean(inputValue)} - style={{ paddingLeft }} + style={{ paddingInlineStart }} value={inputValue} isPrefixVisible={isPrefixVisible} prefix={ diff --git a/packages/experience/src/components/LogtoSignature/index.module.scss b/packages/experience/src/components/LogtoSignature/index.module.scss index d629966e0..db2916e19 100644 --- a/packages/experience/src/components/LogtoSignature/index.module.scss +++ b/packages/experience/src/components/LogtoSignature/index.module.scss @@ -9,6 +9,7 @@ padding: _.unit(1) _.unit(2); text-decoration: none; opacity: 75%; + direction: ltr; .staticIcon { display: block; @@ -32,7 +33,7 @@ } .text { - margin-right: _.unit(1); + margin-inline-end: _.unit(1); } } diff --git a/packages/experience/src/components/NavBar/index.module.scss b/packages/experience/src/components/NavBar/index.module.scss index 81a6ab36b..49d467812 100644 --- a/packages/experience/src/components/NavBar/index.module.scss +++ b/packages/experience/src/components/NavBar/index.module.scss @@ -20,7 +20,7 @@ .navButton { position: absolute; - left: 0; + inset-inline-start: 0; top: 50%; transform: translateY(-50%); font: var(--font-label-2); @@ -30,13 +30,13 @@ .skipButton { position: absolute; - right: 0; + inset-inline-end: 0; top: 50%; transform: translateY(-50%); font: var(--font-label-1); cursor: pointer; color: var(--color-type-link); - padding-right: _.unit(1); + padding-inline-end: _.unit(1); } :global(body.mobile) { diff --git a/packages/experience/src/components/NavBar/index.tsx b/packages/experience/src/components/NavBar/index.tsx index abcfdab53..e5e1bb607 100644 --- a/packages/experience/src/components/NavBar/index.tsx +++ b/packages/experience/src/components/NavBar/index.tsx @@ -7,6 +7,8 @@ import ArrowPrev from '@/assets/icons/arrow-prev.svg?react'; import NavClose from '@/assets/icons/nav-close.svg?react'; import { onKeyDownHandler } from '@/utils/a11y'; +import FlipOnRtl from '../FlipOnRtl'; + import styles from './index.module.scss'; type Props = { @@ -48,7 +50,13 @@ const NavBar = ({ title, type = 'back', isHidden, onClose, onSkip }: Props) => { onKeyDown={onKeyDownHandler(clickHandler)} onClick={clickHandler} > - {isClosable ? : } + {isClosable ? ( + + ) : ( + + + + )} {!isClosable && {t('action.nav_back')}}
{title &&
{title}
} diff --git a/packages/experience/src/components/Notification/AppNotification/index.module.scss b/packages/experience/src/components/Notification/AppNotification/index.module.scss index aeee21fe3..9a191f6b8 100644 --- a/packages/experience/src/components/Notification/AppNotification/index.module.scss +++ b/packages/experience/src/components/Notification/AppNotification/index.module.scss @@ -14,13 +14,13 @@ .icon { width: 20px; height: 20px; - margin-right: _.unit(3); + margin-inline-end: _.unit(3); color: var(--color-neutral-variant-60); } .message { flex: 1; - margin-right: _.unit(4); + margin-inline-end: _.unit(4); } .link { diff --git a/packages/experience/src/components/PasswordSignInForm/index.module.scss b/packages/experience/src/components/PasswordSignInForm/index.module.scss index fd80ec7c5..47ee75ac4 100644 --- a/packages/experience/src/components/PasswordSignInForm/index.module.scss +++ b/packages/experience/src/components/PasswordSignInForm/index.module.scss @@ -26,7 +26,7 @@ } .formErrors { - margin-left: _.unit(0.5); + margin-inline-start: _.unit(0.5); margin-top: _.unit(-3); } diff --git a/packages/experience/src/components/SingleSignOnForm/index.module.scss b/packages/experience/src/components/SingleSignOnForm/index.module.scss index 3706ca03c..e2984c8e2 100644 --- a/packages/experience/src/components/SingleSignOnForm/index.module.scss +++ b/packages/experience/src/components/SingleSignOnForm/index.module.scss @@ -13,7 +13,7 @@ } .formErrors { - margin-left: _.unit(0.5); + margin-inline-start: _.unit(0.5); margin-top: _.unit(-3); } diff --git a/packages/experience/src/components/TextLink/index.module.scss b/packages/experience/src/components/TextLink/index.module.scss index c5bfc937b..5348c7e8c 100644 --- a/packages/experience/src/components/TextLink/index.module.scss +++ b/packages/experience/src/components/TextLink/index.module.scss @@ -7,7 +7,7 @@ justify-content: center; > svg { - margin-right: _.unit(2); + margin-inline-end: _.unit(2); } &.primary { diff --git a/packages/experience/src/components/VerificationCode/index.module.scss b/packages/experience/src/components/VerificationCode/index.module.scss index e182f14fd..f4303d8c3 100644 --- a/packages/experience/src/components/VerificationCode/index.module.scss +++ b/packages/experience/src/components/VerificationCode/index.module.scss @@ -27,7 +27,7 @@ } .passcode + .errorMessage { - margin-left: _.unit(0.5); + margin-inline-start: _.unit(0.5); margin-top: _.unit(1); } diff --git a/packages/experience/src/containers/SetPassword/index.module.scss b/packages/experience/src/containers/SetPassword/index.module.scss index dd3110917..5a15f67af 100644 --- a/packages/experience/src/containers/SetPassword/index.module.scss +++ b/packages/experience/src/containers/SetPassword/index.module.scss @@ -14,7 +14,7 @@ } .formErrors { - margin-left: _.unit(0.5); + margin-inline-start: _.unit(0.5); margin-top: _.unit(-3); } } @@ -26,7 +26,7 @@ cursor: pointer; .checkbox { - margin-right: _.unit(2); + margin-inline-end: _.unit(2); fill: var(--color-type-secondary); cursor: pointer; } diff --git a/packages/experience/src/containers/SocialLinkAccount/index.module.scss b/packages/experience/src/containers/SocialLinkAccount/index.module.scss index d5a8caed6..823d460e6 100644 --- a/packages/experience/src/containers/SocialLinkAccount/index.module.scss +++ b/packages/experience/src/containers/SocialLinkAccount/index.module.scss @@ -11,12 +11,12 @@ .desc { @include _.text-hint; - text-align: left; + text-align: start; } .hint { @include _.text-hint; - text-align: left; + text-align: start; margin-top: _.unit(6); } diff --git a/packages/experience/src/containers/TermsAndPrivacyCheckbox/index.module.scss b/packages/experience/src/containers/TermsAndPrivacyCheckbox/index.module.scss index df79bb41d..c5a828c2d 100644 --- a/packages/experience/src/containers/TermsAndPrivacyCheckbox/index.module.scss +++ b/packages/experience/src/containers/TermsAndPrivacyCheckbox/index.module.scss @@ -8,7 +8,7 @@ } .checkbox { - margin-right: _.unit(2); + margin-inline-end: _.unit(2); fill: var(--color-type-secondary); cursor: pointer; } diff --git a/packages/experience/src/pages/Consent/OrganizationSelector/OrganizationItem/index.module.scss b/packages/experience/src/pages/Consent/OrganizationSelector/OrganizationItem/index.module.scss index cb102c657..016d9f77b 100644 --- a/packages/experience/src/pages/Consent/OrganizationSelector/OrganizationItem/index.module.scss +++ b/packages/experience/src/pages/Consent/OrganizationSelector/OrganizationItem/index.module.scss @@ -10,7 +10,7 @@ width: 20px; height: 20px; color: var(--color-type-secondary); - margin-right: _.unit(2); + margin-inline-end: _.unit(2); } .organizationName { diff --git a/packages/experience/src/pages/Consent/ScopeGroup/index.module.scss b/packages/experience/src/pages/Consent/ScopeGroup/index.module.scss index b16e41b30..a102d9789 100644 --- a/packages/experience/src/pages/Consent/ScopeGroup/index.module.scss +++ b/packages/experience/src/pages/Consent/ScopeGroup/index.module.scss @@ -18,13 +18,13 @@ color: var(--color-success-pressed); width: 20px; height: 20px; - margin-right: _.unit(2); + margin-inline-end: _.unit(2); } .scopeGroupName { font: var(--font-body-2); flex: 1; - margin-right: _.unit(2); + margin-inline-end: _.unit(2); } .toggleButton { diff --git a/packages/experience/src/pages/Consent/ScopesListCard/index.module.scss b/packages/experience/src/pages/Consent/ScopesListCard/index.module.scss index e8339c36d..b2c44e055 100644 --- a/packages/experience/src/pages/Consent/ScopesListCard/index.module.scss +++ b/packages/experience/src/pages/Consent/ScopesListCard/index.module.scss @@ -29,13 +29,13 @@ color: var(--color-success-pressed); width: 20px; height: 20px; - margin-right: _.unit(2); + margin-inline-end: _.unit(2); } .scopeGroupName { font: var(--font-body-2); flex: 1; - margin-right: _.unit(2); + margin-inline-end: _.unit(2); } .toggleButton { diff --git a/packages/experience/src/pages/Consent/UserProfile/index.module.scss b/packages/experience/src/pages/Consent/UserProfile/index.module.scss index be7caea59..2ba69acda 100644 --- a/packages/experience/src/pages/Consent/UserProfile/index.module.scss +++ b/packages/experience/src/pages/Consent/UserProfile/index.module.scss @@ -13,7 +13,7 @@ border-radius: 6px; object-fit: fill; object-position: center; - margin-right: _.unit(3); + margin-inline-end: _.unit(3); } .name { diff --git a/packages/experience/src/pages/Continue/IdentifierProfileForm/index.module.scss b/packages/experience/src/pages/Continue/IdentifierProfileForm/index.module.scss index 74d3215ec..931f63e54 100644 --- a/packages/experience/src/pages/Continue/IdentifierProfileForm/index.module.scss +++ b/packages/experience/src/pages/Continue/IdentifierProfileForm/index.module.scss @@ -13,7 +13,7 @@ } .formErrors { - margin-left: _.unit(0.5); + margin-inline-start: _.unit(0.5); margin-top: _.unit(-3); } } diff --git a/packages/experience/src/pages/ForgotPassword/ForgotPasswordForm/index.module.scss b/packages/experience/src/pages/ForgotPassword/ForgotPasswordForm/index.module.scss index 74d3215ec..931f63e54 100644 --- a/packages/experience/src/pages/ForgotPassword/ForgotPasswordForm/index.module.scss +++ b/packages/experience/src/pages/ForgotPassword/ForgotPasswordForm/index.module.scss @@ -13,7 +13,7 @@ } .formErrors { - margin-left: _.unit(0.5); + margin-inline-start: _.unit(0.5); margin-top: _.unit(-3); } } diff --git a/packages/experience/src/pages/SignInPassword/index.module.scss b/packages/experience/src/pages/SignInPassword/index.module.scss index 40199b36f..d042d3994 100644 --- a/packages/experience/src/pages/SignInPassword/index.module.scss +++ b/packages/experience/src/pages/SignInPassword/index.module.scss @@ -28,7 +28,7 @@ } .formErrors { - margin-left: _.unit(0.5); + margin-inline-start: _.unit(0.5); margin-top: _.unit(-3); } }