@quilted/preact-localize 0.1.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.
Files changed (32) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/build/esm/index.mjs +2 -1
  3. package/build/esm/request-router.mjs +5 -5
  4. package/build/esm/routing/LocalizedLink.mjs +6 -6
  5. package/build/esm/routing/LocalizedNavigation.mjs +48 -0
  6. package/build/esm/routing/LocalizedRouter.mjs +34 -0
  7. package/build/esm/routing/localization/by-locale.mjs +5 -5
  8. package/build/esnext/index.esnext +2 -1
  9. package/build/esnext/request-router.esnext +5 -6
  10. package/build/esnext/routing/LocalizedLink.esnext +7 -7
  11. package/build/esnext/routing/LocalizedNavigation.esnext +36 -0
  12. package/build/esnext/routing/LocalizedRouter.esnext +32 -0
  13. package/build/esnext/routing/localization/by-locale.esnext +9 -13
  14. package/build/tsconfig.tsbuildinfo +1 -1
  15. package/build/typescript/routing/LocalizedNavigation.d.ts +13 -0
  16. package/build/typescript/routing/LocalizedNavigation.d.ts.map +1 -0
  17. package/build/typescript/routing/LocalizedRouter.d.ts +9 -0
  18. package/build/typescript/routing/LocalizedRouter.d.ts.map +1 -0
  19. package/build/typescript/routing/types.d.ts +2 -2
  20. package/build/typescript/routing.d.ts +2 -1
  21. package/build/typescript/routing.d.ts.map +1 -1
  22. package/package.json +4 -4
  23. package/source/request-router.ts +4 -4
  24. package/source/routing/LocalizedLink.tsx +7 -7
  25. package/source/routing/LocalizedNavigation.tsx +64 -0
  26. package/source/routing/LocalizedRouter.ts +46 -0
  27. package/source/routing/localization/by-locale.ts +5 -5
  28. package/source/routing/types.ts +2 -2
  29. package/source/routing.ts +2 -1
  30. package/build/esm/routing/LocalizedRouting.mjs +0 -65
  31. package/build/esnext/routing/LocalizedRouting.esnext +0 -64
  32. package/source/routing/LocalizedRouting.tsx +0 -94
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @quilted/react-localize
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Patch Changes
6
+
7
+ - [#757](https://github.com/lemonmade/quilt/pull/757) [`00cac4b`](https://github.com/lemonmade/quilt/commit/00cac4b4d01831ba654e94152d7a67a0ef75043b) Thanks [@lemonmade](https://github.com/lemonmade)! - Simplify routing library
8
+
9
+ - Updated dependencies [[`00cac4b`](https://github.com/lemonmade/quilt/commit/00cac4b4d01831ba654e94152d7a67a0ef75043b)]:
10
+ - @quilted/request-router@0.3.0
11
+ - @quilted/preact-router@0.2.0
12
+
3
13
  ## 0.2.2
4
14
 
5
15
  ### Patch Changes
@@ -5,7 +5,8 @@ export { useLocale } from './hooks/locale.mjs';
5
5
  export { useLocaleFromEnvironment } from './hooks/locale-from-environment.mjs';
6
6
  export { LocalizedFormattingContext } from './context.mjs';
7
7
  export { LocalizedLink } from './routing/LocalizedLink.mjs';
8
- export { LocalizedRouting } from './routing/LocalizedRouting.mjs';
8
+ export { LocalizedNavigation } from './routing/LocalizedNavigation.mjs';
9
+ export { LocalizedRouter } from './routing/LocalizedRouter.mjs';
9
10
  export { useRouteLocalization } from './routing/context.mjs';
10
11
  export { createRouteLocalization } from './routing/localization/by-locale.mjs';
11
12
  export { createRoutePathLocalization } from './routing/localization/by-path.mjs';
@@ -7,9 +7,9 @@ function createRequestRouterLocalization({
7
7
  }) {
8
8
  const {
9
9
  matchLocale,
10
- redirectUrl,
10
+ redirectURL,
11
11
  defaultLocale,
12
- localeFromUrl
12
+ localeFromURL
13
13
  } = localization;
14
14
  const getDefaultLocaleFromRequest = request => {
15
15
  const acceptLanguage = request.headers.get('Accept-Language');
@@ -20,7 +20,7 @@ function createRequestRouterLocalization({
20
20
  to,
21
21
  ...options
22
22
  }) {
23
- return new RedirectResponse(redirectUrl(new URL(request.url), {
23
+ return new RedirectResponse(redirectURL(new URL(request.url), {
24
24
  to
25
25
  }), options);
26
26
  }
@@ -32,11 +32,11 @@ function createRequestRouterLocalization({
32
32
  return async (request, ...args) => {
33
33
  if (!include(request)) return handler(request, ...args);
34
34
  const url = new URL(request.url);
35
- const urlLocale = localeFromUrl(url);
35
+ const urlLocale = localeFromURL(url);
36
36
  const requestLocale = getLocaleForRequest(request, () => getDefaultLocaleFromRequest(request));
37
37
  const matchedLocale = (requestLocale == null ? undefined : matchLocale(requestLocale)) ?? defaultLocale;
38
38
  if (urlLocale !== matchedLocale) {
39
- return new RedirectResponse(redirectUrl(url, {
39
+ return new RedirectResponse(redirectURL(url, {
40
40
  to: matchedLocale
41
41
  }));
42
42
  }
@@ -1,5 +1,5 @@
1
1
  import { useMemo } from 'preact/hooks';
2
- import { useRouter, useCurrentUrl, Link } from '@quilted/preact-router';
2
+ import { useRouter, useCurrentURL, Link } from '@quilted/preact-router';
3
3
  import { useRouteLocalization } from './context.mjs';
4
4
  import { jsx } from 'preact/jsx-runtime';
5
5
 
@@ -9,16 +9,16 @@ function LocalizedLink({
9
9
  ...props
10
10
  }) {
11
11
  const router = useRouter();
12
- const currentUrl = useCurrentUrl();
12
+ const url = useCurrentURL();
13
13
  const {
14
- redirectUrl
14
+ redirectURL
15
15
  } = useRouteLocalization();
16
- const resolvedUrl = useMemo(() => redirectUrl(to ? router.resolve(to).url : currentUrl, {
16
+ const resolvedURL = useMemo(() => redirectURL(to ? router.resolve(to).url : url, {
17
17
  to: locale
18
- }), [to, currentUrl, locale, redirectUrl, router]);
18
+ }), [to, url, locale, redirectURL, router]);
19
19
  return jsx(Link, {
20
20
  hrefLang: locale,
21
- to: resolvedUrl,
21
+ to: resolvedURL,
22
22
  ...props
23
23
  });
24
24
  }
@@ -0,0 +1,48 @@
1
+ import { useMemo } from 'preact/hooks';
2
+ import { useBrowserDetails } from '@quilted/preact-browser';
3
+ import { Navigation } from '@quilted/preact-router';
4
+ import { Localization } from '../Localization.mjs';
5
+ import { useLocaleFromEnvironment } from '../hooks/locale-from-environment.mjs';
6
+ import { LocalizedRouter } from './LocalizedRouter.mjs';
7
+ import { RouteLocalizationContext } from './context.mjs';
8
+ import { jsx } from 'preact/jsx-runtime';
9
+
10
+ function LocalizedNavigation({
11
+ locale: explicitLocale,
12
+ router,
13
+ routes,
14
+ context,
15
+ localization,
16
+ children
17
+ }) {
18
+ const browser = useBrowserDetails({
19
+ optional: true
20
+ });
21
+ const resolvedRouter = useMemo(() => router ?? new LocalizedRouter(browser?.request.url, {
22
+ localization: localization
23
+ }), [router]);
24
+ const resolvedLocalization = resolvedRouter.localization;
25
+ const localeFromEnvironment = useLocaleFromEnvironment();
26
+ let resolvedLocale;
27
+ if (explicitLocale) {
28
+ resolvedLocale = explicitLocale;
29
+ } else if (localeFromEnvironment != null && localeFromEnvironment.toLowerCase().startsWith(resolvedLocalization.locale.toLowerCase())) {
30
+ resolvedLocale = localeFromEnvironment;
31
+ } else {
32
+ resolvedLocale = resolvedLocalization.locale;
33
+ }
34
+ return jsx(Localization, {
35
+ locale: resolvedLocale,
36
+ children: jsx(RouteLocalizationContext.Provider, {
37
+ value: resolvedLocalization,
38
+ children: jsx(Navigation, {
39
+ router: resolvedRouter,
40
+ routes: routes,
41
+ context: context,
42
+ children: children
43
+ })
44
+ })
45
+ });
46
+ }
47
+
48
+ export { LocalizedNavigation };
@@ -0,0 +1,34 @@
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 };
@@ -6,16 +6,16 @@ function createRouteLocalization({
6
6
  const locales = [...localeMap.keys()].sort((a, b) => b.length - a.length);
7
7
  return {
8
8
  locales,
9
- redirectUrl,
9
+ redirectURL,
10
10
  matchLocale,
11
- localeFromUrl,
11
+ localeFromURL,
12
12
  defaultLocale
13
13
  };
14
14
  function matchLocale(requestLocale) {
15
15
  const language = requestLocale.split('-')[0];
16
16
  return locales.find(locale => locale === requestLocale || locale === language);
17
17
  }
18
- function localeFromUrl(url) {
18
+ function localeFromURL(url) {
19
19
  const hostname = url.hostname.toLowerCase();
20
20
  const pathname = normalizePath(url.pathname.toLowerCase());
21
21
  for (const [locale, target] of sortedLocaleMap) {
@@ -26,10 +26,10 @@ function createRouteLocalization({
26
26
  }
27
27
  }
28
28
  }
29
- function redirectUrl(from, {
29
+ function redirectURL(from, {
30
30
  to: toLocale
31
31
  }) {
32
- const fromLocale = localeFromUrl(from);
32
+ const fromLocale = localeFromURL(from);
33
33
  const toUrl = new URL(from);
34
34
  if (fromLocale === toLocale) return toUrl;
35
35
  const target = localeMap.get(toLocale) ?? localeMap.get(defaultLocale);
@@ -5,7 +5,8 @@ export { useLocale } from './hooks/locale.esnext';
5
5
  export { useLocaleFromEnvironment } from './hooks/locale-from-environment.esnext';
6
6
  export { LocalizedFormattingContext } from './context.esnext';
7
7
  export { LocalizedLink } from './routing/LocalizedLink.esnext';
8
- export { LocalizedRouting } from './routing/LocalizedRouting.esnext';
8
+ export { LocalizedNavigation } from './routing/LocalizedNavigation.esnext';
9
+ export { LocalizedRouter } from './routing/LocalizedRouter.esnext';
9
10
  export { useRouteLocalization } from './routing/context.esnext';
10
11
  export { createRouteLocalization } from './routing/localization/by-locale.esnext';
11
12
  export { createRoutePathLocalization } from './routing/localization/by-path.esnext';
@@ -5,7 +5,7 @@ function createRequestRouterLocalization({
5
5
  localization,
6
6
  requestLocale: customRequestLocale
7
7
  }) {
8
- const { matchLocale, redirectUrl, defaultLocale, localeFromUrl } = localization;
8
+ const { matchLocale, redirectURL, defaultLocale, localeFromURL } = localization;
9
9
  const getDefaultLocaleFromRequest = (request) => {
10
10
  const acceptLanguage = request.headers.get("Accept-Language");
11
11
  return acceptLanguage && parseAcceptLanguageHeader(acceptLanguage) || void 0;
@@ -16,7 +16,7 @@ function createRequestRouterLocalization({
16
16
  ...options
17
17
  }) {
18
18
  return new RedirectResponse(
19
- redirectUrl(new URL(request.url), { to }),
19
+ redirectURL(new URL(request.url), { to }),
20
20
  options
21
21
  );
22
22
  }
@@ -24,10 +24,9 @@ function createRequestRouterLocalization({
24
24
  redirect: localeRedirect,
25
25
  localizedRequestHandler(handler, { include = () => true } = {}) {
26
26
  return async (request, ...args) => {
27
- if (!include(request))
28
- return handler(request, ...args);
27
+ if (!include(request)) return handler(request, ...args);
29
28
  const url = new URL(request.url);
30
- const urlLocale = localeFromUrl(url);
29
+ const urlLocale = localeFromURL(url);
31
30
  const requestLocale = getLocaleForRequest(
32
31
  request,
33
32
  () => getDefaultLocaleFromRequest(request)
@@ -35,7 +34,7 @@ function createRequestRouterLocalization({
35
34
  const matchedLocale = (requestLocale == null ? void 0 : matchLocale(requestLocale)) ?? defaultLocale;
36
35
  if (urlLocale !== matchedLocale) {
37
36
  return new RedirectResponse(
38
- redirectUrl(url, {
37
+ redirectURL(url, {
39
38
  to: matchedLocale
40
39
  })
41
40
  );
@@ -1,6 +1,6 @@
1
1
  import { jsx } from 'preact/jsx-runtime';
2
2
  import { useMemo } from 'preact/hooks';
3
- import { useRouter, useCurrentUrl, Link } from '@quilted/preact-router';
3
+ import { useRouter, useCurrentURL, Link } from '@quilted/preact-router';
4
4
  import { useRouteLocalization } from './context.esnext';
5
5
 
6
6
  function LocalizedLink({
@@ -9,13 +9,13 @@ function LocalizedLink({
9
9
  ...props
10
10
  }) {
11
11
  const router = useRouter();
12
- const currentUrl = useCurrentUrl();
13
- const { redirectUrl } = useRouteLocalization();
14
- const resolvedUrl = useMemo(
15
- () => redirectUrl(to ? router.resolve(to).url : currentUrl, { to: locale }),
16
- [to, currentUrl, locale, redirectUrl, router]
12
+ const url = useCurrentURL();
13
+ const { redirectURL } = useRouteLocalization();
14
+ const resolvedURL = useMemo(
15
+ () => redirectURL(to ? router.resolve(to).url : url, { to: locale }),
16
+ [to, url, locale, redirectURL, router]
17
17
  );
18
- return /* @__PURE__ */ jsx(Link, { hrefLang: locale, to: resolvedUrl, ...props });
18
+ return /* @__PURE__ */ jsx(Link, { hrefLang: locale, to: resolvedURL, ...props });
19
19
  }
20
20
 
21
21
  export { LocalizedLink };
@@ -0,0 +1,36 @@
1
+ import { jsx } from 'preact/jsx-runtime';
2
+ import { useMemo } from 'preact/hooks';
3
+ import { useBrowserDetails } from '@quilted/preact-browser';
4
+ import { Navigation } from '@quilted/preact-router';
5
+ import { Localization } from '../Localization.esnext';
6
+ import { useLocaleFromEnvironment } from '../hooks/locale-from-environment.esnext';
7
+ import { LocalizedRouter } from './LocalizedRouter.esnext';
8
+ import { RouteLocalizationContext } from './context.esnext';
9
+
10
+ function LocalizedNavigation({
11
+ locale: explicitLocale,
12
+ router,
13
+ routes,
14
+ context,
15
+ localization,
16
+ children
17
+ }) {
18
+ const browser = useBrowserDetails({ optional: true });
19
+ const resolvedRouter = useMemo(
20
+ () => router ?? new LocalizedRouter(browser?.request.url, { localization }),
21
+ [router]
22
+ );
23
+ const resolvedLocalization = resolvedRouter.localization;
24
+ const localeFromEnvironment = useLocaleFromEnvironment();
25
+ let resolvedLocale;
26
+ if (explicitLocale) {
27
+ resolvedLocale = explicitLocale;
28
+ } else if (localeFromEnvironment != null && localeFromEnvironment.toLowerCase().startsWith(resolvedLocalization.locale.toLowerCase())) {
29
+ resolvedLocale = localeFromEnvironment;
30
+ } else {
31
+ resolvedLocale = resolvedLocalization.locale;
32
+ }
33
+ return /* @__PURE__ */ jsx(Localization, { locale: resolvedLocale, children: /* @__PURE__ */ jsx(RouteLocalizationContext.Provider, { value: resolvedLocalization, children: /* @__PURE__ */ jsx(Navigation, { router: resolvedRouter, routes, context, children }) }) });
34
+ }
35
+
36
+ export { LocalizedNavigation };
@@ -0,0 +1,32 @@
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 };
@@ -8,9 +8,9 @@ function createRouteLocalization({
8
8
  const locales = [...localeMap.keys()].sort((a, b) => b.length - a.length);
9
9
  return {
10
10
  locales,
11
- redirectUrl,
11
+ redirectURL,
12
12
  matchLocale,
13
- localeFromUrl,
13
+ localeFromURL,
14
14
  defaultLocale
15
15
  };
16
16
  function matchLocale(requestLocale) {
@@ -19,24 +19,21 @@ function createRouteLocalization({
19
19
  (locale) => locale === requestLocale || locale === language
20
20
  );
21
21
  }
22
- function localeFromUrl(url) {
22
+ function localeFromURL(url) {
23
23
  const hostname = url.hostname.toLowerCase();
24
24
  const pathname = normalizePath(url.pathname.toLowerCase());
25
25
  for (const [locale, target] of sortedLocaleMap) {
26
26
  if (target.startsWith("/")) {
27
- if (pathname.startsWith(target))
28
- return locale;
27
+ if (pathname.startsWith(target)) return locale;
29
28
  } else {
30
- if (hostname === target)
31
- return locale;
29
+ if (hostname === target) return locale;
32
30
  }
33
31
  }
34
32
  }
35
- function redirectUrl(from, { to: toLocale }) {
36
- const fromLocale = localeFromUrl(from);
33
+ function redirectURL(from, { to: toLocale }) {
34
+ const fromLocale = localeFromURL(from);
37
35
  const toUrl = new URL(from);
38
- if (fromLocale === toLocale)
39
- return toUrl;
36
+ if (fromLocale === toLocale) return toUrl;
40
37
  const target = localeMap.get(toLocale) ?? localeMap.get(defaultLocale);
41
38
  if (target.startsWith("/")) {
42
39
  const fromTarget = fromLocale == null ? "/" : localeMap.get(fromLocale) ?? "/";
@@ -50,8 +47,7 @@ function createRouteLocalization({
50
47
  }
51
48
  }
52
49
  function normalizePath(path) {
53
- if (path.length === 0)
54
- return "/";
50
+ if (path.length === 0) return "/";
55
51
  return path.endsWith("/") && path.length > 1 ? path.slice(0, -1) : path;
56
52
  }
57
53