Add pluralization support to Translation component (#4441)

* Initial plan

* Add pluralization support to Translation component with comprehensive tests

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* Javascript formatting autofixes

* Update web/tests/translation.test.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update web/components/ui/Translation/Translation.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix: linter warning

* Simplify pluralization logic: use original key for plural, only _one for singular

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* feat(i18n): fix support for nested namespace string and key extraction

* chore: update extracted translations

* fix(i18n): fix linter warnings in extraction script

* Update web/scripts/i18n-extract.js

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* feat(i18n): sort translation keys

* fix(i18n): fix linter warnings

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: gabek <414923+gabek@users.noreply.github.com>
Co-authored-by: Owncast <owncast@owncast.online>
Co-authored-by: Gabe Kangas <gabek@real-ity.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Copilot
2025-07-13 17:34:06 -07:00
committed by GitHub
co-authored by gabek Copilot copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Owncast Gabe Kangas
parent 1fd86fa190
commit 59b905649e
9 changed files with 392 additions and 71 deletions
+88
View File
@@ -21,6 +21,15 @@ const meta: Meta<typeof Translation> = {
control: 'text',
description: 'CSS class name to apply to the component',
},
count: {
control: 'number',
description:
'Count for pluralization support (1 = singular with _one key, others = plural with original key)',
},
defaultText: {
control: 'text',
description: 'Default text to use when translation is missing',
},
},
};
@@ -95,3 +104,82 @@ export const TestDifferentLanguages: Story = {
},
},
};
export const PluralizationSingular: Story = {
args: {
translationKey: Localization.Testing.itemCount,
count: 1,
},
parameters: {
docs: {
description: {
story:
'Pluralization example with singular form (count = 1) - looks for _one key first, falls back to original key',
},
},
},
};
export const PluralizationPlural: Story = {
args: {
translationKey: Localization.Testing.itemCount,
count: 5,
},
parameters: {
docs: {
description: {
story: 'Pluralization example with plural form (count > 1) - uses original key directly',
},
},
},
};
export const PluralizationWithVariables: Story = {
args: {
translationKey: Localization.Testing.messageCount,
count: 3,
vars: {
sender: 'Alice',
},
},
parameters: {
docs: {
description: {
story: 'Pluralization with additional variables',
},
},
},
};
export const PluralizationFallback: Story = {
args: {
translationKey: Localization.Testing.noPluralKey,
count: 2,
},
parameters: {
docs: {
description: {
story:
'Pluralization fallback when no _one key exists (uses original key for both singular and plural)',
},
},
},
};
export const PluralizationWithDefaultText: Story = {
args: {
translationKey: 'non_existent_plural_key' as any,
count: 4,
defaultText: 'This is test number {{count}} for {{name}}',
vars: {
name: 'Bob',
},
},
parameters: {
docs: {
description: {
story: 'Pluralization with default text fallback',
},
},
},
};