@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 +210 -105
- package/dist/index.d.ts +34 -0
- package/dist/widget-iccandle.cjs +8 -8
- package/dist/widget-iccandle.js +2047 -1700
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @iccandle/vuejs-widget
|
|
2
2
|
|
|
3
|
-
Vue 3
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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 {
|
|
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
|
|
39
|
-
const
|
|
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
|
-
<
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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 `
|
|
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
|
-
|
|
90
|
+
## Usage
|
|
69
91
|
|
|
70
|
-
|
|
71
|
-
npm install @iccandle/vuejs-widget
|
|
72
|
-
```
|
|
92
|
+
### 1. Host the Charting Library
|
|
73
93
|
|
|
74
|
-
|
|
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
|
-
###
|
|
96
|
+
### 2. Bootstrap TradingView with replay support
|
|
77
97
|
|
|
78
|
-
|
|
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/";
|
|
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
|
-
|
|
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
|
-
###
|
|
152
|
+
### 3. Wrap the chart with `WidgetIccandle`
|
|
128
153
|
|
|
129
|
-
|
|
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
|
-
:
|
|
135
|
-
theme="
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
:
|
|
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
|
-
###
|
|
170
|
+
### 4. Handle the results iframe URL
|
|
145
171
|
|
|
146
|
-
After a successful scan
|
|
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
|
-
|
|
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
|
-
|
|
192
|
+
`result-iframe-ref` is a mutable `{ current }` box, not a Vue `ref`. Sync it from the iframe element:
|
|
159
193
|
|
|
160
|
-
```
|
|
161
|
-
|
|
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
|
-
###
|
|
203
|
+
### Sign-in
|
|
165
204
|
|
|
166
|
-
|
|
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
|
-
###
|
|
207
|
+
### Theme
|
|
171
208
|
|
|
172
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
217
|
+
### Chart mask colors
|
|
177
218
|
|
|
178
|
-
|
|
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
|
-
|
|
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
|
-
|
|
|
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
|
-
|
|
240
|
+
### Layout helpers
|
|
203
241
|
|
|
204
|
-
|
|
242
|
+
Injected CSS includes split-pane classes used in the demo:
|
|
205
243
|
|
|
206
|
-
|
|
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
|
-
|
|
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
|
-
|
|
255
|
+
## API
|
|
212
256
|
|
|
213
|
-
###
|
|
257
|
+
### Exports
|
|
214
258
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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
|
-
|
|
276
|
+
### `WidgetIccandle` props
|
|
221
277
|
|
|
222
|
-
|
|
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/` (
|
|
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];
|