From eea015600281ed67db7df3d7931e58f976873c15 Mon Sep 17 00:00:00 2001 From: kushagrasarathe <76868364+kushagrasarathe@users.noreply.github.com> Date: Thu, 10 Jul 2025 12:59:48 +0530 Subject: [PATCH] feat: resuable slider component --- package.json | 1 + pnpm-lock.yaml | 111 ++++++++++++++++++ .../AddWithdraw/AddWithdrawRouterView.tsx | 8 +- src/components/Slider/index.tsx | 74 ++++++++++++ .../TransactionDetailsDrawer.tsx | 16 +-- 5 files changed, 201 insertions(+), 9 deletions(-) create mode 100644 src/components/Slider/index.tsx diff --git a/package.json b/package.json index 3af682a87..a2ea4c505 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "@hookform/resolvers": "3.9.1", "@justaname.id/react": "0.3.180", "@justaname.id/sdk": "0.2.177", + "@radix-ui/react-slider": "^1.3.5", "@reduxjs/toolkit": "^2.5.0", "@reown/appkit": "1.6.9", "@reown/appkit-adapter-wagmi": "1.6.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ef1c783c8..ebb8cb8ec 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -52,6 +52,9 @@ importers: '@justaname.id/sdk': specifier: 0.2.177 version: 0.2.177(ethers@5.7.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(siwe@2.3.2(ethers@5.7.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(viem@2.22.11(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1)) + '@radix-ui/react-slider': + specifier: ^1.3.5 + version: 1.3.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@reduxjs/toolkit': specifier: ^2.5.0 version: 2.5.0(react-redux@9.2.0(@types/react@18.3.18)(react@19.1.0)(redux@5.0.1))(react@19.1.0) @@ -2406,9 +2409,25 @@ packages: engines: {node: '>=18'} hasBin: true + '@radix-ui/number@1.1.1': + resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} + '@radix-ui/primitive@1.1.2': resolution: {integrity: sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==} + '@radix-ui/react-collection@1.1.7': + resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-compose-refs@1.1.2': resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} peerDependencies: @@ -2440,6 +2459,15 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-direction@1.1.1': + resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-dismissable-layer@1.1.10': resolution: {integrity: sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==} peerDependencies: @@ -2523,6 +2551,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-slider@1.3.5': + resolution: {integrity: sha512-rkfe2pU2NBAYfGaxa3Mqosi7VZEWX5CxKaanRv0vZd4Zhl9fvQrg0VM93dv3xGLGfrHuoTRF3JXH8nb9g+B3fw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-slot@1.2.3': resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} peerDependencies: @@ -2577,6 +2618,24 @@ packages: '@types/react': optional: true + '@radix-ui/react-use-previous@1.1.1': + resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-size@1.1.1': + resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@react-native/assets-registry@0.77.0': resolution: {integrity: sha512-Ms4tYYAMScgINAXIhE4riCFJPPL/yltughHS950l0VP5sm5glbimn9n7RFn9Tc8cipX74/ddbk19+ydK2iDMmA==} engines: {node: '>=18'} @@ -10476,8 +10535,22 @@ snapshots: - bare-buffer - supports-color + '@radix-ui/number@1.1.1': {} + '@radix-ui/primitive@1.1.2': {} + '@radix-ui/react-collection@1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.18)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@radix-ui/react-compose-refs@1.1.2(@types/react@18.3.18)(react@19.1.0)': dependencies: react: 19.1.0 @@ -10512,6 +10585,12 @@ snapshots: '@types/react': 18.3.18 '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@radix-ui/react-direction@1.1.1(@types/react@18.3.18)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 18.3.18 + '@radix-ui/react-dismissable-layer@1.1.10(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.2 @@ -10578,6 +10657,25 @@ snapshots: '@types/react': 18.3.18 '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@radix-ui/react-slider@1.3.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.18)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.18)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.18)(react@19.1.0) + '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.18)(react@19.1.0) + '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.18)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + '@radix-ui/react-slot@1.2.3(@types/react@18.3.18)(react@19.1.0)': dependencies: '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.18)(react@19.1.0) @@ -10619,6 +10717,19 @@ snapshots: optionalDependencies: '@types/react': 18.3.18 + '@radix-ui/react-use-previous@1.1.1(@types/react@18.3.18)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 18.3.18 + + '@radix-ui/react-use-size@1.1.1(@types/react@18.3.18)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.18)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 18.3.18 + '@react-native/assets-registry@0.77.0': {} '@react-native/babel-plugin-codegen@0.77.0(@babel/preset-env@7.26.0(@babel/core@7.26.0))': diff --git a/src/components/AddWithdraw/AddWithdrawRouterView.tsx b/src/components/AddWithdraw/AddWithdrawRouterView.tsx index 50fc5b49c..e2b8ed69a 100644 --- a/src/components/AddWithdraw/AddWithdrawRouterView.tsx +++ b/src/components/AddWithdraw/AddWithdrawRouterView.tsx @@ -9,7 +9,13 @@ import { import EmptyState from '@/components/Global/EmptyStates/EmptyState' import NavHeader from '@/components/Global/NavHeader' import { SearchInput } from '@/components/SearchUsers/SearchInput' -import { RecentMethod, getUserPreferences, updateUserPreferences, shortenAddressLong, formatIban } from '@/utils/general.utils' +import { + RecentMethod, + getUserPreferences, + updateUserPreferences, + shortenAddressLong, + formatIban, +} from '@/utils/general.utils' import { useRouter } from 'next/navigation' import { FC, useEffect, useMemo, useState } from 'react' import { useUserStore } from '@/redux/hooks' diff --git a/src/components/Slider/index.tsx b/src/components/Slider/index.tsx new file mode 100644 index 000000000..8aa2a3711 --- /dev/null +++ b/src/components/Slider/index.tsx @@ -0,0 +1,74 @@ +'use client' + +import * as React from 'react' +import * as SliderPrimitive from '@radix-ui/react-slider' +import { twMerge } from 'tailwind-merge' +import { Icon } from '../Global/Icons/Icon' + +export interface SliderProps + extends Omit< + React.ComponentPropsWithoutRef, + 'value' | 'onValueChange' | 'max' | 'step' | 'defaultValue' + > { + value?: boolean + onValueChange?: (value: boolean) => void + defaultValue?: boolean +} + +const Slider = React.forwardRef, SliderProps>( + ({ className, value, onValueChange, defaultValue, ...props }, ref) => { + const isControlled = value !== undefined + const [uncontrolledState, setUncontrolledState] = React.useState(defaultValue ?? false) + const currentValue = isControlled ? value : uncontrolledState + + const [slidingValue, setSlidingValue] = React.useState(null) + + const displayValue = slidingValue ?? (currentValue ? [100] : [0]) + + const handleValueChange = (newValue: number[]) => { + setSlidingValue(newValue) + } + + const handleValueCommit = (committedValue: number[]) => { + const isChecked = committedValue[0] > 50 + if (onValueChange) { + onValueChange(isChecked) + } + if (!isControlled) { + setUncontrolledState(isChecked) + } + setSlidingValue(null) + } + + return ( + + + +
+ Slide to Proceed +
+
+ +
+ +
+
+
+ ) + } +) +Slider.displayName = SliderPrimitive.Root.displayName + +export { Slider } diff --git a/src/components/TransactionDetails/TransactionDetailsDrawer.tsx b/src/components/TransactionDetails/TransactionDetailsDrawer.tsx index 4f23b1da8..57935d6ef 100644 --- a/src/components/TransactionDetails/TransactionDetailsDrawer.tsx +++ b/src/components/TransactionDetails/TransactionDetailsDrawer.tsx @@ -440,16 +440,16 @@ export const TransactionDetailsReceipt = ({ value={
- { - formatIban(transaction.extraDataForDrawer.depositInstructions - .iban) - } + {formatIban( + transaction.extraDataForDrawer.depositInstructions + .iban + )}