diff --git a/CHANGELOG.md b/CHANGELOG.md
index 76d76770b5..0f3a5856fe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
### Features
- Accessibility for menu divider @jurokapsiar ([#822](https://github.com/stardust-ui/react/pull/822))
- Added slot class names in `ChatMessage`, `ChatItem`, `Dropdown`, `ItemLayout`, `Layout`, `MenuItem` @mnajdova ([#827](https://github.com/stardust-ui/react/pull/827))
+- Add `badge` and `badgePosition` properties on the `ChatMessage` @mnajdova ([#823](https://github.com/stardust-ui/react/pull/823))
### Fixes
- Fix `Dropdown` component styles regression @Bugaa92 ([#824](https://github.com/stardust-ui/react/pull/824))
diff --git a/docs/src/examples/components/Chat/Types/ChatMessageExampleBadge.shorthand.tsx b/docs/src/examples/components/Chat/Types/ChatMessageExampleBadge.shorthand.tsx
new file mode 100644
index 0000000000..34b9d16a59
--- /dev/null
+++ b/docs/src/examples/components/Chat/Types/ChatMessageExampleBadge.shorthand.tsx
@@ -0,0 +1,51 @@
+import * as React from 'react'
+import { Avatar, Chat } from '@stardust-ui/react'
+
+const janeAvatar = {
+ image: 'public/images/avatar/small/ade.jpg',
+ status: { color: 'green', icon: 'check' },
+}
+
+const items = [
+ {
+ message: {
+ content: (
+
+ ),
+ },
+ contentPosition: 'end',
+ key: 'message-id-1',
+ },
+ {
+ gutter: { content: },
+ message: {
+ content: (
+
+ ),
+ },
+ attached: 'top',
+ key: 'message-id-4',
+ },
+]
+
+const ChatExample = () =>
+
+export default ChatExample
diff --git a/docs/src/examples/components/Chat/Types/ChatMessageExampleStyled.shorthand.tsx b/docs/src/examples/components/Chat/Types/ChatMessageExampleStyled.shorthand.tsx
index 2d6d1c1489..36733fdda2 100644
--- a/docs/src/examples/components/Chat/Types/ChatMessageExampleStyled.shorthand.tsx
+++ b/docs/src/examples/components/Chat/Types/ChatMessageExampleStyled.shorthand.tsx
@@ -17,10 +17,11 @@ const content = (
)
-const slotLabelStyles: any = (label, beforeStyles) => ({
+const slotLabelStyles: any = (label, beforeStyles?, slotStyles?) => ({
position: 'relative',
border: '1px solid #000',
padding: '12px',
+ ...slotStyles,
':before': {
content: `'${label}'`,
position: 'absolute',
@@ -56,6 +57,14 @@ const ChatMessageExampleStyled = () => (
}),
content: { ...slotLabelStyles('content'), backgroundColor: '#F08080' },
timestamp: { ...slotLabelStyles('timestamp'), backgroundColor: '#FFFFE0' },
+ badge: {
+ ...slotLabelStyles(
+ 'badge',
+ { textAlign: 'center', left: '0px' },
+ { position: 'absolute', overflow: 'visible' },
+ ),
+ backgroundColor: '#FFFF00',
+ },
},
},
componentVariables: {
@@ -77,6 +86,8 @@ const ChatMessageExampleStyled = () => (
author="John Doe"
timestamp="Yesterday, 10:15 PM"
mine
+ badge={{ icon: 'at' }}
+ badgePosition="start"
/>
),
},
@@ -92,6 +103,7 @@ const ChatMessageExampleStyled = () => (
content={{ content }}
author="Jane Doe"
timestamp="Yesterday, 10:15 PM"
+ badge={{ icon: 'exclamation' }}
/>
),
},
diff --git a/docs/src/examples/components/Chat/Types/index.tsx b/docs/src/examples/components/Chat/Types/index.tsx
index 935c668be7..83952f611a 100644
--- a/docs/src/examples/components/Chat/Types/index.tsx
+++ b/docs/src/examples/components/Chat/Types/index.tsx
@@ -19,6 +19,11 @@ const Types = () => (
description="A Chat item with custom styles for every slot."
examplePath="components/Chat/Types/ChatMessageExampleStyled"
/>
+
)
diff --git a/packages/react/src/components/Chat/ChatMessage.tsx b/packages/react/src/components/Chat/ChatMessage.tsx
index ad6f27045e..4ff85ae46b 100644
--- a/packages/react/src/components/Chat/ChatMessage.tsx
+++ b/packages/react/src/components/Chat/ChatMessage.tsx
@@ -22,10 +22,12 @@ import { Accessibility, AccessibilityActionHandlers } from '../../lib/accessibil
import Text from '../Text/Text'
import Box from '../Box/Box'
+import Label from '../Label/Label'
export interface ChatMessageSlotClassNames {
author: string
timestamp: string
+ badge: string
content: string
}
@@ -48,6 +50,12 @@ export interface ChatMessageProps
/** Timestamp of the message. */
timestamp?: ShorthandValue
+ /** Badge attached to the message. */
+ badge?: ShorthandValue
+
+ /** A message can format the badge to appear at the start or the end of the message. */
+ badgePosition?: 'start' | 'end'
+
/**
* Called after user's focus.
* @param {SyntheticEvent} event - React's original SyntheticEvent.
@@ -76,6 +84,8 @@ class ChatMessage extends UIComponent, ChatMessageS
...commonPropTypes.createCommon({ content: 'shorthand' }),
accessibility: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
author: customPropTypes.itemShorthand,
+ badge: customPropTypes.itemShorthand,
+ badgePosition: PropTypes.oneOf(['start', 'end']),
mine: PropTypes.bool,
timestamp: customPropTypes.itemShorthand,
onFocus: PropTypes.func,
@@ -84,6 +94,7 @@ class ChatMessage extends UIComponent, ChatMessageS
static defaultProps = {
accessibility: chatMessageBehavior,
as: 'div',
+ badgePosition: 'end',
}
public state = {
@@ -110,9 +121,15 @@ class ChatMessage extends UIComponent, ChatMessageS
unhandledProps,
styles,
}: RenderResultConfig) {
- const { author, children, content, timestamp } = this.props
+ const { author, children, content, timestamp, badge, badgePosition } = this.props
const childrenPropExists = childrenExist(children)
const className = childrenPropExists ? cx(classes.root, classes.content) : classes.root
+ const badgeElement = Label.create(badge, {
+ defaultProps: {
+ className: ChatMessage.slotClassNames.badge,
+ styles: styles.badge,
+ },
+ })
return (
, ChatMessageS
children
) : (
<>
+ {badgePosition === 'start' && badgeElement}
{Text.create(author, {
defaultProps: {
size: 'small',
@@ -142,12 +160,14 @@ class ChatMessage extends UIComponent, ChatMessageS
className: ChatMessage.slotClassNames.timestamp,
},
})}
+
{Box.create(content, {
defaultProps: {
className: ChatMessage.slotClassNames.content,
styles: styles.content,
},
})}
+ {badgePosition === 'end' && badgeElement}
>
)}
@@ -159,6 +179,7 @@ ChatMessage.create = createShorthandFactory(ChatMessage, 'content')
ChatMessage.slotClassNames = {
author: `${ChatMessage.className}__author`,
timestamp: `${ChatMessage.className}__timestamp`,
+ badge: `${ChatMessage.className}__badge`,
content: `${ChatMessage.className}__content`,
}
diff --git a/packages/react/src/themes/teams/components/Chat/chatMessageStyles.ts b/packages/react/src/themes/teams/components/Chat/chatMessageStyles.ts
index 3f8a84d0ec..a3a270044a 100644
--- a/packages/react/src/themes/teams/components/Chat/chatMessageStyles.ts
+++ b/packages/react/src/themes/teams/components/Chat/chatMessageStyles.ts
@@ -6,6 +6,7 @@ import { pxToRem } from '../../../../lib'
const chatMessageStyles: ComponentSlotStylesInput = {
root: ({ props: p, variables: v }): ICSSInJSStyle => ({
+ position: 'relative',
display: 'inline-block',
paddingLeft: v.padding,
paddingRight: v.padding,
@@ -44,6 +45,21 @@ const chatMessageStyles: ComponentSlotStylesInput {
+ const sidePosition = p.badgePosition === 'start' ? 'left' : 'right'
+ return {
+ boxShadow: v.badgeShadow,
+ position: 'absolute',
+ padding: pxToRem(4),
+ height: 'auto',
+ width: 'auto',
+ borderRadius: '50%',
+ top: pxToRem(4),
+ zIndex: '1',
+ [sidePosition]: 0,
+ transform: p.badgePosition === 'start' ? 'translateX(-50%)' : 'translateX(50%)',
+ }
+ },
}
export default chatMessageStyles
diff --git a/packages/react/src/themes/teams/components/Chat/chatMessageVariables.ts b/packages/react/src/themes/teams/components/Chat/chatMessageVariables.ts
index 9b473f6795..cf85908a51 100644
--- a/packages/react/src/themes/teams/components/Chat/chatMessageVariables.ts
+++ b/packages/react/src/themes/teams/components/Chat/chatMessageVariables.ts
@@ -11,6 +11,7 @@ export interface ChatMessageVariables {
headerMarginBottom: string
contentFocusOutlineColor: string
border: string
+ badgeShadow: string
}
export default (siteVars): ChatMessageVariables => ({
@@ -24,4 +25,5 @@ export default (siteVars): ChatMessageVariables => ({
headerMarginBottom: pxToRem(2),
contentFocusOutlineColor: siteVars.brand,
border: 'none',
+ badgeShadow: siteVars.shadowLevel1Darker,
})
diff --git a/packages/react/src/themes/teams/siteVariables.ts b/packages/react/src/themes/teams/siteVariables.ts
index f7cf0aac2f..010188f9a1 100644
--- a/packages/react/src/themes/teams/siteVariables.ts
+++ b/packages/react/src/themes/teams/siteVariables.ts
@@ -45,6 +45,7 @@ export const green04 = '#237b4b'
// SHADOW LEVELS
//
export const shadowLevel1 = '0 .2rem .4rem -.075rem rgba(0, 0, 0, 0.1)'
+export const shadowLevel1Darker = '0 .2rem .4rem -.075rem rgba(0, 0, 0, 0.5)'
//
// FONT SIZES