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 IdValidator from "./Validators/IdValidator"
 | 
				
			||||||
import SlopeValidator from "./Validators/SlopeValidator"
 | 
					import SlopeValidator from "./Validators/SlopeValidator"
 | 
				
			||||||
import VeloparkValidator from "./Validators/VeloparkValidator"
 | 
					import VeloparkValidator from "./Validators/VeloparkValidator"
 | 
				
			||||||
 | 
					import CurrencyValidator from "./Validators/CurrencyValidator"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type ValidatorType = (typeof Validators.availableTypes)[number]
 | 
					export type ValidatorType = (typeof Validators.availableTypes)[number]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,6 +61,7 @@ export default class Validators {
 | 
				
			||||||
        "id",
 | 
					        "id",
 | 
				
			||||||
        "slope",
 | 
					        "slope",
 | 
				
			||||||
        "velopark",
 | 
					        "velopark",
 | 
				
			||||||
 | 
					        "currency"
 | 
				
			||||||
    ] as const
 | 
					    ] as const
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static readonly AllValidators: ReadonlyArray<Validator> = [
 | 
					    public static readonly AllValidators: ReadonlyArray<Validator> = [
 | 
				
			||||||
| 
						 | 
					@ -89,6 +91,7 @@ export default class Validators {
 | 
				
			||||||
        new IdValidator(),
 | 
					        new IdValidator(),
 | 
				
			||||||
        new SlopeValidator(),
 | 
					        new SlopeValidator(),
 | 
				
			||||||
        new VeloparkValidator(),
 | 
					        new VeloparkValidator(),
 | 
				
			||||||
 | 
					        new CurrencyValidator()
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static _byType = Validators._byTypeConstructor()
 | 
					    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