Translations

Translations

Within the @42.nl/ui we support translating every text that the library renders. By default however every text has a fallback text which is in english. This way there is always a text for the user to see.

There are two ways to translate or override these default text.

Overriding

All components provide a text property containing all text which the component renders. For example:

<Pager
  page={page}
  onChange={action('page changed')}
  text=
/>

Here we use the text property to override the next and previous text on the Pager component. When you override a text it should be translated already.

Translating

Another option would be to provide your own translator function. All texts are by default translated before they are rendered, by default the fallback language is rendered.

Here is an example on how to configure the translator:

import { setTranslator } from '@42.nl/ui';

/**
 * Translation provider is given a key and data and is expected
 * to return a translated string.
 */
setTranslator(({ key, data }) => {
  /*
    All translations are given a `key` which is a string, and
    data which is an object containing extra keys.

    The data object will often contain things like the label for
    an error message, or an amount of things.
  */

  return // translated string here...
});

Here is a JSON notation containing all keys and default translations:

{
  "AsyncContent": {
    "LOADING": {
      "TITLE": "Loading..."
    },
    "ERROR": {
      "TITLE": "Oops something went wrong!",
      "RETRY": "Retry"
    },
    "EMPTY": {
      "TITLE": "No results found"
    }
  },
  "ConfirmButton": {
    "MODAL_HEADER": "Confirmation",
    "CANCEL": "Cancel",
    "CONFIRM": "Confirm"
  },
  "MoreOrLess": {
    "LESS": "Show less",
    "MORE": "Show  more"
  },
  "DateTimeInput": {
    "DATE_AFTER_ERROR": "The  must be after the ",
    "DATE_BEFORE_ERROR": "The  must be before the ",
    "DATE_BETWEEN_ERROR": "The  must be between the  and ",
    "INVALID_DATE": "The  must match required format "
  },
  "ImageUpload": {
    "CHANGE": "Change",
    "REMOVE": "Remove",
    "CANCEL": "Cancel",
    "DONE": "Done",
    "REQUIRED": " is required",
    "SIZE_TOO_LARGE": " image is to large. Max size is  MB image size is  MB"
  },
  "EmptyModal": {
    "NO_RESULTS": {
      "TITLE": "No results",
      "SUBTITLE": "No results were found please try again with a different query."
    },
    "EMPTY": {
      "TITLE": "No results",
      "SUBTITLE": "There is nothing here yet, the collection is empty."
    }
  },
  "ModalPicker": {
    "SEARCH": "Search...",
    "SEARCH_LABEL": "Start typing to search",
    "CANCEL": "Cancel",
    "SELECT": "Select"
  },
  "ModalPickerOpener": {
    "CLEAR": "Clear"
  },
  "Select": {
    "LOADING": "Loading..."
  },
  "FileInput": {
    "REQUIRED": " is required",
    "SIZE_TOO_LARGE": " file is to large. Max size is  MB file size is  MB"
  },
  "JarbFinalForm": {
    "VALIDATION": {
      "REQUIRED": " is required",
      "MINIMUM_LENGTH": " must be bigger than  characters",
      "MAXIMUM_LENGTH": " must be smaller than  characters",
      "MIN_VALUE": " must be more than ",
      "MAX_VALUE": " must be less than ",
      "NUMBER": " is not a number",
      "NUMBER_FRACTION": " is not a number. Number may have  digits behind the comma"
    }
  },
  "FormError": {
    "UNKNOWN_ERROR": "Something is wrong"
  },
  "Pager": {
    "NEXT": "Next",
    "PREVIOUS": "Previous"
  },
  "EpicTable": {
    "EpicDetail": {
      "CLOSE": "Close"
    }
  },
  "IconPicker": {
    "CLEAR": "Clear",
    "NO_RESULTS": {
      "TITLE": "No icons found",
      "SUBTITLE": "No icons were found, please try again with a different query."
    },
    "SEARCH_INPUT_LABEL": "Start typing to search an icon",
    "SEARCH": "Search..."
  },
  "ColorPicker": {
    "CLEAR": "Clear",
    "CANCEL": "Cancel",
    "SELECT": "Select"
  },
  "Loading": {
    "LOADING": "Loading..."
  },
  "RadioGroup": {
    "LOADING": "Loading...",
    "CLEAR": "Clear"
  },
  "OpenCloseModal": {
    "CANCEL": "Cancel",
    "SAVE": "Save"
  },
  "DateTimeModal": {
    "SELECT": "Select"
  },
  "NewPasswordInput": {
    "NOT_STRONG_ENOUGH": "Password does not follow rules"
  },
  "PasswordStrength": {
    "LOWERCASE": "Must contain at least one lowercase letter",
    "UPPERCASE": "Must contain at least one lowercase letter",
    "NUMBER": "Must contain at least one number",
    "SPECIAL_CHAR": "Must contain at least one special character ()",
    "MINIMUM_LENGTH": "Must contain at least  characters",
    "NO_SPACE": "Must not contain any space",
    "PROGRESS": "Percentage of rules the password matches"
  },
  "withJarb": {
    "REQUIRED_MARK": " *"
  },
  "ModalPickerMultiple": {
    "NO_OPTION_SELECTED": "No option selected"
  },
  "OrSeparator": {
    "OR": "OR"
  },
  "TypeaheadSingle": {
    "PAGINATION_TEXT": "Display additional results..."
  },
  "TypeaheadMultiple": {
    "PAGINATION_TEXT": "Display additional results..."
  },
  "ErrorBoundary": {
    "ERROR": {
      "TITLE": "Oops something went wrong!"
    }
  },
  "CopyToClipboard": {
    "COPIED": "Copied!"
  },
  "CrudTable": {
    "SEARCH_LABEL": "Start typing to search"
  },
  "Pagination": {
    "PAGE_SIZE_DROPDOWN_LABEL": "Select page size",
    "PAGE_SIZE": " items per page",
    "TOTAL_ELEMENTS": " records found"
  }
}

The JSON is nested to make it more readable. But a key you might be given is Pager.NEXT or JarbFinalForm.VALIDATION.REQUIRED.