@sensiblestats/widget-react 0.61.1 → 0.61.3

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @sensiblestats/widget-react
2
2
 
3
+ ## 0.61.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Guess the XI draws each line with the provider's right-to-left numbering (right back on the right). Career Path shows the player's photo once the career is solved or failed.
8
+
9
+ ## 0.61.2
10
+
11
+ ### Patch Changes
12
+
13
+ - Games: a provider placeholder photo (Sportmonks `placeholder.png`) now shows the player's initials or the crest shield instead of a grey silhouette.
14
+
3
15
  ## 0.61.1
4
16
 
5
17
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -4988,13 +4988,16 @@ function initialsOf(name) {
4988
4988
  if (parts.length === 1 || !last) return first.slice(0, 2).toUpperCase();
4989
4989
  return ((first[0] ?? "") + (last[0] ?? "")).toUpperCase();
4990
4990
  }
4991
+ function isPlaceholderImage(url) {
4992
+ return !!url && /\/placeholder\.(png|jpe?g|svg|webp)(\?|$)/i.test(url);
4993
+ }
4991
4994
  function PlayerAvatar({
4992
4995
  name,
4993
4996
  imagePath,
4994
4997
  className
4995
4998
  }) {
4996
4999
  const [failed, setFailed] = (0, import_react30.useState)(false);
4997
- const showImage = Boolean(imagePath) && !failed;
5000
+ const showImage = Boolean(imagePath) && !isPlaceholderImage(imagePath) && !failed;
4998
5001
  return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className, "aria-hidden": "true", children: showImage ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("img", { src: imagePath, alt: "", loading: "lazy", onError: () => setFailed(true) }) : /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "ss-w-av-initials", children: initialsOf(name) }) });
4999
5002
  }
5000
5003
 
@@ -5491,7 +5494,7 @@ var import_react32 = require("react");
5491
5494
  var import_jsx_runtime69 = require("react/jsx-runtime");
5492
5495
  function CrestShield({ src, name, size = 28 }) {
5493
5496
  const [failed, setFailed] = (0, import_react32.useState)(false);
5494
- if (src && !failed) {
5497
+ if (src && !isPlaceholderImage(src) && !failed) {
5495
5498
  return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("img", { className: "ss-g-crest", src, alt: name, width: size, height: size, loading: "lazy", onError: () => setFailed(true) });
5496
5499
  }
5497
5500
  return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("svg", { className: "ss-g-crest ss-g-crest--ph", width: size, height: size * 32 / 28, viewBox: "0 0 28 32", role: "img", "aria-label": name, children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("path", { d: "M2 3h24v12c0 9-6 14-12 17C8 29 2 24 2 15z", fill: "currentColor" }) });
@@ -5558,7 +5561,7 @@ function CareerPathGame({
5558
5561
  /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(GameHeader, { title, eyebrow: s.eyebrow, right, onBack, backLabel: ui.back }),
5559
5562
  /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: "ss-g-body", children: [
5560
5563
  /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: "ss-g-cp-card", children: [
5561
- /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(Silhouette, { size: 64, variant: isOver ? "default" : "mystery" }),
5564
+ isOver && clientState?.revealedPlayerName ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(PlayerAvatar, { className: "ss-g-cp-photo", name: clientState.revealedPlayerName, imagePath: clientState.revealedPlayerImagePath }) : /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(Silhouette, { size: 64, variant: isOver ? "default" : "mystery" }),
5562
5565
  /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: "ss-g-cp-card-text", children: [
5563
5566
  /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { className: "ss-g-cp-card-title", children: isOver && clientState?.revealedPlayerName ? clientState.revealedPlayerName : s.mysteryPlayer }),
5564
5567
  clientState?.hintLine ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { className: "ss-g-cp-hint", children: clientState.hintLine }) : !isOver ? /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("span", { className: "ss-g-cp-locks", children: [
@@ -5974,7 +5977,8 @@ function toRows(positions) {
5974
5977
  bucket.push(p);
5975
5978
  byRow.set(rowKey, bucket);
5976
5979
  });
5977
- return [...byRow.keys()].sort((a, b) => b - a).map((k) => byRow.get(k));
5980
+ const col = (p) => Number(p.slot?.split(":")[1]) || 0;
5981
+ return [...byRow.keys()].sort((a, b) => b - a).map((k) => [...byRow.get(k)].sort((a, b) => col(b) - col(a)));
5978
5982
  }
5979
5983
  function formationLabel(rowsAttackFirst) {
5980
5984
  if (rowsAttackFirst.length < 2) return "";
@@ -8530,6 +8534,8 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
8530
8534
  .ss-g-mt-portrait .ss-g-sil { font-size: 46px; }
8531
8535
  .ss-g-mt-photo { width: 132px; height: 132px; margin-bottom: 30px; border-radius: 50%; overflow: hidden; display: grid; place-items: center; background: var(--ss-g-accent-tint); color: var(--ss-w-accent); font: 800 40px var(--ss-g-font-display); }
8532
8536
  .ss-g-mt-photo img { width: 100%; height: 100%; object-fit: cover; }
8537
+ .ss-g-cp-photo { width: 64px; height: 64px; flex: none; border-radius: 50%; overflow: hidden; display: grid; place-items: center; background: var(--ss-g-accent-tint); color: var(--ss-w-accent); font: 800 22px var(--ss-g-font-display); }
8538
+ .ss-g-cp-photo img { width: 100%; height: 100%; object-fit: cover; }
8533
8539
  .ss-g-mt-reveal-name { position: absolute; bottom: 6px; left: 12px; right: 12px; text-align: center; font: 800 20px var(--ss-g-font-display); text-transform: uppercase; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
8534
8540
  .ss-g-mt-known { display: grid; gap: 6px; padding: 12px; }
8535
8541
  .ss-g-mt-known-cell { display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 0; }