Skip to content
Open
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
fa46bfa
Update tradebox header tabs
qwinndev Nov 28, 2025
aacdae0
Update leverage component
qwinndev Nov 30, 2025
2608e4b
Fix TradeBoxHeaderTabs rounding
qwinndev Nov 30, 2025
892dcc2
Update Pool and Collateral fields
qwinndev Nov 30, 2025
04f6216
Update fields placement
qwinndev Dec 1, 2025
870b6f9
Update tradebox fields with responsivness
qwinndev Dec 2, 2025
2746a18
Update componennts names from row to field
qwinndev Dec 2, 2025
43af4aa
Add best pool option to PoolSelector
qwinndev Dec 2, 2025
37b99e8
Fix single pool selection and persist best mode enabling
qwinndev Dec 2, 2025
f35e059
Init margin fields
qwinndev Dec 3, 2025
181a585
Update margin fields with designs
qwinndev Dec 3, 2025
0798082
Price field for margin fields
qwinndev Dec 3, 2025
eac92e6
Small UI improvements in tradebox
qwinndev Dec 4, 2025
73a660a
Update submit tradebox button text
qwinndev Dec 4, 2025
8d751f4
Add TP/SL tooltip and update execution details button bg
qwinndev Dec 4, 2025
f110e9a
Fix naming and remove old sidecar logic
qwinndev Dec 5, 2025
3352c9f
Update sidecar orders UI
qwinndev Dec 5, 2025
0d32336
Tradebox display mode change fixes
qwinndev Dec 5, 2025
4200903
Fix sidecar order dropdown
qwinndev Dec 5, 2025
740a40b
Update side order stop loss values calculations
qwinndev Dec 8, 2025
4bbf245
Init TP/SL columns
qwinndev Dec 8, 2025
78b882f
Update positions list actions
qwinndev Dec 9, 2025
8ff74cb
Add size toggle in PositionList
qwinndev Dec 9, 2025
e5c6ebd
Init new TP/SL modal
qwinndev Dec 10, 2025
c4e5baf
Update TP/SL modal for mobile screens
qwinndev Dec 10, 2025
e4adedc
New AddTPSLModal
qwinndev Dec 11, 2025
f29eb2d
Add OrderEditor on edit TPSLOrdersList click
qwinndev Dec 11, 2025
f1569f7
Update margin slider
qwinndev Dec 11, 2025
c52f449
Update close size change on open in AddTPSLModal
qwinndev Dec 11, 2025
13be4a1
Merge branch 'master' of qwinndev:gmx-io/gmx-interface into tradebox-…
qwinndev Dec 12, 2025
c413551
Add TP/SL creation on limit and stop market order edit
qwinndev Dec 15, 2025
ad51aff
Fix TradeboxMarginFields percentage change
qwinndev Dec 15, 2025
2510521
Keep TP/SL tradebox values on pool and collateral change
qwinndev Dec 15, 2025
07b621d
Better persistance for pool selection and bug fixes
qwinndev Dec 15, 2025
0a9ed58
Fix tradebox margin field size mode changing
qwinndev Dec 15, 2025
1fd928b
Update close button labels
qwinndev Dec 15, 2025
89ebf6a
Update tradebox tabs
qwinndev Dec 16, 2025
0341435
Fixed closing suggestions on click outside
qwinndev Dec 16, 2025
8ca9082
Merge branch 'release' of qwinndev:gmx-io/gmx-interface into tradebox…
qwinndev Dec 16, 2025
ccbc92f
Code improvements
qwinndev Dec 17, 2025
7830ced
Improvements to TPSLInputRow
qwinndev Dec 17, 2025
11d5794
Reduce duplications in TPSLOrdersList
qwinndev Dec 17, 2025
d049e53
Code improvements
qwinndev Dec 17, 2025
3a99e40
Update locales
qwinndev Dec 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"build:analyze": "VITE_APP_VERSION=$(git rev-parse HEAD) vite build --mode analyze",
"build-home": "VITE_APP_VERSION=$(git rev-parse HEAD) env-cmd -e production-home vite build --config vite.landing.config.ts",
"build-home:analyze": "VITE_APP_VERSION=$(git rev-parse HEAD) env-cmd -e production-home vite build --config vite.landing.config.ts --mode analyze",
"build-app": "VITE_APP_VERSION=$(git rev-parse HEAD) env-cmd -e production-app vite build",
"build-app": "NODE_OPTIONS=\"--max-old-space-size=8192\" VITE_APP_VERSION=$(git rev-parse HEAD) env-cmd -e production-app vite build",
"test": "vitest",
"test:ci": "vitest run",
"lint": "node node_modules/.bin/eslint src",
Expand Down
19 changes: 19 additions & 0 deletions src/components/BlockField/BlockField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import cx from "classnames";
import { ReactNode } from "react";

type Props = {
label: ReactNode;
content: ReactNode;
className?: string;
labelClassName?: string;
contentClassName?: string;
};

export function BlockField({ label, content, className, labelClassName, contentClassName }: Props) {
return (
<div className={cx("flex items-center justify-between gap-10 rounded-4 bg-slate-800 px-8 py-[3.5px]", className)}>
<div className={cx("text-13 text-typography-secondary", labelClassName)}>{label}</div>
<div className={cx("flex min-w-0 flex-1 justify-end", contentClassName)}>{content}</div>
</div>
);
}
8 changes: 7 additions & 1 deletion src/components/CollateralSelector/CollateralSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,13 @@ export function CollateralSelector(props: Props) {
const isMobile = useMedia(`(max-width: ${SELECTOR_BASE_MOBILE_THRESHOLD}px)`);

return (
<SelectorBase label={props.selectedTokenSymbol} modalLabel={t`Collateral In`} qa="collateral-in-selector">
<SelectorBase
label={props.selectedTokenSymbol}
modalLabel={t`Collateral In`}
qa="collateral-in-selector"
chevronClassName="w-12 text-typography-secondary max-lg:ml-4"
handleClassName="text-12"
>
{isMobile ? <CollateralSelectorMobile {...props} /> : <CollateralSelectorDesktop {...props} />}
</SelectorBase>
);
Expand Down
15 changes: 13 additions & 2 deletions src/components/ExpandableRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ interface Props {
withToggleSwitch?: boolean;
handleClassName?: string;
chevronClassName?: string;
wrapped?: boolean;
}

export function ExpandableRow({
Expand All @@ -83,6 +84,7 @@ export function ExpandableRow({
withToggleSwitch = false,
handleClassName,
chevronClassName,
wrapped = false,
}: Props) {
const previousHasError = usePrevious(hasError);
const contentRef = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -135,9 +137,18 @@ export function ExpandableRow({
);

return (
<div className={cx("min-h-16", className)}>
<div
className={cx("min-h-16", className, {
"rounded-8 border-1/2 border-slate-600 bg-slate-950/50 px-12 py-10": wrapped,
})}
>
<AnimatePresence initial={false}>
<div key="handle" className={cx({ "mb-14": open })}>
<div
key="handle"
className={cx({
"mb-14": open,
})}
>
<SyntheticsInfoRow
className={cx("group relative !items-center gmx-hover:text-blue-300", {
"cursor-not-allowed": disabled,
Expand Down
96 changes: 96 additions & 0 deletions src/components/LeverageField/LeverageField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { useCallback, useEffect, useMemo, useState } from "react";

import SuggestionInput from "components/SuggestionInput/SuggestionInput";

const defaultMarks = [0.1, 25, 50];
const DEFAULT_LEVERAGE = 20;

type Props = {
value: number | null;
onChange: (value: number) => void;
marks: number[];
};

function clampLeverage(value: number, min: number, max: number) {
const safeMin = min > 0 ? min : DEFAULT_LEVERAGE;
return Math.min(Math.max(value, safeMin), max);
}

function formatLeverage(value: number) {
return parseFloat(value.toFixed(2)).toString();
}

export function LeverageField({ value, onChange, marks }: Props) {
const finalMarks = useMemo(() => (marks?.length ? marks : defaultMarks), [marks]);
const minMark = finalMarks[0] ?? DEFAULT_LEVERAGE;
const maxMark = finalMarks.at(-1) ?? DEFAULT_LEVERAGE;

const [inputValue, setInputValue] = useState<string>(() => {
if (value !== null) {
return formatLeverage(clampLeverage(value, minMark, maxMark));
}

return formatLeverage(minMark);
});

useEffect(() => {
if (value !== null) {
setInputValue(formatLeverage(clampLeverage(value, minMark, maxMark)));
}
}, [value, minMark, maxMark]);

const parseAndClampValue = useCallback(
(rawValue: string) => {
const numericValue = parseFloat(rawValue);

if (Number.isNaN(numericValue) || numericValue <= 0) {
return undefined;
}

return clampLeverage(numericValue, minMark, maxMark);
},
[maxMark, minMark]
);

const commitValue = useCallback(
(rawValue?: string) => {
const nextValue = rawValue ?? inputValue;
const parsed = parseAndClampValue(nextValue);
const fallback = clampLeverage(value ?? minMark, minMark, maxMark);
const finalValue = parsed ?? fallback;
const formatted = formatLeverage(finalValue);

setInputValue(formatted);
onChange(finalValue);
},
[inputValue, maxMark, minMark, onChange, value, parseAndClampValue]
);

const handleInputChange = useCallback(
(nextValue: string) => {
setInputValue(nextValue);

const parsed = parseAndClampValue(nextValue);
if (parsed !== undefined) {
onChange(parsed);
}
},
[parseAndClampValue, onChange]
);

return (
<div data-qa="leverage-slider">
<SuggestionInput
suggestionsPlacement="bottom-start"
value={inputValue ?? "N/A"}
setValue={handleInputChange}
onBlur={commitValue}
suggestionList={finalMarks}
suggestionWithSuffix
suffix="x"
inputClassName="w-full text-right"
className="leading-none !rounded-4 px-0 py-[1.5px]"
/>
</div>
);
}
187 changes: 0 additions & 187 deletions src/components/LeverageSlider/LeverageSlider.tsx

This file was deleted.

Loading