Built Twitter Like App - 6

Add ModalBox

Modify file pages/_app.tsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import '../styles/globals.css'
import type { AppProps } from 'next/app'

import Layout from '../components/Layout'
import ModalBox from '../components/ModalBox'

export default function App({ Component, pageProps }: AppProps) {
return (
<>
<ModalBox actionLabel='Submit' isOpen title='Test Modal' />
<Layout>
<Component {...pageProps} />
</Layout>
</>
)
}

Add Button Component

Add file conmponent/Button.tsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import React from 'react';

interface ButtonProps {
label: string;
secondary?: boolean;
fullwidth?: boolean;
large?: boolean;
onClick: () => void;
disabled?: boolean;
outline?: boolean;
}

const Button: React.FC<ButtonProps> = ({
label,
secondary,
fullwidth,
large,
onClick,
disabled,
outline
}) => {
return (
<button
disabled={disabled}
onClick={onClick}
className={`
disabled:opacity-70
disabled:cursor-not-allowed
rounded-full
font-semibold
hover:opacity-80
transition
border-2
${fullwidth? `w-full`:`w-fit`}
${secondary? `bg-white`:`bg-sky-500` }
${secondary? `text-black`: `text-white` }
${secondary? `border-black`: `border-sky-500`}
${large? `text-xl`: `text-md`}
${large? `px-5`: `px-4`}
${large? `py-3`: `py-2`}
${outline? `bg-transparent`:``}
${outline? `border-white`:``}
${outline? `text-white`:``}
`}
>
{label}
</button>
);
}

export default Button;

Add file conmponent/ModalBox.tsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import React, { useCallback } from "react";
import { AiOutlineClose } from 'react-icons/ai'
import Button from './Button'

interface ModalBoxProps {
isOpen?: boolean;
onClose: ()=> void;
onSubmit: ()=> void;
title?: string;
body?: React.ReactElement;
footer?: React.ReactElement;
actionLabel: string;
disabled?: boolean;
}

const ModalBox: React.FC<ModalBoxProps> =({
isOpen,
onClose,
onSubmit,
title,
body,
footer,
actionLabel,
disabled
}) =>{
const handleClose = useCallback(() => {
if (disabled){
return;
}

onClose();
},[disabled, onClose]);

const handleSubmit = useCallback(() => {
if (disabled){
return;
}

onSubmit();
},[disabled, onSubmit]);

if(!isOpen) {
return null;
}

return (
<>
<div
className="
justify-center
items-center
flex
overflow-x-hidden
overflow-y-auto
fixed
inset-0
z-50
outline-none
focus:outline-none
bg-neutral-800
bg-opactiy-70
"
>
<div
className="
relative
w-full
lg:w-3/6
my-6
mx-auto
lg:max-w-3xl
h-full
lg:h-auto
"
>

{/* Content */}
<div
className="
h-full
lg:h-auto
border-0
rounded-lg
shadow-lg
relative
flex
flex-col
w-full
bg-black
outline-none
focus:outline-none
">
{/* Header */}
<div
className="
flex
item-center
justify-between
p-10
rounded-t
">
<h3 className="text-3xl font-semibold text-white">{title}</h3>
<button
onClick={handleClose}
className="
p-1
ml-auto
border-0
text-white
hover:opacity-70
transition
">
<AiOutlineClose size={20}/>
</button>
</div>
{/* Body */}
<div className="relative p-10 flex-auto">
{body}
</div>
{/* Footer */}
<div className="flex flex-col gap-2 p-10">
<Button
disabled={disabled}
label={actionLabel}
secondary
fullwidth
large
onClick={handleSubmit}
/>
</div>
{footer}
</div>
</div>
</div>
</>
);
}

export default ModalBox

请我喝杯咖啡吧~

支付宝
微信