Proposal: frint-intl
- Dominant language
- JavaScript
- Stars
- 756
- Forks
- 33
- PR merge metrics
- No merged PRs in 30d
Description
(Intended to be done outside of this repository)
Very much a work in progress, and needs to be refined further as more feedback keeps coming in.
## Todo
* [ ] Figure out culture
* [ ] CLI usage
---
## Background
To unify l10n/i18n usage in FrintJS Apps, a common API can be considered, instead of having different variations spread across multiple Child Apps.
## Generic requirements
* API to translate/localize labels (text blocks identified by keys) programmatically (just JS)
* React components for embedding labels
* Tool for finding unused/redundant labels in code base (that we can safely remove)
## Proposed packages
The requirements can be handled by these proposed packages below.
The data structure for labels is expected to be like this:
```js
import { createModel, createCollection, Types } from 'frint-data';
const Label = createModel({
schema: {
// unique ID
name: Types.string,
// ICU Message Syntax
value: Types.string,
},
});
const Labels = createCollection({
model: Label,
});
```
Read more about ICU Message Syntax here: http://userguide.icu-project.org/formatparse/messages
### `frint-intl`
Exports:
* `IntlService`
Expected interface (nothing finalized of course):
```js
class IntlService {
constructor(options) {
// options.data: Labels
}
format(key, ...formatWithData) {
return String;
}
}
```
### `frint-intl-react`
React components for embedding at JSX level:
```js
import React from 'react';
import { Format } from 'frint-intl-react';
function MyComponent(props) {
const formatData = {
brand: 'CTNL',
};
return (
);
}
```
Or, format a custom ICU syntax message at component-level:
```js
```
### `frint-intl-cli`
This will expose a `$ frint intl` subcommand in CLI, via which we can find out about unused labels in our code base:
```
$ frint intl find-unused-labels ./**/*.js --source allLabels.json
```
It will first load all the label names as available in `allLabels.json` file, and then execute a search in all JS files matching the pattern `./**/*.js`. If there are any labels usage found that do no exist in `allLabels.json`, it will print line with file name and line number in console.
## Usage
To set up your App:
```js
import { createApp } from 'frint';
import { IntlService } from 'frint-intl';
const App = createApp({
name: 'MyRootApp',
providers: [
{
name: 'intl',
useFactory() {
return new IntlService({
data: [
{
name: 'homepage.title',
value: 'Welcome to {{brand}}!',
},
],
});
},
},
],
});
```
In your component, now you can do:
```js
import { Format } from 'frint-intl-react';
function () {
return (
;
);
}
```
Contributor guide
Research direction
This proposal is explicitly intended to be completed outside the repository and is still a work in progress. Start by refining the proposed packages and resolving the listed TODOs for culture and CLI usage, then define the API and package boundaries. Done means the scope and interfaces are finalized well enough for separate implementation work.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, react
- Domain
- internationalization
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 15/100