@quilted/preact-localize 0.4.0 → 0.4.1

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.
Files changed (46) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/build/esm/hooks/formatting.mjs +4 -2
  3. package/build/esm/hooks/locale.mjs +4 -2
  4. package/build/esm/index.mjs +1 -4
  5. package/build/esm/routing/LocalizedLink.mjs +4 -4
  6. package/build/esm/routing/LocalizedNavigation.mjs +32 -41
  7. package/build/esm/routing/context.mjs +10 -4
  8. package/build/esnext/hooks/formatting.esnext +4 -2
  9. package/build/esnext/hooks/locale.esnext +4 -2
  10. package/build/esnext/index.esnext +1 -4
  11. package/build/esnext/routing/LocalizedLink.esnext +4 -4
  12. package/build/esnext/routing/LocalizedNavigation.esnext +27 -29
  13. package/build/esnext/routing/context.esnext +12 -4
  14. package/build/tsconfig.tsbuildinfo +1 -1
  15. package/build/typescript/context.d.ts +12 -3
  16. package/build/typescript/context.d.ts.map +1 -1
  17. package/build/typescript/hooks/formatting.d.ts +1 -1
  18. package/build/typescript/hooks/formatting.d.ts.map +1 -1
  19. package/build/typescript/hooks/locale.d.ts +1 -1
  20. package/build/typescript/hooks/locale.d.ts.map +1 -1
  21. package/build/typescript/index.d.ts +1 -3
  22. package/build/typescript/index.d.ts.map +1 -1
  23. package/build/typescript/routing/LocalizedLink.d.ts.map +1 -1
  24. package/build/typescript/routing/LocalizedNavigation.d.ts +8 -11
  25. package/build/typescript/routing/LocalizedNavigation.d.ts.map +1 -1
  26. package/build/typescript/routing/context.d.ts +1 -2
  27. package/build/typescript/routing/context.d.ts.map +1 -1
  28. package/build/typescript/routing.d.ts +0 -1
  29. package/build/typescript/routing.d.ts.map +1 -1
  30. package/package.json +7 -7
  31. package/source/context.ts +12 -6
  32. package/source/hooks/formatting.ts +4 -2
  33. package/source/hooks/locale.ts +4 -2
  34. package/source/index.ts +1 -6
  35. package/source/routing/LocalizedLink.tsx +4 -4
  36. package/source/routing/LocalizedNavigation.tsx +45 -59
  37. package/source/routing/context.ts +13 -4
  38. package/source/routing.ts +0 -1
  39. package/build/esm/Localization.mjs +0 -37
  40. package/build/esm/context.mjs +0 -6
  41. package/build/esm/routing/LocalizedRouter.mjs +0 -34
  42. package/build/esnext/Localization.esnext +0 -44
  43. package/build/esnext/context.esnext +0 -6
  44. package/build/esnext/routing/LocalizedRouter.esnext +0 -32
  45. package/source/Localization.tsx +0 -61
  46. package/source/routing/LocalizedRouter.ts +0 -46
@@ -1,63 +1,49 @@
1
- import type {RenderableProps} from 'preact';
2
- import {useMemo} from 'preact/hooks';
3
- import {useBrowserDetails} from '@quilted/preact-browser';
4
- import {Navigation, type RouteDefinition} from '@quilted/preact-router';
5
-
6
- import {Localization} from '../Localization.tsx';
7
-
8
- import {LocalizedRouter} from './LocalizedRouter.ts';
9
- import {RouteLocalizationContext} from './context.ts';
10
- import type {RouteLocalization} from './types.ts';
11
-
12
- export interface LocalizedNavigationProps<Context = unknown> {
13
- locale?: string;
14
- router?: LocalizedRouter;
15
- localization?: RouteLocalization;
16
- routes?: readonly RouteDefinition<any, any, Context>[];
17
- context?: Context;
18
- }
1
+ import {Navigation, type NavigationOptions} from '@quilted/preact-router';
19
2
 
20
- export function LocalizedNavigation<Context = unknown>({
21
- locale: explicitLocale,
22
- router,
23
- routes,
24
- context,
25
- localization,
26
- children,
27
- }: RenderableProps<LocalizedNavigationProps<Context>>) {
28
- const browser = useBrowserDetails({optional: true});
29
- const resolvedRouter = useMemo(
30
- () =>
31
- router ??
32
- new LocalizedRouter(browser?.request.url, {localization: localization!}),
33
- [router],
34
- );
35
- const resolvedLocalization = resolvedRouter.localization;
36
-
37
- const localeFromEnvironment = browser?.locale.value;
38
-
39
- let resolvedLocale: string;
40
-
41
- if (explicitLocale) {
42
- resolvedLocale = explicitLocale;
43
- } else if (
44
- localeFromEnvironment != null &&
45
- localeFromEnvironment
46
- .toLowerCase()
47
- .startsWith(resolvedLocalization.locale.toLowerCase())
48
- ) {
49
- resolvedLocale = localeFromEnvironment;
50
- } else {
51
- resolvedLocale = resolvedLocalization.locale;
3
+ import type {RouteLocalization, ResolvedRouteLocalization} from './types.ts';
4
+
5
+ export class LocalizedNavigation extends Navigation {
6
+ readonly routes: ResolvedRouteLocalization;
7
+
8
+ get locale() {
9
+ return this.routes.locale;
52
10
  }
53
11
 
54
- return (
55
- <Localization locale={resolvedLocale}>
56
- <RouteLocalizationContext.Provider value={resolvedLocalization}>
57
- <Navigation router={resolvedRouter} routes={routes} context={context}>
58
- {children}
59
- </Navigation>
60
- </RouteLocalizationContext.Provider>
61
- </Localization>
62
- );
12
+ constructor(
13
+ initial: ConstructorParameters<typeof Navigation>[0],
14
+ {
15
+ routes,
16
+ isExternal: explicitIsExternal,
17
+ }: {routes: RouteLocalization} & Pick<NavigationOptions, 'isExternal'>,
18
+ ) {
19
+ const {localeFromURL} = routes;
20
+
21
+ let matchedLocale: string | undefined;
22
+
23
+ super(initial, {
24
+ isExternal(url, currentURL) {
25
+ return (
26
+ matchedLocale !== localeFromURL(url) ||
27
+ (explicitIsExternal?.(url, currentURL) ?? false)
28
+ );
29
+ },
30
+ });
31
+
32
+ const currentURL = this.currentRequest.url;
33
+
34
+ matchedLocale = localeFromURL(currentURL);
35
+
36
+ const resolvedLocalization: ResolvedRouteLocalization = {
37
+ locale: matchedLocale ?? routes.defaultLocale,
38
+ ...routes,
39
+ };
40
+
41
+ this.routes = resolvedLocalization;
42
+
43
+ const {pathname: rootPath} = routes.redirectURL(new URL('/', currentURL), {
44
+ to: resolvedLocalization.locale,
45
+ });
46
+
47
+ if (rootPath.length > 1) Object.assign(this, {base: rootPath});
48
+ }
63
49
  }
@@ -1,8 +1,17 @@
1
- import {createOptionalContext} from '@quilted/preact-context';
1
+ import {useNavigation} from '@quilted/preact-router';
2
2
 
3
+ import {LocalizedNavigation} from './LocalizedNavigation.tsx';
3
4
  import type {ResolvedRouteLocalization} from './types.ts';
4
5
 
5
- export const RouteLocalizationContext =
6
- createOptionalContext<ResolvedRouteLocalization>();
6
+ export function useRouteLocalization(): ResolvedRouteLocalization {
7
+ const navigation = useNavigation();
7
8
 
8
- export const useRouteLocalization = RouteLocalizationContext.use;
9
+ if (!(navigation instanceof LocalizedNavigation)) {
10
+ throw new Error(
11
+ 'useRouteLocalization() requires a LocalizedNavigation instance to be provided in context. ' +
12
+ 'Make sure you are passing a LocalizedNavigation to QuiltFrameworkContext.',
13
+ );
14
+ }
15
+
16
+ return navigation.routes;
17
+ }
package/source/routing.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  export {LocalizedLink} from './routing/LocalizedLink.tsx';
2
2
  export {LocalizedNavigation} from './routing/LocalizedNavigation.tsx';
3
- export {LocalizedRouter} from './routing/LocalizedRouter.ts';
4
3
  export {useRouteLocalization} from './routing/context.ts';
5
4
  export {createRouteLocalization} from './routing/localization/by-locale.ts';
6
5
  export {createRoutePathLocalization} from './routing/localization/by-path.ts';
@@ -1,37 +0,0 @@
1
- import { useMemo } from 'preact/hooks';
2
- import { createLocalizedFormatting } from '@quilted/localize';
3
- import { useBrowserDetails, HTMLAttributes } from '@quilted/preact-browser';
4
- import { LocaleContext, LocalizedFormattingContext } from './context.mjs';
5
- import { jsx, jsxs } from 'preact/jsx-runtime';
6
-
7
- const RTL_LOCALES = new Set(['ar', 'arc', 'ckb', 'dv', 'fa', 'ha', 'he', 'khw', 'ks', 'ps', 'sd', 'ur', 'uz-AF', 'yi']);
8
- function Localization({
9
- locale: explicitLocale,
10
- direction: explicitDirection,
11
- children
12
- }) {
13
- const browserDetails = useBrowserDetails({
14
- optional: true
15
- });
16
- const locale = explicitLocale ?? browserDetails?.locale.value ?? getLocaleFromEnvironment();
17
- const formatting = useMemo(() => createLocalizedFormatting(locale), [locale]);
18
- const direction = explicitDirection ?? (RTL_LOCALES.has(locale) ? 'rtl' : 'ltr');
19
- return jsx(LocaleContext.Provider, {
20
- value: locale,
21
- children: jsxs(LocalizedFormattingContext.Provider, {
22
- value: formatting,
23
- children: [browserDetails && jsx(HTMLAttributes, {
24
- lang: locale,
25
- dir: direction
26
- }), children]
27
- })
28
- });
29
- }
30
- function getLocaleFromEnvironment() {
31
- if (typeof navigator === 'undefined') {
32
- throw new Error(`Could not determine the locale automatically`);
33
- }
34
- return navigator.language;
35
- }
36
-
37
- export { Localization };
@@ -1,6 +0,0 @@
1
- import { createOptionalContext } from '@quilted/preact-context';
2
-
3
- const LocalizedFormattingContext = createOptionalContext();
4
- const LocaleContext = createOptionalContext();
5
-
6
- export { LocaleContext, LocalizedFormattingContext };
@@ -1,34 +0,0 @@
1
- import { Router } from '@quilted/preact-router';
2
-
3
- class LocalizedRouter extends Router {
4
- constructor(initial, {
5
- localization,
6
- isExternal: explicitIsExternal
7
- }) {
8
- const {
9
- localeFromURL
10
- } = localization;
11
- super(initial, {
12
- isExternal(url, currentURL) {
13
- return matchedLocale !== localeFromURL(url) || (explicitIsExternal?.(url, currentURL) ?? false);
14
- }
15
- });
16
- const currentURL = this.currentRequest.url;
17
- const matchedLocale = localeFromURL(currentURL);
18
- const resolvedLocalization = {
19
- locale: matchedLocale ?? localization.defaultLocale,
20
- ...localization
21
- };
22
- this.localization = resolvedLocalization;
23
- const {
24
- pathname: rootPath
25
- } = localization.redirectURL(new URL('/', currentURL), {
26
- to: resolvedLocalization.locale
27
- });
28
- if (rootPath.length > 1) Object.assign(this, {
29
- base: rootPath
30
- });
31
- }
32
- }
33
-
34
- export { LocalizedRouter };
@@ -1,44 +0,0 @@
1
- import { jsx, jsxs } from 'preact/jsx-runtime';
2
- import { useMemo } from 'preact/hooks';
3
- import { createLocalizedFormatting } from '@quilted/localize';
4
- import { useBrowserDetails, HTMLAttributes } from '@quilted/preact-browser';
5
- import { LocaleContext, LocalizedFormattingContext } from './context.esnext';
6
-
7
- const RTL_LOCALES = /* @__PURE__ */ new Set([
8
- "ar",
9
- "arc",
10
- "ckb",
11
- "dv",
12
- "fa",
13
- "ha",
14
- "he",
15
- "khw",
16
- "ks",
17
- "ps",
18
- "sd",
19
- "ur",
20
- "uz-AF",
21
- "yi"
22
- ]);
23
- function Localization({
24
- locale: explicitLocale,
25
- direction: explicitDirection,
26
- children
27
- }) {
28
- const browserDetails = useBrowserDetails({ optional: true });
29
- const locale = explicitLocale ?? browserDetails?.locale.value ?? getLocaleFromEnvironment();
30
- const formatting = useMemo(() => createLocalizedFormatting(locale), [locale]);
31
- const direction = explicitDirection ?? (RTL_LOCALES.has(locale) ? "rtl" : "ltr");
32
- return /* @__PURE__ */ jsx(LocaleContext.Provider, { value: locale, children: /* @__PURE__ */ jsxs(LocalizedFormattingContext.Provider, { value: formatting, children: [
33
- browserDetails && /* @__PURE__ */ jsx(HTMLAttributes, { lang: locale, dir: direction }),
34
- children
35
- ] }) });
36
- }
37
- function getLocaleFromEnvironment() {
38
- if (typeof navigator === "undefined") {
39
- throw new Error(`Could not determine the locale automatically`);
40
- }
41
- return navigator.language;
42
- }
43
-
44
- export { Localization };
@@ -1,6 +0,0 @@
1
- import { createOptionalContext } from '@quilted/preact-context';
2
-
3
- const LocalizedFormattingContext = createOptionalContext();
4
- const LocaleContext = createOptionalContext();
5
-
6
- export { LocaleContext, LocalizedFormattingContext };
@@ -1,32 +0,0 @@
1
- import { Router } from '@quilted/preact-router';
2
-
3
- class LocalizedRouter extends Router {
4
- localization;
5
- constructor(initial, {
6
- localization,
7
- isExternal: explicitIsExternal
8
- }) {
9
- const { localeFromURL } = localization;
10
- super(initial, {
11
- isExternal(url, currentURL2) {
12
- return matchedLocale !== localeFromURL(url) || (explicitIsExternal?.(url, currentURL2) ?? false);
13
- }
14
- });
15
- const currentURL = this.currentRequest.url;
16
- const matchedLocale = localeFromURL(currentURL);
17
- const resolvedLocalization = {
18
- locale: matchedLocale ?? localization.defaultLocale,
19
- ...localization
20
- };
21
- this.localization = resolvedLocalization;
22
- const { pathname: rootPath } = localization.redirectURL(
23
- new URL("/", currentURL),
24
- {
25
- to: resolvedLocalization.locale
26
- }
27
- );
28
- if (rootPath.length > 1) Object.assign(this, { base: rootPath });
29
- }
30
- }
31
-
32
- export { LocalizedRouter };
@@ -1,61 +0,0 @@
1
- import type {RenderableProps} from 'preact';
2
- import {useMemo} from 'preact/hooks';
3
- import {createLocalizedFormatting} from '@quilted/localize';
4
- import {HTMLAttributes, useBrowserDetails} from '@quilted/preact-browser';
5
-
6
- import {LocaleContext, LocalizedFormattingContext} from './context.ts';
7
-
8
- export interface LocalizationProps {
9
- locale?: string;
10
- direction?: 'ltr' | 'rtl';
11
- }
12
-
13
- const RTL_LOCALES = new Set([
14
- 'ar',
15
- 'arc',
16
- 'ckb',
17
- 'dv',
18
- 'fa',
19
- 'ha',
20
- 'he',
21
- 'khw',
22
- 'ks',
23
- 'ps',
24
- 'sd',
25
- 'ur',
26
- 'uz-AF',
27
- 'yi',
28
- ]);
29
-
30
- export function Localization({
31
- locale: explicitLocale,
32
- direction: explicitDirection,
33
- children,
34
- }: RenderableProps<LocalizationProps>) {
35
- const browserDetails = useBrowserDetails({optional: true});
36
- const locale =
37
- explicitLocale ??
38
- browserDetails?.locale.value ??
39
- getLocaleFromEnvironment();
40
-
41
- const formatting = useMemo(() => createLocalizedFormatting(locale), [locale]);
42
- const direction =
43
- explicitDirection ?? (RTL_LOCALES.has(locale) ? 'rtl' : 'ltr');
44
-
45
- return (
46
- <LocaleContext.Provider value={locale}>
47
- <LocalizedFormattingContext.Provider value={formatting}>
48
- {browserDetails && <HTMLAttributes lang={locale} dir={direction} />}
49
- {children}
50
- </LocalizedFormattingContext.Provider>
51
- </LocaleContext.Provider>
52
- );
53
- }
54
-
55
- function getLocaleFromEnvironment() {
56
- if (typeof navigator === 'undefined') {
57
- throw new Error(`Could not determine the locale automatically`);
58
- }
59
-
60
- return navigator.language;
61
- }
@@ -1,46 +0,0 @@
1
- import {Router, type RouterOptions} from '@quilted/preact-router';
2
-
3
- import type {RouteLocalization, ResolvedRouteLocalization} from './types.ts';
4
-
5
- export class LocalizedRouter extends Router {
6
- readonly localization: ResolvedRouteLocalization;
7
-
8
- constructor(
9
- initial: ConstructorParameters<typeof Router>[0],
10
- {
11
- localization,
12
- isExternal: explicitIsExternal,
13
- }: {localization: RouteLocalization} & Pick<RouterOptions, 'isExternal'>,
14
- ) {
15
- const {localeFromURL} = localization;
16
-
17
- super(initial, {
18
- isExternal(url, currentURL) {
19
- return (
20
- matchedLocale !== localeFromURL(url) ||
21
- (explicitIsExternal?.(url, currentURL) ?? false)
22
- );
23
- },
24
- });
25
-
26
- const currentURL = this.currentRequest.url;
27
-
28
- const matchedLocale = localeFromURL(currentURL);
29
-
30
- const resolvedLocalization: ResolvedRouteLocalization = {
31
- locale: matchedLocale ?? localization.defaultLocale,
32
- ...localization,
33
- };
34
-
35
- this.localization = resolvedLocalization;
36
-
37
- const {pathname: rootPath} = localization.redirectURL(
38
- new URL('/', currentURL),
39
- {
40
- to: resolvedLocalization.locale,
41
- },
42
- );
43
-
44
- if (rootPath.length > 1) Object.assign(this, {base: rootPath});
45
- }
46
- }