@sensiblestats/widget-react 0.10.1 → 0.12.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 +24 -0
- package/dist/index.cjs +142 -92
- 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 +142 -92
- package/dist/index.js.map +1 -1
- package/dist/styles.css +9 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -24,6 +24,9 @@ var STRINGS = {
|
|
|
24
24
|
marketPrices: "Market prices",
|
|
25
25
|
moreLines: "More lines",
|
|
26
26
|
hideLines: "Hide lines",
|
|
27
|
+
oddsMoved: (was, now, direction) => `was ${was}, now ${now}, ${direction}`,
|
|
28
|
+
oddsShortened: "shortened",
|
|
29
|
+
oddsDrifted: "drifted",
|
|
27
30
|
updatedLabel: "updated",
|
|
28
31
|
inSlip: "In slip",
|
|
29
32
|
slipAdded: (n) => n === void 0 ? "Added to slip" : `Added to slip (${n} selection${n === 1 ? "" : "s"})`,
|
|
@@ -54,6 +57,9 @@ var STRINGS = {
|
|
|
54
57
|
marketPrices: "Piyasa fiyatlar\u0131",
|
|
55
58
|
moreLines: "Di\u011Fer \xE7izgiler",
|
|
56
59
|
hideLines: "\xC7izgileri gizle",
|
|
60
|
+
oddsMoved: (was, now, direction) => `\xF6nce ${was}, \u015Fimdi ${now}, ${direction}`,
|
|
61
|
+
oddsShortened: "d\xFC\u015Ft\xFC",
|
|
62
|
+
oddsDrifted: "y\xFCkseldi",
|
|
57
63
|
updatedLabel: "g\xFCncellendi",
|
|
58
64
|
inSlip: "Kuponda",
|
|
59
65
|
slipAdded: (n) => n === void 0 ? "Kupona eklendi" : `Kupona eklendi (${n} se\xE7im)`,
|
|
@@ -100,6 +106,9 @@ function normalizeUi(cfg) {
|
|
|
100
106
|
marketPrices: strings.marketPrices,
|
|
101
107
|
moreLines: strings.moreLines,
|
|
102
108
|
hideLines: strings.hideLines,
|
|
109
|
+
oddsMoved: strings.oddsMoved,
|
|
110
|
+
oddsShortened: strings.oddsShortened,
|
|
111
|
+
oddsDrifted: strings.oddsDrifted,
|
|
103
112
|
updatedLabel: strings.updatedLabel,
|
|
104
113
|
addToSlip: strings.addToSlip,
|
|
105
114
|
inSlip: strings.inSlip,
|
|
@@ -204,6 +213,9 @@ function toInsightVM(insight) {
|
|
|
204
213
|
const fixture = home && away ? `${home} vs ${away}` : void 0;
|
|
205
214
|
const competition = str(insight.competitionName);
|
|
206
215
|
const scopes = Array.isArray(insight.scopes) ? insight.scopes.map((s) => ({ key: str(s.key), label: str(s.label), stats: readStatCells(s.stats) })).filter((s) => !!s.key && !!s.label) : void 0;
|
|
216
|
+
const previousValue = insight.odds?.previousValue;
|
|
217
|
+
const previous = typeof previousValue === "number" && Number.isFinite(previousValue) ? previousValue : void 0;
|
|
218
|
+
const direction = insight.odds?.movementDirection === "shortened" || insight.odds?.movementDirection === "drifted" ? insight.odds.movementDirection : void 0;
|
|
207
219
|
return {
|
|
208
220
|
id: str(insight.insightId) ?? `${str(insight.ruleId) ?? "insight"}:${num(insight.matchId) ?? ""}`,
|
|
209
221
|
market,
|
|
@@ -223,7 +235,9 @@ function toInsightVM(insight) {
|
|
|
223
235
|
matchOddsId,
|
|
224
236
|
addToSlipEnabled: insight.addToSlipEnabled === true,
|
|
225
237
|
oddsDecimal: typeof oddsValue === "number" && Number.isFinite(oddsValue) ? oddsValue : void 0,
|
|
226
|
-
quotedAtUtc: str(insight.odds?.quotedAtUtc)
|
|
238
|
+
quotedAtUtc: str(insight.odds?.quotedAtUtc),
|
|
239
|
+
previousOdds: previous !== void 0 && direction !== void 0 ? previous.toFixed(2) : void 0,
|
|
240
|
+
movementDirection: previous !== void 0 && direction !== void 0 ? direction : void 0
|
|
227
241
|
};
|
|
228
242
|
}
|
|
229
243
|
function toSlipSelection(vm, conversationId) {
|
|
@@ -243,6 +257,8 @@ function toMarketOddsVM(card) {
|
|
|
243
257
|
const toRow = (r, i) => {
|
|
244
258
|
const selection = [str(r.selectionLabel), str(r.line)].filter(Boolean).join(" ");
|
|
245
259
|
const price = typeof r.price === "number" && Number.isFinite(r.price) ? r.price : void 0;
|
|
260
|
+
const previous = typeof r.previousPrice === "number" && Number.isFinite(r.previousPrice) ? r.previousPrice : void 0;
|
|
261
|
+
const direction = r.movementDirection === "shortened" || r.movementDirection === "drifted" ? r.movementDirection : void 0;
|
|
246
262
|
return {
|
|
247
263
|
key: `${selection}:${str(r.line) ?? ""}:${i}`,
|
|
248
264
|
selection,
|
|
@@ -250,7 +266,9 @@ function toMarketOddsVM(card) {
|
|
|
250
266
|
oddsDecimal: price,
|
|
251
267
|
matchOddsId: typeof r.matchOddsId === "number" ? r.matchOddsId : void 0,
|
|
252
268
|
quotedAtUtc: str(r.quotedAtUtc),
|
|
253
|
-
isMain: r.isMainLine !== false
|
|
269
|
+
isMain: r.isMainLine !== false,
|
|
270
|
+
previousOdds: previous !== void 0 && direction !== void 0 ? previous.toFixed(2) : void 0,
|
|
271
|
+
movementDirection: previous !== void 0 && direction !== void 0 ? direction : void 0
|
|
254
272
|
};
|
|
255
273
|
};
|
|
256
274
|
const vms = rows.map(toRow).filter((r) => r.selection && r.odds);
|
|
@@ -708,20 +726,41 @@ function AddToSlipButton({ it, slip, ui }) {
|
|
|
708
726
|
return /* @__PURE__ */ jsx8(SlipButton, { selection, shownOdds: it.odds ?? "", marketName: it.market, slip, ui });
|
|
709
727
|
}
|
|
710
728
|
|
|
711
|
-
// src/components/
|
|
729
|
+
// src/components/OddsMovementBadge.tsx
|
|
712
730
|
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
731
|
+
function OddsMovementBadge({
|
|
732
|
+
previous,
|
|
733
|
+
current,
|
|
734
|
+
direction,
|
|
735
|
+
ui
|
|
736
|
+
}) {
|
|
737
|
+
if (previous === void 0 || direction === void 0) return null;
|
|
738
|
+
const directionWord = direction === "shortened" ? ui?.oddsShortened ?? "shortened" : ui?.oddsDrifted ?? "drifted";
|
|
739
|
+
const label = ui?.oddsMoved?.(previous, current, directionWord) ?? `was ${previous}, now ${current}, ${directionWord}`;
|
|
740
|
+
return (
|
|
741
|
+
// Strikethrough is invisible to screen readers, so the whole was/now/direction sentence rides
|
|
742
|
+
// on one aria-label and the visual glyphs are hidden from the accessibility tree.
|
|
743
|
+
/* @__PURE__ */ jsxs6("span", { className: "ss-w-move", role: "img", "aria-label": label, children: [
|
|
744
|
+
/* @__PURE__ */ jsx9("span", { className: "ss-w-move-prev", "aria-hidden": "true", children: previous }),
|
|
745
|
+
/* @__PURE__ */ jsx9("span", { className: "ss-w-move-arrow", "aria-hidden": "true", children: direction === "shortened" ? "\u25BC" : "\u25B2" })
|
|
746
|
+
] })
|
|
747
|
+
);
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
// src/components/BettingInsightList.tsx
|
|
751
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
713
752
|
function StatRows2({ stats }) {
|
|
714
|
-
return /* @__PURE__ */
|
|
715
|
-
/* @__PURE__ */
|
|
716
|
-
/* @__PURE__ */
|
|
753
|
+
return /* @__PURE__ */ jsx10("div", { className: "ss-w-bi-rows", children: stats.map((s) => /* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-row", children: [
|
|
754
|
+
/* @__PURE__ */ jsx10("span", { className: "ss-w-bi-row-lbl", children: s.label }),
|
|
755
|
+
/* @__PURE__ */ jsx10("span", { className: "ss-w-bi-row-num", children: s.value })
|
|
717
756
|
] }, `${s.label}:${s.value}`)) });
|
|
718
757
|
}
|
|
719
758
|
function ScopedStats({ scopes }) {
|
|
720
759
|
const [active, setActive] = useState3(0);
|
|
721
760
|
const current = scopes[active] ?? scopes[0] ?? { key: "", label: "", stats: [] };
|
|
722
|
-
return /* @__PURE__ */
|
|
723
|
-
/* @__PURE__ */
|
|
724
|
-
/* @__PURE__ */
|
|
761
|
+
return /* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-scoped", children: [
|
|
762
|
+
/* @__PURE__ */ jsx10("div", { className: "ss-w-bi-scopes", role: "group", children: scopes.map((s, i) => /* @__PURE__ */ jsx10("button", { type: "button", className: "ss-w-bi-chip", "aria-pressed": i === active, onClick: () => setActive(i), children: s.label }, s.key)) }),
|
|
763
|
+
/* @__PURE__ */ jsx10(StatRows2, { stats: current.stats }, current.key)
|
|
725
764
|
] });
|
|
726
765
|
}
|
|
727
766
|
function StatsDisclosure({ it, ui }) {
|
|
@@ -729,8 +768,8 @@ function StatsDisclosure({ it, ui }) {
|
|
|
729
768
|
const hasScopes = !!it.scopes && it.scopes.length >= 2;
|
|
730
769
|
const hasStats = hasScopes || it.stats.length > 0;
|
|
731
770
|
if (!hasStats) return null;
|
|
732
|
-
return /* @__PURE__ */
|
|
733
|
-
/* @__PURE__ */
|
|
771
|
+
return /* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-stats", children: [
|
|
772
|
+
/* @__PURE__ */ jsxs7(
|
|
734
773
|
"button",
|
|
735
774
|
{
|
|
736
775
|
type: "button",
|
|
@@ -738,121 +777,123 @@ function StatsDisclosure({ it, ui }) {
|
|
|
738
777
|
"aria-expanded": open,
|
|
739
778
|
onClick: () => setOpen((v) => !v),
|
|
740
779
|
children: [
|
|
741
|
-
/* @__PURE__ */
|
|
742
|
-
/* @__PURE__ */
|
|
780
|
+
/* @__PURE__ */ jsx10("span", { children: open ? ui?.hideStats ?? "Hide stats" : ui?.showStats ?? "Show stats" }),
|
|
781
|
+
/* @__PURE__ */ jsx10("span", { className: `ss-w-bi-chev${open ? " ss-w-bi-chev-up" : ""}`, "aria-hidden": "true" })
|
|
743
782
|
]
|
|
744
783
|
}
|
|
745
784
|
),
|
|
746
|
-
open ? hasScopes ? /* @__PURE__ */
|
|
785
|
+
open ? hasScopes ? /* @__PURE__ */ jsx10(ScopedStats, { scopes: it.scopes }) : /* @__PURE__ */ jsx10(StatRows2, { stats: it.stats }) : null
|
|
747
786
|
] });
|
|
748
787
|
}
|
|
749
788
|
function InsightCard({ it, ui, slip }) {
|
|
750
789
|
const live = it.isLive || it.phase === "live";
|
|
751
|
-
return /* @__PURE__ */
|
|
752
|
-
live ? /* @__PURE__ */
|
|
753
|
-
/* @__PURE__ */
|
|
790
|
+
return /* @__PURE__ */ jsxs7("div", { className: "ss-w-binsight", children: [
|
|
791
|
+
live ? /* @__PURE__ */ jsx10("div", { className: "ss-w-bi-status", children: /* @__PURE__ */ jsxs7("span", { className: "ss-w-bi-live", children: [
|
|
792
|
+
/* @__PURE__ */ jsx10("span", { className: "ss-w-bi-live-dot", "aria-hidden": "true" }),
|
|
754
793
|
ui?.liveLabel ?? "Live"
|
|
755
794
|
] }) }) : null,
|
|
756
|
-
/* @__PURE__ */
|
|
757
|
-
/* @__PURE__ */
|
|
758
|
-
/* @__PURE__ */
|
|
759
|
-
it.selection ? /* @__PURE__ */
|
|
760
|
-
it.fixture || it.competition ? /* @__PURE__ */
|
|
761
|
-
it.fixture ? /* @__PURE__ */
|
|
762
|
-
it.competition ? /* @__PURE__ */
|
|
795
|
+
/* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-head", children: [
|
|
796
|
+
/* @__PURE__ */ jsxs7("span", { className: "ss-w-bi-mkt", children: [
|
|
797
|
+
/* @__PURE__ */ jsx10("span", { className: "ss-w-bi-market", children: it.market }),
|
|
798
|
+
it.selection ? /* @__PURE__ */ jsx10("span", { className: "ss-w-bi-sel", children: it.selection }) : null,
|
|
799
|
+
it.fixture || it.competition ? /* @__PURE__ */ jsxs7("span", { className: "ss-w-bi-match", children: [
|
|
800
|
+
it.fixture ? /* @__PURE__ */ jsx10("span", { className: "ss-w-bi-fixture", children: it.fixture }) : null,
|
|
801
|
+
it.competition ? /* @__PURE__ */ jsx10("span", { className: "ss-w-bi-comp", children: it.competition }) : null
|
|
763
802
|
] }) : null
|
|
764
803
|
] }),
|
|
765
|
-
/* @__PURE__ */
|
|
766
|
-
it.odds ? /* @__PURE__ */
|
|
767
|
-
/* @__PURE__ */
|
|
768
|
-
/* @__PURE__ */
|
|
769
|
-
|
|
804
|
+
/* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-action", children: [
|
|
805
|
+
it.odds ? /* @__PURE__ */ jsxs7("span", { className: "ss-w-bi-odds", children: [
|
|
806
|
+
/* @__PURE__ */ jsx10("span", { className: "ss-w-bi-odds-cap", children: ui?.oddsLabel ?? "Odds" }),
|
|
807
|
+
/* @__PURE__ */ jsx10("b", { children: it.odds }),
|
|
808
|
+
/* @__PURE__ */ jsx10(OddsMovementBadge, { previous: it.previousOdds, current: it.odds, direction: it.movementDirection, ui }),
|
|
809
|
+
it.bookmaker ? /* @__PURE__ */ jsx10("span", { className: "ss-w-bi-book", children: it.bookmaker }) : null
|
|
770
810
|
] }) : null,
|
|
771
|
-
/* @__PURE__ */
|
|
811
|
+
/* @__PURE__ */ jsx10(AddToSlipButton, { it, slip, ui })
|
|
772
812
|
] })
|
|
773
813
|
] }),
|
|
774
|
-
it.text ? /* @__PURE__ */
|
|
775
|
-
/* @__PURE__ */
|
|
776
|
-
it.disclaimer ? /* @__PURE__ */
|
|
814
|
+
it.text ? /* @__PURE__ */ jsx10("p", { className: "ss-w-bi-text", children: it.text }) : null,
|
|
815
|
+
/* @__PURE__ */ jsx10(StatsDisclosure, { it, ui }),
|
|
816
|
+
it.disclaimer ? /* @__PURE__ */ jsx10("p", { className: "ss-w-bi-disc", children: it.disclaimer }) : null
|
|
777
817
|
] });
|
|
778
818
|
}
|
|
779
819
|
function BettingInsightList({ insights, ui, slip }) {
|
|
780
820
|
if (!insights || insights.length === 0) return null;
|
|
781
|
-
return /* @__PURE__ */
|
|
821
|
+
return /* @__PURE__ */ jsx10("div", { className: "ss-w-binsights", children: insights.map((it) => /* @__PURE__ */ jsx10(InsightCard, { it, ui, slip }, it.id)) });
|
|
782
822
|
}
|
|
783
823
|
|
|
784
824
|
// src/components/MarketOddsCardList.tsx
|
|
785
825
|
import { useState as useState4 } from "react";
|
|
786
|
-
import { jsx as
|
|
826
|
+
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
787
827
|
function OddsRow({ vm, row, ui, slip }) {
|
|
788
828
|
const selection = vm.addToSlipEnabled ? marketOddsRowToSlipSelection(vm, row, slip.conversationId) : null;
|
|
789
|
-
return /* @__PURE__ */
|
|
790
|
-
/* @__PURE__ */
|
|
791
|
-
/* @__PURE__ */
|
|
792
|
-
/* @__PURE__ */
|
|
829
|
+
return /* @__PURE__ */ jsxs8("div", { className: "ss-w-mo-row", children: [
|
|
830
|
+
/* @__PURE__ */ jsx11("span", { className: "ss-w-mo-sel", children: row.selection }),
|
|
831
|
+
/* @__PURE__ */ jsx11(OddsMovementBadge, { previous: row.previousOdds, current: row.odds, direction: row.movementDirection, ui }),
|
|
832
|
+
/* @__PURE__ */ jsx11("span", { className: "ss-w-mo-price", children: row.odds }),
|
|
833
|
+
/* @__PURE__ */ jsx11(SlipButton, { selection, shownOdds: row.odds, marketName: vm.market, slip, ui })
|
|
793
834
|
] });
|
|
794
835
|
}
|
|
795
836
|
function MarketOddsCard({ vm, ui, slip }) {
|
|
796
837
|
const [open, setOpen] = useState4(false);
|
|
797
|
-
return /* @__PURE__ */
|
|
798
|
-
/* @__PURE__ */
|
|
799
|
-
/* @__PURE__ */
|
|
800
|
-
/* @__PURE__ */
|
|
838
|
+
return /* @__PURE__ */ jsxs8("div", { className: "ss-w-mocard", children: [
|
|
839
|
+
/* @__PURE__ */ jsxs8("div", { className: "ss-w-mo-head", children: [
|
|
840
|
+
/* @__PURE__ */ jsx11("span", { className: "ss-w-mo-market", children: vm.market }),
|
|
841
|
+
/* @__PURE__ */ jsx11("span", { className: "ss-w-mo-tag", children: ui?.marketPrices ?? "Market prices" })
|
|
801
842
|
] }),
|
|
802
|
-
vm.fixture || vm.competition ? /* @__PURE__ */
|
|
803
|
-
vm.fixture ? /* @__PURE__ */
|
|
804
|
-
vm.competition ? /* @__PURE__ */
|
|
843
|
+
vm.fixture || vm.competition ? /* @__PURE__ */ jsxs8("div", { className: "ss-w-mo-fixture", children: [
|
|
844
|
+
vm.fixture ? /* @__PURE__ */ jsx11("span", { children: vm.fixture }) : null,
|
|
845
|
+
vm.competition ? /* @__PURE__ */ jsx11("span", { className: "ss-w-mo-comp", children: vm.competition }) : null
|
|
805
846
|
] }) : null,
|
|
806
|
-
/* @__PURE__ */
|
|
807
|
-
vm.mainRows.map((row) => /* @__PURE__ */
|
|
808
|
-
open ? vm.moreRows.map((row) => /* @__PURE__ */
|
|
847
|
+
/* @__PURE__ */ jsxs8("div", { className: "ss-w-mo-rows", children: [
|
|
848
|
+
vm.mainRows.map((row) => /* @__PURE__ */ jsx11(OddsRow, { vm, row, ui, slip }, row.key)),
|
|
849
|
+
open ? vm.moreRows.map((row) => /* @__PURE__ */ jsx11(OddsRow, { vm, row, ui, slip }, row.key)) : null
|
|
809
850
|
] }),
|
|
810
|
-
vm.moreRows.length > 0 ? /* @__PURE__ */
|
|
811
|
-
/* @__PURE__ */
|
|
812
|
-
/* @__PURE__ */
|
|
851
|
+
vm.moreRows.length > 0 ? /* @__PURE__ */ jsxs8("button", { type: "button", className: "ss-w-bi-toggle", "aria-expanded": open, onClick: () => setOpen((v) => !v), children: [
|
|
852
|
+
/* @__PURE__ */ jsx11("span", { children: open ? ui?.hideLines ?? "Hide lines" : `${ui?.moreLines ?? "More lines"} (${vm.moreRows.length})` }),
|
|
853
|
+
/* @__PURE__ */ jsx11("span", { className: `ss-w-bi-chev${open ? " ss-w-bi-chev-up" : ""}`, "aria-hidden": "true" })
|
|
813
854
|
] }) : null,
|
|
814
|
-
vm.bookmaker ? /* @__PURE__ */
|
|
815
|
-
vm.disclaimer ? /* @__PURE__ */
|
|
855
|
+
vm.bookmaker ? /* @__PURE__ */ jsx11("div", { className: "ss-w-mo-foot", children: /* @__PURE__ */ jsx11("span", { children: vm.bookmaker }) }) : null,
|
|
856
|
+
vm.disclaimer ? /* @__PURE__ */ jsx11("p", { className: "ss-w-bi-disc", children: vm.disclaimer }) : null
|
|
816
857
|
] });
|
|
817
858
|
}
|
|
818
859
|
function MarketOddsCardList({ cards, ui, slip }) {
|
|
819
860
|
if (!cards || cards.length === 0) return null;
|
|
820
|
-
return /* @__PURE__ */
|
|
861
|
+
return /* @__PURE__ */ jsx11("div", { className: "ss-w-mocards", children: cards.map((vm) => /* @__PURE__ */ jsx11(MarketOddsCard, { vm, ui, slip }, vm.id)) });
|
|
821
862
|
}
|
|
822
863
|
|
|
823
864
|
// src/components/ActionButtons.tsx
|
|
824
|
-
import { Fragment, jsx as
|
|
865
|
+
import { Fragment, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
825
866
|
function ActionButtons({ actions, loading, disabled, onAct }) {
|
|
826
867
|
if (actions.length === 0 && !loading) return null;
|
|
827
|
-
return /* @__PURE__ */
|
|
828
|
-
actions.map((a, i) => /* @__PURE__ */
|
|
829
|
-
actions.length === 0 && loading ? /* @__PURE__ */
|
|
830
|
-
/* @__PURE__ */
|
|
831
|
-
/* @__PURE__ */
|
|
868
|
+
return /* @__PURE__ */ jsxs9("div", { className: "ss-w-actions", children: [
|
|
869
|
+
actions.map((a, i) => /* @__PURE__ */ jsx12("button", { type: "button", className: "ss-w-abtn", disabled, onClick: () => onAct(a), children: a.label }, `${a.label}-${i}`)),
|
|
870
|
+
actions.length === 0 && loading ? /* @__PURE__ */ jsxs9(Fragment, { children: [
|
|
871
|
+
/* @__PURE__ */ jsx12("span", { className: "ss-w-abtn-shimmer" }),
|
|
872
|
+
/* @__PURE__ */ jsx12("span", { className: "ss-w-abtn-shimmer" })
|
|
832
873
|
] }) : null
|
|
833
874
|
] });
|
|
834
875
|
}
|
|
835
876
|
|
|
836
877
|
// src/components/ChatMessage.tsx
|
|
837
|
-
import { jsx as
|
|
878
|
+
import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
838
879
|
function ChatMessage({ message, disabled, onAct, ui, slip }) {
|
|
839
880
|
if (message.role === "user") {
|
|
840
|
-
return /* @__PURE__ */
|
|
881
|
+
return /* @__PURE__ */ jsx13("div", { className: "ss-w-msg ss-w-user", children: /* @__PURE__ */ jsx13("div", { className: "ss-w-bubble", children: message.text }) });
|
|
841
882
|
}
|
|
842
|
-
return /* @__PURE__ */
|
|
843
|
-
message.text ? /* @__PURE__ */
|
|
844
|
-
/* @__PURE__ */
|
|
845
|
-
/* @__PURE__ */
|
|
846
|
-
/* @__PURE__ */
|
|
847
|
-
/* @__PURE__ */
|
|
883
|
+
return /* @__PURE__ */ jsxs10("div", { className: "ss-w-msg ss-w-bot", children: [
|
|
884
|
+
message.text ? /* @__PURE__ */ jsx13(Markdown, { text: message.text }) : null,
|
|
885
|
+
/* @__PURE__ */ jsx13(EntityCardList, { cards: message.cards, disabled, showLessLabel: ui?.showLess, showMoreLabel: ui?.showMore }),
|
|
886
|
+
/* @__PURE__ */ jsx13(BettingInsightList, { insights: message.insights, ui, slip }),
|
|
887
|
+
/* @__PURE__ */ jsx13(MarketOddsCardList, { cards: message.marketOdds, ui, slip }),
|
|
888
|
+
/* @__PURE__ */ jsx13(ActionButtons, { actions: message.actions, loading: false, disabled, onAct })
|
|
848
889
|
] });
|
|
849
890
|
}
|
|
850
891
|
|
|
851
892
|
// src/components/IntentChips.tsx
|
|
852
|
-
import { jsx as
|
|
893
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
853
894
|
function IntentChips({ chips, onPick }) {
|
|
854
895
|
if (chips.length === 0) return null;
|
|
855
|
-
return /* @__PURE__ */
|
|
896
|
+
return /* @__PURE__ */ jsx14("div", { className: "ss-w-chips", children: chips.map((c, i) => /* @__PURE__ */ jsx14("button", { type: "button", className: "ss-w-chip", onClick: () => onPick(c.text), children: c.text }, `${c.text}-${i}`)) });
|
|
856
897
|
}
|
|
857
898
|
|
|
858
899
|
// src/scroll.ts
|
|
@@ -862,7 +903,7 @@ function isPinnedToBottom(el, threshold = PIN_THRESHOLD) {
|
|
|
862
903
|
}
|
|
863
904
|
|
|
864
905
|
// src/components/MessageList.tsx
|
|
865
|
-
import { jsx as
|
|
906
|
+
import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
866
907
|
function MessageList({ controller, ui, slip }) {
|
|
867
908
|
const { state, send } = controller;
|
|
868
909
|
const listRef = useRef2(null);
|
|
@@ -872,7 +913,7 @@ function MessageList({ controller, ui, slip }) {
|
|
|
872
913
|
if (pinnedRef.current) endRef.current?.scrollIntoView({ block: "end" });
|
|
873
914
|
}, [state.messages, state.status]);
|
|
874
915
|
const empty = state.messages.length === 0;
|
|
875
|
-
return /* @__PURE__ */
|
|
916
|
+
return /* @__PURE__ */ jsxs11(
|
|
876
917
|
"div",
|
|
877
918
|
{
|
|
878
919
|
className: "ss-w-list",
|
|
@@ -882,7 +923,7 @@ function MessageList({ controller, ui, slip }) {
|
|
|
882
923
|
if (listRef.current) pinnedRef.current = isPinnedToBottom(listRef.current);
|
|
883
924
|
},
|
|
884
925
|
children: [
|
|
885
|
-
state.messages.map((m) => /* @__PURE__ */
|
|
926
|
+
state.messages.map((m) => /* @__PURE__ */ jsx15(
|
|
886
927
|
ChatMessage,
|
|
887
928
|
{
|
|
888
929
|
message: m,
|
|
@@ -893,15 +934,15 @@ function MessageList({ controller, ui, slip }) {
|
|
|
893
934
|
},
|
|
894
935
|
m.id
|
|
895
936
|
)),
|
|
896
|
-
state.isStreaming && state.actionsLoading ? /* @__PURE__ */
|
|
937
|
+
state.isStreaming && state.actionsLoading ? /* @__PURE__ */ jsx15(ActionButtons, { actions: [], loading: true, onAct: () => {
|
|
897
938
|
} }) : null,
|
|
898
|
-
state.status ? /* @__PURE__ */
|
|
899
|
-
state.error ? /* @__PURE__ */
|
|
900
|
-
/* @__PURE__ */
|
|
901
|
-
/* @__PURE__ */
|
|
939
|
+
state.status ? /* @__PURE__ */ jsx15("div", { className: "ss-w-status", children: state.status }) : null,
|
|
940
|
+
state.error ? /* @__PURE__ */ jsxs11("div", { className: "ss-w-error", role: "alert", children: [
|
|
941
|
+
/* @__PURE__ */ jsx15("span", { children: "message" in state.error ? state.error.message : ui.somethingWentWrong }),
|
|
942
|
+
/* @__PURE__ */ jsx15("button", { type: "button", className: "ss-w-retry", onClick: () => controller.retry(), children: ui.retry })
|
|
902
943
|
] }) : null,
|
|
903
|
-
empty ? /* @__PURE__ */
|
|
904
|
-
/* @__PURE__ */
|
|
944
|
+
empty ? /* @__PURE__ */ jsx15(IntentChips, { chips: state.starters, onPick: (t) => send(t) }) : null,
|
|
945
|
+
/* @__PURE__ */ jsx15("div", { ref: endRef })
|
|
905
946
|
]
|
|
906
947
|
}
|
|
907
948
|
);
|
|
@@ -909,7 +950,7 @@ function MessageList({ controller, ui, slip }) {
|
|
|
909
950
|
|
|
910
951
|
// src/components/ChatInput.tsx
|
|
911
952
|
import { useState as useState5 } from "react";
|
|
912
|
-
import { jsx as
|
|
953
|
+
import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
913
954
|
function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop response", sendLabel = "Send message" }) {
|
|
914
955
|
const [value, setValue] = useState5("");
|
|
915
956
|
const submit = () => {
|
|
@@ -924,14 +965,14 @@ function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop r
|
|
|
924
965
|
submit();
|
|
925
966
|
}
|
|
926
967
|
};
|
|
927
|
-
return /* @__PURE__ */
|
|
928
|
-
/* @__PURE__ */
|
|
929
|
-
streaming ? /* @__PURE__ */
|
|
968
|
+
return /* @__PURE__ */ jsxs12("div", { className: "ss-w-input", children: [
|
|
969
|
+
/* @__PURE__ */ jsx16("textarea", { className: "ss-w-textarea", rows: 1, placeholder, value, disabled: streaming, onChange: (e) => setValue(e.target.value), onKeyDown }),
|
|
970
|
+
streaming ? /* @__PURE__ */ jsx16("button", { type: "button", className: "ss-w-send ss-w-stop", "aria-label": stopLabel, onClick: onStop, children: /* @__PURE__ */ jsx16("span", { className: "ss-w-stop-glyph" }) }) : /* @__PURE__ */ jsx16("button", { type: "button", className: "ss-w-send", "aria-label": sendLabel, onClick: submit, children: /* @__PURE__ */ jsx16(SendIcon, {}) })
|
|
930
971
|
] });
|
|
931
972
|
}
|
|
932
973
|
|
|
933
974
|
// src/components/ChatPanel.tsx
|
|
934
|
-
import { jsx as
|
|
975
|
+
import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
935
976
|
var FULLSCREEN_QUERY = "(max-width: 639px)";
|
|
936
977
|
function useIsModal() {
|
|
937
978
|
const [modal, setModal] = useState6(false);
|
|
@@ -955,10 +996,10 @@ function ChatPanel({ controller, ui, slip }) {
|
|
|
955
996
|
window.addEventListener("keydown", onKey);
|
|
956
997
|
return () => window.removeEventListener("keydown", onKey);
|
|
957
998
|
}, [close]);
|
|
958
|
-
return /* @__PURE__ */
|
|
959
|
-
/* @__PURE__ */
|
|
960
|
-
/* @__PURE__ */
|
|
961
|
-
/* @__PURE__ */
|
|
999
|
+
return /* @__PURE__ */ jsxs13("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
|
|
1000
|
+
/* @__PURE__ */ jsx17(ChatHeader, { onClose: close, closeLabel: ui.closeChat }),
|
|
1001
|
+
/* @__PURE__ */ jsx17(MessageList, { controller, ui, slip }),
|
|
1002
|
+
/* @__PURE__ */ jsx17(ChatInput, { placeholder: ui.placeholder, streaming: state.isStreaming, onSend: (t) => send(t), onStop: stop, stopLabel: ui.stopResponse, sendLabel: ui.sendMessage })
|
|
962
1003
|
] });
|
|
963
1004
|
}
|
|
964
1005
|
|
|
@@ -1145,6 +1186,15 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
1145
1186
|
.ss-w-mo-row:last-child { border-bottom: none; }
|
|
1146
1187
|
.ss-w-mo-sel { font-size: 12.5px; font-weight: 600; color: var(--ss-w-ink); }
|
|
1147
1188
|
.ss-w-mo-price { margin-left: auto; font-family: ui-monospace, monospace; font-variant-numeric: tabular-nums; font-size: 14px; font-weight: 700; color: var(--ss-w-accent); }
|
|
1189
|
+
/* Movement: BOTH directions share --ss-w-faint on purpose. Green-good/red-bad would frame a
|
|
1190
|
+
shortening price as a discount, which inverts what it actually means for the bettor. */
|
|
1191
|
+
.ss-w-move { display: inline-flex; align-items: baseline; gap: 4px; color: var(--ss-w-faint); }
|
|
1192
|
+
.ss-w-move-prev { font-family: ui-monospace, monospace; font-variant-numeric: tabular-nums; font-size: 12px; text-decoration: line-through; }
|
|
1193
|
+
.ss-w-move-arrow { font-size: 9px; line-height: 1; }
|
|
1194
|
+
/* margin-left:auto is row layout, not badge styling -- it belongs to the market-odds row, which is
|
|
1195
|
+
a flex row, and must NOT follow the badge into the insight card's odds column. */
|
|
1196
|
+
.ss-w-mo-row .ss-w-move { margin-left: auto; }
|
|
1197
|
+
.ss-w-mo-row .ss-w-move + .ss-w-mo-price { margin-left: 0; }
|
|
1148
1198
|
.ss-w-mo-row .ss-w-slip { margin: 0; }
|
|
1149
1199
|
.ss-w-mo-foot { display: flex; align-items: center; gap: 8px; font-size: 10.5px; color: var(--ss-w-faint); }
|
|
1150
1200
|
|
|
@@ -1185,7 +1235,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
1185
1235
|
`;
|
|
1186
1236
|
|
|
1187
1237
|
// src/StatsWidget.tsx
|
|
1188
|
-
import { jsx as
|
|
1238
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
1189
1239
|
function buildClient(props) {
|
|
1190
1240
|
try {
|
|
1191
1241
|
if ("client" in props && props.client) {
|
|
@@ -1234,7 +1284,7 @@ function StatsWidget(props) {
|
|
|
1234
1284
|
}, [built, ui.injectStyles]);
|
|
1235
1285
|
if (!built) return null;
|
|
1236
1286
|
const attrs = themeAttrs(ui);
|
|
1237
|
-
return /* @__PURE__ */
|
|
1287
|
+
return /* @__PURE__ */ jsx18("div", { ref: rootRef, className: "ss-w-root", "data-ss-w-theme": attrs["data-ss-w-theme"], "data-ss-w-pos": attrs["data-ss-w-pos"], style: attrs.style, children: controller.state.isOpen ? /* @__PURE__ */ jsx18(ChatPanel, { controller, ui, slip }) : /* @__PURE__ */ jsx18(
|
|
1238
1288
|
ChatFab,
|
|
1239
1289
|
{
|
|
1240
1290
|
label: ui.launcherLabel,
|