Git Product home page Git Product logo

ibitcy / eo-locale Goto Github PK

View Code? Open in Web Editor NEW
347.0 9.0 12.0 8.29 MB

🌏Internationalize React apps 👔Elegant lightweight library based on Internationalization API

Home Page: https://eo-locale.netlify.com/

License: MIT License

TypeScript 46.74% JavaScript 16.36% CSS 2.07% Shell 0.10% MDX 34.73%
icu tiny i18n react-intl intl globalization react-components internationalization messageformat localization

eo-locale's People

Contributors

cubucul avatar dependabot[bot] avatar dplatonova avatar icegotcha avatar ilyalesik avatar konstantin24121 avatar piterden avatar pret-a-porter avatar ruslanchek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

eo-locale's Issues

memoize result of delve function

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

Differences in Preact API

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

Any way to organize my 'locales' file?

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...

React 18

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

Does not handle ICU offset

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.
image

This makes eo-locale hard to use with pluralisation or tools like Phrase which seem to add offset:0 by default 😅

React v17

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"

React Native support

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.

Need to use 'fullySpecified' Webpack 5 config to use this library

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:

  • Next.js - problem occurs on Next < 12 with esmExternals enabled. Also on Next@12 (esmExternals are turned on by default on that version)
  • regular React app with SSR

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module

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 behaviour incorrect

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.

Wrongly raise `id missing` error when translation === id

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.

[question]: Is there any way to use a component inside a message?

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!

Does not seem to parse complex nested strings

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.

SSR ?

In my experiment, the library is not SSR compatible.
Is there any vision for it ?

Thanks you for great library !

No Error on missing Translation

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.

via parameter

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];
  };

via method

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];
  };

more customizable onError / dedicated onMissing

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'

Better handling of locales in Translator

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.

  • To switch to a new language, a new translator instance is created every time. This is inefficient.
  • There is no point in providing an array of locale data to the constructor if only one locale object is ever used.

I think some changes should be made:

  • Constructor should be allowed to receive a single object instead of an array with one object (this is not critical, but makes sense).
  • Add a new instance method that allows adding locale data to the instance. This would allow lingui-like dynamic loading of messages.
  • Add a new instance method that allows switching between language and locale data without creating a new instance.

Cannot read property 'getMessageById' of undefined

Hey, a nice package you have there 👍

Current behavior

When using useTranslator() in @eo-locale/preact I'm unfortunately getting a
Uncaught (in promise) TypeError: Cannot read property 'getMessageById' of undefined.

To reproduce

Codesandbox

Expected

Message is correctly translated

Environment

  • parcel 1.12.4
  • preact 10.5.7
  • @eo-locale/preact 1.4.10

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.