@iccandle/vuejs-widget 0.1.5 → 0.2.1

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,8 +1,8 @@
1
1
  # @iccandle/vuejs-widget
2
2
 
3
- Vue 3 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.
3
+ Vue 3 scanner overlay for an existing [TradingView Charting Library](https://www.tradingview.com/charting-library-docs/) widget. It adds ICCandle’s draggable scanner popup, pattern search, replay of predicted candles, and a results embed.
4
4
 
5
- Published as ESM and CommonJS; component styles are bundled and injected at runtime (no separate CSS import).
5
+ Published as ESM and CommonJS. Component styles are bundled and injected at runtime no separate CSS import.
6
6
 
7
7
  ## Install
8
8
 
@@ -12,73 +12,90 @@ npm install @iccandle/vuejs-widget
12
12
  pnpm add @iccandle/vuejs-widget
13
13
  ```
14
14
 
15
- ### How to get an API key
15
+ `vue` `^3.5.0` is a **peer dependency**. Install it in your app. `axios` is a runtime dependency of this package.
16
16
 
17
- 1. Register or sign in at the [ICCandle corporate portal](https://corporate-iccandle.vercel.app/).
18
- 2. Use **Create API key** in the dashboard.
19
- 3. When selecting a service, choose **search** so the key is valid for this widget (remote theming, candle cache, and scanner validation).
17
+ ## Prerequisites
20
18
 
21
- Issued keys use the format `icc_search_` followed by 48 hexadecimal characters.
22
-
23
- ### Prerequisites
24
-
25
- - **Vue 3.5+** — `vue` is a **peer dependency** (install it in your app).
26
- - **TradingView Charting Library** — obtain it under your own license from TradingView, host the static assets (e.g. under `/charting_library/` in your public folder), and load the library at runtime. **This package does not ship the charting library.**
27
- - **ICCandle API key** — required for theme, candle cache, and scanner validation; format `icc_search_` plus 48 hex characters. See [How to get an API key](#how-to-get-an-api-key) above.
19
+ - **Vue 3.5+**
20
+ - **TradingView Charting Library** — obtain it under your own license, host the static assets (for example `/charting_library/`), and load it at runtime via `library_path`. **This package does not ship the charting library.**
21
+ - A **results iframe** (or equivalent) that loads ICCandle’s embed app. Scan/tracker actions require the user to sign in inside that embed; the widget stores the session as `iccandle_token` in `localStorage`.
28
22
 
29
23
  ## Quick start
30
24
 
31
25
  ```vue
32
26
  <script setup lang="ts">
33
- import { shallowRef } from "vue";
27
+ import { ref, shallowRef, watch } from "vue";
34
28
  import type { IChartingLibraryWidget } from "charting_library/charting_library";
35
- import { WidgetIccandle } from "@iccandle/vuejs-widget";
29
+ import {
30
+ WidgetIccandle,
31
+ WIDGET_RESULT_URL,
32
+ handleResultIframeLoad,
33
+ } from "@iccandle/vuejs-widget";
36
34
 
37
35
  const chartWidget = shallowRef<IChartingLibraryWidget | null>(null);
38
- const widgetKey = "icc_search_..."; // ICCandle-issued key (48 hex chars after prefix)
39
- const iframeSrc = shallowRef("");
36
+ const language = "en" as const;
37
+ const theme = "dark" as const;
38
+
39
+ const iframeSrc = ref(`${WIDGET_RESULT_URL}/${language}?theme=${theme}&header=true`);
40
+ const iframeLoaded = ref(false);
41
+ const resultIframeRef = ref<HTMLIFrameElement | null>(null);
42
+ const resultIframeBox = { current: null as HTMLIFrameElement | null };
43
+
44
+ watch(
45
+ resultIframeRef,
46
+ (el) => {
47
+ resultIframeBox.current = el;
48
+ },
49
+ { immediate: true },
50
+ );
40
51
 
41
52
  function handleSubmit(src: string) {
42
53
  iframeSrc.value = src;
43
54
  }
55
+
56
+ function handleIframeLoad() {
57
+ iframeLoaded.value = true;
58
+ handleResultIframeLoad(resultIframeRef.value);
59
+ }
44
60
  </script>
45
61
 
46
62
  <template>
47
- <WidgetIccandle
48
- :chart-widget="chartWidget"
49
- :widget-key="widgetKey"
50
- theme="system"
51
- user-id="your-user-id"
52
- email="you@example.com"
53
- :submit-callback="handleSubmit"
54
- >
55
- <template #default="{ chartRefs }">
56
- <!-- Your chart container + TradingView bootstrap; set chartWidget when ready -->
57
- <div id="tv_chart_container" style="height: 100%" />
58
- </template>
59
- </WidgetIccandle>
60
- <iframe v-if="iframeSrc" :src="iframeSrc" title="ICCandle results" />
63
+ <div class="iccandle-selector-widget__container">
64
+ <div class="iccandle-selector-widget__chart-pane">
65
+ <WidgetIccandle
66
+ :chart-widget="chartWidget"
67
+ :submit-callback="handleSubmit"
68
+ :theme="theme"
69
+ :language="language"
70
+ :iframe-loaded="iframeLoaded"
71
+ :result-iframe-ref="resultIframeBox"
72
+ >
73
+ <!-- Bootstrap TradingView here and assign chartWidget when ready -->
74
+ <div id="tv_chart_container" style="height: 100%" />
75
+ </WidgetIccandle>
76
+ </div>
77
+ <iframe
78
+ ref="resultIframeRef"
79
+ :src="iframeSrc"
80
+ class="iccandle-selector-widget__iframe"
81
+ title="ICCandle results"
82
+ @load="handleIframeLoad"
83
+ />
84
+ </div>
61
85
  </template>
62
86
  ```
63
87
 
64
- Replace the chart placeholder with your TradingView initialization and pass the `IChartingLibraryWidget` instance when `onChartReady` (or equivalent) fires.
65
-
66
- ## Usage guide
88
+ Replace the chart placeholder with your TradingView initialization and pass the `IChartingLibraryWidget` instance when the widget is created (typically right after `new widget(options)`).
67
89
 
68
- ### Step 1 — Install the package
90
+ ## Usage
69
91
 
70
- ```bash
71
- npm install @iccandle/vuejs-widget
72
- ```
92
+ ### 1. Host the Charting Library
73
93
 
74
- Ensure `vue` is installed and meets the peer version range.
94
+ Copy the TradingView Charting Library build into a path your app can serve as static files (for example `public/charting_library/` in Vite). Point `library_path` at that URL. The library is **not** bundled inside `@iccandle/vuejs-widget`.
75
95
 
76
- ### Step 2 Host the Charting Library
96
+ ### 2. Bootstrap TradingView with replay support
77
97
 
78
- 1. Copy the TradingView Charting Library build into a path your app can serve as static files (e.g. `public/charting_library/` in Vite).
79
- 2. Import the library constructor from that path in your bundler setup (see TradingView’s integration docs for your framework). The library is **not** bundled inside `@iccandle/vuejs-widget`; it loads at runtime via `library_path` (or equivalent) on the widget options.
80
-
81
- ### Step 3 — Bootstrap TradingView and capture the widget instance
98
+ Wrap your datafeed with `withPlayChart` so the widget can inject predicted bars during replay. Register `getCustomIndicators` so those bars render as generated-candle studies:
82
99
 
83
100
  ```ts
84
101
  import { onMounted, onBeforeUnmount, ref, shallowRef } from "vue";
@@ -88,8 +105,9 @@ import type {
88
105
  ResolutionString,
89
106
  } from "charting_library/charting_library";
90
107
  import { widget } from "charting_library/charting_library";
108
+ import { withPlayChart, getCustomIndicators } from "@iccandle/vuejs-widget";
91
109
 
92
- const LIBRARY_PATH = "/charting_library/"; // must match your hosted assets
110
+ const LIBRARY_PATH = "/charting_library/";
93
111
 
94
112
  const containerRef = ref<HTMLDivElement | null>(null);
95
113
  const chartWidget = shallowRef<IChartingLibraryWidget | null>(null);
@@ -103,9 +121,14 @@ onMounted(() => {
103
121
  library_path: LIBRARY_PATH,
104
122
  symbol: "EURUSD",
105
123
  interval: "60" as ResolutionString,
106
- datafeed: yourDatafeed,
124
+ datafeed: withPlayChart(yourDatafeed),
107
125
  locale: "en",
108
126
  autosize: true,
127
+ drawings_access: {
128
+ type: "black",
129
+ tools: [{ name: "Date Range" }],
130
+ },
131
+ custom_indicators_getter: () => getCustomIndicators("dark"),
109
132
  };
110
133
 
111
134
  const tv = new widget(options);
@@ -122,111 +145,193 @@ onMounted(() => {
122
145
  });
123
146
  ```
124
147
 
125
- You must supply a valid `datafeed`, `symbol`, `interval`, `locale`, and any other options required by your TradingView license and app.
148
+ `withPlayChart` also accepts a factory plus its arguments: `withPlayChart(createDatafeed, arg1, arg2)`.
149
+
150
+ You must supply a valid `datafeed`, `symbol`, `interval`, `locale`, and any other options required by your TradingView license.
126
151
 
127
- ### Step 4 — Wrap the chart with `WidgetIccandle`
152
+ ### 3. Wrap the chart with `WidgetIccandle`
128
153
 
129
- `WidgetIccandle` must wrap the same subtree that contains the chart container so the scanner overlay positions correctly. Pass the live widget instance (or `null` while mounting):
154
+ The component must wrap the same subtree that contains the chart container so the scanner overlay positions correctly. Pass `null` for `chartWidget` until the instance is ready.
130
155
 
131
156
  ```vue
132
157
  <WidgetIccandle
133
158
  :chart-widget="chartWidget"
134
- :widget-key="widgetKey"
135
- theme="system"
136
- user-id="your-user-id"
137
- email="you@example.com"
138
- :submit-callback="(iframeSrc) => { /* see Step 5 */ }"
159
+ :submit-callback="handleSubmit"
160
+ theme="dark"
161
+ language="en"
162
+ :iframe-loaded="iframeLoaded"
163
+ :result-iframe-ref="resultIframeBox"
164
+ :available-intervals="['1', '5', '15', '30', '60']"
139
165
  >
140
166
  <div ref="containerRef" style="height: 100%; min-height: 400px" />
141
167
  </WidgetIccandle>
142
168
  ```
143
169
 
144
- ### Step 5 — Handle the plugin iframe URL
170
+ ### 4. Handle the results iframe URL
145
171
 
146
- After a successful scan setup, `submitCallback` receives a **full HTTPS URL** for the ICCandle plugin iframe. The query string typically includes the bar window (timestamps / size), symbol, `candle_id`, `apiKey` (your widget key), resolved theme, and any active filters—use it as-is in an iframe `src` or deep link.
172
+ After a successful scan, `submitCallback` receives a full HTTPS URL for the ICCandle embed. Typical query parameters include symbol, reference resolution, scan resolution, candle cache id (`cid`), time window (`from` / `to`), theme, and optional filters (`fs`, `period`, `model`, `temp`).
173
+
174
+ **Split pane (recommended)** — keep an iframe beside the chart and update its `src`:
175
+
176
+ ```ts
177
+ const submitCallback = (nextSrc: string) => {
178
+ iframeSrc.value = nextSrc;
179
+ };
180
+ ```
147
181
 
148
182
  **Open in a new tab**
149
183
 
150
184
  ```ts
151
185
  submitCallback: (iframeSrc) => {
152
186
  window.open(iframeSrc, "_blank", "noopener,noreferrer");
153
- }
187
+ };
154
188
  ```
155
189
 
156
- **Show in a modal or side panel**
190
+ On iframe `load`, call `handleResultIframeLoad(iframe)` so the embed knows the parent origin (required for sign-in to write `iccandle_token`) and so a Stripe return of `?payment=success` can refresh the subscription without a full reload.
157
191
 
158
- Store the URL in state and render:
192
+ `result-iframe-ref` is a mutable `{ current }` box, not a Vue `ref`. Sync it from the iframe element:
159
193
 
160
- ```vue
161
- <iframe v-if="iframeSrc" title="ICCandle pattern search" :src="iframeSrc" />
194
+ ```ts
195
+ const resultIframeRef = ref<HTMLIFrameElement | null>(null);
196
+ const resultIframeBox = { current: null as HTMLIFrameElement | null };
197
+
198
+ watch(resultIframeRef, (el) => {
199
+ resultIframeBox.current = el;
200
+ }, { immediate: true });
162
201
  ```
163
202
 
164
- ### Theme and remote branding
203
+ ### Sign-in
165
204
 
166
- - **`theme="light"` / `"dark"`** forces that palette for the scanner chrome and for values forwarded into the plugin URL.
167
- - **`theme="system"`** — follows `prefers-color-scheme` for light/dark resolution.
168
- - On mount, the widget fetches your org’s tokens from ICCandle and sets CSS custom properties on the widget root, e.g. `--iccandle-primary`, `--iccandle-border`.
205
+ Scan and Pattern Tracker require `localStorage.iccandle_token`. The results iframe posts `auth.signIn` / `auth.signOut`; the widget listens and stores or clears the token. Until the user signs in, those actions show a login prompt.
169
206
 
170
- ### Full working example
207
+ ### Theme
171
208
 
172
- See [`src/App.vue`](src/App.vue) and [`src/tradingview/TradingviewChart.vue`](src/tradingview/TradingviewChart.vue) in this repository’s dev app for a concrete in-repo reference (custom datafeed, timezone, visibility handling).
209
+ | `theme` | Behavior |
210
+ | ------- | -------- |
211
+ | `"light"` (default) | Light scanner chrome and embed theme. |
212
+ | `"dark"` | Dark scanner chrome; adds `.iccandle-dark` on the root. |
213
+ | `"system"` | Follows `prefers-color-scheme`. |
173
214
 
174
- ## API
215
+ The root uses CSS custom properties you can override: `--iccandle-primary`, `--iccandle-border`, `--iccandle-text`, `--iccandle-background`, `--iccandle-primary-gradient-end`, `--iccandle-font`.
175
216
 
176
- ### Exports
217
+ ### Chart mask colors
177
218
 
178
- | Name | Kind | Description |
179
- | ---- | ---- | ----------- |
180
- | `WidgetIccandle` | Component | Scanner overlay around your chart subtree |
181
- | `SelectorWidget` | Component | Deprecated alias of `WidgetIccandle` |
182
- | `WidgetIccandleChartRefs` | Type | Chart study refs for generated candles |
183
- | `withPlayChart` | Function | Wrap a datafeed for replay / predicted candles |
184
- | `getCustomIndicators` | Function | TradingView custom indicators for generated candles |
185
- | `getGeneratedCandlesMaskColor` | Function | Theme-aware mask color for predicted bars |
219
+ During replay the widget draws all predicted candles at once and hides the ones that have not been revealed yet by painting them in a solid "mask" color. The illusion only works if that color is identical to the chart pane background, otherwise the hidden bars show up as visible blocks ahead of the replay cursor.
186
220
 
187
- ### `WidgetIccandle` props
221
+ Defaults are `#ffffff` for `light` and `#0F0F0F` for `dark`. If your TradingView `paneProperties.background` differs, pass `chartMaskColors` with the matching value:
222
+
223
+ ```vue
224
+ <WidgetIccandle
225
+ :chart-widget="chartWidget"
226
+ :submit-callback="handleSubmit"
227
+ theme="dark"
228
+ :chart-mask-colors="{ dark: '#2F2F2F', light: '#ffffff' }"
229
+ >
230
+ <div ref="containerRef" style="height: 100%" />
231
+ </WidgetIccandle>
232
+ ```
233
+
234
+ Only the entry for the active theme is used, and each key is optional — omit one to keep its default. Any CSS color string the charting library accepts works, but avoid transparency: a translucent mask lets the real series bleed through. Changing the prop recreates the generated-candle studies, so it can be updated reactively when the host switches themes.
235
+
236
+ ### Language
188
237
 
189
- | Prop | Type | Required | Description |
190
- | ---- | ---- | -------- | ----------- |
191
- | `chartWidget` | `IChartingLibraryWidget \| null` | Yes | Live TradingView widget instance (`null` until ready). |
192
- | `widgetKey` | `string` | Yes | ICCandle API key (`icc_search_` + 48 hex chars). |
193
- | `submitCallback` | `(iframeSrc: string) => void` | Yes | Called after a successful scan setup with the plugin iframe URL. |
194
- | `userId` | `string` | Yes | User id forwarded to the results plugin. |
195
- | `email` | `string` | Yes | User email (pattern tracker). |
196
- | `widgetKeyPatternTracker` | `string` | No | Optional tracker API key (`icc_tracker_…`). |
197
- | `theme` | `"light" \| "dark" \| "system"` | No | Defaults to `"light"`. `"system"` follows `prefers-color-scheme`. |
198
- | `language` | `WidgetLanguage` | No | Scanner UI language (`en`, `zh`, `vi`, …). |
199
- | `onCloseResult` | `() => void` | No | Called when the results iframe posts `close-result`. |
200
- | `iframeLoaded` | `boolean` | No | Disables scanner actions while results iframe is loading. |
238
+ `language` accepts `"en"` | `"zh"` | `"vi"` | `"th"` | `"ko"` | `"ja"` | `"mn"` | `"ru"`. Unknown values fall back to `"en"`. The value is used for scanner copy and is forwarded into embed URLs.
201
239
 
202
- Default slot receives `{ chartRefs }` for wiring custom indicators / generated-candle studies.
240
+ ### Layout helpers
203
241
 
204
- ### Widget key and remote theming
242
+ Injected CSS includes split-pane classes used in the demo:
205
243
 
206
- On mount, the component loads branding colors from ICCandle:
244
+ | Class | Role |
245
+ | ----- | ---- |
246
+ | `.iccandle-selector-widget__container` | Flex row (stacks below 1024px). `--chart-pane-size` defaults to `60%`. |
247
+ | `.iccandle-selector-widget__chart-pane` | Chart column. |
248
+ | `.iccandle-selector-widget__resize-handle` | Drag handle; add `--stacked` for the stacked layout. |
249
+ | `.iccandle-selector-widget__iframe` | Results pane. |
250
+
251
+ ### Full working example
207
252
 
208
- - **URL:** `https://api.iccandle.ai/corporate-client/v1/widgetStyle/search/user/?service_type=search`
209
- - **Header:** `api-key: <widgetKey>`
253
+ See [`src/App.vue`](src/App.vue), [`src/tradingview/TradingviewChart.vue`](src/tradingview/TradingviewChart.vue), and [`src/tradingview/TradingviewChartContainer.vue`](src/tradingview/TradingviewChartContainer.vue) in this repository.
210
254
 
211
- CSS custom properties (`--iccandle-primary`, `--iccandle-border`, etc.) are applied on the widget root so the scanner matches your configured light/dark tokens.
255
+ ## API
212
256
 
213
- ### Behavior summary
257
+ ### Exports
214
258
 
215
- - Subscribes to chart readiness, resolution, symbol changes, and drawing events.
216
- - Manages a `date_range` multipoint drawing so the user can adjust the bar window; window size and exported candles drive the scanner.
217
- - Posts candles to ICCandle’s cache endpoint before opening the plugin URL.
218
- - Listens for `window` `message` events for chart/news/pattern integration (replay, event marks, pattern selection) and can clear persisted news mark selections (`localStorage` keys `tv:selected-news-events`, `tv:clicked-news-event`) when starting a scan.
259
+ | Name | Kind | Description |
260
+ | ---- | ---- | ----------- |
261
+ | `WidgetIccandle` | Component | Scanner overlay around your chart subtree. |
262
+ | `WidgetIccandleProps` | Type | Public props of `WidgetIccandle`. |
263
+ | `WidgetChartMaskColors` | Type | `{ light?: string; dark?: string }` for the `chartMaskColors` prop. |
264
+ | `WidgetLanguage` | Type | Supported UI languages. |
265
+ | `withPlayChart` | Function | Wrap a TradingView datafeed (or factory) so replay can inject bars and block live ticks. |
266
+ | `getCustomIndicators` | Function | Returns custom studies used to draw generated / predicted candles. Pass `"light"` or `"dark"`. |
267
+ | `GeneratedCandlesTheme` | Type | `"light"` \| `"dark"` for `getCustomIndicators`. |
268
+ | `handleResultIframeLoad` | Function | Post parent origin (and optional payment-success) to the results iframe. |
269
+ | `WIDGET_RESULT_URL` | Constant | Default embed origin: `https://embed-iccandle-app.iccandle.ai`. |
270
+ | `OPEN_PRICING_MESSAGE_TYPE` | Constant | `"open-pricing"` postMessage type. |
271
+ | `postOpenPricingToEmbed` | Function | Ask the results iframe to open pricing. Returns `false` if no `contentWindow`. |
272
+ | `postOpenPricingToParent` | Function | Forward pricing to `window.parent` when this widget is itself embedded. |
273
+ | `postOpenPricingToWindow` | Function | Post an `open-pricing` message to an arbitrary `Window`. |
274
+ | `OpenPricingMessage` | Type | `{ type, theme?, language? }`. |
219
275
 
220
- ## Optional: timescale marks (news/events)
276
+ ### `WidgetIccandle` props
221
277
 
222
- 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. See the React sibling docs or `src/lib/data-feed.ts` in this repo for a working example.
278
+ | Prop | Type | Required | Default | Description |
279
+ | ---- | ---- | -------- | ------- | ----------- |
280
+ | `chartWidget` | `IChartingLibraryWidget \| null` | Yes | — | Live TradingView widget (`null` until ready). |
281
+ | `submitCallback` | `(iframeSrc: string) => void` | Yes | — | Called with the embed URL after a scan (and for some pricing / news navigations). |
282
+ | `theme` | `"light" \| "dark" \| "system"` | No | `"light"` | Scanner and forwarded embed theme. |
283
+ | `chartMaskColors` | `WidgetChartMaskColors` | No | `{ light: "#ffffff", dark: "#0F0F0F" }` | Per-theme color used to mask not-yet-revealed predicted candles. Must match your chart pane background. |
284
+ | `language` | `WidgetLanguage` | No | `"en"` | Scanner UI language. |
285
+ | `onCloseResult` | `() => void` | No | — | Called when the embed posts `selector.closeResult`. |
286
+ | `iframeLoaded` | `boolean` | No | `true` | When `false`, Scan and Pattern Tracker are disabled. Set `true` after the results iframe has loaded. |
287
+ | `resultIframeRef` | `{ current: HTMLIFrameElement \| null } \| null` | No | — | Results iframe box. Receives `open-pricing` and chart-resolution postMessages. |
288
+ | `isShowScanButton` | `boolean` | No | `true` | Show Scan inside the popup. |
289
+ | `isShowTrackerButton` | `boolean` | No | `true` | Show Pattern Tracker inside the popup. |
290
+ | `isShowScannerPopup` | `boolean` | No | `true` | Show the scanner popup. |
291
+ | `availableIntervals` | `string[]` | No | — | Resolutions allowed when drawing a pattern date range from embed selection. |
292
+ | `onScanClick` | `() => void` | No | — | Fired when the user clicks Scan, before login / config / scan logic. |
293
+
294
+ Default slot receives `{ chartRefs }` (`highlightBarsRef`, generated-candle study ids). The same object is exposed on the component instance as `chartRefs`.
295
+
296
+ ### Behavior
297
+
298
+ - Subscribes to chart readiness, resolution, symbol, visible range, drawings, and timescale-mark clicks.
299
+ - Draws a `date_range` shape for the scan window; bar count and exported candles drive the scanner.
300
+ - Posts selected candles to ICCandle’s cache, then calls `submitCallback` with the embed URL.
301
+ - Listens for `window` `message` events from the embed (replay, auth, news, pattern selection, navigation, loading).
302
+ - Clears persisted news mark keys (`tv:selected-news-events`, `tv:clicked-news-event`) when a scan starts.
303
+
304
+ ### Embed `postMessage` names
305
+
306
+ The widget handles JSON messages with a `name` (and optional `data`) from the results iframe:
307
+
308
+ | Name | Effect |
309
+ | ---- | ------ |
310
+ | `chart.play` | Replay / predicted candles on the chart. |
311
+ | `chart.stop` | Stop replay and restore live ticks. |
312
+ | `chart.requestResolution` | Re-post the current chart resolution to the iframe. |
313
+ | `selector.closeResult` | Invoke `onCloseResult`. |
314
+ | `selector.loading` | Toggle scanner loading state. |
315
+ | `auth.signIn` | Store `data.idToken` as `iccandle_token`. |
316
+ | `auth.signOut` | Remove `iccandle_token`. |
317
+ | `news.eventClicked` | Draw event marks / target window on the chart. |
318
+ | `news.back` / `news.backToSimilarEvents` | Clear event overlay / replay. |
319
+ | `pattern.classicPatternSelected` / `pattern.custom_pattern_selected` | Draw the compared pattern’s date range. |
320
+ | `pattern.clearClassicPatternSelected` / `pattern.clear_custom_pattern_selected` | Clear pattern overlay. |
321
+ | `nav.click` | Handle embed navigation (clears date range on `/news` routes). |
322
+
323
+ The host → embed helpers use a different shape: `{ type: "parent-origin" | "payment-success" | "open-pricing" | "chart-resolution", ... }`.
324
+
325
+ ## Optional: timescale marks (news / events)
326
+
327
+ If your datafeed implements `getTimescaleMarks`, you can surface stored events from `localStorage` (`tv:selected-news-events`, `tv:clicked-news-event`) as marks on the time axis. See [`src/lib/data-feed.ts`](src/lib/data-feed.ts) in this repo.
223
328
 
224
329
  ## Development (this repo)
225
330
 
226
331
  | Script | Command | Purpose |
227
332
  | ------ | ------- | ------- |
228
- | Dev demo | `pnpm dev` | Vite app with local charting library. |
229
- | Library build | `pnpm build` | Emits `dist/` (JS, CJS, bundled CSS injection, declarations). |
333
+ | Dev demo | `pnpm dev` | Vite app with a local charting library. |
334
+ | Library build | `pnpm build` | Emits `dist/` (ESM, CJS, injected CSS, declarations). |
230
335
  | App build | `pnpm build:app` | Full demo app build. |
231
336
 
232
337
  `prepublishOnly` runs `build` before publish.
package/dist/index.d.ts CHANGED
@@ -24,6 +24,8 @@ declare type __VLS_Props = {
24
24
  chartWidget: IChartingLibraryWidget | null;
25
25
  submitCallback: (iframeSrc: string) => void;
26
26
  theme?: "light" | "dark" | "system";
27
+ /** Simulate-candle mask colors per theme. Defaults: light `#ffffff`, dark `#0F0F0F`. */
28
+ chartMaskColors?: WidgetChartMaskColors;
27
29
  language?: WidgetLanguage;
28
30
  onCloseResult?: () => void;
29
31
  iframeLoaded?: boolean;
@@ -39,6 +41,8 @@ declare type __VLS_Props = {
39
41
  isShowScannerPopup?: boolean;
40
42
  /** Chart resolutions allowed for pattern date-range drawing. */
41
43
  availableIntervals?: string[];
44
+ /** Called when the user clicks Scan in the scanner popup. */
45
+ onScanClick?: () => void;
42
46
  };
43
47
 
44
48
  declare function __VLS_template(): {
@@ -62,6 +66,9 @@ declare type __VLS_WithTemplateSlots<T, S> = T & {
62
66
  };
63
67
  };
64
68
 
69
+ /** Same origin + path → soft update via postMessage (no iframe remount). */
70
+ export declare function canSoftSelectorNavigate(iframe: HTMLIFrameElement | null | undefined, nextSrc: string): boolean;
71
+
65
72
  export declare type GeneratedCandlesTheme = "light" | "dark";
66
73
 
67
74
  export declare const getCustomIndicators: (theme?: GeneratedCandlesTheme) => Promise<readonly CustomIndicator[]>;
@@ -82,10 +89,33 @@ export declare function postOpenPricingToParent(options?: Pick<OpenPricingMessag
82
89
 
83
90
  export declare function postOpenPricingToWindow(target: Window, options?: Pick<OpenPricingMessage, "theme" | "language">): void;
84
91
 
92
+ export declare function postSelectorLoadingToEmbed(iframe: HTMLIFrameElement | null | undefined, isLoading: boolean): boolean;
93
+
94
+ export declare function postSelectorScanToEmbed(iframe: HTMLIFrameElement | null | undefined, url: string): boolean;
95
+
96
+ export declare const SELECTOR_LOADING_MESSAGE_TYPE = "selector-loading";
97
+
98
+ export declare const SELECTOR_SCAN_MESSAGE_TYPE = "selector-scan";
99
+
100
+ export declare type SelectorLoadingMessage = {
101
+ type: typeof SELECTOR_LOADING_MESSAGE_TYPE;
102
+ isLoading: boolean;
103
+ };
104
+
105
+ export declare type SelectorScanMessage = {
106
+ type: typeof SELECTOR_SCAN_MESSAGE_TYPE;
107
+ url: string;
108
+ };
109
+
85
110
  declare const WIDGET_LANGUAGES: readonly ["en", "zh", "vi", "th", "ko", "ja", "mn", "ru"];
86
111
 
87
112
  export declare const WIDGET_RESULT_URL = "https://embed-iccandle-app.iccandle.ai";
88
113
 
114
+ export declare type WidgetChartMaskColors = {
115
+ light?: string;
116
+ dark?: string;
117
+ };
118
+
89
119
  export declare const WidgetIccandle: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
90
120
 
91
121
  declare type WidgetIccandleChartRefs = {
@@ -105,6 +135,8 @@ export declare type WidgetIccandleProps = {
105
135
  chartWidget: IChartingLibraryWidget | null;
106
136
  submitCallback: (iframeSrc: string) => void;
107
137
  theme?: "light" | "dark" | "system";
138
+ /** Simulate-candle mask colors per theme. Defaults: light `#ffffff`, dark `#0F0F0F`. */
139
+ chartMaskColors?: WidgetChartMaskColors;
108
140
  language?: WidgetLanguage;
109
141
  onCloseResult?: () => void;
110
142
  iframeLoaded?: boolean;
@@ -120,6 +152,8 @@ export declare type WidgetIccandleProps = {
120
152
  isShowScannerPopup?: boolean;
121
153
  /** Chart resolutions allowed for pattern date-range drawing. */
122
154
  availableIntervals?: string[];
155
+ /** Called when the user clicks Scan in the scanner popup. */
156
+ onScanClick?: () => void;
123
157
  };
124
158
 
125
159
  export declare type WidgetLanguage = (typeof WIDGET_LANGUAGES)[number];