@sensiblestats/widget-react 0.8.0 → 0.9.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.
- package/CHANGELOG.md +15 -0
- package/dist/index.cjs +86 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +89 -23
- package/dist/index.js.map +1 -1
- package/dist/styles.css +10 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @sensiblestats/widget-react
|
|
2
2
|
|
|
3
|
+
## 0.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Entity cards now show the season and per-competition scope chips. `EntityCard`
|
|
8
|
+
drops the flat `stats` field in favor of `seasonName` + `scopes` (`All` aggregate
|
|
9
|
+
plus one scope per competition, each with an optional logo); the widget renders a
|
|
10
|
+
season label and, for 2+ competitions, a chip row that switches the stat set
|
|
11
|
+
client-side. `widget-embed` re-bundles `widget-react`, so it is republished too.
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies
|
|
16
|
+
- @sensiblestats/widget-sdk@0.8.0
|
|
17
|
+
|
|
3
18
|
## 0.8.0
|
|
4
19
|
|
|
5
20
|
### Minor Changes
|
package/dist/index.cjs
CHANGED
|
@@ -193,19 +193,27 @@ function readStatCells(raw) {
|
|
|
193
193
|
}
|
|
194
194
|
return cells;
|
|
195
195
|
}
|
|
196
|
-
function readStats(card) {
|
|
197
|
-
return readStatCells(card.stats);
|
|
198
|
-
}
|
|
199
196
|
function toCardVM(card) {
|
|
200
197
|
const entityType = str(card.entityType)?.toLowerCase();
|
|
201
198
|
const kind = entityType === "player" ? "player" : entityType === "team" ? "team" : "generic";
|
|
199
|
+
const scopes = Array.isArray(card.scopes) ? card.scopes.map((s) => {
|
|
200
|
+
const label = str(s.label);
|
|
201
|
+
if (!label) return null;
|
|
202
|
+
return {
|
|
203
|
+
competitionId: typeof s.competitionId === "number" ? s.competitionId : null,
|
|
204
|
+
label,
|
|
205
|
+
image: str(s.imagePath),
|
|
206
|
+
stats: readStatCells(s.stats)
|
|
207
|
+
};
|
|
208
|
+
}).filter((s) => s !== null) : [];
|
|
202
209
|
return {
|
|
203
210
|
id: String(card.entityId),
|
|
204
211
|
kind,
|
|
205
212
|
name: card.canonicalName,
|
|
206
213
|
image: str(card.imagePath) ?? str(card.imageUrl) ?? str(card.image_url) ?? str(card.logoUrl) ?? str(card.logo),
|
|
207
214
|
sub: str(card.subtitle) ?? str(card.teamName) ?? str(card.leagueName) ?? str(card.position),
|
|
208
|
-
|
|
215
|
+
season: str(card.seasonName),
|
|
216
|
+
scopes
|
|
209
217
|
};
|
|
210
218
|
}
|
|
211
219
|
function toActionVM(action) {
|
|
@@ -539,13 +547,53 @@ var MAX_VISIBLE = 3;
|
|
|
539
547
|
function initials(name) {
|
|
540
548
|
return name.split(/\s+/).slice(0, 2).map((w) => w[0] ?? "").join("").toUpperCase();
|
|
541
549
|
}
|
|
542
|
-
function
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
550
|
+
function Crest({ scope }) {
|
|
551
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ss-w-ecard-crest", style: { backgroundImage: `url(${scope.image})` }, "aria-hidden": "true" });
|
|
552
|
+
}
|
|
553
|
+
function StatRow({ stats }) {
|
|
554
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "ss-w-ecard-stats", children: stats.map((s) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "ss-w-stat", children: [
|
|
555
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("b", { children: s.value }),
|
|
556
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: s.label })
|
|
557
|
+
] }, s.label)) });
|
|
558
|
+
}
|
|
559
|
+
function ScopeChips({ scopes }) {
|
|
560
|
+
const [active, setActive] = (0, import_react2.useState)(0);
|
|
561
|
+
const current = scopes[active] ?? scopes[0];
|
|
562
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
563
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "ss-w-ecard-scopes", role: "group", children: scopes.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
564
|
+
"button",
|
|
565
|
+
{
|
|
566
|
+
type: "button",
|
|
567
|
+
className: "ss-w-ecard-chip",
|
|
568
|
+
"aria-pressed": i === active,
|
|
569
|
+
"aria-label": s.label,
|
|
570
|
+
title: s.label,
|
|
571
|
+
onClick: () => setActive(i),
|
|
572
|
+
children: s.image ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Crest, { scope: s }) : s.label
|
|
573
|
+
},
|
|
574
|
+
String(s.competitionId ?? "all")
|
|
575
|
+
)) }),
|
|
576
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(StatRow, { stats: current.stats }, String(current.competitionId ?? "all"))
|
|
577
|
+
] });
|
|
578
|
+
}
|
|
579
|
+
function CardScopes({ scopes }) {
|
|
580
|
+
if (scopes.length === 0) return null;
|
|
581
|
+
if (scopes.length === 1) {
|
|
582
|
+
const only = scopes[0];
|
|
583
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
584
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "ss-w-ecard-tag", children: [
|
|
585
|
+
only.image ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Crest, { scope: only }) : null,
|
|
586
|
+
only.label
|
|
587
|
+
] }),
|
|
588
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(StatRow, { stats: only.stats })
|
|
589
|
+
] });
|
|
590
|
+
}
|
|
591
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ScopeChips, { scopes });
|
|
592
|
+
}
|
|
593
|
+
function EntityCardItem({ c }) {
|
|
594
|
+
const season = c.scopes.length > 0 ? c.season : void 0;
|
|
595
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ss-w-ecard", "data-kind": c.kind, children: [
|
|
596
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ss-w-ecard-head", children: [
|
|
549
597
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
550
598
|
"span",
|
|
551
599
|
{
|
|
@@ -557,13 +605,23 @@ function EntityCardList({ cards, disabled, showLessLabel = "Show less", showMore
|
|
|
557
605
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "ss-w-meta", children: [
|
|
558
606
|
c.kind !== "generic" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ss-w-kind", children: c.kind }) : null,
|
|
559
607
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ss-w-nm", children: c.name }),
|
|
560
|
-
c.sub ? /* @__PURE__ */ (0, import_jsx_runtime6.
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
] }
|
|
566
|
-
] }
|
|
608
|
+
c.sub || season ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "ss-w-sub", children: [
|
|
609
|
+
c.sub,
|
|
610
|
+
c.sub && season ? " \xB7 " : "",
|
|
611
|
+
season ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ss-w-season", children: season }) : null
|
|
612
|
+
] }) : null
|
|
613
|
+
] })
|
|
614
|
+
] }),
|
|
615
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CardScopes, { scopes: c.scopes })
|
|
616
|
+
] });
|
|
617
|
+
}
|
|
618
|
+
function EntityCardList({ cards, disabled, showLessLabel = "Show less", showMoreLabel = (n) => `Show ${n} more` }) {
|
|
619
|
+
const [expanded, setExpanded] = (0, import_react2.useState)(false);
|
|
620
|
+
if (cards.length === 0) return null;
|
|
621
|
+
const visible = expanded ? cards : cards.slice(0, MAX_VISIBLE);
|
|
622
|
+
const overflow = cards.length - MAX_VISIBLE;
|
|
623
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ss-w-cards", children: [
|
|
624
|
+
visible.map((c) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(EntityCardItem, { c }, c.id)),
|
|
567
625
|
overflow > 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "ss-w-cards-more", disabled, onClick: () => setExpanded((v) => !v), children: expanded ? showLessLabel : showMoreLabel(overflow) }) : null
|
|
568
626
|
] });
|
|
569
627
|
}
|
|
@@ -1017,7 +1075,8 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
1017
1075
|
|
|
1018
1076
|
/* entity cards */
|
|
1019
1077
|
.ss-w-cards { display: flex; flex-direction: column; gap: 7px; }
|
|
1020
|
-
.ss-w-ecard { display: flex; align-items:
|
|
1078
|
+
.ss-w-ecard { display: flex; flex-direction: column; align-items: stretch; gap: 8px; width: 100%; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; padding: 8px 11px; text-align: left; }
|
|
1079
|
+
.ss-w-ecard-head { display: flex; align-items: center; gap: 11px; }
|
|
1021
1080
|
.ss-w-thumb { width: 40px; height: 40px; flex: none; border-radius: 50%; display: grid; place-items: center; font-size: 13px; font-weight: 700; color: #fff; background-color: var(--ss-w-nav); background-size: cover; background-position: center; }
|
|
1022
1081
|
.ss-w-thumb.ss-w-team { border-radius: 10px; }
|
|
1023
1082
|
.ss-w-ecard[data-kind="player"] .ss-w-thumb { background-color: var(--ss-w-accent); }
|
|
@@ -1025,7 +1084,14 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
1025
1084
|
.ss-w-kind { font-size: 8.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--ss-w-faint); line-height: 1.3; }
|
|
1026
1085
|
.ss-w-nm { font-weight: 660; }
|
|
1027
1086
|
.ss-w-sub { font-size: 11px; color: var(--ss-w-faint); }
|
|
1028
|
-
.ss-w-
|
|
1087
|
+
.ss-w-season { color: var(--ss-w-accent); font-weight: 660; }
|
|
1088
|
+
.ss-w-ecard-scopes { display: inline-flex; align-items: center; gap: 2px; flex-wrap: wrap; align-self: flex-start; background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 9px; padding: 2px; }
|
|
1089
|
+
.ss-w-ecard-chip { display: inline-flex; align-items: center; font-size: 11px; font-weight: 600; border: none; border-radius: 7px; padding: 4px 8px; color: var(--ss-w-faint); background: none; cursor: pointer; }
|
|
1090
|
+
.ss-w-ecard-chip[aria-pressed="true"] { color: var(--ss-w-ink); background: var(--ss-w-panel); box-shadow: 0 1px 2px rgba(0,0,0,.08); }
|
|
1091
|
+
.ss-w-ecard-crest { width: 16px; height: 16px; display: block; border-radius: 4px; background-size: cover; background-position: center; }
|
|
1092
|
+
.ss-w-ecard-tag { display: inline-flex; align-items: center; gap: 6px; align-self: flex-start; font-size: 11px; font-weight: 600; color: var(--ss-w-faint); }
|
|
1093
|
+
.ss-w-ecard-stats { display: flex; gap: 16px; }
|
|
1094
|
+
.ss-w-stat { text-align: center; }
|
|
1029
1095
|
.ss-w-stat b { display: block; font-variant-numeric: tabular-nums; }
|
|
1030
1096
|
.ss-w-stat span { font-size: 9px; text-transform: uppercase; color: var(--ss-w-faint); }
|
|
1031
1097
|
.ss-w-cards-more { align-self: flex-start; font-size: 11.5px; font-weight: 560; color: var(--ss-w-accent); background: none; border: none; cursor: pointer; padding: 3px 2px; }
|