tc39 / proposal-intl-displaynames-v2

Intl DisplayNames API V2
https://tc39.es/proposal-intl-displaynames-v2/
MIT License
23 stars 3 forks source link

support language names alignment for alphabet order #16

Closed hanguokai closed 3 years ago

hanguokai commented 4 years ago

There is a common use case that show a list of languages for users to select. I need to order all languages by their alphabet order.

Example 1 - alphabet order for the same language with different countries:

  1. English (Australia)
  2. English (India)
  3. English (United States)

Example 2 - not alphabet order(if for all languages not only English) and not the same way for the same language with different countries:

  1. Australian English
  2. English (India)
  3. US English

I hope Intl.DisplayNames can give us an option to force format output like example 1.

zbraniecki commented 3 years ago

I don't think DisplayNames should be involved in sorting. Alphabetical sorting should be covered by a separate API and include things like groupings (a..c, d...f, etc.).

hanguokai commented 3 years ago

Currently, for the same code, MS Edge output Example 1, and Google Chrome output Example 2. Why is the output inconsistent by different browser?

zbraniecki commented 3 years ago

I assume one sorts by display name, and another by locale identifier? I'm not sure, but that's in browser UI, and browser UIs often don't use ECMA-402 APIs.

hanguokai commented 3 years ago

I don't know what is "browser UI" you said.

let languageNames = new Intl.DisplayNames([], {type: 'language', style: 'short'});
console.log(languageNames.of('en-US'));

On Edge, output is English (United States). On Chrome, output is US English If the output is not uniform, how to sort it?

zbraniecki commented 3 years ago

If the output is not uniform, how to sort it?

I think sorting is not objectively decided here. The application author may want to sort by codes, or by display names. Sorting is handled by Intl.Collator. I don't think ICU/CLDR or any other intl API provides unified sorting for the locales. This may be even more complex in cases where you may want to have a nested with regions (CA, US, GB) for a single language (en), or locales (en-CA, fr-CA) for a single region (CA).

hanguokai commented 3 years ago

On Chrome

let languageNames = new Intl.DisplayNames([], {type: 'language', style: 'short'});
let langs = ['en-US', 'en-IN', 'fr-CA', 'fr-FR'];
let names = langs.map(l => languageNames.of(l)); // names is ["US English", "English (India)", "Canadian French", "French (France)"]
names.sort((a,b) => a.localeCompare(b)); // names is ["Canadian French", "English (India)", "French (France)", "US English"]

On Edge

let languageNames = new Intl.DisplayNames([], {type: 'language', style: 'short'});
let langs = ['en-US', 'en-IN', 'fr-CA', 'fr-FR'];
let names = langs.map(l => languageNames.of(l)); // name is ["English (United States)", "English (India)", "French (Canada)", "French (France)"]
names.sort((a,b) => a.localeCompare(b)); // name is ["English (India)", "English (United States)", "French (Canada)", "French (France)"]

Above is my use case. You can imagine a long list of languages. Note, I do not specify locales parameter in the constructor of Intl.DisplayNames. And I use string.localeCompare() to sort display names. Therefore, I don't know the user's current language, but I hope this code can display the best results for users with various languages. The user will be satisfied with the output of Edge, but the output of Chrome is very confusing.

This is my original intention to create this issue.

zbraniecki commented 3 years ago

And I use string.localeCompare() to sort display names.

This is your choice. You might instead use localeCompare to compare locale codes. It's up to the user to decide. There's no universal sorting for that.

hanguokai commented 3 years ago

If I first sort by locales, then get their display names. On Chrome, the result is ["English (India)", "US English", "Canadian French", "French (France)"]. This is also imperfect.

If there is a long list of languages, how can you quickly find out what you want?

There's no universal sorting for that.

Hope there will be a perfect solution in the future.

zbraniecki commented 3 years ago

If there is a long list of languages, how can you quickly find out what you want?

Language pickers are notoriously hard to build. The recommendation is to always include a search box that filters for matching locale code, language name both in English and in local language.

Sorting is similarly complicated, as the list gets long. Often clustering and nesting per continent, country or language helps. But searchbox for filtering is the most common solution to navigation.

hax commented 3 years ago

As I understand, it seems not an order issue, but an issue of:

What is short style (or narrow style) mean? It seems diff vendors give a very different style. But people may expect a more stable and consistent output format. Especially consider the common use cases of listing of languages, "Languages (Region)" format is much friendly for fast reading and selecting. So, could we specify short style or narrow style should follow this specific format ? Or could we add a new style (don't know what the style name could be, "human-friendly" ? ) for that?

zbraniecki commented 3 years ago

People should never expect consistent output out of intl APIs. Not just between vendors but between versions, platforms, and user customizations, the output may be different.

FrankYFTang commented 3 years ago

I believe what this issue asked is the same as #13 Close it and consider it as a dup.

hax commented 3 years ago

Thank you @FrankYFTang .

If I understand correctly , now the spec support new Intl.DisplayNames("en", {type: "language", dialectHandling: "standardName"}) to force format output like example 1 in the issue which @hanguokai raised. Am I correct?

FrankYFTang commented 3 years ago

Thank you @FrankYFTang .

If I understand correctly , now the spec support new Intl.DisplayNames("en", {type: "language", dialectHandling: "standardName"}) to force format output like example 1 in the issue which @hanguokai raised. Am I correct?

Yes, if the proposal got approved into Stage 3 and implemented, that will be the case.

hanguokai commented 3 years ago

From V8 release v9.5, Chrome 95 will support languageDisplay option, which value could be either “standard” or “dialect”. In my test, languageDisplay: 'standard' can solve the problem.

let languageNames = new Intl.DisplayNames([], {type: 'language', style: 'short', languageDisplay: 'standard'});

When use "standard", all language names output with "LanguageName (LocaleName)" format.