@sensiblestats/widget-react 0.2.1 → 0.4.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 +17 -0
- package/dist/index.cjs +150 -66
- 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 +150 -66
- package/dist/index.js.map +1 -1
- package/dist/styles.css +24 -3
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -33,6 +33,6 @@ type StatsWidgetProps = {
|
|
|
33
33
|
};
|
|
34
34
|
declare function StatsWidget(props: StatsWidgetProps): JSX.Element | null;
|
|
35
35
|
|
|
36
|
-
declare const WIDGET_CSS = ".ss-w-root { all: revert; }\n.ss-w-root, .ss-w-root * { box-sizing: border-box; margin: 0; padding: 0; }\n.ss-w-root {\n --ss-w-accent: #17936a;\n --ss-w-ink: #14181d; --ss-w-faint: #6b7580; --ss-w-line: #e4e8ec;\n --ss-w-panel: #ffffff; --ss-w-bubble: #f3f5f7; --ss-w-nav: #0e1622;\n --ss-w-radius: 16px; --ss-w-offset-x: 20px; --ss-w-offset-y: 20px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n font-size: 13px; line-height: 1.5; color: var(--ss-w-ink);\n}\n@media (prefers-color-scheme: dark) {\n .ss-w-root[data-ss-w-theme=\"auto\"] {\n --ss-w-accent: #37c891; --ss-w-ink: #e8edf2; --ss-w-faint: #8b95a1;\n --ss-w-line: #2a3441; --ss-w-panel: #141b24; --ss-w-bubble: #1e2732; --ss-w-nav: #0a0f16;\n }\n}\n.ss-w-root[data-ss-w-theme=\"dark\"] {\n --ss-w-accent: #37c891; --ss-w-ink: #e8edf2; --ss-w-faint: #8b95a1;\n --ss-w-line: #2a3441; --ss-w-panel: #141b24; --ss-w-bubble: #1e2732; --ss-w-nav: #0a0f16;\n}\n.ss-w-root[data-ss-w-theme=\"light\"] {\n --ss-w-accent: #17936a; --ss-w-ink: #14181d; --ss-w-faint: #6b7580;\n --ss-w-line: #e4e8ec; --ss-w-panel: #ffffff; --ss-w-bubble: #f3f5f7; --ss-w-nav: #0e1622;\n}\n\n/* launcher */\n.ss-w-fab-wrap { position: fixed; bottom: var(--ss-w-offset-y); z-index: 2147483000; display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }\n.ss-w-root[data-ss-w-pos=\"right\"] .ss-w-fab-wrap { right: var(--ss-w-offset-x); }\n.ss-w-root[data-ss-w-pos=\"left\"] .ss-w-fab-wrap { left: var(--ss-w-offset-x); align-items: flex-start; }\n.ss-w-fab { width: 56px; height: 56px; border: none; border-radius: 50%; background: var(--ss-w-nav); color: #fff; cursor: pointer; display: grid; place-items: center; box-shadow: 0 6px 20px rgba(0,0,0,.28); }\n.ss-w-fab-mark { width: 30px; height: 30px; display: block; }\n.ss-w-greeting { max-width: 240px; display: flex; align-items: flex-start; background: var(--ss-w-panel); color: var(--ss-w-ink); border: 1px solid var(--ss-w-line); border-radius: 12px; box-shadow: 0 4px 14px rgba(0,0,0,.14); }\n.ss-w-greeting-body { flex: 1; min-width: 0; text-align: left; background: none; border: none; color: inherit; font: inherit; cursor: pointer; padding: 9px 4px 9px 12px; }\n.ss-w-greeting-x { flex: none; background: none; border: none; color: var(--ss-w-faint); cursor: pointer; font-size: 17px; line-height: 1; padding: 7px 9px 0 2px; }\n\n/* panel */\n.ss-w-panel { position: fixed; bottom: calc(var(--ss-w-offset-y) + 72px); z-index: 2147483000; display: flex; flex-direction: column; width: min(400px, calc(100vw - 40px)); height: min(620px, calc(100vh - 120px)); background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: var(--ss-w-radius); overflow: hidden; box-shadow: 0 12px 40px rgba(0,0,0,.24); }\n.ss-w-root[data-ss-w-pos=\"right\"] .ss-w-panel { right: var(--ss-w-offset-x); }\n.ss-w-root[data-ss-w-pos=\"left\"] .ss-w-panel { left: var(--ss-w-offset-x); }\n@media (max-width: 639px) {\n /* Fill via inset with no explicit height (like the site's working panel) so the\n input stays visible when the mobile keyboard/URL-bar shrinks the viewport. The\n position-specific selectors override the right/left offsets set above. */\n .ss-w-root[data-ss-w-pos=\"right\"] .ss-w-panel,\n .ss-w-root[data-ss-w-pos=\"left\"] .ss-w-panel { inset: 0; width: auto; height: auto; border: none; border-radius: 0; }\n}\n.ss-w-header { display: flex; align-items: center; gap: 8px; padding: 12px 14px; border-bottom: 1px solid var(--ss-w-line); }\n.ss-w-header-mark { width: 18px; height: 18px; display: block; }\n.ss-w-header-title { font-weight: 660; }\n.ss-w-close { margin-left: auto; background: none; border: none; color: var(--ss-w-faint); cursor: pointer; font-size: 16px; display: grid; place-items: center; }\n\n/* messages */\n.ss-w-list { flex: 1; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 12px; }\n.ss-w-msg { display: flex; }\n.ss-w-user { justify-content: flex-end; }\n.ss-w-user .ss-w-bubble { background: color-mix(in srgb, var(--ss-w-accent) 14%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-accent) 30%, var(--ss-w-line)); border-radius: 14px; padding: 8px 12px; max-width: 80%; }\n.ss-w-bot { flex-direction: column; gap: 8px; }\n.ss-w-status { font-size: 11px; color: var(--ss-w-faint); font-style: italic; }\n.ss-w-error { display: flex; align-items: center; gap: 8px; font-size: 12px; color: #c0392b; }\n.ss-w-retry { background: none; border: 1px solid currentColor; border-radius: 10px; padding: 2px 8px; cursor: pointer; color: inherit; }\n\n/* markdown */\n.ss-w-md { display: flex; flex-direction: column; gap: 8px; }\n.ss-w-md :where(p, ul, ol, table, pre, blockquote, h1, h2, h3, h4) { margin: 0; }\n.ss-w-md > *:first-child { margin-top: 0; }\n.ss-w-md > *:last-child { margin-bottom: 0; }\n.ss-w-md-ul { list-style: disc outside; padding-left: 18px; }\n.ss-w-md-ol { list-style: decimal outside; padding-left: 18px; }\n.ss-w-md-ul li::marker, .ss-w-md-ol li::marker { color: var(--ss-w-accent); }\n.ss-w-md-link { color: var(--ss-w-accent); text-decoration: underline; }\n.ss-w-table-wrap { overflow-x: auto; max-width: 100%; -webkit-overflow-scrolling: touch; }\n.ss-w-md-table { border-collapse: collapse; width: max-content; min-width: 100%; font-variant-numeric: tabular-nums; }\n.ss-w-md-table td, .ss-w-md-table th { border: 1px solid var(--ss-w-line); padding: 4px 8px; text-align: left; white-space: nowrap; }\n.ss-w-md-table th { background: color-mix(in srgb, var(--ss-w-accent) 12%, var(--ss-w-panel)); font-weight: 700; }\n.ss-w-md-table tbody tr:nth-child(even) { background: var(--ss-w-bubble); }\n.ss-w-md-code { background: var(--ss-w-bubble); border-radius: 5px; padding: 1px 5px; font-family: ui-monospace, monospace; }\n\n/* entity cards */\n.ss-w-cards { display: flex; flex-direction: column; gap: 7px; }\n.ss-w-ecard { display: flex; align-items: center; gap: 11px; width: 100%; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; padding: 8px 11px; text-align: left; cursor: pointer; }\n.ss-w-thumb { width: 40px; height: 40px; flex: none; border-radius: 50%; display: grid; place-items: center; font-size: 13px; font-weight: 700; color: #fff; background-color: var(--ss-w-nav); background-size: cover; background-position: center; }\n.ss-w-thumb.ss-w-team { border-radius: 10px; }\n.ss-w-ecard[data-kind=\"player\"] .ss-w-thumb { background-color: var(--ss-w-accent); }\n.ss-w-meta { display: flex; flex-direction: column; min-width: 0; }\n.ss-w-kind { font-size: 8.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--ss-w-faint); line-height: 1.3; }\n.ss-w-nm { font-weight: 660; }\n.ss-w-sub { font-size: 11px; color: var(--ss-w-faint); }\n.ss-w-stat { margin-left: auto; text-align: center; }\n.ss-w-stat b { display: block; font-variant-numeric: tabular-nums; }\n.ss-w-stat span { font-size: 9px; text-transform: uppercase; color: var(--ss-w-faint); }\n.ss-w-chev { color: var(--ss-w-faint); font-size: 16px; display: grid; place-items: center; }\n.ss-w-cards-more { align-self: flex-start; font-size: 11.5px; font-weight: 560; color: var(--ss-w-accent); background: none; border: none; cursor: pointer; padding: 3px 2px; }\n.ss-w-cards-more:hover:not(:disabled) { text-decoration: underline; }\n.ss-w-ecard:disabled, .ss-w-cards-more:disabled { opacity: .5; cursor: default; }\n\n/* action buttons */\n.ss-w-actions { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }\n.ss-w-abtn { font-size: 12px; font-weight: 560; color: var(--ss-w-accent); background: var(--ss-w-panel); border: 1px solid var(--ss-w-accent); border-radius: 16px; padding: 6px 12px; cursor: pointer; }\n.ss-w-abtn:disabled { opacity: .5; cursor: default; }\n.ss-w-abtn-shimmer { width: 140px; height: 30px; border-radius: 16px; background: linear-gradient(90deg, var(--ss-w-bubble), var(--ss-w-line), var(--ss-w-bubble)); background-size: 200% 100%; animation: ss-w-shimmer 1.2s infinite; }\n@keyframes ss-w-shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }\n\n/* intent chips */\n.ss-w-chips { display: flex; flex-wrap: wrap; gap: 6px; }\n.ss-w-chip { font-size: 11.5px; font-weight: 550; color: var(--ss-w-ink); background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 14px; padding: 5px 11px; cursor: pointer; }\n\n/* input */\n.ss-w-input { display: flex; align-items: flex-end; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--ss-w-line); }\n.ss-w-textarea { flex: 1; resize: none; border: 1px solid var(--ss-w-line); border-radius: 12px; padding: 8px 10px; font: inherit; color: inherit; background: var(--ss-w-panel); max-height: 96px; }\n.ss-w-textarea:disabled { opacity: .55; cursor: not-allowed; }\n.ss-w-send { width: 36px; height: 36px; flex: none; border: none; border-radius: 50%; background: var(--ss-w-accent); color: #fff; cursor: pointer; display: grid; place-items: center; font-size: 16px; }\n.ss-w-stop-glyph { width: 11px; height: 11px; background: currentColor; border-radius: 2px; }\n\n@media (prefers-reduced-motion: reduce) {\n .ss-w-abtn-shimmer { animation: none; }\n}\n";
|
|
36
|
+
declare const WIDGET_CSS = ".ss-w-root { all: revert; }\n.ss-w-root, .ss-w-root * { box-sizing: border-box; margin: 0; padding: 0; }\n.ss-w-root {\n --ss-w-accent: #17936a;\n --ss-w-ink: #14181d; --ss-w-faint: #6b7580; --ss-w-line: #e4e8ec;\n --ss-w-panel: #ffffff; --ss-w-bubble: #f3f5f7; --ss-w-nav: #0e1622;\n --ss-w-radius: 16px; --ss-w-offset-x: 20px; --ss-w-offset-y: 20px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n font-size: 13px; line-height: 1.5; color: var(--ss-w-ink);\n}\n@media (prefers-color-scheme: dark) {\n .ss-w-root[data-ss-w-theme=\"auto\"] {\n --ss-w-accent: #37c891; --ss-w-ink: #e8edf2; --ss-w-faint: #8b95a1;\n --ss-w-line: #2a3441; --ss-w-panel: #141b24; --ss-w-bubble: #1e2732; --ss-w-nav: #0a0f16;\n }\n}\n.ss-w-root[data-ss-w-theme=\"dark\"] {\n --ss-w-accent: #37c891; --ss-w-ink: #e8edf2; --ss-w-faint: #8b95a1;\n --ss-w-line: #2a3441; --ss-w-panel: #141b24; --ss-w-bubble: #1e2732; --ss-w-nav: #0a0f16;\n}\n.ss-w-root[data-ss-w-theme=\"light\"] {\n --ss-w-accent: #17936a; --ss-w-ink: #14181d; --ss-w-faint: #6b7580;\n --ss-w-line: #e4e8ec; --ss-w-panel: #ffffff; --ss-w-bubble: #f3f5f7; --ss-w-nav: #0e1622;\n}\n\n/* launcher */\n.ss-w-fab-wrap { position: fixed; bottom: var(--ss-w-offset-y); z-index: 2147483000; display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }\n.ss-w-root[data-ss-w-pos=\"right\"] .ss-w-fab-wrap { right: var(--ss-w-offset-x); }\n.ss-w-root[data-ss-w-pos=\"left\"] .ss-w-fab-wrap { left: var(--ss-w-offset-x); align-items: flex-start; }\n.ss-w-fab { width: 56px; height: 56px; border: none; border-radius: 50%; background: var(--ss-w-nav); color: #fff; cursor: pointer; display: grid; place-items: center; box-shadow: 0 6px 20px rgba(0,0,0,.28); }\n.ss-w-fab-mark { width: 30px; height: 30px; display: block; }\n.ss-w-greeting { max-width: 240px; display: flex; align-items: flex-start; background: var(--ss-w-panel); color: var(--ss-w-ink); border: 1px solid var(--ss-w-line); border-radius: 12px; box-shadow: 0 4px 14px rgba(0,0,0,.14); }\n.ss-w-greeting-body { flex: 1; min-width: 0; text-align: left; background: none; border: none; color: inherit; font: inherit; cursor: pointer; padding: 9px 4px 9px 12px; }\n.ss-w-greeting-x { flex: none; background: none; border: none; color: var(--ss-w-faint); cursor: pointer; font-size: 17px; line-height: 1; padding: 7px 9px 0 2px; }\n\n/* panel */\n.ss-w-panel { position: fixed; bottom: calc(var(--ss-w-offset-y) + 72px); z-index: 2147483000; display: flex; flex-direction: column; width: min(400px, calc(100vw - 40px)); height: min(620px, calc(100vh - 120px)); background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: var(--ss-w-radius); overflow: hidden; box-shadow: 0 12px 40px rgba(0,0,0,.24); }\n.ss-w-root[data-ss-w-pos=\"right\"] .ss-w-panel { right: var(--ss-w-offset-x); }\n.ss-w-root[data-ss-w-pos=\"left\"] .ss-w-panel { left: var(--ss-w-offset-x); }\n@media (max-width: 639px) {\n /* Fill via inset with no explicit height (like the site's working panel) so the\n input stays visible when the mobile keyboard/URL-bar shrinks the viewport. The\n position-specific selectors override the right/left offsets set above. */\n .ss-w-root[data-ss-w-pos=\"right\"] .ss-w-panel,\n .ss-w-root[data-ss-w-pos=\"left\"] .ss-w-panel { inset: 0; width: auto; height: auto; border: none; border-radius: 0; }\n}\n.ss-w-header { display: flex; align-items: center; gap: 8px; padding: 12px 14px; border-bottom: 1px solid var(--ss-w-line); }\n.ss-w-header-mark { width: 18px; height: 18px; display: block; }\n.ss-w-header-title { font-weight: 660; }\n.ss-w-close { margin-left: auto; background: none; border: none; color: var(--ss-w-faint); cursor: pointer; font-size: 16px; display: grid; place-items: center; }\n\n/* messages */\n.ss-w-list { flex: 1; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 12px; }\n.ss-w-msg { display: flex; }\n.ss-w-user { justify-content: flex-end; }\n.ss-w-user .ss-w-bubble { background: color-mix(in srgb, var(--ss-w-accent) 14%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-accent) 30%, var(--ss-w-line)); border-radius: 14px; padding: 8px 12px; max-width: 80%; }\n.ss-w-bot { flex-direction: column; gap: 8px; }\n.ss-w-status { font-size: 11px; color: var(--ss-w-faint); font-style: italic; }\n.ss-w-error { display: flex; align-items: center; gap: 8px; font-size: 12px; color: #c0392b; }\n.ss-w-retry { background: none; border: 1px solid currentColor; border-radius: 10px; padding: 2px 8px; cursor: pointer; color: inherit; }\n\n/* markdown */\n.ss-w-md { display: flex; flex-direction: column; gap: 8px; }\n.ss-w-md :where(p, ul, ol, table, pre, blockquote, h1, h2, h3, h4) { margin: 0; }\n.ss-w-md > *:first-child { margin-top: 0; }\n.ss-w-md > *:last-child { margin-bottom: 0; }\n.ss-w-md-ul { list-style: disc outside; padding-left: 18px; }\n.ss-w-md-ol { list-style: decimal outside; padding-left: 18px; }\n.ss-w-md-ul li::marker, .ss-w-md-ol li::marker { color: var(--ss-w-accent); }\n.ss-w-md-link { color: var(--ss-w-accent); text-decoration: underline; }\n.ss-w-table-wrap { overflow-x: auto; max-width: 100%; -webkit-overflow-scrolling: touch; }\n.ss-w-md-table { border-collapse: collapse; width: max-content; min-width: 100%; font-variant-numeric: tabular-nums; }\n.ss-w-md-table td, .ss-w-md-table th { border: 1px solid var(--ss-w-line); padding: 4px 8px; text-align: left; white-space: nowrap; }\n.ss-w-md-table th { background: color-mix(in srgb, var(--ss-w-accent) 12%, var(--ss-w-panel)); font-weight: 700; }\n.ss-w-md-table tbody tr:nth-child(even) { background: var(--ss-w-bubble); }\n.ss-w-md-code { background: var(--ss-w-bubble); border-radius: 5px; padding: 1px 5px; font-family: ui-monospace, monospace; }\n\n/* entity cards */\n.ss-w-cards { display: flex; flex-direction: column; gap: 7px; }\n.ss-w-ecard { display: flex; align-items: center; gap: 11px; width: 100%; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; padding: 8px 11px; text-align: left; }\n.ss-w-thumb { width: 40px; height: 40px; flex: none; border-radius: 50%; display: grid; place-items: center; font-size: 13px; font-weight: 700; color: #fff; background-color: var(--ss-w-nav); background-size: cover; background-position: center; }\n.ss-w-thumb.ss-w-team { border-radius: 10px; }\n.ss-w-ecard[data-kind=\"player\"] .ss-w-thumb { background-color: var(--ss-w-accent); }\n.ss-w-meta { display: flex; flex-direction: column; min-width: 0; }\n.ss-w-kind { font-size: 8.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--ss-w-faint); line-height: 1.3; }\n.ss-w-nm { font-weight: 660; }\n.ss-w-sub { font-size: 11px; color: var(--ss-w-faint); }\n.ss-w-stat { margin-left: auto; text-align: center; }\n.ss-w-stat b { display: block; font-variant-numeric: tabular-nums; }\n.ss-w-stat span { font-size: 9px; text-transform: uppercase; color: var(--ss-w-faint); }\n.ss-w-cards-more { align-self: flex-start; font-size: 11.5px; font-weight: 560; color: var(--ss-w-accent); background: none; border: none; cursor: pointer; padding: 3px 2px; }\n.ss-w-cards-more:hover:not(:disabled) { text-decoration: underline; }\n.ss-w-cards-more:disabled { opacity: .5; cursor: default; }\n\n/* betting insights */\n.ss-w-binsights { display: flex; flex-direction: column; gap: 7px; }\n.ss-w-binsight { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; border-left: 3px solid var(--ss-w-accent); padding: 9px 11px; display: flex; flex-direction: column; gap: 6px; }\n.ss-w-bi-head { display: flex; align-items: flex-start; gap: 10px; }\n.ss-w-bi-mkt { display: flex; flex-direction: column; min-width: 0; }\n.ss-w-bi-market { font-size: 8.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--ss-w-faint); line-height: 1.3; }\n.ss-w-bi-sel { font-weight: 660; }\n.ss-w-bi-odds { margin-left: auto; display: flex; align-items: center; gap: 6px; flex: none; }\n.ss-w-bi-odds b { font-size: 15px; font-variant-numeric: tabular-nums; color: var(--ss-w-accent); }\n.ss-w-bi-book { font-size: 10px; color: var(--ss-w-faint); }\n.ss-w-bi-live { font-size: 8.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: #fff; background: #c0392b; border-radius: 4px; padding: 1px 5px; }\n.ss-w-bi-text { font-size: 12px; color: var(--ss-w-ink); }\n.ss-w-bi-stats { display: flex; flex-wrap: wrap; gap: 12px; }\n.ss-w-bi-stat b { display: block; font-variant-numeric: tabular-nums; font-weight: 660; }\n.ss-w-bi-stat span { font-size: 9px; text-transform: uppercase; color: var(--ss-w-faint); }\n.ss-w-bi-disc { font-size: 10px; font-style: italic; color: var(--ss-w-faint); }\n\n/* action buttons */\n.ss-w-actions { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }\n.ss-w-abtn { font-size: 12px; font-weight: 560; color: var(--ss-w-accent); background: var(--ss-w-panel); border: 1px solid var(--ss-w-accent); border-radius: 16px; padding: 6px 12px; cursor: pointer; }\n.ss-w-abtn:disabled { opacity: .5; cursor: default; }\n.ss-w-abtn-shimmer { width: 140px; height: 30px; border-radius: 16px; background: linear-gradient(90deg, var(--ss-w-bubble), var(--ss-w-line), var(--ss-w-bubble)); background-size: 200% 100%; animation: ss-w-shimmer 1.2s infinite; }\n@keyframes ss-w-shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }\n\n/* intent chips */\n.ss-w-chips { display: flex; flex-wrap: wrap; gap: 6px; }\n.ss-w-chip { font-size: 11.5px; font-weight: 550; color: var(--ss-w-ink); background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 14px; padding: 5px 11px; cursor: pointer; }\n\n/* input */\n.ss-w-input { display: flex; align-items: flex-end; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--ss-w-line); }\n.ss-w-textarea { flex: 1; resize: none; border: 1px solid var(--ss-w-line); border-radius: 12px; padding: 8px 10px; font: inherit; color: inherit; background: var(--ss-w-panel); max-height: 96px; }\n.ss-w-textarea:disabled { opacity: .55; cursor: not-allowed; }\n/* iOS Safari zooms the page when a focused field's font-size is < 16px. Bump it\n on touch devices only, so the desktop 13px design is unchanged. */\n@media (pointer: coarse) {\n .ss-w-textarea { font-size: 16px; }\n}\n.ss-w-send { width: 36px; height: 36px; flex: none; border: none; border-radius: 50%; background: var(--ss-w-accent); color: #fff; cursor: pointer; display: grid; place-items: center; font-size: 16px; }\n.ss-w-stop-glyph { width: 11px; height: 11px; background: currentColor; border-radius: 2px; }\n\n@media (prefers-reduced-motion: reduce) {\n .ss-w-abtn-shimmer { animation: none; }\n}\n";
|
|
37
37
|
|
|
38
38
|
export { StatsWidget, type StatsWidgetConfig, type StatsWidgetProps, WIDGET_CSS };
|
package/dist/index.js
CHANGED
|
@@ -95,16 +95,19 @@ function str(v) {
|
|
|
95
95
|
function num(v) {
|
|
96
96
|
return typeof v === "number" && Number.isFinite(v) ? String(v) : void 0;
|
|
97
97
|
}
|
|
98
|
-
function
|
|
99
|
-
if (!Array.isArray(
|
|
98
|
+
function readStatCells(raw) {
|
|
99
|
+
if (!Array.isArray(raw)) return [];
|
|
100
100
|
const cells = [];
|
|
101
|
-
for (const entry of
|
|
101
|
+
for (const entry of raw) {
|
|
102
102
|
const label = str(entry.label);
|
|
103
103
|
const value = num(entry.value) ?? str(entry.value);
|
|
104
104
|
if (label !== void 0 && value !== void 0) cells.push({ label, value });
|
|
105
105
|
}
|
|
106
106
|
return cells;
|
|
107
107
|
}
|
|
108
|
+
function readStats(card) {
|
|
109
|
+
return readStatCells(card.stats);
|
|
110
|
+
}
|
|
108
111
|
function toCardVM(card) {
|
|
109
112
|
const entityType = str(card.entityType)?.toLowerCase();
|
|
110
113
|
const kind = entityType === "player" ? "player" : entityType === "team" ? "team" : "generic";
|
|
@@ -114,8 +117,7 @@ function toCardVM(card) {
|
|
|
114
117
|
name: card.canonicalName,
|
|
115
118
|
image: str(card.imagePath) ?? str(card.imageUrl) ?? str(card.image_url) ?? str(card.logoUrl) ?? str(card.logo),
|
|
116
119
|
sub: str(card.subtitle) ?? str(card.teamName) ?? str(card.leagueName) ?? str(card.position),
|
|
117
|
-
stats: readStats(card)
|
|
118
|
-
query: card.canonicalName
|
|
120
|
+
stats: readStats(card)
|
|
119
121
|
};
|
|
120
122
|
}
|
|
121
123
|
function toActionVM(action) {
|
|
@@ -131,6 +133,24 @@ function toChipVM(intent) {
|
|
|
131
133
|
function chipFromText(text) {
|
|
132
134
|
return { text };
|
|
133
135
|
}
|
|
136
|
+
function toInsightVM(insight) {
|
|
137
|
+
const market = str(insight.marketLabel) ?? str(insight.marketDeveloperName) ?? "";
|
|
138
|
+
const selection = [str(insight.selectionLabel), str(insight.line)].filter(Boolean).join(" ") || void 0;
|
|
139
|
+
const value = insight.odds?.value;
|
|
140
|
+
const odds = typeof value === "number" && Number.isFinite(value) ? value.toFixed(2) : void 0;
|
|
141
|
+
return {
|
|
142
|
+
id: str(insight.insightId) ?? `${str(insight.ruleId) ?? "insight"}:${num(insight.matchId) ?? ""}`,
|
|
143
|
+
market,
|
|
144
|
+
selection,
|
|
145
|
+
odds,
|
|
146
|
+
// The wire payload carries bookmakerId (not a name); render a name only if one is present.
|
|
147
|
+
bookmaker: str(insight.odds?.bookmakerName),
|
|
148
|
+
isLive: insight.odds?.isLive === true,
|
|
149
|
+
text: str(insight.text) ?? "",
|
|
150
|
+
stats: readStatCells(insight.stats),
|
|
151
|
+
disclaimer: str(insight.disclaimer)
|
|
152
|
+
};
|
|
153
|
+
}
|
|
134
154
|
|
|
135
155
|
// src/reducer.ts
|
|
136
156
|
var POPUP_MAX = 160;
|
|
@@ -157,6 +177,8 @@ function applyEvent(state, event) {
|
|
|
157
177
|
return { ...state, messages: mapActive(state, (t) => ({ ...t, cards: [...t.cards, toCardVM(event.data.card)] })) };
|
|
158
178
|
case "action_button":
|
|
159
179
|
return { ...state, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, actions: [...t.actions, toActionVM(event.data.action)] })) };
|
|
180
|
+
case "betting_insight":
|
|
181
|
+
return { ...state, messages: mapActive(state, (t) => ({ ...t, insights: [...t.insights, toInsightVM(event.data.insight)] })) };
|
|
160
182
|
case "intent_chip": {
|
|
161
183
|
const chip = toChipVM(event.data.intent);
|
|
162
184
|
return chip ? { ...state, starters: [...state.starters, chip] } : state;
|
|
@@ -174,6 +196,7 @@ function applyEvent(state, event) {
|
|
|
174
196
|
return { ...state, error: suppress ? state.error : event.data, isStreaming: false, status: null, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, done: true })) };
|
|
175
197
|
}
|
|
176
198
|
}
|
|
199
|
+
return state;
|
|
177
200
|
}
|
|
178
201
|
function reducer(state, action) {
|
|
179
202
|
switch (action.kind) {
|
|
@@ -183,11 +206,11 @@ function reducer(state, action) {
|
|
|
183
206
|
return { ...state, isOpen: false, isStreaming: false, status: null, actionsLoading: false };
|
|
184
207
|
case "USER_SENT": {
|
|
185
208
|
const user = { role: "user", id: action.userId, text: action.displayText ?? action.input.message };
|
|
186
|
-
const assistant = { role: "assistant", id: action.assistantId, text: "", cards: [], actions: [], done: false };
|
|
209
|
+
const assistant = { role: "assistant", id: action.assistantId, text: "", cards: [], actions: [], insights: [], done: false };
|
|
187
210
|
return { ...state, messages: [...state.messages, user, assistant], isStreaming: true, status: null, actionsLoading: false, starters: [], error: null, lastUserInput: action.input, lastDisplayText: action.displayText ?? null };
|
|
188
211
|
}
|
|
189
212
|
case "GREETING_SENT": {
|
|
190
|
-
const assistant = { role: "assistant", id: action.assistantId, text: "", cards: [], actions: [], done: false, isGreeting: true };
|
|
213
|
+
const assistant = { role: "assistant", id: action.assistantId, text: "", cards: [], actions: [], insights: [], done: false, isGreeting: true };
|
|
191
214
|
return { ...state, messages: [...state.messages, assistant], isStreaming: true, status: null, error: null };
|
|
192
215
|
}
|
|
193
216
|
case "DISMISS_POPUP":
|
|
@@ -288,9 +311,6 @@ function SendIcon() {
|
|
|
288
311
|
function CloseIcon() {
|
|
289
312
|
return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", width: "1em", height: "1em", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { fill: "none", d: "M18 6L6 18M6 6l12 12", stroke: "currentColor", strokeWidth: "2" }) });
|
|
290
313
|
}
|
|
291
|
-
function ChevronIcon() {
|
|
292
|
-
return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", width: "1em", height: "1em", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { fill: "none", stroke: "currentColor", strokeWidth: "2", d: "M9 6l6 6-6 6" }) });
|
|
293
|
-
}
|
|
294
314
|
|
|
295
315
|
// src/components/GreetingBubble.tsx
|
|
296
316
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
@@ -349,13 +369,13 @@ var MAX_VISIBLE = 3;
|
|
|
349
369
|
function initials(name) {
|
|
350
370
|
return name.split(/\s+/).slice(0, 2).map((w) => w[0] ?? "").join("").toUpperCase();
|
|
351
371
|
}
|
|
352
|
-
function EntityCardList({ cards, disabled,
|
|
372
|
+
function EntityCardList({ cards, disabled, showLessLabel = "Show less", showMoreLabel = (n) => `Show ${n} more` }) {
|
|
353
373
|
const [expanded, setExpanded] = useState(false);
|
|
354
374
|
if (cards.length === 0) return null;
|
|
355
375
|
const visible = expanded ? cards : cards.slice(0, MAX_VISIBLE);
|
|
356
376
|
const overflow = cards.length - MAX_VISIBLE;
|
|
357
377
|
return /* @__PURE__ */ jsxs4("div", { className: "ss-w-cards", children: [
|
|
358
|
-
visible.map((c) => /* @__PURE__ */ jsxs4("
|
|
378
|
+
visible.map((c) => /* @__PURE__ */ jsxs4("div", { className: "ss-w-ecard", "data-kind": c.kind, children: [
|
|
359
379
|
/* @__PURE__ */ jsx6(
|
|
360
380
|
"span",
|
|
361
381
|
{
|
|
@@ -372,82 +392,125 @@ function EntityCardList({ cards, disabled, onSelect, showLessLabel = "Show less"
|
|
|
372
392
|
c.stats.map((s) => /* @__PURE__ */ jsxs4("span", { className: "ss-w-stat", children: [
|
|
373
393
|
/* @__PURE__ */ jsx6("b", { children: s.value }),
|
|
374
394
|
/* @__PURE__ */ jsx6("span", { children: s.label })
|
|
375
|
-
] }, s.label))
|
|
376
|
-
/* @__PURE__ */ jsx6("span", { className: "ss-w-chev", children: /* @__PURE__ */ jsx6(ChevronIcon, {}) })
|
|
395
|
+
] }, s.label))
|
|
377
396
|
] }, c.id)),
|
|
378
397
|
overflow > 0 ? /* @__PURE__ */ jsx6("button", { type: "button", className: "ss-w-cards-more", disabled, onClick: () => setExpanded((v) => !v), children: expanded ? showLessLabel : showMoreLabel(overflow) }) : null
|
|
379
398
|
] });
|
|
380
399
|
}
|
|
381
400
|
|
|
401
|
+
// src/components/BettingInsightList.tsx
|
|
402
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
403
|
+
function BettingInsightList({ insights }) {
|
|
404
|
+
if (!insights || insights.length === 0) return null;
|
|
405
|
+
return /* @__PURE__ */ jsx7("div", { className: "ss-w-binsights", children: insights.map((it) => /* @__PURE__ */ jsxs5("div", { className: "ss-w-binsight", children: [
|
|
406
|
+
/* @__PURE__ */ jsxs5("div", { className: "ss-w-bi-head", children: [
|
|
407
|
+
/* @__PURE__ */ jsxs5("span", { className: "ss-w-bi-mkt", children: [
|
|
408
|
+
/* @__PURE__ */ jsx7("span", { className: "ss-w-bi-market", children: it.market }),
|
|
409
|
+
it.selection ? /* @__PURE__ */ jsx7("span", { className: "ss-w-bi-sel", children: it.selection }) : null
|
|
410
|
+
] }),
|
|
411
|
+
it.odds ? /* @__PURE__ */ jsxs5("span", { className: "ss-w-bi-odds", children: [
|
|
412
|
+
it.isLive ? /* @__PURE__ */ jsx7("span", { className: "ss-w-bi-live", children: "Live" }) : null,
|
|
413
|
+
/* @__PURE__ */ jsx7("b", { children: it.odds }),
|
|
414
|
+
it.bookmaker ? /* @__PURE__ */ jsx7("span", { className: "ss-w-bi-book", children: it.bookmaker }) : null
|
|
415
|
+
] }) : null
|
|
416
|
+
] }),
|
|
417
|
+
it.text ? /* @__PURE__ */ jsx7("p", { className: "ss-w-bi-text", children: it.text }) : null,
|
|
418
|
+
it.stats.length > 0 ? /* @__PURE__ */ jsx7("div", { className: "ss-w-bi-stats", children: it.stats.map((s) => /* @__PURE__ */ jsxs5("span", { className: "ss-w-bi-stat", children: [
|
|
419
|
+
/* @__PURE__ */ jsx7("b", { children: s.value }),
|
|
420
|
+
/* @__PURE__ */ jsx7("span", { children: s.label })
|
|
421
|
+
] }, `${s.label}:${s.value}`)) }) : null,
|
|
422
|
+
it.disclaimer ? /* @__PURE__ */ jsx7("p", { className: "ss-w-bi-disc", children: it.disclaimer }) : null
|
|
423
|
+
] }, it.id)) });
|
|
424
|
+
}
|
|
425
|
+
|
|
382
426
|
// src/components/ActionButtons.tsx
|
|
383
|
-
import { Fragment, jsx as
|
|
427
|
+
import { Fragment, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
384
428
|
function ActionButtons({ actions, loading, disabled, onAct }) {
|
|
385
429
|
if (actions.length === 0 && !loading) return null;
|
|
386
|
-
return /* @__PURE__ */
|
|
387
|
-
actions.map((a, i) => /* @__PURE__ */
|
|
388
|
-
actions.length === 0 && loading ? /* @__PURE__ */
|
|
389
|
-
/* @__PURE__ */
|
|
390
|
-
/* @__PURE__ */
|
|
430
|
+
return /* @__PURE__ */ jsxs6("div", { className: "ss-w-actions", children: [
|
|
431
|
+
actions.map((a, i) => /* @__PURE__ */ jsx8("button", { type: "button", className: "ss-w-abtn", disabled, onClick: () => onAct(a), children: a.label }, `${a.label}-${i}`)),
|
|
432
|
+
actions.length === 0 && loading ? /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
433
|
+
/* @__PURE__ */ jsx8("span", { className: "ss-w-abtn-shimmer" }),
|
|
434
|
+
/* @__PURE__ */ jsx8("span", { className: "ss-w-abtn-shimmer" })
|
|
391
435
|
] }) : null
|
|
392
436
|
] });
|
|
393
437
|
}
|
|
394
438
|
|
|
395
439
|
// src/components/ChatMessage.tsx
|
|
396
|
-
import { jsx as
|
|
397
|
-
function ChatMessage({ message, disabled, onAct,
|
|
440
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
441
|
+
function ChatMessage({ message, disabled, onAct, ui }) {
|
|
398
442
|
if (message.role === "user") {
|
|
399
|
-
return /* @__PURE__ */
|
|
443
|
+
return /* @__PURE__ */ jsx9("div", { className: "ss-w-msg ss-w-user", children: /* @__PURE__ */ jsx9("div", { className: "ss-w-bubble", children: message.text }) });
|
|
400
444
|
}
|
|
401
|
-
return /* @__PURE__ */
|
|
402
|
-
message.text ? /* @__PURE__ */
|
|
403
|
-
/* @__PURE__ */
|
|
404
|
-
/* @__PURE__ */
|
|
445
|
+
return /* @__PURE__ */ jsxs7("div", { className: "ss-w-msg ss-w-bot", children: [
|
|
446
|
+
message.text ? /* @__PURE__ */ jsx9(Markdown, { text: message.text }) : null,
|
|
447
|
+
/* @__PURE__ */ jsx9(EntityCardList, { cards: message.cards, disabled, showLessLabel: ui?.showLess, showMoreLabel: ui?.showMore }),
|
|
448
|
+
/* @__PURE__ */ jsx9(BettingInsightList, { insights: message.insights }),
|
|
449
|
+
/* @__PURE__ */ jsx9(ActionButtons, { actions: message.actions, loading: false, disabled, onAct })
|
|
405
450
|
] });
|
|
406
451
|
}
|
|
407
452
|
|
|
408
453
|
// src/components/IntentChips.tsx
|
|
409
|
-
import { jsx as
|
|
454
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
410
455
|
function IntentChips({ chips, onPick }) {
|
|
411
456
|
if (chips.length === 0) return null;
|
|
412
|
-
return /* @__PURE__ */
|
|
457
|
+
return /* @__PURE__ */ jsx10("div", { className: "ss-w-chips", children: chips.map((c, i) => /* @__PURE__ */ jsx10("button", { type: "button", className: "ss-w-chip", onClick: () => onPick(c.text), children: c.text }, `${c.text}-${i}`)) });
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// src/scroll.ts
|
|
461
|
+
var PIN_THRESHOLD = 48;
|
|
462
|
+
function isPinnedToBottom(el, threshold = PIN_THRESHOLD) {
|
|
463
|
+
return el.scrollHeight - el.scrollTop - el.clientHeight <= threshold;
|
|
413
464
|
}
|
|
414
465
|
|
|
415
466
|
// src/components/MessageList.tsx
|
|
416
|
-
import { jsx as
|
|
467
|
+
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
417
468
|
function MessageList({ controller, ui }) {
|
|
418
469
|
const { state, send } = controller;
|
|
470
|
+
const listRef = useRef2(null);
|
|
419
471
|
const endRef = useRef2(null);
|
|
472
|
+
const pinnedRef = useRef2(true);
|
|
420
473
|
useEffect2(() => {
|
|
421
|
-
endRef.current?.scrollIntoView({ block: "end" });
|
|
474
|
+
if (pinnedRef.current) endRef.current?.scrollIntoView({ block: "end" });
|
|
422
475
|
}, [state.messages, state.status]);
|
|
423
476
|
const empty = state.messages.length === 0;
|
|
424
|
-
return /* @__PURE__ */
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
ui
|
|
477
|
+
return /* @__PURE__ */ jsxs8(
|
|
478
|
+
"div",
|
|
479
|
+
{
|
|
480
|
+
className: "ss-w-list",
|
|
481
|
+
"aria-live": "polite",
|
|
482
|
+
ref: listRef,
|
|
483
|
+
onScroll: () => {
|
|
484
|
+
if (listRef.current) pinnedRef.current = isPinnedToBottom(listRef.current);
|
|
433
485
|
},
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
486
|
+
children: [
|
|
487
|
+
state.messages.map((m) => /* @__PURE__ */ jsx11(
|
|
488
|
+
ChatMessage,
|
|
489
|
+
{
|
|
490
|
+
message: m,
|
|
491
|
+
disabled: state.isStreaming,
|
|
492
|
+
onAct: (a) => send(a.message, { actionId: a.actionId, displayText: a.label }),
|
|
493
|
+
ui
|
|
494
|
+
},
|
|
495
|
+
m.id
|
|
496
|
+
)),
|
|
497
|
+
state.isStreaming && state.actionsLoading ? /* @__PURE__ */ jsx11(ActionButtons, { actions: [], loading: true, onAct: () => {
|
|
498
|
+
} }) : null,
|
|
499
|
+
state.status ? /* @__PURE__ */ jsx11("div", { className: "ss-w-status", children: state.status }) : null,
|
|
500
|
+
state.error ? /* @__PURE__ */ jsxs8("div", { className: "ss-w-error", role: "alert", children: [
|
|
501
|
+
/* @__PURE__ */ jsx11("span", { children: "message" in state.error ? state.error.message : ui.somethingWentWrong }),
|
|
502
|
+
/* @__PURE__ */ jsx11("button", { type: "button", className: "ss-w-retry", onClick: () => controller.retry(), children: ui.retry })
|
|
503
|
+
] }) : null,
|
|
504
|
+
empty ? /* @__PURE__ */ jsx11(IntentChips, { chips: state.starters, onPick: (t) => send(t) }) : null,
|
|
505
|
+
/* @__PURE__ */ jsx11("div", { ref: endRef })
|
|
506
|
+
]
|
|
507
|
+
}
|
|
508
|
+
);
|
|
446
509
|
}
|
|
447
510
|
|
|
448
511
|
// src/components/ChatInput.tsx
|
|
449
512
|
import { useState as useState2 } from "react";
|
|
450
|
-
import { jsx as
|
|
513
|
+
import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
451
514
|
function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop response", sendLabel = "Send message" }) {
|
|
452
515
|
const [value, setValue] = useState2("");
|
|
453
516
|
const submit = () => {
|
|
@@ -462,14 +525,14 @@ function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop r
|
|
|
462
525
|
submit();
|
|
463
526
|
}
|
|
464
527
|
};
|
|
465
|
-
return /* @__PURE__ */
|
|
466
|
-
/* @__PURE__ */
|
|
467
|
-
streaming ? /* @__PURE__ */
|
|
528
|
+
return /* @__PURE__ */ jsxs9("div", { className: "ss-w-input", children: [
|
|
529
|
+
/* @__PURE__ */ jsx12("textarea", { className: "ss-w-textarea", rows: 1, placeholder, value, disabled: streaming, onChange: (e) => setValue(e.target.value), onKeyDown }),
|
|
530
|
+
streaming ? /* @__PURE__ */ jsx12("button", { type: "button", className: "ss-w-send ss-w-stop", "aria-label": stopLabel, onClick: onStop, children: /* @__PURE__ */ jsx12("span", { className: "ss-w-stop-glyph" }) }) : /* @__PURE__ */ jsx12("button", { type: "button", className: "ss-w-send", "aria-label": sendLabel, onClick: submit, children: /* @__PURE__ */ jsx12(SendIcon, {}) })
|
|
468
531
|
] });
|
|
469
532
|
}
|
|
470
533
|
|
|
471
534
|
// src/components/ChatPanel.tsx
|
|
472
|
-
import { jsx as
|
|
535
|
+
import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
473
536
|
var FULLSCREEN_QUERY = "(max-width: 639px)";
|
|
474
537
|
function useIsModal() {
|
|
475
538
|
const [modal, setModal] = useState3(false);
|
|
@@ -493,10 +556,10 @@ function ChatPanel({ controller, ui }) {
|
|
|
493
556
|
window.addEventListener("keydown", onKey);
|
|
494
557
|
return () => window.removeEventListener("keydown", onKey);
|
|
495
558
|
}, [close]);
|
|
496
|
-
return /* @__PURE__ */
|
|
497
|
-
/* @__PURE__ */
|
|
498
|
-
/* @__PURE__ */
|
|
499
|
-
/* @__PURE__ */
|
|
559
|
+
return /* @__PURE__ */ jsxs10("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
|
|
560
|
+
/* @__PURE__ */ jsx13(ChatHeader, { onClose: close, closeLabel: ui.closeChat }),
|
|
561
|
+
/* @__PURE__ */ jsx13(MessageList, { controller, ui }),
|
|
562
|
+
/* @__PURE__ */ jsx13(ChatInput, { placeholder: ui.placeholder, streaming: state.isStreaming, onSend: (t) => send(t), onStop: stop, stopLabel: ui.stopResponse, sendLabel: ui.sendMessage })
|
|
500
563
|
] });
|
|
501
564
|
}
|
|
502
565
|
|
|
@@ -580,7 +643,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
580
643
|
|
|
581
644
|
/* entity cards */
|
|
582
645
|
.ss-w-cards { display: flex; flex-direction: column; gap: 7px; }
|
|
583
|
-
.ss-w-ecard { display: flex; align-items: center; gap: 11px; width: 100%; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; padding: 8px 11px; text-align: left;
|
|
646
|
+
.ss-w-ecard { display: flex; align-items: center; gap: 11px; width: 100%; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; padding: 8px 11px; text-align: left; }
|
|
584
647
|
.ss-w-thumb { width: 40px; height: 40px; flex: none; border-radius: 50%; display: grid; place-items: center; font-size: 13px; font-weight: 700; color: #fff; background-color: var(--ss-w-nav); background-size: cover; background-position: center; }
|
|
585
648
|
.ss-w-thumb.ss-w-team { border-radius: 10px; }
|
|
586
649
|
.ss-w-ecard[data-kind="player"] .ss-w-thumb { background-color: var(--ss-w-accent); }
|
|
@@ -591,10 +654,26 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
591
654
|
.ss-w-stat { margin-left: auto; text-align: center; }
|
|
592
655
|
.ss-w-stat b { display: block; font-variant-numeric: tabular-nums; }
|
|
593
656
|
.ss-w-stat span { font-size: 9px; text-transform: uppercase; color: var(--ss-w-faint); }
|
|
594
|
-
.ss-w-chev { color: var(--ss-w-faint); font-size: 16px; display: grid; place-items: center; }
|
|
595
657
|
.ss-w-cards-more { align-self: flex-start; font-size: 11.5px; font-weight: 560; color: var(--ss-w-accent); background: none; border: none; cursor: pointer; padding: 3px 2px; }
|
|
596
658
|
.ss-w-cards-more:hover:not(:disabled) { text-decoration: underline; }
|
|
597
|
-
.ss-w-
|
|
659
|
+
.ss-w-cards-more:disabled { opacity: .5; cursor: default; }
|
|
660
|
+
|
|
661
|
+
/* betting insights */
|
|
662
|
+
.ss-w-binsights { display: flex; flex-direction: column; gap: 7px; }
|
|
663
|
+
.ss-w-binsight { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; border-left: 3px solid var(--ss-w-accent); padding: 9px 11px; display: flex; flex-direction: column; gap: 6px; }
|
|
664
|
+
.ss-w-bi-head { display: flex; align-items: flex-start; gap: 10px; }
|
|
665
|
+
.ss-w-bi-mkt { display: flex; flex-direction: column; min-width: 0; }
|
|
666
|
+
.ss-w-bi-market { font-size: 8.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--ss-w-faint); line-height: 1.3; }
|
|
667
|
+
.ss-w-bi-sel { font-weight: 660; }
|
|
668
|
+
.ss-w-bi-odds { margin-left: auto; display: flex; align-items: center; gap: 6px; flex: none; }
|
|
669
|
+
.ss-w-bi-odds b { font-size: 15px; font-variant-numeric: tabular-nums; color: var(--ss-w-accent); }
|
|
670
|
+
.ss-w-bi-book { font-size: 10px; color: var(--ss-w-faint); }
|
|
671
|
+
.ss-w-bi-live { font-size: 8.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: #fff; background: #c0392b; border-radius: 4px; padding: 1px 5px; }
|
|
672
|
+
.ss-w-bi-text { font-size: 12px; color: var(--ss-w-ink); }
|
|
673
|
+
.ss-w-bi-stats { display: flex; flex-wrap: wrap; gap: 12px; }
|
|
674
|
+
.ss-w-bi-stat b { display: block; font-variant-numeric: tabular-nums; font-weight: 660; }
|
|
675
|
+
.ss-w-bi-stat span { font-size: 9px; text-transform: uppercase; color: var(--ss-w-faint); }
|
|
676
|
+
.ss-w-bi-disc { font-size: 10px; font-style: italic; color: var(--ss-w-faint); }
|
|
598
677
|
|
|
599
678
|
/* action buttons */
|
|
600
679
|
.ss-w-actions { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
|
|
@@ -611,6 +690,11 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
611
690
|
.ss-w-input { display: flex; align-items: flex-end; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--ss-w-line); }
|
|
612
691
|
.ss-w-textarea { flex: 1; resize: none; border: 1px solid var(--ss-w-line); border-radius: 12px; padding: 8px 10px; font: inherit; color: inherit; background: var(--ss-w-panel); max-height: 96px; }
|
|
613
692
|
.ss-w-textarea:disabled { opacity: .55; cursor: not-allowed; }
|
|
693
|
+
/* iOS Safari zooms the page when a focused field's font-size is < 16px. Bump it
|
|
694
|
+
on touch devices only, so the desktop 13px design is unchanged. */
|
|
695
|
+
@media (pointer: coarse) {
|
|
696
|
+
.ss-w-textarea { font-size: 16px; }
|
|
697
|
+
}
|
|
614
698
|
.ss-w-send { width: 36px; height: 36px; flex: none; border: none; border-radius: 50%; background: var(--ss-w-accent); color: #fff; cursor: pointer; display: grid; place-items: center; font-size: 16px; }
|
|
615
699
|
.ss-w-stop-glyph { width: 11px; height: 11px; background: currentColor; border-radius: 2px; }
|
|
616
700
|
|
|
@@ -620,7 +704,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
620
704
|
`;
|
|
621
705
|
|
|
622
706
|
// src/StatsWidget.tsx
|
|
623
|
-
import { jsx as
|
|
707
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
624
708
|
function buildClient(props) {
|
|
625
709
|
try {
|
|
626
710
|
if ("client" in props && props.client) {
|
|
@@ -656,7 +740,7 @@ function StatsWidget(props) {
|
|
|
656
740
|
}, [built, ui.injectStyles]);
|
|
657
741
|
if (!built) return null;
|
|
658
742
|
const attrs = themeAttrs(ui);
|
|
659
|
-
return /* @__PURE__ */
|
|
743
|
+
return /* @__PURE__ */ jsx14("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__ */ jsx14(ChatPanel, { controller, ui }) : /* @__PURE__ */ jsx14(
|
|
660
744
|
ChatFab,
|
|
661
745
|
{
|
|
662
746
|
label: ui.launcherLabel,
|