Skip to content

Commit

Permalink
lp form ux improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
noahlitvin committed Feb 7, 2025
1 parent edac914 commit a2f6518
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 38 deletions.
30 changes: 24 additions & 6 deletions packages/app/src/components/DepthChart/usePriceRange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,19 @@ export function usePriceRange(
poolData.ticks.length - 1
)
);
const tick = poolData.ticks[tickIndex];

if (tick && (!highPriceX || adjustedX < highPriceX)) {
const snappedX = CHART_LEFT_MARGIN + tickIndex * xScale;
// Find the high price tick index
const highTickIndex = highPriceX
? Math.round((highPriceX - CHART_LEFT_MARGIN) / xScale)
: poolData.ticks.length - 1;

// Ensure we stay at least one tick spacing away from high price
const maxAllowedIndex = highTickIndex - 1;
const constrainedTickIndex = Math.min(tickIndex, maxAllowedIndex);

const tick = poolData.ticks[constrainedTickIndex];
if (tick) {
const snappedX = CHART_LEFT_MARGIN + constrainedTickIndex * xScale;
setLowPriceX(snappedX);
}
},
Expand Down Expand Up @@ -103,10 +112,19 @@ export function usePriceRange(
poolData.ticks.length - 1
)
);
const tick = poolData.ticks[tickIndex];

if (tick && (!lowPriceX || adjustedX > lowPriceX)) {
const snappedX = CHART_LEFT_MARGIN + tickIndex * xScale;
// Find the low price tick index
const lowTickIndex = lowPriceX
? Math.round((lowPriceX - CHART_LEFT_MARGIN) / xScale)
: 0;

// Ensure we stay at least one tick spacing away from low price
const minAllowedIndex = lowTickIndex + 1;
const constrainedTickIndex = Math.max(tickIndex, minAllowedIndex);

const tick = poolData.ticks[constrainedTickIndex];
if (tick) {
const snappedX = CHART_LEFT_MARGIN + constrainedTickIndex * xScale;
setHighPriceX(snappedX);
}
},
Expand Down
36 changes: 35 additions & 1 deletion packages/app/src/components/Liquidity/LiquidityForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1131,8 +1131,42 @@ const LiquidityForm: React.FC = () => {
if (!isEdit) {
const displayPrice = Number(price);
const marketPrice = convertDisplayToMarketPrice(displayPrice);

// Get min and max market prices
const minMarketPrice = tickToPrice(baseAssetMinPriceTick);
const maxMarketPrice = tickToPrice(baseAssetMaxPriceTick);

// Get current other price value for comparison
const otherPriceStr = isLow
? form.getValues('highPrice')
: form.getValues('lowPrice');
const otherDisplayPrice = Number(otherPriceStr);
const otherMarketPrice = convertDisplayToMarketPrice(otherDisplayPrice);

// Calculate price one tick spacing away from other price
const otherTick = priceToTick(otherMarketPrice, tickSpacing);
const oneTickAwayPrice = isLow
? tickToPrice(otherTick - tickSpacing) // One tick below high price
: tickToPrice(otherTick + tickSpacing); // One tick above low price

// Enforce min/max constraints in market units
let constrainedMarketPrice = marketPrice;
if (isLow) {
// Low price must be between min price and one tick below high price
constrainedMarketPrice = Math.min(
Math.max(marketPrice, minMarketPrice),
oneTickAwayPrice
);
} else {
// High price must be between one tick above low price and max price
constrainedMarketPrice = Math.max(
Math.min(marketPrice, maxMarketPrice),
oneTickAwayPrice
);
}

const { tick, price: snappedMarketPrice } = snapPriceToTick(
marketPrice,
constrainedMarketPrice,
tickSpacing
);
const snappedDisplayPrice =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { useContext } from 'react';
import type { Control, Path, FieldValues } from 'react-hook-form';
import { Controller } from 'react-hook-form';

import { useFoil } from '../../../lib/context/FoilProvider';
import { FormItem, FormLabel, FormMessage } from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { PeriodContext } from '~/lib/context/PeriodProvider';
Expand All @@ -18,46 +17,19 @@ interface Props<T extends FieldValues> {
onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
}

const getTickSpacingForFee = (fee: number): number => {
if (fee === 100) {
return 1;
}
if (fee === 500) {
return 10;
}
if (fee === 3000) {
return 60;
}
if (fee === 10000) {
return 200;
}
return 0;
};

const LiquidityPriceInput = <T extends FieldValues>({
label,
name,
control,
isDisabled = false,
onBlur: externalOnBlur,
}: Props<T>) => {
const { stEthPerToken } = useFoil();
const { collateralAssetTicker, useMarketUnits, marketParams } =
useContext(PeriodContext);
const { collateralAssetTicker, useMarketUnits } = useContext(PeriodContext);

const getCurrentUnit = () => {
return useMarketUnits ? `Ggas/${collateralAssetTicker}` : 'gwei';
};

// TODO: I don't think this is right
const tickSpacing = getTickSpacingForFee(marketParams.feeRate);
// Calculate the price ratio for one tick spacing
const priceRatio = 1.0001 ** tickSpacing;
// The step should be the minimum price change
const step = useMarketUnits
? priceRatio - 1 // For market units, use the raw price ratio change
: ((priceRatio - 1) * (stEthPerToken || 0)) / 1e9; // For gwei, convert the price ratio change

return (
<div className="mb-4">
<Controller
Expand Down Expand Up @@ -86,8 +58,7 @@ const LiquidityPriceInput = <T extends FieldValues>({
inputMode="decimal"
disabled={isDisabled}
onWheel={(e) => e.currentTarget.blur()}
className="pr-[120px]"
step={step}
className="pr-[120px] [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
/>
<div className="absolute inset-y-0 right-0 flex items-center px-3 border border-input bg-muted rounded-r-md">
{getCurrentUnit()}
Expand Down

0 comments on commit a2f6518

Please sign in to comment.