Skip to content

Commit 16b8554

Browse files
committed
feat: add mobile sticky action bar for create dao forms
1 parent d4a6e21 commit 16b8554

4 files changed

Lines changed: 186 additions & 70 deletions

File tree

apps/web/src/pages/create.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const CreatePage: NextPageWithLayout = () => {
3232
const { isGnosisSafe } = useIsGnosisSafe(address, chain.id)
3333

3434
const { push } = useRouter()
35+
3536
const handleSuccessfulDeploy = React.useCallback(
3637
async (token: string) => {
3738
await push({
@@ -86,7 +87,7 @@ const CreatePage: NextPageWithLayout = () => {
8687

8788
const reviewAndDeploy: CreateFormSection = {
8889
title: 'Deploy',
89-
subHeading: '[Confirm your contract settings before deploying your DAO]',
90+
subHeading: 'Confirm your contract settings before deploying your DAO',
9091
form: (
9192
<ReviewAndDeploy
9293
key={'review-and-deploy'}

packages/create-dao-ui/src/components/FormNavButtons/FormNavButtons.css.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { vars } from '@buildeross/zord'
12
import { style } from '@vanilla-extract/css'
23

34
export const formNavResetButton = style({
@@ -9,3 +10,38 @@ export const formNavContinueButton = style({
910
height: 60,
1011
marginLeft: 8,
1112
})
13+
14+
export const formNavMobileBar = style({
15+
position: 'fixed',
16+
left: 0,
17+
right: 0,
18+
bottom: 0,
19+
zIndex: 25,
20+
padding: 16,
21+
paddingBottom: 'calc(16px + env(safe-area-inset-bottom))',
22+
background: vars.color.background1,
23+
borderTop: `1px solid ${vars.color.border}`,
24+
'@media': {
25+
'(min-width: 768px)': {
26+
display: 'none',
27+
},
28+
},
29+
})
30+
31+
export const formNavMobileBarSpacer = style({
32+
height: 'calc(92px + env(safe-area-inset-bottom))',
33+
'@media': {
34+
'(min-width: 768px)': {
35+
display: 'none',
36+
},
37+
},
38+
})
39+
40+
export const formNavDesktopRow = style({
41+
display: 'none',
42+
'@media': {
43+
'(min-width: 768px)': {
44+
display: 'block',
45+
},
46+
},
47+
})
Lines changed: 134 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
import { AnimatedModal } from '@buildeross/ui/Modal'
22
import { Button, Flex, Icon } from '@buildeross/zord'
33
import React, { useState } from 'react'
4+
import { createPortal } from 'react-dom'
45

56
import { useFormStore } from '../../stores'
67
import { ConfirmReset } from '../ConfirmReset/ConfirmReset'
7-
import { formNavContinueButton, formNavResetButton } from './FormNavButtons.css'
8+
import {
9+
formNavContinueButton,
10+
formNavDesktopRow,
11+
formNavMobileBar,
12+
formNavMobileBarSpacer,
13+
formNavResetButton,
14+
} from './FormNavButtons.css'
815

916
interface FormNavButtonsProps {
1017
hasPrev?: boolean
@@ -30,14 +37,28 @@ export const FormNavButtons: React.FC<FormNavButtonsProps> = ({
3037
onAfterReset,
3138
}) => {
3239
const [isModalOpen, setIsModalOpen] = useState(false)
40+
const [isMounted, setIsMounted] = useState(false)
3341
const { resetForm } = useFormStore()
3442

43+
React.useEffect(() => {
44+
setIsMounted(true)
45+
}, [])
46+
3547
const handleReset = () => {
3648
resetForm()
3749
setIsModalOpen(false)
3850
onAfterReset?.()
3951
}
4052

53+
const handleMobileContinue = () => {
54+
if (!isSubmit) {
55+
onNext?.()
56+
return
57+
}
58+
59+
document.querySelector('form')?.requestSubmit()
60+
}
61+
4162
return (
4263
<>
4364
{showReset && (
@@ -53,61 +74,121 @@ export const FormNavButtons: React.FC<FormNavButtonsProps> = ({
5374
</AnimatedModal>
5475
)}
5576

56-
<Flex align={'center'} mt={'x8'}>
57-
{showReset && (
58-
<Button
59-
justify={'center'}
60-
align={'center'}
61-
h={'x15'}
62-
minH={'x15'}
63-
minW={'x15'}
64-
variant={'secondary'}
65-
type="button"
66-
onClick={() => setIsModalOpen(true)}
67-
aria-label="Reset form"
68-
className={formNavResetButton}
69-
>
70-
<Icon id="trash" />
71-
</Button>
72-
)}
77+
<div className={formNavDesktopRow}>
78+
<Flex align={'center'} mt={'x8'}>
79+
{showReset && (
80+
<Button
81+
justify={'center'}
82+
align={'center'}
83+
h={'x15'}
84+
minH={'x15'}
85+
minW={'x15'}
86+
variant={'secondary'}
87+
type="button"
88+
onClick={() => setIsModalOpen(true)}
89+
aria-label="Reset form"
90+
className={formNavResetButton}
91+
>
92+
<Icon id="trash" />
93+
</Button>
94+
)}
7395

74-
{hasPrev && (
75-
<Button
76-
justify={'center'}
77-
align={'center'}
78-
h={'x15'}
79-
minH={'x15'}
80-
minW={'x15'}
81-
variant={'secondary'}
82-
type="button"
83-
onClick={onPrev}
84-
aria-label="Back"
85-
>
86-
<Icon id="arrow-left" />
87-
</Button>
88-
)}
96+
{hasPrev && (
97+
<Button
98+
justify={'center'}
99+
align={'center'}
100+
h={'x15'}
101+
minH={'x15'}
102+
minW={'x15'}
103+
variant={'secondary'}
104+
type="button"
105+
onClick={onPrev}
106+
aria-label="Back"
107+
>
108+
<Icon id="arrow-left" />
109+
</Button>
110+
)}
111+
112+
{children ? (
113+
children
114+
) : (
115+
<Button
116+
flex={1}
117+
h={'x15'}
118+
minH={'x15'}
119+
className={formNavContinueButton}
120+
type={isSubmit ? 'submit' : 'button'}
121+
disabled={nextDisabled}
122+
onClick={isSubmit ? undefined : onNext}
123+
onMouseDown={
124+
isSubmit
125+
? (e: React.MouseEvent<HTMLElement>) => e.preventDefault()
126+
: undefined
127+
}
128+
>
129+
{nextLabel}
130+
</Button>
131+
)}
132+
</Flex>
133+
</div>
134+
135+
<div className={formNavMobileBarSpacer} />
136+
{isMounted &&
137+
createPortal(
138+
<div className={formNavMobileBar}>
139+
<Flex align={'center'}>
140+
{showReset && (
141+
<Button
142+
justify={'center'}
143+
align={'center'}
144+
h={'x15'}
145+
minH={'x15'}
146+
minW={'x15'}
147+
variant={'secondary'}
148+
type="button"
149+
onClick={() => setIsModalOpen(true)}
150+
aria-label="Reset form"
151+
className={formNavResetButton}
152+
>
153+
<Icon id="trash" />
154+
</Button>
155+
)}
156+
157+
{hasPrev && (
158+
<Button
159+
justify={'center'}
160+
align={'center'}
161+
h={'x15'}
162+
minH={'x15'}
163+
minW={'x15'}
164+
variant={'secondary'}
165+
type="button"
166+
onClick={onPrev}
167+
aria-label="Back"
168+
>
169+
<Icon id="arrow-left" />
170+
</Button>
171+
)}
89172

90-
{children ? (
91-
children
92-
) : (
93-
<Button
94-
flex={1}
95-
h={'x15'}
96-
minH={'x15'}
97-
className={formNavContinueButton}
98-
type={isSubmit ? 'submit' : 'button'}
99-
disabled={nextDisabled}
100-
onClick={isSubmit ? undefined : onNext}
101-
onMouseDown={
102-
isSubmit
103-
? (e: React.MouseEvent<HTMLElement>) => e.preventDefault()
104-
: undefined
105-
}
106-
>
107-
{nextLabel}
108-
</Button>
173+
{children ? (
174+
children
175+
) : (
176+
<Button
177+
flex={1}
178+
h={'x15'}
179+
minH={'x15'}
180+
className={formNavContinueButton}
181+
type="button"
182+
disabled={nextDisabled}
183+
onClick={handleMobileContinue}
184+
>
185+
{nextLabel}
186+
</Button>
187+
)}
188+
</Flex>
189+
</div>,
190+
document.body
109191
)}
110-
</Flex>
111192
</>
112193
)
113194
}

packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.tsx

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ export const ReviewAndDeploy: React.FC<ReviewAndDeploy> = ({
490490
</Flex>
491491

492492
<Flex className={deployCheckboxHelperText}>
493-
[I have reviewed and acknowledge and agree to the{' '}
493+
I have reviewed and acknowledge and agree to the{' '}
494494
<a
495495
href={'/legal'}
496496
target="_blank"
@@ -499,7 +499,6 @@ export const ReviewAndDeploy: React.FC<ReviewAndDeploy> = ({
499499
>
500500
Nouns Builder Terms of Service
501501
</a>
502-
]
503502
</Flex>
504503
</Flex>
505504
</Flex>
@@ -606,21 +605,20 @@ export const ReviewAndDeploy: React.FC<ReviewAndDeploy> = ({
606605
{deploymentError}
607606
</Flex>
608607
)}
609-
610-
<FormNavButtons hasPrev onPrev={handlePrev}>
611-
<ContractButton
612-
chainId={chain.id}
613-
handleClick={handleDeploy}
614-
flex={1}
615-
disabled={isDisabled}
616-
className={
617-
deployContractButtonStyle[isPendingTransaction ? 'pending' : 'default']
618-
}
619-
>
620-
{`${isPendingTransaction ? 'Deploying' : 'Deploy'} Contracts (1 of 2)`}
621-
</ContractButton>
622-
</FormNavButtons>
623608
</Flex>
609+
<FormNavButtons hasPrev onPrev={handlePrev}>
610+
<ContractButton
611+
chainId={chain.id}
612+
handleClick={handleDeploy}
613+
flex={1}
614+
disabled={isDisabled}
615+
className={
616+
deployContractButtonStyle[isPendingTransaction ? 'pending' : 'default']
617+
}
618+
>
619+
{`${isPendingTransaction ? 'Deploying' : 'Deploy'} Contracts (1 of 2)`}
620+
</ContractButton>
621+
</FormNavButtons>
624622
</Box>
625623
) : (
626624
<SuccessfulDeploy title={title} onSuccessfulDeploy={handleSuccessfulDeploy} />

0 commit comments

Comments
 (0)