-
-
Notifications
You must be signed in to change notification settings - Fork 7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add Trans component for interpolating JSX in translations #6534
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
1 Ignored Deployment
|
@ad1992 I took the code from |
Alright, lets keep as is in the codebase, we can figure out later if want to move all i18n related stuff to a lib. |
src/components/Trans.tsx
Outdated
const Trans = memo<{ i18nKey: string; [key: string]: any }>( | ||
({ i18nKey, children, ...props }) => { | ||
const { t, langCode } = useI18n(); | ||
|
||
const transChildren = React.useMemo(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The useMemo
will never memoize due to props
, and the component memo
won't work either unless we memoized each render function pass to it which I doubt we'll do / would yield much benefit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It depends on the type of props. Props values can also be just strings (see example 1) but I agree that in the Excalidraw codebase, Trans props will probably be more complex so memoization won't make much sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed memo
and useMemo
and added tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Props values can also be just strings (see example 1)
what would be the use case for using strings? EDIT: nvm, the <Trans/>
is meant to also be usable as t()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, <span><Trans i18nKey="my.key" /></span>
is the same as <span>{t("my.key")}</span>
.
@ad1992 I've removed the commit for |
Thanks @bancek! One note, what's the |
I would have to update the examples in the PR description. I just copied those from our internal tests to showcase what is possible. The tests in this PR render proper HTML. |
I've updated the examples. Now it should be more obvious what |
@ad1992 thanks for adding the comments ❤️ |
Hey so as we we were discussing in chat with @dwelle
So Trans API remains the same, the translation string uses tags instead of |
If we don't want to use The reason for switch the syntax:
|
I've implemented support for |
I think |
src/components/Trans.tsx
Outdated
}, | ||
]; | ||
|
||
format.split(REGEXP).forEach((match) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the split
here could be confusing as its introducing unncessary undefined
tags so I think its better if we improve the split here so tokens are correct
eg for "Hello {{audience}}" its splitting to
[ 'Hello ', '{{audience}}', undefined, undefined, '' ]
so we should remove those undefined
tokens
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if it's possible to write a regex with delimiters in JavaScript so that it won't produce undefined
results. For cleaner code we could use format.split(REGEXP).filter(Boolean)
which will filter our empty strings and undefined
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes I meant filtering only after tokens are generated
src/components/Trans.tsx
Outdated
); | ||
} | ||
|
||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this shouldn't be needed if we use else If
instead of multiple ifs and readability wise will be better as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a compromise between readability and performance. If you want to use else if
you need to generate all regex matches before.
const tagStartMatch = match.match(TAG_START_REGEXP);
const tagEndMatch = match.match(TAG_END_REGEXP);
const keyMatch = match.match(KEY_REGEXP);
if (tagStartMatch !== null) {
} else if (tagEndMatch != null) {
} else if (keyMatch !== null) {
} else {
}
src/components/Trans.tsx
Outdated
|
||
import { useI18n } from "../i18n"; | ||
|
||
const REGEXP = /({{\w+?}})|(<\w+?>)|(<\/\w+?>)/g; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets add a comment for this regex to be more clear
Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com>
@ad1992 I'll be offline for the rest of the day so you can fix things yourself or I can do it tomorrow. |
Merging 🚀 Thanks @bancek ❤️ |
"line1": "Looks like you are using Brave browser with the <bold>Aggressively Block Fingerprinting</bold> setting enabled.", | ||
"line2": "This could result in breaking the <bold>Text Elements</bold> in your drawings.", | ||
"line3": "We strongly recommend disabling this setting. You can follow <link>these steps</link> on how to do so.", | ||
"line4": " If disabling this setting doesn't fix the display of text elements, please open an <issueLink>issue</issueLink> on our GitHub, or write us on <discordLink>Discord</discordLink>", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a leading space in line4
and discord
is not needed anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the catch. Fixed in #6561
This is so much better now. Thanks for your help @ad1992 |
…lidraw#6534) * feat: add Trans component * Add comments * tweak * Move brave to trans component * fix test and tweaks * remove any * fix * fix * comment * replace render function type * Use tags for Trans * Fix a typo Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com> * Cleanup, add comments, add support for kebab case * tweaks --------- Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com> Co-authored-by: dwelle <luzar.david@gmail.com>
Fixes #6351
This is a proof of concept PR that shows a possible solution to #6351 (this already works, you can quickly test it by applying the diff at the bottom and removing
if (isBrave() && !isMeasureTextSupported()) {
inApp.tsx
).Trans
component make it possible to use JSX for translations.Examples:
Output:
Trans
component can also be used instead oft()
. E.g.<span><Trans i18nKey="my.key" /></span>
is the same as<span>{t("my.key")}</span>
and<span><Trans i18nKey="my.key" name={currentName} /></span>
is the same as<span>{t("my.key", { name: currentName })}</span>