@medialane/ui 0.36.0 → 0.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/components/load-more-sentinel.cjs +54 -0
  2. package/dist/components/load-more-sentinel.cjs.map +1 -0
  3. package/dist/components/load-more-sentinel.d.cts +17 -0
  4. package/dist/components/load-more-sentinel.d.ts +17 -0
  5. package/dist/components/load-more-sentinel.js +30 -0
  6. package/dist/components/load-more-sentinel.js.map +1 -0
  7. package/dist/components/rewards/badge-shelf.cjs +90 -0
  8. package/dist/components/rewards/badge-shelf.cjs.map +1 -0
  9. package/dist/components/rewards/badge-shelf.d.cts +24 -0
  10. package/dist/components/rewards/badge-shelf.d.ts +24 -0
  11. package/dist/components/rewards/badge-shelf.js +56 -0
  12. package/dist/components/rewards/badge-shelf.js.map +1 -0
  13. package/dist/components/rewards/leaderboard-table.cjs +96 -0
  14. package/dist/components/rewards/leaderboard-table.cjs.map +1 -0
  15. package/dist/components/rewards/leaderboard-table.d.cts +34 -0
  16. package/dist/components/rewards/leaderboard-table.d.ts +34 -0
  17. package/dist/components/rewards/leaderboard-table.js +71 -0
  18. package/dist/components/rewards/leaderboard-table.js.map +1 -0
  19. package/dist/components/rewards/level-badge.cjs +60 -0
  20. package/dist/components/rewards/level-badge.cjs.map +1 -0
  21. package/dist/components/rewards/level-badge.d.cts +14 -0
  22. package/dist/components/rewards/level-badge.d.ts +14 -0
  23. package/dist/components/rewards/level-badge.js +36 -0
  24. package/dist/components/rewards/level-badge.js.map +1 -0
  25. package/dist/components/rewards/level-ladder.cjs +54 -0
  26. package/dist/components/rewards/level-ladder.cjs.map +1 -0
  27. package/dist/components/rewards/level-ladder.d.cts +17 -0
  28. package/dist/components/rewards/level-ladder.d.ts +17 -0
  29. package/dist/components/rewards/level-ladder.js +30 -0
  30. package/dist/components/rewards/level-ladder.js.map +1 -0
  31. package/dist/components/rewards/score-summary-card.cjs +83 -0
  32. package/dist/components/rewards/score-summary-card.cjs.map +1 -0
  33. package/dist/components/rewards/score-summary-card.d.cts +26 -0
  34. package/dist/components/rewards/score-summary-card.d.ts +26 -0
  35. package/dist/components/rewards/score-summary-card.js +59 -0
  36. package/dist/components/rewards/score-summary-card.js.map +1 -0
  37. package/dist/components/rewards/xp-progress.cjs +81 -0
  38. package/dist/components/rewards/xp-progress.cjs.map +1 -0
  39. package/dist/components/rewards/xp-progress.d.cts +18 -0
  40. package/dist/components/rewards/xp-progress.d.ts +18 -0
  41. package/dist/components/rewards/xp-progress.js +57 -0
  42. package/dist/components/rewards/xp-progress.js.map +1 -0
  43. package/dist/components/rewards/xp-toast-content.cjs +49 -0
  44. package/dist/components/rewards/xp-toast-content.cjs.map +1 -0
  45. package/dist/components/rewards/xp-toast-content.d.cts +14 -0
  46. package/dist/components/rewards/xp-toast-content.d.ts +14 -0
  47. package/dist/components/rewards/xp-toast-content.js +25 -0
  48. package/dist/components/rewards/xp-toast-content.js.map +1 -0
  49. package/dist/index.cjs +3 -0
  50. package/dist/index.cjs.map +1 -1
  51. package/dist/index.d.cts +10 -128
  52. package/dist/index.d.ts +10 -128
  53. package/dist/index.js +2 -0
  54. package/dist/index.js.map +1 -1
  55. package/package.json +1 -1
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var level_badge_exports = {};
20
+ __export(level_badge_exports, {
21
+ LevelBadge: () => LevelBadge
22
+ });
23
+ module.exports = __toCommonJS(level_badge_exports);
24
+ var import_jsx_runtime = require("react/jsx-runtime");
25
+ var import_cn = require("../../utils/cn.js");
26
+ function LevelBadge({ level, name, badgeColor, size = "md", className }) {
27
+ const sizeClasses = {
28
+ sm: "h-5 px-1.5 gap-1 text-[10px]",
29
+ md: "h-6 px-2 gap-1.5 text-xs",
30
+ lg: "h-8 px-3 gap-2 text-sm"
31
+ };
32
+ const dotSizes = {
33
+ sm: "h-1.5 w-1.5",
34
+ md: "h-2 w-2",
35
+ lg: "h-2.5 w-2.5"
36
+ };
37
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
38
+ "span",
39
+ {
40
+ className: (0, import_cn.cn)(
41
+ "inline-flex items-center rounded-full border font-semibold tracking-tight whitespace-nowrap",
42
+ sizeClasses[size],
43
+ className
44
+ ),
45
+ style: { borderColor: `${badgeColor}60`, backgroundColor: `${badgeColor}18`, color: badgeColor },
46
+ children: [
47
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: (0, import_cn.cn)("rounded-full shrink-0", dotSizes[size]), style: { backgroundColor: badgeColor } }),
48
+ "Lv.",
49
+ level,
50
+ " ",
51
+ name
52
+ ]
53
+ }
54
+ );
55
+ }
56
+ // Annotate the CommonJS export names for ESM import in node:
57
+ 0 && (module.exports = {
58
+ LevelBadge
59
+ });
60
+ //# sourceMappingURL=level-badge.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/rewards/level-badge.tsx"],"sourcesContent":["import { cn } from \"../../utils/cn.js\";\n\nexport interface LevelBadgeProps {\n level: number;\n name: string;\n badgeColor: string;\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n}\n\n/** Color-coded level chip (\"Lv.6 Voyager\"). Pure presentation — the consuming\n * app supplies level data from the rewards API. */\nexport function LevelBadge({ level, name, badgeColor, size = \"md\", className }: LevelBadgeProps) {\n const sizeClasses = {\n sm: \"h-5 px-1.5 gap-1 text-[10px]\",\n md: \"h-6 px-2 gap-1.5 text-xs\",\n lg: \"h-8 px-3 gap-2 text-sm\",\n };\n\n const dotSizes = {\n sm: \"h-1.5 w-1.5\",\n md: \"h-2 w-2\",\n lg: \"h-2.5 w-2.5\",\n };\n\n return (\n <span\n className={cn(\n \"inline-flex items-center rounded-full border font-semibold tracking-tight whitespace-nowrap\",\n sizeClasses[size],\n className\n )}\n style={{ borderColor: `${badgeColor}60`, backgroundColor: `${badgeColor}18`, color: badgeColor }}\n >\n <span className={cn(\"rounded-full shrink-0\", dotSizes[size])} style={{ backgroundColor: badgeColor }} />\n Lv.{level} {name}\n </span>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA0BI;AA1BJ,gBAAmB;AAYZ,SAAS,WAAW,EAAE,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU,GAAoB;AAC/F,QAAM,cAAc;AAAA,IAClB,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAEA,QAAM,WAAW;AAAA,IACf,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAW;AAAA,QACT;AAAA,QACA,YAAY,IAAI;AAAA,QAChB;AAAA,MACF;AAAA,MACA,OAAO,EAAE,aAAa,GAAG,UAAU,MAAM,iBAAiB,GAAG,UAAU,MAAM,OAAO,WAAW;AAAA,MAE/F;AAAA,oDAAC,UAAK,eAAW,cAAG,yBAAyB,SAAS,IAAI,CAAC,GAAG,OAAO,EAAE,iBAAiB,WAAW,GAAG;AAAA,QAAE;AAAA,QACpG;AAAA,QAAM;AAAA,QAAE;AAAA;AAAA;AAAA,EACd;AAEJ;","names":[]}
@@ -0,0 +1,14 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface LevelBadgeProps {
4
+ level: number;
5
+ name: string;
6
+ badgeColor: string;
7
+ size?: "sm" | "md" | "lg";
8
+ className?: string;
9
+ }
10
+ /** Color-coded level chip ("Lv.6 Voyager"). Pure presentation — the consuming
11
+ * app supplies level data from the rewards API. */
12
+ declare function LevelBadge({ level, name, badgeColor, size, className }: LevelBadgeProps): react_jsx_runtime.JSX.Element;
13
+
14
+ export { LevelBadge, type LevelBadgeProps };
@@ -0,0 +1,14 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface LevelBadgeProps {
4
+ level: number;
5
+ name: string;
6
+ badgeColor: string;
7
+ size?: "sm" | "md" | "lg";
8
+ className?: string;
9
+ }
10
+ /** Color-coded level chip ("Lv.6 Voyager"). Pure presentation — the consuming
11
+ * app supplies level data from the rewards API. */
12
+ declare function LevelBadge({ level, name, badgeColor, size, className }: LevelBadgeProps): react_jsx_runtime.JSX.Element;
13
+
14
+ export { LevelBadge, type LevelBadgeProps };
@@ -0,0 +1,36 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../../utils/cn.js";
3
+ function LevelBadge({ level, name, badgeColor, size = "md", className }) {
4
+ const sizeClasses = {
5
+ sm: "h-5 px-1.5 gap-1 text-[10px]",
6
+ md: "h-6 px-2 gap-1.5 text-xs",
7
+ lg: "h-8 px-3 gap-2 text-sm"
8
+ };
9
+ const dotSizes = {
10
+ sm: "h-1.5 w-1.5",
11
+ md: "h-2 w-2",
12
+ lg: "h-2.5 w-2.5"
13
+ };
14
+ return /* @__PURE__ */ jsxs(
15
+ "span",
16
+ {
17
+ className: cn(
18
+ "inline-flex items-center rounded-full border font-semibold tracking-tight whitespace-nowrap",
19
+ sizeClasses[size],
20
+ className
21
+ ),
22
+ style: { borderColor: `${badgeColor}60`, backgroundColor: `${badgeColor}18`, color: badgeColor },
23
+ children: [
24
+ /* @__PURE__ */ jsx("span", { className: cn("rounded-full shrink-0", dotSizes[size]), style: { backgroundColor: badgeColor } }),
25
+ "Lv.",
26
+ level,
27
+ " ",
28
+ name
29
+ ]
30
+ }
31
+ );
32
+ }
33
+ export {
34
+ LevelBadge
35
+ };
36
+ //# sourceMappingURL=level-badge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/rewards/level-badge.tsx"],"sourcesContent":["import { cn } from \"../../utils/cn.js\";\n\nexport interface LevelBadgeProps {\n level: number;\n name: string;\n badgeColor: string;\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n}\n\n/** Color-coded level chip (\"Lv.6 Voyager\"). Pure presentation — the consuming\n * app supplies level data from the rewards API. */\nexport function LevelBadge({ level, name, badgeColor, size = \"md\", className }: LevelBadgeProps) {\n const sizeClasses = {\n sm: \"h-5 px-1.5 gap-1 text-[10px]\",\n md: \"h-6 px-2 gap-1.5 text-xs\",\n lg: \"h-8 px-3 gap-2 text-sm\",\n };\n\n const dotSizes = {\n sm: \"h-1.5 w-1.5\",\n md: \"h-2 w-2\",\n lg: \"h-2.5 w-2.5\",\n };\n\n return (\n <span\n className={cn(\n \"inline-flex items-center rounded-full border font-semibold tracking-tight whitespace-nowrap\",\n sizeClasses[size],\n className\n )}\n style={{ borderColor: `${badgeColor}60`, backgroundColor: `${badgeColor}18`, color: badgeColor }}\n >\n <span className={cn(\"rounded-full shrink-0\", dotSizes[size])} style={{ backgroundColor: badgeColor }} />\n Lv.{level} {name}\n </span>\n );\n}\n"],"mappings":"AA0BI,SAQE,KARF;AA1BJ,SAAS,UAAU;AAYZ,SAAS,WAAW,EAAE,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU,GAAoB;AAC/F,QAAM,cAAc;AAAA,IAClB,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAEA,QAAM,WAAW;AAAA,IACf,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,YAAY,IAAI;AAAA,QAChB;AAAA,MACF;AAAA,MACA,OAAO,EAAE,aAAa,GAAG,UAAU,MAAM,iBAAiB,GAAG,UAAU,MAAM,OAAO,WAAW;AAAA,MAE/F;AAAA,4BAAC,UAAK,WAAW,GAAG,yBAAyB,SAAS,IAAI,CAAC,GAAG,OAAO,EAAE,iBAAiB,WAAW,GAAG;AAAA,QAAE;AAAA,QACpG;AAAA,QAAM;AAAA,QAAE;AAAA;AAAA;AAAA,EACd;AAEJ;","names":[]}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var level_ladder_exports = {};
20
+ __export(level_ladder_exports, {
21
+ LevelLadder: () => LevelLadder
22
+ });
23
+ module.exports = __toCommonJS(level_ladder_exports);
24
+ var import_jsx_runtime = require("react/jsx-runtime");
25
+ var import_cn = require("../../utils/cn.js");
26
+ function LevelLadder({ levels, currentLevel, className }) {
27
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_cn.cn)("flex gap-2 overflow-x-auto pb-2", className), children: levels.map((l) => {
28
+ const state = l.level < currentLevel ? "done" : l.level === currentLevel ? "current" : "future";
29
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
30
+ "div",
31
+ {
32
+ title: `${l.xpRequired.toLocaleString()} XP`,
33
+ className: (0, import_cn.cn)(
34
+ "flex shrink-0 select-none flex-col items-center gap-0.5 rounded-lg border px-2.5 py-1.5",
35
+ state === "future" && "opacity-45"
36
+ ),
37
+ style: {
38
+ borderColor: state === "current" ? l.badgeColor : `${l.badgeColor}40`,
39
+ backgroundColor: state === "current" ? `${l.badgeColor}22` : `${l.badgeColor}0d`
40
+ },
41
+ children: [
42
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[10px] font-black tabular-nums", style: { color: l.badgeColor }, children: l.level }),
43
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "whitespace-nowrap text-[10px] font-semibold", style: { color: l.badgeColor }, children: l.name })
44
+ ]
45
+ },
46
+ l.level
47
+ );
48
+ }) });
49
+ }
50
+ // Annotate the CommonJS export names for ESM import in node:
51
+ 0 && (module.exports = {
52
+ LevelLadder
53
+ });
54
+ //# sourceMappingURL=level-ladder.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/rewards/level-ladder.tsx"],"sourcesContent":["import { cn } from \"../../utils/cn.js\";\n\nexport interface LevelLadderProps {\n levels: { level: number; name: string; xpRequired: number; badgeColor: string }[];\n currentLevel: number;\n className?: string;\n}\n\n/** The full level arc as a horizontally scrollable chip rail; the current\n * level is highlighted, passed levels render solid, future ones muted. */\nexport function LevelLadder({ levels, currentLevel, className }: LevelLadderProps) {\n return (\n <div className={cn(\"flex gap-2 overflow-x-auto pb-2\", className)}>\n {levels.map((l) => {\n const state = l.level < currentLevel ? \"done\" : l.level === currentLevel ? \"current\" : \"future\";\n return (\n <div\n key={l.level}\n title={`${l.xpRequired.toLocaleString()} XP`}\n className={cn(\n \"flex shrink-0 select-none flex-col items-center gap-0.5 rounded-lg border px-2.5 py-1.5\",\n state === \"future\" && \"opacity-45\"\n )}\n style={{\n borderColor: state === \"current\" ? l.badgeColor : `${l.badgeColor}40`,\n backgroundColor: state === \"current\" ? `${l.badgeColor}22` : `${l.badgeColor}0d`,\n }}\n >\n <span className=\"text-[10px] font-black tabular-nums\" style={{ color: l.badgeColor }}>\n {l.level}\n </span>\n <span className=\"whitespace-nowrap text-[10px] font-semibold\" style={{ color: l.badgeColor }}>\n {l.name}\n </span>\n </div>\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBU;AAhBV,gBAAmB;AAUZ,SAAS,YAAY,EAAE,QAAQ,cAAc,UAAU,GAAqB;AACjF,SACE,4CAAC,SAAI,eAAW,cAAG,mCAAmC,SAAS,GAC5D,iBAAO,IAAI,CAAC,MAAM;AACjB,UAAM,QAAQ,EAAE,QAAQ,eAAe,SAAS,EAAE,UAAU,eAAe,YAAY;AACvF,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,OAAO,GAAG,EAAE,WAAW,eAAe,CAAC;AAAA,QACvC,eAAW;AAAA,UACT;AAAA,UACA,UAAU,YAAY;AAAA,QACxB;AAAA,QACA,OAAO;AAAA,UACL,aAAa,UAAU,YAAY,EAAE,aAAa,GAAG,EAAE,UAAU;AAAA,UACjE,iBAAiB,UAAU,YAAY,GAAG,EAAE,UAAU,OAAO,GAAG,EAAE,UAAU;AAAA,QAC9E;AAAA,QAEA;AAAA,sDAAC,UAAK,WAAU,uCAAsC,OAAO,EAAE,OAAO,EAAE,WAAW,GAChF,YAAE,OACL;AAAA,UACA,4CAAC,UAAK,WAAU,+CAA8C,OAAO,EAAE,OAAO,EAAE,WAAW,GACxF,YAAE,MACL;AAAA;AAAA;AAAA,MAhBK,EAAE;AAAA,IAiBT;AAAA,EAEJ,CAAC,GACH;AAEJ;","names":[]}
@@ -0,0 +1,17 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface LevelLadderProps {
4
+ levels: {
5
+ level: number;
6
+ name: string;
7
+ xpRequired: number;
8
+ badgeColor: string;
9
+ }[];
10
+ currentLevel: number;
11
+ className?: string;
12
+ }
13
+ /** The full level arc as a horizontally scrollable chip rail; the current
14
+ * level is highlighted, passed levels render solid, future ones muted. */
15
+ declare function LevelLadder({ levels, currentLevel, className }: LevelLadderProps): react_jsx_runtime.JSX.Element;
16
+
17
+ export { LevelLadder, type LevelLadderProps };
@@ -0,0 +1,17 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface LevelLadderProps {
4
+ levels: {
5
+ level: number;
6
+ name: string;
7
+ xpRequired: number;
8
+ badgeColor: string;
9
+ }[];
10
+ currentLevel: number;
11
+ className?: string;
12
+ }
13
+ /** The full level arc as a horizontally scrollable chip rail; the current
14
+ * level is highlighted, passed levels render solid, future ones muted. */
15
+ declare function LevelLadder({ levels, currentLevel, className }: LevelLadderProps): react_jsx_runtime.JSX.Element;
16
+
17
+ export { LevelLadder, type LevelLadderProps };
@@ -0,0 +1,30 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../../utils/cn.js";
3
+ function LevelLadder({ levels, currentLevel, className }) {
4
+ return /* @__PURE__ */ jsx("div", { className: cn("flex gap-2 overflow-x-auto pb-2", className), children: levels.map((l) => {
5
+ const state = l.level < currentLevel ? "done" : l.level === currentLevel ? "current" : "future";
6
+ return /* @__PURE__ */ jsxs(
7
+ "div",
8
+ {
9
+ title: `${l.xpRequired.toLocaleString()} XP`,
10
+ className: cn(
11
+ "flex shrink-0 select-none flex-col items-center gap-0.5 rounded-lg border px-2.5 py-1.5",
12
+ state === "future" && "opacity-45"
13
+ ),
14
+ style: {
15
+ borderColor: state === "current" ? l.badgeColor : `${l.badgeColor}40`,
16
+ backgroundColor: state === "current" ? `${l.badgeColor}22` : `${l.badgeColor}0d`
17
+ },
18
+ children: [
19
+ /* @__PURE__ */ jsx("span", { className: "text-[10px] font-black tabular-nums", style: { color: l.badgeColor }, children: l.level }),
20
+ /* @__PURE__ */ jsx("span", { className: "whitespace-nowrap text-[10px] font-semibold", style: { color: l.badgeColor }, children: l.name })
21
+ ]
22
+ },
23
+ l.level
24
+ );
25
+ }) });
26
+ }
27
+ export {
28
+ LevelLadder
29
+ };
30
+ //# sourceMappingURL=level-ladder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/rewards/level-ladder.tsx"],"sourcesContent":["import { cn } from \"../../utils/cn.js\";\n\nexport interface LevelLadderProps {\n levels: { level: number; name: string; xpRequired: number; badgeColor: string }[];\n currentLevel: number;\n className?: string;\n}\n\n/** The full level arc as a horizontally scrollable chip rail; the current\n * level is highlighted, passed levels render solid, future ones muted. */\nexport function LevelLadder({ levels, currentLevel, className }: LevelLadderProps) {\n return (\n <div className={cn(\"flex gap-2 overflow-x-auto pb-2\", className)}>\n {levels.map((l) => {\n const state = l.level < currentLevel ? \"done\" : l.level === currentLevel ? \"current\" : \"future\";\n return (\n <div\n key={l.level}\n title={`${l.xpRequired.toLocaleString()} XP`}\n className={cn(\n \"flex shrink-0 select-none flex-col items-center gap-0.5 rounded-lg border px-2.5 py-1.5\",\n state === \"future\" && \"opacity-45\"\n )}\n style={{\n borderColor: state === \"current\" ? l.badgeColor : `${l.badgeColor}40`,\n backgroundColor: state === \"current\" ? `${l.badgeColor}22` : `${l.badgeColor}0d`,\n }}\n >\n <span className=\"text-[10px] font-black tabular-nums\" style={{ color: l.badgeColor }}>\n {l.level}\n </span>\n <span className=\"whitespace-nowrap text-[10px] font-semibold\" style={{ color: l.badgeColor }}>\n {l.name}\n </span>\n </div>\n );\n })}\n </div>\n );\n}\n"],"mappings":"AAgBU,SAYE,KAZF;AAhBV,SAAS,UAAU;AAUZ,SAAS,YAAY,EAAE,QAAQ,cAAc,UAAU,GAAqB;AACjF,SACE,oBAAC,SAAI,WAAW,GAAG,mCAAmC,SAAS,GAC5D,iBAAO,IAAI,CAAC,MAAM;AACjB,UAAM,QAAQ,EAAE,QAAQ,eAAe,SAAS,EAAE,UAAU,eAAe,YAAY;AACvF,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,OAAO,GAAG,EAAE,WAAW,eAAe,CAAC;AAAA,QACvC,WAAW;AAAA,UACT;AAAA,UACA,UAAU,YAAY;AAAA,QACxB;AAAA,QACA,OAAO;AAAA,UACL,aAAa,UAAU,YAAY,EAAE,aAAa,GAAG,EAAE,UAAU;AAAA,UACjE,iBAAiB,UAAU,YAAY,GAAG,EAAE,UAAU,OAAO,GAAG,EAAE,UAAU;AAAA,QAC9E;AAAA,QAEA;AAAA,8BAAC,UAAK,WAAU,uCAAsC,OAAO,EAAE,OAAO,EAAE,WAAW,GAChF,YAAE,OACL;AAAA,UACA,oBAAC,UAAK,WAAU,+CAA8C,OAAO,EAAE,OAAO,EAAE,WAAW,GACxF,YAAE,MACL;AAAA;AAAA;AAAA,MAhBK,EAAE;AAAA,IAiBT;AAAA,EAEJ,CAAC,GACH;AAEJ;","names":[]}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var score_summary_card_exports = {};
20
+ __export(score_summary_card_exports, {
21
+ ScoreSummaryCard: () => ScoreSummaryCard
22
+ });
23
+ module.exports = __toCommonJS(score_summary_card_exports);
24
+ var import_jsx_runtime = require("react/jsx-runtime");
25
+ var import_cn = require("../../utils/cn.js");
26
+ var import_level_badge = require("./level-badge.js");
27
+ var import_xp_progress = require("./xp-progress.js");
28
+ var import_badge_shelf = require("./badge-shelf.js");
29
+ function ScoreSummaryCard({
30
+ level,
31
+ levelName,
32
+ badgeColor,
33
+ totalXp,
34
+ levelXp,
35
+ nextLevel,
36
+ topBadges,
37
+ href,
38
+ className
39
+ }) {
40
+ const body = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: (0, import_cn.cn)("rounded-xl border border-border bg-card p-4 sm:p-5", className), children: [
41
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-3", children: [
42
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative flex items-center justify-center", children: [
43
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
44
+ import_xp_progress.XpProgress,
45
+ {
46
+ variant: "ring",
47
+ size: 52,
48
+ totalXp,
49
+ levelXp,
50
+ nextLevelXp: nextLevel?.xpRequired ?? null,
51
+ badgeColor
52
+ }
53
+ ),
54
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "absolute text-sm font-black", style: { color: badgeColor }, children: level })
55
+ ] }),
56
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-w-0 flex-1", children: [
57
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_level_badge.LevelBadge, { level, name: levelName, badgeColor, size: "md" }),
58
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "mt-1 text-sm text-muted-foreground", children: [
59
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "font-semibold text-foreground", children: [
60
+ totalXp.toLocaleString(),
61
+ " XP"
62
+ ] }),
63
+ nextLevel && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
64
+ " \xB7 ",
65
+ (nextLevel.xpRequired - totalXp).toLocaleString(),
66
+ " XP to Lv.",
67
+ nextLevel.level,
68
+ " ",
69
+ nextLevel.name
70
+ ] })
71
+ ] })
72
+ ] })
73
+ ] }),
74
+ topBadges && topBadges.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_badge_shelf.BadgeShelf, { badges: topBadges, className: "mt-3" })
75
+ ] });
76
+ if (!href) return body;
77
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href, className: "block active:opacity-80", children: body });
78
+ }
79
+ // Annotate the CommonJS export names for ESM import in node:
80
+ 0 && (module.exports = {
81
+ ScoreSummaryCard
82
+ });
83
+ //# sourceMappingURL=score-summary-card.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/rewards/score-summary-card.tsx"],"sourcesContent":["import { cn } from \"../../utils/cn.js\";\nimport { LevelBadge } from \"./level-badge.js\";\nimport { XpProgress } from \"./xp-progress.js\";\nimport { BadgeShelf, type BadgeShelfBadge } from \"./badge-shelf.js\";\n\nexport interface ScoreSummaryCardProps {\n level: number;\n levelName: string;\n badgeColor: string;\n totalXp: number;\n /** XP required to reach the current level. */\n levelXp: number;\n nextLevel: { level: number; name: string; xpRequired: number } | null;\n /** A few earned badges to preview (already limited by the caller). */\n topBadges?: BadgeShelfBadge[];\n /** Where the card links (\"/rewards\"); rendered as a plain anchor. */\n href?: string;\n className?: string;\n}\n\n/** Compact score overview for portfolio/profile surfaces: level ring, XP,\n * next-level progress, and a short badge preview. */\nexport function ScoreSummaryCard({\n level,\n levelName,\n badgeColor,\n totalXp,\n levelXp,\n nextLevel,\n topBadges,\n href,\n className,\n}: ScoreSummaryCardProps) {\n const body = (\n <div className={cn(\"rounded-xl border border-border bg-card p-4 sm:p-5\", className)}>\n <div className=\"flex items-center gap-3\">\n <div className=\"relative flex items-center justify-center\">\n <XpProgress\n variant=\"ring\"\n size={52}\n totalXp={totalXp}\n levelXp={levelXp}\n nextLevelXp={nextLevel?.xpRequired ?? null}\n badgeColor={badgeColor}\n />\n <span className=\"absolute text-sm font-black\" style={{ color: badgeColor }}>\n {level}\n </span>\n </div>\n <div className=\"min-w-0 flex-1\">\n <LevelBadge level={level} name={levelName} badgeColor={badgeColor} size=\"md\" />\n <p className=\"mt-1 text-sm text-muted-foreground\">\n <span className=\"font-semibold text-foreground\">{totalXp.toLocaleString()} XP</span>\n {nextLevel && (\n <>\n {\" · \"}\n {(nextLevel.xpRequired - totalXp).toLocaleString()} XP to Lv.{nextLevel.level} {nextLevel.name}\n </>\n )}\n </p>\n </div>\n </div>\n {topBadges && topBadges.length > 0 && <BadgeShelf badges={topBadges} className=\"mt-3\" />}\n </div>\n );\n\n if (!href) return body;\n return (\n <a href={href} className=\"block active:opacity-80\">\n {body}\n </a>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAoCQ;AApCR,gBAAmB;AACnB,yBAA2B;AAC3B,yBAA2B;AAC3B,yBAAiD;AAmB1C,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA0B;AACxB,QAAM,OACJ,6CAAC,SAAI,eAAW,cAAG,sDAAsD,SAAS,GAChF;AAAA,iDAAC,SAAI,WAAU,2BACb;AAAA,mDAAC,SAAI,WAAU,6CACb;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA,aAAa,WAAW,cAAc;AAAA,YACtC;AAAA;AAAA,QACF;AAAA,QACA,4CAAC,UAAK,WAAU,+BAA8B,OAAO,EAAE,OAAO,WAAW,GACtE,iBACH;AAAA,SACF;AAAA,MACA,6CAAC,SAAI,WAAU,kBACb;AAAA,oDAAC,iCAAW,OAAc,MAAM,WAAW,YAAwB,MAAK,MAAK;AAAA,QAC7E,6CAAC,OAAE,WAAU,sCACX;AAAA,uDAAC,UAAK,WAAU,iCAAiC;AAAA,oBAAQ,eAAe;AAAA,YAAE;AAAA,aAAG;AAAA,UAC5E,aACC,4EACG;AAAA;AAAA,aACC,UAAU,aAAa,SAAS,eAAe;AAAA,YAAE;AAAA,YAAW,UAAU;AAAA,YAAM;AAAA,YAAE,UAAU;AAAA,aAC5F;AAAA,WAEJ;AAAA,SACF;AAAA,OACF;AAAA,IACC,aAAa,UAAU,SAAS,KAAK,4CAAC,iCAAW,QAAQ,WAAW,WAAU,QAAO;AAAA,KACxF;AAGF,MAAI,CAAC,KAAM,QAAO;AAClB,SACE,4CAAC,OAAE,MAAY,WAAU,2BACtB,gBACH;AAEJ;","names":[]}
@@ -0,0 +1,26 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { BadgeShelfBadge } from './badge-shelf.cjs';
3
+
4
+ interface ScoreSummaryCardProps {
5
+ level: number;
6
+ levelName: string;
7
+ badgeColor: string;
8
+ totalXp: number;
9
+ /** XP required to reach the current level. */
10
+ levelXp: number;
11
+ nextLevel: {
12
+ level: number;
13
+ name: string;
14
+ xpRequired: number;
15
+ } | null;
16
+ /** A few earned badges to preview (already limited by the caller). */
17
+ topBadges?: BadgeShelfBadge[];
18
+ /** Where the card links ("/rewards"); rendered as a plain anchor. */
19
+ href?: string;
20
+ className?: string;
21
+ }
22
+ /** Compact score overview for portfolio/profile surfaces: level ring, XP,
23
+ * next-level progress, and a short badge preview. */
24
+ declare function ScoreSummaryCard({ level, levelName, badgeColor, totalXp, levelXp, nextLevel, topBadges, href, className, }: ScoreSummaryCardProps): react_jsx_runtime.JSX.Element;
25
+
26
+ export { ScoreSummaryCard, type ScoreSummaryCardProps };
@@ -0,0 +1,26 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { BadgeShelfBadge } from './badge-shelf.js';
3
+
4
+ interface ScoreSummaryCardProps {
5
+ level: number;
6
+ levelName: string;
7
+ badgeColor: string;
8
+ totalXp: number;
9
+ /** XP required to reach the current level. */
10
+ levelXp: number;
11
+ nextLevel: {
12
+ level: number;
13
+ name: string;
14
+ xpRequired: number;
15
+ } | null;
16
+ /** A few earned badges to preview (already limited by the caller). */
17
+ topBadges?: BadgeShelfBadge[];
18
+ /** Where the card links ("/rewards"); rendered as a plain anchor. */
19
+ href?: string;
20
+ className?: string;
21
+ }
22
+ /** Compact score overview for portfolio/profile surfaces: level ring, XP,
23
+ * next-level progress, and a short badge preview. */
24
+ declare function ScoreSummaryCard({ level, levelName, badgeColor, totalXp, levelXp, nextLevel, topBadges, href, className, }: ScoreSummaryCardProps): react_jsx_runtime.JSX.Element;
25
+
26
+ export { ScoreSummaryCard, type ScoreSummaryCardProps };
@@ -0,0 +1,59 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../../utils/cn.js";
3
+ import { LevelBadge } from "./level-badge.js";
4
+ import { XpProgress } from "./xp-progress.js";
5
+ import { BadgeShelf } from "./badge-shelf.js";
6
+ function ScoreSummaryCard({
7
+ level,
8
+ levelName,
9
+ badgeColor,
10
+ totalXp,
11
+ levelXp,
12
+ nextLevel,
13
+ topBadges,
14
+ href,
15
+ className
16
+ }) {
17
+ const body = /* @__PURE__ */ jsxs("div", { className: cn("rounded-xl border border-border bg-card p-4 sm:p-5", className), children: [
18
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
19
+ /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center", children: [
20
+ /* @__PURE__ */ jsx(
21
+ XpProgress,
22
+ {
23
+ variant: "ring",
24
+ size: 52,
25
+ totalXp,
26
+ levelXp,
27
+ nextLevelXp: nextLevel?.xpRequired ?? null,
28
+ badgeColor
29
+ }
30
+ ),
31
+ /* @__PURE__ */ jsx("span", { className: "absolute text-sm font-black", style: { color: badgeColor }, children: level })
32
+ ] }),
33
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
34
+ /* @__PURE__ */ jsx(LevelBadge, { level, name: levelName, badgeColor, size: "md" }),
35
+ /* @__PURE__ */ jsxs("p", { className: "mt-1 text-sm text-muted-foreground", children: [
36
+ /* @__PURE__ */ jsxs("span", { className: "font-semibold text-foreground", children: [
37
+ totalXp.toLocaleString(),
38
+ " XP"
39
+ ] }),
40
+ nextLevel && /* @__PURE__ */ jsxs(Fragment, { children: [
41
+ " \xB7 ",
42
+ (nextLevel.xpRequired - totalXp).toLocaleString(),
43
+ " XP to Lv.",
44
+ nextLevel.level,
45
+ " ",
46
+ nextLevel.name
47
+ ] })
48
+ ] })
49
+ ] })
50
+ ] }),
51
+ topBadges && topBadges.length > 0 && /* @__PURE__ */ jsx(BadgeShelf, { badges: topBadges, className: "mt-3" })
52
+ ] });
53
+ if (!href) return body;
54
+ return /* @__PURE__ */ jsx("a", { href, className: "block active:opacity-80", children: body });
55
+ }
56
+ export {
57
+ ScoreSummaryCard
58
+ };
59
+ //# sourceMappingURL=score-summary-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/rewards/score-summary-card.tsx"],"sourcesContent":["import { cn } from \"../../utils/cn.js\";\nimport { LevelBadge } from \"./level-badge.js\";\nimport { XpProgress } from \"./xp-progress.js\";\nimport { BadgeShelf, type BadgeShelfBadge } from \"./badge-shelf.js\";\n\nexport interface ScoreSummaryCardProps {\n level: number;\n levelName: string;\n badgeColor: string;\n totalXp: number;\n /** XP required to reach the current level. */\n levelXp: number;\n nextLevel: { level: number; name: string; xpRequired: number } | null;\n /** A few earned badges to preview (already limited by the caller). */\n topBadges?: BadgeShelfBadge[];\n /** Where the card links (\"/rewards\"); rendered as a plain anchor. */\n href?: string;\n className?: string;\n}\n\n/** Compact score overview for portfolio/profile surfaces: level ring, XP,\n * next-level progress, and a short badge preview. */\nexport function ScoreSummaryCard({\n level,\n levelName,\n badgeColor,\n totalXp,\n levelXp,\n nextLevel,\n topBadges,\n href,\n className,\n}: ScoreSummaryCardProps) {\n const body = (\n <div className={cn(\"rounded-xl border border-border bg-card p-4 sm:p-5\", className)}>\n <div className=\"flex items-center gap-3\">\n <div className=\"relative flex items-center justify-center\">\n <XpProgress\n variant=\"ring\"\n size={52}\n totalXp={totalXp}\n levelXp={levelXp}\n nextLevelXp={nextLevel?.xpRequired ?? null}\n badgeColor={badgeColor}\n />\n <span className=\"absolute text-sm font-black\" style={{ color: badgeColor }}>\n {level}\n </span>\n </div>\n <div className=\"min-w-0 flex-1\">\n <LevelBadge level={level} name={levelName} badgeColor={badgeColor} size=\"md\" />\n <p className=\"mt-1 text-sm text-muted-foreground\">\n <span className=\"font-semibold text-foreground\">{totalXp.toLocaleString()} XP</span>\n {nextLevel && (\n <>\n {\" · \"}\n {(nextLevel.xpRequired - totalXp).toLocaleString()} XP to Lv.{nextLevel.level} {nextLevel.name}\n </>\n )}\n </p>\n </div>\n </div>\n {topBadges && topBadges.length > 0 && <BadgeShelf badges={topBadges} className=\"mt-3\" />}\n </div>\n );\n\n if (!href) return body;\n return (\n <a href={href} className=\"block active:opacity-80\">\n {body}\n </a>\n );\n}\n"],"mappings":"AAoCQ,SAkBM,UAjBJ,KADF;AApCR,SAAS,UAAU;AACnB,SAAS,kBAAkB;AAC3B,SAAS,kBAAkB;AAC3B,SAAS,kBAAwC;AAmB1C,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA0B;AACxB,QAAM,OACJ,qBAAC,SAAI,WAAW,GAAG,sDAAsD,SAAS,GAChF;AAAA,yBAAC,SAAI,WAAU,2BACb;AAAA,2BAAC,SAAI,WAAU,6CACb;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA,aAAa,WAAW,cAAc;AAAA,YACtC;AAAA;AAAA,QACF;AAAA,QACA,oBAAC,UAAK,WAAU,+BAA8B,OAAO,EAAE,OAAO,WAAW,GACtE,iBACH;AAAA,SACF;AAAA,MACA,qBAAC,SAAI,WAAU,kBACb;AAAA,4BAAC,cAAW,OAAc,MAAM,WAAW,YAAwB,MAAK,MAAK;AAAA,QAC7E,qBAAC,OAAE,WAAU,sCACX;AAAA,+BAAC,UAAK,WAAU,iCAAiC;AAAA,oBAAQ,eAAe;AAAA,YAAE;AAAA,aAAG;AAAA,UAC5E,aACC,iCACG;AAAA;AAAA,aACC,UAAU,aAAa,SAAS,eAAe;AAAA,YAAE;AAAA,YAAW,UAAU;AAAA,YAAM;AAAA,YAAE,UAAU;AAAA,aAC5F;AAAA,WAEJ;AAAA,SACF;AAAA,OACF;AAAA,IACC,aAAa,UAAU,SAAS,KAAK,oBAAC,cAAW,QAAQ,WAAW,WAAU,QAAO;AAAA,KACxF;AAGF,MAAI,CAAC,KAAM,QAAO;AAClB,SACE,oBAAC,OAAE,MAAY,WAAU,2BACtB,gBACH;AAEJ;","names":[]}
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var xp_progress_exports = {};
20
+ __export(xp_progress_exports, {
21
+ XpProgress: () => XpProgress
22
+ });
23
+ module.exports = __toCommonJS(xp_progress_exports);
24
+ var import_jsx_runtime = require("react/jsx-runtime");
25
+ var import_cn = require("../../utils/cn.js");
26
+ function progressPct({ totalXp, levelXp, nextLevelXp }) {
27
+ if (nextLevelXp === null || nextLevelXp <= levelXp) return 100;
28
+ return Math.min(100, Math.max(0, Math.round((totalXp - levelXp) / (nextLevelXp - levelXp) * 100)));
29
+ }
30
+ function XpProgress({ totalXp, levelXp, nextLevelXp, badgeColor, variant = "bar", size = 40, className }) {
31
+ const pct = progressPct({ totalXp, levelXp, nextLevelXp });
32
+ if (variant === "ring") {
33
+ const stroke = Math.max(2.5, size / 12);
34
+ const radius = (size - stroke) / 2;
35
+ const circumference = 2 * Math.PI * radius;
36
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
37
+ "svg",
38
+ {
39
+ width: size,
40
+ height: size,
41
+ viewBox: `0 0 ${size} ${size}`,
42
+ className: (0, import_cn.cn)("shrink-0 -rotate-90", className),
43
+ role: "img",
44
+ "aria-label": `${pct}% toward the next level`,
45
+ children: [
46
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: size / 2, cy: size / 2, r: radius, fill: "none", strokeWidth: stroke, className: "stroke-border" }),
47
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
48
+ "circle",
49
+ {
50
+ cx: size / 2,
51
+ cy: size / 2,
52
+ r: radius,
53
+ fill: "none",
54
+ strokeWidth: stroke,
55
+ strokeLinecap: "round",
56
+ stroke: badgeColor,
57
+ strokeDasharray: circumference,
58
+ strokeDashoffset: circumference * (1 - pct / 100)
59
+ }
60
+ )
61
+ ]
62
+ }
63
+ );
64
+ }
65
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
66
+ "div",
67
+ {
68
+ className: (0, import_cn.cn)("h-2 w-full overflow-hidden rounded-full bg-border/60", className),
69
+ role: "progressbar",
70
+ "aria-valuenow": pct,
71
+ "aria-valuemin": 0,
72
+ "aria-valuemax": 100,
73
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-full rounded-full transition-[width]", style: { width: `${pct}%`, backgroundColor: badgeColor } })
74
+ }
75
+ );
76
+ }
77
+ // Annotate the CommonJS export names for ESM import in node:
78
+ 0 && (module.exports = {
79
+ XpProgress
80
+ });
81
+ //# sourceMappingURL=xp-progress.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/rewards/xp-progress.tsx"],"sourcesContent":["import { cn } from \"../../utils/cn.js\";\n\nexport interface XpProgressProps {\n totalXp: number;\n /** XP required to reach the current level. */\n levelXp: number;\n /** XP required for the next level; null at max level (renders full). */\n nextLevelXp: number | null;\n badgeColor: string;\n variant?: \"bar\" | \"ring\";\n /** Ring diameter in px (ring variant only). */\n size?: number;\n className?: string;\n}\n\nfunction progressPct({ totalXp, levelXp, nextLevelXp }: Pick<XpProgressProps, \"totalXp\" | \"levelXp\" | \"nextLevelXp\">): number {\n if (nextLevelXp === null || nextLevelXp <= levelXp) return 100;\n return Math.min(100, Math.max(0, Math.round(((totalXp - levelXp) / (nextLevelXp - levelXp)) * 100)));\n}\n\n/** XP progress toward the next level, as a rounded bar or an SVG ring. */\nexport function XpProgress({ totalXp, levelXp, nextLevelXp, badgeColor, variant = \"bar\", size = 40, className }: XpProgressProps) {\n const pct = progressPct({ totalXp, levelXp, nextLevelXp });\n\n if (variant === \"ring\") {\n const stroke = Math.max(2.5, size / 12);\n const radius = (size - stroke) / 2;\n const circumference = 2 * Math.PI * radius;\n return (\n <svg\n width={size}\n height={size}\n viewBox={`0 0 ${size} ${size}`}\n className={cn(\"shrink-0 -rotate-90\", className)}\n role=\"img\"\n aria-label={`${pct}% toward the next level`}\n >\n <circle cx={size / 2} cy={size / 2} r={radius} fill=\"none\" strokeWidth={stroke} className=\"stroke-border\" />\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n fill=\"none\"\n strokeWidth={stroke}\n strokeLinecap=\"round\"\n stroke={badgeColor}\n strokeDasharray={circumference}\n strokeDashoffset={circumference * (1 - pct / 100)}\n />\n </svg>\n );\n }\n\n return (\n <div\n className={cn(\"h-2 w-full overflow-hidden rounded-full bg-border/60\", className)}\n role=\"progressbar\"\n aria-valuenow={pct}\n aria-valuemin={0}\n aria-valuemax={100}\n >\n <div className=\"h-full rounded-full transition-[width]\" style={{ width: `${pct}%`, backgroundColor: badgeColor }} />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA6BM;AA7BN,gBAAmB;AAenB,SAAS,YAAY,EAAE,SAAS,SAAS,YAAY,GAAyE;AAC5H,MAAI,gBAAgB,QAAQ,eAAe,QAAS,QAAO;AAC3D,SAAO,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,OAAQ,UAAU,YAAY,cAAc,WAAY,GAAG,CAAC,CAAC;AACrG;AAGO,SAAS,WAAW,EAAE,SAAS,SAAS,aAAa,YAAY,UAAU,OAAO,OAAO,IAAI,UAAU,GAAoB;AAChI,QAAM,MAAM,YAAY,EAAE,SAAS,SAAS,YAAY,CAAC;AAEzD,MAAI,YAAY,QAAQ;AACtB,UAAM,SAAS,KAAK,IAAI,KAAK,OAAO,EAAE;AACtC,UAAM,UAAU,OAAO,UAAU;AACjC,UAAM,gBAAgB,IAAI,KAAK,KAAK;AACpC,WACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,SAAS,OAAO,IAAI,IAAI,IAAI;AAAA,QAC5B,eAAW,cAAG,uBAAuB,SAAS;AAAA,QAC9C,MAAK;AAAA,QACL,cAAY,GAAG,GAAG;AAAA,QAElB;AAAA,sDAAC,YAAO,IAAI,OAAO,GAAG,IAAI,OAAO,GAAG,GAAG,QAAQ,MAAK,QAAO,aAAa,QAAQ,WAAU,iBAAgB;AAAA,UAC1G;AAAA,YAAC;AAAA;AAAA,cACC,IAAI,OAAO;AAAA,cACX,IAAI,OAAO;AAAA,cACX,GAAG;AAAA,cACH,MAAK;AAAA,cACL,aAAa;AAAA,cACb,eAAc;AAAA,cACd,QAAQ;AAAA,cACR,iBAAiB;AAAA,cACjB,kBAAkB,iBAAiB,IAAI,MAAM;AAAA;AAAA,UAC/C;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAW,cAAG,wDAAwD,SAAS;AAAA,MAC/E,MAAK;AAAA,MACL,iBAAe;AAAA,MACf,iBAAe;AAAA,MACf,iBAAe;AAAA,MAEf,sDAAC,SAAI,WAAU,0CAAyC,OAAO,EAAE,OAAO,GAAG,GAAG,KAAK,iBAAiB,WAAW,GAAG;AAAA;AAAA,EACpH;AAEJ;","names":[]}
@@ -0,0 +1,18 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface XpProgressProps {
4
+ totalXp: number;
5
+ /** XP required to reach the current level. */
6
+ levelXp: number;
7
+ /** XP required for the next level; null at max level (renders full). */
8
+ nextLevelXp: number | null;
9
+ badgeColor: string;
10
+ variant?: "bar" | "ring";
11
+ /** Ring diameter in px (ring variant only). */
12
+ size?: number;
13
+ className?: string;
14
+ }
15
+ /** XP progress toward the next level, as a rounded bar or an SVG ring. */
16
+ declare function XpProgress({ totalXp, levelXp, nextLevelXp, badgeColor, variant, size, className }: XpProgressProps): react_jsx_runtime.JSX.Element;
17
+
18
+ export { XpProgress, type XpProgressProps };
@@ -0,0 +1,18 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface XpProgressProps {
4
+ totalXp: number;
5
+ /** XP required to reach the current level. */
6
+ levelXp: number;
7
+ /** XP required for the next level; null at max level (renders full). */
8
+ nextLevelXp: number | null;
9
+ badgeColor: string;
10
+ variant?: "bar" | "ring";
11
+ /** Ring diameter in px (ring variant only). */
12
+ size?: number;
13
+ className?: string;
14
+ }
15
+ /** XP progress toward the next level, as a rounded bar or an SVG ring. */
16
+ declare function XpProgress({ totalXp, levelXp, nextLevelXp, badgeColor, variant, size, className }: XpProgressProps): react_jsx_runtime.JSX.Element;
17
+
18
+ export { XpProgress, type XpProgressProps };