Skip to content

Commit 38ebf6e

Browse files
authored
feat: add RTL language support (#531)
* feat: add RTL language support - Add `SITE.dir` config option. - Replace physical Tailwind classes with logical property classes. Resolves #439 * docs: add `dir` section in doc
1 parent 76e15b5 commit 38ebf6e

File tree

10 files changed

+29
-22
lines changed

10 files changed

+29
-22
lines changed

src/components/BackButton.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { SITE } from "@/config";
1212
href="/"
1313
class="focus-outline mt-8 mb-2 flex hover:text-foreground/75"
1414
>
15-
<IconChevronLeft class="inline-block size-6" />
15+
<IconChevronLeft class="inline-block size-6 rtl:rotate-180" />
1616
<span>Go back</span>
1717
</LinkButton>
1818
</div>

src/components/BackToTopButton.astro

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import IconArrowNarrowUp from "@/assets/icons/IconArrowNarrowUp.svg";
66
<div
77
id="btt-btn-container"
88
class:list={[
9-
"fixed right-4 bottom-8 z-50",
10-
"md:sticky md:right-auto md:float-end md:mr-1",
9+
"fixed end-4 bottom-8 z-50",
10+
"md:sticky md:end-auto md:float-end md:me-1",
1111
"translate-y-14 opacity-0 transition duration-500",
1212
]}
1313
>

src/components/Header.astro

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const isActive = (path: string) => {
2727
<a
2828
id="skip-to-content"
2929
href="#main-content"
30-
class="absolute -top-full left-16 z-50 bg-background px-3 py-2 text-accent backdrop-blur-lg transition-all focus:top-4"
30+
class="absolute start-16 -top-full z-50 bg-background px-3 py-2 text-accent backdrop-blur-lg transition-all focus:top-4"
3131
>
3232
Skip to content
3333
</a>
@@ -47,7 +47,7 @@ const isActive = (path: string) => {
4747
</a>
4848
<nav
4949
id="nav-menu"
50-
class="flex w-full flex-col items-center sm:ml-2 sm:flex-row sm:justify-end sm:space-x-4 sm:py-0"
50+
class="flex w-full flex-col items-center sm:ms-2 sm:flex-row sm:justify-end sm:space-x-4 sm:py-0"
5151
>
5252
<button
5353
id="menu-btn"
@@ -65,7 +65,7 @@ const isActive = (path: string) => {
6565
"mt-4 grid w-44 grid-cols-2 place-content-center gap-2",
6666
"[&>li>a]:block [&>li>a]:px-4 [&>li>a]:py-3 [&>li>a]:text-center [&>li>a]:font-medium [&>li>a]:hover:text-accent sm:[&>li>a]:px-2 sm:[&>li>a]:py-1",
6767
"hidden",
68-
"sm:mt-0 sm:ml-0 sm:flex sm:w-auto sm:gap-x-5 sm:gap-y-0",
68+
"sm:mt-0 sm:flex sm:w-auto sm:gap-x-5 sm:gap-y-0",
6969
]}
7070
>
7171
<li class="col-span-2">

src/components/Pagination.astro

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,21 @@ const { page } = Astro.props;
1818
<LinkButton
1919
disabled={!page.url.prev}
2020
href={page.url.prev as string}
21-
class:list={["mr-4 select-none", { "opacity-50": !page.url.prev }]}
21+
class:list={["me-4 select-none", { "opacity-50": !page.url.prev }]}
2222
ariaLabel="Previous"
2323
>
24-
<IconArrowLeft class="inline-block" />
24+
<IconArrowLeft class="inline-block rtl:rotate-180" />
2525
Prev
2626
</LinkButton>
2727
{page.currentPage} / {page.lastPage}
2828
<LinkButton
2929
disabled={!page.url.next}
3030
href={page.url.next as string}
31-
class:list={["ml-4 select-none", { "opacity-50": !page.url.next }]}
31+
class:list={["ms-4 select-none", { "opacity-50": !page.url.next }]}
3232
ariaLabel="Next"
3333
>
3434
Next
35-
<IconArrowRight class="inline-block" />
35+
<IconArrowRight class="inline-block rtl:rotate-180" />
3636
</LinkButton>
3737
</nav>
3838
)

src/components/Tag.astro

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@ const { tag, tagName, size = "sm" } = Astro.props;
2020
href={`/tags/${tag}/`}
2121
transition:name={tag}
2222
class:list={[
23-
"relative pr-2 text-lg underline decoration-dashed group-hover:-top-0.5 group-hover:text-accent focus-visible:p-1",
23+
"relative pe-2 text-lg underline decoration-dashed group-hover:-top-0.5 group-hover:text-accent focus-visible:p-1",
2424
{ "text-sm": size === "sm" },
2525
]}
2626
>
2727
<IconHash
2828
class:list={[
2929
"inline-block opacity-80",
30-
{ "-mr-3.5 size-4": size === "sm" },
31-
{ "-mr-5 size-6": size === "lg" },
30+
{ "-me-3.5 size-4": size === "sm" },
31+
{ "-me-5 size-6": size === "lg" },
3232
]}
3333
/>
3434
&nbsp;<span>{tagName}</span>

src/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export const SITE = {
1717
url: "https://github.com/satnaing/astro-paper/edit/main/",
1818
},
1919
dynamicOgImage: true,
20+
dir: "ltr", // "rtl" | "auto"
2021
lang: "en", // html lang code. Set this empty and default will be "en"
2122
timezone: "Asia/Bangkok", // Default global timezone (IANA format) https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
2223
} as const;

src/data/blog/how-to-configure-astropaper-theme.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export const SITE = {
4343
url: "https://github.com/satnaing/astro-paper/edit/main/",
4444
},
4545
dynamicOgImage: true, // enable automatic dynamic og-image generation
46+
dir: "ltr", // "rtl" | "auto"
4647
lang: "en", // html lang code. Set this empty and default will be "en"
4748
timezone: "Asia/Bangkok", // Default global timezone (IANA format) https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
4849
} as const;
@@ -66,6 +67,7 @@ Here are SITE configuration options
6667
| `showBackButton` | Determines whether to display the `Go back` button in each blog post. |
6768
| `editPost` | This option allows users to suggest changes to a blog post by providing an edit link under blog post titles. This feature can be disabled by setting `SITE.editPost.enabled` to `false`. |
6869
| `dynamicOgImage` | This option controls whether to [generate dynamic og-image](https://astro-paper.pages.dev/posts/dynamic-og-image-generation-in-astropaper-blog-posts/) if no `ogImage` is specified in the blog post frontmatter. If you have many blog posts, you might want to disable this feature. See the [trade-off](https://astro-paper.pages.dev/posts/dynamic-og-image-generation-in-astropaper-blog-posts/#trade-off) for more details. |
70+
| `dir` | Specifies the text direction of the entire blog. Used as [HTML dir attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/dir) in `<html dir="ltr">`. Supported values: `ltr` \| `rtl` \| `auto` |
6971
| `lang` | Used as HTML ISO Language code in `<html lang"en">`. Default is `en`. |
7072
| `timezone` | This option allows you to specify your timezone using the [IANA format](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). Setting this ensures consistent timestamps across your localhost and deployed site, eliminating time differences. |
7173

src/layouts/Layout.astro

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@ const structuredData = {
4848
---
4949

5050
<!doctype html>
51-
<html lang=`${SITE.lang ?? "en"}` class={`${scrollSmooth && "scroll-smooth"}`}>
51+
<html
52+
dir={SITE.dir}
53+
lang=`${SITE.lang ?? "en"}`
54+
class={`${scrollSmooth && "scroll-smooth"}`}
55+
>
5256
<head>
5357
<meta charset="UTF-8" />
5458
<meta name="viewport" content="width=device-width" />

src/layouts/PostDetails.astro

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ const nextPost =
132132
href={getPath(prevPost.id, prevPost.filePath)}
133133
class="flex w-full gap-1 hover:opacity-75"
134134
>
135-
<IconChevronLeft class="inline-block flex-none" />
135+
<IconChevronLeft class="inline-block flex-none rtl:rotate-180" />
136136
<div>
137137
<span>Previous Post</span>
138138
<div class="text-sm text-accent/85">{prevPost.title}</div>
@@ -144,13 +144,13 @@ const nextPost =
144144
nextPost && (
145145
<a
146146
href={getPath(nextPost.id, nextPost.filePath)}
147-
class="flex w-full justify-end gap-1 text-right hover:opacity-75 sm:col-start-2"
147+
class="flex w-full justify-end gap-1 text-end hover:opacity-75 sm:col-start-2"
148148
>
149149
<div>
150150
<span>Next Post</span>
151151
<div class="text-sm text-accent/85">{nextPost.title}</div>
152152
</div>
153-
<IconChevronRight class="inline-block flex-none" />
153+
<IconChevronRight class="inline-block flex-none rtl:rotate-180" />
154154
</a>
155155
)
156156
}
@@ -211,7 +211,7 @@ const nextPost =
211211
heading.classList.add("group");
212212
const link = document.createElement("a");
213213
link.className =
214-
"heading-link ml-2 opacity-0 group-hover:opacity-100 focus:opacity-100";
214+
"heading-link ms-2 opacity-0 group-hover:opacity-100 focus:opacity-100";
215215
link.href = "#" + heading.id;
216216

217217
const span = document.createElement("span");
@@ -235,7 +235,7 @@ const nextPost =
235235

236236
const copyButton = document.createElement("button");
237237
copyButton.className =
238-
"copy-code absolute right-3 -top-3 rounded bg-muted px-2 py-1 text-xs leading-4 text-foreground font-medium";
238+
"copy-code absolute end-3 -top-3 rounded bg-muted px-2 py-1 text-xs leading-4 text-foreground font-medium";
239239
copyButton.innerHTML = copyButtonLabel;
240240
codeBlock.setAttribute("tabindex", "0");
241241
codeBlock.appendChild(copyButton);

src/pages/index.astro

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const recentPosts = sortedPosts.filter(({ data }) => !data.featured);
3737
<IconRss
3838
width={20}
3939
height={20}
40-
class="scale-125 stroke-accent stroke-3"
40+
class="scale-125 stroke-accent stroke-3 rtl:-rotate-90"
4141
/>
4242
<span class="sr-only">RSS Feed</span>
4343
</a>
@@ -61,7 +61,7 @@ const recentPosts = sortedPosts.filter(({ data }) => !data.featured);
6161
// only display if at least one social link is enabled
6262
SOCIALS.length > 0 && (
6363
<div class="mt-4 flex flex-col sm:flex-row sm:items-center">
64-
<div class="mr-2 mb-1 whitespace-nowrap sm:mb-0">Social Links:</div>
64+
<div class="me-2 mb-1 whitespace-nowrap sm:mb-0">Social Links:</div>
6565
<Socials />
6666
</div>
6767
)
@@ -103,7 +103,7 @@ const recentPosts = sortedPosts.filter(({ data }) => !data.featured);
103103
<div class="my-8 text-center">
104104
<LinkButton href="/posts/">
105105
All Posts
106-
<IconArrowRight class="inline-block" />
106+
<IconArrowRight class="inline-block rtl:-rotate-180" />
107107
</LinkButton>
108108
</div>
109109
</main>

0 commit comments

Comments
 (0)