├── 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 |
9 | Chat support! 10 |
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 | ![Sample Setup](http://g.recordit.co/r3vIKlmdYc.gif) 54 | 55 | # Example Customization 56 | ![Example Outout](http://g.recordit.co/wvNlpakfKl.gif) 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 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/images/icons/chatbox-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/images/icons/emojis.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/images/icons/microphone.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 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 |
17 |
18 | image 19 |
20 |
21 |

Chat support

22 |

There are many variations of passages of Lorem Ipsum available

23 |
24 |
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 |
13 | Chat support! 14 |
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 | --------------------------------------------------------------------------------