@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.mjs CHANGED
@@ -50,9 +50,9 @@ function useMarketCategoriesConfig() {
50
50
  // src/version.ts
51
51
  if (typeof window !== "undefined") {
52
52
  window.__ORDERLY_VERSION__ = window.__ORDERLY_VERSION__ || {};
53
- window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "3.0.4-alpha.4";
53
+ window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "3.1.0-alpha.0";
54
54
  }
55
- var version_default = "3.0.4-alpha.4";
55
+ var version_default = "3.1.0-alpha.0";
56
56
  var fetcher = (url, init2 = {}, queryOptions) => get(url, init2, queryOptions?.formatter);
57
57
  var noCacheConfig = {
58
58
  dedupingInterval: 0,
@@ -7394,6 +7394,7 @@ var useLeverageBySymbol = (symbol, marginMode) => {
7394
7394
  function useMaxQty(symbol, side, reduceOnlyOrOptions, marginMode) {
7395
7395
  const reduceOnly = typeof reduceOnlyOrOptions === "object" && reduceOnlyOrOptions !== null ? reduceOnlyOrOptions.reduceOnly ?? false : reduceOnlyOrOptions ?? false;
7396
7396
  const finalMarginMode = typeof reduceOnlyOrOptions === "object" && reduceOnlyOrOptions !== null ? reduceOnlyOrOptions.marginMode ?? MarginMode.CROSS : marginMode ?? MarginMode.CROSS;
7397
+ const currentOrderReferencePrice = typeof reduceOnlyOrOptions === "object" && reduceOnlyOrOptions !== null && typeof reduceOnlyOrOptions.currentOrderReferencePrice === "number" && reduceOnlyOrOptions.currentOrderReferencePrice > 0 ? reduceOnlyOrOptions.currentOrderReferencePrice : void 0;
7397
7398
  const positions3 = usePositions();
7398
7399
  const accountInfo = useAccountInfo();
7399
7400
  const symbolInfo = useSymbolsInfo();
@@ -7434,18 +7435,18 @@ function useMaxQty(symbol, side, reduceOnlyOrOptions, marginMode) {
7434
7435
  const pendingLongOrders = buyOrdersQty > 0 ? [{ referencePrice: markPrice, quantity: buyOrdersQty }] : [];
7435
7436
  const pendingSellOrders = sellOrdersQty > 0 ? [{ referencePrice: markPrice, quantity: sellOrdersQty }] : [];
7436
7437
  const markPriceDecimal = new Decimal(markPrice);
7437
- const leverageDecimal = new Decimal(leverage);
7438
- const isoOrderFrozenLong = buyOrdersQty > 0 ? markPriceDecimal.mul(buyOrdersQty).div(leverageDecimal).toNumber() : 0;
7439
- const isoOrderFrozenShort = sellOrdersQty > 0 ? markPriceDecimal.mul(sellOrdersQty).div(leverageDecimal).toNumber() : 0;
7438
+ const marginRate = account.isolatedMarginRate({ leverage });
7439
+ const isoOrderFrozenLong = buyOrdersQty > 0 ? markPriceDecimal.mul(buyOrdersQty).mul(marginRate).toNumber() : 0;
7440
+ const isoOrderFrozenShort = sellOrdersQty > 0 ? markPriceDecimal.mul(sellOrdersQty).mul(marginRate).toNumber() : 0;
7440
7441
  const symbolMaxNotional = accountInfo.max_notional?.[symbol] ?? positions.maxPositionNotional({
7441
7442
  leverage,
7442
7443
  IMRFactor: IMR_Factor
7443
7444
  });
7444
- const currentOrderReferencePrice = typeof reduceOnlyOrOptions === "object" && reduceOnlyOrOptions !== null && typeof reduceOnlyOrOptions.currentOrderReferencePrice === "number" && reduceOnlyOrOptions.currentOrderReferencePrice > 0 ? reduceOnlyOrOptions.currentOrderReferencePrice : markPrice;
7445
+ const effectiveOrderReferencePrice = currentOrderReferencePrice ?? markPrice;
7445
7446
  return account.maxQtyForIsolatedMargin({
7446
7447
  symbol,
7447
7448
  orderSide: side,
7448
- currentOrderReferencePrice,
7449
+ currentOrderReferencePrice: effectiveOrderReferencePrice,
7449
7450
  availableBalance,
7450
7451
  leverage,
7451
7452
  baseIMR,
@@ -7488,8 +7489,10 @@ function useMaxQty(symbol, side, reduceOnlyOrOptions, marginMode) {
7488
7489
  symbolInfo,
7489
7490
  side,
7490
7491
  totalCollateral,
7492
+ freeCollateralUSDCOnly,
7491
7493
  finalMarginMode,
7492
- symbolLeverage
7494
+ symbolLeverage,
7495
+ currentOrderReferencePrice
7493
7496
  ]);
7494
7497
  return Math.max(maxQty, 0);
7495
7498
  }
@@ -12788,15 +12791,17 @@ var BackgroundPaint = class extends BasePaint {
12788
12791
  );
12789
12792
  }
12790
12793
  async _drawImage(options) {
12794
+ const width = this.painter.width * this.painter.ratio;
12795
+ const height = this.painter.height * this.painter.ratio;
12791
12796
  return this.loadImg(options.backgroundImg).then((img) => {
12792
12797
  this.img = img;
12793
- this.ctx.drawImage(
12794
- this.img,
12795
- 0,
12796
- 0,
12797
- this.painter.width * this.painter.ratio,
12798
- this.painter.height * this.painter.ratio
12799
- );
12798
+ this.ctx.save();
12799
+ if (options.direction === "rtl") {
12800
+ this.ctx.translate(width, 0);
12801
+ this.ctx.scale(-1, 1);
12802
+ }
12803
+ this.ctx.drawImage(this.img, 0, 0, width, height);
12804
+ this.ctx.restore();
12800
12805
  });
12801
12806
  }
12802
12807
  loadImg(url) {
@@ -12859,6 +12864,7 @@ var DataPaint = class extends BasePaint {
12859
12864
  this.BROKER_BADGE_HEIGHT = 18;
12860
12865
  this.BROKER_BADGE_PADDING_X = 8;
12861
12866
  this.BROKER_BADGE_RADIUS = 4;
12867
+ this.ITEM_GAP = 7;
12862
12868
  }
12863
12869
  formatMarginMode(marginMode) {
12864
12870
  return marginMode === MarginMode.ISOLATED ? "Isolated" : "Cross";
@@ -12906,7 +12912,9 @@ var DataPaint = class extends BasePaint {
12906
12912
  color: layout.color,
12907
12913
  fontSize: this._ratio(layout.fontSize),
12908
12914
  top: this._ratio(position.top),
12909
- left: this._ratio(position.left),
12915
+ left: this.inlineStart(options, position.left),
12916
+ textAlign: this.inlineStartAlign(options),
12917
+ direction: this.textDirection(options),
12910
12918
  textBaseline: "top",
12911
12919
  fontFamily: options.fontFamily
12912
12920
  });
@@ -12917,126 +12925,63 @@ var DataPaint = class extends BasePaint {
12917
12925
  options
12918
12926
  );
12919
12927
  const { position, fontSize = 14 } = layout;
12920
- let left = this._ratio(position.left);
12928
+ let cursor = this.inlineStart(options, position.left);
12921
12929
  const top = layout.position.top + offsetTop + this.transformTop;
12922
- let prevElementBoundingBox = {};
12930
+ const items = [];
12923
12931
  if (typeof options.data?.position.side !== "undefined") {
12924
- prevElementBoundingBox = this._drawText(options.data.position.side, {
12932
+ items.push({
12933
+ kind: "text",
12934
+ text: options.data.position.side,
12925
12935
  color: options.data?.position.side.toUpperCase() === "LONG" ? options.profitColor || this.DEFAULT_PROFIT_COLOR : options.lossColor || this.DEFAULT_LOSS_COLOR,
12926
- left,
12927
- top: this._ratio(top),
12928
- fontSize: this._ratio(fontSize),
12929
- fontFamily: options.fontFamily
12936
+ fontSize: this._ratio(fontSize)
12930
12937
  });
12931
12938
  }
12932
12939
  if (typeof options.data?.position.symbol !== "undefined") {
12933
- left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
12934
- if (prevElementBoundingBox.width) {
12935
- prevElementBoundingBox = this._drawText("|", {
12936
- color: "rgba(255,255,255,0.2)",
12937
- left,
12938
- top: this._ratio(top),
12939
- fontSize: this._ratio(fontSize),
12940
- fontFamily: options.fontFamily
12941
- });
12942
- }
12943
- left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
12944
- prevElementBoundingBox = this._drawText(options.data?.position.symbol, {
12940
+ items.push({
12941
+ kind: "text",
12942
+ text: options.data.position.symbol,
12945
12943
  color: layout.color,
12946
- left,
12947
- top: this._ratio(top),
12948
- fontSize: this._ratio(fontSize),
12949
- fontFamily: options.fontFamily
12944
+ fontSize: this._ratio(fontSize)
12945
+ });
12946
+ }
12947
+ const brokerName = options.data?.position.brokerName?.trim();
12948
+ if (brokerName) {
12949
+ items.push({
12950
+ kind: "badge",
12951
+ text: brokerName,
12952
+ fontSize: this._ratio(12),
12953
+ fontWeight: 600
12950
12954
  });
12951
- const brokerName = options.data?.position.brokerName?.trim();
12952
- if (brokerName) {
12953
- left += (prevElementBoundingBox.width ?? 0) + this._ratio(10);
12954
- const badgeHeight = this._ratio(this.BROKER_BADGE_HEIGHT);
12955
- const badgePaddingX = this._ratio(this.BROKER_BADGE_PADDING_X);
12956
- const badgeRadius = this._ratio(this.BROKER_BADGE_RADIUS);
12957
- const badgeFontSize = this._ratio(12);
12958
- const badgeFontWeight = 600;
12959
- const textMetrics = this._drawText(
12960
- brokerName,
12961
- {
12962
- left: 0,
12963
- top: 0,
12964
- fontSize: badgeFontSize,
12965
- fontWeight: badgeFontWeight,
12966
- fontFamily: options.fontFamily
12967
- },
12968
- true
12969
- );
12970
- const badgeWidth = (textMetrics.width ?? 0) + badgePaddingX * 2;
12971
- const badgeTop = this._ratio(top) - badgeHeight / 2;
12972
- this._fillRoundedRect(
12973
- left,
12974
- badgeTop,
12975
- badgeWidth,
12976
- badgeHeight,
12977
- badgeRadius,
12978
- "rgba(255,255,255,0.06)"
12979
- );
12980
- this._drawText(brokerName, {
12981
- color: "rgba(255,255,255,0.36)",
12982
- left: left + badgePaddingX,
12983
- top: badgeTop + badgeHeight / 2,
12984
- fontSize: badgeFontSize,
12985
- fontWeight: badgeFontWeight,
12986
- fontFamily: options.fontFamily,
12987
- textBaseline: "middle"
12988
- });
12989
- prevElementBoundingBox = {
12990
- ...prevElementBoundingBox,
12991
- width: badgeWidth
12992
- };
12993
- }
12994
12955
  }
12995
12956
  const marginMode = options.data?.position.marginMode;
12996
12957
  if (marginMode) {
12997
- left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
12998
- if (prevElementBoundingBox.width) {
12999
- prevElementBoundingBox = this._drawText("|", {
13000
- color: "rgba(255,255,255,0.2)",
13001
- left,
13002
- top: this._ratio(top),
13003
- fontSize: this._ratio(fontSize),
13004
- fontFamily: options.fontFamily
13005
- });
13006
- }
13007
- left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
13008
- const marginModeText = this.formatMarginMode(marginMode);
13009
- prevElementBoundingBox = this._drawText(marginModeText, {
12958
+ items.push({
12959
+ kind: "text",
12960
+ text: this.formatMarginMode(marginMode),
13010
12961
  color: layout.color,
13011
- left,
13012
- top: this._ratio(top),
13013
- fontSize: this._ratio(fontSize),
13014
- fontFamily: options.fontFamily
12962
+ fontSize: this._ratio(fontSize)
13015
12963
  });
13016
12964
  }
13017
12965
  if (typeof options.data?.position.leverage !== "undefined") {
13018
- left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
13019
- if (prevElementBoundingBox.width) {
13020
- prevElementBoundingBox = this._drawText("|", {
13021
- color: "rgba(255,255,255,0.2)",
13022
- left,
13023
- top: this._ratio(top),
13024
- fontSize: this._ratio(fontSize),
13025
- fontFamily: options.fontFamily
13026
- });
13027
- }
13028
- left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
13029
- prevElementBoundingBox = this._drawText(
13030
- `${options.data?.position.leverage}X`,
13031
- {
13032
- color: layout.color,
13033
- left,
13034
- top: this._ratio(top),
13035
- fontSize: this._ratio(fontSize),
13036
- fontFamily: options.fontFamily
13037
- }
13038
- );
12966
+ items.push({
12967
+ kind: "text",
12968
+ text: `${options.data.position.leverage}X`,
12969
+ color: layout.color,
12970
+ fontSize: this._ratio(fontSize)
12971
+ });
13039
12972
  }
12973
+ const topPx = this._ratio(top);
12974
+ items.forEach((item, index) => {
12975
+ cursor = this.drawInlineItem(options, item, cursor, topPx);
12976
+ if (index < items.length - 1) {
12977
+ cursor = this.drawInlineSeparator(
12978
+ options,
12979
+ cursor,
12980
+ topPx,
12981
+ this._ratio(fontSize)
12982
+ );
12983
+ }
12984
+ });
13040
12985
  }
13041
12986
  _fillRoundedRect(x, y, width, height, radius, color) {
13042
12987
  const r = Math.min(radius, width / 2, height / 2);
@@ -13058,7 +13003,7 @@ var DataPaint = class extends BasePaint {
13058
13003
  options
13059
13004
  );
13060
13005
  const { position } = layout;
13061
- let left = this._ratio(position.left);
13006
+ let cursor = this.inlineStart(options, position.left);
13062
13007
  let prevElementBoundingBox = {};
13063
13008
  const top = (position.top ?? 0) + offsetTop + this.transformTop;
13064
13009
  if (typeof options.data?.position.ROI !== "undefined") {
@@ -13067,11 +13012,13 @@ var DataPaint = class extends BasePaint {
13067
13012
  `${prefix}${commify(options.data?.position.ROI)}%`,
13068
13013
  {
13069
13014
  color: prefix === "+" ? options.profitColor || this.DEFAULT_PROFIT_COLOR : options.lossColor || this.DEFAULT_LOSS_COLOR,
13070
- left,
13015
+ left: cursor,
13071
13016
  top: this._ratio(top),
13072
13017
  fontSize: this._ratio(layout.fontSize),
13073
13018
  fontWeight: 700,
13074
- fontFamily: options.fontFamily
13019
+ fontFamily: options.fontFamily,
13020
+ textAlign: this.inlineStartAlign(options),
13021
+ direction: this.textDirection(options)
13075
13022
  }
13076
13023
  );
13077
13024
  }
@@ -13080,21 +13027,27 @@ var DataPaint = class extends BasePaint {
13080
13027
  let text = `${prefix}${commify(options.data?.position.pnl)} ${options.data?.position.currency}`;
13081
13028
  let fontWeight = 600;
13082
13029
  if (prevElementBoundingBox.width) {
13083
- left += (prevElementBoundingBox.width ?? 0) + this._ratio(8);
13030
+ cursor = this.advanceCursor(
13031
+ options,
13032
+ cursor,
13033
+ (prevElementBoundingBox.width ?? 0) + this._ratio(8)
13034
+ );
13084
13035
  text = `(${text})`;
13085
13036
  } else {
13086
- left = this._ratio(position.left);
13037
+ cursor = this.inlineStart(options, position.left);
13087
13038
  fontWeight = 700;
13088
13039
  }
13089
13040
  const color = typeof options.data.position.ROI === "undefined" ? prefix === "+" ? options.profitColor || this.DEFAULT_PROFIT_COLOR : options.lossColor || this.DEFAULT_LOSS_COLOR : layout.secondaryColor;
13090
13041
  const fontSize = typeof options.data.position.ROI === "undefined" ? this._ratio(layout.fontSize) : this._ratio(layout.secondaryFontSize);
13091
13042
  prevElementBoundingBox = this._drawText(text, {
13092
13043
  color,
13093
- left,
13044
+ left: cursor,
13094
13045
  top: this._ratio(top),
13095
13046
  fontSize,
13096
13047
  fontWeight,
13097
- fontFamily: options.fontFamily
13048
+ fontFamily: options.fontFamily,
13049
+ textAlign: this.inlineStartAlign(options),
13050
+ direction: this.textDirection(options)
13098
13051
  });
13099
13052
  }
13100
13053
  }
@@ -13108,22 +13061,27 @@ var DataPaint = class extends BasePaint {
13108
13061
  (options.data?.position.informations.length ?? 0) === 2;
13109
13062
  const col = informations.length > 4 ? 3 : 2;
13110
13063
  informations.forEach((info, index) => {
13111
- const left = position.left + index % col * this.positionInfoCellWidth;
13064
+ const colIndex = index % col;
13065
+ const inlineOffset = position.left + colIndex * this.positionInfoCellWidth;
13112
13066
  const top = position.top + Math.floor(index / col) * 38 + this.transformTop;
13113
13067
  this._drawText(info.title, {
13114
- left: this._ratio(left),
13068
+ left: this.inlineStart(options, inlineOffset),
13115
13069
  top: this._ratio(top),
13116
13070
  fontSize: this._ratio(10),
13117
13071
  color: layout.labelColor,
13118
- fontFamily: options.fontFamily
13072
+ fontFamily: options.fontFamily,
13073
+ textAlign: this.inlineStartAlign(options),
13074
+ direction: this.textDirection(options)
13119
13075
  });
13120
13076
  this._drawText(info.value, {
13121
- left: this._ratio(left),
13077
+ left: this.inlineStart(options, inlineOffset),
13122
13078
  top: this._ratio(top + 17),
13123
13079
  fontSize: this._ratio(layout.fontSize),
13124
13080
  fontWeight: 500,
13125
13081
  color: layout.color,
13126
- fontFamily: options.fontFamily
13082
+ fontFamily: options.fontFamily,
13083
+ textAlign: this.inlineStartAlign(options),
13084
+ direction: this.textDirection(options)
13127
13085
  });
13128
13086
  });
13129
13087
  }
@@ -13138,13 +13096,14 @@ var DataPaint = class extends BasePaint {
13138
13096
  return this._drawText(
13139
13097
  options.data?.domain,
13140
13098
  {
13141
- left: !hasReferral ? this._ratio(position.left) : this._ratio(this.painter.width - 20),
13099
+ left: !hasReferral ? this.inlineStart(options, position.left) : this.inlineEnd(options, 20),
13142
13100
  top: !hasReferral ? this._ratio(top) : this._ratio(this.painter.height - 16),
13143
13101
  fontSize: this._ratio(layout.fontSize),
13144
13102
  color: options.brandColor ?? this.DEFAULT_PROFIT_COLOR,
13145
13103
  fontFamily: options.fontFamily,
13146
13104
  textBaseline: layout.textBaseline,
13147
- textAlign: !hasReferral ? layout.textAlign : "end",
13105
+ textAlign: !hasReferral ? this.inlineStartAlign(options) : this.inlineEndAlign(options),
13106
+ direction: this.textDirection(options),
13148
13107
  fontWeight: 600
13149
13108
  },
13150
13109
  onlyMeasure
@@ -13158,10 +13117,10 @@ var DataPaint = class extends BasePaint {
13158
13117
  const { position } = layout;
13159
13118
  const hasReferral = this.hasReferral(options);
13160
13119
  let top = this.painter.height - position.bottom;
13161
- let left = this._ratio(position.left);
13120
+ let left = this.inlineStart(options, position.left);
13162
13121
  if (hasReferral) {
13163
13122
  const metrics = this.drawDomainUrl(options, true);
13164
- left = this._ratio(this.painter.width) - metrics.width - this._ratio(8 + position.left);
13123
+ left = this.inlineStart(options, position.left + 8) + (this.isRTL(options) ? metrics.width : -metrics.width);
13165
13124
  top = this.painter.height - position.bottom;
13166
13125
  }
13167
13126
  this._drawText(
@@ -13173,9 +13132,10 @@ var DataPaint = class extends BasePaint {
13173
13132
  fontSize: this._ratio(layout.fontSize),
13174
13133
  color: layout.color,
13175
13134
  // color: "red",
13176
- textAlign: !hasReferral ? layout.textAlign : "end",
13135
+ textAlign: !hasReferral ? this.inlineStartAlign(options) : this.inlineEndAlign(options),
13177
13136
  fontFamily: options.fontFamily,
13178
- textBaseline: layout.textBaseline
13137
+ textBaseline: layout.textBaseline,
13138
+ direction: this.textDirection(options)
13179
13139
  }
13180
13140
  );
13181
13141
  }
@@ -13197,36 +13157,44 @@ var DataPaint = class extends BasePaint {
13197
13157
  const searchParams = url.searchParams;
13198
13158
  searchParams.append("ref", options.data.referral.code);
13199
13159
  url.search = searchParams.toString();
13160
+ const qrSize = this._ratio(this.QRCODE_SIZE);
13161
+ const qrLeft = this.isRTL(options) ? this.inlineStart(options, position.left) - qrSize : this.inlineStart(options, position.left);
13200
13162
  qrPaint(this.ctx, {
13201
13163
  size: this._ratio(this.QRCODE_SIZE),
13202
13164
  padding: this._ratio(2),
13203
- left: this._ratio(position.left),
13165
+ left: qrLeft,
13204
13166
  top: this._ratio(top - this.QRCODE_SIZE),
13205
13167
  data: `${url.toString()}`
13206
13168
  });
13207
13169
  this._drawText(options.data.referral.slogan, {
13208
- left: this._ratio(position.left + 66),
13170
+ left: this.inlineStart(options, position.left + 66),
13209
13171
  top: this._ratio(top - this.QRCODE_SIZE),
13210
13172
  fontSize: this._ratio(14),
13211
13173
  color: options.brandColor ?? this.DEFAULT_PROFIT_COLOR,
13212
13174
  fontFamily: options.fontFamily,
13213
- textBaseline: "top"
13175
+ textBaseline: "top",
13176
+ textAlign: this.inlineStartAlign(options),
13177
+ direction: this.textDirection(options)
13214
13178
  });
13215
13179
  this._drawText("Referral Code", {
13216
- left: this._ratio(position.left + 66),
13180
+ left: this.inlineStart(options, position.left + 66),
13217
13181
  top: this._ratio(top - 29),
13218
13182
  fontSize: this._ratio(12),
13219
13183
  color: layout.color,
13220
13184
  fontFamily: options.fontFamily,
13221
- textBaseline: "middle"
13185
+ textBaseline: "middle",
13186
+ textAlign: this.inlineStartAlign(options),
13187
+ direction: this.textDirection(options)
13222
13188
  });
13223
13189
  this._drawText(options.data.referral.code, {
13224
- left: this._ratio(position.left + 66),
13190
+ left: this.inlineStart(options, position.left + 66),
13225
13191
  top: this._ratio(top),
13226
13192
  fontSize: this._ratio(16),
13227
13193
  color: messageLayout.color,
13228
13194
  fontFamily: options.fontFamily,
13229
- textBaseline: "bottom"
13195
+ textBaseline: "bottom",
13196
+ textAlign: this.inlineStartAlign(options),
13197
+ direction: this.textDirection(options)
13230
13198
  });
13231
13199
  }
13232
13200
  _drawText(str, options, onlyMeasure = false) {
@@ -13238,13 +13206,15 @@ var DataPaint = class extends BasePaint {
13238
13206
  fontWeight = 500,
13239
13207
  color = "black",
13240
13208
  textBaseline = "middle",
13241
- textAlign = "start"
13209
+ textAlign = "start",
13210
+ direction = "ltr"
13242
13211
  } = options ?? {};
13243
13212
  this.ctx.save();
13244
13213
  this.ctx.font = `${fontWeight} ${fontSize}px ${options?.fontFamily}`;
13245
13214
  this.ctx.fillStyle = color;
13246
13215
  this.ctx.textBaseline = textBaseline;
13247
13216
  this.ctx.textAlign = textAlign;
13217
+ this.ctx.direction = direction;
13248
13218
  boundingBox = this.ctx.measureText(str);
13249
13219
  if (!onlyMeasure) {
13250
13220
  this.ctx.fillText(str, left, top);
@@ -13258,6 +13228,98 @@ var DataPaint = class extends BasePaint {
13258
13228
  _ratio(num) {
13259
13229
  return num * this.painter.ratio;
13260
13230
  }
13231
+ canvasWidth() {
13232
+ return this._ratio(this.painter.width);
13233
+ }
13234
+ textDirection(options) {
13235
+ return this.isRTL(options) ? "rtl" : "ltr";
13236
+ }
13237
+ isRTL(options) {
13238
+ return options.direction === "rtl";
13239
+ }
13240
+ inlineStart(options, value) {
13241
+ return this.isRTL(options) ? this.canvasWidth() - this._ratio(value) : this._ratio(value);
13242
+ }
13243
+ inlineEnd(options, value) {
13244
+ return this.isRTL(options) ? this._ratio(value) : this.canvasWidth() - this._ratio(value);
13245
+ }
13246
+ inlineStartAlign(options) {
13247
+ return this.isRTL(options) ? "right" : "left";
13248
+ }
13249
+ inlineEndAlign(options) {
13250
+ return this.isRTL(options) ? "left" : "right";
13251
+ }
13252
+ advanceCursor(options, cursor, width) {
13253
+ return this.isRTL(options) ? cursor - width : cursor + width;
13254
+ }
13255
+ drawInlineSeparator(options, cursor, top, fontSize) {
13256
+ const gap = this._ratio(this.ITEM_GAP);
13257
+ const separatorMetrics = this._drawText("|", {
13258
+ color: "rgba(255,255,255,0.2)",
13259
+ left: this.advanceCursor(options, cursor, gap),
13260
+ top,
13261
+ fontSize,
13262
+ fontFamily: options.fontFamily,
13263
+ textAlign: this.inlineStartAlign(options),
13264
+ direction: this.textDirection(options)
13265
+ });
13266
+ return this.advanceCursor(
13267
+ options,
13268
+ this.advanceCursor(options, cursor, gap),
13269
+ (separatorMetrics.width ?? 0) + gap
13270
+ );
13271
+ }
13272
+ drawInlineItem(options, item, cursor, top) {
13273
+ if (item.kind === "text") {
13274
+ const metrics = this._drawText(item.text, {
13275
+ color: item.color,
13276
+ left: cursor,
13277
+ top,
13278
+ fontSize: item.fontSize,
13279
+ fontWeight: item.fontWeight,
13280
+ fontFamily: options.fontFamily,
13281
+ textAlign: this.inlineStartAlign(options),
13282
+ direction: this.textDirection(options)
13283
+ });
13284
+ return this.advanceCursor(options, cursor, metrics.width ?? 0);
13285
+ }
13286
+ const badgeHeight = this._ratio(this.BROKER_BADGE_HEIGHT);
13287
+ const badgePaddingX = this._ratio(this.BROKER_BADGE_PADDING_X);
13288
+ const badgeRadius = this._ratio(this.BROKER_BADGE_RADIUS);
13289
+ const textMetrics = this._drawText(
13290
+ item.text,
13291
+ {
13292
+ left: 0,
13293
+ top: 0,
13294
+ fontSize: item.fontSize,
13295
+ fontWeight: item.fontWeight ?? 600,
13296
+ direction: this.textDirection(options)
13297
+ },
13298
+ true
13299
+ );
13300
+ const badgeWidth = (textMetrics.width ?? 0) + badgePaddingX * 2;
13301
+ const badgeTop = top - badgeHeight / 2;
13302
+ const badgeLeft = this.isRTL(options) ? cursor - badgeWidth : cursor;
13303
+ this._fillRoundedRect(
13304
+ badgeLeft,
13305
+ badgeTop,
13306
+ badgeWidth,
13307
+ badgeHeight,
13308
+ badgeRadius,
13309
+ "rgba(255,255,255,0.06)"
13310
+ );
13311
+ this._drawText(item.text, {
13312
+ color: "rgba(255,255,255,0.36)",
13313
+ left: this.isRTL(options) ? badgeLeft + badgeWidth - badgePaddingX : badgeLeft + badgePaddingX,
13314
+ top: badgeTop + badgeHeight / 2,
13315
+ fontSize: item.fontSize,
13316
+ fontWeight: item.fontWeight ?? 600,
13317
+ textBaseline: "middle",
13318
+ textAlign: this.inlineStartAlign(options),
13319
+ direction: this.textDirection(options)
13320
+ });
13321
+ return this.advanceCursor(options, cursor, badgeWidth);
13322
+ }
13261
13323
  };
13262
13324
 
13263
13325
  // src/services/painter/painter.ts
@@ -19046,20 +19108,39 @@ var useOrderEntry2 = (symbol, options = {}) => {
19046
19108
  symbolLeverage
19047
19109
  });
19048
19110
  const [estSlippage, setEstSlippage] = useState(null);
19111
+ const [bestAskBidSnapshot, setBestAskBidSnapshot] = useState([]);
19049
19112
  const [doCreateOrder, { isMutating }] = useMutation(
19050
19113
  getCreateOrderUrl(formattedOrder)
19051
19114
  );
19052
- const bestAskBid = askAndBid.current?.[0] || [];
19053
- const referencePriceFromOrder = bestAskBid.length >= 2 && formattedOrder.order_type && formattedOrder.side ? getOrderReferencePriceFromOrder(formattedOrder, bestAskBid) : null;
19115
+ const bestAskBid = bestAskBidSnapshot;
19116
+ const getReferencePriceForSide = (side) => {
19117
+ if (bestAskBid.length < 2 || !formattedOrder.order_type) {
19118
+ return null;
19119
+ }
19120
+ const referencePrice = getOrderReferencePriceFromOrder(
19121
+ {
19122
+ ...formattedOrder,
19123
+ side
19124
+ },
19125
+ bestAskBid
19126
+ );
19127
+ const slippage = Number(formattedOrder.slippage);
19128
+ if (effectiveMarginMode !== MarginMode.ISOLATED || side !== OrderSide.BUY || formattedOrder.order_type !== OrderType.MARKET || !referencePrice || !Number.isFinite(slippage) || slippage <= 0) {
19129
+ return referencePrice;
19130
+ }
19131
+ return new Decimal(referencePrice).mul(new Decimal(1).add(new Decimal(slippage).div(100))).toNumber();
19132
+ };
19133
+ const buyReferencePriceFromOrder = getReferencePriceForSide(OrderSide.BUY);
19134
+ const sellReferencePriceFromOrder = getReferencePriceForSide(OrderSide.SELL);
19054
19135
  const maxBuyQtyValue = useMaxQty(symbol, OrderSide.BUY, {
19055
19136
  reduceOnly: formattedOrder.reduce_only,
19056
19137
  marginMode: effectiveMarginMode,
19057
- currentOrderReferencePrice: referencePriceFromOrder && referencePriceFromOrder > 0 ? referencePriceFromOrder : void 0
19138
+ currentOrderReferencePrice: buyReferencePriceFromOrder && buyReferencePriceFromOrder > 0 ? buyReferencePriceFromOrder : void 0
19058
19139
  });
19059
19140
  const maxSellQtyValue = useMaxQty(symbol, OrderSide.SELL, {
19060
19141
  reduceOnly: formattedOrder.reduce_only,
19061
19142
  marginMode: effectiveMarginMode,
19062
- currentOrderReferencePrice: referencePriceFromOrder && referencePriceFromOrder > 0 ? referencePriceFromOrder : void 0
19143
+ currentOrderReferencePrice: sellReferencePriceFromOrder && sellReferencePriceFromOrder > 0 ? sellReferencePriceFromOrder : void 0
19063
19144
  });
19064
19145
  const maxQtyValue = formattedOrder.side === OrderSide.BUY ? maxBuyQtyValue : maxSellQtyValue;
19065
19146
  const maxQty = options.maxQty ?? maxQtyValue;
@@ -19151,6 +19232,10 @@ var useOrderEntry2 = (symbol, options = {}) => {
19151
19232
  useEffect(() => {
19152
19233
  updateOrderPrice();
19153
19234
  }, [formattedOrder.order_type_ext, formattedOrder.level]);
19235
+ useEffect(() => {
19236
+ askAndBid.current = [[]];
19237
+ setBestAskBidSnapshot([]);
19238
+ }, [symbol]);
19154
19239
  const onOrderBookUpdate = useDebouncedCallback((data) => {
19155
19240
  const parsedData = [
19156
19241
  [data.asks?.[data.asks.length - 1]?.[0], data.bids?.[0]?.[0]],
@@ -19160,6 +19245,10 @@ var useOrderEntry2 = (symbol, options = {}) => {
19160
19245
  [data.asks?.[data.asks.length - 5]?.[0], data.bids?.[4]?.[0]]
19161
19246
  ];
19162
19247
  askAndBid.current = parsedData;
19248
+ const nextBestAskBid = parsedData[0] || [];
19249
+ setBestAskBidSnapshot(
19250
+ (prev) => prev[0] === nextBestAskBid[0] && prev[1] === nextBestAskBid[1] ? prev : nextBestAskBid
19251
+ );
19163
19252
  updateOrderPriceByOrderBook();
19164
19253
  updateEstSlippage(data);
19165
19254
  }, 200);