Skip to content

Commit

Permalink
Add formatFullname(givenName, familyName, locale)
Browse files Browse the repository at this point in the history
  • Loading branch information
mvantellingen committed Oct 15, 2024
1 parent 13b1aa2 commit 65b6a85
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/wet-dots-rule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@labdigital/toolkit": minor
---

Add formatFullname(givenName, familyName, locale)
22 changes: 21 additions & 1 deletion src/i18n.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getLocalizedValue, parseLocale } from "./i18n";
import { formatFullname, getLocalizedValue, parseLocale } from "./i18n";
import { describe, expect, it } from "vitest";

describe("getLocalizedValue", () => {
Expand Down Expand Up @@ -80,3 +80,23 @@ describe("parseLocale", () => {
expect(result.subTag).toBe(expected.subTag);
});
});

describe("formatFullname", () => {
it.each([
// Test cases: [givenName, familyName, locale, expectedResult]
["John", "Doe", "en-US", "John Doe"],
["John", "Doe", "ja-JP", "Doe John"],
["John", "Doe", "zh-CN", "Doe John"],
["Jean", "Dupont", "fr-FR", "Jean Dupont"],
["Minh", "Nguyen", "vi-VN", "Nguyen Minh"],
["John", "Doe", undefined, "John Doe"],
["John", "Doe", "fr", "John Doe"],
["John", "Doe", "hu-HU", "Doe John"],
])(
"should format '%s %s' correctly for locale '%s'",
(givenName, familyName, locale, expected) => {
const result = formatFullname(givenName, familyName, locale);
expect(result).toBe(expected);
},
);
});
46 changes: 46 additions & 0 deletions src/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,49 @@ export const parseLocale = (
const [languageTag, subTag] = locale.split("-");
return { languageTag, subTag };
};

// Locales where family name comes first
const familyNameFirstLocales = [
"ja-JP", // Japan
"zh-CN", // Mainland China
"zh-TW", // Taiwan
"ko-KR", // Korea
"vi-VN", // Vietnam
"hu-HU", // Hungary
"mn-MN", // Mongolia
];

/**
* Formats a full name based on locale-specific conventions.
*
* Certain locales place the family name (last name) before the given name
* (first name), while others place the given name first. This function formats
* the full name accordingly.
*
* @param {string} givenName - The given (first) name of the person.
* @param {string} familyName - The family (last) name of the person.
* @param {string} locale - The locale to format the name in (e.g., 'en-US', 'ja-JP').
*
* @returns {string} The formatted full name according to the locale.
*
* @example
* // Returns "John Doe" for US locale
* formatFullname("John", "Doe", "en-US");
*
* @example
* // Returns "Doe John" for Japanese locale
* formatFullname("John", "Doe", "ja-JP");
*/
export const formatFullname = (
givenName: string,
familyName: string,
locale: string,
): string => {
// Check if the locale prefers family name first
if (familyNameFirstLocales.includes(locale)) {
return `${familyName} ${givenName}`;
}

// For other locales, given name comes first by default
return `${givenName} ${familyName}`;
};

0 comments on commit 65b6a85

Please sign in to comment.