1- import {
2- Divider ,
3- Flex ,
4- FormControl ,
5- InputGroup ,
6- InputRightElement ,
7- Tooltip ,
8- useBreakpointValue ,
9- } from "@chakra-ui/react" ;
1+ import { Checkbox , CheckboxWithLabel } from "@/components/ui/checkbox" ;
2+ import { InlineCode } from "@/components/ui/inline-code" ;
3+ import { Switch } from "@/components/ui/switch" ;
4+ import { FormControl , useBreakpointValue } from "@chakra-ui/react" ;
105import type { AbiParameter } from "abitype" ;
116import { SolidityInput } from "contract-ui/components/solidity-inputs" ;
127import { getTemplateValuesForType } from "lib/deployment/template-values" ;
138import { useState } from "react" ;
149import { useFormContext } from "react-hook-form" ;
15- import {
16- Button ,
17- Card ,
18- Checkbox ,
19- FormErrorMessage ,
20- FormLabel ,
21- Heading ,
22- Text ,
23- } from "tw-components" ;
2410import { RefInputImplFieldset } from "./ref-contract-impl-input/ref-input-impl-fieldset" ;
2511
2612interface ImplementationParamsFieldsetProps {
@@ -37,177 +23,154 @@ export const ImplementationParamsFieldset: React.FC<
3723 Array ( implParams . length ) . fill ( false ) ,
3824 ) ;
3925
40- const handleToggleCustomInput = ( index : number ) => {
41- setIsCustomInputEnabled ( ( prev ) => {
42- const updated = [ ... prev ] ;
43- updated [ index ] = ! updated [ index ] ;
26+ const handleToggleCustomInput = ( index : number , newValue : boolean ) => {
27+ const newIsCustomInputEnabled = [ ... isCustomInputEnabled ] ;
28+ newIsCustomInputEnabled [ index ] = newValue ;
29+ setIsCustomInputEnabled ( newIsCustomInputEnabled ) ;
4430
45- // Clear or set values accordingly when toggling between input types
46- if ( updated [ index ] ) {
47- form . setValue (
48- `implConstructorParams.${ implParams [ index ] ?. name || "*" } .dynamicValue.type` ,
49- implParams [ index ] ?. type ,
50- ) ;
51- form . setValue (
52- `implConstructorParams.${ implParams [ index ] ?. name || "*" } .defaultValue` ,
53- "" ,
54- {
55- shouldDirty : true ,
56- } ,
57- ) ;
58- } else {
59- form . setValue (
60- `implConstructorParams.${ implParams [ index ] ?. name || "*" } .dynamicValue.type` ,
61- "" ,
62- ) ;
63- form . setValue (
64- `implConstructorParams.${ implParams [ index ] ?. name || "*" } .dynamicValue` ,
65- "" ,
66- {
67- shouldDirty : true ,
68- } ,
69- ) ;
70- }
71- return updated ;
72- } ) ;
31+ // Clear or set values accordingly when toggling between input types
32+ if ( newValue ) {
33+ form . setValue (
34+ `implConstructorParams.${ implParams [ index ] ?. name || "*" } .dynamicValue.type` ,
35+ implParams [ index ] ?. type ,
36+ ) ;
37+ form . setValue (
38+ `implConstructorParams.${ implParams [ index ] ?. name || "*" } .defaultValue` ,
39+ "" ,
40+ {
41+ shouldDirty : true ,
42+ } ,
43+ ) ;
44+ } else {
45+ form . setValue (
46+ `implConstructorParams.${ implParams [ index ] ?. name || "*" } .dynamicValue.type` ,
47+ "" ,
48+ ) ;
49+ form . setValue (
50+ `implConstructorParams.${ implParams [ index ] ?. name || "*" } .dynamicValue` ,
51+ "" ,
52+ {
53+ shouldDirty : true ,
54+ } ,
55+ ) ;
56+ }
7357 } ;
7458
7559 return (
76- < Flex gap = { 16 } direction = "column" as = "fieldset" >
77- < Flex gap = { 2 } direction = "column" >
78- < Heading size = "title.lg" >
79- Implementation Contract Constructor Parameters
80- </ Heading >
81- < Text fontStyle = "normal" >
82- These are the parameters users will need to fill in when deploying
83- this contract.
84- </ Text >
85- </ Flex >
86- < Flex flexDir = "column" gap = { 10 } >
60+ < fieldset >
61+ < h2 className = "font-semibold text-3xl tracking-tight" >
62+ Implementation Contract Constructor Parameters
63+ </ h2 >
64+ < p className = "text-muted-foreground" >
65+ These are the parameters users will need to fill in when deploying this
66+ contract.
67+ </ p >
68+
69+ < div className = "h-6" />
70+
71+ < div className = "flex flex-col gap-8" >
8772 { implParams . map ( ( param , idx ) => {
8873 const paramTemplateValues = getTemplateValuesForType ( param . type ) ;
8974 return (
90- < Flex flexDir = "column" gap = { 6 } key = { `implementation_${ param . name } ` } >
91- < Flex justify = "space-between" align = "center" >
92- { param . name ? (
93- < Heading size = "title.sm" > { param . name } </ Heading >
94- ) : (
95- < Heading size = "title.sm" fontStyle = "italic" >
96- Unnamed param (will not be used)
97- </ Heading >
98- ) }
99- < Text size = "body.sm" > { param . type } </ Text >
100- </ Flex >
101- < Flex gap = { 6 } flexDir = "column" >
102- < Flex gap = { 4 } flexDir = { { base : "column" , md : "row" } } >
103- < FormControl
104- isInvalid = {
105- ! ! form . getFieldState (
75+ < div
76+ key = { `implementation_${ param . name } ` }
77+ className = "rounded-lg border border-border bg-muted/50 p-6"
78+ >
79+ { /* Title + Type */ }
80+ < div className = "flex items-center gap-3" >
81+ < h3 className = "font-semibold text-xl tracking-tight" >
82+ { param . name ? (
83+ param . name
84+ ) : (
85+ < span className = "italic" >
86+ Unnamed param (will not be used)
87+ </ span >
88+ ) }
89+ </ h3 >
90+ < InlineCode
91+ className = "px-2 text-base text-muted-foreground"
92+ code = { param . type }
93+ />
94+ </ div >
95+ < div className = "h-5" />
96+ < div className = "flex flex-col gap-5" >
97+ { /* Title + Description + Switch */ }
98+ < div className = "flex flex-col justify-between gap-6 md:flex-row md:items-start" >
99+ < div >
100+ < h4 className = "font-medium text-base" > Default Value </ h4 >
101+ < p className = "text-muted-foreground text-sm" >
102+ Value prefilled in deployment form
103+ </ p >
104+ </ div >
105+ { ( param . type === "address" ||
106+ param . type === "address[]" ||
107+ param . type === "bytes" ||
108+ param . type === "bytes[]" ) && (
109+ < div className = "flex items-center gap-3 text-sm" >
110+ Dynamic Input
111+ < Switch
112+ checked = { isCustomInputEnabled [ idx ] }
113+ onCheckedChange = { ( v ) => handleToggleCustomInput ( idx , v ) }
114+ />
115+ </ div >
116+ ) }
117+ </ div >
118+
119+ { ! isCustomInputEnabled [ idx ] ? (
120+ < FormControl >
121+ < SolidityInput
122+ className = "!bg-background !text-sm placeholder:!text-sm"
123+ solidityType = { param . type }
124+ placeholder = {
125+ isMobile ||
126+ paramTemplateValues ?. [ 0 ] ?. value ===
127+ "{{trusted_forwarders}}"
128+ ? "Pre-filled value."
129+ : "This value will be pre-filled in the deploy form."
130+ }
131+ { ...form . register (
106132 `implConstructorParams.${
107133 param . name ? param . name : "*"
108134 } .defaultValue`,
109- form . formState ,
110- ) . error
111- }
112- >
113- < FormLabel as = { Text } > Default Value</ FormLabel >
114- < InputGroup size = "md" >
115- < Flex flexDir = "column" w = "full" >
116- { ! isCustomInputEnabled [ idx ] ? (
117- < >
118- < SolidityInput
119- solidityType = { param . type }
120- placeholder = {
121- isMobile ||
122- paramTemplateValues ?. [ 0 ] ?. value ===
123- "{{trusted_forwarders}}"
124- ? "Pre-filled value."
125- : "This value will be pre-filled in the deploy form."
126- }
127- { ...form . register (
128- `implConstructorParams.${
129- param . name ? param . name : "*"
130- } .defaultValue`,
131- ) }
132- />
133- </ >
134- ) : (
135- < RefInputImplFieldset param = { param } />
136- ) }
137-
138- { ( param . type === "address" ||
139- param . type === "address[]" ||
140- param . type === "bytes" ||
141- param . type === "bytes[]" ) && (
142- < Checkbox
143- isChecked = { isCustomInputEnabled [ idx ] }
144- onChange = { ( ) => handleToggleCustomInput ( idx ) }
145- >
146- Use Custom Input
147- </ Checkbox >
148- ) }
149- </ Flex >
150- { paramTemplateValues . length > 0 &&
151- ! isCustomInputEnabled [ idx ] && (
152- < InputRightElement width = "10.5rem" >
153- < Tooltip
154- bg = "transparent"
155- boxShadow = "none"
156- shouldWrapChildren
157- label = {
158- < Card
159- as = { Flex }
160- flexDir = "column"
161- gap = { 2 }
162- bgColor = "backgroundHighlight"
163- >
164- < Text >
165- { paramTemplateValues [ 0 ] ?. helperText } Click
166- to apply.
167- </ Text >
168- </ Card >
169- }
170- >
171- < Button
172- size = "xs"
173- padding = "3"
174- paddingY = "3.5"
175- onClick = { ( ) => {
176- form . setValue (
177- `implConstructorParams.${
178- param . name ? param . name : "*"
179- } .defaultValue`,
180- paramTemplateValues [ 0 ] ?. value ,
181- {
182- shouldDirty : true ,
183- } ,
184- ) ;
185- } }
186- >
187- { paramTemplateValues [ 0 ] ?. value }
188- </ Button >
189- </ Tooltip >
190- </ InputRightElement >
191- ) }
192- </ InputGroup >
193- < FormErrorMessage >
194- {
195- form . getFieldState (
196- `implConstructorParams.${
197- param . name ? param . name : "*"
198- } .defaultValue`,
199- form . formState ,
200- ) . error ?. message
201- }
202- </ FormErrorMessage >
135+ ) }
136+ />
203137 </ FormControl >
204- </ Flex >
205- </ Flex >
206- { idx !== implParams . length - 1 ? < Divider mt = { 8 } /> : null }
207- </ Flex >
138+ ) : (
139+ < RefInputImplFieldset param = { param } />
140+ ) }
141+
142+ { paramTemplateValues . length > 0 &&
143+ ! isCustomInputEnabled [ idx ] &&
144+ paramTemplateValues [ 0 ] ?. helperText && (
145+ < CheckboxWithLabel className = "text-foreground" >
146+ < Checkbox
147+ checked = {
148+ form . watch (
149+ `implConstructorParams.${
150+ param . name ? param . name : "*"
151+ } .defaultValue`,
152+ ) === paramTemplateValues [ 0 ] ?. value
153+ }
154+ onCheckedChange = { ( v ) => {
155+ form . setValue (
156+ `implConstructorParams.${
157+ param . name ? param . name : "*"
158+ } .defaultValue`,
159+ v ? paramTemplateValues [ 0 ] ?. value : "" ,
160+ {
161+ shouldDirty : true ,
162+ } ,
163+ ) ;
164+ } }
165+ />
166+ { paramTemplateValues [ 0 ] ?. helperText }
167+ </ CheckboxWithLabel >
168+ ) }
169+ </ div >
170+ </ div >
208171 ) ;
209172 } ) }
210- </ Flex >
211- </ Flex >
173+ </ div >
174+ </ fieldset >
212175 ) ;
213176} ;
0 commit comments