Skip to content
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

v3 #40

Merged
merged 13 commits into from
Feb 3, 2020
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
node_modules
*.log
dist/
coverage/
/types/
/coverage/
/dist/
/types/
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
# [3.0.0](https://github.com/kaisermann/svelte-i18n/compare/v2.3.1...v3.0.0) (2020-02-03)


### Features

* 🎸 add runtime typings ([90bf171](https://github.com/kaisermann/svelte-i18n/commit/90bf171139ad6b55faa0e36b3d28d317de538985)), closes [#43](https://github.com/kaisermann/svelte-i18n/issues/43)
* 🎸 make date,time and number formatters tree-shakeable ([fb82a40](https://github.com/kaisermann/svelte-i18n/commit/fb82a400f349d8d997c1d14f8d16b1d5c8da7f3e))
* 🎸 make getClientLocale tree-shakeable ([4881acb](https://github.com/kaisermann/svelte-i18n/commit/4881acb7b3a9aacd64b0f00f3b85fd736aa53316))


### BREAKING CHANGES

* It's now needed to explicitly import the `getClientLocale` method to use
its heuristics when setting the initial locale. This makes the method
and its helpers to be tree-shakeable.

```js
import { init, getClientLocale } from 'svelte-i18n'

init({
initialLocale: getClientLocale({ ... })
})
```
* Changes completely the API. Now, to format a number, date or time, the
developer must explicitly import the formatter store:

`import { time, date, number } from 'svelte-i18n'`



## [2.3.1](https://github.com/kaisermann/svelte-i18n/compare/v2.3.0...v2.3.1) (2020-01-29)


Expand Down
45 changes: 14 additions & 31 deletions docs/Formatting.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,62 +60,45 @@ If the message id literal value is not in the root of the dicitonary, `.` (dots)
<div>{$_('deep.prop')}</div> <!-- Deep property -->
```

### Formatting utilities
### `$time(number: Date, options: MessageObject)`

The formatter method also provides some casing methods:

- `_.upper` - transforms a localized message into uppercase;
- `_.lower` - transforms a localized message into lowercase;
- `_.capital` - capitalize a localized message;
- `_.title` - transforms the message into title case;

```html
<div>{$_.upper('greeting.ask')}</div>
<!-- PLEASE TYPE YOUR NAME -->

<div>{$_.lower('greeting.ask')}</div>
<!-- please type your name -->

<div>{$_.capital('greeting.ask')}</div>
<!-- Please type your name -->

<div>{$_.title('greeting.ask')}</div>
<!-- Please Type Your Name -->
```

#### `_.time(time: Date, options: MessageObject): string`
`import { time } from 'svelte-i18n'`

Formats a date object into a time string with the specified format. Please refer to the [#formats](#formats) section to see available formats.

```html
<div>{$_.time(new Date(2019, 3, 24, 23, 45))}</div>
<div>{$time(new Date(2019, 3, 24, 23, 45))}</div>
<!-- 11:45 PM -->

<div>{$_.time(new Date(2019, 3, 24, 23, 45), { format: 'medium' } )}</div>
<div>{$time(new Date(2019, 3, 24, 23, 45), { format: 'medium' } )}</div>
<!-- 11:45:00 PM -->
```

#### `_.date(date: Date, options: MessageObject): string`
#### `$date(date: Date, options: MessageObject)`

`import { date } from 'svelte-i18n'`

Formats a date object into a string with the specified format. Please refer to the [#formats](#formats) section to see available formats.

```html
<div>{$_.date(new Date(2019, 3, 24, 23, 45))}</div>
<div>{$date(new Date(2019, 3, 24, 23, 45))}</div>
<!-- 4/24/19 -->

<div>{$_.date(new Date(2019, 3, 24, 23, 45), { format: 'medium' } )}</div>
<div>{$date(new Date(2019, 3, 24, 23, 45), { format: 'medium' } )}</div>
<!-- Apr 24, 2019 -->
```

#### `_.number(number: number, options: MessageObject): string`
#### `$number(number: number, options: MessageObject)`

`import { number } from 'svelte-i18n'`

Formats a number with the specified locale and format. Please refer to the [#formats](#formats) section to see available formats.

```html
<div>{$_.number(100000000)}</div>
<div>{$number(100000000)}</div>
<!-- 100,000,000 -->

<div>{$_.number(100000000, { locale: 'pt' })}</div>
<div>{$number(100000000, { locale: 'pt' })}</div>
<!-- 100.000.000 -->
```

Expand Down
14 changes: 7 additions & 7 deletions docs/Getting Started.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ There are two different ways of adding a new dicitonary of messages to a certain

##### 2.1 Synchronous

Just `import`/`require` your locale `.json` files and pass them to the [`addMessages(locale, dict)`](/docs/Methods.md#addmessages) method.
Just `import`/`require` your locale `.json` files and pass them to the [`addMessages(locale, dict)`](/docs/Methods.md#addmessage) method.

```js
// src/i18n.js
Expand Down Expand Up @@ -60,11 +60,11 @@ register('pt', () => import('./pt.json'))

#### 3. Initializing

After populating your [`$dictionary`](/docs/Dictionary) with [`addMessages()`](/docs/Methods.md#addmessages) or registering loaders via [`register()`](/docs/Methods.md#register), you are ready to bootstrap the library. You can use [`init()`](/docs/Methods.md#init) to define the fallback locale, initial locale and other options of your app.
After populating your [`$dictionary`](/docs/Dictionary.md) with [`addMessages()`](/docs/Methods.md#addmessages) or registering loaders via [`register()`](/docs/Methods.md#register), you are ready to bootstrap the library. You can use [`init()`](/docs/Methods.md#init) to define the fallback locale, initial locale and other options of your app.

```js
// src/i18n.js
import { register, init } from 'svelte-i18n'
import { register, init, getClientLocale } from 'svelte-i18n'

register('en', () => import('./en.json'))
register('en-US', () => import('./en-US.json'))
Expand All @@ -73,9 +73,9 @@ register('pt', () => import('./pt.json'))

init({
fallbackLocale: 'en',
initialLocale: {
initialLocale: getClientLocale({
navigator: true, // i.e 'en-US'
},
}),
})
// starts loading 'en-US' and 'en'
```
Expand Down Expand Up @@ -104,7 +104,7 @@ Please note that the `fallbackLocale` is always loaded, independent of the curre

#### 4. Localizing your app

After having the initial locale set, you're ready to start localizing your app. Import the [`$format`](/docs/Formatting) method, or any of its aliases, to any component that needs to be translated. Then, just call [`$format`](/docs/Formatting) passing the message `id` on your layout and voila! 🎉
After having the initial locale set, you're ready to start localizing your app. Import the [`$format`](/docs/Formatting.md) method, or any of its aliases, to any component that needs to be translated. Then, just call [`$format`](/docs/Formatting.md) passing the message `id` on your layout and voila! 🎉

```svelte
<script>
Expand All @@ -121,4 +121,4 @@ After having the initial locale set, you're ready to start localizing your app.
</nav>
```

See [Formatting](/docs/Formatting) to read about the supported message syntax.
See [Formatting](/docs/Formatting.md) to read about the supported message syntax.
80 changes: 51 additions & 29 deletions docs/Methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,46 +10,24 @@ Method responsible for configuring some of the library behaviours such as the gl
interface InitOptions {
// the global fallback locale
fallbackLocale: string
// set of heuristic configs to define the client's locale
initialLocale?: InitialLocaleOptions
// the app initial locale
initialLocale?: string
// custom time/date/number formats
formats?: Formats
// loading delay interval
loadingDelay?: number
}

interface InitialLocaleOptions {
// the fallback locale to use if no message is found in the current one
fallback?: string
// when 'true', check the 'window.navigator.language' to set the current locale
navigator?: boolean
// key to look for a locale on 'window.location.search'
// 'example.com?locale=en-US'
search?: string
// key to look for a locale on 'window.location.hash'
// 'example.com#locale=en-US'
hash?: string
// pattern to look in the window.location.pathname.
// It returns the first capturing group.
pathname?: RegExp
// pattern to look in the window.location.hostname.
// It returns the first capturing group.
hostname?: RegExp
}
```

**Example**:

```js
import { init } from 'svelte-i18n'
import { init, getClientLocale } from 'svelte-i18n'

init({
// fallback to en if current locale is not in the dictionary
fallbackLocale: 'en',
initialLocale: {
// based on the user's browser
navigator: true,
},
initialLocale: 'pt-br',
})
```

Expand Down Expand Up @@ -90,6 +68,50 @@ init({
<!-- 123.456,79 € -->
```

#### getClientLocale

> `import { getClientLocale } from 'svelte-i18n'`

`getClientLocale(options: GetClientLocaleOptions): void`

Optional utility method to help getting the initial locale of a user. Use it together with the [`init()`](#init) method.

```ts
interface GetClientLocaleOptions {
// the fallback locale to use if no message is found in the current one
fallback?: string
// when 'true', check the 'window.navigator.language' to set the current locale
navigator?: boolean
// key to look for a locale on 'window.location.search'
// 'example.com?locale=en-US'
search?: string
// key to look for a locale on 'window.location.hash'
// 'example.com#locale=en-US'
hash?: string
// pattern to look in the window.location.pathname.
// It returns the first capturing group.
pathname?: RegExp
// pattern to look in the window.location.hostname.
// It returns the first capturing group.
hostname?: RegExp
}
```

**Example**:

```js
import { init, getClientLocale } from 'svelte-i18n'

init({
// fallback to en if current locale is not in the dictionary
fallbackLocale: 'en',
initialLocale: getClientLocale({
// based on the user's browser
navigator: true,
}),
})
```

#### addMessages

`import { addMessages } from 'svelte-i18n`
Expand Down Expand Up @@ -137,15 +159,15 @@ register('en', () => import('./_locales/en.json'))
register('pt', () => import('./_locales/pt.json'))
```

See [how to asynchronously load dictionaries](/svelte-i18n/wiki#22-asynchronous).
See [how to asynchronously load dictionaries](/svelte-i18n/blob/master/docs#22-asynchronous).

#### waitLocale

> `import { waitLocale } from 'svelte-i18n'`

`waitLocale(locale: string = $locale): Promise<void>`

Executes the queue of `locale`. If the queue isn't resolved yet, the same promise is returned. Great to use in the `preload` method of Sapper for awaiting [`loaders`](/svelte-i18n/wiki#22-asynchronous).
Executes the queue of `locale`. If the queue isn't resolved yet, the same promise is returned. Great to use in the `preload` method of Sapper for awaiting [`loaders`](/svelte-i18n/blob/master/docs#22-asynchronous).

**Example**:

Expand Down Expand Up @@ -191,7 +213,7 @@ getNumberFormatter(
): Intl.NumberFormat
```

Each of these methods return their respective [`Intl.xxxxFormatter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects.md#Internationalization) variant. Click [here](/docs/formatting.md#accessing-formatters-directly) for an example of usage.
Each of these methods return their respective [`Intl.xxxxFormatter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects#Internationalization) variant. Click [here](/docs/formatting.md#accessing-formatters-directly) for an example of usage.

#### getMessageFormatter

Expand Down
92 changes: 92 additions & 0 deletions docs/Migration.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,95 @@
<!-- @import "[TOC]" {cmd="toc" depthFrom=1 depthTo=6 orderedList=false} -->

<!-- code_chunk_output -->

- [From `v2` to `v3`](#from-v2-to-v3)
- [Formatting numbers, dates and times](#formatting-numbers-dates-and-times)
- [Casing utilities](#casing-utilities)
- [Getting the client locale](#getting-the-client-locale)
- [From `v1` to `v2`](#from-v1-to-v2)
- [Adding dictionaries](#adding-dictionaries)
- [Setting the initial and fallback locales](#setting-the-initial-and-fallback-locales)
- [Interpolating values](#interpolating-values)
- [Adding custom formats](#adding-custom-formats)

<!-- /code_chunk_output -->

#### From `v2` to `v3`

##### Formatting numbers, dates and times

In `v2`, to format numbers, dates and times you would access the `date`, `time` or `number` method of the main formatter method:

```js
$_.time(dateValue)
$_.date(dateValue)
$_.number(100000000)
```

In `v3`, these utilities are exported as standalone formatter stores, making them tree-shakeable:

```js
import { time, date, number } from 'svelte-i18n'

$time(someDateValue)
$date(someDateValue)
$number(100000000)
```

##### Casing utilities

The casing utilities `$_.title`, `$_.capital`, `$_.lower`, `$_.upper` were removed from the library.

In `v2`:

```js
$_.lower('message.id')
$_.upper('message.id')
$_.title('message.id')
$_.capital('message.id')
```

In `v3`:

```js
function capital(str: string) {
return str.replace(/(^|\s)\S/, l => l.toLocaleUpperCase())
}

function title(str: string) {
return str.replace(/(^|\s)\S/g, l => l.toLocaleUpperCase())
}

$_('message.id').toLocaleLowerCase()
$_('message.id').toLocaleUpperCase()
title($_('message.id'))
capital($_('message.id'))
```

##### Getting the client locale

In `v2`, the [`init`](/docs/Methods.md#init) method could automatically set the initial locale based on some heuristcs from the client:

```js
import { init, getClientLocale } from 'svelte-i18n'

init({
initialLocale: {
navigator: true,
},
})
```

However, many people didn't need that kind of extra weight in their apps. So in `v3`, to have the same behavior as `v2`, you have to import the [`getClientLocale`](/docs/Methods.md#getclientlocale) method.

```js
import { init, getClientLocale } from 'svelte-i18n'

init({
initialLocale: getClientLocale({ ... })
})
```

#### From `v1` to `v2`

##### Adding dictionaries
Expand Down