@sensiblestats/widget-react 0.20.0 → 0.21.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 CHANGED
@@ -1,5 +1,16 @@
1
1
  # @sensiblestats/widget-react
2
2
 
3
+ ## 0.21.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Match Preview card: deterministic matchPreviewCard block type (sdk) + renderer (react).
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies
12
+ - @sensiblestats/widget-sdk@0.18.0
13
+
3
14
  ## 0.20.0
4
15
 
5
16
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -1387,21 +1387,27 @@ function FixtureHeroBlock({
1387
1387
  ] });
1388
1388
  }
1389
1389
 
1390
- // src/components/club-dashboard/FormGuideBlock.tsx
1390
+ // src/components/club-dashboard/ResultPills.tsx
1391
1391
  var import_jsx_runtime19 = require("react/jsx-runtime");
1392
+ function ResultPills({ results }) {
1393
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, { children: results.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: `ss-w-cdash-pill ss-w-cdash-pill--${r.toLowerCase()}`, children: r }, i)) });
1394
+ }
1395
+
1396
+ // src/components/club-dashboard/FormGuideBlock.tsx
1397
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1392
1398
  function FormGuideBlock({ block }) {
1393
1399
  if (block.rows.length === 0) return null;
1394
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "ss-w-cdash-form", children: block.rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "ss-w-cdash-form-row", children: [
1395
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "ss-w-cdash-form-name", children: [
1400
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "ss-w-cdash-form", children: block.rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "ss-w-cdash-form-row", children: [
1401
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "ss-w-cdash-form-name", children: [
1396
1402
  row.name,
1397
1403
  row.position != null ? ` #${row.position}` : ""
1398
1404
  ] }),
1399
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ss-w-cdash-form-pills", children: row.last5.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: `ss-w-cdash-pill ss-w-cdash-pill--${r.toLowerCase()}`, children: r }, i)) })
1405
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-cdash-form-pills", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ResultPills, { results: row.last5 }) })
1400
1406
  ] }, row.name)) });
1401
1407
  }
1402
1408
 
1403
1409
  // src/components/club-dashboard/MatchPreviewBlock.tsx
1404
- var import_jsx_runtime20 = require("react/jsx-runtime");
1410
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1405
1411
  function MatchPreviewBlock({
1406
1412
  block,
1407
1413
  ui,
@@ -1409,10 +1415,10 @@ function MatchPreviewBlock({
1409
1415
  }) {
1410
1416
  if (block.facts.length === 0) return null;
1411
1417
  const heading = ui.clubMatchPreviewHeading;
1412
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "ss-w-cdash-lines", children: [
1413
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-cdash-lines-heading", children: heading }),
1418
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "ss-w-cdash-lines", children: [
1419
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "ss-w-cdash-lines-heading", children: heading }),
1414
1420
  block.facts.map(
1415
- (f, i) => f.actionRef ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1421
+ (f, i) => f.actionRef ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
1416
1422
  "button",
1417
1423
  {
1418
1424
  type: "button",
@@ -1420,20 +1426,54 @@ function MatchPreviewBlock({
1420
1426
  onClick: () => onAction(f.label ?? f.sentence, { actionRef: f.actionRef }),
1421
1427
  children: [
1422
1428
  f.sentence,
1423
- f.label ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "ss-w-cdash-fact-label", children: [
1429
+ f.label ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "ss-w-cdash-fact-label", children: [
1424
1430
  " ",
1425
1431
  f.label
1426
1432
  ] }) : null
1427
1433
  ]
1428
1434
  },
1429
1435
  i
1430
- ) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { children: f.sentence }, i)
1436
+ ) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { children: f.sentence }, i)
1431
1437
  )
1432
1438
  ] });
1433
1439
  }
1434
1440
 
1441
+ // src/components/club-dashboard/MatchPreviewCardBlock.tsx
1442
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1443
+ function position(p) {
1444
+ return p != null ? `#${p}` : "\u2014";
1445
+ }
1446
+ function MatchPreviewCardBlock({ block }) {
1447
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "ss-w-cdash-preview", children: [
1448
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "ss-w-cdash-preview-header", children: [
1449
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "ss-w-cdash-team", children: block.homeName }),
1450
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "ss-w-cdash-vs", children: "v" }),
1451
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "ss-w-cdash-team", children: block.awayName })
1452
+ ] }),
1453
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "ss-w-cdash-preview-row", children: [
1454
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "ss-w-cdash-preview-value", children: position(block.homePosition) }),
1455
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "ss-w-cdash-preview-label", children: block.tableLabel }),
1456
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "ss-w-cdash-preview-value", children: position(block.awayPosition) })
1457
+ ] }),
1458
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "ss-w-cdash-preview-row", children: [
1459
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "ss-w-cdash-preview-pills", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ResultPills, { results: block.homeLast5 }) }),
1460
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "ss-w-cdash-preview-label", children: block.last5Label }),
1461
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "ss-w-cdash-preview-pills", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ResultPills, { results: block.awayLast5 }) })
1462
+ ] }),
1463
+ block.edgeTeamName ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "ss-w-cdash-preview-edge", children: [
1464
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { "aria-hidden": "true", children: "\u25B8" }),
1465
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("strong", { children: block.edgeTeamName }),
1466
+ block.edgeReason ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { children: [
1467
+ " \u2014 ",
1468
+ block.edgeReason
1469
+ ] }) : null
1470
+ ] }) : null,
1471
+ block.h2HLines.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "ss-w-cdash-preview-h2h", children: block.h2HLines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { children: line }, i)) }) : null
1472
+ ] });
1473
+ }
1474
+
1435
1475
  // src/components/club-dashboard/TeamDnaBlock.tsx
1436
- var import_jsx_runtime21 = require("react/jsx-runtime");
1476
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1437
1477
  function TeamDnaBlock({
1438
1478
  block,
1439
1479
  ui,
@@ -1441,10 +1481,10 @@ function TeamDnaBlock({
1441
1481
  }) {
1442
1482
  if (block.facts.length === 0) return null;
1443
1483
  const heading = ui.clubTeamDnaHeading;
1444
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "ss-w-cdash-lines", children: [
1445
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "ss-w-cdash-lines-heading", children: heading }),
1484
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "ss-w-cdash-lines", children: [
1485
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "ss-w-cdash-lines-heading", children: heading }),
1446
1486
  block.facts.map(
1447
- (f, i) => f.actionRef ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
1487
+ (f, i) => f.actionRef ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
1448
1488
  "button",
1449
1489
  {
1450
1490
  type: "button",
@@ -1452,21 +1492,21 @@ function TeamDnaBlock({
1452
1492
  onClick: () => onAction(f.label ?? f.sentence, { actionRef: f.actionRef }),
1453
1493
  children: [
1454
1494
  f.sentence,
1455
- f.label ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "ss-w-cdash-fact-label", children: [
1495
+ f.label ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: "ss-w-cdash-fact-label", children: [
1456
1496
  " ",
1457
1497
  f.label
1458
1498
  ] }) : null
1459
1499
  ]
1460
1500
  },
1461
1501
  i
1462
- ) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { children: f.sentence }, i)
1502
+ ) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { children: f.sentence }, i)
1463
1503
  )
1464
1504
  ] });
1465
1505
  }
1466
1506
 
1467
1507
  // src/components/club-dashboard/CountdownBlock.tsx
1468
1508
  var import_react9 = require("react");
1469
- var import_jsx_runtime22 = require("react/jsx-runtime");
1509
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1470
1510
  var DAY_MS = 24 * 3600 * 1e3;
1471
1511
  function pad2(n) {
1472
1512
  return String(n).padStart(2, "0");
@@ -1491,30 +1531,31 @@ function CountdownBlock({ block, ui }) {
1491
1531
  if (remainingMs <= 0) return null;
1492
1532
  if (remainingMs > DAY_MS) return null;
1493
1533
  const { h, m, s } = splitRemaining(remainingMs);
1494
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "ss-w-cdash-cd", "aria-label": ui.clubKickoffAria(block.kickoffUnix * 1e3), children: [
1495
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "ss-w-cdash-cd-clock", "aria-hidden": "true", children: [
1496
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "ss-w-cdash-cd-h", children: h }),
1534
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "ss-w-cdash-cd", "aria-label": ui.clubKickoffAria(block.kickoffUnix * 1e3), children: [
1535
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "ss-w-cdash-cd-clock", "aria-hidden": "true", children: [
1536
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "ss-w-cdash-cd-h", children: h }),
1497
1537
  "h",
1498
1538
  " ",
1499
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "ss-w-cdash-cd-m", children: m }),
1539
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "ss-w-cdash-cd-m", children: m }),
1500
1540
  "m",
1501
1541
  " ",
1502
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "ss-w-cdash-cd-s", children: s }),
1542
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "ss-w-cdash-cd-s", children: s }),
1503
1543
  "s"
1504
1544
  ] }),
1505
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "ss-w-cdash-cd-label", children: ui.clubCountdownLabel })
1545
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "ss-w-cdash-cd-label", children: ui.clubCountdownLabel })
1506
1546
  ] });
1507
1547
  }
1508
1548
 
1509
1549
  // src/components/club-dashboard/ClubDashboard.tsx
1510
- var import_jsx_runtime23 = require("react/jsx-runtime");
1550
+ var import_jsx_runtime25 = require("react/jsx-runtime");
1511
1551
  var CLUB_BLOCK_REGISTRY = {
1512
- greetingHeader: ({ block }) => block.type === "greetingHeader" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(GreetingHeaderBlock, { block }) : null,
1513
- fixtureHero: ({ block, ui, onAction }) => block.type === "fixtureHero" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(FixtureHeroBlock, { block, ui, onAction }) : null,
1514
- formGuide: ({ block, ui }) => block.type === "formGuide" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(FormGuideBlock, { block, ui }) : null,
1515
- matchPreview: ({ block, ui, onAction }) => block.type === "matchPreview" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(MatchPreviewBlock, { block, ui, onAction }) : null,
1516
- teamDna: ({ block, ui, onAction }) => block.type === "teamDna" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TeamDnaBlock, { block, ui, onAction }) : null,
1517
- countdown: ({ block, ui }) => block.type === "countdown" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CountdownBlock, { block, ui }) : null
1552
+ greetingHeader: ({ block }) => block.type === "greetingHeader" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GreetingHeaderBlock, { block }) : null,
1553
+ fixtureHero: ({ block, ui, onAction }) => block.type === "fixtureHero" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(FixtureHeroBlock, { block, ui, onAction }) : null,
1554
+ formGuide: ({ block, ui }) => block.type === "formGuide" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(FormGuideBlock, { block, ui }) : null,
1555
+ matchPreview: ({ block, ui, onAction }) => block.type === "matchPreview" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(MatchPreviewBlock, { block, ui, onAction }) : null,
1556
+ matchPreviewCard: ({ block, ui }) => block.type === "matchPreviewCard" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(MatchPreviewCardBlock, { block, ui }) : null,
1557
+ teamDna: ({ block, ui, onAction }) => block.type === "teamDna" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TeamDnaBlock, { block, ui, onAction }) : null,
1558
+ countdown: ({ block, ui }) => block.type === "countdown" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CountdownBlock, { block, ui }) : null
1518
1559
  };
1519
1560
  function ClubDashboard({
1520
1561
  dashboard,
@@ -1522,39 +1563,39 @@ function ClubDashboard({
1522
1563
  onAction
1523
1564
  }) {
1524
1565
  if (!dashboard.blocks.length) return null;
1525
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "ss-w-cdash", children: dashboard.blocks.map((block, i) => {
1566
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "ss-w-cdash", children: dashboard.blocks.map((block, i) => {
1526
1567
  const Comp = Object.prototype.hasOwnProperty.call(CLUB_BLOCK_REGISTRY, block.type) ? CLUB_BLOCK_REGISTRY[block.type] : void 0;
1527
1568
  if (!Comp) {
1528
1569
  console.warn(`[club-dashboard] no renderer for block type "${block.type}"`);
1529
1570
  return null;
1530
1571
  }
1531
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "ss-w-cdash-block", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Comp, { block, ui, onAction }) }, i);
1572
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "ss-w-cdash-block", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Comp, { block, ui, onAction }) }, i);
1532
1573
  }) });
1533
1574
  }
1534
1575
 
1535
1576
  // src/components/ChatMessage.tsx
1536
- var import_jsx_runtime24 = require("react/jsx-runtime");
1577
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1537
1578
  function ChatMessage({ message, disabled, onAct, onTap, onClubAction, ui, slip }) {
1538
1579
  if (message.role === "user") {
1539
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "ss-w-msg ss-w-user", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "ss-w-bubble", children: message.text }) });
1580
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "ss-w-msg ss-w-user", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "ss-w-bubble", children: message.text }) });
1540
1581
  }
1541
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "ss-w-msg ss-w-bot", children: [
1542
- message.text && !message.greetingDashboard && !message.clubDashboard ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Markdown, { text: message.text }) : null,
1543
- message.greetingDashboard ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GreetingDashboard, { dashboard: message.greetingDashboard, onTap }) : null,
1544
- message.clubDashboard && ui ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ClubDashboard, { dashboard: message.clubDashboard, ui, onAction: onClubAction }) : null,
1545
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(EntityCardList, { cards: message.cards, disabled, showLessLabel: ui?.showLess, showMoreLabel: ui?.showMore }),
1546
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(BettingInsightList, { insights: message.insights, ui, slip }),
1547
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(MarketOddsCardList, { cards: message.marketOdds, ui, slip }),
1548
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(OddsMovementCardList, { cards: message.oddsMovement, ui }),
1549
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ActionButtons, { actions: message.actions, loading: false, disabled, onAct })
1582
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "ss-w-msg ss-w-bot", children: [
1583
+ message.text && !message.greetingDashboard && !message.clubDashboard ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Markdown, { text: message.text }) : null,
1584
+ message.greetingDashboard ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(GreetingDashboard, { dashboard: message.greetingDashboard, onTap }) : null,
1585
+ message.clubDashboard && ui ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ClubDashboard, { dashboard: message.clubDashboard, ui, onAction: onClubAction }) : null,
1586
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EntityCardList, { cards: message.cards, disabled, showLessLabel: ui?.showLess, showMoreLabel: ui?.showMore }),
1587
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(BettingInsightList, { insights: message.insights, ui, slip }),
1588
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(MarketOddsCardList, { cards: message.marketOdds, ui, slip }),
1589
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(OddsMovementCardList, { cards: message.oddsMovement, ui }),
1590
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ActionButtons, { actions: message.actions, loading: false, disabled, onAct })
1550
1591
  ] });
1551
1592
  }
1552
1593
 
1553
1594
  // src/components/IntentChips.tsx
1554
- var import_jsx_runtime25 = require("react/jsx-runtime");
1595
+ var import_jsx_runtime27 = require("react/jsx-runtime");
1555
1596
  function IntentChips({ chips, onPick }) {
1556
1597
  if (chips.length === 0) return null;
1557
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "ss-w-chips", children: chips.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: "ss-w-chip", onClick: () => onPick(c.text), children: c.text }, `${c.text}-${i}`)) });
1598
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "ss-w-chips", children: chips.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", className: "ss-w-chip", onClick: () => onPick(c.text), children: c.text }, `${c.text}-${i}`)) });
1558
1599
  }
1559
1600
 
1560
1601
  // src/scroll.ts
@@ -1564,7 +1605,7 @@ function isPinnedToBottom(el, threshold = PIN_THRESHOLD) {
1564
1605
  }
1565
1606
 
1566
1607
  // src/components/MessageList.tsx
1567
- var import_jsx_runtime26 = require("react/jsx-runtime");
1608
+ var import_jsx_runtime28 = require("react/jsx-runtime");
1568
1609
  function MessageList({ controller, ui, slip, onDashboardTap }) {
1569
1610
  const { state, send } = controller;
1570
1611
  const listRef = (0, import_react10.useRef)(null);
@@ -1575,7 +1616,7 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
1575
1616
  }, [state.messages, state.status]);
1576
1617
  const hasUserMessage = state.messages.some((m) => m.role === "user");
1577
1618
  const hasDashboard = state.messages.some((m) => m.role === "assistant" && m.greetingDashboard);
1578
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
1619
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
1579
1620
  "div",
1580
1621
  {
1581
1622
  className: "ss-w-list",
@@ -1585,7 +1626,7 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
1585
1626
  if (listRef.current) pinnedRef.current = isPinnedToBottom(listRef.current);
1586
1627
  },
1587
1628
  children: [
1588
- state.messages.map((m) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1629
+ state.messages.map((m) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1589
1630
  ChatMessage,
1590
1631
  {
1591
1632
  message: m,
@@ -1601,15 +1642,15 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
1601
1642
  },
1602
1643
  m.id
1603
1644
  )),
1604
- state.isStreaming && state.actionsLoading ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ActionButtons, { actions: [], loading: true, onAct: () => {
1645
+ state.isStreaming && state.actionsLoading ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ActionButtons, { actions: [], loading: true, onAct: () => {
1605
1646
  } }) : null,
1606
- state.status ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "ss-w-status", children: state.status }) : null,
1607
- state.error ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "ss-w-error", role: "alert", children: [
1608
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "message" in state.error ? state.error.message : ui.somethingWentWrong }),
1609
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: "ss-w-retry", onClick: () => controller.retry(), children: ui.retry })
1647
+ state.status ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "ss-w-status", children: state.status }) : null,
1648
+ state.error ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "ss-w-error", role: "alert", children: [
1649
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { children: "message" in state.error ? state.error.message : ui.somethingWentWrong }),
1650
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", className: "ss-w-retry", onClick: () => controller.retry(), children: ui.retry })
1610
1651
  ] }) : null,
1611
- !hasUserMessage && !hasDashboard ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(IntentChips, { chips: state.starters, onPick: (t) => send(t) }) : null,
1612
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { ref: endRef })
1652
+ !hasUserMessage && !hasDashboard ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(IntentChips, { chips: state.starters, onPick: (t) => send(t) }) : null,
1653
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { ref: endRef })
1613
1654
  ]
1614
1655
  }
1615
1656
  );
@@ -1617,7 +1658,7 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
1617
1658
 
1618
1659
  // src/components/ChatInput.tsx
1619
1660
  var import_react11 = require("react");
1620
- var import_jsx_runtime27 = require("react/jsx-runtime");
1661
+ var import_jsx_runtime29 = require("react/jsx-runtime");
1621
1662
  function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop response", sendLabel = "Send message" }) {
1622
1663
  const [value, setValue] = (0, import_react11.useState)("");
1623
1664
  const submit = () => {
@@ -1632,14 +1673,14 @@ function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop r
1632
1673
  submit();
1633
1674
  }
1634
1675
  };
1635
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "ss-w-input", children: [
1636
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("textarea", { className: "ss-w-textarea", rows: 1, placeholder, value, disabled: streaming, onChange: (e) => setValue(e.target.value), onKeyDown }),
1637
- streaming ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", className: "ss-w-send ss-w-stop", "aria-label": stopLabel, onClick: onStop, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-stop-glyph" }) }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", className: "ss-w-send", "aria-label": sendLabel, onClick: submit, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(SendIcon, {}) })
1676
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "ss-w-input", children: [
1677
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("textarea", { className: "ss-w-textarea", rows: 1, placeholder, value, disabled: streaming, onChange: (e) => setValue(e.target.value), onKeyDown }),
1678
+ streaming ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", className: "ss-w-send ss-w-stop", "aria-label": stopLabel, onClick: onStop, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "ss-w-stop-glyph" }) }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", className: "ss-w-send", "aria-label": sendLabel, onClick: submit, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(SendIcon, {}) })
1638
1679
  ] });
1639
1680
  }
1640
1681
 
1641
1682
  // src/components/ChatPanel.tsx
1642
- var import_jsx_runtime28 = require("react/jsx-runtime");
1683
+ var import_jsx_runtime30 = require("react/jsx-runtime");
1643
1684
  var FULLSCREEN_QUERY = "(max-width: 639px)";
1644
1685
  function useIsModal() {
1645
1686
  const [modal, setModal] = (0, import_react12.useState)(false);
@@ -1663,10 +1704,10 @@ function ChatPanel({ controller, ui, slip, onDashboardTap }) {
1663
1704
  window.addEventListener("keydown", onKey);
1664
1705
  return () => window.removeEventListener("keydown", onKey);
1665
1706
  }, [close]);
1666
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
1667
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ChatHeader, { onClose: close, closeLabel: ui.closeChat }),
1668
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(MessageList, { controller, ui, slip, onDashboardTap }),
1669
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ChatInput, { placeholder: ui.placeholder, streaming: state.isStreaming, onSend: (t) => send(t), onStop: stop, stopLabel: ui.stopResponse, sendLabel: ui.sendMessage })
1707
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
1708
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ChatHeader, { onClose: close, closeLabel: ui.closeChat }),
1709
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(MessageList, { controller, ui, slip, onDashboardTap }),
1710
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ChatInput, { placeholder: ui.placeholder, streaming: state.isStreaming, onSend: (t) => send(t), onStop: stop, stopLabel: ui.stopResponse, sendLabel: ui.sendMessage })
1670
1711
  ] });
1671
1712
  }
1672
1713
 
@@ -2058,10 +2099,27 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
2058
2099
  .ss-w-cdash-cd-clock { display: flex; align-items: baseline; justify-content: center; gap: 2px; font-variant-numeric: tabular-nums; font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-weight: 700; font-size: 18px; color: var(--ss-w-ink); }
2059
2100
  .ss-w-cdash-cd-h, .ss-w-cdash-cd-m, .ss-w-cdash-cd-s { color: var(--ss-w-accent); }
2060
2101
  .ss-w-cdash-cd-label { font-size: 11px; font-weight: 600; color: var(--ss-w-faint); }
2102
+
2103
+ .ss-w-cdash-preview { display: flex; flex-direction: column; gap: 8px; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; padding: 10px 12px; }
2104
+ .ss-w-cdash-preview-header { display: grid; grid-template-columns: 1fr auto 1fr; align-items: baseline; gap: 6px; }
2105
+ .ss-w-cdash-preview-header .ss-w-cdash-team:first-child { justify-self: start; text-align: left; }
2106
+ .ss-w-cdash-preview-header .ss-w-cdash-team:last-child { justify-self: end; text-align: right; }
2107
+ .ss-w-cdash-preview-row { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 6px; }
2108
+ .ss-w-cdash-preview-label { font-size: 10.5px; font-weight: 600; color: var(--ss-w-faint); text-align: center; text-transform: uppercase; letter-spacing: 0.03em; }
2109
+ .ss-w-cdash-preview-value { font-size: 12px; font-weight: 700; color: var(--ss-w-ink); text-align: center; }
2110
+ .ss-w-cdash-preview-pills { display: flex; align-items: center; justify-content: center; gap: 3px; }
2111
+ .ss-w-cdash-preview-row:first-of-type .ss-w-cdash-preview-value { justify-self: start; }
2112
+ .ss-w-cdash-preview-row:first-of-type .ss-w-cdash-preview-value:last-child { justify-self: end; }
2113
+ .ss-w-cdash-preview-row:last-of-type .ss-w-cdash-preview-pills:first-child { justify-self: start; }
2114
+ .ss-w-cdash-preview-row:last-of-type .ss-w-cdash-preview-pills:last-child { justify-self: end; }
2115
+ .ss-w-cdash-preview-edge { display: flex; align-items: baseline; gap: 4px; font-size: 12px; line-height: 1.4; color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 10%, transparent); border-radius: 8px; padding: 6px 8px; }
2116
+ .ss-w-cdash-preview-edge strong { color: var(--ss-w-ink); }
2117
+ .ss-w-cdash-preview-h2h { display: flex; flex-direction: column; gap: 2px; }
2118
+ .ss-w-cdash-preview-h2h p { font-size: 11.5px; line-height: 1.4; color: var(--ss-w-faint); margin: 0; }
2061
2119
  `;
2062
2120
 
2063
2121
  // src/StatsWidget.tsx
2064
- var import_jsx_runtime29 = require("react/jsx-runtime");
2122
+ var import_jsx_runtime31 = require("react/jsx-runtime");
2065
2123
  function buildClient(props) {
2066
2124
  try {
2067
2125
  if ("client" in props && props.client) {
@@ -2114,7 +2172,7 @@ function StatsWidget(props) {
2114
2172
  }, [built, ui.injectStyles]);
2115
2173
  if (!built) return null;
2116
2174
  const attrs = themeAttrs(ui);
2117
- return /* @__PURE__ */ (0, import_jsx_runtime29.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_runtime29.jsx)(ChatPanel, { controller, ui, slip, onDashboardTap }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
2175
+ return /* @__PURE__ */ (0, import_jsx_runtime31.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_runtime31.jsx)(ChatPanel, { controller, ui, slip, onDashboardTap }) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2118
2176
  ChatFab,
2119
2177
  {
2120
2178
  label: ui.launcherLabel,