@sensiblestats/widget-react 0.73.0 → 0.74.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 +12 -0
- package/dist/index.cjs +74 -11
- 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 +74 -11
- package/dist/index.js.map +1 -1
- package/dist/styles.css +14 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @sensiblestats/widget-react
|
|
2
2
|
|
|
3
|
+
## 0.74.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Set the numbers: a fifth row, "BTTS picks today", with a market dropdown (BTTS, Over 2.5, Under 2.5, Double chance, Match winner), an "N ready" pill and the round send. It shows only when the server's preset grid has a `markets` section.
|
|
8
|
+
|
|
9
|
+
## 0.73.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Goal dashboard rows are compact cards: 60px tall with 8px corners, and a tile's badge shows as a price column on the right instead of a pill under the subtitle.
|
|
14
|
+
|
|
3
15
|
## 0.73.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/dist/index.cjs
CHANGED
|
@@ -187,7 +187,11 @@ var STRINGS = {
|
|
|
187
187
|
maxPriceName: "Max price",
|
|
188
188
|
minPriceName: "Lowest price",
|
|
189
189
|
notToday: " \xB7 not today",
|
|
190
|
-
changeCombo: "Change total or matches"
|
|
190
|
+
changeCombo: "Change total or matches",
|
|
191
|
+
marketRow: "{market} picks today",
|
|
192
|
+
marketName: "Market",
|
|
193
|
+
marketShort: (dev, market, sel) => ({ BOTH_TEAMS_TO_SCORE: "BTTS", DOUBLE_CHANCE: "Double chance", FULLTIME_RESULT: "Match winner" })[dev] ?? (dev === "GOALS_OVER_UNDER" && sel ? sel : sel ? `${market} ${sel}` : market),
|
|
194
|
+
marketMessage: (market, sel, count) => `Show me ${count} ${sel ? `${market} \u2013 ${sel}` : market} picks.`
|
|
191
195
|
},
|
|
192
196
|
games: {
|
|
193
197
|
lang: "en",
|
|
@@ -521,7 +525,11 @@ var STRINGS = {
|
|
|
521
525
|
maxPriceName: "En y\xFCksek oran",
|
|
522
526
|
minPriceName: "En d\xFC\u015F\xFCk oran",
|
|
523
527
|
notToday: " \xB7 bug\xFCn yok",
|
|
524
|
-
changeCombo: "Toplam\u0131 veya ma\xE7lar\u0131 de\u011Fi\u015Ftir"
|
|
528
|
+
changeCombo: "Toplam\u0131 veya ma\xE7lar\u0131 de\u011Fi\u015Ftir",
|
|
529
|
+
marketRow: "Bug\xFCnk\xFC {market} se\xE7imleri",
|
|
530
|
+
marketName: "Bahis t\xFCr\xFC",
|
|
531
|
+
marketShort: (dev, market, sel) => ({ BOTH_TEAMS_TO_SCORE: "KG Var", DOUBLE_CHANCE: "\xC7ifte \u015Fans", FULLTIME_RESULT: "Ma\xE7 sonucu" })[dev] ?? (dev === "GOALS_OVER_UNDER" && sel ? sel : sel ? `${market} ${sel}` : market),
|
|
532
|
+
marketMessage: (market, sel, count) => `${count} ${sel ? `${market} \u2013 ${sel}` : market} se\xE7imi g\xF6ster.`
|
|
525
533
|
},
|
|
526
534
|
games: {
|
|
527
535
|
lang: "tr",
|
|
@@ -2977,6 +2985,16 @@ function comboAsk(cell, s) {
|
|
|
2977
2985
|
preset: { kind: "combo", total: cell.total, legs: cell.legs, ...idsOf(cell.combo.legs) }
|
|
2978
2986
|
};
|
|
2979
2987
|
}
|
|
2988
|
+
function marketAsk(cell, s) {
|
|
2989
|
+
return {
|
|
2990
|
+
message: s.marketMessage(cell.marketLabel, cell.selectionLabel ?? null, cell.count),
|
|
2991
|
+
displayText: marketDisplay(cell, s),
|
|
2992
|
+
preset: { kind: "market", marketDeveloperName: cell.marketDeveloperName, ...idsOf(cell.picks) }
|
|
2993
|
+
};
|
|
2994
|
+
}
|
|
2995
|
+
function marketDisplay(cell, s) {
|
|
2996
|
+
return s.marketRow.replace("{market}", s.marketShort(cell.marketDeveloperName, cell.marketLabel, cell.selectionLabel ?? null));
|
|
2997
|
+
}
|
|
2980
2998
|
|
|
2981
2999
|
// src/usePresetGrid.ts
|
|
2982
3000
|
var GRID_MAX_AGE_MS = 6e5;
|
|
@@ -3024,7 +3042,7 @@ function usePresetGrid({ getPricePresets, isOpen, locale, now = Date.now }) {
|
|
|
3024
3042
|
return grid;
|
|
3025
3043
|
}
|
|
3026
3044
|
function hasAnyCell(grid) {
|
|
3027
|
-
return grid.singles.length > 0 || grid.singlesFrom.length > 0 || grid.combos.length > 0;
|
|
3045
|
+
return grid.singles.length > 0 || grid.singlesFrom.length > 0 || grid.combos.length > 0 || grid.markets !== void 0 && grid.markets.length > 0;
|
|
3028
3046
|
}
|
|
3029
3047
|
|
|
3030
3048
|
// src/liveClock.ts
|
|
@@ -4200,11 +4218,13 @@ function HeroTile({ tile, onTap, oddsLabel }) {
|
|
|
4200
4218
|
] })
|
|
4201
4219
|
] });
|
|
4202
4220
|
}
|
|
4203
|
-
function DashboardTile({ tile, onTap, oddsLabel = "Odds" }) {
|
|
4221
|
+
function DashboardTile({ tile, onTap, oddsLabel = "Odds", badgePlacement = "meta" }) {
|
|
4204
4222
|
if (tile.emphasis === "hero") return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(HeroTile, { tile, onTap, oddsLabel });
|
|
4205
4223
|
const spanClass = tile.span === "full" ? "ss-w-dash-tile--full" : "ss-w-dash-tile--half";
|
|
4206
4224
|
const crests = (tile.imageUrls ?? []).slice(0, MAX_CRESTS);
|
|
4207
|
-
const
|
|
4225
|
+
const endBadge = badgePlacement === "end" && tile.badgeText ? tile.badgeText : null;
|
|
4226
|
+
const metaBadge = endBadge ? null : tile.badgeText;
|
|
4227
|
+
const hasMeta = Boolean(metaBadge) || crests.length > 0;
|
|
4208
4228
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { type: "button", className: `ss-w-dash-tile ${spanClass}`, onClick: onTap, children: [
|
|
4209
4229
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-dash-tile-icon", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DashboardIcon, { name: tile.icon }) }),
|
|
4210
4230
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "ss-w-dash-tile-body", children: [
|
|
@@ -4215,12 +4235,12 @@ function DashboardTile({ tile, onTap, oddsLabel = "Odds" }) {
|
|
|
4215
4235
|
// icon/chevron row -- at the half-span tile's ~180px width a nowrap badge alone
|
|
4216
4236
|
// (~70px) left the title column at ~22px and forced character-by-character wrapping.
|
|
4217
4237
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "ss-w-dash-tile-meta", children: [
|
|
4218
|
-
|
|
4238
|
+
metaBadge ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-dash-tile-badge", children: metaBadge }) : null,
|
|
4219
4239
|
crests.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-dash-tile-crests", children: crests.map((url, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-dash-tile-crest", style: { backgroundImage: `url(${url})` }, "aria-hidden": "true" }, `${url}-${i}`)) }) : null
|
|
4220
4240
|
] })
|
|
4221
4241
|
) : null
|
|
4222
4242
|
] }),
|
|
4223
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-dash-tile-chevron", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ChevronIcon, {}) })
|
|
4243
|
+
endBadge ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-dash-tile-value", children: endBadge }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-dash-tile-chevron", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ChevronIcon, {}) })
|
|
4224
4244
|
] });
|
|
4225
4245
|
}
|
|
4226
4246
|
|
|
@@ -4235,12 +4255,14 @@ function layoutClass(layout) {
|
|
|
4235
4255
|
return Object.prototype.hasOwnProperty.call(LAYOUT_CLASSES, layout) ? LAYOUT_CLASSES[layout] : LAYOUT_CLASSES.goal;
|
|
4236
4256
|
}
|
|
4237
4257
|
function GreetingDashboard({ dashboard, onTap, oddsLabel }) {
|
|
4238
|
-
|
|
4258
|
+
const layout = layoutClass(dashboard.layout);
|
|
4259
|
+
const badgePlacement = layout === LAYOUT_CLASSES.goal ? "end" : "meta";
|
|
4260
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: `ss-w-dash ${layout}`, children: [
|
|
4239
4261
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "ss-w-dash-head", children: [
|
|
4240
4262
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "ss-w-dash-title", children: dashboard.title }),
|
|
4241
4263
|
dashboard.subtitle ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "ss-w-dash-subtitle", children: dashboard.subtitle }) : null
|
|
4242
4264
|
] }),
|
|
4243
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "ss-w-dash-grid", children: dashboard.tiles.map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DashboardTile, { tile: t, onTap: () => onTap(t, i), oddsLabel }, `${t.title}-${i}`)) }),
|
|
4265
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "ss-w-dash-grid", children: dashboard.tiles.map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DashboardTile, { tile: t, onTap: () => onTap(t, i), oddsLabel, badgePlacement }, `${t.title}-${i}`)) }),
|
|
4244
4266
|
dashboard.footerTip ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "ss-w-dash-foot", children: dashboard.footerTip }) : null
|
|
4245
4267
|
] });
|
|
4246
4268
|
}
|
|
@@ -8730,6 +8752,13 @@ function NumberSelect({ current, choices: choices2, label, notToday, lockEmpty =
|
|
|
8730
8752
|
}, children: choices2.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("option", { value: String(i), disabled: lockEmpty && !c.available && i !== selected, children: c.available ? c.text : `${c.text}${notToday}` }, i)) })
|
|
8731
8753
|
] });
|
|
8732
8754
|
}
|
|
8755
|
+
function ChoiceSelect({ currentIdx, sizeLabels, optionLabels, label, onChoose }) {
|
|
8756
|
+
const sizeText = sizeLabels[currentIdx] ?? "";
|
|
8757
|
+
return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("span", { className: "ss-w-tool-num", children: [
|
|
8758
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { className: "ss-w-tool-num-size", "aria-hidden": "true", children: sizeText }),
|
|
8759
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("select", { className: "ss-w-tool-num-select", "aria-label": label, value: String(currentIdx), onChange: (e) => onChoose(Number(e.target.value)), children: optionLabels.map((opt, i) => /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("option", { value: String(i), children: opt }, i)) })
|
|
8760
|
+
] });
|
|
8761
|
+
}
|
|
8733
8762
|
function SendButton({ label, display, disabled, onClick }) {
|
|
8734
8763
|
return /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("button", { type: "button", className: "ss-w-tool-send", "aria-label": `${label}: ${display}`, disabled, onClick, children: label });
|
|
8735
8764
|
}
|
|
@@ -8793,6 +8822,11 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
|
|
|
8793
8822
|
const comboCell = findCombo(grid, total, legs);
|
|
8794
8823
|
const bigCell = findCombo(grid, bigTotal, bigLegs);
|
|
8795
8824
|
const announce = (display, available) => setAnnouncement(available ? display : `${display}. ${strings.unavailable}`);
|
|
8825
|
+
const chooseMarket = (idx) => {
|
|
8826
|
+
setMarketIdx(idx);
|
|
8827
|
+
const cell = markets[idx];
|
|
8828
|
+
if (cell) announce(marketDisplay(cell, strings), cell.count > 0);
|
|
8829
|
+
};
|
|
8796
8830
|
const chooseMax = (v) => {
|
|
8797
8831
|
setMaxPrice(v);
|
|
8798
8832
|
announce(strings.maxPriceDisplay(count, v), !!findSingles(grid.singles, v, count));
|
|
@@ -8825,6 +8859,10 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
|
|
|
8825
8859
|
const minChoices = floors.map((v) => ({ value: v, text: v.toFixed(2), available: !!findSingles(grid.singlesFrom, v, count) }));
|
|
8826
8860
|
const totalChoices = totals.map((v) => ({ value: v, text: v.toFixed(1), available: legChoices.some((n) => !!findCombo(grid, v, n)) }));
|
|
8827
8861
|
const legChoicesFor = (t) => legChoices.map((n) => ({ value: n, text: String(n), available: !!findCombo(grid, t, n) }));
|
|
8862
|
+
const markets = grid.markets ?? [];
|
|
8863
|
+
const [marketIdx, setMarketIdx] = (0, import_react51.useState)(0);
|
|
8864
|
+
const marketCell = markets[marketIdx] ?? null;
|
|
8865
|
+
const marketLabels = markets.map((c) => strings.marketShort(c.marketDeveloperName, c.marketLabel, c.selectionLabel ?? null));
|
|
8828
8866
|
const singlesReady = (cell) => cell ? strings.readyCount(cell.picks.length) : strings.unavailable;
|
|
8829
8867
|
const comboReady = (cell) => cell ? strings.readyAt(cell.combo.total) : strings.unavailable;
|
|
8830
8868
|
return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(PresetToolModal, { title: strings.setNumbers, closeLabel: strings.close, onClose, children: [
|
|
@@ -8884,6 +8922,19 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
|
|
|
8884
8922
|
} })
|
|
8885
8923
|
}
|
|
8886
8924
|
),
|
|
8925
|
+
markets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
8926
|
+
AskRow,
|
|
8927
|
+
{
|
|
8928
|
+
icon: "\u26BD",
|
|
8929
|
+
ask: fillTemplate(strings.marketRow, {
|
|
8930
|
+
market: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(ChoiceSelect, { currentIdx: marketIdx, sizeLabels: marketLabels, optionLabels: marketLabels, label: strings.marketName, onChoose: chooseMarket })
|
|
8931
|
+
}),
|
|
8932
|
+
ready: marketCell ? strings.readyCount(marketCell.count) : null,
|
|
8933
|
+
send: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(RoundSend, { label: strings.send, display: marketCell ? marketDisplay(marketCell, strings) : "", disabled: !marketCell || streaming, onClick: () => {
|
|
8934
|
+
if (marketCell) onSend(marketAsk(marketCell, strings));
|
|
8935
|
+
} })
|
|
8936
|
+
}
|
|
8937
|
+
),
|
|
8887
8938
|
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("p", { className: "ss-w-vh", "aria-live": "polite", children: announcement })
|
|
8888
8939
|
] });
|
|
8889
8940
|
}
|
|
@@ -9873,9 +9924,21 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
9873
9924
|
part of that visual language rather than a plain unstyled button. */
|
|
9874
9925
|
.ss-w-dash--market .ss-w-dash-tile { border-left: 3px solid var(--ss-w-accent); }
|
|
9875
9926
|
|
|
9876
|
-
/* Goal: one column of
|
|
9927
|
+
/* Goal: one column of compact cards, 60px tall with the badge as a price column on the right.
|
|
9928
|
+
The value ink is accent mixed toward ink (as on the hero price): plain light accent on the
|
|
9929
|
+
panel is 3.9:1, under the 4.5:1 small text needs. */
|
|
9877
9930
|
.ss-w-dash--goal .ss-w-dash-grid { grid-template-columns: 1fr; }
|
|
9878
|
-
.ss-w-dash--goal .ss-w-dash-tile {
|
|
9931
|
+
.ss-w-dash--goal .ss-w-dash-tile { gap: 12px; min-height: 60px; padding: 8px 12px 8px 14px; border-radius: 8px; }
|
|
9932
|
+
.ss-w-dash--goal .ss-w-dash-tile:hover { background: var(--ss-w-bubble); }
|
|
9933
|
+
.ss-w-dash--goal .ss-w-dash-tile-icon { width: 24px; height: 24px; font-size: 20px; }
|
|
9934
|
+
.ss-w-dash--goal .ss-w-dash-tile-body { gap: 1px; }
|
|
9935
|
+
.ss-w-dash--goal .ss-w-dash-tile-title { font-size: 15px; line-height: 1.25; }
|
|
9936
|
+
.ss-w-dash--goal .ss-w-dash-tile-subtitle { font-size: 13px; line-height: 1.3; overflow-wrap: break-word; }
|
|
9937
|
+
.ss-w-dash-tile-value {
|
|
9938
|
+
flex: none; margin-left: auto; max-width: 40%; text-align: right;
|
|
9939
|
+
font-size: 16px; font-weight: 700; line-height: 1.2; font-variant-numeric: tabular-nums;
|
|
9940
|
+
color: color-mix(in srgb, var(--ss-w-accent) 70%, var(--ss-w-ink));
|
|
9941
|
+
}
|
|
9879
9942
|
|
|
9880
9943
|
/* Discovery: tinted bento cards. Stacked (icon over text) so a two- or three-word title gets
|
|
9881
9944
|
the tile's full width instead of the ~100px left of a horizontal icon+chevron -- that narrow
|