Skip to content

ember-intl integration #2878

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 77 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
5a5bac5
using test helpers import path
zamoore May 19, 2025
41ae6ed
fixing import
zamoore May 19, 2025
9f84f26
first run at translations
zamoore May 14, 2025
97a36c8
updated lockfile
zamoore May 14, 2025
4101b01
fixed template string
zamoore May 14, 2025
53787a0
fixing translations
zamoore May 14, 2025
4496ddf
fixing failing test
zamoore May 15, 2025
678005a
fixing tests
zamoore May 15, 2025
2a8c971
linting for @text values
zamoore May 16, 2025
632e7c6
fixing intl test setup
zamoore May 16, 2025
053b192
added missing translation
zamoore May 16, 2025
d63f470
removed translation
zamoore May 16, 2025
b915cfb
setting up rendering tests correctly
zamoore May 16, 2025
0bb2952
fixed failing tests
zamoore May 16, 2025
79c0c7b
added changeset
zamoore May 16, 2025
d99e0c4
fixing pagination translation
zamoore May 16, 2025
3591fd1
fixing tests
zamoore May 16, 2025
3f9685b
added missed translation
zamoore May 16, 2025
e0a6028
responding to pr feedback
zamoore May 19, 2025
bdb929b
fixing malformed translations
zamoore May 19, 2025
f6da0ee
downgraded ember-intl to work with cloud-ui
zamoore May 19, 2025
0f12770
Apply suggestions from code review
zamoore May 19, 2025
a56ad2a
made ember-intl optional
zamoore May 20, 2025
f65ba78
moved translations to sep files
zamoore May 20, 2025
8ec1f68
updating import
zamoore May 20, 2025
6220d07
setting up namespaces
zamoore May 20, 2025
5b95ae5
fix file extension
zamoore May 20, 2025
e767ef5
fixing translation keys
zamoore May 20, 2025
f46fc84
fix dash character
zamoore May 21, 2025
210b73a
working on making things work in projects without ember-intl
zamoore May 21, 2025
ea67c2f
fixing use of t helper
zamoore May 21, 2025
1ba0ac0
adding polyfill for ember-getowner
zamoore May 21, 2025
8dea761
trying the deprecated getOwner
zamoore May 21, 2025
63bc592
added integration test for hds-t helper
zamoore May 22, 2025
d10a4e4
addressed trailing comma issue
zamoore May 22, 2025
68d2c20
addressing pr feedback
zamoore May 22, 2025
ba317ea
removed custom lint plugin
zamoore May 22, 2025
df0380e
removed unused rule
zamoore May 22, 2025
d894a71
setting the 3.28lts version to be allowed to fail
zamoore May 30, 2025
f412416
firming up deps and docs
zamoore Jun 16, 2025
d952e21
adding a translation demo page
zamoore Jun 16, 2025
00cf2fe
adding multiple languages
zamoore Jun 16, 2025
af089e7
adding docs
zamoore Jun 16, 2025
673b75b
revert accidental change
zamoore Jun 16, 2025
7ad7647
added service wrapper and use it instead in helper
zamoore Jun 16, 2025
af073d7
fixing tests
zamoore Jun 17, 2025
3dfc52c
responding to PR feedback
zamoore Jun 17, 2025
6a39b80
namespaces translations
zamoore Jun 17, 2025
bda2eb4
updated changelog
zamoore Jun 18, 2025
cfcc2ac
fixing tests
zamoore Jun 18, 2025
b2f849f
changed back to cjs file
zamoore Jun 18, 2025
08b9d55
changed back to cjs file
zamoore Jun 18, 2025
21ff4fc
fixing tons of files added to build
zamoore Jun 18, 2025
72386da
changing the rollup config
zamoore Jun 18, 2025
2c76fdc
updated rollup config to be more explicit
zamoore Jun 18, 2025
8e86d08
updating rollup config
zamoore Jun 18, 2025
72ce039
fixing typo
zamoore Jun 18, 2025
0c93e8e
fixed overeager find and replace
zamoore Jun 18, 2025
8be1541
responding to pr feedback
zamoore Jun 18, 2025
78b3b2e
fixing build issues
zamoore Jun 18, 2025
8339ab4
fixing tests
zamoore Jun 18, 2025
8b54ae3
added translations for values outside of templates
zamoore Jun 18, 2025
0e6d7e1
added override examples
zamoore Jun 18, 2025
35ea344
fixing linting error
zamoore Jun 18, 2025
ae65b27
revert bad path changes
zamoore Jun 19, 2025
197a750
Apply suggestions from code review
zamoore Jun 19, 2025
d045fb3
removed extraneous change
zamoore Jun 19, 2025
99e97de
removed extraneous change
zamoore Jun 19, 2025
50d25f7
reverting unneeded change
zamoore Jun 19, 2025
7e6f44c
removing quotes from translations
zamoore Jun 19, 2025
c1b530f
responding to PR feedback
zamoore Jun 19, 2025
0b495a6
code clion up
zamoore Jun 19, 2025
9193a98
code cleann up
zamoore Jun 19, 2025
daa9920
small tweaks to the showcase page for the `internationalization`
didoo Jun 19, 2025
2bc8708
removed empty container
didoo Jun 19, 2025
0552e94
responding to pr feedback
zamoore Jun 20, 2025
4bbfefd
responding to PR feedback
zamoore Jun 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .changeset/early-years-jog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
"@hashicorp/design-system-components": minor
---

- Added `ember-intl` as a dependency
- Added `hdsIntl` service for translations with default fallback values
- Added `hds-t` helper which uses the `hds-intl` service to provide translations in templates

`AdvancedTable` - Translated template strings. Removed extraneous screen-reader-only text.

`AppFooter` - Translated template strings

`AppSideNav` - Translated template strings

`ApplicationState` - Translated template strings

`CodeEditor` - Translated template strings

`DismissButton` - Translated template strings

`MaskedInput` - Translated template strings

`SuperSelect` - Translated template strings

`Pagination` - Translated template strings

`SideNav` - Translated template strings

`Table` - Translated template strings

`Time` - Translated template strings
1 change: 1 addition & 0 deletions packages/components/.template-lintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ module.exports = {
'no-unnecessary-curly-strings': false,
'no-redundant-role': false,
'no-builtin-form-components': false,
'no-bare-strings': true,
},
};
95 changes: 95 additions & 0 deletions packages/components/config/ember-intl.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
'use strict';

module.exports = function (/* environment */) {
return {
/**
* Cause a build error if missing translations are detected.
*
* See https://ember-intl.github.io/ember-intl/docs/guide/missing-translations#throwing-a-build-error-on-missing-when-required-translations
*
* @property errorOnMissingTranslations
* @type {Boolean}
* @default "false"
*/
errorOnMissingTranslations: false,

/**
* Cause a build error if ICU argument mismatches are detected between translations
* with the same key across all locales.
*
* @property errorOnNamedArgumentMismatch
* @type {Boolean}
* @default "false"
*/
errorOnNamedArgumentMismatch: false,

/**
* Merges the fallback locale's translations into all other locales as a
* build-time fallback strategy.
*
* This will **not** prevent missing translation warnings or errors from occurring.
* It's meant as safety net when warnings are enabled.
* When enabled along with `errorOnMissingTranslations` any fallback attempts will result in an error.
*
* @property fallbackLocale
* @type {String?}
* @default "null"
*/
fallbackLocale: null,

/**
* Path where translations are stored. This is relative to the project root.
* For example, if your translations are an npm dependency, set this to:
*`'./node_modules/path/to/translations'`
*
* @property inputPath
* @type {String}
* @default "'translations'"
*/
inputPath: 'translations',

/**
* Prevents the translations from being bundled with the application code.
* This enables asynchronously loading the translations for the active locale
* by fetching them from the asset folder of the build.
*
* See: https://ember-intl.github.io/ember-intl/docs/guide/asynchronously-loading-translations
*
* @property publicOnly
* @type {Boolean}
* @default "false"
*/
publicOnly: false,

/**
* A function that is called whenever any translation key, from any locale, is missing at build time.
*
* See https://ember-intl.github.io/ember-intl/docs/guide/missing-translations#requiring-translations
*
* @property requiresTranslation
* @type {Function}
* @default "function(key,locale) { return true }"
*/
requiresTranslation(/* key, locale */) {
return true;
},

/**
* Removes empty translations from the build output.
*
* @property stripEmptyTranslations
* @type {Boolean}
* @default "false"
*/
stripEmptyTranslations: false,

/**
* Add the subdirectories of the translations as a namespace for all keys.
*
* @property wrapTranslationsWithNamespace
* @type {Boolean}
* @default "false"
*/
wrapTranslationsWithNamespace: true,
};
};
12 changes: 10 additions & 2 deletions packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
"babel-plugin-ember-template-compilation": "^2.4.1",
"concurrently": "^9.1.2",
"ember-basic-dropdown": "^8.6.1",
"ember-intl": "^7.3.0",
"ember-source": "^6.4.0",
"ember-template-lint": "^7.0.2",
"ember-template-lint-plugin-prettier": "^5.0.0",
Expand All @@ -119,11 +120,15 @@
"webpack": "^5.97.1"
},
"peerDependencies": {
"ember-engines": ">= 0.11.0"
"ember-engines": ">= 0.11.0",
"ember-intl": "^7.3.0"
},
"peerDependenciesMeta": {
"ember-engines": {
"optional": true
},
"ember-intl": {
"optional": true
}
},
"ember": {
Expand Down Expand Up @@ -349,6 +354,7 @@
"./helpers/hds-format-relative.js": "./dist/_app_/helpers/hds-format-relative.js",
"./helpers/hds-link-to-models.js": "./dist/_app_/helpers/hds-link-to-models.js",
"./helpers/hds-link-to-query.js": "./dist/_app_/helpers/hds-link-to-query.js",
"./helpers/hds-t.js": "./dist/_app_/helpers/hds-t.js",
"./instance-initializers/load-sprite.js": "./dist/_app_/instance-initializers/load-sprite.js",
"./modifiers/hds-advanced-table-cell.js": "./dist/_app_/modifiers/hds-advanced-table-cell.js",
"./modifiers/hds-advanced-table-cell/dom-management.js": "./dist/_app_/modifiers/hds-advanced-table-cell/dom-management.js",
Expand All @@ -365,6 +371,7 @@
"./modifiers/hds-code-editor/types.js": "./dist/_app_/modifiers/hds-code-editor/types.js",
"./modifiers/hds-register-event.js": "./dist/_app_/modifiers/hds-register-event.js",
"./modifiers/hds-tooltip.js": "./dist/_app_/modifiers/hds-tooltip.js",
"./services/hds-intl.js": "./dist/_app_/services/hds-intl.js",
"./services/hds-time.js": "./dist/_app_/services/hds-time.js"
}
},
Expand All @@ -389,7 +396,8 @@
"files": [
"addon-main.cjs",
"declarations",
"dist"
"dist",
"translations"
],
"engines": {
"node": ">= 18"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@
{{on "click" this.onClick}}
aria-labelledby="{{this._prefixLabelId}} {{@labelId}}"
aria-expanded="{{this.isExpanded}}"
aria-description="Toggle the visibility of the related rows."
aria-description={{hds-t
"hds.components.advanced-table.th-button-expand.aria-description"
default="Toggle the visibility of the related rows."
}}
...attributes
>
{{! template-lint-enable no-unsupported-role-attributes}}
<span id={{this._prefixLabelId}} class="hds-advanced-table__th-button-aria-label-hidden-segment">Toggle</span>
<span id={{this._prefixLabelId}} class="hds-advanced-table__th-button-aria-label-hidden-segment">
{{hds-t "hds.components.common.toggle" default="Toggle"}}
</span>
<Hds::Icon @name={{this.icon}} />
</button>
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
aria-labelledby="{{this._prefixLabelId}} {{@labelId}} {{this._suffixLabelId}}"
...attributes
>
<span id={{this._prefixLabelId}} class="hds-advanced-table__th-button-aria-label-hidden-segment">Sort by</span>
<span id={{this._prefixLabelId}} class="hds-advanced-table__th-button-aria-label-hidden-segment">
{{hds-t "hds.components.common.sort-by" default="Sort by"}}
</span>
<span
id={{this._suffixLabelId}}
class="hds-advanced-table__th-button-aria-label-hidden-segment"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
aria-labelledby="{{this._prefixLabelId}} {{@labelId}}"
...attributes
>
<span id={{this._prefixLabelId}} class="hds-advanced-table__th-button-aria-label-hidden-segment">More information for</span>
<span id={{this._prefixLabelId}} class="hds-advanced-table__th-button-aria-label-hidden-segment">
{{hds-t "hds.components.common.tooltip-prefix" default="More information for"}}
</span>
<Hds::Icon @name="info" />
</button>
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
{{on "change" this.onSelectionChange}}
/>
{{#if this.isSortable}}
<span id={{this._labelId}} class="sr-only">selection state</span>
<Hds::AdvancedTable::ThButtonSort
@sortOrder={{@sortBySelectedOrder}}
@onClick={{@onClickSortBySelected}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,11 @@

<div class="hds-app-footer__copyright" ...attributes>
<Hds::Icon @name="hashicorp" />
<Hds::Text::Body @tag="span" @size="100">© {{this.year}} HashiCorp</Hds::Text::Body>
<Hds::Text::Body @tag="span" @size="100">
{{hds-t
"hds.components.app-footer.copyright.copyright-text"
default=(concat "© " this.year " HashiCorp")
year=this.year
}}
</Hds::Text::Body>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,20 @@

<Hds::AppFooter::Item>
<ul class="hds-app-footer__legal-links" aria-label={{this.ariaLabel}} ...attributes>
<Hds::AppFooter::Link @href={{this.hrefForSupport}}>Support</Hds::AppFooter::Link>
<Hds::AppFooter::Link @href={{this.hrefForTerms}}>Terms</Hds::AppFooter::Link>
<Hds::AppFooter::Link @href={{this.hrefForPrivacy}}>Privacy</Hds::AppFooter::Link>
<Hds::AppFooter::Link @href={{this.hrefForSecurity}}>Security</Hds::AppFooter::Link>
<Hds::AppFooter::Link @href={{this.hrefForAccessibility}}>Accessibility</Hds::AppFooter::Link>
<Hds::AppFooter::Link @href={{this.hrefForSupport}}>
{{hds-t "hds.components.app-footer.legal-links.support" default="Support"}}
</Hds::AppFooter::Link>
<Hds::AppFooter::Link @href={{this.hrefForTerms}}>
{{hds-t "hds.components.app-footer.legal-links.terms" default="Terms"}}
</Hds::AppFooter::Link>
<Hds::AppFooter::Link @href={{this.hrefForPrivacy}}>
{{hds-t "hds.components.app-footer.legal-links.privacy" default="Privacy"}}
</Hds::AppFooter::Link>
<Hds::AppFooter::Link @href={{this.hrefForSecurity}}>
{{hds-t "hds.components.app-footer.legal-links.security" default="Security"}}
</Hds::AppFooter::Link>
<Hds::AppFooter::Link @href={{this.hrefForAccessibility}}>
{{hds-t "hds.components.app-footer.legal-links.accessibility" default="Accessibility"}}
</Hds::AppFooter::Link>
</ul>
</Hds::AppFooter::Item>
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<Hds::Button
class="hds-app-header__menu-button"
@text="Menu"
@text={{hds-t "hds.components.common.menu" default="Menu"}}
@icon={{this.icon}}
@iconPosition="trailing"
{{on "click" this.onClick}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
{{focus-trap isActive=this.shouldTrapFocus}}
{{this._setUpBodyElement}}
>
<h2 class="sr-only" id="hds-app-side-nav-header">Application local navigation</h2>
<h2 class="sr-only" id="hds-app-side-nav-header">
{{hds-t "hds.components.app-side-nav.heading" default="Application local navigation"}}
</h2>

<div class="hds-app-side-nav__wrapper">
{{#if this.showToggleButton}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<div class="hds-application-state__header" ...attributes>
{{#if @errorCode}}
<Hds::Text::Body class="hds-application-state__error-code" @tag="div" @size="100" @weight="medium" @color="faint">
ERROR
{{hds-t "hds.components.common.error" default="Error"}}
{{@errorCode}}
</Hds::Text::Body>
{{/if}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
@color="secondary"
@size="small"
@icon={{this.state}}
@text="Toggle full screen view"
@text={{hds-t "hds.components.code-editor.full-screen-button.text" default="Toggle full screen view"}}
{{on "click" @onToggleFullScreen}}
...attributes
/>
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
{{#unless this._isSetupComplete}}
<div class="hds-code-editor__loader" aria-live="polite" role="status">
<Hds::Icon @name="loading" @size="24" />
<span class="sr-only">Loading</span>
<span class="sr-only">{{hds-t "hds.components.common.loading" default="Loading"}}</span>
</div>
{{/unless}}
</div>
17 changes: 11 additions & 6 deletions packages/components/src/components/hds/dismiss-button/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
*/

import Component from '@glimmer/component';
import { service } from '@ember/service';

import type HdsIntlService from '../../../services/hds-intl';

export interface HdsDismissButtonSignature {
Args: {
Expand All @@ -13,12 +16,14 @@ export interface HdsDismissButtonSignature {
}

export default class HdsDismissButton extends Component<HdsDismissButtonSignature> {
/**
* @param ariaLabel
* @type {string}
* @default 'Dismiss'
*/
@service hdsIntl!: HdsIntlService;

get ariaLabel(): string {
return this.args.ariaLabel ?? 'Dismiss';
return (
this.args.ariaLabel ??
this.hdsIntl.t('hds.components.dismiss-button.aria-label', {
default: 'Dismiss',
})
);
}
}
12 changes: 10 additions & 2 deletions packages/components/src/components/hds/form/indicator/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@
SPDX-License-Identifier: MPL-2.0
}}
{{#if @isOptional}}
<Hds::Text::Body class={{this.classNames}} tag="span" @size="100" @weight="regular">(Optional)</Hds::Text::Body>
<Hds::Text::Body class={{this.classNames}} tag="span" @size="100" @weight="regular">
({{hds-t "hds.components.form.common.optional_field_indicator" default="Optional"}})
</Hds::Text::Body>
{{/if}}
{{#if @isRequired}}
&nbsp;<Hds::Badge aria-hidden="true" class={{this.classNames}} @size="small" @color="neutral" @text="Required" />
&nbsp;<Hds::Badge
aria-hidden="true"
class={{this.classNames}}
@size="small"
@color="neutral"
@text={{hds-t "hds.components.form.common.required_field_indicator" default="Required"}}
/>
{{/if}}
Loading