diff --git a/src/components/AdjustableSidebarWidth.vue b/src/components/AdjustableSidebarWidth.vue
index 61a0a4ef5..02dd90209 100644
--- a/src/components/AdjustableSidebarWidth.vue
+++ b/src/components/AdjustableSidebarWidth.vue
@@ -461,11 +461,10 @@ export default {
position: fixed;
top: var(--top-offset-mobile);
bottom: 0;
- left: 0;
+ inset-inline-start: 0;
z-index: $nav-z-index + 1;
transform: translateX(-100%);
transition: transform var(--nav-transition-duration) ease-in;
- left: 0;
:deep(.aside-animated-child) {
opacity: 0;
@@ -502,7 +501,7 @@ export default {
cursor: col-resize;
top: 0;
bottom: 0;
- right: 0;
+ inset-inline-end: 0;
width: 5px;
height: 100%;
user-select: none;
diff --git a/src/components/Badge.vue b/src/components/Badge.vue
index 623504e0d..4635b3606 100644
--- a/src/components/Badge.vue
+++ b/src/components/Badge.vue
@@ -59,7 +59,7 @@ export default {
border-style: var(--badge-border-style, none);
border-width: var(--badge-border-width, 1px);
margin: auto;
- margin-left: 5px;
+ margin-inline-start: 5px;
color: var(--colors-badge-text, var(--color-badge-text));
background-color: var(--badge-color);
@include prefers-dark {
diff --git a/src/components/CodeBlock.vue b/src/components/CodeBlock.vue
index 2b2dd23e7..159633ff8 100644
--- a/src/components/CodeBlock.vue
+++ b/src/components/CodeBlock.vue
@@ -29,6 +29,10 @@ export default {
@import 'docc-render/styles/_core.scss';
code {
+ /* enforce "ltr" direction for text in code blocks right now since code is
+ likely to remain as English and not translated */
+ direction: ltr;
+
&::before {
content: attr(data-before-code);
}
diff --git a/src/components/ContentNode/Aside.vue b/src/components/ContentNode/Aside.vue
index 46f968071..f9b9ffec6 100644
--- a/src/components/ContentNode/Aside.vue
+++ b/src/components/ContentNode/Aside.vue
@@ -53,11 +53,13 @@ aside {
break-inside: avoid;
border-radius: var(--aside-border-radius, $border-radius);
border-style: var(--aside-border-style, solid);
- border-width: var(--aside-border-width,
+ /*border-width: var(--aside-border-width,
$aside-width-border
$aside-width-border
$aside-width-border
- $aside-width-left-border);
+ $aside-width-left-border);*/
+ border-block-width: $aside-width-border;
+ border-inline-width: $aside-width-left-border 0;
padding: rem(16px);
text-align: start;
diff --git a/src/components/ContentNode/LinkableHeading.vue b/src/components/ContentNode/LinkableHeading.vue
index 1a1352419..25945ff9c 100644
--- a/src/components/ContentNode/LinkableHeading.vue
+++ b/src/components/ContentNode/LinkableHeading.vue
@@ -78,7 +78,7 @@ $icon-margin: 7px;
color: inherit;
text-decoration: none;
position: relative;
- padding-right: $icon-size-default + $icon-margin;
+ padding-inline-end: $icon-size-default + $icon-margin;
display: inline-block;
&::after {
@@ -88,11 +88,11 @@ $icon-margin: 7px;
.icon {
position: absolute;
- right: 0;
+ inset-inline-end: 0;
bottom: .2em;
display: none;
height: $icon-size-default;
- margin-left: $icon-margin;
+ margin-inline-start: $icon-margin;
}
&:hover, &:focus {
diff --git a/src/components/ContentNode/TabNavigator.vue b/src/components/ContentNode/TabNavigator.vue
index 06b285580..f703f4415 100644
--- a/src/components/ContentNode/TabNavigator.vue
+++ b/src/components/ContentNode/TabNavigator.vue
@@ -130,9 +130,9 @@ export default {
.tabs-content {
flex: 1 1 auto;
min-width: 0;
- padding-right: var(--spacing-stacked-margin-xlarge);
+ padding-inline-end: var(--spacing-stacked-margin-xlarge);
@include breakpoint(small) {
- padding-right: 0;
+ padding-inline-end: 0;
padding-bottom: var(--spacing-stacked-margin-large);
}
}
diff --git a/src/components/DocumentationLayout.vue b/src/components/DocumentationLayout.vue
index 6f2fdf9a9..b3eb520e2 100644
--- a/src/components/DocumentationLayout.vue
+++ b/src/components/DocumentationLayout.vue
@@ -248,7 +248,7 @@ export default {
}
.navigator-filter .quick-navigation-open {
- margin-left: var(--nav-filter-horizontal-padding);
+ margin-inline-start: var(--nav-filter-horizontal-padding);
width: calc(var(--nav-filter-horizontal-padding) * 2);
}
}
@@ -268,14 +268,14 @@ export default {
.documentation-layout-aside {
height: 100%;
box-sizing: border-box;
- border-right: $generic-border-style;
+ border-inline-end: $generic-border-style;
@include breakpoint(medium, nav) {
background: var(--color-fill);
- border-right: none;
+ border-inline-end: none;
.sidebar-transitioning & {
- border-right: $generic-border-style;
+ border-inline-end: $generic-border-style;
}
}
}
@@ -293,8 +293,7 @@ export default {
@include inTargetWeb {
@include breakpoint-full-width-container();
@include breakpoints-from(xlarge) {
- border-left: $generic-border-style;
- border-right: $generic-border-style;
+ border-inline: $generic-border-style;
box-sizing: border-box;
}
}
diff --git a/src/components/DocumentationTopic.vue b/src/components/DocumentationTopic.vue
index 888d8018e..23c110f9d 100644
--- a/src/components/DocumentationTopic.vue
+++ b/src/components/DocumentationTopic.vue
@@ -816,7 +816,7 @@ $space-size: 15px;
small {
font-size: 1rem;
- padding-left: 0.416rem;
+ padding-inline-start: 0.416rem;
}
}
diff --git a/src/components/DocumentationTopic/DecoratedTopicTitle.vue b/src/components/DocumentationTopic/DecoratedTopicTitle.vue
index f2a3be6e1..faa853a51 100644
--- a/src/components/DocumentationTopic/DecoratedTopicTitle.vue
+++ b/src/components/DocumentationTopic/DecoratedTopicTitle.vue
@@ -75,6 +75,12 @@ export default {
diff --git a/src/components/DocumentationTopic/PrimaryContent/Parameters.vue b/src/components/DocumentationTopic/PrimaryContent/Parameters.vue
index 6528e93b9..b3e542757 100644
--- a/src/components/DocumentationTopic/PrimaryContent/Parameters.vue
+++ b/src/components/DocumentationTopic/PrimaryContent/Parameters.vue
@@ -55,7 +55,7 @@ export default {
.param-name {
font-weight: $font-weight-semibold;
- padding-left: 1rem;
+ padding-inline-start: 1rem;
padding-top: var(--spacing-param);
&:first-child {
@@ -63,15 +63,15 @@ export default {
}
@include breakpoint(small) {
- padding-left: 0;
+ padding-inline-start: 0;
}
}
.param-content {
- padding-left: 2rem;
+ padding-inline-start: 2rem;
@include breakpoint(small) {
- padding-left: 0;
+ padding-inline-start: 0;
}
:deep(dt) {
@@ -79,7 +79,7 @@ export default {
}
:deep(dd) {
- margin-left: 1em;
+ margin-inline-start: 1em;
}
}
diff --git a/src/components/DocumentationTopic/RelationshipsList.vue b/src/components/DocumentationTopic/RelationshipsList.vue
index c42c2bab1..a0f006a44 100644
--- a/src/components/DocumentationTopic/RelationshipsList.vue
+++ b/src/components/DocumentationTopic/RelationshipsList.vue
@@ -131,7 +131,7 @@ export default {
list-style: none;
&.column {
- margin-left: 0;
+ margin-inline-start: 0;
margin-top: 15px;
}
@@ -144,7 +144,7 @@ export default {
flex-direction: row;
flex-wrap: wrap;
margin-top: 15px;
- margin-left: 0;
+ margin-inline-start: 0;
li:not(:last-child)::after {
content: ",\00a0"
diff --git a/src/components/DocumentationTopic/Summary/Availability.vue b/src/components/DocumentationTopic/Summary/Availability.vue
index 8fe18ec59..1f320bbe2 100644
--- a/src/components/DocumentationTopic/Summary/Availability.vue
+++ b/src/components/DocumentationTopic/Summary/Availability.vue
@@ -113,7 +113,7 @@ $availability-info-spacing: 10px;
.changed {
$-coin-spacer: 5px;
- padding-left: $icon-size-default - $-coin-spacer + 2;
+ padding-inline-start: $icon-size-default - $-coin-spacer + 2;
border: none;
&::after {
@@ -124,7 +124,7 @@ $availability-info-spacing: 10px;
&::before {
@include coin($modified-svg, $icon-size-default);
margin: 0;
- left: -$-coin-spacer;
+ inset-inline-start: -$-coin-spacer;
@include prefers-dark {
background-image: $modified-dark-svg;
@@ -162,7 +162,7 @@ $availability-info-spacing: 10px;
width: 1px;
height: 1em;
background: currentColor;
- margin-left: $availability-info-spacing;
+ margin-inline-start: $availability-info-spacing;
}
&:last-child::after {
diff --git a/src/components/DocumentationTopic/TopicLinkBlockIcon.vue b/src/components/DocumentationTopic/TopicLinkBlockIcon.vue
index 5cfa7df53..eef0b3a9f 100644
--- a/src/components/DocumentationTopic/TopicLinkBlockIcon.vue
+++ b/src/components/DocumentationTopic/TopicLinkBlockIcon.vue
@@ -64,7 +64,7 @@ export default {
height: rem(25px);
flex: 0 0 $topic-link-icon-width;
width: $topic-link-icon-width;
- margin-right: $topic-link-icon-spacing;
+ margin-inline-end: $topic-link-icon-spacing;
}
.topic-icon {
diff --git a/src/components/DocumentationTopic/TopicsLinkBlock.vue b/src/components/DocumentationTopic/TopicsLinkBlock.vue
index f790a6e91..d9e4b4b84 100644
--- a/src/components/DocumentationTopic/TopicsLinkBlock.vue
+++ b/src/components/DocumentationTopic/TopicsLinkBlock.vue
@@ -216,11 +216,11 @@ export default {
.abstract,
.link-block :deep(.badge) {
- margin-left: calc(#{$topic-link-icon-spacing} + #{$topic-link-icon-width});
+ margin-inline-start: calc(#{$topic-link-icon-spacing} + #{$topic-link-icon-width});
}
.link-block .badge + .badge {
- margin-left: 1rem;
+ margin-inline-start: 1rem;
}
.link {
@@ -238,7 +238,7 @@ export default {
flex-flow: row wrap;
.badge {
- margin-left: 1rem;
+ margin-inline-start: 1rem;
margin-top: 0;
}
}
diff --git a/src/components/Filter/FilterInput.vue b/src/components/Filter/FilterInput.vue
index dcdf72334..9c0614500 100644
--- a/src/components/Filter/FilterInput.vue
+++ b/src/components/Filter/FilterInput.vue
@@ -456,11 +456,10 @@ $input-height: rem(28px);
position: relative;
z-index: 1;
cursor: text;
- margin-left: var(--input-horizontal-spacing);
- margin-right: rem(3px);
+ margin-inline: var(--input-horizontal-spacing) rem(3px);
@include breakpoint(small) {
- margin-right: rem(7px);
+ margin-inline-end: rem(7px);
}
.svg-icon {
@@ -522,11 +521,11 @@ $input-height: rem(28px);
&__selected-tags {
z-index: 1;
- padding-left: $tag-outline-padding;
+ padding-inline-start: $tag-outline-padding;
margin: -$tag-outline-padding 0;
@include breakpoint(small) {
- padding-left: 0;
+ padding-inline-start: 0;
}
:deep() {
@@ -534,11 +533,11 @@ $input-height: rem(28px);
padding: $tag-outline-padding;
@include breakpoint(small) {
- padding-right: rem(7px);
+ padding-inline-end: rem(7px);
}
.tag:last-child {
- padding-right: 0;
+ padding-inline-end: 0;
}
}
}
@@ -562,8 +561,7 @@ $input-height: rem(28px);
&__delete-button-wrapper {
display: flex;
align-items: center;
- padding-right: var(--input-horizontal-spacing);
- padding-left: rem(3px);
+ padding-inline: rem(3px) var(--input-horizontal-spacing);
border-top-right-radius: $small-border-radius;
border-bottom-right-radius: $small-border-radius;
}
diff --git a/src/components/Icons/InlineChevronRightIcon.vue b/src/components/Icons/InlineChevronRightIcon.vue
index 8e0d9846c..9f4d09198 100644
--- a/src/components/Icons/InlineChevronRightIcon.vue
+++ b/src/components/Icons/InlineChevronRightIcon.vue
@@ -22,3 +22,9 @@ export default {
components: { SVGIcon },
};
+
+
diff --git a/src/components/Icons/SidenavIcon.vue b/src/components/Icons/SidenavIcon.vue
index cc0121c56..79ef28c5e 100644
--- a/src/components/Icons/SidenavIcon.vue
+++ b/src/components/Icons/SidenavIcon.vue
@@ -24,3 +24,9 @@ export default {
components: { SVGIcon },
};
+
+
diff --git a/src/components/Icons/TwoLetterSymbolIcon.vue b/src/components/Icons/TwoLetterSymbolIcon.vue
index bdf63028c..7a5a137de 100644
--- a/src/components/Icons/TwoLetterSymbolIcon.vue
+++ b/src/components/Icons/TwoLetterSymbolIcon.vue
@@ -46,3 +46,12 @@ export default {
},
};
+
+
diff --git a/src/components/NavMenuItemBase.vue b/src/components/NavMenuItemBase.vue
index 5a8d94ddb..c0ea398f1 100644
--- a/src/components/NavMenuItemBase.vue
+++ b/src/components/NavMenuItemBase.vue
@@ -36,12 +36,12 @@ export default {
@import "docc-render/styles/_core.scss";
.nav-menu-item {
- margin-left: $nav-menu-item-left-margin;
+ margin-inline-start: $nav-menu-item-left-margin;
list-style: none;
min-width: 0;
@include nav-in-breakpoint {
- margin-left: 0;
+ margin-inline-start: 0;
width: 100%;
min-height: rem(42px);
// remove the first border of the first element
diff --git a/src/components/Navigator/BaseNavigatorCard.vue b/src/components/Navigator/BaseNavigatorCard.vue
index 9ef7bdd0c..cf573acce 100644
--- a/src/components/Navigator/BaseNavigatorCard.vue
+++ b/src/components/Navigator/BaseNavigatorCard.vue
@@ -134,7 +134,7 @@ $close-icon-padding: 5px;
display: flex;
flex-direction: column;
// right padding is added by the items, so visually the scroller is stuck to the side
- padding-right: 0;
+ padding-inline-end: 0;
flex: 1 1 auto;
min-height: 0;
height: 100%;
diff --git a/src/components/Navigator/BaseNavigatorCardItem.vue b/src/components/Navigator/BaseNavigatorCardItem.vue
index efe29b47f..a45102571 100644
--- a/src/components/Navigator/BaseNavigatorCardItem.vue
+++ b/src/components/Navigator/BaseNavigatorCardItem.vue
@@ -67,7 +67,9 @@ $nesting-spacing: $nav-card-horizontal-spacing + $nav-card-horizontal-spacing-sm
align-items: stretch;
min-height: $item-height;
box-sizing: border-box;
- padding: 0 var(--nav-head-wrapper-right-space) 0 var(--nav-head-wrapper-left-space);
+ padding-block: 0;
+ padding-inline-start: var(--nav-head-wrapper-left-space);
+ padding-inline-end: var(--nav-head-wrapper-right-space);
&.active {
.head-wrapper {
@@ -99,7 +101,7 @@ $nesting-spacing: $nav-card-horizontal-spacing + $nav-card-horizontal-spacing-sm
}
.navigator-icon-wrapper {
- margin-right: 7px;
+ margin-inline-end: 7px;
}
.head-wrapper {
@@ -119,3 +121,13 @@ $nesting-spacing: $nav-card-horizontal-spacing + $nav-card-horizontal-spacing-sm
@include safe-area-right-set(padding-right, var(--nav-head-wrapper-right-space));
}
+
+
diff --git a/src/components/Navigator/NavigatorCard.vue b/src/components/Navigator/NavigatorCard.vue
index 5b4199382..04df6767d 100644
--- a/src/components/Navigator/NavigatorCard.vue
+++ b/src/components/Navigator/NavigatorCard.vue
@@ -1020,7 +1020,7 @@ $navigator-card-vertical-spacing: 8px !default;
@include safe-area-left-set(margin-left, var(--card-horizontal-spacing));
@include safe-area-right-set(margin-right, var(--card-horizontal-spacing));
padding: $navigator-card-vertical-spacing $nav-card-horizontal-spacing;
- padding-left: $nav-card-horizontal-spacing * 2;
+ padding-inline-start: $nav-card-horizontal-spacing * 2;
background: $technology-title-background;
border-radius: $nano-border-radius;
display: flex;
diff --git a/src/components/Navigator/NavigatorCardItem.vue b/src/components/Navigator/NavigatorCardItem.vue
index c7c950692..73a6b0ba1 100644
--- a/src/components/Navigator/NavigatorCardItem.vue
+++ b/src/components/Navigator/NavigatorCardItem.vue
@@ -366,7 +366,7 @@ $chevron-width: $nav-card-horizontal-spacing;
position: absolute;
width: 100%;
height: 100%;
- padding-right: $tree-toggle-padding;
+ padding-inline-end: $tree-toggle-padding;
box-sizing: border-box;
z-index: 1;
display: flex;
diff --git a/src/components/Navigator/QuickNavigationModal.vue b/src/components/Navigator/QuickNavigationModal.vue
index 0fd0c90c4..7b9a8be81 100644
--- a/src/components/Navigator/QuickNavigationModal.vue
+++ b/src/components/Navigator/QuickNavigationModal.vue
@@ -531,7 +531,7 @@ $input-horizontal-spacing: rem(15px);
overflow: auto;
}
&__preview {
- border-left: $base-border-width solid var(--color-grid);
+ border-inline-start: $base-border-width solid var(--color-grid);
flex: 0 0 61.8%;
overflow: auto;
position: sticky;
@@ -560,7 +560,7 @@ $input-horizontal-spacing: rem(15px);
margin: auto;
width: 100%;
.navigator-icon {
- margin-right: rem(10px);
+ margin-inline-end: rem(10px);
}
.symbol-name {
display: flex;
@@ -572,11 +572,11 @@ $input-horizontal-spacing: rem(15px);
@include font-styles(body-reduced-tight);
color: var(--color-figure-gray-secondary);
display: flex;
- margin-left: rem(27px);
+ margin-inline-start: rem(27px);
overflow: hidden;
white-space: nowrap;
.parent-path {
- padding-right: rem(5px);
+ padding-inline-end: rem(5px);
}
}
}
diff --git a/src/components/TabnavItem.vue b/src/components/TabnavItem.vue
index 394e1e3bb..35666fa1f 100644
--- a/src/components/TabnavItem.vue
+++ b/src/components/TabnavItem.vue
@@ -58,12 +58,12 @@ $tabnav-item-gutter: rem(30px);
display: flex;
list-style: none;
- padding-left: $tabnav-item-gutter;
+ padding-inline-start: $tabnav-item-gutter;
margin: 0;
outline: none;
&:first-child {
- padding-left: 0;
+ padding-inline-start: 0;
}
// hack to make sure item margin is not overwritten by external css
@@ -97,7 +97,7 @@ $tabnav-item-gutter: rem(30px);
content: '';
position: absolute;
bottom: -1 * ($tabnav-margin + 1);
- left: 0;
+ inset-inline-start: 0;
width: 100%;
border: 1px solid transparent;
}
diff --git a/src/lang/index.js b/src/lang/index.js
index 0eb5a1122..fa1429769 100644
--- a/src/lang/index.js
+++ b/src/lang/index.js
@@ -9,15 +9,17 @@
*/
/* eslint-disable camelcase */
+import ar from './locales/ar.json';
import en_US from './locales/en-US.json';
import zh_CN from './locales/zh-CN.json';
import ja_JP from './locales/ja-JP.json';
import ko_KR from './locales/ko-KR.json';
// default locale
-export const defaultLocale = 'en-US';
+export const defaultLocale = process.env.VUE_APP_DEFAULT_LOCALE ?? 'en-US';
// translated locales
export const messages = {
+ ar,
'en-US': en_US,
'zh-CN': zh_CN,
'ja-JP': ja_JP,
diff --git a/src/lang/locales.json b/src/lang/locales.json
index 4c340feb7..079525d84 100644
--- a/src/lang/locales.json
+++ b/src/lang/locales.json
@@ -1,4 +1,9 @@
[
+ {
+ "code": "ar",
+ "name": "Arabic",
+ "slug": "ar"
+ },
{
"code": "en-US",
"name": "English",
diff --git a/src/lang/locales/ar.json b/src/lang/locales/ar.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/src/lang/locales/ar.json
@@ -0,0 +1 @@
+{}
diff --git a/src/styles/_base.scss b/src/styles/_base.scss
index ec8e3b97e..f07b584d0 100644
--- a/src/styles/_base.scss
+++ b/src/styles/_base.scss
@@ -28,3 +28,11 @@
:root {
--app-height: 100vh;
}
+
+html {
+ --scale-inline: 1;
+}
+
+html[dir="rtl"] {
+ --scale-inline: -1;
+}
diff --git a/src/styles/base/_reset.scss b/src/styles/base/_reset.scss
index e5589cccb..4e6c5d44b 100644
--- a/src/styles/base/_reset.scss
+++ b/src/styles/base/_reset.scss
@@ -80,7 +80,7 @@ img {
//============================================================
caption,
th {
- text-align: left;
+ text-align: start;
}
//============================================================
diff --git a/src/styles/base/_typography.scss b/src/styles/base/_typography.scss
index b33d872e5..53a9e8d01 100644
--- a/src/styles/base/_typography.scss
+++ b/src/styles/base/_typography.scss
@@ -63,8 +63,7 @@ button {
-moz-font-feature-settings: 'kern';
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
- direction: ltr;
- text-align: left;
+ text-align: start;
}
//
@@ -105,7 +104,7 @@ ol {
//
ul,
ol {
- margin-left: em(20px);
+ margin-inline-start: em(20px);
// remove the top margin when nesting lists
ul,
diff --git a/src/utils/metadata.js b/src/utils/metadata.js
index 2b8aeb3b7..b318ab563 100644
--- a/src/utils/metadata.js
+++ b/src/utils/metadata.js
@@ -122,10 +122,39 @@ export function addOrUpdateMetadata({
);
}
+// these are hardcoded constants needed for manually determining the
+// directionality of locales in Firefox
+//
+// this is very incomplete and will need to be manually updated to support other
+// rtl languages until the `getTextInfo().direction` API is supported in FF —
+// for now, this is just a basic set of example rtl languages
+const RtlLocales = new Set([
+ 'ar', // Arabic
+ 'he', // Hebrew
+ 'ur', // Urdu
+]);
+
+const Direction = {
+ ltr: 'ltf',
+ rtl: 'rtl',
+};
+
+function getDirection(localeName) {
+ const locale = new Intl.Locale(localeName);
+ if ((typeof locale.getTextInfo) === 'function') {
+ return locale.getTextInfo()?.direction ?? Direction.ltr;
+ }
+
+ // only needed for Firefox, which doesn't support `Intl.Locale.getTextInfo`
+ return RtlLocales.has(localeName) ? Direction.rtl : Direction.ltr;
+}
+
/**
* It updates the document setting a new lang attribute with the iso code or fallback on the locale
* @param {String} locale
*/
export function updateLangTag(locale) {
- document.querySelector('html').setAttribute('lang', locale);
+ const htmlElement = document.querySelector('html');
+ htmlElement.setAttribute('lang', locale);
+ htmlElement.setAttribute('dir', getDirection(locale));
}