@tradecanvas/chart 0.6.0 → 0.7.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/README.md +570 -545
- package/dist/Chart-0R7hFD6z.cjs +2 -0
- package/dist/Chart-0R7hFD6z.cjs.map +1 -0
- package/dist/{Chart-CrrTKx3r.js → Chart-BodmeuC5.js} +116 -47
- package/dist/Chart-BodmeuC5.js.map +1 -0
- package/dist/Chart.d.ts +24 -0
- package/dist/Chart.d.ts.map +1 -1
- package/dist/charts/ChartTypeStrategy.d.ts.map +1 -1
- package/dist/grid/ChartGrid.d.ts +39 -0
- package/dist/grid/ChartGrid.d.ts.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +183 -31
- package/dist/index.js.map +1 -1
- package/dist/widget/ChartWidget.d.ts +5 -0
- package/dist/widget/ChartWidget.d.ts.map +1 -1
- package/dist/widget/WidgetCommandPalette.d.ts +39 -0
- package/dist/widget/WidgetCommandPalette.d.ts.map +1 -0
- package/dist/widget/index.cjs +877 -739
- package/dist/widget/index.cjs.map +1 -1
- package/dist/widget/index.js +263 -5
- package/dist/widget/index.js.map +1 -1
- package/dist/widget/widgetConfig.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/Chart-CrrTKx3r.js.map +0 -1
- package/dist/Chart-DoR8L8Uk.cjs +0 -2
- package/dist/Chart-DoR8L8Uk.cjs.map +0 -1
package/dist/widget/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as e } from "../Chart-
|
|
1
|
+
import { t as e } from "../Chart-BodmeuC5.js";
|
|
2
2
|
import { DARK_THEME as t, LIGHT_THEME as n } from "@tradecanvas/commons";
|
|
3
3
|
//#region src/widget/widgetConfig.ts
|
|
4
4
|
var r = [
|
|
@@ -54,6 +54,22 @@ var r = [
|
|
|
54
54
|
{
|
|
55
55
|
label: "Baseline",
|
|
56
56
|
value: "baseline"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
label: "Volume Candles",
|
|
60
|
+
value: "volumeCandles"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
label: "HLC Area",
|
|
64
|
+
value: "hlcArea"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
label: "Step Line",
|
|
68
|
+
value: "stepLine"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
label: "Line + Markers",
|
|
72
|
+
value: "lineWithMarkers"
|
|
57
73
|
}
|
|
58
74
|
], a = [
|
|
59
75
|
{
|
|
@@ -179,6 +195,11 @@ var r = [
|
|
|
179
195
|
name: "EMA",
|
|
180
196
|
type: "overlay"
|
|
181
197
|
},
|
|
198
|
+
{
|
|
199
|
+
id: "hma",
|
|
200
|
+
name: "Hull MA",
|
|
201
|
+
type: "overlay"
|
|
202
|
+
},
|
|
182
203
|
{
|
|
183
204
|
id: "bb",
|
|
184
205
|
name: "Bollinger Bands",
|
|
@@ -189,6 +210,11 @@ var r = [
|
|
|
189
210
|
name: "VWAP",
|
|
190
211
|
type: "overlay"
|
|
191
212
|
},
|
|
213
|
+
{
|
|
214
|
+
id: "avwap",
|
|
215
|
+
name: "Anchored VWAP",
|
|
216
|
+
type: "overlay"
|
|
217
|
+
},
|
|
192
218
|
{
|
|
193
219
|
id: "ichimoku",
|
|
194
220
|
name: "Ichimoku Cloud",
|
|
@@ -214,6 +240,21 @@ var r = [
|
|
|
214
240
|
name: "Donchian Channel",
|
|
215
241
|
type: "overlay"
|
|
216
242
|
},
|
|
243
|
+
{
|
|
244
|
+
id: "pivots",
|
|
245
|
+
name: "Pivot Points",
|
|
246
|
+
type: "overlay"
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
id: "zigzag",
|
|
250
|
+
name: "ZigZag",
|
|
251
|
+
type: "overlay"
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
id: "lrc",
|
|
255
|
+
name: "Linear Regression Channel",
|
|
256
|
+
type: "overlay"
|
|
257
|
+
},
|
|
217
258
|
{
|
|
218
259
|
id: "rsi",
|
|
219
260
|
name: "RSI",
|
|
@@ -294,6 +335,16 @@ var r = [
|
|
|
294
335
|
name: "Acc/Dist",
|
|
295
336
|
type: "panel"
|
|
296
337
|
},
|
|
338
|
+
{
|
|
339
|
+
id: "ao",
|
|
340
|
+
name: "Awesome Oscillator",
|
|
341
|
+
type: "panel"
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
id: "chaikinOsc",
|
|
345
|
+
name: "Chaikin Oscillator",
|
|
346
|
+
type: "panel"
|
|
347
|
+
},
|
|
297
348
|
{
|
|
298
349
|
id: "volumeProfile",
|
|
299
350
|
name: "Volume Profile",
|
|
@@ -330,7 +381,7 @@ var r = [
|
|
|
330
381
|
autoScale: !0,
|
|
331
382
|
crosshairMode: "magnet",
|
|
332
383
|
numberLocale: "en-US"
|
|
333
|
-
}, u = "/* === TradeCanvas Widget Styles === */\n\n.tcw-root {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n font-size: 13px;\n color: #d1d4dc;\n background: #131722;\n position: relative;\n overflow: hidden;\n\n /* Dark theme tokens (default) */\n --tcw-bg: #131722;\n --tcw-bg-elevated: #1E222D;\n --tcw-border: #2A2E39;\n --tcw-text: #d1d4dc;\n --tcw-text-dim: #b2b5be;\n --tcw-text-muted: #787b86;\n --tcw-accent: #2962ff;\n --tcw-accent-dim: rgba(41,98,255,0.15);\n --tcw-accent-glow: rgba(41,98,255,0.12);\n --tcw-red: #ef5350;\n --tcw-green: #26a69a;\n --tcw-transition: 0.15s ease;\n --tcw-radius-lg: 8px;\n --tcw-font-mono: 'SF Mono', 'Fira Code', 'Consolas', monospace;\n --tcw-hover-bg: rgba(255,255,255,0.04);\n}\n\n.tcw-root[data-tcw-theme=\"light\"] {\n color: #131722;\n background: #ffffff;\n\n --tcw-bg: #ffffff;\n --tcw-bg-elevated: #f0f3fa;\n --tcw-border: #e0e3eb;\n --tcw-text: #131722;\n --tcw-text-dim: #434651;\n --tcw-text-muted: #787b86;\n --tcw-accent: #2962ff;\n --tcw-accent-dim: rgba(41,98,255,0.1);\n --tcw-accent-glow: rgba(41,98,255,0.08);\n --tcw-red: #ef5350;\n --tcw-green: #26a69a;\n --tcw-hover-bg: rgba(0,0,0,0.04);\n}\n\n/* === Toolbar === */\n\n.tcw-toolbar {\n display: flex;\n align-items: center;\n gap: 0;\n padding: 0 12px;\n height: 40px;\n border-bottom: 1px solid var(--tcw-border);\n background: var(--tcw-bg-elevated);\n flex-shrink: 0;\n position: relative;\n z-index: 20;\n}\n\n.tcw-toolbar-symbol {\n font-size: 13px;\n font-weight: 700;\n color: var(--tcw-text);\n padding: 0 10px;\n white-space: nowrap;\n letter-spacing: -0.01em;\n cursor: pointer;\n border: none;\n background: none;\n font-family: inherit;\n}\n\n.tcw-toolbar-sep {\n width: 1px;\n height: 20px;\n background: var(--tcw-border);\n flex-shrink: 0;\n}\n\n.tcw-toolbar-group {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 0 8px;\n}\n\n.tcw-toolbar-spacer {\n flex: 1;\n}\n\n.tcw-btn {\n padding: 4px 8px;\n font-size: 12px;\n font-family: inherit;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--tcw-text-dim);\n cursor: pointer;\n transition: all var(--tcw-transition);\n white-space: nowrap;\n line-height: 1;\n}\n\n.tcw-btn:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-btn.tcw-active {\n background: var(--tcw-accent);\n color: white;\n}\n\n.tcw-btn-icon {\n width: 32px;\n height: 32px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-family: inherit;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n transition: all var(--tcw-transition);\n line-height: 1;\n position: relative;\n}\n\n.tcw-btn-icon:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-badge-count {\n font-size: 10px;\n color: var(--tcw-accent);\n background: var(--tcw-accent-dim);\n padding: 0 4px;\n border-radius: 8px;\n font-weight: 600;\n}\n\n.tcw-indicator-chips {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 0 4px;\n flex-wrap: nowrap;\n overflow: hidden;\n}\n\n.tcw-indicator-chip {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 6px 2px 8px;\n font-size: 11px;\n font-weight: 500;\n background: var(--tcw-accent-dim);\n color: var(--tcw-accent);\n border-radius: 4px;\n white-space: nowrap;\n line-height: 1.4;\n}\n\n.tcw-chip-remove {\n cursor: pointer;\n opacity: 0.6;\n padding: 0 2px;\n transition: opacity var(--tcw-transition);\n border: none;\n background: none;\n color: inherit;\n display: inline-flex;\n align-items: center;\n}\n\n.tcw-chip-remove:hover {\n opacity: 1;\n}\n\n/* === Dropdown === */\n\n.tcw-dropdown-trigger {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n font-size: 12px;\n font-family: inherit;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--tcw-text-dim);\n cursor: pointer;\n transition: all var(--tcw-transition);\n white-space: nowrap;\n line-height: 1;\n}\n\n.tcw-dropdown-trigger:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-dropdown {\n position: absolute;\n top: 100%;\n margin-top: 4px;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-radius-lg);\n box-shadow: 0 8px 32px rgba(0,0,0,0.4);\n z-index: 50;\n padding: 4px 0;\n max-height: 400px;\n overflow-y: auto;\n}\n\n.tcw-dropdown-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 12px;\n font-size: 12px;\n color: var(--tcw-text-dim);\n cursor: pointer;\n transition: background var(--tcw-transition), color var(--tcw-transition);\n width: 100%;\n border: none;\n background: none;\n font-family: inherit;\n text-align: left;\n}\n\n.tcw-dropdown-item:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-dropdown-item.tcw-active {\n color: var(--tcw-accent);\n}\n\n.tcw-dropdown-label {\n text-transform: uppercase;\n font-size: 10px;\n color: var(--tcw-text-muted);\n letter-spacing: 0.05em;\n padding: 6px 12px;\n font-weight: 600;\n}\n\n.tcw-dropdown-divider {\n border-top: 1px solid var(--tcw-border);\n margin: 4px 0;\n}\n\n.tcw-tag {\n font-size: 10px;\n color: var(--tcw-text-muted);\n padding: 1px 5px;\n border-radius: 3px;\n background: var(--tcw-hover-bg);\n}\n\n/* === Body === */\n\n.tcw-body {\n display: flex;\n flex: 1;\n min-height: 0;\n}\n\n.tcw-chart-container {\n flex: 1;\n min-width: 0;\n min-height: 0;\n width: 100%;\n height: 100%;\n}\n\n/* === Sidebar === */\n\n.tcw-sidebar {\n width: 36px;\n flex-shrink: 0;\n background: var(--tcw-bg-elevated);\n border-right: 1px solid var(--tcw-border);\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 4px 0;\n overflow: visible;\n}\n\n.tcw-tool-group-wrap {\n position: relative;\n}\n\n.tcw-sidebar-btn {\n width: 36px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n font-family: inherit;\n transition: all var(--tcw-transition);\n position: relative;\n flex-shrink: 0;\n line-height: 1;\n}\n\n.tcw-sidebar-btn:hover {\n color: var(--tcw-text);\n background: var(--tcw-hover-bg);\n}\n\n.tcw-sidebar-btn.tcw-active {\n color: var(--tcw-accent);\n background: var(--tcw-accent-glow);\n}\n\n.tcw-sidebar-btn.tcw-danger:hover {\n color: var(--tcw-red);\n background: rgba(239,68,68,0.1);\n}\n\n.tcw-multi-dot {\n position: absolute;\n bottom: 2px;\n right: 2px;\n width: 4px;\n height: 4px;\n border-radius: 50%;\n background: var(--tcw-text-muted);\n}\n\n.tcw-sidebar-divider {\n width: 20px;\n height: 1px;\n background: var(--tcw-border);\n margin: 4px 0;\n flex-shrink: 0;\n}\n\n.tcw-sidebar-spacer {\n flex: 1;\n}\n\n/* === Flyout === */\n\n.tcw-flyout {\n position: absolute;\n left: 100%;\n top: 0;\n margin-left: 2px;\n min-width: 160px;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-radius-lg);\n box-shadow: 0 8px 32px rgba(0,0,0,0.4);\n z-index: 30;\n padding: 4px 0;\n}\n\n.tcw-flyout-header {\n text-transform: uppercase;\n font-size: 10px;\n color: var(--tcw-text-muted);\n letter-spacing: 0.05em;\n padding: 6px 12px;\n font-weight: 600;\n}\n\n.tcw-flyout-item {\n padding: 6px 12px;\n font-size: 12px;\n color: var(--tcw-text-dim);\n cursor: pointer;\n width: 100%;\n display: block;\n border: none;\n background: none;\n text-align: left;\n font-family: inherit;\n transition: background var(--tcw-transition), color var(--tcw-transition);\n}\n\n.tcw-flyout-item:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-flyout-item.tcw-active {\n color: var(--tcw-accent);\n}\n\n/* === Modal === */\n\n.tcw-modal-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0,0,0,0.5);\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n z-index: 100;\n}\n\n.tcw-modal {\n position: fixed;\n z-index: 101;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-radius-lg);\n width: 480px;\n max-width: 90vw;\n max-height: 80vh;\n display: flex;\n flex-direction: column;\n box-shadow: 0 24px 64px rgba(0,0,0,0.5);\n}\n\n.tcw-modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--tcw-border);\n}\n\n.tcw-modal-header h3 {\n font-size: 15px;\n font-weight: 600;\n margin: 0;\n color: var(--tcw-text);\n}\n\n.tcw-modal-close {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n border-radius: 4px;\n transition: all var(--tcw-transition);\n}\n\n.tcw-modal-close:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-modal-tabs {\n display: flex;\n gap: 0;\n padding: 0 20px;\n border-bottom: 1px solid var(--tcw-border);\n}\n\n.tcw-modal-tab {\n padding: 10px 16px;\n font-size: 12px;\n font-weight: 500;\n color: var(--tcw-text-muted);\n border: none;\n background: none;\n cursor: pointer;\n border-bottom: 2px solid transparent;\n margin-bottom: -1px;\n transition: color var(--tcw-transition);\n font-family: inherit;\n text-transform: capitalize;\n}\n\n.tcw-modal-tab:hover {\n color: var(--tcw-text-dim);\n}\n\n.tcw-modal-tab.tcw-active {\n color: var(--tcw-accent);\n border-bottom-color: var(--tcw-accent);\n}\n\n.tcw-modal-body {\n padding: 20px;\n overflow-y: auto;\n flex: 1;\n}\n\n.tcw-settings-section {\n margin-bottom: 20px;\n}\n\n.tcw-settings-section:last-child {\n margin-bottom: 0;\n}\n\n.tcw-settings-section-title {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--tcw-text-muted);\n margin-bottom: 12px;\n}\n\n.tcw-settings-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 0;\n}\n\n.tcw-settings-row + .tcw-settings-row {\n border-top: 1px solid rgba(255,255,255,0.03);\n}\n\n.tcw-root[data-tcw-theme=\"light\"] .tcw-settings-row + .tcw-settings-row {\n border-top: 1px solid rgba(0,0,0,0.04);\n}\n\n.tcw-settings-label {\n font-size: 13px;\n color: var(--tcw-text-dim);\n}\n\n.tcw-color-picker-wrap {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.tcw-color-picker-wrap input[type='color'] {\n width: 28px;\n height: 28px;\n border: 1px solid var(--tcw-border);\n border-radius: 4px;\n background: none;\n cursor: pointer;\n padding: 2px;\n}\n\n.tcw-color-picker-wrap input[type='color']::-webkit-color-swatch-wrapper {\n padding: 0;\n}\n\n.tcw-color-picker-wrap input[type='color']::-webkit-color-swatch {\n border: none;\n border-radius: 2px;\n}\n\n.tcw-color-hex {\n font-size: 11px;\n font-family: var(--tcw-font-mono);\n color: var(--tcw-text-muted);\n min-width: 60px;\n}\n\n.tcw-toggle {\n width: 36px;\n height: 20px;\n background: rgba(255,255,255,0.1);\n border-radius: 10px;\n position: relative;\n cursor: pointer;\n transition: background var(--tcw-transition);\n border: none;\n padding: 0;\n flex-shrink: 0;\n}\n\n.tcw-toggle::after {\n content: '';\n position: absolute;\n top: 2px;\n left: 2px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--tcw-text-muted);\n transition: all var(--tcw-transition);\n}\n\n.tcw-toggle.tcw-on {\n background: var(--tcw-accent);\n}\n\n.tcw-toggle.tcw-on::after {\n left: 18px;\n background: white;\n}\n\n.tcw-root[data-tcw-theme=\"light\"] .tcw-toggle {\n background: rgba(0,0,0,0.1);\n}\n\n.tcw-root[data-tcw-theme=\"light\"] .tcw-toggle::after {\n background: #888;\n}\n\n.tcw-root[data-tcw-theme=\"light\"] .tcw-toggle.tcw-on {\n background: var(--tcw-accent);\n}\n\n.tcw-root[data-tcw-theme=\"light\"] .tcw-toggle.tcw-on::after {\n background: white;\n}\n\n.tcw-settings-select {\n padding: 4px 8px;\n font-size: 12px;\n font-family: inherit;\n background: var(--tcw-bg);\n border: 1px solid var(--tcw-border);\n border-radius: 4px;\n color: var(--tcw-text);\n cursor: pointer;\n}\n\n.tcw-modal-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 20px;\n border-top: 1px solid var(--tcw-border);\n}\n\n.tcw-reset-link {\n font-size: 12px;\n color: var(--tcw-text-muted);\n cursor: pointer;\n border: none;\n background: none;\n font-family: inherit;\n text-decoration: underline;\n text-underline-offset: 2px;\n transition: color var(--tcw-transition);\n}\n\n.tcw-reset-link:hover {\n color: var(--tcw-text-dim);\n}\n\n.tcw-done-btn {\n padding: 6px 16px;\n font-size: 12px;\n font-weight: 500;\n background: var(--tcw-accent);\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n font-family: inherit;\n transition: background var(--tcw-transition);\n}\n\n.tcw-done-btn:hover {\n background: #2563eb;\n}\n\n/* === Status Bar === */\n\n.tcw-statusbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 16px;\n border-top: 1px solid var(--tcw-border);\n background: var(--tcw-bg-elevated);\n font-size: 11px;\n color: var(--tcw-text-muted);\n flex-shrink: 0;\n}\n\n.tcw-status-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.tcw-status-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--tcw-text-muted);\n transition: background 0.3s;\n}\n\n.tcw-status-dot.tcw-connected {\n background: var(--tcw-green);\n}\n\n.tcw-status-dot.tcw-error {\n background: var(--tcw-red);\n}\n\n/* === Responsive === */\n\n@media (max-width: 768px) {\n .tcw-toolbar {\n padding: 0 8px;\n height: 36px;\n }\n .tcw-toolbar-sep {\n display: none;\n }\n .tcw-indicator-chips {\n display: none;\n }\n .tcw-sidebar {\n width: 32px;\n }\n .tcw-sidebar-btn {\n width: 32px;\n height: 28px;\n }\n}\n", d = 0, f = "tcw-styles";
|
|
384
|
+
}, u = "/* === TradeCanvas Widget Styles === */\r\n\r\n.tcw-root {\r\n display: flex;\r\n flex-direction: column;\r\n width: 100%;\r\n height: 100%;\r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\r\n font-size: 13px;\r\n color: #d1d4dc;\r\n background: #131722;\r\n position: relative;\r\n overflow: hidden;\r\n\r\n /* Dark theme tokens (default) */\r\n --tcw-bg: #131722;\r\n --tcw-bg-elevated: #1E222D;\r\n --tcw-border: #2A2E39;\r\n --tcw-text: #d1d4dc;\r\n --tcw-text-dim: #b2b5be;\r\n --tcw-text-muted: #787b86;\r\n --tcw-accent: #2962ff;\r\n --tcw-accent-dim: rgba(41,98,255,0.15);\r\n --tcw-accent-glow: rgba(41,98,255,0.12);\r\n --tcw-red: #ef5350;\r\n --tcw-green: #26a69a;\r\n --tcw-transition: 0.15s ease;\r\n --tcw-radius-lg: 8px;\r\n --tcw-font-mono: 'SF Mono', 'Fira Code', 'Consolas', monospace;\r\n --tcw-hover-bg: rgba(255,255,255,0.04);\r\n}\r\n\r\n.tcw-root[data-tcw-theme=\"light\"] {\r\n color: #131722;\r\n background: #ffffff;\r\n\r\n --tcw-bg: #ffffff;\r\n --tcw-bg-elevated: #f0f3fa;\r\n --tcw-border: #e0e3eb;\r\n --tcw-text: #131722;\r\n --tcw-text-dim: #434651;\r\n --tcw-text-muted: #787b86;\r\n --tcw-accent: #2962ff;\r\n --tcw-accent-dim: rgba(41,98,255,0.1);\r\n --tcw-accent-glow: rgba(41,98,255,0.08);\r\n --tcw-red: #ef5350;\r\n --tcw-green: #26a69a;\r\n --tcw-hover-bg: rgba(0,0,0,0.04);\r\n}\r\n\r\n/* === Toolbar === */\r\n\r\n.tcw-toolbar {\r\n display: flex;\r\n align-items: center;\r\n gap: 0;\r\n padding: 0 12px;\r\n height: 40px;\r\n border-bottom: 1px solid var(--tcw-border);\r\n background: var(--tcw-bg-elevated);\r\n flex-shrink: 0;\r\n position: relative;\r\n z-index: 20;\r\n}\r\n\r\n.tcw-toolbar-symbol {\r\n font-size: 13px;\r\n font-weight: 700;\r\n color: var(--tcw-text);\r\n padding: 0 10px;\r\n white-space: nowrap;\r\n letter-spacing: -0.01em;\r\n cursor: pointer;\r\n border: none;\r\n background: none;\r\n font-family: inherit;\r\n}\r\n\r\n.tcw-toolbar-sep {\r\n width: 1px;\r\n height: 20px;\r\n background: var(--tcw-border);\r\n flex-shrink: 0;\r\n}\r\n\r\n.tcw-toolbar-group {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n padding: 0 8px;\r\n}\r\n\r\n.tcw-toolbar-spacer {\r\n flex: 1;\r\n}\r\n\r\n.tcw-btn {\r\n padding: 4px 8px;\r\n font-size: 12px;\r\n font-family: inherit;\r\n border: none;\r\n border-radius: 4px;\r\n background: transparent;\r\n color: var(--tcw-text-dim);\r\n cursor: pointer;\r\n transition: all var(--tcw-transition);\r\n white-space: nowrap;\r\n line-height: 1;\r\n}\r\n\r\n.tcw-btn:hover {\r\n background: var(--tcw-hover-bg);\r\n color: var(--tcw-text);\r\n}\r\n\r\n.tcw-btn.tcw-active {\r\n background: var(--tcw-accent);\r\n color: white;\r\n}\r\n\r\n.tcw-btn-icon {\r\n width: 32px;\r\n height: 32px;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-family: inherit;\r\n border: none;\r\n border-radius: 4px;\r\n background: transparent;\r\n color: var(--tcw-text-muted);\r\n cursor: pointer;\r\n transition: all var(--tcw-transition);\r\n line-height: 1;\r\n position: relative;\r\n}\r\n\r\n.tcw-btn-icon:hover {\r\n background: var(--tcw-hover-bg);\r\n color: var(--tcw-text);\r\n}\r\n\r\n.tcw-badge-count {\r\n font-size: 10px;\r\n color: var(--tcw-accent);\r\n background: var(--tcw-accent-dim);\r\n padding: 0 4px;\r\n border-radius: 8px;\r\n font-weight: 600;\r\n}\r\n\r\n.tcw-indicator-chips {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n padding: 0 4px;\r\n flex-wrap: nowrap;\r\n overflow: hidden;\r\n}\r\n\r\n.tcw-indicator-chip {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 4px;\r\n padding: 2px 6px 2px 8px;\r\n font-size: 11px;\r\n font-weight: 500;\r\n background: var(--tcw-accent-dim);\r\n color: var(--tcw-accent);\r\n border-radius: 4px;\r\n white-space: nowrap;\r\n line-height: 1.4;\r\n}\r\n\r\n.tcw-chip-remove {\r\n cursor: pointer;\r\n opacity: 0.6;\r\n padding: 0 2px;\r\n transition: opacity var(--tcw-transition);\r\n border: none;\r\n background: none;\r\n color: inherit;\r\n display: inline-flex;\r\n align-items: center;\r\n}\r\n\r\n.tcw-chip-remove:hover {\r\n opacity: 1;\r\n}\r\n\r\n/* === Dropdown === */\r\n\r\n.tcw-dropdown-trigger {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 4px;\r\n padding: 4px 8px;\r\n font-size: 12px;\r\n font-family: inherit;\r\n border: none;\r\n border-radius: 4px;\r\n background: transparent;\r\n color: var(--tcw-text-dim);\r\n cursor: pointer;\r\n transition: all var(--tcw-transition);\r\n white-space: nowrap;\r\n line-height: 1;\r\n}\r\n\r\n.tcw-dropdown-trigger:hover {\r\n background: var(--tcw-hover-bg);\r\n color: var(--tcw-text);\r\n}\r\n\r\n.tcw-dropdown {\r\n position: absolute;\r\n top: 100%;\r\n margin-top: 4px;\r\n background: var(--tcw-bg-elevated);\r\n border: 1px solid var(--tcw-border);\r\n border-radius: var(--tcw-radius-lg);\r\n box-shadow: 0 8px 32px rgba(0,0,0,0.4);\r\n z-index: 50;\r\n padding: 4px 0;\r\n max-height: 400px;\r\n overflow-y: auto;\r\n}\r\n\r\n.tcw-dropdown-item {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 6px 12px;\r\n font-size: 12px;\r\n color: var(--tcw-text-dim);\r\n cursor: pointer;\r\n transition: background var(--tcw-transition), color var(--tcw-transition);\r\n width: 100%;\r\n border: none;\r\n background: none;\r\n font-family: inherit;\r\n text-align: left;\r\n}\r\n\r\n.tcw-dropdown-item:hover {\r\n background: var(--tcw-hover-bg);\r\n color: var(--tcw-text);\r\n}\r\n\r\n.tcw-dropdown-item.tcw-active {\r\n color: var(--tcw-accent);\r\n}\r\n\r\n.tcw-dropdown-label {\r\n text-transform: uppercase;\r\n font-size: 10px;\r\n color: var(--tcw-text-muted);\r\n letter-spacing: 0.05em;\r\n padding: 6px 12px;\r\n font-weight: 600;\r\n}\r\n\r\n.tcw-dropdown-divider {\r\n border-top: 1px solid var(--tcw-border);\r\n margin: 4px 0;\r\n}\r\n\r\n.tcw-tag {\r\n font-size: 10px;\r\n color: var(--tcw-text-muted);\r\n padding: 1px 5px;\r\n border-radius: 3px;\r\n background: var(--tcw-hover-bg);\r\n}\r\n\r\n/* === Body === */\r\n\r\n.tcw-body {\r\n display: flex;\r\n flex: 1;\r\n min-height: 0;\r\n}\r\n\r\n.tcw-chart-container {\r\n flex: 1;\r\n min-width: 0;\r\n min-height: 0;\r\n width: 100%;\r\n height: 100%;\r\n}\r\n\r\n/* === Sidebar === */\r\n\r\n.tcw-sidebar {\r\n width: 36px;\r\n flex-shrink: 0;\r\n background: var(--tcw-bg-elevated);\r\n border-right: 1px solid var(--tcw-border);\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n padding: 4px 0;\r\n overflow: visible;\r\n}\r\n\r\n.tcw-tool-group-wrap {\r\n position: relative;\r\n}\r\n\r\n.tcw-sidebar-btn {\r\n width: 36px;\r\n height: 32px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n border: none;\r\n background: transparent;\r\n color: var(--tcw-text-muted);\r\n cursor: pointer;\r\n font-family: inherit;\r\n transition: all var(--tcw-transition);\r\n position: relative;\r\n flex-shrink: 0;\r\n line-height: 1;\r\n}\r\n\r\n.tcw-sidebar-btn:hover {\r\n color: var(--tcw-text);\r\n background: var(--tcw-hover-bg);\r\n}\r\n\r\n.tcw-sidebar-btn.tcw-active {\r\n color: var(--tcw-accent);\r\n background: var(--tcw-accent-glow);\r\n}\r\n\r\n.tcw-sidebar-btn.tcw-danger:hover {\r\n color: var(--tcw-red);\r\n background: rgba(239,68,68,0.1);\r\n}\r\n\r\n.tcw-multi-dot {\r\n position: absolute;\r\n bottom: 2px;\r\n right: 2px;\r\n width: 4px;\r\n height: 4px;\r\n border-radius: 50%;\r\n background: var(--tcw-text-muted);\r\n}\r\n\r\n.tcw-sidebar-divider {\r\n width: 20px;\r\n height: 1px;\r\n background: var(--tcw-border);\r\n margin: 4px 0;\r\n flex-shrink: 0;\r\n}\r\n\r\n.tcw-sidebar-spacer {\r\n flex: 1;\r\n}\r\n\r\n/* === Flyout === */\r\n\r\n.tcw-flyout {\r\n position: absolute;\r\n left: 100%;\r\n top: 0;\r\n margin-left: 2px;\r\n min-width: 160px;\r\n background: var(--tcw-bg-elevated);\r\n border: 1px solid var(--tcw-border);\r\n border-radius: var(--tcw-radius-lg);\r\n box-shadow: 0 8px 32px rgba(0,0,0,0.4);\r\n z-index: 30;\r\n padding: 4px 0;\r\n}\r\n\r\n.tcw-flyout-header {\r\n text-transform: uppercase;\r\n font-size: 10px;\r\n color: var(--tcw-text-muted);\r\n letter-spacing: 0.05em;\r\n padding: 6px 12px;\r\n font-weight: 600;\r\n}\r\n\r\n.tcw-flyout-item {\r\n padding: 6px 12px;\r\n font-size: 12px;\r\n color: var(--tcw-text-dim);\r\n cursor: pointer;\r\n width: 100%;\r\n display: block;\r\n border: none;\r\n background: none;\r\n text-align: left;\r\n font-family: inherit;\r\n transition: background var(--tcw-transition), color var(--tcw-transition);\r\n}\r\n\r\n.tcw-flyout-item:hover {\r\n background: var(--tcw-hover-bg);\r\n color: var(--tcw-text);\r\n}\r\n\r\n.tcw-flyout-item.tcw-active {\r\n color: var(--tcw-accent);\r\n}\r\n\r\n/* === Modal === */\r\n\r\n.tcw-modal-backdrop {\r\n position: fixed;\r\n inset: 0;\r\n background: rgba(0,0,0,0.5);\r\n backdrop-filter: blur(4px);\r\n -webkit-backdrop-filter: blur(4px);\r\n z-index: 100;\r\n}\r\n\r\n.tcw-modal {\r\n position: fixed;\r\n z-index: 101;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n background: var(--tcw-bg-elevated);\r\n border: 1px solid var(--tcw-border);\r\n border-radius: var(--tcw-radius-lg);\r\n width: 480px;\r\n max-width: 90vw;\r\n max-height: 80vh;\r\n display: flex;\r\n flex-direction: column;\r\n box-shadow: 0 24px 64px rgba(0,0,0,0.5);\r\n}\r\n\r\n.tcw-modal-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 16px 20px;\r\n border-bottom: 1px solid var(--tcw-border);\r\n}\r\n\r\n.tcw-modal-header h3 {\r\n font-size: 15px;\r\n font-weight: 600;\r\n margin: 0;\r\n color: var(--tcw-text);\r\n}\r\n\r\n.tcw-modal-close {\r\n width: 28px;\r\n height: 28px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n border: none;\r\n background: transparent;\r\n color: var(--tcw-text-muted);\r\n cursor: pointer;\r\n border-radius: 4px;\r\n transition: all var(--tcw-transition);\r\n}\r\n\r\n.tcw-modal-close:hover {\r\n background: var(--tcw-hover-bg);\r\n color: var(--tcw-text);\r\n}\r\n\r\n.tcw-modal-tabs {\r\n display: flex;\r\n gap: 0;\r\n padding: 0 20px;\r\n border-bottom: 1px solid var(--tcw-border);\r\n}\r\n\r\n.tcw-modal-tab {\r\n padding: 10px 16px;\r\n font-size: 12px;\r\n font-weight: 500;\r\n color: var(--tcw-text-muted);\r\n border: none;\r\n background: none;\r\n cursor: pointer;\r\n border-bottom: 2px solid transparent;\r\n margin-bottom: -1px;\r\n transition: color var(--tcw-transition);\r\n font-family: inherit;\r\n text-transform: capitalize;\r\n}\r\n\r\n.tcw-modal-tab:hover {\r\n color: var(--tcw-text-dim);\r\n}\r\n\r\n.tcw-modal-tab.tcw-active {\r\n color: var(--tcw-accent);\r\n border-bottom-color: var(--tcw-accent);\r\n}\r\n\r\n.tcw-modal-body {\r\n padding: 20px;\r\n overflow-y: auto;\r\n flex: 1;\r\n}\r\n\r\n.tcw-settings-section {\r\n margin-bottom: 20px;\r\n}\r\n\r\n.tcw-settings-section:last-child {\r\n margin-bottom: 0;\r\n}\r\n\r\n.tcw-settings-section-title {\r\n font-size: 11px;\r\n font-weight: 600;\r\n text-transform: uppercase;\r\n letter-spacing: 0.05em;\r\n color: var(--tcw-text-muted);\r\n margin-bottom: 12px;\r\n}\r\n\r\n.tcw-settings-row {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 8px 0;\r\n}\r\n\r\n.tcw-settings-row + .tcw-settings-row {\r\n border-top: 1px solid rgba(255,255,255,0.03);\r\n}\r\n\r\n.tcw-root[data-tcw-theme=\"light\"] .tcw-settings-row + .tcw-settings-row {\r\n border-top: 1px solid rgba(0,0,0,0.04);\r\n}\r\n\r\n.tcw-settings-label {\r\n font-size: 13px;\r\n color: var(--tcw-text-dim);\r\n}\r\n\r\n.tcw-color-picker-wrap {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n}\r\n\r\n.tcw-color-picker-wrap input[type='color'] {\r\n width: 28px;\r\n height: 28px;\r\n border: 1px solid var(--tcw-border);\r\n border-radius: 4px;\r\n background: none;\r\n cursor: pointer;\r\n padding: 2px;\r\n}\r\n\r\n.tcw-color-picker-wrap input[type='color']::-webkit-color-swatch-wrapper {\r\n padding: 0;\r\n}\r\n\r\n.tcw-color-picker-wrap input[type='color']::-webkit-color-swatch {\r\n border: none;\r\n border-radius: 2px;\r\n}\r\n\r\n.tcw-color-hex {\r\n font-size: 11px;\r\n font-family: var(--tcw-font-mono);\r\n color: var(--tcw-text-muted);\r\n min-width: 60px;\r\n}\r\n\r\n.tcw-toggle {\r\n width: 36px;\r\n height: 20px;\r\n background: rgba(255,255,255,0.1);\r\n border-radius: 10px;\r\n position: relative;\r\n cursor: pointer;\r\n transition: background var(--tcw-transition);\r\n border: none;\r\n padding: 0;\r\n flex-shrink: 0;\r\n}\r\n\r\n.tcw-toggle::after {\r\n content: '';\r\n position: absolute;\r\n top: 2px;\r\n left: 2px;\r\n width: 16px;\r\n height: 16px;\r\n border-radius: 50%;\r\n background: var(--tcw-text-muted);\r\n transition: all var(--tcw-transition);\r\n}\r\n\r\n.tcw-toggle.tcw-on {\r\n background: var(--tcw-accent);\r\n}\r\n\r\n.tcw-toggle.tcw-on::after {\r\n left: 18px;\r\n background: white;\r\n}\r\n\r\n.tcw-root[data-tcw-theme=\"light\"] .tcw-toggle {\r\n background: rgba(0,0,0,0.1);\r\n}\r\n\r\n.tcw-root[data-tcw-theme=\"light\"] .tcw-toggle::after {\r\n background: #888;\r\n}\r\n\r\n.tcw-root[data-tcw-theme=\"light\"] .tcw-toggle.tcw-on {\r\n background: var(--tcw-accent);\r\n}\r\n\r\n.tcw-root[data-tcw-theme=\"light\"] .tcw-toggle.tcw-on::after {\r\n background: white;\r\n}\r\n\r\n.tcw-settings-select {\r\n padding: 4px 8px;\r\n font-size: 12px;\r\n font-family: inherit;\r\n background: var(--tcw-bg);\r\n border: 1px solid var(--tcw-border);\r\n border-radius: 4px;\r\n color: var(--tcw-text);\r\n cursor: pointer;\r\n}\r\n\r\n.tcw-modal-footer {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 12px 20px;\r\n border-top: 1px solid var(--tcw-border);\r\n}\r\n\r\n.tcw-reset-link {\r\n font-size: 12px;\r\n color: var(--tcw-text-muted);\r\n cursor: pointer;\r\n border: none;\r\n background: none;\r\n font-family: inherit;\r\n text-decoration: underline;\r\n text-underline-offset: 2px;\r\n transition: color var(--tcw-transition);\r\n}\r\n\r\n.tcw-reset-link:hover {\r\n color: var(--tcw-text-dim);\r\n}\r\n\r\n.tcw-done-btn {\r\n padding: 6px 16px;\r\n font-size: 12px;\r\n font-weight: 500;\r\n background: var(--tcw-accent);\r\n color: white;\r\n border: none;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font-family: inherit;\r\n transition: background var(--tcw-transition);\r\n}\r\n\r\n.tcw-done-btn:hover {\r\n background: #2563eb;\r\n}\r\n\r\n/* === Status Bar === */\r\n\r\n.tcw-statusbar {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 6px 16px;\r\n border-top: 1px solid var(--tcw-border);\r\n background: var(--tcw-bg-elevated);\r\n font-size: 11px;\r\n color: var(--tcw-text-muted);\r\n flex-shrink: 0;\r\n}\r\n\r\n.tcw-status-indicator {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n}\r\n\r\n.tcw-status-dot {\r\n width: 6px;\r\n height: 6px;\r\n border-radius: 50%;\r\n background: var(--tcw-text-muted);\r\n transition: background 0.3s;\r\n}\r\n\r\n.tcw-status-dot.tcw-connected {\r\n background: var(--tcw-green);\r\n}\r\n\r\n.tcw-status-dot.tcw-error {\r\n background: var(--tcw-red);\r\n}\r\n\r\n/* === Command Palette === */\r\n\r\n.tcw-cmd-palette {\r\n position: fixed;\r\n z-index: 102;\r\n top: 20%;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n background: var(--tcw-bg-elevated);\r\n border: 1px solid var(--tcw-border);\r\n border-radius: var(--tcw-radius-lg);\r\n width: 520px;\r\n max-width: 90vw;\r\n max-height: 60vh;\r\n display: flex;\r\n flex-direction: column;\r\n box-shadow: 0 24px 64px rgba(0,0,0,0.5);\r\n overflow: hidden;\r\n}\r\n\r\n.tcw-cmd-header {\r\n display: flex;\r\n align-items: center;\r\n padding: 12px 16px;\r\n border-bottom: 1px solid var(--tcw-border);\r\n gap: 10px;\r\n}\r\n\r\n.tcw-cmd-icon {\r\n font-size: 18px;\r\n color: var(--tcw-text-muted);\r\n flex-shrink: 0;\r\n}\r\n\r\n.tcw-cmd-input {\r\n flex: 1;\r\n background: none;\r\n border: none;\r\n outline: none;\r\n font-size: 14px;\r\n font-family: inherit;\r\n color: var(--tcw-text);\r\n caret-color: var(--tcw-accent);\r\n}\r\n\r\n.tcw-cmd-input::placeholder {\r\n color: var(--tcw-text-muted);\r\n}\r\n\r\n.tcw-cmd-hint {\r\n font-size: 10px;\r\n color: var(--tcw-text-muted);\r\n border: 1px solid var(--tcw-border);\r\n padding: 2px 6px;\r\n border-radius: 3px;\r\n flex-shrink: 0;\r\n}\r\n\r\n.tcw-cmd-list {\r\n overflow-y: auto;\r\n flex: 1;\r\n padding: 4px 0;\r\n max-height: 360px;\r\n}\r\n\r\n.tcw-cmd-category {\r\n text-transform: uppercase;\r\n font-size: 10px;\r\n color: var(--tcw-text-muted);\r\n letter-spacing: 0.05em;\r\n padding: 8px 16px 4px;\r\n font-weight: 600;\r\n}\r\n\r\n.tcw-cmd-item {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 8px 16px;\r\n font-size: 13px;\r\n color: var(--tcw-text-dim);\r\n cursor: pointer;\r\n width: 100%;\r\n border: none;\r\n background: none;\r\n font-family: inherit;\r\n text-align: left;\r\n transition: background 80ms ease;\r\n gap: 8px;\r\n}\r\n\r\n.tcw-cmd-item:hover,\r\n.tcw-cmd-item.tcw-selected {\r\n background: var(--tcw-hover-bg);\r\n color: var(--tcw-text);\r\n}\r\n\r\n.tcw-cmd-item.tcw-active .tcw-cmd-item-label {\r\n color: var(--tcw-accent);\r\n}\r\n\r\n.tcw-cmd-item-label {\r\n flex: 1;\r\n}\r\n\r\n.tcw-cmd-check {\r\n color: var(--tcw-accent);\r\n font-size: 14px;\r\n font-weight: 600;\r\n}\r\n\r\n.tcw-cmd-kbd {\r\n font-size: 10px;\r\n font-family: var(--tcw-font-mono);\r\n color: var(--tcw-text-muted);\r\n background: var(--tcw-bg);\r\n border: 1px solid var(--tcw-border);\r\n padding: 1px 5px;\r\n border-radius: 3px;\r\n}\r\n\r\n.tcw-cmd-empty {\r\n padding: 24px 16px;\r\n text-align: center;\r\n color: var(--tcw-text-muted);\r\n font-size: 13px;\r\n}\r\n\r\n.tcw-cmd-footer {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n padding: 8px 16px;\r\n border-top: 1px solid var(--tcw-border);\r\n font-size: 11px;\r\n color: var(--tcw-text-muted);\r\n}\r\n\r\n/* === Responsive === */\r\n\r\n@media (max-width: 768px) {\r\n .tcw-toolbar {\r\n padding: 0 8px;\r\n height: 36px;\r\n }\r\n .tcw-toolbar-sep {\r\n display: none;\r\n }\r\n .tcw-indicator-chips {\r\n display: none;\r\n }\r\n .tcw-sidebar {\r\n width: 32px;\r\n }\r\n .tcw-sidebar-btn {\r\n width: 32px;\r\n height: 28px;\r\n }\r\n}\r\n", d = 0, f = "tcw-styles";
|
|
334
385
|
function p() {
|
|
335
386
|
if (d++, d > 1 || document.getElementById(f)) return;
|
|
336
387
|
let e = document.createElement("style");
|
|
@@ -789,12 +840,138 @@ var _ = class {
|
|
|
789
840
|
this.el.remove();
|
|
790
841
|
}
|
|
791
842
|
}, w = class {
|
|
843
|
+
backdrop = null;
|
|
844
|
+
modal = null;
|
|
845
|
+
input = null;
|
|
846
|
+
list = null;
|
|
847
|
+
items = [];
|
|
848
|
+
filtered = [];
|
|
849
|
+
selectedIndex = 0;
|
|
850
|
+
callbacks;
|
|
851
|
+
boundKeydown;
|
|
852
|
+
constructor(e) {
|
|
853
|
+
this.callbacks = e, this.boundKeydown = this.handleKeydown.bind(this);
|
|
854
|
+
}
|
|
855
|
+
open(e) {
|
|
856
|
+
if (this.backdrop) return;
|
|
857
|
+
this.items = e, this.filtered = e, this.selectedIndex = 0, this.backdrop = document.createElement("div"), this.backdrop.className = "tcw-modal-backdrop", this.backdrop.addEventListener("click", () => this.close()), this.modal = document.createElement("div"), this.modal.className = "tcw-cmd-palette";
|
|
858
|
+
let t = document.createElement("div");
|
|
859
|
+
t.className = "tcw-cmd-header";
|
|
860
|
+
let n = document.createElement("span");
|
|
861
|
+
n.className = "tcw-cmd-icon", n.textContent = "⌕", t.appendChild(n), this.input = document.createElement("input"), this.input.className = "tcw-cmd-input", this.input.type = "text", this.input.placeholder = "Search indicators, chart types, tools...", this.input.addEventListener("input", () => this.filter()), t.appendChild(this.input);
|
|
862
|
+
let r = document.createElement("span");
|
|
863
|
+
r.className = "tcw-cmd-hint", r.textContent = "ESC", t.appendChild(r), this.modal.appendChild(t), this.list = document.createElement("div"), this.list.className = "tcw-cmd-list", this.modal.appendChild(this.list);
|
|
864
|
+
let i = document.createElement("div");
|
|
865
|
+
i.className = "tcw-cmd-footer", i.innerHTML = "<span>↑↓ Navigate</span><span>⏎ Select</span><span>Esc Close</span>", this.modal.appendChild(i), document.body.appendChild(this.backdrop), document.body.appendChild(this.modal), this.renderList(), this.input.focus(), document.addEventListener("keydown", this.boundKeydown);
|
|
866
|
+
}
|
|
867
|
+
close() {
|
|
868
|
+
document.removeEventListener("keydown", this.boundKeydown), this.backdrop?.remove(), this.modal?.remove(), this.backdrop = null, this.modal = null, this.input = null, this.list = null, this.callbacks.onClose();
|
|
869
|
+
}
|
|
870
|
+
isOpen() {
|
|
871
|
+
return this.backdrop !== null;
|
|
872
|
+
}
|
|
873
|
+
filter() {
|
|
874
|
+
let e = this.input?.value.toLowerCase().trim() ?? "";
|
|
875
|
+
e ? this.filtered = this.items.filter((t) => t.label.toLowerCase().includes(e) || t.category.toLowerCase().includes(e) || t.id.toLowerCase().includes(e)) : this.filtered = this.items, this.selectedIndex = 0, this.renderList();
|
|
876
|
+
}
|
|
877
|
+
renderList() {
|
|
878
|
+
if (!this.list) return;
|
|
879
|
+
if (this.list.innerHTML = "", this.filtered.length === 0) {
|
|
880
|
+
let e = document.createElement("div");
|
|
881
|
+
e.className = "tcw-cmd-empty", e.textContent = "No results found", this.list.appendChild(e);
|
|
882
|
+
return;
|
|
883
|
+
}
|
|
884
|
+
let e = "";
|
|
885
|
+
for (let t = 0; t < this.filtered.length; t++) {
|
|
886
|
+
let n = this.filtered[t];
|
|
887
|
+
if (n.category !== e) {
|
|
888
|
+
e = n.category;
|
|
889
|
+
let t = document.createElement("div");
|
|
890
|
+
t.className = "tcw-cmd-category", t.textContent = this.categoryLabel(e), this.list.appendChild(t);
|
|
891
|
+
}
|
|
892
|
+
let r = document.createElement("button");
|
|
893
|
+
r.className = "tcw-cmd-item", t === this.selectedIndex && r.classList.add("tcw-selected"), n.active && r.classList.add("tcw-active"), r.dataset.index = String(t);
|
|
894
|
+
let i = document.createElement("span");
|
|
895
|
+
if (i.className = "tcw-cmd-item-label", i.textContent = n.label, r.appendChild(i), n.active) {
|
|
896
|
+
let e = document.createElement("span");
|
|
897
|
+
e.className = "tcw-cmd-check", e.textContent = "✓", r.appendChild(e);
|
|
898
|
+
}
|
|
899
|
+
if (n.shortcut) {
|
|
900
|
+
let e = document.createElement("kbd");
|
|
901
|
+
e.className = "tcw-cmd-kbd", e.textContent = n.shortcut, r.appendChild(e);
|
|
902
|
+
}
|
|
903
|
+
r.addEventListener("click", () => this.select(t)), r.addEventListener("mouseenter", () => {
|
|
904
|
+
this.selectedIndex = t, this.updateSelection();
|
|
905
|
+
}), this.list.appendChild(r);
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
updateSelection() {
|
|
909
|
+
if (!this.list) return;
|
|
910
|
+
let e = this.list.querySelectorAll(".tcw-cmd-item");
|
|
911
|
+
e.forEach((e, t) => {
|
|
912
|
+
e.classList.toggle("tcw-selected", t === this.selectedIndex);
|
|
913
|
+
}), e[this.selectedIndex]?.scrollIntoView({ block: "nearest" });
|
|
914
|
+
}
|
|
915
|
+
select(e) {
|
|
916
|
+
let t = this.filtered[e];
|
|
917
|
+
if (t) {
|
|
918
|
+
switch (t.category) {
|
|
919
|
+
case "indicator":
|
|
920
|
+
this.callbacks.onIndicator(t.id);
|
|
921
|
+
break;
|
|
922
|
+
case "chartType":
|
|
923
|
+
this.callbacks.onChartType(t.id);
|
|
924
|
+
break;
|
|
925
|
+
case "drawing":
|
|
926
|
+
this.callbacks.onDrawingTool(t.id);
|
|
927
|
+
break;
|
|
928
|
+
case "timeframe":
|
|
929
|
+
this.callbacks.onTimeframe(t.id);
|
|
930
|
+
break;
|
|
931
|
+
case "action":
|
|
932
|
+
this.callbacks.onAction(t.id);
|
|
933
|
+
break;
|
|
934
|
+
}
|
|
935
|
+
this.close();
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
handleKeydown(e) {
|
|
939
|
+
switch (e.key) {
|
|
940
|
+
case "Escape":
|
|
941
|
+
e.preventDefault(), this.close();
|
|
942
|
+
break;
|
|
943
|
+
case "ArrowDown":
|
|
944
|
+
e.preventDefault(), this.filtered.length > 0 && (this.selectedIndex = (this.selectedIndex + 1) % this.filtered.length, this.updateSelection());
|
|
945
|
+
break;
|
|
946
|
+
case "ArrowUp":
|
|
947
|
+
e.preventDefault(), this.filtered.length > 0 && (this.selectedIndex = (this.selectedIndex - 1 + this.filtered.length) % this.filtered.length, this.updateSelection());
|
|
948
|
+
break;
|
|
949
|
+
case "Enter":
|
|
950
|
+
e.preventDefault(), this.select(this.selectedIndex);
|
|
951
|
+
break;
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
categoryLabel(e) {
|
|
955
|
+
switch (e) {
|
|
956
|
+
case "indicator": return "Indicators";
|
|
957
|
+
case "chartType": return "Chart Types";
|
|
958
|
+
case "drawing": return "Drawing Tools";
|
|
959
|
+
case "timeframe": return "Timeframes";
|
|
960
|
+
case "action": return "Actions";
|
|
961
|
+
default: return e;
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
destroy() {
|
|
965
|
+
this.close();
|
|
966
|
+
}
|
|
967
|
+
}, T = class {
|
|
792
968
|
chart;
|
|
793
969
|
state;
|
|
794
970
|
toolbar = null;
|
|
795
971
|
sidebar = null;
|
|
796
972
|
settings = null;
|
|
797
973
|
statusBar = null;
|
|
974
|
+
commandPalette = null;
|
|
798
975
|
root;
|
|
799
976
|
chartContainer;
|
|
800
977
|
destroyed = !1;
|
|
@@ -803,6 +980,7 @@ var _ = class {
|
|
|
803
980
|
symbols;
|
|
804
981
|
settingsState;
|
|
805
982
|
adapter = null;
|
|
983
|
+
boundGlobalKeydown = null;
|
|
806
984
|
constructor(t, n = {}) {
|
|
807
985
|
this.options = n, this.symbols = n.symbols ?? c, this.settingsState = { ...l };
|
|
808
986
|
let u = this.resolveIsDark(n.theme), d = this.resolveTheme(n.theme);
|
|
@@ -874,7 +1052,16 @@ var _ = class {
|
|
|
874
1052
|
onChange: (e) => this.applySettings(e),
|
|
875
1053
|
onReset: () => this.resetSettings(),
|
|
876
1054
|
onClose: () => {}
|
|
877
|
-
})),
|
|
1055
|
+
})), this.commandPalette = new w({
|
|
1056
|
+
onIndicator: (e) => this.handleAddIndicator(e),
|
|
1057
|
+
onChartType: (e) => this.handleChartType(e),
|
|
1058
|
+
onDrawingTool: (e) => this.handleDrawingTool(e),
|
|
1059
|
+
onTimeframe: (e) => this.handleTimeframe(e),
|
|
1060
|
+
onAction: (e) => this.handleAction(e),
|
|
1061
|
+
onClose: () => {}
|
|
1062
|
+
}), this.boundGlobalKeydown = (e) => {
|
|
1063
|
+
(e.ctrlKey || e.metaKey) && e.key === "k" && (e.preventDefault(), this.toggleCommandPalette());
|
|
1064
|
+
}, document.addEventListener("keydown", this.boundGlobalKeydown), n.adapter && (this.adapter = n.adapter, this.connectStream()), this.updateUI(), n.onReady?.(this.chart);
|
|
878
1065
|
}
|
|
879
1066
|
async setSymbol(e) {
|
|
880
1067
|
this.state = {
|
|
@@ -901,7 +1088,7 @@ var _ = class {
|
|
|
901
1088
|
return this.chart;
|
|
902
1089
|
}
|
|
903
1090
|
destroy() {
|
|
904
|
-
this.destroyed || (this.destroyed = !0, this.toolbar?.destroy(), this.sidebar?.destroy(), this.settings?.destroy(), this.statusBar?.destroy(), this.chart.destroy(), this.root.remove(), m());
|
|
1091
|
+
this.destroyed || (this.destroyed = !0, this.boundGlobalKeydown && document.removeEventListener("keydown", this.boundGlobalKeydown), this.commandPalette?.destroy(), this.toolbar?.destroy(), this.sidebar?.destroy(), this.settings?.destroy(), this.statusBar?.destroy(), this.chart.destroy(), this.root.remove(), m());
|
|
905
1092
|
}
|
|
906
1093
|
handleSymbolClick() {
|
|
907
1094
|
this.symbolIndex = (this.symbolIndex + 1) % this.symbols.length;
|
|
@@ -956,6 +1143,77 @@ var _ = class {
|
|
|
956
1143
|
activeIndicators: t
|
|
957
1144
|
}, this.updateUI();
|
|
958
1145
|
}
|
|
1146
|
+
toggleCommandPalette() {
|
|
1147
|
+
if (this.commandPalette?.isOpen()) {
|
|
1148
|
+
this.commandPalette.close();
|
|
1149
|
+
return;
|
|
1150
|
+
}
|
|
1151
|
+
this.commandPalette?.open(this.buildCommandItems());
|
|
1152
|
+
}
|
|
1153
|
+
buildCommandItems() {
|
|
1154
|
+
let e = [];
|
|
1155
|
+
for (let t of o) e.push({
|
|
1156
|
+
id: t.id,
|
|
1157
|
+
label: t.name,
|
|
1158
|
+
category: "indicator",
|
|
1159
|
+
active: this.state.activeIndicators.has(t.id)
|
|
1160
|
+
});
|
|
1161
|
+
for (let t of i) e.push({
|
|
1162
|
+
id: t.value,
|
|
1163
|
+
label: t.label,
|
|
1164
|
+
category: "chartType",
|
|
1165
|
+
active: this.state.chartType === t.value
|
|
1166
|
+
});
|
|
1167
|
+
for (let t of a) for (let n of t.tools) e.push({
|
|
1168
|
+
id: n.value,
|
|
1169
|
+
label: n.label,
|
|
1170
|
+
category: "drawing",
|
|
1171
|
+
active: this.state.activeTool === n.value
|
|
1172
|
+
});
|
|
1173
|
+
for (let t of r) e.push({
|
|
1174
|
+
id: t.value,
|
|
1175
|
+
label: t.label,
|
|
1176
|
+
category: "timeframe",
|
|
1177
|
+
active: this.state.timeframe === t.value
|
|
1178
|
+
});
|
|
1179
|
+
return e.push({
|
|
1180
|
+
id: "screenshot",
|
|
1181
|
+
label: "Screenshot",
|
|
1182
|
+
category: "action",
|
|
1183
|
+
shortcut: ""
|
|
1184
|
+
}, {
|
|
1185
|
+
id: "toggleTheme",
|
|
1186
|
+
label: "Toggle Theme",
|
|
1187
|
+
category: "action"
|
|
1188
|
+
}, {
|
|
1189
|
+
id: "settings",
|
|
1190
|
+
label: "Settings",
|
|
1191
|
+
category: "action"
|
|
1192
|
+
}, {
|
|
1193
|
+
id: "clearDrawings",
|
|
1194
|
+
label: "Clear All Drawings",
|
|
1195
|
+
category: "action"
|
|
1196
|
+
}), e;
|
|
1197
|
+
}
|
|
1198
|
+
handleAction(e) {
|
|
1199
|
+
switch (e) {
|
|
1200
|
+
case "screenshot":
|
|
1201
|
+
this.chart.screenshot();
|
|
1202
|
+
break;
|
|
1203
|
+
case "toggleTheme":
|
|
1204
|
+
this.handleToggleTheme();
|
|
1205
|
+
break;
|
|
1206
|
+
case "settings":
|
|
1207
|
+
this.openSettings();
|
|
1208
|
+
break;
|
|
1209
|
+
case "clearDrawings":
|
|
1210
|
+
this.chart.clearDrawings(), this.state = {
|
|
1211
|
+
...this.state,
|
|
1212
|
+
activeTool: null
|
|
1213
|
+
}, this.updateUI();
|
|
1214
|
+
break;
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
959
1217
|
handleDrawingTool(e) {
|
|
960
1218
|
this.state = {
|
|
961
1219
|
...this.state,
|
|
@@ -1053,6 +1311,6 @@ var _ = class {
|
|
|
1053
1311
|
}
|
|
1054
1312
|
};
|
|
1055
1313
|
//#endregion
|
|
1056
|
-
export {
|
|
1314
|
+
export { T as ChartWidget };
|
|
1057
1315
|
|
|
1058
1316
|
//# sourceMappingURL=index.js.map
|