Skip to content

Commit

Permalink
Merge pull request #17 from Wolox/responsive-full-view
Browse files Browse the repository at this point in the history
Responsive full view
  • Loading branch information
Martín Callegari committed Sep 21, 2017
2 parents 8d8f341 + ffeec24 commit 04f18c6
Show file tree
Hide file tree
Showing 21 changed files with 180 additions and 45 deletions.
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class App extends Component {
export default App;
```

4- Customize the widget to match your app design! You can add both props to manage the title of the widget, the avatar it will use and of course, you can change, from the CSS, the styles the widget will have.
4- Customize the widget to match your app design! You can add both props to manage the title of the widget and the avatar it will use. Of course, feel free to change the styles the widget will have in the CSS

```js
import React, { Component } from 'react';
Expand Down Expand Up @@ -141,11 +141,12 @@ export default App;

#### Props

- **handleNewUserMessage:** (PropTypes.func.isRequired) Function to handle the user input, will receive the full text message when submitted
- **title:** (PropTypes.string) Title of the widget
- **subtitle:** (PropTypes.string) Subtitle of the widget
- **senderPlaceHolder:** (PropTypes.string) The placeholder of the message input
- **profileAvatar:** (PropTypes.string.isRequired) The profile image that will be set on the responses
- **handleNewUserMessage:** (PropTypes.func.isRequired) Function to handle the user input, will receive the full text message when submitted
- **profileAvatar:** (PropTypes.string) The profile image that will be set on the responses
- **showCloseButton:** (PropTypes.bool) Show or hide the close button in full screen mode

#### Styles

Expand Down Expand Up @@ -198,6 +199,18 @@ In order to add new messages, you are provided with the following methods:

**Markdown is supported for the responses and user messages.**

#### Widget behavior

You can also control certain actions of the widget:

- **toggleWidget**
- params: No params expected
- This method is to toggle the widget at will without the need to trigger the click event on the launcher

- **toggleInputDisabled**
- params: No params expected
- Method to toggle the availability of the message input for the user to write on

## About

This project is maintained by [Martín Callegari](https://github.com/mcallegari10) and it was written by [Wolox](http://www.wolox.com.ar).
Expand Down
6 changes: 4 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import {
addResponseMessage,
addLinkSnippet,
renderCustomComponent,
toggleWidget
toggleWidget,
toggleInputDisabled
} from './src/store/actions/dispatcher';

export {
Expand All @@ -13,5 +14,6 @@ export {
addResponseMessage,
addLinkSnippet,
renderCustomComponent,
toggleWidget
toggleWidget,
toggleInputDisabled
};
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
import React from 'react';
import PropTypes from 'prop-types';

import close from 'assets/clear-button.svg';
import './style.scss';

const Header = ({ title, subtitle }) =>
const Header = ({ title, subtitle, toggleChat, showCloseButton }) =>
<div className="header">
{
showCloseButton &&
<button className="close-button" onClick={toggleChat}>
<img src={close} className="close" alt="close" />
</button>
}
<h4 className="title">{title}</h4>
<span>{subtitle}</span>
</div>;

Header.propTypes = {
title: PropTypes.string,
subtitle: PropTypes.string
subtitle: PropTypes.string,
toggleChat: PropTypes.func,
showCloseButton: PropTypes.bool
};

export default Header;
Original file line number Diff line number Diff line change
@@ -1,15 +1,48 @@
@import "variables.scss";

.header {
text-align: center;
background-color: $turqois-1;
border-radius: 10px 10px 0 0;
color: $white;
display: flex;
flex-direction: column;
text-align: center;
padding: 15px 0 25px;
}

.title {
font-size: 24px;
margin: 0;
padding: 15px 0;
}

.close-button {
display: none;
}

@media screen and (max-width: 800px) {
.header {
border-radius: 0;
flex-shrink: 0;
position: relative;
}

.title {
font-size: 24px;
margin: 0;
padding: 15px;
padding: 0 0 15px 0;
}

.close-button {
background-color: $turqois-1;
border: 0;
display: block;
position: absolute;
right: 10px;
top: 20px;
width: 40px;
}

.close {
width: 20px;
height: 20px;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ class Snippet extends PureComponent {
return (
<div className="snippet">
<h5 className="snippet-title">
{this.props.message.get('title')}
{ this.props.message.get('title') }
</h5>
<div className="snippet-details">
<a href={this.props.message.get('link')} className="link">
{this.props.message.get('link')}
{ this.props.message.get('link') }
</a>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,19 @@ class Messages extends Component {
render() {
return (
<div id="messages" className="messages-container">
{this.props.messages.map((message, index) =>
<div className="message" key={index}>
{message.get('showAvatar') &&
<img src={this.props.profileAvatar} className="avatar" alt="profile" />
}
{ this.getComponentToRender(message) }
</div>
)}
{
this.props.messages.map((message, index) =>
<div className="message" key={index}>
{
message.get('showAvatar') &&
<img src={this.props.profileAvatar} className="avatar" alt="profile" />
}
{
this.getComponentToRender(message)
}
</div>
)
}
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,10 @@
overflow-y: scroll;
padding-top: 10px;
}

@media screen and (max-width: 800px) {
.messages-container {
height: 100%;
max-height: none;
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import React from 'react';
import PropTypes from 'prop-types';

import send from 'assets/send_button.svg';
import './style.scss';

const Sender = ({ sendMessage, placeholder }) =>
const Sender = ({ sendMessage, placeholder, disabledInput }) =>
<form className="sender" onSubmit={sendMessage}>
<input type="text" className="new-message" name="message" placeholder={placeholder} autoFocus autoComplete="off" />
<input type="text" className="new-message" name="message" placeholder={placeholder} disabled={disabledInput} autoFocus autoComplete="off" />
<button type="submit" className="send">
<img src={send} className="send-icon" alt="send" />
</button>
</form>;

Sender.propTypes = {
sendMessage: PropTypes.func,
placeholder: PropTypes.string
placeholder: PropTypes.string,
disabledInput: PropTypes.bool
};

export default Sender;
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@import "variables.scss";

.sender {
align-items: center;
display: flex;
background-color: $grey-2;
height: 45px;
Expand All @@ -11,7 +12,6 @@
.new-message {
width: 100%;
border: 0;
align-self: center;
background-color: $grey-2;
height: 30px;
padding-left: 15px;
Expand All @@ -29,3 +29,10 @@
height: 25px;
}
}

@media screen and (max-width: 800px) {
.sender {
border-radius: 0;
flex-shrink: 0;
}
}
15 changes: 7 additions & 8 deletions src/components/Widget/components/Conversation/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ const Conversation = props =>
<Header
title={props.title}
subtitle={props.subtitle}
toggleChat={props.toggleChat}
showCloseButton={props.showCloseButton}
/>
<Messages
profileAvatar={props.profileAvatar}
/>
<Sender
sendMessage={props.sendMessage}
placeholder={props.senderPlaceHolder}
disabledInput={props.disabledInput}
/>
</div>;

Expand All @@ -26,14 +29,10 @@ Conversation.propTypes = {
subtitle: PropTypes.string,
sendMessage: PropTypes.func,
senderPlaceHolder: PropTypes.string,
profileAvatar: PropTypes.string
};

Conversation.defaultProps = {
headerStyles: {},
messageStyles: {},
responsesStyles: {},
snippetStyles: {}
profileAvatar: PropTypes.string,
toggleChat: PropTypes.func,
showCloseButton: PropTypes.bool,
disabledInput: PropTypes.bool
};

export default Conversation;
8 changes: 8 additions & 0 deletions src/components/Widget/components/Conversation/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,11 @@
.slide-out {
@include animation(0, 0.5s, slide-out);
}

@media screen and (max-width: 800px) {
.conversation-container {
display: flex;
flex-direction: column;
height: 100%;
}
}
9 changes: 5 additions & 4 deletions src/components/Widget/components/Launcher/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import close from 'assets/clear-button.svg';
import './style.scss';

const Launcher = ({ toggle, chatOpened }) =>
<button type="button" className="launcher" onClick={toggle}>
{chatOpened ?
<img src={close} className="close-launcher" alt="" /> :
<img src={openLauncher} className="open-launcher" alt="" />
<button type="button" className={chatOpened ? 'launcher hide-sm' : 'launcher'} onClick={toggle}>
{
chatOpened ?
<img src={close} className="close-launcher" alt="" /> :
<img src={openLauncher} className="open-launcher" alt="" />
}
</button>;

Expand Down
13 changes: 13 additions & 0 deletions src/components/Widget/components/Launcher/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,16 @@
width: 20px;
@include animation(0, 0.5s, rotation-lr);
}

@media screen and (max-width: 800px){
.launcher {
bottom: 0;
margin: 20px;
position: fixed;
right: 0;
}

.hide-sm {
display: none;
}
}
9 changes: 6 additions & 3 deletions src/components/Widget/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,26 @@ class Widget extends Component {
subtitle={this.props.subtitle}
senderPlaceHolder={this.props.senderPlaceHolder}
profileAvatar={this.props.profileAvatar}
showCloseButton={this.props.showCloseButton}
/>
);
}
}

Widget.propTypes = {
handleNewUserMessage: PropTypes.func.isRequired,
title: PropTypes.string,
subtitle: PropTypes.string,
handleNewUserMessage: PropTypes.func.isRequired,
senderPlaceHolder: PropTypes.string,
profileAvatar: PropTypes.string
profileAvatar: PropTypes.string,
showCloseButton: PropTypes.bool
};

Widget.defaultProps = {
title: 'Welcome',
subtitle: 'This is your chat subtitle',
senderPlaceHolder: 'Type a message...'
senderPlaceHolder: 'Type a message...',
showCloseButton: true
};

export default connect()(Widget);
14 changes: 11 additions & 3 deletions src/components/Widget/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@ import './style.scss';

const WidgetLayout = props =>
<div className="widget-container">
{props.showChat &&
{
props.showChat &&
<Conversation
title={props.title}
subtitle={props.subtitle}
sendMessage={props.onSendMessage}
senderPlaceHolder={props.senderPlaceHolder}
profileAvatar={props.profileAvatar}
toggleChat={props.onToggleConversation}
showChat={props.showChat}
showCloseButton={props.showCloseButton}
disabledInput={props.disabledInput}
/>
}
<Launcher
Expand All @@ -29,9 +34,12 @@ WidgetLayout.propTypes = {
onToggleConversation: PropTypes.func,
showChat: PropTypes.bool,
senderPlaceHolder: PropTypes.string,
profileAvatar: PropTypes.string
profileAvatar: PropTypes.string,
showCloseButton: PropTypes.bool,
disabledInput: PropTypes.bool
};

export default connect(store => ({
showChat: store.behavior.get('showChat')
showChat: store.behavior.get('showChat'),
disabledInput: store.behavior.get('disabledInput')
}))(WidgetLayout);
Loading

0 comments on commit 04f18c6

Please sign in to comment.