
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
UAE Dirham currency symbol (U+20C3). Web font, CSS, React, and Web Component for Vue, Angular, Svelte & vanilla JS
The UAE Dirham currency symbol () as a web font, CSS utility, React component, and Web Component for Vue, Angular, Svelte & vanilla JS.
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.
npm install dirham
# or
pnpm add dirham
# or
yarn add dirham
Renders an inline SVG. No font loading required; works with SSR and React Server Components.
import { DirhamSymbol } from "dirham/react";
function Price() {
return (
<span>
100 <DirhamSymbol size={16} />
</span>
);
}
Weight variants match the symbol stroke to surrounding text weight:
thin extralight light regular medium semibold bold extrabold black
<DirhamSymbol size="1em" weight="bold" />
import "dirham/css";
<i class="dirham-symbol" aria-label="UAE Dirham"></i>
@use "dirham/scss";
import { formatDirham, parseDirham, DIRHAM_UNICODE } from "dirham";
formatDirham(1234.5); // "\u20C3 1,234.50"
formatDirham(1234.5, { locale: "ar-AE" }); // "١٬٢٣٤٫٥٠ \u20C3"
formatDirham(100, { useCode: true }); // "AED 100.00"
formatDirham(1500000, { notation: "compact" }); // "\u20C3 1.5M"
parseDirham("\u20C3 1,234.50"); // 1234.5
Combines formatting + symbol into a single component. Accepts className for custom styling:
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" />
Count-up / count-down transitions using requestAnimationFrame. No external deps.
import { AnimatedDirhamPrice } from "dirham/react";
<AnimatedDirhamPrice amount={1250} />
<AnimatedDirhamPrice amount={5000} duration={800} easing="easeInOut" />
<AnimatedDirhamPrice amount={99.9} useCode notation="compact" />
| Prop | Default | Description |
|---|---|---|
amount | — | Target value to animate to |
duration | 600 | Animation duration in ms |
easing | "easeOut" | linear · easeIn · easeOut · easeInOut |
locale | "en-AE" | Intl locale |
decimals | 2 | Decimal places |
useCode | false | Show AED instead of symbol |
notation | "standard" | "standard" or "compact" |
weight | "regular" | Symbol weight |
Masked currency input with auto-formatting, paste handling, and Arabic numeral support:
import { DirhamInput } from "dirham/react";
<DirhamInput defaultValue={100} onChange={(v) => console.log(v)} />
<DirhamInput value={amount} onChange={setAmount} min={0} max={999999} />
<DirhamInput locale="ar-AE" useCode />
| Prop | Default | Description |
|---|---|---|
value | — | Controlled numeric value |
defaultValue | — | Uncontrolled initial value |
onChange | — | (value: number | null) => void |
locale | "en-AE" | Intl locale |
decimals | 2 | Maximum decimal places |
min / max | — | Clamps value on blur |
showSymbol | true | Show inline SVG symbol |
useCode | false | Show AED text instead of symbol |
selectOnFocus | true | Select all text on focus |
Fetch live exchange rates and convert AED amounts:
import { useDirhamRate } from "dirham/react";
function PriceInUSD({ amount }: { amount: number }) {
const { rate, convert, loading, error } = useDirhamRate("USD");
if (loading) return <span>Loading…</span>;
if (error) return <span>Error: {error}</span>;
return <span>${convert(amount)} USD (rate: {rate})</span>;
}
Framework-agnostic — works in Vue, Angular, Svelte, or vanilla 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:
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 |
<dirham-animated-price>Animated count-up/count-down price display:
<dirham-animated-price amount="1250" duration="600" easing="easeOut"></dirham-animated-price>
Attributes: amount, duration, easing, locale, decimals, notation, use-code, symbol-size, weight
<dirham-input>Masked currency input with auto-formatting:
<dirham-input value="100" min="0" max="999999" decimals="2"></dirham-input>
<dirham-input locale="ar-AE" placeholder="المبلغ"></dirham-input>
Attributes: value, locale, decimals, min, max, placeholder, disabled, readonly, show-symbol, use-code, symbol-size, weight
Fires dirham-change event with { detail: { value: number | null } }.
<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>
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 {}
<script>
import "dirham/web-component";
</script>
<dirham-symbol size="24" weight="bold"></dirham-symbol>
<dirham-price amount="1250"></dirham-price>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/dirham/dist/css/dirham.css"
/>
<i class="dirham-symbol" aria-label="UAE Dirham"></i>
import { copyDirhamSymbol } from "dirham";
await copyDirhamSymbol(); // copies \u20C3 to clipboard
await copyDirhamSymbol("html"); // copies ⃃
await copyDirhamSymbol("css"); // copies \20C3
import { copyDirhamAmount } from "dirham";
await copyDirhamAmount(1234.5); // copies "د.إ 1,234.50"
await copyDirhamAmount(1234.5, { useCode: true }); // copies "AED 1,234.50"
await copyDirhamAmount(500, { locale: "ar-AE" }); // copies "٥٠٠٫٠٠ د.إ"
UAE VAT (5%) calculation utilities with configurable rate and precision:
import { addVAT, removeVAT, getVAT, UAE_VAT_RATE } from "dirham";
addVAT(100); // 105
removeVAT(105); // 100
getVAT(100); // 5
addVAT(100, { rate: 0.1 }); // 110 (custom 10% rate)
addVAT(99.99, { decimals: 4 }); // 104.9895
Convert amounts between AED and other currencies. Rates are fetched from a free exchange rate API and cached for 1 hour:
import { convertFromAED, convertToAED, fetchExchangeRates } from "dirham";
const usd = await convertFromAED(100, "USD"); // e.g. 27.23
const aed = await convertToAED(27.23, "USD"); // e.g. 100
const manual = await convertFromAED(100, "USD", { rate: 0.2723 }); // skip fetch
const rates = await fetchExchangeRates(); // { USD: 0.2723, EUR: 0.2511, ... }
Requires react-native-svg as a peer dependency:
import { DirhamSymbol, DirhamPrice } from "dirham/react-native";
<DirhamSymbol size={24} color="#000" weight="bold" />
<DirhamPrice amount={1250} />
<DirhamPrice amount={500} locale="ar-AE" useCode />
Add the Dirham symbol plugin to your Tailwind config:
// tailwind.config.js
import dirhamPlugin from "dirham/tailwind";
export default {
plugins: [dirhamPlugin],
};
Available utility classes:
| Class | Description |
|---|---|
.dirham | Base — sets font-family to Dirham |
.dirham-thin | Thin weight |
.dirham-light | Light weight |
.dirham-regular | Regular weight (default) |
.dirham-bold | Bold weight |
.dirham-black | Black weight |
.dirham-xs | Extra small size (0.75rem) |
.dirham-sm | Small size (0.875rem) |
.dirham-base | Base size (1rem) |
.dirham-lg | Large size (1.25rem) |
.dirham-xl | Extra large size (1.5rem) |
.dirham-2xl | 2× large size (2rem) |
.dirham-3xl | 3× large size (2.5rem) |
.dirham-4xl | 4× large size (3rem) |
.dirham-before | Pseudo-element ::before with \20C3 content |
.dirham-after | Pseudo-element ::after with \20C3 content |
.dirham-price | Component class (nowrap + tabular-nums) |
Pre-configured next/font/local instance with the Dirham WOFF2 font:
import { dirhamFont } from "dirham/next";
// In your layout:
<html className={dirhamFont.className}>
{children}
</html>
// Or use the CSS variable:
<div style={{ fontFamily: "var(--font-dirham)" }}>
⃃
</div>
For manual configuration, use the raw config:
import { dirhamFontConfig } from "dirham/next";
import localFont from "next/font/local";
const myDirham = localFont(dirhamFontConfig);
npx dirham # Print symbol info
npx dirham copy # Copy \u20C3 to clipboard
npx dirham copy html # Copy HTML entity
Generate shareable price card images for Open Graph and Twitter Cards.
import { generatePriceCardSVG } from "dirham/og";
const svg = generatePriceCardSVG({
amount: 12500,
title: "Monthly Rent",
subtitle: "Dubai Marina, Studio",
accentColor: "#22c55e",
});
// Returns a self-contained <svg> string (1200×630 by default)
@vercel/og)// app/api/og/route.tsx
import { ImageResponse } from "next/og";
import { DirhamPriceCard } from "dirham/og";
export const runtime = "edge";
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const amount = Number(searchParams.get("amount") ?? "0");
const title = searchParams.get("title") ?? undefined;
return new ImageResponse(
<DirhamPriceCard amount={amount} title={title} />,
{ width: 1200, height: 630 },
);
}
Then in your page <head>:
<meta property="og:image" content="/api/og?amount=12500&title=Monthly+Rent" />
| Prop | Type | Default | Description |
|---|---|---|---|
amount | number | — | Price amount (required) |
title | string | — | Header text above the price |
subtitle | string | — | Footer text below the price |
locale | string | "en-AE" | Intl locale (RTL auto-detected) |
decimals | number | 2 | Decimal places |
notation | "standard" | "compact" | "standard" | Number notation |
width | number | 1200 | Image width in px |
height | number | 630 | Image height in px |
background | string | "#0a0a0a" | Background color |
textColor | string | "#ffffff" | Text color |
accentColor | string | "#22c55e" | Dirham symbol & badge color |
| Import path | Description |
|---|---|
dirham | Core utilities, constants, clipboard, VAT, conversion |
dirham/react | DirhamSymbol, DirhamIcon, DirhamPrice, AnimatedDirhamPrice, DirhamInput, useDirhamRate |
dirham/react-native | DirhamSymbol, DirhamPrice (requires react-native-svg) |
dirham/web-component | <dirham-symbol>, <dirham-price>, <dirham-animated-price>, <dirham-input> |
dirham/tailwind | Tailwind CSS plugin with Dirham utility classes |
dirham/next | Next.js next/font/local wrapper (dirhamFont, dirhamFontConfig) |
dirham/og | OG image generation (DirhamPriceCard, generatePriceCardSVG) |
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 |
U+20C3 (UAE DIRHAM SIGN) was accepted by the Unicode Technical Committee on 2025-Jul-22 and is scheduled for Unicode 18.0 (September 2026). This package already uses that codepoint, so when system fonts gain native support the custom web font simply becomes unused — no API or template changes needed.
MIT. The Dirham symbol glyph is sourced from the Central Bank of UAE.
FAQs
UAE Dirham currency symbol (U+20C3). Web font, CSS, React, and Web Component for Vue, Angular, Svelte & vanilla JS
We found that dirham demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.