mirror of
https://github.com/halo-dev/theme-earth.git
synced 2026-01-13 07:03:50 +08:00
Add number formatter web component to profile stats (#242)
在个人资料模块中,使用自定义元素 `<number-formatter>` 来格式化显示的数字,使其更易读。该组件将大数字转换为简写形式(如 1K, 1M, 1B),提升用户体验。 ```release-note 优化个人资料小部件的数值显示 ```
This commit is contained in:
44
src/components/number-formatter.ts
Normal file
44
src/components/number-formatter.ts
Normal file
@@ -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);
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -18,35 +18,37 @@
|
||||
</div>
|
||||
<div class="grid grid-cols-4 gap-5">
|
||||
<div class="inline-flex flex-col items-center">
|
||||
<span class="text-xl font-medium tabular-nums text-gray-900 dark:text-slate-100" th:text="${stats.post}"></span>
|
||||
<span class="text-xl font-medium tabular-nums text-gray-900 dark:text-slate-100">
|
||||
<number-formatter th:attr="value=${stats.post}" />
|
||||
</span>
|
||||
<span
|
||||
class="text-xs font-light text-gray-600 dark:text-slate-300"
|
||||
th:text="#{widget.profile.postCount.label}"
|
||||
></span>
|
||||
</div>
|
||||
<div class="inline-flex flex-col items-center">
|
||||
<span
|
||||
class="text-xl font-medium tabular-nums text-gray-900 dark:text-slate-100"
|
||||
th:text="${stats.category}"
|
||||
></span>
|
||||
<span class="text-xl font-medium tabular-nums text-gray-900 dark:text-slate-100">
|
||||
<number-formatter th:attr="value=${stats.category}" />
|
||||
</span>
|
||||
<span
|
||||
class="text-xs font-light text-gray-600 dark:text-slate-300"
|
||||
th:text="#{widget.profile.categoryCount.label}"
|
||||
></span>
|
||||
</div>
|
||||
<div class="inline-flex flex-col items-center">
|
||||
<span
|
||||
class="text-xl font-medium tabular-nums text-gray-900 dark:text-slate-100"
|
||||
th:text="${stats.comment}"
|
||||
></span>
|
||||
<span class="text-xl font-medium tabular-nums text-gray-900 dark:text-slate-100">
|
||||
<number-formatter th:attr="value=${stats.comment}" />
|
||||
</span>
|
||||
<span
|
||||
class="text-xs font-light text-gray-600 dark:text-slate-300"
|
||||
th:text="#{widget.profile.commentCount.label}"
|
||||
></span>
|
||||
</div>
|
||||
<div class="inline-flex flex-col items-center">
|
||||
<span class="text-xl font-medium tabular-nums text-gray-900 dark:text-slate-100" th:text="${stats.visit}"></span
|
||||
><span
|
||||
<span class="text-xl font-medium tabular-nums text-gray-900 dark:text-slate-100">
|
||||
<number-formatter th:attr="value=${stats.visit}" />
|
||||
</span>
|
||||
<span
|
||||
class="text-xs font-light text-gray-600 dark:text-slate-300"
|
||||
th:text="#{widget.profile.visitCount.label}"
|
||||
></span>
|
||||
|
||||
Reference in New Issue
Block a user