├── Chat.js
├── README.md
├── app.js
├── chat.css
├── example
├── app.js
├── assets
│ ├── css
│ │ ├── chat.css
│ │ └── typing.css
│ └── js
│ │ └── Chat.js
├── images
│ ├── icons
│ │ ├── attachment.svg
│ │ ├── chatbox-icon.svg
│ │ ├── emojis.svg
│ │ └── microphone.svg
│ ├── image.png
│ └── thumbnail.png
├── index.html
└── style.css
├── index.html
└── typing.css
/Chat.js:
--------------------------------------------------------------------------------
1 | class InteractiveChatbox {
2 | constructor(a, b, c) {
3 | this.args = {
4 | button: a,
5 | chatbox: b
6 | }
7 | this.icons = c;
8 | this.state = false;
9 | }
10 |
11 | display() {
12 | const {button, chatbox} = this.args;
13 |
14 | button.addEventListener('click', () => this.toggleState(chatbox))
15 | }
16 |
17 | toggleState(chatbox) {
18 | this.state = !this.state;
19 | this.showOrHideChatBox(chatbox, this.args.button);
20 | }
21 |
22 | showOrHideChatBox(chatbox, button) {
23 | if(this.state) {
24 | chatbox.classList.add('chatbox--active')
25 | this.toggleIcon(true, button);
26 | } else if (!this.state) {
27 | chatbox.classList.remove('chatbox--active')
28 | this.toggleIcon(false, button);
29 | }
30 | }
31 |
32 | toggleIcon(state, button) {
33 | const { isClicked, isNotClicked } = this.icons;
34 | let b = button.children[0].innerHTML;
35 |
36 | if(state) {
37 | button.children[0].innerHTML = isClicked;
38 | } else if(!state) {
39 | button.children[0].innerHTML = isNotClicked;
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Chat.js Front-end Starter
2 |
3 | ### 1). HTML Minimum setup:
4 |
5 | ```
6 |
7 |
8 |
11 |
12 |
13 |
14 | Hi!
15 |
16 |
17 | What is it?
18 |
19 | .
20 |
21 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 | ```
35 |
36 | ### 2). Copy the Chat.css
37 | ### 3). Copy Chat.js
38 | ### 4). JS Minimum Setup
39 | ```
40 | const chatButton = document.querySelector('.chatbox__button');
41 | const chatContent = document.querySelector('.chatbox__support');
42 | const icons = {
43 | isClicked: 'Clicked',
44 | isNotClicked: 'Not Clicked" />'
45 | }
46 | const chatbox = new InteractiveChatbox(chatButton, chatContent, icons);
47 | chatbox.display();
48 | chatbox.toggleIcon(false, chatButton);
49 | ```
50 |
51 | ### 5). Linked all CSS and JS files in index.html
52 | ### Sample output after setting up
53 | 
54 |
55 | # Example Customization
56 | 
57 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | const chatButton = document.querySelector('.chatbox__button');
2 | const chatContent = document.querySelector('.chatbox__support');
3 | const icons = {
4 | isClicked: 'Clicked!',
5 | isNotClicked: 'Not clicked!
'
6 | }
7 | const chatbox = new InteractiveChatbox(chatButton, chatContent, icons);
8 | chatbox.display();
9 | chatbox.toggleIcon(false, chatButton);
10 |
--------------------------------------------------------------------------------
/chat.css:
--------------------------------------------------------------------------------
1 |
2 |
3 | /* CHATBOX
4 | =============== */
5 | .chatbox {
6 | position: absolute;
7 | bottom: 30px;
8 | right: 30px;
9 | }
10 |
11 | /* CONTENT IS CLOSE */
12 | .chatbox__support {
13 | display: flex;
14 | flex-direction: column;
15 | background: #eee;
16 | width: 300px;
17 | height: 350px;
18 | z-index: -123456;
19 | opacity: 0;
20 | transition: all .5s ease-in-out;
21 | }
22 |
23 | /* CONTENT ISOPEN */
24 | .chatbox--active {
25 | transform: translateY(-40px);
26 | z-index: 123456;
27 | opacity: 1;
28 |
29 | }
30 |
31 | /* BUTTON */
32 | .chatbox__button {
33 | text-align: right;
34 | }
35 |
36 |
37 | /* HEADER */
38 | .chatbox__header {
39 | position: sticky;
40 | top: 0;
41 | background: orange;
42 | }
43 |
44 | /* MESSAGES */
45 | .chatbox__messages {
46 | margin-top: auto;
47 | display: flex;
48 | flex-direction: column;
49 | overflow-y: scroll;
50 | flex-direction: column-reverse;
51 | }
52 |
53 | .messages__item {
54 | background: orange;
55 | max-width: 60.6%;
56 | width: fit-content;
57 | }
58 |
59 | .messages__item--operator {
60 | margin-left: auto;
61 | }
62 |
63 | .messages__item--visitor {
64 | margin-right: auto;
65 | }
66 |
67 | /* FOOTER */
68 | .chatbox__footer {
69 | position: sticky;
70 | bottom: 0;
71 | }
72 |
73 |
74 |
--------------------------------------------------------------------------------
/example/app.js:
--------------------------------------------------------------------------------
1 | const chatButton = document.querySelector('.chatbox__button');
2 | const chatContent = document.querySelector('.chatbox__support');
3 | const icons = {
4 | isClicked: '
',
5 | isNotClicked: '
'
6 | }
7 | const chatbox = new InteractiveChatbox(chatButton, chatContent, icons);
8 | chatbox.display();
9 | chatbox.toggleIcon(false, chatButton);
--------------------------------------------------------------------------------
/example/assets/css/chat.css:
--------------------------------------------------------------------------------
1 |
2 |
3 | /* CHATBOX
4 | =============== */
5 | .chatbox {
6 | position: absolute;
7 | bottom: 30px;
8 | right: 30px;
9 | }
10 |
11 | /* CONTENT IS CLOSE */
12 | .chatbox__support {
13 | display: flex;
14 | flex-direction: column;
15 | background: #eee;
16 | width: 300px;
17 | height: 350px;
18 | z-index: -123456;
19 | opacity: 0;
20 | transition: all .5s ease-in-out;
21 | }
22 |
23 | /* CONTENT ISOPEN */
24 | .chatbox--active {
25 | transform: translateY(-40px);
26 | z-index: 123456;
27 | opacity: 1;
28 |
29 | }
30 |
31 | /* BUTTON */
32 | .chatbox__button {
33 | text-align: right;
34 | }
35 |
36 |
37 | /* HEADER */
38 | .chatbox__header {
39 | position: sticky;
40 | top: 0;
41 | background: orange;
42 | }
43 |
44 | /* MESSAGES */
45 | .chatbox__messages {
46 | margin-top: auto;
47 | display: flex;
48 | flex-direction: column;
49 | overflow-y: scroll;
50 | flex-direction: column-reverse;
51 | }
52 |
53 | .messages__item {
54 | background: orange;
55 | max-width: 60.6%;
56 | width: fit-content;
57 | }
58 |
59 | .messages__item--operator {
60 | margin-left: auto;
61 | }
62 |
63 | .messages__item--visitor {
64 | margin-right: auto;
65 | }
66 |
67 | /* FOOTER */
68 | .chatbox__footer {
69 | position: sticky;
70 | bottom: 0;
71 | }
72 |
73 |
74 |
--------------------------------------------------------------------------------
/example/assets/css/typing.css:
--------------------------------------------------------------------------------
1 | .messages__item--typing {
2 | will-change: transform;
3 | width: auto;
4 | border-top-right-radius: 20px;
5 | border-top-left-radius: 20px;
6 | border-bottom-right-radius: 20px;
7 | padding: 15px 20px;
8 | display: table;
9 | margin-right: auto;
10 | position: relative;
11 | animation: 2s bulge infinite ease-out;
12 | }
13 |
14 | .messages__item--typing::before,
15 | .messages__item--typing::after {
16 | content: '';
17 | position: absolute;
18 | bottom: -2px;
19 | left: -2px;
20 | height: 10px;
21 | width: 10px;
22 | border-radius: 50%;
23 | }
24 | .messages__item--typing::after {
25 | height: 10px;
26 | width: 10px;
27 | left: -10px;
28 | bottom: -10px;
29 | }
30 | span.messages__dot {
31 | height: 8px;
32 | width: 8px;
33 | float: left;
34 | margin: 0 1px;
35 | background-color: #9E9EA1;
36 | display: block;
37 | border-radius: 50%;
38 | opacity: 0.4;
39 | animation: 1s blink infinite;
40 | }
41 |
42 | @keyframes blink {
43 | 50% {
44 | opacity: 1;
45 | }
46 | }
47 |
48 | @keyframes bulge {
49 | 50% {
50 | transform: scale(1.05);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/example/assets/js/Chat.js:
--------------------------------------------------------------------------------
1 | class InteractiveChatbox {
2 | constructor(a, b, c) {
3 | this.args = {
4 | button: a,
5 | chatbox: b
6 | }
7 | this.icons = c;
8 | this.state = false;
9 | }
10 |
11 | display() {
12 | const {button, chatbox} = this.args;
13 |
14 | button.addEventListener('click', () => this.toggleState(chatbox))
15 | }
16 |
17 | toggleState(chatbox) {
18 | this.state = !this.state;
19 | this.showOrHideChatBox(chatbox, this.args.button);
20 | }
21 |
22 | showOrHideChatBox(chatbox, button) {
23 | if(this.state) {
24 | chatbox.classList.add('chatbox--active')
25 | this.toggleIcon(true, button);
26 | } else if (!this.state) {
27 | chatbox.classList.remove('chatbox--active')
28 | this.toggleIcon(false, button);
29 | }
30 | }
31 |
32 | toggleIcon(state, button) {
33 | const { isClicked, isNotClicked } = this.icons;
34 | let b = button.children[0].innerHTML;
35 |
36 | if(state) {
37 | button.children[0].innerHTML = isClicked;
38 | } else if(!state) {
39 | button.children[0].innerHTML = isNotClicked;
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/example/images/icons/attachment.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/example/images/icons/chatbox-icon.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/example/images/icons/emojis.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/example/images/icons/microphone.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/example/images/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hitchcliff/front-end-chatjs/22ea095d7736011239f969b447621d5d4f4a8cf1/example/images/image.png
--------------------------------------------------------------------------------
/example/images/thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hitchcliff/front-end-chatjs/22ea095d7736011239f969b447621d5d4f4a8cf1/example/images/thumbnail.png
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Chatbox
11 |
12 |
13 |
14 |
15 |
16 |
25 |
26 |
27 |
28 | Can you let me talk to the support?
29 |
30 |
31 | Sure!
32 |
33 |
34 | Need your help, I need a developer in my site.
35 |
36 |
37 | Hi... What is it? I'm a front-end developer, yay!
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/example/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | margin: 0;
4 | padding: 0;
5 | }
6 |
7 | *, html {
8 | --primaryGradient: linear-gradient(93.12deg, #581B98 0.52%, #9C1DE7 100%);
9 | --secondaryGradient: linear-gradient(268.91deg, #581B98 -2.14%, #9C1DE7 99.69%);
10 | --primaryBoxShadow: 0px 10px 15px rgba(0, 0, 0, 0.1);
11 | --secondaryBoxShadow: 0px -10px 15px rgba(0, 0, 0, 0.1);
12 | --light: 300;
13 | --regular: 400;
14 | --semiBold: 600;
15 | --extraLight: 300;
16 | --italic: 300;
17 | --primary: #581B98;
18 | }
19 |
20 | /* 300;0,400;0,600;1,300 */
21 |
22 | body {
23 | font-family: 'Nunito', sans-serif;
24 | font-weight: 400;
25 | font-size: 100%;
26 | background: #F1F1F1;
27 | }
28 |
29 | .chatbox__support {
30 | background: #f9f9f9;
31 | height: 450px;
32 | width: 350px;
33 | box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.1);
34 | border-top-left-radius: 20px;
35 | border-top-right-radius: 20px;
36 | }
37 |
38 | /* HEADER */
39 | .chatbox__header {
40 | background: var(--primaryGradient);
41 | display: flex;
42 | flex-direction: row;
43 | align-items: center;
44 | justify-content: center;
45 | padding: 15px 20px;
46 | border-top-left-radius: 20px;
47 | border-top-right-radius: 20px;
48 | box-shadow: var(--primaryBoxShadow);
49 | }
50 |
51 | .chatbox__image--header {
52 | margin-right: 10px;
53 | }
54 |
55 | .chatbox__heading--header {
56 | font-size: 1.2rem;
57 | color: white;
58 | }
59 |
60 | .chatbox__description--header {
61 | font-size: .9rem;
62 | color: white;
63 | }
64 |
65 | /* Messages */
66 | .chatbox__messages {
67 | padding: 0 20px;
68 | }
69 |
70 | .messages__item {
71 | margin-top: 10px;
72 | background: #E0E0E0;
73 | padding: 8px 12px;
74 | max-width: 70%;
75 | }
76 |
77 | .messages__item--visitor,
78 | .messages__item--typing {
79 | border-top-left-radius: 20px;
80 | border-top-right-radius: 20px;
81 | border-bottom-right-radius: 20px;
82 | }
83 |
84 | .messages__item--operator {
85 | border-top-left-radius: 20px;
86 | border-top-right-radius: 20px;
87 | border-bottom-left-radius: 20px;
88 | background: var(--primary);
89 | color: white;
90 | }
91 |
92 | /* FOOTER */
93 | .chatbox__footer {
94 | display: flex;
95 | flex-direction: row;
96 | align-items: center;
97 | justify-content: space-between;
98 | padding: 20px 20px;
99 | background: var(--secondaryGradient);
100 | box-shadow: var(--secondaryBoxShadow);
101 | border-bottom-right-radius: 10px;
102 | border-bottom-left-radius: 10px;
103 | margin-top: 20px;
104 | }
105 |
106 | .chatbox__footer input {
107 | border: none;
108 | padding: 10px 10px;
109 | border-radius: 30px;
110 | text-align: center;
111 | }
112 |
113 | .chatbox__send--footer {
114 | color: white;
115 | }
116 |
117 | .chatbox__button button,
118 | .chatbox__button button:focus,
119 | .chatbox__button button:visited {
120 | padding: 10px;
121 | background: white;
122 | border: none;
123 | outline: none;
124 | border-top-left-radius: 50px;
125 | border-top-right-radius: 50px;
126 | border-bottom-left-radius: 50px;
127 | box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1);
128 | cursor: pointer;
129 | }
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 | Hi!
19 |
20 |
21 | What is it?
22 |
23 | .
24 |
25 |
26 |
27 |
28 |
29 |
30 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/typing.css:
--------------------------------------------------------------------------------
1 | .messages__item--typing {
2 | will-change: transform;
3 | width: auto;
4 | border-top-right-radius: 20px;
5 | border-top-left-radius: 20px;
6 | border-bottom-right-radius: 20px;
7 | padding: 15px 20px;
8 | display: table;
9 | margin-right: auto;
10 | position: relative;
11 | animation: 2s bulge infinite ease-out;
12 | }
13 |
14 | .messages__item--typing::before,
15 | .messages__item--typing::after {
16 | content: '';
17 | position: absolute;
18 | bottom: -2px;
19 | left: -2px;
20 | height: 10px;
21 | width: 10px;
22 | border-radius: 50%;
23 | }
24 | .messages__item--typing::after {
25 | height: 10px;
26 | width: 10px;
27 | left: -10px;
28 | bottom: -10px;
29 | }
30 | span.messages__dot {
31 | height: 8px;
32 | width: 8px;
33 | float: left;
34 | margin: 0 1px;
35 | background-color: #9E9EA1;
36 | display: block;
37 | border-radius: 50%;
38 | opacity: 0.4;
39 | animation: 1s blink infinite;
40 | }
41 |
42 | @keyframes blink {
43 | 50% {
44 | opacity: 1;
45 | }
46 | }
47 |
48 | @keyframes bulge {
49 | 50% {
50 | transform: scale(1.05);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------