Skip to content
This repository has been archived by the owner on Mar 4, 2020. It is now read-only.

feat(Chat): add different chat item types #255

Merged
merged 36 commits into from
Oct 1, 2018
Merged

Conversation

mnajdova
Copy link
Contributor

@mnajdova mnajdova commented Sep 20, 2018

ChatMessage

This PR aims to add different types of messages for the chat. We should support the following types:

  • control messages
    image
  • bubble messages (this is currently the implementation of the ChatMessage itself)
    image
  • divider messages
    image

TODO

  • Conformance test
  • Minimal doc site example
  • Stardust base theme
  • Teams Light theme
  • Teams Dark theme
  • Teams Contrast theme
  • Confirm RTL usage
  • W3 accessibility check
  • Stardust accessibility check
  • Update glossary props table
  • Update the CHANGELOG.md

I have three proposals and would like to hear your opinion on.

API Proposal 1

type: 'bubble' | 'control' | 'divider'

The type property will be used for rendering one of the three different components. The properties will remain the same, we would just add additional icon shorthand for the control component.

Usage:

<ChatMessage type='bubble' author={...} ... />
<ChatMessage type='control' icon={...} ... />
<ChatMessage type='divider' content={'Yesterday'} ... />

This would be easy for use, but not much open for fully customizing the generated component.

API Proposal 2

bubble: shorthand for the Message.Bubble component

control: shorthand for the Message.Control component

divider: shorthand for the Message.Divider component

Open for customization and consistent with the other usages of the shorthand. One problem is that, a message cannot be at the same time two of these types, so we will kind a have to decide behind the scene which would take precedence.

Usage

<ChatMessage bubble={{author: 'John Doe', ...}} ... />
<ChatMessage control={{icon: {{...}}, content='Some content...'}} ... />
<ChatMessage divider={{content: '.Yesterday}}... />

API Proposal 3

This proposal is combination of the previous two. We should use the type for deciding which component will be rendered, but will use the shorthand for generating the component itself.

type: 'bubble' | 'control' | 'divider'

bubble: shorthand for the Message.Bubble component

control: shorthand for the Message.Control component

divider: shorthand for the Message.Divider component

<ChatMessage type='bubble' bubble={{author: 'John Doe', ...}} ... />
<ChatMessage type='control'  control={{icon: {{...}}, content='Some content...'}} ... />
<ChatMessage type='divider' divider={{content: '.Yesterday}}... />

@codecov
Copy link

codecov bot commented Sep 20, 2018

Codecov Report

❗ No coverage uploaded for pull request base (master@ea881ee). Click here to learn what that means.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff            @@
##             master     #255   +/-   ##
=========================================
  Coverage          ?   91.69%           
=========================================
  Files             ?       62           
  Lines             ?     1168           
  Branches          ?      150           
=========================================
  Hits              ?     1071           
  Misses            ?       94           
  Partials          ?        3
Impacted Files Coverage Δ
src/components/Chat/ChatMessage.tsx 93.61% <ø> (ø)
src/components/Grid/Grid.tsx 100% <ø> (ø)
src/components/Chat/Chat.tsx 95.45% <100%> (ø)
src/index.ts 100% <100%> (ø)
src/components/Chat/ChatItem.tsx 100% <100%> (ø)
src/components/Chat/index.ts 100% <100%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ea881ee...e97beac. Read the comment docs.

@mnajdova mnajdova added RFC help wanted Extra attention is needed labels Sep 20, 2018
@kuzhelov
Copy link
Contributor

kuzhelov commented Sep 20, 2018

From those options that are provided would rather vote against the third one, due to that it opens way to (accidentally) do things improperly on the consumer's side:

<ChatMessage type='divider' bubble={{author: 'John Doe', ...}} ... />

Speaking of the rest two (Proposal 1 and Proposal 2) - the safest approach would be to start with just different type values being supported (no shorthands for now), and see how it will go afterwards; although I should notice that I do really like a shorthand-based approach (i.e. Proposal 2) as well 👍

@kuzhelov kuzhelov added the needs author feedback Author's opinion is asked label Sep 20, 2018
@mnajdova
Copy link
Contributor Author

Got it, I agree it's the easiest from user perspective as well. Will start with the Proposal 1, we can easily migrate to 2 if we see it would be needed.

@mnajdova mnajdova added 🚧 WIP and removed help wanted Extra attention is needed needs author feedback Author's opinion is asked labels Sep 20, 2018
@mnajdova
Copy link
Contributor Author

Actually, let's go directly with the Proposal 2, because even now I can see some problems with allowing the user to define different types for the Divider for example. I would like to avoid having to change the whole API rather soon...

@alinais
Copy link
Contributor

alinais commented Sep 20, 2018

I'd go also with the second proposal.
One thing though: why do we need the divider type of the message? Can't divider be simply a divider and used where needed?

@mnajdova
Copy link
Contributor Author

Not really in this moment, as the messages are collection shorthand inside the chat component, so we aren't really capable of adding some other component in between..

@mnajdova
Copy link
Contributor Author

To be more specific the chat definition would look something like this:

<Chat items={[
    {{bubble: {avatar: {...}, content: '...'}}},
    {{bubble: {avatar: {...}, content: '...'}}},
    {{control: {icon: {...}, content: 'Meeting started...'}}}, //now that I think about this, maybe the better naming would be action
    {{divider: {content: 'Today'}}},
    {{bubble: {avatar: {...}, content: '...'}}},
  ]}

So the general change is that, the chat messages will be transformed to chat items, which can be messages, dividers, action etc..

-renamed chat message to chat item component
@mnajdova
Copy link
Contributor Author

mnajdova commented Sep 20, 2018

Still work in progress, but this is how it currently looks:
image

And here is the code for that example:

import React from 'react'

import { Chat } from '@stardust-ui/react'

const janeAvatar = {
  src: 'public/images/avatar/small/ade.jpg',
  status: {
    color: 'green',
    icon: 'check',
    title: 'Available',
  },
}

const items = [
  {
    key: 1,
    bubble: { content: 'Hello', author: 'John Doe', timestamp: 'Yesterday, 10:15 PM', mine: true },
  },
  {
    key: 2,
    bubble: {
      content: 'Hi',
      author: 'Jane Doe',
      timestamp: 'Yesterday, 10:15 PM',
      avatar: janeAvatar,
    },
  },
  {
    key: 3,
    bubble: {
      content: 'Would you like to grab a lunch?',
      author: 'John Doe',
      timestamp: 'Yesterday, 10:16 PM',
      mine: true,
    },
  },
  {
    key: 4,
    bubble: {
      content: "Sure! Let's try the new place downtown",
      author: 'Jane Doe',
      timestamp: 'Yesterday, 10:16 PM',
      avatar: janeAvatar,
    },
  },
  { key: 5, divider: { content: 'Today', type: 'primary', important: 'true' } },
  {
    key: 6,
    bubble: {
      content: "Let's have a call",
      author: 'John Doe',
      timestamp: 'Today, 11:15 PM',
      mine: true,
    },
  },
  {
    key: 7,
    action: { icon: 'record', content: 'Meeting started', timestamp: 'Today, 11:15 PM' },
  },
]

const ChatExampleShorthand = () => <Chat items={items} />

export default ChatExampleShorthand

@kuzhelov @alinais please give me your feedback about the API.

@mnajdova mnajdova changed the title feat(Message): add different types feat(Chat): add different chat item types Sep 20, 2018
@@ -1,11 +1,9 @@
import React from 'react'
import Types from './Types'
import Variations from './Variations'

const MessageExamples = () => (
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it's out of scope of PR, but we might want to rename to ChatExamples to avoid confusion

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I will restructure to example containing all different chat items. Will consider this as well.

static propTypes = {
as: customPropTypes.as,

/** Shorthand for the bubble message. */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since bubble, divider and action props are mutually exclusive, we need a better way to prevent users try more than one at a time; I'd suggest something like this:

/** Shorthand for the bubble message. */
bubble: customPropTypes.disallow(['action', 'divider']),

/** Shorthand for the divider message. */
divider: customPropTypes.disallow(['action', 'bubble']),

/** Shorthand for the control message. */
action: customPropTypes.disallow(['bubble', 'divider']),

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just the thing I was missing. Thanks a lot for the suggestion Alex!

src/components/Chat/ChatItem.tsx Outdated Show resolved Hide resolved
src/components/Chat/ChatBubble.tsx Outdated Show resolved Hide resolved
}: IRenderResultConfig<IChatActionProps>) {
const { as, icon, children } = this.props

return childrenExist(children) ? (
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mnajdova - it looks like the Chat.Action subcomponent is more complex (per @codepretty 's comments in our chats, we can have an array of actions with more complicated logic on what's rendered); I'm not even sure it falls under Stardust principles, maybe we should be more generic with the action prop in Chat component

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion, we shouldn't alter this component at this moment. We can reason for this in the following manner:

  • Chat.Action can have children which can define whatever the user wants inside - in this case we won't change anything right now
  • We can add actions as a list and make the Chat.Action use the Accordion component, but in that case it would be in my opinion very much Team's specific rather then common web (as @Bugaa92 said, it doesn't really fall under stardust principles)

My final thought on this is, leaving the Chat.Action component as is for this now, and address this later if we think would be necessary. First, I would like after this is merged, to try and address this in the chat pane and we will see how much complication it would bring.

-fixed style for the bubble when the content contains long words
@mnajdova
Copy link
Contributor Author

This is ready for final review @levithomason @kuzhelov @miroslavstastny

ElementType,
classes,
rest,
styles,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: seems that these two guys could be omitted, as those are not used anywhere

const { children, content } = this.props

return (
<ElementType {...rest} className={cx(classes.root, classes.content)}>
Copy link
Contributor

@kuzhelov kuzhelov Oct 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have potentially unreliable styling logic here - could you, please, suggest what are our plans to address it? Would rather expect this merge being performed in styles file, and exposed as item styles then

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a wrong copy/paste error, thanks for noticing. Actually we will have just the classes.root here.

static displayName = 'ChatItem'

static propTypes = {
as: customPropTypes.as,
Copy link
Contributor

@kuzhelov kuzhelov Oct 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: description for this prop is missing (as well s for a few other components of this PR, like ChatMessage) - is it intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not intentional, will provide description for all prop types in the components added/changed in this PR.

@@ -0,0 +1,52 @@
import React from 'react'
Copy link
Contributor

@kuzhelov kuzhelov Oct 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shorthand API currently is not working correctly in docs examples - the problem is apparent if one would try to click on 'Shorthand API' button:

image

Do we really want to dismiss shorthand case for Chat? This seems to be confusing, as by looking on Chat's implementation it is clearly visible that items prop is exposed - thus, it is possible to utilize shorthand advantages for this component. More than that, it seems that we won't be able to get rid of Shorthand API support, due to in this case there won't be clear mechanisms for handling Chat component's accessibility concerns.

@@ -18,6 +18,9 @@ const chatMessageStyles: IComponentPartStylesInput<IChatMessageProps, IChatMessa
marginRight: 'auto',
}),
maxWidth: v.messageWidth,
width: 'max-content',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you, please, suggest what would be the styling problem if this CSS property won't be applied? The reason I am asking is because this one is marked as experimental: https://developer.mozilla.org/en-US/docs/Web/CSS/width

Copy link
Contributor Author

@mnajdova mnajdova Oct 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without that prop this is how the chat looks:
image

I will try to implement this behavior using some other styling then...

/** Shorthand array of messages. */
messages: PropTypes.arrayOf(PropTypes.any),
/** Shorthand array of the items inside the chat. */
items: PropTypes.arrayOf(PropTypes.any),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: seems that we could be more specific here:

items:  PropTypes.arrayOf(customPropTypes.itemShorthand)

Copy link
Contributor

@kuzhelov kuzhelov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall the vector of changes taken looks good to me 👍 - few moments that have raised my concerns, left comments for them.

@kuzhelov kuzhelov added needs author feedback Author's opinion is asked RFC and removed RFC labels Oct 1, 2018
… the chat message, provided description of the properties)
/>
),
},
<Chat.Item>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

frankly, a bot unsure whether we should provide sort of heterogenous approach in the example - probably, it would be more intuitive if all the items will be the same (especially given that those that are at the end have different content - won't like to mix this differentiation aspect with another one that is about using Chat.Item directly instead of content prop)

const { children, content } = this.props

return (
<ElementType {...rest} className={cx(classes.root, classes.content)}>
<ElementType {...rest} className={classes.root}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@mnajdova mnajdova merged commit 3e5c4fb into master Oct 1, 2018
@levithomason levithomason deleted the feat/chat-message-types branch October 11, 2018 21:23
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants