@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.mjs
CHANGED
|
@@ -282,6 +282,7 @@ function HousePositionSlider({
|
|
|
282
282
|
pendingOrders = [],
|
|
283
283
|
defaultOrderType = "market",
|
|
284
284
|
orderbook,
|
|
285
|
+
ownershipPercentOverride,
|
|
285
286
|
onConfirmOrder,
|
|
286
287
|
className,
|
|
287
288
|
...props
|
|
@@ -292,6 +293,7 @@ function HousePositionSlider({
|
|
|
292
293
|
const [deltaTokensBuy, setDeltaTokensBuy] = React5.useState(0);
|
|
293
294
|
const [deltaTokensSell, setDeltaTokensSell] = React5.useState(0);
|
|
294
295
|
const [isDragging, setIsDragging] = React5.useState(false);
|
|
296
|
+
const [visualTargetPct, setVisualTargetPct] = React5.useState(null);
|
|
295
297
|
const [orderType, setOrderType] = React5.useState(defaultOrderType);
|
|
296
298
|
const [limitPrice, setLimitPrice] = React5.useState(currentPrice);
|
|
297
299
|
const [limitPriceInput, setLimitPriceInput] = React5.useState(currentPrice.toFixed(2));
|
|
@@ -313,9 +315,8 @@ function HousePositionSlider({
|
|
|
313
315
|
const effectiveAvailableCash = Math.max(0, availableCash - pendingBuyValue);
|
|
314
316
|
const effectiveTokensHeld = Math.max(0, tokensHeld - pendingSellTokens);
|
|
315
317
|
const holdingsValue = tokensHeld * effectivePrice;
|
|
316
|
-
const
|
|
317
|
-
const
|
|
318
|
-
const baselinePct = sliderTotalCapacity <= 0 ? 0 : sliderHoldingsValue / sliderTotalCapacity * 100;
|
|
318
|
+
const safeTotalTokens = totalTokens > 0 ? totalTokens : 1;
|
|
319
|
+
const baselineOwnershipActual = clamp(effectiveTokensHeld / safeTotalTokens * 100, 0, 100);
|
|
319
320
|
let deltaTokens = 0;
|
|
320
321
|
let deltaValue = 0;
|
|
321
322
|
let marketAvgPrice = null;
|
|
@@ -361,29 +362,21 @@ function HousePositionSlider({
|
|
|
361
362
|
}
|
|
362
363
|
targetTokens = tokensHeld + deltaTokens;
|
|
363
364
|
targetValue = targetTokens * effectivePrice;
|
|
364
|
-
const
|
|
365
|
-
|
|
366
|
-
if (buyTrackingMode === "dollars") {
|
|
367
|
-
const notional = Math.min(Math.max(0, deltaDollars), effectiveAvailableCash);
|
|
368
|
-
return notional;
|
|
369
|
-
}
|
|
370
|
-
const tokensPlanned = Math.max(0, deltaTokensBuy);
|
|
371
|
-
const referencePrice = orderType === "market" ? currentPrice || limitPriceSafe : limitPriceSafe;
|
|
372
|
-
return Math.min(tokensPlanned * referencePrice, effectiveAvailableCash);
|
|
373
|
-
}
|
|
374
|
-
if (orderMode === "sell") {
|
|
375
|
-
const tokensToSell = Math.abs(Math.min(0, deltaTokensSell));
|
|
376
|
-
const sellValue = tokensToSell * effectivePrice;
|
|
377
|
-
return -Math.min(sellValue, sliderHoldingsValue);
|
|
378
|
-
}
|
|
379
|
-
return 0;
|
|
380
|
-
})();
|
|
381
|
-
const sliderTargetValue = clamp(sliderHoldingsValue + plannedDeltaValue, 0, sliderTotalCapacity);
|
|
382
|
-
const targetPct = sliderTotalCapacity <= 0 ? 0 : sliderTargetValue / sliderTotalCapacity * 100;
|
|
365
|
+
const sliderTargetTokens = clamp(effectiveTokensHeld + deltaTokens, 0, safeTotalTokens);
|
|
366
|
+
const normalizedTargetPct = sliderTargetTokens / safeTotalTokens * 100;
|
|
383
367
|
const isIncrease = orderMode === "buy";
|
|
384
368
|
const hasChange = orderMode !== "none" && (Math.abs(deltaTokens) > 1e-3 || Math.abs(deltaValue) > 0.01);
|
|
385
|
-
const currentOwnership = totalTokens <= 0 ? 0 : tokensHeld / totalTokens * 100;
|
|
386
|
-
const targetOwnership = totalTokens <= 0 ? 0 : targetTokens / totalTokens * 100;
|
|
369
|
+
const currentOwnership = totalTokens <= 0 ? 0 : clamp(tokensHeld / totalTokens * 100, 0, 100);
|
|
370
|
+
const targetOwnership = totalTokens <= 0 ? 0 : clamp(targetTokens / totalTokens * 100, 0, 100);
|
|
371
|
+
const ownershipOverrideValue = typeof ownershipPercentOverride === "number" && Number.isFinite(ownershipPercentOverride) ? clamp(ownershipPercentOverride, 0, 100) : null;
|
|
372
|
+
const ownershipShift = ownershipOverrideValue != null ? ownershipOverrideValue - baselineOwnershipActual : 0;
|
|
373
|
+
const baselinePct = clamp(ownershipOverrideValue ?? baselineOwnershipActual, 0, 100);
|
|
374
|
+
const impliedTargetPct = clamp(normalizedTargetPct + ownershipShift, 0, 100);
|
|
375
|
+
const displayTargetPct = visualTargetPct ?? impliedTargetPct;
|
|
376
|
+
const targetPct = displayTargetPct;
|
|
377
|
+
const displayCurrentOwnership = clamp(ownershipOverrideValue ?? currentOwnership, 0, 100);
|
|
378
|
+
const impliedDisplayTargetOwnership = clamp(targetOwnership + ownershipShift, 0, 100);
|
|
379
|
+
const displayTargetOwnership = visualTargetPct ?? impliedDisplayTargetOwnership;
|
|
387
380
|
const estFeeTokens = Math.abs(deltaValue) * 5e-3 / (effectivePrice || 1);
|
|
388
381
|
const resetOrder = React5.useCallback(() => {
|
|
389
382
|
setOrderMode("none");
|
|
@@ -391,6 +384,7 @@ function HousePositionSlider({
|
|
|
391
384
|
setDeltaDollars(0);
|
|
392
385
|
setDeltaTokensBuy(0);
|
|
393
386
|
setDeltaTokensSell(0);
|
|
387
|
+
setVisualTargetPct(null);
|
|
394
388
|
}, []);
|
|
395
389
|
const updateOrderFromTargetValue = React5.useCallback(
|
|
396
390
|
(newTargetValue) => {
|
|
@@ -421,6 +415,7 @@ function HousePositionSlider({
|
|
|
421
415
|
const nextOwnership = clamp(newOwnershipPercent, 0, 100);
|
|
422
416
|
const newTargetTokens = nextOwnership / 100 * totalTokens;
|
|
423
417
|
updateOrderFromTargetValue(newTargetTokens * effectivePrice);
|
|
418
|
+
setVisualTargetPct(nextOwnership);
|
|
424
419
|
},
|
|
425
420
|
[effectivePrice, totalTokens, updateOrderFromTargetValue]
|
|
426
421
|
);
|
|
@@ -453,12 +448,14 @@ function HousePositionSlider({
|
|
|
453
448
|
const magnitude = Math.min(Math.abs(normalized), 1);
|
|
454
449
|
if (magnitude < 0.02) {
|
|
455
450
|
resetOrder();
|
|
451
|
+
setVisualTargetPct(null);
|
|
456
452
|
return;
|
|
457
453
|
}
|
|
458
454
|
if (normalized > 0) {
|
|
459
455
|
const notional = clamp(magnitude * effectiveAvailableCash, 0, effectiveAvailableCash);
|
|
460
456
|
if (notional <= 0) {
|
|
461
457
|
resetOrder();
|
|
458
|
+
setVisualTargetPct(null);
|
|
462
459
|
return;
|
|
463
460
|
}
|
|
464
461
|
setOrderMode("buy");
|
|
@@ -466,12 +463,14 @@ function HousePositionSlider({
|
|
|
466
463
|
setDeltaDollars(notional);
|
|
467
464
|
setDeltaTokensBuy(0);
|
|
468
465
|
setDeltaTokensSell(0);
|
|
466
|
+
setVisualTargetPct(clamp(pct, 0, 100));
|
|
469
467
|
return;
|
|
470
468
|
}
|
|
471
469
|
if (normalized < 0) {
|
|
472
470
|
const tokensToSell = clamp(magnitude * effectiveTokensHeld, 0, effectiveTokensHeld);
|
|
473
471
|
if (tokensToSell <= 0) {
|
|
474
472
|
resetOrder();
|
|
473
|
+
setVisualTargetPct(null);
|
|
475
474
|
return;
|
|
476
475
|
}
|
|
477
476
|
setOrderMode("sell");
|
|
@@ -479,9 +478,11 @@ function HousePositionSlider({
|
|
|
479
478
|
setDeltaTokensSell(-tokensToSell);
|
|
480
479
|
setDeltaDollars(0);
|
|
481
480
|
setDeltaTokensBuy(0);
|
|
481
|
+
setVisualTargetPct(clamp(pct, 0, 100));
|
|
482
482
|
return;
|
|
483
483
|
}
|
|
484
484
|
resetOrder();
|
|
485
|
+
setVisualTargetPct(null);
|
|
485
486
|
},
|
|
486
487
|
[effectiveAvailableCash, effectiveTokensHeld, resetOrder]
|
|
487
488
|
);
|
|
@@ -644,19 +645,19 @@ function HousePositionSlider({
|
|
|
644
645
|
" Ownership"
|
|
645
646
|
] }),
|
|
646
647
|
/* @__PURE__ */ jsxs("span", { className: "text-white", children: [
|
|
647
|
-
|
|
648
|
+
displayCurrentOwnership.toFixed(2),
|
|
648
649
|
"%",
|
|
649
650
|
/* @__PURE__ */ jsx("span", { className: "mx-1.5 text-white/50", children: "\u2192" }),
|
|
650
651
|
/* @__PURE__ */ jsx(
|
|
651
652
|
"input",
|
|
652
653
|
{
|
|
653
654
|
type: "text",
|
|
654
|
-
value: ownershipInput ||
|
|
655
|
+
value: ownershipInput || displayTargetOwnership.toFixed(2),
|
|
655
656
|
onChange: (e) => {
|
|
656
657
|
const val = e.target.value;
|
|
657
658
|
if (val === "" || /^[0-9]*\.?[0-9]*$/.test(val)) setOwnershipInput(val);
|
|
658
659
|
},
|
|
659
|
-
onFocus: () => setOwnershipInput(
|
|
660
|
+
onFocus: () => setOwnershipInput(displayTargetOwnership.toFixed(2)),
|
|
660
661
|
onBlur: () => {
|
|
661
662
|
const num = Number.parseFloat(ownershipInput);
|
|
662
663
|
if (Number.isFinite(num)) updateOrderFromOwnership(num);
|
|
@@ -667,7 +668,7 @@ function HousePositionSlider({
|
|
|
667
668
|
},
|
|
668
669
|
className: cn(
|
|
669
670
|
"w-[70px] rounded-[4px] border bg-white/10 px-2 py-1 text-right font-semibold outline-none",
|
|
670
|
-
|
|
671
|
+
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]"
|
|
671
672
|
)
|
|
672
673
|
}
|
|
673
674
|
)
|
|
@@ -1295,12 +1296,13 @@ var PropertyCompareBar = React5.forwardRef(
|
|
|
1295
1296
|
{
|
|
1296
1297
|
ref,
|
|
1297
1298
|
className: cn(
|
|
1298
|
-
"flex w-full flex-col gap-3
|
|
1299
|
+
"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",
|
|
1299
1300
|
className
|
|
1300
1301
|
),
|
|
1302
|
+
style: { borderRadius: "16px" },
|
|
1301
1303
|
...props,
|
|
1302
1304
|
children: [
|
|
1303
|
-
/* @__PURE__ */ jsxs("div", { className: "relative
|
|
1305
|
+
/* @__PURE__ */ jsxs("div", { className: "relative w-auto", ref: dropdownRef, children: [
|
|
1304
1306
|
/* @__PURE__ */ jsxs(
|
|
1305
1307
|
"button",
|
|
1306
1308
|
{
|
|
@@ -1308,7 +1310,7 @@ var PropertyCompareBar = React5.forwardRef(
|
|
|
1308
1310
|
disabled: !hasAddresses,
|
|
1309
1311
|
onClick: () => setIsDropdownOpen((prev) => !prev),
|
|
1310
1312
|
className: cn(
|
|
1311
|
-
"flex h-[42px] w-
|
|
1313
|
+
"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",
|
|
1312
1314
|
!hasAddresses && "text-white/40"
|
|
1313
1315
|
),
|
|
1314
1316
|
children: [
|
|
@@ -1327,7 +1329,7 @@ var PropertyCompareBar = React5.forwardRef(
|
|
|
1327
1329
|
]
|
|
1328
1330
|
}
|
|
1329
1331
|
),
|
|
1330
|
-
isDropdownOpen && hasAddresses ? /* @__PURE__ */ jsx("div", { className: "absolute left-0 top-[calc(100%+8px)] z-20 w-full rounded-[12px] border border-
|
|
1332
|
+
isDropdownOpen && hasAddresses ? /* @__PURE__ */ 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) => {
|
|
1331
1333
|
const active = option.id === resolvedSelectedId;
|
|
1332
1334
|
return /* @__PURE__ */ jsx(
|
|
1333
1335
|
"button",
|
|
@@ -1349,7 +1351,7 @@ var PropertyCompareBar = React5.forwardRef(
|
|
|
1349
1351
|
{
|
|
1350
1352
|
variant: "accentOutline",
|
|
1351
1353
|
size: "sm",
|
|
1352
|
-
className: "flex
|
|
1354
|
+
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",
|
|
1353
1355
|
onClick: onCompareClick,
|
|
1354
1356
|
disabled: !hasAddresses,
|
|
1355
1357
|
children: [
|