forked from MapComplete/MapComplete
		
	Themes: add currency type which does some reformatting
This commit is contained in:
		
							parent
							
								
									c8eef2c8f6
								
							
						
					
					
						commit
						d40474d47e
					
				
					 2 changed files with 76 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -28,6 +28,7 @@ import TagValidator from "./Validators/TagValidator"
 | 
			
		|||
import IdValidator from "./Validators/IdValidator"
 | 
			
		||||
import SlopeValidator from "./Validators/SlopeValidator"
 | 
			
		||||
import VeloparkValidator from "./Validators/VeloparkValidator"
 | 
			
		||||
import CurrencyValidator from "./Validators/CurrencyValidator"
 | 
			
		||||
 | 
			
		||||
export type ValidatorType = (typeof Validators.availableTypes)[number]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -60,6 +61,7 @@ export default class Validators {
 | 
			
		|||
        "id",
 | 
			
		||||
        "slope",
 | 
			
		||||
        "velopark",
 | 
			
		||||
        "currency"
 | 
			
		||||
    ] as const
 | 
			
		||||
 | 
			
		||||
    public static readonly AllValidators: ReadonlyArray<Validator> = [
 | 
			
		||||
| 
						 | 
				
			
			@ -89,6 +91,7 @@ export default class Validators {
 | 
			
		|||
        new IdValidator(),
 | 
			
		||||
        new SlopeValidator(),
 | 
			
		||||
        new VeloparkValidator(),
 | 
			
		||||
        new CurrencyValidator()
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    private static _byType = Validators._byTypeConstructor()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										73
									
								
								src/UI/InputElement/Validators/CurrencyValidator.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								src/UI/InputElement/Validators/CurrencyValidator.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,73 @@
 | 
			
		|||
import { Validator } from "../Validator"
 | 
			
		||||
import { Utils } from "../../../Utils"
 | 
			
		||||
 | 
			
		||||
export default class CurrencyValidator extends Validator {
 | 
			
		||||
    private readonly segmenter: Intl.Segmenter
 | 
			
		||||
    private readonly symbolToCurrencyMapping: Map<string, string>
 | 
			
		||||
    private readonly supportedCurrencies: Set<string>
 | 
			
		||||
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super("currency", "Validates monetary amounts")
 | 
			
		||||
        if (Intl.Segmenter === undefined || Utils.runningFromConsole) {
 | 
			
		||||
            // Librewolf doesn't support this
 | 
			
		||||
            return
 | 
			
		||||
        }
 | 
			
		||||
        let locale = "en-US"
 | 
			
		||||
        if(!Utils.runningFromConsole){
 | 
			
		||||
             locale??= navigator.language
 | 
			
		||||
        }
 | 
			
		||||
        this.segmenter = new Intl.Segmenter(locale, {
 | 
			
		||||
            granularity: "word"
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        const mapping: Map<string, string> = new Map<string, string>()
 | 
			
		||||
        const supportedCurrencies: Set<string> = new Set(Intl.supportedValuesOf("currency"))
 | 
			
		||||
        this.supportedCurrencies = supportedCurrencies
 | 
			
		||||
        for (const currency of supportedCurrencies) {
 | 
			
		||||
            const symbol = (0).toLocaleString(
 | 
			
		||||
                locale,
 | 
			
		||||
                {
 | 
			
		||||
                    style: "currency",
 | 
			
		||||
                    currency: currency,
 | 
			
		||||
                    minimumFractionDigits: 0,
 | 
			
		||||
                    maximumFractionDigits: 0
 | 
			
		||||
                }
 | 
			
		||||
            ).replace(/\d/g, "").trim()
 | 
			
		||||
 | 
			
		||||
            mapping.set(symbol.toLowerCase(), currency)
 | 
			
		||||
        }
 | 
			
		||||
        this.symbolToCurrencyMapping = mapping
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    reformat(s: string): string {
 | 
			
		||||
        if (!this.segmenter) {
 | 
			
		||||
            return s
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const parts = Array.from(this.segmenter.segment(s)).map(i => i.segment).filter(part => part.trim().length > 0)
 | 
			
		||||
        if(parts.length !== 2){
 | 
			
		||||
            return s
 | 
			
		||||
        }
 | 
			
		||||
        const mapping = this.symbolToCurrencyMapping
 | 
			
		||||
        let currency: string = undefined
 | 
			
		||||
        let amount = undefined
 | 
			
		||||
        for (const part of parts) {
 | 
			
		||||
            const lc = part.toLowerCase()
 | 
			
		||||
            if (this.supportedCurrencies.has(part.toUpperCase())) {
 | 
			
		||||
                currency = part.toUpperCase()
 | 
			
		||||
                continue
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (mapping.has(lc)) {
 | 
			
		||||
                currency = mapping.get(lc)
 | 
			
		||||
                continue
 | 
			
		||||
            }
 | 
			
		||||
            amount = part
 | 
			
		||||
        }
 | 
			
		||||
        if(amount === undefined || currency === undefined){
 | 
			
		||||
            return s
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return amount+" "+currency
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue