@kodiak-finance/orderly-layout-split 2.9.2-alpha.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/dist/index.js ADDED
@@ -0,0 +1,3385 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var orderlyUi = require('@kodiak-finance/orderly-ui');
5
+ var ResizablePrimitive = require('react-resizable-panels');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+ var orderlyI18n = require('@kodiak-finance/orderly-i18n');
8
+ var core = require('@dnd-kit/core');
9
+ var modifiers = require('@dnd-kit/modifiers');
10
+ var sortable = require('@dnd-kit/sortable');
11
+ var utilities = require('@dnd-kit/utilities');
12
+ var orderlyHooks = require('@kodiak-finance/orderly-hooks');
13
+ var orderlyLayoutCore = require('@kodiak-finance/orderly-layout-core');
14
+ var orderlyTypes = require('@kodiak-finance/orderly-types');
15
+ var Split = require('@uiw/react-split');
16
+ var modifiers$1 = require('@dnd-kit/abstract/modifiers');
17
+ var react = require('@dnd-kit/react');
18
+ var sortable$1 = require('@dnd-kit/react/sortable');
19
+
20
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
21
+
22
+ function _interopNamespace(e) {
23
+ if (e && e.__esModule) return e;
24
+ var n = Object.create(null);
25
+ if (e) {
26
+ Object.keys(e).forEach(function (k) {
27
+ if (k !== 'default') {
28
+ var d = Object.getOwnPropertyDescriptor(e, k);
29
+ Object.defineProperty(n, k, d.get ? d : {
30
+ enumerable: true,
31
+ get: function () { return e[k]; }
32
+ });
33
+ }
34
+ });
35
+ }
36
+ n.default = e;
37
+ return Object.freeze(n);
38
+ }
39
+
40
+ var React__default = /*#__PURE__*/_interopDefault(React);
41
+ var ResizablePrimitive__namespace = /*#__PURE__*/_interopNamespace(ResizablePrimitive);
42
+ var Split__default = /*#__PURE__*/_interopDefault(Split);
43
+
44
+ // src/components/SplitLayout.tsx
45
+ function ResizablePanelGroup({
46
+ className,
47
+ ...props
48
+ }) {
49
+ return /* @__PURE__ */ jsxRuntime.jsx(
50
+ ResizablePrimitive__namespace.Group,
51
+ {
52
+ "data-slot": "resizable-panel-group",
53
+ className: orderlyUi.cn(
54
+ "aria-[orientation=vertical]:oui-flex-col oui-flex oui-w-full oui-h-full",
55
+ className
56
+ ),
57
+ ...props
58
+ }
59
+ );
60
+ }
61
+ function ResizablePanel({
62
+ className,
63
+ ...props
64
+ }) {
65
+ return /* @__PURE__ */ jsxRuntime.jsx(
66
+ ResizablePrimitive__namespace.Panel,
67
+ {
68
+ "data-slot": "resizable-panel",
69
+ className: orderlyUi.cn(className),
70
+ ...props
71
+ }
72
+ );
73
+ }
74
+ function ResizableHandle({
75
+ withHandle,
76
+ className,
77
+ ...props
78
+ }) {
79
+ return /* @__PURE__ */ jsxRuntime.jsx(
80
+ ResizablePrimitive__namespace.Separator,
81
+ {
82
+ "data-slot": "resizable-handle",
83
+ className: orderlyUi.cn(
84
+ "oui-bg-primary focus:oui-ring-0 focus-visible:oui-ring-0 focus-visible:oui-outline-none after:oui-absolute after:oui-inset-y-0 after:oui-left-1/2 after:oui-w-1 after:-oui-translate-x-1/2 aria-[orientation=horizontal]:oui-h-px aria-[orientation=horizontal]:oui-w-full aria-[orientation=horizontal]:after:oui-left-0 aria-[orientation=horizontal]:after:oui-h-1 aria-[orientation=horizontal]:after:oui-w-full aria-[orientation=horizontal]:after:oui-translate-x-0 aria-[orientation=horizontal]:after:-oui-translate-y-1/2 [&[aria-orientation=horizontal]>div]:oui-rotate-90 oui-relative oui-flex oui-w-px oui-items-center oui-justify-center",
85
+ className
86
+ ),
87
+ ...props,
88
+ children: withHandle && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oui-bg-primary oui-z-10 oui-flex oui-h-6 oui-w-1 oui-shrink-0 oui-rounded-lg" })
89
+ }
90
+ );
91
+ }
92
+ function sizesToDefaultLayout(sizes, count) {
93
+ if (!sizes || sizes.length !== count) return void 0;
94
+ const result = {};
95
+ let fixedTotal = 0;
96
+ const autoIndices = [];
97
+ for (let i = 0; i < count; i++) {
98
+ const s = sizes[i];
99
+ if (s === "fixed") continue;
100
+ const num = parseFloat(String(s).replace(/%/g, ""));
101
+ if (!isNaN(num)) {
102
+ result[String(i)] = Math.round(num);
103
+ fixedTotal += num;
104
+ } else {
105
+ autoIndices.push(i);
106
+ }
107
+ }
108
+ if (autoIndices.length > 0) {
109
+ const remainder = Math.max(0, 100 - fixedTotal);
110
+ const autoSize = remainder / autoIndices.length;
111
+ for (const i of autoIndices) {
112
+ result[String(i)] = Math.round(autoSize);
113
+ }
114
+ }
115
+ return Object.keys(result).length > 0 ? result : void 0;
116
+ }
117
+ var SPLIT_HANDLE_BASE_CLASSNAME = [
118
+ "!oui-transition-none",
119
+ "!oui-shadow-none",
120
+ "!oui-bg-transparent",
121
+ "hover:!oui-bg-primary-light",
122
+ "hover:!oui-shadow-[0px_0px_2px_0px]",
123
+ "hover:!oui-shadow-primary-light/80",
124
+ "active:!oui-bg-primary-light",
125
+ "active:!oui-shadow-[0px_0px_2px_0px]",
126
+ "active:!oui-shadow-primary-light/80"
127
+ // "focus:!oui-bg-primary-light",
128
+ // "focus:!oui-shadow-[0px_0px_4px_0px]",
129
+ // "focus:!oui-shadow-primary-light/80",
130
+ ];
131
+ function SplitLayout({
132
+ orientation,
133
+ sizes,
134
+ panelConstraints,
135
+ onSizeChange,
136
+ children,
137
+ className,
138
+ style,
139
+ classNames,
140
+ gap
141
+ }) {
142
+ const childArray = React__default.default.Children.toArray(children);
143
+ const count = childArray.length;
144
+ const defaultLayout = React.useMemo(
145
+ () => sizesToDefaultLayout(sizes, count),
146
+ [sizes, count]
147
+ );
148
+ const handleLayoutChanged = React.useCallback(
149
+ (layout) => {
150
+ const panelIds = Array.from({ length: count }, (_, i) => String(i));
151
+ const sizesAsStrings = panelIds.map((id, index) => {
152
+ const value = layout[id];
153
+ if (typeof value === "number") {
154
+ return `${Math.round(value)}%`;
155
+ }
156
+ const originalSize = sizes?.[index];
157
+ return originalSize ?? "auto";
158
+ });
159
+ onSizeChange?.(sizesAsStrings);
160
+ },
161
+ [onSizeChange, count]
162
+ );
163
+ if (count === 0) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {});
164
+ const marginPx = gap != null ? gap * 2 : 4;
165
+ const handleStyle = orientation === "horizontal" ? { width: 2, marginLeft: marginPx, marginRight: marginPx } : { height: 2, marginTop: marginPx, marginBottom: marginPx };
166
+ return /* @__PURE__ */ jsxRuntime.jsx(
167
+ ResizablePanelGroup,
168
+ {
169
+ orientation,
170
+ defaultLayout,
171
+ onLayoutChanged: handleLayoutChanged,
172
+ className: orderlyUi.cn(className, classNames?.panelGroup),
173
+ style,
174
+ children: childArray.map((child, index) => {
175
+ const constraints = panelConstraints?.[index];
176
+ const size = sizes?.[index];
177
+ const isFixed = size === "fixed";
178
+ const nextIsFixed = sizes?.[index + 1] === "fixed";
179
+ return /* @__PURE__ */ jsxRuntime.jsxs(React__default.default.Fragment, { children: [
180
+ isFixed ? child : /* @__PURE__ */ jsxRuntime.jsx(
181
+ ResizablePanel,
182
+ {
183
+ id: String(index),
184
+ defaultSize: size,
185
+ minSize: constraints?.minSize,
186
+ maxSize: constraints?.maxSize,
187
+ disabled: constraints?.disabled,
188
+ className: classNames?.panel,
189
+ children: child
190
+ }
191
+ ),
192
+ index < count - 1 && !isFixed && !nextIsFixed && /* @__PURE__ */ jsxRuntime.jsx(
193
+ ResizableHandle,
194
+ {
195
+ className: orderlyUi.cn(SPLIT_HANDLE_BASE_CLASSNAME, classNames?.handle),
196
+ style: handleStyle
197
+ }
198
+ )
199
+ ] }, `panel-${index}`);
200
+ })
201
+ }
202
+ );
203
+ }
204
+ SplitLayout.displayName = "SplitLayout";
205
+
206
+ // src/constants.ts
207
+ var BREAKPOINT_KEYS = [
208
+ "lg",
209
+ "md",
210
+ "sm",
211
+ "xs"
212
+ ];
213
+ var BREAKPOINT_VALUES = {
214
+ lg: 1680,
215
+ md: 1440,
216
+ sm: 1280,
217
+ xs: 768
218
+ };
219
+ var SPLIT_BREAKPOINT_ORDER = BREAKPOINT_KEYS;
220
+ var DEFAULT_SPLIT_BREAKPOINTS = BREAKPOINT_VALUES;
221
+ var VIEWPORT_BREAKPOINTS = BREAKPOINT_VALUES;
222
+ var VIEWPORT_BREAKPOINT_ORDER = BREAKPOINT_KEYS;
223
+
224
+ // src/utils/splitLayoutUtils.ts
225
+ function getSortableIdForChild(child, path, index) {
226
+ if (child.type === "panel" && child.id) {
227
+ return child.id;
228
+ }
229
+ return `sortable-${path.join("-")}-${index}`;
230
+ }
231
+ function updateOrderAtPath(node, path, newOrder) {
232
+ if (node.type === "panel") return node;
233
+ if (path.length === 0) {
234
+ return { ...node, children: newOrder };
235
+ }
236
+ const [childIndex, ...restPath] = path;
237
+ const updatedChildren = [...node.children];
238
+ if (childIndex < updatedChildren.length) {
239
+ updatedChildren[childIndex] = updateOrderAtPath(
240
+ updatedChildren[childIndex],
241
+ restPath,
242
+ newOrder
243
+ );
244
+ }
245
+ return { ...node, children: updatedChildren };
246
+ }
247
+ function createDefaultSplitLayout(panelIds) {
248
+ if (panelIds.length === 0) {
249
+ throw new Error(
250
+ "Cannot create default split layout: no panel IDs provided"
251
+ );
252
+ }
253
+ let singleRoot;
254
+ if (panelIds.length === 1) {
255
+ singleRoot = { type: "panel", id: panelIds[0] };
256
+ } else {
257
+ singleRoot = {
258
+ type: "split",
259
+ orientation: "horizontal",
260
+ children: panelIds.map((panelId) => ({
261
+ type: "panel",
262
+ id: panelId
263
+ }))
264
+ };
265
+ }
266
+ const layouts = {
267
+ lg: singleRoot,
268
+ md: singleRoot,
269
+ sm: singleRoot,
270
+ xs: singleRoot
271
+ };
272
+ return {
273
+ layouts,
274
+ breakpoints: DEFAULT_SPLIT_BREAKPOINTS
275
+ };
276
+ }
277
+ function isValidOrientation(v) {
278
+ return v === "horizontal" || v === "vertical";
279
+ }
280
+ function validateContainerNode(n) {
281
+ return isValidOrientation(n.orientation) && Array.isArray(n.children) && n.children.every((c) => validateSplitLayoutNode(c));
282
+ }
283
+ function validateSplitLayoutNode(node) {
284
+ if (!node || typeof node !== "object") return false;
285
+ const n = node;
286
+ if (n.type === "panel") {
287
+ return typeof n.id === "string" && n.id.length > 0 && (n.size === void 0 || typeof n.size === "string") && (n.minSize === void 0 || typeof n.minSize === "string") && (n.maxSize === void 0 || typeof n.maxSize === "string") && (n.disabled === void 0 || typeof n.disabled === "boolean") && (n.className === void 0 || typeof n.className === "string") && (n.style === void 0 || typeof n.style === "object");
288
+ }
289
+ if (n.type === "split" || n.type === "sort") return validateContainerNode(n);
290
+ return false;
291
+ }
292
+ function validateSplitLayoutModel(parsed) {
293
+ if (!parsed || typeof parsed !== "object") return false;
294
+ const p = parsed;
295
+ const layoutsSource = p.layouts ?? p.roots;
296
+ if (!layoutsSource || typeof layoutsSource !== "object") return false;
297
+ if (!p.breakpoints || typeof p.breakpoints !== "object") return false;
298
+ const layouts = layoutsSource;
299
+ const bp = p.breakpoints;
300
+ for (const k of SPLIT_BREAKPOINT_ORDER) {
301
+ if (!validateSplitLayoutNode(layouts[k]) || typeof bp[k] !== "number") {
302
+ return false;
303
+ }
304
+ }
305
+ return true;
306
+ }
307
+ function serializeSplitLayout(layout) {
308
+ return JSON.stringify(layout);
309
+ }
310
+ function deserializeSplitLayout(json) {
311
+ try {
312
+ const parsed = JSON.parse(json);
313
+ if (!validateSplitLayoutModel(parsed)) {
314
+ throw new Error(
315
+ "Invalid split layout: must have layouts (lg,md,sm,xs) and breakpoints"
316
+ );
317
+ }
318
+ const layout = parsed;
319
+ const layoutsSource = layout.layouts ?? layout.roots;
320
+ const layouts = {};
321
+ for (const bp of SPLIT_BREAKPOINT_ORDER) {
322
+ layouts[bp] = layoutsSource[bp];
323
+ }
324
+ const { roots: _roots, ...rest } = layout;
325
+ return { ...rest, layouts };
326
+ } catch (error) {
327
+ if (error instanceof Error) {
328
+ throw new Error(`Failed to deserialize split layout: ${error.message}`);
329
+ }
330
+ throw new Error(`Failed to deserialize split layout: ${error}`);
331
+ }
332
+ }
333
+ var SplitLayoutConfigContext = React.createContext(
334
+ null
335
+ );
336
+ function SplitLayoutConfigProvider({
337
+ panels,
338
+ layout,
339
+ breakpoint,
340
+ onLayoutChange,
341
+ onSizeChange,
342
+ onSizePersist,
343
+ classNames,
344
+ gap,
345
+ collapsedPanels,
346
+ togglePanelCollapse,
347
+ isPanelCollapsed,
348
+ collapsiblePanels,
349
+ isPanelCollapsible,
350
+ children
351
+ }) {
352
+ const value = React.useMemo(
353
+ () => ({
354
+ panels,
355
+ layout,
356
+ breakpoint,
357
+ onLayoutChange,
358
+ onSizeChange,
359
+ onSizePersist,
360
+ classNames,
361
+ gap,
362
+ collapsedPanels,
363
+ togglePanelCollapse,
364
+ isPanelCollapsed,
365
+ collapsiblePanels,
366
+ isPanelCollapsible
367
+ }),
368
+ [
369
+ panels,
370
+ layout,
371
+ breakpoint,
372
+ onLayoutChange,
373
+ onSizeChange,
374
+ onSizePersist,
375
+ classNames,
376
+ gap,
377
+ collapsedPanels,
378
+ togglePanelCollapse,
379
+ isPanelCollapsed,
380
+ collapsiblePanels,
381
+ isPanelCollapsible
382
+ ]
383
+ );
384
+ return /* @__PURE__ */ jsxRuntime.jsx(SplitLayoutConfigContext.Provider, { value, children });
385
+ }
386
+ function useSplitLayoutConfig() {
387
+ const ctx = React.useContext(SplitLayoutConfigContext);
388
+ if (!ctx) {
389
+ throw new Error(
390
+ "useSplitLayoutConfig must be used within SplitLayoutConfigProvider"
391
+ );
392
+ }
393
+ return ctx;
394
+ }
395
+ var OrderEntryIcon = (props) => /* @__PURE__ */ jsxRuntime.jsxs(
396
+ "svg",
397
+ {
398
+ width: "36",
399
+ height: "84",
400
+ viewBox: "0 0 36 84",
401
+ fill: "none",
402
+ xmlns: "http://www.w3.org/2000/svg",
403
+ ...props,
404
+ children: [
405
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "36", height: "17", rx: "2", fill: "rgb(var(--oui-color-base-7))" }),
406
+ /* @__PURE__ */ jsxRuntime.jsx(
407
+ "rect",
408
+ {
409
+ y: "19",
410
+ width: "36",
411
+ height: "54",
412
+ rx: "2",
413
+ fill: "rgb(var(--oui-color-base-7))"
414
+ }
415
+ ),
416
+ /* @__PURE__ */ jsxRuntime.jsx(
417
+ "rect",
418
+ {
419
+ y: "75",
420
+ width: "36",
421
+ height: "9",
422
+ rx: "2",
423
+ fill: "rgb(var(--oui-color-base-7))"
424
+ }
425
+ ),
426
+ /* @__PURE__ */ jsxRuntime.jsx(
427
+ "rect",
428
+ {
429
+ x: "3",
430
+ y: "79",
431
+ width: "30",
432
+ height: "1",
433
+ rx: "0.5",
434
+ fill: "url(#paint0_linear_17647_26849)"
435
+ }
436
+ ),
437
+ /* @__PURE__ */ jsxRuntime.jsx(
438
+ "rect",
439
+ {
440
+ x: "3",
441
+ y: "22",
442
+ width: "14",
443
+ height: "6",
444
+ rx: "2",
445
+ fill: "rgb(var(--oui-color-success-darken))"
446
+ }
447
+ ),
448
+ /* @__PURE__ */ jsxRuntime.jsx(
449
+ "rect",
450
+ {
451
+ x: "19",
452
+ y: "22",
453
+ width: "14",
454
+ height: "6",
455
+ rx: "2",
456
+ fill: "rgb(var(--oui-color-danger-darken))"
457
+ }
458
+ ),
459
+ /* @__PURE__ */ jsxRuntime.jsx(
460
+ "rect",
461
+ {
462
+ x: "3",
463
+ y: "11",
464
+ width: "14",
465
+ height: "3",
466
+ rx: "1.5",
467
+ fill: "rgb(var(--oui-color-base-4))"
468
+ }
469
+ ),
470
+ /* @__PURE__ */ jsxRuntime.jsx(
471
+ "rect",
472
+ {
473
+ x: "19",
474
+ y: "11",
475
+ width: "14",
476
+ height: "3",
477
+ rx: "1.5",
478
+ fill: "rgb(var(--oui-color-primary-darken))"
479
+ }
480
+ ),
481
+ /* @__PURE__ */ jsxRuntime.jsx(
482
+ "rect",
483
+ {
484
+ x: "3",
485
+ y: "62",
486
+ width: "30",
487
+ height: "8",
488
+ rx: "2",
489
+ fill: "rgb(var(--oui-color-success-darken))"
490
+ }
491
+ ),
492
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs(
493
+ "linearGradient",
494
+ {
495
+ id: "paint0_linear_17647_26849",
496
+ x1: "33",
497
+ y1: "79.5",
498
+ x2: "3",
499
+ y2: "79.5",
500
+ gradientUnits: "userSpaceOnUse",
501
+ children: [
502
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { stopColor: "rgb(var(--oui-color-primary-light))" }),
503
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "1", stopColor: "rgb(var(--oui-gradient-brand-start))" })
504
+ ]
505
+ }
506
+ ) })
507
+ ]
508
+ }
509
+ );
510
+ var MarketLeftIcon = ({
511
+ isSelected,
512
+ isHovered,
513
+ ...props
514
+ }) => {
515
+ const getStrokeColor = () => {
516
+ if (isSelected) return "rgb(var(--oui-color-primary-light))";
517
+ if (isHovered) return "rgb(var(--oui-color-primary-light))";
518
+ return "rgb(var(--oui-color-base-5))";
519
+ };
520
+ return /* @__PURE__ */ jsxRuntime.jsxs(
521
+ "svg",
522
+ {
523
+ width: "148",
524
+ height: "100",
525
+ viewBox: "0 0 148 100",
526
+ fill: "none",
527
+ xmlns: "http://www.w3.org/2000/svg",
528
+ ...props,
529
+ children: [
530
+ /* @__PURE__ */ jsxRuntime.jsx(
531
+ "rect",
532
+ {
533
+ x: "2",
534
+ y: "2",
535
+ width: "144",
536
+ height: "96",
537
+ rx: "10",
538
+ fill: "rgb(var(--oui-color-base-10))",
539
+ stroke: getStrokeColor(),
540
+ strokeWidth: "4"
541
+ }
542
+ ),
543
+ /* @__PURE__ */ jsxRuntime.jsx(
544
+ "rect",
545
+ {
546
+ x: "8",
547
+ y: "8",
548
+ width: "24",
549
+ height: "84",
550
+ rx: "2",
551
+ fill: "rgb(var(--oui-color-base-7))"
552
+ }
553
+ ),
554
+ /* @__PURE__ */ jsxRuntime.jsx(
555
+ "rect",
556
+ {
557
+ x: "16",
558
+ y: "10",
559
+ width: "4",
560
+ height: "2",
561
+ rx: "1",
562
+ fill: "rgb(var(--oui-color-base-4))"
563
+ }
564
+ ),
565
+ /* @__PURE__ */ jsxRuntime.jsx(
566
+ "rect",
567
+ {
568
+ x: "21",
569
+ y: "10",
570
+ width: "4",
571
+ height: "2",
572
+ rx: "1",
573
+ fill: "rgb(var(--oui-color-base-4))"
574
+ }
575
+ ),
576
+ /* @__PURE__ */ jsxRuntime.jsx(
577
+ "rect",
578
+ {
579
+ x: "26",
580
+ y: "10",
581
+ width: "4",
582
+ height: "2",
583
+ rx: "1",
584
+ fill: "rgb(var(--oui-color-base-4))"
585
+ }
586
+ ),
587
+ /* @__PURE__ */ jsxRuntime.jsx(
588
+ "rect",
589
+ {
590
+ x: "10",
591
+ y: "10",
592
+ width: "5",
593
+ height: "2",
594
+ rx: "1",
595
+ fill: "rgb(var(--oui-color-primary-darken))"
596
+ }
597
+ ),
598
+ /* @__PURE__ */ jsxRuntime.jsx(
599
+ "rect",
600
+ {
601
+ x: "10",
602
+ y: "14",
603
+ width: "20",
604
+ height: "76",
605
+ rx: "2",
606
+ fill: "rgb(var(--oui-color-base-5))"
607
+ }
608
+ )
609
+ ]
610
+ }
611
+ );
612
+ };
613
+ var MarketTopIcon = ({
614
+ isSelected,
615
+ isHovered,
616
+ ...props
617
+ }) => {
618
+ const getStrokeColor = () => {
619
+ if (isSelected) return "rgb(var(--oui-color-primary-light))";
620
+ if (isHovered) return "rgb(var(--oui-color-primary-light))";
621
+ return "rgb(var(--oui-color-base-5))";
622
+ };
623
+ return /* @__PURE__ */ jsxRuntime.jsxs(
624
+ "svg",
625
+ {
626
+ width: "148",
627
+ height: "100",
628
+ viewBox: "0 0 148 100",
629
+ fill: "none",
630
+ xmlns: "http://www.w3.org/2000/svg",
631
+ ...props,
632
+ children: [
633
+ /* @__PURE__ */ jsxRuntime.jsx(
634
+ "rect",
635
+ {
636
+ x: "2",
637
+ y: "2",
638
+ width: "144",
639
+ height: "96",
640
+ rx: "10",
641
+ fill: "rgb(var(--oui-color-base-10))",
642
+ stroke: getStrokeColor(),
643
+ strokeWidth: "4"
644
+ }
645
+ ),
646
+ /* @__PURE__ */ jsxRuntime.jsx(
647
+ "rect",
648
+ {
649
+ x: "8",
650
+ y: "8",
651
+ width: "132",
652
+ height: "8",
653
+ rx: "2",
654
+ fill: "rgb(var(--oui-color-base-7))"
655
+ }
656
+ ),
657
+ /* @__PURE__ */ jsxRuntime.jsxs("g", { clipPath: "url(#clip0_31319_74729)", children: [
658
+ /* @__PURE__ */ jsxRuntime.jsx(
659
+ "rect",
660
+ {
661
+ x: "10",
662
+ y: "10",
663
+ width: "16",
664
+ height: "4",
665
+ rx: "2",
666
+ fill: "rgb(var(--oui-color-primary-darken))"
667
+ }
668
+ ),
669
+ /* @__PURE__ */ jsxRuntime.jsx(
670
+ "rect",
671
+ {
672
+ x: "28",
673
+ y: "10",
674
+ width: "16",
675
+ height: "4",
676
+ rx: "2",
677
+ fill: "rgb(var(--oui-color-base-4))"
678
+ }
679
+ ),
680
+ /* @__PURE__ */ jsxRuntime.jsx(
681
+ "rect",
682
+ {
683
+ x: "46",
684
+ y: "10",
685
+ width: "16",
686
+ height: "4",
687
+ rx: "2",
688
+ fill: "rgb(var(--oui-color-base-4))"
689
+ }
690
+ ),
691
+ /* @__PURE__ */ jsxRuntime.jsx(
692
+ "rect",
693
+ {
694
+ x: "64",
695
+ y: "10",
696
+ width: "16",
697
+ height: "4",
698
+ rx: "2",
699
+ fill: "rgb(var(--oui-color-base-4))"
700
+ }
701
+ ),
702
+ /* @__PURE__ */ jsxRuntime.jsx(
703
+ "rect",
704
+ {
705
+ x: "82",
706
+ y: "10",
707
+ width: "16",
708
+ height: "4",
709
+ rx: "2",
710
+ fill: "rgb(var(--oui-color-base-4))"
711
+ }
712
+ ),
713
+ /* @__PURE__ */ jsxRuntime.jsx(
714
+ "rect",
715
+ {
716
+ x: "100",
717
+ y: "10",
718
+ width: "16",
719
+ height: "4",
720
+ rx: "2",
721
+ fill: "rgb(var(--oui-color-base-4))"
722
+ }
723
+ ),
724
+ /* @__PURE__ */ jsxRuntime.jsx(
725
+ "rect",
726
+ {
727
+ x: "118",
728
+ y: "10",
729
+ width: "16",
730
+ height: "4",
731
+ rx: "2",
732
+ fill: "rgb(var(--oui-color-base-4))"
733
+ }
734
+ ),
735
+ /* @__PURE__ */ jsxRuntime.jsx(
736
+ "rect",
737
+ {
738
+ x: "136",
739
+ y: "10",
740
+ width: "16",
741
+ height: "4",
742
+ rx: "2",
743
+ fill: "rgb(var(--oui-color-base-4))"
744
+ }
745
+ )
746
+ ] }),
747
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip0_31319_74729", children: /* @__PURE__ */ jsxRuntime.jsx(
748
+ "rect",
749
+ {
750
+ width: "130",
751
+ height: "4",
752
+ fill: "rgb(var(--oui-color-base-foreground))",
753
+ transform: "translate(10 10)"
754
+ }
755
+ ) }) })
756
+ ]
757
+ }
758
+ );
759
+ };
760
+ var MarketBottomIcon = ({
761
+ isSelected,
762
+ isHovered,
763
+ ...props
764
+ }) => {
765
+ const getStrokeColor = () => {
766
+ if (isSelected) return "rgb(var(--oui-color-primary-light))";
767
+ if (isHovered) return "rgb(var(--oui-color-primary-light))";
768
+ return "rgb(var(--oui-color-base-5))";
769
+ };
770
+ return /* @__PURE__ */ jsxRuntime.jsxs(
771
+ "svg",
772
+ {
773
+ width: "148",
774
+ height: "100",
775
+ viewBox: "0 0 148 100",
776
+ fill: "none",
777
+ xmlns: "http://www.w3.org/2000/svg",
778
+ ...props,
779
+ children: [
780
+ /* @__PURE__ */ jsxRuntime.jsx(
781
+ "rect",
782
+ {
783
+ x: "2",
784
+ y: "2",
785
+ width: "144",
786
+ height: "96",
787
+ rx: "10",
788
+ fill: "rgb(var(--oui-color-base-10))",
789
+ stroke: getStrokeColor(),
790
+ strokeWidth: "4"
791
+ }
792
+ ),
793
+ /* @__PURE__ */ jsxRuntime.jsx(
794
+ "rect",
795
+ {
796
+ x: "8",
797
+ y: "84",
798
+ width: "132",
799
+ height: "8",
800
+ rx: "2",
801
+ fill: "rgb(var(--oui-color-base-7))"
802
+ }
803
+ ),
804
+ /* @__PURE__ */ jsxRuntime.jsxs("g", { clipPath: "url(#clip0_31319_74743)", children: [
805
+ /* @__PURE__ */ jsxRuntime.jsx(
806
+ "rect",
807
+ {
808
+ x: "10",
809
+ y: "86",
810
+ width: "16",
811
+ height: "4",
812
+ rx: "2",
813
+ fill: "rgb(var(--oui-color-primary-darken))"
814
+ }
815
+ ),
816
+ /* @__PURE__ */ jsxRuntime.jsx(
817
+ "rect",
818
+ {
819
+ x: "28",
820
+ y: "86",
821
+ width: "16",
822
+ height: "4",
823
+ rx: "2",
824
+ fill: "rgb(var(--oui-color-base-4))"
825
+ }
826
+ ),
827
+ /* @__PURE__ */ jsxRuntime.jsx(
828
+ "rect",
829
+ {
830
+ x: "46",
831
+ y: "86",
832
+ width: "16",
833
+ height: "4",
834
+ rx: "2",
835
+ fill: "rgb(var(--oui-color-base-4))"
836
+ }
837
+ ),
838
+ /* @__PURE__ */ jsxRuntime.jsx(
839
+ "rect",
840
+ {
841
+ x: "64",
842
+ y: "86",
843
+ width: "16",
844
+ height: "4",
845
+ rx: "2",
846
+ fill: "rgb(var(--oui-color-base-4))"
847
+ }
848
+ ),
849
+ /* @__PURE__ */ jsxRuntime.jsx(
850
+ "rect",
851
+ {
852
+ x: "82",
853
+ y: "86",
854
+ width: "16",
855
+ height: "4",
856
+ rx: "2",
857
+ fill: "rgb(var(--oui-color-base-4))"
858
+ }
859
+ ),
860
+ /* @__PURE__ */ jsxRuntime.jsx(
861
+ "rect",
862
+ {
863
+ x: "100",
864
+ y: "86",
865
+ width: "16",
866
+ height: "4",
867
+ rx: "2",
868
+ fill: "rgb(var(--oui-color-base-4))"
869
+ }
870
+ ),
871
+ /* @__PURE__ */ jsxRuntime.jsx(
872
+ "rect",
873
+ {
874
+ x: "118",
875
+ y: "86",
876
+ width: "16",
877
+ height: "4",
878
+ rx: "2",
879
+ fill: "rgb(var(--oui-color-base-4))"
880
+ }
881
+ ),
882
+ /* @__PURE__ */ jsxRuntime.jsx(
883
+ "rect",
884
+ {
885
+ x: "136",
886
+ y: "86",
887
+ width: "16",
888
+ height: "4",
889
+ rx: "2",
890
+ fill: "rgb(var(--oui-color-base-4))"
891
+ }
892
+ )
893
+ ] }),
894
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip0_31319_74743", children: /* @__PURE__ */ jsxRuntime.jsx(
895
+ "rect",
896
+ {
897
+ width: "130",
898
+ height: "4",
899
+ fill: "rgb(var(--oui-color-base-foreground))",
900
+ transform: "translate(10 86)"
901
+ }
902
+ ) }) })
903
+ ]
904
+ }
905
+ );
906
+ };
907
+ var MarketHideIcon = ({
908
+ isSelected,
909
+ isHovered,
910
+ ...props
911
+ }) => {
912
+ const getStrokeColor = () => {
913
+ if (isSelected) return "rgb(var(--oui-color-primary-light))";
914
+ if (isHovered) return "rgb(var(--oui-color-primary-light))";
915
+ return "rgb(var(--oui-color-base-5))";
916
+ };
917
+ return /* @__PURE__ */ jsxRuntime.jsxs(
918
+ "svg",
919
+ {
920
+ width: "148",
921
+ height: "100",
922
+ viewBox: "0 0 148 100",
923
+ fill: "none",
924
+ xmlns: "http://www.w3.org/2000/svg",
925
+ ...props,
926
+ children: [
927
+ /* @__PURE__ */ jsxRuntime.jsx(
928
+ "rect",
929
+ {
930
+ x: "2",
931
+ y: "2",
932
+ width: "144",
933
+ height: "96",
934
+ rx: "10",
935
+ fill: "rgb(var(--oui-color-base-10))",
936
+ stroke: getStrokeColor(),
937
+ strokeWidth: "4"
938
+ }
939
+ ),
940
+ /* @__PURE__ */ jsxRuntime.jsxs("g", { clipPath: "url(#clip0_31319_74757)", children: [
941
+ /* @__PURE__ */ jsxRuntime.jsx(
942
+ "rect",
943
+ {
944
+ x: "8",
945
+ y: "8",
946
+ width: "132",
947
+ height: "84",
948
+ rx: "2",
949
+ fill: "rgb(var(--oui-color-base-7))"
950
+ }
951
+ ),
952
+ /* @__PURE__ */ jsxRuntime.jsx(
953
+ "rect",
954
+ {
955
+ x: "66.8789",
956
+ y: "-76",
957
+ width: "4",
958
+ height: "188",
959
+ rx: "2",
960
+ transform: "rotate(45 66.8789 -76)",
961
+ fill: "rgb(var(--oui-color-base-6))"
962
+ }
963
+ ),
964
+ /* @__PURE__ */ jsxRuntime.jsx(
965
+ "rect",
966
+ {
967
+ x: "73.9492",
968
+ y: "-68.929",
969
+ width: "4",
970
+ height: "188",
971
+ rx: "2",
972
+ transform: "rotate(45 73.9492 -68.929)",
973
+ fill: "rgb(var(--oui-color-base-6))"
974
+ }
975
+ ),
976
+ /* @__PURE__ */ jsxRuntime.jsx(
977
+ "rect",
978
+ {
979
+ x: "81.0195",
980
+ y: "-61.8579",
981
+ width: "4",
982
+ height: "188",
983
+ rx: "2",
984
+ transform: "rotate(45 81.0195 -61.8579)",
985
+ fill: "rgb(var(--oui-color-base-6))"
986
+ }
987
+ ),
988
+ /* @__PURE__ */ jsxRuntime.jsx(
989
+ "rect",
990
+ {
991
+ x: "88.0938",
992
+ y: "-54.7867",
993
+ width: "4",
994
+ height: "188",
995
+ rx: "2",
996
+ transform: "rotate(45 88.0938 -54.7867)",
997
+ fill: "rgb(var(--oui-color-base-6))"
998
+ }
999
+ ),
1000
+ /* @__PURE__ */ jsxRuntime.jsx(
1001
+ "rect",
1002
+ {
1003
+ x: "95.1641",
1004
+ y: "-47.7157",
1005
+ width: "4",
1006
+ height: "188",
1007
+ rx: "2",
1008
+ transform: "rotate(45 95.1641 -47.7157)",
1009
+ fill: "rgb(var(--oui-color-base-6))"
1010
+ }
1011
+ ),
1012
+ /* @__PURE__ */ jsxRuntime.jsx(
1013
+ "rect",
1014
+ {
1015
+ x: "102.234",
1016
+ y: "-40.6447",
1017
+ width: "4",
1018
+ height: "188",
1019
+ rx: "2",
1020
+ transform: "rotate(45 102.234 -40.6447)",
1021
+ fill: "rgb(var(--oui-color-base-6))"
1022
+ }
1023
+ ),
1024
+ /* @__PURE__ */ jsxRuntime.jsx(
1025
+ "rect",
1026
+ {
1027
+ x: "109.305",
1028
+ y: "-33.5736",
1029
+ width: "4",
1030
+ height: "188",
1031
+ rx: "2",
1032
+ transform: "rotate(45 109.305 -33.5736)",
1033
+ fill: "rgb(var(--oui-color-base-6))"
1034
+ }
1035
+ ),
1036
+ /* @__PURE__ */ jsxRuntime.jsx(
1037
+ "rect",
1038
+ {
1039
+ x: "116.375",
1040
+ y: "-26.5026",
1041
+ width: "4",
1042
+ height: "188",
1043
+ rx: "2",
1044
+ transform: "rotate(45 116.375 -26.5026)",
1045
+ fill: "rgb(var(--oui-color-base-6))"
1046
+ }
1047
+ ),
1048
+ /* @__PURE__ */ jsxRuntime.jsx(
1049
+ "rect",
1050
+ {
1051
+ x: "123.449",
1052
+ y: "-19.4315",
1053
+ width: "4",
1054
+ height: "188",
1055
+ rx: "2",
1056
+ transform: "rotate(45 123.449 -19.4315)",
1057
+ fill: "rgb(var(--oui-color-base-6))"
1058
+ }
1059
+ ),
1060
+ /* @__PURE__ */ jsxRuntime.jsx(
1061
+ "rect",
1062
+ {
1063
+ x: "130.52",
1064
+ y: "-12.3604",
1065
+ width: "4",
1066
+ height: "188",
1067
+ rx: "2",
1068
+ transform: "rotate(45 130.52 -12.3604)",
1069
+ fill: "rgb(var(--oui-color-base-6))"
1070
+ }
1071
+ ),
1072
+ /* @__PURE__ */ jsxRuntime.jsx(
1073
+ "rect",
1074
+ {
1075
+ x: "137.59",
1076
+ y: "-5.28931",
1077
+ width: "4",
1078
+ height: "188",
1079
+ rx: "2",
1080
+ transform: "rotate(45 137.59 -5.28931)",
1081
+ fill: "rgb(var(--oui-color-base-6))"
1082
+ }
1083
+ ),
1084
+ /* @__PURE__ */ jsxRuntime.jsx(
1085
+ "rect",
1086
+ {
1087
+ x: "144.66",
1088
+ y: "1.78174",
1089
+ width: "4",
1090
+ height: "188",
1091
+ rx: "2",
1092
+ transform: "rotate(45 144.66 1.78174)",
1093
+ fill: "rgb(var(--oui-color-base-6))"
1094
+ }
1095
+ ),
1096
+ /* @__PURE__ */ jsxRuntime.jsx(
1097
+ "rect",
1098
+ {
1099
+ x: "151.73",
1100
+ y: "8.85278",
1101
+ width: "4",
1102
+ height: "188",
1103
+ rx: "2",
1104
+ transform: "rotate(45 151.73 8.85278)",
1105
+ fill: "rgb(var(--oui-color-base-6))"
1106
+ }
1107
+ ),
1108
+ /* @__PURE__ */ jsxRuntime.jsx(
1109
+ "rect",
1110
+ {
1111
+ x: "158.805",
1112
+ y: "15.9238",
1113
+ width: "4",
1114
+ height: "188",
1115
+ rx: "2",
1116
+ transform: "rotate(45 158.805 15.9238)",
1117
+ fill: "rgb(var(--oui-color-base-6))"
1118
+ }
1119
+ ),
1120
+ /* @__PURE__ */ jsxRuntime.jsx(
1121
+ "rect",
1122
+ {
1123
+ x: "165.875",
1124
+ y: "22.995",
1125
+ width: "4",
1126
+ height: "188",
1127
+ rx: "2",
1128
+ transform: "rotate(45 165.875 22.995)",
1129
+ fill: "rgb(var(--oui-color-base-6))"
1130
+ }
1131
+ ),
1132
+ /* @__PURE__ */ jsxRuntime.jsx(
1133
+ "rect",
1134
+ {
1135
+ x: "172.945",
1136
+ y: "30.066",
1137
+ width: "4",
1138
+ height: "188",
1139
+ rx: "2",
1140
+ transform: "rotate(45 172.945 30.066)",
1141
+ fill: "rgb(var(--oui-color-base-6))"
1142
+ }
1143
+ ),
1144
+ /* @__PURE__ */ jsxRuntime.jsx(
1145
+ "rect",
1146
+ {
1147
+ x: "180.016",
1148
+ y: "37.1371",
1149
+ width: "4",
1150
+ height: "188",
1151
+ rx: "2",
1152
+ transform: "rotate(45 180.016 37.1371)",
1153
+ fill: "rgb(var(--oui-color-base-6))"
1154
+ }
1155
+ ),
1156
+ /* @__PURE__ */ jsxRuntime.jsx(
1157
+ "rect",
1158
+ {
1159
+ x: "187.086",
1160
+ y: "44.2081",
1161
+ width: "4",
1162
+ height: "188",
1163
+ rx: "2",
1164
+ transform: "rotate(45 187.086 44.2081)",
1165
+ fill: "rgb(var(--oui-color-base-6))"
1166
+ }
1167
+ ),
1168
+ /* @__PURE__ */ jsxRuntime.jsx(
1169
+ "rect",
1170
+ {
1171
+ x: "194.156",
1172
+ y: "51.2792",
1173
+ width: "4",
1174
+ height: "188",
1175
+ rx: "2",
1176
+ transform: "rotate(45 194.156 51.2792)",
1177
+ fill: "rgb(var(--oui-color-base-6))"
1178
+ }
1179
+ ),
1180
+ /* @__PURE__ */ jsxRuntime.jsx(
1181
+ "rect",
1182
+ {
1183
+ x: "201.23",
1184
+ y: "58.3503",
1185
+ width: "4",
1186
+ height: "188",
1187
+ rx: "2",
1188
+ transform: "rotate(45 201.23 58.3503)",
1189
+ fill: "rgb(var(--oui-color-base-6))"
1190
+ }
1191
+ )
1192
+ ] }),
1193
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip0_31319_74757", children: /* @__PURE__ */ jsxRuntime.jsx(
1194
+ "rect",
1195
+ {
1196
+ width: "132",
1197
+ height: "84",
1198
+ fill: "rgb(var(--oui-color-base-foreground))",
1199
+ transform: "translate(8 8)"
1200
+ }
1201
+ ) }) })
1202
+ ]
1203
+ }
1204
+ );
1205
+ };
1206
+ var LayoutSwitchButton = ({
1207
+ layout,
1208
+ markets,
1209
+ onLayoutChange,
1210
+ onMarketChange
1211
+ }) => {
1212
+ const { t } = orderlyI18n.useTranslation();
1213
+ const [open, setOpen] = React__default.default.useState(false);
1214
+ const [hoveredMarket, setHoveredMarket] = React__default.default.useState(null);
1215
+ const renderLayoutItem = (position) => /* @__PURE__ */ jsxRuntime.jsxs(
1216
+ orderlyUi.Flex,
1217
+ {
1218
+ direction: "column",
1219
+ gapY: 2,
1220
+ onClick: () => {
1221
+ onLayoutChange(position);
1222
+ setOpen(false);
1223
+ },
1224
+ className: "oui-group",
1225
+ children: [
1226
+ /* @__PURE__ */ jsxRuntime.jsx(
1227
+ orderlyUi.Flex,
1228
+ {
1229
+ justify: position === "right" ? "end" : "start",
1230
+ className: orderlyUi.cn(
1231
+ "oui-w-[148px] oui-h-[100px]",
1232
+ "oui-bg-base-10 oui-rounded-[10px]",
1233
+ "oui-border-[4px] oui-border-base-5 group-hover:oui-border-primary-light",
1234
+ layout === position && "!oui-border-primary-light"
1235
+ ),
1236
+ children: /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.Box, { p: 1, children: /* @__PURE__ */ jsxRuntime.jsx(OrderEntryIcon, {}) })
1237
+ }
1238
+ ),
1239
+ /* @__PURE__ */ jsxRuntime.jsx(
1240
+ orderlyUi.Text,
1241
+ {
1242
+ size: "2xs",
1243
+ intensity: 54,
1244
+ className: orderlyUi.cn(
1245
+ "oui-text-base-contrast-54 group-hover:oui-text-base-contrast-80",
1246
+ layout === position && "oui-text-base-contrast-80"
1247
+ ),
1248
+ children: String(
1249
+ position === "right" ? t("trading.layout.advanced.right") : t("trading.layout.advanced.left")
1250
+ )
1251
+ }
1252
+ )
1253
+ ]
1254
+ }
1255
+ );
1256
+ const renderMarketItem = (position) => {
1257
+ const isSelected = markets === position;
1258
+ const isHovered = hoveredMarket === position;
1259
+ const getLabel = () => {
1260
+ switch (position) {
1261
+ case "left":
1262
+ return t("trading.layout.markets.left");
1263
+ case "top":
1264
+ return t("trading.layout.markets.top");
1265
+ case "bottom":
1266
+ return t("trading.layout.markets.bottom");
1267
+ case "hide":
1268
+ return t("trading.layout.markets.hide");
1269
+ default:
1270
+ return t("trading.layout.markets.left");
1271
+ }
1272
+ };
1273
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1274
+ orderlyUi.Flex,
1275
+ {
1276
+ direction: "column",
1277
+ gapY: 2,
1278
+ onClick: () => {
1279
+ onMarketChange(position);
1280
+ setOpen(false);
1281
+ },
1282
+ onMouseEnter: () => setHoveredMarket(position),
1283
+ onMouseLeave: () => setHoveredMarket(null),
1284
+ className: "oui-group",
1285
+ children: [
1286
+ /* @__PURE__ */ jsxRuntime.jsxs(orderlyUi.Flex, { justify: "center", className: "oui-w-[148px] oui-h-[100px]", children: [
1287
+ position === "left" && /* @__PURE__ */ jsxRuntime.jsx(MarketLeftIcon, { isSelected, isHovered }),
1288
+ position === "top" && /* @__PURE__ */ jsxRuntime.jsx(MarketTopIcon, { isSelected, isHovered }),
1289
+ position === "bottom" && /* @__PURE__ */ jsxRuntime.jsx(MarketBottomIcon, { isSelected, isHovered }),
1290
+ position === "hide" && /* @__PURE__ */ jsxRuntime.jsx(MarketHideIcon, { isSelected, isHovered })
1291
+ ] }),
1292
+ /* @__PURE__ */ jsxRuntime.jsx(
1293
+ orderlyUi.Text,
1294
+ {
1295
+ size: "2xs",
1296
+ intensity: 54,
1297
+ className: orderlyUi.cn(
1298
+ "oui-text-base-contrast-54 group-hover:oui-text-base-contrast-80",
1299
+ isSelected && "oui-text-base-contrast-80"
1300
+ ),
1301
+ children: String(getLabel())
1302
+ }
1303
+ )
1304
+ ]
1305
+ }
1306
+ );
1307
+ };
1308
+ const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1309
+ /* @__PURE__ */ jsxRuntime.jsxs(
1310
+ orderlyUi.Flex,
1311
+ {
1312
+ itemAlign: "center",
1313
+ justify: "between",
1314
+ mt: 3,
1315
+ className: "oui-mb-[10px] oui-min-w-[500px]",
1316
+ children: [
1317
+ /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.Text, { size: "base", intensity: 98, children: t("trading.layout") }),
1318
+ /* @__PURE__ */ jsxRuntime.jsx(
1319
+ orderlyUi.CloseIcon,
1320
+ {
1321
+ size: 16,
1322
+ className: "oui-cursor-pointer oui-text-base-contrast-80",
1323
+ opacity: 0.98,
1324
+ onClick: () => {
1325
+ setOpen(false);
1326
+ }
1327
+ }
1328
+ )
1329
+ ]
1330
+ }
1331
+ ),
1332
+ /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.Divider, {}),
1333
+ /* @__PURE__ */ jsxRuntime.jsxs(orderlyUi.Flex, { direction: "column", gapY: 2, mt: 5, itemAlign: "start", children: [
1334
+ /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.Text, { size: "xs", intensity: 98, children: String(t("trading.layout.advanced")) }),
1335
+ /* @__PURE__ */ jsxRuntime.jsxs(orderlyUi.Flex, { gapX: 6, children: [
1336
+ renderLayoutItem("left"),
1337
+ renderLayoutItem("right")
1338
+ ] })
1339
+ ] }),
1340
+ /* @__PURE__ */ jsxRuntime.jsxs(orderlyUi.Flex, { direction: "column", gapY: 2, mt: 5, itemAlign: "start", children: [
1341
+ /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.Text, { size: "xs", intensity: 98, children: String(t("trading.layout.markets")) }),
1342
+ /* @__PURE__ */ jsxRuntime.jsxs(orderlyUi.Flex, { gapX: 6, children: [
1343
+ renderMarketItem("left"),
1344
+ renderMarketItem("top"),
1345
+ renderMarketItem("bottom"),
1346
+ renderMarketItem("hide")
1347
+ ] })
1348
+ ] })
1349
+ ] });
1350
+ return /* @__PURE__ */ jsxRuntime.jsxs(orderlyUi.DropdownMenuRoot, { open, onOpenChange: setOpen, children: [
1351
+ /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1352
+ orderlyUi.Flex,
1353
+ {
1354
+ px: 3,
1355
+ className: orderlyUi.cn(
1356
+ "oui-rounded-md",
1357
+ "oui-h-[28px]",
1358
+ "oui-cursor-pointer oui-transition-all",
1359
+ "oui-bg-base-6 hover:oui-bg-base-4",
1360
+ "oui-text-base-contrast-54 hover:oui-text-base-contrast-80"
1361
+ ),
1362
+ gapX: 1,
1363
+ ml: 3,
1364
+ justify: "center",
1365
+ itemAlign: "center",
1366
+ children: /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.Text, { size: "2xs", weight: "semibold", children: t("trading.layout") })
1367
+ }
1368
+ ) }),
1369
+ /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.DropdownMenuPortal, { children: /* @__PURE__ */ jsxRuntime.jsx(
1370
+ orderlyUi.DropdownMenuContent,
1371
+ {
1372
+ onCloseAutoFocus: (e) => e.preventDefault(),
1373
+ onClick: (e) => e.stopPropagation(),
1374
+ align: "end",
1375
+ className: orderlyUi.cn("oui-bg-base-8 oui-p-5 oui-pt-0 oui-font-semibold"),
1376
+ children: content
1377
+ }
1378
+ ) })
1379
+ ] });
1380
+ };
1381
+ var SymbolBarLayoutSwitcher = ({
1382
+ layout = "right",
1383
+ marketLayout = "left",
1384
+ onLayoutChange,
1385
+ onMarketLayoutChange
1386
+ }) => {
1387
+ if (!onLayoutChange || !onMarketLayoutChange) {
1388
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {});
1389
+ }
1390
+ return /* @__PURE__ */ jsxRuntime.jsx(
1391
+ LayoutSwitchButton,
1392
+ {
1393
+ layout,
1394
+ markets: marketLayout,
1395
+ onLayoutChange,
1396
+ onMarketChange: onMarketLayoutChange
1397
+ }
1398
+ );
1399
+ };
1400
+ function getViewportBreakpointKey(viewportWidth, breakpoints = VIEWPORT_BREAKPOINTS) {
1401
+ for (const bp of BREAKPOINT_KEYS) {
1402
+ if (viewportWidth >= breakpoints[bp]) return bp;
1403
+ }
1404
+ return "xs";
1405
+ }
1406
+ function useViewportBreakpoint(options = {}) {
1407
+ const {
1408
+ breakpoints = VIEWPORT_BREAKPOINTS,
1409
+ fallbackWidth = typeof window !== "undefined" ? window.innerWidth : 1440
1410
+ } = options;
1411
+ const [width, setWidth] = React.useState(fallbackWidth);
1412
+ React.useEffect(() => {
1413
+ const element = document.documentElement;
1414
+ if (!element) return;
1415
+ setWidth(window.innerWidth);
1416
+ const resizeObserver = new ResizeObserver((entries) => {
1417
+ for (const entry of entries) {
1418
+ setWidth(entry.contentRect.width);
1419
+ }
1420
+ });
1421
+ resizeObserver.observe(element);
1422
+ return () => resizeObserver.disconnect();
1423
+ }, []);
1424
+ const bp = getViewportBreakpointKey(width, breakpoints);
1425
+ return bp;
1426
+ }
1427
+
1428
+ // src/hooks/useSplitLayout.ts
1429
+ var ORDER_ENTRY_MIN_WIDTH = 280;
1430
+ var ORDER_ENTRY_MAX_WIDTH = 360;
1431
+ var ORDERBOOK_MIN_WIDTH = 280;
1432
+ var ORDERBOOK_MAX_WIDTH = 732;
1433
+ var ORDERBOOK_MIN_HEIGHT = 464;
1434
+ var ORDERBOOK_MAX_HEIGHT = 728;
1435
+ var TRADINGVIEW_MIN_HEIGHT = 320;
1436
+ var TRADINGVIEW_MIN_WIDTH = 540;
1437
+ var DATA_LIST_MAX_HEIGHT = 800;
1438
+ var DATA_LIST_INITIAL_HEIGHT = 350;
1439
+ var SPACE = 8;
1440
+ var SYMBOL_INFO_BAR_HEIGHT = 54;
1441
+ var ORDERLY_ORDER_ENTRY_SIDE_MARKETS_LAYOUT = "orderly_order_entry_side_markets_layout";
1442
+ var ORDERLY_SIDE_MARKETS_MODE_KEY = "orderly_side_markets_mode";
1443
+ var ORDERLY_HORIZONTAL_MARKETS_LAYOUT = "orderly_horizontal_markets_layout";
1444
+ var ORDERLY_MAIN_SPLIT_SIZE = "orderly_main_split_size";
1445
+ var ORDERLY_DATA_LIST_SPLIT_SIZE = "orderly_datalist_split_size";
1446
+ var ORDERLY_ORDERBOOK_SPLIT_SIZE = "orderly_orderbook_split_size";
1447
+ var ORDERLY_DATA_LIST_SPLIT_HEIGHT_SM = "orderly_datalist_split_height_sm";
1448
+ var ORDERLY_ORDERBOOK_SPLIT_HEIGHT_SM = "orderly_orderbook_split_height_sm";
1449
+ var ORDERLY_ORDER_ENTRY_EXTRA_HEIGHT = "orderly_order_entry_extra_height";
1450
+ function buildLayoutTree(layout, marketLayout, max2XL) {
1451
+ if (max2XL) {
1452
+ return buildSMLayoutTree(layout, marketLayout);
1453
+ }
1454
+ return buildLGLayoutTree(layout, marketLayout);
1455
+ }
1456
+ function buildLGLayoutTree(layout, marketLayout) {
1457
+ const orderEntrySort = {
1458
+ type: "sort",
1459
+ orientation: "vertical",
1460
+ children: [
1461
+ { type: "panel", id: orderlyLayoutCore.TRADING_PANEL_IDS.MARGIN },
1462
+ { type: "panel", id: orderlyLayoutCore.TRADING_PANEL_IDS.ASSETS },
1463
+ { type: "panel", id: orderlyLayoutCore.TRADING_PANEL_IDS.ORDER_ENTRY }
1464
+ ]
1465
+ };
1466
+ const tvObSplit = {
1467
+ type: "split",
1468
+ orientation: "horizontal",
1469
+ children: [
1470
+ { type: "panel", id: orderlyLayoutCore.TRADING_PANEL_IDS.TRADING_VIEW },
1471
+ { type: "panel", id: orderlyLayoutCore.TRADING_PANEL_IDS.ORDERBOOK }
1472
+ ]
1473
+ };
1474
+ const mainCol = {
1475
+ type: "split",
1476
+ orientation: "vertical",
1477
+ children: [
1478
+ {
1479
+ type: "panel",
1480
+ id: orderlyLayoutCore.TRADING_PANEL_IDS.SYMBOL_INFO_BAR,
1481
+ size: "fixed",
1482
+ disabled: true
1483
+ },
1484
+ tvObSplit,
1485
+ { type: "panel", id: orderlyLayoutCore.TRADING_PANEL_IDS.DATA_LIST }
1486
+ ]
1487
+ };
1488
+ if (marketLayout === "top") {
1489
+ return {
1490
+ type: "split",
1491
+ orientation: "vertical",
1492
+ children: [
1493
+ {
1494
+ type: "panel",
1495
+ id: orderlyLayoutCore.TRADING_PANEL_IDS.HORIZONTAL_MARKETS,
1496
+ size: "fixed",
1497
+ disabled: true
1498
+ },
1499
+ layout === "left" ? {
1500
+ type: "split",
1501
+ orientation: "horizontal",
1502
+ children: [orderEntrySort, mainCol]
1503
+ } : {
1504
+ type: "split",
1505
+ orientation: "horizontal",
1506
+ children: [mainCol, orderEntrySort]
1507
+ }
1508
+ ]
1509
+ };
1510
+ }
1511
+ if (marketLayout === "bottom") {
1512
+ return layout === "left" ? {
1513
+ type: "split",
1514
+ orientation: "horizontal",
1515
+ children: [
1516
+ orderEntrySort,
1517
+ {
1518
+ type: "split",
1519
+ orientation: "vertical",
1520
+ children: [
1521
+ mainCol,
1522
+ {
1523
+ type: "panel",
1524
+ id: orderlyLayoutCore.TRADING_PANEL_IDS.HORIZONTAL_MARKETS,
1525
+ size: "fixed",
1526
+ disabled: true
1527
+ }
1528
+ ]
1529
+ }
1530
+ ]
1531
+ } : {
1532
+ type: "split",
1533
+ orientation: "horizontal",
1534
+ children: [
1535
+ {
1536
+ type: "split",
1537
+ orientation: "vertical",
1538
+ children: [
1539
+ mainCol,
1540
+ {
1541
+ type: "panel",
1542
+ id: orderlyLayoutCore.TRADING_PANEL_IDS.HORIZONTAL_MARKETS,
1543
+ size: "fixed",
1544
+ disabled: true
1545
+ }
1546
+ ]
1547
+ },
1548
+ orderEntrySort
1549
+ ]
1550
+ };
1551
+ }
1552
+ if (marketLayout === "hide") {
1553
+ return layout === "left" ? {
1554
+ type: "split",
1555
+ orientation: "horizontal",
1556
+ children: [orderEntrySort, mainCol]
1557
+ } : {
1558
+ type: "split",
1559
+ orientation: "horizontal",
1560
+ children: [mainCol, orderEntrySort]
1561
+ };
1562
+ }
1563
+ return {
1564
+ type: "split",
1565
+ orientation: "horizontal",
1566
+ children: [
1567
+ {
1568
+ type: "panel",
1569
+ id: orderlyLayoutCore.TRADING_PANEL_IDS.MARKETS,
1570
+ size: "fixed",
1571
+ disabled: true
1572
+ },
1573
+ layout === "left" ? {
1574
+ type: "split",
1575
+ orientation: "horizontal",
1576
+ children: [orderEntrySort, mainCol]
1577
+ } : {
1578
+ type: "split",
1579
+ orientation: "horizontal",
1580
+ children: [mainCol, orderEntrySort]
1581
+ }
1582
+ ]
1583
+ };
1584
+ }
1585
+ function buildSMLayoutTree(layout, marketLayout) {
1586
+ const orderEntrySort = {
1587
+ type: "sort",
1588
+ orientation: "vertical",
1589
+ children: [
1590
+ { type: "panel", id: orderlyLayoutCore.TRADING_PANEL_IDS.MARGIN },
1591
+ { type: "panel", id: orderlyLayoutCore.TRADING_PANEL_IDS.ASSETS },
1592
+ { type: "panel", id: orderlyLayoutCore.TRADING_PANEL_IDS.ORDER_ENTRY }
1593
+ ]
1594
+ };
1595
+ const tvObSplit = {
1596
+ type: "split",
1597
+ orientation: "vertical",
1598
+ children: [
1599
+ { type: "panel", id: orderlyLayoutCore.TRADING_PANEL_IDS.TRADING_VIEW },
1600
+ { type: "panel", id: orderlyLayoutCore.TRADING_PANEL_IDS.ORDERBOOK }
1601
+ ]
1602
+ };
1603
+ const mainCol = {
1604
+ type: "split",
1605
+ orientation: "vertical",
1606
+ children: [
1607
+ {
1608
+ type: "panel",
1609
+ id: orderlyLayoutCore.TRADING_PANEL_IDS.SYMBOL_INFO_BAR,
1610
+ size: "fixed",
1611
+ disabled: true
1612
+ },
1613
+ tvObSplit,
1614
+ { type: "panel", id: orderlyLayoutCore.TRADING_PANEL_IDS.DATA_LIST }
1615
+ ]
1616
+ };
1617
+ if (marketLayout === "top") {
1618
+ return {
1619
+ type: "split",
1620
+ orientation: "vertical",
1621
+ children: [
1622
+ {
1623
+ type: "panel",
1624
+ id: orderlyLayoutCore.TRADING_PANEL_IDS.HORIZONTAL_MARKETS,
1625
+ size: "fixed",
1626
+ disabled: true
1627
+ },
1628
+ {
1629
+ type: "split",
1630
+ orientation: "vertical",
1631
+ children: [orderEntrySort, mainCol]
1632
+ }
1633
+ ]
1634
+ };
1635
+ }
1636
+ if (marketLayout === "hide") {
1637
+ return {
1638
+ type: "split",
1639
+ orientation: "vertical",
1640
+ children: [orderEntrySort, mainCol]
1641
+ };
1642
+ }
1643
+ if (marketLayout === "bottom") {
1644
+ return {
1645
+ type: "split",
1646
+ orientation: "vertical",
1647
+ children: [
1648
+ mainCol,
1649
+ {
1650
+ type: "panel",
1651
+ id: orderlyLayoutCore.TRADING_PANEL_IDS.HORIZONTAL_MARKETS,
1652
+ size: "fixed",
1653
+ disabled: true
1654
+ }
1655
+ ]
1656
+ };
1657
+ }
1658
+ return {
1659
+ type: "split",
1660
+ orientation: "vertical",
1661
+ children: [
1662
+ {
1663
+ type: "split",
1664
+ orientation: "horizontal",
1665
+ children: [orderEntrySort, mainCol]
1666
+ }
1667
+ ]
1668
+ };
1669
+ }
1670
+ function useSplitLayout(options = {}) {
1671
+ const {
1672
+ initialLayout = "right",
1673
+ initialMarketLayout = "left",
1674
+ canTrade = true,
1675
+ isFirstTimeDeposit = false
1676
+ } = options;
1677
+ const max2XL = orderlyHooks.useMediaQuery("(max-width: 1279px)");
1678
+ const min3XL = orderlyHooks.useMediaQuery("(min-width: 1440px)");
1679
+ const max4XL = orderlyHooks.useMediaQuery("(max-width: 1680px)");
1680
+ const breakpoint = useViewportBreakpoint();
1681
+ const [layout, setLayout] = orderlyHooks.useLocalStorage(
1682
+ ORDERLY_ORDER_ENTRY_SIDE_MARKETS_LAYOUT,
1683
+ initialLayout
1684
+ );
1685
+ const [marketLayout, setMarketLayout] = orderlyHooks.useLocalStorage(
1686
+ ORDERLY_HORIZONTAL_MARKETS_LAYOUT,
1687
+ initialMarketLayout
1688
+ );
1689
+ const [panelSize, setPanelSize] = orderlyHooks.useLocalStorage(
1690
+ ORDERLY_SIDE_MARKETS_MODE_KEY,
1691
+ "large"
1692
+ );
1693
+ const marketsWidth = React.useMemo(() => {
1694
+ switch (panelSize) {
1695
+ case "small":
1696
+ return 0;
1697
+ case "middle":
1698
+ return 70;
1699
+ case "large":
1700
+ return 280;
1701
+ default:
1702
+ return 0;
1703
+ }
1704
+ }, [panelSize]);
1705
+ const horizontalDraggable = min3XL;
1706
+ const [mainSplitSize, setMainSplitSize] = orderlyHooks.useLocalStorage(
1707
+ ORDERLY_MAIN_SPLIT_SIZE,
1708
+ `${ORDER_ENTRY_MIN_WIDTH}px`
1709
+ );
1710
+ const [orderBookSplitSize, setOrderbookSplitSize] = orderlyHooks.useLocalStorage(
1711
+ ORDERLY_ORDERBOOK_SPLIT_SIZE,
1712
+ "280px"
1713
+ );
1714
+ const [dataListSplitSize, setDataListSplitSize] = orderlyHooks.useLocalStorage(
1715
+ ORDERLY_DATA_LIST_SPLIT_SIZE,
1716
+ `${DATA_LIST_INITIAL_HEIGHT}px`
1717
+ );
1718
+ const [dataListSplitHeightSM, setDataListSplitHeightSM] = orderlyHooks.useLocalStorage(
1719
+ ORDERLY_DATA_LIST_SPLIT_HEIGHT_SM,
1720
+ "350px"
1721
+ );
1722
+ const [orderBookSplitHeightSM, setOrderbookSplitHeightSM] = orderlyHooks.useLocalStorage(
1723
+ ORDERLY_ORDERBOOK_SPLIT_HEIGHT_SM,
1724
+ "280px"
1725
+ );
1726
+ const [extraHeight, setExtraHeight] = orderlyHooks.useLocalStorage(
1727
+ ORDERLY_ORDER_ENTRY_EXTRA_HEIGHT,
1728
+ 0
1729
+ );
1730
+ React.useCallback(
1731
+ (preSize, nextSize, boxHeight) => {
1732
+ if (!boxHeight) return;
1733
+ const splitTradingviewHeight = boxHeight * preSize / 100;
1734
+ const splitOrderbookHeight = boxHeight * nextSize / 100;
1735
+ const tradingviewHeight = Math.min(
1736
+ Math.max(splitTradingviewHeight, TRADINGVIEW_MIN_HEIGHT),
1737
+ max2XL ? 1200 : 600
1738
+ );
1739
+ const orderbookHeight = Math.min(
1740
+ Math.max(splitOrderbookHeight, ORDERBOOK_MIN_HEIGHT),
1741
+ ORDERBOOK_MAX_HEIGHT
1742
+ );
1743
+ if (splitOrderbookHeight >= orderbookHeight) {
1744
+ const offset = splitOrderbookHeight - orderbookHeight;
1745
+ setExtraHeight(Math.max(0, extraHeight - offset));
1746
+ } else if (tradingviewHeight + orderbookHeight < (max2XL ? 1200 : 600) + ORDERBOOK_MAX_HEIGHT) {
1747
+ const height = tradingviewHeight + orderbookHeight + SPACE + SYMBOL_INFO_BAR_HEIGHT;
1748
+ const offset = Math.max(0, height - 0);
1749
+ setExtraHeight(extraHeight + offset);
1750
+ }
1751
+ },
1752
+ [max2XL, extraHeight, setExtraHeight]
1753
+ );
1754
+ const tradingviewMaxHeight = max2XL ? 1200 : 600;
1755
+ const dataListHeight = canTrade ? 379 : 277;
1756
+ const memoizedPanelSize = React.useMemo(() => {
1757
+ const normalized = panelSize === "large" ? "large" : "middle";
1758
+ return horizontalDraggable ? normalized : "middle";
1759
+ }, [horizontalDraggable, panelSize]);
1760
+ const layoutTree = React.useMemo(
1761
+ () => buildLayoutTree(layout, marketLayout, max2XL),
1762
+ [layout, marketLayout, max2XL]
1763
+ );
1764
+ return {
1765
+ // Layout position
1766
+ layout,
1767
+ setLayout,
1768
+ marketLayout,
1769
+ setMarketLayout,
1770
+ // Breakpoint
1771
+ breakpoint,
1772
+ max2XL,
1773
+ min3XL,
1774
+ max4XL,
1775
+ horizontalDraggable,
1776
+ // Markets panel
1777
+ panelSize: memoizedPanelSize,
1778
+ setPanelSize: (size) => setPanelSize(size),
1779
+ marketsWidth,
1780
+ // Split sizes
1781
+ mainSplitSize,
1782
+ setMainSplitSize,
1783
+ orderBookSplitSize,
1784
+ setOrderbookSplitSize,
1785
+ dataListSplitSize,
1786
+ setDataListSplitSize,
1787
+ dataListSplitHeightSM,
1788
+ setDataListSplitHeightSM,
1789
+ orderBookSplitHeightSM,
1790
+ setOrderbookSplitHeightSM,
1791
+ // Extra height
1792
+ extraHeight,
1793
+ setExtraHeight,
1794
+ // Data list
1795
+ dataListHeight,
1796
+ // Trading view
1797
+ tradingviewMaxHeight,
1798
+ // Layout tree (for compat)
1799
+ layoutTree,
1800
+ // Constants
1801
+ symbolInfoBarHeight: SYMBOL_INFO_BAR_HEIGHT,
1802
+ space: SPACE,
1803
+ orderbookMinWidth: ORDERBOOK_MIN_WIDTH,
1804
+ orderbookMaxWidth: ORDERBOOK_MAX_WIDTH,
1805
+ orderbookMinHeight: ORDERBOOK_MIN_HEIGHT,
1806
+ orderbookMaxHeight: ORDERBOOK_MAX_HEIGHT,
1807
+ tradingviewMinHeight: TRADINGVIEW_MIN_HEIGHT,
1808
+ orderEntryMinWidth: ORDER_ENTRY_MIN_WIDTH,
1809
+ orderEntryMaxWidth: ORDER_ENTRY_MAX_WIDTH
1810
+ };
1811
+ }
1812
+ var IndicatorIcon = (props) => /* @__PURE__ */ jsxRuntime.jsxs(
1813
+ "svg",
1814
+ {
1815
+ width: "10",
1816
+ height: "16",
1817
+ viewBox: "0 0 10 16",
1818
+ fill: "currentColor",
1819
+ xmlns: "http://www.w3.org/2000/svg",
1820
+ ...props,
1821
+ children: [
1822
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "2", y: "2", width: "6", height: "2", rx: "1" }),
1823
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "2", y: "7", width: "6", height: "2", rx: "1" }),
1824
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "2", y: "12", width: "6", height: "2", rx: "1" })
1825
+ ]
1826
+ }
1827
+ );
1828
+ var TradingSortablePanel = (props) => {
1829
+ const { showIndicator, dragOverlay } = props;
1830
+ const nodeRef = React.useRef(null);
1831
+ const [dimensions, setDimensions] = React__default.default.useState(null);
1832
+ const {
1833
+ setNodeRef,
1834
+ attributes,
1835
+ listeners,
1836
+ transform,
1837
+ transition,
1838
+ isDragging,
1839
+ setActivatorNodeRef
1840
+ } = sortable.useSortable({ id: props.id });
1841
+ React.useEffect(() => {
1842
+ if (isDragging && nodeRef.current && !dimensions) {
1843
+ const rect = nodeRef.current.getBoundingClientRect();
1844
+ setDimensions({ width: rect.width, height: rect.height });
1845
+ } else if (!isDragging && dimensions) {
1846
+ setDimensions(null);
1847
+ }
1848
+ }, [isDragging, dimensions]);
1849
+ const combinedRef = (node) => {
1850
+ setNodeRef(node);
1851
+ nodeRef.current = node;
1852
+ };
1853
+ const style = {
1854
+ transform: utilities.CSS.Transform.toString(transform),
1855
+ transition
1856
+ };
1857
+ if (isDragging && dimensions && !dragOverlay) {
1858
+ return /* @__PURE__ */ jsxRuntime.jsx(
1859
+ orderlyUi.Box,
1860
+ {
1861
+ intensity: 900,
1862
+ r: "2xl",
1863
+ p: 3,
1864
+ className: "oui-relative",
1865
+ style: {
1866
+ ...style,
1867
+ width: dimensions.width,
1868
+ height: dimensions.height,
1869
+ minWidth: dimensions.width,
1870
+ minHeight: dimensions.height,
1871
+ maxWidth: dimensions.width,
1872
+ maxHeight: dimensions.height,
1873
+ border: "1px solid rgb(var(--oui-color-primary))",
1874
+ backgroundImage: `repeating-linear-gradient(135deg, rgb(var(--oui-color-base-6)) 0px, rgb(var(--oui-color-base-6)) 4px, transparent 4px, transparent 8px)`
1875
+ }
1876
+ }
1877
+ );
1878
+ }
1879
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1880
+ orderlyUi.Box,
1881
+ {
1882
+ intensity: 900,
1883
+ r: "2xl",
1884
+ p: 3,
1885
+ width: "100%",
1886
+ className: orderlyUi.cn("oui-relative", props.className),
1887
+ ref: combinedRef,
1888
+ style,
1889
+ children: [
1890
+ /* @__PURE__ */ jsxRuntime.jsx(
1891
+ "div",
1892
+ {
1893
+ className: orderlyUi.cn(
1894
+ "inner-content oui-transition-transform",
1895
+ dragOverlay && "oui-scale-95"
1896
+ ),
1897
+ children: props.children
1898
+ }
1899
+ ),
1900
+ showIndicator && /* @__PURE__ */ jsxRuntime.jsx(
1901
+ "button",
1902
+ {
1903
+ ...attributes,
1904
+ ...listeners,
1905
+ className: "oui-absolute oui-right-0 oui-top-4 oui-cursor-move oui-py-1",
1906
+ style: { touchAction: "none" },
1907
+ ref: setActivatorNodeRef,
1908
+ children: /* @__PURE__ */ jsxRuntime.jsx(IndicatorIcon, { className: "oui-text-base-contrast-20 hover:oui-text-base-contrast-80" })
1909
+ }
1910
+ )
1911
+ ]
1912
+ }
1913
+ );
1914
+ };
1915
+ var SplitLineBar = (props) => {
1916
+ const { onMouseDown, mode = "horizontal", ...rest } = props;
1917
+ const disable = React.useMemo(
1918
+ () => props.className?.split(" ").includes("disable"),
1919
+ [props.className]
1920
+ );
1921
+ const filteredCls = React.useMemo(
1922
+ () => props.className?.split(" ").filter((cls) => cls !== "disable"),
1923
+ [props.className]
1924
+ );
1925
+ return /* @__PURE__ */ jsxRuntime.jsx(
1926
+ "div",
1927
+ {
1928
+ ...rest,
1929
+ className: orderlyUi.cn(
1930
+ filteredCls,
1931
+ "!oui-transition-none",
1932
+ "!oui-shadow-none !oui-bg-transparent",
1933
+ "hover:!oui-bg-primary-light hover:!oui-shadow-[0px_0px_4px_0px] hover:!oui-shadow-primary-light/80",
1934
+ "active:!oui-bg-primary-light active:!oui-shadow-[0px_0px_4px_0px] active:!oui-shadow-primary-light/80",
1935
+ "focus:!oui-bg-primary-light focus:!oui-shadow-[0px_0px_4px_0px] focus:!oui-shadow-primary-light/80",
1936
+ mode === "horizontal" ? "!oui-w-[2px] !oui-min-w-[2px] !oui-mx-[3px]" : "!oui-h-[2px] !oui-min-h-[2px] !oui-my-[3px]",
1937
+ disable && "oui-pointer-events-none"
1938
+ ),
1939
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1940
+ "div",
1941
+ {
1942
+ onMouseDown,
1943
+ className: orderlyUi.cn(
1944
+ "!oui-transition-none",
1945
+ mode === "horizontal" ? "after:!oui-w-[2px]" : "after:!oui-h-[2px]",
1946
+ "after:!oui-bg-transparent after:!oui-shadow-transparent"
1947
+ )
1948
+ }
1949
+ )
1950
+ }
1951
+ );
1952
+ };
1953
+ var TradingSplitLayout = React.forwardRef(
1954
+ (props, ref) => {
1955
+ const { onSizeChange, ...rest } = props;
1956
+ return /* @__PURE__ */ jsxRuntime.jsx(
1957
+ Split__default.default,
1958
+ {
1959
+ ref,
1960
+ ...rest,
1961
+ lineBar: true,
1962
+ renderBar: (barProps) => /* @__PURE__ */ jsxRuntime.jsx(SplitLineBar, { ...barProps, mode: props.mode }),
1963
+ onDragEnd: (_, width) => onSizeChange?.(`${width}`)
1964
+ }
1965
+ );
1966
+ }
1967
+ );
1968
+ TradingSplitLayout.displayName = "TradingSplitLayout";
1969
+ var SCROLLBAR_WIDTH = 6;
1970
+ var TOP_BAR_HEIGHT = 48;
1971
+ var BOTTOM_BAR_HEIGHT = 29;
1972
+ var ORDER_ENTRY_SORT_KEY = "orderly_order_entry_sortable_items";
1973
+ var DEFAULT_SORTABLE_ITEMS = [
1974
+ orderlyLayoutCore.TRADING_PANEL_IDS.MARGIN,
1975
+ orderlyLayoutCore.TRADING_PANEL_IDS.ASSETS,
1976
+ orderlyLayoutCore.TRADING_PANEL_IDS.ORDER_ENTRY
1977
+ ];
1978
+ var dropAnimationConfig = {
1979
+ keyframes({
1980
+ transform
1981
+ }) {
1982
+ return [
1983
+ {
1984
+ transform: utilities.CSS.Transform.toString({
1985
+ ...transform.initial,
1986
+ scaleX: 1.05,
1987
+ scaleY: 1.05
1988
+ })
1989
+ },
1990
+ {
1991
+ transform: utilities.CSS.Transform.toString({
1992
+ ...transform.final,
1993
+ scaleX: 1,
1994
+ scaleY: 1
1995
+ })
1996
+ }
1997
+ ];
1998
+ },
1999
+ sideEffects: ({
2000
+ active,
2001
+ dragOverlay
2002
+ }) => {
2003
+ active.node.style.opacity = "0";
2004
+ const inner = dragOverlay.node.querySelector(".inner-content");
2005
+ if (inner) inner.classList.add("oui-animate-shake");
2006
+ return () => {
2007
+ active.node.style.opacity = "";
2008
+ };
2009
+ }
2010
+ };
2011
+ function SplitTradingLayout(props) {
2012
+ const { panels, className } = props;
2013
+ const {
2014
+ layout,
2015
+ marketLayout,
2016
+ max2XL,
2017
+ max4XL,
2018
+ horizontalDraggable,
2019
+ panelSize,
2020
+ setPanelSize,
2021
+ marketsWidth,
2022
+ mainSplitSize,
2023
+ setMainSplitSize,
2024
+ orderBookSplitSize,
2025
+ setOrderbookSplitSize,
2026
+ dataListSplitSize,
2027
+ setDataListSplitSize,
2028
+ dataListSplitHeightSM,
2029
+ setDataListSplitHeightSM,
2030
+ orderBookSplitHeightSM,
2031
+ setOrderbookSplitHeightSM,
2032
+ tradingviewMaxHeight: tradindviewMaxHeight,
2033
+ extraHeight,
2034
+ setExtraHeight,
2035
+ dataListHeight: dataListMinHeight,
2036
+ symbolInfoBarHeight
2037
+ } = useSplitLayout();
2038
+ const [tradingViewFullScreen] = orderlyHooks.useLocalStorage(
2039
+ orderlyTypes.TradingviewFullscreenKey,
2040
+ false
2041
+ );
2042
+ const [animating, setAnimating] = React.useState(false);
2043
+ const [sortableItems, setSortableItems] = orderlyHooks.useLocalStorage(
2044
+ ORDER_ENTRY_SORT_KEY,
2045
+ DEFAULT_SORTABLE_ITEMS
2046
+ );
2047
+ const tradingviewAndOrderbookSplitRef = React.useRef(null);
2048
+ const max2XLSplitRef = React.useRef(null);
2049
+ const orderEntryViewRef = React.useRef(null);
2050
+ const [orderEntryHeight, setOrderEntryHeight] = React.useState(0);
2051
+ React.useEffect(() => {
2052
+ const el = orderEntryViewRef.current;
2053
+ if (!el) return;
2054
+ const observer = new ResizeObserver((entries) => {
2055
+ const entry = entries[0];
2056
+ if (entry) setOrderEntryHeight(entry.contentRect.height);
2057
+ });
2058
+ observer.observe(el);
2059
+ return () => observer.disconnect();
2060
+ }, []);
2061
+ const onDataListSplitHeightDragging = React.useCallback(() => {
2062
+ setExtraHeight(0);
2063
+ }, [setExtraHeight]);
2064
+ const onTradingviewAndOrderbookDragging = React.useCallback(() => {
2065
+ }, []);
2066
+ const [activeId, setActiveId] = React.useState(null);
2067
+ const showPositionIcon = true;
2068
+ const sensors = core.useSensors(
2069
+ core.useSensor(core.PointerSensor, { activationConstraint: { distance: 5 } }),
2070
+ core.useSensor(core.KeyboardSensor, {
2071
+ coordinateGetter: sortable.sortableKeyboardCoordinates
2072
+ })
2073
+ );
2074
+ function handleDragStart(event) {
2075
+ setActiveId(event.active.id);
2076
+ }
2077
+ function handleDragEnd(event) {
2078
+ const { active, over } = event;
2079
+ if (active.id !== over?.id && over) {
2080
+ const oldIndex = sortableItems.indexOf(active.id);
2081
+ const newIndex = sortableItems.indexOf(over.id);
2082
+ if (oldIndex !== -1 && newIndex !== -1) {
2083
+ setSortableItems(sortable.arrayMove(sortableItems, oldIndex, newIndex));
2084
+ }
2085
+ }
2086
+ setActiveId(null);
2087
+ }
2088
+ const onMainSplitSizeChange = (width) => layout === "left" ? setMainSplitSize(`${100 - Math.min(Number(width), 100)}`) : setMainSplitSize(width);
2089
+ const minScreenHeight = React.useMemo(() => {
2090
+ return tradingViewFullScreen ? 0 : symbolInfoBarHeight + ORDERBOOK_MAX_HEIGHT + DATA_LIST_INITIAL_HEIGHT + SPACE * 4;
2091
+ }, [tradingViewFullScreen, symbolInfoBarHeight]);
2092
+ const minScreenHeightSM = TOP_BAR_HEIGHT + BOTTOM_BAR_HEIGHT + symbolInfoBarHeight + TRADINGVIEW_MIN_HEIGHT + ORDERBOOK_MIN_HEIGHT + dataListMinHeight + SPACE * 4;
2093
+ const containerPaddingX = React.useMemo(() => max4XL ? 12 : 8, [max4XL]);
2094
+ const getPanel = (id) => panels.get(id)?.node ?? null;
2095
+ const horizontalMarketsView = getPanel(orderlyLayoutCore.TRADING_PANEL_IDS.HORIZONTAL_MARKETS);
2096
+ const stickyHorizontalMarketsView = /* @__PURE__ */ jsxRuntime.jsx(
2097
+ orderlyUi.Box,
2098
+ {
2099
+ className: orderlyUi.cn(
2100
+ "oui-trading-markets-container",
2101
+ "oui-bg-base-10",
2102
+ "oui-sticky oui-z-30 oui-mb-[-8px] oui-py-2",
2103
+ !max4XL && "oui-mt-[-8px]"
2104
+ ),
2105
+ style: {
2106
+ bottom: 0,
2107
+ minWidth: (max4XL ? 1024 : 1440) - SCROLLBAR_WIDTH - containerPaddingX * 2
2108
+ },
2109
+ children: horizontalMarketsView
2110
+ }
2111
+ );
2112
+ const marketsWidget = getPanel(orderlyLayoutCore.TRADING_PANEL_IDS.MARKETS);
2113
+ const marketsView = /* @__PURE__ */ jsxRuntime.jsx(
2114
+ orderlyUi.Box,
2115
+ {
2116
+ intensity: 900,
2117
+ pt: 3,
2118
+ r: "2xl",
2119
+ height: "100%",
2120
+ width: marketsWidth,
2121
+ style: { minWidth: marketsWidth },
2122
+ className: "oui-trading-markets-container oui-transition-all oui-duration-150",
2123
+ onTransitionEnd: () => setAnimating(false),
2124
+ children: !animating && marketLayout === "left" && marketsWidget
2125
+ }
2126
+ );
2127
+ const symbolInfoBarView = /* @__PURE__ */ jsxRuntime.jsx(
2128
+ orderlyUi.Box,
2129
+ {
2130
+ className: "oui-trading-symbolInfoBar-container",
2131
+ intensity: 900,
2132
+ r: "2xl",
2133
+ px: 3,
2134
+ width: "100%",
2135
+ style: { minHeight: symbolInfoBarHeight, height: symbolInfoBarHeight },
2136
+ children: getPanel(orderlyLayoutCore.TRADING_PANEL_IDS.SYMBOL_INFO_BAR)
2137
+ }
2138
+ );
2139
+ const tradingviewWidget = getPanel(orderlyLayoutCore.TRADING_PANEL_IDS.TRADING_VIEW);
2140
+ const tradingView = /* @__PURE__ */ jsxRuntime.jsx(
2141
+ orderlyUi.Box,
2142
+ {
2143
+ width: "100%",
2144
+ height: "100%",
2145
+ intensity: 900,
2146
+ r: "2xl",
2147
+ style: { flex: 1, minWidth: TRADINGVIEW_MIN_WIDTH },
2148
+ className: "oui-trading-tradingview-container oui-overflow-hidden",
2149
+ children: tradingviewWidget
2150
+ }
2151
+ );
2152
+ const orderbookView = /* @__PURE__ */ jsxRuntime.jsx(
2153
+ orderlyUi.Box,
2154
+ {
2155
+ r: "2xl",
2156
+ height: "100%",
2157
+ style: {
2158
+ minWidth: ORDERBOOK_MIN_WIDTH,
2159
+ maxWidth: horizontalDraggable ? ORDERBOOK_MAX_WIDTH : ORDERBOOK_MIN_WIDTH,
2160
+ width: orderBookSplitSize
2161
+ },
2162
+ className: "oui-trading-orderBook-container oui-overflow-hidden",
2163
+ children: getPanel(orderlyLayoutCore.TRADING_PANEL_IDS.ORDERBOOK)
2164
+ }
2165
+ );
2166
+ const dataListView = /* @__PURE__ */ jsxRuntime.jsx(
2167
+ orderlyUi.Box,
2168
+ {
2169
+ intensity: 900,
2170
+ r: "2xl",
2171
+ p: 2,
2172
+ style: {
2173
+ height: dataListSplitSize,
2174
+ minHeight: DATA_LIST_INITIAL_HEIGHT
2175
+ },
2176
+ className: "oui-trading-dataList-container oui-overflow-hidden",
2177
+ children: getPanel(orderlyLayoutCore.TRADING_PANEL_IDS.DATA_LIST)
2178
+ }
2179
+ );
2180
+ const orderEntryView = /* @__PURE__ */ jsxRuntime.jsx(
2181
+ orderlyUi.Flex,
2182
+ {
2183
+ className: "oui-trading-orderEntry-container",
2184
+ gapY: 2,
2185
+ direction: "column",
2186
+ height: "100%",
2187
+ style: {
2188
+ minWidth: ORDER_ENTRY_MIN_WIDTH,
2189
+ maxWidth: horizontalDraggable ? ORDER_ENTRY_MAX_WIDTH : ORDER_ENTRY_MIN_WIDTH,
2190
+ width: mainSplitSize
2191
+ },
2192
+ children: sortableItems.map((id) => /* @__PURE__ */ jsxRuntime.jsx(
2193
+ TradingSortablePanel,
2194
+ {
2195
+ id,
2196
+ showIndicator: showPositionIcon,
2197
+ className: orderlyUi.cn(
2198
+ id === orderlyLayoutCore.TRADING_PANEL_IDS.MARGIN && "oui-trading-riskRate-container",
2199
+ id === orderlyLayoutCore.TRADING_PANEL_IDS.ASSETS && "oui-trading-assetsView-container oui-border oui-border-line-12",
2200
+ id === orderlyLayoutCore.TRADING_PANEL_IDS.ORDER_ENTRY && "oui-trading-orderEntry-container",
2201
+ // Support legacy short-name keys
2202
+ id === "margin" && "oui-trading-riskRate-container",
2203
+ id === "assets" && "oui-trading-assetsView-container oui-border oui-border-line-12",
2204
+ id === "orderEntry" && "oui-trading-orderEntry-container"
2205
+ ),
2206
+ children: getPanel(id)
2207
+ },
2208
+ id
2209
+ ))
2210
+ }
2211
+ );
2212
+ const renderTradingView = () => {
2213
+ if (max4XL && layout === "right") {
2214
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2215
+ orderlyUi.Flex,
2216
+ {
2217
+ gap: 2,
2218
+ className: "oui-flex-1 oui-overflow-hidden",
2219
+ style: { minWidth: marketsWidth + TRADINGVIEW_MIN_WIDTH + SPACE },
2220
+ children: [
2221
+ marketLayout === "left" && marketsView,
2222
+ tradingView
2223
+ ]
2224
+ }
2225
+ );
2226
+ }
2227
+ return tradingView;
2228
+ };
2229
+ const tradingViewAndOrderbookView = /* @__PURE__ */ jsxRuntime.jsxs(
2230
+ TradingSplitLayout,
2231
+ {
2232
+ style: { flex: 1, minHeight: ORDERBOOK_MIN_HEIGHT },
2233
+ onSizeChange: setOrderbookSplitSize,
2234
+ disable: !horizontalDraggable,
2235
+ children: [
2236
+ renderTradingView(),
2237
+ orderbookView
2238
+ ]
2239
+ }
2240
+ );
2241
+ const renderTradingViewAndOrderbookView = () => {
2242
+ if (max4XL && layout === "left") {
2243
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2244
+ orderlyUi.Flex,
2245
+ {
2246
+ gapX: 2,
2247
+ style: { minHeight: ORDERBOOK_MIN_HEIGHT },
2248
+ height: "100%",
2249
+ children: [
2250
+ tradingViewAndOrderbookView,
2251
+ marketLayout === "left" && marketsView
2252
+ ]
2253
+ }
2254
+ );
2255
+ }
2256
+ return tradingViewAndOrderbookView;
2257
+ };
2258
+ const mainView = /* @__PURE__ */ jsxRuntime.jsxs(
2259
+ orderlyUi.Flex,
2260
+ {
2261
+ direction: "column",
2262
+ className: "oui-flex-1 oui-overflow-hidden",
2263
+ gap: 2,
2264
+ style: {
2265
+ minWidth: max4XL ? marketsWidth + TRADINGVIEW_MIN_WIDTH + ORDERBOOK_MIN_WIDTH + SPACE * 2 : TRADINGVIEW_MIN_WIDTH + ORDERBOOK_MIN_WIDTH + SPACE
2266
+ },
2267
+ children: [
2268
+ symbolInfoBarView,
2269
+ /* @__PURE__ */ jsxRuntime.jsxs(
2270
+ TradingSplitLayout,
2271
+ {
2272
+ style: {
2273
+ maxHeight: `calc(100% - ${symbolInfoBarHeight}px - ${SPACE}px)`
2274
+ },
2275
+ className: "oui-w-full",
2276
+ mode: "vertical",
2277
+ onSizeChange: setDataListSplitSize,
2278
+ children: [
2279
+ renderTradingViewAndOrderbookView(),
2280
+ dataListView
2281
+ ]
2282
+ }
2283
+ )
2284
+ ]
2285
+ }
2286
+ );
2287
+ const dragOverlayContent = activeId ? /* @__PURE__ */ jsxRuntime.jsx(
2288
+ TradingSortablePanel,
2289
+ {
2290
+ id: activeId,
2291
+ showIndicator: showPositionIcon,
2292
+ dragOverlay: true,
2293
+ className: "oui-shadow-lg oui-shadow-base-9",
2294
+ children: getPanel(activeId)
2295
+ }
2296
+ ) : null;
2297
+ if (max2XL) {
2298
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2299
+ core.DndContext,
2300
+ {
2301
+ sensors,
2302
+ collisionDetection: core.closestCenter,
2303
+ onDragStart: handleDragStart,
2304
+ onDragEnd: handleDragEnd,
2305
+ modifiers: [modifiers.restrictToVerticalAxis],
2306
+ children: [
2307
+ /* @__PURE__ */ jsxRuntime.jsx(
2308
+ sortable.SortableContext,
2309
+ {
2310
+ items: sortableItems,
2311
+ strategy: sortable.verticalListSortingStrategy,
2312
+ children: /* @__PURE__ */ jsxRuntime.jsxs(orderlyUi.Box, { height: "100%", children: [
2313
+ marketLayout === "top" && /* @__PURE__ */ jsxRuntime.jsx(
2314
+ orderlyUi.Box,
2315
+ {
2316
+ className: orderlyUi.cn(
2317
+ "oui-trading-markets-container oui-mt-2 oui-max-h-8 oui-px-3",
2318
+ className
2319
+ ),
2320
+ children: horizontalMarketsView
2321
+ }
2322
+ ),
2323
+ /* @__PURE__ */ jsxRuntime.jsxs(
2324
+ TradingSplitLayout,
2325
+ {
2326
+ ref: max2XLSplitRef,
2327
+ style: {
2328
+ minHeight: minScreenHeightSM,
2329
+ minWidth: 1024 - SCROLLBAR_WIDTH
2330
+ },
2331
+ className: orderlyUi.cn(
2332
+ "oui-flex oui-flex-1",
2333
+ "oui-size-full oui-min-w-[1018px]",
2334
+ "oui-px-3 oui-py-2",
2335
+ className
2336
+ ),
2337
+ onSizeChange: setDataListSplitHeightSM,
2338
+ onDragging: onDataListSplitHeightDragging,
2339
+ mode: "vertical",
2340
+ children: [
2341
+ /* @__PURE__ */ jsxRuntime.jsxs(
2342
+ orderlyUi.Flex,
2343
+ {
2344
+ gapX: 2,
2345
+ itemAlign: "stretch",
2346
+ className: orderlyUi.cn(
2347
+ "oui-flex-1",
2348
+ layout === "left" && "oui-flex-row-reverse"
2349
+ ),
2350
+ style: {
2351
+ minHeight: Math.max(
2352
+ symbolInfoBarHeight + TRADINGVIEW_MIN_HEIGHT + ORDERBOOK_MIN_HEIGHT + SPACE * 2,
2353
+ orderEntryHeight
2354
+ ),
2355
+ maxHeight: symbolInfoBarHeight + tradindviewMaxHeight + ORDERBOOK_MAX_HEIGHT + SPACE * 2
2356
+ },
2357
+ children: [
2358
+ /* @__PURE__ */ jsxRuntime.jsxs(
2359
+ orderlyUi.Flex,
2360
+ {
2361
+ height: "100%",
2362
+ className: "oui-w-[calc(100%_-_280px_-_12px)] oui-flex-1",
2363
+ direction: "column",
2364
+ gapY: 2,
2365
+ children: [
2366
+ symbolInfoBarView,
2367
+ /* @__PURE__ */ jsxRuntime.jsxs(
2368
+ orderlyUi.Flex,
2369
+ {
2370
+ width: "100%",
2371
+ height: "100%",
2372
+ gapX: 2,
2373
+ itemAlign: "stretch",
2374
+ style: {
2375
+ minHeight: TRADINGVIEW_MIN_HEIGHT + ORDERBOOK_MIN_HEIGHT + SPACE,
2376
+ maxHeight: tradindviewMaxHeight + ORDERBOOK_MAX_HEIGHT + SPACE
2377
+ },
2378
+ className: orderlyUi.cn(
2379
+ "oui-flex-1",
2380
+ layout === "left" && "oui-flex-row-reverse"
2381
+ ),
2382
+ children: [
2383
+ marketLayout === "left" && /* @__PURE__ */ jsxRuntime.jsx(
2384
+ orderlyUi.Box,
2385
+ {
2386
+ intensity: 900,
2387
+ pt: 3,
2388
+ r: "2xl",
2389
+ width: marketsWidth,
2390
+ style: {
2391
+ minHeight: TRADINGVIEW_MIN_HEIGHT + ORDERBOOK_MIN_HEIGHT + SPACE,
2392
+ maxHeight: tradindviewMaxHeight + ORDERBOOK_MAX_HEIGHT + SPACE
2393
+ },
2394
+ children: marketsWidget
2395
+ }
2396
+ ),
2397
+ /* @__PURE__ */ jsxRuntime.jsxs(
2398
+ TradingSplitLayout,
2399
+ {
2400
+ ref: tradingviewAndOrderbookSplitRef,
2401
+ mode: "vertical",
2402
+ style: { width: `calc(100% - ${marketsWidth}px)` },
2403
+ className: "oui-flex-1",
2404
+ onSizeChange: setOrderbookSplitHeightSM,
2405
+ onDragging: onTradingviewAndOrderbookDragging,
2406
+ children: [
2407
+ /* @__PURE__ */ jsxRuntime.jsx(
2408
+ orderlyUi.Box,
2409
+ {
2410
+ width: "100%",
2411
+ intensity: 900,
2412
+ r: "2xl",
2413
+ style: {
2414
+ minHeight: TRADINGVIEW_MIN_HEIGHT,
2415
+ maxHeight: tradindviewMaxHeight,
2416
+ height: 1200
2417
+ },
2418
+ children: tradingviewWidget
2419
+ }
2420
+ ),
2421
+ /* @__PURE__ */ jsxRuntime.jsx(
2422
+ orderlyUi.Box,
2423
+ {
2424
+ r: "2xl",
2425
+ height: "100%",
2426
+ width: "100%",
2427
+ style: {
2428
+ minHeight: ORDERBOOK_MIN_HEIGHT,
2429
+ maxHeight: ORDERBOOK_MAX_HEIGHT,
2430
+ height: orderBookSplitHeightSM
2431
+ },
2432
+ className: "oui-flex-1",
2433
+ children: getPanel(orderlyLayoutCore.TRADING_PANEL_IDS.ORDERBOOK)
2434
+ }
2435
+ )
2436
+ ]
2437
+ }
2438
+ )
2439
+ ]
2440
+ }
2441
+ )
2442
+ ]
2443
+ }
2444
+ ),
2445
+ /* @__PURE__ */ jsxRuntime.jsxs(
2446
+ orderlyUi.Flex,
2447
+ {
2448
+ ref: orderEntryViewRef,
2449
+ id: "orderEntryView",
2450
+ gapY: 3,
2451
+ direction: "column",
2452
+ className: "oui-relative",
2453
+ style: {
2454
+ width: ORDER_ENTRY_MIN_WIDTH,
2455
+ height: "max-content"
2456
+ },
2457
+ children: [
2458
+ /* @__PURE__ */ jsxRuntime.jsx(
2459
+ orderlyUi.Flex,
2460
+ {
2461
+ gapY: 2,
2462
+ direction: "column",
2463
+ height: "100%",
2464
+ style: {
2465
+ minWidth: ORDER_ENTRY_MIN_WIDTH,
2466
+ maxWidth: horizontalDraggable ? ORDER_ENTRY_MAX_WIDTH : ORDER_ENTRY_MIN_WIDTH,
2467
+ width: mainSplitSize
2468
+ },
2469
+ children: sortableItems.map((id) => /* @__PURE__ */ jsxRuntime.jsx(
2470
+ TradingSortablePanel,
2471
+ {
2472
+ id,
2473
+ showIndicator: showPositionIcon,
2474
+ className: orderlyUi.cn(
2475
+ id === orderlyLayoutCore.TRADING_PANEL_IDS.MARGIN && "oui-trading-riskRate-container",
2476
+ id === orderlyLayoutCore.TRADING_PANEL_IDS.ASSETS && "oui-trading-assetsView-container oui-border oui-border-line-12",
2477
+ id === orderlyLayoutCore.TRADING_PANEL_IDS.ORDER_ENTRY && "oui-trading-orderEntry-container",
2478
+ id === "margin" && "oui-trading-riskRate-container",
2479
+ id === "assets" && "oui-trading-assetsView-container oui-border oui-border-line-12",
2480
+ id === "orderEntry" && "oui-trading-orderEntry-container"
2481
+ ),
2482
+ children: getPanel(id)
2483
+ },
2484
+ id
2485
+ ))
2486
+ }
2487
+ ),
2488
+ /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.Box, { height: extraHeight })
2489
+ ]
2490
+ }
2491
+ )
2492
+ ]
2493
+ }
2494
+ ),
2495
+ /* @__PURE__ */ jsxRuntime.jsx(
2496
+ orderlyUi.Box,
2497
+ {
2498
+ intensity: 900,
2499
+ r: "2xl",
2500
+ p: 2,
2501
+ style: {
2502
+ height: dataListSplitHeightSM,
2503
+ minHeight: Math.max(dataListMinHeight, 0),
2504
+ maxHeight: DATA_LIST_MAX_HEIGHT
2505
+ },
2506
+ className: "oui-overflow-hidden",
2507
+ children: getPanel(orderlyLayoutCore.TRADING_PANEL_IDS.DATA_LIST)
2508
+ }
2509
+ ),
2510
+ marketLayout === "bottom" && stickyHorizontalMarketsView
2511
+ ]
2512
+ }
2513
+ )
2514
+ ] })
2515
+ }
2516
+ ),
2517
+ /* @__PURE__ */ jsxRuntime.jsx(core.DragOverlay, { dropAnimation: dropAnimationConfig, children: dragOverlayContent })
2518
+ ]
2519
+ }
2520
+ );
2521
+ }
2522
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2523
+ core.DndContext,
2524
+ {
2525
+ sensors,
2526
+ collisionDetection: core.closestCenter,
2527
+ onDragStart: handleDragStart,
2528
+ onDragEnd: handleDragEnd,
2529
+ modifiers: [modifiers.restrictToVerticalAxis],
2530
+ children: [
2531
+ /* @__PURE__ */ jsxRuntime.jsx(
2532
+ sortable.SortableContext,
2533
+ {
2534
+ items: sortableItems,
2535
+ strategy: sortable.verticalListSortingStrategy,
2536
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
2537
+ orderlyUi.Flex,
2538
+ {
2539
+ style: {
2540
+ minHeight: minScreenHeight,
2541
+ minWidth: 1440 - SCROLLBAR_WIDTH
2542
+ },
2543
+ className: orderlyUi.cn(
2544
+ className,
2545
+ "oui-justify-start",
2546
+ tradingViewFullScreen && "oui-relative oui-h-[calc(100vh-80px)] oui-w-screen oui-overflow-hidden !oui-p-0"
2547
+ ),
2548
+ width: "100%",
2549
+ p: 2,
2550
+ gap: 2,
2551
+ itemAlign: "stretch",
2552
+ direction: "column",
2553
+ children: [
2554
+ marketLayout === "top" && horizontalMarketsView,
2555
+ /* @__PURE__ */ jsxRuntime.jsxs(
2556
+ orderlyUi.Flex,
2557
+ {
2558
+ className: orderlyUi.cn(
2559
+ "oui-flex-1 oui-overflow-hidden",
2560
+ layout === "left" && "oui-flex-row-reverse"
2561
+ ),
2562
+ gap: 2,
2563
+ children: [
2564
+ !max4XL && marketLayout === "left" && marketsView,
2565
+ /* @__PURE__ */ jsxRuntime.jsxs(
2566
+ TradingSplitLayout,
2567
+ {
2568
+ className: "oui-flex oui-flex-1 oui-overflow-hidden",
2569
+ onSizeChange: onMainSplitSizeChange,
2570
+ disable: !horizontalDraggable,
2571
+ children: [
2572
+ layout === "left" && orderEntryView,
2573
+ mainView,
2574
+ layout === "right" && orderEntryView
2575
+ ]
2576
+ }
2577
+ )
2578
+ ]
2579
+ }
2580
+ ),
2581
+ marketLayout === "bottom" && stickyHorizontalMarketsView
2582
+ ]
2583
+ }
2584
+ )
2585
+ }
2586
+ ),
2587
+ /* @__PURE__ */ jsxRuntime.jsx(core.DragOverlay, { dropAnimation: dropAnimationConfig, children: dragOverlayContent })
2588
+ ]
2589
+ }
2590
+ );
2591
+ }
2592
+
2593
+ // src/splitTradingStrategy.ts
2594
+ var splitTradingStrategy = {
2595
+ id: "split-trading",
2596
+ displayName: "Split Trading Layout",
2597
+ /** No layout model needed — state is managed internally by SplitTradingLayout. */
2598
+ defaultLayout: () => ({}),
2599
+ serialize: () => "{}",
2600
+ deserialize: () => ({}),
2601
+ /** SplitTradingLayout implements LayoutRendererProps<Record<string, unknown>>. */
2602
+ Renderer: SplitTradingLayout
2603
+ };
2604
+ var PLUGIN_ID = "orderly-layout-split";
2605
+ var PLUGIN_NAME = "Split Layout";
2606
+ var PLUGIN_VERSION = "1.0.0";
2607
+ function registerLayoutSplitPlugin(options = {}) {
2608
+ return (SDK) => {
2609
+ SDK.registerPlugin({
2610
+ id: PLUGIN_ID,
2611
+ name: PLUGIN_NAME,
2612
+ version: PLUGIN_VERSION,
2613
+ orderlyVersion: ">=1.0.0",
2614
+ interceptors: [
2615
+ orderlyUi.createInterceptor("Trading.Layout.Desktop", (Original, props) => /* @__PURE__ */ jsxRuntime.jsx(
2616
+ Original,
2617
+ {
2618
+ ...props,
2619
+ layoutStrategy: splitTradingStrategy,
2620
+ getInitialLayout: () => ({}),
2621
+ disableLayoutPersistence: true
2622
+ }
2623
+ )),
2624
+ orderlyUi.createInterceptor(
2625
+ "Trading.SymbolInfoBar.Desktop",
2626
+ (Original, props) => /* @__PURE__ */ jsxRuntime.jsx(
2627
+ Original,
2628
+ {
2629
+ ...props,
2630
+ trailing: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2631
+ props.trailing,
2632
+ /* @__PURE__ */ jsxRuntime.jsx(SymbolBarLayoutSwitcher, {})
2633
+ ] })
2634
+ }
2635
+ )
2636
+ )
2637
+ ]
2638
+ });
2639
+ };
2640
+ }
2641
+ var SplitTradingDesktopContext = React__default.default.createContext(null);
2642
+ SplitTradingDesktopContext.displayName = "SplitTradingDesktopContext";
2643
+ function useSplitTradingDesktopContext() {
2644
+ return React__default.default.useContext(SplitTradingDesktopContext);
2645
+ }
2646
+ function useDropAnimationConfig() {
2647
+ return React.useMemo(
2648
+ () => ({
2649
+ keyframes({
2650
+ transform
2651
+ }) {
2652
+ return [
2653
+ {
2654
+ transform: utilities.CSS.Transform.toString({
2655
+ ...transform.initial,
2656
+ scaleX: 1.05,
2657
+ scaleY: 1.05
2658
+ })
2659
+ },
2660
+ {
2661
+ transform: utilities.CSS.Transform.toString({
2662
+ ...transform.final,
2663
+ scaleX: 1,
2664
+ scaleY: 1
2665
+ })
2666
+ }
2667
+ ];
2668
+ },
2669
+ sideEffects: ({
2670
+ active,
2671
+ dragOverlay
2672
+ }) => {
2673
+ active.node.style.opacity = "0";
2674
+ const inner = dragOverlay.node.querySelector(".inner-content");
2675
+ if (inner) inner.classList.add("oui-animate-shake");
2676
+ return () => {
2677
+ active.node.style.opacity = "";
2678
+ };
2679
+ }
2680
+ }),
2681
+ []
2682
+ );
2683
+ }
2684
+ function SplitTradingDesktopChrome(props) {
2685
+ const {
2686
+ children,
2687
+ max2XL,
2688
+ tradingViewFullScreen,
2689
+ sortableItems,
2690
+ setSortableItems,
2691
+ className
2692
+ } = props;
2693
+ const [activeId, setActiveId] = React.useState(null);
2694
+ const dropAnimationConfig2 = useDropAnimationConfig();
2695
+ const sensors = core.useSensors(
2696
+ core.useSensor(core.PointerSensor, { activationConstraint: { distance: 5 } }),
2697
+ core.useSensor(core.KeyboardSensor, {
2698
+ coordinateGetter: sortable.sortableKeyboardCoordinates
2699
+ })
2700
+ );
2701
+ const handleDragStart = (event) => {
2702
+ setActiveId(event.active.id);
2703
+ };
2704
+ const handleDragEnd = (event) => {
2705
+ const { active, over } = event;
2706
+ if (active.id !== over?.id && over) {
2707
+ const oldIndex = sortableItems?.indexOf(active.id) ?? -1;
2708
+ const newIndex = sortableItems?.indexOf(over.id) ?? -1;
2709
+ if (oldIndex !== -1 && newIndex !== -1) {
2710
+ setSortableItems?.(
2711
+ sortable.arrayMove(sortableItems ?? [], oldIndex, newIndex)
2712
+ );
2713
+ }
2714
+ }
2715
+ setActiveId(null);
2716
+ };
2717
+ return /* @__PURE__ */ jsxRuntime.jsx(SplitTradingDesktopContext.Provider, { value: props, children: /* @__PURE__ */ jsxRuntime.jsxs(
2718
+ core.DndContext,
2719
+ {
2720
+ sensors,
2721
+ collisionDetection: core.closestCenter,
2722
+ onDragStart: handleDragStart,
2723
+ onDragEnd: handleDragEnd,
2724
+ modifiers: [modifiers.restrictToVerticalAxis],
2725
+ children: [
2726
+ /* @__PURE__ */ jsxRuntime.jsx(
2727
+ sortable.SortableContext,
2728
+ {
2729
+ items: sortableItems ?? [],
2730
+ strategy: sortable.verticalListSortingStrategy,
2731
+ children: max2XL ? /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.Box, { height: "100%", className, children }) : /* @__PURE__ */ jsxRuntime.jsx(
2732
+ orderlyUi.Flex,
2733
+ {
2734
+ style: {
2735
+ // minHeight: minScreenHeight,
2736
+ // minWidth: 1440 - scrollBarWidth,
2737
+ },
2738
+ className: orderlyUi.cn(
2739
+ className,
2740
+ "oui-flex-1 oui-justify-start oui-overflow-hidden",
2741
+ tradingViewFullScreen && "oui-relative oui-h-[calc(100vh-80px)] oui-w-screen oui-overflow-hidden !oui-p-0"
2742
+ ),
2743
+ width: "100%",
2744
+ p: 2,
2745
+ gap: 2,
2746
+ itemAlign: "stretch",
2747
+ direction: "column",
2748
+ children
2749
+ }
2750
+ )
2751
+ }
2752
+ ),
2753
+ /* @__PURE__ */ jsxRuntime.jsx(core.DragOverlay, { dropAnimation: dropAnimationConfig2, children: activeId ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-pointer-events-none oui-opacity-80", children: [
2754
+ "id: ",
2755
+ activeId
2756
+ ] }) : null })
2757
+ ]
2758
+ }
2759
+ ) });
2760
+ }
2761
+ var SplitPresetContext = React.createContext(null);
2762
+ function useSplitPresetContext() {
2763
+ return React.useContext(SplitPresetContext);
2764
+ }
2765
+ var ExpandIcon = (props) => /* @__PURE__ */ jsxRuntime.jsx(
2766
+ "svg",
2767
+ {
2768
+ width: "16",
2769
+ height: "16",
2770
+ viewBox: "0 0 16 16",
2771
+ fill: "currentColor",
2772
+ xmlns: "http://www.w3.org/2000/svg",
2773
+ ...props,
2774
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6.326 8.826a.84.84 0 0 0-.6.234L2.16 12.627v-2.135H.492v4.167c0 .46.373.833.834.833h4.166v-1.667H3.357l3.567-3.567a.857.857 0 0 0 0-1.198.84.84 0 0 0-.598-.234M10.502.492V2.16h2.135L9.07 5.726a.857.857 0 0 0 0 1.199.86.86 0 0 0 1.197 0l3.568-3.568v2.135h1.667V1.326a.834.834 0 0 0-.834-.834z" })
2775
+ }
2776
+ );
2777
+ var CollapseIcon = (props) => /* @__PURE__ */ jsxRuntime.jsx(
2778
+ "svg",
2779
+ {
2780
+ width: "16",
2781
+ height: "16",
2782
+ viewBox: "0 0 16 16",
2783
+ fill: "currentColor",
2784
+ xmlns: "http://www.w3.org/2000/svg",
2785
+ ...props,
2786
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M14.668.492a.85.85 0 0 0-.599.234l-3.567 3.568V2.159H8.835v4.167c0 .46.373.833.833.833h4.167V5.492H11.7l3.569-3.567a.86.86 0 0 0 0-1.199.85.85 0 0 0-.6-.234m-12.5 8.334v1.666h2.135L.736 14.06a.86.86 0 0 0 0 1.198.86.86 0 0 0 1.198 0l3.568-3.567v2.134h1.666V9.66a.834.834 0 0 0-.833-.833z" })
2787
+ }
2788
+ );
2789
+ var CollapsiblePanel = ({
2790
+ title,
2791
+ collapsible,
2792
+ collapsed,
2793
+ onToggle,
2794
+ minSize,
2795
+ maxSize,
2796
+ children,
2797
+ className,
2798
+ style
2799
+ }) => {
2800
+ const computedStyle = Object.assign(
2801
+ {},
2802
+ style,
2803
+ typeof collapsible !== "undefined" ? collapsed ? { width: minSize } : { width: maxSize } : {}
2804
+ );
2805
+ const bodyClassName = React.useMemo(() => {
2806
+ return typeof !!title ? "oui-h-[calc(100%_-_40px)]" : "oui-h-full";
2807
+ }, [title]);
2808
+ const renderCollapsibleHeader = () => {
2809
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2810
+ orderlyUi.Flex,
2811
+ {
2812
+ className: orderlyUi.cn(
2813
+ "oui-text-base-contrast-36"
2814
+ // collapsed ? "oui-absolute oui-end-[-20px] oui-z-50" : "oui-relative",
2815
+ ),
2816
+ justify: collapsed ? "center" : "between",
2817
+ width: "100%",
2818
+ px: 3,
2819
+ pt: 3,
2820
+ children: [
2821
+ !collapsed && title && /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.Text, { size: "base", intensity: 80, children: title }),
2822
+ /* @__PURE__ */ jsxRuntime.jsx(
2823
+ "button",
2824
+ {
2825
+ onClick: onToggle,
2826
+ className: orderlyUi.cn("oui-cursor-pointer hover:oui-text-base-contrast-80"),
2827
+ children: collapsed ? /* @__PURE__ */ jsxRuntime.jsx(ExpandIcon, { className: "oui-text-base-contrast-36" }) : /* @__PURE__ */ jsxRuntime.jsx(CollapseIcon, { className: "oui-text-base-contrast-36" })
2828
+ }
2829
+ )
2830
+ ]
2831
+ }
2832
+ );
2833
+ };
2834
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2835
+ "div",
2836
+ {
2837
+ className: orderlyUi.cn(
2838
+ "oui-flex oui-flex-col oui-gap-y-5 oui-overflow-hidden oui-rounded-2xl oui-bg-base-9 oui-w-full oui-h-full",
2839
+ className
2840
+ ),
2841
+ style: computedStyle,
2842
+ children: [
2843
+ renderCollapsibleHeader(),
2844
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: orderlyUi.cn("oui-collapsible-content", bodyClassName), children: React__default.default.cloneElement(children, {
2845
+ collapsed
2846
+ // panelSize: "small",
2847
+ }) })
2848
+ ]
2849
+ }
2850
+ );
2851
+ };
2852
+ var DEFAULT_SHOW_INDICATOR = true;
2853
+ function IndicatorIcon2(props) {
2854
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2855
+ "svg",
2856
+ {
2857
+ width: "10",
2858
+ height: "16",
2859
+ viewBox: "0 0 10 16",
2860
+ fill: "currentColor",
2861
+ xmlns: "http://www.w3.org/2000/svg",
2862
+ ...props,
2863
+ children: [
2864
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "2", y: "2", width: "6", height: "2", rx: "1" }),
2865
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "2", y: "7", width: "6", height: "2", rx: "1" }),
2866
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "2", y: "12", width: "6", height: "2", rx: "1" })
2867
+ ]
2868
+ }
2869
+ );
2870
+ }
2871
+ function SortableSortChild({
2872
+ id,
2873
+ child,
2874
+ showIndicator,
2875
+ path,
2876
+ rootNode,
2877
+ index
2878
+ }) {
2879
+ const { ref, handleRef, isDragging } = sortable$1.useSortable({
2880
+ id,
2881
+ index
2882
+ });
2883
+ const showHandle = showIndicator && child.type === "panel";
2884
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2885
+ "div",
2886
+ {
2887
+ ref,
2888
+ className: orderlyUi.cn("oui-relative", isDragging && "oui-opacity-50"),
2889
+ children: [
2890
+ showHandle && /* @__PURE__ */ jsxRuntime.jsx(
2891
+ "button",
2892
+ {
2893
+ className: "oui-absolute oui-right-0 oui-top-4 oui-cursor-move oui-py-1",
2894
+ style: { touchAction: "none" },
2895
+ ref: handleRef,
2896
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2897
+ IndicatorIcon2,
2898
+ {
2899
+ className: orderlyUi.cn(
2900
+ "oui-text-base-contrast-20 hover:oui-text-base-contrast-80"
2901
+ )
2902
+ }
2903
+ )
2904
+ }
2905
+ ),
2906
+ /* @__PURE__ */ jsxRuntime.jsx(SplitNodeRenderer, { node: child, path, rootNode })
2907
+ ]
2908
+ }
2909
+ );
2910
+ }
2911
+ function SortNodeRenderer({
2912
+ node,
2913
+ path,
2914
+ rootNode,
2915
+ classNames
2916
+ }) {
2917
+ const { onLayoutChange, layout, breakpoint } = useSplitLayoutConfig();
2918
+ const { orientation, children } = node;
2919
+ const ctx = useSplitPresetContext();
2920
+ const showIndicator = ctx?.showIndicator ?? DEFAULT_SHOW_INDICATOR;
2921
+ const items = children.map(
2922
+ (child, index) => getSortableIdForChild(child, path, index)
2923
+ );
2924
+ const isVertical = orientation === "vertical";
2925
+ const handleDragEnd = React.useCallback(
2926
+ (event) => {
2927
+ const anyEvent = event;
2928
+ if (!anyEvent.operation || anyEvent.canceled) return;
2929
+ const { source } = anyEvent.operation;
2930
+ if (!sortable$1.isSortable(source)) return;
2931
+ const { initialIndex, index } = source;
2932
+ if (initialIndex === index) return;
2933
+ const newOrder = [...children];
2934
+ const [removed] = newOrder.splice(initialIndex, 1);
2935
+ newOrder.splice(index, 0, removed);
2936
+ const updatedRoot = updateOrderAtPath(rootNode, path, newOrder);
2937
+ onLayoutChange({
2938
+ ...layout,
2939
+ layouts: {
2940
+ ...layout.layouts,
2941
+ [breakpoint]: updatedRoot
2942
+ }
2943
+ });
2944
+ },
2945
+ [children, path, rootNode, breakpoint, layout, onLayoutChange]
2946
+ );
2947
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
2948
+ react.DragDropProvider,
2949
+ {
2950
+ onDragEnd: handleDragEnd,
2951
+ modifiers: (defaults) => [...defaults, modifiers$1.RestrictToVerticalAxis],
2952
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2953
+ "div",
2954
+ {
2955
+ className: orderlyUi.cn(
2956
+ isVertical ? "oui-flex oui-w-full oui-flex-col oui-gap-2" : "oui-flex oui-w-full oui-flex-row oui-gap-2",
2957
+ node.className,
2958
+ classNames?.panel
2959
+ ),
2960
+ style: node.style,
2961
+ children: children.map((child, index) => /* @__PURE__ */ jsxRuntime.jsx(
2962
+ SortableSortChild,
2963
+ {
2964
+ id: items[index],
2965
+ child,
2966
+ showIndicator,
2967
+ path: [...path, index],
2968
+ rootNode,
2969
+ index
2970
+ },
2971
+ items[index]
2972
+ ))
2973
+ }
2974
+ )
2975
+ }
2976
+ ) });
2977
+ }
2978
+ function SplitNodeRenderer({
2979
+ node,
2980
+ path,
2981
+ rootNode
2982
+ }) {
2983
+ const {
2984
+ panels,
2985
+ onSizeChange,
2986
+ onSizePersist,
2987
+ classNames,
2988
+ gap,
2989
+ isPanelCollapsed,
2990
+ togglePanelCollapse,
2991
+ isPanelCollapsible
2992
+ } = useSplitLayoutConfig();
2993
+ if (node.type === "panel") {
2994
+ const panelWrapper = panels.get(node.id);
2995
+ const panel = panelWrapper?.node;
2996
+ if (!panel) {
2997
+ return /* @__PURE__ */ jsxRuntime.jsx(
2998
+ "div",
2999
+ {
3000
+ className: orderlyUi.cn(
3001
+ "oui-text-base-contrast-40 oui-rounded-2xl oui-bg-base-9 oui-p-3 oui-text-xs",
3002
+ node.size !== "fixed" && "oui-size-full",
3003
+ classNames?.panel,
3004
+ node.className
3005
+ ),
3006
+ style: node.style,
3007
+ "data-panel-id": node.id,
3008
+ children: node.id ? `Panel not found: ${node.id}` : "Panel not found"
3009
+ }
3010
+ );
3011
+ }
3012
+ const title = node.title ?? panelWrapper?.props?.title;
3013
+ if (typeof node.collapsible !== "undefined") {
3014
+ return /* @__PURE__ */ jsxRuntime.jsx(
3015
+ CollapsiblePanel,
3016
+ {
3017
+ title,
3018
+ collapsible: node.collapsible || isPanelCollapsible(node.id),
3019
+ collapsed: isPanelCollapsed(node.id),
3020
+ onToggle: () => togglePanelCollapse(node.id),
3021
+ minSize: node.minSize,
3022
+ maxSize: node.maxSize,
3023
+ className: orderlyUi.cn(
3024
+ node.size !== "fixed" && "oui-size-full",
3025
+ classNames?.panel,
3026
+ node.className
3027
+ ),
3028
+ style: node.style,
3029
+ "data-panel-id": node.id,
3030
+ children: panel
3031
+ }
3032
+ );
3033
+ }
3034
+ return /* @__PURE__ */ jsxRuntime.jsx(
3035
+ "div",
3036
+ {
3037
+ className: orderlyUi.cn(
3038
+ "oui-overflow-hidden oui-rounded-2xl oui-bg-base-9",
3039
+ node.size !== "fixed" && "oui-size-full",
3040
+ classNames?.panel,
3041
+ node.className
3042
+ ),
3043
+ style: node.style,
3044
+ "data-panel-id": node.id,
3045
+ children: panel
3046
+ }
3047
+ );
3048
+ }
3049
+ if (node.type === "sort") {
3050
+ return /* @__PURE__ */ jsxRuntime.jsx(
3051
+ SortNodeRenderer,
3052
+ {
3053
+ node,
3054
+ path,
3055
+ rootNode,
3056
+ classNames
3057
+ }
3058
+ );
3059
+ }
3060
+ const { orientation, children } = node;
3061
+ const sizes = children.map((child) => child.size ?? "auto");
3062
+ const panelConstraints = children.map((child) => ({
3063
+ // Nested split/sort nodes need minSize to prevent collapse (lib default 0% causes inner area to collapse)
3064
+ minSize: child.minSize ?? (child.type === "split" || child.type === "sort" ? "10%" : void 0),
3065
+ maxSize: child.maxSize,
3066
+ disabled: child.disabled
3067
+ }));
3068
+ return /* @__PURE__ */ jsxRuntime.jsx(
3069
+ SplitLayout,
3070
+ {
3071
+ orientation,
3072
+ sizes,
3073
+ panelConstraints,
3074
+ onSizeChange: (sizesAsStrings) => {
3075
+ onSizeChange(path, sizesAsStrings);
3076
+ onSizePersist?.(path, sizesAsStrings);
3077
+ },
3078
+ classNames,
3079
+ gap,
3080
+ className: node.className,
3081
+ style: node.style,
3082
+ children: children.map((child, index) => /* @__PURE__ */ jsxRuntime.jsx(
3083
+ SplitNodeRenderer,
3084
+ {
3085
+ node: child,
3086
+ path: [...path, index],
3087
+ rootNode
3088
+ },
3089
+ `child-${index}`
3090
+ ))
3091
+ }
3092
+ );
3093
+ }
3094
+
3095
+ // src/utils/splitRendererUtils.ts
3096
+ function getNodeAtPath(node, path) {
3097
+ if (path.length === 0) return node;
3098
+ if (node.type === "panel") return null;
3099
+ const [childIndex, ...restPath] = path;
3100
+ if (childIndex >= node.children.length) return null;
3101
+ return getNodeAtPath(node.children[childIndex], restPath);
3102
+ }
3103
+ function getSizesFromChildren(children) {
3104
+ return children.map((child) => child.size ?? "auto");
3105
+ }
3106
+ function sizesAreEqual(current, next) {
3107
+ if (!current || current.length !== next.length) return false;
3108
+ const toNum = (value) => Math.round(parseFloat(String(value).replace(/%/g, "")) || 0);
3109
+ return current.every((c, index) => toNum(c) === toNum(next[index]));
3110
+ }
3111
+ function updateDefaultCollapsedAtPath(node, panelId, defaultCollapsed) {
3112
+ if (node.type === "panel" && node.id === panelId) {
3113
+ return { ...node, defaultCollapsed };
3114
+ }
3115
+ if (node.type === "split" || node.type === "sort") {
3116
+ return {
3117
+ ...node,
3118
+ children: node.children.map(
3119
+ (child) => updateDefaultCollapsedAtPath(child, panelId, defaultCollapsed)
3120
+ )
3121
+ };
3122
+ }
3123
+ return node;
3124
+ }
3125
+ function updateSizeAtPath(node, path, newSizes) {
3126
+ if (node.type === "panel") {
3127
+ const size = newSizes[0];
3128
+ return size !== void 0 ? { ...node, size } : node;
3129
+ }
3130
+ if (node.type === "sort") {
3131
+ if (path.length === 0) return node;
3132
+ const [childIndex2, ...restPath2] = path;
3133
+ const updatedChildren = [...node.children];
3134
+ if (childIndex2 < updatedChildren.length) {
3135
+ updatedChildren[childIndex2] = updateSizeAtPath(
3136
+ updatedChildren[childIndex2],
3137
+ restPath2,
3138
+ newSizes
3139
+ );
3140
+ }
3141
+ return { ...node, children: updatedChildren };
3142
+ }
3143
+ const updatedNode = {
3144
+ ...node,
3145
+ children: [...node.children]
3146
+ };
3147
+ if (path.length === 0) {
3148
+ updatedNode.children = node.children.map((child, index) => ({
3149
+ ...child,
3150
+ size: newSizes[index] ?? child.size ?? "auto"
3151
+ }));
3152
+ return updatedNode;
3153
+ }
3154
+ const [childIndex, ...restPath] = path;
3155
+ if (childIndex < updatedNode.children.length) {
3156
+ updatedNode.children[childIndex] = updateSizeAtPath(
3157
+ updatedNode.children[childIndex],
3158
+ restPath,
3159
+ newSizes
3160
+ );
3161
+ }
3162
+ return updatedNode;
3163
+ }
3164
+ function getCollapsiblePanels(node) {
3165
+ const collapsible = /* @__PURE__ */ new Map();
3166
+ const traverse = (n) => {
3167
+ if (n.type === "panel" && n.id) {
3168
+ collapsible.set(n.id, n.collapsible ?? false);
3169
+ }
3170
+ if (n.type === "split" || n.type === "sort") {
3171
+ for (const child of n.children ?? []) {
3172
+ traverse(child);
3173
+ }
3174
+ }
3175
+ };
3176
+ traverse(node);
3177
+ return collapsible;
3178
+ }
3179
+ function createUpdatedLayout(rootNode, layout, breakpoint, path, sizes) {
3180
+ const updatedRoot = updateSizeAtPath(rootNode, path, sizes);
3181
+ return {
3182
+ ...layout,
3183
+ layouts: {
3184
+ ...layout.layouts,
3185
+ [breakpoint]: updatedRoot
3186
+ }
3187
+ };
3188
+ }
3189
+ function SplitRenderer(props) {
3190
+ const { layout, panels, onLayoutChange, onLayoutPersist, className, style } = props;
3191
+ const ctx = useSplitPresetContext();
3192
+ const containerRef = React.useRef(null);
3193
+ const presetName = ctx?.presets?.find(
3194
+ (p) => p.id === ctx?.selectedPresetId
3195
+ )?.name;
3196
+ const breakpoint = useViewportBreakpoint({
3197
+ fallbackWidth: typeof window !== "undefined" ? window.innerWidth : 1440
3198
+ });
3199
+ const rootNode = layout.layouts[breakpoint];
3200
+ const computeUpdatedLayout = React.useCallback(
3201
+ (path, sizes) => {
3202
+ const nodeAtPath = getNodeAtPath(rootNode, path);
3203
+ const currentSizes = nodeAtPath?.type === "split" ? getSizesFromChildren(nodeAtPath.children) : void 0;
3204
+ if (sizesAreEqual(currentSizes, sizes)) {
3205
+ return null;
3206
+ }
3207
+ return createUpdatedLayout(rootNode, layout, breakpoint, path, sizes);
3208
+ },
3209
+ [layout, breakpoint, rootNode]
3210
+ );
3211
+ const handleSizeChange = React.useCallback(
3212
+ (path, sizes) => {
3213
+ const updatedLayout = computeUpdatedLayout(path, sizes);
3214
+ if (updatedLayout) {
3215
+ onLayoutChange(updatedLayout);
3216
+ }
3217
+ },
3218
+ [computeUpdatedLayout, onLayoutChange]
3219
+ );
3220
+ const handleSizePersist = React.useCallback(
3221
+ (path, sizes) => {
3222
+ if (!onLayoutPersist) return;
3223
+ const updatedLayout = computeUpdatedLayout(path, sizes);
3224
+ if (updatedLayout) {
3225
+ onLayoutPersist(updatedLayout);
3226
+ }
3227
+ },
3228
+ [computeUpdatedLayout, onLayoutPersist]
3229
+ );
3230
+ const collapsiblePanels = React.useMemo(
3231
+ () => getCollapsiblePanels(rootNode),
3232
+ [rootNode]
3233
+ );
3234
+ const collapsedPanels = React.useMemo(() => {
3235
+ const collapsed = /* @__PURE__ */ new Set();
3236
+ const traverse = (node) => {
3237
+ if (node.type === "panel" && node.id && node.defaultCollapsed) {
3238
+ collapsed.add(node.id);
3239
+ }
3240
+ if (node.type === "split" || node.type === "sort") {
3241
+ node.children?.forEach(traverse);
3242
+ }
3243
+ };
3244
+ traverse(rootNode);
3245
+ return collapsed;
3246
+ }, [rootNode]);
3247
+ const computeUpdatedLayoutForCollapse = React.useCallback(
3248
+ (panelId, collapsed) => {
3249
+ const updatedLayouts = {};
3250
+ for (const bp of BREAKPOINT_KEYS) {
3251
+ if (layout.layouts[bp]) {
3252
+ updatedLayouts[bp] = updateDefaultCollapsedAtPath(
3253
+ layout.layouts[bp],
3254
+ panelId,
3255
+ collapsed
3256
+ );
3257
+ }
3258
+ }
3259
+ return { ...layout, layouts: updatedLayouts };
3260
+ },
3261
+ [layout]
3262
+ );
3263
+ const isPanelCollapsible = React.useCallback(
3264
+ (panelId) => collapsiblePanels.get(panelId) ?? false,
3265
+ [collapsiblePanels]
3266
+ );
3267
+ const togglePanelCollapse = React.useCallback(
3268
+ (panelId) => {
3269
+ const isCurrentlyCollapsed = collapsedPanels.has(panelId);
3270
+ const updatedLayout = computeUpdatedLayoutForCollapse(
3271
+ panelId,
3272
+ !isCurrentlyCollapsed
3273
+ );
3274
+ onLayoutChange(updatedLayout);
3275
+ onLayoutPersist?.(updatedLayout);
3276
+ },
3277
+ [
3278
+ collapsedPanels,
3279
+ computeUpdatedLayoutForCollapse,
3280
+ onLayoutChange,
3281
+ onLayoutPersist
3282
+ ]
3283
+ );
3284
+ const isPanelCollapsed = React.useCallback(
3285
+ (panelId) => collapsedPanels.has(panelId),
3286
+ [collapsedPanels]
3287
+ );
3288
+ if (panels.size === 0) {
3289
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className, style });
3290
+ }
3291
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className, children: [
3292
+ /* @__PURE__ */ jsxRuntime.jsx(
3293
+ SplitLayoutConfigProvider,
3294
+ {
3295
+ panels,
3296
+ layout,
3297
+ breakpoint,
3298
+ onLayoutChange,
3299
+ onSizeChange: handleSizeChange,
3300
+ onSizePersist: handleSizePersist,
3301
+ classNames: ctx?.classNames,
3302
+ gap: ctx?.gap,
3303
+ collapsedPanels,
3304
+ togglePanelCollapse,
3305
+ isPanelCollapsed,
3306
+ collapsiblePanels,
3307
+ isPanelCollapsible,
3308
+ children: /* @__PURE__ */ jsxRuntime.jsx(SplitNodeRenderer, { node: rootNode, path: [], rootNode })
3309
+ }
3310
+ ),
3311
+ /* @__PURE__ */ jsxRuntime.jsxs(
3312
+ "div",
3313
+ {
3314
+ className: "oui-fixed oui-right-2 oui-bottom-5 oui-text-lg oui-text-trade-loss oui-flex oui-flex-col oui-items-end",
3315
+ style: { zIndex: 1e3 },
3316
+ children: [
3317
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: breakpoint }),
3318
+ presetName && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oui-text-sm", children: presetName }),
3319
+ /* @__PURE__ */ jsxRuntime.jsx(
3320
+ "button",
3321
+ {
3322
+ onClick: () => ctx?.reset(),
3323
+ className: "oui-mt-1 oui-px-2 oui-py-1 oui-text-sm oui-bg-gray-500 oui-text-white oui-rounded",
3324
+ children: "Reset"
3325
+ }
3326
+ )
3327
+ ]
3328
+ }
3329
+ )
3330
+ ] });
3331
+ }
3332
+
3333
+ // src/splitStrategy.ts
3334
+ var splitStrategy = {
3335
+ id: "split",
3336
+ displayName: "Split Layout",
3337
+ defaultLayout: createDefaultSplitLayout,
3338
+ serialize: serializeSplitLayout,
3339
+ deserialize: deserializeSplitLayout,
3340
+ Renderer: SplitRenderer
3341
+ };
3342
+ function SplitInlinedLayout({
3343
+ Original,
3344
+ props
3345
+ }) {
3346
+ const layoutStrategy = props.layoutStrategy ?? splitStrategy;
3347
+ return /* @__PURE__ */ jsxRuntime.jsx(SplitTradingDesktopChrome, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx(Original, { ...props, layoutStrategy }) });
3348
+ }
3349
+
3350
+ exports.DATA_LIST_INITIAL_HEIGHT = DATA_LIST_INITIAL_HEIGHT;
3351
+ exports.DATA_LIST_MAX_HEIGHT = DATA_LIST_MAX_HEIGHT;
3352
+ exports.DEFAULT_SPLIT_BREAKPOINTS = DEFAULT_SPLIT_BREAKPOINTS;
3353
+ exports.ORDERBOOK_MAX_HEIGHT = ORDERBOOK_MAX_HEIGHT;
3354
+ exports.ORDERBOOK_MAX_WIDTH = ORDERBOOK_MAX_WIDTH;
3355
+ exports.ORDERBOOK_MIN_HEIGHT = ORDERBOOK_MIN_HEIGHT;
3356
+ exports.ORDERBOOK_MIN_WIDTH = ORDERBOOK_MIN_WIDTH;
3357
+ exports.ORDER_ENTRY_MAX_WIDTH = ORDER_ENTRY_MAX_WIDTH;
3358
+ exports.ORDER_ENTRY_MIN_WIDTH = ORDER_ENTRY_MIN_WIDTH;
3359
+ exports.SPACE = SPACE;
3360
+ exports.SPLIT_BREAKPOINT_ORDER = SPLIT_BREAKPOINT_ORDER;
3361
+ exports.SYMBOL_INFO_BAR_HEIGHT = SYMBOL_INFO_BAR_HEIGHT;
3362
+ exports.SplitInlinedLayout = SplitInlinedLayout;
3363
+ exports.SplitLayout = SplitLayout;
3364
+ exports.SplitLayoutConfigProvider = SplitLayoutConfigProvider;
3365
+ exports.SplitTradingDesktopChrome = SplitTradingDesktopChrome;
3366
+ exports.SplitTradingLayout = SplitTradingLayout;
3367
+ exports.TRADINGVIEW_MIN_HEIGHT = TRADINGVIEW_MIN_HEIGHT;
3368
+ exports.TRADINGVIEW_MIN_WIDTH = TRADINGVIEW_MIN_WIDTH;
3369
+ exports.TradingSortablePanel = TradingSortablePanel;
3370
+ exports.TradingSplitLayout = TradingSplitLayout;
3371
+ exports.VIEWPORT_BREAKPOINTS = VIEWPORT_BREAKPOINTS;
3372
+ exports.VIEWPORT_BREAKPOINT_ORDER = VIEWPORT_BREAKPOINT_ORDER;
3373
+ exports.createDefaultSplitLayout = createDefaultSplitLayout;
3374
+ exports.deserializeSplitLayout = deserializeSplitLayout;
3375
+ exports.getSortableIdForChild = getSortableIdForChild;
3376
+ exports.registerLayoutSplitPlugin = registerLayoutSplitPlugin;
3377
+ exports.serializeSplitLayout = serializeSplitLayout;
3378
+ exports.splitTradingStrategy = splitTradingStrategy;
3379
+ exports.updateOrderAtPath = updateOrderAtPath;
3380
+ exports.useSplitLayout = useSplitLayout;
3381
+ exports.useSplitLayoutConfig = useSplitLayoutConfig;
3382
+ exports.useSplitTradingDesktopContext = useSplitTradingDesktopContext;
3383
+ exports.useViewportBreakpoint = useViewportBreakpoint;
3384
+ //# sourceMappingURL=index.js.map
3385
+ //# sourceMappingURL=index.js.map