@iccandle/vuejs-widget 0.0.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 ADDED
@@ -0,0 +1,236 @@
1
+ # @iccandle/vuejs-widget
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.
4
+
5
+ Published as ESM and CommonJS; component styles are bundled and injected at runtime (no separate CSS import).
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @iccandle/vuejs-widget
11
+ # or
12
+ pnpm add @iccandle/vuejs-widget
13
+ ```
14
+
15
+ ### How to get an API key
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).
20
+
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.
28
+
29
+ ## Quick start
30
+
31
+ ```vue
32
+ <script setup lang="ts">
33
+ import { shallowRef } from "vue";
34
+ import type { IChartingLibraryWidget } from "charting_library/charting_library";
35
+ import { WidgetIccandle } from "@iccandle/vuejs-widget";
36
+
37
+ const chartWidget = shallowRef<IChartingLibraryWidget | null>(null);
38
+ const widgetKey = "icc_search_..."; // ICCandle-issued key (48 hex chars after prefix)
39
+ const iframeSrc = shallowRef("");
40
+
41
+ function handleSubmit(src: string) {
42
+ iframeSrc.value = src;
43
+ }
44
+ </script>
45
+
46
+ <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" />
61
+ </template>
62
+ ```
63
+
64
+ Replace the chart placeholder with your TradingView initialization and pass the `IChartingLibraryWidget` instance when `onChartReady` (or equivalent) fires.
65
+
66
+ ## Usage guide
67
+
68
+ ### Step 1 — Install the package
69
+
70
+ ```bash
71
+ npm install @iccandle/vuejs-widget
72
+ ```
73
+
74
+ Ensure `vue` is installed and meets the peer version range.
75
+
76
+ ### Step 2 — Host the Charting Library
77
+
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
82
+
83
+ ```ts
84
+ import { onMounted, onBeforeUnmount, ref, shallowRef } from "vue";
85
+ import type {
86
+ ChartingLibraryWidgetOptions,
87
+ IChartingLibraryWidget,
88
+ ResolutionString,
89
+ } from "charting_library/charting_library";
90
+ import { widget } from "charting_library/charting_library";
91
+
92
+ const LIBRARY_PATH = "/charting_library/"; // must match your hosted assets
93
+
94
+ const containerRef = ref<HTMLDivElement | null>(null);
95
+ const chartWidget = shallowRef<IChartingLibraryWidget | null>(null);
96
+
97
+ onMounted(() => {
98
+ const el = containerRef.value;
99
+ if (!el) return;
100
+
101
+ const options: ChartingLibraryWidgetOptions = {
102
+ container: el,
103
+ library_path: LIBRARY_PATH,
104
+ symbol: "EURUSD",
105
+ interval: "60" as ResolutionString,
106
+ datafeed: yourDatafeed,
107
+ locale: "en",
108
+ autosize: true,
109
+ };
110
+
111
+ const tv = new widget(options);
112
+ chartWidget.value = tv;
113
+
114
+ onBeforeUnmount(() => {
115
+ try {
116
+ tv.remove();
117
+ } catch {
118
+ /* no-op */
119
+ }
120
+ chartWidget.value = null;
121
+ });
122
+ });
123
+ ```
124
+
125
+ You must supply a valid `datafeed`, `symbol`, `interval`, `locale`, and any other options required by your TradingView license and app.
126
+
127
+ ### Step 4 — Wrap the chart with `WidgetIccandle`
128
+
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):
130
+
131
+ ```vue
132
+ <WidgetIccandle
133
+ :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 */ }"
139
+ >
140
+ <div ref="containerRef" style="height: 100%; min-height: 400px" />
141
+ </WidgetIccandle>
142
+ ```
143
+
144
+ ### Step 5 — Handle the plugin iframe URL
145
+
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.
147
+
148
+ **Open in a new tab**
149
+
150
+ ```ts
151
+ submitCallback: (iframeSrc) => {
152
+ window.open(iframeSrc, "_blank", "noopener,noreferrer");
153
+ }
154
+ ```
155
+
156
+ **Show in a modal or side panel**
157
+
158
+ Store the URL in state and render:
159
+
160
+ ```vue
161
+ <iframe v-if="iframeSrc" title="ICCandle pattern search" :src="iframeSrc" />
162
+ ```
163
+
164
+ ### Theme and remote branding
165
+
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`.
169
+
170
+ ### Full working example
171
+
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).
173
+
174
+ ## API
175
+
176
+ ### Exports
177
+
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 |
186
+
187
+ ### `WidgetIccandle` props
188
+
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. |
201
+
202
+ Default slot receives `{ chartRefs }` for wiring custom indicators / generated-candle studies.
203
+
204
+ ### Widget key and remote theming
205
+
206
+ On mount, the component loads branding colors from ICCandle:
207
+
208
+ - **URL:** `https://api.iccandle.ai/corporate-client/v1/widgetStyle/search/user/?service_type=search`
209
+ - **Header:** `api-key: <widgetKey>`
210
+
211
+ CSS custom properties (`--iccandle-primary`, `--iccandle-border`, etc.) are applied on the widget root so the scanner matches your configured light/dark tokens.
212
+
213
+ ### Behavior summary
214
+
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.
219
+
220
+ ## Optional: timescale marks (news/events)
221
+
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.
223
+
224
+ ## Development (this repo)
225
+
226
+ | Script | Command | Purpose |
227
+ | ------ | ------- | ------- |
228
+ | Dev demo | `pnpm dev` | Vite app with local charting library. |
229
+ | Library build | `pnpm build` | Emits `dist/` (JS, CJS, bundled CSS injection, declarations). |
230
+ | App build | `pnpm build:app` | Full demo app build. |
231
+
232
+ `prepublishOnly` runs `build` before publish.
233
+
234
+ ## License
235
+
236
+ MIT. TradingView Charting Library is subject to its own license from TradingView.
@@ -0,0 +1,103 @@
1
+ import { Bar } from './tradingview-types/charting_library';
2
+ import { ComponentOptionsMixin } from 'vue';
3
+ import { ComponentProvideOptions } from 'vue';
4
+ import { CustomIndicator } from '.././tradingview-types/charting_library';
5
+ import { DefineComponent } from 'vue';
6
+ import { EntityId } from './tradingview-types/charting_library';
7
+ import { IBasicDataFeed } from './tradingview-types/charting_library';
8
+ import { IChartingLibraryWidget } from './tradingview-types/charting_library';
9
+ import { PublicProps } from 'vue';
10
+
11
+ declare const __VLS_component: DefineComponent<__VLS_Props, {
12
+ chartRefs: WidgetIccandleChartRefs;
13
+ }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
14
+ theme: "light" | "dark" | "system";
15
+ iframeLoaded: boolean;
16
+ }, {}, {}, {}, string, ComponentProvideOptions, false, {
17
+ rootEl: HTMLDivElement;
18
+ }, HTMLDivElement>;
19
+
20
+ declare type __VLS_Props = {
21
+ chartWidget: IChartingLibraryWidget | null;
22
+ theme?: "light" | "dark" | "system";
23
+ language?: WidgetLanguage;
24
+ onCloseResult?: () => void;
25
+ iframeLoaded?: boolean;
26
+ };
27
+
28
+ declare function __VLS_template(): {
29
+ attrs: Partial<{}>;
30
+ slots: {
31
+ default?(_: {
32
+ chartRefs: WidgetIccandleChartRefs;
33
+ }): any;
34
+ };
35
+ refs: {
36
+ rootEl: HTMLDivElement;
37
+ };
38
+ rootEl: HTMLDivElement;
39
+ };
40
+
41
+ declare type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
42
+
43
+ declare type __VLS_WithTemplateSlots<T, S> = T & {
44
+ new (): {
45
+ $slots: S;
46
+ };
47
+ };
48
+
49
+ declare type ChartItem = {
50
+ o: number;
51
+ h: number;
52
+ l: number;
53
+ c: number;
54
+ timestamp: number;
55
+ v?: number;
56
+ };
57
+
58
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
59
+ export { _default as SelectorWidget }
60
+ export { _default as WidgetIccandle }
61
+
62
+ export declare type GeneratedCandlesTheme = "light" | "dark";
63
+
64
+ export declare const getCustomIndicators: (theme?: GeneratedCandlesTheme) => Promise<readonly CustomIndicator[]>;
65
+
66
+ /** Pane-matching mask color so predicted bars hide the underlying series. */
67
+ export declare const getGeneratedCandlesMaskColor: (theme?: GeneratedCandlesTheme) => string;
68
+
69
+ /** @deprecated Use `WidgetIccandleChartRefs`. */
70
+ export declare type SelectorWidgetChartRefs = WidgetIccandleChartRefs;
71
+
72
+ export declare type TradingViewCandleType = ChartItem;
73
+
74
+ declare const WIDGET_LANGUAGES: readonly ["en", "zh", "vi", "th", "ko", "ja", "mn", "ru"];
75
+
76
+ export declare type WidgetIccandleChartRefs = {
77
+ highlightBarsRef: {
78
+ current: Bar[];
79
+ };
80
+ generatedCandlesBackgroundStudyIdRef: {
81
+ current: EntityId | null;
82
+ };
83
+ generatedCandlesStudyIdRef: {
84
+ current: EntityId | null;
85
+ };
86
+ };
87
+
88
+ /** Props for the published `WidgetIccandle` component. */
89
+ export declare type WidgetIccandleProps = {
90
+ chartWidget: IChartingLibraryWidget | null;
91
+ theme?: "light" | "dark" | "system";
92
+ language?: WidgetLanguage;
93
+ onCloseResult?: () => void;
94
+ iframeLoaded?: boolean;
95
+ };
96
+
97
+ export declare type WidgetLanguage = (typeof WIDGET_LANGUAGES)[number];
98
+
99
+ export declare function withPlayChart<T extends IBasicDataFeed>(datafeed: T): T;
100
+
101
+ export declare function withPlayChart<A extends unknown[]>(factory: (...args: A) => IBasicDataFeed, ...args: A): IBasicDataFeed;
102
+
103
+ export { }