@sap-ux/ui-components
Version:
SAP UI Components Library
163 lines • 6.56 kB
JavaScript
import React, { useCallback } from 'react';
import { UITextInput } from '../UIInput/index.js';
import { UiIcons } from '../Icons.js';
import { UITranslationButton } from './UITranslationButton.js';
import { TranslationKeyGenerator, SuggestValueType } from './UITranslationButton.types.js';
import { extractI18nKey, generateI18nKey, applyI18nPattern, getTranslationByKey, getTranslationByText } from './UITranslationUtils.js';
import { defaultTranslationInputStrings } from './defaults.js';
import { UIFormattedText, formatText } from './UIFormattedText.js';
/**
* Method returns suggestion object with message and tooltip based on passed translation button props.
*
* @param props Properties of translation input component.
* @returns Translation suggestion object.
*/
const getTranslationSuggestion = (props) => {
const { value = '', allowedPatterns, entries, strings = defaultTranslationInputStrings, namingConvention = TranslationKeyGenerator.CamelCase, defaultPattern, i18nPrefix, allowedI18nPrefixes } = props;
const i18nKey = extractI18nKey(value, allowedPatterns, allowedI18nPrefixes || [i18nPrefix]);
let message = '';
let tooltip = '';
let suggest;
if (i18nKey) {
// There is already i18n binding as value
const entry = getTranslationByKey(entries, i18nKey);
if (entry) {
tooltip = strings.i18nEntryExistsTooltip;
suggest = {
entry,
type: SuggestValueType.Existing,
icon: UiIcons.WorldArrow
};
}
else {
message = strings.i18nKeyMissingDescription;
tooltip = strings.i18nKeyMissingTooltip;
suggest = {
entry: {
key: {
value: i18nKey
},
value: {
value: i18nKey
}
},
type: SuggestValueType.New,
icon: UiIcons.WorldWarning
};
}
}
else {
// Use generation format passed from outside or use default as 'Standard';
const existingEntry = getTranslationByText(entries, value);
if (existingEntry) {
message = strings.i18nReplaceWithExistingDescription;
tooltip = strings.i18nReplaceWithExistingTooltip;
suggest = {
entry: existingEntry,
type: SuggestValueType.Update
};
}
else {
message = strings.i18nValueMissingDescription;
tooltip = strings.i18nValueMissingTooltip;
const key = generateI18nKey(value, namingConvention, entries);
suggest = {
entry: {
key: {
value: key
},
value: {
value
}
},
type: SuggestValueType.New
};
}
}
// I18n string to apply for input value
suggest.i18n = applyI18nPattern(suggest.entry.key.value, defaultPattern, i18nPrefix);
// Format message to show in callout
const messageValues = {
key: suggest.entry.key.value,
value: suggest.entry.value.value,
i18n: suggest.i18n
};
tooltip = formatText(tooltip, messageValues);
return {
message: (React.createElement(UIFormattedText, { values: messageValues, className: "ui-translatable__message__text" }, message)),
tooltip,
suggest
};
};
/**
* Generates the CSS class names for the translation input component.
*
* @param props - Component props containing styling options.
* @returns A string containing the computed class names.
*/
const getClassNames = (props) => {
const { className, invertedCalloutTheme } = props;
let classNames = ' ui-translatable__input';
// Custom external classes
if (className) {
classNames += ` ${className}`;
}
if (invertedCalloutTheme) {
classNames += ` ui-translatable--inverted`;
}
return classNames;
};
/**
* Component to render translation input with button to provide helper callout with i18n generation option.
*
* @param props Component properties.
* @returns Component to render translation input.
*/
export const UITranslationInput = (props) => {
const { id, onChange, value, allowedPatterns, defaultPattern, entries, busy, i18nPrefix, allowedI18nPrefixes, namingConvention, onCreateNewEntry, onShowExistingEntry, disabled, strings, invertedCalloutTheme } = props;
const suggestion = getTranslationSuggestion(props);
const classNames = getClassNames(props);
const onUpdateValue = useCallback((newValue) => {
onChange?.({}, newValue);
}, [onChange]);
// Generate DOM id for i18n button
let buttonId = `${id}-i18n`;
let title = props.title;
if (suggestion.suggest?.type === SuggestValueType.Existing && strings?.i18nEntryExistsInputTooltip) {
// Change DOM id with additional suffix
buttonId += '-navigate';
if (!title) {
title = formatText(strings.i18nEntryExistsInputTooltip, {
value: value || '',
translation: suggestion.suggest.entry.value.value
});
}
}
const onRenderSuffix = useCallback(() => {
return (React.createElement(UITranslationButton, { id: buttonId, value: value, busy: busy, onCreateNewEntry: onCreateNewEntry, onShowExistingEntry: onShowExistingEntry, onUpdateValue: onUpdateValue, disabled: disabled, strings: strings, suggestion: suggestion, invertedCalloutTheme: invertedCalloutTheme }));
}, [
value,
allowedPatterns,
defaultPattern,
entries,
busy,
disabled,
i18nPrefix,
allowedI18nPrefixes,
namingConvention,
onCreateNewEntry,
onShowExistingEntry,
onUpdateValue
]);
const onRenderInput = useCallback((props, defaultRender) => {
if (defaultRender) {
return (React.createElement("div", { className: "ui-translatable__field", title: title }, defaultRender({ ...props, title: undefined })));
}
return null;
}, [title]);
return (React.createElement(UITextInput, { ...props, onRenderSuffix: value?.trim() ? onRenderSuffix : undefined, className: classNames, onRenderInput: onRenderInput }));
};
UITranslationInput.defaultProps = {
strings: defaultTranslationInputStrings
};
//# sourceMappingURL=UITranslationInput.js.map