diff --git a/src/components/number-formatter.ts b/src/components/number-formatter.ts new file mode 100644 index 0000000..b62bd1b --- /dev/null +++ b/src/components/number-formatter.ts @@ -0,0 +1,44 @@ +export default class NumberFormatterElement extends HTMLElement { + static get observedAttributes() { + return ["value"]; + } + + constructor() { + super(); + } + + connectedCallback() { + this.render(); + } + + attributeChangedCallback() { + this.render(); + } + + render() { + const value = this.getAttribute("value"); + if (value === null) { + this.textContent = "0"; + return; + } + + const num = parseInt(value, 10); + if (isNaN(num)) { + this.textContent = value; + return; + } + + this.textContent = this.formatNumber(num); + } + + formatNumber(num: number): string { + const formatter = new Intl.NumberFormat("en-US", { + notation: "compact", + compactDisplay: "short", + maximumFractionDigits: 1, + }); + return formatter.format(num); + } +} + +customElements.define("number-formatter", NumberFormatterElement); diff --git a/src/main.ts b/src/main.ts index 8e8eda0..a92bdb7 100644 --- a/src/main.ts +++ b/src/main.ts @@ -7,6 +7,7 @@ import colorSchemeSwitcher from "./alpine-data/color-scheme-switcher"; import upvote from "./alpine-data/upvote"; import share from "./alpine-data/share"; import uiPermission from "./alpine-data/ui-permission"; +import "./components/number-formatter"; window.Alpine = Alpine; diff --git a/templates/modules/widgets/profile.html b/templates/modules/widgets/profile.html index d36a7a0..a82f3cd 100644 --- a/templates/modules/widgets/profile.html +++ b/templates/modules/widgets/profile.html @@ -18,35 +18,37 @@