├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── public
├── favicon.ico
└── index.html
└── src
├── App.css
├── App.js
├── FBPost.css
├── FBPost.js
├── imgs
├── angred.PNG
├── comment-btn.PNG
├── default-avatar.jpg
├── hahaed.PNG
├── like-btn.PNG
├── liked.PNG
├── loved.PNG
├── privacy-friends.PNG
├── privacy-public.PNG
├── saded.PNG
├── share-btn.PNG
└── wowed.PNG
├── index.css
├── index.js
└── react-fb-image-grid
├── components
├── Images.js
└── Modal.js
├── css
└── style.css
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # backup
13 | /src/Backup
14 |
15 | # misc
16 | .DS_Store
17 | .env.local
18 | .env.development.local
19 | .env.test.local
20 | .env.production.local
21 |
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 |
26 | .eslintrc.js
27 | .prettierrc.js
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Dummy Facebook Post Creator
2 |
3 | Live: https://muhammadovi.github.io/react-fb-post-creator
4 |
5 | \*Use on PC/Laptop for good experience.
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-fb-post-creator",
3 | "version": "0.1.0",
4 | "private": true,
5 | "homepage": "https://oyeovi.github.io/react-fb-post-creator",
6 | "dependencies": {
7 | "antd": "^3.9.2",
8 | "react": "^16.5.1",
9 | "react-bootstrap": "^0.32.4",
10 | "react-dom": "^16.5.1",
11 | "react-facebook-emoji": "^1.0.11",
12 | "react-fb-image-grid": "^0.1.3",
13 | "react-image-lightbox": "^5.0.0",
14 | "react-scripts": "1.1.5"
15 | },
16 | "devDependencies": {
17 | "babel-eslint": "^8.2.6",
18 | "eslint": "4.19.1",
19 | "eslint-config-airbnb": "^17.0.0",
20 | "eslint-config-prettier": "^2.9.0",
21 | "eslint-plugin-import": "^2.13.0",
22 | "eslint-plugin-prettier": "^2.6.2",
23 | "eslint-plugin-react": "^7.10.0",
24 | "html-webpack-plugin": "^3.2.0",
25 | "prettier": "^1.14.2"
26 | },
27 | "scripts": {
28 | "start": "react-scripts start",
29 | "build": "react-scripts build",
30 | "predeploy": "npm run build",
31 | "deploy": "gh-pages -d build",
32 | "test": "react-scripts test --env=jsdom",
33 | "eject": "react-scripts eject"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuhammadOvi/react-fb-post-creator/58a1aa03d61ea207dce9403739a62a0fab875313/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Facebook Post Creator
10 |
17 |
18 |
19 |
20 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | html::-webkit-scrollbar,
2 | body::-webkit-scrollbar {
3 | display: none; /* might be enought */
4 | background: transparent;
5 | visibility: hidden;
6 | width: 0px;
7 | }
8 |
9 | body {
10 | background: #e9ebee !important;
11 | }
12 |
13 | .App {
14 | /* text-align: center; */
15 | padding: 20px;
16 | background: #e9ebee;
17 | width: 100%;
18 | min-height: 100%;
19 | text-align: left;
20 | }
21 |
22 | .editor {
23 | position: relative;
24 | margin: auto;
25 | width: calc(50% - 20px);
26 | /* min-height: 400px; */
27 | background: white;
28 | float: left;
29 | padding: 20px;
30 | margin-bottom: 20px;
31 | margin-right: 20px;
32 | }
33 |
34 | .editor-hide-button {
35 | display: none !important;
36 | width: 200px;
37 | position: absolute;
38 | left: calc(50% - 100px);
39 | margin-bottom: 20px;
40 | }
41 |
42 | .editor_avtar {
43 | width: 120px;
44 | float: left;
45 | margin-top: 5px;
46 | }
47 |
48 | .editor_name,
49 | .editor_caption,
50 | .editor_time_privacy {
51 | width: calc(100% - 120px);
52 | margin-bottom: 8px;
53 | float: left;
54 | }
55 |
56 | .select-time {
57 | width: calc(65% - 10px) !important;
58 | margin-right: 10px !important;
59 | }
60 |
61 | .editor-privacy {
62 | width: 35% !important;
63 | }
64 |
65 | .result {
66 | width: 50%;
67 | float: left;
68 | }
69 |
70 | @media screen and (max-width: 899px) {
71 | .App {
72 | padding: 20px 5px;
73 | }
74 | .editor {
75 | width: 100%;
76 | float: none;
77 | }
78 | .result {
79 | width: 100%;
80 | float: none;
81 | }
82 | .editor-hide-button {
83 | display: block !important;
84 | }
85 | .select-time {
86 | width: 100% !important;
87 | margin-right: 0 !important;
88 | }
89 |
90 | .editor-privacy {
91 | width: 100% !important;
92 | margin: 10px 0 0 0 !important;
93 | }
94 | .editor_caption {
95 | width: 100%;
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import FBPost from './FBPost';
3 |
4 | import {
5 | Upload,
6 | Icon,
7 | Divider,
8 | Input,
9 | Select,
10 | TimePicker,
11 | Button,
12 | InputNumber,
13 | Checkbox,
14 | } from 'antd';
15 |
16 | import './App.css';
17 |
18 | const { Option } = Select;
19 |
20 | class App extends Component {
21 | constructor(props) {
22 | super(props);
23 |
24 | this.state = {
25 | avtars: [],
26 | images: [],
27 | includeLike: false,
28 | includeLove: false,
29 | includeHaha: false,
30 | includeWow: false,
31 | includeSad: false,
32 | includeAngry: false,
33 | editorShown: true,
34 | };
35 | }
36 |
37 | toggleEditor = () => {
38 | let { editorShown } = this.state;
39 | this.setState({ editorShown: !editorShown });
40 | };
41 |
42 | uploadAvtar = ({ fileList }) => this.setState({ avtars: fileList });
43 |
44 | setTime = (time, timeString) => {
45 | this.setState({ time: timeString });
46 | };
47 |
48 | setPrivacy = value => {
49 | this.setState({ privacy: value });
50 | };
51 |
52 | uploadImages = ({ fileList }) => {
53 | const images = fileList.map(file => {
54 | return file.thumbUrl;
55 | });
56 | this.setState({ images });
57 | };
58 |
59 | includeLike = () => {
60 | let { includeLike } = this.state;
61 | this.setState({ includeLike: !includeLike });
62 | };
63 |
64 | includeLove = () => {
65 | let { includeLove } = this.state;
66 | this.setState({ includeLove: !includeLove });
67 | };
68 |
69 | includeHaha = () => {
70 | let { includeHaha } = this.state;
71 | this.setState({ includeHaha: !includeHaha });
72 | };
73 |
74 | includeWow = () => {
75 | let { includeWow } = this.state;
76 | this.setState({ includeWow: !includeWow });
77 | };
78 |
79 | includeSad = () => {
80 | let { includeSad } = this.state;
81 | this.setState({ includeSad: !includeSad });
82 | };
83 |
84 | includeAngry = () => {
85 | let { includeAngry } = this.state;
86 | this.setState({ includeAngry: !includeAngry });
87 | };
88 |
89 | render() {
90 | const {
91 | avtars,
92 | name,
93 | caption,
94 | time,
95 | privacy,
96 | likes,
97 | images,
98 | editorShown,
99 | } = this.state;
100 | let {
101 | includeLike,
102 | includeLove,
103 | includeHaha,
104 | includeWow,
105 | includeSad,
106 | includeAngry,
107 | } = this.state;
108 |
109 | const uploadButton = (
110 |
111 |
112 |
Upload Avtar
113 |
114 | );
115 |
116 | return (
117 |
118 |
121 |
122 | {editorShown && (
123 |
124 |
125 | {}}
129 | accept="image/*"
130 | onChange={this.uploadAvtar}
131 | >
132 | {avtars.length >= 1 ? null : uploadButton}
133 |
134 |
135 |
136 |
137 |
141 | }
142 | onChange={e => this.setState({ name: e.target.value })}
143 | />
144 |
145 |
146 |
147 |
154 |
155 |
166 |
167 |
168 |
169 | this.setState({ caption: e.target.value })}
173 | />
174 |
175 |
176 |
177 |
178 |
179 | Upload Pictures: Upload Multiples by clicking CTRL
180 | ;)
181 |
182 |
{}}
187 | accept="image/*"
188 | onChange={this.uploadImages}
189 | >
190 |
193 |
194 |
195 |
196 |
197 |
this.setState({ likes: value })}
201 | />
202 |
203 |
204 |
205 | Includes:
206 |
207 |
211 | Likes
212 |
213 |
217 | Love
218 |
219 |
223 | Haha
224 |
225 |
229 | WoW
230 |
231 |
235 | Sad
236 |
237 |
241 | Angry
242 |
243 |
244 | )}
245 |
246 |
247 |
262 |
263 |
264 |
265 | );
266 | }
267 | }
268 |
269 | export default App;
270 |
--------------------------------------------------------------------------------
/src/FBPost.css:
--------------------------------------------------------------------------------
1 | .post {
2 | position: relative;
3 | margin: auto;
4 | /* min-height: 400px; */
5 | background: white;
6 | width: 100%;
7 | float: left;
8 | padding-top: 55px;
9 | }
10 |
11 | .avatar {
12 | position: absolute;
13 | display: inline-block;
14 | top: 10px;
15 | width: 45px;
16 | height: 45px;
17 | margin-left: 10px;
18 | border-radius: 50%;
19 | background: #e8e8e8;
20 | }
21 |
22 | .avatar img,
23 | .privacy img {
24 | height: 100%;
25 | width: 100%;
26 | border-radius: inherit;
27 | cursor: pointer;
28 | }
29 |
30 | .name {
31 | position: absolute;
32 | top: 15px;
33 | left: 65px;
34 | font-weight: bold;
35 | color: #365899;
36 | cursor: pointer;
37 | font-size: 0.95em;
38 | }
39 |
40 | .time {
41 | position: absolute;
42 | top: 35px;
43 | left: 65px;
44 | color: #737880;
45 | cursor: pointer;
46 | font-size: 0.75em;
47 | }
48 |
49 | .time:hover {
50 | text-decoration: underline;
51 | }
52 |
53 | .privacy {
54 | position: absolute;
55 | top: -1px;
56 | height: 16px;
57 | width: 16px;
58 | right: -20px;
59 | color: #737880;
60 | font-size: 1em;
61 | }
62 |
63 | .dots {
64 | position: absolute;
65 | right: 10px;
66 | top: 10px;
67 | padding: 5px;
68 | cursor: pointer;
69 | }
70 |
71 | .dots span {
72 | display: block;
73 | float: right;
74 | margin: 2px;
75 | height: 4px;
76 | width: 4px;
77 | border-radius: 50%;
78 | background: #737880;
79 | }
80 |
81 | .dots:hover span {
82 | background: black;
83 | }
84 |
85 | .caption {
86 | position: relative;
87 | padding: 10px 10px 5px;
88 | font-size: 0.9em;
89 | }
90 |
91 | .images {
92 | height: 400px;
93 | }
94 |
95 | .likesCount {
96 | color: #737880;
97 | font-size: 0.9em;
98 | margin: 10px 10px 0;
99 | padding-bottom: 5px;
100 | border-bottom: 1px solid #e8e8e8;
101 | }
102 |
103 | .btns {
104 | display: flex;
105 | justify-content: space-evenly;
106 | align-items: center;
107 | height: 40px;
108 | text-align: center;
109 | padding: 0 5px;
110 | /* border: 1px solid lightgray; */
111 | border-bottom: 1px solid #e8e8e8;
112 | }
113 |
114 | .likeBtn,
115 | .commentBtn,
116 | .shareBtn {
117 | width: 100%;
118 | height: 80%;
119 | border-radius: 5px;
120 | cursor: pointer;
121 | display: flex;
122 | justify-content: center;
123 | align-items: center;
124 | background: #fff;
125 | margin: 3px;
126 | }
127 |
128 | .likeBtn:hover,
129 | .commentBtn:hover,
130 | .shareBtn:hover {
131 | background: #f1f1f1;
132 | }
133 |
134 | .likeBtn {
135 | position: relative;
136 | }
137 |
138 | .likes img {
139 | height: 20px;
140 | }
141 |
142 | .emojies {
143 | position: absolute;
144 | bottom: 30px;
145 | width: 290px;
146 | left: -5px;
147 | background: #fff;
148 | padding: 5px 5px 0;
149 | border-radius: 20px;
150 | box-shadow: 1px 2px 2px rgba(0, 0, 0, 0.1);
151 | }
152 |
153 | .emoji {
154 | display: inline-block;
155 | width: 40px;
156 | margin: 0 3px;
157 | transition: all 0.3s;
158 | cursor: pointer;
159 | }
160 |
161 | .emoji:hover {
162 | transform: scale(1.3);
163 | }
164 |
--------------------------------------------------------------------------------
/src/FBPost.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import FbImageLibrary from './react-fb-image-grid';
3 | import FacebookEmoji from 'react-facebook-emoji';
4 |
5 | import './FBPost.css';
6 |
7 | import defaultAvtar from './imgs/default-avatar.jpg';
8 | import privacyPublic from './imgs/privacy-public.PNG';
9 | import privacyFriends from './imgs/privacy-friends.PNG';
10 | import LikeBtn from './imgs/like-btn.PNG';
11 | import CommentBtn from './imgs/comment-btn.PNG';
12 | import ShareBtn from './imgs/share-btn.PNG';
13 | import Liked from './imgs/liked.PNG';
14 | import Loved from './imgs/loved.PNG';
15 | import Hahaed from './imgs/hahaed.PNG';
16 | import Wowed from './imgs/wowed.PNG';
17 | import Saded from './imgs/saded.PNG';
18 | import Angred from './imgs/angred.PNG';
19 |
20 | let LikeBtnImg = LikeBtn;
21 |
22 | class FBPost extends Component {
23 | static defaultProps = {
24 | avtar: false,
25 | name: 'Your Name',
26 | time: 'Just Now',
27 | privacy: 'public',
28 | caption: 'Some Awesome Caption',
29 | images: [],
30 | likes: 0,
31 | includeLike: false,
32 | includeLove: false,
33 | includeHaha: false,
34 | includeWow: false,
35 | includeSad: false,
36 | includeAngry: false,
37 | };
38 |
39 | constructor(props) {
40 | super(props);
41 |
42 | this.state = {
43 | emojiesShown: false,
44 | emoji: null,
45 | iLiked: false,
46 | iLoved: false,
47 | iHahaed: false,
48 | iWowed: false,
49 | iSaded: false,
50 | iAngred: false,
51 | };
52 | }
53 |
54 | showEmojies = isTrue => {
55 | this.setState({ emojiesShown: isTrue });
56 | };
57 |
58 | setEmoji = (newEmoji, fromBtn) => {
59 | const { emoji } = this.state;
60 |
61 | if (emoji && emoji !== 'like' && fromBtn) {
62 | this.setState({ emoji: null }, this.setEmojiImg(null));
63 | return;
64 | }
65 |
66 | if (!emoji || emoji !== newEmoji)
67 | this.setState({ emoji: newEmoji }, this.setEmojiImg(newEmoji));
68 |
69 | if (emoji === newEmoji)
70 | this.setState({ emoji: null }, this.setEmojiImg(null));
71 |
72 | this.showEmojies(false);
73 | };
74 |
75 | setEmojiImg = emoji => {
76 | let { iLiked, iLoved, iHahaed, iWowed, iSaded, iAngred } = this.state;
77 |
78 | switch (emoji) {
79 | case 'like':
80 | LikeBtnImg = Liked;
81 | this.setState({
82 | iLiked: !iLiked,
83 | iLoved: false,
84 | iHahaed: false,
85 | iWowed: false,
86 | iSaded: false,
87 | iAngred: false,
88 | });
89 | break;
90 |
91 | case 'love':
92 | LikeBtnImg = Loved;
93 | this.setState({
94 | iLiked: false,
95 | iLoved: !iLoved,
96 | iHahaed: false,
97 | iWowed: false,
98 | iSaded: false,
99 | iAngred: false,
100 | });
101 | break;
102 |
103 | case 'haha':
104 | LikeBtnImg = Hahaed;
105 | this.setState({
106 | iLiked: false,
107 | iLoved: false,
108 | iHahaed: !iHahaed,
109 | iWowed: false,
110 | iSaded: false,
111 | iAngred: false,
112 | });
113 | break;
114 |
115 | case 'wow':
116 | LikeBtnImg = Wowed;
117 | this.setState({
118 | iLiked: false,
119 | iLoved: false,
120 | iHahaed: false,
121 | iWowed: !iWowed,
122 | iSaded: false,
123 | iAngred: false,
124 | });
125 | break;
126 |
127 | case 'sad':
128 | LikeBtnImg = Saded;
129 | this.setState({
130 | iLiked: false,
131 | iLoved: false,
132 | iHahaed: false,
133 | iWowed: false,
134 | iSaded: !iSaded,
135 | iAngred: false,
136 | });
137 | break;
138 |
139 | case 'angry':
140 | LikeBtnImg = Angred;
141 | this.setState({
142 | iLiked: false,
143 | iLoved: false,
144 | iHahaed: false,
145 | iWowed: false,
146 | iSaded: false,
147 | iAngred: !iAngred,
148 | });
149 | break;
150 |
151 | default:
152 | LikeBtnImg = LikeBtn;
153 | this.setState({
154 | iLiked: false,
155 | iLoved: false,
156 | iHahaed: false,
157 | iWowed: false,
158 | iSaded: false,
159 | iAngred: false,
160 | });
161 | break;
162 | }
163 | };
164 |
165 | render() {
166 | const {
167 | emojiesShown,
168 | emoji,
169 | iLiked,
170 | iLoved,
171 | iHahaed,
172 | iWowed,
173 | iSaded,
174 | iAngred,
175 | } = this.state;
176 | const {
177 | avtar,
178 | name,
179 | time,
180 | privacy,
181 | caption,
182 | images,
183 | likes,
184 | includeLike,
185 | includeLove,
186 | includeHaha,
187 | includeWow,
188 | includeSad,
189 | includeAngry,
190 | } = this.props;
191 |
192 | return (
193 |
194 |
195 |
196 |

197 |
198 |
199 |
{name}
200 |
201 |
202 | {time} -
203 |
204 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
{caption}
219 |
0 ? { height: 400 } : { height: 0 }}
222 | >
223 |
224 |
225 |
226 |
227 |
228 | {(includeLike || iLiked || likes > 0) && (
229 |

230 | )}
231 | {(includeLove || iLoved) &&

}
232 | {(includeHaha || iHahaed) &&

}
233 | {(includeWow || iWowed) &&

}
234 | {(includeSad || iSaded) &&

}
235 | {(includeAngry || iAngred) &&

}
236 | {emoji && ' You'} {emoji && likes > 0 && ' & '}
237 | {likes > 0 && likes} {emoji && likes > 0 && ' Others'}
238 |
239 |
240 |
241 |
242 |
this.showEmojies(true)}
245 | onMouseLeave={() => this.showEmojies(false)}
246 | >
247 | {emojiesShown && (
248 |
249 |
this.setEmoji('like')}>
250 |
251 |
252 |
this.setEmoji('love')}>
253 |
254 |
255 |
this.setEmoji('haha')}>
256 |
257 |
258 |
this.setEmoji('wow')}>
259 |
260 |
261 |
this.setEmoji('sad')}>
262 |
263 |
264 |
this.setEmoji('angry')}>
265 |
266 |
267 |
268 | )}
269 |
![]()
this.setEmoji('like', true)}
271 | src={LikeBtnImg}
272 | alt="Like"
273 | />
274 |
275 |
276 |

277 |
278 |
279 |

280 |
281 |
282 |
283 | );
284 | }
285 | }
286 |
287 | export default FBPost;
288 |
--------------------------------------------------------------------------------
/src/imgs/angred.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuhammadOvi/react-fb-post-creator/58a1aa03d61ea207dce9403739a62a0fab875313/src/imgs/angred.PNG
--------------------------------------------------------------------------------
/src/imgs/comment-btn.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuhammadOvi/react-fb-post-creator/58a1aa03d61ea207dce9403739a62a0fab875313/src/imgs/comment-btn.PNG
--------------------------------------------------------------------------------
/src/imgs/default-avatar.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuhammadOvi/react-fb-post-creator/58a1aa03d61ea207dce9403739a62a0fab875313/src/imgs/default-avatar.jpg
--------------------------------------------------------------------------------
/src/imgs/hahaed.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuhammadOvi/react-fb-post-creator/58a1aa03d61ea207dce9403739a62a0fab875313/src/imgs/hahaed.PNG
--------------------------------------------------------------------------------
/src/imgs/like-btn.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuhammadOvi/react-fb-post-creator/58a1aa03d61ea207dce9403739a62a0fab875313/src/imgs/like-btn.PNG
--------------------------------------------------------------------------------
/src/imgs/liked.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuhammadOvi/react-fb-post-creator/58a1aa03d61ea207dce9403739a62a0fab875313/src/imgs/liked.PNG
--------------------------------------------------------------------------------
/src/imgs/loved.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuhammadOvi/react-fb-post-creator/58a1aa03d61ea207dce9403739a62a0fab875313/src/imgs/loved.PNG
--------------------------------------------------------------------------------
/src/imgs/privacy-friends.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuhammadOvi/react-fb-post-creator/58a1aa03d61ea207dce9403739a62a0fab875313/src/imgs/privacy-friends.PNG
--------------------------------------------------------------------------------
/src/imgs/privacy-public.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuhammadOvi/react-fb-post-creator/58a1aa03d61ea207dce9403739a62a0fab875313/src/imgs/privacy-public.PNG
--------------------------------------------------------------------------------
/src/imgs/saded.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuhammadOvi/react-fb-post-creator/58a1aa03d61ea207dce9403739a62a0fab875313/src/imgs/saded.PNG
--------------------------------------------------------------------------------
/src/imgs/share-btn.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuhammadOvi/react-fb-post-creator/58a1aa03d61ea207dce9403739a62a0fab875313/src/imgs/share-btn.PNG
--------------------------------------------------------------------------------
/src/imgs/wowed.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuhammadOvi/react-fb-post-creator/58a1aa03d61ea207dce9403739a62a0fab875313/src/imgs/wowed.PNG
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | margin: 0;
4 | padding: 0;
5 | }
6 |
7 | body {
8 | font-family: sans-serif;
9 | }
10 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 |
6 | import 'antd/dist/antd.css';
7 |
8 | ReactDOM.render(, document.getElementById('root'));
9 |
--------------------------------------------------------------------------------
/src/react-fb-image-grid/components/Images.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Grid, Row, Col } from 'react-bootstrap';
3 | import PropTypes from 'prop-types';
4 | import Modal from './Modal';
5 |
6 | class Images extends Component {
7 | static defaultProps = {
8 | beautify: false,
9 | countFrom: 5,
10 | hideOverlay: false,
11 | images: [],
12 | onClickEach: null,
13 | overlayBackgroundColor: '#222222',
14 | renderOverlay: () => 'Preview Image',
15 | upperHeight: 65,
16 | width: 100,
17 | };
18 |
19 | constructor(props) {
20 | super(props);
21 |
22 | this.state = {
23 | countFrom:
24 | props.countFrom > 0 && props.countFrom < 5 ? props.countFrom : 5,
25 | modal: false,
26 | };
27 |
28 | this.openModal = this.openModal.bind(this);
29 | this.onClose = this.onClose.bind(this);
30 |
31 | if (props.countFrom <= 0 || props.countFrom > 5) {
32 | console.warn('countFrom is limited to 5!');
33 | }
34 | }
35 |
36 | onClose() {
37 | this.setState({ modal: false });
38 | }
39 |
40 | openModal(index) {
41 | const { onClickEach, images } = this.props;
42 |
43 | if (onClickEach) {
44 | return onClickEach({ index, src: images[index] });
45 | }
46 |
47 | this.setState({ index, modal: true });
48 | }
49 |
50 | renderOne() {
51 | const { images, beautify, upperHeight } = this.props;
52 | const { countFrom } = this.state;
53 | const height = images.length === 1 ? '100%' : `${upperHeight}%`;
54 |
55 | const overlay =
56 | images.length > countFrom && countFrom === 1
57 | ? this.renderCountOverlay(true)
58 | : this.renderOverlay();
59 |
60 | return (
61 |
62 |
63 |
71 | {overlay}
72 |
73 |
74 |
75 | );
76 | }
77 |
78 | renderTwo() {
79 | const { images, beautify, upperHeight } = this.props;
80 | const { countFrom } = this.state;
81 | const overlay =
82 | images.length > countFrom && [2, 3].includes(+countFrom)
83 | ? this.renderCountOverlay(true)
84 | : this.renderOverlay();
85 | const height =
86 | images.length === 2
87 | ? '100%'
88 | : images.length === 3
89 | ? `${100 - upperHeight}%`
90 | : `${upperHeight}%`;
91 | const conditionalRender =
92 | [3, 4].includes(images.length) ||
93 | (images.length > +countFrom && [3, 4].includes(+countFrom));
94 |
95 | return (
96 |
97 |
98 |
109 | {this.renderOverlay()}
110 |
111 |
122 | {overlay}
123 |
124 |
125 |
126 | );
127 | }
128 |
129 | renderThree() {
130 | const { images, beautify, upperHeight } = this.props;
131 | const { countFrom } = this.state;
132 | const overlay =
133 | !countFrom ||
134 | countFrom > 5 ||
135 | (images.length > countFrom && [4, 5].includes(+countFrom))
136 | ? this.renderCountOverlay(true)
137 | : this.renderOverlay();
138 | const height = `${100 - upperHeight}%`;
139 | const conditionalRender =
140 | images.length === 4 || (images.length > +countFrom && +countFrom === 4);
141 |
142 | return (
143 |
144 |
145 |
156 | {this.renderOverlay()}
157 |
158 |
169 | {this.renderOverlay()}
170 |
171 |
182 | {overlay}
183 |
184 |
185 |
186 | );
187 | }
188 |
189 | renderOverlay() {
190 | const {
191 | hideOverlay,
192 | renderOverlay,
193 | overlayBackgroundColor,
194 | width,
195 | beautify,
196 | } = this.props;
197 | const fontSize = `${3 * (width / 100)}%`;
198 |
199 | if (hideOverlay) {
200 | return false;
201 | }
202 |
203 | return [
204 | ,
209 |
214 | {renderOverlay()}
215 |
,
216 | ];
217 | }
218 |
219 | renderCountOverlay(more) {
220 | const { images, width, beautify } = this.props;
221 | const { countFrom } = this.state;
222 | const extra = images.length - (countFrom && countFrom > 5 ? 5 : countFrom);
223 | const fontSize = `${7 * (width / 100)}%`;
224 |
225 | return [
226 | more && (
227 |
231 | ),
232 | more && (
233 |
236 | ),
237 | ];
238 | }
239 |
240 | render() {
241 | const { modal, index, countFrom } = this.state;
242 | const { images, width } = this.props;
243 | const imagesToShow = [...images];
244 |
245 | if (countFrom && images.length > countFrom) {
246 | imagesToShow.length = countFrom;
247 | }
248 |
249 | return (
250 |
257 | {[1, 3, 4].includes(imagesToShow.length) && this.renderOne()}
258 | {imagesToShow.length >= 2 &&
259 | imagesToShow.length !== 4 &&
260 | this.renderTwo()}
261 | {imagesToShow.length >= 4 && this.renderThree()}
262 |
263 | {modal && (
264 |
265 | )}
266 |
267 | );
268 | }
269 | }
270 |
271 | Images.propTypes = {
272 | beautify: PropTypes.bool,
273 | countFrom: PropTypes.number,
274 | hideOverlay: PropTypes.bool,
275 | onClickEach: PropTypes.func,
276 | overlayBackgroundColor: PropTypes.string,
277 | renderOverlay: PropTypes.func,
278 | upperHeight: PropTypes.number,
279 | width: PropTypes.number,
280 | };
281 |
282 | export default Images;
283 |
--------------------------------------------------------------------------------
/src/react-fb-image-grid/components/Modal.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import Lightbox from 'react-image-lightbox';
3 | import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app
4 |
5 | class ModalComponent extends Component {
6 | constructor(props) {
7 | super(props);
8 | this.state = {
9 | currentImageIndex: props.index,
10 | images: props.images || [],
11 | };
12 |
13 | this.onMovePrevRequest = this.onMovePrevRequest.bind(this);
14 | this.onMoveNextRequest = this.onMoveNextRequest.bind(this);
15 | }
16 |
17 | onMovePrevRequest() {
18 | const { currentImageIndex, images } = this.state;
19 |
20 | this.setState({
21 | currentImageIndex:
22 | (currentImageIndex + images.length - 1) % images.length,
23 | });
24 | }
25 |
26 | onMoveNextRequest() {
27 | const { currentImageIndex, images } = this.state;
28 |
29 | this.setState({
30 | currentImageIndex: (currentImageIndex + 1) % images.length,
31 | });
32 | }
33 |
34 | render() {
35 | const { images, currentImageIndex } = this.state;
36 | const { onClose } = this.props;
37 |
38 | return (
39 |
49 | );
50 | }
51 | }
52 |
53 | export default ModalComponent;
54 |
--------------------------------------------------------------------------------
/src/react-fb-image-grid/css/style.css:
--------------------------------------------------------------------------------
1 | @import 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css';
2 | @import 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css';
3 |
4 | html,
5 | body,
6 | #root,
7 | .App {
8 | height: 100%;
9 | }
10 |
11 | /* Images Component CSS */
12 |
13 | .react-fb-image-grid {
14 | margin: auto;
15 | }
16 |
17 | .react-fb-image-grid * {
18 | margin: 0;
19 | box-sizing: border-box;
20 | padding: 0;
21 | /* cursor: pointer; */
22 | }
23 |
24 | .col-md-4 {
25 | width: 33.33333333%;
26 | }
27 |
28 | .border {
29 | border: none;
30 | border-radius: 0;
31 | }
32 |
33 | .background {
34 | background-size: cover !important;
35 | background-position: center !important;
36 | background-repeat: no-repeat !important;
37 | }
38 |
39 | .height-one {
40 | height: 100%;
41 | width: 100% !important;
42 | }
43 |
44 | .height-two {
45 | height: 65%;
46 | width: 100% !important;
47 | }
48 |
49 | .cover {
50 | background-color: #222;
51 | opacity: 0.8;
52 | position: absolute;
53 | right: 0;
54 | top: 0;
55 | left: 0;
56 | bottom: 0;
57 | }
58 |
59 | .cover-text {
60 | right: 0;
61 | left: 0;
62 | bottom: 0;
63 | color: white;
64 | font-size: 1.2em !important;
65 | position: absolute;
66 | top: 50%;
67 | -webkit-transform: translate(0%, -50%);
68 | -ms-transform: translate(0%, -50%);
69 | transform: translate(0%, -50%);
70 | text-align: center;
71 | }
72 |
73 | .cover-text > p {
74 | margin: 0;
75 | position: absolute;
76 | font-size: 1.5em !important;
77 | top: 50%;
78 | left: 50%;
79 | transform: translate(-50%, -50%);
80 | }
81 |
82 | .slide {
83 | height: 0;
84 | bottom: 100%;
85 | transition: 0.4s ease;
86 | overflow: hidden;
87 | }
88 |
89 | .border:hover .slide {
90 | bottom: 0;
91 | height: auto;
92 | }
93 |
94 | .border:hover .animate-text {
95 | top: 62%;
96 | }
97 |
98 | .beautify {
99 | border: 2px solid white;
100 | border-radius: 6px;
101 | }
102 |
103 | .cover-beautify {
104 | border-radius: 6px;
105 | }
106 |
--------------------------------------------------------------------------------
/src/react-fb-image-grid/index.js:
--------------------------------------------------------------------------------
1 | import './css/style.css';
2 | import FbGridImages from './components/Images';
3 |
4 | export default FbGridImages;
5 |
--------------------------------------------------------------------------------