diff --git a/.changeset/odd-taxis-suffer.md b/.changeset/odd-taxis-suffer.md new file mode 100644 index 0000000..48f974c --- /dev/null +++ b/.changeset/odd-taxis-suffer.md @@ -0,0 +1,5 @@ +--- +"@tsevdos/el-utils": minor +--- + +Create a formatUtils module and add a formatWeight util diff --git a/README.md b/README.md index 4133885..73d769b 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,10 @@ The library is currently split into the following modules: - [getQuarters()](https://github.com/tsevdos/elUtils/blob/main/docs/dateUtils.md#getQuarters) - [getEras()](https://github.com/tsevdos/elUtils/blob/main/docs/dateUtils.md#getEras) +- [**`formatUtils`**](https://github.com/tsevdos/elUtils/blob/main/docs/formatUtils.md) + + - [formatWeight()](https://github.com/tsevdos/elUtils/blob/main/docs/formatUtils.md#formatWeight) + ## Contribute See the [Contributing guide](https://github.com/tsevdos/elUtils/blob/main/CONTRIBUTING.md). diff --git a/data/weights.json b/data/weights.json new file mode 100644 index 0000000..8f5d42a --- /dev/null +++ b/data/weights.json @@ -0,0 +1,173 @@ +{ + "weights": { + "pound": { + "international": "(lb)", + "el": { + "full": "λίβρες", + "short": "lb", + "full_single": "λίβρα" + }, + "en": { + "full": "pounds", + "short": "lb", + "full_single": "pound" + } + }, + "centigram": { + "international": "(cg)", + "el": { + "full": "εκατοστόγραμμα", + "short": "cg", + "full_single": "εκατοστόγραμμο" + }, + "en": { + "full": "centigrams", + "short": "cg", + "full_single": "centigram" + } + }, + "carat": { + "international": "(ct)", + "el": { + "full": "καράτια", + "short": "ct", + "full_single": "καράτι" + }, + "en": { + "full": "carats", + "short": "ct", + "full_single": "carat" + } + }, + "dram": { + "international": "(dr)", + "el": { + "full": "δράμια", + "short": "dr", + "full_single": "δράμι" + }, + "en": { + "full": "drams", + "short": "dr", + "full_single": "dram" + } + }, + "gram": { + "international": "(g)", + "el": { + "full": "γραμμάρια", + "short": "g", + "full_single": "γραμμάριο" + }, + "en": { + "full": "grams", + "short": "g", + "full_single": "gram" + } + }, + "grain": { + "international": "(gr)", + "el": { + "full": "κόκκους", + "short": "gr", + "full_single": "κόκκος" + }, + "en": { + "full": "grains", + "short": "gr", + "full_single": "grain" + } + }, + "hectogram": { + "international": "(hg)", + "el": { + "full": "εκατόγραμμα", + "short": "hg", + "full_single": "εκατόγραμμο" + }, + "en": { + "full": "hectograms", + "short": "hg", + "full_single": "hectogram" + } + }, + "kilogram": { + "international": "(kg)", + "el": { + "full": "κιλά", + "short": "kg", + "full_single": "κιλό" + }, + "en": { + "full": "kilograms", + "short": "kg", + "full_single": "kilogram" + } + }, + "kilonewton": { + "international": "(kN)", + "el": { + "full": "κιλονιούτον", + "short": "kN", + "full_single": "κιλονιούτον" + }, + "en": { + "full": "kilonewtons", + "short": "kN", + "full_single": "kilonewton" + } + }, + "milligram": { + "international": "(mg)", + "el": { + "full": "χιλιοστόγραμμα", + "short": "mg", + "full_single": "χιλιοστόγραμμο" + }, + "en": { + "full": "milligrams", + "short": "mg", + "full_single": "milligram" + } + }, + "nanogram": { + "international": "(ng)", + "el": { + "full": "νανογραμμάρια", + "short": "ng", + "full_single": "νανογραμμάριο" + }, + "en": { + "full": "nanograms", + "short": "ng", + "full_single": "nanogram" + } + }, + "ounce": { + "international": "(oz)", + "el": { + "full": "ουγγιές", + "short": "oz", + "full_single": "ουγγιά" + }, + "en": { + "full": "ounces", + "short": "oz", + "full_single": "ounce" + } + }, + "ton": { + "international": "(t)", + "el": { + "full": "τόνοι", + "short": "t", + "full_single": "τόνος" + }, + "en": { + "full": "tons", + "short": "t", + "full_single": "ton" + } + } + } +} diff --git a/docs/formatUtils.md b/docs/formatUtils.md new file mode 100644 index 0000000..0883a9d --- /dev/null +++ b/docs/formatUtils.md @@ -0,0 +1,26 @@ +# FormatUtils + +> The **`formatUtils`** module provides functions for formating data such as weight, speed, time, price, numbers, dates etc. + +## Table of Contents + +- [**formatWeight()**](#formatWeight) + +--- + +### formatWeight() + +**Description**: Given a type of weight and a value it returns a string that appends the SI symbol and handles the plural/single state. + +**Parameters:** + +**`value`**: The weight value as a number + +**`options`**: An object specifying formating options. + +- **`type`**: The type of weight(e.g. pounds, centigrams, kilograms etc.) you want to format. +- **`locale`** (optional, default: "el"): The locale for the type of weight("el" for Greek, "en" for English). +- **`format`** (optional, default: "full"): Makes the weight text short(e.g. p) or full(e.g. pound). +- **`withInternational`** (optional): Appends the International System of Units(SI) symbol at the end(e.g. 2 pounds (lb)). + +**Return Type**: A string. diff --git a/package-lock.json b/package-lock.json index 55454f1..6660996 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@tsevdos/el-utils", - "version": "0.1.0", + "version": "0.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@tsevdos/el-utils", - "version": "0.1.0", + "version": "0.2.0", "license": "MIT", "devDependencies": { "@changesets/changelog-github": "^0.5.0", diff --git a/src/__tests__/formatUtils/formatWeight.test.ts b/src/__tests__/formatUtils/formatWeight.test.ts new file mode 100644 index 0000000..91127ec --- /dev/null +++ b/src/__tests__/formatUtils/formatWeight.test.ts @@ -0,0 +1,84 @@ +import { formatWeight, WeightTypes } from "../../formatUtils"; + +const testSingleValue = (typeWeight: WeightTypes, expectedGrData: string, expectedEnData: string) => { + expect(formatWeight(1, { type: typeWeight })).toBe(expectedGrData); + expect(formatWeight(1, { type: typeWeight, locale: "el", format: "full" })).toBe(expectedGrData); + expect(formatWeight(1, { type: typeWeight, locale: "en", format: "full" })).toBe(expectedEnData); +}; + +const testPluralValue = (typeWeight: WeightTypes, expectedGrData: string, expectedEnData: string) => { + expect(formatWeight(2, { type: typeWeight })).toBe(expectedGrData); + expect(formatWeight(2, { type: typeWeight, locale: "el", format: "full" })).toBe(expectedGrData); + expect(formatWeight(2, { type: typeWeight, locale: "en", format: "full" })).toBe(expectedEnData); +}; + +const testValueWithShortString = (typeWeight: WeightTypes, expectedGrData: string, expectedEnData: string) => { + expect(formatWeight(2, { type: typeWeight, format: "short" })).toBe(expectedGrData); + expect(formatWeight(2, { type: typeWeight, locale: "el", format: "short" })).toBe(expectedGrData); + expect(formatWeight(2, { type: typeWeight, format: "short", locale: "en" })).toBe(expectedEnData); +}; + +const testValueWithInternational = (typeWeight: WeightTypes, expectedGrData: string, expectedEnData: string) => { + expect(formatWeight(2, { type: typeWeight, withInternational: true })).toBe(expectedGrData); + expect(formatWeight(2, { type: typeWeight, locale: "en", withInternational: true })).toBe(expectedEnData); +}; + +describe("formatWeight", () => { + // Pounds + it("returns single pound string", () => { + const expectedGrData = "1 λίβρα"; + const expectedEnData = "1 pound"; + + testSingleValue("pound", expectedGrData, expectedEnData); + }); + + it("returns multiple pounds string", () => { + const expectedGrData = "2 λίβρες"; + const expectedEnData = "2 pounds"; + + testPluralValue("pound", expectedGrData, expectedEnData); + }); + + it("returns multiple pounds with short string", () => { + const expectedGrData = "2 lb"; + const expectedEnData = "2 lb"; + + testValueWithShortString("pound", expectedGrData, expectedEnData); + }); + + it("returns multiple pounds string with international symbol appended", () => { + const expectedGrData = "2 λίβρες (lb)"; + const expectedEnData = "2 pounds (lb)"; + + testValueWithInternational("pound", expectedGrData, expectedEnData); + }); + + // Centigrams + it("returns single centigram string", () => { + const expectedGrData = "1 εκατοστόγραμμο"; + const expectedEnData = "1 centigram"; + + testSingleValue("centigram", expectedGrData, expectedEnData); + }); + + it("returns multiple centigrams string", () => { + const expectedGrData = "2 εκατοστόγραμμα"; + const expectedEnData = "2 centigrams"; + + testPluralValue("centigram", expectedGrData, expectedEnData); + }); + + it("returns multiple centigrams with short string", () => { + const expectedGrData = "2 cg"; + const expectedEnData = "2 cg"; + + testValueWithShortString("centigram", expectedGrData, expectedEnData); + }); + + it("returns multiple centigrams string with international symbol appended", () => { + const expectedGrData = "2 εκατοστόγραμμα (cg)"; + const expectedEnData = "2 centigrams (cg)"; + + testValueWithInternational("centigram", expectedGrData, expectedEnData); + }); +}); diff --git a/src/formatUtils.ts b/src/formatUtils.ts new file mode 100644 index 0000000..58997e5 --- /dev/null +++ b/src/formatUtils.ts @@ -0,0 +1,62 @@ +import weightsData from "../data/weights.json"; + +export type WeightTypes = + | "pound" + | "kilogram" + | "centigram" + | "carat" + | "dram" + | "gram" + | "grain" + | "hectogram" + | "kilonewton" + | "milligram" + | "nanogram" + | "ounce" + | "ton"; + +type FormatWeightsOptions = { + locale?: "el" | "en"; + type?: WeightTypes; +} & ( + | { + format?: "full" | "full_single"; + withInternational?: boolean; + } + | { + // we don't want to have both a short format and the international symbol + // since we will end up with "two" symbols e.g 1 lb (lb) + format?: "short"; + withInternational?: never; + } +); + +type WithInternationalOptions = Pick; + +// helper to add international symbol +const withInternationalSymbol = (value: string, options: WithInternationalOptions = {}): string => { + const { type = "pound" } = options; + + if (weightsData.weights[type].international) { + return `${value} ${weightsData.weights[type].international}`; + } + + return value; +}; + +export const formatWeight = (value: number, options: FormatWeightsOptions = {}): string => { + const { locale = "el", format = "full", type = "pound", withInternational = false } = options; + let getFormat = format; + + if (getFormat !== "short") { + getFormat = value > 1 ? "full" : "full_single"; + } + + const result = `${value} ${weightsData.weights[type][locale][getFormat]}`; + + if (withInternational) { + return withInternationalSymbol(result, { type }); + } + + return result; +}; diff --git a/src/index.ts b/src/index.ts index 6650614..b7cb87f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,3 +14,4 @@ export { } from "./geoUtils"; export { getDays, getMonths, getQuarters, getEras } from "./dateUtils"; export { validatePostalCode, validateAMKA } from "./validationUtils"; +export { formatWeight } from "./formatUtils";