update bybit ui to include hedge

master
TZGyn 9 months ago
parent 7e88251df7
commit 3e3d1088d4
Signed by: TZGyn
GPG Key ID: 122EAF77AE81FD4A

@ -17,13 +17,14 @@
}, },
"devDependencies": { "devDependencies": {
"@internationalized/date": "^3.5.6", "@internationalized/date": "^3.5.6",
"@lucide/svelte": "^0.482.0",
"@sveltejs/adapter-auto": "^3.0.0", "@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/adapter-node": "^5.2.12", "@sveltejs/adapter-node": "^5.2.12",
"@sveltejs/kit": "^2.17.1", "@sveltejs/kit": "^2.17.1",
"@sveltejs/vite-plugin-svelte": "^4.0.0", "@sveltejs/vite-plugin-svelte": "^4.0.0",
"@types/bun": "^1.2.2", "@types/bun": "^1.2.2",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"bits-ui": "^1.0.0-next.86", "bits-ui": "^1.3.12",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"formsnap": "^2.0.0-next.1", "formsnap": "^2.0.0-next.1",
"lucide-svelte": "^0.471.0", "lucide-svelte": "^0.471.0",
@ -295,6 +296,8 @@
"@layerzerolabs/scan-client": ["@layerzerolabs/scan-client@0.0.8", "", { "peerDependencies": { "axios": "*" } }, "sha512-V9vvt9GW0+AHoWXfOSNmZ9WUa28fVBmC93J/f9RLeDMEy5VR8srW2Du5pf1mMAg6ncEL0kQ1xkVCu+X6ARFBtQ=="], "@layerzerolabs/scan-client": ["@layerzerolabs/scan-client@0.0.8", "", { "peerDependencies": { "axios": "*" } }, "sha512-V9vvt9GW0+AHoWXfOSNmZ9WUa28fVBmC93J/f9RLeDMEy5VR8srW2Du5pf1mMAg6ncEL0kQ1xkVCu+X6ARFBtQ=="],
"@lucide/svelte": ["@lucide/svelte@0.482.0", "", { "peerDependencies": { "svelte": "^5" } }, "sha512-n2ycHU9cNcleRDwwpEHBJ6pYzVhHIaL3a+9dQa8kns9hB2g05bY+v2p2KP8v0pZwtNhYTHk/F2o2uZ1bVtQGhw=="],
"@metamask/eth-sig-util": ["@metamask/eth-sig-util@4.0.1", "", { "dependencies": { "ethereumjs-abi": "^0.6.8", "ethereumjs-util": "^6.2.1", "ethjs-util": "^0.1.6", "tweetnacl": "^1.0.3", "tweetnacl-util": "^0.15.1" } }, "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ=="], "@metamask/eth-sig-util": ["@metamask/eth-sig-util@4.0.1", "", { "dependencies": { "ethereumjs-abi": "^0.6.8", "ethereumjs-util": "^6.2.1", "ethjs-util": "^0.1.6", "tweetnacl": "^1.0.3", "tweetnacl-util": "^0.15.1" } }, "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ=="],
"@metaplex-foundation/beet": ["@metaplex-foundation/beet@0.2.0", "", { "dependencies": { "ansicolors": "^0.3.2", "bn.js": "^5.2.0", "debug": "^4.3.3" } }, "sha512-H570hkJxmx/FxET1OggPPLkPL7psYQa71rNI9NJjYRM8WXdrEvmI/IRIEUW2KR6RqwWWN3FvlRHnKoQUV/lQtA=="], "@metaplex-foundation/beet": ["@metaplex-foundation/beet@0.2.0", "", { "dependencies": { "ansicolors": "^0.3.2", "bn.js": "^5.2.0", "debug": "^4.3.3" } }, "sha512-H570hkJxmx/FxET1OggPPLkPL7psYQa71rNI9NJjYRM8WXdrEvmI/IRIEUW2KR6RqwWWN3FvlRHnKoQUV/lQtA=="],
@ -825,7 +828,7 @@
"bitcoin-address-validation": ["bitcoin-address-validation@2.2.1", "", { "dependencies": { "base58-js": "^1.0.0", "bech32": "^2.0.0", "sha256-uint8array": "^0.10.3" } }, "sha512-f6LXNpvRKlTbHWb37N9tHoAbYGbshzM8FPWvCtloh++hxZ0/dmkokvKNVLz6HkG82zVwo8w6Sq4JmfO2timzyg=="], "bitcoin-address-validation": ["bitcoin-address-validation@2.2.1", "", { "dependencies": { "base58-js": "^1.0.0", "bech32": "^2.0.0", "sha256-uint8array": "^0.10.3" } }, "sha512-f6LXNpvRKlTbHWb37N9tHoAbYGbshzM8FPWvCtloh++hxZ0/dmkokvKNVLz6HkG82zVwo8w6Sq4JmfO2timzyg=="],
"bits-ui": ["bits-ui@1.0.0-next.86", "", { "dependencies": { "@floating-ui/core": "^1.6.4", "@floating-ui/dom": "^1.6.7", "@internationalized/date": "^3.5.6", "esm-env": "^1.1.2", "runed": "^0.23.2", "svelte-toolbelt": "^0.7.1" }, "peerDependencies": { "svelte": "^5.11.0" } }, "sha512-C2sTO3sasGoRhoMG2CUUsGfOhAoRL5Jc4pVB6AxoKQ+FBmX/uG9K1tW44eT/801iMoH+QeaH6fNCnoshpZtS8A=="], "bits-ui": ["bits-ui@1.3.12", "", { "dependencies": { "@floating-ui/core": "^1.6.4", "@floating-ui/dom": "^1.6.7", "@internationalized/date": "^3.5.6", "esm-env": "^1.1.2", "runed": "^0.23.2", "svelte-toolbelt": "^0.7.1", "tabbable": "^6.2.0" }, "peerDependencies": { "svelte": "^5.11.0" } }, "sha512-RhPvg2e7mTQSXR9WMdsyR5eTC2DSa4ch5MT/TjIaN3suMJ3RGlbzYPNvf4n56Lgck3W4Xm+L4jSgrzTdynuM8Q=="],
"bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="], "bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="],
@ -1927,6 +1930,8 @@
"symbol.inspect": ["symbol.inspect@1.0.1", "", {}, "sha512-YQSL4duoHmLhsTD1Pw8RW6TZ5MaTX5rXJnqacJottr2P2LZBF/Yvrc3ku4NUpMOm8aM0KOCqM+UAkMA5HWQCzQ=="], "symbol.inspect": ["symbol.inspect@1.0.1", "", {}, "sha512-YQSL4duoHmLhsTD1Pw8RW6TZ5MaTX5rXJnqacJottr2P2LZBF/Yvrc3ku4NUpMOm8aM0KOCqM+UAkMA5HWQCzQ=="],
"tabbable": ["tabbable@6.2.0", "", {}, "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="],
"tailwind-merge": ["tailwind-merge@2.5.4", "", {}, "sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q=="], "tailwind-merge": ["tailwind-merge@2.5.4", "", {}, "sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q=="],
"tailwind-variants": ["tailwind-variants@0.2.1", "", { "dependencies": { "tailwind-merge": "^2.2.0" }, "peerDependencies": { "tailwindcss": "*" } }, "sha512-2xmhAf4UIc3PijOUcJPA1LP4AbxhpcHuHM2C26xM0k81r0maAO6uoUSHl3APmvHZcY5cZCY/bYuJdfFa4eGoaw=="], "tailwind-variants": ["tailwind-variants@0.2.1", "", { "dependencies": { "tailwind-merge": "^2.2.0" }, "peerDependencies": { "tailwindcss": "*" } }, "sha512-2xmhAf4UIc3PijOUcJPA1LP4AbxhpcHuHM2C26xM0k81r0maAO6uoUSHl3APmvHZcY5cZCY/bYuJdfFa4eGoaw=="],

@ -16,13 +16,14 @@
}, },
"devDependencies": { "devDependencies": {
"@internationalized/date": "^3.5.6", "@internationalized/date": "^3.5.6",
"@lucide/svelte": "^0.482.0",
"@sveltejs/adapter-auto": "^3.0.0", "@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/adapter-node": "^5.2.12", "@sveltejs/adapter-node": "^5.2.12",
"@sveltejs/kit": "^2.17.1", "@sveltejs/kit": "^2.17.1",
"@sveltejs/vite-plugin-svelte": "^4.0.0", "@sveltejs/vite-plugin-svelte": "^4.0.0",
"@types/bun": "^1.2.2", "@types/bun": "^1.2.2",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"bits-ui": "^1.0.0-next.86", "bits-ui": "^1.3.12",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"formsnap": "^2.0.0-next.1", "formsnap": "^2.0.0-next.1",
"lucide-svelte": "^0.471.0", "lucide-svelte": "^0.471.0",

@ -0,0 +1,35 @@
<script lang="ts">
import { Checkbox as CheckboxPrimitive, type WithoutChildrenOrChild } from "bits-ui";
import Check from "@lucide/svelte/icons/check";
import Minus from "@lucide/svelte/icons/minus";
import { cn } from "$lib/utils.js";
let {
ref = $bindable(null),
checked = $bindable(false),
indeterminate = $bindable(false),
class: className,
...restProps
}: WithoutChildrenOrChild<CheckboxPrimitive.RootProps> = $props();
</script>
<CheckboxPrimitive.Root
bind:ref
class={cn(
"border-primary ring-offset-background focus-visible:ring-ring data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground peer box-content size-4 shrink-0 rounded-sm border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50",
className
)}
bind:checked
bind:indeterminate
{...restProps}
>
{#snippet children({ checked, indeterminate })}
<div class="flex size-4 items-center justify-center text-current">
{#if indeterminate}
<Minus class="size-3.5" />
{:else}
<Check class={cn("size-3.5", !checked && "text-transparent")} />
{/if}
</div>
{/snippet}
</CheckboxPrimitive.Root>

@ -0,0 +1,6 @@
import Root from "./checkbox.svelte";
export {
Root,
//
Root as Checkbox,
};

@ -15,6 +15,7 @@
import copy from 'copy-to-clipboard' import copy from 'copy-to-clipboard'
import json5 from 'json5' import json5 from 'json5'
import { toast } from 'svelte-sonner' import { toast } from 'svelte-sonner'
import { Checkbox } from '$lib/components/ui/checkbox'
let { data } = $props() let { data } = $props()
@ -32,6 +33,7 @@
leverage: $formData.leverage.toString(), leverage: $formData.leverage.toString(),
takeProfit: $formData.takeProfit.toString(), takeProfit: $formData.takeProfit.toString(),
stopLoss: $formData.stopLoss.toString(), stopLoss: $formData.stopLoss.toString(),
hedge: $formData.hedge.toString(),
}, },
null, null,
2, 2,
@ -62,6 +64,7 @@
$percentFormData.takeProfitPercent.toString(), $percentFormData.takeProfitPercent.toString(),
stopLossPercent: stopLossPercent:
$percentFormData.stopLossPercent.toString(), $percentFormData.stopLossPercent.toString(),
hedge: $percentFormData.hedge.toString(),
}, },
null, null,
2, 2,
@ -84,6 +87,8 @@
{ {
type: 'Close Position', type: 'Close Position',
...$closePositionFormData, ...$closePositionFormData,
hedge: $closePositionFormData.hedge.toString(),
side: $closePositionFormData.side.toString(),
}, },
null, null,
2, 2,
@ -211,6 +216,16 @@
<Form.Description>Stop Loss</Form.Description> <Form.Description>Stop Loss</Form.Description>
<Form.FieldErrors /> <Form.FieldErrors />
</Form.Field> </Form.Field>
<Form.Field {form} name="hedge">
<Form.Control>
{#snippet children({ props })}
<Form.Label>Hedge</Form.Label>
<Checkbox {...props} bind:checked={$formData.hedge} />
{/snippet}
</Form.Control>
<Form.Description>Leverage</Form.Description>
<Form.FieldErrors />
</Form.Field>
<Form.Button class="col-span-2">Copy</Form.Button> <Form.Button class="col-span-2">Copy</Form.Button>
</form> </form>
@ -222,6 +237,7 @@
leverage: $formData.leverage.toString(), leverage: $formData.leverage.toString(),
takeProfit: $formData.takeProfit.toString(), takeProfit: $formData.takeProfit.toString(),
stopLoss: $formData.stopLoss.toString(), stopLoss: $formData.stopLoss.toString(),
hedge: $formData.hedge.toString(),
}} /> }} />
</Tabs.Content> </Tabs.Content>
<Tabs.Content value="percent"> <Tabs.Content value="percent">
@ -368,6 +384,18 @@
max={100} max={100}
step={0.1} /> step={0.1} />
</Form.Field> </Form.Field>
<Form.Field form={percentForm} name="hedge">
<Form.Control>
{#snippet children({ props })}
<Form.Label>Hedge</Form.Label>
<Checkbox
{...props}
bind:checked={$percentFormData.hedge} />
{/snippet}
</Form.Control>
<Form.Description>Leverage</Form.Description>
<Form.FieldErrors />
</Form.Field>
<Form.Button class="col-span-2">Copy</Form.Button> <Form.Button class="col-span-2">Copy</Form.Button>
</form> </form>
@ -384,6 +412,7 @@
$percentFormData.takeProfitPercent.toString(), $percentFormData.takeProfitPercent.toString(),
stopLossPercent: stopLossPercent:
$percentFormData.stopLossPercent.toString(), $percentFormData.stopLossPercent.toString(),
hedge: $percentFormData.hedge.toString(),
}} /> }} />
</Tabs.Content> </Tabs.Content>
<Tabs.Content value="close"> <Tabs.Content value="close">
@ -427,12 +456,49 @@
<Form.Description>Symbol</Form.Description> <Form.Description>Symbol</Form.Description>
<Form.FieldErrors /> <Form.FieldErrors />
</Form.Field> </Form.Field>
<Form.Field form={closePositionForm} name="hedge">
<Form.Control>
{#snippet children({ props })}
<Form.Label>Hedge</Form.Label>
<Checkbox
{...props}
bind:checked={$closePositionFormData.hedge} />
{/snippet}
</Form.Control>
<Form.Description>Leverage</Form.Description>
<Form.FieldErrors />
</Form.Field>
{#if $closePositionFormData.hedge}
<Form.Field form={closePositionForm} name="side">
<Form.Control>
{#snippet children({ props })}
<Form.Label>Side</Form.Label>
<Select.Root
type="single"
bind:value={$closePositionFormData.side}
name={props.name}>
<Select.Trigger {...props}>
{$closePositionFormData.side ?? 'Select a side'}
</Select.Trigger>
<Select.Content>
<Select.Item value={'Buy'} label={'Buy'} />
<Select.Item value={'Sell'} label={'Sell'} />
</Select.Content>
</Select.Root>
{/snippet}
</Form.Control>
<Form.Description>Side</Form.Description>
<Form.FieldErrors />
</Form.Field>
{/if}
<Form.Button class="col-span-2">Copy</Form.Button> <Form.Button class="col-span-2">Copy</Form.Button>
</form> </form>
<JsonView <JsonView
json={{ json={{
type: 'Close Position', type: 'Close Position',
...$closePositionFormData, ...$closePositionFormData,
hedge: $closePositionFormData.hedge.toString(),
side: $closePositionFormData.side.toString(),
}} /> }} />
</Tabs.Content> </Tabs.Content>
</Tabs.Root> </Tabs.Root>

@ -13,6 +13,7 @@ export const formSchema = z.object({
leverage: z.number().default(100), leverage: z.number().default(100),
takeProfit: z.number(), takeProfit: z.number(),
stopLoss: z.number(), stopLoss: z.number(),
hedge: z.boolean(),
}) })
export const percentSchema = z.object({ export const percentSchema = z.object({
@ -25,12 +26,15 @@ export const percentSchema = z.object({
leverage: z.number().default(100), leverage: z.number().default(100),
takeProfitPercent: z.number(), takeProfitPercent: z.number(),
stopLossPercent: z.number(), stopLossPercent: z.number(),
hedge: z.boolean(),
}) })
export const closePositionSchema = z.object({ export const closePositionSchema = z.object({
key: z.string(), key: z.string(),
secret: z.string(), secret: z.string(),
symbol: z.string(), symbol: z.string(),
hedge: z.boolean(),
side: z.enum(['Buy', 'Sell']),
}) })
export type PercentSchema = typeof percentSchema export type PercentSchema = typeof percentSchema

Loading…
Cancel
Save