@loafmarkets/ui 0.0.5 → 0.0.6
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 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +35 -33
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +35 -33
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -116,9 +116,10 @@ interface HousePositionSliderProps extends React.HTMLAttributes<HTMLDivElement>
|
|
|
116
116
|
pendingOrders?: HousePositionPendingOrder[];
|
|
117
117
|
defaultOrderType?: "market" | "limit";
|
|
118
118
|
orderbook?: HousePositionOrderbook;
|
|
119
|
+
ownershipPercentOverride?: number;
|
|
119
120
|
onConfirmOrder?: (payload: HousePositionSliderOrderPayload) => void;
|
|
120
121
|
}
|
|
121
|
-
declare function HousePositionSlider({ tokenId, tokenSymbol, totalTokens, currentPrice, availableCash, tokensHeld, pendingOrders, defaultOrderType, orderbook, onConfirmOrder, className, ...props }: HousePositionSliderProps): react_jsx_runtime.JSX.Element;
|
|
122
|
+
declare function HousePositionSlider({ tokenId, tokenSymbol, totalTokens, currentPrice, availableCash, tokensHeld, pendingOrders, defaultOrderType, orderbook, ownershipPercentOverride, onConfirmOrder, className, ...props }: HousePositionSliderProps): react_jsx_runtime.JSX.Element;
|
|
122
123
|
|
|
123
124
|
type PropertyTourProps = Omit<React.ComponentPropsWithoutRef<typeof Card>, "title"> & {
|
|
124
125
|
title: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -116,9 +116,10 @@ interface HousePositionSliderProps extends React.HTMLAttributes<HTMLDivElement>
|
|
|
116
116
|
pendingOrders?: HousePositionPendingOrder[];
|
|
117
117
|
defaultOrderType?: "market" | "limit";
|
|
118
118
|
orderbook?: HousePositionOrderbook;
|
|
119
|
+
ownershipPercentOverride?: number;
|
|
119
120
|
onConfirmOrder?: (payload: HousePositionSliderOrderPayload) => void;
|
|
120
121
|
}
|
|
121
|
-
declare function HousePositionSlider({ tokenId, tokenSymbol, totalTokens, currentPrice, availableCash, tokensHeld, pendingOrders, defaultOrderType, orderbook, onConfirmOrder, className, ...props }: HousePositionSliderProps): react_jsx_runtime.JSX.Element;
|
|
122
|
+
declare function HousePositionSlider({ tokenId, tokenSymbol, totalTokens, currentPrice, availableCash, tokensHeld, pendingOrders, defaultOrderType, orderbook, ownershipPercentOverride, onConfirmOrder, className, ...props }: HousePositionSliderProps): react_jsx_runtime.JSX.Element;
|
|
122
123
|
|
|
123
124
|
type PropertyTourProps = Omit<React.ComponentPropsWithoutRef<typeof Card>, "title"> & {
|
|
124
125
|
title: string;
|
package/dist/index.js
CHANGED
|
@@ -304,6 +304,7 @@ function HousePositionSlider({
|
|
|
304
304
|
pendingOrders = [],
|
|
305
305
|
defaultOrderType = "market",
|
|
306
306
|
orderbook,
|
|
307
|
+
ownershipPercentOverride,
|
|
307
308
|
onConfirmOrder,
|
|
308
309
|
className,
|
|
309
310
|
...props
|
|
@@ -314,6 +315,7 @@ function HousePositionSlider({
|
|
|
314
315
|
const [deltaTokensBuy, setDeltaTokensBuy] = React5__namespace.useState(0);
|
|
315
316
|
const [deltaTokensSell, setDeltaTokensSell] = React5__namespace.useState(0);
|
|
316
317
|
const [isDragging, setIsDragging] = React5__namespace.useState(false);
|
|
318
|
+
const [visualTargetPct, setVisualTargetPct] = React5__namespace.useState(null);
|
|
317
319
|
const [orderType, setOrderType] = React5__namespace.useState(defaultOrderType);
|
|
318
320
|
const [limitPrice, setLimitPrice] = React5__namespace.useState(currentPrice);
|
|
319
321
|
const [limitPriceInput, setLimitPriceInput] = React5__namespace.useState(currentPrice.toFixed(2));
|
|
@@ -335,9 +337,8 @@ function HousePositionSlider({
|
|
|
335
337
|
const effectiveAvailableCash = Math.max(0, availableCash - pendingBuyValue);
|
|
336
338
|
const effectiveTokensHeld = Math.max(0, tokensHeld - pendingSellTokens);
|
|
337
339
|
const holdingsValue = tokensHeld * effectivePrice;
|
|
338
|
-
const
|
|
339
|
-
const
|
|
340
|
-
const baselinePct = sliderTotalCapacity <= 0 ? 0 : sliderHoldingsValue / sliderTotalCapacity * 100;
|
|
340
|
+
const safeTotalTokens = totalTokens > 0 ? totalTokens : 1;
|
|
341
|
+
const baselineOwnershipActual = clamp(effectiveTokensHeld / safeTotalTokens * 100, 0, 100);
|
|
341
342
|
let deltaTokens = 0;
|
|
342
343
|
let deltaValue = 0;
|
|
343
344
|
let marketAvgPrice = null;
|
|
@@ -383,29 +384,21 @@ function HousePositionSlider({
|
|
|
383
384
|
}
|
|
384
385
|
targetTokens = tokensHeld + deltaTokens;
|
|
385
386
|
targetValue = targetTokens * effectivePrice;
|
|
386
|
-
const
|
|
387
|
-
|
|
388
|
-
if (buyTrackingMode === "dollars") {
|
|
389
|
-
const notional = Math.min(Math.max(0, deltaDollars), effectiveAvailableCash);
|
|
390
|
-
return notional;
|
|
391
|
-
}
|
|
392
|
-
const tokensPlanned = Math.max(0, deltaTokensBuy);
|
|
393
|
-
const referencePrice = orderType === "market" ? currentPrice || limitPriceSafe : limitPriceSafe;
|
|
394
|
-
return Math.min(tokensPlanned * referencePrice, effectiveAvailableCash);
|
|
395
|
-
}
|
|
396
|
-
if (orderMode === "sell") {
|
|
397
|
-
const tokensToSell = Math.abs(Math.min(0, deltaTokensSell));
|
|
398
|
-
const sellValue = tokensToSell * effectivePrice;
|
|
399
|
-
return -Math.min(sellValue, sliderHoldingsValue);
|
|
400
|
-
}
|
|
401
|
-
return 0;
|
|
402
|
-
})();
|
|
403
|
-
const sliderTargetValue = clamp(sliderHoldingsValue + plannedDeltaValue, 0, sliderTotalCapacity);
|
|
404
|
-
const targetPct = sliderTotalCapacity <= 0 ? 0 : sliderTargetValue / sliderTotalCapacity * 100;
|
|
387
|
+
const sliderTargetTokens = clamp(effectiveTokensHeld + deltaTokens, 0, safeTotalTokens);
|
|
388
|
+
const normalizedTargetPct = sliderTargetTokens / safeTotalTokens * 100;
|
|
405
389
|
const isIncrease = orderMode === "buy";
|
|
406
390
|
const hasChange = orderMode !== "none" && (Math.abs(deltaTokens) > 1e-3 || Math.abs(deltaValue) > 0.01);
|
|
407
|
-
const currentOwnership = totalTokens <= 0 ? 0 : tokensHeld / totalTokens * 100;
|
|
408
|
-
const targetOwnership = totalTokens <= 0 ? 0 : targetTokens / totalTokens * 100;
|
|
391
|
+
const currentOwnership = totalTokens <= 0 ? 0 : clamp(tokensHeld / totalTokens * 100, 0, 100);
|
|
392
|
+
const targetOwnership = totalTokens <= 0 ? 0 : clamp(targetTokens / totalTokens * 100, 0, 100);
|
|
393
|
+
const ownershipOverrideValue = typeof ownershipPercentOverride === "number" && Number.isFinite(ownershipPercentOverride) ? clamp(ownershipPercentOverride, 0, 100) : null;
|
|
394
|
+
const ownershipShift = ownershipOverrideValue != null ? ownershipOverrideValue - baselineOwnershipActual : 0;
|
|
395
|
+
const baselinePct = clamp(ownershipOverrideValue ?? baselineOwnershipActual, 0, 100);
|
|
396
|
+
const impliedTargetPct = clamp(normalizedTargetPct + ownershipShift, 0, 100);
|
|
397
|
+
const displayTargetPct = visualTargetPct ?? impliedTargetPct;
|
|
398
|
+
const targetPct = displayTargetPct;
|
|
399
|
+
const displayCurrentOwnership = clamp(ownershipOverrideValue ?? currentOwnership, 0, 100);
|
|
400
|
+
const impliedDisplayTargetOwnership = clamp(targetOwnership + ownershipShift, 0, 100);
|
|
401
|
+
const displayTargetOwnership = visualTargetPct ?? impliedDisplayTargetOwnership;
|
|
409
402
|
const estFeeTokens = Math.abs(deltaValue) * 5e-3 / (effectivePrice || 1);
|
|
410
403
|
const resetOrder = React5__namespace.useCallback(() => {
|
|
411
404
|
setOrderMode("none");
|
|
@@ -413,6 +406,7 @@ function HousePositionSlider({
|
|
|
413
406
|
setDeltaDollars(0);
|
|
414
407
|
setDeltaTokensBuy(0);
|
|
415
408
|
setDeltaTokensSell(0);
|
|
409
|
+
setVisualTargetPct(null);
|
|
416
410
|
}, []);
|
|
417
411
|
const updateOrderFromTargetValue = React5__namespace.useCallback(
|
|
418
412
|
(newTargetValue) => {
|
|
@@ -443,6 +437,7 @@ function HousePositionSlider({
|
|
|
443
437
|
const nextOwnership = clamp(newOwnershipPercent, 0, 100);
|
|
444
438
|
const newTargetTokens = nextOwnership / 100 * totalTokens;
|
|
445
439
|
updateOrderFromTargetValue(newTargetTokens * effectivePrice);
|
|
440
|
+
setVisualTargetPct(nextOwnership);
|
|
446
441
|
},
|
|
447
442
|
[effectivePrice, totalTokens, updateOrderFromTargetValue]
|
|
448
443
|
);
|
|
@@ -475,12 +470,14 @@ function HousePositionSlider({
|
|
|
475
470
|
const magnitude = Math.min(Math.abs(normalized), 1);
|
|
476
471
|
if (magnitude < 0.02) {
|
|
477
472
|
resetOrder();
|
|
473
|
+
setVisualTargetPct(null);
|
|
478
474
|
return;
|
|
479
475
|
}
|
|
480
476
|
if (normalized > 0) {
|
|
481
477
|
const notional = clamp(magnitude * effectiveAvailableCash, 0, effectiveAvailableCash);
|
|
482
478
|
if (notional <= 0) {
|
|
483
479
|
resetOrder();
|
|
480
|
+
setVisualTargetPct(null);
|
|
484
481
|
return;
|
|
485
482
|
}
|
|
486
483
|
setOrderMode("buy");
|
|
@@ -488,12 +485,14 @@ function HousePositionSlider({
|
|
|
488
485
|
setDeltaDollars(notional);
|
|
489
486
|
setDeltaTokensBuy(0);
|
|
490
487
|
setDeltaTokensSell(0);
|
|
488
|
+
setVisualTargetPct(clamp(pct, 0, 100));
|
|
491
489
|
return;
|
|
492
490
|
}
|
|
493
491
|
if (normalized < 0) {
|
|
494
492
|
const tokensToSell = clamp(magnitude * effectiveTokensHeld, 0, effectiveTokensHeld);
|
|
495
493
|
if (tokensToSell <= 0) {
|
|
496
494
|
resetOrder();
|
|
495
|
+
setVisualTargetPct(null);
|
|
497
496
|
return;
|
|
498
497
|
}
|
|
499
498
|
setOrderMode("sell");
|
|
@@ -501,9 +500,11 @@ function HousePositionSlider({
|
|
|
501
500
|
setDeltaTokensSell(-tokensToSell);
|
|
502
501
|
setDeltaDollars(0);
|
|
503
502
|
setDeltaTokensBuy(0);
|
|
503
|
+
setVisualTargetPct(clamp(pct, 0, 100));
|
|
504
504
|
return;
|
|
505
505
|
}
|
|
506
506
|
resetOrder();
|
|
507
|
+
setVisualTargetPct(null);
|
|
507
508
|
},
|
|
508
509
|
[effectiveAvailableCash, effectiveTokensHeld, resetOrder]
|
|
509
510
|
);
|
|
@@ -666,19 +667,19 @@ function HousePositionSlider({
|
|
|
666
667
|
" Ownership"
|
|
667
668
|
] }),
|
|
668
669
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-white", children: [
|
|
669
|
-
|
|
670
|
+
displayCurrentOwnership.toFixed(2),
|
|
670
671
|
"%",
|
|
671
672
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "mx-1.5 text-white/50", children: "\u2192" }),
|
|
672
673
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
673
674
|
"input",
|
|
674
675
|
{
|
|
675
676
|
type: "text",
|
|
676
|
-
value: ownershipInput ||
|
|
677
|
+
value: ownershipInput || displayTargetOwnership.toFixed(2),
|
|
677
678
|
onChange: (e) => {
|
|
678
679
|
const val = e.target.value;
|
|
679
680
|
if (val === "" || /^[0-9]*\.?[0-9]*$/.test(val)) setOwnershipInput(val);
|
|
680
681
|
},
|
|
681
|
-
onFocus: () => setOwnershipInput(
|
|
682
|
+
onFocus: () => setOwnershipInput(displayTargetOwnership.toFixed(2)),
|
|
682
683
|
onBlur: () => {
|
|
683
684
|
const num = Number.parseFloat(ownershipInput);
|
|
684
685
|
if (Number.isFinite(num)) updateOrderFromOwnership(num);
|
|
@@ -689,7 +690,7 @@ function HousePositionSlider({
|
|
|
689
690
|
},
|
|
690
691
|
className: cn(
|
|
691
692
|
"w-[70px] rounded-[4px] border bg-white/10 px-2 py-1 text-right font-semibold outline-none",
|
|
692
|
-
|
|
693
|
+
displayTargetOwnership >= displayCurrentOwnership ? "border-[rgba(14,203,129,0.3)] text-[#0ecb81] focus:border-[#0ecb81]" : "border-[rgba(246,70,93,0.3)] text-[#f6465d] focus:border-[#f6465d]"
|
|
693
694
|
)
|
|
694
695
|
}
|
|
695
696
|
)
|
|
@@ -1317,12 +1318,13 @@ var PropertyCompareBar = React5__namespace.forwardRef(
|
|
|
1317
1318
|
{
|
|
1318
1319
|
ref,
|
|
1319
1320
|
className: cn(
|
|
1320
|
-
"flex w-full flex-col gap-3
|
|
1321
|
+
"flex w-full flex-col gap-3 border border-white/10 px-4 py-3 text-white shadow-[0_18px_40px_rgba(0,0,0,0.55)] md:flex-row md:items-center md:justify-between md:gap-4",
|
|
1321
1322
|
className
|
|
1322
1323
|
),
|
|
1324
|
+
style: { borderRadius: "16px" },
|
|
1323
1325
|
...props,
|
|
1324
1326
|
children: [
|
|
1325
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative
|
|
1327
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-auto", ref: dropdownRef, children: [
|
|
1326
1328
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1327
1329
|
"button",
|
|
1328
1330
|
{
|
|
@@ -1330,7 +1332,7 @@ var PropertyCompareBar = React5__namespace.forwardRef(
|
|
|
1330
1332
|
disabled: !hasAddresses,
|
|
1331
1333
|
onClick: () => setIsDropdownOpen((prev) => !prev),
|
|
1332
1334
|
className: cn(
|
|
1333
|
-
"flex h-[42px] w-
|
|
1335
|
+
"flex h-[42px] w-auto items-center gap-2 rounded-[12px] border border-transparent bg-transparent px-0 text-left text-[15px] font-semibold text-white transition hover:text-white/80 focus-visible:outline-none",
|
|
1334
1336
|
!hasAddresses && "text-white/40"
|
|
1335
1337
|
),
|
|
1336
1338
|
children: [
|
|
@@ -1349,7 +1351,7 @@ var PropertyCompareBar = React5__namespace.forwardRef(
|
|
|
1349
1351
|
]
|
|
1350
1352
|
}
|
|
1351
1353
|
),
|
|
1352
|
-
isDropdownOpen && hasAddresses ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0 top-[calc(100%+8px)] z-20 w-full rounded-[12px] border border-
|
|
1354
|
+
isDropdownOpen && hasAddresses ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0 top-[calc(100%+8px)] z-20 w-full rounded-[12px] border border-white/10 py-1 shadow-[0_25px_55px_rgba(0,0,0,0.6)] bg-black", children: normalizedAddresses.map((option) => {
|
|
1353
1355
|
const active = option.id === resolvedSelectedId;
|
|
1354
1356
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1355
1357
|
"button",
|
|
@@ -1371,7 +1373,7 @@ var PropertyCompareBar = React5__namespace.forwardRef(
|
|
|
1371
1373
|
{
|
|
1372
1374
|
variant: "accentOutline",
|
|
1373
1375
|
size: "sm",
|
|
1374
|
-
className: "flex
|
|
1376
|
+
className: "flex items-center justify-center gap-2 rounded-[10px] border-[var(--color-accent,#e6c87e)] bg-transparent px-4 py-2 text-[14px] font-semibold text-[var(--color-accent,#e6c87e)] transition hover:bg-[rgba(230,200,126,0.08)] md:ml-auto",
|
|
1375
1377
|
onClick: onCompareClick,
|
|
1376
1378
|
disabled: !hasAddresses,
|
|
1377
1379
|
children: [
|