@orderly.network/hooks 3.0.4-alpha.4 → 3.1.0-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.d.mts CHANGED
@@ -170,7 +170,7 @@ declare global {
170
170
  };
171
171
  }
172
172
  }
173
- declare const _default: "3.0.4-alpha.4";
173
+ declare const _default: "3.1.0-alpha.0";
174
174
 
175
175
  declare const fetcher: (url: string, init: RequestInit | undefined, queryOptions: useQueryOptions<any>) => Promise<any>;
176
176
  type useQueryOptions<T> = SWRConfiguration & {
@@ -2406,6 +2406,7 @@ type PosterLayoutConfig = {
2406
2406
  updateTime?: layoutInfo;
2407
2407
  };
2408
2408
  type DrawOptions = {
2409
+ direction?: "ltr" | "rtl";
2409
2410
  /**
2410
2411
  * Color of common text
2411
2412
  */
package/dist/index.d.ts CHANGED
@@ -170,7 +170,7 @@ declare global {
170
170
  };
171
171
  }
172
172
  }
173
- declare const _default: "3.0.4-alpha.4";
173
+ declare const _default: "3.1.0-alpha.0";
174
174
 
175
175
  declare const fetcher: (url: string, init: RequestInit | undefined, queryOptions: useQueryOptions<any>) => Promise<any>;
176
176
  type useQueryOptions<T> = SWRConfiguration & {
@@ -2406,6 +2406,7 @@ type PosterLayoutConfig = {
2406
2406
  updateTime?: layoutInfo;
2407
2407
  };
2408
2408
  type DrawOptions = {
2409
+ direction?: "ltr" | "rtl";
2409
2410
  /**
2410
2411
  * Color of common text
2411
2412
  */
package/dist/index.js CHANGED
@@ -76,9 +76,9 @@ function useMarketCategoriesConfig() {
76
76
  // src/version.ts
77
77
  if (typeof window !== "undefined") {
78
78
  window.__ORDERLY_VERSION__ = window.__ORDERLY_VERSION__ || {};
79
- window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "3.0.4-alpha.4";
79
+ window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "3.1.0-alpha.0";
80
80
  }
81
- var version_default = "3.0.4-alpha.4";
81
+ var version_default = "3.1.0-alpha.0";
82
82
  var fetcher = (url, init2 = {}, queryOptions) => net.get(url, init2, queryOptions?.formatter);
83
83
  var noCacheConfig = {
84
84
  dedupingInterval: 0,
@@ -7420,6 +7420,7 @@ var useLeverageBySymbol = (symbol, marginMode) => {
7420
7420
  function useMaxQty(symbol, side, reduceOnlyOrOptions, marginMode) {
7421
7421
  const reduceOnly = typeof reduceOnlyOrOptions === "object" && reduceOnlyOrOptions !== null ? reduceOnlyOrOptions.reduceOnly ?? false : reduceOnlyOrOptions ?? false;
7422
7422
  const finalMarginMode = typeof reduceOnlyOrOptions === "object" && reduceOnlyOrOptions !== null ? reduceOnlyOrOptions.marginMode ?? types.MarginMode.CROSS : marginMode ?? types.MarginMode.CROSS;
7423
+ const currentOrderReferencePrice = typeof reduceOnlyOrOptions === "object" && reduceOnlyOrOptions !== null && typeof reduceOnlyOrOptions.currentOrderReferencePrice === "number" && reduceOnlyOrOptions.currentOrderReferencePrice > 0 ? reduceOnlyOrOptions.currentOrderReferencePrice : void 0;
7423
7424
  const positions3 = usePositions();
7424
7425
  const accountInfo = useAccountInfo();
7425
7426
  const symbolInfo = useSymbolsInfo();
@@ -7460,18 +7461,18 @@ function useMaxQty(symbol, side, reduceOnlyOrOptions, marginMode) {
7460
7461
  const pendingLongOrders = buyOrdersQty > 0 ? [{ referencePrice: markPrice, quantity: buyOrdersQty }] : [];
7461
7462
  const pendingSellOrders = sellOrdersQty > 0 ? [{ referencePrice: markPrice, quantity: sellOrdersQty }] : [];
7462
7463
  const markPriceDecimal = new utils.Decimal(markPrice);
7463
- const leverageDecimal = new utils.Decimal(leverage);
7464
- const isoOrderFrozenLong = buyOrdersQty > 0 ? markPriceDecimal.mul(buyOrdersQty).div(leverageDecimal).toNumber() : 0;
7465
- const isoOrderFrozenShort = sellOrdersQty > 0 ? markPriceDecimal.mul(sellOrdersQty).div(leverageDecimal).toNumber() : 0;
7464
+ const marginRate = perp.account.isolatedMarginRate({ leverage });
7465
+ const isoOrderFrozenLong = buyOrdersQty > 0 ? markPriceDecimal.mul(buyOrdersQty).mul(marginRate).toNumber() : 0;
7466
+ const isoOrderFrozenShort = sellOrdersQty > 0 ? markPriceDecimal.mul(sellOrdersQty).mul(marginRate).toNumber() : 0;
7466
7467
  const symbolMaxNotional = accountInfo.max_notional?.[symbol] ?? perp.positions.maxPositionNotional({
7467
7468
  leverage,
7468
7469
  IMRFactor: IMR_Factor
7469
7470
  });
7470
- const currentOrderReferencePrice = typeof reduceOnlyOrOptions === "object" && reduceOnlyOrOptions !== null && typeof reduceOnlyOrOptions.currentOrderReferencePrice === "number" && reduceOnlyOrOptions.currentOrderReferencePrice > 0 ? reduceOnlyOrOptions.currentOrderReferencePrice : markPrice;
7471
+ const effectiveOrderReferencePrice = currentOrderReferencePrice ?? markPrice;
7471
7472
  return perp.account.maxQtyForIsolatedMargin({
7472
7473
  symbol,
7473
7474
  orderSide: side,
7474
- currentOrderReferencePrice,
7475
+ currentOrderReferencePrice: effectiveOrderReferencePrice,
7475
7476
  availableBalance,
7476
7477
  leverage,
7477
7478
  baseIMR,
@@ -7514,8 +7515,10 @@ function useMaxQty(symbol, side, reduceOnlyOrOptions, marginMode) {
7514
7515
  symbolInfo,
7515
7516
  side,
7516
7517
  totalCollateral,
7518
+ freeCollateralUSDCOnly,
7517
7519
  finalMarginMode,
7518
- symbolLeverage
7520
+ symbolLeverage,
7521
+ currentOrderReferencePrice
7519
7522
  ]);
7520
7523
  return Math.max(maxQty, 0);
7521
7524
  }
@@ -12814,15 +12817,17 @@ var BackgroundPaint = class extends BasePaint {
12814
12817
  );
12815
12818
  }
12816
12819
  async _drawImage(options) {
12820
+ const width = this.painter.width * this.painter.ratio;
12821
+ const height = this.painter.height * this.painter.ratio;
12817
12822
  return this.loadImg(options.backgroundImg).then((img) => {
12818
12823
  this.img = img;
12819
- this.ctx.drawImage(
12820
- this.img,
12821
- 0,
12822
- 0,
12823
- this.painter.width * this.painter.ratio,
12824
- this.painter.height * this.painter.ratio
12825
- );
12824
+ this.ctx.save();
12825
+ if (options.direction === "rtl") {
12826
+ this.ctx.translate(width, 0);
12827
+ this.ctx.scale(-1, 1);
12828
+ }
12829
+ this.ctx.drawImage(this.img, 0, 0, width, height);
12830
+ this.ctx.restore();
12826
12831
  });
12827
12832
  }
12828
12833
  loadImg(url) {
@@ -12885,6 +12890,7 @@ var DataPaint = class extends BasePaint {
12885
12890
  this.BROKER_BADGE_HEIGHT = 18;
12886
12891
  this.BROKER_BADGE_PADDING_X = 8;
12887
12892
  this.BROKER_BADGE_RADIUS = 4;
12893
+ this.ITEM_GAP = 7;
12888
12894
  }
12889
12895
  formatMarginMode(marginMode) {
12890
12896
  return marginMode === types.MarginMode.ISOLATED ? "Isolated" : "Cross";
@@ -12932,7 +12938,9 @@ var DataPaint = class extends BasePaint {
12932
12938
  color: layout.color,
12933
12939
  fontSize: this._ratio(layout.fontSize),
12934
12940
  top: this._ratio(position.top),
12935
- left: this._ratio(position.left),
12941
+ left: this.inlineStart(options, position.left),
12942
+ textAlign: this.inlineStartAlign(options),
12943
+ direction: this.textDirection(options),
12936
12944
  textBaseline: "top",
12937
12945
  fontFamily: options.fontFamily
12938
12946
  });
@@ -12943,126 +12951,63 @@ var DataPaint = class extends BasePaint {
12943
12951
  options
12944
12952
  );
12945
12953
  const { position, fontSize = 14 } = layout;
12946
- let left = this._ratio(position.left);
12954
+ let cursor = this.inlineStart(options, position.left);
12947
12955
  const top = layout.position.top + offsetTop + this.transformTop;
12948
- let prevElementBoundingBox = {};
12956
+ const items = [];
12949
12957
  if (typeof options.data?.position.side !== "undefined") {
12950
- prevElementBoundingBox = this._drawText(options.data.position.side, {
12958
+ items.push({
12959
+ kind: "text",
12960
+ text: options.data.position.side,
12951
12961
  color: options.data?.position.side.toUpperCase() === "LONG" ? options.profitColor || this.DEFAULT_PROFIT_COLOR : options.lossColor || this.DEFAULT_LOSS_COLOR,
12952
- left,
12953
- top: this._ratio(top),
12954
- fontSize: this._ratio(fontSize),
12955
- fontFamily: options.fontFamily
12962
+ fontSize: this._ratio(fontSize)
12956
12963
  });
12957
12964
  }
12958
12965
  if (typeof options.data?.position.symbol !== "undefined") {
12959
- left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
12960
- if (prevElementBoundingBox.width) {
12961
- prevElementBoundingBox = this._drawText("|", {
12962
- color: "rgba(255,255,255,0.2)",
12963
- left,
12964
- top: this._ratio(top),
12965
- fontSize: this._ratio(fontSize),
12966
- fontFamily: options.fontFamily
12967
- });
12968
- }
12969
- left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
12970
- prevElementBoundingBox = this._drawText(options.data?.position.symbol, {
12966
+ items.push({
12967
+ kind: "text",
12968
+ text: options.data.position.symbol,
12971
12969
  color: layout.color,
12972
- left,
12973
- top: this._ratio(top),
12974
- fontSize: this._ratio(fontSize),
12975
- fontFamily: options.fontFamily
12970
+ fontSize: this._ratio(fontSize)
12971
+ });
12972
+ }
12973
+ const brokerName = options.data?.position.brokerName?.trim();
12974
+ if (brokerName) {
12975
+ items.push({
12976
+ kind: "badge",
12977
+ text: brokerName,
12978
+ fontSize: this._ratio(12),
12979
+ fontWeight: 600
12976
12980
  });
12977
- const brokerName = options.data?.position.brokerName?.trim();
12978
- if (brokerName) {
12979
- left += (prevElementBoundingBox.width ?? 0) + this._ratio(10);
12980
- const badgeHeight = this._ratio(this.BROKER_BADGE_HEIGHT);
12981
- const badgePaddingX = this._ratio(this.BROKER_BADGE_PADDING_X);
12982
- const badgeRadius = this._ratio(this.BROKER_BADGE_RADIUS);
12983
- const badgeFontSize = this._ratio(12);
12984
- const badgeFontWeight = 600;
12985
- const textMetrics = this._drawText(
12986
- brokerName,
12987
- {
12988
- left: 0,
12989
- top: 0,
12990
- fontSize: badgeFontSize,
12991
- fontWeight: badgeFontWeight,
12992
- fontFamily: options.fontFamily
12993
- },
12994
- true
12995
- );
12996
- const badgeWidth = (textMetrics.width ?? 0) + badgePaddingX * 2;
12997
- const badgeTop = this._ratio(top) - badgeHeight / 2;
12998
- this._fillRoundedRect(
12999
- left,
13000
- badgeTop,
13001
- badgeWidth,
13002
- badgeHeight,
13003
- badgeRadius,
13004
- "rgba(255,255,255,0.06)"
13005
- );
13006
- this._drawText(brokerName, {
13007
- color: "rgba(255,255,255,0.36)",
13008
- left: left + badgePaddingX,
13009
- top: badgeTop + badgeHeight / 2,
13010
- fontSize: badgeFontSize,
13011
- fontWeight: badgeFontWeight,
13012
- fontFamily: options.fontFamily,
13013
- textBaseline: "middle"
13014
- });
13015
- prevElementBoundingBox = {
13016
- ...prevElementBoundingBox,
13017
- width: badgeWidth
13018
- };
13019
- }
13020
12981
  }
13021
12982
  const marginMode = options.data?.position.marginMode;
13022
12983
  if (marginMode) {
13023
- left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
13024
- if (prevElementBoundingBox.width) {
13025
- prevElementBoundingBox = this._drawText("|", {
13026
- color: "rgba(255,255,255,0.2)",
13027
- left,
13028
- top: this._ratio(top),
13029
- fontSize: this._ratio(fontSize),
13030
- fontFamily: options.fontFamily
13031
- });
13032
- }
13033
- left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
13034
- const marginModeText = this.formatMarginMode(marginMode);
13035
- prevElementBoundingBox = this._drawText(marginModeText, {
12984
+ items.push({
12985
+ kind: "text",
12986
+ text: this.formatMarginMode(marginMode),
13036
12987
  color: layout.color,
13037
- left,
13038
- top: this._ratio(top),
13039
- fontSize: this._ratio(fontSize),
13040
- fontFamily: options.fontFamily
12988
+ fontSize: this._ratio(fontSize)
13041
12989
  });
13042
12990
  }
13043
12991
  if (typeof options.data?.position.leverage !== "undefined") {
13044
- left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
13045
- if (prevElementBoundingBox.width) {
13046
- prevElementBoundingBox = this._drawText("|", {
13047
- color: "rgba(255,255,255,0.2)",
13048
- left,
13049
- top: this._ratio(top),
13050
- fontSize: this._ratio(fontSize),
13051
- fontFamily: options.fontFamily
13052
- });
13053
- }
13054
- left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
13055
- prevElementBoundingBox = this._drawText(
13056
- `${options.data?.position.leverage}X`,
13057
- {
13058
- color: layout.color,
13059
- left,
13060
- top: this._ratio(top),
13061
- fontSize: this._ratio(fontSize),
13062
- fontFamily: options.fontFamily
13063
- }
13064
- );
12992
+ items.push({
12993
+ kind: "text",
12994
+ text: `${options.data.position.leverage}X`,
12995
+ color: layout.color,
12996
+ fontSize: this._ratio(fontSize)
12997
+ });
13065
12998
  }
12999
+ const topPx = this._ratio(top);
13000
+ items.forEach((item, index) => {
13001
+ cursor = this.drawInlineItem(options, item, cursor, topPx);
13002
+ if (index < items.length - 1) {
13003
+ cursor = this.drawInlineSeparator(
13004
+ options,
13005
+ cursor,
13006
+ topPx,
13007
+ this._ratio(fontSize)
13008
+ );
13009
+ }
13010
+ });
13066
13011
  }
13067
13012
  _fillRoundedRect(x, y, width, height, radius, color) {
13068
13013
  const r = Math.min(radius, width / 2, height / 2);
@@ -13084,7 +13029,7 @@ var DataPaint = class extends BasePaint {
13084
13029
  options
13085
13030
  );
13086
13031
  const { position } = layout;
13087
- let left = this._ratio(position.left);
13032
+ let cursor = this.inlineStart(options, position.left);
13088
13033
  let prevElementBoundingBox = {};
13089
13034
  const top = (position.top ?? 0) + offsetTop + this.transformTop;
13090
13035
  if (typeof options.data?.position.ROI !== "undefined") {
@@ -13093,11 +13038,13 @@ var DataPaint = class extends BasePaint {
13093
13038
  `${prefix}${utils.commify(options.data?.position.ROI)}%`,
13094
13039
  {
13095
13040
  color: prefix === "+" ? options.profitColor || this.DEFAULT_PROFIT_COLOR : options.lossColor || this.DEFAULT_LOSS_COLOR,
13096
- left,
13041
+ left: cursor,
13097
13042
  top: this._ratio(top),
13098
13043
  fontSize: this._ratio(layout.fontSize),
13099
13044
  fontWeight: 700,
13100
- fontFamily: options.fontFamily
13045
+ fontFamily: options.fontFamily,
13046
+ textAlign: this.inlineStartAlign(options),
13047
+ direction: this.textDirection(options)
13101
13048
  }
13102
13049
  );
13103
13050
  }
@@ -13106,21 +13053,27 @@ var DataPaint = class extends BasePaint {
13106
13053
  let text = `${prefix}${utils.commify(options.data?.position.pnl)} ${options.data?.position.currency}`;
13107
13054
  let fontWeight = 600;
13108
13055
  if (prevElementBoundingBox.width) {
13109
- left += (prevElementBoundingBox.width ?? 0) + this._ratio(8);
13056
+ cursor = this.advanceCursor(
13057
+ options,
13058
+ cursor,
13059
+ (prevElementBoundingBox.width ?? 0) + this._ratio(8)
13060
+ );
13110
13061
  text = `(${text})`;
13111
13062
  } else {
13112
- left = this._ratio(position.left);
13063
+ cursor = this.inlineStart(options, position.left);
13113
13064
  fontWeight = 700;
13114
13065
  }
13115
13066
  const color = typeof options.data.position.ROI === "undefined" ? prefix === "+" ? options.profitColor || this.DEFAULT_PROFIT_COLOR : options.lossColor || this.DEFAULT_LOSS_COLOR : layout.secondaryColor;
13116
13067
  const fontSize = typeof options.data.position.ROI === "undefined" ? this._ratio(layout.fontSize) : this._ratio(layout.secondaryFontSize);
13117
13068
  prevElementBoundingBox = this._drawText(text, {
13118
13069
  color,
13119
- left,
13070
+ left: cursor,
13120
13071
  top: this._ratio(top),
13121
13072
  fontSize,
13122
13073
  fontWeight,
13123
- fontFamily: options.fontFamily
13074
+ fontFamily: options.fontFamily,
13075
+ textAlign: this.inlineStartAlign(options),
13076
+ direction: this.textDirection(options)
13124
13077
  });
13125
13078
  }
13126
13079
  }
@@ -13134,22 +13087,27 @@ var DataPaint = class extends BasePaint {
13134
13087
  (options.data?.position.informations.length ?? 0) === 2;
13135
13088
  const col = informations.length > 4 ? 3 : 2;
13136
13089
  informations.forEach((info, index) => {
13137
- const left = position.left + index % col * this.positionInfoCellWidth;
13090
+ const colIndex = index % col;
13091
+ const inlineOffset = position.left + colIndex * this.positionInfoCellWidth;
13138
13092
  const top = position.top + Math.floor(index / col) * 38 + this.transformTop;
13139
13093
  this._drawText(info.title, {
13140
- left: this._ratio(left),
13094
+ left: this.inlineStart(options, inlineOffset),
13141
13095
  top: this._ratio(top),
13142
13096
  fontSize: this._ratio(10),
13143
13097
  color: layout.labelColor,
13144
- fontFamily: options.fontFamily
13098
+ fontFamily: options.fontFamily,
13099
+ textAlign: this.inlineStartAlign(options),
13100
+ direction: this.textDirection(options)
13145
13101
  });
13146
13102
  this._drawText(info.value, {
13147
- left: this._ratio(left),
13103
+ left: this.inlineStart(options, inlineOffset),
13148
13104
  top: this._ratio(top + 17),
13149
13105
  fontSize: this._ratio(layout.fontSize),
13150
13106
  fontWeight: 500,
13151
13107
  color: layout.color,
13152
- fontFamily: options.fontFamily
13108
+ fontFamily: options.fontFamily,
13109
+ textAlign: this.inlineStartAlign(options),
13110
+ direction: this.textDirection(options)
13153
13111
  });
13154
13112
  });
13155
13113
  }
@@ -13164,13 +13122,14 @@ var DataPaint = class extends BasePaint {
13164
13122
  return this._drawText(
13165
13123
  options.data?.domain,
13166
13124
  {
13167
- left: !hasReferral ? this._ratio(position.left) : this._ratio(this.painter.width - 20),
13125
+ left: !hasReferral ? this.inlineStart(options, position.left) : this.inlineEnd(options, 20),
13168
13126
  top: !hasReferral ? this._ratio(top) : this._ratio(this.painter.height - 16),
13169
13127
  fontSize: this._ratio(layout.fontSize),
13170
13128
  color: options.brandColor ?? this.DEFAULT_PROFIT_COLOR,
13171
13129
  fontFamily: options.fontFamily,
13172
13130
  textBaseline: layout.textBaseline,
13173
- textAlign: !hasReferral ? layout.textAlign : "end",
13131
+ textAlign: !hasReferral ? this.inlineStartAlign(options) : this.inlineEndAlign(options),
13132
+ direction: this.textDirection(options),
13174
13133
  fontWeight: 600
13175
13134
  },
13176
13135
  onlyMeasure
@@ -13184,10 +13143,10 @@ var DataPaint = class extends BasePaint {
13184
13143
  const { position } = layout;
13185
13144
  const hasReferral = this.hasReferral(options);
13186
13145
  let top = this.painter.height - position.bottom;
13187
- let left = this._ratio(position.left);
13146
+ let left = this.inlineStart(options, position.left);
13188
13147
  if (hasReferral) {
13189
13148
  const metrics = this.drawDomainUrl(options, true);
13190
- left = this._ratio(this.painter.width) - metrics.width - this._ratio(8 + position.left);
13149
+ left = this.inlineStart(options, position.left + 8) + (this.isRTL(options) ? metrics.width : -metrics.width);
13191
13150
  top = this.painter.height - position.bottom;
13192
13151
  }
13193
13152
  this._drawText(
@@ -13199,9 +13158,10 @@ var DataPaint = class extends BasePaint {
13199
13158
  fontSize: this._ratio(layout.fontSize),
13200
13159
  color: layout.color,
13201
13160
  // color: "red",
13202
- textAlign: !hasReferral ? layout.textAlign : "end",
13161
+ textAlign: !hasReferral ? this.inlineStartAlign(options) : this.inlineEndAlign(options),
13203
13162
  fontFamily: options.fontFamily,
13204
- textBaseline: layout.textBaseline
13163
+ textBaseline: layout.textBaseline,
13164
+ direction: this.textDirection(options)
13205
13165
  }
13206
13166
  );
13207
13167
  }
@@ -13223,36 +13183,44 @@ var DataPaint = class extends BasePaint {
13223
13183
  const searchParams = url.searchParams;
13224
13184
  searchParams.append("ref", options.data.referral.code);
13225
13185
  url.search = searchParams.toString();
13186
+ const qrSize = this._ratio(this.QRCODE_SIZE);
13187
+ const qrLeft = this.isRTL(options) ? this.inlineStart(options, position.left) - qrSize : this.inlineStart(options, position.left);
13226
13188
  qrPaint(this.ctx, {
13227
13189
  size: this._ratio(this.QRCODE_SIZE),
13228
13190
  padding: this._ratio(2),
13229
- left: this._ratio(position.left),
13191
+ left: qrLeft,
13230
13192
  top: this._ratio(top - this.QRCODE_SIZE),
13231
13193
  data: `${url.toString()}`
13232
13194
  });
13233
13195
  this._drawText(options.data.referral.slogan, {
13234
- left: this._ratio(position.left + 66),
13196
+ left: this.inlineStart(options, position.left + 66),
13235
13197
  top: this._ratio(top - this.QRCODE_SIZE),
13236
13198
  fontSize: this._ratio(14),
13237
13199
  color: options.brandColor ?? this.DEFAULT_PROFIT_COLOR,
13238
13200
  fontFamily: options.fontFamily,
13239
- textBaseline: "top"
13201
+ textBaseline: "top",
13202
+ textAlign: this.inlineStartAlign(options),
13203
+ direction: this.textDirection(options)
13240
13204
  });
13241
13205
  this._drawText("Referral Code", {
13242
- left: this._ratio(position.left + 66),
13206
+ left: this.inlineStart(options, position.left + 66),
13243
13207
  top: this._ratio(top - 29),
13244
13208
  fontSize: this._ratio(12),
13245
13209
  color: layout.color,
13246
13210
  fontFamily: options.fontFamily,
13247
- textBaseline: "middle"
13211
+ textBaseline: "middle",
13212
+ textAlign: this.inlineStartAlign(options),
13213
+ direction: this.textDirection(options)
13248
13214
  });
13249
13215
  this._drawText(options.data.referral.code, {
13250
- left: this._ratio(position.left + 66),
13216
+ left: this.inlineStart(options, position.left + 66),
13251
13217
  top: this._ratio(top),
13252
13218
  fontSize: this._ratio(16),
13253
13219
  color: messageLayout.color,
13254
13220
  fontFamily: options.fontFamily,
13255
- textBaseline: "bottom"
13221
+ textBaseline: "bottom",
13222
+ textAlign: this.inlineStartAlign(options),
13223
+ direction: this.textDirection(options)
13256
13224
  });
13257
13225
  }
13258
13226
  _drawText(str, options, onlyMeasure = false) {
@@ -13264,13 +13232,15 @@ var DataPaint = class extends BasePaint {
13264
13232
  fontWeight = 500,
13265
13233
  color = "black",
13266
13234
  textBaseline = "middle",
13267
- textAlign = "start"
13235
+ textAlign = "start",
13236
+ direction = "ltr"
13268
13237
  } = options ?? {};
13269
13238
  this.ctx.save();
13270
13239
  this.ctx.font = `${fontWeight} ${fontSize}px ${options?.fontFamily}`;
13271
13240
  this.ctx.fillStyle = color;
13272
13241
  this.ctx.textBaseline = textBaseline;
13273
13242
  this.ctx.textAlign = textAlign;
13243
+ this.ctx.direction = direction;
13274
13244
  boundingBox = this.ctx.measureText(str);
13275
13245
  if (!onlyMeasure) {
13276
13246
  this.ctx.fillText(str, left, top);
@@ -13284,6 +13254,98 @@ var DataPaint = class extends BasePaint {
13284
13254
  _ratio(num) {
13285
13255
  return num * this.painter.ratio;
13286
13256
  }
13257
+ canvasWidth() {
13258
+ return this._ratio(this.painter.width);
13259
+ }
13260
+ textDirection(options) {
13261
+ return this.isRTL(options) ? "rtl" : "ltr";
13262
+ }
13263
+ isRTL(options) {
13264
+ return options.direction === "rtl";
13265
+ }
13266
+ inlineStart(options, value) {
13267
+ return this.isRTL(options) ? this.canvasWidth() - this._ratio(value) : this._ratio(value);
13268
+ }
13269
+ inlineEnd(options, value) {
13270
+ return this.isRTL(options) ? this._ratio(value) : this.canvasWidth() - this._ratio(value);
13271
+ }
13272
+ inlineStartAlign(options) {
13273
+ return this.isRTL(options) ? "right" : "left";
13274
+ }
13275
+ inlineEndAlign(options) {
13276
+ return this.isRTL(options) ? "left" : "right";
13277
+ }
13278
+ advanceCursor(options, cursor, width) {
13279
+ return this.isRTL(options) ? cursor - width : cursor + width;
13280
+ }
13281
+ drawInlineSeparator(options, cursor, top, fontSize) {
13282
+ const gap = this._ratio(this.ITEM_GAP);
13283
+ const separatorMetrics = this._drawText("|", {
13284
+ color: "rgba(255,255,255,0.2)",
13285
+ left: this.advanceCursor(options, cursor, gap),
13286
+ top,
13287
+ fontSize,
13288
+ fontFamily: options.fontFamily,
13289
+ textAlign: this.inlineStartAlign(options),
13290
+ direction: this.textDirection(options)
13291
+ });
13292
+ return this.advanceCursor(
13293
+ options,
13294
+ this.advanceCursor(options, cursor, gap),
13295
+ (separatorMetrics.width ?? 0) + gap
13296
+ );
13297
+ }
13298
+ drawInlineItem(options, item, cursor, top) {
13299
+ if (item.kind === "text") {
13300
+ const metrics = this._drawText(item.text, {
13301
+ color: item.color,
13302
+ left: cursor,
13303
+ top,
13304
+ fontSize: item.fontSize,
13305
+ fontWeight: item.fontWeight,
13306
+ fontFamily: options.fontFamily,
13307
+ textAlign: this.inlineStartAlign(options),
13308
+ direction: this.textDirection(options)
13309
+ });
13310
+ return this.advanceCursor(options, cursor, metrics.width ?? 0);
13311
+ }
13312
+ const badgeHeight = this._ratio(this.BROKER_BADGE_HEIGHT);
13313
+ const badgePaddingX = this._ratio(this.BROKER_BADGE_PADDING_X);
13314
+ const badgeRadius = this._ratio(this.BROKER_BADGE_RADIUS);
13315
+ const textMetrics = this._drawText(
13316
+ item.text,
13317
+ {
13318
+ left: 0,
13319
+ top: 0,
13320
+ fontSize: item.fontSize,
13321
+ fontWeight: item.fontWeight ?? 600,
13322
+ direction: this.textDirection(options)
13323
+ },
13324
+ true
13325
+ );
13326
+ const badgeWidth = (textMetrics.width ?? 0) + badgePaddingX * 2;
13327
+ const badgeTop = top - badgeHeight / 2;
13328
+ const badgeLeft = this.isRTL(options) ? cursor - badgeWidth : cursor;
13329
+ this._fillRoundedRect(
13330
+ badgeLeft,
13331
+ badgeTop,
13332
+ badgeWidth,
13333
+ badgeHeight,
13334
+ badgeRadius,
13335
+ "rgba(255,255,255,0.06)"
13336
+ );
13337
+ this._drawText(item.text, {
13338
+ color: "rgba(255,255,255,0.36)",
13339
+ left: this.isRTL(options) ? badgeLeft + badgeWidth - badgePaddingX : badgeLeft + badgePaddingX,
13340
+ top: badgeTop + badgeHeight / 2,
13341
+ fontSize: item.fontSize,
13342
+ fontWeight: item.fontWeight ?? 600,
13343
+ textBaseline: "middle",
13344
+ textAlign: this.inlineStartAlign(options),
13345
+ direction: this.textDirection(options)
13346
+ });
13347
+ return this.advanceCursor(options, cursor, badgeWidth);
13348
+ }
13287
13349
  };
13288
13350
 
13289
13351
  // src/services/painter/painter.ts
@@ -19072,20 +19134,39 @@ var useOrderEntry2 = (symbol, options = {}) => {
19072
19134
  symbolLeverage
19073
19135
  });
19074
19136
  const [estSlippage, setEstSlippage] = React.useState(null);
19137
+ const [bestAskBidSnapshot, setBestAskBidSnapshot] = React.useState([]);
19075
19138
  const [doCreateOrder, { isMutating }] = useMutation(
19076
19139
  getCreateOrderUrl(formattedOrder)
19077
19140
  );
19078
- const bestAskBid = askAndBid.current?.[0] || [];
19079
- const referencePriceFromOrder = bestAskBid.length >= 2 && formattedOrder.order_type && formattedOrder.side ? getOrderReferencePriceFromOrder(formattedOrder, bestAskBid) : null;
19141
+ const bestAskBid = bestAskBidSnapshot;
19142
+ const getReferencePriceForSide = (side) => {
19143
+ if (bestAskBid.length < 2 || !formattedOrder.order_type) {
19144
+ return null;
19145
+ }
19146
+ const referencePrice = getOrderReferencePriceFromOrder(
19147
+ {
19148
+ ...formattedOrder,
19149
+ side
19150
+ },
19151
+ bestAskBid
19152
+ );
19153
+ const slippage = Number(formattedOrder.slippage);
19154
+ if (effectiveMarginMode !== types.MarginMode.ISOLATED || side !== types.OrderSide.BUY || formattedOrder.order_type !== types.OrderType.MARKET || !referencePrice || !Number.isFinite(slippage) || slippage <= 0) {
19155
+ return referencePrice;
19156
+ }
19157
+ return new utils.Decimal(referencePrice).mul(new utils.Decimal(1).add(new utils.Decimal(slippage).div(100))).toNumber();
19158
+ };
19159
+ const buyReferencePriceFromOrder = getReferencePriceForSide(types.OrderSide.BUY);
19160
+ const sellReferencePriceFromOrder = getReferencePriceForSide(types.OrderSide.SELL);
19080
19161
  const maxBuyQtyValue = useMaxQty(symbol, types.OrderSide.BUY, {
19081
19162
  reduceOnly: formattedOrder.reduce_only,
19082
19163
  marginMode: effectiveMarginMode,
19083
- currentOrderReferencePrice: referencePriceFromOrder && referencePriceFromOrder > 0 ? referencePriceFromOrder : void 0
19164
+ currentOrderReferencePrice: buyReferencePriceFromOrder && buyReferencePriceFromOrder > 0 ? buyReferencePriceFromOrder : void 0
19084
19165
  });
19085
19166
  const maxSellQtyValue = useMaxQty(symbol, types.OrderSide.SELL, {
19086
19167
  reduceOnly: formattedOrder.reduce_only,
19087
19168
  marginMode: effectiveMarginMode,
19088
- currentOrderReferencePrice: referencePriceFromOrder && referencePriceFromOrder > 0 ? referencePriceFromOrder : void 0
19169
+ currentOrderReferencePrice: sellReferencePriceFromOrder && sellReferencePriceFromOrder > 0 ? sellReferencePriceFromOrder : void 0
19089
19170
  });
19090
19171
  const maxQtyValue = formattedOrder.side === types.OrderSide.BUY ? maxBuyQtyValue : maxSellQtyValue;
19091
19172
  const maxQty = options.maxQty ?? maxQtyValue;
@@ -19177,6 +19258,10 @@ var useOrderEntry2 = (symbol, options = {}) => {
19177
19258
  React.useEffect(() => {
19178
19259
  updateOrderPrice();
19179
19260
  }, [formattedOrder.order_type_ext, formattedOrder.level]);
19261
+ React.useEffect(() => {
19262
+ askAndBid.current = [[]];
19263
+ setBestAskBidSnapshot([]);
19264
+ }, [symbol]);
19180
19265
  const onOrderBookUpdate = useDebounce.useDebouncedCallback((data) => {
19181
19266
  const parsedData = [
19182
19267
  [data.asks?.[data.asks.length - 1]?.[0], data.bids?.[0]?.[0]],
@@ -19186,6 +19271,10 @@ var useOrderEntry2 = (symbol, options = {}) => {
19186
19271
  [data.asks?.[data.asks.length - 5]?.[0], data.bids?.[4]?.[0]]
19187
19272
  ];
19188
19273
  askAndBid.current = parsedData;
19274
+ const nextBestAskBid = parsedData[0] || [];
19275
+ setBestAskBidSnapshot(
19276
+ (prev) => prev[0] === nextBestAskBid[0] && prev[1] === nextBestAskBid[1] ? prev : nextBestAskBid
19277
+ );
19189
19278
  updateOrderPriceByOrderBook();
19190
19279
  updateEstSlippage(data);
19191
19280
  }, 200);