svelte-ux
svelte-ux copied to clipboard
Internationalization (i18n) support
- https://github.com/ivanhofer/typesafe-i18n
- Ivan Hofer - SvelteKit and i18n: let's finally solve this never ending story
- https://t18s.sigrist.dev/
- https://inlang.com/
-
Paraglide JS
- https://github.com/opral/monorepo/tree/main/inlang/source-code/paraglide/paraglide-js-adapter-svelte/example
Perhaps these links might also offer some more inspiration:
- https://github.com/jacob-8/poly-i18n
- https://github.com/rinart73/sveltekit-localize-url
The thread is quite lengthy, but provides valuable background information https://github.com/sveltejs/kit/issues/553.
I'm curious if anyone has any experience/examples from a library perspective as well, or if most try to avoid having any "embedded text". I need to identify which components have this issue, as we might be able to remove/workaround the few cases.
A few that come to mind:
-
MultiSelect(Field|Menu)
- Apply/Cancel buttons
- Formatted selection ("X selected")
-
DateRangeField (and other date components)
- Types
- Presets (which can be overridden already)
- Date values (which we should be able to leverage the work being done for formatDate()
- OK / Cancel buttons
Any others I'm overlooking?
I'm thinking we might be able to just expose enough slots / props to allow configuring this (and maybe even via context if needed, similar to the recent format()
change), and then the responsibility of providing translated text is the responsibility of the user.
Exposing something via settings to control the OK/Cancel values (aka Apply/Cancel), etc could go a long way for some of this (just like the number formats). This would also allow us to control the order (should it be OK/Cancel or Cancel/OK) and possibly pass props to those buttons (which button variant should we use, for example).
The more I think about this, I think we shouldn't do i18n directly within Svelte UX, but provide enough hooks/customization to allow it to be configured.
I might be able to work with you on this one. In my part of the world it's fairly common to deliver i18n and l10n enabled apps by default. My customers within 600 miles speak 15 different languages.
I am still fairly new to Svelte-UX but will dig into it and see what could be improved upon. Slots & props are looking good. As from library point of view, I've been using svelte-i18n
for years in combination with i18n Ally
VSCode extension. Works like a charm for me.
@alesvaupotic Sounds great! I appreciate all the help I can get, and having someone with experience (and requirements) would be great. I'm thinking most of the i18n / translations would be an app's responsibility, but the library doesn't get in the way of providing those strings/translations.
I think one of the first steps would be to identify where Svelte UX (and LayerChart at some point) are getting in the way, and seeing if those can be improved via slots/props/settings context. I like the idea of leaning into the settings context like we did for format()
and will be for formatDate()
in the near future.
I'm thinking most of the i18n / translations would be an app's responsibility, but the library doesn't get in the way of providing those strings/translations.
The more I think about this, I think we shouldn't do i18n directly within Svelte UX, but provide enough hooks/customization to allow it to be configured.
Intuitively I think this is a great approach, as a developer I would love to be flexible enough in providing the translated texts in components when they are indeed needed. Another example is the multiselect 'search items' placeholder string, which is such a generic label similar to the proposed cancel an apply button settings. In date related components I would also like to be able to override the language translation texts (like daynames etc) even when they are provided by a framework or library as translations.
Intuitively I think this is a great approach, as a developer I would love to be flexible enough in providing the translated texts in components when they are indeed needed. Another example is the multiselect 'search items' placeholder string, which is such a generic label similar to the proposed cancel an apply button settings. In date related components I would also like to be able to override the language translation texts (like daynames etc) even when they are provided by a framework or library as translations.
Agreed. Currently format()
for number formatting (using Intl.NumberFormat) you can specify the locales
and currency
under settings({ formats: { number: { ... } })
...
settings({
// ...
formats: {
numbers: {
default: {
locales: 'en',
currency: 'USD',
fractionDigits: 2,
currencyDisplay: 'symbol',
},
currency: {
locales: 'fr',
currency: 'EUR',
},
},
},
});
I could see adding locales
at the top-level as well to default all Intl.*
(or similar) functions. We are in the process of converting formatDate()
to leverage Intl.DateTimeFormat instead of date-fns. As long as this works out, it will be a big win for date display within Svelte UX, especially for i18n.
For non-Intl.* display, such as OK/Cancel
, # selected
, etc, I could see exposing those as extra properties under settings({ formats: { ... })
and you could do the lookup/display here based on the app environment.
The more places we can side step the issue by allowing the user to specify it at the call site (ex. <Button>Some String</Button>
) the better, but there are going to be some places where this isn't easy, and I think settings()
/ context will work well here.
We have a big i18n/locale improvement coming with PR #137 (huge thanks to @jycouet), which also includes some genreal i18n improvements, along with all the date specific improvements.
Related, I also looked at how React Aria does internationalization. They use the IntlMessageFormat package, which is interesting (formats messages using Intl.NumberFormat and Intl.DateTimeFormat like our format()
does (now)). Might be worth looking at a little closer, although might not be needed.
I also looked at Material UI (React) just to see how another large component library handles localization. They appear to use an approach similar to our settings()
by using context. I'm not overly fond with how they define the localization per component TBH, but this might be the validation I need to stick with our current approach for now though :).
Once we merge #137 this week, we can reevaluate where we still need to improve (I know there is the "# selected" strings at least, but I'm sure there are others), but this is great progress in that direction.
I'll be happy to do # selected
after the #137 👍