ibitcy / eo-locale Goto Github PK
View Code? Open in Web Editor NEW🌏Internationalize React apps 👔Elegant lightweight library based on Internationalization API
Home Page: https://eo-locale.netlify.com/
License: MIT License
🌏Internationalize React apps 👔Elegant lightweight library based on Internationalization API
Home Page: https://eo-locale.netlify.com/
License: MIT License
It's a good practice to memoize results of a function that returns value from nested object by dot notation. This speeds things up, especially for React.
Update: this bug report relates to Translator.translate
method from @eo-locale/core
but I can't find bug tracker for it
The @eo-locale/preact
API is different than @eo-locale/react
in:
Components are exported in EOLocale
namespace
import { EOLocale } from '@eo-locale/preact'
const TranslationsProvider = EOLocale.Provider
const Text = EOLocale.Text
TranslationsProvider doesn't use the setLanguage
function
The useTranslator
hook is not implemented
Reference: #30
Hi, just wondering if there is way to organize contents in my 'locales' file that is provided to the locales
prop? Like separate the messages based on the component they are used in coz otherwise, it would become a gigantic 'locales' file...
E.g. in EUR currency there's no universal way to format the amount. See https://en.wikipedia.org/wiki/Euro_sign#Use
It's possible to get Translator
(mentioned at useTranslator) fields only from types.
Hi! I like to use your library, but it does not work with React 18.
npx create-react-app my-app
cd my-app
npm i @eo-locale/react --save
ICU format specifies offset:N
which eo-locale currently doesn't handle parsing, neither ignoring or using.
Example from ICU user guide http://userguide.icu-project.org/formatparse/messages
{num_guests, plural, offset:1 "
"=0 {{host} does not give a party.}"
"=1 {{host} invites {guest} to her party.}"
"=2 {{host} invites {guest} and one other person to her party.}
eo-locale will just print the entire translation text in this case.
This makes eo-locale hard to use with pluralisation or tools like Phrase which seem to add offset:0 by default 😅
Hi!
First of all, thanks for your lib.
npm i @eo-locale/react --save
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/react
npm ERR! react@"17.0.2" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.8.0" from @eo-locale/[email protected]
npm ERR! node_modules/@eo-locale/react
npm ERR! @eo-locale/react@"*" from the root project
I suppose it should be something like "react": ">= 16.8.0"
Hi, thank you for this nice and small translation library.
In commit 3c1d0a0 renderToStaticMarkup
from react-dom/server
was introduced to the Text Component, unfortunately that leads to the inclusion for react-dom-server in the client build and bloating the filesize.
Does anyone know how to render the string in my <EOLocale.Text id="placeholder" />
in a <input />
's placeholder?
<input placeholder={<EOLocale.Text id="placeholder" />}
I'm getting [object object]
when I do that...
For using with Flow, type defs are needed. I can make PR with Flow defs.
https://codesandbox.io/s/agitated-boyd-hnc3d?file=/src/App.js
I need to display other
message when other cases are not matched.
It would be nice for library to work with React Native.
I had troubles installing it. It was asking for react-dom
which isn't a best fit for RN apps.
Finally using components inside RN app was throwing exceptions so I assume it's not RN friendly.
In .mjs files or .js files with a package.json with "type": "module" imports need to be fully specified.
This means you need to have an extension.
webpack/webpack#11467 (comment)
Solution is to use (not working with Next.js with esmExternals):
{
test: /\.m?js/,
resolve: {
fullySpecified: false
}
}
It's better to align this lib and not enforce its users to have to use Webpack config and avoid such errors:
error - unhandledRejection: Error [ERR_MODULE_NOT_FOUND]: Cannot find module '[...]/node_modules/react-dom/server' imported from [...]/node_modules/@eo-locale/react/lib/index.js
Did you mean to import react-dom/server.js?
at new NodeError (node:internal/errors:371:5)
at finalizeResolution (node:internal/modules/esm/resolve:416:11)
at moduleResolve (node:internal/modules/esm/resolve:932:10)
at defaultResolve (node:internal/modules/esm/resolve:1044:11)
at ESMLoader.resolve (node:internal/modules/esm/loader:422:30)
at ESMLoader.getModuleJob (node:internal/modules/esm/loader:222:40)
at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:76:40)
at link (node:internal/modules/esm/module_job:75:36) {
code: 'ERR_MODULE_NOT_FOUND'
}
We should modify https://github.com/ibitcy/eo-locale/blob/master/packages/react/src/index.tsx#L9 to have extension.
Tested on:
Hi! For all versions above 1.4.7, I'm getting the error below:
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /xxxxxxxx/node_modules/@eo-locale/core/lib/index.js
require() of ES modules is not supported.
require() of /xxxxxxxx/node_modules/@eo-locale/core/lib/index.js from /xxxxxxx/node_modules/@eo-locale/react/lib/index..
Instead rename /xxxxxxx/node_modules/@eo-locale/core/lib/index.js to end in .cjs, change the requiring code to use import(), or remove "type: module"
In 1.4.8 the new exports
and type
properties were introduced in package.json
for both @eo-locale/core
and @eo-locale/react
(possibly other packages as well - I didn't check).
I'm not familiar with these properties but apparently, for node > 13 they will cause an exception when misconfigured, whereas in node < 13 they will merely emit a warning.
Downgrading to @eo-locale/[email protected]
solved the issue. I also had to add a resolution for the same version for @eo-locale/core
since 1.4.11 will be auto-installed otherwise. The error above is emitted for both packages.
IDE auto-import behavior is incorrect.
In .tsx file If you start to type <EOLocale...
IntelliSense or JetBrains autocomplete offers you to auto-import such things:
EOLocaleDate, EOLocaleText, ...
That is correct (as a regular coder thinks), but for example, EOLocaleText won't work after all, at compile time it throws this error:
Module not found: Can't resolve 'eo-locale/dist/components/text' in '~/.../component'
And after small research, you see that correct way is to use it like this:
import { EOLocale } from 'eo-locale'; ... <EOLocale.Text />
Can we just use both ways? Or, to be more strict only one of the ways.
@pret-a-porter if you want give a chanse to use eo-locale without react you must remove react and react-dom form peerDependecies
https://codesandbox.io/s/rw090rkw7o
I think we can made two files, one for react comunity and one for vanila using. Otherwise we force vanila-users install react as dependency
Move https://github.com/eo-locale/preact in packages directory
Current code forbids having a translation be the id, and erroneously says that the locale is missing the translation.
this.onError(new Error(`[eo-locale] id missing "${id}"`));
}```
Even though using text as id is not a best practice, this error message is wrong.
Hi,
Is there any way to use a component inside a message? Something like how it works in react-intl
or lingui
.
<Text
id='some.id'
defaultMessage='Some message with <link>link text</link> in the middle.'
link={<CustomLink to='...' />}
// or link={(text) => <CustomLink to='...'>{text}</CustomLink>}
/>
Thanks!
Hi,
I'm making some tests and see that @eo-locale/core
doesn't parse the following:
{gender_of_host, select,
female {
{num_guests, plural, offset:1
=0 {{host} does not give a party.}
=1 {{host} invites {guest} to her party.}
=2 {{host} invites {guest} and one other person to her party.}
other {{host} invites {guest} and # other people to her party.}
}
}
male {
{num_guests, plural, offset:1
=0 {{host} does not give a party.}
=1 {{host} invites {guest} to his party.}
=2 {{host} invites {guest} and one other person to his party.}
other {{host} invites {guest} and # other people to his party.}
}
}
other {
{num_guests, plural, offset:1
=0 {{host} does not give a party.}
=1 {{host} invites {guest} to their party.}
=2 {{host} invites {guest} and one other person to their party.}
other {{host} invites {guest} and # other people to their party.}
}
}
}
I get a Unexpected character "}" on position 335.
To be fair, I don't know how common it is to have a string like this, just wanted to report it as it is a valid ICU Messageformat string.
In my experiment, the library is not SSR compatible.
Is there any vision for it ?
Thanks you for great library !
For the Company im working we use eo-locale in several React-UIs and are pleased – Thanks for the great Work.
In several situations I miss the option to disable the '[eo-locale] id missing ...' Error.
F.E. the API delivers an status-key and an fallback message. Each Region has its own (huge) set of status. Some of the status-keys should be translated, some not. In this case, using the fallback message is wanted. But it throws an Error that pollutes our monitoring...
I miss an option, to disable the Error or know if a id exists.
If there should be something implemented, I could create a pull request. I would like to know witch is the desired Version. I have several implementation approaches:
Would love to here if an implementation is wished and if I can help.
extend getMessageById by a custom paramter. The Smallest Option.
public getMessageById = (
id: string,
defaultMessage?: string,
// Optional Parameter
ignoreMissing? boolean,
): Message | object | null => {
if (!this.memo[id]) {
let message: object | string | undefined = id
.split('.')
.reduce(
(acc, current) => (acc ? (acc as any)[current] : undefined),
this.messages,
);
if (typeof message !== 'string') {
// Wrap Error
if (!ignoreMissing) {
this.onError(new Error(`[eo-locale] id missing "${id}"`));
}
message = defaultMessage || id;
}
this.memo[id] = message;
}
return this.memo[id];
};
a dedicated Method would return a boolean value. Maybe the more intuitive version. Bitewise perhaps the biggest option.
public hasMessage = (
id: string,
): boolean => {
if (!this.issetMemo[id]) {
let message: object | string | undefined = id
.split('.')
.reduce(
(acc, current) => (acc ? (acc as any)[current] : undefined),
this.messages,
);
this.issetMemo[id] = typeof message === 'string';
}
return this.issetMemo[id];
};
with a custom Missing Logger that receives some more information, a custom filter can be implemented or even more advanced messages could be implemented.
export class Translator {
// ...
// Add separate logger for Missing - can be overwritten with custom logger
public onMissing: MissingLogger = (id, {options, languages}) => {
// downward compatible
this.onError(new Error(`[eo-locale] id missing "${id}"`))
}
// ...
public translate = (
id: string,
options: FormatMessageOptions = {},
): string => {
// Add options
const message = this.getMessageById(id, options.defaultMessage, options);
// ...
return String(message);
};
public getMessageById = (
id: string,
defaultMessage?: string,
// Add option (only for Logging) - could be merged with / replace defaultMessage with working downward compatible
_options: FormatMessageOptions = {},
): Message | object | null => {
// ...
if (typeof message !== 'string') {
// Use onMissing
this.onMissing(
id,
{
options: _options,
language: this.language,
}
);
// ...
}
// ...
};
}
export type ErrorLogger = (error: Error) => void;
export type MissingLogger = (id: string, {options: FormatMessageOptions, language: string, }
In the Project setting a custom onMissing with a custom option could filter the Error or do custom logging:
translator.onMissing = (id, {options, language}) => {
if (!options.ignoreMissing) {
console.warn(`[UI-Name] - missing translation for '${id}' in ${language}`)
}
}
const text = translator.translate('unknown', {ignoreMissing: true, defaultMessage: 'fallback {param}', param: 'PARAM'})
// text: 'fallback PARAM'
Currently, the translator receives an array of locales. Its constructor selects the locale object that matches the language
parameter, and the remaining locale objects are essentially thrown away, nothing utilizes them in the translator instance.
I think some changes should be made:
How I could extract dictionary with all messages for translation?
I mean something like formatjs extract
Hey, a nice package you have there 👍
When using useTranslator()
in @eo-locale/preact I'm unfortunately getting a
Uncaught (in promise) TypeError: Cannot read property 'getMessageById' of undefined
.
Message is correctly translated
parcel
1.12.4preact
10.5.7@eo-locale/preact
1.4.10@pret-a-porter Max why you mark values as required arg in translator.formattMessage function? I think we can use this function without values)
this sting is annoying
translator.formatMessage('__APP__::VERIFICATION_DIALOG::PHONE_CODE', {})
https://github.com/ibitcy/eo-locale/blob/master/src/utils/translator.ts#L42
What do you think? I can fix it, if you are agree with proposal
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.