widget-iccandle 0.0.38 → 0.0.40

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 CHANGED
@@ -1,95 +1,136 @@
1
1
  # widget-iccandle
2
2
 
3
- React components for the TradingView Charting Library: chart wrapper and selector/scanner UI.
3
+ React component that wraps an existing [TradingView Charting Library](https://www.tradingview.com/charting-library-docs/) widget and adds ICCandle’s **scanner UI**: a draggable popup to run pattern search over a user-selected bar range, with theming loaded from ICCandle’s API.
4
4
 
5
- ## SelectorWidget
5
+ Published as ESM and CommonJS; component styles are bundled and injected at runtime (no separate CSS import).
6
6
 
7
- `SelectorWidget` wraps a TradingView chart instance and adds a **scanner popup** with date-range selection on the chart. Users can trigger the scanner, draw or adjust a date range on the chart, and submit a request (e.g. for key levels or candles in that range).
7
+ ## Install
8
8
 
9
- ### Props
9
+ ```bash
10
+ npm install widget-iccandle
11
+ ```
12
+
13
+ **Peer dependencies:** `react` and `react-dom` **≥ 18**.
10
14
 
11
- | Prop | Type | Description |
12
- | ---------------- | ---------------------------------- | ---------------------------------------------------------------------------------------------------- |
13
- | `chartWidget` | `IChartingLibraryWidget \| null` | The TradingView chart widget instance (from the charting library). |
14
- | `children` | `ReactNode` | Content rendered above the scanner UI (e.g. the chart container). |
15
- | `submitCallback` | `(params: RequestPattern, embeddedUrl: string) => void` | Called when the user submits from the scanner (receives the request pattern and an embedded plugin URL for the selected range). |
15
+ You must obtain the TradingView Charting Library under your own license and load it in your app. This package does not ship the charting library assets.
16
16
 
17
- ### Usage
17
+ ## Quick start
18
18
 
19
19
  ```tsx
20
- import { SelectorWidget } from "widget-iccandle"; // or from your path, e.g. "@/tradingview/selector-widget"
20
+ import { useState } from "react";
21
+ import type { IChartingLibraryWidget } from "charting_library/charting_library";
22
+ import { SelectorWidget } from "widget-iccandle";
21
23
 
22
- function ChartWithScanner() {
24
+ function App() {
23
25
  const [chartWidget, setChartWidget] = useState<IChartingLibraryWidget | null>(
24
26
  null,
25
27
  );
26
-
27
- const handleSubmit = (params: RequestPattern, embeddedUrl: string) => {
28
- // Handle scanner submit (e.g. fetch candles for the selected range; use embeddedUrl to open or share the plugin view)
29
- };
28
+ const widgetKey = "icc_search_..."; // ICCandle-issued key (48 hex chars after prefix)
30
29
 
31
30
  return (
32
- <SelectorWidget chartWidget={chartWidget} submitCallback={handleSubmit}>
33
- <TradingViewWidget onChartReady={(widget) => setChartWidget(widget)} />
31
+ <SelectorWidget
32
+ chartWidget={chartWidget}
33
+ widgetKey={widgetKey}
34
+ theme="system"
35
+ submitCallback={(iframeSrc) => {
36
+ // Full URL for the ICCandle plugin iframe (open in modal, new window, etc.)
37
+ console.log(iframeSrc);
38
+ }}
39
+ >
40
+ {/* Your chart container + TradingView bootstrap; call setChartWidget when ready */}
41
+ <div id="tv_chart_container" style={{ height: "100%" }} />
34
42
  </SelectorWidget>
35
43
  );
36
44
  }
37
45
  ```
38
46
 
39
- ### Behavior
47
+ Replace the chart placeholder with your TradingView initialization and pass the `IChartingLibraryWidget` instance when `onChartReady` (or equivalent) fires.
48
+
49
+ ## API
50
+
51
+ ### Exports
52
+
53
+ | Name | Kind | Description |
54
+ | -------------------- | ------ | -------------------------------------------- |
55
+ | `SelectorWidget` | Component | Scanner overlay around your chart subtree |
56
+ | `SelectorWidgetProps`| Type | Props for `SelectorWidget` |
57
+
58
+ ### `SelectorWidget` props
59
+
60
+ | Prop | Type | Required | Description |
61
+ | ----------------- | --------------------------------------- | -------- | ----------- |
62
+ | `chartWidget` | `IChartingLibraryWidget \| null` | Yes | Live TradingView widget instance (`null` until ready). |
63
+ | `children` | `ReactNode` | Yes | Your chart UI (e.g. container + library bootstrap). |
64
+ | `widgetKey` | `string` | Yes | ICCandle API key (`icc_search_` + 48 hex chars). Used for theme fetch, candle cache, and scanner validation. |
65
+ | `submitCallback` | `(iframeSrc: string) => void` | Yes | Called after a successful scan setup with the **plugin iframe URL** (query string includes window size, timestamps, symbol, `candle_id`, `apiKey`, theme, optional filters). |
66
+ | `theme` | `"light" \| "dark" \| "system"` | No | Defaults to sensible behavior; `"system"` follows `prefers-color-scheme`. Affects resolved theme tokens and the plugin URL. |
67
+
68
+ ### Widget key and remote theming
69
+
70
+ On mount, the component loads branding colors from ICCandle:
40
71
 
41
- - **Chart integration**: Requires a ready `chartWidget` (TradingView’s `IChartingLibraryWidget`). Subscribes to `drawing_event` and manages a single “date range” multipoint shape.
42
- - **Scanner popup**: Renders `ScannerPopUp` with trigger, window size, resolution, symbol, and timestamp derived from the chart and the drawn range.
43
- - **Date range**: When the scanner is triggered, a date-range shape is drawn over the visible range; the user can drag points to change the range. `search_timestamp` and `window_size` are updated from that shape and passed into the scanner.
44
- - **Static symbols**: The widget currently uses a static symbol list (e.g. XAU/USD and timeframes). Symbol/resolution come from the chart and the static config.
72
+ - **URL:** `https://api.iccandle.ai/corporate-client/v1/widgetStyle/search/user/?service_type=search`
73
+ - **Header:** `api-key: <widgetKey>`
45
74
 
46
- ### Dependencies
75
+ CSS custom properties (`--iccandle-primary`, `--iccandle-border`, etc.) are applied on the widget root so the scanner matches your configured light/dark tokens.
47
76
 
48
- - TradingView Charting Library types (e.g. `IChartingLibraryWidget`, `EntityId`, `DrawingEventType`, `ResolutionString`).
49
- - Internal: `ScannerPopUp`, selector constants (`DateRangeOptions`, `SearchComponentSpacing`, `WINDOW_SIZE`), data-feed types (`RequestPattern`, `SymbolData`), and utils (`debounce`, `getBarDurationMs`, `normalizeTimestamp`).
77
+ ### Behavior summary
50
78
 
51
- ## Datafeed integration
79
+ - Subscribes to chart readiness, resolution, symbol changes, and drawing events.
80
+ - Manages a `date_range` multipoint drawing so the user can adjust the bar window; window size and exported candles drive the scanner.
81
+ - Posts candles to ICCandle’s cache endpoint before opening the plugin URL (see scanner implementation for details).
82
+ - Listens for `window` `message` events for chart/news integration and can clear persisted news mark selections (`localStorage` key `tv:selected-news-events`) when starting a scan.
52
83
 
53
- To display news events as timescale marks on the TradingView chart, add the following implementation to your `data-feed.ts` (inside the `dataFeed` object), replacing the existing `getTimescaleMarks` stub:
84
+ ## Optional: timescale marks (news/events)
85
+
86
+ If your data feed implements `getTimescaleMarks`, you can surface stored events (e.g. from `localStorage` under `tv:selected-news-events`) as marks on the time axis. Example shape:
54
87
 
55
88
  ```ts
56
89
  getTimescaleMarks: async (
57
90
  symbolInfo: LibrarySymbolInfo,
58
91
  from: number,
59
92
  to: number,
60
- onResult: GetMarksCallback<TimescaleMark>
93
+ onResult: GetMarksCallback<TimescaleMark>,
61
94
  ) => {
62
95
  const marks: TimescaleMark[] = [];
63
-
64
- // ... add your code here
65
96
  try {
66
97
  const allNewsEvents = JSON.parse(
67
- localStorage.getItem("tv:selected-news-events") || "[]"
98
+ localStorage.getItem("tv:selected-news-events") || "[]",
68
99
  ) as NewsEventType[];
69
100
 
70
- allNewsEvents?.forEach(
71
- ({ id, timestamp, event_name, currency }) => {
72
- if (!id || !Number.isFinite(timestamp) || timestamp <= 0) return;
73
- const hasAlready = marks.some((m) => String(m.id) === String(id));
74
- if (hasAlready) return;
75
-
76
- marks.push({
77
- id,
78
- time: timestamp / 1000,
79
- color: "green",
80
- label: event_name.slice(0, 1) || "N",
81
- tooltip: [event_name],
82
- ...(currency
83
- ? { imageUrl: `/images/symbols/${currency}.svg` }
84
- : {}),
85
- showLabelWhenImageLoaded: true,
86
- });
87
- },
88
- );
101
+ allNewsEvents?.forEach(({ id, timestamp, event_name, currency }) => {
102
+ if (!id || !Number.isFinite(timestamp) || timestamp <= 0) return;
103
+ if (marks.some((m) => String(m.id) === String(id))) return;
104
+
105
+ marks.push({
106
+ id,
107
+ time: timestamp / 1000,
108
+ color: "green",
109
+ label: event_name.slice(0, 1) || "N",
110
+ tooltip: [event_name],
111
+ ...(currency ? { imageUrl: `/images/symbols/${currency}.svg` } : {}),
112
+ showLabelWhenImageLoaded: true,
113
+ });
114
+ });
89
115
  } catch {
90
- // no-op
116
+ /* ignore */
91
117
  }
92
-
93
118
  onResult(marks);
94
- }
119
+ };
95
120
  ```
121
+
122
+ Adjust paths and types to match your app and TradingView typings.
123
+
124
+ ## Development (this repo)
125
+
126
+ | Script | Command | Purpose |
127
+ | ------------- | ------------ | ------- |
128
+ | Dev demo | `npm run dev` | Vite app with local charting library (see `vite.config.ts`). |
129
+ | Library build | `npm run build` | Emits `dist/` (JS, CJS, bundled CSS injection, declarations). |
130
+ | Lint | `npm run lint` | ESLint. |
131
+
132
+ `prepublishOnly` runs `build` before publish.
133
+
134
+ ## License
135
+
136
+ MIT. TradingView Charting Library is subject to its own license from TradingView.