Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
078a5626
Commit
078a5626
authored
Dec 26, 2023
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[skip ci] special style for native coin value field
parent
24b0f112
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
68 additions
and
16 deletions
+68
-16
contract.ts
types/api/contract.ts
+1
-0
ContractMethodCallable.tsx
ui/address/contract/ContractMethodCallable.tsx
+5
-1
ContractMethodCallableRow.tsx
ui/address/contract/ContractMethodCallableRow.tsx
+28
-5
ContractMethodField.tsx
ui/address/contract/ContractMethodField.tsx
+33
-9
ContractMethodsAccordionItem.tsx
ui/address/contract/ContractMethodsAccordionItem.tsx
+1
-1
No files found.
types/api/contract.ts
View file @
078a5626
...
@@ -89,6 +89,7 @@ export interface SmartContractMethodInput {
...
@@ -89,6 +89,7 @@ export interface SmartContractMethodInput {
name
:
string
;
name
:
string
;
type
:
SmartContractMethodArgType
;
type
:
SmartContractMethodArgType
;
components
?:
Array
<
SmartContractMethodInput
>
;
components
?:
Array
<
SmartContractMethodInput
>
;
fieldType
?:
'
native_coin
'
;
}
}
export
interface
SmartContractMethodOutput
extends
SmartContractMethodInput
{
export
interface
SmartContractMethodOutput
extends
SmartContractMethodInput
{
...
...
ui/address/contract/ContractMethodCallable.tsx
View file @
078a5626
...
@@ -6,6 +6,7 @@ import { useForm, FormProvider } from 'react-hook-form';
...
@@ -6,6 +6,7 @@ import { useForm, FormProvider } from 'react-hook-form';
import
type
{
MethodFormFields
,
ContractMethodCallResult
}
from
'
./types
'
;
import
type
{
MethodFormFields
,
ContractMethodCallResult
}
from
'
./types
'
;
import
type
{
SmartContractMethodInput
,
SmartContractMethod
}
from
'
types/api/contract
'
;
import
type
{
SmartContractMethodInput
,
SmartContractMethod
}
from
'
types/api/contract
'
;
import
config
from
'
configs/app
'
;
import
arrowIcon
from
'
icons/arrows/down-right.svg
'
;
import
arrowIcon
from
'
icons/arrows/down-right.svg
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
...
@@ -38,9 +39,10 @@ const ContractMethodCallable = <T extends SmartContractMethod>({ data, onSubmit,
...
@@ -38,9 +39,10 @@ const ContractMethodCallable = <T extends SmartContractMethod>({ data, onSubmit,
return
[
return
[
...(
'
inputs
'
in
data
?
data
.
inputs
:
[]),
...(
'
inputs
'
in
data
?
data
.
inputs
:
[]),
...(
'
stateMutability
'
in
data
&&
data
.
stateMutability
===
'
payable
'
?
[
{
...(
'
stateMutability
'
in
data
&&
data
.
stateMutability
===
'
payable
'
?
[
{
name
:
'
value
'
,
name
:
`Send native ${ config.chain.currency.symbol }`
,
type
:
'
uint256
'
as
const
,
type
:
'
uint256
'
as
const
,
internalType
:
'
uint256
'
as
const
,
internalType
:
'
uint256
'
as
const
,
fieldType
:
'
native_coin
'
as
const
,
}
]
:
[]),
}
]
:
[]),
];
];
},
[
data
]);
},
[
data
]);
...
@@ -139,9 +141,11 @@ const ContractMethodCallable = <T extends SmartContractMethod>({ data, onSubmit,
...
@@ -139,9 +141,11 @@ const ContractMethodCallable = <T extends SmartContractMethod>({ data, onSubmit,
<
ContractMethodCallableRow
<
ContractMethodCallableRow
key=
{
fieldName
}
key=
{
fieldName
}
fieldName=
{
fieldName
}
fieldName=
{
fieldName
}
fieldType=
{
input
.
fieldType
}
argName=
{
input
.
name
}
argName=
{
input
.
name
}
argType=
{
input
.
type
}
argType=
{
input
.
type
}
isDisabled=
{
isLoading
}
isDisabled=
{
isLoading
}
isOptional=
{
input
.
fieldType
===
'
native_coin
'
&&
inputs
.
length
>
1
}
onChange=
{
handleFormChange
}
onChange=
{
handleFormChange
}
/>
/>
);
);
...
...
ui/address/contract/ContractMethodCallableRow.tsx
View file @
078a5626
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
{
useFormContext
}
from
'
react-hook-form
'
;
import
{
useFormContext
}
from
'
react-hook-form
'
;
import
type
{
MethodFormFields
}
from
'
./types
'
;
import
type
{
MethodFormFields
}
from
'
./types
'
;
import
type
{
SmartContractMethodArgType
}
from
'
types/api/contract
'
;
import
type
{
SmartContractMethodArgType
,
SmartContractMethodInput
}
from
'
types/api/contract
'
;
import
ContractMethodField
from
'
./ContractMethodField
'
;
import
ContractMethodField
from
'
./ContractMethodField
'
;
import
ContractMethodFieldArray
from
'
./ContractMethodFieldArray
'
;
import
ContractMethodFieldArray
from
'
./ContractMethodFieldArray
'
;
...
@@ -11,16 +11,19 @@ import { ARRAY_REGEXP } from './utils';
...
@@ -11,16 +11,19 @@ import { ARRAY_REGEXP } from './utils';
interface
Props
{
interface
Props
{
fieldName
:
string
;
fieldName
:
string
;
fieldType
?:
SmartContractMethodInput
[
'
fieldType
'
];
argName
:
string
;
argName
:
string
;
argType
:
SmartContractMethodArgType
;
argType
:
SmartContractMethodArgType
;
onChange
:
()
=>
void
;
onChange
:
()
=>
void
;
isDisabled
:
boolean
;
isDisabled
:
boolean
;
isGrouped
?:
boolean
;
isGrouped
?:
boolean
;
isOptional
?:
boolean
;
}
}
const
ContractMethodCallableRow
=
({
argName
,
fieldName
,
argType
,
onChange
,
isDisabled
,
isGrouped
}:
Props
)
=>
{
const
ContractMethodCallableRow
=
({
argName
,
fieldName
,
fieldType
,
argType
,
onChange
,
isDisabled
,
isGrouped
,
isOptional
}:
Props
)
=>
{
const
{
control
,
getValues
,
setValue
}
=
useFormContext
<
MethodFormFields
>
();
const
{
control
,
getValues
,
setValue
}
=
useFormContext
<
MethodFormFields
>
();
const
arrayTypeMatch
=
argType
.
match
(
ARRAY_REGEXP
);
const
arrayTypeMatch
=
argType
.
match
(
ARRAY_REGEXP
);
const
nativeCoinFieldBgColor
=
useColorModeValue
(
'
blackAlpha.50
'
,
'
whiteAlpha.100
'
);
const
content
=
arrayTypeMatch
?
(
const
content
=
arrayTypeMatch
?
(
<
ContractMethodFieldArray
<
ContractMethodFieldArray
...
@@ -36,27 +39,47 @@ const ContractMethodCallableRow = ({ argName, fieldName, argType, onChange, isDi
...
@@ -36,27 +39,47 @@ const ContractMethodCallableRow = ({ argName, fieldName, argType, onChange, isDi
)
:
(
)
:
(
<
ContractMethodField
<
ContractMethodField
name=
{
fieldName
}
name=
{
fieldName
}
type=
{
fieldType
}
argType=
{
argType
}
argType=
{
argType
}
placeholder=
{
argType
}
placeholder=
{
argType
}
control=
{
control
}
control=
{
control
}
setValue=
{
setValue
}
setValue=
{
setValue
}
getValues=
{
getValues
}
getValues=
{
getValues
}
isDisabled=
{
isDisabled
}
isDisabled=
{
isDisabled
}
isOptional=
{
isOptional
}
onChange=
{
onChange
}
onChange=
{
onChange
}
/>
/>
);
);
const
isNativeCoinField
=
fieldType
===
'
native_coin
'
;
return
(
return
(
<>
<>
<
Box
<
Box
position=
"relative"
fontWeight=
{
500
}
fontWeight=
{
500
}
lineHeight=
"20px"
lineHeight=
"20px"
py=
{
{
lg
:
'
6px
'
}
}
pt=
{
{
base
:
isNativeCoinField
?
'
6px
'
:
0
,
lg
:
isNativeCoinField
?
'
10px
'
:
'
6px
'
}
}
pb=
{
{
lg
:
isNativeCoinField
?
'
10px
'
:
'
6px
'
}
}
fontSize=
"sm"
fontSize=
"sm"
color=
{
isGrouped
?
'
text_secondary
'
:
'
initial
'
}
color=
{
isGrouped
?
'
text_secondary
'
:
'
initial
'
}
wordBreak=
"break-word"
wordBreak=
"break-word"
_before=
{
isNativeCoinField
?
{
content
:
`" "`
,
position
:
'
absolute
'
,
top
:
0
,
left
:
'
-6px
'
,
width
:
{
base
:
'
calc(100% + 12px)
'
,
lg
:
'
calc(100% + 18px)
'
},
height
:
{
base
:
'
calc(100% + 8px)
'
,
lg
:
'
100%
'
},
bgColor
:
nativeCoinFieldBgColor
,
borderTopLeftRadius
:
'
base
'
,
borderTopRightRadius
:
{
base
:
'
base
'
,
lg
:
'
none
'
},
borderBottomRightRadius
:
'
none
'
,
borderBottomLeftRadius
:
{
base
:
'
none
'
,
lg
:
'
base
'
},
zIndex
:
-
1
,
}
:
undefined
}
>
>
{
argName
}
(
{
argType
}
)
{
argName
}
{
isOptional
?
''
:
'
*
'
}
(
{
argType
}
)
</
Box
>
</
Box
>
{
content
}
{
content
}
</>
</>
...
...
ui/address/contract/ContractMethodField.tsx
View file @
078a5626
...
@@ -4,6 +4,7 @@ import {
...
@@ -4,6 +4,7 @@ import {
Input
,
Input
,
InputGroup
,
InputGroup
,
InputRightElement
,
InputRightElement
,
useColorModeValue
,
}
from
'
@chakra-ui/react
'
;
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
Control
,
ControllerRenderProps
,
FieldError
,
UseFormGetValues
,
UseFormSetValue
,
UseFormStateReturn
}
from
'
react-hook-form
'
;
import
type
{
Control
,
ControllerRenderProps
,
FieldError
,
UseFormGetValues
,
UseFormSetValue
,
UseFormStateReturn
}
from
'
react-hook-form
'
;
...
@@ -12,7 +13,7 @@ import { NumericFormat } from 'react-number-format';
...
@@ -12,7 +13,7 @@ import { NumericFormat } from 'react-number-format';
import
{
isAddress
,
isHex
,
getAddress
}
from
'
viem
'
;
import
{
isAddress
,
isHex
,
getAddress
}
from
'
viem
'
;
import
type
{
MethodFormFields
}
from
'
./types
'
;
import
type
{
MethodFormFields
}
from
'
./types
'
;
import
type
{
SmartContractMethodArgType
}
from
'
types/api/contract
'
;
import
type
{
SmartContractMethodArgType
,
SmartContractMethodInput
}
from
'
types/api/contract
'
;
import
ClearButton
from
'
ui/shared/ClearButton
'
;
import
ClearButton
from
'
ui/shared/ClearButton
'
;
...
@@ -21,6 +22,7 @@ import { INT_REGEXP, BYTES_REGEXP, getIntBoundaries, formatBooleanValue } from '
...
@@ -21,6 +22,7 @@ import { INT_REGEXP, BYTES_REGEXP, getIntBoundaries, formatBooleanValue } from '
interface
Props
{
interface
Props
{
name
:
string
;
name
:
string
;
type
?:
SmartContractMethodInput
[
'
fieldType
'
];
index
?:
number
;
index
?:
number
;
groupName
?:
string
;
groupName
?:
string
;
placeholder
:
string
;
placeholder
:
string
;
...
@@ -29,11 +31,14 @@ interface Props {
...
@@ -29,11 +31,14 @@ interface Props {
setValue
:
UseFormSetValue
<
MethodFormFields
>
;
setValue
:
UseFormSetValue
<
MethodFormFields
>
;
getValues
:
UseFormGetValues
<
MethodFormFields
>
;
getValues
:
UseFormGetValues
<
MethodFormFields
>
;
isDisabled
:
boolean
;
isDisabled
:
boolean
;
isOptional
?:
boolean
;
onChange
:
()
=>
void
;
onChange
:
()
=>
void
;
}
}
const
ContractMethodField
=
({
control
,
name
,
groupName
,
index
,
argType
,
placeholder
,
setValue
,
getValues
,
isDisabled
,
onChange
}:
Props
)
=>
{
const
ContractMethodField
=
({
control
,
name
,
type
,
groupName
,
index
,
argType
,
placeholder
,
setValue
,
getValues
,
isDisabled
,
isOptional
,
onChange
}:
Props
)
=>
{
const
ref
=
React
.
useRef
<
HTMLInputElement
>
(
null
);
const
ref
=
React
.
useRef
<
HTMLInputElement
>
(
null
);
const
nativeCoinFieldBgColor
=
useColorModeValue
(
'
blackAlpha.50
'
,
'
whiteAlpha.100
'
);
const
bgColor
=
useColorModeValue
(
'
white
'
,
'
black
'
);
const
handleClear
=
React
.
useCallback
(()
=>
{
const
handleClear
=
React
.
useCallback
(()
=>
{
setValue
(
name
,
''
);
setValue
(
name
,
''
);
...
@@ -76,10 +81,28 @@ const ContractMethodField = ({ control, name, groupName, index, argType, placeho
...
@@ -76,10 +81,28 @@ const ContractMethodField = ({ control, name, groupName, index, argType, placeho
const
hasZerosControl
=
intMatch
&&
Number
(
intMatch
.
power
)
>=
64
;
const
hasZerosControl
=
intMatch
&&
Number
(
intMatch
.
power
)
>=
64
;
return
(
return
(
<
Box
w=
"100%"
>
<
Box
w=
"100%"
pt=
{
{
lg
:
type
===
'
native_coin
'
?
1
:
0
}
}
pb=
{
{
base
:
type
===
'
native_coin
'
?
'
6px
'
:
0
,
lg
:
type
===
'
native_coin
'
?
1
:
0
}
}
position=
"relative"
_before=
{
type
===
'
native_coin
'
?
{
content
:
`" "`
,
position
:
'
absolute
'
,
top
:
0
,
right
:
'
-6px
'
,
width
:
{
base
:
'
calc(100% + 12px)
'
,
lg
:
'
calc(100% + 6px)
'
},
height
:
'
100%
'
,
bgColor
:
nativeCoinFieldBgColor
,
borderTopLeftRadius
:
'
none
'
,
borderTopRightRadius
:
{
lg
:
'
base
'
},
borderBottomRightRadius
:
'
base
'
,
borderBottomLeftRadius
:
{
base
:
'
base
'
,
lg
:
'
none
'
},
zIndex
:
-
1
,
}
:
undefined
}
>
<
FormControl
<
FormControl
id=
{
name
}
id=
{
name
}
mb=
{
{
base
:
1
,
lg
:
0
}
}
isDisabled=
{
isDisabled
}
isDisabled=
{
isDisabled
}
>
>
<
InputGroup
size=
"xs"
>
<
InputGroup
size=
"xs"
>
...
@@ -93,10 +116,11 @@ const ContractMethodField = ({ control, name, groupName, index, argType, placeho
...
@@ -93,10 +116,11 @@ const ContractMethodField = ({ control, name, groupName, index, argType, placeho
}
:
{})
}
}
:
{})
}
ref=
{
ref
}
ref=
{
ref
}
isInvalid=
{
Boolean
(
error
)
}
isInvalid=
{
Boolean
(
error
)
}
required
required
=
{
!
isOptional
}
placeholder=
{
placeholder
}
placeholder=
{
placeholder
}
paddingRight=
{
hasZerosControl
?
'
120px
'
:
'
40px
'
}
paddingRight=
{
hasZerosControl
?
'
120px
'
:
'
40px
'
}
autoComplete=
"off"
autoComplete=
"off"
bgColor=
{
bgColor
}
/>
/>
<
InputRightElement
w=
"auto"
right=
{
1
}
>
<
InputRightElement
w=
"auto"
right=
{
1
}
>
{
typeof
field
.
value
===
'
string
'
&&
field
.
value
.
replace
(
'
\n
'
,
''
)
&&
<
ClearButton
onClick=
{
handleClear
}
isDisabled=
{
isDisabled
}
/>
}
{
typeof
field
.
value
===
'
string
'
&&
field
.
value
.
replace
(
'
\n
'
,
''
)
&&
<
ClearButton
onClick=
{
handleClear
}
isDisabled=
{
isDisabled
}
/>
}
...
@@ -107,7 +131,7 @@ const ContractMethodField = ({ control, name, groupName, index, argType, placeho
...
@@ -107,7 +131,7 @@ const ContractMethodField = ({ control, name, groupName, index, argType, placeho
{
error
&&
<
Box
color=
"error"
fontSize=
"sm"
mt=
{
1
}
>
{
error
.
message
}
</
Box
>
}
{
error
&&
<
Box
color=
"error"
fontSize=
"sm"
mt=
{
1
}
>
{
error
.
message
}
</
Box
>
}
</
Box
>
</
Box
>
);
);
},
[
index
,
groupName
,
name
,
intMatch
,
isDisabled
,
placeholde
r
,
handleClear
,
handleAddZeroesClick
]);
},
[
index
,
groupName
,
name
,
intMatch
,
type
,
nativeCoinFieldBgColor
,
isDisabled
,
isOptional
,
placeholder
,
bgColo
r
,
handleClear
,
handleAddZeroesClick
]);
const
validate
=
React
.
useCallback
((
_value
:
string
|
Array
<
string
>
)
=>
{
const
validate
=
React
.
useCallback
((
_value
:
string
|
Array
<
string
>
)
=>
{
if
(
typeof
_value
===
'
object
'
)
{
if
(
typeof
_value
===
'
object
'
)
{
...
@@ -116,7 +140,7 @@ const ContractMethodField = ({ control, name, groupName, index, argType, placeho
...
@@ -116,7 +140,7 @@ const ContractMethodField = ({ control, name, groupName, index, argType, placeho
const
value
=
_value
.
replace
(
'
\n
'
,
''
);
const
value
=
_value
.
replace
(
'
\n
'
,
''
);
if
(
!
value
)
{
if
(
!
value
&&
!
isOptional
)
{
return
'
Field is required
'
;
return
'
Field is required
'
;
}
}
...
@@ -174,14 +198,14 @@ const ContractMethodField = ({ control, name, groupName, index, argType, placeho
...
@@ -174,14 +198,14 @@ const ContractMethodField = ({ control, name, groupName, index, argType, placeho
}
}
return
true
;
return
true
;
},
[
bytesMatch
,
intMatch
,
argType
]);
},
[
isOptional
,
argType
,
intMatch
,
bytesMatch
]);
return
(
return
(
<
Controller
<
Controller
name=
{
name
}
name=
{
name
}
control=
{
control
}
control=
{
control
}
render=
{
renderInput
}
render=
{
renderInput
}
rules=
{
{
required
:
'
Field is required
'
,
validate
}
}
rules=
{
{
required
:
isOptional
?
false
:
'
Field is required
'
,
validate
}
}
/>
/>
);
);
};
};
...
...
ui/address/contract/ContractMethodsAccordionItem.tsx
View file @
078a5626
...
@@ -86,7 +86,7 @@ const ContractMethodsAccordionItem = <T extends SmartContractMethod>({ data, ind
...
@@ -86,7 +86,7 @@ const ContractMethodsAccordionItem = <T extends SmartContractMethod>({ data, ind
<
AccordionIcon
/>
<
AccordionIcon
/>
</
AccordionButton
>
</
AccordionButton
>
</
Element
>
</
Element
>
<
AccordionPanel
pb=
{
4
}
pr=
{
0
}
pl=
"28px"
>
<
AccordionPanel
pb=
{
4
}
pr=
{
0
}
pl=
"28px"
w=
"calc(100% - 6px)"
>
{
renderContent
(
data
,
index
,
id
)
}
{
renderContent
(
data
,
index
,
id
)
}
</
AccordionPanel
>
</
AccordionPanel
>
</
AccordionItem
>
</
AccordionItem
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment