@sensiblestats/widget-react 0.26.2 → 0.27.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/dist/index.js CHANGED
@@ -816,8 +816,15 @@ function initials(name) {
816
816
  function shortSeason(season) {
817
817
  return season.replace(/\d{4}/g, (year) => year.slice(2));
818
818
  }
819
- function Crest({ image }) {
820
- return /* @__PURE__ */ jsx6("span", { className: "ss-w-ecard-crest", style: { backgroundImage: `url(${image})` }, "aria-hidden": "true" });
819
+ function Crest({ image, label }) {
820
+ return /* @__PURE__ */ jsx6(
821
+ "span",
822
+ {
823
+ className: "ss-w-ecard-crest",
824
+ style: { backgroundImage: `url(${image})` },
825
+ ...label ? { role: "img", title: label, "aria-label": label } : { "aria-hidden": "true" }
826
+ }
827
+ );
821
828
  }
822
829
  function FormBar({ w, d, l }) {
823
830
  if (w + d + l === 0) return null;
@@ -827,73 +834,73 @@ function FormBar({ w, d, l }) {
827
834
  l > 0 ? /* @__PURE__ */ jsx6("span", { className: "ss-w-form-l", style: { flexGrow: l } }) : null
828
835
  ] });
829
836
  }
830
- function StatRows({ stats }) {
831
- return /* @__PURE__ */ jsx6("div", { className: "ss-w-ecard-stats", children: stats.map((s) => {
832
- const m = RECORD_RE.exec(s.value);
833
- return /* @__PURE__ */ jsxs4("div", { className: "ss-w-ecard-row", children: [
834
- /* @__PURE__ */ jsx6("span", { className: "ss-w-ecard-rlabel", children: s.label }),
835
- m ? /* @__PURE__ */ jsx6(FormBar, { w: Number(m[1]), d: Number(m[2]), l: Number(m[3]) }) : /* @__PURE__ */ jsx6("span", {}),
836
- /* @__PURE__ */ jsx6("span", { className: "ss-w-ecard-rval", children: s.value })
837
- ] }, s.label);
838
- }) });
839
- }
840
- function CardBody({ c }) {
841
- const [active, setActive] = useState(0);
842
- if (c.scopes.length === 0) return null;
843
- const season = c.season ? /* @__PURE__ */ jsx6("span", { className: "ss-w-ecard-season", children: shortSeason(c.season) }) : null;
844
- if (c.scopes.length === 1) {
845
- const only = c.scopes[0];
846
- return /* @__PURE__ */ jsxs4("div", { className: "ss-w-ecard-body", children: [
847
- /* @__PURE__ */ jsxs4("div", { className: "ss-w-ecard-tabs ss-w-ecard-tabs-static", children: [
848
- /* @__PURE__ */ jsxs4("span", { className: "ss-w-ecard-lead", title: only.label, children: [
849
- only.image ? /* @__PURE__ */ jsx6(Crest, { image: only.image }) : null,
850
- /* @__PURE__ */ jsx6("span", { className: "ss-w-ecard-lead-txt", children: only.label })
851
- ] }),
852
- season
853
- ] }),
854
- /* @__PURE__ */ jsx6(StatRows, { stats: only.stats })
837
+ function StatCellView({ s }) {
838
+ const m = RECORD_RE.exec(s.value);
839
+ if (m) {
840
+ return /* @__PURE__ */ jsxs4("div", { className: "ss-w-ecard-cell", children: [
841
+ /* @__PURE__ */ jsx6("span", { className: "ss-w-ecard-cval", children: /* @__PURE__ */ jsx6(FormBar, { w: Number(m[1]), d: Number(m[2]), l: Number(m[3]) }) }),
842
+ /* @__PURE__ */ jsx6("span", { className: "ss-w-ecard-clabel", children: s.value })
855
843
  ] });
856
844
  }
857
- const current = c.scopes[active] ?? c.scopes[0];
858
- return /* @__PURE__ */ jsxs4("div", { className: "ss-w-ecard-body", children: [
859
- /* @__PURE__ */ jsxs4("div", { className: "ss-w-ecard-tabs", role: "tablist", children: [
860
- c.scopes.map((s, i) => /* @__PURE__ */ jsx6(
861
- "button",
862
- {
863
- type: "button",
864
- role: "tab",
865
- className: "ss-w-ecard-tab",
866
- "aria-selected": i === active,
867
- "aria-label": s.label,
868
- title: s.label,
869
- onClick: () => setActive(i),
870
- children: s.image ? /* @__PURE__ */ jsx6(Crest, { image: s.image }) : s.label
871
- },
872
- String(s.competitionId ?? "all")
873
- )),
874
- season
845
+ return /* @__PURE__ */ jsxs4("div", { className: "ss-w-ecard-cell", children: [
846
+ /* @__PURE__ */ jsx6("span", { className: "ss-w-ecard-cval", children: s.value }),
847
+ /* @__PURE__ */ jsx6("span", { className: "ss-w-ecard-clabel", children: s.label })
848
+ ] });
849
+ }
850
+ function StatStrip({ stats }) {
851
+ if (stats.length === 0) return null;
852
+ const cols = Math.min(stats.length, 4);
853
+ return /* @__PURE__ */ jsx6("div", { className: "ss-w-ecard-strip", style: { gridTemplateColumns: `repeat(${cols}, 1fr)` }, children: stats.map((s) => /* @__PURE__ */ jsx6(StatCellView, { s }, s.label + s.value)) });
854
+ }
855
+ function CardHeader({ c, showScopeCrest }) {
856
+ const onlyScope = c.scopes.length === 1 ? c.scopes[0] : null;
857
+ return /* @__PURE__ */ jsxs4("div", { className: "ss-w-ecard-hd", children: [
858
+ /* @__PURE__ */ jsx6(
859
+ "span",
860
+ {
861
+ className: c.kind === "team" ? "ss-w-thumb ss-w-team" : "ss-w-thumb",
862
+ style: c.image ? { backgroundImage: `url(${c.image})` } : void 0,
863
+ children: c.image ? "" : initials(c.name)
864
+ }
865
+ ),
866
+ /* @__PURE__ */ jsxs4("span", { className: "ss-w-ecard-idtext", children: [
867
+ /* @__PURE__ */ jsx6("span", { className: "ss-w-nm", children: c.name }),
868
+ c.sub ? /* @__PURE__ */ jsx6("span", { className: "ss-w-sub", children: c.sub }) : null
875
869
  ] }),
876
- /* @__PURE__ */ jsx6(StatRows, { stats: current.stats }, String(current.competitionId ?? "all"))
870
+ /* @__PURE__ */ jsxs4("span", { className: "ss-w-ecard-meta", children: [
871
+ showScopeCrest && onlyScope?.image ? /* @__PURE__ */ jsx6(Crest, { image: onlyScope.image, label: onlyScope.label }) : null,
872
+ c.season ? /* @__PURE__ */ jsx6("span", { className: "ss-w-ecard-season", children: shortSeason(c.season) }) : null
873
+ ] })
877
874
  ] });
878
875
  }
876
+ function ScopeTabs({ scopes, active, onSelect }) {
877
+ return /* @__PURE__ */ jsx6("div", { className: "ss-w-ecard-scopes", role: "tablist", children: scopes.map((s, i) => /* @__PURE__ */ jsx6(
878
+ "button",
879
+ {
880
+ type: "button",
881
+ role: "tab",
882
+ className: "ss-w-ecard-scope",
883
+ "aria-selected": i === active,
884
+ "aria-label": s.label,
885
+ title: s.label,
886
+ onClick: () => onSelect(i),
887
+ children: s.image ? /* @__PURE__ */ jsx6(Crest, { image: s.image }) : s.label
888
+ },
889
+ String(s.competitionId ?? "all")
890
+ )) });
891
+ }
879
892
  function EntityCardItem({ c }) {
893
+ const [active, setActive] = useState(0);
880
894
  const hasBody = c.scopes.length > 0;
881
- return /* @__PURE__ */ jsxs4("div", { className: hasBody ? "ss-w-ecard" : "ss-w-ecard ss-w-ecard-bare", "data-kind": c.kind, children: [
882
- /* @__PURE__ */ jsxs4("div", { className: "ss-w-ecard-id", children: [
883
- /* @__PURE__ */ jsx6(
884
- "span",
885
- {
886
- className: c.kind === "team" ? "ss-w-thumb ss-w-team" : "ss-w-thumb",
887
- style: c.image ? { backgroundImage: `url(${c.image})` } : void 0,
888
- children: c.image ? "" : initials(c.name)
889
- }
890
- ),
891
- /* @__PURE__ */ jsxs4("span", { className: "ss-w-ecard-idtext", children: [
892
- /* @__PURE__ */ jsx6("span", { className: "ss-w-nm", children: c.name }),
893
- c.sub ? /* @__PURE__ */ jsx6("span", { className: "ss-w-sub", children: c.sub }) : null
894
- ] })
895
- ] }),
896
- /* @__PURE__ */ jsx6(CardBody, { c })
895
+ if (!hasBody) {
896
+ return /* @__PURE__ */ jsx6("div", { className: "ss-w-ecard ss-w-ecard-bare", "data-kind": c.kind, children: /* @__PURE__ */ jsx6(CardHeader, { c, showScopeCrest: false }) });
897
+ }
898
+ const multi = c.scopes.length > 1;
899
+ const scope = c.scopes[multi ? c.scopes[active] ? active : 0 : 0];
900
+ return /* @__PURE__ */ jsxs4("div", { className: "ss-w-ecard", "data-kind": c.kind, children: [
901
+ /* @__PURE__ */ jsx6(CardHeader, { c, showScopeCrest: !multi }),
902
+ multi ? /* @__PURE__ */ jsx6(ScopeTabs, { scopes: c.scopes, active, onSelect: setActive }) : null,
903
+ /* @__PURE__ */ jsx6(StatStrip, { stats: scope.stats })
897
904
  ] });
898
905
  }
899
906
  function EntityCardList({ cards, disabled, showLessLabel = "Show less", showMoreLabel = (n) => `Show ${n} more` }) {
@@ -1048,7 +1055,7 @@ function Crest2({ url, name, kind }) {
1048
1055
 
1049
1056
  // src/components/BettingInsightList.tsx
1050
1057
  import { Fragment, jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
1051
- function StatRows2({ stats }) {
1058
+ function StatRows({ stats }) {
1052
1059
  return /* @__PURE__ */ jsx11("div", { className: "ss-w-bi-rows", children: stats.map((s) => /* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-row", children: [
1053
1060
  /* @__PURE__ */ jsx11("span", { className: "ss-w-bi-row-lbl", children: s.label }),
1054
1061
  /* @__PURE__ */ jsx11("span", { className: "ss-w-bi-row-num", children: s.value })
@@ -1059,7 +1066,7 @@ function ScopedStats({ scopes }) {
1059
1066
  const current = scopes[active] ?? scopes[0] ?? { key: "", label: "", stats: [] };
1060
1067
  return /* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-scoped", children: [
1061
1068
  /* @__PURE__ */ jsx11("div", { className: "ss-w-bi-scopes", role: "group", children: scopes.map((s, i) => /* @__PURE__ */ jsx11("button", { type: "button", className: "ss-w-bi-chip", "aria-pressed": i === active, onClick: () => setActive(i), children: s.label }, s.key)) }),
1062
- /* @__PURE__ */ jsx11(StatRows2, { stats: current.stats }, current.key)
1069
+ /* @__PURE__ */ jsx11(StatRows, { stats: current.stats }, current.key)
1063
1070
  ] });
1064
1071
  }
1065
1072
  function hasStatsContent(it) {
@@ -1076,7 +1083,7 @@ function ReasonStrip({ it, ui }) {
1076
1083
  /* @__PURE__ */ jsx11("span", { className: "ss-w-bi-chart", "aria-hidden": "true" }),
1077
1084
  /* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-reason-body", children: [
1078
1085
  hasText ? /* @__PURE__ */ jsx11("p", { className: `ss-w-bi-text${open ? "" : " ss-w-bi-text-clamp"}`, children: it.text }) : null,
1079
- open && hasStats ? hasScopes ? /* @__PURE__ */ jsx11(ScopedStats, { scopes: it.scopes }) : /* @__PURE__ */ jsx11(StatRows2, { stats: it.stats }) : null
1086
+ open && hasStats ? hasScopes ? /* @__PURE__ */ jsx11(ScopedStats, { scopes: it.scopes }) : /* @__PURE__ */ jsx11(StatRows, { stats: it.stats }) : null
1080
1087
  ] }),
1081
1088
  expandable ? /* @__PURE__ */ jsx11(
1082
1089
  "button",
@@ -2051,10 +2058,9 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
2051
2058
  /* entity cards */
2052
2059
  .ss-w-cards { display: flex; flex-direction: column; gap: 8px; }
2053
2060
 
2054
- /* Identity Hero: crest-led identity block | tabbed stats panel */
2055
- .ss-w-ecard { display: grid; grid-template-columns: 112px 1fr; align-items: stretch; width: 100%; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; overflow: hidden; text-align: left; }
2061
+ /* Entity card: identity header row over a horizontal stat strip */
2062
+ .ss-w-ecard { display: flex; flex-direction: column; width: 100%; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; overflow: hidden; text-align: left; }
2056
2063
 
2057
- .ss-w-ecard-id { display: flex; flex-direction: column; align-items: center; gap: 7px; text-align: center; padding: 13px 10px; border-right: 1px solid var(--ss-w-line); background: linear-gradient(158deg, var(--ss-w-bubble), color-mix(in srgb, var(--ss-w-accent) 9%, var(--ss-w-bubble))); }
2058
2064
  .ss-w-ecard-idtext { display: flex; flex-direction: column; gap: 1px; min-width: 0; max-width: 100%; }
2059
2065
  .ss-w-thumb { width: 54px; height: 54px; flex: none; border-radius: 50%; display: grid; place-items: center; font-size: 16px; font-weight: 700; color: #fff; background-color: var(--ss-w-nav); background-size: cover; background-position: center; box-shadow: 0 1px 3px rgba(0,0,0,.14); }
2060
2066
  .ss-w-thumb.ss-w-team { border-radius: 12px; }
@@ -2064,27 +2070,31 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
2064
2070
 
2065
2071
  /* bare card (no stat scopes): simple avatar + name row */
2066
2072
  .ss-w-ecard-bare { display: flex; align-items: center; }
2067
- .ss-w-ecard-bare .ss-w-ecard-id { flex-direction: row; text-align: left; gap: 11px; background: none; border-right: none; padding: 10px 12px; }
2068
- .ss-w-ecard-bare .ss-w-thumb { width: 40px; height: 40px; font-size: 13px; box-shadow: none; }
2069
- .ss-w-ecard-bare .ss-w-thumb.ss-w-team { border-radius: 10px; }
2070
-
2071
- .ss-w-ecard-body { min-width: 0; padding: 9px 12px 12px; display: flex; flex-direction: column; }
2072
-
2073
- /* tab strip seated on the stats panel's top edge; active tab underlined in accent */
2074
- .ss-w-ecard-tabs { display: flex; align-items: stretch; gap: 3px; border-bottom: 1px solid var(--ss-w-line); margin-bottom: 9px; flex-wrap: wrap; }
2075
- .ss-w-ecard-tab { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 620; color: var(--ss-w-faint); background: none; border: none; cursor: pointer; padding: 5px 8px 8px; margin-bottom: -1px; border-bottom: 2px solid transparent; }
2076
- .ss-w-ecard-tab[aria-selected="true"] { color: var(--ss-w-ink); border-bottom-color: var(--ss-w-accent); }
2077
- .ss-w-ecard-tabs-static { align-items: center; flex-wrap: nowrap; }
2078
- .ss-w-ecard-lead { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 640; color: var(--ss-w-ink); padding: 4px 2px 8px; min-width: 0; flex: 1; }
2079
- .ss-w-ecard-lead-txt { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2073
+ .ss-w-ecard-bare .ss-w-ecard-hd { padding: 10px 12px; }
2074
+
2075
+ .ss-w-ecard-hd { display: flex; align-items: center; gap: 11px; padding: 11px 13px; }
2076
+ .ss-w-ecard-hd .ss-w-thumb { width: 40px; height: 40px; font-size: 13px; box-shadow: none; }
2077
+ .ss-w-ecard-hd .ss-w-thumb.ss-w-team { border-radius: 10px; }
2078
+ .ss-w-ecard-meta { display: inline-flex; align-items: center; gap: 7px; flex: none; align-self: flex-start; margin-left: auto; }
2079
+ .ss-w-ecard-meta .ss-w-ecard-season { margin: 0; }
2080
+
2081
+ /* scope tabs: reuse the underline pattern, relocated above the strip */
2082
+ .ss-w-ecard-scopes { display: flex; align-items: stretch; gap: 2px; padding: 0 11px; border-top: 1px solid var(--ss-w-line); flex-wrap: wrap; }
2083
+ .ss-w-ecard-scope { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 620; color: var(--ss-w-faint); background: none; border: none; cursor: pointer; padding: 7px 8px; margin-bottom: -1px; border-bottom: 2px solid transparent; }
2084
+ .ss-w-ecard-scope[aria-selected="true"] { color: var(--ss-w-ink); border-bottom-color: var(--ss-w-accent); }
2085
+ .ss-w-ecard-scope .ss-w-ecard-crest { width: 14px; height: 14px; }
2086
+ .ss-w-ecard-scopes + .ss-w-ecard-strip { border-top: none; }
2087
+
2080
2088
  .ss-w-ecard-crest { width: 15px; height: 15px; flex: none; display: block; border-radius: 4px; background-size: cover; background-position: center; }
2081
2089
  .ss-w-ecard-season { flex: none; margin-left: auto; align-self: center; margin-bottom: 5px; font-size: 10.5px; font-weight: 700; color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 13%, var(--ss-w-panel)); border-radius: 999px; padding: 3px 9px; white-space: nowrap; }
2082
- .ss-w-ecard-tabs-static .ss-w-ecard-season { margin-bottom: 4px; }
2083
2090
 
2084
- .ss-w-ecard-stats { display: flex; flex-direction: column; gap: 4px; }
2085
- .ss-w-ecard-row { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 10px; }
2086
- .ss-w-ecard-rlabel { font-size: 9.5px; text-transform: uppercase; letter-spacing: .045em; color: var(--ss-w-faint); font-weight: 600; }
2087
- .ss-w-ecard-rval { justify-self: end; font-size: 15px; font-weight: 720; font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
2091
+ /* stat strip: 1px gap over a line-colored ground paints hairlines between cells, wrap-safe */
2092
+ .ss-w-ecard-strip { display: grid; gap: 1px; background: var(--ss-w-line); border-top: 1px solid var(--ss-w-line); }
2093
+ .ss-w-ecard-cell { display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: 4px; padding: 10px 4px 11px; background: var(--ss-w-panel); }
2094
+ .ss-w-ecard-cval { height: 20px; display: flex; align-items: center; font-size: 17px; font-weight: 720; font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
2095
+ .ss-w-ecard-cval .ss-w-form { width: 42px; }
2096
+ .ss-w-ecard-clabel { font-size: 9px; text-transform: uppercase; letter-spacing: .05em; color: var(--ss-w-faint); font-weight: 600; font-variant-numeric: tabular-nums; }
2097
+
2088
2098
  .ss-w-form { justify-self: end; display: flex; height: 6px; width: 48px; border-radius: 4px; overflow: hidden; gap: 2px; }
2089
2099
  .ss-w-form span { display: block; border-radius: 2px; }
2090
2100
  .ss-w-form-w { background: var(--ss-w-pos); }