You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
session-desktop/ts/components/basic/Localizer.tsx

63 lines
2.4 KiB
TypeScript

import styled from 'styled-components';
import { SessionHtmlRenderer } from './SessionHTMLRenderer';
import {
GetMessageArgs,
LocalizerComponentProps,
MergedLocalizerTokens,
sanitizeArgs,
} from '../../localization/localeTools';
import { getCrowdinLocale } from '../../util/i18n/shared';
/** An array of supported html tags to render if found in a string */
export const supportedFormattingTags = ['b', 'i', 'u', 's', 'br', 'span'];
/** NOTE: self-closing tags must also be listed in {@link supportedFormattingTags} */
const supportedSelfClosingFormattingTags = ['br'];
function createSupportedFormattingTagsRegex() {
return new RegExp(
`<(?:${supportedFormattingTags.join('|')})>.*?</(?:${supportedFormattingTags.join('|')})>|<(?:${supportedSelfClosingFormattingTags.join('|')})\\/>`,
'g'
);
}
const StyledHtmlRenderer = styled.span`
* > span {
color: var(--renderer-span-primary-color);
}
`;
/**
* Retrieve a localized message string, substituting dynamic parts where necessary and formatting it as HTML if necessary.
*
* @param props.token - The token identifying the message to retrieve and an optional record of substitution variables and their replacement values.
* @param props.args - An optional record of substitution variables and their replacement values. This is required if the string has dynamic parts.
* @param props.as - An optional HTML tag to render the component as. Defaults to a fragment, unless the string contains html tags. In that case, it will render as HTML in a div tag.
*
* @returns The localized message string with substitutions and formatting applied.
*/
export const Localizer = <T extends MergedLocalizerTokens>(props: LocalizerComponentProps<T>) => {
const args = 'args' in props ? props.args : undefined;
const rawString = window.i18n.getRawMessage<T>(
getCrowdinLocale(),
...([props.token, args] as GetMessageArgs<T>)
);
const containsFormattingTags = createSupportedFormattingTagsRegex().test(rawString);
const cleanArgs = args && containsFormattingTags ? sanitizeArgs(args) : args;
const i18nString = window.i18n.formatMessageWithArgs(
rawString,
cleanArgs as GetMessageArgs<T>[1]
);
return containsFormattingTags ? (
/** If the string contains a relevant formatting tag, render it as HTML */
<StyledHtmlRenderer>
<SessionHtmlRenderer tag={props.asTag} html={i18nString} className={props.className} />
</StyledHtmlRenderer>
) : (
i18nString
);
};