@transifex/react
Version:
i18n React framework using Transifex Native
260 lines (246 loc) • 7.27 kB
JavaScript
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var React = require('react');
var React__default = _interopDefault(React);
var native = require('@transifex/native');
var PropTypes = _interopDefault(require('prop-types'));
const TXNativeContext = /*#__PURE__*/React.createContext({
instance: null
});
function useLanguages(txInstance) {
const context = React.useContext(TXNativeContext);
const instance = txInstance || context.instance || native.tx;
const [languages, setLanguages] = React.useState([]);
React.useEffect(() => {
const fetch = function () {
try {
return Promise.resolve(instance.getLanguages()).then(function (_instance$getLanguage) {
setLanguages(_instance$getLanguage);
});
} catch (e) {
return Promise.reject(e);
}
};
fetch();
}, [instance]);
return languages;
}
function useLocale(txInstance) {
const context = React.useContext(TXNativeContext);
const instance = txInstance || context.instance || native.tx;
const [locale, setLocale] = React.useState(instance.getCurrentLocale());
React.useEffect(() => {
function cb(_, caller) {
if (caller === instance) {
setLocale(instance.getCurrentLocale());
}
}
native.onEvent(native.LOCALE_CHANGED, cb);
return () => {
native.offEvent(native.LOCALE_CHANGED, cb);
};
}, [instance]);
return locale;
}
function translateWithElements(_str, props, tx) {
let _t = native.t;
if (tx) {
if (tx.instance && tx.instance.t) {
_t = tx.instance.t;
} else if (tx.t) {
_t = tx.t;
}
}
const actualProps = {};
const reactElements = [];
if (props) {
Object.entries(props).forEach(([key, value]) => {
if (/*#__PURE__*/React__default.isValidElement(value)) {
actualProps[key] = `__txnative__${reactElements.length}__txnative__`;
reactElements.push(value);
} else {
actualProps[key] = value;
}
});
}
const translation = _t(_str, actualProps);
const result = [];
let lastEnd = 0;
let lastKey = 0;
const regexp = RegExp('__txnative__(\\d+)__txnative__', 'g');
let match = regexp.exec(translation);
while (match !== null) {
const chunk = translation.slice(lastEnd, match.index);
if (chunk) {
result.push(/*#__PURE__*/React__default.createElement(React.Fragment, {
key: lastKey
}, chunk));
lastKey += 1;
}
result.push(/*#__PURE__*/React__default.cloneElement(reactElements[parseInt(match[1], 10)], {
key: lastKey
}));
lastKey += 1;
lastEnd = match.index + match[0].length;
match = regexp.exec(translation);
}
const chunk = translation.slice(lastEnd);
if (chunk) {
result.push(/*#__PURE__*/React__default.createElement(React.Fragment, {
key: lastKey
}, chunk));
}
if (result.length === 0) {
return '';
}
if (result.length === 1) {
return result[0].props.children;
}
return /*#__PURE__*/React__default.createElement(React.Fragment, null, result);
}
function useT(txInstance) {
const context = React.useContext(TXNativeContext);
const instance = txInstance || context.instance || native.tx;
const [counter, setCounter] = React.useState(0);
React.useEffect(() => {
function rerender(_, caller) {
if (instance === caller) {
setCounter(c => c + 1);
}
}
native.onEvent(native.LOCALE_CHANGED, rerender);
native.onEvent(native.TRANSLATIONS_FETCHED, rerender);
return () => {
native.offEvent(native.LOCALE_CHANGED, rerender);
native.offEvent(native.TRANSLATIONS_FETCHED, rerender);
};
}, [setCounter, instance]);
return React.useCallback((_str, props) => translateWithElements(_str, props, instance), [instance, counter]);
}
function useTX() {
const context = React.useContext(TXNativeContext);
return context.instance || native.tx;
}
function useTranslations(filterTags, txInstance) {
const context = React.useContext(TXNativeContext);
const instance = txInstance || context.instance || native.tx;
const [ready, setReady] = React.useState((instance.fetchedTags[instance.currentLocale] || []).indexOf(filterTags) !== -1);
React.useEffect(() => {
function setReadyToFalse({
filterTags: eventFilterTags
}, caller) {
if (caller !== instance) return;
if (eventFilterTags === filterTags) {
setReady(false);
}
}
const fetchTranslations = function () {
try {
function _temp2() {
setReady(true);
}
const _temp = function () {
if (instance.currentLocale) {
return Promise.resolve(instance.fetchTranslations(instance.currentLocale, {
filterTags
})).then(function () {});
}
}();
return Promise.resolve(_temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp));
} catch (e) {
return Promise.reject(e);
}
};
native.onEvent(native.FETCHING_TRANSLATIONS, setReadyToFalse);
function setReadyToTrue({
filterTags: eventFilterTags
}, caller) {
if (caller !== instance) return;
if (eventFilterTags === filterTags) {
setReady(true);
}
}
native.onEvent(native.TRANSLATIONS_FETCHED, setReadyToTrue);
fetchTranslations();
native.onEvent(native.LOCALE_CHANGED, fetchTranslations);
return () => {
native.offEvent(native.FETCHING_TRANSLATIONS, setReadyToFalse);
native.offEvent(native.TRANSLATIONS_FETCHED, setReadyToTrue);
native.offEvent(native.LOCALE_CHANGED, fetchTranslations);
};
}, [filterTags, instance]);
return {
ready
};
}
function LanguagePicker({
className = ''
}) {
const languages = useLanguages();
const locale = useLocale();
const tx = useTX();
return /*#__PURE__*/React__default.createElement("select", {
className: className,
value: locale,
onChange: e => tx.setCurrentLocale(e.target.value)
}, languages.map(({
name,
code
}) => /*#__PURE__*/React__default.createElement("option", {
key: code,
value: code
}, name)));
}
LanguagePicker.propTypes = {
className: PropTypes.string
};
function T({
_str,
...props
}) {
return useT()(_str, props);
}
T.propTypes = {
_str: PropTypes.string.isRequired
};
function UT({
_str,
_inline = false,
...props
}) {
const translation = useT()(_str, {
_inline,
_escapeVars: true,
...props
});
const parentProps = {
dangerouslySetInnerHTML: {
__html: translation
}
};
const parent = _inline ? 'span' : 'div';
return /*#__PURE__*/React__default.createElement(parent, parentProps);
}
UT.propTypes = {
_str: PropTypes.string.isRequired,
_inline: PropTypes.bool
};
function TXProvider({
instance,
children
}) {
return /*#__PURE__*/React__default.createElement(TXNativeContext.Provider, {
value: {
instance
}
}, children);
}
exports.LanguagePicker = LanguagePicker;
exports.T = T;
exports.TXProvider = TXProvider;
exports.UT = UT;
exports.useLanguages = useLanguages;
exports.useLocale = useLocale;
exports.useT = useT;
exports.useTX = useTX;
exports.useTranslations = useTranslations;
//# sourceMappingURL=index.js.map