-
Notifications
You must be signed in to change notification settings - Fork 76
internationalization
Typically, components allow users to supply text values via slots and attributes, but there are cases where components need to take additional steps to support internationalization.
Formatting of values, such as numbers and dates, for display should use the Intl
APIs.
To add right-to-left (RTL) support to your components you should use CSS Logical properties within CSS. If you need to know direction in JavaScript, use the internal getElementDir
helper in the dom utility.
Some CSS properties do not have logical equivalents. Such as...
- box-shadow
- text-shadow
- transform
- background-position
For these properties, you should use the internal getElementDir
helper to apply the CSS_UTILITY.rtl
class to your component.
Previously, components provided Intl properties (intl<Prop>
) to allow users to pass string translations. While this is still supported for backwards compatibility, our components also have translations built-in.
The following section covers how to add built-in translation support to components.
This pattern enables components to support built-in translations. In order to support this, a component must:
- Add the following translation bundles as component assets under a
t9n
folder (please refer to https://github.com/Esri/calcite-design-system/blob/main/packages/calcite-components/conventions/README.md#assets for additional info on assets)-
messages.json
– main bundle -
messages_en.json
– locale-specific bundle (kept in sync with main one via scripts)
-
- Implement the
T9nComponent
interface- The
onMessagesChange
method must be empty as it is wired up by the support utils. - The
onMessagesChange
method must also be configured to watch themessageOverrides
property.
- The
- Use the
setUpMessages
util in the component'scomponentWillLoad
lifecycle methods. This must be awaited on to have an initial set of strings available before rendering. - Use the
connectMessages
/disconnectMessages
utils in the component'sconnectedCallback
/disconnectedCallback
lifecycle methods. This will set up and tear down supporting methods on the component. - Add an appropriate E2E test by using the
t9n
common test helper. - Composite components need to forward message overrides props to supporting t9n components.
- If the parent supports translations:
- Add the
messageOverrides
property (its type should be the union of the parent and supporting component messages types). - Pass the
messageOverrides
into supporting components in the render method.
- Add the
- If the parent does not support translations:
- Add the
messageOverrides
property (its type should be the union of supporting component messages types). - Pass the
messageOverrides
into supporting components in the render method.
- Add the
- If the parent supports translations:
- Internal components that support public t9n components
- Do not have to implement the
T9nComponent
interface - Should use an internal, immutable,
messages
property (its type should correspond to the parent component's messages type)
- Do not have to implement the
- This pattern depends on
LocalizedComponent
being implemented. -
connectLocalized
(fromLocalizedComponent
) must be called beforeconnectMessages
. - You can also look at the interface and util documentation for additional info.
- The internal
messages
property should be used as the source of truth for translations in rendering. - List of supported locales can be found on our Localization support page.
- Placeholders in message bundle strings should:
- Use the following syntax:
{placeholder}
(e.g.,Hello {userName}, my old friend. 👋
). - Have an expressive name to provide context regarding its use.
- Use the following syntax:
Note
In the future it will likely become necessary to provide string translations for components. An example would be the aria-label
for the <calcite-modal>
close button. Initial research looks promising and we could likely implement one of these approaches and set a lang
for each component.
- https://medium.com/stencil-tricks/implementing-internationalisation-i18n-with-stencil-5e6559554117 and https://codesandbox.io/s/43pmx55vo9
- https://github.com/ionic-team/ionic-stencil-conference-app/issues/69
Until we implement a lang
facility and set up translations for all components, we have been allowing a small number of strings to be passed in as properties. Properties that represent translated strings should have the syntax: text-label-x
, where x
is the name for the string. For example, when providing a string from "Close", use the property name text-label-close
. In the component, these properties should default to their English equivalent (this is useful for non-localized apps):
@Prop() textLabelClose: string = 'Close';