mirror of
https://github.com/Snigdha-OS/documentation.git
synced 2025-09-13 20:14:56 +02:00
93 lines
3.4 KiB
JavaScript
93 lines
3.4 KiB
JavaScript
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
import { useMemo } from 'react';
|
|
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
|
// We want to ensurer a stable plural form order in all cases
|
|
// It is more convenient and natural to handle "small values" first
|
|
// See https://twitter.com/sebastienlorber/status/1366820663261077510
|
|
const OrderedPluralForms = [
|
|
'zero',
|
|
'one',
|
|
'two',
|
|
'few',
|
|
'many',
|
|
'other',
|
|
];
|
|
function sortPluralForms(pluralForms) {
|
|
return OrderedPluralForms.filter((pf) => pluralForms.includes(pf));
|
|
}
|
|
// Hardcoded english/fallback implementation
|
|
const EnglishPluralForms = {
|
|
locale: 'en',
|
|
pluralForms: sortPluralForms(['one', 'other']),
|
|
select: (count) => (count === 1 ? 'one' : 'other'),
|
|
};
|
|
function createLocalePluralForms(locale) {
|
|
const pluralRules = new Intl.PluralRules(locale);
|
|
return {
|
|
locale,
|
|
pluralForms: sortPluralForms(pluralRules.resolvedOptions().pluralCategories),
|
|
select: (count) => pluralRules.select(count),
|
|
};
|
|
}
|
|
/**
|
|
* Poor man's `PluralSelector` implementation, using an English fallback. We
|
|
* want a lightweight, future-proof and good-enough solution. We don't want a
|
|
* perfect and heavy solution.
|
|
*
|
|
* Docusaurus classic theme has only 2 deeply nested labels requiring complex
|
|
* plural rules. We don't want to use `Intl` + `PluralRules` polyfills + full
|
|
* ICU syntax (react-intl) just for that.
|
|
*
|
|
* Notes:
|
|
* - 2021: 92+% Browsers support `Intl.PluralRules`, and support will increase
|
|
* in the future
|
|
* - NodeJS >= 13 has full ICU support by default
|
|
* - In case of "mismatch" between SSR and Browser ICU support, React keeps
|
|
* working!
|
|
*/
|
|
function useLocalePluralForms() {
|
|
const { i18n: { currentLocale }, } = useDocusaurusContext();
|
|
return useMemo(() => {
|
|
try {
|
|
return createLocalePluralForms(currentLocale);
|
|
}
|
|
catch (err) {
|
|
console.error(`Failed to use Intl.PluralRules for locale "${currentLocale}".
|
|
Docusaurus will fallback to the default (English) implementation.
|
|
Error: ${err.message}
|
|
`);
|
|
return EnglishPluralForms;
|
|
}
|
|
}, [currentLocale]);
|
|
}
|
|
function selectPluralMessage(pluralMessages, count, localePluralForms) {
|
|
const separator = '|';
|
|
const parts = pluralMessages.split(separator);
|
|
if (parts.length === 1) {
|
|
return parts[0];
|
|
}
|
|
if (parts.length > localePluralForms.pluralForms.length) {
|
|
console.error(`For locale=${localePluralForms.locale}, a maximum of ${localePluralForms.pluralForms.length} plural forms are expected (${localePluralForms.pluralForms.join(',')}), but the message contains ${parts.length}: ${pluralMessages}`);
|
|
}
|
|
const pluralForm = localePluralForms.select(count);
|
|
const pluralFormIndex = localePluralForms.pluralForms.indexOf(pluralForm);
|
|
// In case of not enough plural form messages, we take the last one (other)
|
|
// instead of returning undefined
|
|
return parts[Math.min(pluralFormIndex, parts.length - 1)];
|
|
}
|
|
/**
|
|
* Reads the current locale and returns an interface very similar to
|
|
* `Intl.PluralRules`.
|
|
*/
|
|
export function usePluralForm() {
|
|
const localePluralForm = useLocalePluralForms();
|
|
return {
|
|
selectMessage: (count, pluralMessages) => selectPluralMessage(pluralMessages, count, localePluralForm),
|
|
};
|
|
}
|
|
//# sourceMappingURL=usePluralForm.js.map
|