svelte-date-utils 0.2.0 → 0.3.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.
@@ -0,0 +1,13 @@
1
+ export interface UserLocaleOptions {
2
+ /** Add `fallbackLocale` at the end of the list. Defaults to true. */
3
+ useFallbackLocale?: boolean;
4
+ /** Defaults to `en-US`. */
5
+ fallbackLocale?: string;
6
+ }
7
+ /** The locales of the browser, most preferred first, without duplicates. */
8
+ export declare function getUserLocales({ useFallbackLocale, fallbackLocale, }?: UserLocaleOptions): string[];
9
+ /** The most preferred locale of the browser. With `useFallbackLocale: false` there may be none. */
10
+ export declare function getUserLocale(options?: UserLocaleOptions & {
11
+ useFallbackLocale?: true;
12
+ }): string;
13
+ export declare function getUserLocale(options: UserLocaleOptions): string | undefined;
@@ -0,0 +1,39 @@
1
+ // A dependency-free replacement for `get-user-locale` (and its `memoize` dependency).
2
+ const splitCommas = (locale) => (locale.includes(',') ? locale.split(',') : [locale]);
3
+ /** Turns `en-us` into `en-US`, `en-US.UTF-8` and `en-US@posix` into `en-US`, and `C` into `en-US`. */
4
+ function normalizeLocale(locale) {
5
+ if (!locale)
6
+ return locale;
7
+ if (locale === 'C' || locale === 'posix' || locale === 'POSIX')
8
+ return 'en-US';
9
+ // "en-US.UTF-8": keep the part before the dot
10
+ if (locale.includes('.'))
11
+ return normalizeLocale(locale.split('.')[0] ?? '');
12
+ // "en-US@posix": keep the part before the at sign
13
+ if (locale.includes('@'))
14
+ return normalizeLocale(locale.split('@')[0] ?? '');
15
+ // already "en-US", or has no region
16
+ if (!locale.includes('-') || locale.toLowerCase() !== locale)
17
+ return locale;
18
+ const [language, region = ''] = locale.split('-');
19
+ return `${language}-${region.toUpperCase()}`;
20
+ }
21
+ /** The locales of the browser, most preferred first, without duplicates. */
22
+ export function getUserLocales({ useFallbackLocale = true, fallbackLocale = 'en-US', } = {}) {
23
+ const list = [];
24
+ if (typeof navigator !== 'undefined') {
25
+ for (const language of navigator.languages ?? [])
26
+ list.push(...splitCommas(language));
27
+ if (navigator.language)
28
+ list.push(...splitCommas(navigator.language));
29
+ }
30
+ if (useFallbackLocale)
31
+ list.push(fallbackLocale);
32
+ return list
33
+ .filter((locale) => typeof locale === 'string')
34
+ .map(normalizeLocale)
35
+ .filter((locale, index, all) => all.indexOf(locale) === index);
36
+ }
37
+ export function getUserLocale(options) {
38
+ return getUserLocales(options)[0];
39
+ }
package/dist/index.d.ts CHANGED
@@ -3,6 +3,8 @@ export type { AdapterDateOptions } from './AdapterDate.js';
3
3
  export { createDateUtils } from './createDateUtils.js';
4
4
  export type { DateUtils, TimeLike, YearLike } from './createDateUtils.js';
5
5
  export type { DateAdapter } from './types.js';
6
+ export { getUserLocale, getUserLocales } from './getUserLocale.js';
7
+ export type { UserLocaleOptions } from './getUserLocale.js';
6
8
  /**
7
9
  * The helpers on the native `Date`, with the names and behavior of `@wojtekmaj/date-utils`.
8
10
  * For date-fns or Luxon, call `createDateUtils` with `AdapterDateFns` or `AdapterLuxon`
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ import { AdapterDate } from './AdapterDate.js';
2
2
  import { createDateUtils } from './createDateUtils.js';
3
3
  export { AdapterDate } from './AdapterDate.js';
4
4
  export { createDateUtils } from './createDateUtils.js';
5
+ export { getUserLocale, getUserLocales } from './getUserLocale.js';
5
6
  /**
6
7
  * The helpers on the native `Date`, with the names and behavior of `@wojtekmaj/date-utils`.
7
8
  * For date-fns or Luxon, call `createDateUtils` with `AdapterDateFns` or `AdapterLuxon`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-date-utils",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Date helpers for calendars and date inputs (start, end, previous, next and range of a century, decade, year, month and day) that work on native Date, date-fns or Luxon through adapters.",
5
5
  "keywords": [
6
6
  "date",
@@ -0,0 +1,50 @@
1
+ // A dependency-free replacement for `get-user-locale` (and its `memoize` dependency).
2
+
3
+ export interface UserLocaleOptions {
4
+ /** Add `fallbackLocale` at the end of the list. Defaults to true. */
5
+ useFallbackLocale?: boolean;
6
+ /** Defaults to `en-US`. */
7
+ fallbackLocale?: string;
8
+ }
9
+
10
+ const splitCommas = (locale: string) => (locale.includes(',') ? locale.split(',') : [locale]);
11
+
12
+ /** Turns `en-us` into `en-US`, `en-US.UTF-8` and `en-US@posix` into `en-US`, and `C` into `en-US`. */
13
+ function normalizeLocale(locale: string): string {
14
+ if (!locale) return locale;
15
+ if (locale === 'C' || locale === 'posix' || locale === 'POSIX') return 'en-US';
16
+ // "en-US.UTF-8": keep the part before the dot
17
+ if (locale.includes('.')) return normalizeLocale(locale.split('.')[0] ?? '');
18
+ // "en-US@posix": keep the part before the at sign
19
+ if (locale.includes('@')) return normalizeLocale(locale.split('@')[0] ?? '');
20
+ // already "en-US", or has no region
21
+ if (!locale.includes('-') || locale.toLowerCase() !== locale) return locale;
22
+ const [language, region = ''] = locale.split('-');
23
+ return `${language}-${region.toUpperCase()}`;
24
+ }
25
+
26
+ /** The locales of the browser, most preferred first, without duplicates. */
27
+ export function getUserLocales({
28
+ useFallbackLocale = true,
29
+ fallbackLocale = 'en-US',
30
+ }: UserLocaleOptions = {}): string[] {
31
+ const list: unknown[] = [];
32
+
33
+ if (typeof navigator !== 'undefined') {
34
+ for (const language of navigator.languages ?? []) list.push(...splitCommas(language));
35
+ if (navigator.language) list.push(...splitCommas(navigator.language));
36
+ }
37
+ if (useFallbackLocale) list.push(fallbackLocale);
38
+
39
+ return list
40
+ .filter((locale): locale is string => typeof locale === 'string')
41
+ .map(normalizeLocale)
42
+ .filter((locale, index, all) => all.indexOf(locale) === index);
43
+ }
44
+
45
+ /** The most preferred locale of the browser. With `useFallbackLocale: false` there may be none. */
46
+ export function getUserLocale(options?: UserLocaleOptions & { useFallbackLocale?: true }): string;
47
+ export function getUserLocale(options: UserLocaleOptions): string | undefined;
48
+ export function getUserLocale(options?: UserLocaleOptions): string | undefined {
49
+ return getUserLocales(options)[0];
50
+ }
package/src/index.ts CHANGED
@@ -6,6 +6,8 @@ export type { AdapterDateOptions } from './AdapterDate.js';
6
6
  export { createDateUtils } from './createDateUtils.js';
7
7
  export type { DateUtils, TimeLike, YearLike } from './createDateUtils.js';
8
8
  export type { DateAdapter } from './types.js';
9
+ export { getUserLocale, getUserLocales } from './getUserLocale.js';
10
+ export type { UserLocaleOptions } from './getUserLocale.js';
9
11
 
10
12
  /**
11
13
  * The helpers on the native `Date`, with the names and behavior of `@wojtekmaj/date-utils`.