@loafmarkets/ui 0.1.50 → 0.1.52
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 +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +311 -267
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +190 -146
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as React5 from 'react';
|
|
2
|
+
import React5__default, { createContext, useState, useEffect, useMemo, useCallback, useRef, useContext } from 'react';
|
|
3
3
|
import { Slot } from '@radix-ui/react-slot';
|
|
4
4
|
import { cva } from 'class-variance-authority';
|
|
5
5
|
import { clsx } from 'clsx';
|
|
@@ -50,7 +50,7 @@ var buttonVariants = cva(
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
);
|
|
53
|
-
var Button =
|
|
53
|
+
var Button = React5.forwardRef(
|
|
54
54
|
({ className, variant, size, radius, asChild = false, ...props }, ref) => {
|
|
55
55
|
const Comp = asChild ? Slot : "button";
|
|
56
56
|
const coercedRadius = radius ?? (variant === "onboarding" || variant === "onboardingOutline" ? "square" : void 0);
|
|
@@ -89,11 +89,11 @@ var badgeVariants = cva(
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
);
|
|
92
|
-
var Badge =
|
|
92
|
+
var Badge = React5.forwardRef(
|
|
93
93
|
({ className, variant, size, ...props }, ref) => /* @__PURE__ */ jsx("span", { ref, className: cn(badgeVariants({ variant, size }), className), ...props })
|
|
94
94
|
);
|
|
95
95
|
Badge.displayName = "Badge";
|
|
96
|
-
var Card =
|
|
96
|
+
var Card = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
97
97
|
"div",
|
|
98
98
|
{
|
|
99
99
|
ref,
|
|
@@ -105,11 +105,11 @@ var Card = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ j
|
|
|
105
105
|
}
|
|
106
106
|
));
|
|
107
107
|
Card.displayName = "Card";
|
|
108
|
-
var CardHeader =
|
|
108
|
+
var CardHeader = React5.forwardRef(
|
|
109
109
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col space-y-1.5 p-6", className), ...props })
|
|
110
110
|
);
|
|
111
111
|
CardHeader.displayName = "CardHeader";
|
|
112
|
-
var CardTitle =
|
|
112
|
+
var CardTitle = React5.forwardRef(
|
|
113
113
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
114
114
|
"h3",
|
|
115
115
|
{
|
|
@@ -120,15 +120,15 @@ var CardTitle = React9.forwardRef(
|
|
|
120
120
|
)
|
|
121
121
|
);
|
|
122
122
|
CardTitle.displayName = "CardTitle";
|
|
123
|
-
var CardDescription =
|
|
123
|
+
var CardDescription = React5.forwardRef(
|
|
124
124
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx("p", { ref, className: cn("text-sm text-slate-500", className), ...props })
|
|
125
125
|
);
|
|
126
126
|
CardDescription.displayName = "CardDescription";
|
|
127
|
-
var CardContent =
|
|
127
|
+
var CardContent = React5.forwardRef(
|
|
128
128
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("px-6 pb-6 pt-2 text-sm text-slate-600", className), ...props })
|
|
129
129
|
);
|
|
130
130
|
CardContent.displayName = "CardContent";
|
|
131
|
-
var CardFooter =
|
|
131
|
+
var CardFooter = React5.forwardRef(
|
|
132
132
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("flex items-center border-t border-slate-100 px-6 py-4", className), ...props })
|
|
133
133
|
);
|
|
134
134
|
CardFooter.displayName = "CardFooter";
|
|
@@ -146,7 +146,7 @@ var defaultFormatSignedCurrency = (value) => {
|
|
|
146
146
|
const sign = value >= 0 ? "+" : "-";
|
|
147
147
|
return `${sign}${defaultFormatCurrency(Math.abs(value))}`;
|
|
148
148
|
};
|
|
149
|
-
var PortfolioSummary =
|
|
149
|
+
var PortfolioSummary = React5.forwardRef(
|
|
150
150
|
({
|
|
151
151
|
availableCash,
|
|
152
152
|
portfolioValue,
|
|
@@ -296,23 +296,23 @@ function HousePositionSlider({
|
|
|
296
296
|
className,
|
|
297
297
|
...props
|
|
298
298
|
}) {
|
|
299
|
-
const [orderMode, setOrderMode] =
|
|
300
|
-
const [buyTrackingMode, setBuyTrackingMode] =
|
|
301
|
-
const [deltaDollars, setDeltaDollars] =
|
|
302
|
-
const [deltaTokensBuy, setDeltaTokensBuy] =
|
|
303
|
-
const [deltaTokensSell, setDeltaTokensSell] =
|
|
304
|
-
const [_isDragging, setIsDragging] =
|
|
305
|
-
const [visualTargetPct, setVisualTargetPct] =
|
|
306
|
-
const [orderType, setOrderType] =
|
|
307
|
-
const [limitPrice, setLimitPrice] =
|
|
308
|
-
const [limitPriceInput, setLimitPriceInput] =
|
|
309
|
-
const [limitPriceDirty, setLimitPriceDirty] =
|
|
310
|
-
const [ownershipInput, setOwnershipInput] =
|
|
311
|
-
const [tokenAmountInput, setTokenAmountInput] =
|
|
312
|
-
const houseRef =
|
|
299
|
+
const [orderMode, setOrderMode] = React5.useState("none");
|
|
300
|
+
const [buyTrackingMode, setBuyTrackingMode] = React5.useState("dollars");
|
|
301
|
+
const [deltaDollars, setDeltaDollars] = React5.useState(0);
|
|
302
|
+
const [deltaTokensBuy, setDeltaTokensBuy] = React5.useState(0);
|
|
303
|
+
const [deltaTokensSell, setDeltaTokensSell] = React5.useState(0);
|
|
304
|
+
const [_isDragging, setIsDragging] = React5.useState(false);
|
|
305
|
+
const [visualTargetPct, setVisualTargetPct] = React5.useState(null);
|
|
306
|
+
const [orderType, setOrderType] = React5.useState(defaultOrderType);
|
|
307
|
+
const [limitPrice, setLimitPrice] = React5.useState(currentPrice);
|
|
308
|
+
const [limitPriceInput, setLimitPriceInput] = React5.useState(currentPrice.toFixed(2));
|
|
309
|
+
const [limitPriceDirty, setLimitPriceDirty] = React5.useState(false);
|
|
310
|
+
const [ownershipInput, setOwnershipInput] = React5.useState("");
|
|
311
|
+
const [tokenAmountInput, setTokenAmountInput] = React5.useState("");
|
|
312
|
+
const houseRef = React5.useRef(null);
|
|
313
313
|
const asks = orderbook?.asks ?? [];
|
|
314
314
|
const bids = orderbook?.bids ?? [];
|
|
315
|
-
|
|
315
|
+
React5.useEffect(() => {
|
|
316
316
|
if (orderType !== "limit") return;
|
|
317
317
|
if (limitPriceDirty) return;
|
|
318
318
|
setLimitPrice(currentPrice);
|
|
@@ -387,7 +387,7 @@ function HousePositionSlider({
|
|
|
387
387
|
const impliedDisplayTargetOwnership = clamp(targetOwnership + ownershipShift, 0, 100);
|
|
388
388
|
const displayTargetOwnership = visualTargetPct ?? impliedDisplayTargetOwnership;
|
|
389
389
|
const estFeeTokens = Math.abs(deltaValue) * 5e-3 / (effectivePrice || 1);
|
|
390
|
-
const resetOrder =
|
|
390
|
+
const resetOrder = React5.useCallback(() => {
|
|
391
391
|
setOrderMode("none");
|
|
392
392
|
setBuyTrackingMode("dollars");
|
|
393
393
|
setDeltaDollars(0);
|
|
@@ -395,7 +395,7 @@ function HousePositionSlider({
|
|
|
395
395
|
setDeltaTokensSell(0);
|
|
396
396
|
setVisualTargetPct(null);
|
|
397
397
|
}, []);
|
|
398
|
-
const updateOrderFromTargetValue =
|
|
398
|
+
const updateOrderFromTargetValue = React5.useCallback(
|
|
399
399
|
(newTargetValue) => {
|
|
400
400
|
const newDeltaValue = newTargetValue - holdingsValue;
|
|
401
401
|
if (newDeltaValue > 0) {
|
|
@@ -419,7 +419,7 @@ function HousePositionSlider({
|
|
|
419
419
|
},
|
|
420
420
|
[effectiveAvailableCash, effectivePrice, effectiveTokensHeld, holdingsValue, resetOrder, tokensHeld]
|
|
421
421
|
);
|
|
422
|
-
const updateOrderFromOwnership =
|
|
422
|
+
const updateOrderFromOwnership = React5.useCallback(
|
|
423
423
|
(newOwnershipPercent) => {
|
|
424
424
|
const nextOwnership = clamp(newOwnershipPercent, 0, 100);
|
|
425
425
|
const newTargetTokens = nextOwnership / 100 * totalTokens;
|
|
@@ -428,7 +428,7 @@ function HousePositionSlider({
|
|
|
428
428
|
},
|
|
429
429
|
[effectivePrice, totalTokens, updateOrderFromTargetValue]
|
|
430
430
|
);
|
|
431
|
-
const updateOrderFromTokenAmount =
|
|
431
|
+
const updateOrderFromTokenAmount = React5.useCallback(
|
|
432
432
|
(tokenAmountSigned) => {
|
|
433
433
|
if (tokenAmountSigned > 0) {
|
|
434
434
|
const maxTokens = effectiveAvailableCash / (effectivePrice || 1);
|
|
@@ -451,7 +451,7 @@ function HousePositionSlider({
|
|
|
451
451
|
},
|
|
452
452
|
[effectiveAvailableCash, effectivePrice, effectiveTokensHeld, resetOrder]
|
|
453
453
|
);
|
|
454
|
-
const updateOrderFromSlider =
|
|
454
|
+
const updateOrderFromSlider = React5.useCallback(
|
|
455
455
|
(pct) => {
|
|
456
456
|
const normalized = (pct - 50) / 50;
|
|
457
457
|
const magnitude = Math.min(Math.abs(normalized), 1);
|
|
@@ -495,7 +495,7 @@ function HousePositionSlider({
|
|
|
495
495
|
},
|
|
496
496
|
[effectiveAvailableCash, effectiveTokensHeld, resetOrder]
|
|
497
497
|
);
|
|
498
|
-
const handleDragAtClientY =
|
|
498
|
+
const handleDragAtClientY = React5.useCallback(
|
|
499
499
|
(clientY) => {
|
|
500
500
|
if (!houseRef.current) return;
|
|
501
501
|
const rect = houseRef.current.getBoundingClientRect();
|
|
@@ -1011,18 +1011,18 @@ function HousePositionSliderMobile({
|
|
|
1011
1011
|
className,
|
|
1012
1012
|
...props
|
|
1013
1013
|
}) {
|
|
1014
|
-
const [orderMode, setOrderMode] =
|
|
1015
|
-
const [deltaDollars, setDeltaDollars] =
|
|
1016
|
-
const [deltaTokensSell, setDeltaTokensSell] =
|
|
1017
|
-
const [deltaTokensBuy, setDeltaTokensBuy] =
|
|
1018
|
-
const [buyTrackingMode, setBuyTrackingMode] =
|
|
1019
|
-
const [orderType, setOrderType] =
|
|
1020
|
-
const [limitPrice, setLimitPrice] =
|
|
1021
|
-
const [limitPriceInput, setLimitPriceInput] =
|
|
1022
|
-
const [limitPriceDirty, setLimitPriceDirty] =
|
|
1023
|
-
const [tokenAmountInput, setTokenAmountInput] =
|
|
1024
|
-
const houseRef =
|
|
1025
|
-
|
|
1014
|
+
const [orderMode, setOrderMode] = React5.useState("none");
|
|
1015
|
+
const [deltaDollars, setDeltaDollars] = React5.useState(0);
|
|
1016
|
+
const [deltaTokensSell, setDeltaTokensSell] = React5.useState(0);
|
|
1017
|
+
const [deltaTokensBuy, setDeltaTokensBuy] = React5.useState(0);
|
|
1018
|
+
const [buyTrackingMode, setBuyTrackingMode] = React5.useState("dollars");
|
|
1019
|
+
const [orderType, setOrderType] = React5.useState(defaultOrderType);
|
|
1020
|
+
const [limitPrice, setLimitPrice] = React5.useState(currentPrice);
|
|
1021
|
+
const [limitPriceInput, setLimitPriceInput] = React5.useState(currentPrice.toFixed(2));
|
|
1022
|
+
const [limitPriceDirty, setLimitPriceDirty] = React5.useState(false);
|
|
1023
|
+
const [tokenAmountInput, setTokenAmountInput] = React5.useState("");
|
|
1024
|
+
const houseRef = React5.useRef(null);
|
|
1025
|
+
React5.useEffect(() => {
|
|
1026
1026
|
if (orderType !== "limit") return;
|
|
1027
1027
|
if (limitPriceDirty) return;
|
|
1028
1028
|
setLimitPrice(currentPrice);
|
|
@@ -1064,7 +1064,7 @@ function HousePositionSliderMobile({
|
|
|
1064
1064
|
const hasChange = orderMode !== "none" && (Math.abs(deltaTokens) > 1e-3 || Math.abs(deltaValue) > 0.01);
|
|
1065
1065
|
const targetOwnership = totalTokens > 0 ? targetTokens / totalTokens * 100 : 0;
|
|
1066
1066
|
const estFeeTokens = effectivePrice > 0 ? Math.abs(deltaValue) * 5e-3 / effectivePrice : 0;
|
|
1067
|
-
const updateOrderFromTargetValue =
|
|
1067
|
+
const updateOrderFromTargetValue = React5.useCallback(
|
|
1068
1068
|
(newTargetValue) => {
|
|
1069
1069
|
const newDeltaValue = newTargetValue - holdingsValue;
|
|
1070
1070
|
if (newDeltaValue > 0.01) {
|
|
@@ -1092,7 +1092,7 @@ function HousePositionSliderMobile({
|
|
|
1092
1092
|
},
|
|
1093
1093
|
[holdingsValue, availableCash, effectivePrice, tokensHeld]
|
|
1094
1094
|
);
|
|
1095
|
-
const updateOrderFromTokenAmount =
|
|
1095
|
+
const updateOrderFromTokenAmount = React5.useCallback(
|
|
1096
1096
|
(tokenAmount) => {
|
|
1097
1097
|
if (tokenAmount > 0) {
|
|
1098
1098
|
const maxTokens = effectivePrice > 0 ? availableCash / effectivePrice : 0;
|
|
@@ -1119,14 +1119,14 @@ function HousePositionSliderMobile({
|
|
|
1119
1119
|
},
|
|
1120
1120
|
[effectivePrice, availableCash, tokensHeld]
|
|
1121
1121
|
);
|
|
1122
|
-
const handleMarkerClick =
|
|
1122
|
+
const handleMarkerClick = React5.useCallback(
|
|
1123
1123
|
(pct) => {
|
|
1124
1124
|
const newTargetValue = pct / 100 * totalCapacity;
|
|
1125
1125
|
updateOrderFromTargetValue(newTargetValue);
|
|
1126
1126
|
},
|
|
1127
1127
|
[totalCapacity, updateOrderFromTargetValue]
|
|
1128
1128
|
);
|
|
1129
|
-
const onMouseDown =
|
|
1129
|
+
const onMouseDown = React5.useCallback(
|
|
1130
1130
|
(e) => {
|
|
1131
1131
|
e.preventDefault();
|
|
1132
1132
|
const move = (ev) => {
|
|
@@ -1146,7 +1146,7 @@ function HousePositionSliderMobile({
|
|
|
1146
1146
|
},
|
|
1147
1147
|
[totalCapacity, updateOrderFromTargetValue]
|
|
1148
1148
|
);
|
|
1149
|
-
const onTouchStart =
|
|
1149
|
+
const onTouchStart = React5.useCallback(
|
|
1150
1150
|
(e) => {
|
|
1151
1151
|
e.preventDefault();
|
|
1152
1152
|
e.stopPropagation();
|
|
@@ -1704,7 +1704,7 @@ var LiquidityText = styled24.span`
|
|
|
1704
1704
|
letter-spacing: 0.1px;
|
|
1705
1705
|
}
|
|
1706
1706
|
`;
|
|
1707
|
-
var LoafLiquidityBadge =
|
|
1707
|
+
var LoafLiquidityBadge = React5.forwardRef(
|
|
1708
1708
|
({ className, isGlowing, onClick, children, ...props }, ref) => {
|
|
1709
1709
|
return /* @__PURE__ */ jsxs(
|
|
1710
1710
|
LogoContainer,
|
|
@@ -1733,7 +1733,7 @@ var LoafLiquidityBadge = React9.forwardRef(
|
|
|
1733
1733
|
);
|
|
1734
1734
|
LoafLiquidityBadge.displayName = "LoafLiquidityBadge";
|
|
1735
1735
|
var toSize = (v, fallback) => v == null ? fallback : typeof v === "number" ? `${v}px` : v;
|
|
1736
|
-
var Skeleton =
|
|
1736
|
+
var Skeleton = React5.forwardRef(
|
|
1737
1737
|
({ width, height, radius, className, style, ...props }, ref) => {
|
|
1738
1738
|
return /* @__PURE__ */ jsx(
|
|
1739
1739
|
"div",
|
|
@@ -1758,8 +1758,8 @@ var Skeleton = React9.forwardRef(
|
|
|
1758
1758
|
);
|
|
1759
1759
|
Skeleton.displayName = "Skeleton";
|
|
1760
1760
|
function useViewportCompact(breakpoint) {
|
|
1761
|
-
const [isCompact, setIsCompact] =
|
|
1762
|
-
|
|
1761
|
+
const [isCompact, setIsCompact] = React5.useState(false);
|
|
1762
|
+
React5.useEffect(() => {
|
|
1763
1763
|
if (typeof window === "undefined") return;
|
|
1764
1764
|
const check = () => setIsCompact(window.innerWidth <= breakpoint);
|
|
1765
1765
|
check();
|
|
@@ -1778,8 +1778,8 @@ function getTradeKey(trade, fallbackIndex) {
|
|
|
1778
1778
|
return `idx-${fallbackIndex}-${trade.type}-${trade.price}-${trade.amount}`;
|
|
1779
1779
|
}
|
|
1780
1780
|
function useAmountChangeFlash(ref, amount, side) {
|
|
1781
|
-
const prevAmountRef =
|
|
1782
|
-
|
|
1781
|
+
const prevAmountRef = React5.useRef(amount);
|
|
1782
|
+
React5.useEffect(() => {
|
|
1783
1783
|
const prev = prevAmountRef.current;
|
|
1784
1784
|
const node = ref.current;
|
|
1785
1785
|
if (prev !== amount && node && typeof node.animate === "function") {
|
|
@@ -1793,8 +1793,8 @@ function useAmountChangeFlash(ref, amount, side) {
|
|
|
1793
1793
|
}, [amount, ref, side]);
|
|
1794
1794
|
}
|
|
1795
1795
|
function useMidPriceFlash(ref, midPrice, restBgColor) {
|
|
1796
|
-
const prevMidRef =
|
|
1797
|
-
|
|
1796
|
+
const prevMidRef = React5.useRef(midPrice);
|
|
1797
|
+
React5.useEffect(() => {
|
|
1798
1798
|
const prev = prevMidRef.current;
|
|
1799
1799
|
const node = ref.current;
|
|
1800
1800
|
if (prev !== midPrice && prev > 0 && midPrice > 0 && node && typeof node.animate === "function") {
|
|
@@ -1815,9 +1815,9 @@ function TradeRow({
|
|
|
1815
1815
|
seenTradeKeysRef,
|
|
1816
1816
|
compact
|
|
1817
1817
|
}) {
|
|
1818
|
-
const rowRef =
|
|
1818
|
+
const rowRef = React5.useRef(null);
|
|
1819
1819
|
const { type } = trade;
|
|
1820
|
-
|
|
1820
|
+
React5.useEffect(() => {
|
|
1821
1821
|
if (seenTradeKeysRef.current.has(tradeKey)) return;
|
|
1822
1822
|
seenTradeKeysRef.current.add(tradeKey);
|
|
1823
1823
|
const node = rowRef.current;
|
|
@@ -1879,7 +1879,7 @@ function DepthRow({
|
|
|
1879
1879
|
hasUserOrder
|
|
1880
1880
|
}) {
|
|
1881
1881
|
const isAsk = side === "ask";
|
|
1882
|
-
const rowRef =
|
|
1882
|
+
const rowRef = React5.useRef(null);
|
|
1883
1883
|
useAmountChangeFlash(rowRef, amount, side);
|
|
1884
1884
|
return /* @__PURE__ */ jsxs(
|
|
1885
1885
|
"div",
|
|
@@ -1926,7 +1926,7 @@ var DEPTH_ROW_HEIGHT_PX = 26;
|
|
|
1926
1926
|
var COMPACT_ROWS_VISIBLE = 5;
|
|
1927
1927
|
var COMPACT_ROW_HEIGHT_PX = 30;
|
|
1928
1928
|
var COMPACT_BREAKPOINT_PX = 1024;
|
|
1929
|
-
var Orderbook =
|
|
1929
|
+
var Orderbook = React5.forwardRef(
|
|
1930
1930
|
({
|
|
1931
1931
|
asks,
|
|
1932
1932
|
bids,
|
|
@@ -1948,10 +1948,10 @@ var Orderbook = React9.forwardRef(
|
|
|
1948
1948
|
...props
|
|
1949
1949
|
}, ref) => {
|
|
1950
1950
|
const resolvedRightHeader = rightHeader ?? /* @__PURE__ */ jsx(LoafLiquidityBadge, { className: "text-[0.6rem]", onClick: onLoafLiquidityClick });
|
|
1951
|
-
const [tab, setTab] =
|
|
1952
|
-
const [tradeFilter, setTradeFilter] =
|
|
1951
|
+
const [tab, setTab] = React5.useState(defaultTab);
|
|
1952
|
+
const [tradeFilter, setTradeFilter] = React5.useState("all");
|
|
1953
1953
|
const viewportCompact = useViewportCompact(COMPACT_BREAKPOINT_PX);
|
|
1954
|
-
const { userAskPrices, userBidPrices } =
|
|
1954
|
+
const { userAskPrices, userBidPrices } = React5.useMemo(() => {
|
|
1955
1955
|
const ask = /* @__PURE__ */ new Set();
|
|
1956
1956
|
const bid = /* @__PURE__ */ new Set();
|
|
1957
1957
|
if (!userOrderPrices) return { userAskPrices: ask, userBidPrices: bid };
|
|
@@ -1961,15 +1961,15 @@ var Orderbook = React9.forwardRef(
|
|
|
1961
1961
|
}
|
|
1962
1962
|
return { userAskPrices: ask, userBidPrices: bid };
|
|
1963
1963
|
}, [userOrderPrices]);
|
|
1964
|
-
const seenTradeKeysRef =
|
|
1965
|
-
const initializedRef =
|
|
1964
|
+
const seenTradeKeysRef = React5.useRef(/* @__PURE__ */ new Set());
|
|
1965
|
+
const initializedRef = React5.useRef(false);
|
|
1966
1966
|
if (!initializedRef.current && trades.length > 0) {
|
|
1967
1967
|
for (let i = 0; i < trades.length; i++) {
|
|
1968
1968
|
seenTradeKeysRef.current.add(getTradeKey(trades[i], i));
|
|
1969
1969
|
}
|
|
1970
1970
|
initializedRef.current = true;
|
|
1971
1971
|
}
|
|
1972
|
-
|
|
1972
|
+
React5.useEffect(() => {
|
|
1973
1973
|
if (!initializedRef.current) return;
|
|
1974
1974
|
const live = /* @__PURE__ */ new Set();
|
|
1975
1975
|
for (let i = 0; i < trades.length; i++) {
|
|
@@ -1980,7 +1980,7 @@ var Orderbook = React9.forwardRef(
|
|
|
1980
1980
|
if (!live.has(key)) seen.delete(key);
|
|
1981
1981
|
}
|
|
1982
1982
|
}, [trades]);
|
|
1983
|
-
|
|
1983
|
+
React5.useEffect(() => {
|
|
1984
1984
|
setTab(defaultTab);
|
|
1985
1985
|
}, [defaultTab]);
|
|
1986
1986
|
const handleTab = (next) => {
|
|
@@ -1989,8 +1989,26 @@ var Orderbook = React9.forwardRef(
|
|
|
1989
1989
|
};
|
|
1990
1990
|
const isCompact = variant === "compact" || variant === "auto" && viewportCompact;
|
|
1991
1991
|
const sectionHeight = isCompact ? COMPACT_ROWS_VISIBLE * COMPACT_ROW_HEIGHT_PX : LEVEL_ROWS_VISIBLE * DEPTH_ROW_HEIGHT_PX;
|
|
1992
|
-
const
|
|
1993
|
-
const
|
|
1992
|
+
const rowCount = isCompact ? COMPACT_ROWS_VISIBLE : LEVEL_ROWS_VISIBLE;
|
|
1993
|
+
const askVisibleLevels = asks.slice(-rowCount);
|
|
1994
|
+
const bidVisibleLevels = bids.slice(0, rowCount);
|
|
1995
|
+
const askCumDepths = new Array(askVisibleLevels.length);
|
|
1996
|
+
{
|
|
1997
|
+
let acc = 0;
|
|
1998
|
+
for (let i = askVisibleLevels.length - 1; i >= 0; i--) {
|
|
1999
|
+
acc += askVisibleLevels[i].amount;
|
|
2000
|
+
askCumDepths[i] = acc;
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
2003
|
+
const bidCumDepths = new Array(bidVisibleLevels.length);
|
|
2004
|
+
{
|
|
2005
|
+
let acc = 0;
|
|
2006
|
+
for (let i = 0; i < bidVisibleLevels.length; i++) {
|
|
2007
|
+
acc += bidVisibleLevels[i].amount;
|
|
2008
|
+
bidCumDepths[i] = acc;
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
const combinedMaxCumDepth = Math.max(1, ...askCumDepths, ...bidCumDepths);
|
|
1994
2012
|
const midClass = midChangePercent == null ? "text-white" : midChangePercent >= 0 ? "text-[#0ecb81]" : "text-[#f6465d]";
|
|
1995
2013
|
const tradeFiltered = trades.filter((t) => tradeFilter === "all" || t.type === tradeFilter);
|
|
1996
2014
|
const layoutProps = {
|
|
@@ -2006,8 +2024,11 @@ var Orderbook = React9.forwardRef(
|
|
|
2006
2024
|
amountPrecision,
|
|
2007
2025
|
asks,
|
|
2008
2026
|
bids,
|
|
2009
|
-
|
|
2010
|
-
|
|
2027
|
+
askVisibleLevels,
|
|
2028
|
+
bidVisibleLevels,
|
|
2029
|
+
askCumDepths,
|
|
2030
|
+
bidCumDepths,
|
|
2031
|
+
combinedMaxCumDepth,
|
|
2011
2032
|
midPrice,
|
|
2012
2033
|
midChangePercent,
|
|
2013
2034
|
midClass,
|
|
@@ -2067,10 +2088,11 @@ function DesktopOrderbookLayout({
|
|
|
2067
2088
|
tradeFiltered,
|
|
2068
2089
|
precision,
|
|
2069
2090
|
amountPrecision,
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2091
|
+
askVisibleLevels,
|
|
2092
|
+
bidVisibleLevels,
|
|
2093
|
+
askCumDepths,
|
|
2094
|
+
bidCumDepths,
|
|
2095
|
+
combinedMaxCumDepth,
|
|
2074
2096
|
midPrice,
|
|
2075
2097
|
midChangePercent,
|
|
2076
2098
|
midClass,
|
|
@@ -2080,7 +2102,7 @@ function DesktopOrderbookLayout({
|
|
|
2080
2102
|
isLoading,
|
|
2081
2103
|
seenTradeKeysRef
|
|
2082
2104
|
}) {
|
|
2083
|
-
const midRef =
|
|
2105
|
+
const midRef = React5.useRef(null);
|
|
2084
2106
|
useMidPriceFlash(midRef, midPrice, "#0b1a24");
|
|
2085
2107
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2086
2108
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 pt-4", children: [
|
|
@@ -2186,13 +2208,13 @@ function DesktopOrderbookLayout({
|
|
|
2186
2208
|
{
|
|
2187
2209
|
className: "flex flex-col justify-end divide-y divide-white/5 overflow-hidden",
|
|
2188
2210
|
style: { height: `${sectionHeight}px` },
|
|
2189
|
-
children: isLoading ? Array.from({ length: LEVEL_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsx(SkeletonRow, {}, `ask-skel-${i}`)) :
|
|
2211
|
+
children: isLoading ? Array.from({ length: LEVEL_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsx(SkeletonRow, {}, `ask-skel-${i}`)) : askVisibleLevels.length === 0 ? /* @__PURE__ */ jsx("div", { className: "flex h-full items-center justify-center px-3 text-xs text-white/40", children: "No asks" }) : askVisibleLevels.map((l, i) => /* @__PURE__ */ jsx(
|
|
2190
2212
|
DepthRow,
|
|
2191
2213
|
{
|
|
2192
2214
|
side: "ask",
|
|
2193
2215
|
price: l.price,
|
|
2194
2216
|
amount: l.amount,
|
|
2195
|
-
depthPct:
|
|
2217
|
+
depthPct: askCumDepths[i] / combinedMaxCumDepth * 100,
|
|
2196
2218
|
precision,
|
|
2197
2219
|
amountPrecision,
|
|
2198
2220
|
hasUserOrder: userAskPrices.has(l.price)
|
|
@@ -2225,13 +2247,13 @@ function DesktopOrderbookLayout({
|
|
|
2225
2247
|
{
|
|
2226
2248
|
className: "divide-y divide-white/5 overflow-hidden",
|
|
2227
2249
|
style: { height: `${sectionHeight}px` },
|
|
2228
|
-
children: isLoading ? Array.from({ length: LEVEL_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsx(SkeletonRow, {}, `bid-skel-${i}`)) :
|
|
2250
|
+
children: isLoading ? Array.from({ length: LEVEL_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsx(SkeletonRow, {}, `bid-skel-${i}`)) : bidVisibleLevels.length === 0 ? /* @__PURE__ */ jsx("div", { className: "flex h-full items-center justify-center px-3 text-xs text-white/40", children: "No bids" }) : bidVisibleLevels.map((l, i) => /* @__PURE__ */ jsx(
|
|
2229
2251
|
DepthRow,
|
|
2230
2252
|
{
|
|
2231
2253
|
side: "bid",
|
|
2232
2254
|
price: l.price,
|
|
2233
2255
|
amount: l.amount,
|
|
2234
|
-
depthPct:
|
|
2256
|
+
depthPct: bidCumDepths[i] / combinedMaxCumDepth * 100,
|
|
2235
2257
|
precision,
|
|
2236
2258
|
amountPrecision,
|
|
2237
2259
|
hasUserOrder: userBidPrices.has(l.price)
|
|
@@ -2255,10 +2277,11 @@ function MobileOrderbookLayout({
|
|
|
2255
2277
|
tradeFiltered,
|
|
2256
2278
|
precision,
|
|
2257
2279
|
amountPrecision,
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2280
|
+
askVisibleLevels: visibleAsks,
|
|
2281
|
+
bidVisibleLevels: visibleBids,
|
|
2282
|
+
askCumDepths,
|
|
2283
|
+
bidCumDepths,
|
|
2284
|
+
combinedMaxCumDepth,
|
|
2262
2285
|
midPrice,
|
|
2263
2286
|
midChangePercent,
|
|
2264
2287
|
midClass,
|
|
@@ -2268,10 +2291,8 @@ function MobileOrderbookLayout({
|
|
|
2268
2291
|
isLoading,
|
|
2269
2292
|
seenTradeKeysRef
|
|
2270
2293
|
}) {
|
|
2271
|
-
const midRef =
|
|
2294
|
+
const midRef = React5.useRef(null);
|
|
2272
2295
|
useMidPriceFlash(midRef, midPrice, "transparent");
|
|
2273
|
-
const visibleAsks = React9.useMemo(() => asks.slice(-COMPACT_ROWS_VISIBLE), [asks]);
|
|
2274
|
-
const visibleBids = React9.useMemo(() => bids.slice(0, COMPACT_ROWS_VISIBLE), [bids]);
|
|
2275
2296
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2276
2297
|
/* @__PURE__ */ jsx("div", { className: "px-3 pt-2", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
2277
2298
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
@@ -2340,13 +2361,13 @@ function MobileOrderbookLayout({
|
|
|
2340
2361
|
]
|
|
2341
2362
|
}
|
|
2342
2363
|
),
|
|
2343
|
-
/* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column" }, children: isLoading ? Array.from({ length: COMPACT_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsx(SkeletonRow, { compact: true }, `m-ask-skel-${i}`)) : visibleAsks.length === 0 ? /* @__PURE__ */ jsx("div", { style: { padding: "0.75rem 0", textAlign: "center", color: "rgba(255,255,255,0.4)", fontSize: "0.72rem" }, children: "No asks" }) : visibleAsks.map((l) => /* @__PURE__ */ jsx(
|
|
2364
|
+
/* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column" }, children: isLoading ? Array.from({ length: COMPACT_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsx(SkeletonRow, { compact: true }, `m-ask-skel-${i}`)) : visibleAsks.length === 0 ? /* @__PURE__ */ jsx("div", { style: { padding: "0.75rem 0", textAlign: "center", color: "rgba(255,255,255,0.4)", fontSize: "0.72rem" }, children: "No asks" }) : visibleAsks.map((l, i) => /* @__PURE__ */ jsx(
|
|
2344
2365
|
MobileDepthRow,
|
|
2345
2366
|
{
|
|
2346
2367
|
side: "ask",
|
|
2347
2368
|
price: l.price,
|
|
2348
2369
|
amount: l.amount,
|
|
2349
|
-
depthPct:
|
|
2370
|
+
depthPct: askCumDepths[i] / combinedMaxCumDepth * 100,
|
|
2350
2371
|
precision,
|
|
2351
2372
|
amountPrecision,
|
|
2352
2373
|
hasUserOrder: userAskPrices.has(l.price)
|
|
@@ -2386,13 +2407,13 @@ function MobileOrderbookLayout({
|
|
|
2386
2407
|
]
|
|
2387
2408
|
}
|
|
2388
2409
|
),
|
|
2389
|
-
/* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column" }, children: isLoading ? Array.from({ length: COMPACT_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsx(SkeletonRow, { compact: true }, `m-bid-skel-${i}`)) : visibleBids.length === 0 ? /* @__PURE__ */ jsx("div", { style: { padding: "0.75rem 0", textAlign: "center", color: "rgba(255,255,255,0.4)", fontSize: "0.72rem" }, children: "No bids" }) : visibleBids.map((l) => /* @__PURE__ */ jsx(
|
|
2410
|
+
/* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column" }, children: isLoading ? Array.from({ length: COMPACT_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsx(SkeletonRow, { compact: true }, `m-bid-skel-${i}`)) : visibleBids.length === 0 ? /* @__PURE__ */ jsx("div", { style: { padding: "0.75rem 0", textAlign: "center", color: "rgba(255,255,255,0.4)", fontSize: "0.72rem" }, children: "No bids" }) : visibleBids.map((l, i) => /* @__PURE__ */ jsx(
|
|
2390
2411
|
MobileDepthRow,
|
|
2391
2412
|
{
|
|
2392
2413
|
side: "bid",
|
|
2393
2414
|
price: l.price,
|
|
2394
2415
|
amount: l.amount,
|
|
2395
|
-
depthPct:
|
|
2416
|
+
depthPct: bidCumDepths[i] / combinedMaxCumDepth * 100,
|
|
2396
2417
|
precision,
|
|
2397
2418
|
amountPrecision,
|
|
2398
2419
|
hasUserOrder: userBidPrices.has(l.price)
|
|
@@ -2439,7 +2460,7 @@ function MobileDepthRow({
|
|
|
2439
2460
|
hasUserOrder
|
|
2440
2461
|
}) {
|
|
2441
2462
|
const isAsk = side === "ask";
|
|
2442
|
-
const rowRef =
|
|
2463
|
+
const rowRef = React5.useRef(null);
|
|
2443
2464
|
useAmountChangeFlash(rowRef, amount, side);
|
|
2444
2465
|
return /* @__PURE__ */ jsxs(
|
|
2445
2466
|
"div",
|
|
@@ -2496,7 +2517,7 @@ function MobileDepthRow({
|
|
|
2496
2517
|
}
|
|
2497
2518
|
);
|
|
2498
2519
|
}
|
|
2499
|
-
var PropertyTour =
|
|
2520
|
+
var PropertyTour = React5.forwardRef(
|
|
2500
2521
|
({
|
|
2501
2522
|
className,
|
|
2502
2523
|
title,
|
|
@@ -2509,8 +2530,8 @@ var PropertyTour = React9.forwardRef(
|
|
|
2509
2530
|
playsInline = true,
|
|
2510
2531
|
...props
|
|
2511
2532
|
}, ref) => {
|
|
2512
|
-
const videoRef =
|
|
2513
|
-
|
|
2533
|
+
const videoRef = React5.useRef(null);
|
|
2534
|
+
React5.useEffect(() => {
|
|
2514
2535
|
const video = videoRef.current;
|
|
2515
2536
|
if (!video) return;
|
|
2516
2537
|
const handleFullscreenChange = () => {
|
|
@@ -2642,7 +2663,7 @@ var formatTimeAgo = (timestamp) => {
|
|
|
2642
2663
|
if (diff < 3600) return `${Math.floor(diff / 60)}m ago`;
|
|
2643
2664
|
return `${Math.floor(diff / 3600)}h ago`;
|
|
2644
2665
|
};
|
|
2645
|
-
var PropertyNewsUpdates =
|
|
2666
|
+
var PropertyNewsUpdates = React5.forwardRef(
|
|
2646
2667
|
({
|
|
2647
2668
|
className,
|
|
2648
2669
|
heading,
|
|
@@ -2654,20 +2675,21 @@ var PropertyNewsUpdates = React9.forwardRef(
|
|
|
2654
2675
|
purchases: purchasesProp,
|
|
2655
2676
|
viewAllHref,
|
|
2656
2677
|
viewAllLabel = "View All News",
|
|
2678
|
+
connectionStatus = "live",
|
|
2657
2679
|
...props
|
|
2658
2680
|
}, ref) => {
|
|
2659
2681
|
const isPurchaseVariant = variant === "purchases";
|
|
2660
2682
|
const isHomeVariant = variant === "home";
|
|
2661
2683
|
const resolvedHeading = heading ?? (isPurchaseVariant ? "Live Purchases" : "Property News & Headlines");
|
|
2662
|
-
const [homeTab, setHomeTab] =
|
|
2684
|
+
const [homeTab, setHomeTab] = React5.useState("all");
|
|
2663
2685
|
const purchaseItems = purchasesProp ?? [];
|
|
2664
|
-
const [page, setPage] =
|
|
2665
|
-
|
|
2686
|
+
const [page, setPage] = React5.useState(0);
|
|
2687
|
+
React5.useEffect(() => {
|
|
2666
2688
|
ensureAnimationsInjected();
|
|
2667
2689
|
}, []);
|
|
2668
2690
|
const hasItems = Array.isArray(items) && items.length > 0;
|
|
2669
|
-
const totalPages =
|
|
2670
|
-
|
|
2691
|
+
const totalPages = React5.useMemo(() => hasItems ? Math.max(1, Math.ceil(items.length / ITEMS_PER_PAGE)) : 1, [hasItems, items.length]);
|
|
2692
|
+
React5.useEffect(() => {
|
|
2671
2693
|
setPage((prev) => Math.min(prev, totalPages - 1));
|
|
2672
2694
|
}, [totalPages]);
|
|
2673
2695
|
const paginatedItems = hasItems ? items.slice(page * ITEMS_PER_PAGE, page * ITEMS_PER_PAGE + ITEMS_PER_PAGE) : [];
|
|
@@ -2721,7 +2743,30 @@ var PropertyNewsUpdates = React9.forwardRef(
|
|
|
2721
2743
|
/* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" }) })
|
|
2722
2744
|
]
|
|
2723
2745
|
}
|
|
2724
|
-
) : !isHomeVariant && !isPurchaseVariant ? /* @__PURE__ */ jsxs(
|
|
2746
|
+
) : !isHomeVariant && !isPurchaseVariant ? connectionStatus === "connecting" ? /* @__PURE__ */ jsxs(
|
|
2747
|
+
"div",
|
|
2748
|
+
{
|
|
2749
|
+
className: "inline-flex items-center font-semibold uppercase",
|
|
2750
|
+
style: { gap: "0.35rem", fontSize: "0.8rem", letterSpacing: "0.15em", color: "#f97316" },
|
|
2751
|
+
children: [
|
|
2752
|
+
/* @__PURE__ */ jsx(
|
|
2753
|
+
"span",
|
|
2754
|
+
{
|
|
2755
|
+
style: {
|
|
2756
|
+
display: "inline-block",
|
|
2757
|
+
width: "10px",
|
|
2758
|
+
height: "10px",
|
|
2759
|
+
borderRadius: "50%",
|
|
2760
|
+
border: "2px solid rgba(249,115,22,0.3)",
|
|
2761
|
+
borderTopColor: "#f97316",
|
|
2762
|
+
animation: "propertyNewsSpin 0.8s linear infinite"
|
|
2763
|
+
}
|
|
2764
|
+
}
|
|
2765
|
+
),
|
|
2766
|
+
"CONNECTING"
|
|
2767
|
+
]
|
|
2768
|
+
}
|
|
2769
|
+
) : /* @__PURE__ */ jsxs(
|
|
2725
2770
|
"div",
|
|
2726
2771
|
{
|
|
2727
2772
|
className: "inline-flex items-center font-semibold uppercase text-emerald-300",
|
|
@@ -2975,7 +3020,7 @@ var defaultFormat = (value) => new Intl.NumberFormat("en-US", {
|
|
|
2975
3020
|
notation: value >= 1e5 ? "compact" : "standard",
|
|
2976
3021
|
maximumFractionDigits: value >= 1e3 ? 0 : 2
|
|
2977
3022
|
}).format(value);
|
|
2978
|
-
var TradingSlider =
|
|
3023
|
+
var TradingSlider = React5.forwardRef(
|
|
2979
3024
|
({
|
|
2980
3025
|
label = "Trade size",
|
|
2981
3026
|
helperText = "Drag to pick the desired notional.",
|
|
@@ -2993,7 +3038,7 @@ var TradingSlider = React9.forwardRef(
|
|
|
2993
3038
|
...rest
|
|
2994
3039
|
}, ref) => {
|
|
2995
3040
|
const isControlled = value !== void 0;
|
|
2996
|
-
const [internalValue, setInternalValue] =
|
|
3041
|
+
const [internalValue, setInternalValue] = React5.useState(
|
|
2997
3042
|
defaultValue ?? (typeof min === "number" ? min : 0)
|
|
2998
3043
|
);
|
|
2999
3044
|
const currentValue = isControlled ? Number(value) : internalValue;
|
|
@@ -3096,7 +3141,7 @@ var MobileToggleButton = styled24.button`
|
|
|
3096
3141
|
padding: 0.6rem 0.5rem;
|
|
3097
3142
|
}
|
|
3098
3143
|
`;
|
|
3099
|
-
var MobileTradeNav =
|
|
3144
|
+
var MobileTradeNav = React5.forwardRef(
|
|
3100
3145
|
({ className, items, activeId, onChange, ...props }, ref) => {
|
|
3101
3146
|
return /* @__PURE__ */ jsx(MobileToggleContainer, { ref, className: cn(className), ...props, children: items.map((item) => /* @__PURE__ */ jsxs(
|
|
3102
3147
|
MobileToggleButton,
|
|
@@ -3747,7 +3792,7 @@ var formatPercent = (value, fractionDigits = 2) => {
|
|
|
3747
3792
|
if (value == null || Number.isNaN(value)) return "\u2014";
|
|
3748
3793
|
return `${value.toFixed(fractionDigits)}%`;
|
|
3749
3794
|
};
|
|
3750
|
-
var YourOrders =
|
|
3795
|
+
var YourOrders = React5.forwardRef(
|
|
3751
3796
|
({
|
|
3752
3797
|
className,
|
|
3753
3798
|
title,
|
|
@@ -3760,10 +3805,10 @@ var YourOrders = React9.forwardRef(
|
|
|
3760
3805
|
pageSize: pageSizeOverride,
|
|
3761
3806
|
...props
|
|
3762
3807
|
}, ref) => {
|
|
3763
|
-
const [internalActiveTab, setInternalActiveTab] =
|
|
3764
|
-
const [page, setPage] =
|
|
3808
|
+
const [internalActiveTab, setInternalActiveTab] = React5.useState(tabs?.[0]?.id ?? "portfolio");
|
|
3809
|
+
const [page, setPage] = React5.useState(0);
|
|
3765
3810
|
const effectiveActiveTabId = activeTabId ?? internalActiveTab;
|
|
3766
|
-
|
|
3811
|
+
React5.useEffect(() => {
|
|
3767
3812
|
setPage(0);
|
|
3768
3813
|
}, [effectiveActiveTabId]);
|
|
3769
3814
|
const handleTabChange = (tabId) => {
|
|
@@ -4145,7 +4190,7 @@ function createCandlestickSeries(chart, options) {
|
|
|
4145
4190
|
}
|
|
4146
4191
|
throw new Error("Candlestick series API is not available in the current lightweight-charts version.");
|
|
4147
4192
|
}
|
|
4148
|
-
var PriceChart =
|
|
4193
|
+
var PriceChart = React5.forwardRef(
|
|
4149
4194
|
({
|
|
4150
4195
|
className,
|
|
4151
4196
|
title = "Price Chart",
|
|
@@ -4159,18 +4204,18 @@ var PriceChart = React9.forwardRef(
|
|
|
4159
4204
|
height = 301.52,
|
|
4160
4205
|
...props
|
|
4161
4206
|
}, ref) => {
|
|
4162
|
-
const containerRef =
|
|
4163
|
-
const chartRef =
|
|
4164
|
-
const seriesRef =
|
|
4165
|
-
const priceLineRef =
|
|
4166
|
-
const [hoveredRange, setHoveredRange] =
|
|
4167
|
-
const [dropdownOpen, setDropdownOpen] =
|
|
4168
|
-
const dropdownRef =
|
|
4169
|
-
const isAutoScrollRef =
|
|
4207
|
+
const containerRef = React5.useRef(null);
|
|
4208
|
+
const chartRef = React5.useRef(null);
|
|
4209
|
+
const seriesRef = React5.useRef(null);
|
|
4210
|
+
const priceLineRef = React5.useRef(null);
|
|
4211
|
+
const [hoveredRange, setHoveredRange] = React5.useState(null);
|
|
4212
|
+
const [dropdownOpen, setDropdownOpen] = React5.useState(false);
|
|
4213
|
+
const dropdownRef = React5.useRef(null);
|
|
4214
|
+
const isAutoScrollRef = React5.useRef(true);
|
|
4170
4215
|
const visibleRanges = ranges.slice(0, VISIBLE_RANGE_COUNT);
|
|
4171
4216
|
const dropdownRanges = ranges.slice(VISIBLE_RANGE_COUNT);
|
|
4172
4217
|
const selectedInDropdown = dropdownRanges.includes(selectedRange);
|
|
4173
|
-
|
|
4218
|
+
React5.useEffect(() => {
|
|
4174
4219
|
const handleClickOutside = (e) => {
|
|
4175
4220
|
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
4176
4221
|
setDropdownOpen(false);
|
|
@@ -4179,25 +4224,25 @@ var PriceChart = React9.forwardRef(
|
|
|
4179
4224
|
document.addEventListener("mousedown", handleClickOutside);
|
|
4180
4225
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
4181
4226
|
}, []);
|
|
4182
|
-
const resolvedPrice =
|
|
4227
|
+
const resolvedPrice = React5.useMemo(() => {
|
|
4183
4228
|
if (price != null) return price;
|
|
4184
4229
|
const last = data.at(-1);
|
|
4185
4230
|
return last?.close;
|
|
4186
4231
|
}, [data, price]);
|
|
4187
|
-
const inferredChangePercent =
|
|
4232
|
+
const inferredChangePercent = React5.useMemo(() => {
|
|
4188
4233
|
if (changePercent != null) return changePercent;
|
|
4189
4234
|
const first = data[0]?.open;
|
|
4190
4235
|
const last = data.at(-1)?.close;
|
|
4191
4236
|
if (first == null || last == null || first === 0) return void 0;
|
|
4192
4237
|
return (last - first) / first * 100;
|
|
4193
4238
|
}, [changePercent, data]);
|
|
4194
|
-
const dollarChange =
|
|
4239
|
+
const dollarChange = React5.useMemo(() => {
|
|
4195
4240
|
const first = data[0]?.open;
|
|
4196
4241
|
const last = data.at(-1)?.close;
|
|
4197
4242
|
if (first == null || last == null) return void 0;
|
|
4198
4243
|
return last - first;
|
|
4199
4244
|
}, [data]);
|
|
4200
|
-
|
|
4245
|
+
React5.useEffect(() => {
|
|
4201
4246
|
const el = containerRef.current;
|
|
4202
4247
|
if (!el) return;
|
|
4203
4248
|
const chart = LightweightCharts.createChart(el, {
|
|
@@ -4242,7 +4287,7 @@ var PriceChart = React9.forwardRef(
|
|
|
4242
4287
|
chart.remove();
|
|
4243
4288
|
};
|
|
4244
4289
|
}, []);
|
|
4245
|
-
|
|
4290
|
+
React5.useEffect(() => {
|
|
4246
4291
|
const chart = chartRef.current;
|
|
4247
4292
|
if (!chart) return;
|
|
4248
4293
|
const effectiveRange = selectedRange ?? ranges?.[0] ?? "1D";
|
|
@@ -4250,7 +4295,7 @@ var PriceChart = React9.forwardRef(
|
|
|
4250
4295
|
timeScale: getTimeScaleOptions(effectiveRange)
|
|
4251
4296
|
});
|
|
4252
4297
|
}, [selectedRange, ranges]);
|
|
4253
|
-
|
|
4298
|
+
React5.useEffect(() => {
|
|
4254
4299
|
const chart = chartRef.current;
|
|
4255
4300
|
const series = seriesRef.current;
|
|
4256
4301
|
if (!chart || !series) return;
|
|
@@ -4455,7 +4500,7 @@ var formatPrice3 = (value, currencySymbol) => {
|
|
|
4455
4500
|
maximumFractionDigits: 3
|
|
4456
4501
|
})}`;
|
|
4457
4502
|
};
|
|
4458
|
-
var PropertyHeroHeader =
|
|
4503
|
+
var PropertyHeroHeader = React5.forwardRef(
|
|
4459
4504
|
({
|
|
4460
4505
|
className,
|
|
4461
4506
|
imageUrl,
|
|
@@ -4482,8 +4527,8 @@ var PropertyHeroHeader = React9.forwardRef(
|
|
|
4482
4527
|
const isPositive = changePercent == null ? void 0 : changePercent >= 0;
|
|
4483
4528
|
const accentColor = "#e6c87e";
|
|
4484
4529
|
const tradeHoverColor = "#f5dd9a";
|
|
4485
|
-
const [isTradeInteracting, setIsTradeInteracting] =
|
|
4486
|
-
const [isOfferInteracting, setIsOfferInteracting] =
|
|
4530
|
+
const [isTradeInteracting, setIsTradeInteracting] = React5.useState(false);
|
|
4531
|
+
const [isOfferInteracting, setIsOfferInteracting] = React5.useState(false);
|
|
4487
4532
|
const hasAmenities = isLoading || beds != null || baths != null || cars != null || propertyTypeLabel != null;
|
|
4488
4533
|
const isTradeDisabled = !onTrade;
|
|
4489
4534
|
const isMakeOfferButtonDisabled = makeOfferDisabled || !onMakeOffer;
|
|
@@ -5093,7 +5138,7 @@ var Header = ({
|
|
|
5093
5138
|
setShowLoginPopup(true);
|
|
5094
5139
|
}
|
|
5095
5140
|
};
|
|
5096
|
-
const handleLoginPopupClose =
|
|
5141
|
+
const handleLoginPopupClose = React5__default.useCallback(() => {
|
|
5097
5142
|
setShowLoginPopup(false);
|
|
5098
5143
|
setLoginPopupInitialView(void 0);
|
|
5099
5144
|
}, []);
|
|
@@ -5809,10 +5854,10 @@ var MobileNavItem = styled24.div`
|
|
|
5809
5854
|
padding-left: 24px;
|
|
5810
5855
|
}
|
|
5811
5856
|
`;
|
|
5812
|
-
var PropertySubheader =
|
|
5857
|
+
var PropertySubheader = React5.forwardRef(
|
|
5813
5858
|
({ className, tabs, activeTabId, onTabChange, actions, ...props }, ref) => {
|
|
5814
|
-
const tabsContainerRef =
|
|
5815
|
-
|
|
5859
|
+
const tabsContainerRef = React5.useRef(null);
|
|
5860
|
+
React5.useEffect(() => {
|
|
5816
5861
|
const container = tabsContainerRef.current;
|
|
5817
5862
|
if (!container) return;
|
|
5818
5863
|
const isMobile = window.innerWidth <= 768;
|
|
@@ -5968,7 +6013,7 @@ var LoginPopup = ({
|
|
|
5968
6013
|
const [fiatFundingLoading, setFiatFundingLoading] = useState(false);
|
|
5969
6014
|
const [fundingError, setFundingError] = useState("");
|
|
5970
6015
|
const [transakWidgetUrl, setTransakWidgetUrl] = useState(null);
|
|
5971
|
-
const suppressAutoCloseRef =
|
|
6016
|
+
const suppressAutoCloseRef = React5__default.useRef(false);
|
|
5972
6017
|
useEffect(() => {
|
|
5973
6018
|
if (typeof initialView === "string") {
|
|
5974
6019
|
setView(initialView);
|
|
@@ -6220,13 +6265,12 @@ var LoginPopup = ({
|
|
|
6220
6265
|
}
|
|
6221
6266
|
setFundingError("");
|
|
6222
6267
|
setCryptoFundingLoading(true);
|
|
6268
|
+
const fundPromise = onFundWallet({ amount: fundingAmount, mode: "crypto" });
|
|
6269
|
+
onClose();
|
|
6223
6270
|
try {
|
|
6224
|
-
|
|
6225
|
-
if (result?.funded) {
|
|
6226
|
-
onClose();
|
|
6227
|
-
}
|
|
6271
|
+
await fundPromise;
|
|
6228
6272
|
} catch (err) {
|
|
6229
|
-
|
|
6273
|
+
console.error("[LoginPopup] crypto fund flow failed", err);
|
|
6230
6274
|
} finally {
|
|
6231
6275
|
setCryptoFundingLoading(false);
|
|
6232
6276
|
}
|
|
@@ -7148,7 +7192,7 @@ var MiniLiveFeed = () => {
|
|
|
7148
7192
|
);
|
|
7149
7193
|
};
|
|
7150
7194
|
LoginPopup.displayName = "LoginPopup";
|
|
7151
|
-
var PropertyCompareBar =
|
|
7195
|
+
var PropertyCompareBar = React5.forwardRef(
|
|
7152
7196
|
({
|
|
7153
7197
|
className,
|
|
7154
7198
|
addresses,
|
|
@@ -7159,7 +7203,7 @@ var PropertyCompareBar = React9.forwardRef(
|
|
|
7159
7203
|
price,
|
|
7160
7204
|
...props
|
|
7161
7205
|
}, ref) => {
|
|
7162
|
-
const normalizedAddresses =
|
|
7206
|
+
const normalizedAddresses = React5.useMemo(() => {
|
|
7163
7207
|
return addresses.map(
|
|
7164
7208
|
(option) => typeof option === "string" ? { id: option, label: option } : option
|
|
7165
7209
|
);
|
|
@@ -7167,11 +7211,11 @@ var PropertyCompareBar = React9.forwardRef(
|
|
|
7167
7211
|
const hasAddresses = normalizedAddresses.length > 0;
|
|
7168
7212
|
const firstAddressId = normalizedAddresses[0]?.id;
|
|
7169
7213
|
const isControlled = selectedAddressId !== void 0;
|
|
7170
|
-
const [internalSelectedId, setInternalSelectedId] =
|
|
7214
|
+
const [internalSelectedId, setInternalSelectedId] = React5.useState(
|
|
7171
7215
|
() => isControlled ? void 0 : firstAddressId
|
|
7172
7216
|
);
|
|
7173
7217
|
const resolvedSelectedId = isControlled ? selectedAddressId : internalSelectedId;
|
|
7174
|
-
|
|
7218
|
+
React5.useEffect(() => {
|
|
7175
7219
|
if (!isControlled) {
|
|
7176
7220
|
setInternalSelectedId((current) => {
|
|
7177
7221
|
if (current != null && normalizedAddresses.some((option) => option.id === current)) {
|
|
@@ -7182,9 +7226,9 @@ var PropertyCompareBar = React9.forwardRef(
|
|
|
7182
7226
|
}
|
|
7183
7227
|
}, [firstAddressId, isControlled, normalizedAddresses]);
|
|
7184
7228
|
const selectedOption = normalizedAddresses.find((option) => option.id === resolvedSelectedId) ?? normalizedAddresses[0];
|
|
7185
|
-
const [isDropdownOpen, setIsDropdownOpen] =
|
|
7186
|
-
const dropdownRef =
|
|
7187
|
-
|
|
7229
|
+
const [isDropdownOpen, setIsDropdownOpen] = React5.useState(false);
|
|
7230
|
+
const dropdownRef = React5.useRef(null);
|
|
7231
|
+
React5.useEffect(() => {
|
|
7188
7232
|
if (!isDropdownOpen) return;
|
|
7189
7233
|
const handleClick = (event) => {
|
|
7190
7234
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|