@kodiak-finance/orderly-ui-order-entry 2.10.0-alpha.2 → 2.10.0-alpha.4

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.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _kodiak_finance_orderly_types from '@kodiak-finance/orderly-types';
2
2
  import { MarginMode, OrderSide, OrderType, OrderLevel, OrderlyOrder, API } from '@kodiak-finance/orderly-types';
3
3
  import * as react from 'react';
4
- import react__default, { FC } from 'react';
4
+ import react__default, { ReactNode, FC } from 'react';
5
5
  import * as _kodiak_finance_orderly_hooks from '@kodiak-finance/orderly-hooks';
6
6
  import * as react_jsx_runtime from 'react/jsx-runtime';
7
7
 
@@ -60,6 +60,22 @@ type OrderEntrySubmitSectionProps = {
60
60
  };
61
61
  };
62
62
 
63
+ /**
64
+ * Host-provided panel that takes over the order-entry slot when selected
65
+ * from the order-type dropdown.
66
+ */
67
+ interface ExtraTradeEntryPanel {
68
+ /** Stable unique id (e.g. "grid-bot"). */
69
+ id: string;
70
+ /** Label shown in the order-type dropdown. */
71
+ label: string;
72
+ /** Renders the panel body, scoped to the trade screen's current symbol. */
73
+ render: (props: {
74
+ symbol: string;
75
+ }) => ReactNode;
76
+ /** Suppress the Buy/Sell side buttons — for panels that act on both sides. */
77
+ hideSideButtons?: boolean;
78
+ }
63
79
  declare enum InputType {
64
80
  NONE = 0,
65
81
  PRICE = 1,// price input focus
@@ -175,6 +191,13 @@ declare const useOrderEntryScript: (inputs: OrderEntryScriptInputs) => {
175
191
  type OrderEntryProps = OrderEntryScriptReturn & {
176
192
  containerRef?: react__default.RefObject<HTMLDivElement>;
177
193
  disableFeatures?: ("slippageSetting" | "feesInfo")[];
194
+ /** Host-provided extras in the Advanced dropdown (e.g. grid bot). */
195
+ extraOptions?: Array<{
196
+ id: string;
197
+ label: string;
198
+ }>;
199
+ selectedExtraId?: string | null;
200
+ onExtraSelect?: (id: string | null) => void;
178
201
  };
179
202
  declare const OrderEntry: react__default.FC<OrderEntryProps>;
180
203
 
@@ -198,6 +221,8 @@ declare module "@kodiak-finance/orderly-plugin-core" {
198
221
  declare const OrderEntryWidget: react__default.FC<OrderEntryScriptInputs & {
199
222
  containerRef?: react__default.RefObject<HTMLDivElement>;
200
223
  disableFeatures?: ("slippageSetting" | "feesInfo")[];
224
+ /** Host-provided extras (e.g. grid-bot). */
225
+ extraPanels?: ExtraTradeEntryPanel[];
201
226
  }>;
202
227
 
203
228
  type OrderConfirmDialogProps = {
@@ -239,4 +264,4 @@ type SymbolBadgeProps = {
239
264
  };
240
265
  declare const SymbolBadge: FC<SymbolBadgeProps>;
241
266
 
242
- export { AdditionalInfo, FeesWidget, LTVRiskTooltipWidget, OrderConfirmDialog, OrderEntry, OrderEntryWidget, SymbolBadge, useOrderEntryScript };
267
+ export { AdditionalInfo, type ExtraTradeEntryPanel, FeesWidget, LTVRiskTooltipWidget, OrderConfirmDialog, OrderEntry, OrderEntryWidget, SymbolBadge, useOrderEntryScript };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _kodiak_finance_orderly_types from '@kodiak-finance/orderly-types';
2
2
  import { MarginMode, OrderSide, OrderType, OrderLevel, OrderlyOrder, API } from '@kodiak-finance/orderly-types';
3
3
  import * as react from 'react';
4
- import react__default, { FC } from 'react';
4
+ import react__default, { ReactNode, FC } from 'react';
5
5
  import * as _kodiak_finance_orderly_hooks from '@kodiak-finance/orderly-hooks';
6
6
  import * as react_jsx_runtime from 'react/jsx-runtime';
7
7
 
@@ -60,6 +60,22 @@ type OrderEntrySubmitSectionProps = {
60
60
  };
61
61
  };
62
62
 
63
+ /**
64
+ * Host-provided panel that takes over the order-entry slot when selected
65
+ * from the order-type dropdown.
66
+ */
67
+ interface ExtraTradeEntryPanel {
68
+ /** Stable unique id (e.g. "grid-bot"). */
69
+ id: string;
70
+ /** Label shown in the order-type dropdown. */
71
+ label: string;
72
+ /** Renders the panel body, scoped to the trade screen's current symbol. */
73
+ render: (props: {
74
+ symbol: string;
75
+ }) => ReactNode;
76
+ /** Suppress the Buy/Sell side buttons — for panels that act on both sides. */
77
+ hideSideButtons?: boolean;
78
+ }
63
79
  declare enum InputType {
64
80
  NONE = 0,
65
81
  PRICE = 1,// price input focus
@@ -175,6 +191,13 @@ declare const useOrderEntryScript: (inputs: OrderEntryScriptInputs) => {
175
191
  type OrderEntryProps = OrderEntryScriptReturn & {
176
192
  containerRef?: react__default.RefObject<HTMLDivElement>;
177
193
  disableFeatures?: ("slippageSetting" | "feesInfo")[];
194
+ /** Host-provided extras in the Advanced dropdown (e.g. grid bot). */
195
+ extraOptions?: Array<{
196
+ id: string;
197
+ label: string;
198
+ }>;
199
+ selectedExtraId?: string | null;
200
+ onExtraSelect?: (id: string | null) => void;
178
201
  };
179
202
  declare const OrderEntry: react__default.FC<OrderEntryProps>;
180
203
 
@@ -198,6 +221,8 @@ declare module "@kodiak-finance/orderly-plugin-core" {
198
221
  declare const OrderEntryWidget: react__default.FC<OrderEntryScriptInputs & {
199
222
  containerRef?: react__default.RefObject<HTMLDivElement>;
200
223
  disableFeatures?: ("slippageSetting" | "feesInfo")[];
224
+ /** Host-provided extras (e.g. grid-bot). */
225
+ extraPanels?: ExtraTradeEntryPanel[];
201
226
  }>;
202
227
 
203
228
  type OrderConfirmDialogProps = {
@@ -239,4 +264,4 @@ type SymbolBadgeProps = {
239
264
  };
240
265
  declare const SymbolBadge: FC<SymbolBadgeProps>;
241
266
 
242
- export { AdditionalInfo, FeesWidget, LTVRiskTooltipWidget, OrderConfirmDialog, OrderEntry, OrderEntryWidget, SymbolBadge, useOrderEntryScript };
267
+ export { AdditionalInfo, type ExtraTradeEntryPanel, FeesWidget, LTVRiskTooltipWidget, OrderConfirmDialog, OrderEntry, OrderEntryWidget, SymbolBadge, useOrderEntryScript };
package/dist/index.js CHANGED
@@ -1434,10 +1434,35 @@ orderlyUi.registerSimpleDialog(scaledOrderConfirmDialogId, ScaledOrderConfirmWid
1434
1434
  // className: "oui-p-0",
1435
1435
  }
1436
1436
  });
1437
+ var EXTRA_VALUE_PREFIX = "extra:";
1437
1438
  var OrderTypeSelect = (props) => {
1438
1439
  const { t } = orderlyI18n.useTranslation();
1439
1440
  const { isMobile } = orderlyUi.useScreen();
1440
- const { marketOrderDisabled = false, marketOrderDisabledTooltip } = props;
1441
+ const {
1442
+ marketOrderDisabled = false,
1443
+ marketOrderDisabledTooltip,
1444
+ extraOptions,
1445
+ selectedExtraId,
1446
+ onExtraSelect
1447
+ } = props;
1448
+ const extraEntries = React4.useMemo(
1449
+ () => (extraOptions ?? []).map((opt) => ({
1450
+ label: opt.label,
1451
+ value: `${EXTRA_VALUE_PREFIX}${opt.id}`,
1452
+ extraId: opt.id
1453
+ })),
1454
+ [extraOptions]
1455
+ );
1456
+ const routeAdvancedChange = (value) => {
1457
+ if (value.startsWith(EXTRA_VALUE_PREFIX)) {
1458
+ const id = value.slice(EXTRA_VALUE_PREFIX.length);
1459
+ onExtraSelect?.(id);
1460
+ return;
1461
+ }
1462
+ onExtraSelect?.(null);
1463
+ props.onChange(value);
1464
+ };
1465
+ const advancedValue = selectedExtraId ? `${EXTRA_VALUE_PREFIX}${selectedExtraId}` : props.type;
1441
1466
  const allOptions = React4.useMemo(() => {
1442
1467
  return [
1443
1468
  { label: t("orderEntry.orderType.limitOrder"), value: orderlyTypes.OrderType.LIMIT },
@@ -1457,9 +1482,12 @@ var OrderTypeSelect = (props) => {
1457
1482
  {
1458
1483
  label: t("orderEntry.orderType.trailingStop"),
1459
1484
  value: orderlyTypes.OrderType.TRAILING_STOP
1460
- }
1485
+ },
1486
+ // Host-provided extras (e.g. grid bot) appear at the bottom of the
1487
+ // mobile dropdown.
1488
+ ...extraEntries.map((e) => ({ label: e.label, value: e.value }))
1461
1489
  ];
1462
- }, [t]);
1490
+ }, [t, extraEntries]);
1463
1491
  const advancedOptions = React4.useMemo(() => {
1464
1492
  return [
1465
1493
  {
@@ -1474,9 +1502,12 @@ var OrderTypeSelect = (props) => {
1474
1502
  {
1475
1503
  label: t("orderEntry.orderType.trailingStop"),
1476
1504
  value: orderlyTypes.OrderType.TRAILING_STOP
1477
- }
1505
+ },
1506
+ // Host-provided extras (e.g. grid bot) appear at the bottom of the
1507
+ // Advanced desktop dropdown.
1508
+ ...extraEntries.map((e) => ({ label: e.label, value: e.value }))
1478
1509
  ];
1479
- }, [t]);
1510
+ }, [t, extraEntries]);
1480
1511
  const displayLabelMap = React4.useMemo(() => {
1481
1512
  return {
1482
1513
  [orderlyTypes.OrderType.LIMIT]: t("orderEntry.orderType.limit"),
@@ -1499,8 +1530,11 @@ var OrderTypeSelect = (props) => {
1499
1530
  "oui-bg-base-7 oui-text-base-contrast-36"
1500
1531
  );
1501
1532
  const handleChange = (type) => {
1533
+ if (selectedExtraId) onExtraSelect?.(null);
1502
1534
  props.onChange(type);
1503
1535
  };
1536
+ const limitSelected = !selectedExtraId && props.type === orderlyTypes.OrderType.LIMIT;
1537
+ const marketSelected = !selectedExtraId && props.type === orderlyTypes.OrderType.MARKET;
1504
1538
  return /* @__PURE__ */ jsxRuntime.jsxs(
1505
1539
  "div",
1506
1540
  {
@@ -1511,8 +1545,8 @@ var OrderTypeSelect = (props) => {
1511
1545
  "button",
1512
1546
  {
1513
1547
  type: "button",
1514
- className: props.type === orderlyTypes.OrderType.LIMIT ? selectedButtonClassName : unselectedButtonClassName,
1515
- "aria-pressed": props.type === orderlyTypes.OrderType.LIMIT,
1548
+ className: limitSelected ? selectedButtonClassName : unselectedButtonClassName,
1549
+ "aria-pressed": limitSelected,
1516
1550
  onClick: () => handleChange(orderlyTypes.OrderType.LIMIT),
1517
1551
  disabled: !props.canTrade,
1518
1552
  "data-testid": "oui-testid-orderEntry-orderType-limit",
@@ -1540,8 +1574,8 @@ var OrderTypeSelect = (props) => {
1540
1574
  "button",
1541
1575
  {
1542
1576
  type: "button",
1543
- className: props.type === orderlyTypes.OrderType.MARKET ? selectedButtonClassName : unselectedButtonClassName,
1544
- "aria-pressed": props.type === orderlyTypes.OrderType.MARKET,
1577
+ className: marketSelected ? selectedButtonClassName : unselectedButtonClassName,
1578
+ "aria-pressed": marketSelected,
1545
1579
  onClick: () => handleChange(orderlyTypes.OrderType.MARKET),
1546
1580
  disabled: !props.canTrade,
1547
1581
  "data-testid": "oui-testid-orderEntry-orderType-market",
@@ -1557,10 +1591,10 @@ var OrderTypeSelect = (props) => {
1557
1591
  orderlyUi.Select.options,
1558
1592
  {
1559
1593
  testid: "oui-testid-orderEntry-orderType-advanced-select",
1560
- currentValue: props.type,
1561
- value: props.type,
1594
+ currentValue: advancedValue,
1595
+ value: advancedValue,
1562
1596
  options: advancedOptions,
1563
- onValueChange: props.onChange,
1597
+ onValueChange: (v) => routeAdvancedChange(v),
1564
1598
  placeholder: t("trading.layout.advanced"),
1565
1599
  disabled: !props.canTrade,
1566
1600
  contentProps: {
@@ -1570,6 +1604,11 @@ var OrderTypeSelect = (props) => {
1570
1604
  trigger: "oui-bg-base-7 oui-border-none oui-h-8 oui-rounded-md"
1571
1605
  },
1572
1606
  valueFormatter: (value, option) => {
1607
+ if (typeof value === "string" && value.startsWith(EXTRA_VALUE_PREFIX)) {
1608
+ const id = value.slice(EXTRA_VALUE_PREFIX.length);
1609
+ const match = extraEntries.find((e) => e.extraId === id);
1610
+ return /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.Text, { size: "xs", className: "oui-text-base-contrast-80", children: match?.label ?? option.placeholder });
1611
+ }
1573
1612
  const isAdvanced = value === orderlyTypes.OrderType.STOP_LIMIT || value === orderlyTypes.OrderType.STOP_MARKET || value === orderlyTypes.OrderType.SCALED || value === orderlyTypes.OrderType.TRAILING_STOP;
1574
1613
  if (!isAdvanced) {
1575
1614
  return /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.Text, { size: "xs", className: "oui-text-base-contrast-80", children: option.placeholder });
@@ -1587,6 +1626,10 @@ var OrderTypeSelect = (props) => {
1587
1626
  );
1588
1627
  }
1589
1628
  const handleMobileValueChange = (value) => {
1629
+ if (value.startsWith(EXTRA_VALUE_PREFIX)) {
1630
+ onExtraSelect?.(value.slice(EXTRA_VALUE_PREFIX.length));
1631
+ return;
1632
+ }
1590
1633
  if (marketOrderDisabled && value === orderlyTypes.OrderType.MARKET && marketOrderDisabledTooltip) {
1591
1634
  orderlyUi.modal.alert({
1592
1635
  title: t("common.tips"),
@@ -1594,14 +1637,15 @@ var OrderTypeSelect = (props) => {
1594
1637
  });
1595
1638
  return;
1596
1639
  }
1640
+ if (selectedExtraId) onExtraSelect?.(null);
1597
1641
  props.onChange(value);
1598
1642
  };
1599
1643
  return /* @__PURE__ */ jsxRuntime.jsx(
1600
1644
  orderlyUi.Select.options,
1601
1645
  {
1602
1646
  testid: "oui-testid-orderEntry-orderType-button",
1603
- currentValue: props.type,
1604
- value: props.type,
1647
+ currentValue: advancedValue,
1648
+ value: advancedValue,
1605
1649
  options: mobileOptions,
1606
1650
  onValueChange: handleMobileValueChange,
1607
1651
  contentProps: {
@@ -1617,6 +1661,11 @@ var OrderTypeSelect = (props) => {
1617
1661
  )
1618
1662
  },
1619
1663
  valueFormatter: (value, option) => {
1664
+ if (typeof value === "string" && value.startsWith(EXTRA_VALUE_PREFIX)) {
1665
+ const id = value.slice(EXTRA_VALUE_PREFIX.length);
1666
+ const match = extraEntries.find((e) => e.extraId === id);
1667
+ return /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.Text, { size: "xs", className: "oui-text-base-contrast-80", children: match?.label ?? option.placeholder });
1668
+ }
1620
1669
  const item = allOptions.find((o) => o.value === value);
1621
1670
  if (!item) {
1622
1671
  return /* @__PURE__ */ jsxRuntime.jsx(orderlyUi.Text, { size: "xs", children: option.placeholder });
@@ -2505,10 +2554,13 @@ function OrderEntryHeader(props) {
2505
2554
  setOrderValue("order_type", type);
2506
2555
  },
2507
2556
  marketOrderDisabled: props.marketOrderDisabled,
2508
- marketOrderDisabledTooltip: props.marketOrderDisabledTooltip
2557
+ marketOrderDisabledTooltip: props.marketOrderDisabledTooltip,
2558
+ extraOptions: props.extraOptions,
2559
+ selectedExtraId: props.selectedExtraId,
2560
+ onExtraSelect: props.onExtraSelect
2509
2561
  }
2510
2562
  ) }),
2511
- /* @__PURE__ */ jsxRuntime.jsxs(
2563
+ !props.hideSideButtons && /* @__PURE__ */ jsxRuntime.jsxs(
2512
2564
  "div",
2513
2565
  {
2514
2566
  className: orderlyUi.cn(
@@ -5932,7 +5984,10 @@ var OrderEntry = (props) => {
5932
5984
  marketOrderDisabled: props.isSymbolPostOnly,
5933
5985
  marketOrderDisabledTooltip: t(
5934
5986
  "orderEntry.orderType.symbolPostOnly.tooltip"
5935
- )
5987
+ ),
5988
+ extraOptions: props.extraOptions,
5989
+ selectedExtraId: props.selectedExtraId,
5990
+ onExtraSelect: props.onExtraSelect
5936
5991
  }
5937
5992
  ),
5938
5993
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -6631,12 +6686,40 @@ var InjectableOrderEntry = orderlyUi.injectable(
6631
6686
  );
6632
6687
  var OrderEntryWidget = (props) => {
6633
6688
  const state = useOrderEntryScript(props);
6689
+ const [selectedExtraId, setSelectedExtraId] = React4.useState(null);
6690
+ const extras = props.extraPanels ?? [];
6691
+ const extraOptions = extras.map((e) => ({ id: e.id, label: e.label }));
6692
+ const activeExtra = selectedExtraId ? extras.find((e) => e.id === selectedExtraId) ?? null : null;
6693
+ if (activeExtra) {
6694
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oui-space-y-2 xl:oui-space-y-3", ref: props.containerRef, children: [
6695
+ /* @__PURE__ */ jsxRuntime.jsx(
6696
+ OrderEntryHeader,
6697
+ {
6698
+ symbol: props.symbol,
6699
+ canTrade: state.canTrade,
6700
+ side: state.side,
6701
+ order_type: state.formattedOrder.order_type,
6702
+ setOrderValue: state.manualSetOrderValue,
6703
+ symbolLeverage: state.symbolLeverage,
6704
+ marginMode: state.marginMode,
6705
+ extraOptions,
6706
+ selectedExtraId,
6707
+ onExtraSelect: setSelectedExtraId,
6708
+ hideSideButtons: activeExtra.hideSideButtons
6709
+ }
6710
+ ),
6711
+ activeExtra.render({ symbol: props.symbol })
6712
+ ] });
6713
+ }
6634
6714
  return /* @__PURE__ */ jsxRuntime.jsx(
6635
6715
  InjectableOrderEntry,
6636
6716
  {
6637
6717
  ...state,
6638
6718
  containerRef: props.containerRef,
6639
- disableFeatures: props.disableFeatures
6719
+ disableFeatures: props.disableFeatures,
6720
+ extraOptions,
6721
+ selectedExtraId,
6722
+ onExtraSelect: setSelectedExtraId
6640
6723
  }
6641
6724
  );
6642
6725
  };