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.
		
		
		
		
		
			
		
			
	
	
		
			80 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			TypeScript
		
	
		
		
			
		
	
	
			80 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			TypeScript
		
	
| 
											7 years ago
										 | import React from 'react'; | ||
|  | 
 | ||
|  | import { Localizer, RenderTextCallback } from '../types/Util'; | ||
|  | 
 | ||
|  | type FullJSX = Array<JSX.Element | string> | JSX.Element | string; | ||
|  | 
 | ||
|  | interface Props { | ||
|  |   /** The translation string id */ | ||
|  |   id: string; | ||
|  |   i18n: Localizer; | ||
|  |   components?: Array<FullJSX>; | ||
|  |   renderText?: RenderTextCallback; | ||
|  | } | ||
|  | 
 | ||
|  | export class Intl extends React.Component<Props> { | ||
|  |   public static defaultProps: Partial<Props> = { | ||
|  |     renderText: ({ text }) => text, | ||
|  |   }; | ||
|  | 
 | ||
|  |   public getComponent(index: number): FullJSX | null { | ||
|  |     const { id, components } = this.props; | ||
|  | 
 | ||
|  |     if (!components || !components.length || components.length <= index) { | ||
|  |       // tslint:disable-next-line no-console
 | ||
|  |       console.log( | ||
|  |         `Error: Intl missing provided components for id ${id}, index ${index}` | ||
|  |       ); | ||
|  | 
 | ||
|  |       return null; | ||
|  |     } | ||
|  | 
 | ||
|  |     return components[index]; | ||
|  |   } | ||
|  | 
 | ||
|  |   public render() { | ||
|  |     const { id, i18n, renderText } = this.props; | ||
|  | 
 | ||
|  |     const text = i18n(id); | ||
|  |     const results: Array<any> = []; | ||
|  |     const FIND_REPLACEMENTS = /\$[^$]+\$/g; | ||
|  | 
 | ||
|  |     // We have to do this, because renderText is not required in our Props object,
 | ||
|  |     //   but it is always provided via defaultProps.
 | ||
|  |     if (!renderText) { | ||
|  |       return; | ||
|  |     } | ||
|  | 
 | ||
|  |     let componentIndex = 0; | ||
|  |     let key = 0; | ||
|  |     let lastTextIndex = 0; | ||
|  |     let match = FIND_REPLACEMENTS.exec(text); | ||
|  | 
 | ||
|  |     if (!match) { | ||
|  |       return renderText({ text, key: 0 }); | ||
|  |     } | ||
|  | 
 | ||
|  |     while (match) { | ||
|  |       if (lastTextIndex < match.index) { | ||
|  |         const textWithNoReplacements = text.slice(lastTextIndex, match.index); | ||
|  |         results.push(renderText({ text: textWithNoReplacements, key: key })); | ||
|  |         key += 1; | ||
|  |       } | ||
|  | 
 | ||
|  |       results.push(this.getComponent(componentIndex)); | ||
|  |       componentIndex += 1; | ||
|  | 
 | ||
|  |       // @ts-ignore
 | ||
|  |       lastTextIndex = FIND_REPLACEMENTS.lastIndex; | ||
|  |       match = FIND_REPLACEMENTS.exec(text); | ||
|  |     } | ||
|  | 
 | ||
|  |     if (lastTextIndex < text.length) { | ||
|  |       results.push(renderText({ text: text.slice(lastTextIndex), key: key })); | ||
|  |       key += 1; | ||
|  |     } | ||
|  | 
 | ||
|  |     return results; | ||
|  |   } | ||
|  | } |