diff --git a/README.md b/README.md
index e8702eb..2e809bc 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Qwik Speak ⚡️
+# Qwik Speak ![logo](https://user-images.githubusercontent.com/14012361/230638591-98477fff-2c07-47fd-ac2a-cc5c81098f60.png)
[![Node.js CI](https://github.com/robisim74/qwik-speak/actions/workflows/node.js.yml/badge.svg)](https://github.com/robisim74/qwik-speak/actions/workflows/node.js.yml) [![Playwright](https://github.com/robisim74/qwik-speak/actions/workflows/playwright.yml/badge.svg)](https://github.com/robisim74/qwik-speak/actions/workflows/playwright.yml)
> Internationalization (i18n) library to translate texts, dates and numbers in Qwik apps
@@ -158,6 +158,9 @@ Formats a relative time using [Intl.RelativeTimeFormat](https://developer.mozill
- `formatNumber(value: number | string, options?: Intl.NumberFormatOptions, locale?: SpeakLocale, lang?: string, currency?: string)`
Formats a number using [Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) API
+- `displayName(code: string, options: Intl.DisplayNamesOptions, locale?: SpeakLocale, lang?: string)`
+Returns the translation of language, region, script or currency display names using [Intl.DisplayNames](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames) API
+
## Development Builds
### Library & tools
#### Build
diff --git a/public/favicon.svg b/public/favicon.svg
index 0ded7c1..b621341 100644
--- a/public/favicon.svg
+++ b/public/favicon.svg
@@ -1 +1,17 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/components/change-locale/change-locale.css b/src/components/change-locale/change-locale.css
new file mode 100644
index 0000000..969a313
--- /dev/null
+++ b/src/components/change-locale/change-locale.css
@@ -0,0 +1,27 @@
+.change-locale {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ padding: 20px;
+ box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
+ border-radius: 6px;
+}
+
+.change-locale h2 {
+ margin-bottom: 20px;
+ font-weight: bold;
+ text-align: center;
+}
+
+.change-locale .names {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.change-locale .names button.active {
+ background-color: #327335;
+ color: #fff;
+}
\ No newline at end of file
diff --git a/src/components/change-locale/change-locale.tsx b/src/components/change-locale/change-locale.tsx
index 90b0036..42fc8a6 100644
--- a/src/components/change-locale/change-locale.tsx
+++ b/src/components/change-locale/change-locale.tsx
@@ -1,7 +1,7 @@
import { $, component$, useStyles$ } from '@builder.io/qwik';
import { useLocation } from '@builder.io/qwik-city';
import type { SpeakLocale } from 'qwik-speak';
-import { $translate as t, useSpeakLocale, useSpeakConfig } from 'qwik-speak';
+import { $translate as t, displayName as dn, useSpeakLocale, useSpeakConfig } from 'qwik-speak';
import styles from './change-locale.css?inline';
@@ -32,12 +32,14 @@ export const ChangeLocale = component$(() => {
return (
{t('app.changeLocale')}
- {config.supportedLocales.map(value => (
-
await navigateByLocale$(value)}>
- {value.lang}
-
- ))}
+
+ {config.supportedLocales.map(value => (
+
+ ))}
+
);
});
diff --git a/src/components/header/change-locale.tsx b/src/components/header/change-locale.tsx
deleted file mode 100644
index be3cbc3..0000000
--- a/src/components/header/change-locale.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import { $, component$ } from '@builder.io/qwik';
-import { useLocation } from '@builder.io/qwik-city';
-import type { SpeakLocale } from 'qwik-speak';
-import { $translate as t, useSpeakLocale, useSpeakConfig } from 'qwik-speak';
-
-export const ChangeLocale = component$(() => {
- const loc = useLocation();
-
- const locale = useSpeakLocale();
- const config = useSpeakConfig();
-
- // Replace the locale and navigate to the new URL
- const navigateByLocale$ = $((newLocale: SpeakLocale) => {
- const url = new URL(location.href);
- if (loc.params.lang) {
- if (newLocale.lang !== config.defaultLocale.lang) {
- url.pathname = url.pathname.replace(loc.params.lang, newLocale.lang);
- } else {
- url.pathname = url.pathname.replace(new RegExp(`(/${loc.params.lang}/)|(/${loc.params.lang}$)`), '/');
- }
- } else if (newLocale.lang !== config.defaultLocale.lang) {
- url.pathname = `/${newLocale.lang}${url.pathname}`;
- }
-
- location.href = url.toString();
- });
-
- return (
-
-
{t('app.changeLocale')}
- {config.supportedLocales.map(value => (
-
await navigateByLocale$(value)}>
- {value.lang}
-
- ))}
-
- );
-});
diff --git a/src/components/header/header.css b/src/components/header/header.css
index d6d69ee..5e4fb0f 100644
--- a/src/components/header/header.css
+++ b/src/components/header/header.css
@@ -1,52 +1,52 @@
-header {
- background-color: #006fb3;
-}
-
-header .header-inner {
- display: grid;
- grid-template-columns: 1fr auto;
+.header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
padding: 10px;
- max-width: 800px;
- margin: 0 auto;
}
-header a {
- color: white;
- text-decoration: none;
- padding: 4px 8px;
- margin-right: 5px;
- border-radius: 4px;
+.logo {
+ width: 160px;
}
-header a:hover {
- background-color: #ffffff30;
+.header ul {
+ padding: 0;
+ margin: 0;
+ list-style: none;
}
-header .active {
- background-color: #ffffff15;
+.header li {
+ margin: 0;
+ padding: 0;
+ display: inline-block;
}
-.change-locale {
- padding: 8px;
- color: white;
- display: flex;
- align-items: center;
- gap: 10px;
+.header li a {
+ font-weight: 700;
+ color: #000000;
+ display: inline-block;
+ padding: 0 0.5em;
+ text-decoration: none;
}
-.change-locale .button {
- color: white;
- text-decoration: none;
- padding: 4px 8px;
- margin-right: 5px;
- border-radius: 4px;
- cursor: pointer;
+.header li a:hover {
+ color: #3e8e41;
}
-.change-locale .button:hover {
- background-color: #ffffff30;
+.header li a.active {
+ color: #327335;
}
-.change-locale .active {
- background-color: #ffffff15;
+@media (min-width: 768px) {
+ .header {
+ padding: 20px 70px;
+ }
+
+ .logo {
+ width: 200px;
+ }
+
+ .header li a {
+ padding: 0 1em;
+ }
}
\ No newline at end of file
diff --git a/src/components/header/header.tsx b/src/components/header/header.tsx
index 4c98bce..3e9bc6d 100644
--- a/src/components/header/header.tsx
+++ b/src/components/header/header.tsx
@@ -2,7 +2,8 @@ import { component$, useStyles$ } from '@builder.io/qwik';
import { Link, useLocation } from '@builder.io/qwik-city';
import { $translate as t, useSpeakConfig, useSpeakLocale } from 'qwik-speak';
-import { ChangeLocale } from './change-locale';
+import { ChangeLocale } from '../change-locale/change-locale';
+import { SpeakLogo } from '../icons/speak';
import styles from './header.css?inline';
@@ -18,23 +19,29 @@ export const Header = component$(() => {
};
return (
-
-
+
+ -
+ pathname.endsWith(`${x.lang}/`)) }}>
+ {t('app.nav.home')}
+
+
+ -
+
+ {t('app.nav.page')}
+
+
+
+
+
+ >
);
});
diff --git a/src/components/icons/speak.tsx b/src/components/icons/speak.tsx
new file mode 100644
index 0000000..59cb1ed
--- /dev/null
+++ b/src/components/icons/speak.tsx
@@ -0,0 +1,20 @@
+export const SpeakLogo = () => (
+
+);
diff --git a/src/global.css b/src/global.css
index a75d7a9..3871b14 100644
--- a/src/global.css
+++ b/src/global.css
@@ -1,12 +1,58 @@
body {
- margin: 0;
- padding: 0;
- font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue',
- sans-serif;
+ font-family: Arial, sans-serif;
+ font-size: 14px;
+ background-color: #f2f2f2;
}
main {
- padding: 10px 20px;
- max-width: 800px;
margin: 0 auto;
+ padding: 10px 10px 50px 10px;
+ background-color: #fff;
+ box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
+ display: flex;
+ flex-direction: column;
+ border-radius: 6px;
+}
+
+main .content {
+ padding: 10px;
+ text-align: center;
+}
+
+button {
+ display: inline-block;
+ padding: 5px 10px;
+ margin: 5px 10px;
+ border-radius: 5px;
+ border-width: 1px;
+ background-color: #fff;
+ font-size: 14px;
+ text-decoration: none;
+}
+
+button:hover {
+ background-color: #f2f2f2;
+ cursor: pointer;
+}
+
+@media (min-width: 768px) {
+ body {
+ font-size: 16px;
+ }
+
+ main {
+ max-width: 1000px;
+ padding: 20px;
+ }
+
+ main .content {
+ padding: 20px 70px;
+ }
+
+ button {
+ display: inline-block;
+ padding: 10px 20px;
+ font-size: 16px;
+ text-decoration: none;
+ }
}
\ No newline at end of file
diff --git a/src/routes/[...lang]/index.tsx b/src/routes/[...lang]/index.tsx
index 099a6f1..f886a11 100644
--- a/src/routes/[...lang]/index.tsx
+++ b/src/routes/[...lang]/index.tsx
@@ -16,7 +16,7 @@ export const Home = component$(() => {
const count = useSignal(0);
return (
- <>
+
{t('app.title')}
{t('app.subtitle')}
@@ -27,8 +27,8 @@ export const Home = component$(() => {
{t('home.plural')}
-
{p(count.value, 'home.devs')}
+
{t('home.dates')}
{fd(Date.now(), { dateStyle: 'full', timeStyle: 'short' })}
@@ -38,7 +38,7 @@ export const Home = component$(() => {
{fn(1000000)}
{fn(1000000, { style: 'currency' })}
{fn(1, { style: 'unit', unit: units['length'] })}
- >
+
);
});
diff --git a/src/routes/layout.tsx b/src/routes/layout.tsx
index c07472c..a6d733e 100644
--- a/src/routes/layout.tsx
+++ b/src/routes/layout.tsx
@@ -6,12 +6,10 @@ import { config } from '../speak-config';
export default component$(() => {
return (
- <>
+
-
-
-
- >
+
+
);
});
diff --git a/src/speak-config.ts b/src/speak-config.ts
index 890c183..bfdb099 100644
--- a/src/speak-config.ts
+++ b/src/speak-config.ts
@@ -6,8 +6,8 @@ import type { SpeakConfig } from 'qwik-speak';
export const config: SpeakConfig = {
defaultLocale: { lang: 'en-US', currency: 'USD', timeZone: 'America/Los_Angeles', units: { 'length': 'mile' } },
supportedLocales: [
- { lang: 'it-IT', currency: 'EUR', timeZone: 'Europe/Rome', units: { 'length': 'kilometer' } },
- { lang: 'en-US', currency: 'USD', timeZone: 'America/Los_Angeles', units: { 'length': 'mile' } }
+ { lang: 'en-US', currency: 'USD', timeZone: 'America/Los_Angeles', units: { 'length': 'mile' } },
+ { lang: 'it-IT', currency: 'EUR', timeZone: 'Europe/Rome', units: { 'length': 'kilometer' } }
],
assets: [
'app' // Translations shared by the pages