@shoelace-style/localize 2.1.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.2.0
4
+
5
+ - Added `dir()` method to return the target element's directionality
6
+ - Added `lang()` method to return the target element's language
7
+
8
+ ## 2.1.3
9
+
10
+ - Renamed `updateLocalizedTerms()` to `update()` (forgive me SemVer, but nobody was using this I promise)
11
+
12
+ ## 2.1.2
13
+
14
+ - Removed all dependencies
15
+
3
16
  ## 2.1.1
4
17
 
5
18
  - Change import to ensure only types get used
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Shoelace: Localize
2
2
 
3
- This micro library does not aim to replicate a full-blown localization tool. For that, you should use something like [i18next](https://www.i18next.com/). What this library _does_ do is provide a lightweight, framework-agnostic mechanism for sharing and applying translations across one or more custom elements in a component library.
3
+ This zero-dependency micro library does not aim to replicate a full-blown localization tool. For that, you should use something like [i18next](https://www.i18next.com/). What this library _does_ do is provide a lightweight, framework-agnostic mechanism for sharing and applying translations across one or more custom elements in a component library.
4
4
 
5
5
  Included are methods for translating terms, dates, currencies, and numbers and a [Reactive Controller](https://lit.dev/docs/composition/controllers/) that can be used as a mixin in Lit and other supportive component authoring libraries.
6
6
 
@@ -185,6 +185,9 @@ export class MyElement extends LitElement {
185
185
 
186
186
  <!-- Number/currency -->
187
187
  ${this.localize.number(1000, { style: 'currency', currency: 'USD'})}
188
+
189
+ <!-- Determining directionality, e.g. 'ltr' or 'rtl' -->
190
+ ${this.localize.dir()}
188
191
  `;
189
192
  }
190
193
  }
@@ -193,7 +196,8 @@ export class MyElement extends LitElement {
193
196
  ## Advantages
194
197
 
195
198
  - Extremely lightweight
196
- - ~2.5 KB compared to ~33 KB for i18next (both without translations/minifications)
199
+ - Zero dependencies
200
+ - Version 2.1 measures 726 bytes (yes, _bytes_) after minify + gzip
197
201
  - Uses existing platform features
198
202
  - Supports simple terms, plurals, and complex translations
199
203
  - Fun fact: some languages have [six plural forms](https://lingohub.com/blog/2019/02/pluralization) and this will support that
package/dist/index.d.ts CHANGED
@@ -11,12 +11,14 @@ export declare function term<K extends keyof Translation>(lang: string, key: K,
11
11
  export declare function date(lang: string, dateToFormat: Date | string, options?: Intl.DateTimeFormatOptions): string;
12
12
  export declare function number(lang: string, numberToFormat: number | string, options?: Intl.NumberFormatOptions): string;
13
13
  export declare function relativeTime(lang: string, value: number, unit: Intl.RelativeTimeFormatUnit, options?: Intl.RelativeTimeFormatOptions): string;
14
- export declare function updateLocalizedTerms(): void;
14
+ export declare function update(): void;
15
15
  export declare class LocalizeController implements ReactiveController {
16
16
  host: ReactiveControllerHost & HTMLElement;
17
17
  constructor(host: ReactiveControllerHost & HTMLElement);
18
18
  hostConnected(): void;
19
19
  hostDisconnected(): void;
20
+ dir(): string;
21
+ lang(): string;
20
22
  term<K extends keyof Translation>(key: K, ...args: FunctionParams<Translation[K]>): any;
21
23
  date(dateToFormat: Date | string, options?: Intl.DateTimeFormatOptions): string;
22
24
  number(numberToFormat: number | string, options?: Intl.NumberFormatOptions): string;
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  const connectedElements = new Set();
2
- const documentElementObserver = new MutationObserver(updateLocalizedTerms);
2
+ const documentElementObserver = new MutationObserver(update);
3
3
  const translations = new Map();
4
+ let documentDirection = document.documentElement.dir || 'ltr';
4
5
  let documentLanguage = document.documentElement.lang || navigator.language;
5
6
  let fallback;
6
7
  documentElementObserver.observe(document.documentElement, {
@@ -15,7 +16,7 @@ export function registerTranslation(...translation) {
15
16
  fallback = t;
16
17
  }
17
18
  });
18
- updateLocalizedTerms();
19
+ update();
19
20
  }
20
21
  export function term(lang, key, ...args) {
21
22
  const code = lang.toLowerCase().slice(0, 2);
@@ -52,7 +53,8 @@ export function number(lang, numberToFormat, options) {
52
53
  export function relativeTime(lang, value, unit, options) {
53
54
  return new Intl.RelativeTimeFormat(lang, options).format(value, unit);
54
55
  }
55
- export function updateLocalizedTerms() {
56
+ export function update() {
57
+ documentDirection = document.documentElement.dir || 'ltr';
56
58
  documentLanguage = document.documentElement.lang || navigator.language;
57
59
  [...connectedElements.keys()].map((el) => {
58
60
  if (typeof el.requestUpdate === 'function') {
@@ -71,6 +73,12 @@ export class LocalizeController {
71
73
  hostDisconnected() {
72
74
  connectedElements.delete(this.host);
73
75
  }
76
+ dir() {
77
+ return `${this.host.dir || documentDirection}`.toLowerCase();
78
+ }
79
+ lang() {
80
+ return `${this.host.lang || documentLanguage}`.toLowerCase();
81
+ }
74
82
  term(key, ...args) {
75
83
  return term(this.host.lang || documentLanguage, key, ...args);
76
84
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shoelace-style/localize",
3
- "version": "2.1.1",
3
+ "version": "2.2.0",
4
4
  "description": "A micro library for localizing custom elements using Lit's Reactive Controller model.",
5
5
  "main": "/dist/index.js",
6
6
  "module": "/dist/index.js",
@@ -34,9 +34,7 @@
34
34
  "homepage": "https://github.com/shoelace-style/localize#readme",
35
35
  "devDependencies": {
36
36
  "del": "^6.0.0",
37
+ "lit": "^2.0.2",
37
38
  "typescript": "^4.4.3"
38
- },
39
- "dependencies": {
40
- "lit": "^2.0.2"
41
39
  }
42
40
  }
package/src/index.ts CHANGED
@@ -10,8 +10,9 @@ export interface Translation {
10
10
  }
11
11
 
12
12
  const connectedElements = new Set<HTMLElement>();
13
- const documentElementObserver = new MutationObserver(updateLocalizedTerms);
13
+ const documentElementObserver = new MutationObserver(update);
14
14
  const translations: Map<string, Translation> = new Map();
15
+ let documentDirection = document.documentElement.dir || 'ltr';
15
16
  let documentLanguage = document.documentElement.lang || navigator.language;
16
17
  let fallback: Translation;
17
18
 
@@ -35,7 +36,7 @@ export function registerTranslation(...translation: Translation[]) {
35
36
  }
36
37
  });
37
38
 
38
- updateLocalizedTerms();
39
+ update();
39
40
  }
40
41
 
41
42
  //
@@ -97,9 +98,10 @@ export function relativeTime(
97
98
  }
98
99
 
99
100
  //
100
- // Updates the locale for all localized elements that are currently connected
101
+ // Updates all localized elements that are currently connected
101
102
  //
102
- export function updateLocalizedTerms() {
103
+ export function update() {
104
+ documentDirection = document.documentElement.dir || 'ltr';
103
105
  documentLanguage = document.documentElement.lang || navigator.language;
104
106
 
105
107
  [...connectedElements.keys()].map((el: LitElement) => {
@@ -143,18 +145,38 @@ export class LocalizeController implements ReactiveController {
143
145
  connectedElements.delete(this.host);
144
146
  }
145
147
 
148
+ /**
149
+ * Gets the host element's directionality as determined by the `dir` attribute. The return value is transformed to
150
+ * lowercase.
151
+ */
152
+ dir() {
153
+ return `${this.host.dir || documentDirection}`.toLowerCase();
154
+ }
155
+
156
+ /**
157
+ * Gets the host element's language as determined by the `lang` attribute. The return value is transformed to
158
+ * lowercase.
159
+ */
160
+ lang() {
161
+ return `${this.host.lang || documentLanguage}`.toLowerCase();
162
+ }
163
+
146
164
  term<K extends keyof Translation>(key: K, ...args: FunctionParams<Translation[K]>) {
165
+ /** Outputs a localized term. */
147
166
  return term(this.host.lang || documentLanguage, key, ...args);
148
167
  }
149
168
 
169
+ /** Outputs a localized date in the specified format. */
150
170
  date(dateToFormat: Date | string, options?: Intl.DateTimeFormatOptions) {
151
171
  return date(this.host.lang || documentLanguage, dateToFormat, options);
152
172
  }
153
173
 
174
+ /** Outputs a localized number in the specified format. */
154
175
  number(numberToFormat: number | string, options?: Intl.NumberFormatOptions) {
155
176
  return number(this.host.lang || documentLanguage, numberToFormat, options);
156
177
  }
157
178
 
179
+ /** Outputs a localized time in relative format. */
158
180
  relativeTime(value: number, unit: Intl.RelativeTimeFormatUnit, options?: Intl.RelativeTimeFormatOptions) {
159
181
  return relativeTime(this.host.lang || documentLanguage, value, unit, options);
160
182
  }