From 7c2bcc83b1d6cc237830970239d2951c66fcc42c Mon Sep 17 00:00:00 2001 From: GustaveWPM Date: Sun, 29 Oct 2023 20:28:40 +0100 Subject: [PATCH 1/6] chore(docs): add rtl support (#220) --- docs/pages/docs/rtl-support.mdx | 118 ++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 docs/pages/docs/rtl-support.mdx diff --git a/docs/pages/docs/rtl-support.mdx b/docs/pages/docs/rtl-support.mdx new file mode 100644 index 0000000..cba0ad3 --- /dev/null +++ b/docs/pages/docs/rtl-support.mdx @@ -0,0 +1,118 @@ +import { Tabs, Tab } from 'nextra/components' + +# RTL supoprt + +In case you want the `dir` attribute of your HTML node to adjust based on the current locale, you'll need to add some logic. + +## From the root layout + +```tsx +// layout.tsx (root layout) +export default function Layout({ children, params: { locale } }: { children: ReactElement, params: { locale: string } }) => { + const dir = new Intl.Locale(locale).getTextInfo().direction + + return ( + + + {children} + + + ); +}; +``` + +### Caveat + +Note that this doesn't work in Firefox, if your root layout is a client component. +This is because `Intl.Locale.prototype.getTextInfo` is not yet supported in Firefox, even if it is built-in in Node.js. + +To cover this, you can add a _polyfill_ to guarantee compatibility with all browsers, until this standard is fully adopted. + +To do this, you can firstly add this polyfill: + + + + ```bash + pnpm install intl-locale-textinfo-polyfill + ``` + + + ```bash + npm install intl-locale-textinfo-polyfill + ``` + + + ```bash + yarn add intl-locale-textinfo-polyfill + ``` + + + ```bash + bun add intl-locale-textinfo-polyfill + ``` + + + +And then write: + +```tsx +// layout.tsx (root layout) +import Locale from 'intl-locale-textinfo-polyfill'; + +export default function Layout({ children, params: { locale } }: { children: ReactElement, params: { locale: string } }) => { + const { direction: dir } = new Locale(locale).textInfo; + + return ( + + + {children} + + + ); +}; +``` + +Or you can use a lib like [rtl-detect](https://github.com/shadiabuhilal/rtl-detect) + +## With a useEffect call + +You may implement your RTL support with a `useEffect` as well. + +For instance, if you have a language switcher component on all your pages, you could also choose to write the language direction detection logic in it. + +Something like: + +```tsx +// LanguageSwitcher.tsx +'use client'; + +import { useChangeLocale, useCurrentLocale } from '../../locales/client' +import { FunctionComponent, useEffect } from 'react'; + +interface LanguageSwitcherProps {} + +const LanguageSwitcher: FunctionComponent = () => { + const currentLocale = useCurrentLocale(); + const changeLocale = useChangeLocale(); + + useEffect(() => { + if (__YOUR_CUSTOM_RTL_DETECT__(currentLocale)) document.documentElement.dir = 'rtl'; + else document.documentElement.dir = 'ltr'; + }, [currentLocale]); + + return ( +
+ + +
+ ); +}; +export default LanguageSwitcher; +``` + +Where `__YOUR_CUSTOM_RTL_DETECT__` could be a call to a lib like [rtl-detect](https://github.com/shadiabuhilal/rtl-detect), or the implementation mentioned just above, based on `Intl.Locale.prototype.getTextInfo`, including the polyfill currently required to ensure compatibility with Firefox-based browsers. + +### Caveat + +Note that this choice of implementation will cause an UI flickering when your user loads your web pages for the first time. +This is because the page will first be mounted with the default `dir` attribute value of your HTML node, then updates when the component including the `useEffect` is mounted. This will introduce CLS (Cumulative Layout Shift) issues. From a9c2d48aa0c4dea23acb09ac5e3cf0107a9b7dda Mon Sep 17 00:00:00 2001 From: Gustave <118654172+gustaveWPM@users.noreply.github.com> Date: Mon, 30 Oct 2023 09:38:30 +0100 Subject: [PATCH 2/6] fix: typos/proofread Co-authored-by: Tom Lienard --- docs/pages/docs/rtl-support.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/pages/docs/rtl-support.mdx b/docs/pages/docs/rtl-support.mdx index cba0ad3..3c46a85 100644 --- a/docs/pages/docs/rtl-support.mdx +++ b/docs/pages/docs/rtl-support.mdx @@ -1,8 +1,8 @@ import { Tabs, Tab } from 'nextra/components' -# RTL supoprt +# RTL support -In case you want the `dir` attribute of your HTML node to adjust based on the current locale, you'll need to add some logic. +If you want to support the `dir` attribute in your `` tag, you'll need to add some logic: ## From the root layout From 4b44e9e68eba3b18407f6eaab3d617e688c108bf Mon Sep 17 00:00:00 2001 From: Gustave <118654172+gustaveWPM@users.noreply.github.com> Date: Mon, 30 Oct 2023 09:38:59 +0100 Subject: [PATCH 3/6] fix: typos/proofread Co-authored-by: Tom Lienard --- docs/pages/docs/rtl-support.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/pages/docs/rtl-support.mdx b/docs/pages/docs/rtl-support.mdx index 3c46a85..b8dde8c 100644 --- a/docs/pages/docs/rtl-support.mdx +++ b/docs/pages/docs/rtl-support.mdx @@ -7,7 +7,7 @@ If you want to support the `dir` attribute in your `` tag, you'll need to ## From the root layout ```tsx -// layout.tsx (root layout) +// app/[locale]/layout.tsx export default function Layout({ children, params: { locale } }: { children: ReactElement, params: { locale: string } }) => { const dir = new Intl.Locale(locale).getTextInfo().direction @@ -17,8 +17,8 @@ export default function Layout({ children, params: { locale } }: { children: Rea {children} - ); -}; + ) +} ``` ### Caveat From 1c4cab70aba7cc54c15e6925f53cac155056a43f Mon Sep 17 00:00:00 2001 From: Gustave <118654172+gustaveWPM@users.noreply.github.com> Date: Mon, 30 Oct 2023 09:40:40 +0100 Subject: [PATCH 4/6] fix: proofread Co-authored-by: Tom Lienard --- docs/pages/docs/rtl-support.mdx | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/docs/pages/docs/rtl-support.mdx b/docs/pages/docs/rtl-support.mdx index b8dde8c..03c998b 100644 --- a/docs/pages/docs/rtl-support.mdx +++ b/docs/pages/docs/rtl-support.mdx @@ -84,30 +84,26 @@ Something like: ```tsx // LanguageSwitcher.tsx -'use client'; +'use client' import { useChangeLocale, useCurrentLocale } from '../../locales/client' -import { FunctionComponent, useEffect } from 'react'; +import { FunctionComponent, useEffect } from 'react' -interface LanguageSwitcherProps {} - -const LanguageSwitcher: FunctionComponent = () => { - const currentLocale = useCurrentLocale(); - const changeLocale = useChangeLocale(); +export default function LanguageSwitcher() { + const currentLocale = useCurrentLocale() + const changeLocale = useChangeLocale() useEffect(() => { - if (__YOUR_CUSTOM_RTL_DETECT__(currentLocale)) document.documentElement.dir = 'rtl'; - else document.documentElement.dir = 'ltr'; - }, [currentLocale]); + document.documentElement.dir = isLocaleRTL(currentLocale) ? 'rtl' : 'ltr' + }, [currentLocale]) return (
- ); -}; -export default LanguageSwitcher; + ) +} ``` Where `__YOUR_CUSTOM_RTL_DETECT__` could be a call to a lib like [rtl-detect](https://github.com/shadiabuhilal/rtl-detect), or the implementation mentioned just above, based on `Intl.Locale.prototype.getTextInfo`, including the polyfill currently required to ensure compatibility with Firefox-based browsers. From f1904e567aece27c057ace04b06a41d7dad3a0fd Mon Sep 17 00:00:00 2001 From: GustaveWPM Date: Mon, 30 Oct 2023 09:54:06 +0100 Subject: [PATCH 5/6] add: proofread + updated _meta.json --- docs/pages/docs/_meta.json | 1 + docs/pages/docs/rtl-support.mdx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/pages/docs/_meta.json b/docs/pages/docs/_meta.json index 0d09d16..9e823c4 100644 --- a/docs/pages/docs/_meta.json +++ b/docs/pages/docs/_meta.json @@ -1,6 +1,7 @@ { "index": "Get Started", "writing-locales": "Writing locales", + "rtl-support": "RTL support", "testing": "Testing", "examples": "Examples", "-- App Router": { diff --git a/docs/pages/docs/rtl-support.mdx b/docs/pages/docs/rtl-support.mdx index 03c998b..f09068f 100644 --- a/docs/pages/docs/rtl-support.mdx +++ b/docs/pages/docs/rtl-support.mdx @@ -106,7 +106,7 @@ export default function LanguageSwitcher() { } ``` -Where `__YOUR_CUSTOM_RTL_DETECT__` could be a call to a lib like [rtl-detect](https://github.com/shadiabuhilal/rtl-detect), or the implementation mentioned just above, based on `Intl.Locale.prototype.getTextInfo`, including the polyfill currently required to ensure compatibility with Firefox-based browsers. +Where `isLocaleRTL` could be a call to a lib like [rtl-detect](https://github.com/shadiabuhilal/rtl-detect), or the implementation mentioned just above, based on `Intl.Locale.prototype.getTextInfo`, including the polyfill currently required to ensure compatibility with Firefox-based browsers. ### Caveat From f9074983ef5dc9327298000bb091053b4c49538a Mon Sep 17 00:00:00 2001 From: GustaveWPM Date: Mon, 30 Oct 2023 10:00:13 +0100 Subject: [PATCH 6/6] fix: proofread --- docs/pages/docs/rtl-support.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/docs/rtl-support.mdx b/docs/pages/docs/rtl-support.mdx index f09068f..c335410 100644 --- a/docs/pages/docs/rtl-support.mdx +++ b/docs/pages/docs/rtl-support.mdx @@ -56,7 +56,7 @@ To do this, you can firstly add this polyfill: And then write: ```tsx -// layout.tsx (root layout) +// app/[locale]/layout.tsx import Locale from 'intl-locale-textinfo-polyfill'; export default function Layout({ children, params: { locale } }: { children: ReactElement, params: { locale: string } }) => {