Skip to content

Commit a9f6c7f

Browse files
committed
feat(@clayui/language-picker): LPD-45714 Add different labels to indicate the translation
1 parent 847228e commit a9f6c7f

File tree

3 files changed

+88
-27
lines changed

3 files changed

+88
-27
lines changed

packages/clay-language-picker/src/__tests__/index.tsx

+30-2
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ describe('ClayLanguagePicker', () => {
9292
labels={{
9393
default: 'Default Label',
9494
translated: 'Translated Label',
95+
translating: 'Translating Label',
9596
trigger: 'Trigger Label',
9697
untranslated: 'Untranslated Label',
9798
}}
@@ -127,8 +128,8 @@ describe('ClayLanguagePicker', () => {
127128
selectedLocale={locales[0]!}
128129
spritemap="/path/to/svg"
129130
translations={{
130-
'en-US': 'Apple',
131-
'es-ES': 'Manzana',
131+
'es-ES': {total: 4, translated: 2},
132+
'fr-FR': {total: 4, translated: 4},
132133
}}
133134
/>
134135
);
@@ -150,6 +151,33 @@ describe('ClayLanguagePicker', () => {
150151
expect(container).toMatchSnapshot();
151152
});
152153

154+
it('renders different labels for translations', () => {
155+
render(
156+
<ClayLanguagePicker
157+
locales={locales}
158+
onSelectedLocaleChange={onSelectedLocaleChange}
159+
selectedLocale={locales[0]!}
160+
spritemap="/path/to/svg"
161+
translations={{
162+
'es-ES': {total: 4, translated: 2},
163+
'fr-FR': {total: 4, translated: 4},
164+
}}
165+
/>
166+
);
167+
168+
fireEvent.click(screen.getByRole('combobox'));
169+
170+
const esOption = screen.getByRole('option', {name: /es-ES/});
171+
const enOption = screen.getByRole('option', {name: /en-US/});
172+
const frOption = screen.getByRole('option', {name: /fr-FR/});
173+
const nlOption = screen.getByRole('option', {name: /nl-NL/});
174+
175+
expect(enOption).toHaveTextContent('Default');
176+
expect(esOption).toHaveTextContent('Translating 2/4');
177+
expect(frOption).toHaveTextContent('Translated');
178+
expect(nlOption).toHaveTextContent('Untranslated');
179+
});
180+
153181
it('calls onSelectedLocaleChange when a language is selected', () => {
154182
render(
155183
<ClayLanguagePicker

packages/clay-language-picker/src/index.tsx

+56-23
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,27 @@ import {InternalDispatch, sub} from '@clayui/shared';
1212
import classNames from 'classnames';
1313
import React from 'react';
1414

15+
type DisplayType = 'info' | 'secondary' | 'success' | 'warning';
16+
1517
type Item = {
1618
href?: string;
1719
id: string;
1820
label: string;
1921
symbol: string;
2022
};
2123

24+
type Labels = {
25+
default: string;
26+
trigger: string;
27+
translated: string;
28+
translating: string;
29+
untranslated: string;
30+
};
31+
32+
type Translation = {total: number; translated: number};
33+
2234
type Translations = {
23-
[key: string]: string;
35+
[key: string]: Translation;
2436
};
2537

2638
type Props = {
@@ -49,12 +61,7 @@ type Props = {
4961
/**
5062
* Labels for the component
5163
*/
52-
labels?: {
53-
default: string;
54-
trigger: string;
55-
translated: string;
56-
untranslated: string;
57-
};
64+
labels?: Labels;
5865

5966
/**
6067
* List of locales to allow localization for
@@ -93,6 +100,40 @@ type Props = {
93100
translations?: Translations;
94101
};
95102

103+
const TranslationLabel = ({
104+
defaultLanguage,
105+
labels,
106+
locale,
107+
translation,
108+
}: {
109+
defaultLanguage: Item;
110+
labels: Labels;
111+
locale: Item;
112+
translation: Translation;
113+
}) => {
114+
let displayType: DisplayType = 'warning';
115+
let label = labels.untranslated;
116+
117+
if (locale.label === defaultLanguage?.label) {
118+
displayType = 'info';
119+
label = labels.default;
120+
} else if (translation) {
121+
const {total, translated} = translation;
122+
123+
if (total && total === translated) {
124+
displayType = 'success';
125+
label = labels.translated;
126+
} else {
127+
displayType = 'secondary';
128+
label = sub(labels.translating, [translated, total]);
129+
}
130+
}
131+
132+
return <ClayLabel displayType={displayType}>{label}</ClayLabel>;
133+
};
134+
135+
TranslationLabel.displayName = 'Label';
136+
96137
const Trigger = React.forwardRef<HTMLButtonElement>(
97138
(
98139
{
@@ -144,6 +185,7 @@ const ClayLanguagePicker = ({
144185
labels = {
145186
default: 'Default',
146187
translated: 'Translated',
188+
translating: 'Translating {0}/{1}',
147189
trigger: 'Select a language, current language: {0}.',
148190
untranslated: 'Untranslated',
149191
},
@@ -201,23 +243,14 @@ const ClayLanguagePicker = ({
201243
{hasTranslations ? (
202244
<ClayLayout.ContentCol containerElement="span">
203245
<ClayLayout.ContentSection>
204-
<ClayLabel
205-
displayType={
206-
locale.label ===
207-
defaultLanguage?.label
208-
? 'info'
209-
: translations[locale.label]
210-
? 'success'
211-
: 'warning'
246+
<TranslationLabel
247+
defaultLanguage={defaultLanguage!}
248+
labels={labels}
249+
locale={locale}
250+
translation={
251+
translations[locale.label]!
212252
}
213-
>
214-
{locale.label ===
215-
defaultLanguage?.label
216-
? labels.default
217-
: translations[locale.label]
218-
? labels.translated
219-
: labels.untranslated}
220-
</ClayLabel>
253+
/>
221254
</ClayLayout.ContentSection>
222255
</ClayLayout.ContentCol>
223256
) : null}

packages/clay-language-picker/stories/LanguagePicker.stories.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ Default.args = {
6868
export const LanguagePickerWithTranslations = (args: any) => {
6969
const [selectedLocale, setSelectedLocale] = useState<any>(locales[0]);
7070
const translations = {
71-
'en-US': 'Apple',
72-
'es-ES': 'Manzana',
71+
'ca-ES': {total: 4, translated: 2},
72+
'nl-NL': {total: 4, translated: 4},
7373
};
7474

7575
return (

0 commit comments

Comments
 (0)