+85
| #!/usr/bin/env node | ||
| "use strict"; | ||
| // src/cli.ts | ||
| var SYMBOL = "\u20C3"; | ||
| var CODEPOINT = "U+20C3"; | ||
| var HTML_ENTITY = "⃃"; | ||
| var CSS_CONTENT = "\\20C3"; | ||
| var JS_ESCAPE = "\\u20C3"; | ||
| var ARABIC = "\u062F.\u0625"; | ||
| var CURRENCY_CODE = "AED"; | ||
| var HELP = ` | ||
| dirham \u2014 UAE Dirham currency symbol (${SYMBOL}) CLI | ||
| Usage: | ||
| npx dirham Print symbol info | ||
| npx dirham copy Copy ${SYMBOL} to clipboard (macOS/Linux) | ||
| npx dirham copy html Copy HTML entity | ||
| npx dirham copy css Copy CSS content value | ||
| npx dirham --help Show this help | ||
| Unicode: ${CODEPOINT} (Unicode 18.0 \u2014 UAE DIRHAM SIGN) | ||
| npm: https://www.npmjs.com/package/dirham | ||
| Docs: https://pooya.blog/dirham/ | ||
| `; | ||
| var INFO = ` | ||
| \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 | ||
| \u2502 UAE Dirham Symbol \u2014 ${SYMBOL} \u2502 | ||
| \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 | ||
| \u2502 Symbol: ${SYMBOL} \u2502 | ||
| \u2502 Codepoint: ${CODEPOINT} \u2502 | ||
| \u2502 HTML Entity: ${HTML_ENTITY} \u2502 | ||
| \u2502 CSS Content: ${CSS_CONTENT} \u2502 | ||
| \u2502 JS Escape: ${JS_ESCAPE} \u2502 | ||
| \u2502 Arabic: ${ARABIC} \u2502 | ||
| \u2502 ISO 4217: ${CURRENCY_CODE} \u2502 | ||
| \u2502 Unicode Ver: 18.0 (Sep 2026) \u2502 | ||
| \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 | ||
| \u2502 npm install dirham \u2502 | ||
| \u2502 https://pooya.blog/dirham/ \u2502 | ||
| \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 | ||
| `; | ||
| function main() { | ||
| const args = process.argv.slice(2); | ||
| if (args.includes("--help") || args.includes("-h")) { | ||
| console.log(HELP); | ||
| return; | ||
| } | ||
| if (args[0] === "copy") { | ||
| const format = args[1] || "unicode"; | ||
| const values = { | ||
| unicode: SYMBOL, | ||
| html: HTML_ENTITY, | ||
| css: CSS_CONTENT, | ||
| js: JS_ESCAPE, | ||
| arabic: ARABIC, | ||
| code: CURRENCY_CODE | ||
| }; | ||
| const text = values[format] || values.unicode; | ||
| const { execSync } = require("child_process"); | ||
| try { | ||
| const platform = process.platform; | ||
| if (platform === "darwin") { | ||
| execSync("pbcopy", { input: text }); | ||
| } else if (platform === "linux") { | ||
| try { | ||
| execSync("xclip -selection clipboard", { input: text }); | ||
| } catch { | ||
| execSync("xsel --clipboard --input", { input: text }); | ||
| } | ||
| } else if (platform === "win32") { | ||
| execSync("clip", { input: text }); | ||
| } else { | ||
| console.log(`Copied value (paste manually): ${text}`); | ||
| return; | ||
| } | ||
| console.log(`\u2713 Copied "${text}" (${format}) to clipboard`); | ||
| } catch { | ||
| console.log(`Could not access clipboard. Here's the value: ${text}`); | ||
| } | ||
| return; | ||
| } | ||
| console.log(INFO); | ||
| } | ||
| main(); |
| 'use strict'; | ||
| var __typeError = (msg) => { | ||
| throw TypeError(msg); | ||
| }; | ||
| var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); | ||
| var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); | ||
| var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value); | ||
| var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value); | ||
| var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method); | ||
| // src/core/constants.ts | ||
| var DIRHAM_UNICODE = "\u20C3"; | ||
| var DIRHAM_CURRENCY_CODE = "AED"; | ||
| var DIRHAM_STROKE_MAP = { | ||
| thin: 0, | ||
| extralight: 0, | ||
| light: 0, | ||
| regular: 0, | ||
| medium: 8, | ||
| semibold: 16, | ||
| bold: 24, | ||
| extrabold: 36, | ||
| black: 48 | ||
| }; | ||
| // src/web-component/DirhamSymbolElement.ts | ||
| var SVG_PATH = "m88.3 1c0.4 0.6 2.6 3.3 4.7 5.9 15.3 18.2 26.8 47.8 33 85.1 4.1 24.5 4.3 32.2 4.3 125.6v87h-41.8c-38.2 0-42.6-0.2-50.1-1.7-11.8-2.5-24-9.2-32.2-17.8-6.5-6.9-6.3-7.3-5.9 13.6 0.5 17.3 0.7 19.2 3.2 28.6 4 14.9 9.5 26 17.8 35.9 11.3 13.6 22.8 21.2 39.2 26.3 3.5 1 10.9 1.4 37.1 1.6l32.7 0.5v43.3 43.4l-46.1-0.3-46.3-0.3-8-3.2c-9.5-3.8-13.8-6.6-23.1-14.9l-6.8-6.1 0.4 19.1c0.5 17.7 0.6 19.7 3.1 28.7 8.7 31.8 29.7 54.5 57.4 61.9 6.9 1.9 9.6 2 38.5 2.4l30.9 0.4v89.6c0 54.1-0.3 94-0.8 100.8-0.5 6.2-2.1 17.8-3.5 25.9-6.5 37.3-18.2 65.4-35 83.6l-3.4 3.7h169.1c101.1 0 176.7-0.4 187.8-0.9 19.5-1 63-5.3 72.8-7.4 3.1-0.6 8.9-1.5 12.7-2.1 8.1-1.2 21.5-4 40.8-8.9 27.2-6.8 52-15.3 76.3-26.1 7.6-3.4 29.4-14.5 35.2-18 3.1-1.8 6.8-4 8.2-4.7 3.9-2.1 10.4-6.3 19.9-13.1 4.7-3.4 9.4-6.7 10.4-7.4 4.2-2.8 18.7-14.9 25.3-21 25.1-23.1 46.1-48.8 62.4-76.3 2.3-4 5.3-9 6.6-11.1 3.3-5.6 16.9-33.6 18.2-37.8 0.6-1.9 1.4-3.9 1.8-4.3 2.6-3.4 17.6-50.6 19.4-60.9 0.6-3.3 0.9-3.8 3.4-4.3 1.6-0.3 24.9-0.3 51.8-0.1 53.8 0.4 53.8 0.4 65.7 5.9 6.7 3.1 8.7 4.5 16.1 11.2 9.7 8.7 8.8 10.1 8.2-11.7-0.4-12.8-0.9-20.7-1.8-23.9-3.4-12.3-4.2-14.9-7.2-21.1-9.8-21.4-26.2-36.7-47.2-44l-8.2-3-33.4-0.4-33.3-0.5 0.4-11.7c0.4-15.4 0.4-45.9-0.1-61.6l-0.4-12.6 44.6-0.2c38.2-0.2 45.3 0 49.5 1.1 12.6 3.5 21.1 8.3 31.5 17.8l5.8 5.4v-14.8c0-17.6-0.9-25.4-4.5-37-7.1-23.5-21.1-41-41.1-51.8-13-7-13.8-7.2-58.5-7.5-26.2-0.2-39.9-0.6-40.6-1.2-0.6-0.6-1.1-1.6-1.1-2.4 0-0.8-1.5-7.1-3.5-13.9-23.4-82.7-67.1-148.4-131-197.1-8.7-6.7-30-20.8-38.6-25.6-3.3-1.9-6.9-3.9-7.8-4.5-4.2-2.3-28.3-14.1-34.3-16.6-3.6-1.6-8.3-3.6-10.4-4.4-35.3-15.3-94.5-29.8-139.7-34.3-7.4-0.7-17.2-1.8-21.7-2.2-20.4-2.3-48.7-2.6-209.4-2.6-135.8 0-169.9 0.3-169.4 1zm330.7 43.3c33.8 2 54.6 4.6 78.9 10.5 74.2 17.6 126.4 54.8 164.3 117 3.5 5.8 18.3 36 20.5 42.1 10.5 28.3 15.6 45.1 20.1 67.3 1.1 5.4 2.6 12.6 3.3 16 0.7 3.3 1 6.4 0.7 6.7-0.5 0.4-100.9 0.6-223.3 0.5l-222.5-0.2-0.3-128.5c-0.1-70.6 0-129.3 0.3-130.4l0.4-1.9h71.1c39 0 78 0.4 86.5 0.9zm297.5 350.3c0.7 4.3 0.7 77.3 0 80.9l-0.6 2.7-227.5-0.2-227.4-0.3-0.2-42.4c-0.2-23.3 0-42.7 0.2-43.1 0.3-0.5 97.2-0.8 227.7-0.8h227.2zm-10.2 171.7c0.5 1.5-1.9 13.8-6.8 33.8-5.6 22.5-13.2 45.2-20.9 62-3.8 8.6-13.3 27.2-15.6 30.7-1.1 1.6-4.3 6.7-7.1 11.2-18 28.2-43.7 53.9-73 72.9-10.7 6.8-32.7 18.4-38.6 20.2-1.2 0.3-2.5 0.9-3 1.3-0.7 0.6-9.8 4-20.4 7.8-19.5 6.9-56.6 14.4-86.4 17.5-19.3 1.9-22.4 2-96.7 2h-76.9v-129.7-129.8l220.9-0.4c121.5-0.2 221.6-0.5 222.4-0.7 0.9-0.1 1.8 0.5 2.1 1.2z"; | ||
| var VALID_WEIGHTS = /* @__PURE__ */ new Set([ | ||
| "thin", | ||
| "extralight", | ||
| "light", | ||
| "regular", | ||
| "medium", | ||
| "semibold", | ||
| "bold", | ||
| "extrabold", | ||
| "black" | ||
| ]); | ||
| var _shadow, _DirhamSymbolElement_instances, render_fn; | ||
| var DirhamSymbolElement = class extends HTMLElement { | ||
| constructor() { | ||
| super(); | ||
| __privateAdd(this, _DirhamSymbolElement_instances); | ||
| __privateAdd(this, _shadow); | ||
| __privateSet(this, _shadow, this.attachShadow({ mode: "open" })); | ||
| __privateMethod(this, _DirhamSymbolElement_instances, render_fn).call(this); | ||
| } | ||
| static get observedAttributes() { | ||
| return ["size", "color", "weight", "aria-label"]; | ||
| } | ||
| attributeChangedCallback() { | ||
| __privateMethod(this, _DirhamSymbolElement_instances, render_fn).call(this); | ||
| } | ||
| }; | ||
| _shadow = new WeakMap(); | ||
| _DirhamSymbolElement_instances = new WeakSet(); | ||
| render_fn = function() { | ||
| const size = this.getAttribute("size") || "24"; | ||
| const color = this.getAttribute("color") || "currentColor"; | ||
| const weightAttr = this.getAttribute("weight") || "regular"; | ||
| const weight = VALID_WEIGHTS.has(weightAttr) ? weightAttr : "regular"; | ||
| const ariaLabel = this.getAttribute("aria-label") || "UAE Dirham"; | ||
| const strokeWidth = DIRHAM_STROKE_MAP[weight]; | ||
| const strokeAttrs = strokeWidth > 0 ? `stroke="${color}" stroke-width="${strokeWidth}" stroke-linejoin="round" paint-order="stroke"` : ""; | ||
| __privateGet(this, _shadow).innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 870" width="${size}" height="${size}" fill="${color}" role="img" aria-label="${ariaLabel}" style="display:inline-block;vertical-align:middle"><path d="${SVG_PATH}" ${strokeAttrs}/></svg>`; | ||
| }; | ||
| if (typeof customElements !== "undefined" && !customElements.get("dirham-symbol")) { | ||
| customElements.define("dirham-symbol", DirhamSymbolElement); | ||
| } | ||
| // src/core/format.ts | ||
| var _fmtCache = /* @__PURE__ */ new Map(); | ||
| function getFormatter(locale, decimals, notation = "standard") { | ||
| const key = `${locale}:${decimals}:${notation}`; | ||
| let fmt = _fmtCache.get(key); | ||
| if (!fmt) { | ||
| fmt = new Intl.NumberFormat(locale, { | ||
| minimumFractionDigits: notation === "compact" ? 0 : decimals, | ||
| maximumFractionDigits: decimals, | ||
| ...notation === "compact" && { notation: "compact", compactDisplay: "short" } | ||
| }); | ||
| _fmtCache.set(key, fmt); | ||
| } | ||
| return fmt; | ||
| } | ||
| function formatDirham(amount, options = {}) { | ||
| if (!Number.isFinite(amount)) { | ||
| throw new RangeError( | ||
| `formatDirham: amount must be a finite number, got ${amount}` | ||
| ); | ||
| } | ||
| const { | ||
| locale = "en-AE", | ||
| decimals = 2, | ||
| useCode = false, | ||
| separator = "\xA0", | ||
| // non-breaking space | ||
| notation = "standard" | ||
| } = options; | ||
| const symbol = useCode ? DIRHAM_CURRENCY_CODE : DIRHAM_UNICODE; | ||
| let symbolFirst; | ||
| if (options.symbolFirst !== void 0) { | ||
| symbolFirst = options.symbolFirst; | ||
| } else { | ||
| symbolFirst = !locale.startsWith("ar"); | ||
| } | ||
| const formatted = getFormatter(locale, decimals, notation).format(amount); | ||
| return symbolFirst ? `${symbol}${separator}${formatted}` : `${formatted}${separator}${symbol}`; | ||
| } | ||
| // src/web-component/DirhamPriceElement.ts | ||
| var SVG_PATH2 = "m88.3 1c0.4 0.6 2.6 3.3 4.7 5.9 15.3 18.2 26.8 47.8 33 85.1 4.1 24.5 4.3 32.2 4.3 125.6v87h-41.8c-38.2 0-42.6-0.2-50.1-1.7-11.8-2.5-24-9.2-32.2-17.8-6.5-6.9-6.3-7.3-5.9 13.6 0.5 17.3 0.7 19.2 3.2 28.6 4 14.9 9.5 26 17.8 35.9 11.3 13.6 22.8 21.2 39.2 26.3 3.5 1 10.9 1.4 37.1 1.6l32.7 0.5v43.3 43.4l-46.1-0.3-46.3-0.3-8-3.2c-9.5-3.8-13.8-6.6-23.1-14.9l-6.8-6.1 0.4 19.1c0.5 17.7 0.6 19.7 3.1 28.7 8.7 31.8 29.7 54.5 57.4 61.9 6.9 1.9 9.6 2 38.5 2.4l30.9 0.4v89.6c0 54.1-0.3 94-0.8 100.8-0.5 6.2-2.1 17.8-3.5 25.9-6.5 37.3-18.2 65.4-35 83.6l-3.4 3.7h169.1c101.1 0 176.7-0.4 187.8-0.9 19.5-1 63-5.3 72.8-7.4 3.1-0.6 8.9-1.5 12.7-2.1 8.1-1.2 21.5-4 40.8-8.9 27.2-6.8 52-15.3 76.3-26.1 7.6-3.4 29.4-14.5 35.2-18 3.1-1.8 6.8-4 8.2-4.7 3.9-2.1 10.4-6.3 19.9-13.1 4.7-3.4 9.4-6.7 10.4-7.4 4.2-2.8 18.7-14.9 25.3-21 25.1-23.1 46.1-48.8 62.4-76.3 2.3-4 5.3-9 6.6-11.1 3.3-5.6 16.9-33.6 18.2-37.8 0.6-1.9 1.4-3.9 1.8-4.3 2.6-3.4 17.6-50.6 19.4-60.9 0.6-3.3 0.9-3.8 3.4-4.3 1.6-0.3 24.9-0.3 51.8-0.1 53.8 0.4 53.8 0.4 65.7 5.9 6.7 3.1 8.7 4.5 16.1 11.2 9.7 8.7 8.8 10.1 8.2-11.7-0.4-12.8-0.9-20.7-1.8-23.9-3.4-12.3-4.2-14.9-7.2-21.1-9.8-21.4-26.2-36.7-47.2-44l-8.2-3-33.4-0.4-33.3-0.5 0.4-11.7c0.4-15.4 0.4-45.9-0.1-61.6l-0.4-12.6 44.6-0.2c38.2-0.2 45.3 0 49.5 1.1 12.6 3.5 21.1 8.3 31.5 17.8l5.8 5.4v-14.8c0-17.6-0.9-25.4-4.5-37-7.1-23.5-21.1-41-41.1-51.8-13-7-13.8-7.2-58.5-7.5-26.2-0.2-39.9-0.6-40.6-1.2-0.6-0.6-1.1-1.6-1.1-2.4 0-0.8-1.5-7.1-3.5-13.9-23.4-82.7-67.1-148.4-131-197.1-8.7-6.7-30-20.8-38.6-25.6-3.3-1.9-6.9-3.9-7.8-4.5-4.2-2.3-28.3-14.1-34.3-16.6-3.6-1.6-8.3-3.6-10.4-4.4-35.3-15.3-94.5-29.8-139.7-34.3-7.4-0.7-17.2-1.8-21.7-2.2-20.4-2.3-48.7-2.6-209.4-2.6-135.8 0-169.9 0.3-169.4 1zm330.7 43.3c33.8 2 54.6 4.6 78.9 10.5 74.2 17.6 126.4 54.8 164.3 117 3.5 5.8 18.3 36 20.5 42.1 10.5 28.3 15.6 45.1 20.1 67.3 1.1 5.4 2.6 12.6 3.3 16 0.7 3.3 1 6.4 0.7 6.7-0.5 0.4-100.9 0.6-223.3 0.5l-222.5-0.2-0.3-128.5c-0.1-70.6 0-129.3 0.3-130.4l0.4-1.9h71.1c39 0 78 0.4 86.5 0.9zm297.5 350.3c0.7 4.3 0.7 77.3 0 80.9l-0.6 2.7-227.5-0.2-227.4-0.3-0.2-42.4c-0.2-23.3 0-42.7 0.2-43.1 0.3-0.5 97.2-0.8 227.7-0.8h227.2zm-10.2 171.7c0.5 1.5-1.9 13.8-6.8 33.8-5.6 22.5-13.2 45.2-20.9 62-3.8 8.6-13.3 27.2-15.6 30.7-1.1 1.6-4.3 6.7-7.1 11.2-18 28.2-43.7 53.9-73 72.9-10.7 6.8-32.7 18.4-38.6 20.2-1.2 0.3-2.5 0.9-3 1.3-0.7 0.6-9.8 4-20.4 7.8-19.5 6.9-56.6 14.4-86.4 17.5-19.3 1.9-22.4 2-96.7 2h-76.9v-129.7-129.8l220.9-0.4c121.5-0.2 221.6-0.5 222.4-0.7 0.9-0.1 1.8 0.5 2.1 1.2z"; | ||
| var VALID_WEIGHTS2 = /* @__PURE__ */ new Set([ | ||
| "thin", | ||
| "extralight", | ||
| "light", | ||
| "regular", | ||
| "medium", | ||
| "semibold", | ||
| "bold", | ||
| "extrabold", | ||
| "black" | ||
| ]); | ||
| var _shadow2, _DirhamPriceElement_instances, render_fn2, escape_fn; | ||
| var DirhamPriceElement = class extends HTMLElement { | ||
| constructor() { | ||
| super(); | ||
| __privateAdd(this, _DirhamPriceElement_instances); | ||
| __privateAdd(this, _shadow2); | ||
| __privateSet(this, _shadow2, this.attachShadow({ mode: "open" })); | ||
| __privateMethod(this, _DirhamPriceElement_instances, render_fn2).call(this); | ||
| } | ||
| static get observedAttributes() { | ||
| return [ | ||
| "amount", | ||
| "locale", | ||
| "decimals", | ||
| "notation", | ||
| "use-code", | ||
| "symbol-size", | ||
| "weight", | ||
| "currency" | ||
| ]; | ||
| } | ||
| attributeChangedCallback() { | ||
| __privateMethod(this, _DirhamPriceElement_instances, render_fn2).call(this); | ||
| } | ||
| }; | ||
| _shadow2 = new WeakMap(); | ||
| _DirhamPriceElement_instances = new WeakSet(); | ||
| render_fn2 = function() { | ||
| const amountStr = this.getAttribute("amount"); | ||
| const amount = amountStr !== null ? Number(amountStr) : 0; | ||
| const locale = this.getAttribute("locale") || "en-AE"; | ||
| const decimals = Number(this.getAttribute("decimals") ?? "2"); | ||
| const notation = this.getAttribute("notation") === "compact" ? "compact" : "standard"; | ||
| const useCode = this.hasAttribute("use-code"); | ||
| const symbolSize = this.getAttribute("symbol-size") || "1em"; | ||
| const weightAttr = this.getAttribute("weight") || "regular"; | ||
| const weight = VALID_WEIGHTS2.has(weightAttr) ? weightAttr : "regular"; | ||
| const currency = this.getAttribute("currency") || void 0; | ||
| const symbolFirst = !locale.startsWith("ar"); | ||
| let formatted; | ||
| if (!Number.isFinite(amount)) { | ||
| formatted = "\u2014"; | ||
| } else { | ||
| formatted = formatDirham(amount, { | ||
| locale, | ||
| decimals, | ||
| useCode: true, | ||
| notation | ||
| }).replace("AED", "").trim(); | ||
| } | ||
| if (useCode) { | ||
| const code = currency || "AED"; | ||
| const text = symbolFirst ? `${code}\xA0${formatted}` : `${formatted}\xA0${code}`; | ||
| __privateGet(this, _shadow2).innerHTML = `<span style="white-space:nowrap">${__privateMethod(this, _DirhamPriceElement_instances, escape_fn).call(this, text)}</span>`; | ||
| return; | ||
| } | ||
| const strokeWidth = DIRHAM_STROKE_MAP[weight]; | ||
| const strokeAttrs = strokeWidth > 0 ? ` stroke="currentColor" stroke-width="${strokeWidth}" stroke-linejoin="round" paint-order="stroke"` : ""; | ||
| const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 870" width="${__privateMethod(this, _DirhamPriceElement_instances, escape_fn).call(this, String(symbolSize))}" height="${__privateMethod(this, _DirhamPriceElement_instances, escape_fn).call(this, String(symbolSize))}" fill="currentColor" role="img" aria-label="UAE Dirham" style="display:inline-block;vertical-align:middle"><path d="${SVG_PATH2}"${strokeAttrs}/></svg>`; | ||
| const parts = symbolFirst ? `${svg}\xA0${__privateMethod(this, _DirhamPriceElement_instances, escape_fn).call(this, formatted)}` : `${__privateMethod(this, _DirhamPriceElement_instances, escape_fn).call(this, formatted)}\xA0${svg}`; | ||
| __privateGet(this, _shadow2).innerHTML = `<span style="white-space:nowrap">${parts}</span>`; | ||
| }; | ||
| escape_fn = function(str) { | ||
| return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """); | ||
| }; | ||
| if (typeof customElements !== "undefined" && !customElements.get("dirham-price")) { | ||
| customElements.define("dirham-price", DirhamPriceElement); | ||
| } | ||
| exports.DirhamPriceElement = DirhamPriceElement; | ||
| exports.DirhamSymbolElement = DirhamSymbolElement; | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
| {"version":3,"sources":["../../src/core/constants.ts","../../src/web-component/DirhamSymbolElement.ts","../../src/core/format.ts","../../src/web-component/DirhamPriceElement.ts"],"names":["SVG_PATH","VALID_WEIGHTS","_shadow","render_fn"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * UAE Dirham currency symbol constants.\n *\n * This package maps the Dirham glyph to the official Unicode codepoint U+20C3\n * (UAE DIRHAM SIGN) via a custom web font. The codepoint was accepted by the\n * Unicode Technical Committee for Unicode 18.0 (expected September 2026).\n *\n * Until system fonts ship native U+20C3 glyphs, the bundled web font provides\n * the rendering. When OS/font support lands, the web font becomes optional;\n * zero migration required.\n *\n * @module dirham\n * @see https://www.unicode.org/alloc/Pipeline.html\n */\n\n/** Unicode character for the Dirham symbol (U+20C3, requires Dirham web font until system fonts support it) */\nexport const DIRHAM_UNICODE = \"\\u20C3\";\n\n/** HTML entity for the Dirham symbol */\nexport const DIRHAM_HTML_ENTITY = \"⃃\";\n\n/** CSS content value for use in `::before` / `::after` pseudo-elements */\nexport const DIRHAM_CSS_CONTENT = \"\\\\20C3\";\n\n/** ISO 4217 currency code for UAE Dirham */\nexport const DIRHAM_CURRENCY_CODE = \"AED\";\n\n/** Arabic text representation of the Dirham symbol (د.إ) */\nexport const DIRHAM_SYMBOL_TEXT = \"د.إ\";\n\n/** The font family name used for the Dirham web font */\nexport const DIRHAM_FONT_FAMILY = \"Dirham\";\n\n/** CSS class name for the Dirham icon */\nexport const DIRHAM_CSS_CLASS = \"dirham-symbol\";\n\n/** Unicode codepoint as a number (0x20C3) */\nexport const DIRHAM_CODEPOINT = 0x20c3;\n\n// ── Font weight mapping ─────────────────────────────────────────────────\n\n/**\n * Supported visual weights for the Dirham symbol SVG component.\n *\n * Because the Dirham symbol is not yet in standard fonts (until Unicode 18.0),\n * weight simulation is applied via SVG stroke to match surrounding text weight,\n * similar to how $, €, £ adapt to their font's weight.\n */\nexport type DirhamWeight =\n\t| \"thin\"\n\t| \"extralight\"\n\t| \"light\"\n\t| \"regular\"\n\t| \"medium\"\n\t| \"semibold\"\n\t| \"bold\"\n\t| \"extrabold\"\n\t| \"black\";\n\n/**\n * Map from weight name to CSS `font-weight` numeric value.\n * Used for matching the symbol weight to surrounding text.\n */\nexport const DIRHAM_WEIGHT_MAP: Record<DirhamWeight, number> = {\n\tthin: 100,\n\textralight: 200,\n\tlight: 300,\n\tregular: 400,\n\tmedium: 500,\n\tsemibold: 600,\n\tbold: 700,\n\textrabold: 800,\n\tblack: 900,\n};\n\n/**\n * SVG stroke-width values that simulate font weight.\n * Applied with `paint-order: stroke` so stroke renders behind fill.\n */\nexport const DIRHAM_STROKE_MAP: Record<DirhamWeight, number> = {\n\tthin: 0,\n\textralight: 0,\n\tlight: 0,\n\tregular: 0,\n\tmedium: 8,\n\tsemibold: 16,\n\tbold: 24,\n\textrabold: 36,\n\tblack: 48,\n};\n","import { DIRHAM_STROKE_MAP, type DirhamWeight } from \"../core/constants\";\n\nconst SVG_PATH =\n\t\"m88.3 1c0.4 0.6 2.6 3.3 4.7 5.9 15.3 18.2 26.8 47.8 33 85.1 4.1 24.5 4.3 32.2 4.3 125.6v87h-41.8c-38.2 0-42.6-0.2-50.1-1.7-11.8-2.5-24-9.2-32.2-17.8-6.5-6.9-6.3-7.3-5.9 13.6 0.5 17.3 0.7 19.2 3.2 28.6 4 14.9 9.5 26 17.8 35.9 11.3 13.6 22.8 21.2 39.2 26.3 3.5 1 10.9 1.4 37.1 1.6l32.7 0.5v43.3 43.4l-46.1-0.3-46.3-0.3-8-3.2c-9.5-3.8-13.8-6.6-23.1-14.9l-6.8-6.1 0.4 19.1c0.5 17.7 0.6 19.7 3.1 28.7 8.7 31.8 29.7 54.5 57.4 61.9 6.9 1.9 9.6 2 38.5 2.4l30.9 0.4v89.6c0 54.1-0.3 94-0.8 100.8-0.5 6.2-2.1 17.8-3.5 25.9-6.5 37.3-18.2 65.4-35 83.6l-3.4 3.7h169.1c101.1 0 176.7-0.4 187.8-0.9 19.5-1 63-5.3 72.8-7.4 3.1-0.6 8.9-1.5 12.7-2.1 8.1-1.2 21.5-4 40.8-8.9 27.2-6.8 52-15.3 76.3-26.1 7.6-3.4 29.4-14.5 35.2-18 3.1-1.8 6.8-4 8.2-4.7 3.9-2.1 10.4-6.3 19.9-13.1 4.7-3.4 9.4-6.7 10.4-7.4 4.2-2.8 18.7-14.9 25.3-21 25.1-23.1 46.1-48.8 62.4-76.3 2.3-4 5.3-9 6.6-11.1 3.3-5.6 16.9-33.6 18.2-37.8 0.6-1.9 1.4-3.9 1.8-4.3 2.6-3.4 17.6-50.6 19.4-60.9 0.6-3.3 0.9-3.8 3.4-4.3 1.6-0.3 24.9-0.3 51.8-0.1 53.8 0.4 53.8 0.4 65.7 5.9 6.7 3.1 8.7 4.5 16.1 11.2 9.7 8.7 8.8 10.1 8.2-11.7-0.4-12.8-0.9-20.7-1.8-23.9-3.4-12.3-4.2-14.9-7.2-21.1-9.8-21.4-26.2-36.7-47.2-44l-8.2-3-33.4-0.4-33.3-0.5 0.4-11.7c0.4-15.4 0.4-45.9-0.1-61.6l-0.4-12.6 44.6-0.2c38.2-0.2 45.3 0 49.5 1.1 12.6 3.5 21.1 8.3 31.5 17.8l5.8 5.4v-14.8c0-17.6-0.9-25.4-4.5-37-7.1-23.5-21.1-41-41.1-51.8-13-7-13.8-7.2-58.5-7.5-26.2-0.2-39.9-0.6-40.6-1.2-0.6-0.6-1.1-1.6-1.1-2.4 0-0.8-1.5-7.1-3.5-13.9-23.4-82.7-67.1-148.4-131-197.1-8.7-6.7-30-20.8-38.6-25.6-3.3-1.9-6.9-3.9-7.8-4.5-4.2-2.3-28.3-14.1-34.3-16.6-3.6-1.6-8.3-3.6-10.4-4.4-35.3-15.3-94.5-29.8-139.7-34.3-7.4-0.7-17.2-1.8-21.7-2.2-20.4-2.3-48.7-2.6-209.4-2.6-135.8 0-169.9 0.3-169.4 1zm330.7 43.3c33.8 2 54.6 4.6 78.9 10.5 74.2 17.6 126.4 54.8 164.3 117 3.5 5.8 18.3 36 20.5 42.1 10.5 28.3 15.6 45.1 20.1 67.3 1.1 5.4 2.6 12.6 3.3 16 0.7 3.3 1 6.4 0.7 6.7-0.5 0.4-100.9 0.6-223.3 0.5l-222.5-0.2-0.3-128.5c-0.1-70.6 0-129.3 0.3-130.4l0.4-1.9h71.1c39 0 78 0.4 86.5 0.9zm297.5 350.3c0.7 4.3 0.7 77.3 0 80.9l-0.6 2.7-227.5-0.2-227.4-0.3-0.2-42.4c-0.2-23.3 0-42.7 0.2-43.1 0.3-0.5 97.2-0.8 227.7-0.8h227.2zm-10.2 171.7c0.5 1.5-1.9 13.8-6.8 33.8-5.6 22.5-13.2 45.2-20.9 62-3.8 8.6-13.3 27.2-15.6 30.7-1.1 1.6-4.3 6.7-7.1 11.2-18 28.2-43.7 53.9-73 72.9-10.7 6.8-32.7 18.4-38.6 20.2-1.2 0.3-2.5 0.9-3 1.3-0.7 0.6-9.8 4-20.4 7.8-19.5 6.9-56.6 14.4-86.4 17.5-19.3 1.9-22.4 2-96.7 2h-76.9v-129.7-129.8l220.9-0.4c121.5-0.2 221.6-0.5 222.4-0.7 0.9-0.1 1.8 0.5 2.1 1.2z\";\n\nconst VALID_WEIGHTS = new Set<string>([\n\t\"thin\",\n\t\"extralight\",\n\t\"light\",\n\t\"regular\",\n\t\"medium\",\n\t\"semibold\",\n\t\"bold\",\n\t\"extrabold\",\n\t\"black\",\n]);\n\n/**\n * `<dirham-symbol>` — framework-agnostic Web Component.\n *\n * @example\n * ```html\n * <script type=\"module\">\n * import \"dirham/web-component\";\n * </script>\n *\n * <dirham-symbol size=\"24\" weight=\"bold\"></dirham-symbol>\n * ```\n *\n * Attributes: size, color, weight, aria-label\n */\nexport class DirhamSymbolElement extends HTMLElement {\n\tstatic get observedAttributes() {\n\t\treturn [\"size\", \"color\", \"weight\", \"aria-label\"];\n\t}\n\n\t#shadow: ShadowRoot;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.#shadow = this.attachShadow({ mode: \"open\" });\n\t\tthis.#render();\n\t}\n\n\tattributeChangedCallback() {\n\t\tthis.#render();\n\t}\n\n\t#render() {\n\t\tconst size = this.getAttribute(\"size\") || \"24\";\n\t\tconst color = this.getAttribute(\"color\") || \"currentColor\";\n\t\tconst weightAttr = this.getAttribute(\"weight\") || \"regular\";\n\t\tconst weight: DirhamWeight = VALID_WEIGHTS.has(weightAttr)\n\t\t\t? (weightAttr as DirhamWeight)\n\t\t\t: \"regular\";\n\t\tconst ariaLabel = this.getAttribute(\"aria-label\") || \"UAE Dirham\";\n\t\tconst strokeWidth = DIRHAM_STROKE_MAP[weight];\n\n\t\tconst strokeAttrs =\n\t\t\tstrokeWidth > 0\n\t\t\t\t? `stroke=\"${color}\" stroke-width=\"${strokeWidth}\" stroke-linejoin=\"round\" paint-order=\"stroke\"`\n\t\t\t\t: \"\";\n\n\t\tthis.#shadow.innerHTML = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1000 870\" width=\"${size}\" height=\"${size}\" fill=\"${color}\" role=\"img\" aria-label=\"${ariaLabel}\" style=\"display:inline-block;vertical-align:middle\"><path d=\"${SVG_PATH}\" ${strokeAttrs}/></svg>`;\n\t}\n}\n\nif (\n\ttypeof customElements !== \"undefined\" &&\n\t!customElements.get(\"dirham-symbol\")\n) {\n\tcustomElements.define(\"dirham-symbol\", DirhamSymbolElement);\n}\n","import {\n\tDIRHAM_CURRENCY_CODE,\n\tDIRHAM_SYMBOL_TEXT,\n\tDIRHAM_UNICODE,\n} from \"./constants\";\n\n// ─── Intl.NumberFormat cache ─────────────────────────────────────────────────\n// Constructing Intl.NumberFormat is expensive (~µs). Cache instances keyed on\n// \"locale:decimals\" so repeated calls (e.g., rendering a price list) reuse\n// the same formatter instead of allocating a new object each time.\nconst _fmtCache = new Map<string, Intl.NumberFormat>();\n\nfunction getFormatter(\n\tlocale: string,\n\tdecimals: number,\n\tnotation: \"standard\" | \"compact\" = \"standard\",\n): Intl.NumberFormat {\n\tconst key = `${locale}:${decimals}:${notation}`;\n\tlet fmt = _fmtCache.get(key);\n\tif (!fmt) {\n\t\tfmt = new Intl.NumberFormat(locale, {\n\t\t\tminimumFractionDigits: notation === \"compact\" ? 0 : decimals,\n\t\t\tmaximumFractionDigits: decimals,\n\t\t\t...(notation === \"compact\" && { notation: \"compact\", compactDisplay: \"short\" }),\n\t\t});\n\t\t_fmtCache.set(key, fmt);\n\t}\n\treturn fmt;\n}\n\n/**\n * Options for formatting a Dirham amount.\n */\nexport interface FormatDirhamOptions {\n\t/**\n\t * Locale string for number formatting.\n\t * @default \"en-AE\"\n\t */\n\tlocale?: string;\n\n\t/**\n\t * Number of decimal places.\n\t * @default 2\n\t */\n\tdecimals?: number;\n\n\t/**\n\t * Whether to place the symbol before the amount.\n\t * When `undefined`, determined by locale:\n\t * - Arabic locales (ar-*): symbol after amount\n\t * - Other locales: symbol before amount\n\t */\n\tsymbolFirst?: boolean;\n\n\t/**\n\t * Use ISO currency code (AED) instead of the symbol.\n\t * @default false\n\t */\n\tuseCode?: boolean;\n\n\t/**\n\t * Separator between symbol and amount.\n\t * @default \" \" (non-breaking space)\n\t */\n\tseparator?: string;\n\n\t/**\n\t * Number notation style.\n\t * - `\"standard\"` — full digits (e.g. 1,500,000.00)\n\t * - `\"compact\"` — abbreviated (e.g. 1.5M)\n\t * @default \"standard\"\n\t */\n\tnotation?: \"standard\" | \"compact\";\n}\n\n/**\n * Format a number as a Dirham currency string.\n *\n * @example\n * ```ts\n * formatDirham(100); // \"\\u20C3 100.00\"\n * formatDirham(1234.5); // \"\\u20C3 1,234.50\"\n * formatDirham(100, { locale: \"ar-AE\" }); // \"100.00 \\u20C3\"\n * formatDirham(100, { useCode: true }); // \"AED 100.00\"\n * formatDirham(1500000, { notation: \"compact\" }); // \"\\u20C3 1.5M\"\n * ```\n */\nexport function formatDirham(\n\tamount: number,\n\toptions: FormatDirhamOptions = {},\n): string {\n\tif (!Number.isFinite(amount)) {\n\t\tthrow new RangeError(\n\t\t\t`formatDirham: amount must be a finite number, got ${amount}`,\n\t\t);\n\t}\n\n\tconst {\n\t\tlocale = \"en-AE\",\n\t\tdecimals = 2,\n\t\tuseCode = false,\n\t\tseparator = \"\\u00A0\", // non-breaking space\n\t\tnotation = \"standard\",\n\t} = options;\n\n\tconst symbol = useCode ? DIRHAM_CURRENCY_CODE : DIRHAM_UNICODE;\n\n\t// Determine symbol placement\n\tlet symbolFirst: boolean;\n\tif (options.symbolFirst !== undefined) {\n\t\tsymbolFirst = options.symbolFirst;\n\t} else {\n\t\t// Arabic locales place symbol after amount\n\t\tsymbolFirst = !locale.startsWith(\"ar\");\n\t}\n\n\t// Format the number (use cached formatter)\n\tconst formatted = getFormatter(locale, decimals, notation).format(amount);\n\n\treturn symbolFirst\n\t\t? `${symbol}${separator}${formatted}`\n\t\t: `${formatted}${separator}${symbol}`;\n}\n\n/**\n * Options for parsing a Dirham-formatted string.\n */\nexport interface ParseDirhamOptions {\n\t/**\n\t * Normalize Arabic-Indic digits (٠١٢٣٤٥٦٧٨٩ / U+0660–U+0669) to ASCII\n\t * digits before parsing. Enables round-tripping strings produced by\n\t * `formatDirham` with Arabic locales (e.g. `\"ar-AE\"`).\n\t * @default true\n\t */\n\tnormalizeArabicNumerals?: boolean;\n}\n\n/**\n * Parse a Dirham-formatted string back to a number.\n * Strips currency symbols, codes, and formatting characters.\n * By default also normalizes Arabic-Indic digits so strings produced by\n * `formatDirham({ locale: \"ar-AE\" })` round-trip correctly.\n *\n * @example\n * ```ts\n * parseDirham(\"\\u20C3 1,234.50\"); // 1234.5\n * parseDirham(\"AED 100.00\"); // 100\n * parseDirham(\"١٬٢٣٤٫٥٠ \\u20C3\"); // 1234.5\n * parseDirham(\"١٠٠٫٠٠ \\u20C3\", { normalizeArabicNumerals: false }); // throws\n * ```\n */\nexport function parseDirham(\n\tvalue: string,\n\toptions: ParseDirhamOptions = {},\n): number {\n\tconst { normalizeArabicNumerals = true } = options;\n\n\tlet cleaned = value\n\t\t.replaceAll(DIRHAM_UNICODE, \"\")\n\t\t.replaceAll(DIRHAM_SYMBOL_TEXT, \"\")\n\t\t.replaceAll(DIRHAM_CURRENCY_CODE, \"\")\n\t\t.replace(/[,\\s\\u00A0\\u066C]/g, \"\") // ASCII comma, whitespace, NBSP, Arabic thousands sep\n\t\t.trim();\n\n\tif (normalizeArabicNumerals) {\n\t\t// Arabic-Indic digits U+0660–U+0669 → ASCII 0–9\n\t\tcleaned = cleaned.replace(\n\t\t\t/[\\u0660-\\u0669]/g,\n\t\t\t(d) => String(d.charCodeAt(0) - 0x0660),\n\t\t);\n\t\t// Arabic decimal separator (U+066B) → '.'\n\t\tcleaned = cleaned.replace(/\\u066B/g, \".\");\n\t}\n\n\tconst result = Number.parseFloat(cleaned);\n\tif (Number.isNaN(result)) {\n\t\tthrow new Error(`Cannot parse \"${value}\" as a Dirham amount`);\n\t}\n\treturn result;\n}\n","import { DIRHAM_STROKE_MAP, type DirhamWeight } from \"../core/constants\";\nimport { formatDirham } from \"../core/format\";\n\nconst SVG_PATH =\n\t\"m88.3 1c0.4 0.6 2.6 3.3 4.7 5.9 15.3 18.2 26.8 47.8 33 85.1 4.1 24.5 4.3 32.2 4.3 125.6v87h-41.8c-38.2 0-42.6-0.2-50.1-1.7-11.8-2.5-24-9.2-32.2-17.8-6.5-6.9-6.3-7.3-5.9 13.6 0.5 17.3 0.7 19.2 3.2 28.6 4 14.9 9.5 26 17.8 35.9 11.3 13.6 22.8 21.2 39.2 26.3 3.5 1 10.9 1.4 37.1 1.6l32.7 0.5v43.3 43.4l-46.1-0.3-46.3-0.3-8-3.2c-9.5-3.8-13.8-6.6-23.1-14.9l-6.8-6.1 0.4 19.1c0.5 17.7 0.6 19.7 3.1 28.7 8.7 31.8 29.7 54.5 57.4 61.9 6.9 1.9 9.6 2 38.5 2.4l30.9 0.4v89.6c0 54.1-0.3 94-0.8 100.8-0.5 6.2-2.1 17.8-3.5 25.9-6.5 37.3-18.2 65.4-35 83.6l-3.4 3.7h169.1c101.1 0 176.7-0.4 187.8-0.9 19.5-1 63-5.3 72.8-7.4 3.1-0.6 8.9-1.5 12.7-2.1 8.1-1.2 21.5-4 40.8-8.9 27.2-6.8 52-15.3 76.3-26.1 7.6-3.4 29.4-14.5 35.2-18 3.1-1.8 6.8-4 8.2-4.7 3.9-2.1 10.4-6.3 19.9-13.1 4.7-3.4 9.4-6.7 10.4-7.4 4.2-2.8 18.7-14.9 25.3-21 25.1-23.1 46.1-48.8 62.4-76.3 2.3-4 5.3-9 6.6-11.1 3.3-5.6 16.9-33.6 18.2-37.8 0.6-1.9 1.4-3.9 1.8-4.3 2.6-3.4 17.6-50.6 19.4-60.9 0.6-3.3 0.9-3.8 3.4-4.3 1.6-0.3 24.9-0.3 51.8-0.1 53.8 0.4 53.8 0.4 65.7 5.9 6.7 3.1 8.7 4.5 16.1 11.2 9.7 8.7 8.8 10.1 8.2-11.7-0.4-12.8-0.9-20.7-1.8-23.9-3.4-12.3-4.2-14.9-7.2-21.1-9.8-21.4-26.2-36.7-47.2-44l-8.2-3-33.4-0.4-33.3-0.5 0.4-11.7c0.4-15.4 0.4-45.9-0.1-61.6l-0.4-12.6 44.6-0.2c38.2-0.2 45.3 0 49.5 1.1 12.6 3.5 21.1 8.3 31.5 17.8l5.8 5.4v-14.8c0-17.6-0.9-25.4-4.5-37-7.1-23.5-21.1-41-41.1-51.8-13-7-13.8-7.2-58.5-7.5-26.2-0.2-39.9-0.6-40.6-1.2-0.6-0.6-1.1-1.6-1.1-2.4 0-0.8-1.5-7.1-3.5-13.9-23.4-82.7-67.1-148.4-131-197.1-8.7-6.7-30-20.8-38.6-25.6-3.3-1.9-6.9-3.9-7.8-4.5-4.2-2.3-28.3-14.1-34.3-16.6-3.6-1.6-8.3-3.6-10.4-4.4-35.3-15.3-94.5-29.8-139.7-34.3-7.4-0.7-17.2-1.8-21.7-2.2-20.4-2.3-48.7-2.6-209.4-2.6-135.8 0-169.9 0.3-169.4 1zm330.7 43.3c33.8 2 54.6 4.6 78.9 10.5 74.2 17.6 126.4 54.8 164.3 117 3.5 5.8 18.3 36 20.5 42.1 10.5 28.3 15.6 45.1 20.1 67.3 1.1 5.4 2.6 12.6 3.3 16 0.7 3.3 1 6.4 0.7 6.7-0.5 0.4-100.9 0.6-223.3 0.5l-222.5-0.2-0.3-128.5c-0.1-70.6 0-129.3 0.3-130.4l0.4-1.9h71.1c39 0 78 0.4 86.5 0.9zm297.5 350.3c0.7 4.3 0.7 77.3 0 80.9l-0.6 2.7-227.5-0.2-227.4-0.3-0.2-42.4c-0.2-23.3 0-42.7 0.2-43.1 0.3-0.5 97.2-0.8 227.7-0.8h227.2zm-10.2 171.7c0.5 1.5-1.9 13.8-6.8 33.8-5.6 22.5-13.2 45.2-20.9 62-3.8 8.6-13.3 27.2-15.6 30.7-1.1 1.6-4.3 6.7-7.1 11.2-18 28.2-43.7 53.9-73 72.9-10.7 6.8-32.7 18.4-38.6 20.2-1.2 0.3-2.5 0.9-3 1.3-0.7 0.6-9.8 4-20.4 7.8-19.5 6.9-56.6 14.4-86.4 17.5-19.3 1.9-22.4 2-96.7 2h-76.9v-129.7-129.8l220.9-0.4c121.5-0.2 221.6-0.5 222.4-0.7 0.9-0.1 1.8 0.5 2.1 1.2z\";\n\nconst VALID_WEIGHTS = new Set<string>([\n\t\"thin\",\n\t\"extralight\",\n\t\"light\",\n\t\"regular\",\n\t\"medium\",\n\t\"semibold\",\n\t\"bold\",\n\t\"extrabold\",\n\t\"black\",\n]);\n\n/**\n * `<dirham-price>` — framework-agnostic Web Component for displaying formatted prices.\n *\n * Works in Vue, Angular, Svelte, or any HTML page.\n *\n * @example\n * ```html\n * <script type=\"module\">\n * import \"dirham/web-component\";\n * </script>\n *\n * <dirham-price amount=\"1250\"></dirham-price>\n * <dirham-price amount=\"5000000\" notation=\"compact\"></dirham-price>\n * <dirham-price amount=\"100\" locale=\"ar-AE\"></dirham-price>\n * <dirham-price amount=\"500\" use-code></dirham-price>\n * ```\n *\n * Attributes: amount, locale, decimals, notation, use-code, symbol-size, weight, currency\n */\nexport class DirhamPriceElement extends HTMLElement {\n\tstatic get observedAttributes() {\n\t\treturn [\n\t\t\t\"amount\",\n\t\t\t\"locale\",\n\t\t\t\"decimals\",\n\t\t\t\"notation\",\n\t\t\t\"use-code\",\n\t\t\t\"symbol-size\",\n\t\t\t\"weight\",\n\t\t\t\"currency\",\n\t\t];\n\t}\n\n\t#shadow: ShadowRoot;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.#shadow = this.attachShadow({ mode: \"open\" });\n\t\tthis.#render();\n\t}\n\n\tattributeChangedCallback() {\n\t\tthis.#render();\n\t}\n\n\t#render() {\n\t\tconst amountStr = this.getAttribute(\"amount\");\n\t\tconst amount = amountStr !== null ? Number(amountStr) : 0;\n\t\tconst locale = this.getAttribute(\"locale\") || \"en-AE\";\n\t\tconst decimals = Number(this.getAttribute(\"decimals\") ?? \"2\");\n\t\tconst notation =\n\t\t\tthis.getAttribute(\"notation\") === \"compact\" ? \"compact\" : \"standard\";\n\t\tconst useCode = this.hasAttribute(\"use-code\");\n\t\tconst symbolSize = this.getAttribute(\"symbol-size\") || \"1em\";\n\t\tconst weightAttr = this.getAttribute(\"weight\") || \"regular\";\n\t\tconst weight: DirhamWeight = VALID_WEIGHTS.has(weightAttr)\n\t\t\t? (weightAttr as DirhamWeight)\n\t\t\t: \"regular\";\n\t\tconst currency = this.getAttribute(\"currency\") || undefined;\n\n\t\tconst symbolFirst = !locale.startsWith(\"ar\");\n\n\t\t// Format the numeric part (strip AED code — we render the SVG instead)\n\t\tlet formatted: string;\n\t\tif (!Number.isFinite(amount)) {\n\t\t\tformatted = \"—\";\n\t\t} else {\n\t\t\tformatted = formatDirham(amount, {\n\t\t\t\tlocale,\n\t\t\t\tdecimals,\n\t\t\t\tuseCode: true,\n\t\t\t\tnotation,\n\t\t\t})\n\t\t\t\t.replace(\"AED\", \"\")\n\t\t\t\t.trim();\n\t\t}\n\n\t\tif (useCode) {\n\t\t\tconst code = currency || \"AED\";\n\t\t\tconst text = symbolFirst\n\t\t\t\t? `${code}\\u00A0${formatted}`\n\t\t\t\t: `${formatted}\\u00A0${code}`;\n\t\t\tthis.#shadow.innerHTML = `<span style=\"white-space:nowrap\">${this.#escape(text)}</span>`;\n\t\t\treturn;\n\t\t}\n\n\t\tconst strokeWidth = DIRHAM_STROKE_MAP[weight];\n\t\tconst strokeAttrs =\n\t\t\tstrokeWidth > 0\n\t\t\t\t? ` stroke=\"currentColor\" stroke-width=\"${strokeWidth}\" stroke-linejoin=\"round\" paint-order=\"stroke\"`\n\t\t\t\t: \"\";\n\n\t\tconst svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1000 870\" width=\"${this.#escape(String(symbolSize))}\" height=\"${this.#escape(String(symbolSize))}\" fill=\"currentColor\" role=\"img\" aria-label=\"UAE Dirham\" style=\"display:inline-block;vertical-align:middle\"><path d=\"${SVG_PATH}\"${strokeAttrs}/></svg>`;\n\n\t\tconst parts = symbolFirst\n\t\t\t? `${svg}\\u00A0${this.#escape(formatted)}`\n\t\t\t: `${this.#escape(formatted)}\\u00A0${svg}`;\n\n\t\tthis.#shadow.innerHTML = `<span style=\"white-space:nowrap\">${parts}</span>`;\n\t}\n\n\t#escape(str: string): string {\n\t\treturn str\n\t\t\t.replace(/&/g, \"&\")\n\t\t\t.replace(/</g, \"<\")\n\t\t\t.replace(/>/g, \">\")\n\t\t\t.replace(/\"/g, \""\");\n\t}\n}\n\nif (\n\ttypeof customElements !== \"undefined\" &&\n\t!customElements.get(\"dirham-price\")\n) {\n\tcustomElements.define(\"dirham-price\", DirhamPriceElement);\n}\n"]} |
| /** | ||
| * `<dirham-symbol>` — framework-agnostic Web Component. | ||
| * | ||
| * @example | ||
| * ```html | ||
| * <script type="module"> | ||
| * import "dirham/web-component"; | ||
| * </script> | ||
| * | ||
| * <dirham-symbol size="24" weight="bold"></dirham-symbol> | ||
| * ``` | ||
| * | ||
| * Attributes: size, color, weight, aria-label | ||
| */ | ||
| declare class DirhamSymbolElement extends HTMLElement { | ||
| #private; | ||
| static get observedAttributes(): string[]; | ||
| constructor(); | ||
| attributeChangedCallback(): void; | ||
| } | ||
| /** | ||
| * `<dirham-price>` — framework-agnostic Web Component for displaying formatted prices. | ||
| * | ||
| * Works in Vue, Angular, Svelte, or any HTML page. | ||
| * | ||
| * @example | ||
| * ```html | ||
| * <script type="module"> | ||
| * import "dirham/web-component"; | ||
| * </script> | ||
| * | ||
| * <dirham-price amount="1250"></dirham-price> | ||
| * <dirham-price amount="5000000" notation="compact"></dirham-price> | ||
| * <dirham-price amount="100" locale="ar-AE"></dirham-price> | ||
| * <dirham-price amount="500" use-code></dirham-price> | ||
| * ``` | ||
| * | ||
| * Attributes: amount, locale, decimals, notation, use-code, symbol-size, weight, currency | ||
| */ | ||
| declare class DirhamPriceElement extends HTMLElement { | ||
| #private; | ||
| static get observedAttributes(): string[]; | ||
| constructor(); | ||
| attributeChangedCallback(): void; | ||
| } | ||
| export { DirhamPriceElement, DirhamSymbolElement }; |
| /** | ||
| * `<dirham-symbol>` — framework-agnostic Web Component. | ||
| * | ||
| * @example | ||
| * ```html | ||
| * <script type="module"> | ||
| * import "dirham/web-component"; | ||
| * </script> | ||
| * | ||
| * <dirham-symbol size="24" weight="bold"></dirham-symbol> | ||
| * ``` | ||
| * | ||
| * Attributes: size, color, weight, aria-label | ||
| */ | ||
| declare class DirhamSymbolElement extends HTMLElement { | ||
| #private; | ||
| static get observedAttributes(): string[]; | ||
| constructor(); | ||
| attributeChangedCallback(): void; | ||
| } | ||
| /** | ||
| * `<dirham-price>` — framework-agnostic Web Component for displaying formatted prices. | ||
| * | ||
| * Works in Vue, Angular, Svelte, or any HTML page. | ||
| * | ||
| * @example | ||
| * ```html | ||
| * <script type="module"> | ||
| * import "dirham/web-component"; | ||
| * </script> | ||
| * | ||
| * <dirham-price amount="1250"></dirham-price> | ||
| * <dirham-price amount="5000000" notation="compact"></dirham-price> | ||
| * <dirham-price amount="100" locale="ar-AE"></dirham-price> | ||
| * <dirham-price amount="500" use-code></dirham-price> | ||
| * ``` | ||
| * | ||
| * Attributes: amount, locale, decimals, notation, use-code, symbol-size, weight, currency | ||
| */ | ||
| declare class DirhamPriceElement extends HTMLElement { | ||
| #private; | ||
| static get observedAttributes(): string[]; | ||
| constructor(); | ||
| attributeChangedCallback(): void; | ||
| } | ||
| export { DirhamPriceElement, DirhamSymbolElement }; |
| var __typeError = (msg) => { | ||
| throw TypeError(msg); | ||
| }; | ||
| var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); | ||
| var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); | ||
| var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value); | ||
| var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value); | ||
| var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method); | ||
| // src/core/constants.ts | ||
| var DIRHAM_UNICODE = "\u20C3"; | ||
| var DIRHAM_CURRENCY_CODE = "AED"; | ||
| var DIRHAM_STROKE_MAP = { | ||
| thin: 0, | ||
| extralight: 0, | ||
| light: 0, | ||
| regular: 0, | ||
| medium: 8, | ||
| semibold: 16, | ||
| bold: 24, | ||
| extrabold: 36, | ||
| black: 48 | ||
| }; | ||
| // src/web-component/DirhamSymbolElement.ts | ||
| var SVG_PATH = "m88.3 1c0.4 0.6 2.6 3.3 4.7 5.9 15.3 18.2 26.8 47.8 33 85.1 4.1 24.5 4.3 32.2 4.3 125.6v87h-41.8c-38.2 0-42.6-0.2-50.1-1.7-11.8-2.5-24-9.2-32.2-17.8-6.5-6.9-6.3-7.3-5.9 13.6 0.5 17.3 0.7 19.2 3.2 28.6 4 14.9 9.5 26 17.8 35.9 11.3 13.6 22.8 21.2 39.2 26.3 3.5 1 10.9 1.4 37.1 1.6l32.7 0.5v43.3 43.4l-46.1-0.3-46.3-0.3-8-3.2c-9.5-3.8-13.8-6.6-23.1-14.9l-6.8-6.1 0.4 19.1c0.5 17.7 0.6 19.7 3.1 28.7 8.7 31.8 29.7 54.5 57.4 61.9 6.9 1.9 9.6 2 38.5 2.4l30.9 0.4v89.6c0 54.1-0.3 94-0.8 100.8-0.5 6.2-2.1 17.8-3.5 25.9-6.5 37.3-18.2 65.4-35 83.6l-3.4 3.7h169.1c101.1 0 176.7-0.4 187.8-0.9 19.5-1 63-5.3 72.8-7.4 3.1-0.6 8.9-1.5 12.7-2.1 8.1-1.2 21.5-4 40.8-8.9 27.2-6.8 52-15.3 76.3-26.1 7.6-3.4 29.4-14.5 35.2-18 3.1-1.8 6.8-4 8.2-4.7 3.9-2.1 10.4-6.3 19.9-13.1 4.7-3.4 9.4-6.7 10.4-7.4 4.2-2.8 18.7-14.9 25.3-21 25.1-23.1 46.1-48.8 62.4-76.3 2.3-4 5.3-9 6.6-11.1 3.3-5.6 16.9-33.6 18.2-37.8 0.6-1.9 1.4-3.9 1.8-4.3 2.6-3.4 17.6-50.6 19.4-60.9 0.6-3.3 0.9-3.8 3.4-4.3 1.6-0.3 24.9-0.3 51.8-0.1 53.8 0.4 53.8 0.4 65.7 5.9 6.7 3.1 8.7 4.5 16.1 11.2 9.7 8.7 8.8 10.1 8.2-11.7-0.4-12.8-0.9-20.7-1.8-23.9-3.4-12.3-4.2-14.9-7.2-21.1-9.8-21.4-26.2-36.7-47.2-44l-8.2-3-33.4-0.4-33.3-0.5 0.4-11.7c0.4-15.4 0.4-45.9-0.1-61.6l-0.4-12.6 44.6-0.2c38.2-0.2 45.3 0 49.5 1.1 12.6 3.5 21.1 8.3 31.5 17.8l5.8 5.4v-14.8c0-17.6-0.9-25.4-4.5-37-7.1-23.5-21.1-41-41.1-51.8-13-7-13.8-7.2-58.5-7.5-26.2-0.2-39.9-0.6-40.6-1.2-0.6-0.6-1.1-1.6-1.1-2.4 0-0.8-1.5-7.1-3.5-13.9-23.4-82.7-67.1-148.4-131-197.1-8.7-6.7-30-20.8-38.6-25.6-3.3-1.9-6.9-3.9-7.8-4.5-4.2-2.3-28.3-14.1-34.3-16.6-3.6-1.6-8.3-3.6-10.4-4.4-35.3-15.3-94.5-29.8-139.7-34.3-7.4-0.7-17.2-1.8-21.7-2.2-20.4-2.3-48.7-2.6-209.4-2.6-135.8 0-169.9 0.3-169.4 1zm330.7 43.3c33.8 2 54.6 4.6 78.9 10.5 74.2 17.6 126.4 54.8 164.3 117 3.5 5.8 18.3 36 20.5 42.1 10.5 28.3 15.6 45.1 20.1 67.3 1.1 5.4 2.6 12.6 3.3 16 0.7 3.3 1 6.4 0.7 6.7-0.5 0.4-100.9 0.6-223.3 0.5l-222.5-0.2-0.3-128.5c-0.1-70.6 0-129.3 0.3-130.4l0.4-1.9h71.1c39 0 78 0.4 86.5 0.9zm297.5 350.3c0.7 4.3 0.7 77.3 0 80.9l-0.6 2.7-227.5-0.2-227.4-0.3-0.2-42.4c-0.2-23.3 0-42.7 0.2-43.1 0.3-0.5 97.2-0.8 227.7-0.8h227.2zm-10.2 171.7c0.5 1.5-1.9 13.8-6.8 33.8-5.6 22.5-13.2 45.2-20.9 62-3.8 8.6-13.3 27.2-15.6 30.7-1.1 1.6-4.3 6.7-7.1 11.2-18 28.2-43.7 53.9-73 72.9-10.7 6.8-32.7 18.4-38.6 20.2-1.2 0.3-2.5 0.9-3 1.3-0.7 0.6-9.8 4-20.4 7.8-19.5 6.9-56.6 14.4-86.4 17.5-19.3 1.9-22.4 2-96.7 2h-76.9v-129.7-129.8l220.9-0.4c121.5-0.2 221.6-0.5 222.4-0.7 0.9-0.1 1.8 0.5 2.1 1.2z"; | ||
| var VALID_WEIGHTS = /* @__PURE__ */ new Set([ | ||
| "thin", | ||
| "extralight", | ||
| "light", | ||
| "regular", | ||
| "medium", | ||
| "semibold", | ||
| "bold", | ||
| "extrabold", | ||
| "black" | ||
| ]); | ||
| var _shadow, _DirhamSymbolElement_instances, render_fn; | ||
| var DirhamSymbolElement = class extends HTMLElement { | ||
| constructor() { | ||
| super(); | ||
| __privateAdd(this, _DirhamSymbolElement_instances); | ||
| __privateAdd(this, _shadow); | ||
| __privateSet(this, _shadow, this.attachShadow({ mode: "open" })); | ||
| __privateMethod(this, _DirhamSymbolElement_instances, render_fn).call(this); | ||
| } | ||
| static get observedAttributes() { | ||
| return ["size", "color", "weight", "aria-label"]; | ||
| } | ||
| attributeChangedCallback() { | ||
| __privateMethod(this, _DirhamSymbolElement_instances, render_fn).call(this); | ||
| } | ||
| }; | ||
| _shadow = new WeakMap(); | ||
| _DirhamSymbolElement_instances = new WeakSet(); | ||
| render_fn = function() { | ||
| const size = this.getAttribute("size") || "24"; | ||
| const color = this.getAttribute("color") || "currentColor"; | ||
| const weightAttr = this.getAttribute("weight") || "regular"; | ||
| const weight = VALID_WEIGHTS.has(weightAttr) ? weightAttr : "regular"; | ||
| const ariaLabel = this.getAttribute("aria-label") || "UAE Dirham"; | ||
| const strokeWidth = DIRHAM_STROKE_MAP[weight]; | ||
| const strokeAttrs = strokeWidth > 0 ? `stroke="${color}" stroke-width="${strokeWidth}" stroke-linejoin="round" paint-order="stroke"` : ""; | ||
| __privateGet(this, _shadow).innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 870" width="${size}" height="${size}" fill="${color}" role="img" aria-label="${ariaLabel}" style="display:inline-block;vertical-align:middle"><path d="${SVG_PATH}" ${strokeAttrs}/></svg>`; | ||
| }; | ||
| if (typeof customElements !== "undefined" && !customElements.get("dirham-symbol")) { | ||
| customElements.define("dirham-symbol", DirhamSymbolElement); | ||
| } | ||
| // src/core/format.ts | ||
| var _fmtCache = /* @__PURE__ */ new Map(); | ||
| function getFormatter(locale, decimals, notation = "standard") { | ||
| const key = `${locale}:${decimals}:${notation}`; | ||
| let fmt = _fmtCache.get(key); | ||
| if (!fmt) { | ||
| fmt = new Intl.NumberFormat(locale, { | ||
| minimumFractionDigits: notation === "compact" ? 0 : decimals, | ||
| maximumFractionDigits: decimals, | ||
| ...notation === "compact" && { notation: "compact", compactDisplay: "short" } | ||
| }); | ||
| _fmtCache.set(key, fmt); | ||
| } | ||
| return fmt; | ||
| } | ||
| function formatDirham(amount, options = {}) { | ||
| if (!Number.isFinite(amount)) { | ||
| throw new RangeError( | ||
| `formatDirham: amount must be a finite number, got ${amount}` | ||
| ); | ||
| } | ||
| const { | ||
| locale = "en-AE", | ||
| decimals = 2, | ||
| useCode = false, | ||
| separator = "\xA0", | ||
| // non-breaking space | ||
| notation = "standard" | ||
| } = options; | ||
| const symbol = useCode ? DIRHAM_CURRENCY_CODE : DIRHAM_UNICODE; | ||
| let symbolFirst; | ||
| if (options.symbolFirst !== void 0) { | ||
| symbolFirst = options.symbolFirst; | ||
| } else { | ||
| symbolFirst = !locale.startsWith("ar"); | ||
| } | ||
| const formatted = getFormatter(locale, decimals, notation).format(amount); | ||
| return symbolFirst ? `${symbol}${separator}${formatted}` : `${formatted}${separator}${symbol}`; | ||
| } | ||
| // src/web-component/DirhamPriceElement.ts | ||
| var SVG_PATH2 = "m88.3 1c0.4 0.6 2.6 3.3 4.7 5.9 15.3 18.2 26.8 47.8 33 85.1 4.1 24.5 4.3 32.2 4.3 125.6v87h-41.8c-38.2 0-42.6-0.2-50.1-1.7-11.8-2.5-24-9.2-32.2-17.8-6.5-6.9-6.3-7.3-5.9 13.6 0.5 17.3 0.7 19.2 3.2 28.6 4 14.9 9.5 26 17.8 35.9 11.3 13.6 22.8 21.2 39.2 26.3 3.5 1 10.9 1.4 37.1 1.6l32.7 0.5v43.3 43.4l-46.1-0.3-46.3-0.3-8-3.2c-9.5-3.8-13.8-6.6-23.1-14.9l-6.8-6.1 0.4 19.1c0.5 17.7 0.6 19.7 3.1 28.7 8.7 31.8 29.7 54.5 57.4 61.9 6.9 1.9 9.6 2 38.5 2.4l30.9 0.4v89.6c0 54.1-0.3 94-0.8 100.8-0.5 6.2-2.1 17.8-3.5 25.9-6.5 37.3-18.2 65.4-35 83.6l-3.4 3.7h169.1c101.1 0 176.7-0.4 187.8-0.9 19.5-1 63-5.3 72.8-7.4 3.1-0.6 8.9-1.5 12.7-2.1 8.1-1.2 21.5-4 40.8-8.9 27.2-6.8 52-15.3 76.3-26.1 7.6-3.4 29.4-14.5 35.2-18 3.1-1.8 6.8-4 8.2-4.7 3.9-2.1 10.4-6.3 19.9-13.1 4.7-3.4 9.4-6.7 10.4-7.4 4.2-2.8 18.7-14.9 25.3-21 25.1-23.1 46.1-48.8 62.4-76.3 2.3-4 5.3-9 6.6-11.1 3.3-5.6 16.9-33.6 18.2-37.8 0.6-1.9 1.4-3.9 1.8-4.3 2.6-3.4 17.6-50.6 19.4-60.9 0.6-3.3 0.9-3.8 3.4-4.3 1.6-0.3 24.9-0.3 51.8-0.1 53.8 0.4 53.8 0.4 65.7 5.9 6.7 3.1 8.7 4.5 16.1 11.2 9.7 8.7 8.8 10.1 8.2-11.7-0.4-12.8-0.9-20.7-1.8-23.9-3.4-12.3-4.2-14.9-7.2-21.1-9.8-21.4-26.2-36.7-47.2-44l-8.2-3-33.4-0.4-33.3-0.5 0.4-11.7c0.4-15.4 0.4-45.9-0.1-61.6l-0.4-12.6 44.6-0.2c38.2-0.2 45.3 0 49.5 1.1 12.6 3.5 21.1 8.3 31.5 17.8l5.8 5.4v-14.8c0-17.6-0.9-25.4-4.5-37-7.1-23.5-21.1-41-41.1-51.8-13-7-13.8-7.2-58.5-7.5-26.2-0.2-39.9-0.6-40.6-1.2-0.6-0.6-1.1-1.6-1.1-2.4 0-0.8-1.5-7.1-3.5-13.9-23.4-82.7-67.1-148.4-131-197.1-8.7-6.7-30-20.8-38.6-25.6-3.3-1.9-6.9-3.9-7.8-4.5-4.2-2.3-28.3-14.1-34.3-16.6-3.6-1.6-8.3-3.6-10.4-4.4-35.3-15.3-94.5-29.8-139.7-34.3-7.4-0.7-17.2-1.8-21.7-2.2-20.4-2.3-48.7-2.6-209.4-2.6-135.8 0-169.9 0.3-169.4 1zm330.7 43.3c33.8 2 54.6 4.6 78.9 10.5 74.2 17.6 126.4 54.8 164.3 117 3.5 5.8 18.3 36 20.5 42.1 10.5 28.3 15.6 45.1 20.1 67.3 1.1 5.4 2.6 12.6 3.3 16 0.7 3.3 1 6.4 0.7 6.7-0.5 0.4-100.9 0.6-223.3 0.5l-222.5-0.2-0.3-128.5c-0.1-70.6 0-129.3 0.3-130.4l0.4-1.9h71.1c39 0 78 0.4 86.5 0.9zm297.5 350.3c0.7 4.3 0.7 77.3 0 80.9l-0.6 2.7-227.5-0.2-227.4-0.3-0.2-42.4c-0.2-23.3 0-42.7 0.2-43.1 0.3-0.5 97.2-0.8 227.7-0.8h227.2zm-10.2 171.7c0.5 1.5-1.9 13.8-6.8 33.8-5.6 22.5-13.2 45.2-20.9 62-3.8 8.6-13.3 27.2-15.6 30.7-1.1 1.6-4.3 6.7-7.1 11.2-18 28.2-43.7 53.9-73 72.9-10.7 6.8-32.7 18.4-38.6 20.2-1.2 0.3-2.5 0.9-3 1.3-0.7 0.6-9.8 4-20.4 7.8-19.5 6.9-56.6 14.4-86.4 17.5-19.3 1.9-22.4 2-96.7 2h-76.9v-129.7-129.8l220.9-0.4c121.5-0.2 221.6-0.5 222.4-0.7 0.9-0.1 1.8 0.5 2.1 1.2z"; | ||
| var VALID_WEIGHTS2 = /* @__PURE__ */ new Set([ | ||
| "thin", | ||
| "extralight", | ||
| "light", | ||
| "regular", | ||
| "medium", | ||
| "semibold", | ||
| "bold", | ||
| "extrabold", | ||
| "black" | ||
| ]); | ||
| var _shadow2, _DirhamPriceElement_instances, render_fn2, escape_fn; | ||
| var DirhamPriceElement = class extends HTMLElement { | ||
| constructor() { | ||
| super(); | ||
| __privateAdd(this, _DirhamPriceElement_instances); | ||
| __privateAdd(this, _shadow2); | ||
| __privateSet(this, _shadow2, this.attachShadow({ mode: "open" })); | ||
| __privateMethod(this, _DirhamPriceElement_instances, render_fn2).call(this); | ||
| } | ||
| static get observedAttributes() { | ||
| return [ | ||
| "amount", | ||
| "locale", | ||
| "decimals", | ||
| "notation", | ||
| "use-code", | ||
| "symbol-size", | ||
| "weight", | ||
| "currency" | ||
| ]; | ||
| } | ||
| attributeChangedCallback() { | ||
| __privateMethod(this, _DirhamPriceElement_instances, render_fn2).call(this); | ||
| } | ||
| }; | ||
| _shadow2 = new WeakMap(); | ||
| _DirhamPriceElement_instances = new WeakSet(); | ||
| render_fn2 = function() { | ||
| const amountStr = this.getAttribute("amount"); | ||
| const amount = amountStr !== null ? Number(amountStr) : 0; | ||
| const locale = this.getAttribute("locale") || "en-AE"; | ||
| const decimals = Number(this.getAttribute("decimals") ?? "2"); | ||
| const notation = this.getAttribute("notation") === "compact" ? "compact" : "standard"; | ||
| const useCode = this.hasAttribute("use-code"); | ||
| const symbolSize = this.getAttribute("symbol-size") || "1em"; | ||
| const weightAttr = this.getAttribute("weight") || "regular"; | ||
| const weight = VALID_WEIGHTS2.has(weightAttr) ? weightAttr : "regular"; | ||
| const currency = this.getAttribute("currency") || void 0; | ||
| const symbolFirst = !locale.startsWith("ar"); | ||
| let formatted; | ||
| if (!Number.isFinite(amount)) { | ||
| formatted = "\u2014"; | ||
| } else { | ||
| formatted = formatDirham(amount, { | ||
| locale, | ||
| decimals, | ||
| useCode: true, | ||
| notation | ||
| }).replace("AED", "").trim(); | ||
| } | ||
| if (useCode) { | ||
| const code = currency || "AED"; | ||
| const text = symbolFirst ? `${code}\xA0${formatted}` : `${formatted}\xA0${code}`; | ||
| __privateGet(this, _shadow2).innerHTML = `<span style="white-space:nowrap">${__privateMethod(this, _DirhamPriceElement_instances, escape_fn).call(this, text)}</span>`; | ||
| return; | ||
| } | ||
| const strokeWidth = DIRHAM_STROKE_MAP[weight]; | ||
| const strokeAttrs = strokeWidth > 0 ? ` stroke="currentColor" stroke-width="${strokeWidth}" stroke-linejoin="round" paint-order="stroke"` : ""; | ||
| const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 870" width="${__privateMethod(this, _DirhamPriceElement_instances, escape_fn).call(this, String(symbolSize))}" height="${__privateMethod(this, _DirhamPriceElement_instances, escape_fn).call(this, String(symbolSize))}" fill="currentColor" role="img" aria-label="UAE Dirham" style="display:inline-block;vertical-align:middle"><path d="${SVG_PATH2}"${strokeAttrs}/></svg>`; | ||
| const parts = symbolFirst ? `${svg}\xA0${__privateMethod(this, _DirhamPriceElement_instances, escape_fn).call(this, formatted)}` : `${__privateMethod(this, _DirhamPriceElement_instances, escape_fn).call(this, formatted)}\xA0${svg}`; | ||
| __privateGet(this, _shadow2).innerHTML = `<span style="white-space:nowrap">${parts}</span>`; | ||
| }; | ||
| escape_fn = function(str) { | ||
| return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """); | ||
| }; | ||
| if (typeof customElements !== "undefined" && !customElements.get("dirham-price")) { | ||
| customElements.define("dirham-price", DirhamPriceElement); | ||
| } | ||
| export { DirhamPriceElement, DirhamSymbolElement }; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"sources":["../../src/core/constants.ts","../../src/web-component/DirhamSymbolElement.ts","../../src/core/format.ts","../../src/web-component/DirhamPriceElement.ts"],"names":["SVG_PATH","VALID_WEIGHTS","_shadow","render_fn"],"mappings":";;;;;;;;;;AAgBO,IAAM,cAAA,GAAiB,QAAA;AASvB,IAAM,oBAAA,GAAuB,KAAA;AAsD7B,IAAM,iBAAA,GAAkD;AAAA,EAC9D,IAAA,EAAM,CAAA;AAAA,EACN,UAAA,EAAY,CAAA;AAAA,EACZ,KAAA,EAAO,CAAA;AAAA,EACP,OAAA,EAAS,CAAA;AAAA,EACT,MAAA,EAAQ,CAAA;AAAA,EACR,QAAA,EAAU,EAAA;AAAA,EACV,IAAA,EAAM,EAAA;AAAA,EACN,SAAA,EAAW,EAAA;AAAA,EACX,KAAA,EAAO;AACR,CAAA;;;ACvFA,IAAM,QAAA,GACL,25EAAA;AAED,IAAM,aAAA,uBAAoB,GAAA,CAAY;AAAA,EACrC,MAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA,WAAA;AAAA,EACA;AACD,CAAC,CAAA;AAfD,IAAA,OAAA,EAAA,8BAAA,EAAA,SAAA;AA+BO,IAAM,mBAAA,GAAN,cAAkC,WAAA,CAAY;AAAA,EAOpD,WAAA,GAAc;AACb,IAAA,KAAA,EAAM;AARD,IAAA,YAAA,CAAA,IAAA,EAAA,8BAAA,CAAA;AAKN,IAAA,YAAA,CAAA,IAAA,EAAA,OAAA,CAAA;AAIC,IAAA,YAAA,CAAA,IAAA,EAAK,SAAU,IAAA,CAAK,YAAA,CAAa,EAAE,IAAA,EAAM,QAAQ,CAAA,CAAA;AACjD,IAAA,eAAA,CAAA,IAAA,EAAK,8BAAA,EAAA,SAAA,CAAA,CAAL,IAAA,CAAA,IAAA,CAAA;AAAA,EACD;AAAA,EAVA,WAAW,kBAAA,GAAqB;AAC/B,IAAA,OAAO,CAAC,MAAA,EAAQ,OAAA,EAAS,QAAA,EAAU,YAAY,CAAA;AAAA,EAChD;AAAA,EAUA,wBAAA,GAA2B;AAC1B,IAAA,eAAA,CAAA,IAAA,EAAK,8BAAA,EAAA,SAAA,CAAA,CAAL,IAAA,CAAA,IAAA,CAAA;AAAA,EACD;AAmBD;AA7BC,OAAA,GAAA,IAAA,OAAA,EAAA;AALM,8BAAA,GAAA,IAAA,OAAA,EAAA;AAiBN,SAAA,GAAO,WAAG;AACT,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,YAAA,CAAa,MAAM,CAAA,IAAK,IAAA;AAC1C,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,YAAA,CAAa,OAAO,CAAA,IAAK,cAAA;AAC5C,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,YAAA,CAAa,QAAQ,CAAA,IAAK,SAAA;AAClD,EAAA,MAAM,MAAA,GAAuB,aAAA,CAAc,GAAA,CAAI,UAAU,IACrD,UAAA,GACD,SAAA;AACH,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,YAAA,CAAa,YAAY,CAAA,IAAK,YAAA;AACrD,EAAA,MAAM,WAAA,GAAc,kBAAkB,MAAM,CAAA;AAE5C,EAAA,MAAM,cACL,WAAA,GAAc,CAAA,GACX,WAAW,KAAK,CAAA,gBAAA,EAAmB,WAAW,CAAA,8CAAA,CAAA,GAC9C,EAAA;AAEJ,EAAA,YAAA,CAAA,IAAA,EAAK,OAAA,CAAA,CAAQ,SAAA,GAAY,CAAA,sEAAA,EAAyE,IAAI,CAAA,UAAA,EAAa,IAAI,CAAA,QAAA,EAAW,KAAK,CAAA,yBAAA,EAA4B,SAAS,CAAA,8DAAA,EAAiE,QAAQ,KAAK,WAAW,CAAA,QAAA,CAAA;AACtQ,CAAA;AAGD,IACC,OAAO,cAAA,KAAmB,WAAA,IAC1B,CAAC,cAAA,CAAe,GAAA,CAAI,eAAe,CAAA,EAClC;AACD,EAAA,cAAA,CAAe,MAAA,CAAO,iBAAiB,mBAAmB,CAAA;AAC3D;;;AC9DA,IAAM,SAAA,uBAAgB,GAAA,EAA+B;AAErD,SAAS,YAAA,CACR,MAAA,EACA,QAAA,EACA,QAAA,GAAmC,UAAA,EACf;AACpB,EAAA,MAAM,MAAM,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,QAAQ,IAAI,QAAQ,CAAA,CAAA;AAC7C,EAAA,IAAI,GAAA,GAAM,SAAA,CAAU,GAAA,CAAI,GAAG,CAAA;AAC3B,EAAA,IAAI,CAAC,GAAA,EAAK;AACT,IAAA,GAAA,GAAM,IAAI,IAAA,CAAK,YAAA,CAAa,MAAA,EAAQ;AAAA,MACnC,qBAAA,EAAuB,QAAA,KAAa,SAAA,GAAY,CAAA,GAAI,QAAA;AAAA,MACpD,qBAAA,EAAuB,QAAA;AAAA,MACvB,GAAI,QAAA,KAAa,SAAA,IAAa,EAAE,QAAA,EAAU,SAAA,EAAW,gBAAgB,OAAA;AAAQ,KAC7E,CAAA;AACD,IAAA,SAAA,CAAU,GAAA,CAAI,KAAK,GAAG,CAAA;AAAA,EACvB;AACA,EAAA,OAAO,GAAA;AACR;AA2DO,SAAS,YAAA,CACf,MAAA,EACA,OAAA,GAA+B,EAAC,EACvB;AACT,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,EAAG;AAC7B,IAAA,MAAM,IAAI,UAAA;AAAA,MACT,qDAAqD,MAAM,CAAA;AAAA,KAC5D;AAAA,EACD;AAEA,EAAA,MAAM;AAAA,IACL,MAAA,GAAS,OAAA;AAAA,IACT,QAAA,GAAW,CAAA;AAAA,IACX,OAAA,GAAU,KAAA;AAAA,IACV,SAAA,GAAY,MAAA;AAAA;AAAA,IACZ,QAAA,GAAW;AAAA,GACZ,GAAI,OAAA;AAEJ,EAAA,MAAM,MAAA,GAAS,UAAU,oBAAA,GAAuB,cAAA;AAGhD,EAAA,IAAI,WAAA;AACJ,EAAA,IAAI,OAAA,CAAQ,gBAAgB,MAAA,EAAW;AACtC,IAAA,WAAA,GAAc,OAAA,CAAQ,WAAA;AAAA,EACvB,CAAA,MAAO;AAEN,IAAA,WAAA,GAAc,CAAC,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AAAA,EACtC;AAGA,EAAA,MAAM,YAAY,YAAA,CAAa,MAAA,EAAQ,UAAU,QAAQ,CAAA,CAAE,OAAO,MAAM,CAAA;AAExE,EAAA,OAAO,WAAA,GACJ,CAAA,EAAG,MAAM,CAAA,EAAG,SAAS,CAAA,EAAG,SAAS,CAAA,CAAA,GACjC,CAAA,EAAG,SAAS,CAAA,EAAG,SAAS,GAAG,MAAM,CAAA,CAAA;AACrC;;;ACvHA,IAAMA,SAAAA,GACL,25EAAA;AAED,IAAMC,cAAAA,uBAAoB,GAAA,CAAY;AAAA,EACrC,MAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA,WAAA;AAAA,EACA;AACD,CAAC,CAAA;AAhBD,IAAAC,QAAAA,EAAA,+BAAAC,UAAAA,EAAA,SAAA;AAqCO,IAAM,kBAAA,GAAN,cAAiC,WAAA,CAAY;AAAA,EAgBnD,WAAA,GAAc;AACb,IAAA,KAAA,EAAM;AAjBD,IAAA,YAAA,CAAA,IAAA,EAAA,6BAAA,CAAA;AAcN,IAAA,YAAA,CAAA,IAAA,EAAAD,QAAAA,CAAAA;AAIC,IAAA,YAAA,CAAA,IAAA,EAAKA,UAAU,IAAA,CAAK,YAAA,CAAa,EAAE,IAAA,EAAM,QAAQ,CAAA,CAAA;AACjD,IAAA,eAAA,CAAA,IAAA,EAAK,+BAAAC,UAAAA,CAAAA,CAAL,IAAA,CAAA,IAAA,CAAA;AAAA,EACD;AAAA,EAnBA,WAAW,kBAAA,GAAqB;AAC/B,IAAA,OAAO;AAAA,MACN,QAAA;AAAA,MACA,QAAA;AAAA,MACA,UAAA;AAAA,MACA,UAAA;AAAA,MACA,UAAA;AAAA,MACA,aAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACD;AAAA,EACD;AAAA,EAUA,wBAAA,GAA2B;AAC1B,IAAA,eAAA,CAAA,IAAA,EAAK,+BAAAA,UAAAA,CAAAA,CAAL,IAAA,CAAA,IAAA,CAAA;AAAA,EACD;AAiED;AA3ECD,QAAAA,GAAA,IAAA,OAAA,EAAA;AAdM,6BAAA,GAAA,IAAA,OAAA,EAAA;AA0BNC,UAAAA,GAAO,WAAG;AACT,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,YAAA,CAAa,QAAQ,CAAA;AAC5C,EAAA,MAAM,MAAA,GAAS,SAAA,KAAc,IAAA,GAAO,MAAA,CAAO,SAAS,CAAA,GAAI,CAAA;AACxD,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,YAAA,CAAa,QAAQ,CAAA,IAAK,OAAA;AAC9C,EAAA,MAAM,WAAW,MAAA,CAAO,IAAA,CAAK,YAAA,CAAa,UAAU,KAAK,GAAG,CAAA;AAC5D,EAAA,MAAM,WACL,IAAA,CAAK,YAAA,CAAa,UAAU,CAAA,KAAM,YAAY,SAAA,GAAY,UAAA;AAC3D,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,YAAA,CAAa,UAAU,CAAA;AAC5C,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,YAAA,CAAa,aAAa,CAAA,IAAK,KAAA;AACvD,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,YAAA,CAAa,QAAQ,CAAA,IAAK,SAAA;AAClD,EAAA,MAAM,MAAA,GAAuBF,cAAAA,CAAc,GAAA,CAAI,UAAU,IACrD,UAAA,GACD,SAAA;AACH,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,YAAA,CAAa,UAAU,CAAA,IAAK,MAAA;AAElD,EAAA,MAAM,WAAA,GAAc,CAAC,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AAG3C,EAAA,IAAI,SAAA;AACJ,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,EAAG;AAC7B,IAAA,SAAA,GAAY,QAAA;AAAA,EACb,CAAA,MAAO;AACN,IAAA,SAAA,GAAY,aAAa,MAAA,EAAQ;AAAA,MAChC,MAAA;AAAA,MACA,QAAA;AAAA,MACA,OAAA,EAAS,IAAA;AAAA,MACT;AAAA,KACA,CAAA,CACC,OAAA,CAAQ,KAAA,EAAO,EAAE,EACjB,IAAA,EAAK;AAAA,EACR;AAEA,EAAA,IAAI,OAAA,EAAS;AACZ,IAAA,MAAM,OAAO,QAAA,IAAY,KAAA;AACzB,IAAA,MAAM,IAAA,GAAO,WAAA,GACV,CAAA,EAAG,IAAI,CAAA,IAAA,EAAS,SAAS,CAAA,CAAA,GACzB,CAAA,EAAG,SAAS,CAAA,IAAA,EAAS,IAAI,CAAA,CAAA;AAC5B,IAAA,YAAA,CAAA,IAAA,EAAKC,UAAQ,SAAA,GAAY,CAAA,iCAAA,EAAoC,eAAA,CAAA,IAAA,EAAK,6BAAA,EAAA,SAAA,CAAA,CAAL,WAAa,IAAA,CAAK,CAAA,OAAA,CAAA;AAC/E,IAAA;AAAA,EACD;AAEA,EAAA,MAAM,WAAA,GAAc,kBAAkB,MAAM,CAAA;AAC5C,EAAA,MAAM,WAAA,GACL,WAAA,GAAc,CAAA,GACX,CAAA,qCAAA,EAAwC,WAAW,CAAA,8CAAA,CAAA,GACnD,EAAA;AAEJ,EAAA,MAAM,MAAM,CAAA,sEAAA,EAAyE,eAAA,CAAA,IAAA,EAAK,0CAAL,IAAA,CAAA,IAAA,EAAa,MAAA,CAAO,UAAU,CAAA,CAAE,CAAA,UAAA,EAAa,eAAA,CAAA,IAAA,EAAK,6BAAA,EAAA,SAAA,CAAA,CAAL,WAAa,MAAA,CAAO,UAAU,EAAE,CAAA,qHAAA,EAAwHF,SAAQ,IAAI,WAAW,CAAA,QAAA,CAAA;AAEjT,EAAA,MAAM,QAAQ,WAAA,GACX,CAAA,EAAG,GAAG,CAAA,IAAA,EAAS,sBAAK,6BAAA,EAAA,SAAA,CAAA,CAAL,IAAA,CAAA,IAAA,EAAa,SAAA,CAAU,CAAA,CAAA,GACtC,GAAG,eAAA,CAAA,IAAA,EAAK,6BAAA,EAAA,SAAA,CAAA,CAAL,IAAA,CAAA,IAAA,EAAa,SAAA,CAAU,OAAS,GAAG,CAAA,CAAA;AAEzC,EAAA,YAAA,CAAA,IAAA,EAAKE,QAAAA,CAAAA,CAAQ,SAAA,GAAY,CAAA,iCAAA,EAAoC,KAAK,CAAA,OAAA,CAAA;AACnE,CAAA;AAEA,SAAA,GAAO,SAAC,GAAA,EAAqB;AAC5B,EAAA,OAAO,GAAA,CACL,OAAA,CAAQ,IAAA,EAAM,OAAO,EACrB,OAAA,CAAQ,IAAA,EAAM,MAAM,CAAA,CACpB,QAAQ,IAAA,EAAM,MAAM,CAAA,CACpB,OAAA,CAAQ,MAAM,QAAQ,CAAA;AACzB,CAAA;AAGD,IACC,OAAO,cAAA,KAAmB,WAAA,IAC1B,CAAC,cAAA,CAAe,GAAA,CAAI,cAAc,CAAA,EACjC;AACD,EAAA,cAAA,CAAe,MAAA,CAAO,gBAAgB,kBAAkB,CAAA;AACzD","file":"index.js","sourcesContent":["/**\n * UAE Dirham currency symbol constants.\n *\n * This package maps the Dirham glyph to the official Unicode codepoint U+20C3\n * (UAE DIRHAM SIGN) via a custom web font. The codepoint was accepted by the\n * Unicode Technical Committee for Unicode 18.0 (expected September 2026).\n *\n * Until system fonts ship native U+20C3 glyphs, the bundled web font provides\n * the rendering. When OS/font support lands, the web font becomes optional;\n * zero migration required.\n *\n * @module dirham\n * @see https://www.unicode.org/alloc/Pipeline.html\n */\n\n/** Unicode character for the Dirham symbol (U+20C3, requires Dirham web font until system fonts support it) */\nexport const DIRHAM_UNICODE = \"\\u20C3\";\n\n/** HTML entity for the Dirham symbol */\nexport const DIRHAM_HTML_ENTITY = \"⃃\";\n\n/** CSS content value for use in `::before` / `::after` pseudo-elements */\nexport const DIRHAM_CSS_CONTENT = \"\\\\20C3\";\n\n/** ISO 4217 currency code for UAE Dirham */\nexport const DIRHAM_CURRENCY_CODE = \"AED\";\n\n/** Arabic text representation of the Dirham symbol (د.إ) */\nexport const DIRHAM_SYMBOL_TEXT = \"د.إ\";\n\n/** The font family name used for the Dirham web font */\nexport const DIRHAM_FONT_FAMILY = \"Dirham\";\n\n/** CSS class name for the Dirham icon */\nexport const DIRHAM_CSS_CLASS = \"dirham-symbol\";\n\n/** Unicode codepoint as a number (0x20C3) */\nexport const DIRHAM_CODEPOINT = 0x20c3;\n\n// ── Font weight mapping ─────────────────────────────────────────────────\n\n/**\n * Supported visual weights for the Dirham symbol SVG component.\n *\n * Because the Dirham symbol is not yet in standard fonts (until Unicode 18.0),\n * weight simulation is applied via SVG stroke to match surrounding text weight,\n * similar to how $, €, £ adapt to their font's weight.\n */\nexport type DirhamWeight =\n\t| \"thin\"\n\t| \"extralight\"\n\t| \"light\"\n\t| \"regular\"\n\t| \"medium\"\n\t| \"semibold\"\n\t| \"bold\"\n\t| \"extrabold\"\n\t| \"black\";\n\n/**\n * Map from weight name to CSS `font-weight` numeric value.\n * Used for matching the symbol weight to surrounding text.\n */\nexport const DIRHAM_WEIGHT_MAP: Record<DirhamWeight, number> = {\n\tthin: 100,\n\textralight: 200,\n\tlight: 300,\n\tregular: 400,\n\tmedium: 500,\n\tsemibold: 600,\n\tbold: 700,\n\textrabold: 800,\n\tblack: 900,\n};\n\n/**\n * SVG stroke-width values that simulate font weight.\n * Applied with `paint-order: stroke` so stroke renders behind fill.\n */\nexport const DIRHAM_STROKE_MAP: Record<DirhamWeight, number> = {\n\tthin: 0,\n\textralight: 0,\n\tlight: 0,\n\tregular: 0,\n\tmedium: 8,\n\tsemibold: 16,\n\tbold: 24,\n\textrabold: 36,\n\tblack: 48,\n};\n","import { DIRHAM_STROKE_MAP, type DirhamWeight } from \"../core/constants\";\n\nconst SVG_PATH =\n\t\"m88.3 1c0.4 0.6 2.6 3.3 4.7 5.9 15.3 18.2 26.8 47.8 33 85.1 4.1 24.5 4.3 32.2 4.3 125.6v87h-41.8c-38.2 0-42.6-0.2-50.1-1.7-11.8-2.5-24-9.2-32.2-17.8-6.5-6.9-6.3-7.3-5.9 13.6 0.5 17.3 0.7 19.2 3.2 28.6 4 14.9 9.5 26 17.8 35.9 11.3 13.6 22.8 21.2 39.2 26.3 3.5 1 10.9 1.4 37.1 1.6l32.7 0.5v43.3 43.4l-46.1-0.3-46.3-0.3-8-3.2c-9.5-3.8-13.8-6.6-23.1-14.9l-6.8-6.1 0.4 19.1c0.5 17.7 0.6 19.7 3.1 28.7 8.7 31.8 29.7 54.5 57.4 61.9 6.9 1.9 9.6 2 38.5 2.4l30.9 0.4v89.6c0 54.1-0.3 94-0.8 100.8-0.5 6.2-2.1 17.8-3.5 25.9-6.5 37.3-18.2 65.4-35 83.6l-3.4 3.7h169.1c101.1 0 176.7-0.4 187.8-0.9 19.5-1 63-5.3 72.8-7.4 3.1-0.6 8.9-1.5 12.7-2.1 8.1-1.2 21.5-4 40.8-8.9 27.2-6.8 52-15.3 76.3-26.1 7.6-3.4 29.4-14.5 35.2-18 3.1-1.8 6.8-4 8.2-4.7 3.9-2.1 10.4-6.3 19.9-13.1 4.7-3.4 9.4-6.7 10.4-7.4 4.2-2.8 18.7-14.9 25.3-21 25.1-23.1 46.1-48.8 62.4-76.3 2.3-4 5.3-9 6.6-11.1 3.3-5.6 16.9-33.6 18.2-37.8 0.6-1.9 1.4-3.9 1.8-4.3 2.6-3.4 17.6-50.6 19.4-60.9 0.6-3.3 0.9-3.8 3.4-4.3 1.6-0.3 24.9-0.3 51.8-0.1 53.8 0.4 53.8 0.4 65.7 5.9 6.7 3.1 8.7 4.5 16.1 11.2 9.7 8.7 8.8 10.1 8.2-11.7-0.4-12.8-0.9-20.7-1.8-23.9-3.4-12.3-4.2-14.9-7.2-21.1-9.8-21.4-26.2-36.7-47.2-44l-8.2-3-33.4-0.4-33.3-0.5 0.4-11.7c0.4-15.4 0.4-45.9-0.1-61.6l-0.4-12.6 44.6-0.2c38.2-0.2 45.3 0 49.5 1.1 12.6 3.5 21.1 8.3 31.5 17.8l5.8 5.4v-14.8c0-17.6-0.9-25.4-4.5-37-7.1-23.5-21.1-41-41.1-51.8-13-7-13.8-7.2-58.5-7.5-26.2-0.2-39.9-0.6-40.6-1.2-0.6-0.6-1.1-1.6-1.1-2.4 0-0.8-1.5-7.1-3.5-13.9-23.4-82.7-67.1-148.4-131-197.1-8.7-6.7-30-20.8-38.6-25.6-3.3-1.9-6.9-3.9-7.8-4.5-4.2-2.3-28.3-14.1-34.3-16.6-3.6-1.6-8.3-3.6-10.4-4.4-35.3-15.3-94.5-29.8-139.7-34.3-7.4-0.7-17.2-1.8-21.7-2.2-20.4-2.3-48.7-2.6-209.4-2.6-135.8 0-169.9 0.3-169.4 1zm330.7 43.3c33.8 2 54.6 4.6 78.9 10.5 74.2 17.6 126.4 54.8 164.3 117 3.5 5.8 18.3 36 20.5 42.1 10.5 28.3 15.6 45.1 20.1 67.3 1.1 5.4 2.6 12.6 3.3 16 0.7 3.3 1 6.4 0.7 6.7-0.5 0.4-100.9 0.6-223.3 0.5l-222.5-0.2-0.3-128.5c-0.1-70.6 0-129.3 0.3-130.4l0.4-1.9h71.1c39 0 78 0.4 86.5 0.9zm297.5 350.3c0.7 4.3 0.7 77.3 0 80.9l-0.6 2.7-227.5-0.2-227.4-0.3-0.2-42.4c-0.2-23.3 0-42.7 0.2-43.1 0.3-0.5 97.2-0.8 227.7-0.8h227.2zm-10.2 171.7c0.5 1.5-1.9 13.8-6.8 33.8-5.6 22.5-13.2 45.2-20.9 62-3.8 8.6-13.3 27.2-15.6 30.7-1.1 1.6-4.3 6.7-7.1 11.2-18 28.2-43.7 53.9-73 72.9-10.7 6.8-32.7 18.4-38.6 20.2-1.2 0.3-2.5 0.9-3 1.3-0.7 0.6-9.8 4-20.4 7.8-19.5 6.9-56.6 14.4-86.4 17.5-19.3 1.9-22.4 2-96.7 2h-76.9v-129.7-129.8l220.9-0.4c121.5-0.2 221.6-0.5 222.4-0.7 0.9-0.1 1.8 0.5 2.1 1.2z\";\n\nconst VALID_WEIGHTS = new Set<string>([\n\t\"thin\",\n\t\"extralight\",\n\t\"light\",\n\t\"regular\",\n\t\"medium\",\n\t\"semibold\",\n\t\"bold\",\n\t\"extrabold\",\n\t\"black\",\n]);\n\n/**\n * `<dirham-symbol>` — framework-agnostic Web Component.\n *\n * @example\n * ```html\n * <script type=\"module\">\n * import \"dirham/web-component\";\n * </script>\n *\n * <dirham-symbol size=\"24\" weight=\"bold\"></dirham-symbol>\n * ```\n *\n * Attributes: size, color, weight, aria-label\n */\nexport class DirhamSymbolElement extends HTMLElement {\n\tstatic get observedAttributes() {\n\t\treturn [\"size\", \"color\", \"weight\", \"aria-label\"];\n\t}\n\n\t#shadow: ShadowRoot;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.#shadow = this.attachShadow({ mode: \"open\" });\n\t\tthis.#render();\n\t}\n\n\tattributeChangedCallback() {\n\t\tthis.#render();\n\t}\n\n\t#render() {\n\t\tconst size = this.getAttribute(\"size\") || \"24\";\n\t\tconst color = this.getAttribute(\"color\") || \"currentColor\";\n\t\tconst weightAttr = this.getAttribute(\"weight\") || \"regular\";\n\t\tconst weight: DirhamWeight = VALID_WEIGHTS.has(weightAttr)\n\t\t\t? (weightAttr as DirhamWeight)\n\t\t\t: \"regular\";\n\t\tconst ariaLabel = this.getAttribute(\"aria-label\") || \"UAE Dirham\";\n\t\tconst strokeWidth = DIRHAM_STROKE_MAP[weight];\n\n\t\tconst strokeAttrs =\n\t\t\tstrokeWidth > 0\n\t\t\t\t? `stroke=\"${color}\" stroke-width=\"${strokeWidth}\" stroke-linejoin=\"round\" paint-order=\"stroke\"`\n\t\t\t\t: \"\";\n\n\t\tthis.#shadow.innerHTML = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1000 870\" width=\"${size}\" height=\"${size}\" fill=\"${color}\" role=\"img\" aria-label=\"${ariaLabel}\" style=\"display:inline-block;vertical-align:middle\"><path d=\"${SVG_PATH}\" ${strokeAttrs}/></svg>`;\n\t}\n}\n\nif (\n\ttypeof customElements !== \"undefined\" &&\n\t!customElements.get(\"dirham-symbol\")\n) {\n\tcustomElements.define(\"dirham-symbol\", DirhamSymbolElement);\n}\n","import {\n\tDIRHAM_CURRENCY_CODE,\n\tDIRHAM_SYMBOL_TEXT,\n\tDIRHAM_UNICODE,\n} from \"./constants\";\n\n// ─── Intl.NumberFormat cache ─────────────────────────────────────────────────\n// Constructing Intl.NumberFormat is expensive (~µs). Cache instances keyed on\n// \"locale:decimals\" so repeated calls (e.g., rendering a price list) reuse\n// the same formatter instead of allocating a new object each time.\nconst _fmtCache = new Map<string, Intl.NumberFormat>();\n\nfunction getFormatter(\n\tlocale: string,\n\tdecimals: number,\n\tnotation: \"standard\" | \"compact\" = \"standard\",\n): Intl.NumberFormat {\n\tconst key = `${locale}:${decimals}:${notation}`;\n\tlet fmt = _fmtCache.get(key);\n\tif (!fmt) {\n\t\tfmt = new Intl.NumberFormat(locale, {\n\t\t\tminimumFractionDigits: notation === \"compact\" ? 0 : decimals,\n\t\t\tmaximumFractionDigits: decimals,\n\t\t\t...(notation === \"compact\" && { notation: \"compact\", compactDisplay: \"short\" }),\n\t\t});\n\t\t_fmtCache.set(key, fmt);\n\t}\n\treturn fmt;\n}\n\n/**\n * Options for formatting a Dirham amount.\n */\nexport interface FormatDirhamOptions {\n\t/**\n\t * Locale string for number formatting.\n\t * @default \"en-AE\"\n\t */\n\tlocale?: string;\n\n\t/**\n\t * Number of decimal places.\n\t * @default 2\n\t */\n\tdecimals?: number;\n\n\t/**\n\t * Whether to place the symbol before the amount.\n\t * When `undefined`, determined by locale:\n\t * - Arabic locales (ar-*): symbol after amount\n\t * - Other locales: symbol before amount\n\t */\n\tsymbolFirst?: boolean;\n\n\t/**\n\t * Use ISO currency code (AED) instead of the symbol.\n\t * @default false\n\t */\n\tuseCode?: boolean;\n\n\t/**\n\t * Separator between symbol and amount.\n\t * @default \" \" (non-breaking space)\n\t */\n\tseparator?: string;\n\n\t/**\n\t * Number notation style.\n\t * - `\"standard\"` — full digits (e.g. 1,500,000.00)\n\t * - `\"compact\"` — abbreviated (e.g. 1.5M)\n\t * @default \"standard\"\n\t */\n\tnotation?: \"standard\" | \"compact\";\n}\n\n/**\n * Format a number as a Dirham currency string.\n *\n * @example\n * ```ts\n * formatDirham(100); // \"\\u20C3 100.00\"\n * formatDirham(1234.5); // \"\\u20C3 1,234.50\"\n * formatDirham(100, { locale: \"ar-AE\" }); // \"100.00 \\u20C3\"\n * formatDirham(100, { useCode: true }); // \"AED 100.00\"\n * formatDirham(1500000, { notation: \"compact\" }); // \"\\u20C3 1.5M\"\n * ```\n */\nexport function formatDirham(\n\tamount: number,\n\toptions: FormatDirhamOptions = {},\n): string {\n\tif (!Number.isFinite(amount)) {\n\t\tthrow new RangeError(\n\t\t\t`formatDirham: amount must be a finite number, got ${amount}`,\n\t\t);\n\t}\n\n\tconst {\n\t\tlocale = \"en-AE\",\n\t\tdecimals = 2,\n\t\tuseCode = false,\n\t\tseparator = \"\\u00A0\", // non-breaking space\n\t\tnotation = \"standard\",\n\t} = options;\n\n\tconst symbol = useCode ? DIRHAM_CURRENCY_CODE : DIRHAM_UNICODE;\n\n\t// Determine symbol placement\n\tlet symbolFirst: boolean;\n\tif (options.symbolFirst !== undefined) {\n\t\tsymbolFirst = options.symbolFirst;\n\t} else {\n\t\t// Arabic locales place symbol after amount\n\t\tsymbolFirst = !locale.startsWith(\"ar\");\n\t}\n\n\t// Format the number (use cached formatter)\n\tconst formatted = getFormatter(locale, decimals, notation).format(amount);\n\n\treturn symbolFirst\n\t\t? `${symbol}${separator}${formatted}`\n\t\t: `${formatted}${separator}${symbol}`;\n}\n\n/**\n * Options for parsing a Dirham-formatted string.\n */\nexport interface ParseDirhamOptions {\n\t/**\n\t * Normalize Arabic-Indic digits (٠١٢٣٤٥٦٧٨٩ / U+0660–U+0669) to ASCII\n\t * digits before parsing. Enables round-tripping strings produced by\n\t * `formatDirham` with Arabic locales (e.g. `\"ar-AE\"`).\n\t * @default true\n\t */\n\tnormalizeArabicNumerals?: boolean;\n}\n\n/**\n * Parse a Dirham-formatted string back to a number.\n * Strips currency symbols, codes, and formatting characters.\n * By default also normalizes Arabic-Indic digits so strings produced by\n * `formatDirham({ locale: \"ar-AE\" })` round-trip correctly.\n *\n * @example\n * ```ts\n * parseDirham(\"\\u20C3 1,234.50\"); // 1234.5\n * parseDirham(\"AED 100.00\"); // 100\n * parseDirham(\"١٬٢٣٤٫٥٠ \\u20C3\"); // 1234.5\n * parseDirham(\"١٠٠٫٠٠ \\u20C3\", { normalizeArabicNumerals: false }); // throws\n * ```\n */\nexport function parseDirham(\n\tvalue: string,\n\toptions: ParseDirhamOptions = {},\n): number {\n\tconst { normalizeArabicNumerals = true } = options;\n\n\tlet cleaned = value\n\t\t.replaceAll(DIRHAM_UNICODE, \"\")\n\t\t.replaceAll(DIRHAM_SYMBOL_TEXT, \"\")\n\t\t.replaceAll(DIRHAM_CURRENCY_CODE, \"\")\n\t\t.replace(/[,\\s\\u00A0\\u066C]/g, \"\") // ASCII comma, whitespace, NBSP, Arabic thousands sep\n\t\t.trim();\n\n\tif (normalizeArabicNumerals) {\n\t\t// Arabic-Indic digits U+0660–U+0669 → ASCII 0–9\n\t\tcleaned = cleaned.replace(\n\t\t\t/[\\u0660-\\u0669]/g,\n\t\t\t(d) => String(d.charCodeAt(0) - 0x0660),\n\t\t);\n\t\t// Arabic decimal separator (U+066B) → '.'\n\t\tcleaned = cleaned.replace(/\\u066B/g, \".\");\n\t}\n\n\tconst result = Number.parseFloat(cleaned);\n\tif (Number.isNaN(result)) {\n\t\tthrow new Error(`Cannot parse \"${value}\" as a Dirham amount`);\n\t}\n\treturn result;\n}\n","import { DIRHAM_STROKE_MAP, type DirhamWeight } from \"../core/constants\";\nimport { formatDirham } from \"../core/format\";\n\nconst SVG_PATH =\n\t\"m88.3 1c0.4 0.6 2.6 3.3 4.7 5.9 15.3 18.2 26.8 47.8 33 85.1 4.1 24.5 4.3 32.2 4.3 125.6v87h-41.8c-38.2 0-42.6-0.2-50.1-1.7-11.8-2.5-24-9.2-32.2-17.8-6.5-6.9-6.3-7.3-5.9 13.6 0.5 17.3 0.7 19.2 3.2 28.6 4 14.9 9.5 26 17.8 35.9 11.3 13.6 22.8 21.2 39.2 26.3 3.5 1 10.9 1.4 37.1 1.6l32.7 0.5v43.3 43.4l-46.1-0.3-46.3-0.3-8-3.2c-9.5-3.8-13.8-6.6-23.1-14.9l-6.8-6.1 0.4 19.1c0.5 17.7 0.6 19.7 3.1 28.7 8.7 31.8 29.7 54.5 57.4 61.9 6.9 1.9 9.6 2 38.5 2.4l30.9 0.4v89.6c0 54.1-0.3 94-0.8 100.8-0.5 6.2-2.1 17.8-3.5 25.9-6.5 37.3-18.2 65.4-35 83.6l-3.4 3.7h169.1c101.1 0 176.7-0.4 187.8-0.9 19.5-1 63-5.3 72.8-7.4 3.1-0.6 8.9-1.5 12.7-2.1 8.1-1.2 21.5-4 40.8-8.9 27.2-6.8 52-15.3 76.3-26.1 7.6-3.4 29.4-14.5 35.2-18 3.1-1.8 6.8-4 8.2-4.7 3.9-2.1 10.4-6.3 19.9-13.1 4.7-3.4 9.4-6.7 10.4-7.4 4.2-2.8 18.7-14.9 25.3-21 25.1-23.1 46.1-48.8 62.4-76.3 2.3-4 5.3-9 6.6-11.1 3.3-5.6 16.9-33.6 18.2-37.8 0.6-1.9 1.4-3.9 1.8-4.3 2.6-3.4 17.6-50.6 19.4-60.9 0.6-3.3 0.9-3.8 3.4-4.3 1.6-0.3 24.9-0.3 51.8-0.1 53.8 0.4 53.8 0.4 65.7 5.9 6.7 3.1 8.7 4.5 16.1 11.2 9.7 8.7 8.8 10.1 8.2-11.7-0.4-12.8-0.9-20.7-1.8-23.9-3.4-12.3-4.2-14.9-7.2-21.1-9.8-21.4-26.2-36.7-47.2-44l-8.2-3-33.4-0.4-33.3-0.5 0.4-11.7c0.4-15.4 0.4-45.9-0.1-61.6l-0.4-12.6 44.6-0.2c38.2-0.2 45.3 0 49.5 1.1 12.6 3.5 21.1 8.3 31.5 17.8l5.8 5.4v-14.8c0-17.6-0.9-25.4-4.5-37-7.1-23.5-21.1-41-41.1-51.8-13-7-13.8-7.2-58.5-7.5-26.2-0.2-39.9-0.6-40.6-1.2-0.6-0.6-1.1-1.6-1.1-2.4 0-0.8-1.5-7.1-3.5-13.9-23.4-82.7-67.1-148.4-131-197.1-8.7-6.7-30-20.8-38.6-25.6-3.3-1.9-6.9-3.9-7.8-4.5-4.2-2.3-28.3-14.1-34.3-16.6-3.6-1.6-8.3-3.6-10.4-4.4-35.3-15.3-94.5-29.8-139.7-34.3-7.4-0.7-17.2-1.8-21.7-2.2-20.4-2.3-48.7-2.6-209.4-2.6-135.8 0-169.9 0.3-169.4 1zm330.7 43.3c33.8 2 54.6 4.6 78.9 10.5 74.2 17.6 126.4 54.8 164.3 117 3.5 5.8 18.3 36 20.5 42.1 10.5 28.3 15.6 45.1 20.1 67.3 1.1 5.4 2.6 12.6 3.3 16 0.7 3.3 1 6.4 0.7 6.7-0.5 0.4-100.9 0.6-223.3 0.5l-222.5-0.2-0.3-128.5c-0.1-70.6 0-129.3 0.3-130.4l0.4-1.9h71.1c39 0 78 0.4 86.5 0.9zm297.5 350.3c0.7 4.3 0.7 77.3 0 80.9l-0.6 2.7-227.5-0.2-227.4-0.3-0.2-42.4c-0.2-23.3 0-42.7 0.2-43.1 0.3-0.5 97.2-0.8 227.7-0.8h227.2zm-10.2 171.7c0.5 1.5-1.9 13.8-6.8 33.8-5.6 22.5-13.2 45.2-20.9 62-3.8 8.6-13.3 27.2-15.6 30.7-1.1 1.6-4.3 6.7-7.1 11.2-18 28.2-43.7 53.9-73 72.9-10.7 6.8-32.7 18.4-38.6 20.2-1.2 0.3-2.5 0.9-3 1.3-0.7 0.6-9.8 4-20.4 7.8-19.5 6.9-56.6 14.4-86.4 17.5-19.3 1.9-22.4 2-96.7 2h-76.9v-129.7-129.8l220.9-0.4c121.5-0.2 221.6-0.5 222.4-0.7 0.9-0.1 1.8 0.5 2.1 1.2z\";\n\nconst VALID_WEIGHTS = new Set<string>([\n\t\"thin\",\n\t\"extralight\",\n\t\"light\",\n\t\"regular\",\n\t\"medium\",\n\t\"semibold\",\n\t\"bold\",\n\t\"extrabold\",\n\t\"black\",\n]);\n\n/**\n * `<dirham-price>` — framework-agnostic Web Component for displaying formatted prices.\n *\n * Works in Vue, Angular, Svelte, or any HTML page.\n *\n * @example\n * ```html\n * <script type=\"module\">\n * import \"dirham/web-component\";\n * </script>\n *\n * <dirham-price amount=\"1250\"></dirham-price>\n * <dirham-price amount=\"5000000\" notation=\"compact\"></dirham-price>\n * <dirham-price amount=\"100\" locale=\"ar-AE\"></dirham-price>\n * <dirham-price amount=\"500\" use-code></dirham-price>\n * ```\n *\n * Attributes: amount, locale, decimals, notation, use-code, symbol-size, weight, currency\n */\nexport class DirhamPriceElement extends HTMLElement {\n\tstatic get observedAttributes() {\n\t\treturn [\n\t\t\t\"amount\",\n\t\t\t\"locale\",\n\t\t\t\"decimals\",\n\t\t\t\"notation\",\n\t\t\t\"use-code\",\n\t\t\t\"symbol-size\",\n\t\t\t\"weight\",\n\t\t\t\"currency\",\n\t\t];\n\t}\n\n\t#shadow: ShadowRoot;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.#shadow = this.attachShadow({ mode: \"open\" });\n\t\tthis.#render();\n\t}\n\n\tattributeChangedCallback() {\n\t\tthis.#render();\n\t}\n\n\t#render() {\n\t\tconst amountStr = this.getAttribute(\"amount\");\n\t\tconst amount = amountStr !== null ? Number(amountStr) : 0;\n\t\tconst locale = this.getAttribute(\"locale\") || \"en-AE\";\n\t\tconst decimals = Number(this.getAttribute(\"decimals\") ?? \"2\");\n\t\tconst notation =\n\t\t\tthis.getAttribute(\"notation\") === \"compact\" ? \"compact\" : \"standard\";\n\t\tconst useCode = this.hasAttribute(\"use-code\");\n\t\tconst symbolSize = this.getAttribute(\"symbol-size\") || \"1em\";\n\t\tconst weightAttr = this.getAttribute(\"weight\") || \"regular\";\n\t\tconst weight: DirhamWeight = VALID_WEIGHTS.has(weightAttr)\n\t\t\t? (weightAttr as DirhamWeight)\n\t\t\t: \"regular\";\n\t\tconst currency = this.getAttribute(\"currency\") || undefined;\n\n\t\tconst symbolFirst = !locale.startsWith(\"ar\");\n\n\t\t// Format the numeric part (strip AED code — we render the SVG instead)\n\t\tlet formatted: string;\n\t\tif (!Number.isFinite(amount)) {\n\t\t\tformatted = \"—\";\n\t\t} else {\n\t\t\tformatted = formatDirham(amount, {\n\t\t\t\tlocale,\n\t\t\t\tdecimals,\n\t\t\t\tuseCode: true,\n\t\t\t\tnotation,\n\t\t\t})\n\t\t\t\t.replace(\"AED\", \"\")\n\t\t\t\t.trim();\n\t\t}\n\n\t\tif (useCode) {\n\t\t\tconst code = currency || \"AED\";\n\t\t\tconst text = symbolFirst\n\t\t\t\t? `${code}\\u00A0${formatted}`\n\t\t\t\t: `${formatted}\\u00A0${code}`;\n\t\t\tthis.#shadow.innerHTML = `<span style=\"white-space:nowrap\">${this.#escape(text)}</span>`;\n\t\t\treturn;\n\t\t}\n\n\t\tconst strokeWidth = DIRHAM_STROKE_MAP[weight];\n\t\tconst strokeAttrs =\n\t\t\tstrokeWidth > 0\n\t\t\t\t? ` stroke=\"currentColor\" stroke-width=\"${strokeWidth}\" stroke-linejoin=\"round\" paint-order=\"stroke\"`\n\t\t\t\t: \"\";\n\n\t\tconst svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1000 870\" width=\"${this.#escape(String(symbolSize))}\" height=\"${this.#escape(String(symbolSize))}\" fill=\"currentColor\" role=\"img\" aria-label=\"UAE Dirham\" style=\"display:inline-block;vertical-align:middle\"><path d=\"${SVG_PATH}\"${strokeAttrs}/></svg>`;\n\n\t\tconst parts = symbolFirst\n\t\t\t? `${svg}\\u00A0${this.#escape(formatted)}`\n\t\t\t: `${this.#escape(formatted)}\\u00A0${svg}`;\n\n\t\tthis.#shadow.innerHTML = `<span style=\"white-space:nowrap\">${parts}</span>`;\n\t}\n\n\t#escape(str: string): string {\n\t\treturn str\n\t\t\t.replace(/&/g, \"&\")\n\t\t\t.replace(/</g, \"<\")\n\t\t\t.replace(/>/g, \">\")\n\t\t\t.replace(/\"/g, \""\");\n\t}\n}\n\nif (\n\ttypeof customElements !== \"undefined\" &&\n\t!customElements.get(\"dirham-price\")\n) {\n\tcustomElements.define(\"dirham-price\", DirhamPriceElement);\n}\n"]} |
+26
-6
@@ -37,9 +37,10 @@ 'use strict'; | ||
| var _fmtCache = /* @__PURE__ */ new Map(); | ||
| function getFormatter(locale, decimals) { | ||
| const key = `${locale}:${decimals}`; | ||
| function getFormatter(locale, decimals, notation = "standard") { | ||
| const key = `${locale}:${decimals}:${notation}`; | ||
| let fmt = _fmtCache.get(key); | ||
| if (!fmt) { | ||
| fmt = new Intl.NumberFormat(locale, { | ||
| minimumFractionDigits: decimals, | ||
| maximumFractionDigits: decimals | ||
| minimumFractionDigits: notation === "compact" ? 0 : decimals, | ||
| maximumFractionDigits: decimals, | ||
| ...notation === "compact" && { notation: "compact", compactDisplay: "short" } | ||
| }); | ||
@@ -60,4 +61,5 @@ _fmtCache.set(key, fmt); | ||
| useCode = false, | ||
| separator = "\xA0" | ||
| separator = "\xA0", | ||
| // non-breaking space | ||
| notation = "standard" | ||
| } = options; | ||
@@ -71,3 +73,3 @@ const symbol = useCode ? DIRHAM_CURRENCY_CODE : DIRHAM_UNICODE; | ||
| } | ||
| const formatted = getFormatter(locale, decimals).format(amount); | ||
| const formatted = getFormatter(locale, decimals, notation).format(amount); | ||
| return symbolFirst ? `${symbol}${separator}${formatted}` : `${formatted}${separator}${symbol}`; | ||
@@ -92,2 +94,19 @@ } | ||
| // src/core/clipboard.ts | ||
| var FORMAT_MAP = { | ||
| unicode: DIRHAM_UNICODE, | ||
| html: DIRHAM_HTML_ENTITY, | ||
| css: DIRHAM_CSS_CONTENT, | ||
| arabic: DIRHAM_SYMBOL_TEXT | ||
| }; | ||
| async function copyDirhamSymbol(format = "unicode") { | ||
| const text = FORMAT_MAP[format]; | ||
| if (typeof navigator === "undefined" || !navigator.clipboard) { | ||
| throw new Error( | ||
| "copyDirhamSymbol: Clipboard API is not available in this environment" | ||
| ); | ||
| } | ||
| await navigator.clipboard.writeText(text); | ||
| } | ||
| exports.DIRHAM_CODEPOINT = DIRHAM_CODEPOINT; | ||
@@ -103,2 +122,3 @@ exports.DIRHAM_CSS_CLASS = DIRHAM_CSS_CLASS; | ||
| exports.DIRHAM_WEIGHT_MAP = DIRHAM_WEIGHT_MAP; | ||
| exports.copyDirhamSymbol = copyDirhamSymbol; | ||
| exports.formatDirham = formatDirham; | ||
@@ -105,0 +125,0 @@ exports.parseDirham = parseDirham; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../src/core/constants.ts","../src/core/format.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * UAE Dirham currency symbol constants.\n *\n * This package maps the Dirham glyph to the official Unicode codepoint U+20C3\n * (UAE DIRHAM SIGN) via a custom web font. The codepoint was accepted by the\n * Unicode Technical Committee for Unicode 18.0 (expected September 2026).\n *\n * Until system fonts ship native U+20C3 glyphs, the bundled web font provides\n * the rendering. When OS/font support lands, the web font becomes optional;\n * zero migration required.\n *\n * @module dirham\n * @see https://www.unicode.org/alloc/Pipeline.html\n */\n\n/** Unicode character for the Dirham symbol (U+20C3, requires Dirham web font until system fonts support it) */\nexport const DIRHAM_UNICODE = \"\\u20C3\";\n\n/** HTML entity for the Dirham symbol */\nexport const DIRHAM_HTML_ENTITY = \"⃃\";\n\n/** CSS content value for use in `::before` / `::after` pseudo-elements */\nexport const DIRHAM_CSS_CONTENT = \"\\\\20C3\";\n\n/** ISO 4217 currency code for UAE Dirham */\nexport const DIRHAM_CURRENCY_CODE = \"AED\";\n\n/** Arabic text representation of the Dirham symbol (د.إ) */\nexport const DIRHAM_SYMBOL_TEXT = \"د.إ\";\n\n/** The font family name used for the Dirham web font */\nexport const DIRHAM_FONT_FAMILY = \"Dirham\";\n\n/** CSS class name for the Dirham icon */\nexport const DIRHAM_CSS_CLASS = \"dirham-symbol\";\n\n/** Unicode codepoint as a number (0x20C3) */\nexport const DIRHAM_CODEPOINT = 0x20c3;\n\n// ── Font weight mapping ─────────────────────────────────────────────────\n\n/**\n * Supported visual weights for the Dirham symbol SVG component.\n *\n * Because the Dirham symbol is not yet in standard fonts (until Unicode 18.0),\n * weight simulation is applied via SVG stroke to match surrounding text weight,\n * similar to how $, €, £ adapt to their font's weight.\n */\nexport type DirhamWeight =\n\t| \"thin\"\n\t| \"extralight\"\n\t| \"light\"\n\t| \"regular\"\n\t| \"medium\"\n\t| \"semibold\"\n\t| \"bold\"\n\t| \"extrabold\"\n\t| \"black\";\n\n/**\n * Map from weight name to CSS `font-weight` numeric value.\n * Used for matching the symbol weight to surrounding text.\n */\nexport const DIRHAM_WEIGHT_MAP: Record<DirhamWeight, number> = {\n\tthin: 100,\n\textralight: 200,\n\tlight: 300,\n\tregular: 400,\n\tmedium: 500,\n\tsemibold: 600,\n\tbold: 700,\n\textrabold: 800,\n\tblack: 900,\n};\n\n/**\n * SVG stroke-width values that simulate font weight.\n * Applied with `paint-order: stroke` so stroke renders behind fill.\n */\nexport const DIRHAM_STROKE_MAP: Record<DirhamWeight, number> = {\n\tthin: 0,\n\textralight: 0,\n\tlight: 0,\n\tregular: 0,\n\tmedium: 8,\n\tsemibold: 16,\n\tbold: 24,\n\textrabold: 36,\n\tblack: 48,\n};\n","import {\n\tDIRHAM_CURRENCY_CODE,\n\tDIRHAM_SYMBOL_TEXT,\n\tDIRHAM_UNICODE,\n} from \"./constants\";\n\n// ─── Intl.NumberFormat cache ─────────────────────────────────────────────────\n// Constructing Intl.NumberFormat is expensive (~µs). Cache instances keyed on\n// \"locale:decimals\" so repeated calls (e.g., rendering a price list) reuse\n// the same formatter instead of allocating a new object each time.\nconst _fmtCache = new Map<string, Intl.NumberFormat>();\n\nfunction getFormatter(locale: string, decimals: number): Intl.NumberFormat {\n\tconst key = `${locale}:${decimals}`;\n\tlet fmt = _fmtCache.get(key);\n\tif (!fmt) {\n\t\tfmt = new Intl.NumberFormat(locale, {\n\t\t\tminimumFractionDigits: decimals,\n\t\t\tmaximumFractionDigits: decimals,\n\t\t});\n\t\t_fmtCache.set(key, fmt);\n\t}\n\treturn fmt;\n}\n\n/**\n * Options for formatting a Dirham amount.\n */\nexport interface FormatDirhamOptions {\n\t/**\n\t * Locale string for number formatting.\n\t * @default \"en-AE\"\n\t */\n\tlocale?: string;\n\n\t/**\n\t * Number of decimal places.\n\t * @default 2\n\t */\n\tdecimals?: number;\n\n\t/**\n\t * Whether to place the symbol before the amount.\n\t * When `undefined`, determined by locale:\n\t * - Arabic locales (ar-*): symbol after amount\n\t * - Other locales: symbol before amount\n\t */\n\tsymbolFirst?: boolean;\n\n\t/**\n\t * Use ISO currency code (AED) instead of the symbol.\n\t * @default false\n\t */\n\tuseCode?: boolean;\n\n\t/**\n\t * Separator between symbol and amount.\n\t * @default \" \" (non-breaking space)\n\t */\n\tseparator?: string;\n}\n\n/**\n * Format a number as a Dirham currency string.\n *\n * @example\n * ```ts\n * formatDirham(100); // \"\\u20C3 100.00\"\n * formatDirham(1234.5); // \"\\u20C3 1,234.50\"\n * formatDirham(100, { locale: \"ar-AE\" }); // \"100.00 \\u20C3\"\n * formatDirham(100, { useCode: true }); // \"AED 100.00\"\n * ```\n */\nexport function formatDirham(\n\tamount: number,\n\toptions: FormatDirhamOptions = {},\n): string {\n\tif (!Number.isFinite(amount)) {\n\t\tthrow new RangeError(\n\t\t\t`formatDirham: amount must be a finite number, got ${amount}`,\n\t\t);\n\t}\n\n\tconst {\n\t\tlocale = \"en-AE\",\n\t\tdecimals = 2,\n\t\tuseCode = false,\n\t\tseparator = \"\\u00A0\", // non-breaking space\n\t} = options;\n\n\tconst symbol = useCode ? DIRHAM_CURRENCY_CODE : DIRHAM_UNICODE;\n\n\t// Determine symbol placement\n\tlet symbolFirst: boolean;\n\tif (options.symbolFirst !== undefined) {\n\t\tsymbolFirst = options.symbolFirst;\n\t} else {\n\t\t// Arabic locales place symbol after amount\n\t\tsymbolFirst = !locale.startsWith(\"ar\");\n\t}\n\n\t// Format the number (use cached formatter)\n\tconst formatted = getFormatter(locale, decimals).format(amount);\n\n\treturn symbolFirst\n\t\t? `${symbol}${separator}${formatted}`\n\t\t: `${formatted}${separator}${symbol}`;\n}\n\n/**\n * Options for parsing a Dirham-formatted string.\n */\nexport interface ParseDirhamOptions {\n\t/**\n\t * Normalize Arabic-Indic digits (٠١٢٣٤٥٦٧٨٩ / U+0660–U+0669) to ASCII\n\t * digits before parsing. Enables round-tripping strings produced by\n\t * `formatDirham` with Arabic locales (e.g. `\"ar-AE\"`).\n\t * @default true\n\t */\n\tnormalizeArabicNumerals?: boolean;\n}\n\n/**\n * Parse a Dirham-formatted string back to a number.\n * Strips currency symbols, codes, and formatting characters.\n * By default also normalizes Arabic-Indic digits so strings produced by\n * `formatDirham({ locale: \"ar-AE\" })` round-trip correctly.\n *\n * @example\n * ```ts\n * parseDirham(\"\\u20C3 1,234.50\"); // 1234.5\n * parseDirham(\"AED 100.00\"); // 100\n * parseDirham(\"١٬٢٣٤٫٥٠ \\u20C3\"); // 1234.5\n * parseDirham(\"١٠٠٫٠٠ \\u20C3\", { normalizeArabicNumerals: false }); // throws\n * ```\n */\nexport function parseDirham(\n\tvalue: string,\n\toptions: ParseDirhamOptions = {},\n): number {\n\tconst { normalizeArabicNumerals = true } = options;\n\n\tlet cleaned = value\n\t\t.replaceAll(DIRHAM_UNICODE, \"\")\n\t\t.replaceAll(DIRHAM_SYMBOL_TEXT, \"\")\n\t\t.replaceAll(DIRHAM_CURRENCY_CODE, \"\")\n\t\t.replace(/[,\\s\\u00A0\\u066C]/g, \"\") // ASCII comma, whitespace, NBSP, Arabic thousands sep\n\t\t.trim();\n\n\tif (normalizeArabicNumerals) {\n\t\t// Arabic-Indic digits U+0660–U+0669 → ASCII 0–9\n\t\tcleaned = cleaned.replace(\n\t\t\t/[\\u0660-\\u0669]/g,\n\t\t\t(d) => String(d.charCodeAt(0) - 0x0660),\n\t\t);\n\t\t// Arabic decimal separator (U+066B) → '.'\n\t\tcleaned = cleaned.replace(/\\u066B/g, \".\");\n\t}\n\n\tconst result = Number.parseFloat(cleaned);\n\tif (Number.isNaN(result)) {\n\t\tthrow new Error(`Cannot parse \"${value}\" as a Dirham amount`);\n\t}\n\treturn result;\n}\n"]} | ||
| {"version":3,"sources":["../src/core/constants.ts","../src/core/format.ts","../src/core/clipboard.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * UAE Dirham currency symbol constants.\n *\n * This package maps the Dirham glyph to the official Unicode codepoint U+20C3\n * (UAE DIRHAM SIGN) via a custom web font. The codepoint was accepted by the\n * Unicode Technical Committee for Unicode 18.0 (expected September 2026).\n *\n * Until system fonts ship native U+20C3 glyphs, the bundled web font provides\n * the rendering. When OS/font support lands, the web font becomes optional;\n * zero migration required.\n *\n * @module dirham\n * @see https://www.unicode.org/alloc/Pipeline.html\n */\n\n/** Unicode character for the Dirham symbol (U+20C3, requires Dirham web font until system fonts support it) */\nexport const DIRHAM_UNICODE = \"\\u20C3\";\n\n/** HTML entity for the Dirham symbol */\nexport const DIRHAM_HTML_ENTITY = \"⃃\";\n\n/** CSS content value for use in `::before` / `::after` pseudo-elements */\nexport const DIRHAM_CSS_CONTENT = \"\\\\20C3\";\n\n/** ISO 4217 currency code for UAE Dirham */\nexport const DIRHAM_CURRENCY_CODE = \"AED\";\n\n/** Arabic text representation of the Dirham symbol (د.إ) */\nexport const DIRHAM_SYMBOL_TEXT = \"د.إ\";\n\n/** The font family name used for the Dirham web font */\nexport const DIRHAM_FONT_FAMILY = \"Dirham\";\n\n/** CSS class name for the Dirham icon */\nexport const DIRHAM_CSS_CLASS = \"dirham-symbol\";\n\n/** Unicode codepoint as a number (0x20C3) */\nexport const DIRHAM_CODEPOINT = 0x20c3;\n\n// ── Font weight mapping ─────────────────────────────────────────────────\n\n/**\n * Supported visual weights for the Dirham symbol SVG component.\n *\n * Because the Dirham symbol is not yet in standard fonts (until Unicode 18.0),\n * weight simulation is applied via SVG stroke to match surrounding text weight,\n * similar to how $, €, £ adapt to their font's weight.\n */\nexport type DirhamWeight =\n\t| \"thin\"\n\t| \"extralight\"\n\t| \"light\"\n\t| \"regular\"\n\t| \"medium\"\n\t| \"semibold\"\n\t| \"bold\"\n\t| \"extrabold\"\n\t| \"black\";\n\n/**\n * Map from weight name to CSS `font-weight` numeric value.\n * Used for matching the symbol weight to surrounding text.\n */\nexport const DIRHAM_WEIGHT_MAP: Record<DirhamWeight, number> = {\n\tthin: 100,\n\textralight: 200,\n\tlight: 300,\n\tregular: 400,\n\tmedium: 500,\n\tsemibold: 600,\n\tbold: 700,\n\textrabold: 800,\n\tblack: 900,\n};\n\n/**\n * SVG stroke-width values that simulate font weight.\n * Applied with `paint-order: stroke` so stroke renders behind fill.\n */\nexport const DIRHAM_STROKE_MAP: Record<DirhamWeight, number> = {\n\tthin: 0,\n\textralight: 0,\n\tlight: 0,\n\tregular: 0,\n\tmedium: 8,\n\tsemibold: 16,\n\tbold: 24,\n\textrabold: 36,\n\tblack: 48,\n};\n","import {\n\tDIRHAM_CURRENCY_CODE,\n\tDIRHAM_SYMBOL_TEXT,\n\tDIRHAM_UNICODE,\n} from \"./constants\";\n\n// ─── Intl.NumberFormat cache ─────────────────────────────────────────────────\n// Constructing Intl.NumberFormat is expensive (~µs). Cache instances keyed on\n// \"locale:decimals\" so repeated calls (e.g., rendering a price list) reuse\n// the same formatter instead of allocating a new object each time.\nconst _fmtCache = new Map<string, Intl.NumberFormat>();\n\nfunction getFormatter(\n\tlocale: string,\n\tdecimals: number,\n\tnotation: \"standard\" | \"compact\" = \"standard\",\n): Intl.NumberFormat {\n\tconst key = `${locale}:${decimals}:${notation}`;\n\tlet fmt = _fmtCache.get(key);\n\tif (!fmt) {\n\t\tfmt = new Intl.NumberFormat(locale, {\n\t\t\tminimumFractionDigits: notation === \"compact\" ? 0 : decimals,\n\t\t\tmaximumFractionDigits: decimals,\n\t\t\t...(notation === \"compact\" && { notation: \"compact\", compactDisplay: \"short\" }),\n\t\t});\n\t\t_fmtCache.set(key, fmt);\n\t}\n\treturn fmt;\n}\n\n/**\n * Options for formatting a Dirham amount.\n */\nexport interface FormatDirhamOptions {\n\t/**\n\t * Locale string for number formatting.\n\t * @default \"en-AE\"\n\t */\n\tlocale?: string;\n\n\t/**\n\t * Number of decimal places.\n\t * @default 2\n\t */\n\tdecimals?: number;\n\n\t/**\n\t * Whether to place the symbol before the amount.\n\t * When `undefined`, determined by locale:\n\t * - Arabic locales (ar-*): symbol after amount\n\t * - Other locales: symbol before amount\n\t */\n\tsymbolFirst?: boolean;\n\n\t/**\n\t * Use ISO currency code (AED) instead of the symbol.\n\t * @default false\n\t */\n\tuseCode?: boolean;\n\n\t/**\n\t * Separator between symbol and amount.\n\t * @default \" \" (non-breaking space)\n\t */\n\tseparator?: string;\n\n\t/**\n\t * Number notation style.\n\t * - `\"standard\"` — full digits (e.g. 1,500,000.00)\n\t * - `\"compact\"` — abbreviated (e.g. 1.5M)\n\t * @default \"standard\"\n\t */\n\tnotation?: \"standard\" | \"compact\";\n}\n\n/**\n * Format a number as a Dirham currency string.\n *\n * @example\n * ```ts\n * formatDirham(100); // \"\\u20C3 100.00\"\n * formatDirham(1234.5); // \"\\u20C3 1,234.50\"\n * formatDirham(100, { locale: \"ar-AE\" }); // \"100.00 \\u20C3\"\n * formatDirham(100, { useCode: true }); // \"AED 100.00\"\n * formatDirham(1500000, { notation: \"compact\" }); // \"\\u20C3 1.5M\"\n * ```\n */\nexport function formatDirham(\n\tamount: number,\n\toptions: FormatDirhamOptions = {},\n): string {\n\tif (!Number.isFinite(amount)) {\n\t\tthrow new RangeError(\n\t\t\t`formatDirham: amount must be a finite number, got ${amount}`,\n\t\t);\n\t}\n\n\tconst {\n\t\tlocale = \"en-AE\",\n\t\tdecimals = 2,\n\t\tuseCode = false,\n\t\tseparator = \"\\u00A0\", // non-breaking space\n\t\tnotation = \"standard\",\n\t} = options;\n\n\tconst symbol = useCode ? DIRHAM_CURRENCY_CODE : DIRHAM_UNICODE;\n\n\t// Determine symbol placement\n\tlet symbolFirst: boolean;\n\tif (options.symbolFirst !== undefined) {\n\t\tsymbolFirst = options.symbolFirst;\n\t} else {\n\t\t// Arabic locales place symbol after amount\n\t\tsymbolFirst = !locale.startsWith(\"ar\");\n\t}\n\n\t// Format the number (use cached formatter)\n\tconst formatted = getFormatter(locale, decimals, notation).format(amount);\n\n\treturn symbolFirst\n\t\t? `${symbol}${separator}${formatted}`\n\t\t: `${formatted}${separator}${symbol}`;\n}\n\n/**\n * Options for parsing a Dirham-formatted string.\n */\nexport interface ParseDirhamOptions {\n\t/**\n\t * Normalize Arabic-Indic digits (٠١٢٣٤٥٦٧٨٩ / U+0660–U+0669) to ASCII\n\t * digits before parsing. Enables round-tripping strings produced by\n\t * `formatDirham` with Arabic locales (e.g. `\"ar-AE\"`).\n\t * @default true\n\t */\n\tnormalizeArabicNumerals?: boolean;\n}\n\n/**\n * Parse a Dirham-formatted string back to a number.\n * Strips currency symbols, codes, and formatting characters.\n * By default also normalizes Arabic-Indic digits so strings produced by\n * `formatDirham({ locale: \"ar-AE\" })` round-trip correctly.\n *\n * @example\n * ```ts\n * parseDirham(\"\\u20C3 1,234.50\"); // 1234.5\n * parseDirham(\"AED 100.00\"); // 100\n * parseDirham(\"١٬٢٣٤٫٥٠ \\u20C3\"); // 1234.5\n * parseDirham(\"١٠٠٫٠٠ \\u20C3\", { normalizeArabicNumerals: false }); // throws\n * ```\n */\nexport function parseDirham(\n\tvalue: string,\n\toptions: ParseDirhamOptions = {},\n): number {\n\tconst { normalizeArabicNumerals = true } = options;\n\n\tlet cleaned = value\n\t\t.replaceAll(DIRHAM_UNICODE, \"\")\n\t\t.replaceAll(DIRHAM_SYMBOL_TEXT, \"\")\n\t\t.replaceAll(DIRHAM_CURRENCY_CODE, \"\")\n\t\t.replace(/[,\\s\\u00A0\\u066C]/g, \"\") // ASCII comma, whitespace, NBSP, Arabic thousands sep\n\t\t.trim();\n\n\tif (normalizeArabicNumerals) {\n\t\t// Arabic-Indic digits U+0660–U+0669 → ASCII 0–9\n\t\tcleaned = cleaned.replace(\n\t\t\t/[\\u0660-\\u0669]/g,\n\t\t\t(d) => String(d.charCodeAt(0) - 0x0660),\n\t\t);\n\t\t// Arabic decimal separator (U+066B) → '.'\n\t\tcleaned = cleaned.replace(/\\u066B/g, \".\");\n\t}\n\n\tconst result = Number.parseFloat(cleaned);\n\tif (Number.isNaN(result)) {\n\t\tthrow new Error(`Cannot parse \"${value}\" as a Dirham amount`);\n\t}\n\treturn result;\n}\n","import {\n\tDIRHAM_CSS_CONTENT,\n\tDIRHAM_HTML_ENTITY,\n\tDIRHAM_SYMBOL_TEXT,\n\tDIRHAM_UNICODE,\n} from \"./constants\";\n\n/**\n * Format of the Dirham symbol to copy.\n *\n * - `\"unicode\"` — the character itself (`\\u20C3`)\n * - `\"html\"` — HTML entity (`⃃`)\n * - `\"css\"` — CSS content value (`\\\\20C3`)\n * - `\"arabic\"` — Arabic text (د.إ)\n */\nexport type DirhamCopyFormat = \"unicode\" | \"html\" | \"css\" | \"arabic\";\n\nconst FORMAT_MAP: Record<DirhamCopyFormat, string> = {\n\tunicode: DIRHAM_UNICODE,\n\thtml: DIRHAM_HTML_ENTITY,\n\tcss: DIRHAM_CSS_CONTENT,\n\tarabic: DIRHAM_SYMBOL_TEXT,\n};\n\n/**\n * Copy the Dirham symbol to the clipboard in the specified format.\n *\n * @returns A promise that resolves when the text is on the clipboard.\n * @throws If the Clipboard API is unavailable (e.g. non-browser environment).\n *\n * @example\n * ```ts\n * import { copyDirhamSymbol } from \"dirham\";\n *\n * await copyDirhamSymbol(); // copies \"\\u20C3\"\n * await copyDirhamSymbol(\"html\"); // copies \"⃃\"\n * await copyDirhamSymbol(\"css\"); // copies \"\\\\20C3\"\n * ```\n */\nexport async function copyDirhamSymbol(\n\tformat: DirhamCopyFormat = \"unicode\",\n): Promise<void> {\n\tconst text = FORMAT_MAP[format];\n\tif (typeof navigator === \"undefined\" || !navigator.clipboard) {\n\t\tthrow new Error(\n\t\t\t\"copyDirhamSymbol: Clipboard API is not available in this environment\",\n\t\t);\n\t}\n\tawait navigator.clipboard.writeText(text);\n}\n"]} |
+35
-1
@@ -81,2 +81,9 @@ /** | ||
| separator?: string; | ||
| /** | ||
| * Number notation style. | ||
| * - `"standard"` — full digits (e.g. 1,500,000.00) | ||
| * - `"compact"` — abbreviated (e.g. 1.5M) | ||
| * @default "standard" | ||
| */ | ||
| notation?: "standard" | "compact"; | ||
| } | ||
@@ -92,2 +99,3 @@ /** | ||
| * formatDirham(100, { useCode: true }); // "AED 100.00" | ||
| * formatDirham(1500000, { notation: "compact" }); // "\u20C3 1.5M" | ||
| * ``` | ||
@@ -124,2 +132,28 @@ */ | ||
| export { DIRHAM_CODEPOINT, DIRHAM_CSS_CLASS, DIRHAM_CSS_CONTENT, DIRHAM_CURRENCY_CODE, DIRHAM_FONT_FAMILY, DIRHAM_HTML_ENTITY, DIRHAM_STROKE_MAP, DIRHAM_SYMBOL_TEXT, DIRHAM_UNICODE, DIRHAM_WEIGHT_MAP, type DirhamWeight, type FormatDirhamOptions, formatDirham, parseDirham }; | ||
| /** | ||
| * Format of the Dirham symbol to copy. | ||
| * | ||
| * - `"unicode"` — the character itself (`\u20C3`) | ||
| * - `"html"` — HTML entity (`⃃`) | ||
| * - `"css"` — CSS content value (`\\20C3`) | ||
| * - `"arabic"` — Arabic text (د.إ) | ||
| */ | ||
| type DirhamCopyFormat = "unicode" | "html" | "css" | "arabic"; | ||
| /** | ||
| * Copy the Dirham symbol to the clipboard in the specified format. | ||
| * | ||
| * @returns A promise that resolves when the text is on the clipboard. | ||
| * @throws If the Clipboard API is unavailable (e.g. non-browser environment). | ||
| * | ||
| * @example | ||
| * ```ts | ||
| * import { copyDirhamSymbol } from "dirham"; | ||
| * | ||
| * await copyDirhamSymbol(); // copies "\u20C3" | ||
| * await copyDirhamSymbol("html"); // copies "⃃" | ||
| * await copyDirhamSymbol("css"); // copies "\\20C3" | ||
| * ``` | ||
| */ | ||
| declare function copyDirhamSymbol(format?: DirhamCopyFormat): Promise<void>; | ||
| export { DIRHAM_CODEPOINT, DIRHAM_CSS_CLASS, DIRHAM_CSS_CONTENT, DIRHAM_CURRENCY_CODE, DIRHAM_FONT_FAMILY, DIRHAM_HTML_ENTITY, DIRHAM_STROKE_MAP, DIRHAM_SYMBOL_TEXT, DIRHAM_UNICODE, DIRHAM_WEIGHT_MAP, type DirhamCopyFormat, type DirhamWeight, type FormatDirhamOptions, copyDirhamSymbol, formatDirham, parseDirham }; |
+35
-1
@@ -81,2 +81,9 @@ /** | ||
| separator?: string; | ||
| /** | ||
| * Number notation style. | ||
| * - `"standard"` — full digits (e.g. 1,500,000.00) | ||
| * - `"compact"` — abbreviated (e.g. 1.5M) | ||
| * @default "standard" | ||
| */ | ||
| notation?: "standard" | "compact"; | ||
| } | ||
@@ -92,2 +99,3 @@ /** | ||
| * formatDirham(100, { useCode: true }); // "AED 100.00" | ||
| * formatDirham(1500000, { notation: "compact" }); // "\u20C3 1.5M" | ||
| * ``` | ||
@@ -124,2 +132,28 @@ */ | ||
| export { DIRHAM_CODEPOINT, DIRHAM_CSS_CLASS, DIRHAM_CSS_CONTENT, DIRHAM_CURRENCY_CODE, DIRHAM_FONT_FAMILY, DIRHAM_HTML_ENTITY, DIRHAM_STROKE_MAP, DIRHAM_SYMBOL_TEXT, DIRHAM_UNICODE, DIRHAM_WEIGHT_MAP, type DirhamWeight, type FormatDirhamOptions, formatDirham, parseDirham }; | ||
| /** | ||
| * Format of the Dirham symbol to copy. | ||
| * | ||
| * - `"unicode"` — the character itself (`\u20C3`) | ||
| * - `"html"` — HTML entity (`⃃`) | ||
| * - `"css"` — CSS content value (`\\20C3`) | ||
| * - `"arabic"` — Arabic text (د.إ) | ||
| */ | ||
| type DirhamCopyFormat = "unicode" | "html" | "css" | "arabic"; | ||
| /** | ||
| * Copy the Dirham symbol to the clipboard in the specified format. | ||
| * | ||
| * @returns A promise that resolves when the text is on the clipboard. | ||
| * @throws If the Clipboard API is unavailable (e.g. non-browser environment). | ||
| * | ||
| * @example | ||
| * ```ts | ||
| * import { copyDirhamSymbol } from "dirham"; | ||
| * | ||
| * await copyDirhamSymbol(); // copies "\u20C3" | ||
| * await copyDirhamSymbol("html"); // copies "⃃" | ||
| * await copyDirhamSymbol("css"); // copies "\\20C3" | ||
| * ``` | ||
| */ | ||
| declare function copyDirhamSymbol(format?: DirhamCopyFormat): Promise<void>; | ||
| export { DIRHAM_CODEPOINT, DIRHAM_CSS_CLASS, DIRHAM_CSS_CONTENT, DIRHAM_CURRENCY_CODE, DIRHAM_FONT_FAMILY, DIRHAM_HTML_ENTITY, DIRHAM_STROKE_MAP, DIRHAM_SYMBOL_TEXT, DIRHAM_UNICODE, DIRHAM_WEIGHT_MAP, type DirhamCopyFormat, type DirhamWeight, type FormatDirhamOptions, copyDirhamSymbol, formatDirham, parseDirham }; |
+26
-7
@@ -35,9 +35,10 @@ // src/core/constants.ts | ||
| var _fmtCache = /* @__PURE__ */ new Map(); | ||
| function getFormatter(locale, decimals) { | ||
| const key = `${locale}:${decimals}`; | ||
| function getFormatter(locale, decimals, notation = "standard") { | ||
| const key = `${locale}:${decimals}:${notation}`; | ||
| let fmt = _fmtCache.get(key); | ||
| if (!fmt) { | ||
| fmt = new Intl.NumberFormat(locale, { | ||
| minimumFractionDigits: decimals, | ||
| maximumFractionDigits: decimals | ||
| minimumFractionDigits: notation === "compact" ? 0 : decimals, | ||
| maximumFractionDigits: decimals, | ||
| ...notation === "compact" && { notation: "compact", compactDisplay: "short" } | ||
| }); | ||
@@ -58,4 +59,5 @@ _fmtCache.set(key, fmt); | ||
| useCode = false, | ||
| separator = "\xA0" | ||
| separator = "\xA0", | ||
| // non-breaking space | ||
| notation = "standard" | ||
| } = options; | ||
@@ -69,3 +71,3 @@ const symbol = useCode ? DIRHAM_CURRENCY_CODE : DIRHAM_UNICODE; | ||
| } | ||
| const formatted = getFormatter(locale, decimals).format(amount); | ||
| const formatted = getFormatter(locale, decimals, notation).format(amount); | ||
| return symbolFirst ? `${symbol}${separator}${formatted}` : `${formatted}${separator}${symbol}`; | ||
@@ -90,4 +92,21 @@ } | ||
| export { DIRHAM_CODEPOINT, DIRHAM_CSS_CLASS, DIRHAM_CSS_CONTENT, DIRHAM_CURRENCY_CODE, DIRHAM_FONT_FAMILY, DIRHAM_HTML_ENTITY, DIRHAM_STROKE_MAP, DIRHAM_SYMBOL_TEXT, DIRHAM_UNICODE, DIRHAM_WEIGHT_MAP, formatDirham, parseDirham }; | ||
| // src/core/clipboard.ts | ||
| var FORMAT_MAP = { | ||
| unicode: DIRHAM_UNICODE, | ||
| html: DIRHAM_HTML_ENTITY, | ||
| css: DIRHAM_CSS_CONTENT, | ||
| arabic: DIRHAM_SYMBOL_TEXT | ||
| }; | ||
| async function copyDirhamSymbol(format = "unicode") { | ||
| const text = FORMAT_MAP[format]; | ||
| if (typeof navigator === "undefined" || !navigator.clipboard) { | ||
| throw new Error( | ||
| "copyDirhamSymbol: Clipboard API is not available in this environment" | ||
| ); | ||
| } | ||
| await navigator.clipboard.writeText(text); | ||
| } | ||
| export { DIRHAM_CODEPOINT, DIRHAM_CSS_CLASS, DIRHAM_CSS_CONTENT, DIRHAM_CURRENCY_CODE, DIRHAM_FONT_FAMILY, DIRHAM_HTML_ENTITY, DIRHAM_STROKE_MAP, DIRHAM_SYMBOL_TEXT, DIRHAM_UNICODE, DIRHAM_WEIGHT_MAP, copyDirhamSymbol, formatDirham, parseDirham }; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../src/core/constants.ts","../src/core/format.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * UAE Dirham currency symbol constants.\n *\n * This package maps the Dirham glyph to the official Unicode codepoint U+20C3\n * (UAE DIRHAM SIGN) via a custom web font. The codepoint was accepted by the\n * Unicode Technical Committee for Unicode 18.0 (expected September 2026).\n *\n * Until system fonts ship native U+20C3 glyphs, the bundled web font provides\n * the rendering. When OS/font support lands, the web font becomes optional;\n * zero migration required.\n *\n * @module dirham\n * @see https://www.unicode.org/alloc/Pipeline.html\n */\n\n/** Unicode character for the Dirham symbol (U+20C3, requires Dirham web font until system fonts support it) */\nexport const DIRHAM_UNICODE = \"\\u20C3\";\n\n/** HTML entity for the Dirham symbol */\nexport const DIRHAM_HTML_ENTITY = \"⃃\";\n\n/** CSS content value for use in `::before` / `::after` pseudo-elements */\nexport const DIRHAM_CSS_CONTENT = \"\\\\20C3\";\n\n/** ISO 4217 currency code for UAE Dirham */\nexport const DIRHAM_CURRENCY_CODE = \"AED\";\n\n/** Arabic text representation of the Dirham symbol (د.إ) */\nexport const DIRHAM_SYMBOL_TEXT = \"د.إ\";\n\n/** The font family name used for the Dirham web font */\nexport const DIRHAM_FONT_FAMILY = \"Dirham\";\n\n/** CSS class name for the Dirham icon */\nexport const DIRHAM_CSS_CLASS = \"dirham-symbol\";\n\n/** Unicode codepoint as a number (0x20C3) */\nexport const DIRHAM_CODEPOINT = 0x20c3;\n\n// ── Font weight mapping ─────────────────────────────────────────────────\n\n/**\n * Supported visual weights for the Dirham symbol SVG component.\n *\n * Because the Dirham symbol is not yet in standard fonts (until Unicode 18.0),\n * weight simulation is applied via SVG stroke to match surrounding text weight,\n * similar to how $, €, £ adapt to their font's weight.\n */\nexport type DirhamWeight =\n\t| \"thin\"\n\t| \"extralight\"\n\t| \"light\"\n\t| \"regular\"\n\t| \"medium\"\n\t| \"semibold\"\n\t| \"bold\"\n\t| \"extrabold\"\n\t| \"black\";\n\n/**\n * Map from weight name to CSS `font-weight` numeric value.\n * Used for matching the symbol weight to surrounding text.\n */\nexport const DIRHAM_WEIGHT_MAP: Record<DirhamWeight, number> = {\n\tthin: 100,\n\textralight: 200,\n\tlight: 300,\n\tregular: 400,\n\tmedium: 500,\n\tsemibold: 600,\n\tbold: 700,\n\textrabold: 800,\n\tblack: 900,\n};\n\n/**\n * SVG stroke-width values that simulate font weight.\n * Applied with `paint-order: stroke` so stroke renders behind fill.\n */\nexport const DIRHAM_STROKE_MAP: Record<DirhamWeight, number> = {\n\tthin: 0,\n\textralight: 0,\n\tlight: 0,\n\tregular: 0,\n\tmedium: 8,\n\tsemibold: 16,\n\tbold: 24,\n\textrabold: 36,\n\tblack: 48,\n};\n","import {\n\tDIRHAM_CURRENCY_CODE,\n\tDIRHAM_SYMBOL_TEXT,\n\tDIRHAM_UNICODE,\n} from \"./constants\";\n\n// ─── Intl.NumberFormat cache ─────────────────────────────────────────────────\n// Constructing Intl.NumberFormat is expensive (~µs). Cache instances keyed on\n// \"locale:decimals\" so repeated calls (e.g., rendering a price list) reuse\n// the same formatter instead of allocating a new object each time.\nconst _fmtCache = new Map<string, Intl.NumberFormat>();\n\nfunction getFormatter(locale: string, decimals: number): Intl.NumberFormat {\n\tconst key = `${locale}:${decimals}`;\n\tlet fmt = _fmtCache.get(key);\n\tif (!fmt) {\n\t\tfmt = new Intl.NumberFormat(locale, {\n\t\t\tminimumFractionDigits: decimals,\n\t\t\tmaximumFractionDigits: decimals,\n\t\t});\n\t\t_fmtCache.set(key, fmt);\n\t}\n\treturn fmt;\n}\n\n/**\n * Options for formatting a Dirham amount.\n */\nexport interface FormatDirhamOptions {\n\t/**\n\t * Locale string for number formatting.\n\t * @default \"en-AE\"\n\t */\n\tlocale?: string;\n\n\t/**\n\t * Number of decimal places.\n\t * @default 2\n\t */\n\tdecimals?: number;\n\n\t/**\n\t * Whether to place the symbol before the amount.\n\t * When `undefined`, determined by locale:\n\t * - Arabic locales (ar-*): symbol after amount\n\t * - Other locales: symbol before amount\n\t */\n\tsymbolFirst?: boolean;\n\n\t/**\n\t * Use ISO currency code (AED) instead of the symbol.\n\t * @default false\n\t */\n\tuseCode?: boolean;\n\n\t/**\n\t * Separator between symbol and amount.\n\t * @default \" \" (non-breaking space)\n\t */\n\tseparator?: string;\n}\n\n/**\n * Format a number as a Dirham currency string.\n *\n * @example\n * ```ts\n * formatDirham(100); // \"\\u20C3 100.00\"\n * formatDirham(1234.5); // \"\\u20C3 1,234.50\"\n * formatDirham(100, { locale: \"ar-AE\" }); // \"100.00 \\u20C3\"\n * formatDirham(100, { useCode: true }); // \"AED 100.00\"\n * ```\n */\nexport function formatDirham(\n\tamount: number,\n\toptions: FormatDirhamOptions = {},\n): string {\n\tif (!Number.isFinite(amount)) {\n\t\tthrow new RangeError(\n\t\t\t`formatDirham: amount must be a finite number, got ${amount}`,\n\t\t);\n\t}\n\n\tconst {\n\t\tlocale = \"en-AE\",\n\t\tdecimals = 2,\n\t\tuseCode = false,\n\t\tseparator = \"\\u00A0\", // non-breaking space\n\t} = options;\n\n\tconst symbol = useCode ? DIRHAM_CURRENCY_CODE : DIRHAM_UNICODE;\n\n\t// Determine symbol placement\n\tlet symbolFirst: boolean;\n\tif (options.symbolFirst !== undefined) {\n\t\tsymbolFirst = options.symbolFirst;\n\t} else {\n\t\t// Arabic locales place symbol after amount\n\t\tsymbolFirst = !locale.startsWith(\"ar\");\n\t}\n\n\t// Format the number (use cached formatter)\n\tconst formatted = getFormatter(locale, decimals).format(amount);\n\n\treturn symbolFirst\n\t\t? `${symbol}${separator}${formatted}`\n\t\t: `${formatted}${separator}${symbol}`;\n}\n\n/**\n * Options for parsing a Dirham-formatted string.\n */\nexport interface ParseDirhamOptions {\n\t/**\n\t * Normalize Arabic-Indic digits (٠١٢٣٤٥٦٧٨٩ / U+0660–U+0669) to ASCII\n\t * digits before parsing. Enables round-tripping strings produced by\n\t * `formatDirham` with Arabic locales (e.g. `\"ar-AE\"`).\n\t * @default true\n\t */\n\tnormalizeArabicNumerals?: boolean;\n}\n\n/**\n * Parse a Dirham-formatted string back to a number.\n * Strips currency symbols, codes, and formatting characters.\n * By default also normalizes Arabic-Indic digits so strings produced by\n * `formatDirham({ locale: \"ar-AE\" })` round-trip correctly.\n *\n * @example\n * ```ts\n * parseDirham(\"\\u20C3 1,234.50\"); // 1234.5\n * parseDirham(\"AED 100.00\"); // 100\n * parseDirham(\"١٬٢٣٤٫٥٠ \\u20C3\"); // 1234.5\n * parseDirham(\"١٠٠٫٠٠ \\u20C3\", { normalizeArabicNumerals: false }); // throws\n * ```\n */\nexport function parseDirham(\n\tvalue: string,\n\toptions: ParseDirhamOptions = {},\n): number {\n\tconst { normalizeArabicNumerals = true } = options;\n\n\tlet cleaned = value\n\t\t.replaceAll(DIRHAM_UNICODE, \"\")\n\t\t.replaceAll(DIRHAM_SYMBOL_TEXT, \"\")\n\t\t.replaceAll(DIRHAM_CURRENCY_CODE, \"\")\n\t\t.replace(/[,\\s\\u00A0\\u066C]/g, \"\") // ASCII comma, whitespace, NBSP, Arabic thousands sep\n\t\t.trim();\n\n\tif (normalizeArabicNumerals) {\n\t\t// Arabic-Indic digits U+0660–U+0669 → ASCII 0–9\n\t\tcleaned = cleaned.replace(\n\t\t\t/[\\u0660-\\u0669]/g,\n\t\t\t(d) => String(d.charCodeAt(0) - 0x0660),\n\t\t);\n\t\t// Arabic decimal separator (U+066B) → '.'\n\t\tcleaned = cleaned.replace(/\\u066B/g, \".\");\n\t}\n\n\tconst result = Number.parseFloat(cleaned);\n\tif (Number.isNaN(result)) {\n\t\tthrow new Error(`Cannot parse \"${value}\" as a Dirham amount`);\n\t}\n\treturn result;\n}\n"]} | ||
| {"version":3,"sources":["../src/core/constants.ts","../src/core/format.ts","../src/core/clipboard.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * UAE Dirham currency symbol constants.\n *\n * This package maps the Dirham glyph to the official Unicode codepoint U+20C3\n * (UAE DIRHAM SIGN) via a custom web font. The codepoint was accepted by the\n * Unicode Technical Committee for Unicode 18.0 (expected September 2026).\n *\n * Until system fonts ship native U+20C3 glyphs, the bundled web font provides\n * the rendering. When OS/font support lands, the web font becomes optional;\n * zero migration required.\n *\n * @module dirham\n * @see https://www.unicode.org/alloc/Pipeline.html\n */\n\n/** Unicode character for the Dirham symbol (U+20C3, requires Dirham web font until system fonts support it) */\nexport const DIRHAM_UNICODE = \"\\u20C3\";\n\n/** HTML entity for the Dirham symbol */\nexport const DIRHAM_HTML_ENTITY = \"⃃\";\n\n/** CSS content value for use in `::before` / `::after` pseudo-elements */\nexport const DIRHAM_CSS_CONTENT = \"\\\\20C3\";\n\n/** ISO 4217 currency code for UAE Dirham */\nexport const DIRHAM_CURRENCY_CODE = \"AED\";\n\n/** Arabic text representation of the Dirham symbol (د.إ) */\nexport const DIRHAM_SYMBOL_TEXT = \"د.إ\";\n\n/** The font family name used for the Dirham web font */\nexport const DIRHAM_FONT_FAMILY = \"Dirham\";\n\n/** CSS class name for the Dirham icon */\nexport const DIRHAM_CSS_CLASS = \"dirham-symbol\";\n\n/** Unicode codepoint as a number (0x20C3) */\nexport const DIRHAM_CODEPOINT = 0x20c3;\n\n// ── Font weight mapping ─────────────────────────────────────────────────\n\n/**\n * Supported visual weights for the Dirham symbol SVG component.\n *\n * Because the Dirham symbol is not yet in standard fonts (until Unicode 18.0),\n * weight simulation is applied via SVG stroke to match surrounding text weight,\n * similar to how $, €, £ adapt to their font's weight.\n */\nexport type DirhamWeight =\n\t| \"thin\"\n\t| \"extralight\"\n\t| \"light\"\n\t| \"regular\"\n\t| \"medium\"\n\t| \"semibold\"\n\t| \"bold\"\n\t| \"extrabold\"\n\t| \"black\";\n\n/**\n * Map from weight name to CSS `font-weight` numeric value.\n * Used for matching the symbol weight to surrounding text.\n */\nexport const DIRHAM_WEIGHT_MAP: Record<DirhamWeight, number> = {\n\tthin: 100,\n\textralight: 200,\n\tlight: 300,\n\tregular: 400,\n\tmedium: 500,\n\tsemibold: 600,\n\tbold: 700,\n\textrabold: 800,\n\tblack: 900,\n};\n\n/**\n * SVG stroke-width values that simulate font weight.\n * Applied with `paint-order: stroke` so stroke renders behind fill.\n */\nexport const DIRHAM_STROKE_MAP: Record<DirhamWeight, number> = {\n\tthin: 0,\n\textralight: 0,\n\tlight: 0,\n\tregular: 0,\n\tmedium: 8,\n\tsemibold: 16,\n\tbold: 24,\n\textrabold: 36,\n\tblack: 48,\n};\n","import {\n\tDIRHAM_CURRENCY_CODE,\n\tDIRHAM_SYMBOL_TEXT,\n\tDIRHAM_UNICODE,\n} from \"./constants\";\n\n// ─── Intl.NumberFormat cache ─────────────────────────────────────────────────\n// Constructing Intl.NumberFormat is expensive (~µs). Cache instances keyed on\n// \"locale:decimals\" so repeated calls (e.g., rendering a price list) reuse\n// the same formatter instead of allocating a new object each time.\nconst _fmtCache = new Map<string, Intl.NumberFormat>();\n\nfunction getFormatter(\n\tlocale: string,\n\tdecimals: number,\n\tnotation: \"standard\" | \"compact\" = \"standard\",\n): Intl.NumberFormat {\n\tconst key = `${locale}:${decimals}:${notation}`;\n\tlet fmt = _fmtCache.get(key);\n\tif (!fmt) {\n\t\tfmt = new Intl.NumberFormat(locale, {\n\t\t\tminimumFractionDigits: notation === \"compact\" ? 0 : decimals,\n\t\t\tmaximumFractionDigits: decimals,\n\t\t\t...(notation === \"compact\" && { notation: \"compact\", compactDisplay: \"short\" }),\n\t\t});\n\t\t_fmtCache.set(key, fmt);\n\t}\n\treturn fmt;\n}\n\n/**\n * Options for formatting a Dirham amount.\n */\nexport interface FormatDirhamOptions {\n\t/**\n\t * Locale string for number formatting.\n\t * @default \"en-AE\"\n\t */\n\tlocale?: string;\n\n\t/**\n\t * Number of decimal places.\n\t * @default 2\n\t */\n\tdecimals?: number;\n\n\t/**\n\t * Whether to place the symbol before the amount.\n\t * When `undefined`, determined by locale:\n\t * - Arabic locales (ar-*): symbol after amount\n\t * - Other locales: symbol before amount\n\t */\n\tsymbolFirst?: boolean;\n\n\t/**\n\t * Use ISO currency code (AED) instead of the symbol.\n\t * @default false\n\t */\n\tuseCode?: boolean;\n\n\t/**\n\t * Separator between symbol and amount.\n\t * @default \" \" (non-breaking space)\n\t */\n\tseparator?: string;\n\n\t/**\n\t * Number notation style.\n\t * - `\"standard\"` — full digits (e.g. 1,500,000.00)\n\t * - `\"compact\"` — abbreviated (e.g. 1.5M)\n\t * @default \"standard\"\n\t */\n\tnotation?: \"standard\" | \"compact\";\n}\n\n/**\n * Format a number as a Dirham currency string.\n *\n * @example\n * ```ts\n * formatDirham(100); // \"\\u20C3 100.00\"\n * formatDirham(1234.5); // \"\\u20C3 1,234.50\"\n * formatDirham(100, { locale: \"ar-AE\" }); // \"100.00 \\u20C3\"\n * formatDirham(100, { useCode: true }); // \"AED 100.00\"\n * formatDirham(1500000, { notation: \"compact\" }); // \"\\u20C3 1.5M\"\n * ```\n */\nexport function formatDirham(\n\tamount: number,\n\toptions: FormatDirhamOptions = {},\n): string {\n\tif (!Number.isFinite(amount)) {\n\t\tthrow new RangeError(\n\t\t\t`formatDirham: amount must be a finite number, got ${amount}`,\n\t\t);\n\t}\n\n\tconst {\n\t\tlocale = \"en-AE\",\n\t\tdecimals = 2,\n\t\tuseCode = false,\n\t\tseparator = \"\\u00A0\", // non-breaking space\n\t\tnotation = \"standard\",\n\t} = options;\n\n\tconst symbol = useCode ? DIRHAM_CURRENCY_CODE : DIRHAM_UNICODE;\n\n\t// Determine symbol placement\n\tlet symbolFirst: boolean;\n\tif (options.symbolFirst !== undefined) {\n\t\tsymbolFirst = options.symbolFirst;\n\t} else {\n\t\t// Arabic locales place symbol after amount\n\t\tsymbolFirst = !locale.startsWith(\"ar\");\n\t}\n\n\t// Format the number (use cached formatter)\n\tconst formatted = getFormatter(locale, decimals, notation).format(amount);\n\n\treturn symbolFirst\n\t\t? `${symbol}${separator}${formatted}`\n\t\t: `${formatted}${separator}${symbol}`;\n}\n\n/**\n * Options for parsing a Dirham-formatted string.\n */\nexport interface ParseDirhamOptions {\n\t/**\n\t * Normalize Arabic-Indic digits (٠١٢٣٤٥٦٧٨٩ / U+0660–U+0669) to ASCII\n\t * digits before parsing. Enables round-tripping strings produced by\n\t * `formatDirham` with Arabic locales (e.g. `\"ar-AE\"`).\n\t * @default true\n\t */\n\tnormalizeArabicNumerals?: boolean;\n}\n\n/**\n * Parse a Dirham-formatted string back to a number.\n * Strips currency symbols, codes, and formatting characters.\n * By default also normalizes Arabic-Indic digits so strings produced by\n * `formatDirham({ locale: \"ar-AE\" })` round-trip correctly.\n *\n * @example\n * ```ts\n * parseDirham(\"\\u20C3 1,234.50\"); // 1234.5\n * parseDirham(\"AED 100.00\"); // 100\n * parseDirham(\"١٬٢٣٤٫٥٠ \\u20C3\"); // 1234.5\n * parseDirham(\"١٠٠٫٠٠ \\u20C3\", { normalizeArabicNumerals: false }); // throws\n * ```\n */\nexport function parseDirham(\n\tvalue: string,\n\toptions: ParseDirhamOptions = {},\n): number {\n\tconst { normalizeArabicNumerals = true } = options;\n\n\tlet cleaned = value\n\t\t.replaceAll(DIRHAM_UNICODE, \"\")\n\t\t.replaceAll(DIRHAM_SYMBOL_TEXT, \"\")\n\t\t.replaceAll(DIRHAM_CURRENCY_CODE, \"\")\n\t\t.replace(/[,\\s\\u00A0\\u066C]/g, \"\") // ASCII comma, whitespace, NBSP, Arabic thousands sep\n\t\t.trim();\n\n\tif (normalizeArabicNumerals) {\n\t\t// Arabic-Indic digits U+0660–U+0669 → ASCII 0–9\n\t\tcleaned = cleaned.replace(\n\t\t\t/[\\u0660-\\u0669]/g,\n\t\t\t(d) => String(d.charCodeAt(0) - 0x0660),\n\t\t);\n\t\t// Arabic decimal separator (U+066B) → '.'\n\t\tcleaned = cleaned.replace(/\\u066B/g, \".\");\n\t}\n\n\tconst result = Number.parseFloat(cleaned);\n\tif (Number.isNaN(result)) {\n\t\tthrow new Error(`Cannot parse \"${value}\" as a Dirham amount`);\n\t}\n\treturn result;\n}\n","import {\n\tDIRHAM_CSS_CONTENT,\n\tDIRHAM_HTML_ENTITY,\n\tDIRHAM_SYMBOL_TEXT,\n\tDIRHAM_UNICODE,\n} from \"./constants\";\n\n/**\n * Format of the Dirham symbol to copy.\n *\n * - `\"unicode\"` — the character itself (`\\u20C3`)\n * - `\"html\"` — HTML entity (`⃃`)\n * - `\"css\"` — CSS content value (`\\\\20C3`)\n * - `\"arabic\"` — Arabic text (د.إ)\n */\nexport type DirhamCopyFormat = \"unicode\" | \"html\" | \"css\" | \"arabic\";\n\nconst FORMAT_MAP: Record<DirhamCopyFormat, string> = {\n\tunicode: DIRHAM_UNICODE,\n\thtml: DIRHAM_HTML_ENTITY,\n\tcss: DIRHAM_CSS_CONTENT,\n\tarabic: DIRHAM_SYMBOL_TEXT,\n};\n\n/**\n * Copy the Dirham symbol to the clipboard in the specified format.\n *\n * @returns A promise that resolves when the text is on the clipboard.\n * @throws If the Clipboard API is unavailable (e.g. non-browser environment).\n *\n * @example\n * ```ts\n * import { copyDirhamSymbol } from \"dirham\";\n *\n * await copyDirhamSymbol(); // copies \"\\u20C3\"\n * await copyDirhamSymbol(\"html\"); // copies \"⃃\"\n * await copyDirhamSymbol(\"css\"); // copies \"\\\\20C3\"\n * ```\n */\nexport async function copyDirhamSymbol(\n\tformat: DirhamCopyFormat = \"unicode\",\n): Promise<void> {\n\tconst text = FORMAT_MAP[format];\n\tif (typeof navigator === \"undefined\" || !navigator.clipboard) {\n\t\tthrow new Error(\n\t\t\t\"copyDirhamSymbol: Clipboard API is not available in this environment\",\n\t\t);\n\t}\n\tawait navigator.clipboard.writeText(text);\n}\n"]} |
+99
-0
@@ -9,2 +9,4 @@ 'use strict'; | ||
| // src/core/constants.ts | ||
| var DIRHAM_UNICODE = "\u20C3"; | ||
| var DIRHAM_CURRENCY_CODE = "AED"; | ||
| var DIRHAM_STROKE_MAP = { | ||
@@ -102,5 +104,102 @@ thin: 0, | ||
| // src/core/format.ts | ||
| var _fmtCache = /* @__PURE__ */ new Map(); | ||
| function getFormatter(locale, decimals, notation = "standard") { | ||
| const key = `${locale}:${decimals}:${notation}`; | ||
| let fmt = _fmtCache.get(key); | ||
| if (!fmt) { | ||
| fmt = new Intl.NumberFormat(locale, { | ||
| minimumFractionDigits: notation === "compact" ? 0 : decimals, | ||
| maximumFractionDigits: decimals, | ||
| ...notation === "compact" && { notation: "compact", compactDisplay: "short" } | ||
| }); | ||
| _fmtCache.set(key, fmt); | ||
| } | ||
| return fmt; | ||
| } | ||
| function formatDirham(amount, options = {}) { | ||
| if (!Number.isFinite(amount)) { | ||
| throw new RangeError( | ||
| `formatDirham: amount must be a finite number, got ${amount}` | ||
| ); | ||
| } | ||
| const { | ||
| locale = "en-AE", | ||
| decimals = 2, | ||
| useCode = false, | ||
| separator = "\xA0", | ||
| // non-breaking space | ||
| notation = "standard" | ||
| } = options; | ||
| const symbol = useCode ? DIRHAM_CURRENCY_CODE : DIRHAM_UNICODE; | ||
| let symbolFirst; | ||
| if (options.symbolFirst !== void 0) { | ||
| symbolFirst = options.symbolFirst; | ||
| } else { | ||
| symbolFirst = !locale.startsWith("ar"); | ||
| } | ||
| const formatted = getFormatter(locale, decimals, notation).format(amount); | ||
| return symbolFirst ? `${symbol}${separator}${formatted}` : `${formatted}${separator}${symbol}`; | ||
| } | ||
| var DirhamPriceBase = react.forwardRef( | ||
| ({ | ||
| amount, | ||
| locale = "en-AE", | ||
| decimals = 2, | ||
| useCode = false, | ||
| notation = "standard", | ||
| symbolSize = "1em", | ||
| weight = "regular", | ||
| "aria-label": ariaLabel, | ||
| style, | ||
| className, | ||
| ...props | ||
| }, ref) => { | ||
| const symbolFirst = !locale.startsWith("ar"); | ||
| const formatted = react.useMemo(() => { | ||
| if (!Number.isFinite(amount)) return "\u2014"; | ||
| return formatDirham(amount, { | ||
| locale, | ||
| decimals, | ||
| useCode: true, | ||
| // Always use code so we can strip it and render SVG instead | ||
| notation | ||
| }).replace("AED", "").trim(); | ||
| }, [amount, locale, decimals, notation]); | ||
| const symbol = useCode ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: "AED" }) : /* @__PURE__ */ jsxRuntime.jsx( | ||
| DirhamSymbol, | ||
| { | ||
| size: symbolSize, | ||
| weight, | ||
| "aria-label": ariaLabel ?? "UAE Dirham" | ||
| } | ||
| ); | ||
| return /* @__PURE__ */ jsxRuntime.jsx( | ||
| "span", | ||
| { | ||
| ref, | ||
| className, | ||
| style: { whiteSpace: "nowrap", ...style }, | ||
| ...props, | ||
| children: symbolFirst ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [ | ||
| symbol, | ||
| "\xA0", | ||
| formatted | ||
| ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [ | ||
| formatted, | ||
| "\xA0", | ||
| symbol | ||
| ] }) | ||
| } | ||
| ); | ||
| } | ||
| ); | ||
| DirhamPriceBase.displayName = "DirhamPrice"; | ||
| var DirhamPrice = react.memo(DirhamPriceBase); | ||
| DirhamPrice.displayName = "DirhamPrice"; | ||
| exports.DirhamIcon = DirhamIcon; | ||
| exports.DirhamPrice = DirhamPrice; | ||
| exports.DirhamSymbol = DirhamSymbol; | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../../src/core/constants.ts","../../src/react/DirhamSymbol.tsx","../../src/react/DirhamIcon.tsx"],"names":["forwardRef","jsx","memo"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * UAE Dirham currency symbol constants.\n *\n * This package maps the Dirham glyph to the official Unicode codepoint U+20C3\n * (UAE DIRHAM SIGN) via a custom web font. The codepoint was accepted by the\n * Unicode Technical Committee for Unicode 18.0 (expected September 2026).\n *\n * Until system fonts ship native U+20C3 glyphs, the bundled web font provides\n * the rendering. When OS/font support lands, the web font becomes optional;\n * zero migration required.\n *\n * @module dirham\n * @see https://www.unicode.org/alloc/Pipeline.html\n */\n\n/** Unicode character for the Dirham symbol (U+20C3, requires Dirham web font until system fonts support it) */\nexport const DIRHAM_UNICODE = \"\\u20C3\";\n\n/** HTML entity for the Dirham symbol */\nexport const DIRHAM_HTML_ENTITY = \"⃃\";\n\n/** CSS content value for use in `::before` / `::after` pseudo-elements */\nexport const DIRHAM_CSS_CONTENT = \"\\\\20C3\";\n\n/** ISO 4217 currency code for UAE Dirham */\nexport const DIRHAM_CURRENCY_CODE = \"AED\";\n\n/** Arabic text representation of the Dirham symbol (د.إ) */\nexport const DIRHAM_SYMBOL_TEXT = \"د.إ\";\n\n/** The font family name used for the Dirham web font */\nexport const DIRHAM_FONT_FAMILY = \"Dirham\";\n\n/** CSS class name for the Dirham icon */\nexport const DIRHAM_CSS_CLASS = \"dirham-symbol\";\n\n/** Unicode codepoint as a number (0x20C3) */\nexport const DIRHAM_CODEPOINT = 0x20c3;\n\n// ── Font weight mapping ─────────────────────────────────────────────────\n\n/**\n * Supported visual weights for the Dirham symbol SVG component.\n *\n * Because the Dirham symbol is not yet in standard fonts (until Unicode 18.0),\n * weight simulation is applied via SVG stroke to match surrounding text weight,\n * similar to how $, €, £ adapt to their font's weight.\n */\nexport type DirhamWeight =\n\t| \"thin\"\n\t| \"extralight\"\n\t| \"light\"\n\t| \"regular\"\n\t| \"medium\"\n\t| \"semibold\"\n\t| \"bold\"\n\t| \"extrabold\"\n\t| \"black\";\n\n/**\n * Map from weight name to CSS `font-weight` numeric value.\n * Used for matching the symbol weight to surrounding text.\n */\nexport const DIRHAM_WEIGHT_MAP: Record<DirhamWeight, number> = {\n\tthin: 100,\n\textralight: 200,\n\tlight: 300,\n\tregular: 400,\n\tmedium: 500,\n\tsemibold: 600,\n\tbold: 700,\n\textrabold: 800,\n\tblack: 900,\n};\n\n/**\n * SVG stroke-width values that simulate font weight.\n * Applied with `paint-order: stroke` so stroke renders behind fill.\n */\nexport const DIRHAM_STROKE_MAP: Record<DirhamWeight, number> = {\n\tthin: 0,\n\textralight: 0,\n\tlight: 0,\n\tregular: 0,\n\tmedium: 8,\n\tsemibold: 16,\n\tbold: 24,\n\textrabold: 36,\n\tblack: 48,\n};\n","import type React from \"react\";\nimport { forwardRef, memo } from \"react\";\nimport { DIRHAM_STROKE_MAP, type DirhamWeight } from \"../core/constants\";\n\nexport interface DirhamSymbolProps\n\textends Omit<React.SVGProps<SVGSVGElement>, \"children\"> {\n\t/**\n\t * Size of the symbol in pixels. Sets both width and height.\n\t * @default 24\n\t */\n\tsize?: number | string;\n\n\t/**\n\t * Color of the symbol. Uses `currentColor` by default to inherit text color.\n\t * @default \"currentColor\"\n\t */\n\tcolor?: string;\n\n\t/**\n\t * Accessible label for screen readers.\n\t * @default \"UAE Dirham\"\n\t */\n\t\"aria-label\"?: string;\n\n\t/**\n\t * Visual weight of the symbol. Simulates font-weight via SVG stroke\n\t * so the symbol matches surrounding text weight.\n\t *\n\t * @example\n\t * ```tsx\n\t * <h1 style={{ fontWeight: 700 }}>\n\t * Price: 100 <DirhamSymbol size=\"1em\" weight=\"bold\" />\n\t * </h1>\n\t * ```\n\t *\n\t * @default \"regular\"\n\t */\n\tweight?: DirhamWeight;\n}\n\n/**\n * SVG-based UAE Dirham symbol React component.\n *\n * Renders the Dirham symbol as an inline SVG. No font loading required.\n * Works with SSR, is tree-shakeable, and avoids FOIT.\n *\n * @example\n * ```tsx\n * import { DirhamSymbol } from \"dirham/react\";\n *\n * <DirhamSymbol size={16} />\n * <DirhamSymbol size={24} color=\"green\" />\n * <span>100 <DirhamSymbol size=\"1em\" /></span>\n * ```\n */\nconst DirhamSymbolBase = forwardRef<SVGSVGElement, DirhamSymbolProps>(\n\t(\n\t\t{\n\t\t\tsize = 24,\n\t\t\tcolor = \"currentColor\",\n\t\t\t\"aria-label\": ariaLabel = \"UAE Dirham\",\n\t\t\tweight = \"regular\",\n\t\t\tstyle,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst strokeWidth = DIRHAM_STROKE_MAP[weight];\n\n\t\treturn (\n\t\t\t<svg\n\t\t\t\tref={ref}\n\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\tviewBox=\"0 0 1000 870\"\n\t\t\t\twidth={size}\n\t\t\t\theight={size}\n\t\t\t\tfill={color}\n\t\t\t\trole=\"img\"\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\tstyle={{\n\t\t\t\t\tdisplay: \"inline-block\",\n\t\t\t\t\tverticalAlign: \"middle\",\n\t\t\t\t\t...style,\n\t\t\t\t}}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<path\n\t\t\t\t\td=\"m88.3 1c0.4 0.6 2.6 3.3 4.7 5.9 15.3 18.2 26.8 47.8 33 85.1 4.1 24.5 4.3 32.2 4.3 125.6v87h-41.8c-38.2 0-42.6-0.2-50.1-1.7-11.8-2.5-24-9.2-32.2-17.8-6.5-6.9-6.3-7.3-5.9 13.6 0.5 17.3 0.7 19.2 3.2 28.6 4 14.9 9.5 26 17.8 35.9 11.3 13.6 22.8 21.2 39.2 26.3 3.5 1 10.9 1.4 37.1 1.6l32.7 0.5v43.3 43.4l-46.1-0.3-46.3-0.3-8-3.2c-9.5-3.8-13.8-6.6-23.1-14.9l-6.8-6.1 0.4 19.1c0.5 17.7 0.6 19.7 3.1 28.7 8.7 31.8 29.7 54.5 57.4 61.9 6.9 1.9 9.6 2 38.5 2.4l30.9 0.4v89.6c0 54.1-0.3 94-0.8 100.8-0.5 6.2-2.1 17.8-3.5 25.9-6.5 37.3-18.2 65.4-35 83.6l-3.4 3.7h169.1c101.1 0 176.7-0.4 187.8-0.9 19.5-1 63-5.3 72.8-7.4 3.1-0.6 8.9-1.5 12.7-2.1 8.1-1.2 21.5-4 40.8-8.9 27.2-6.8 52-15.3 76.3-26.1 7.6-3.4 29.4-14.5 35.2-18 3.1-1.8 6.8-4 8.2-4.7 3.9-2.1 10.4-6.3 19.9-13.1 4.7-3.4 9.4-6.7 10.4-7.4 4.2-2.8 18.7-14.9 25.3-21 25.1-23.1 46.1-48.8 62.4-76.3 2.3-4 5.3-9 6.6-11.1 3.3-5.6 16.9-33.6 18.2-37.8 0.6-1.9 1.4-3.9 1.8-4.3 2.6-3.4 17.6-50.6 19.4-60.9 0.6-3.3 0.9-3.8 3.4-4.3 1.6-0.3 24.9-0.3 51.8-0.1 53.8 0.4 53.8 0.4 65.7 5.9 6.7 3.1 8.7 4.5 16.1 11.2 9.7 8.7 8.8 10.1 8.2-11.7-0.4-12.8-0.9-20.7-1.8-23.9-3.4-12.3-4.2-14.9-7.2-21.1-9.8-21.4-26.2-36.7-47.2-44l-8.2-3-33.4-0.4-33.3-0.5 0.4-11.7c0.4-15.4 0.4-45.9-0.1-61.6l-0.4-12.6 44.6-0.2c38.2-0.2 45.3 0 49.5 1.1 12.6 3.5 21.1 8.3 31.5 17.8l5.8 5.4v-14.8c0-17.6-0.9-25.4-4.5-37-7.1-23.5-21.1-41-41.1-51.8-13-7-13.8-7.2-58.5-7.5-26.2-0.2-39.9-0.6-40.6-1.2-0.6-0.6-1.1-1.6-1.1-2.4 0-0.8-1.5-7.1-3.5-13.9-23.4-82.7-67.1-148.4-131-197.1-8.7-6.7-30-20.8-38.6-25.6-3.3-1.9-6.9-3.9-7.8-4.5-4.2-2.3-28.3-14.1-34.3-16.6-3.6-1.6-8.3-3.6-10.4-4.4-35.3-15.3-94.5-29.8-139.7-34.3-7.4-0.7-17.2-1.8-21.7-2.2-20.4-2.3-48.7-2.6-209.4-2.6-135.8 0-169.9 0.3-169.4 1zm330.7 43.3c33.8 2 54.6 4.6 78.9 10.5 74.2 17.6 126.4 54.8 164.3 117 3.5 5.8 18.3 36 20.5 42.1 10.5 28.3 15.6 45.1 20.1 67.3 1.1 5.4 2.6 12.6 3.3 16 0.7 3.3 1 6.4 0.7 6.7-0.5 0.4-100.9 0.6-223.3 0.5l-222.5-0.2-0.3-128.5c-0.1-70.6 0-129.3 0.3-130.4l0.4-1.9h71.1c39 0 78 0.4 86.5 0.9zm297.5 350.3c0.7 4.3 0.7 77.3 0 80.9l-0.6 2.7-227.5-0.2-227.4-0.3-0.2-42.4c-0.2-23.3 0-42.7 0.2-43.1 0.3-0.5 97.2-0.8 227.7-0.8h227.2zm-10.2 171.7c0.5 1.5-1.9 13.8-6.8 33.8-5.6 22.5-13.2 45.2-20.9 62-3.8 8.6-13.3 27.2-15.6 30.7-1.1 1.6-4.3 6.7-7.1 11.2-18 28.2-43.7 53.9-73 72.9-10.7 6.8-32.7 18.4-38.6 20.2-1.2 0.3-2.5 0.9-3 1.3-0.7 0.6-9.8 4-20.4 7.8-19.5 6.9-56.6 14.4-86.4 17.5-19.3 1.9-22.4 2-96.7 2h-76.9v-129.7-129.8l220.9-0.4c121.5-0.2 221.6-0.5 222.4-0.7 0.9-0.1 1.8 0.5 2.1 1.2z\"\n\t\t\t\t\t{...(strokeWidth > 0 && {\n\t\t\t\t\t\tstroke: color,\n\t\t\t\t\t\tstrokeWidth,\n\t\t\t\t\t\tstrokeLinejoin: \"round\" as const,\n\t\t\t\t\t\tpaintOrder: \"stroke\",\n\t\t\t\t\t})}\n\t\t\t\t/>\n\t\t\t</svg>\n\t\t);\n\t},\n);\n\nDirhamSymbolBase.displayName = \"DirhamSymbol\";\n\n// Memoize so the component only re-renders when its own props change.\n// This is important when DirhamSymbol is used inside list items or tables\n// that re-render frequently due to unrelated parent state changes.\nexport const DirhamSymbol = memo(DirhamSymbolBase);\nDirhamSymbol.displayName = \"DirhamSymbol\";\n","import type React from \"react\";\nimport { forwardRef, memo } from \"react\";\n\nexport interface DirhamIconProps\n\textends Omit<React.HTMLProps<HTMLElement>, \"children\" | \"size\"> {\n\t/**\n\t * Font size of the icon. Applied as the CSS `font-size` property.\n\t * @default \"inherit\"\n\t */\n\tsize?: number | string;\n\n\t/**\n\t * Color of the icon. Applied as the CSS `color` property.\n\t * @default \"currentColor\"\n\t */\n\tcolor?: string;\n\n\t/**\n\t * Accessible label for screen readers.\n\t * @default \"UAE Dirham\"\n\t */\n\t\"aria-label\"?: string;\n\n\t/**\n\t * HTML tag to render.\n\t * @default \"i\"\n\t */\n\tas?: \"i\" | \"span\";\n}\n\n/**\n * Font-based UAE Dirham symbol React component.\n *\n * Requires `dirham/css` to be imported for the `@font-face` and\n * `.dirham-symbol` class to be available.\n *\n * @example\n * ```tsx\n * import \"dirham/css\";\n * import { DirhamIcon } from \"dirham/react\";\n *\n * <DirhamIcon />\n * <DirhamIcon size={32} color=\"green\" />\n * ```\n */\nconst DirhamIconBase = forwardRef<HTMLElement, DirhamIconProps>(\n\t(\n\t\t{\n\t\t\tsize,\n\t\t\tcolor = \"currentColor\",\n\t\t\t\"aria-label\": ariaLabel = \"UAE Dirham\",\n\t\t\tas: Tag = \"i\",\n\t\t\tclassName = \"\",\n\t\t\tstyle,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst classes = `dirham-symbol${className ? ` ${className}` : \"\"}`;\n\t\tconst iconStyle: React.CSSProperties = {\n\t\t\t...(size !== undefined && {\n\t\t\t\tfontSize: typeof size === \"number\" ? `${size}px` : size,\n\t\t\t}),\n\t\t\tcolor,\n\t\t\t...style,\n\t\t};\n\n\t\treturn (\n\t\t\t<Tag\n\t\t\t\tref={ref as React.Ref<HTMLElement>}\n\t\t\t\tclassName={classes}\n\t\t\t\tstyle={iconStyle}\n\t\t\t\trole=\"img\"\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\t{...(props as React.HTMLProps<HTMLElement>)}\n\t\t\t/>\n\t\t);\n\t},\n);\n\nDirhamIconBase.displayName = \"DirhamIcon\";\n\n// Memoize so the component only re-renders when its own props change.\nexport const DirhamIcon = memo(DirhamIconBase);\nDirhamIcon.displayName = \"DirhamIcon\";\n"]} | ||
| {"version":3,"sources":["../../src/core/constants.ts","../../src/react/DirhamSymbol.tsx","../../src/react/DirhamIcon.tsx","../../src/core/format.ts","../../src/react/DirhamPrice.tsx"],"names":["forwardRef","jsx","memo","useMemo","jsxs","Fragment"],"mappings":";;;;;;;;AAgBO,IAAM,cAAA,GAAiB,QAAA;AASvB,IAAM,oBAAA,GAAuB,KAAA;AAsD7B,IAAM,iBAAA,GAAkD;AAAA,EAC9D,IAAA,EAAM,CAAA;AAAA,EACN,UAAA,EAAY,CAAA;AAAA,EACZ,KAAA,EAAO,CAAA;AAAA,EACP,OAAA,EAAS,CAAA;AAAA,EACT,MAAA,EAAQ,CAAA;AAAA,EACR,QAAA,EAAU,EAAA;AAAA,EACV,IAAA,EAAM,EAAA;AAAA,EACN,SAAA,EAAW,EAAA;AAAA,EACX,KAAA,EAAO;AACR,CAAA;AClCA,IAAM,gBAAA,GAAmBA,gBAAA;AAAA,EACxB,CACC;AAAA,IACC,IAAA,GAAO,EAAA;AAAA,IACP,KAAA,GAAQ,cAAA;AAAA,IACR,cAAc,SAAA,GAAY,YAAA;AAAA,IAC1B,MAAA,GAAS,SAAA;AAAA,IACT,KAAA;AAAA,IACA,GAAG;AAAA,KAEJ,GAAA,KACI;AACJ,IAAA,MAAM,WAAA,GAAc,kBAAkB,MAAM,CAAA;AAE5C,IAAA,uBACCC,cAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACA,GAAA;AAAA,QACA,KAAA,EAAM,4BAAA;AAAA,QACN,OAAA,EAAQ,cAAA;AAAA,QACR,KAAA,EAAO,IAAA;AAAA,QACP,MAAA,EAAQ,IAAA;AAAA,QACR,IAAA,EAAM,KAAA;AAAA,QACN,IAAA,EAAK,KAAA;AAAA,QACL,YAAA,EAAY,SAAA;AAAA,QACZ,KAAA,EAAO;AAAA,UACN,OAAA,EAAS,cAAA;AAAA,UACT,aAAA,EAAe,QAAA;AAAA,UACf,GAAG;AAAA,SACJ;AAAA,QACC,GAAG,KAAA;AAAA,QAEJ,QAAA,kBAAAA,cAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACA,CAAA,EAAE,25EAAA;AAAA,YACD,GAAI,cAAc,CAAA,IAAK;AAAA,cACvB,MAAA,EAAQ,KAAA;AAAA,cACR,WAAA;AAAA,cACA,cAAA,EAAgB,OAAA;AAAA,cAChB,UAAA,EAAY;AAAA;AACb;AAAA;AACD;AAAA,KACD;AAAA,EAEF;AACD,CAAA;AAEA,gBAAA,CAAiB,WAAA,GAAc,cAAA;AAKxB,IAAM,YAAA,GAAeC,WAAK,gBAAgB;AACjD,YAAA,CAAa,WAAA,GAAc,cAAA;AC7D3B,IAAM,cAAA,GAAiBF,gBAAAA;AAAA,EACtB,CACC;AAAA,IACC,IAAA;AAAA,IACA,KAAA,GAAQ,cAAA;AAAA,IACR,cAAc,SAAA,GAAY,YAAA;AAAA,IAC1B,IAAI,GAAA,GAAM,GAAA;AAAA,IACV,SAAA,GAAY,EAAA;AAAA,IACZ,KAAA;AAAA,IACA,GAAG;AAAA,KAEJ,GAAA,KACI;AACJ,IAAA,MAAM,UAAU,CAAA,aAAA,EAAgB,SAAA,GAAY,CAAA,CAAA,EAAI,SAAS,KAAK,EAAE,CAAA,CAAA;AAChE,IAAA,MAAM,SAAA,GAAiC;AAAA,MACtC,GAAI,SAAS,MAAA,IAAa;AAAA,QACzB,UAAU,OAAO,IAAA,KAAS,QAAA,GAAW,CAAA,EAAG,IAAI,CAAA,EAAA,CAAA,GAAO;AAAA,OACpD;AAAA,MACA,KAAA;AAAA,MACA,GAAG;AAAA,KACJ;AAEA,IAAA,uBACCC,cAAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACA,GAAA;AAAA,QACA,SAAA,EAAW,OAAA;AAAA,QACX,KAAA,EAAO,SAAA;AAAA,QACP,IAAA,EAAK,KAAA;AAAA,QACL,YAAA,EAAY,SAAA;AAAA,QACX,GAAI;AAAA;AAAA,KACN;AAAA,EAEF;AACD,CAAA;AAEA,cAAA,CAAe,WAAA,GAAc,YAAA;AAGtB,IAAM,UAAA,GAAaC,WAAK,cAAc;AAC7C,UAAA,CAAW,WAAA,GAAc,YAAA;;;AC1EzB,IAAM,SAAA,uBAAgB,GAAA,EAA+B;AAErD,SAAS,YAAA,CACR,MAAA,EACA,QAAA,EACA,QAAA,GAAmC,UAAA,EACf;AACpB,EAAA,MAAM,MAAM,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,QAAQ,IAAI,QAAQ,CAAA,CAAA;AAC7C,EAAA,IAAI,GAAA,GAAM,SAAA,CAAU,GAAA,CAAI,GAAG,CAAA;AAC3B,EAAA,IAAI,CAAC,GAAA,EAAK;AACT,IAAA,GAAA,GAAM,IAAI,IAAA,CAAK,YAAA,CAAa,MAAA,EAAQ;AAAA,MACnC,qBAAA,EAAuB,QAAA,KAAa,SAAA,GAAY,CAAA,GAAI,QAAA;AAAA,MACpD,qBAAA,EAAuB,QAAA;AAAA,MACvB,GAAI,QAAA,KAAa,SAAA,IAAa,EAAE,QAAA,EAAU,SAAA,EAAW,gBAAgB,OAAA;AAAQ,KAC7E,CAAA;AACD,IAAA,SAAA,CAAU,GAAA,CAAI,KAAK,GAAG,CAAA;AAAA,EACvB;AACA,EAAA,OAAO,GAAA;AACR;AA2DO,SAAS,YAAA,CACf,MAAA,EACA,OAAA,GAA+B,EAAC,EACvB;AACT,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,EAAG;AAC7B,IAAA,MAAM,IAAI,UAAA;AAAA,MACT,qDAAqD,MAAM,CAAA;AAAA,KAC5D;AAAA,EACD;AAEA,EAAA,MAAM;AAAA,IACL,MAAA,GAAS,OAAA;AAAA,IACT,QAAA,GAAW,CAAA;AAAA,IACX,OAAA,GAAU,KAAA;AAAA,IACV,SAAA,GAAY,MAAA;AAAA;AAAA,IACZ,QAAA,GAAW;AAAA,GACZ,GAAI,OAAA;AAEJ,EAAA,MAAM,MAAA,GAAS,UAAU,oBAAA,GAAuB,cAAA;AAGhD,EAAA,IAAI,WAAA;AACJ,EAAA,IAAI,OAAA,CAAQ,gBAAgB,MAAA,EAAW;AACtC,IAAA,WAAA,GAAc,OAAA,CAAQ,WAAA;AAAA,EACvB,CAAA,MAAO;AAEN,IAAA,WAAA,GAAc,CAAC,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AAAA,EACtC;AAGA,EAAA,MAAM,YAAY,YAAA,CAAa,MAAA,EAAQ,UAAU,QAAQ,CAAA,CAAE,OAAO,MAAM,CAAA;AAExE,EAAA,OAAO,WAAA,GACJ,CAAA,EAAG,MAAM,CAAA,EAAG,SAAS,CAAA,EAAG,SAAS,CAAA,CAAA,GACjC,CAAA,EAAG,SAAS,CAAA,EAAG,SAAS,GAAG,MAAM,CAAA,CAAA;AACrC;ACvDA,IAAM,eAAA,GAAkBF,gBAAAA;AAAA,EACvB,CACC;AAAA,IACC,MAAA;AAAA,IACA,MAAA,GAAS,OAAA;AAAA,IACT,QAAA,GAAW,CAAA;AAAA,IACX,OAAA,GAAU,KAAA;AAAA,IACV,QAAA,GAAW,UAAA;AAAA,IACX,UAAA,GAAa,KAAA;AAAA,IACb,MAAA,GAAS,SAAA;AAAA,IACT,YAAA,EAAc,SAAA;AAAA,IACd,KAAA;AAAA,IACA,SAAA;AAAA,IACA,GAAG;AAAA,KAEJ,GAAA,KACI;AACJ,IAAA,MAAM,WAAA,GAAc,CAAC,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AAE3C,IAAA,MAAM,SAAA,GAAYG,cAAQ,MAAM;AAC/B,MAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,MAAM,GAAG,OAAO,QAAA;AACrC,MAAA,OAAO,aAAa,MAAA,EAAQ;AAAA,QAC3B,MAAA;AAAA,QACA,QAAA;AAAA,QACA,OAAA,EAAS,IAAA;AAAA;AAAA,QACT;AAAA,OACA,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,EAAE,EAAE,IAAA,EAAK;AAAA,IAC5B,GAAG,CAAC,MAAA,EAAQ,MAAA,EAAQ,QAAA,EAAU,QAAQ,CAAC,CAAA;AAEvC,IAAA,MAAM,SAAS,OAAA,mBACdF,eAAC,MAAA,EAAA,EAAK,QAAA,EAAA,KAAA,EAAG,oBAETA,cAAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACA,IAAA,EAAM,UAAA;AAAA,QACN,MAAA;AAAA,QACA,cAAY,SAAA,IAAa;AAAA;AAAA,KAC1B;AAGD,IAAA,uBACCA,cAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACA,GAAA;AAAA,QACA,SAAA;AAAA,QACA,KAAA,EAAO,EAAE,UAAA,EAAY,QAAA,EAAU,GAAG,KAAA,EAAM;AAAA,QACvC,GAAG,KAAA;AAAA,QAEH,wCACAG,eAAA,CAAAC,mBAAA,EAAA,EACE,QAAA,EAAA;AAAA,UAAA,MAAA;AAAA,UACA,MAAA;AAAA,UACA;AAAA,SAAA,EACF,oBAEAD,eAAA,CAAAC,mBAAA,EAAA,EACE,QAAA,EAAA;AAAA,UAAA,SAAA;AAAA,UACA,MAAA;AAAA,UACA;AAAA,SAAA,EACF;AAAA;AAAA,KAEF;AAAA,EAEF;AACD,CAAA;AAEA,eAAA,CAAgB,WAAA,GAAc,aAAA;AAEvB,IAAM,WAAA,GAAcH,WAAK,eAAe;AAC/C,WAAA,CAAY,WAAA,GAAc,aAAA","file":"index.cjs","sourcesContent":["/**\n * UAE Dirham currency symbol constants.\n *\n * This package maps the Dirham glyph to the official Unicode codepoint U+20C3\n * (UAE DIRHAM SIGN) via a custom web font. The codepoint was accepted by the\n * Unicode Technical Committee for Unicode 18.0 (expected September 2026).\n *\n * Until system fonts ship native U+20C3 glyphs, the bundled web font provides\n * the rendering. When OS/font support lands, the web font becomes optional;\n * zero migration required.\n *\n * @module dirham\n * @see https://www.unicode.org/alloc/Pipeline.html\n */\n\n/** Unicode character for the Dirham symbol (U+20C3, requires Dirham web font until system fonts support it) */\nexport const DIRHAM_UNICODE = \"\\u20C3\";\n\n/** HTML entity for the Dirham symbol */\nexport const DIRHAM_HTML_ENTITY = \"⃃\";\n\n/** CSS content value for use in `::before` / `::after` pseudo-elements */\nexport const DIRHAM_CSS_CONTENT = \"\\\\20C3\";\n\n/** ISO 4217 currency code for UAE Dirham */\nexport const DIRHAM_CURRENCY_CODE = \"AED\";\n\n/** Arabic text representation of the Dirham symbol (د.إ) */\nexport const DIRHAM_SYMBOL_TEXT = \"د.إ\";\n\n/** The font family name used for the Dirham web font */\nexport const DIRHAM_FONT_FAMILY = \"Dirham\";\n\n/** CSS class name for the Dirham icon */\nexport const DIRHAM_CSS_CLASS = \"dirham-symbol\";\n\n/** Unicode codepoint as a number (0x20C3) */\nexport const DIRHAM_CODEPOINT = 0x20c3;\n\n// ── Font weight mapping ─────────────────────────────────────────────────\n\n/**\n * Supported visual weights for the Dirham symbol SVG component.\n *\n * Because the Dirham symbol is not yet in standard fonts (until Unicode 18.0),\n * weight simulation is applied via SVG stroke to match surrounding text weight,\n * similar to how $, €, £ adapt to their font's weight.\n */\nexport type DirhamWeight =\n\t| \"thin\"\n\t| \"extralight\"\n\t| \"light\"\n\t| \"regular\"\n\t| \"medium\"\n\t| \"semibold\"\n\t| \"bold\"\n\t| \"extrabold\"\n\t| \"black\";\n\n/**\n * Map from weight name to CSS `font-weight` numeric value.\n * Used for matching the symbol weight to surrounding text.\n */\nexport const DIRHAM_WEIGHT_MAP: Record<DirhamWeight, number> = {\n\tthin: 100,\n\textralight: 200,\n\tlight: 300,\n\tregular: 400,\n\tmedium: 500,\n\tsemibold: 600,\n\tbold: 700,\n\textrabold: 800,\n\tblack: 900,\n};\n\n/**\n * SVG stroke-width values that simulate font weight.\n * Applied with `paint-order: stroke` so stroke renders behind fill.\n */\nexport const DIRHAM_STROKE_MAP: Record<DirhamWeight, number> = {\n\tthin: 0,\n\textralight: 0,\n\tlight: 0,\n\tregular: 0,\n\tmedium: 8,\n\tsemibold: 16,\n\tbold: 24,\n\textrabold: 36,\n\tblack: 48,\n};\n","import type React from \"react\";\nimport { forwardRef, memo } from \"react\";\nimport { DIRHAM_STROKE_MAP, type DirhamWeight } from \"../core/constants\";\n\nexport interface DirhamSymbolProps\n\textends Omit<React.SVGProps<SVGSVGElement>, \"children\"> {\n\t/**\n\t * Size of the symbol in pixels. Sets both width and height.\n\t * @default 24\n\t */\n\tsize?: number | string;\n\n\t/**\n\t * Color of the symbol. Uses `currentColor` by default to inherit text color.\n\t * @default \"currentColor\"\n\t */\n\tcolor?: string;\n\n\t/**\n\t * Accessible label for screen readers.\n\t * @default \"UAE Dirham\"\n\t */\n\t\"aria-label\"?: string;\n\n\t/**\n\t * Visual weight of the symbol. Simulates font-weight via SVG stroke\n\t * so the symbol matches surrounding text weight.\n\t *\n\t * @example\n\t * ```tsx\n\t * <h1 style={{ fontWeight: 700 }}>\n\t * Price: 100 <DirhamSymbol size=\"1em\" weight=\"bold\" />\n\t * </h1>\n\t * ```\n\t *\n\t * @default \"regular\"\n\t */\n\tweight?: DirhamWeight;\n}\n\n/**\n * SVG-based UAE Dirham symbol React component.\n *\n * Renders the Dirham symbol as an inline SVG. No font loading required.\n * Works with SSR, is tree-shakeable, and avoids FOIT.\n *\n * @example\n * ```tsx\n * import { DirhamSymbol } from \"dirham/react\";\n *\n * <DirhamSymbol size={16} />\n * <DirhamSymbol size={24} color=\"green\" />\n * <span>100 <DirhamSymbol size=\"1em\" /></span>\n * ```\n */\nconst DirhamSymbolBase = forwardRef<SVGSVGElement, DirhamSymbolProps>(\n\t(\n\t\t{\n\t\t\tsize = 24,\n\t\t\tcolor = \"currentColor\",\n\t\t\t\"aria-label\": ariaLabel = \"UAE Dirham\",\n\t\t\tweight = \"regular\",\n\t\t\tstyle,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst strokeWidth = DIRHAM_STROKE_MAP[weight];\n\n\t\treturn (\n\t\t\t<svg\n\t\t\t\tref={ref}\n\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\tviewBox=\"0 0 1000 870\"\n\t\t\t\twidth={size}\n\t\t\t\theight={size}\n\t\t\t\tfill={color}\n\t\t\t\trole=\"img\"\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\tstyle={{\n\t\t\t\t\tdisplay: \"inline-block\",\n\t\t\t\t\tverticalAlign: \"middle\",\n\t\t\t\t\t...style,\n\t\t\t\t}}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<path\n\t\t\t\t\td=\"m88.3 1c0.4 0.6 2.6 3.3 4.7 5.9 15.3 18.2 26.8 47.8 33 85.1 4.1 24.5 4.3 32.2 4.3 125.6v87h-41.8c-38.2 0-42.6-0.2-50.1-1.7-11.8-2.5-24-9.2-32.2-17.8-6.5-6.9-6.3-7.3-5.9 13.6 0.5 17.3 0.7 19.2 3.2 28.6 4 14.9 9.5 26 17.8 35.9 11.3 13.6 22.8 21.2 39.2 26.3 3.5 1 10.9 1.4 37.1 1.6l32.7 0.5v43.3 43.4l-46.1-0.3-46.3-0.3-8-3.2c-9.5-3.8-13.8-6.6-23.1-14.9l-6.8-6.1 0.4 19.1c0.5 17.7 0.6 19.7 3.1 28.7 8.7 31.8 29.7 54.5 57.4 61.9 6.9 1.9 9.6 2 38.5 2.4l30.9 0.4v89.6c0 54.1-0.3 94-0.8 100.8-0.5 6.2-2.1 17.8-3.5 25.9-6.5 37.3-18.2 65.4-35 83.6l-3.4 3.7h169.1c101.1 0 176.7-0.4 187.8-0.9 19.5-1 63-5.3 72.8-7.4 3.1-0.6 8.9-1.5 12.7-2.1 8.1-1.2 21.5-4 40.8-8.9 27.2-6.8 52-15.3 76.3-26.1 7.6-3.4 29.4-14.5 35.2-18 3.1-1.8 6.8-4 8.2-4.7 3.9-2.1 10.4-6.3 19.9-13.1 4.7-3.4 9.4-6.7 10.4-7.4 4.2-2.8 18.7-14.9 25.3-21 25.1-23.1 46.1-48.8 62.4-76.3 2.3-4 5.3-9 6.6-11.1 3.3-5.6 16.9-33.6 18.2-37.8 0.6-1.9 1.4-3.9 1.8-4.3 2.6-3.4 17.6-50.6 19.4-60.9 0.6-3.3 0.9-3.8 3.4-4.3 1.6-0.3 24.9-0.3 51.8-0.1 53.8 0.4 53.8 0.4 65.7 5.9 6.7 3.1 8.7 4.5 16.1 11.2 9.7 8.7 8.8 10.1 8.2-11.7-0.4-12.8-0.9-20.7-1.8-23.9-3.4-12.3-4.2-14.9-7.2-21.1-9.8-21.4-26.2-36.7-47.2-44l-8.2-3-33.4-0.4-33.3-0.5 0.4-11.7c0.4-15.4 0.4-45.9-0.1-61.6l-0.4-12.6 44.6-0.2c38.2-0.2 45.3 0 49.5 1.1 12.6 3.5 21.1 8.3 31.5 17.8l5.8 5.4v-14.8c0-17.6-0.9-25.4-4.5-37-7.1-23.5-21.1-41-41.1-51.8-13-7-13.8-7.2-58.5-7.5-26.2-0.2-39.9-0.6-40.6-1.2-0.6-0.6-1.1-1.6-1.1-2.4 0-0.8-1.5-7.1-3.5-13.9-23.4-82.7-67.1-148.4-131-197.1-8.7-6.7-30-20.8-38.6-25.6-3.3-1.9-6.9-3.9-7.8-4.5-4.2-2.3-28.3-14.1-34.3-16.6-3.6-1.6-8.3-3.6-10.4-4.4-35.3-15.3-94.5-29.8-139.7-34.3-7.4-0.7-17.2-1.8-21.7-2.2-20.4-2.3-48.7-2.6-209.4-2.6-135.8 0-169.9 0.3-169.4 1zm330.7 43.3c33.8 2 54.6 4.6 78.9 10.5 74.2 17.6 126.4 54.8 164.3 117 3.5 5.8 18.3 36 20.5 42.1 10.5 28.3 15.6 45.1 20.1 67.3 1.1 5.4 2.6 12.6 3.3 16 0.7 3.3 1 6.4 0.7 6.7-0.5 0.4-100.9 0.6-223.3 0.5l-222.5-0.2-0.3-128.5c-0.1-70.6 0-129.3 0.3-130.4l0.4-1.9h71.1c39 0 78 0.4 86.5 0.9zm297.5 350.3c0.7 4.3 0.7 77.3 0 80.9l-0.6 2.7-227.5-0.2-227.4-0.3-0.2-42.4c-0.2-23.3 0-42.7 0.2-43.1 0.3-0.5 97.2-0.8 227.7-0.8h227.2zm-10.2 171.7c0.5 1.5-1.9 13.8-6.8 33.8-5.6 22.5-13.2 45.2-20.9 62-3.8 8.6-13.3 27.2-15.6 30.7-1.1 1.6-4.3 6.7-7.1 11.2-18 28.2-43.7 53.9-73 72.9-10.7 6.8-32.7 18.4-38.6 20.2-1.2 0.3-2.5 0.9-3 1.3-0.7 0.6-9.8 4-20.4 7.8-19.5 6.9-56.6 14.4-86.4 17.5-19.3 1.9-22.4 2-96.7 2h-76.9v-129.7-129.8l220.9-0.4c121.5-0.2 221.6-0.5 222.4-0.7 0.9-0.1 1.8 0.5 2.1 1.2z\"\n\t\t\t\t\t{...(strokeWidth > 0 && {\n\t\t\t\t\t\tstroke: color,\n\t\t\t\t\t\tstrokeWidth,\n\t\t\t\t\t\tstrokeLinejoin: \"round\" as const,\n\t\t\t\t\t\tpaintOrder: \"stroke\",\n\t\t\t\t\t})}\n\t\t\t\t/>\n\t\t\t</svg>\n\t\t);\n\t},\n);\n\nDirhamSymbolBase.displayName = \"DirhamSymbol\";\n\n// Memoize so the component only re-renders when its own props change.\n// This is important when DirhamSymbol is used inside list items or tables\n// that re-render frequently due to unrelated parent state changes.\nexport const DirhamSymbol = memo(DirhamSymbolBase);\nDirhamSymbol.displayName = \"DirhamSymbol\";\n","import type React from \"react\";\nimport { forwardRef, memo } from \"react\";\n\nexport interface DirhamIconProps\n\textends Omit<React.HTMLProps<HTMLElement>, \"children\" | \"size\"> {\n\t/**\n\t * Font size of the icon. Applied as the CSS `font-size` property.\n\t * @default \"inherit\"\n\t */\n\tsize?: number | string;\n\n\t/**\n\t * Color of the icon. Applied as the CSS `color` property.\n\t * @default \"currentColor\"\n\t */\n\tcolor?: string;\n\n\t/**\n\t * Accessible label for screen readers.\n\t * @default \"UAE Dirham\"\n\t */\n\t\"aria-label\"?: string;\n\n\t/**\n\t * HTML tag to render.\n\t * @default \"i\"\n\t */\n\tas?: \"i\" | \"span\";\n}\n\n/**\n * Font-based UAE Dirham symbol React component.\n *\n * Requires `dirham/css` to be imported for the `@font-face` and\n * `.dirham-symbol` class to be available.\n *\n * @example\n * ```tsx\n * import \"dirham/css\";\n * import { DirhamIcon } from \"dirham/react\";\n *\n * <DirhamIcon />\n * <DirhamIcon size={32} color=\"green\" />\n * ```\n */\nconst DirhamIconBase = forwardRef<HTMLElement, DirhamIconProps>(\n\t(\n\t\t{\n\t\t\tsize,\n\t\t\tcolor = \"currentColor\",\n\t\t\t\"aria-label\": ariaLabel = \"UAE Dirham\",\n\t\t\tas: Tag = \"i\",\n\t\t\tclassName = \"\",\n\t\t\tstyle,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst classes = `dirham-symbol${className ? ` ${className}` : \"\"}`;\n\t\tconst iconStyle: React.CSSProperties = {\n\t\t\t...(size !== undefined && {\n\t\t\t\tfontSize: typeof size === \"number\" ? `${size}px` : size,\n\t\t\t}),\n\t\t\tcolor,\n\t\t\t...style,\n\t\t};\n\n\t\treturn (\n\t\t\t<Tag\n\t\t\t\tref={ref as React.Ref<HTMLElement>}\n\t\t\t\tclassName={classes}\n\t\t\t\tstyle={iconStyle}\n\t\t\t\trole=\"img\"\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\t{...(props as React.HTMLProps<HTMLElement>)}\n\t\t\t/>\n\t\t);\n\t},\n);\n\nDirhamIconBase.displayName = \"DirhamIcon\";\n\n// Memoize so the component only re-renders when its own props change.\nexport const DirhamIcon = memo(DirhamIconBase);\nDirhamIcon.displayName = \"DirhamIcon\";\n","import {\n\tDIRHAM_CURRENCY_CODE,\n\tDIRHAM_SYMBOL_TEXT,\n\tDIRHAM_UNICODE,\n} from \"./constants\";\n\n// ─── Intl.NumberFormat cache ─────────────────────────────────────────────────\n// Constructing Intl.NumberFormat is expensive (~µs). Cache instances keyed on\n// \"locale:decimals\" so repeated calls (e.g., rendering a price list) reuse\n// the same formatter instead of allocating a new object each time.\nconst _fmtCache = new Map<string, Intl.NumberFormat>();\n\nfunction getFormatter(\n\tlocale: string,\n\tdecimals: number,\n\tnotation: \"standard\" | \"compact\" = \"standard\",\n): Intl.NumberFormat {\n\tconst key = `${locale}:${decimals}:${notation}`;\n\tlet fmt = _fmtCache.get(key);\n\tif (!fmt) {\n\t\tfmt = new Intl.NumberFormat(locale, {\n\t\t\tminimumFractionDigits: notation === \"compact\" ? 0 : decimals,\n\t\t\tmaximumFractionDigits: decimals,\n\t\t\t...(notation === \"compact\" && { notation: \"compact\", compactDisplay: \"short\" }),\n\t\t});\n\t\t_fmtCache.set(key, fmt);\n\t}\n\treturn fmt;\n}\n\n/**\n * Options for formatting a Dirham amount.\n */\nexport interface FormatDirhamOptions {\n\t/**\n\t * Locale string for number formatting.\n\t * @default \"en-AE\"\n\t */\n\tlocale?: string;\n\n\t/**\n\t * Number of decimal places.\n\t * @default 2\n\t */\n\tdecimals?: number;\n\n\t/**\n\t * Whether to place the symbol before the amount.\n\t * When `undefined`, determined by locale:\n\t * - Arabic locales (ar-*): symbol after amount\n\t * - Other locales: symbol before amount\n\t */\n\tsymbolFirst?: boolean;\n\n\t/**\n\t * Use ISO currency code (AED) instead of the symbol.\n\t * @default false\n\t */\n\tuseCode?: boolean;\n\n\t/**\n\t * Separator between symbol and amount.\n\t * @default \" \" (non-breaking space)\n\t */\n\tseparator?: string;\n\n\t/**\n\t * Number notation style.\n\t * - `\"standard\"` — full digits (e.g. 1,500,000.00)\n\t * - `\"compact\"` — abbreviated (e.g. 1.5M)\n\t * @default \"standard\"\n\t */\n\tnotation?: \"standard\" | \"compact\";\n}\n\n/**\n * Format a number as a Dirham currency string.\n *\n * @example\n * ```ts\n * formatDirham(100); // \"\\u20C3 100.00\"\n * formatDirham(1234.5); // \"\\u20C3 1,234.50\"\n * formatDirham(100, { locale: \"ar-AE\" }); // \"100.00 \\u20C3\"\n * formatDirham(100, { useCode: true }); // \"AED 100.00\"\n * formatDirham(1500000, { notation: \"compact\" }); // \"\\u20C3 1.5M\"\n * ```\n */\nexport function formatDirham(\n\tamount: number,\n\toptions: FormatDirhamOptions = {},\n): string {\n\tif (!Number.isFinite(amount)) {\n\t\tthrow new RangeError(\n\t\t\t`formatDirham: amount must be a finite number, got ${amount}`,\n\t\t);\n\t}\n\n\tconst {\n\t\tlocale = \"en-AE\",\n\t\tdecimals = 2,\n\t\tuseCode = false,\n\t\tseparator = \"\\u00A0\", // non-breaking space\n\t\tnotation = \"standard\",\n\t} = options;\n\n\tconst symbol = useCode ? DIRHAM_CURRENCY_CODE : DIRHAM_UNICODE;\n\n\t// Determine symbol placement\n\tlet symbolFirst: boolean;\n\tif (options.symbolFirst !== undefined) {\n\t\tsymbolFirst = options.symbolFirst;\n\t} else {\n\t\t// Arabic locales place symbol after amount\n\t\tsymbolFirst = !locale.startsWith(\"ar\");\n\t}\n\n\t// Format the number (use cached formatter)\n\tconst formatted = getFormatter(locale, decimals, notation).format(amount);\n\n\treturn symbolFirst\n\t\t? `${symbol}${separator}${formatted}`\n\t\t: `${formatted}${separator}${symbol}`;\n}\n\n/**\n * Options for parsing a Dirham-formatted string.\n */\nexport interface ParseDirhamOptions {\n\t/**\n\t * Normalize Arabic-Indic digits (٠١٢٣٤٥٦٧٨٩ / U+0660–U+0669) to ASCII\n\t * digits before parsing. Enables round-tripping strings produced by\n\t * `formatDirham` with Arabic locales (e.g. `\"ar-AE\"`).\n\t * @default true\n\t */\n\tnormalizeArabicNumerals?: boolean;\n}\n\n/**\n * Parse a Dirham-formatted string back to a number.\n * Strips currency symbols, codes, and formatting characters.\n * By default also normalizes Arabic-Indic digits so strings produced by\n * `formatDirham({ locale: \"ar-AE\" })` round-trip correctly.\n *\n * @example\n * ```ts\n * parseDirham(\"\\u20C3 1,234.50\"); // 1234.5\n * parseDirham(\"AED 100.00\"); // 100\n * parseDirham(\"١٬٢٣٤٫٥٠ \\u20C3\"); // 1234.5\n * parseDirham(\"١٠٠٫٠٠ \\u20C3\", { normalizeArabicNumerals: false }); // throws\n * ```\n */\nexport function parseDirham(\n\tvalue: string,\n\toptions: ParseDirhamOptions = {},\n): number {\n\tconst { normalizeArabicNumerals = true } = options;\n\n\tlet cleaned = value\n\t\t.replaceAll(DIRHAM_UNICODE, \"\")\n\t\t.replaceAll(DIRHAM_SYMBOL_TEXT, \"\")\n\t\t.replaceAll(DIRHAM_CURRENCY_CODE, \"\")\n\t\t.replace(/[,\\s\\u00A0\\u066C]/g, \"\") // ASCII comma, whitespace, NBSP, Arabic thousands sep\n\t\t.trim();\n\n\tif (normalizeArabicNumerals) {\n\t\t// Arabic-Indic digits U+0660–U+0669 → ASCII 0–9\n\t\tcleaned = cleaned.replace(\n\t\t\t/[\\u0660-\\u0669]/g,\n\t\t\t(d) => String(d.charCodeAt(0) - 0x0660),\n\t\t);\n\t\t// Arabic decimal separator (U+066B) → '.'\n\t\tcleaned = cleaned.replace(/\\u066B/g, \".\");\n\t}\n\n\tconst result = Number.parseFloat(cleaned);\n\tif (Number.isNaN(result)) {\n\t\tthrow new Error(`Cannot parse \"${value}\" as a Dirham amount`);\n\t}\n\treturn result;\n}\n","import type React from \"react\";\nimport { forwardRef, memo, useMemo } from \"react\";\nimport { formatDirham, type FormatDirhamOptions } from \"../core/format\";\nimport type { DirhamWeight } from \"../core/constants\";\nimport { DirhamSymbol } from \"./DirhamSymbol\";\n\nexport interface DirhamPriceProps\n\textends Omit<React.HTMLProps<HTMLSpanElement>, \"children\"> {\n\t/**\n\t * Numeric amount to display.\n\t */\n\tamount: number;\n\n\t/**\n\t * Locale string for number formatting.\n\t * @default \"en-AE\"\n\t */\n\tlocale?: string;\n\n\t/**\n\t * Number of decimal places.\n\t * @default 2\n\t */\n\tdecimals?: number;\n\n\t/**\n\t * Use ISO currency code (AED) instead of the symbol.\n\t * @default false\n\t */\n\tuseCode?: boolean;\n\n\t/**\n\t * Number notation style.\n\t * @default \"standard\"\n\t */\n\tnotation?: \"standard\" | \"compact\";\n\n\t/**\n\t * Size of the Dirham symbol when using SVG variant.\n\t * @default \"1em\"\n\t */\n\tsymbolSize?: number | string;\n\n\t/**\n\t * Visual weight of the SVG symbol.\n\t * @default \"regular\"\n\t */\n\tweight?: DirhamWeight;\n\n\t/**\n\t * Accessible label for the currency symbol.\n\t * @default \"UAE Dirham\"\n\t */\n\t\"aria-label\"?: string;\n\n\t/**\n\t * Additional CSS class name(s) to apply to the root `<span>` element.\n\t * Useful for custom styling via Tailwind, CSS modules, etc.\n\t *\n\t * @example\n\t * ```tsx\n\t * <DirhamPrice amount={100} className=\"text-green-500 font-bold\" />\n\t * ```\n\t */\n\tclassName?: string;\n}\n\nconst DirhamPriceBase = forwardRef<HTMLSpanElement, DirhamPriceProps>(\n\t(\n\t\t{\n\t\t\tamount,\n\t\t\tlocale = \"en-AE\",\n\t\t\tdecimals = 2,\n\t\t\tuseCode = false,\n\t\t\tnotation = \"standard\",\n\t\t\tsymbolSize = \"1em\",\n\t\t\tweight = \"regular\",\n\t\t\t\"aria-label\": ariaLabel,\n\t\t\tstyle,\n\t\t\tclassName,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst symbolFirst = !locale.startsWith(\"ar\");\n\n\t\tconst formatted = useMemo(() => {\n\t\t\tif (!Number.isFinite(amount)) return \"—\";\n\t\t\treturn formatDirham(amount, {\n\t\t\t\tlocale,\n\t\t\t\tdecimals,\n\t\t\t\tuseCode: true, // Always use code so we can strip it and render SVG instead\n\t\t\t\tnotation,\n\t\t\t}).replace(\"AED\", \"\").trim();\n\t\t}, [amount, locale, decimals, notation]);\n\n\t\tconst symbol = useCode ? (\n\t\t\t<span>AED</span>\n\t\t) : (\n\t\t\t<DirhamSymbol\n\t\t\t\tsize={symbolSize}\n\t\t\t\tweight={weight}\n\t\t\t\taria-label={ariaLabel ?? \"UAE Dirham\"}\n\t\t\t/>\n\t\t);\n\n\t\treturn (\n\t\t\t<span\n\t\t\t\tref={ref}\n\t\t\t\tclassName={className}\n\t\t\t\tstyle={{ whiteSpace: \"nowrap\", ...style }}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{symbolFirst ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{symbol}\n\t\t\t\t\t\t{\"\\u00A0\"}\n\t\t\t\t\t\t{formatted}\n\t\t\t\t\t</>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{formatted}\n\t\t\t\t\t\t{\"\\u00A0\"}\n\t\t\t\t\t\t{symbol}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</span>\n\t\t);\n\t},\n);\n\nDirhamPriceBase.displayName = \"DirhamPrice\";\n\nexport const DirhamPrice = memo(DirhamPriceBase);\nDirhamPrice.displayName = \"DirhamPrice\";\n"]} |
@@ -69,2 +69,55 @@ import React from 'react'; | ||
| export { DirhamIcon, type DirhamIconProps, DirhamSymbol, type DirhamSymbolProps }; | ||
| interface DirhamPriceProps extends Omit<React.HTMLProps<HTMLSpanElement>, "children"> { | ||
| /** | ||
| * Numeric amount to display. | ||
| */ | ||
| amount: number; | ||
| /** | ||
| * Locale string for number formatting. | ||
| * @default "en-AE" | ||
| */ | ||
| locale?: string; | ||
| /** | ||
| * Number of decimal places. | ||
| * @default 2 | ||
| */ | ||
| decimals?: number; | ||
| /** | ||
| * Use ISO currency code (AED) instead of the symbol. | ||
| * @default false | ||
| */ | ||
| useCode?: boolean; | ||
| /** | ||
| * Number notation style. | ||
| * @default "standard" | ||
| */ | ||
| notation?: "standard" | "compact"; | ||
| /** | ||
| * Size of the Dirham symbol when using SVG variant. | ||
| * @default "1em" | ||
| */ | ||
| symbolSize?: number | string; | ||
| /** | ||
| * Visual weight of the SVG symbol. | ||
| * @default "regular" | ||
| */ | ||
| weight?: DirhamWeight; | ||
| /** | ||
| * Accessible label for the currency symbol. | ||
| * @default "UAE Dirham" | ||
| */ | ||
| "aria-label"?: string; | ||
| /** | ||
| * Additional CSS class name(s) to apply to the root `<span>` element. | ||
| * Useful for custom styling via Tailwind, CSS modules, etc. | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <DirhamPrice amount={100} className="text-green-500 font-bold" /> | ||
| * ``` | ||
| */ | ||
| className?: string; | ||
| } | ||
| declare const DirhamPrice: React.NamedExoticComponent<Omit<DirhamPriceProps, "ref"> & React.RefAttributes<HTMLSpanElement>>; | ||
| export { DirhamIcon, type DirhamIconProps, DirhamPrice, type DirhamPriceProps, DirhamSymbol, type DirhamSymbolProps }; |
@@ -69,2 +69,55 @@ import React from 'react'; | ||
| export { DirhamIcon, type DirhamIconProps, DirhamSymbol, type DirhamSymbolProps }; | ||
| interface DirhamPriceProps extends Omit<React.HTMLProps<HTMLSpanElement>, "children"> { | ||
| /** | ||
| * Numeric amount to display. | ||
| */ | ||
| amount: number; | ||
| /** | ||
| * Locale string for number formatting. | ||
| * @default "en-AE" | ||
| */ | ||
| locale?: string; | ||
| /** | ||
| * Number of decimal places. | ||
| * @default 2 | ||
| */ | ||
| decimals?: number; | ||
| /** | ||
| * Use ISO currency code (AED) instead of the symbol. | ||
| * @default false | ||
| */ | ||
| useCode?: boolean; | ||
| /** | ||
| * Number notation style. | ||
| * @default "standard" | ||
| */ | ||
| notation?: "standard" | "compact"; | ||
| /** | ||
| * Size of the Dirham symbol when using SVG variant. | ||
| * @default "1em" | ||
| */ | ||
| symbolSize?: number | string; | ||
| /** | ||
| * Visual weight of the SVG symbol. | ||
| * @default "regular" | ||
| */ | ||
| weight?: DirhamWeight; | ||
| /** | ||
| * Accessible label for the currency symbol. | ||
| * @default "UAE Dirham" | ||
| */ | ||
| "aria-label"?: string; | ||
| /** | ||
| * Additional CSS class name(s) to apply to the root `<span>` element. | ||
| * Useful for custom styling via Tailwind, CSS modules, etc. | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <DirhamPrice amount={100} className="text-green-500 font-bold" /> | ||
| * ``` | ||
| */ | ||
| className?: string; | ||
| } | ||
| declare const DirhamPrice: React.NamedExoticComponent<Omit<DirhamPriceProps, "ref"> & React.RefAttributes<HTMLSpanElement>>; | ||
| export { DirhamIcon, type DirhamIconProps, DirhamPrice, type DirhamPriceProps, DirhamSymbol, type DirhamSymbolProps }; |
+101
-3
@@ -1,3 +0,3 @@ | ||
| import { forwardRef, memo } from 'react'; | ||
| import { jsx } from 'react/jsx-runtime'; | ||
| import { forwardRef, memo, useMemo } from 'react'; | ||
| import { jsx, jsxs, Fragment } from 'react/jsx-runtime'; | ||
@@ -7,2 +7,4 @@ // src/react/DirhamSymbol.tsx | ||
| // src/core/constants.ts | ||
| var DIRHAM_UNICODE = "\u20C3"; | ||
| var DIRHAM_CURRENCY_CODE = "AED"; | ||
| var DIRHAM_STROKE_MAP = { | ||
@@ -100,4 +102,100 @@ thin: 0, | ||
| export { DirhamIcon, DirhamSymbol }; | ||
| // src/core/format.ts | ||
| var _fmtCache = /* @__PURE__ */ new Map(); | ||
| function getFormatter(locale, decimals, notation = "standard") { | ||
| const key = `${locale}:${decimals}:${notation}`; | ||
| let fmt = _fmtCache.get(key); | ||
| if (!fmt) { | ||
| fmt = new Intl.NumberFormat(locale, { | ||
| minimumFractionDigits: notation === "compact" ? 0 : decimals, | ||
| maximumFractionDigits: decimals, | ||
| ...notation === "compact" && { notation: "compact", compactDisplay: "short" } | ||
| }); | ||
| _fmtCache.set(key, fmt); | ||
| } | ||
| return fmt; | ||
| } | ||
| function formatDirham(amount, options = {}) { | ||
| if (!Number.isFinite(amount)) { | ||
| throw new RangeError( | ||
| `formatDirham: amount must be a finite number, got ${amount}` | ||
| ); | ||
| } | ||
| const { | ||
| locale = "en-AE", | ||
| decimals = 2, | ||
| useCode = false, | ||
| separator = "\xA0", | ||
| // non-breaking space | ||
| notation = "standard" | ||
| } = options; | ||
| const symbol = useCode ? DIRHAM_CURRENCY_CODE : DIRHAM_UNICODE; | ||
| let symbolFirst; | ||
| if (options.symbolFirst !== void 0) { | ||
| symbolFirst = options.symbolFirst; | ||
| } else { | ||
| symbolFirst = !locale.startsWith("ar"); | ||
| } | ||
| const formatted = getFormatter(locale, decimals, notation).format(amount); | ||
| return symbolFirst ? `${symbol}${separator}${formatted}` : `${formatted}${separator}${symbol}`; | ||
| } | ||
| var DirhamPriceBase = forwardRef( | ||
| ({ | ||
| amount, | ||
| locale = "en-AE", | ||
| decimals = 2, | ||
| useCode = false, | ||
| notation = "standard", | ||
| symbolSize = "1em", | ||
| weight = "regular", | ||
| "aria-label": ariaLabel, | ||
| style, | ||
| className, | ||
| ...props | ||
| }, ref) => { | ||
| const symbolFirst = !locale.startsWith("ar"); | ||
| const formatted = useMemo(() => { | ||
| if (!Number.isFinite(amount)) return "\u2014"; | ||
| return formatDirham(amount, { | ||
| locale, | ||
| decimals, | ||
| useCode: true, | ||
| // Always use code so we can strip it and render SVG instead | ||
| notation | ||
| }).replace("AED", "").trim(); | ||
| }, [amount, locale, decimals, notation]); | ||
| const symbol = useCode ? /* @__PURE__ */ jsx("span", { children: "AED" }) : /* @__PURE__ */ jsx( | ||
| DirhamSymbol, | ||
| { | ||
| size: symbolSize, | ||
| weight, | ||
| "aria-label": ariaLabel ?? "UAE Dirham" | ||
| } | ||
| ); | ||
| return /* @__PURE__ */ jsx( | ||
| "span", | ||
| { | ||
| ref, | ||
| className, | ||
| style: { whiteSpace: "nowrap", ...style }, | ||
| ...props, | ||
| children: symbolFirst ? /* @__PURE__ */ jsxs(Fragment, { children: [ | ||
| symbol, | ||
| "\xA0", | ||
| formatted | ||
| ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [ | ||
| formatted, | ||
| "\xA0", | ||
| symbol | ||
| ] }) | ||
| } | ||
| ); | ||
| } | ||
| ); | ||
| DirhamPriceBase.displayName = "DirhamPrice"; | ||
| var DirhamPrice = memo(DirhamPriceBase); | ||
| DirhamPrice.displayName = "DirhamPrice"; | ||
| export { DirhamIcon, DirhamPrice, DirhamSymbol }; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../../src/core/constants.ts","../../src/react/DirhamSymbol.tsx","../../src/react/DirhamIcon.tsx"],"names":["forwardRef","jsx","memo"],"mappings":";;;;;;AA+EO,IAAM,iBAAA,GAAkD;AAAA,EAC9D,IAAA,EAAM,CAAA;AAAA,EACN,UAAA,EAAY,CAAA;AAAA,EACZ,KAAA,EAAO,CAAA;AAAA,EACP,OAAA,EAAS,CAAA;AAAA,EACT,MAAA,EAAQ,CAAA;AAAA,EACR,QAAA,EAAU,EAAA;AAAA,EACV,IAAA,EAAM,EAAA;AAAA,EACN,SAAA,EAAW,EAAA;AAAA,EACX,KAAA,EAAO;AACR,CAAA;AClCA,IAAM,gBAAA,GAAmB,UAAA;AAAA,EACxB,CACC;AAAA,IACC,IAAA,GAAO,EAAA;AAAA,IACP,KAAA,GAAQ,cAAA;AAAA,IACR,cAAc,SAAA,GAAY,YAAA;AAAA,IAC1B,MAAA,GAAS,SAAA;AAAA,IACT,KAAA;AAAA,IACA,GAAG;AAAA,KAEJ,GAAA,KACI;AACJ,IAAA,MAAM,WAAA,GAAc,kBAAkB,MAAM,CAAA;AAE5C,IAAA,uBACC,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACA,GAAA;AAAA,QACA,KAAA,EAAM,4BAAA;AAAA,QACN,OAAA,EAAQ,cAAA;AAAA,QACR,KAAA,EAAO,IAAA;AAAA,QACP,MAAA,EAAQ,IAAA;AAAA,QACR,IAAA,EAAM,KAAA;AAAA,QACN,IAAA,EAAK,KAAA;AAAA,QACL,YAAA,EAAY,SAAA;AAAA,QACZ,KAAA,EAAO;AAAA,UACN,OAAA,EAAS,cAAA;AAAA,UACT,aAAA,EAAe,QAAA;AAAA,UACf,GAAG;AAAA,SACJ;AAAA,QACC,GAAG,KAAA;AAAA,QAEJ,QAAA,kBAAA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACA,CAAA,EAAE,25EAAA;AAAA,YACD,GAAI,cAAc,CAAA,IAAK;AAAA,cACvB,MAAA,EAAQ,KAAA;AAAA,cACR,WAAA;AAAA,cACA,cAAA,EAAgB,OAAA;AAAA,cAChB,UAAA,EAAY;AAAA;AACb;AAAA;AACD;AAAA,KACD;AAAA,EAEF;AACD,CAAA;AAEA,gBAAA,CAAiB,WAAA,GAAc,cAAA;AAKxB,IAAM,YAAA,GAAe,KAAK,gBAAgB;AACjD,YAAA,CAAa,WAAA,GAAc,cAAA;AC7D3B,IAAM,cAAA,GAAiBA,UAAAA;AAAA,EACtB,CACC;AAAA,IACC,IAAA;AAAA,IACA,KAAA,GAAQ,cAAA;AAAA,IACR,cAAc,SAAA,GAAY,YAAA;AAAA,IAC1B,IAAI,GAAA,GAAM,GAAA;AAAA,IACV,SAAA,GAAY,EAAA;AAAA,IACZ,KAAA;AAAA,IACA,GAAG;AAAA,KAEJ,GAAA,KACI;AACJ,IAAA,MAAM,UAAU,CAAA,aAAA,EAAgB,SAAA,GAAY,CAAA,CAAA,EAAI,SAAS,KAAK,EAAE,CAAA,CAAA;AAChE,IAAA,MAAM,SAAA,GAAiC;AAAA,MACtC,GAAI,SAAS,MAAA,IAAa;AAAA,QACzB,UAAU,OAAO,IAAA,KAAS,QAAA,GAAW,CAAA,EAAG,IAAI,CAAA,EAAA,CAAA,GAAO;AAAA,OACpD;AAAA,MACA,KAAA;AAAA,MACA,GAAG;AAAA,KACJ;AAEA,IAAA,uBACCC,GAAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACA,GAAA;AAAA,QACA,SAAA,EAAW,OAAA;AAAA,QACX,KAAA,EAAO,SAAA;AAAA,QACP,IAAA,EAAK,KAAA;AAAA,QACL,YAAA,EAAY,SAAA;AAAA,QACX,GAAI;AAAA;AAAA,KACN;AAAA,EAEF;AACD,CAAA;AAEA,cAAA,CAAe,WAAA,GAAc,YAAA;AAGtB,IAAM,UAAA,GAAaC,KAAK,cAAc;AAC7C,UAAA,CAAW,WAAA,GAAc,YAAA","file":"index.js","sourcesContent":["/**\n * UAE Dirham currency symbol constants.\n *\n * This package maps the Dirham glyph to the official Unicode codepoint U+20C3\n * (UAE DIRHAM SIGN) via a custom web font. The codepoint was accepted by the\n * Unicode Technical Committee for Unicode 18.0 (expected September 2026).\n *\n * Until system fonts ship native U+20C3 glyphs, the bundled web font provides\n * the rendering. When OS/font support lands, the web font becomes optional;\n * zero migration required.\n *\n * @module dirham\n * @see https://www.unicode.org/alloc/Pipeline.html\n */\n\n/** Unicode character for the Dirham symbol (U+20C3, requires Dirham web font until system fonts support it) */\nexport const DIRHAM_UNICODE = \"\\u20C3\";\n\n/** HTML entity for the Dirham symbol */\nexport const DIRHAM_HTML_ENTITY = \"⃃\";\n\n/** CSS content value for use in `::before` / `::after` pseudo-elements */\nexport const DIRHAM_CSS_CONTENT = \"\\\\20C3\";\n\n/** ISO 4217 currency code for UAE Dirham */\nexport const DIRHAM_CURRENCY_CODE = \"AED\";\n\n/** Arabic text representation of the Dirham symbol (د.إ) */\nexport const DIRHAM_SYMBOL_TEXT = \"د.إ\";\n\n/** The font family name used for the Dirham web font */\nexport const DIRHAM_FONT_FAMILY = \"Dirham\";\n\n/** CSS class name for the Dirham icon */\nexport const DIRHAM_CSS_CLASS = \"dirham-symbol\";\n\n/** Unicode codepoint as a number (0x20C3) */\nexport const DIRHAM_CODEPOINT = 0x20c3;\n\n// ── Font weight mapping ─────────────────────────────────────────────────\n\n/**\n * Supported visual weights for the Dirham symbol SVG component.\n *\n * Because the Dirham symbol is not yet in standard fonts (until Unicode 18.0),\n * weight simulation is applied via SVG stroke to match surrounding text weight,\n * similar to how $, €, £ adapt to their font's weight.\n */\nexport type DirhamWeight =\n\t| \"thin\"\n\t| \"extralight\"\n\t| \"light\"\n\t| \"regular\"\n\t| \"medium\"\n\t| \"semibold\"\n\t| \"bold\"\n\t| \"extrabold\"\n\t| \"black\";\n\n/**\n * Map from weight name to CSS `font-weight` numeric value.\n * Used for matching the symbol weight to surrounding text.\n */\nexport const DIRHAM_WEIGHT_MAP: Record<DirhamWeight, number> = {\n\tthin: 100,\n\textralight: 200,\n\tlight: 300,\n\tregular: 400,\n\tmedium: 500,\n\tsemibold: 600,\n\tbold: 700,\n\textrabold: 800,\n\tblack: 900,\n};\n\n/**\n * SVG stroke-width values that simulate font weight.\n * Applied with `paint-order: stroke` so stroke renders behind fill.\n */\nexport const DIRHAM_STROKE_MAP: Record<DirhamWeight, number> = {\n\tthin: 0,\n\textralight: 0,\n\tlight: 0,\n\tregular: 0,\n\tmedium: 8,\n\tsemibold: 16,\n\tbold: 24,\n\textrabold: 36,\n\tblack: 48,\n};\n","import type React from \"react\";\nimport { forwardRef, memo } from \"react\";\nimport { DIRHAM_STROKE_MAP, type DirhamWeight } from \"../core/constants\";\n\nexport interface DirhamSymbolProps\n\textends Omit<React.SVGProps<SVGSVGElement>, \"children\"> {\n\t/**\n\t * Size of the symbol in pixels. Sets both width and height.\n\t * @default 24\n\t */\n\tsize?: number | string;\n\n\t/**\n\t * Color of the symbol. Uses `currentColor` by default to inherit text color.\n\t * @default \"currentColor\"\n\t */\n\tcolor?: string;\n\n\t/**\n\t * Accessible label for screen readers.\n\t * @default \"UAE Dirham\"\n\t */\n\t\"aria-label\"?: string;\n\n\t/**\n\t * Visual weight of the symbol. Simulates font-weight via SVG stroke\n\t * so the symbol matches surrounding text weight.\n\t *\n\t * @example\n\t * ```tsx\n\t * <h1 style={{ fontWeight: 700 }}>\n\t * Price: 100 <DirhamSymbol size=\"1em\" weight=\"bold\" />\n\t * </h1>\n\t * ```\n\t *\n\t * @default \"regular\"\n\t */\n\tweight?: DirhamWeight;\n}\n\n/**\n * SVG-based UAE Dirham symbol React component.\n *\n * Renders the Dirham symbol as an inline SVG. No font loading required.\n * Works with SSR, is tree-shakeable, and avoids FOIT.\n *\n * @example\n * ```tsx\n * import { DirhamSymbol } from \"dirham/react\";\n *\n * <DirhamSymbol size={16} />\n * <DirhamSymbol size={24} color=\"green\" />\n * <span>100 <DirhamSymbol size=\"1em\" /></span>\n * ```\n */\nconst DirhamSymbolBase = forwardRef<SVGSVGElement, DirhamSymbolProps>(\n\t(\n\t\t{\n\t\t\tsize = 24,\n\t\t\tcolor = \"currentColor\",\n\t\t\t\"aria-label\": ariaLabel = \"UAE Dirham\",\n\t\t\tweight = \"regular\",\n\t\t\tstyle,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst strokeWidth = DIRHAM_STROKE_MAP[weight];\n\n\t\treturn (\n\t\t\t<svg\n\t\t\t\tref={ref}\n\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\tviewBox=\"0 0 1000 870\"\n\t\t\t\twidth={size}\n\t\t\t\theight={size}\n\t\t\t\tfill={color}\n\t\t\t\trole=\"img\"\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\tstyle={{\n\t\t\t\t\tdisplay: \"inline-block\",\n\t\t\t\t\tverticalAlign: \"middle\",\n\t\t\t\t\t...style,\n\t\t\t\t}}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<path\n\t\t\t\t\td=\"m88.3 1c0.4 0.6 2.6 3.3 4.7 5.9 15.3 18.2 26.8 47.8 33 85.1 4.1 24.5 4.3 32.2 4.3 125.6v87h-41.8c-38.2 0-42.6-0.2-50.1-1.7-11.8-2.5-24-9.2-32.2-17.8-6.5-6.9-6.3-7.3-5.9 13.6 0.5 17.3 0.7 19.2 3.2 28.6 4 14.9 9.5 26 17.8 35.9 11.3 13.6 22.8 21.2 39.2 26.3 3.5 1 10.9 1.4 37.1 1.6l32.7 0.5v43.3 43.4l-46.1-0.3-46.3-0.3-8-3.2c-9.5-3.8-13.8-6.6-23.1-14.9l-6.8-6.1 0.4 19.1c0.5 17.7 0.6 19.7 3.1 28.7 8.7 31.8 29.7 54.5 57.4 61.9 6.9 1.9 9.6 2 38.5 2.4l30.9 0.4v89.6c0 54.1-0.3 94-0.8 100.8-0.5 6.2-2.1 17.8-3.5 25.9-6.5 37.3-18.2 65.4-35 83.6l-3.4 3.7h169.1c101.1 0 176.7-0.4 187.8-0.9 19.5-1 63-5.3 72.8-7.4 3.1-0.6 8.9-1.5 12.7-2.1 8.1-1.2 21.5-4 40.8-8.9 27.2-6.8 52-15.3 76.3-26.1 7.6-3.4 29.4-14.5 35.2-18 3.1-1.8 6.8-4 8.2-4.7 3.9-2.1 10.4-6.3 19.9-13.1 4.7-3.4 9.4-6.7 10.4-7.4 4.2-2.8 18.7-14.9 25.3-21 25.1-23.1 46.1-48.8 62.4-76.3 2.3-4 5.3-9 6.6-11.1 3.3-5.6 16.9-33.6 18.2-37.8 0.6-1.9 1.4-3.9 1.8-4.3 2.6-3.4 17.6-50.6 19.4-60.9 0.6-3.3 0.9-3.8 3.4-4.3 1.6-0.3 24.9-0.3 51.8-0.1 53.8 0.4 53.8 0.4 65.7 5.9 6.7 3.1 8.7 4.5 16.1 11.2 9.7 8.7 8.8 10.1 8.2-11.7-0.4-12.8-0.9-20.7-1.8-23.9-3.4-12.3-4.2-14.9-7.2-21.1-9.8-21.4-26.2-36.7-47.2-44l-8.2-3-33.4-0.4-33.3-0.5 0.4-11.7c0.4-15.4 0.4-45.9-0.1-61.6l-0.4-12.6 44.6-0.2c38.2-0.2 45.3 0 49.5 1.1 12.6 3.5 21.1 8.3 31.5 17.8l5.8 5.4v-14.8c0-17.6-0.9-25.4-4.5-37-7.1-23.5-21.1-41-41.1-51.8-13-7-13.8-7.2-58.5-7.5-26.2-0.2-39.9-0.6-40.6-1.2-0.6-0.6-1.1-1.6-1.1-2.4 0-0.8-1.5-7.1-3.5-13.9-23.4-82.7-67.1-148.4-131-197.1-8.7-6.7-30-20.8-38.6-25.6-3.3-1.9-6.9-3.9-7.8-4.5-4.2-2.3-28.3-14.1-34.3-16.6-3.6-1.6-8.3-3.6-10.4-4.4-35.3-15.3-94.5-29.8-139.7-34.3-7.4-0.7-17.2-1.8-21.7-2.2-20.4-2.3-48.7-2.6-209.4-2.6-135.8 0-169.9 0.3-169.4 1zm330.7 43.3c33.8 2 54.6 4.6 78.9 10.5 74.2 17.6 126.4 54.8 164.3 117 3.5 5.8 18.3 36 20.5 42.1 10.5 28.3 15.6 45.1 20.1 67.3 1.1 5.4 2.6 12.6 3.3 16 0.7 3.3 1 6.4 0.7 6.7-0.5 0.4-100.9 0.6-223.3 0.5l-222.5-0.2-0.3-128.5c-0.1-70.6 0-129.3 0.3-130.4l0.4-1.9h71.1c39 0 78 0.4 86.5 0.9zm297.5 350.3c0.7 4.3 0.7 77.3 0 80.9l-0.6 2.7-227.5-0.2-227.4-0.3-0.2-42.4c-0.2-23.3 0-42.7 0.2-43.1 0.3-0.5 97.2-0.8 227.7-0.8h227.2zm-10.2 171.7c0.5 1.5-1.9 13.8-6.8 33.8-5.6 22.5-13.2 45.2-20.9 62-3.8 8.6-13.3 27.2-15.6 30.7-1.1 1.6-4.3 6.7-7.1 11.2-18 28.2-43.7 53.9-73 72.9-10.7 6.8-32.7 18.4-38.6 20.2-1.2 0.3-2.5 0.9-3 1.3-0.7 0.6-9.8 4-20.4 7.8-19.5 6.9-56.6 14.4-86.4 17.5-19.3 1.9-22.4 2-96.7 2h-76.9v-129.7-129.8l220.9-0.4c121.5-0.2 221.6-0.5 222.4-0.7 0.9-0.1 1.8 0.5 2.1 1.2z\"\n\t\t\t\t\t{...(strokeWidth > 0 && {\n\t\t\t\t\t\tstroke: color,\n\t\t\t\t\t\tstrokeWidth,\n\t\t\t\t\t\tstrokeLinejoin: \"round\" as const,\n\t\t\t\t\t\tpaintOrder: \"stroke\",\n\t\t\t\t\t})}\n\t\t\t\t/>\n\t\t\t</svg>\n\t\t);\n\t},\n);\n\nDirhamSymbolBase.displayName = \"DirhamSymbol\";\n\n// Memoize so the component only re-renders when its own props change.\n// This is important when DirhamSymbol is used inside list items or tables\n// that re-render frequently due to unrelated parent state changes.\nexport const DirhamSymbol = memo(DirhamSymbolBase);\nDirhamSymbol.displayName = \"DirhamSymbol\";\n","import type React from \"react\";\nimport { forwardRef, memo } from \"react\";\n\nexport interface DirhamIconProps\n\textends Omit<React.HTMLProps<HTMLElement>, \"children\" | \"size\"> {\n\t/**\n\t * Font size of the icon. Applied as the CSS `font-size` property.\n\t * @default \"inherit\"\n\t */\n\tsize?: number | string;\n\n\t/**\n\t * Color of the icon. Applied as the CSS `color` property.\n\t * @default \"currentColor\"\n\t */\n\tcolor?: string;\n\n\t/**\n\t * Accessible label for screen readers.\n\t * @default \"UAE Dirham\"\n\t */\n\t\"aria-label\"?: string;\n\n\t/**\n\t * HTML tag to render.\n\t * @default \"i\"\n\t */\n\tas?: \"i\" | \"span\";\n}\n\n/**\n * Font-based UAE Dirham symbol React component.\n *\n * Requires `dirham/css` to be imported for the `@font-face` and\n * `.dirham-symbol` class to be available.\n *\n * @example\n * ```tsx\n * import \"dirham/css\";\n * import { DirhamIcon } from \"dirham/react\";\n *\n * <DirhamIcon />\n * <DirhamIcon size={32} color=\"green\" />\n * ```\n */\nconst DirhamIconBase = forwardRef<HTMLElement, DirhamIconProps>(\n\t(\n\t\t{\n\t\t\tsize,\n\t\t\tcolor = \"currentColor\",\n\t\t\t\"aria-label\": ariaLabel = \"UAE Dirham\",\n\t\t\tas: Tag = \"i\",\n\t\t\tclassName = \"\",\n\t\t\tstyle,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst classes = `dirham-symbol${className ? ` ${className}` : \"\"}`;\n\t\tconst iconStyle: React.CSSProperties = {\n\t\t\t...(size !== undefined && {\n\t\t\t\tfontSize: typeof size === \"number\" ? `${size}px` : size,\n\t\t\t}),\n\t\t\tcolor,\n\t\t\t...style,\n\t\t};\n\n\t\treturn (\n\t\t\t<Tag\n\t\t\t\tref={ref as React.Ref<HTMLElement>}\n\t\t\t\tclassName={classes}\n\t\t\t\tstyle={iconStyle}\n\t\t\t\trole=\"img\"\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\t{...(props as React.HTMLProps<HTMLElement>)}\n\t\t\t/>\n\t\t);\n\t},\n);\n\nDirhamIconBase.displayName = \"DirhamIcon\";\n\n// Memoize so the component only re-renders when its own props change.\nexport const DirhamIcon = memo(DirhamIconBase);\nDirhamIcon.displayName = \"DirhamIcon\";\n"]} | ||
| {"version":3,"sources":["../../src/core/constants.ts","../../src/react/DirhamSymbol.tsx","../../src/react/DirhamIcon.tsx","../../src/core/format.ts","../../src/react/DirhamPrice.tsx"],"names":["forwardRef","jsx","memo"],"mappings":";;;;;;AAgBO,IAAM,cAAA,GAAiB,QAAA;AASvB,IAAM,oBAAA,GAAuB,KAAA;AAsD7B,IAAM,iBAAA,GAAkD;AAAA,EAC9D,IAAA,EAAM,CAAA;AAAA,EACN,UAAA,EAAY,CAAA;AAAA,EACZ,KAAA,EAAO,CAAA;AAAA,EACP,OAAA,EAAS,CAAA;AAAA,EACT,MAAA,EAAQ,CAAA;AAAA,EACR,QAAA,EAAU,EAAA;AAAA,EACV,IAAA,EAAM,EAAA;AAAA,EACN,SAAA,EAAW,EAAA;AAAA,EACX,KAAA,EAAO;AACR,CAAA;AClCA,IAAM,gBAAA,GAAmB,UAAA;AAAA,EACxB,CACC;AAAA,IACC,IAAA,GAAO,EAAA;AAAA,IACP,KAAA,GAAQ,cAAA;AAAA,IACR,cAAc,SAAA,GAAY,YAAA;AAAA,IAC1B,MAAA,GAAS,SAAA;AAAA,IACT,KAAA;AAAA,IACA,GAAG;AAAA,KAEJ,GAAA,KACI;AACJ,IAAA,MAAM,WAAA,GAAc,kBAAkB,MAAM,CAAA;AAE5C,IAAA,uBACC,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACA,GAAA;AAAA,QACA,KAAA,EAAM,4BAAA;AAAA,QACN,OAAA,EAAQ,cAAA;AAAA,QACR,KAAA,EAAO,IAAA;AAAA,QACP,MAAA,EAAQ,IAAA;AAAA,QACR,IAAA,EAAM,KAAA;AAAA,QACN,IAAA,EAAK,KAAA;AAAA,QACL,YAAA,EAAY,SAAA;AAAA,QACZ,KAAA,EAAO;AAAA,UACN,OAAA,EAAS,cAAA;AAAA,UACT,aAAA,EAAe,QAAA;AAAA,UACf,GAAG;AAAA,SACJ;AAAA,QACC,GAAG,KAAA;AAAA,QAEJ,QAAA,kBAAA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACA,CAAA,EAAE,25EAAA;AAAA,YACD,GAAI,cAAc,CAAA,IAAK;AAAA,cACvB,MAAA,EAAQ,KAAA;AAAA,cACR,WAAA;AAAA,cACA,cAAA,EAAgB,OAAA;AAAA,cAChB,UAAA,EAAY;AAAA;AACb;AAAA;AACD;AAAA,KACD;AAAA,EAEF;AACD,CAAA;AAEA,gBAAA,CAAiB,WAAA,GAAc,cAAA;AAKxB,IAAM,YAAA,GAAe,KAAK,gBAAgB;AACjD,YAAA,CAAa,WAAA,GAAc,cAAA;AC7D3B,IAAM,cAAA,GAAiBA,UAAAA;AAAA,EACtB,CACC;AAAA,IACC,IAAA;AAAA,IACA,KAAA,GAAQ,cAAA;AAAA,IACR,cAAc,SAAA,GAAY,YAAA;AAAA,IAC1B,IAAI,GAAA,GAAM,GAAA;AAAA,IACV,SAAA,GAAY,EAAA;AAAA,IACZ,KAAA;AAAA,IACA,GAAG;AAAA,KAEJ,GAAA,KACI;AACJ,IAAA,MAAM,UAAU,CAAA,aAAA,EAAgB,SAAA,GAAY,CAAA,CAAA,EAAI,SAAS,KAAK,EAAE,CAAA,CAAA;AAChE,IAAA,MAAM,SAAA,GAAiC;AAAA,MACtC,GAAI,SAAS,MAAA,IAAa;AAAA,QACzB,UAAU,OAAO,IAAA,KAAS,QAAA,GAAW,CAAA,EAAG,IAAI,CAAA,EAAA,CAAA,GAAO;AAAA,OACpD;AAAA,MACA,KAAA;AAAA,MACA,GAAG;AAAA,KACJ;AAEA,IAAA,uBACCC,GAAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACA,GAAA;AAAA,QACA,SAAA,EAAW,OAAA;AAAA,QACX,KAAA,EAAO,SAAA;AAAA,QACP,IAAA,EAAK,KAAA;AAAA,QACL,YAAA,EAAY,SAAA;AAAA,QACX,GAAI;AAAA;AAAA,KACN;AAAA,EAEF;AACD,CAAA;AAEA,cAAA,CAAe,WAAA,GAAc,YAAA;AAGtB,IAAM,UAAA,GAAaC,KAAK,cAAc;AAC7C,UAAA,CAAW,WAAA,GAAc,YAAA;;;AC1EzB,IAAM,SAAA,uBAAgB,GAAA,EAA+B;AAErD,SAAS,YAAA,CACR,MAAA,EACA,QAAA,EACA,QAAA,GAAmC,UAAA,EACf;AACpB,EAAA,MAAM,MAAM,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,QAAQ,IAAI,QAAQ,CAAA,CAAA;AAC7C,EAAA,IAAI,GAAA,GAAM,SAAA,CAAU,GAAA,CAAI,GAAG,CAAA;AAC3B,EAAA,IAAI,CAAC,GAAA,EAAK;AACT,IAAA,GAAA,GAAM,IAAI,IAAA,CAAK,YAAA,CAAa,MAAA,EAAQ;AAAA,MACnC,qBAAA,EAAuB,QAAA,KAAa,SAAA,GAAY,CAAA,GAAI,QAAA;AAAA,MACpD,qBAAA,EAAuB,QAAA;AAAA,MACvB,GAAI,QAAA,KAAa,SAAA,IAAa,EAAE,QAAA,EAAU,SAAA,EAAW,gBAAgB,OAAA;AAAQ,KAC7E,CAAA;AACD,IAAA,SAAA,CAAU,GAAA,CAAI,KAAK,GAAG,CAAA;AAAA,EACvB;AACA,EAAA,OAAO,GAAA;AACR;AA2DO,SAAS,YAAA,CACf,MAAA,EACA,OAAA,GAA+B,EAAC,EACvB;AACT,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,EAAG;AAC7B,IAAA,MAAM,IAAI,UAAA;AAAA,MACT,qDAAqD,MAAM,CAAA;AAAA,KAC5D;AAAA,EACD;AAEA,EAAA,MAAM;AAAA,IACL,MAAA,GAAS,OAAA;AAAA,IACT,QAAA,GAAW,CAAA;AAAA,IACX,OAAA,GAAU,KAAA;AAAA,IACV,SAAA,GAAY,MAAA;AAAA;AAAA,IACZ,QAAA,GAAW;AAAA,GACZ,GAAI,OAAA;AAEJ,EAAA,MAAM,MAAA,GAAS,UAAU,oBAAA,GAAuB,cAAA;AAGhD,EAAA,IAAI,WAAA;AACJ,EAAA,IAAI,OAAA,CAAQ,gBAAgB,MAAA,EAAW;AACtC,IAAA,WAAA,GAAc,OAAA,CAAQ,WAAA;AAAA,EACvB,CAAA,MAAO;AAEN,IAAA,WAAA,GAAc,CAAC,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AAAA,EACtC;AAGA,EAAA,MAAM,YAAY,YAAA,CAAa,MAAA,EAAQ,UAAU,QAAQ,CAAA,CAAE,OAAO,MAAM,CAAA;AAExE,EAAA,OAAO,WAAA,GACJ,CAAA,EAAG,MAAM,CAAA,EAAG,SAAS,CAAA,EAAG,SAAS,CAAA,CAAA,GACjC,CAAA,EAAG,SAAS,CAAA,EAAG,SAAS,GAAG,MAAM,CAAA,CAAA;AACrC;ACvDA,IAAM,eAAA,GAAkBF,UAAAA;AAAA,EACvB,CACC;AAAA,IACC,MAAA;AAAA,IACA,MAAA,GAAS,OAAA;AAAA,IACT,QAAA,GAAW,CAAA;AAAA,IACX,OAAA,GAAU,KAAA;AAAA,IACV,QAAA,GAAW,UAAA;AAAA,IACX,UAAA,GAAa,KAAA;AAAA,IACb,MAAA,GAAS,SAAA;AAAA,IACT,YAAA,EAAc,SAAA;AAAA,IACd,KAAA;AAAA,IACA,SAAA;AAAA,IACA,GAAG;AAAA,KAEJ,GAAA,KACI;AACJ,IAAA,MAAM,WAAA,GAAc,CAAC,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AAE3C,IAAA,MAAM,SAAA,GAAY,QAAQ,MAAM;AAC/B,MAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,MAAM,GAAG,OAAO,QAAA;AACrC,MAAA,OAAO,aAAa,MAAA,EAAQ;AAAA,QAC3B,MAAA;AAAA,QACA,QAAA;AAAA,QACA,OAAA,EAAS,IAAA;AAAA;AAAA,QACT;AAAA,OACA,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,EAAE,EAAE,IAAA,EAAK;AAAA,IAC5B,GAAG,CAAC,MAAA,EAAQ,MAAA,EAAQ,QAAA,EAAU,QAAQ,CAAC,CAAA;AAEvC,IAAA,MAAM,SAAS,OAAA,mBACdC,IAAC,MAAA,EAAA,EAAK,QAAA,EAAA,KAAA,EAAG,oBAETA,GAAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACA,IAAA,EAAM,UAAA;AAAA,QACN,MAAA;AAAA,QACA,cAAY,SAAA,IAAa;AAAA;AAAA,KAC1B;AAGD,IAAA,uBACCA,GAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACA,GAAA;AAAA,QACA,SAAA;AAAA,QACA,KAAA,EAAO,EAAE,UAAA,EAAY,QAAA,EAAU,GAAG,KAAA,EAAM;AAAA,QACvC,GAAG,KAAA;AAAA,QAEH,wCACA,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,UAAA,MAAA;AAAA,UACA,MAAA;AAAA,UACA;AAAA,SAAA,EACF,oBAEA,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,UAAA,SAAA;AAAA,UACA,MAAA;AAAA,UACA;AAAA,SAAA,EACF;AAAA;AAAA,KAEF;AAAA,EAEF;AACD,CAAA;AAEA,eAAA,CAAgB,WAAA,GAAc,aAAA;AAEvB,IAAM,WAAA,GAAcC,KAAK,eAAe;AAC/C,WAAA,CAAY,WAAA,GAAc,aAAA","file":"index.js","sourcesContent":["/**\n * UAE Dirham currency symbol constants.\n *\n * This package maps the Dirham glyph to the official Unicode codepoint U+20C3\n * (UAE DIRHAM SIGN) via a custom web font. The codepoint was accepted by the\n * Unicode Technical Committee for Unicode 18.0 (expected September 2026).\n *\n * Until system fonts ship native U+20C3 glyphs, the bundled web font provides\n * the rendering. When OS/font support lands, the web font becomes optional;\n * zero migration required.\n *\n * @module dirham\n * @see https://www.unicode.org/alloc/Pipeline.html\n */\n\n/** Unicode character for the Dirham symbol (U+20C3, requires Dirham web font until system fonts support it) */\nexport const DIRHAM_UNICODE = \"\\u20C3\";\n\n/** HTML entity for the Dirham symbol */\nexport const DIRHAM_HTML_ENTITY = \"⃃\";\n\n/** CSS content value for use in `::before` / `::after` pseudo-elements */\nexport const DIRHAM_CSS_CONTENT = \"\\\\20C3\";\n\n/** ISO 4217 currency code for UAE Dirham */\nexport const DIRHAM_CURRENCY_CODE = \"AED\";\n\n/** Arabic text representation of the Dirham symbol (د.إ) */\nexport const DIRHAM_SYMBOL_TEXT = \"د.إ\";\n\n/** The font family name used for the Dirham web font */\nexport const DIRHAM_FONT_FAMILY = \"Dirham\";\n\n/** CSS class name for the Dirham icon */\nexport const DIRHAM_CSS_CLASS = \"dirham-symbol\";\n\n/** Unicode codepoint as a number (0x20C3) */\nexport const DIRHAM_CODEPOINT = 0x20c3;\n\n// ── Font weight mapping ─────────────────────────────────────────────────\n\n/**\n * Supported visual weights for the Dirham symbol SVG component.\n *\n * Because the Dirham symbol is not yet in standard fonts (until Unicode 18.0),\n * weight simulation is applied via SVG stroke to match surrounding text weight,\n * similar to how $, €, £ adapt to their font's weight.\n */\nexport type DirhamWeight =\n\t| \"thin\"\n\t| \"extralight\"\n\t| \"light\"\n\t| \"regular\"\n\t| \"medium\"\n\t| \"semibold\"\n\t| \"bold\"\n\t| \"extrabold\"\n\t| \"black\";\n\n/**\n * Map from weight name to CSS `font-weight` numeric value.\n * Used for matching the symbol weight to surrounding text.\n */\nexport const DIRHAM_WEIGHT_MAP: Record<DirhamWeight, number> = {\n\tthin: 100,\n\textralight: 200,\n\tlight: 300,\n\tregular: 400,\n\tmedium: 500,\n\tsemibold: 600,\n\tbold: 700,\n\textrabold: 800,\n\tblack: 900,\n};\n\n/**\n * SVG stroke-width values that simulate font weight.\n * Applied with `paint-order: stroke` so stroke renders behind fill.\n */\nexport const DIRHAM_STROKE_MAP: Record<DirhamWeight, number> = {\n\tthin: 0,\n\textralight: 0,\n\tlight: 0,\n\tregular: 0,\n\tmedium: 8,\n\tsemibold: 16,\n\tbold: 24,\n\textrabold: 36,\n\tblack: 48,\n};\n","import type React from \"react\";\nimport { forwardRef, memo } from \"react\";\nimport { DIRHAM_STROKE_MAP, type DirhamWeight } from \"../core/constants\";\n\nexport interface DirhamSymbolProps\n\textends Omit<React.SVGProps<SVGSVGElement>, \"children\"> {\n\t/**\n\t * Size of the symbol in pixels. Sets both width and height.\n\t * @default 24\n\t */\n\tsize?: number | string;\n\n\t/**\n\t * Color of the symbol. Uses `currentColor` by default to inherit text color.\n\t * @default \"currentColor\"\n\t */\n\tcolor?: string;\n\n\t/**\n\t * Accessible label for screen readers.\n\t * @default \"UAE Dirham\"\n\t */\n\t\"aria-label\"?: string;\n\n\t/**\n\t * Visual weight of the symbol. Simulates font-weight via SVG stroke\n\t * so the symbol matches surrounding text weight.\n\t *\n\t * @example\n\t * ```tsx\n\t * <h1 style={{ fontWeight: 700 }}>\n\t * Price: 100 <DirhamSymbol size=\"1em\" weight=\"bold\" />\n\t * </h1>\n\t * ```\n\t *\n\t * @default \"regular\"\n\t */\n\tweight?: DirhamWeight;\n}\n\n/**\n * SVG-based UAE Dirham symbol React component.\n *\n * Renders the Dirham symbol as an inline SVG. No font loading required.\n * Works with SSR, is tree-shakeable, and avoids FOIT.\n *\n * @example\n * ```tsx\n * import { DirhamSymbol } from \"dirham/react\";\n *\n * <DirhamSymbol size={16} />\n * <DirhamSymbol size={24} color=\"green\" />\n * <span>100 <DirhamSymbol size=\"1em\" /></span>\n * ```\n */\nconst DirhamSymbolBase = forwardRef<SVGSVGElement, DirhamSymbolProps>(\n\t(\n\t\t{\n\t\t\tsize = 24,\n\t\t\tcolor = \"currentColor\",\n\t\t\t\"aria-label\": ariaLabel = \"UAE Dirham\",\n\t\t\tweight = \"regular\",\n\t\t\tstyle,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst strokeWidth = DIRHAM_STROKE_MAP[weight];\n\n\t\treturn (\n\t\t\t<svg\n\t\t\t\tref={ref}\n\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\tviewBox=\"0 0 1000 870\"\n\t\t\t\twidth={size}\n\t\t\t\theight={size}\n\t\t\t\tfill={color}\n\t\t\t\trole=\"img\"\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\tstyle={{\n\t\t\t\t\tdisplay: \"inline-block\",\n\t\t\t\t\tverticalAlign: \"middle\",\n\t\t\t\t\t...style,\n\t\t\t\t}}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<path\n\t\t\t\t\td=\"m88.3 1c0.4 0.6 2.6 3.3 4.7 5.9 15.3 18.2 26.8 47.8 33 85.1 4.1 24.5 4.3 32.2 4.3 125.6v87h-41.8c-38.2 0-42.6-0.2-50.1-1.7-11.8-2.5-24-9.2-32.2-17.8-6.5-6.9-6.3-7.3-5.9 13.6 0.5 17.3 0.7 19.2 3.2 28.6 4 14.9 9.5 26 17.8 35.9 11.3 13.6 22.8 21.2 39.2 26.3 3.5 1 10.9 1.4 37.1 1.6l32.7 0.5v43.3 43.4l-46.1-0.3-46.3-0.3-8-3.2c-9.5-3.8-13.8-6.6-23.1-14.9l-6.8-6.1 0.4 19.1c0.5 17.7 0.6 19.7 3.1 28.7 8.7 31.8 29.7 54.5 57.4 61.9 6.9 1.9 9.6 2 38.5 2.4l30.9 0.4v89.6c0 54.1-0.3 94-0.8 100.8-0.5 6.2-2.1 17.8-3.5 25.9-6.5 37.3-18.2 65.4-35 83.6l-3.4 3.7h169.1c101.1 0 176.7-0.4 187.8-0.9 19.5-1 63-5.3 72.8-7.4 3.1-0.6 8.9-1.5 12.7-2.1 8.1-1.2 21.5-4 40.8-8.9 27.2-6.8 52-15.3 76.3-26.1 7.6-3.4 29.4-14.5 35.2-18 3.1-1.8 6.8-4 8.2-4.7 3.9-2.1 10.4-6.3 19.9-13.1 4.7-3.4 9.4-6.7 10.4-7.4 4.2-2.8 18.7-14.9 25.3-21 25.1-23.1 46.1-48.8 62.4-76.3 2.3-4 5.3-9 6.6-11.1 3.3-5.6 16.9-33.6 18.2-37.8 0.6-1.9 1.4-3.9 1.8-4.3 2.6-3.4 17.6-50.6 19.4-60.9 0.6-3.3 0.9-3.8 3.4-4.3 1.6-0.3 24.9-0.3 51.8-0.1 53.8 0.4 53.8 0.4 65.7 5.9 6.7 3.1 8.7 4.5 16.1 11.2 9.7 8.7 8.8 10.1 8.2-11.7-0.4-12.8-0.9-20.7-1.8-23.9-3.4-12.3-4.2-14.9-7.2-21.1-9.8-21.4-26.2-36.7-47.2-44l-8.2-3-33.4-0.4-33.3-0.5 0.4-11.7c0.4-15.4 0.4-45.9-0.1-61.6l-0.4-12.6 44.6-0.2c38.2-0.2 45.3 0 49.5 1.1 12.6 3.5 21.1 8.3 31.5 17.8l5.8 5.4v-14.8c0-17.6-0.9-25.4-4.5-37-7.1-23.5-21.1-41-41.1-51.8-13-7-13.8-7.2-58.5-7.5-26.2-0.2-39.9-0.6-40.6-1.2-0.6-0.6-1.1-1.6-1.1-2.4 0-0.8-1.5-7.1-3.5-13.9-23.4-82.7-67.1-148.4-131-197.1-8.7-6.7-30-20.8-38.6-25.6-3.3-1.9-6.9-3.9-7.8-4.5-4.2-2.3-28.3-14.1-34.3-16.6-3.6-1.6-8.3-3.6-10.4-4.4-35.3-15.3-94.5-29.8-139.7-34.3-7.4-0.7-17.2-1.8-21.7-2.2-20.4-2.3-48.7-2.6-209.4-2.6-135.8 0-169.9 0.3-169.4 1zm330.7 43.3c33.8 2 54.6 4.6 78.9 10.5 74.2 17.6 126.4 54.8 164.3 117 3.5 5.8 18.3 36 20.5 42.1 10.5 28.3 15.6 45.1 20.1 67.3 1.1 5.4 2.6 12.6 3.3 16 0.7 3.3 1 6.4 0.7 6.7-0.5 0.4-100.9 0.6-223.3 0.5l-222.5-0.2-0.3-128.5c-0.1-70.6 0-129.3 0.3-130.4l0.4-1.9h71.1c39 0 78 0.4 86.5 0.9zm297.5 350.3c0.7 4.3 0.7 77.3 0 80.9l-0.6 2.7-227.5-0.2-227.4-0.3-0.2-42.4c-0.2-23.3 0-42.7 0.2-43.1 0.3-0.5 97.2-0.8 227.7-0.8h227.2zm-10.2 171.7c0.5 1.5-1.9 13.8-6.8 33.8-5.6 22.5-13.2 45.2-20.9 62-3.8 8.6-13.3 27.2-15.6 30.7-1.1 1.6-4.3 6.7-7.1 11.2-18 28.2-43.7 53.9-73 72.9-10.7 6.8-32.7 18.4-38.6 20.2-1.2 0.3-2.5 0.9-3 1.3-0.7 0.6-9.8 4-20.4 7.8-19.5 6.9-56.6 14.4-86.4 17.5-19.3 1.9-22.4 2-96.7 2h-76.9v-129.7-129.8l220.9-0.4c121.5-0.2 221.6-0.5 222.4-0.7 0.9-0.1 1.8 0.5 2.1 1.2z\"\n\t\t\t\t\t{...(strokeWidth > 0 && {\n\t\t\t\t\t\tstroke: color,\n\t\t\t\t\t\tstrokeWidth,\n\t\t\t\t\t\tstrokeLinejoin: \"round\" as const,\n\t\t\t\t\t\tpaintOrder: \"stroke\",\n\t\t\t\t\t})}\n\t\t\t\t/>\n\t\t\t</svg>\n\t\t);\n\t},\n);\n\nDirhamSymbolBase.displayName = \"DirhamSymbol\";\n\n// Memoize so the component only re-renders when its own props change.\n// This is important when DirhamSymbol is used inside list items or tables\n// that re-render frequently due to unrelated parent state changes.\nexport const DirhamSymbol = memo(DirhamSymbolBase);\nDirhamSymbol.displayName = \"DirhamSymbol\";\n","import type React from \"react\";\nimport { forwardRef, memo } from \"react\";\n\nexport interface DirhamIconProps\n\textends Omit<React.HTMLProps<HTMLElement>, \"children\" | \"size\"> {\n\t/**\n\t * Font size of the icon. Applied as the CSS `font-size` property.\n\t * @default \"inherit\"\n\t */\n\tsize?: number | string;\n\n\t/**\n\t * Color of the icon. Applied as the CSS `color` property.\n\t * @default \"currentColor\"\n\t */\n\tcolor?: string;\n\n\t/**\n\t * Accessible label for screen readers.\n\t * @default \"UAE Dirham\"\n\t */\n\t\"aria-label\"?: string;\n\n\t/**\n\t * HTML tag to render.\n\t * @default \"i\"\n\t */\n\tas?: \"i\" | \"span\";\n}\n\n/**\n * Font-based UAE Dirham symbol React component.\n *\n * Requires `dirham/css` to be imported for the `@font-face` and\n * `.dirham-symbol` class to be available.\n *\n * @example\n * ```tsx\n * import \"dirham/css\";\n * import { DirhamIcon } from \"dirham/react\";\n *\n * <DirhamIcon />\n * <DirhamIcon size={32} color=\"green\" />\n * ```\n */\nconst DirhamIconBase = forwardRef<HTMLElement, DirhamIconProps>(\n\t(\n\t\t{\n\t\t\tsize,\n\t\t\tcolor = \"currentColor\",\n\t\t\t\"aria-label\": ariaLabel = \"UAE Dirham\",\n\t\t\tas: Tag = \"i\",\n\t\t\tclassName = \"\",\n\t\t\tstyle,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst classes = `dirham-symbol${className ? ` ${className}` : \"\"}`;\n\t\tconst iconStyle: React.CSSProperties = {\n\t\t\t...(size !== undefined && {\n\t\t\t\tfontSize: typeof size === \"number\" ? `${size}px` : size,\n\t\t\t}),\n\t\t\tcolor,\n\t\t\t...style,\n\t\t};\n\n\t\treturn (\n\t\t\t<Tag\n\t\t\t\tref={ref as React.Ref<HTMLElement>}\n\t\t\t\tclassName={classes}\n\t\t\t\tstyle={iconStyle}\n\t\t\t\trole=\"img\"\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\t{...(props as React.HTMLProps<HTMLElement>)}\n\t\t\t/>\n\t\t);\n\t},\n);\n\nDirhamIconBase.displayName = \"DirhamIcon\";\n\n// Memoize so the component only re-renders when its own props change.\nexport const DirhamIcon = memo(DirhamIconBase);\nDirhamIcon.displayName = \"DirhamIcon\";\n","import {\n\tDIRHAM_CURRENCY_CODE,\n\tDIRHAM_SYMBOL_TEXT,\n\tDIRHAM_UNICODE,\n} from \"./constants\";\n\n// ─── Intl.NumberFormat cache ─────────────────────────────────────────────────\n// Constructing Intl.NumberFormat is expensive (~µs). Cache instances keyed on\n// \"locale:decimals\" so repeated calls (e.g., rendering a price list) reuse\n// the same formatter instead of allocating a new object each time.\nconst _fmtCache = new Map<string, Intl.NumberFormat>();\n\nfunction getFormatter(\n\tlocale: string,\n\tdecimals: number,\n\tnotation: \"standard\" | \"compact\" = \"standard\",\n): Intl.NumberFormat {\n\tconst key = `${locale}:${decimals}:${notation}`;\n\tlet fmt = _fmtCache.get(key);\n\tif (!fmt) {\n\t\tfmt = new Intl.NumberFormat(locale, {\n\t\t\tminimumFractionDigits: notation === \"compact\" ? 0 : decimals,\n\t\t\tmaximumFractionDigits: decimals,\n\t\t\t...(notation === \"compact\" && { notation: \"compact\", compactDisplay: \"short\" }),\n\t\t});\n\t\t_fmtCache.set(key, fmt);\n\t}\n\treturn fmt;\n}\n\n/**\n * Options for formatting a Dirham amount.\n */\nexport interface FormatDirhamOptions {\n\t/**\n\t * Locale string for number formatting.\n\t * @default \"en-AE\"\n\t */\n\tlocale?: string;\n\n\t/**\n\t * Number of decimal places.\n\t * @default 2\n\t */\n\tdecimals?: number;\n\n\t/**\n\t * Whether to place the symbol before the amount.\n\t * When `undefined`, determined by locale:\n\t * - Arabic locales (ar-*): symbol after amount\n\t * - Other locales: symbol before amount\n\t */\n\tsymbolFirst?: boolean;\n\n\t/**\n\t * Use ISO currency code (AED) instead of the symbol.\n\t * @default false\n\t */\n\tuseCode?: boolean;\n\n\t/**\n\t * Separator between symbol and amount.\n\t * @default \" \" (non-breaking space)\n\t */\n\tseparator?: string;\n\n\t/**\n\t * Number notation style.\n\t * - `\"standard\"` — full digits (e.g. 1,500,000.00)\n\t * - `\"compact\"` — abbreviated (e.g. 1.5M)\n\t * @default \"standard\"\n\t */\n\tnotation?: \"standard\" | \"compact\";\n}\n\n/**\n * Format a number as a Dirham currency string.\n *\n * @example\n * ```ts\n * formatDirham(100); // \"\\u20C3 100.00\"\n * formatDirham(1234.5); // \"\\u20C3 1,234.50\"\n * formatDirham(100, { locale: \"ar-AE\" }); // \"100.00 \\u20C3\"\n * formatDirham(100, { useCode: true }); // \"AED 100.00\"\n * formatDirham(1500000, { notation: \"compact\" }); // \"\\u20C3 1.5M\"\n * ```\n */\nexport function formatDirham(\n\tamount: number,\n\toptions: FormatDirhamOptions = {},\n): string {\n\tif (!Number.isFinite(amount)) {\n\t\tthrow new RangeError(\n\t\t\t`formatDirham: amount must be a finite number, got ${amount}`,\n\t\t);\n\t}\n\n\tconst {\n\t\tlocale = \"en-AE\",\n\t\tdecimals = 2,\n\t\tuseCode = false,\n\t\tseparator = \"\\u00A0\", // non-breaking space\n\t\tnotation = \"standard\",\n\t} = options;\n\n\tconst symbol = useCode ? DIRHAM_CURRENCY_CODE : DIRHAM_UNICODE;\n\n\t// Determine symbol placement\n\tlet symbolFirst: boolean;\n\tif (options.symbolFirst !== undefined) {\n\t\tsymbolFirst = options.symbolFirst;\n\t} else {\n\t\t// Arabic locales place symbol after amount\n\t\tsymbolFirst = !locale.startsWith(\"ar\");\n\t}\n\n\t// Format the number (use cached formatter)\n\tconst formatted = getFormatter(locale, decimals, notation).format(amount);\n\n\treturn symbolFirst\n\t\t? `${symbol}${separator}${formatted}`\n\t\t: `${formatted}${separator}${symbol}`;\n}\n\n/**\n * Options for parsing a Dirham-formatted string.\n */\nexport interface ParseDirhamOptions {\n\t/**\n\t * Normalize Arabic-Indic digits (٠١٢٣٤٥٦٧٨٩ / U+0660–U+0669) to ASCII\n\t * digits before parsing. Enables round-tripping strings produced by\n\t * `formatDirham` with Arabic locales (e.g. `\"ar-AE\"`).\n\t * @default true\n\t */\n\tnormalizeArabicNumerals?: boolean;\n}\n\n/**\n * Parse a Dirham-formatted string back to a number.\n * Strips currency symbols, codes, and formatting characters.\n * By default also normalizes Arabic-Indic digits so strings produced by\n * `formatDirham({ locale: \"ar-AE\" })` round-trip correctly.\n *\n * @example\n * ```ts\n * parseDirham(\"\\u20C3 1,234.50\"); // 1234.5\n * parseDirham(\"AED 100.00\"); // 100\n * parseDirham(\"١٬٢٣٤٫٥٠ \\u20C3\"); // 1234.5\n * parseDirham(\"١٠٠٫٠٠ \\u20C3\", { normalizeArabicNumerals: false }); // throws\n * ```\n */\nexport function parseDirham(\n\tvalue: string,\n\toptions: ParseDirhamOptions = {},\n): number {\n\tconst { normalizeArabicNumerals = true } = options;\n\n\tlet cleaned = value\n\t\t.replaceAll(DIRHAM_UNICODE, \"\")\n\t\t.replaceAll(DIRHAM_SYMBOL_TEXT, \"\")\n\t\t.replaceAll(DIRHAM_CURRENCY_CODE, \"\")\n\t\t.replace(/[,\\s\\u00A0\\u066C]/g, \"\") // ASCII comma, whitespace, NBSP, Arabic thousands sep\n\t\t.trim();\n\n\tif (normalizeArabicNumerals) {\n\t\t// Arabic-Indic digits U+0660–U+0669 → ASCII 0–9\n\t\tcleaned = cleaned.replace(\n\t\t\t/[\\u0660-\\u0669]/g,\n\t\t\t(d) => String(d.charCodeAt(0) - 0x0660),\n\t\t);\n\t\t// Arabic decimal separator (U+066B) → '.'\n\t\tcleaned = cleaned.replace(/\\u066B/g, \".\");\n\t}\n\n\tconst result = Number.parseFloat(cleaned);\n\tif (Number.isNaN(result)) {\n\t\tthrow new Error(`Cannot parse \"${value}\" as a Dirham amount`);\n\t}\n\treturn result;\n}\n","import type React from \"react\";\nimport { forwardRef, memo, useMemo } from \"react\";\nimport { formatDirham, type FormatDirhamOptions } from \"../core/format\";\nimport type { DirhamWeight } from \"../core/constants\";\nimport { DirhamSymbol } from \"./DirhamSymbol\";\n\nexport interface DirhamPriceProps\n\textends Omit<React.HTMLProps<HTMLSpanElement>, \"children\"> {\n\t/**\n\t * Numeric amount to display.\n\t */\n\tamount: number;\n\n\t/**\n\t * Locale string for number formatting.\n\t * @default \"en-AE\"\n\t */\n\tlocale?: string;\n\n\t/**\n\t * Number of decimal places.\n\t * @default 2\n\t */\n\tdecimals?: number;\n\n\t/**\n\t * Use ISO currency code (AED) instead of the symbol.\n\t * @default false\n\t */\n\tuseCode?: boolean;\n\n\t/**\n\t * Number notation style.\n\t * @default \"standard\"\n\t */\n\tnotation?: \"standard\" | \"compact\";\n\n\t/**\n\t * Size of the Dirham symbol when using SVG variant.\n\t * @default \"1em\"\n\t */\n\tsymbolSize?: number | string;\n\n\t/**\n\t * Visual weight of the SVG symbol.\n\t * @default \"regular\"\n\t */\n\tweight?: DirhamWeight;\n\n\t/**\n\t * Accessible label for the currency symbol.\n\t * @default \"UAE Dirham\"\n\t */\n\t\"aria-label\"?: string;\n\n\t/**\n\t * Additional CSS class name(s) to apply to the root `<span>` element.\n\t * Useful for custom styling via Tailwind, CSS modules, etc.\n\t *\n\t * @example\n\t * ```tsx\n\t * <DirhamPrice amount={100} className=\"text-green-500 font-bold\" />\n\t * ```\n\t */\n\tclassName?: string;\n}\n\nconst DirhamPriceBase = forwardRef<HTMLSpanElement, DirhamPriceProps>(\n\t(\n\t\t{\n\t\t\tamount,\n\t\t\tlocale = \"en-AE\",\n\t\t\tdecimals = 2,\n\t\t\tuseCode = false,\n\t\t\tnotation = \"standard\",\n\t\t\tsymbolSize = \"1em\",\n\t\t\tweight = \"regular\",\n\t\t\t\"aria-label\": ariaLabel,\n\t\t\tstyle,\n\t\t\tclassName,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst symbolFirst = !locale.startsWith(\"ar\");\n\n\t\tconst formatted = useMemo(() => {\n\t\t\tif (!Number.isFinite(amount)) return \"—\";\n\t\t\treturn formatDirham(amount, {\n\t\t\t\tlocale,\n\t\t\t\tdecimals,\n\t\t\t\tuseCode: true, // Always use code so we can strip it and render SVG instead\n\t\t\t\tnotation,\n\t\t\t}).replace(\"AED\", \"\").trim();\n\t\t}, [amount, locale, decimals, notation]);\n\n\t\tconst symbol = useCode ? (\n\t\t\t<span>AED</span>\n\t\t) : (\n\t\t\t<DirhamSymbol\n\t\t\t\tsize={symbolSize}\n\t\t\t\tweight={weight}\n\t\t\t\taria-label={ariaLabel ?? \"UAE Dirham\"}\n\t\t\t/>\n\t\t);\n\n\t\treturn (\n\t\t\t<span\n\t\t\t\tref={ref}\n\t\t\t\tclassName={className}\n\t\t\t\tstyle={{ whiteSpace: \"nowrap\", ...style }}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{symbolFirst ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{symbol}\n\t\t\t\t\t\t{\"\\u00A0\"}\n\t\t\t\t\t\t{formatted}\n\t\t\t\t\t</>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{formatted}\n\t\t\t\t\t\t{\"\\u00A0\"}\n\t\t\t\t\t\t{symbol}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</span>\n\t\t);\n\t},\n);\n\nDirhamPriceBase.displayName = \"DirhamPrice\";\n\nexport const DirhamPrice = memo(DirhamPriceBase);\nDirhamPrice.displayName = \"DirhamPrice\";\n"]} |
+85
-4
| # dirham | ||
| > UAE Dirham (د.إ) currency symbol as a web font, CSS, and React component — built on the official Unicode 18.0 codepoint U+20C3. | ||
| > UAE Dirham (د.إ) currency symbol as a web font, CSS, React component, and Web Component for Vue, Angular, Svelte & vanilla JS — built on the official Unicode 18.0 codepoint U+20C3. | ||
| ## Overview | ||
| The `dirham` npm package provides the UAE Dirham currency symbol (U+20C3) for use in web applications. It ships a custom web font, CSS, SCSS, React components, and JavaScript/TypeScript utilities for formatting and parsing Dirham amounts. | ||
| The `dirham` npm package provides the UAE Dirham currency symbol (U+20C3) for use in web applications. It ships a custom web font, CSS, SCSS, React components, framework-agnostic Web Components (`<dirham-symbol>` and `<dirham-price>`), and JavaScript/TypeScript utilities for formatting and parsing Dirham amounts. The Web Components work natively in Vue, Angular, Svelte, and any JavaScript framework — no wrappers needed. | ||
@@ -30,4 +30,5 @@ The glyph is sourced from the Central Bank of UAE and mapped to the official Unicode 18.0 codepoint U+20C3 (UAE DIRHAM SIGN), approved by the Unicode Technical Committee on 2025-Jul-22. When OS/browser fonts adopt Unicode 18.0 (expected September 2026), the web font gracefully becomes unnecessary with zero migration needed. | ||
| |---|---| | ||
| | `dirham` | Core JS/TS utilities (formatDirham, parseDirham, constants) | | ||
| | `dirham/react` | React SVG component (DirhamSymbol) and font icon component (DirhamIcon) | | ||
| | `dirham` | Core JS/TS utilities (formatDirham, parseDirham, copyDirhamSymbol, constants) | | ||
| | `dirham/react` | React components (DirhamSymbol, DirhamIcon, DirhamPrice) | | ||
| | `dirham/web-component` | Framework-agnostic `<dirham-symbol>` and `<dirham-price>` custom elements | | ||
| | `dirham/css` | CSS with @font-face for the Dirham web font | | ||
@@ -62,2 +63,22 @@ | `dirham/scss` | SCSS with @font-face for the Dirham web font | | ||
| ### DirhamPrice | ||
| All-in-one price display component. Renders the SVG symbol inline with a formatted amount. | ||
| ```tsx | ||
| import { DirhamPrice } from "dirham/react"; | ||
| <DirhamPrice amount={1234.5} /> | ||
| <DirhamPrice amount={5000000} notation="compact" /> | ||
| <DirhamPrice amount={99.9} decimals={0} useCode /> | ||
| ``` | ||
| Props: | ||
| - `amount`: number (required) — the numeric value to display | ||
| - `locale`: string (default: "en-AE") — locale for number formatting | ||
| - `decimals`: number (default: 2) — decimal places | ||
| - `useCode`: boolean (default: false) — show "AED" text instead of symbol | ||
| - `notation`: "standard" | "compact" (default: "standard") — compact shows K/M/B | ||
| - `symbolSize`: number | string (default: "0.75em") — size of the inline symbol | ||
| - `weight`: DirhamWeight (default: "regular") — symbol weight | ||
| ### DirhamIcon | ||
@@ -106,2 +127,3 @@ | ||
| formatDirham(100, { symbolFirst: false }); // "100.00 د.إ" | ||
| formatDirham(5000000, { notation: "compact" }); // "د.إ 5M" | ||
| ``` | ||
@@ -115,2 +137,3 @@ | ||
| - `separator`: string (default: non-breaking space) — between symbol and amount | ||
| - `notation`: "standard" | "compact" (default: "standard") — compact uses K/M/B abbreviations | ||
@@ -126,2 +149,58 @@ ### parseDirham(formatted) | ||
| ### copyDirhamSymbol(format?) | ||
| Copy the Dirham symbol to the clipboard in various formats. | ||
| ```ts | ||
| import { copyDirhamSymbol } from "dirham"; | ||
| await copyDirhamSymbol(); // copies "\u20C3" (unicode) | ||
| await copyDirhamSymbol("html"); // copies "⃃" | ||
| await copyDirhamSymbol("css"); // copies "\\20C3" | ||
| await copyDirhamSymbol("arabic"); // copies "د.إ" | ||
| ``` | ||
| Formats: `"unicode"` (default), `"html"`, `"css"`, `"arabic"` | ||
| ## Web Component | ||
| Framework-agnostic custom elements, usable in any HTML page or framework (Vue, Angular, Svelte, etc.). | ||
| ```html | ||
| <script type="module"> | ||
| import "dirham/web-component"; | ||
| </script> | ||
| <dirham-symbol size="24" color="currentColor" weight="regular"></dirham-symbol> | ||
| <dirham-price amount="1250"></dirham-price> | ||
| <dirham-price amount="5000000" notation="compact"></dirham-price> | ||
| <dirham-price amount="500" use-code></dirham-price> | ||
| ``` | ||
| `<dirham-symbol>` attributes: `size`, `color`, `weight`, `aria-label` | ||
| `<dirham-price>` attributes: `amount`, `locale`, `decimals`, `notation`, `use-code`, `symbol-size`, `weight`, `currency` | ||
| ## CDN Usage (No Install) | ||
| Use via jsDelivr or unpkg without npm install: | ||
| ```html | ||
| <!-- CSS web font --> | ||
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dirham/dist/css/dirham.css" /> | ||
| <i class="dirham-symbol"></i> | ||
| <!-- Web Component --> | ||
| <script type="module" src="https://cdn.jsdelivr.net/npm/dirham/dist/web-component/index.js"></script> | ||
| <dirham-symbol size="20"></dirham-symbol> | ||
| <dirham-price amount="1250"></dirham-price> | ||
| ``` | ||
| ## CLI | ||
| ```bash | ||
| npx dirham # prints symbol info table | ||
| npx dirham copy # copies Unicode symbol to clipboard | ||
| npx dirham copy html # copies HTML entity | ||
| ``` | ||
| Formats: `unicode`, `html`, `css`, `js`, `arabic`, `code` | ||
| ## CSS / Web Font Usage | ||
@@ -165,1 +244,3 @@ | ||
| - Zero runtime dependencies for the core module | ||
| - Web Component (custom element) for framework-agnostic usage | ||
| - CLI tool (`npx dirham`) for quick access |
+30
-6
| { | ||
| "name": "dirham", | ||
| "version": "1.2.0", | ||
| "description": "UAE Dirham currency symbol (U+20C3). Web font, CSS, and React component", | ||
| "version": "1.3.0", | ||
| "description": "UAE Dirham currency symbol (U+20C3). Web font, CSS, React, and Web Component for Vue, Angular, Svelte & vanilla JS", | ||
| "license": "MIT", | ||
@@ -10,3 +10,3 @@ "author": "Pooya Golchian <pooya@golchian.com>", | ||
| "type": "git", | ||
| "url": "https://github.com/pooyagolchian/dirham.git" | ||
| "url": "git+https://github.com/pooyagolchian/dirham.git" | ||
| }, | ||
@@ -18,14 +18,30 @@ "bugs": { | ||
| "dirham", | ||
| "dirham symbol", | ||
| "dirham symbol text copy", | ||
| "dirham sign", | ||
| "aed", | ||
| "aed symbol", | ||
| "uae", | ||
| "uae dirham sign", | ||
| "u+20c3", | ||
| "u20c3", | ||
| "currency", | ||
| "currency symbol", | ||
| "symbol", | ||
| "unicode", | ||
| "font", | ||
| "web font", | ||
| "icon", | ||
| "react", | ||
| "u20c3", | ||
| "web component", | ||
| "css", | ||
| "arabic", | ||
| "emoji", | ||
| "payment" | ||
| "payment", | ||
| "fintech", | ||
| "dubai", | ||
| "middle east", | ||
| "copy clipboard", | ||
| "intl", | ||
| "formatting" | ||
| ], | ||
@@ -55,4 +71,12 @@ "type": "module", | ||
| "./font/mono/woff2": "./dist/fonts/mono/dirham-mono.woff2", | ||
| "./font/arabic/woff2": "./dist/fonts/arabic/dirham-arabic.woff2" | ||
| "./font/arabic/woff2": "./dist/fonts/arabic/dirham-arabic.woff2", | ||
| "./web-component": { | ||
| "types": "./dist/web-component/index.d.ts", | ||
| "import": "./dist/web-component/index.js", | ||
| "require": "./dist/web-component/index.cjs" | ||
| } | ||
| }, | ||
| "bin": { | ||
| "dirham": "./dist/cli.cjs" | ||
| }, | ||
| "files": [ | ||
@@ -59,0 +83,0 @@ "dist", |
+131
-14
@@ -9,3 +9,3 @@ # dirham | ||
| The UAE Dirham currency symbol (⃃) as a web font, CSS utility, and React component. | ||
| The UAE Dirham currency symbol (⃃) as a web font, CSS utility, React component, and **Web Component** for Vue, Angular, Svelte & vanilla JS. | ||
@@ -76,20 +76,137 @@ Built on **U+20C3**, the codepoint assigned to the UAE Dirham Sign in Unicode 18.0. Because the package renders the symbol through a custom web font today, it will continue working without any code changes when operating systems ship native Unicode 18.0 support in September 2026. | ||
| formatDirham(100, { useCode: true }); // "AED 100.00" | ||
| formatDirham(1500000, { notation: "compact" }); // "\u20C3 1.5M" | ||
| parseDirham("\u20C3 1,234.50"); // 1234.5 | ||
| ``` | ||
| ### React — Price component | ||
| Combines formatting + symbol into a single component. Accepts `className` for custom styling: | ||
| ```tsx | ||
| import { DirhamPrice } from "dirham/react"; | ||
| <DirhamPrice amount={1250} /> | ||
| <DirhamPrice amount={1500000} notation="compact" weight="bold" /> | ||
| <DirhamPrice amount={100} useCode /> | ||
| <DirhamPrice amount={750} className="text-emerald-400 text-2xl" /> | ||
| ``` | ||
| ### Web Component | ||
| Framework-agnostic — works in Vue, Angular, Svelte, or vanilla HTML: | ||
| ```html | ||
| <script type="module" src="https://cdn.jsdelivr.net/npm/dirham/dist/web-component/index.js"></script> | ||
| <!-- Symbol only --> | ||
| <dirham-symbol size="24" weight="bold"></dirham-symbol> | ||
| <!-- Formatted price --> | ||
| <dirham-price amount="1250"></dirham-price> | ||
| <dirham-price amount="5000000" notation="compact"></dirham-price> | ||
| <dirham-price amount="100" locale="ar-AE"></dirham-price> | ||
| <dirham-price amount="500" use-code></dirham-price> | ||
| ``` | ||
| Or import in a bundler: | ||
| ```ts | ||
| import "dirham/web-component"; | ||
| ``` | ||
| #### `<dirham-price>` Attributes | ||
| | Attribute | Default | Description | | ||
| | ------------- | ------------ | ----------------------------------------- | | ||
| | `amount` | `0` | Numeric value to display | | ||
| | `locale` | `"en-AE"` | Intl locale string (e.g. `ar-AE`) | | ||
| | `decimals` | `2` | Number of decimal places | | ||
| | `notation` | `"standard"` | `"standard"` or `"compact"` | | ||
| | `use-code` | — | Boolean attr — show AED instead of symbol | | ||
| | `symbol-size` | `"1em"` | SVG symbol width/height | | ||
| | `weight` | `"regular"` | `thin` · `light` · `regular` · `bold` … | | ||
| | `currency` | `"AED"` | Currency code when `use-code` is set | | ||
| #### Vue | ||
| ```vue | ||
| <script setup> | ||
| import "dirham/web-component"; | ||
| </script> | ||
| <template> | ||
| <dirham-symbol size="24" weight="bold" /> | ||
| <dirham-price amount="1250" /> | ||
| <dirham-price amount="5000000" notation="compact" /> | ||
| </template> | ||
| ``` | ||
| #### Angular | ||
| ```ts | ||
| import { CUSTOM_ELEMENTS_SCHEMA, Component } from "@angular/core"; | ||
| import "dirham/web-component"; | ||
| @Component({ | ||
| schemas: [CUSTOM_ELEMENTS_SCHEMA], | ||
| template: ` | ||
| <dirham-symbol size="24" weight="bold"></dirham-symbol> | ||
| <dirham-price amount="1250"></dirham-price> | ||
| ` | ||
| }) | ||
| export class AppComponent {} | ||
| ``` | ||
| #### Svelte | ||
| ```svelte | ||
| <script> | ||
| import "dirham/web-component"; | ||
| </script> | ||
| <dirham-symbol size="24" weight="bold"></dirham-symbol> | ||
| <dirham-price amount="1250"></dirham-price> | ||
| ``` | ||
| ### CDN (no bundler) | ||
| ```html | ||
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dirham/dist/css/dirham.css" /> | ||
| <i class="dirham-symbol" aria-label="UAE Dirham"></i> | ||
| ``` | ||
| ### Clipboard utility | ||
| ```ts | ||
| import { copyDirhamSymbol } from "dirham"; | ||
| await copyDirhamSymbol(); // copies \u20C3 to clipboard | ||
| await copyDirhamSymbol("html"); // copies ⃃ | ||
| await copyDirhamSymbol("css"); // copies \20C3 | ||
| ``` | ||
| ### CLI | ||
| ```bash | ||
| npx dirham # Print symbol info | ||
| npx dirham copy # Copy \u20C3 to clipboard | ||
| npx dirham copy html # Copy HTML entity | ||
| ``` | ||
| ## Exports | ||
| | Import path | Description | | ||
| | -------------------------- | -------------------------------------------- | | ||
| | `dirham` | Core utilities and constants | | ||
| | `dirham/react` | `DirhamSymbol` (SVG) and `DirhamIcon` (font) | | ||
| | `dirham/css` | CSS with `@font-face` | | ||
| | `dirham/scss` | SCSS with `@font-face` | | ||
| | `dirham/font/woff2` | WOFF2 font file (default) | | ||
| | `dirham/font/woff` | WOFF font file | | ||
| | `dirham/font/ttf` | TTF font file | | ||
| | `dirham/font/sans/woff2` | Sans-serif variant WOFF2 | | ||
| | `dirham/font/serif/woff2` | Serif variant WOFF2 | | ||
| | `dirham/font/mono/woff2` | Monospace variant WOFF2 | | ||
| | `dirham/font/arabic/woff2` | Arabic variant WOFF2 | | ||
| | Import path | Description | | ||
| | -------------------------- | ------------------------------------------------ | | ||
| | `dirham` | Core utilities, constants, clipboard | | ||
| | `dirham/react` | `DirhamSymbol`, `DirhamIcon`, `DirhamPrice` | | ||
| | `dirham/web-component` | `<dirham-symbol>` and `<dirham-price>` custom elements | | ||
| | `dirham/css` | CSS with `@font-face` | | ||
| | `dirham/scss` | SCSS with `@font-face` | | ||
| | `dirham/font/woff2` | WOFF2 font file (default) | | ||
| | `dirham/font/woff` | WOFF font file | | ||
| | `dirham/font/ttf` | TTF font file | | ||
| | `dirham/font/sans/woff2` | Sans-serif variant WOFF2 | | ||
| | `dirham/font/serif/woff2` | Serif variant WOFF2 | | ||
| | `dirham/font/mono/woff2` | Monospace variant WOFF2 | | ||
| | `dirham/font/arabic/woff2` | Arabic variant WOFF2 | | ||
@@ -96,0 +213,0 @@ ## Unicode |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
246928
115.56%44
18.92%1585
119.83%218
115.84%8
166.67%1
Infinity%