@sensiblestats/widget-react 0.23.0 → 0.24.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 +19 -0
- package/dist/index.cjs +160 -49
- 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 +160 -49
- package/dist/index.js.map +1 -1
- package/dist/styles.css +30 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @sensiblestats/widget-react
|
|
2
2
|
|
|
3
|
+
## 0.24.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 04c6e5b: Add post-match club dashboard cards (result, goals, stats, top performer, what's next); the three interactive cards tap through via actionRef.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [04c6e5b]
|
|
12
|
+
- @sensiblestats/widget-sdk@0.22.0
|
|
13
|
+
|
|
14
|
+
## 0.23.1
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- a1d4987: Fan-dashboard fixture and congested-week card taps now send the card's opaque `actionRef` alongside its `actionLabel`, so the server resolves the pre-issued action binding for that card instead of re-planning a prose command.
|
|
19
|
+
- Updated dependencies [a1d4987]
|
|
20
|
+
- @sensiblestats/widget-sdk@0.21.0
|
|
21
|
+
|
|
3
22
|
## 0.23.0
|
|
4
23
|
|
|
5
24
|
### Minor Changes
|
package/dist/index.cjs
CHANGED
|
@@ -359,8 +359,9 @@ function toCardVM(card) {
|
|
|
359
359
|
function toActionVM(action) {
|
|
360
360
|
const label = str(action.actionLabel) ?? str(action.label) ?? str(action.text) ?? str(action.title) ?? "Continue";
|
|
361
361
|
const actionId = str(action.actionId) ?? str(action.id);
|
|
362
|
+
const actionRef = str(action.actionRef);
|
|
362
363
|
const message = str(action.actionValue) ?? str(action.message) ?? str(action.query) ?? label;
|
|
363
|
-
return { label, actionId, message };
|
|
364
|
+
return { label, actionId, actionRef, message };
|
|
364
365
|
}
|
|
365
366
|
function toChipVM(intent) {
|
|
366
367
|
const text = str(intent.text) ?? str(intent.label) ?? str(intent.title);
|
|
@@ -1557,67 +1558,147 @@ function LinksCard({ card }) {
|
|
|
1557
1558
|
] });
|
|
1558
1559
|
}
|
|
1559
1560
|
|
|
1560
|
-
// src/components/dashboard/
|
|
1561
|
+
// src/components/dashboard/PostMatchResultCard.tsx
|
|
1561
1562
|
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
1563
|
+
function PostMatchResultCard({ card }) {
|
|
1564
|
+
const { data } = card;
|
|
1565
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-postmatch-result", children: [
|
|
1566
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
1567
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ss-w-fandash-postmatch-scoreboard", children: [
|
|
1568
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-postmatch-team", children: data.homeName }),
|
|
1569
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-postmatch-score", children: data.homeScore }),
|
|
1570
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-postmatch-sep", children: "\u2013" }),
|
|
1571
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-postmatch-score", children: data.awayScore }),
|
|
1572
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-postmatch-team ss-w-fandash-postmatch-team--away", children: data.awayName })
|
|
1573
|
+
] }),
|
|
1574
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ss-w-fandash-postmatch-meta", children: [
|
|
1575
|
+
data.resultLabel,
|
|
1576
|
+
" \xB7 ",
|
|
1577
|
+
data.kickoffLabel,
|
|
1578
|
+
data.competition ? ` \xB7 ${data.competition}` : ""
|
|
1579
|
+
] })
|
|
1580
|
+
] });
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
// src/components/dashboard/PostMatchGoalsCard.tsx
|
|
1584
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
1585
|
+
function PostMatchGoalsCard({ card, onTap }) {
|
|
1586
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("button", { type: "button", className: "ss-w-fandash-card ss-w-fandash-card--tap ss-w-fandash-postmatch-goals", onClick: () => onTap(card), children: [
|
|
1587
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
1588
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("ul", { className: "ss-w-fandash-postmatch-goal-list", children: card.data.goals.map((g, i) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("li", { className: g.scoredByClub ? "ss-w-fandash-postmatch-goal ss-w-fandash-postmatch-goal--club" : "ss-w-fandash-postmatch-goal", children: g.text }, `${g.text}-${i}`)) }),
|
|
1589
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
|
|
1590
|
+
] });
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1593
|
+
// src/components/dashboard/PostMatchStatsCard.tsx
|
|
1594
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
1595
|
+
function PostMatchStatsCard({ card, onTap }) {
|
|
1596
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("button", { type: "button", className: "ss-w-fandash-card ss-w-fandash-card--tap ss-w-fandash-postmatch-stats", onClick: () => onTap(card), children: [
|
|
1597
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
1598
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "ss-w-fandash-postmatch-stat-rows", children: card.data.rows.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "ss-w-fandash-postmatch-stat-row", children: [
|
|
1599
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-postmatch-stat-value", children: r.clubValue }),
|
|
1600
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-postmatch-stat-label", children: r.label }),
|
|
1601
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-postmatch-stat-value", children: r.oppValue })
|
|
1602
|
+
] }, `${r.label}-${i}`)) }),
|
|
1603
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
|
|
1604
|
+
] });
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
// src/components/dashboard/PostMatchTopPerformerCard.tsx
|
|
1608
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1609
|
+
function PostMatchTopPerformerCard({ card, onTap }) {
|
|
1610
|
+
const { data } = card;
|
|
1611
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("button", { type: "button", className: "ss-w-fandash-card ss-w-fandash-card--tap ss-w-fandash-postmatch-performer", onClick: () => onTap(card), children: [
|
|
1612
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
1613
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "ss-w-fandash-postmatch-performer-row", children: [
|
|
1614
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-postmatch-performer-name", children: data.playerName }),
|
|
1615
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-postmatch-performer-rating", children: data.ratingLabel })
|
|
1616
|
+
] }),
|
|
1617
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
|
|
1618
|
+
] });
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
// src/components/dashboard/PostMatchNextCard.tsx
|
|
1622
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
1623
|
+
function PostMatchNextCard({ card }) {
|
|
1624
|
+
const { data } = card;
|
|
1625
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-postmatch-next", children: [
|
|
1626
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
1627
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "ss-w-fandash-postmatch-next-row", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "ss-w-fandash-postmatch-next-when", children: data.whenLabel }) })
|
|
1628
|
+
] });
|
|
1629
|
+
}
|
|
1630
|
+
|
|
1631
|
+
// src/components/dashboard/ClubFanDashboard.tsx
|
|
1632
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
1562
1633
|
function ClubFanDashboard({ dashboard, onTap, ui }) {
|
|
1563
1634
|
const orderedCards = [
|
|
1564
1635
|
...dashboard.cards.filter((c) => c.cardType === "countdown"),
|
|
1565
1636
|
...dashboard.cards.filter((c) => c.cardType !== "countdown")
|
|
1566
1637
|
];
|
|
1567
|
-
return /* @__PURE__ */ (0,
|
|
1568
|
-
dashboard.greeting ? /* @__PURE__ */ (0,
|
|
1569
|
-
/* @__PURE__ */ (0,
|
|
1638
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "ss-w-fandash", children: [
|
|
1639
|
+
dashboard.greeting ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "ss-w-fandash-greeting", children: dashboard.greeting }) : null,
|
|
1640
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "ss-w-fandash-cards", children: orderedCards.map((card, i) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(FanDashboardCard, { card, onTap, ui }, `${card.cardType}-${i}`)) })
|
|
1570
1641
|
] });
|
|
1571
1642
|
}
|
|
1572
1643
|
function FanDashboardCard({ card, onTap, ui }) {
|
|
1573
1644
|
switch (card.cardType) {
|
|
1574
1645
|
case "fixture":
|
|
1575
|
-
return /* @__PURE__ */ (0,
|
|
1646
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(FixtureCard, { card, onTap });
|
|
1576
1647
|
case "countdown":
|
|
1577
|
-
return /* @__PURE__ */ (0,
|
|
1648
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(CountdownCard, { card });
|
|
1578
1649
|
case "injuries":
|
|
1579
|
-
return /* @__PURE__ */ (0,
|
|
1650
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(InjuriesCard, { card });
|
|
1580
1651
|
case "reasonToBet":
|
|
1581
|
-
return /* @__PURE__ */ (0,
|
|
1652
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ReasonToBetCard, { card });
|
|
1582
1653
|
case "whereToWatch":
|
|
1583
|
-
return /* @__PURE__ */ (0,
|
|
1654
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(WhereToWatchCard, { card });
|
|
1584
1655
|
case "congestedWeek":
|
|
1585
|
-
return /* @__PURE__ */ (0,
|
|
1656
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(CongestedWeekCard, { card, onTap });
|
|
1586
1657
|
case "transfers":
|
|
1587
|
-
return /* @__PURE__ */ (0,
|
|
1658
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TransfersCard, { card });
|
|
1588
1659
|
case "links":
|
|
1589
|
-
return /* @__PURE__ */ (0,
|
|
1660
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(LinksCard, { card });
|
|
1661
|
+
case "postMatchResult":
|
|
1662
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PostMatchResultCard, { card });
|
|
1663
|
+
case "postMatchGoals":
|
|
1664
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PostMatchGoalsCard, { card, onTap });
|
|
1665
|
+
case "postMatchStats":
|
|
1666
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PostMatchStatsCard, { card, onTap });
|
|
1667
|
+
case "postMatchTopPerformer":
|
|
1668
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PostMatchTopPerformerCard, { card, onTap });
|
|
1669
|
+
case "postMatchNext":
|
|
1670
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(PostMatchNextCard, { card });
|
|
1590
1671
|
default:
|
|
1591
1672
|
return null;
|
|
1592
1673
|
}
|
|
1593
1674
|
}
|
|
1594
1675
|
|
|
1595
1676
|
// src/components/ChatMessage.tsx
|
|
1596
|
-
var
|
|
1677
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
1597
1678
|
function ChatMessage({ message, disabled, onAct, onTap, ui, slip }) {
|
|
1598
1679
|
if (message.role === "user") {
|
|
1599
|
-
return /* @__PURE__ */ (0,
|
|
1680
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "ss-w-msg ss-w-user", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "ss-w-bubble", children: message.text }) });
|
|
1600
1681
|
}
|
|
1601
1682
|
const onFanDashboardTap = (card) => {
|
|
1602
|
-
onAct({ message: card.
|
|
1683
|
+
onAct({ message: card.actionLabel, actionRef: card.actionRef, label: card.actionLabel || card.title || "" });
|
|
1603
1684
|
};
|
|
1604
|
-
return /* @__PURE__ */ (0,
|
|
1605
|
-
message.text && !message.greetingDashboard && !message.clubFanDashboard ? /* @__PURE__ */ (0,
|
|
1606
|
-
message.greetingDashboard && !message.clubFanDashboard ? /* @__PURE__ */ (0,
|
|
1607
|
-
message.clubFanDashboard ? /* @__PURE__ */ (0,
|
|
1608
|
-
/* @__PURE__ */ (0,
|
|
1609
|
-
/* @__PURE__ */ (0,
|
|
1610
|
-
/* @__PURE__ */ (0,
|
|
1611
|
-
/* @__PURE__ */ (0,
|
|
1612
|
-
/* @__PURE__ */ (0,
|
|
1685
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "ss-w-msg ss-w-bot", children: [
|
|
1686
|
+
message.text && !message.greetingDashboard && !message.clubFanDashboard ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Markdown, { text: message.text }) : null,
|
|
1687
|
+
message.greetingDashboard && !message.clubFanDashboard ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(GreetingDashboard, { dashboard: message.greetingDashboard, onTap }) : null,
|
|
1688
|
+
message.clubFanDashboard ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ClubFanDashboard, { dashboard: message.clubFanDashboard, onTap: onFanDashboardTap, ui }) : null,
|
|
1689
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(EntityCardList, { cards: message.cards, disabled, showLessLabel: ui?.showLess, showMoreLabel: ui?.showMore }),
|
|
1690
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(BettingInsightList, { insights: message.insights, ui, slip }),
|
|
1691
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MarketOddsCardList, { cards: message.marketOdds, ui, slip }),
|
|
1692
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(OddsMovementCardList, { cards: message.oddsMovement, ui }),
|
|
1693
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ActionButtons, { actions: message.actions, loading: false, disabled, onAct })
|
|
1613
1694
|
] });
|
|
1614
1695
|
}
|
|
1615
1696
|
|
|
1616
1697
|
// src/components/IntentChips.tsx
|
|
1617
|
-
var
|
|
1698
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
1618
1699
|
function IntentChips({ chips, onPick }) {
|
|
1619
1700
|
if (chips.length === 0) return null;
|
|
1620
|
-
return /* @__PURE__ */ (0,
|
|
1701
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "ss-w-chips", children: chips.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("button", { type: "button", className: "ss-w-chip", onClick: () => onPick(c.text), children: c.text }, `${c.text}-${i}`)) });
|
|
1621
1702
|
}
|
|
1622
1703
|
|
|
1623
1704
|
// src/scroll.ts
|
|
@@ -1627,7 +1708,7 @@ function isPinnedToBottom(el, threshold = PIN_THRESHOLD) {
|
|
|
1627
1708
|
}
|
|
1628
1709
|
|
|
1629
1710
|
// src/components/MessageList.tsx
|
|
1630
|
-
var
|
|
1711
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
1631
1712
|
function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
1632
1713
|
const { state, send } = controller;
|
|
1633
1714
|
const listRef = (0, import_react9.useRef)(null);
|
|
@@ -1638,7 +1719,7 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
|
1638
1719
|
}, [state.messages, state.status]);
|
|
1639
1720
|
const hasUserMessage = state.messages.some((m) => m.role === "user");
|
|
1640
1721
|
const hasDashboard = state.messages.some((m) => m.role === "assistant" && (m.greetingDashboard || m.clubFanDashboard));
|
|
1641
|
-
return /* @__PURE__ */ (0,
|
|
1722
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
1642
1723
|
"div",
|
|
1643
1724
|
{
|
|
1644
1725
|
className: "ss-w-list",
|
|
@@ -1648,12 +1729,12 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
|
1648
1729
|
if (listRef.current) pinnedRef.current = isPinnedToBottom(listRef.current);
|
|
1649
1730
|
},
|
|
1650
1731
|
children: [
|
|
1651
|
-
state.messages.map((m) => /* @__PURE__ */ (0,
|
|
1732
|
+
state.messages.map((m) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
1652
1733
|
ChatMessage,
|
|
1653
1734
|
{
|
|
1654
1735
|
message: m,
|
|
1655
1736
|
disabled: state.isStreaming,
|
|
1656
|
-
onAct: (a) => send(a.message, { actionId: a.actionId, displayText: a.label }),
|
|
1737
|
+
onAct: (a) => send(a.message, { actionId: a.actionId, actionRef: a.actionRef, displayText: a.label }),
|
|
1657
1738
|
onTap: (tile, index) => {
|
|
1658
1739
|
send(tile.actionValue, { displayText: tile.title });
|
|
1659
1740
|
if (m.role === "assistant" && m.greetingDashboard) onDashboardTap?.(tile, index, m.greetingDashboard.layout);
|
|
@@ -1663,15 +1744,15 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
|
1663
1744
|
},
|
|
1664
1745
|
m.id
|
|
1665
1746
|
)),
|
|
1666
|
-
state.isStreaming && state.actionsLoading ? /* @__PURE__ */ (0,
|
|
1747
|
+
state.isStreaming && state.actionsLoading ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ActionButtons, { actions: [], loading: true, onAct: () => {
|
|
1667
1748
|
} }) : null,
|
|
1668
|
-
state.status ? /* @__PURE__ */ (0,
|
|
1669
|
-
state.error ? /* @__PURE__ */ (0,
|
|
1670
|
-
/* @__PURE__ */ (0,
|
|
1671
|
-
/* @__PURE__ */ (0,
|
|
1749
|
+
state.status ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "ss-w-status", children: state.status }) : null,
|
|
1750
|
+
state.error ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "ss-w-error", role: "alert", children: [
|
|
1751
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { children: "message" in state.error ? state.error.message : ui.somethingWentWrong }),
|
|
1752
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("button", { type: "button", className: "ss-w-retry", onClick: () => controller.retry(), children: ui.retry })
|
|
1672
1753
|
] }) : null,
|
|
1673
|
-
!hasUserMessage && !hasDashboard ? /* @__PURE__ */ (0,
|
|
1674
|
-
/* @__PURE__ */ (0,
|
|
1754
|
+
!hasUserMessage && !hasDashboard ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(IntentChips, { chips: state.starters, onPick: (t) => send(t) }) : null,
|
|
1755
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { ref: endRef })
|
|
1675
1756
|
]
|
|
1676
1757
|
}
|
|
1677
1758
|
);
|
|
@@ -1679,7 +1760,7 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
|
1679
1760
|
|
|
1680
1761
|
// src/components/ChatInput.tsx
|
|
1681
1762
|
var import_react10 = require("react");
|
|
1682
|
-
var
|
|
1763
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
1683
1764
|
function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop response", sendLabel = "Send message" }) {
|
|
1684
1765
|
const [value, setValue] = (0, import_react10.useState)("");
|
|
1685
1766
|
const submit = () => {
|
|
@@ -1694,14 +1775,14 @@ function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop r
|
|
|
1694
1775
|
submit();
|
|
1695
1776
|
}
|
|
1696
1777
|
};
|
|
1697
|
-
return /* @__PURE__ */ (0,
|
|
1698
|
-
/* @__PURE__ */ (0,
|
|
1699
|
-
streaming ? /* @__PURE__ */ (0,
|
|
1778
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "ss-w-input", children: [
|
|
1779
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("textarea", { className: "ss-w-textarea", rows: 1, placeholder, value, disabled: streaming, onChange: (e) => setValue(e.target.value), onKeyDown }),
|
|
1780
|
+
streaming ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("button", { type: "button", className: "ss-w-send ss-w-stop", "aria-label": stopLabel, onClick: onStop, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "ss-w-stop-glyph" }) }) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("button", { type: "button", className: "ss-w-send", "aria-label": sendLabel, onClick: submit, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(SendIcon, {}) })
|
|
1700
1781
|
] });
|
|
1701
1782
|
}
|
|
1702
1783
|
|
|
1703
1784
|
// src/components/ChatPanel.tsx
|
|
1704
|
-
var
|
|
1785
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
1705
1786
|
var FULLSCREEN_QUERY = "(max-width: 639px)";
|
|
1706
1787
|
function useIsModal() {
|
|
1707
1788
|
const [modal, setModal] = (0, import_react11.useState)(false);
|
|
@@ -1725,10 +1806,10 @@ function ChatPanel({ controller, ui, slip, onDashboardTap }) {
|
|
|
1725
1806
|
window.addEventListener("keydown", onKey);
|
|
1726
1807
|
return () => window.removeEventListener("keydown", onKey);
|
|
1727
1808
|
}, [close]);
|
|
1728
|
-
return /* @__PURE__ */ (0,
|
|
1729
|
-
/* @__PURE__ */ (0,
|
|
1730
|
-
/* @__PURE__ */ (0,
|
|
1731
|
-
/* @__PURE__ */ (0,
|
|
1809
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
|
|
1810
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(ChatHeader, { onClose: close, closeLabel: ui.closeChat }),
|
|
1811
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(MessageList, { controller, ui, slip, onDashboardTap }),
|
|
1812
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(ChatInput, { placeholder: ui.placeholder, streaming: state.isStreaming, onSend: (t) => send(t), onStop: stop, stopLabel: ui.stopResponse, sendLabel: ui.sendMessage })
|
|
1732
1813
|
] });
|
|
1733
1814
|
}
|
|
1734
1815
|
|
|
@@ -2193,10 +2274,40 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
2193
2274
|
.ss-w-fandash-link-tile:hover { background: color-mix(in srgb, var(--ss-w-accent) 16%, var(--ss-w-panel)); }
|
|
2194
2275
|
.ss-w-fandash-link-label { font-size: 12.5px; font-weight: 650; overflow-wrap: anywhere; }
|
|
2195
2276
|
.ss-w-fandash-link-chevron { flex: none; width: 12px; height: 12px; color: var(--ss-w-accent); }
|
|
2277
|
+
|
|
2278
|
+
/* post-match result: full-time scoreboard -- team names flank the score, meta line underneath */
|
|
2279
|
+
.ss-w-fandash-postmatch-scoreboard { display: flex; align-items: center; gap: 8px; }
|
|
2280
|
+
.ss-w-fandash-postmatch-team { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; font-weight: 650; }
|
|
2281
|
+
.ss-w-fandash-postmatch-team--away { text-align: right; }
|
|
2282
|
+
.ss-w-fandash-postmatch-score { flex: none; font-size: 20px; font-weight: 750; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
|
|
2283
|
+
.ss-w-fandash-postmatch-sep { flex: none; font-size: 14px; font-weight: 700; color: var(--ss-w-faint); }
|
|
2284
|
+
.ss-w-fandash-postmatch-meta { font-size: 11.5px; color: var(--ss-w-faint); }
|
|
2285
|
+
|
|
2286
|
+
/* post-match goals: a plain list, the club's own goals picked out in the accent color */
|
|
2287
|
+
.ss-w-fandash-postmatch-goal-list { list-style: none; display: flex; flex-direction: column; gap: 4px; }
|
|
2288
|
+
.ss-w-fandash-postmatch-goal { font-size: 12.5px; color: var(--ss-w-faint); }
|
|
2289
|
+
.ss-w-fandash-postmatch-goal--club { color: var(--ss-w-ink); font-weight: 650; }
|
|
2290
|
+
|
|
2291
|
+
/* post-match stats: club value / stat label / opponent value, three columns per row */
|
|
2292
|
+
.ss-w-fandash-postmatch-stat-rows { display: flex; flex-direction: column; gap: 5px; }
|
|
2293
|
+
.ss-w-fandash-postmatch-stat-row { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 8px; }
|
|
2294
|
+
.ss-w-fandash-postmatch-stat-value { font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
|
|
2295
|
+
.ss-w-fandash-postmatch-stat-row .ss-w-fandash-postmatch-stat-value:last-child { text-align: right; }
|
|
2296
|
+
.ss-w-fandash-postmatch-stat-label { font-size: 10.5px; text-align: center; color: var(--ss-w-faint); text-transform: uppercase; letter-spacing: .03em; }
|
|
2297
|
+
|
|
2298
|
+
/* post-match top performer: player name left, rating pill right */
|
|
2299
|
+
.ss-w-fandash-postmatch-performer-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
|
|
2300
|
+
.ss-w-fandash-postmatch-performer-name { font-size: 13px; font-weight: 650; overflow-wrap: anywhere; }
|
|
2301
|
+
.ss-w-fandash-postmatch-performer-rating { flex: none; font-size: 12px; 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: 2px 9px; }
|
|
2302
|
+
|
|
2303
|
+
/* post-match next: the upcoming fixture teaser -- opponent left, when-label right */
|
|
2304
|
+
.ss-w-fandash-postmatch-next-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
|
|
2305
|
+
.ss-w-fandash-postmatch-next-opponent { font-size: 13px; font-weight: 650; overflow-wrap: anywhere; }
|
|
2306
|
+
.ss-w-fandash-postmatch-next-when { flex: none; font-size: 11.5px; color: var(--ss-w-faint); }
|
|
2196
2307
|
`;
|
|
2197
2308
|
|
|
2198
2309
|
// src/StatsWidget.tsx
|
|
2199
|
-
var
|
|
2310
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
2200
2311
|
function buildClient(props) {
|
|
2201
2312
|
try {
|
|
2202
2313
|
if ("client" in props && props.client) {
|
|
@@ -2249,7 +2360,7 @@ function StatsWidget(props) {
|
|
|
2249
2360
|
}, [built, ui.injectStyles]);
|
|
2250
2361
|
if (!built) return null;
|
|
2251
2362
|
const attrs = themeAttrs(ui);
|
|
2252
|
-
return /* @__PURE__ */ (0,
|
|
2363
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("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__ */ (0, import_jsx_runtime36.jsx)(ChatPanel, { controller, ui, slip, onDashboardTap }) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
2253
2364
|
ChatFab,
|
|
2254
2365
|
{
|
|
2255
2366
|
label: ui.launcherLabel,
|