@trade-it/react 0.1.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/CHANGELOG.md +21 -0
- package/README.md +35 -0
- package/dist/index.cjs +454 -0
- package/dist/index.d.cts +222 -0
- package/dist/index.d.ts +222 -0
- package/dist/index.js +397 -0
- package/package.json +44 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@trade-it/react` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## 0.1.0 - 2026-02-25
|
|
6
|
+
|
|
7
|
+
Initial public SDK release (v1 foundation).
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Responsive iframe modal for embedded Trade It connect and trade experiences
|
|
12
|
+
- Declarative `<TradeItModal />` API
|
|
13
|
+
- Imperative `useTradeIt()` hook
|
|
14
|
+
- `postMessage` event forwarding for embedded lifecycle and trade events
|
|
15
|
+
- Trade URL template support (`[ticker]`) with SDK-side query serialization
|
|
16
|
+
- ESM + CommonJS builds with bundled runtime dependencies (excluding peers)
|
|
17
|
+
|
|
18
|
+
### Notes
|
|
19
|
+
|
|
20
|
+
- `@trade-it/react` depends on `@trade-it/core`
|
|
21
|
+
- Trade It session URLs should be created by your backend via `POST /api/session/url`
|
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# `@trade-it/react`
|
|
2
|
+
|
|
3
|
+
React SDK for embedding Trade It connect and trade experiences directly inside your app.
|
|
4
|
+
|
|
5
|
+
Use this package when you want to:
|
|
6
|
+
|
|
7
|
+
- open the Trade It connect flow in a modal
|
|
8
|
+
- open prefilled trade flows in a modal
|
|
9
|
+
- keep users on your site while they connect brokerages and place trades
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm i @trade-it/react
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Peer dependencies:
|
|
18
|
+
|
|
19
|
+
- `react` (`^18 || ^19`)
|
|
20
|
+
- `react-dom` (`^18 || ^19`)
|
|
21
|
+
|
|
22
|
+
## Documentation
|
|
23
|
+
|
|
24
|
+
Full integration guides, examples, and API references:
|
|
25
|
+
|
|
26
|
+
- [React SDK Overview](https://docs.tradeit.app/sdk)
|
|
27
|
+
- [Authentication](https://docs.tradeit.app/sdk/authentication)
|
|
28
|
+
- [Connect a Brokerage](https://docs.tradeit.app/sdk/connect)
|
|
29
|
+
- [Place Trades](https://docs.tradeit.app/sdk/trades)
|
|
30
|
+
- [SDK Enums Reference](https://docs.tradeit.app/sdk/enums)
|
|
31
|
+
|
|
32
|
+
## Notes
|
|
33
|
+
|
|
34
|
+
- Request Trade It session URLs from your server, not from the browser.
|
|
35
|
+
- `@trade-it/react` depends on `@trade-it/core`.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
//#region rolldown:runtime
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
+
key = keys[i];
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
+
get: ((k) => from[k]).bind(null, key),
|
|
13
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
value: mod,
|
|
20
|
+
enumerable: true
|
|
21
|
+
}) : target, mod));
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
const __trade_it_core = __toESM(require("@trade-it/core"));
|
|
25
|
+
const react = __toESM(require("react"));
|
|
26
|
+
const react_dom = __toESM(require("react-dom"));
|
|
27
|
+
const react_jsx_runtime = __toESM(require("react/jsx-runtime"));
|
|
28
|
+
|
|
29
|
+
//#region src/LoaderCircleSpinner.tsx
|
|
30
|
+
const SPINNER_WRAPPER_SIZE = 44;
|
|
31
|
+
const SPINNER_ICON_SIZE = 32;
|
|
32
|
+
const SPINNER_WRAPPER_STYLE = {
|
|
33
|
+
width: SPINNER_WRAPPER_SIZE,
|
|
34
|
+
height: SPINNER_WRAPPER_SIZE,
|
|
35
|
+
display: "flex",
|
|
36
|
+
alignItems: "center",
|
|
37
|
+
justifyContent: "center",
|
|
38
|
+
animation: "tradeItSdkSpin 0.9s linear infinite",
|
|
39
|
+
transformOrigin: "50% 50%"
|
|
40
|
+
};
|
|
41
|
+
const SPINNER_SVG_STYLE = {
|
|
42
|
+
display: "block",
|
|
43
|
+
width: SPINNER_ICON_SIZE,
|
|
44
|
+
height: SPINNER_ICON_SIZE,
|
|
45
|
+
color: "#111827"
|
|
46
|
+
};
|
|
47
|
+
const SPINNER_KEYFRAMES_CSS = `
|
|
48
|
+
@keyframes tradeItSdkSpin {
|
|
49
|
+
from { transform: rotate(0deg); }
|
|
50
|
+
to { transform: rotate(360deg); }
|
|
51
|
+
}
|
|
52
|
+
@media (prefers-reduced-motion: reduce) {
|
|
53
|
+
.tradeit-sdk-spinner {
|
|
54
|
+
animation: none !important;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
`;
|
|
58
|
+
function LoaderCircleSpinner() {
|
|
59
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: SPINNER_KEYFRAMES_CSS }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
60
|
+
className: "tradeit-sdk-spinner",
|
|
61
|
+
style: SPINNER_WRAPPER_STYLE,
|
|
62
|
+
"aria-hidden": "true",
|
|
63
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
64
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
65
|
+
width: SPINNER_ICON_SIZE,
|
|
66
|
+
height: SPINNER_ICON_SIZE,
|
|
67
|
+
viewBox: "0 0 24 24",
|
|
68
|
+
fill: "none",
|
|
69
|
+
stroke: "currentColor",
|
|
70
|
+
strokeWidth: "2",
|
|
71
|
+
strokeLinecap: "round",
|
|
72
|
+
strokeLinejoin: "round",
|
|
73
|
+
style: SPINNER_SVG_STYLE,
|
|
74
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
|
|
75
|
+
})
|
|
76
|
+
})] });
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region src/TradeItModalLoader.tsx
|
|
81
|
+
const LOADING_STYLE = {
|
|
82
|
+
position: "absolute",
|
|
83
|
+
inset: 0,
|
|
84
|
+
background: "#ffffff"
|
|
85
|
+
};
|
|
86
|
+
const LOADING_CONTENT_STYLE = {
|
|
87
|
+
position: "relative",
|
|
88
|
+
zIndex: 1,
|
|
89
|
+
display: "flex",
|
|
90
|
+
flexDirection: "column",
|
|
91
|
+
alignItems: "center",
|
|
92
|
+
justifyContent: "center",
|
|
93
|
+
width: "100%",
|
|
94
|
+
height: "100%"
|
|
95
|
+
};
|
|
96
|
+
function TradeItModalLoader() {
|
|
97
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
98
|
+
style: LOADING_STYLE,
|
|
99
|
+
"aria-live": "polite",
|
|
100
|
+
"aria-busy": "true",
|
|
101
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
102
|
+
style: LOADING_CONTENT_STYLE,
|
|
103
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LoaderCircleSpinner, {})
|
|
104
|
+
})
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region src/TradeItModal.tsx
|
|
110
|
+
const OVERLAY_STYLE = {
|
|
111
|
+
position: "fixed",
|
|
112
|
+
inset: 0,
|
|
113
|
+
background: "rgba(15, 23, 42, 0.55)",
|
|
114
|
+
backdropFilter: "blur(4px)",
|
|
115
|
+
display: "flex",
|
|
116
|
+
alignItems: "center",
|
|
117
|
+
justifyContent: "center",
|
|
118
|
+
padding: 12
|
|
119
|
+
};
|
|
120
|
+
const DIALOG_DESKTOP_STYLE = {
|
|
121
|
+
position: "relative",
|
|
122
|
+
width: "min(960px, calc(100vw - 24px))",
|
|
123
|
+
height: "min(760px, calc(100vh - 24px))",
|
|
124
|
+
background: "#fff",
|
|
125
|
+
borderRadius: 18,
|
|
126
|
+
boxShadow: "0 24px 80px rgba(2, 6, 23, 0.28)",
|
|
127
|
+
border: "1px solid rgba(148, 163, 184, 0.35)",
|
|
128
|
+
overflow: "hidden"
|
|
129
|
+
};
|
|
130
|
+
const DIALOG_MOBILE_STYLE = {
|
|
131
|
+
...DIALOG_DESKTOP_STYLE,
|
|
132
|
+
width: "100vw",
|
|
133
|
+
height: "100vh",
|
|
134
|
+
borderRadius: 0,
|
|
135
|
+
border: 0
|
|
136
|
+
};
|
|
137
|
+
const CLOSE_BUTTON_STYLE = {
|
|
138
|
+
position: "absolute",
|
|
139
|
+
top: 10,
|
|
140
|
+
right: 10,
|
|
141
|
+
zIndex: 2,
|
|
142
|
+
width: 34,
|
|
143
|
+
height: 34,
|
|
144
|
+
borderRadius: 999,
|
|
145
|
+
border: "1px solid rgba(148,163,184,0.45)",
|
|
146
|
+
background: "rgba(255,255,255,0.92)",
|
|
147
|
+
color: "#0f172a",
|
|
148
|
+
cursor: "pointer",
|
|
149
|
+
fontSize: 18,
|
|
150
|
+
lineHeight: "32px",
|
|
151
|
+
textAlign: "center",
|
|
152
|
+
padding: 0
|
|
153
|
+
};
|
|
154
|
+
const IFRAME_STYLE = {
|
|
155
|
+
width: "100%",
|
|
156
|
+
height: "100%",
|
|
157
|
+
border: 0,
|
|
158
|
+
background: "#fff"
|
|
159
|
+
};
|
|
160
|
+
function useIsMobile(maxWidth = 640) {
|
|
161
|
+
const [isMobile, setIsMobile] = (0, react.useState)(false);
|
|
162
|
+
(0, react.useEffect)(() => {
|
|
163
|
+
if (typeof window === "undefined") return;
|
|
164
|
+
const mediaQuery = window.matchMedia(`(max-width: ${maxWidth}px)`);
|
|
165
|
+
const onChange = () => setIsMobile(mediaQuery.matches);
|
|
166
|
+
onChange();
|
|
167
|
+
if (typeof mediaQuery.addEventListener === "function") {
|
|
168
|
+
mediaQuery.addEventListener("change", onChange);
|
|
169
|
+
return () => mediaQuery.removeEventListener("change", onChange);
|
|
170
|
+
}
|
|
171
|
+
mediaQuery.addListener(onChange);
|
|
172
|
+
return () => mediaQuery.removeListener(onChange);
|
|
173
|
+
}, [maxWidth]);
|
|
174
|
+
return isMobile;
|
|
175
|
+
}
|
|
176
|
+
function TradeItModal(props) {
|
|
177
|
+
const { open, onOpenChange, onEvent, onError, iframeTitle, keepMounted = false, closeOnEscape = true, closeOnOverlayClick = true, closeOnCloseRequestedEvent = true, showCloseButton = true, zIndex = 9999, title, className } = props;
|
|
178
|
+
const isMobile = useIsMobile();
|
|
179
|
+
const [isMounted, setIsMounted] = (0, react.useState)(false);
|
|
180
|
+
const [iframeLoaded, setIframeLoaded] = (0, react.useState)(false);
|
|
181
|
+
const resolved = (0, react.useMemo)(() => {
|
|
182
|
+
try {
|
|
183
|
+
return {
|
|
184
|
+
url: (0, __trade_it_core.resolveLaunchUrl)(props.launch),
|
|
185
|
+
error: null
|
|
186
|
+
};
|
|
187
|
+
} catch (error) {
|
|
188
|
+
return {
|
|
189
|
+
url: null,
|
|
190
|
+
error: error instanceof Error ? error : new Error("Failed to build Trade It iframe URL")
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
}, [props.launch]);
|
|
194
|
+
(0, react.useEffect)(() => {
|
|
195
|
+
setIsMounted(true);
|
|
196
|
+
}, []);
|
|
197
|
+
(0, react.useEffect)(() => {
|
|
198
|
+
if (!resolved.error) return;
|
|
199
|
+
onError?.(resolved.error);
|
|
200
|
+
}, [resolved.error, onError]);
|
|
201
|
+
(0, react.useEffect)(() => {
|
|
202
|
+
if (!open) return;
|
|
203
|
+
setIframeLoaded(false);
|
|
204
|
+
}, [open, resolved.url]);
|
|
205
|
+
(0, react.useEffect)(() => {
|
|
206
|
+
if (!open || !closeOnEscape) return;
|
|
207
|
+
const onKeyDown = (event) => {
|
|
208
|
+
if (event.key === "Escape") onOpenChange?.(false);
|
|
209
|
+
};
|
|
210
|
+
window.addEventListener("keydown", onKeyDown);
|
|
211
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
212
|
+
}, [
|
|
213
|
+
open,
|
|
214
|
+
closeOnEscape,
|
|
215
|
+
onOpenChange
|
|
216
|
+
]);
|
|
217
|
+
(0, react.useEffect)(() => {
|
|
218
|
+
if (!open) return;
|
|
219
|
+
const originalOverflow = document.body.style.overflow;
|
|
220
|
+
document.body.style.overflow = "hidden";
|
|
221
|
+
return () => {
|
|
222
|
+
document.body.style.overflow = originalOverflow;
|
|
223
|
+
};
|
|
224
|
+
}, [open]);
|
|
225
|
+
(0, react.useEffect)(() => {
|
|
226
|
+
if (!open || !resolved.url) return;
|
|
227
|
+
const expectedOrigin = (0, __trade_it_core.getUrlOrigin)(resolved.url);
|
|
228
|
+
if (!expectedOrigin) return;
|
|
229
|
+
const handleMessage = (event) => {
|
|
230
|
+
if (event.origin !== expectedOrigin) return;
|
|
231
|
+
if (!(0, __trade_it_core.isTradeItEvent)(event.data)) return;
|
|
232
|
+
onEvent?.(event.data);
|
|
233
|
+
if (event.data.type === "tradeit.error") onError?.(new Error((0, __trade_it_core.getTradeItErrorMessage)(event.data)));
|
|
234
|
+
if (event.data.type === "tradeit.close_requested" && closeOnCloseRequestedEvent) onOpenChange?.(false);
|
|
235
|
+
};
|
|
236
|
+
window.addEventListener("message", handleMessage);
|
|
237
|
+
return () => window.removeEventListener("message", handleMessage);
|
|
238
|
+
}, [
|
|
239
|
+
open,
|
|
240
|
+
resolved.url,
|
|
241
|
+
onEvent,
|
|
242
|
+
onError,
|
|
243
|
+
closeOnCloseRequestedEvent,
|
|
244
|
+
onOpenChange
|
|
245
|
+
]);
|
|
246
|
+
if (!isMounted) return null;
|
|
247
|
+
if (!open && !keepMounted) return null;
|
|
248
|
+
if (!resolved.url) return null;
|
|
249
|
+
const dialogStyle = isMobile ? DIALOG_MOBILE_STYLE : DIALOG_DESKTOP_STYLE;
|
|
250
|
+
const overlayStyle = {
|
|
251
|
+
...OVERLAY_STYLE,
|
|
252
|
+
zIndex
|
|
253
|
+
};
|
|
254
|
+
const dialogLabel = title ?? iframeTitle ?? "Trade It";
|
|
255
|
+
const modal = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
256
|
+
"aria-hidden": !open,
|
|
257
|
+
style: {
|
|
258
|
+
...overlayStyle,
|
|
259
|
+
visibility: open ? "visible" : "hidden",
|
|
260
|
+
pointerEvents: open ? "auto" : "none"
|
|
261
|
+
},
|
|
262
|
+
onMouseDown: (event) => {
|
|
263
|
+
if (!closeOnOverlayClick) return;
|
|
264
|
+
if (event.target === event.currentTarget) onOpenChange?.(false);
|
|
265
|
+
},
|
|
266
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
267
|
+
role: "dialog",
|
|
268
|
+
"aria-modal": "true",
|
|
269
|
+
"aria-label": dialogLabel,
|
|
270
|
+
className,
|
|
271
|
+
style: dialogStyle,
|
|
272
|
+
children: [
|
|
273
|
+
showCloseButton && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
274
|
+
type: "button",
|
|
275
|
+
"aria-label": "Close",
|
|
276
|
+
onClick: () => onOpenChange?.(false),
|
|
277
|
+
style: CLOSE_BUTTON_STYLE,
|
|
278
|
+
children: "×"
|
|
279
|
+
}),
|
|
280
|
+
!iframeLoaded && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TradeItModalLoader, {}),
|
|
281
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
|
|
282
|
+
title: dialogLabel,
|
|
283
|
+
src: resolved.url,
|
|
284
|
+
style: IFRAME_STYLE,
|
|
285
|
+
allow: "fullscreen",
|
|
286
|
+
onLoad: () => setIframeLoaded(true)
|
|
287
|
+
})
|
|
288
|
+
]
|
|
289
|
+
})
|
|
290
|
+
});
|
|
291
|
+
return (0, react_dom.createPortal)(modal, document.body);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
//#endregion
|
|
295
|
+
//#region src/useTradeIt.ts
|
|
296
|
+
function useTradeIt(defaults = {}) {
|
|
297
|
+
const [modalState, setModalState] = (0, react.useState)(null);
|
|
298
|
+
const close = (0, react.useCallback)(() => {
|
|
299
|
+
setModalState((prev) => prev ? {
|
|
300
|
+
...prev,
|
|
301
|
+
open: false
|
|
302
|
+
} : prev);
|
|
303
|
+
}, []);
|
|
304
|
+
const destroy = (0, react.useCallback)(() => {
|
|
305
|
+
setModalState(null);
|
|
306
|
+
}, []);
|
|
307
|
+
const openConnect = (0, react.useCallback)((options) => {
|
|
308
|
+
setModalState({
|
|
309
|
+
...defaults,
|
|
310
|
+
...options,
|
|
311
|
+
open: true,
|
|
312
|
+
launch: {
|
|
313
|
+
...options.launch,
|
|
314
|
+
mode: "connect"
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
}, [defaults]);
|
|
318
|
+
const openTrade = (0, react.useCallback)((options) => {
|
|
319
|
+
setModalState({
|
|
320
|
+
...defaults,
|
|
321
|
+
...options,
|
|
322
|
+
open: true,
|
|
323
|
+
launch: {
|
|
324
|
+
...options.launch,
|
|
325
|
+
mode: "trade"
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
}, [defaults]);
|
|
329
|
+
const modalProps = (0, react.useMemo)(() => {
|
|
330
|
+
if (!modalState) return null;
|
|
331
|
+
const handleOpenChange = (open) => {
|
|
332
|
+
setModalState((prev) => prev ? {
|
|
333
|
+
...prev,
|
|
334
|
+
open
|
|
335
|
+
} : prev);
|
|
336
|
+
modalState.onOpenChange?.(open);
|
|
337
|
+
};
|
|
338
|
+
return {
|
|
339
|
+
...modalState,
|
|
340
|
+
onOpenChange: handleOpenChange
|
|
341
|
+
};
|
|
342
|
+
}, [modalState]);
|
|
343
|
+
return {
|
|
344
|
+
isOpen: modalState?.open ?? false,
|
|
345
|
+
modalProps,
|
|
346
|
+
openConnect,
|
|
347
|
+
openTrade,
|
|
348
|
+
close,
|
|
349
|
+
destroy
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
//#endregion
|
|
354
|
+
//#region ../../lib/types/src/enums/trading.enums.ts
|
|
355
|
+
let TradeAction = /* @__PURE__ */ function(TradeAction$1) {
|
|
356
|
+
TradeAction$1["Buy"] = "buy";
|
|
357
|
+
TradeAction$1["Sell"] = "sell";
|
|
358
|
+
return TradeAction$1;
|
|
359
|
+
}({});
|
|
360
|
+
let PositionEffect = /* @__PURE__ */ function(PositionEffect$1) {
|
|
361
|
+
PositionEffect$1["Open"] = "open";
|
|
362
|
+
PositionEffect$1["Close"] = "close";
|
|
363
|
+
return PositionEffect$1;
|
|
364
|
+
}({});
|
|
365
|
+
let OrderType = /* @__PURE__ */ function(OrderType$1) {
|
|
366
|
+
OrderType$1["Market"] = "market";
|
|
367
|
+
OrderType$1["Limit"] = "limit";
|
|
368
|
+
OrderType$1["Stop"] = "stop";
|
|
369
|
+
OrderType$1["StopLimit"] = "stop_limit";
|
|
370
|
+
return OrderType$1;
|
|
371
|
+
}({});
|
|
372
|
+
let OrderDirection = /* @__PURE__ */ function(OrderDirection$1) {
|
|
373
|
+
OrderDirection$1["Debit"] = "debit";
|
|
374
|
+
OrderDirection$1["Credit"] = "credit";
|
|
375
|
+
return OrderDirection$1;
|
|
376
|
+
}({});
|
|
377
|
+
let TimeInForce = /* @__PURE__ */ function(TimeInForce$1) {
|
|
378
|
+
TimeInForce$1["Day"] = "day";
|
|
379
|
+
TimeInForce$1["GoodTillCanceled"] = "gtc";
|
|
380
|
+
TimeInForce$1["ImmediateOrCancel"] = "ioc";
|
|
381
|
+
TimeInForce$1["FillOrKill"] = "fok";
|
|
382
|
+
return TimeInForce$1;
|
|
383
|
+
}({});
|
|
384
|
+
let TradeUnit = /* @__PURE__ */ function(TradeUnit$1) {
|
|
385
|
+
TradeUnit$1["Dollars"] = "dollars";
|
|
386
|
+
TradeUnit$1["Shares"] = "shares";
|
|
387
|
+
return TradeUnit$1;
|
|
388
|
+
}({});
|
|
389
|
+
let LegType = /* @__PURE__ */ function(LegType$1) {
|
|
390
|
+
LegType$1["Option"] = "option";
|
|
391
|
+
LegType$1["Equity"] = "equity";
|
|
392
|
+
return LegType$1;
|
|
393
|
+
}({});
|
|
394
|
+
let TradeType = /* @__PURE__ */ function(TradeType$1) {
|
|
395
|
+
TradeType$1[TradeType$1["Simple"] = 0] = "Simple";
|
|
396
|
+
TradeType$1[TradeType$1["MultiLeg"] = 1] = "MultiLeg";
|
|
397
|
+
return TradeType$1;
|
|
398
|
+
}({});
|
|
399
|
+
|
|
400
|
+
//#endregion
|
|
401
|
+
//#region ../../lib/types/src/types/trade-link.types.ts
|
|
402
|
+
/**
|
|
403
|
+
* Short query parameter keys for trade link URLs
|
|
404
|
+
*/
|
|
405
|
+
let TradeLinkParam = /* @__PURE__ */ function(TradeLinkParam$1) {
|
|
406
|
+
TradeLinkParam$1["TradeType"] = "tt";
|
|
407
|
+
TradeLinkParam$1["Action"] = "t";
|
|
408
|
+
TradeLinkParam$1["OrderType"] = "ot";
|
|
409
|
+
TradeLinkParam$1["Amount"] = "a";
|
|
410
|
+
TradeLinkParam$1["Unit"] = "u";
|
|
411
|
+
TradeLinkParam$1["LimitPrice"] = "lp";
|
|
412
|
+
TradeLinkParam$1["StopPrice"] = "sp";
|
|
413
|
+
TradeLinkParam$1["TimeInForce"] = "tif";
|
|
414
|
+
TradeLinkParam$1["UtmReferred"] = "ref";
|
|
415
|
+
TradeLinkParam$1["Legs"] = "legs";
|
|
416
|
+
return TradeLinkParam$1;
|
|
417
|
+
}({});
|
|
418
|
+
|
|
419
|
+
//#endregion
|
|
420
|
+
exports.LegType = LegType;
|
|
421
|
+
exports.OrderDirection = OrderDirection;
|
|
422
|
+
exports.OrderType = OrderType;
|
|
423
|
+
exports.PositionEffect = PositionEffect;
|
|
424
|
+
exports.TimeInForce = TimeInForce;
|
|
425
|
+
exports.TradeAction = TradeAction;
|
|
426
|
+
exports.TradeItModal = TradeItModal;
|
|
427
|
+
exports.TradeLinkParam = TradeLinkParam;
|
|
428
|
+
exports.TradeType = TradeType;
|
|
429
|
+
exports.TradeUnit = TradeUnit;
|
|
430
|
+
Object.defineProperty(exports, 'getTradeItErrorMessage', {
|
|
431
|
+
enumerable: true,
|
|
432
|
+
get: function () {
|
|
433
|
+
return __trade_it_core.getTradeItErrorMessage;
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
Object.defineProperty(exports, 'getUrlOrigin', {
|
|
437
|
+
enumerable: true,
|
|
438
|
+
get: function () {
|
|
439
|
+
return __trade_it_core.getUrlOrigin;
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
Object.defineProperty(exports, 'isTradeItEvent', {
|
|
443
|
+
enumerable: true,
|
|
444
|
+
get: function () {
|
|
445
|
+
return __trade_it_core.isTradeItEvent;
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
Object.defineProperty(exports, 'resolveLaunchUrl', {
|
|
449
|
+
enumerable: true,
|
|
450
|
+
get: function () {
|
|
451
|
+
return __trade_it_core.resolveLaunchUrl;
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
exports.useTradeIt = useTradeIt;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import * as react0 from "react";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
//#region ../../lib/types/src/enums/trading.enums.d.ts
|
|
5
|
+
declare enum TradeAction {
|
|
6
|
+
Buy = "buy",
|
|
7
|
+
Sell = "sell",
|
|
8
|
+
}
|
|
9
|
+
declare enum PositionEffect {
|
|
10
|
+
Open = "open",
|
|
11
|
+
Close = "close",
|
|
12
|
+
}
|
|
13
|
+
declare enum OrderType {
|
|
14
|
+
Market = "market",
|
|
15
|
+
Limit = "limit",
|
|
16
|
+
Stop = "stop",
|
|
17
|
+
StopLimit = "stop_limit",
|
|
18
|
+
}
|
|
19
|
+
declare enum OrderDirection {
|
|
20
|
+
Debit = "debit",
|
|
21
|
+
Credit = "credit",
|
|
22
|
+
}
|
|
23
|
+
declare enum TimeInForce {
|
|
24
|
+
Day = "day",
|
|
25
|
+
GoodTillCanceled = "gtc",
|
|
26
|
+
ImmediateOrCancel = "ioc",
|
|
27
|
+
FillOrKill = "fok",
|
|
28
|
+
}
|
|
29
|
+
declare enum TradeUnit {
|
|
30
|
+
Dollars = "dollars",
|
|
31
|
+
Shares = "shares",
|
|
32
|
+
}
|
|
33
|
+
declare enum LegType {
|
|
34
|
+
Option = "option",
|
|
35
|
+
Equity = "equity",
|
|
36
|
+
}
|
|
37
|
+
declare enum TradeType {
|
|
38
|
+
Simple = 0,
|
|
39
|
+
MultiLeg = 1,
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region ../../lib/types/src/schemas/trade-link.schemas.d.ts
|
|
43
|
+
/**
|
|
44
|
+
* Trade Link Leg Config - derived from TradeLeg without execution_price
|
|
45
|
+
*/
|
|
46
|
+
declare const zTradeLinkLegConfig: z.ZodObject<Omit<{
|
|
47
|
+
type: z.ZodNativeEnum<typeof LegType>;
|
|
48
|
+
action: z.ZodNativeEnum<typeof TradeAction>;
|
|
49
|
+
position_effect: z.ZodNullable<z.ZodNativeEnum<typeof PositionEffect>>;
|
|
50
|
+
occ: z.ZodNullable<z.ZodString>;
|
|
51
|
+
quantity: z.ZodNumber;
|
|
52
|
+
execution_price: z.ZodNullable<z.ZodObject<{
|
|
53
|
+
amount: z.ZodNumber;
|
|
54
|
+
currency: z.ZodString;
|
|
55
|
+
}, "strip", z.ZodTypeAny, {
|
|
56
|
+
amount: number;
|
|
57
|
+
currency: string;
|
|
58
|
+
}, {
|
|
59
|
+
amount: number;
|
|
60
|
+
currency: string;
|
|
61
|
+
}>>;
|
|
62
|
+
}, "execution_price">, "strip", z.ZodTypeAny, {
|
|
63
|
+
type: LegType;
|
|
64
|
+
action: TradeAction;
|
|
65
|
+
position_effect: PositionEffect | null;
|
|
66
|
+
occ: string | null;
|
|
67
|
+
quantity: number;
|
|
68
|
+
}, {
|
|
69
|
+
type: LegType;
|
|
70
|
+
action: TradeAction;
|
|
71
|
+
position_effect: PositionEffect | null;
|
|
72
|
+
occ: string | null;
|
|
73
|
+
quantity: number;
|
|
74
|
+
}>;
|
|
75
|
+
/**
|
|
76
|
+
* Full Trade Link Config - stored in database as JSONB
|
|
77
|
+
* Supports both simple trades and multi-leg options trades
|
|
78
|
+
*/
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region ../../lib/types/src/types/misc.types.d.ts
|
|
81
|
+
type SnakeToCamelCase<S extends string> = S extends `${infer P1}_${infer P2}` ? `${P1}${Capitalize<SnakeToCamelCase<P2>>}` : S;
|
|
82
|
+
/** Converts a type's snake_case keys to camelCase keys */
|
|
83
|
+
type Camelize<T> = T extends object ? { [K in keyof T as K extends string ? SnakeToCamelCase<K> : K]: Camelize<T[K]> } : T;
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region ../../lib/types/src/types/trade-link.types.d.ts
|
|
86
|
+
/** Configuration for a leg in a multi-leg trade link */
|
|
87
|
+
type TradeLinkLegConfig = z.infer<typeof zTradeLinkLegConfig>;
|
|
88
|
+
/** Full configuration stored in the trade link */
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Short query parameter keys for trade link URLs
|
|
92
|
+
*/
|
|
93
|
+
declare enum TradeLinkParam {
|
|
94
|
+
TradeType = "tt",
|
|
95
|
+
// s (simple), m (multi_leg)
|
|
96
|
+
Action = "t",
|
|
97
|
+
// b, s, bto, btc, sto, stc
|
|
98
|
+
OrderType = "ot",
|
|
99
|
+
// m, l, st, sl
|
|
100
|
+
Amount = "a",
|
|
101
|
+
// number
|
|
102
|
+
Unit = "u",
|
|
103
|
+
// d, s
|
|
104
|
+
LimitPrice = "lp",
|
|
105
|
+
// number
|
|
106
|
+
StopPrice = "sp",
|
|
107
|
+
// number
|
|
108
|
+
TimeInForce = "tif",
|
|
109
|
+
// d, gtc, ioc, fok
|
|
110
|
+
UtmReferred = "ref",
|
|
111
|
+
// string
|
|
112
|
+
Legs = "legs",
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region ../trade-it-core/src/types.d.ts
|
|
116
|
+
type TradeItEventType = 'tradeit.ready' | 'tradeit.close_requested' | 'tradeit.brokerage_connected' | 'tradeit.trade_submitted' | 'tradeit.trade_executed' | 'tradeit.error' | 'tradeit.login_required';
|
|
117
|
+
interface TradeItEvent<TPayload = Record<string, unknown>> {
|
|
118
|
+
source: 'tradeit';
|
|
119
|
+
version: 1;
|
|
120
|
+
type: TradeItEventType;
|
|
121
|
+
payload?: TPayload;
|
|
122
|
+
}
|
|
123
|
+
type TradeItMode = 'connect' | 'trade';
|
|
124
|
+
type TradeItMultiLegTradeLegConfig = Partial<Camelize<TradeLinkLegConfig>>;
|
|
125
|
+
/**
|
|
126
|
+
* Query params accepted by Trade It's /t/[ticker] page.
|
|
127
|
+
* User-facing config uses descriptive keys; core converts them to the short-key
|
|
128
|
+
* query format used by the page parser (tt, t, ot, a, u, lp, sp, tif, ref, legs).
|
|
129
|
+
*/
|
|
130
|
+
interface TradeItTradeConfigBase {
|
|
131
|
+
ticker: string;
|
|
132
|
+
orderType?: OrderType;
|
|
133
|
+
limitPrice?: number;
|
|
134
|
+
stopPrice?: number;
|
|
135
|
+
timeInForce?: TimeInForce;
|
|
136
|
+
referral?: string;
|
|
137
|
+
}
|
|
138
|
+
interface TradeItSimpleTradeConfig extends TradeItTradeConfigBase {
|
|
139
|
+
tradeType?: TradeType.Simple;
|
|
140
|
+
action?: TradeAction;
|
|
141
|
+
amount?: number;
|
|
142
|
+
unit?: TradeUnit;
|
|
143
|
+
}
|
|
144
|
+
interface TradeItMultiLegTradeConfig extends TradeItTradeConfigBase {
|
|
145
|
+
tradeType: TradeType.MultiLeg;
|
|
146
|
+
direction?: OrderDirection;
|
|
147
|
+
legs: TradeItMultiLegTradeLegConfig[];
|
|
148
|
+
}
|
|
149
|
+
type TradeItTradeConfig = TradeItSimpleTradeConfig | TradeItMultiLegTradeConfig;
|
|
150
|
+
interface TradeItLaunchConfigMap {
|
|
151
|
+
connect: undefined;
|
|
152
|
+
trade: TradeItTradeConfig;
|
|
153
|
+
}
|
|
154
|
+
type TradeItLaunchShape<TMode extends TradeItMode> = {
|
|
155
|
+
mode: TMode;
|
|
156
|
+
url: string;
|
|
157
|
+
} & (TMode extends 'connect' ? {
|
|
158
|
+
config?: undefined;
|
|
159
|
+
} : {
|
|
160
|
+
config: TradeItLaunchConfigMap[TMode];
|
|
161
|
+
});
|
|
162
|
+
type TradeItLaunch<TMode extends TradeItMode = TradeItMode> = TMode extends TradeItMode ? TradeItLaunchShape<TMode> : never;
|
|
163
|
+
type TradeItConnectLaunch = TradeItLaunch<'connect'>;
|
|
164
|
+
type TradeItTradeLaunch = TradeItLaunch<'trade'>;
|
|
165
|
+
//#endregion
|
|
166
|
+
//#region ../trade-it-core/src/events.d.ts
|
|
167
|
+
declare function isTradeItEvent(data: unknown): data is TradeItEvent;
|
|
168
|
+
declare function getTradeItErrorMessage(event: TradeItEvent): string;
|
|
169
|
+
//#endregion
|
|
170
|
+
//#region ../trade-it-core/src/url.d.ts
|
|
171
|
+
declare function resolveLaunchUrl(launch: TradeItLaunch): string;
|
|
172
|
+
declare function getUrlOrigin(url: string): string | null;
|
|
173
|
+
//#endregion
|
|
174
|
+
//#region src/types.d.ts
|
|
175
|
+
interface TradeItModalAppearance {
|
|
176
|
+
closeOnEscape?: boolean;
|
|
177
|
+
closeOnOverlayClick?: boolean;
|
|
178
|
+
closeOnCloseRequestedEvent?: boolean;
|
|
179
|
+
showCloseButton?: boolean;
|
|
180
|
+
zIndex?: number;
|
|
181
|
+
title?: string;
|
|
182
|
+
}
|
|
183
|
+
interface TradeItModalCallbacks {
|
|
184
|
+
onOpenChange?: (open: boolean) => void;
|
|
185
|
+
onEvent?: (event: TradeItEvent) => void;
|
|
186
|
+
onError?: (error: Error) => void;
|
|
187
|
+
}
|
|
188
|
+
interface TradeItModalProps extends TradeItModalAppearance, TradeItModalCallbacks {
|
|
189
|
+
launch: TradeItLaunch;
|
|
190
|
+
open: boolean;
|
|
191
|
+
iframeTitle?: string;
|
|
192
|
+
keepMounted?: boolean;
|
|
193
|
+
className?: string;
|
|
194
|
+
}
|
|
195
|
+
interface UseTradeItOptions extends TradeItModalAppearance, TradeItModalCallbacks {
|
|
196
|
+
iframeTitle?: string;
|
|
197
|
+
keepMounted?: boolean;
|
|
198
|
+
}
|
|
199
|
+
interface OpenConnectOptions extends Partial<TradeItModalAppearance>, Partial<TradeItModalCallbacks> {
|
|
200
|
+
launch: TradeItConnectLaunch;
|
|
201
|
+
iframeTitle?: string;
|
|
202
|
+
}
|
|
203
|
+
interface OpenTradeOptions extends Partial<TradeItModalAppearance>, Partial<TradeItModalCallbacks> {
|
|
204
|
+
launch: TradeItTradeLaunch;
|
|
205
|
+
iframeTitle?: string;
|
|
206
|
+
}
|
|
207
|
+
//#endregion
|
|
208
|
+
//#region src/TradeItModal.d.ts
|
|
209
|
+
declare function TradeItModal(props: TradeItModalProps): react0.ReactPortal | null;
|
|
210
|
+
//#endregion
|
|
211
|
+
//#region src/useTradeIt.d.ts
|
|
212
|
+
interface UseTradeItReturn {
|
|
213
|
+
isOpen: boolean;
|
|
214
|
+
modalProps: TradeItModalProps | null;
|
|
215
|
+
openConnect: (options: OpenConnectOptions) => void;
|
|
216
|
+
openTrade: (options: OpenTradeOptions) => void;
|
|
217
|
+
close: () => void;
|
|
218
|
+
destroy: () => void;
|
|
219
|
+
}
|
|
220
|
+
declare function useTradeIt(defaults?: UseTradeItOptions): UseTradeItReturn;
|
|
221
|
+
//#endregion
|
|
222
|
+
export { LegType, type OpenConnectOptions, type OpenTradeOptions, OrderDirection, OrderType, PositionEffect, TimeInForce, TradeAction, type TradeItConnectLaunch, type TradeItEvent, type TradeItEventType, type TradeItLaunch, TradeItModal, type TradeItModalAppearance, type TradeItModalProps, type TradeItMultiLegTradeConfig, type TradeItMultiLegTradeLegConfig, type TradeItSimpleTradeConfig, type TradeItTradeConfig, type TradeItTradeLaunch, type TradeLinkLegConfig, TradeLinkParam, TradeType, TradeUnit, type UseTradeItOptions, getTradeItErrorMessage, getUrlOrigin, isTradeItEvent, resolveLaunchUrl, useTradeIt };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import * as react0 from "react";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
//#region ../../lib/types/src/enums/trading.enums.d.ts
|
|
5
|
+
declare enum TradeAction {
|
|
6
|
+
Buy = "buy",
|
|
7
|
+
Sell = "sell",
|
|
8
|
+
}
|
|
9
|
+
declare enum PositionEffect {
|
|
10
|
+
Open = "open",
|
|
11
|
+
Close = "close",
|
|
12
|
+
}
|
|
13
|
+
declare enum OrderType {
|
|
14
|
+
Market = "market",
|
|
15
|
+
Limit = "limit",
|
|
16
|
+
Stop = "stop",
|
|
17
|
+
StopLimit = "stop_limit",
|
|
18
|
+
}
|
|
19
|
+
declare enum OrderDirection {
|
|
20
|
+
Debit = "debit",
|
|
21
|
+
Credit = "credit",
|
|
22
|
+
}
|
|
23
|
+
declare enum TimeInForce {
|
|
24
|
+
Day = "day",
|
|
25
|
+
GoodTillCanceled = "gtc",
|
|
26
|
+
ImmediateOrCancel = "ioc",
|
|
27
|
+
FillOrKill = "fok",
|
|
28
|
+
}
|
|
29
|
+
declare enum TradeUnit {
|
|
30
|
+
Dollars = "dollars",
|
|
31
|
+
Shares = "shares",
|
|
32
|
+
}
|
|
33
|
+
declare enum LegType {
|
|
34
|
+
Option = "option",
|
|
35
|
+
Equity = "equity",
|
|
36
|
+
}
|
|
37
|
+
declare enum TradeType {
|
|
38
|
+
Simple = 0,
|
|
39
|
+
MultiLeg = 1,
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region ../../lib/types/src/schemas/trade-link.schemas.d.ts
|
|
43
|
+
/**
|
|
44
|
+
* Trade Link Leg Config - derived from TradeLeg without execution_price
|
|
45
|
+
*/
|
|
46
|
+
declare const zTradeLinkLegConfig: z.ZodObject<Omit<{
|
|
47
|
+
type: z.ZodNativeEnum<typeof LegType>;
|
|
48
|
+
action: z.ZodNativeEnum<typeof TradeAction>;
|
|
49
|
+
position_effect: z.ZodNullable<z.ZodNativeEnum<typeof PositionEffect>>;
|
|
50
|
+
occ: z.ZodNullable<z.ZodString>;
|
|
51
|
+
quantity: z.ZodNumber;
|
|
52
|
+
execution_price: z.ZodNullable<z.ZodObject<{
|
|
53
|
+
amount: z.ZodNumber;
|
|
54
|
+
currency: z.ZodString;
|
|
55
|
+
}, "strip", z.ZodTypeAny, {
|
|
56
|
+
amount: number;
|
|
57
|
+
currency: string;
|
|
58
|
+
}, {
|
|
59
|
+
amount: number;
|
|
60
|
+
currency: string;
|
|
61
|
+
}>>;
|
|
62
|
+
}, "execution_price">, "strip", z.ZodTypeAny, {
|
|
63
|
+
type: LegType;
|
|
64
|
+
action: TradeAction;
|
|
65
|
+
position_effect: PositionEffect | null;
|
|
66
|
+
occ: string | null;
|
|
67
|
+
quantity: number;
|
|
68
|
+
}, {
|
|
69
|
+
type: LegType;
|
|
70
|
+
action: TradeAction;
|
|
71
|
+
position_effect: PositionEffect | null;
|
|
72
|
+
occ: string | null;
|
|
73
|
+
quantity: number;
|
|
74
|
+
}>;
|
|
75
|
+
/**
|
|
76
|
+
* Full Trade Link Config - stored in database as JSONB
|
|
77
|
+
* Supports both simple trades and multi-leg options trades
|
|
78
|
+
*/
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region ../../lib/types/src/types/misc.types.d.ts
|
|
81
|
+
type SnakeToCamelCase<S extends string> = S extends `${infer P1}_${infer P2}` ? `${P1}${Capitalize<SnakeToCamelCase<P2>>}` : S;
|
|
82
|
+
/** Converts a type's snake_case keys to camelCase keys */
|
|
83
|
+
type Camelize<T> = T extends object ? { [K in keyof T as K extends string ? SnakeToCamelCase<K> : K]: Camelize<T[K]> } : T;
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region ../../lib/types/src/types/trade-link.types.d.ts
|
|
86
|
+
/** Configuration for a leg in a multi-leg trade link */
|
|
87
|
+
type TradeLinkLegConfig = z.infer<typeof zTradeLinkLegConfig>;
|
|
88
|
+
/** Full configuration stored in the trade link */
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Short query parameter keys for trade link URLs
|
|
92
|
+
*/
|
|
93
|
+
declare enum TradeLinkParam {
|
|
94
|
+
TradeType = "tt",
|
|
95
|
+
// s (simple), m (multi_leg)
|
|
96
|
+
Action = "t",
|
|
97
|
+
// b, s, bto, btc, sto, stc
|
|
98
|
+
OrderType = "ot",
|
|
99
|
+
// m, l, st, sl
|
|
100
|
+
Amount = "a",
|
|
101
|
+
// number
|
|
102
|
+
Unit = "u",
|
|
103
|
+
// d, s
|
|
104
|
+
LimitPrice = "lp",
|
|
105
|
+
// number
|
|
106
|
+
StopPrice = "sp",
|
|
107
|
+
// number
|
|
108
|
+
TimeInForce = "tif",
|
|
109
|
+
// d, gtc, ioc, fok
|
|
110
|
+
UtmReferred = "ref",
|
|
111
|
+
// string
|
|
112
|
+
Legs = "legs",
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region ../trade-it-core/src/types.d.ts
|
|
116
|
+
type TradeItEventType = 'tradeit.ready' | 'tradeit.close_requested' | 'tradeit.brokerage_connected' | 'tradeit.trade_submitted' | 'tradeit.trade_executed' | 'tradeit.error' | 'tradeit.login_required';
|
|
117
|
+
interface TradeItEvent<TPayload = Record<string, unknown>> {
|
|
118
|
+
source: 'tradeit';
|
|
119
|
+
version: 1;
|
|
120
|
+
type: TradeItEventType;
|
|
121
|
+
payload?: TPayload;
|
|
122
|
+
}
|
|
123
|
+
type TradeItMode = 'connect' | 'trade';
|
|
124
|
+
type TradeItMultiLegTradeLegConfig = Partial<Camelize<TradeLinkLegConfig>>;
|
|
125
|
+
/**
|
|
126
|
+
* Query params accepted by Trade It's /t/[ticker] page.
|
|
127
|
+
* User-facing config uses descriptive keys; core converts them to the short-key
|
|
128
|
+
* query format used by the page parser (tt, t, ot, a, u, lp, sp, tif, ref, legs).
|
|
129
|
+
*/
|
|
130
|
+
interface TradeItTradeConfigBase {
|
|
131
|
+
ticker: string;
|
|
132
|
+
orderType?: OrderType;
|
|
133
|
+
limitPrice?: number;
|
|
134
|
+
stopPrice?: number;
|
|
135
|
+
timeInForce?: TimeInForce;
|
|
136
|
+
referral?: string;
|
|
137
|
+
}
|
|
138
|
+
interface TradeItSimpleTradeConfig extends TradeItTradeConfigBase {
|
|
139
|
+
tradeType?: TradeType.Simple;
|
|
140
|
+
action?: TradeAction;
|
|
141
|
+
amount?: number;
|
|
142
|
+
unit?: TradeUnit;
|
|
143
|
+
}
|
|
144
|
+
interface TradeItMultiLegTradeConfig extends TradeItTradeConfigBase {
|
|
145
|
+
tradeType: TradeType.MultiLeg;
|
|
146
|
+
direction?: OrderDirection;
|
|
147
|
+
legs: TradeItMultiLegTradeLegConfig[];
|
|
148
|
+
}
|
|
149
|
+
type TradeItTradeConfig = TradeItSimpleTradeConfig | TradeItMultiLegTradeConfig;
|
|
150
|
+
interface TradeItLaunchConfigMap {
|
|
151
|
+
connect: undefined;
|
|
152
|
+
trade: TradeItTradeConfig;
|
|
153
|
+
}
|
|
154
|
+
type TradeItLaunchShape<TMode extends TradeItMode> = {
|
|
155
|
+
mode: TMode;
|
|
156
|
+
url: string;
|
|
157
|
+
} & (TMode extends 'connect' ? {
|
|
158
|
+
config?: undefined;
|
|
159
|
+
} : {
|
|
160
|
+
config: TradeItLaunchConfigMap[TMode];
|
|
161
|
+
});
|
|
162
|
+
type TradeItLaunch<TMode extends TradeItMode = TradeItMode> = TMode extends TradeItMode ? TradeItLaunchShape<TMode> : never;
|
|
163
|
+
type TradeItConnectLaunch = TradeItLaunch<'connect'>;
|
|
164
|
+
type TradeItTradeLaunch = TradeItLaunch<'trade'>;
|
|
165
|
+
//#endregion
|
|
166
|
+
//#region ../trade-it-core/src/events.d.ts
|
|
167
|
+
declare function isTradeItEvent(data: unknown): data is TradeItEvent;
|
|
168
|
+
declare function getTradeItErrorMessage(event: TradeItEvent): string;
|
|
169
|
+
//#endregion
|
|
170
|
+
//#region ../trade-it-core/src/url.d.ts
|
|
171
|
+
declare function resolveLaunchUrl(launch: TradeItLaunch): string;
|
|
172
|
+
declare function getUrlOrigin(url: string): string | null;
|
|
173
|
+
//#endregion
|
|
174
|
+
//#region src/types.d.ts
|
|
175
|
+
interface TradeItModalAppearance {
|
|
176
|
+
closeOnEscape?: boolean;
|
|
177
|
+
closeOnOverlayClick?: boolean;
|
|
178
|
+
closeOnCloseRequestedEvent?: boolean;
|
|
179
|
+
showCloseButton?: boolean;
|
|
180
|
+
zIndex?: number;
|
|
181
|
+
title?: string;
|
|
182
|
+
}
|
|
183
|
+
interface TradeItModalCallbacks {
|
|
184
|
+
onOpenChange?: (open: boolean) => void;
|
|
185
|
+
onEvent?: (event: TradeItEvent) => void;
|
|
186
|
+
onError?: (error: Error) => void;
|
|
187
|
+
}
|
|
188
|
+
interface TradeItModalProps extends TradeItModalAppearance, TradeItModalCallbacks {
|
|
189
|
+
launch: TradeItLaunch;
|
|
190
|
+
open: boolean;
|
|
191
|
+
iframeTitle?: string;
|
|
192
|
+
keepMounted?: boolean;
|
|
193
|
+
className?: string;
|
|
194
|
+
}
|
|
195
|
+
interface UseTradeItOptions extends TradeItModalAppearance, TradeItModalCallbacks {
|
|
196
|
+
iframeTitle?: string;
|
|
197
|
+
keepMounted?: boolean;
|
|
198
|
+
}
|
|
199
|
+
interface OpenConnectOptions extends Partial<TradeItModalAppearance>, Partial<TradeItModalCallbacks> {
|
|
200
|
+
launch: TradeItConnectLaunch;
|
|
201
|
+
iframeTitle?: string;
|
|
202
|
+
}
|
|
203
|
+
interface OpenTradeOptions extends Partial<TradeItModalAppearance>, Partial<TradeItModalCallbacks> {
|
|
204
|
+
launch: TradeItTradeLaunch;
|
|
205
|
+
iframeTitle?: string;
|
|
206
|
+
}
|
|
207
|
+
//#endregion
|
|
208
|
+
//#region src/TradeItModal.d.ts
|
|
209
|
+
declare function TradeItModal(props: TradeItModalProps): react0.ReactPortal | null;
|
|
210
|
+
//#endregion
|
|
211
|
+
//#region src/useTradeIt.d.ts
|
|
212
|
+
interface UseTradeItReturn {
|
|
213
|
+
isOpen: boolean;
|
|
214
|
+
modalProps: TradeItModalProps | null;
|
|
215
|
+
openConnect: (options: OpenConnectOptions) => void;
|
|
216
|
+
openTrade: (options: OpenTradeOptions) => void;
|
|
217
|
+
close: () => void;
|
|
218
|
+
destroy: () => void;
|
|
219
|
+
}
|
|
220
|
+
declare function useTradeIt(defaults?: UseTradeItOptions): UseTradeItReturn;
|
|
221
|
+
//#endregion
|
|
222
|
+
export { LegType, type OpenConnectOptions, type OpenTradeOptions, OrderDirection, OrderType, PositionEffect, TimeInForce, TradeAction, type TradeItConnectLaunch, type TradeItEvent, type TradeItEventType, type TradeItLaunch, TradeItModal, type TradeItModalAppearance, type TradeItModalProps, type TradeItMultiLegTradeConfig, type TradeItMultiLegTradeLegConfig, type TradeItSimpleTradeConfig, type TradeItTradeConfig, type TradeItTradeLaunch, type TradeLinkLegConfig, TradeLinkParam, TradeType, TradeUnit, type UseTradeItOptions, getTradeItErrorMessage, getUrlOrigin, isTradeItEvent, resolveLaunchUrl, useTradeIt };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
import { getTradeItErrorMessage, getTradeItErrorMessage as getTradeItErrorMessage$1, getUrlOrigin, getUrlOrigin as getUrlOrigin$1, isTradeItEvent, isTradeItEvent as isTradeItEvent$1, resolveLaunchUrl, resolveLaunchUrl as resolveLaunchUrl$1 } from "@trade-it/core";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
3
|
+
import { createPortal } from "react-dom";
|
|
4
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
|
|
6
|
+
//#region src/LoaderCircleSpinner.tsx
|
|
7
|
+
const SPINNER_WRAPPER_SIZE = 44;
|
|
8
|
+
const SPINNER_ICON_SIZE = 32;
|
|
9
|
+
const SPINNER_WRAPPER_STYLE = {
|
|
10
|
+
width: SPINNER_WRAPPER_SIZE,
|
|
11
|
+
height: SPINNER_WRAPPER_SIZE,
|
|
12
|
+
display: "flex",
|
|
13
|
+
alignItems: "center",
|
|
14
|
+
justifyContent: "center",
|
|
15
|
+
animation: "tradeItSdkSpin 0.9s linear infinite",
|
|
16
|
+
transformOrigin: "50% 50%"
|
|
17
|
+
};
|
|
18
|
+
const SPINNER_SVG_STYLE = {
|
|
19
|
+
display: "block",
|
|
20
|
+
width: SPINNER_ICON_SIZE,
|
|
21
|
+
height: SPINNER_ICON_SIZE,
|
|
22
|
+
color: "#111827"
|
|
23
|
+
};
|
|
24
|
+
const SPINNER_KEYFRAMES_CSS = `
|
|
25
|
+
@keyframes tradeItSdkSpin {
|
|
26
|
+
from { transform: rotate(0deg); }
|
|
27
|
+
to { transform: rotate(360deg); }
|
|
28
|
+
}
|
|
29
|
+
@media (prefers-reduced-motion: reduce) {
|
|
30
|
+
.tradeit-sdk-spinner {
|
|
31
|
+
animation: none !important;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
`;
|
|
35
|
+
function LoaderCircleSpinner() {
|
|
36
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("style", { children: SPINNER_KEYFRAMES_CSS }), /* @__PURE__ */ jsx("div", {
|
|
37
|
+
className: "tradeit-sdk-spinner",
|
|
38
|
+
style: SPINNER_WRAPPER_STYLE,
|
|
39
|
+
"aria-hidden": "true",
|
|
40
|
+
children: /* @__PURE__ */ jsx("svg", {
|
|
41
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
42
|
+
width: SPINNER_ICON_SIZE,
|
|
43
|
+
height: SPINNER_ICON_SIZE,
|
|
44
|
+
viewBox: "0 0 24 24",
|
|
45
|
+
fill: "none",
|
|
46
|
+
stroke: "currentColor",
|
|
47
|
+
strokeWidth: "2",
|
|
48
|
+
strokeLinecap: "round",
|
|
49
|
+
strokeLinejoin: "round",
|
|
50
|
+
style: SPINNER_SVG_STYLE,
|
|
51
|
+
children: /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
|
|
52
|
+
})
|
|
53
|
+
})] });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//#endregion
|
|
57
|
+
//#region src/TradeItModalLoader.tsx
|
|
58
|
+
const LOADING_STYLE = {
|
|
59
|
+
position: "absolute",
|
|
60
|
+
inset: 0,
|
|
61
|
+
background: "#ffffff"
|
|
62
|
+
};
|
|
63
|
+
const LOADING_CONTENT_STYLE = {
|
|
64
|
+
position: "relative",
|
|
65
|
+
zIndex: 1,
|
|
66
|
+
display: "flex",
|
|
67
|
+
flexDirection: "column",
|
|
68
|
+
alignItems: "center",
|
|
69
|
+
justifyContent: "center",
|
|
70
|
+
width: "100%",
|
|
71
|
+
height: "100%"
|
|
72
|
+
};
|
|
73
|
+
function TradeItModalLoader() {
|
|
74
|
+
return /* @__PURE__ */ jsx("div", {
|
|
75
|
+
style: LOADING_STYLE,
|
|
76
|
+
"aria-live": "polite",
|
|
77
|
+
"aria-busy": "true",
|
|
78
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
79
|
+
style: LOADING_CONTENT_STYLE,
|
|
80
|
+
children: /* @__PURE__ */ jsx(LoaderCircleSpinner, {})
|
|
81
|
+
})
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
//#endregion
|
|
86
|
+
//#region src/TradeItModal.tsx
|
|
87
|
+
const OVERLAY_STYLE = {
|
|
88
|
+
position: "fixed",
|
|
89
|
+
inset: 0,
|
|
90
|
+
background: "rgba(15, 23, 42, 0.55)",
|
|
91
|
+
backdropFilter: "blur(4px)",
|
|
92
|
+
display: "flex",
|
|
93
|
+
alignItems: "center",
|
|
94
|
+
justifyContent: "center",
|
|
95
|
+
padding: 12
|
|
96
|
+
};
|
|
97
|
+
const DIALOG_DESKTOP_STYLE = {
|
|
98
|
+
position: "relative",
|
|
99
|
+
width: "min(960px, calc(100vw - 24px))",
|
|
100
|
+
height: "min(760px, calc(100vh - 24px))",
|
|
101
|
+
background: "#fff",
|
|
102
|
+
borderRadius: 18,
|
|
103
|
+
boxShadow: "0 24px 80px rgba(2, 6, 23, 0.28)",
|
|
104
|
+
border: "1px solid rgba(148, 163, 184, 0.35)",
|
|
105
|
+
overflow: "hidden"
|
|
106
|
+
};
|
|
107
|
+
const DIALOG_MOBILE_STYLE = {
|
|
108
|
+
...DIALOG_DESKTOP_STYLE,
|
|
109
|
+
width: "100vw",
|
|
110
|
+
height: "100vh",
|
|
111
|
+
borderRadius: 0,
|
|
112
|
+
border: 0
|
|
113
|
+
};
|
|
114
|
+
const CLOSE_BUTTON_STYLE = {
|
|
115
|
+
position: "absolute",
|
|
116
|
+
top: 10,
|
|
117
|
+
right: 10,
|
|
118
|
+
zIndex: 2,
|
|
119
|
+
width: 34,
|
|
120
|
+
height: 34,
|
|
121
|
+
borderRadius: 999,
|
|
122
|
+
border: "1px solid rgba(148,163,184,0.45)",
|
|
123
|
+
background: "rgba(255,255,255,0.92)",
|
|
124
|
+
color: "#0f172a",
|
|
125
|
+
cursor: "pointer",
|
|
126
|
+
fontSize: 18,
|
|
127
|
+
lineHeight: "32px",
|
|
128
|
+
textAlign: "center",
|
|
129
|
+
padding: 0
|
|
130
|
+
};
|
|
131
|
+
const IFRAME_STYLE = {
|
|
132
|
+
width: "100%",
|
|
133
|
+
height: "100%",
|
|
134
|
+
border: 0,
|
|
135
|
+
background: "#fff"
|
|
136
|
+
};
|
|
137
|
+
function useIsMobile(maxWidth = 640) {
|
|
138
|
+
const [isMobile, setIsMobile] = useState(false);
|
|
139
|
+
useEffect(() => {
|
|
140
|
+
if (typeof window === "undefined") return;
|
|
141
|
+
const mediaQuery = window.matchMedia(`(max-width: ${maxWidth}px)`);
|
|
142
|
+
const onChange = () => setIsMobile(mediaQuery.matches);
|
|
143
|
+
onChange();
|
|
144
|
+
if (typeof mediaQuery.addEventListener === "function") {
|
|
145
|
+
mediaQuery.addEventListener("change", onChange);
|
|
146
|
+
return () => mediaQuery.removeEventListener("change", onChange);
|
|
147
|
+
}
|
|
148
|
+
mediaQuery.addListener(onChange);
|
|
149
|
+
return () => mediaQuery.removeListener(onChange);
|
|
150
|
+
}, [maxWidth]);
|
|
151
|
+
return isMobile;
|
|
152
|
+
}
|
|
153
|
+
function TradeItModal(props) {
|
|
154
|
+
const { open, onOpenChange, onEvent, onError, iframeTitle, keepMounted = false, closeOnEscape = true, closeOnOverlayClick = true, closeOnCloseRequestedEvent = true, showCloseButton = true, zIndex = 9999, title, className } = props;
|
|
155
|
+
const isMobile = useIsMobile();
|
|
156
|
+
const [isMounted, setIsMounted] = useState(false);
|
|
157
|
+
const [iframeLoaded, setIframeLoaded] = useState(false);
|
|
158
|
+
const resolved = useMemo(() => {
|
|
159
|
+
try {
|
|
160
|
+
return {
|
|
161
|
+
url: resolveLaunchUrl$1(props.launch),
|
|
162
|
+
error: null
|
|
163
|
+
};
|
|
164
|
+
} catch (error) {
|
|
165
|
+
return {
|
|
166
|
+
url: null,
|
|
167
|
+
error: error instanceof Error ? error : new Error("Failed to build Trade It iframe URL")
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
}, [props.launch]);
|
|
171
|
+
useEffect(() => {
|
|
172
|
+
setIsMounted(true);
|
|
173
|
+
}, []);
|
|
174
|
+
useEffect(() => {
|
|
175
|
+
if (!resolved.error) return;
|
|
176
|
+
onError?.(resolved.error);
|
|
177
|
+
}, [resolved.error, onError]);
|
|
178
|
+
useEffect(() => {
|
|
179
|
+
if (!open) return;
|
|
180
|
+
setIframeLoaded(false);
|
|
181
|
+
}, [open, resolved.url]);
|
|
182
|
+
useEffect(() => {
|
|
183
|
+
if (!open || !closeOnEscape) return;
|
|
184
|
+
const onKeyDown = (event) => {
|
|
185
|
+
if (event.key === "Escape") onOpenChange?.(false);
|
|
186
|
+
};
|
|
187
|
+
window.addEventListener("keydown", onKeyDown);
|
|
188
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
189
|
+
}, [
|
|
190
|
+
open,
|
|
191
|
+
closeOnEscape,
|
|
192
|
+
onOpenChange
|
|
193
|
+
]);
|
|
194
|
+
useEffect(() => {
|
|
195
|
+
if (!open) return;
|
|
196
|
+
const originalOverflow = document.body.style.overflow;
|
|
197
|
+
document.body.style.overflow = "hidden";
|
|
198
|
+
return () => {
|
|
199
|
+
document.body.style.overflow = originalOverflow;
|
|
200
|
+
};
|
|
201
|
+
}, [open]);
|
|
202
|
+
useEffect(() => {
|
|
203
|
+
if (!open || !resolved.url) return;
|
|
204
|
+
const expectedOrigin = getUrlOrigin$1(resolved.url);
|
|
205
|
+
if (!expectedOrigin) return;
|
|
206
|
+
const handleMessage = (event) => {
|
|
207
|
+
if (event.origin !== expectedOrigin) return;
|
|
208
|
+
if (!isTradeItEvent$1(event.data)) return;
|
|
209
|
+
onEvent?.(event.data);
|
|
210
|
+
if (event.data.type === "tradeit.error") onError?.(new Error(getTradeItErrorMessage$1(event.data)));
|
|
211
|
+
if (event.data.type === "tradeit.close_requested" && closeOnCloseRequestedEvent) onOpenChange?.(false);
|
|
212
|
+
};
|
|
213
|
+
window.addEventListener("message", handleMessage);
|
|
214
|
+
return () => window.removeEventListener("message", handleMessage);
|
|
215
|
+
}, [
|
|
216
|
+
open,
|
|
217
|
+
resolved.url,
|
|
218
|
+
onEvent,
|
|
219
|
+
onError,
|
|
220
|
+
closeOnCloseRequestedEvent,
|
|
221
|
+
onOpenChange
|
|
222
|
+
]);
|
|
223
|
+
if (!isMounted) return null;
|
|
224
|
+
if (!open && !keepMounted) return null;
|
|
225
|
+
if (!resolved.url) return null;
|
|
226
|
+
const dialogStyle = isMobile ? DIALOG_MOBILE_STYLE : DIALOG_DESKTOP_STYLE;
|
|
227
|
+
const overlayStyle = {
|
|
228
|
+
...OVERLAY_STYLE,
|
|
229
|
+
zIndex
|
|
230
|
+
};
|
|
231
|
+
const dialogLabel = title ?? iframeTitle ?? "Trade It";
|
|
232
|
+
const modal = /* @__PURE__ */ jsx("div", {
|
|
233
|
+
"aria-hidden": !open,
|
|
234
|
+
style: {
|
|
235
|
+
...overlayStyle,
|
|
236
|
+
visibility: open ? "visible" : "hidden",
|
|
237
|
+
pointerEvents: open ? "auto" : "none"
|
|
238
|
+
},
|
|
239
|
+
onMouseDown: (event) => {
|
|
240
|
+
if (!closeOnOverlayClick) return;
|
|
241
|
+
if (event.target === event.currentTarget) onOpenChange?.(false);
|
|
242
|
+
},
|
|
243
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
244
|
+
role: "dialog",
|
|
245
|
+
"aria-modal": "true",
|
|
246
|
+
"aria-label": dialogLabel,
|
|
247
|
+
className,
|
|
248
|
+
style: dialogStyle,
|
|
249
|
+
children: [
|
|
250
|
+
showCloseButton && /* @__PURE__ */ jsx("button", {
|
|
251
|
+
type: "button",
|
|
252
|
+
"aria-label": "Close",
|
|
253
|
+
onClick: () => onOpenChange?.(false),
|
|
254
|
+
style: CLOSE_BUTTON_STYLE,
|
|
255
|
+
children: "×"
|
|
256
|
+
}),
|
|
257
|
+
!iframeLoaded && /* @__PURE__ */ jsx(TradeItModalLoader, {}),
|
|
258
|
+
/* @__PURE__ */ jsx("iframe", {
|
|
259
|
+
title: dialogLabel,
|
|
260
|
+
src: resolved.url,
|
|
261
|
+
style: IFRAME_STYLE,
|
|
262
|
+
allow: "fullscreen",
|
|
263
|
+
onLoad: () => setIframeLoaded(true)
|
|
264
|
+
})
|
|
265
|
+
]
|
|
266
|
+
})
|
|
267
|
+
});
|
|
268
|
+
return createPortal(modal, document.body);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
//#endregion
|
|
272
|
+
//#region src/useTradeIt.ts
|
|
273
|
+
function useTradeIt(defaults = {}) {
|
|
274
|
+
const [modalState, setModalState] = useState(null);
|
|
275
|
+
const close = useCallback(() => {
|
|
276
|
+
setModalState((prev) => prev ? {
|
|
277
|
+
...prev,
|
|
278
|
+
open: false
|
|
279
|
+
} : prev);
|
|
280
|
+
}, []);
|
|
281
|
+
const destroy = useCallback(() => {
|
|
282
|
+
setModalState(null);
|
|
283
|
+
}, []);
|
|
284
|
+
const openConnect = useCallback((options) => {
|
|
285
|
+
setModalState({
|
|
286
|
+
...defaults,
|
|
287
|
+
...options,
|
|
288
|
+
open: true,
|
|
289
|
+
launch: {
|
|
290
|
+
...options.launch,
|
|
291
|
+
mode: "connect"
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
}, [defaults]);
|
|
295
|
+
const openTrade = useCallback((options) => {
|
|
296
|
+
setModalState({
|
|
297
|
+
...defaults,
|
|
298
|
+
...options,
|
|
299
|
+
open: true,
|
|
300
|
+
launch: {
|
|
301
|
+
...options.launch,
|
|
302
|
+
mode: "trade"
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
}, [defaults]);
|
|
306
|
+
const modalProps = useMemo(() => {
|
|
307
|
+
if (!modalState) return null;
|
|
308
|
+
const handleOpenChange = (open) => {
|
|
309
|
+
setModalState((prev) => prev ? {
|
|
310
|
+
...prev,
|
|
311
|
+
open
|
|
312
|
+
} : prev);
|
|
313
|
+
modalState.onOpenChange?.(open);
|
|
314
|
+
};
|
|
315
|
+
return {
|
|
316
|
+
...modalState,
|
|
317
|
+
onOpenChange: handleOpenChange
|
|
318
|
+
};
|
|
319
|
+
}, [modalState]);
|
|
320
|
+
return {
|
|
321
|
+
isOpen: modalState?.open ?? false,
|
|
322
|
+
modalProps,
|
|
323
|
+
openConnect,
|
|
324
|
+
openTrade,
|
|
325
|
+
close,
|
|
326
|
+
destroy
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
//#endregion
|
|
331
|
+
//#region ../../lib/types/src/enums/trading.enums.ts
|
|
332
|
+
let TradeAction = /* @__PURE__ */ function(TradeAction$1) {
|
|
333
|
+
TradeAction$1["Buy"] = "buy";
|
|
334
|
+
TradeAction$1["Sell"] = "sell";
|
|
335
|
+
return TradeAction$1;
|
|
336
|
+
}({});
|
|
337
|
+
let PositionEffect = /* @__PURE__ */ function(PositionEffect$1) {
|
|
338
|
+
PositionEffect$1["Open"] = "open";
|
|
339
|
+
PositionEffect$1["Close"] = "close";
|
|
340
|
+
return PositionEffect$1;
|
|
341
|
+
}({});
|
|
342
|
+
let OrderType = /* @__PURE__ */ function(OrderType$1) {
|
|
343
|
+
OrderType$1["Market"] = "market";
|
|
344
|
+
OrderType$1["Limit"] = "limit";
|
|
345
|
+
OrderType$1["Stop"] = "stop";
|
|
346
|
+
OrderType$1["StopLimit"] = "stop_limit";
|
|
347
|
+
return OrderType$1;
|
|
348
|
+
}({});
|
|
349
|
+
let OrderDirection = /* @__PURE__ */ function(OrderDirection$1) {
|
|
350
|
+
OrderDirection$1["Debit"] = "debit";
|
|
351
|
+
OrderDirection$1["Credit"] = "credit";
|
|
352
|
+
return OrderDirection$1;
|
|
353
|
+
}({});
|
|
354
|
+
let TimeInForce = /* @__PURE__ */ function(TimeInForce$1) {
|
|
355
|
+
TimeInForce$1["Day"] = "day";
|
|
356
|
+
TimeInForce$1["GoodTillCanceled"] = "gtc";
|
|
357
|
+
TimeInForce$1["ImmediateOrCancel"] = "ioc";
|
|
358
|
+
TimeInForce$1["FillOrKill"] = "fok";
|
|
359
|
+
return TimeInForce$1;
|
|
360
|
+
}({});
|
|
361
|
+
let TradeUnit = /* @__PURE__ */ function(TradeUnit$1) {
|
|
362
|
+
TradeUnit$1["Dollars"] = "dollars";
|
|
363
|
+
TradeUnit$1["Shares"] = "shares";
|
|
364
|
+
return TradeUnit$1;
|
|
365
|
+
}({});
|
|
366
|
+
let LegType = /* @__PURE__ */ function(LegType$1) {
|
|
367
|
+
LegType$1["Option"] = "option";
|
|
368
|
+
LegType$1["Equity"] = "equity";
|
|
369
|
+
return LegType$1;
|
|
370
|
+
}({});
|
|
371
|
+
let TradeType = /* @__PURE__ */ function(TradeType$1) {
|
|
372
|
+
TradeType$1[TradeType$1["Simple"] = 0] = "Simple";
|
|
373
|
+
TradeType$1[TradeType$1["MultiLeg"] = 1] = "MultiLeg";
|
|
374
|
+
return TradeType$1;
|
|
375
|
+
}({});
|
|
376
|
+
|
|
377
|
+
//#endregion
|
|
378
|
+
//#region ../../lib/types/src/types/trade-link.types.ts
|
|
379
|
+
/**
|
|
380
|
+
* Short query parameter keys for trade link URLs
|
|
381
|
+
*/
|
|
382
|
+
let TradeLinkParam = /* @__PURE__ */ function(TradeLinkParam$1) {
|
|
383
|
+
TradeLinkParam$1["TradeType"] = "tt";
|
|
384
|
+
TradeLinkParam$1["Action"] = "t";
|
|
385
|
+
TradeLinkParam$1["OrderType"] = "ot";
|
|
386
|
+
TradeLinkParam$1["Amount"] = "a";
|
|
387
|
+
TradeLinkParam$1["Unit"] = "u";
|
|
388
|
+
TradeLinkParam$1["LimitPrice"] = "lp";
|
|
389
|
+
TradeLinkParam$1["StopPrice"] = "sp";
|
|
390
|
+
TradeLinkParam$1["TimeInForce"] = "tif";
|
|
391
|
+
TradeLinkParam$1["UtmReferred"] = "ref";
|
|
392
|
+
TradeLinkParam$1["Legs"] = "legs";
|
|
393
|
+
return TradeLinkParam$1;
|
|
394
|
+
}({});
|
|
395
|
+
|
|
396
|
+
//#endregion
|
|
397
|
+
export { LegType, OrderDirection, OrderType, PositionEffect, TimeInForce, TradeAction, TradeItModal, TradeLinkParam, TradeType, TradeUnit, getTradeItErrorMessage, getUrlOrigin, isTradeItEvent, resolveLaunchUrl, useTradeIt };
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@trade-it/react",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "React SDK for embedding Trade It connect and trade experiences in an iframe modal.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"require": "./dist/index.cjs"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md",
|
|
20
|
+
"CHANGELOG.md"
|
|
21
|
+
],
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsdown src/index.ts --format esm,cjs --dts --out-dir dist && node ../../scripts/fix-trade-it-sdk-dts.mjs dist/index.d.ts dist/index.d.cts",
|
|
28
|
+
"dev": "tsdown src/index.ts --format esm,cjs --dts --out-dir dist --watch"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@trade-it/core": "*",
|
|
32
|
+
"zod": "^3.25.67"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
36
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/react": "^19.1.1",
|
|
40
|
+
"@types/react-dom": "^19.1.1",
|
|
41
|
+
"tsdown": "^0.11.0",
|
|
42
|
+
"typescript": "^5.7.2"
|
|
43
|
+
}
|
|
44
|
+
}
|