From 138892f895fad8f7e5ae37e58c2b824dec98948e Mon Sep 17 00:00:00 2001 From: Lisa Meyer <84317589+Lisa18289@users.noreply.github.com> Date: Thu, 30 Jan 2025 14:54:31 +0100 Subject: [PATCH] feat(MessageThread): add message thread component --- packages/components/package.json | 5 ++ .../components/Message/Message.module.scss | 37 +++++----- .../src/components/Message/Message.tsx | 13 +--- .../Message/stories/Default.stories.tsx | 4 +- .../MessageThread/MessageThread.module.scss | 5 ++ .../MessageThread/MessageThread.tsx | 15 ++++ .../src/components/MessageThread/index.ts | 4 + .../MessageThread/stories/Default.stories.tsx | 68 +++++++++++++++++ packages/components/vite.build.config.base.ts | 1 + .../src/content/messageThread.yml | 3 + .../content/message/examples/right.tsx | 46 ------------ .../examples/{responder.tsx => sender.tsx} | 2 +- .../content/message/overview.mdx | 14 +--- .../content/messageThread/develop.mdx | 3 + .../messageThread/examples/default.tsx | 73 +++++++++++++++++++ .../content/messageThread/examples/intro.tsx | 47 ++++++++++++ .../content/messageThread/index.mdx | 8 ++ .../content/messageThread/overview.mdx | 3 + 18 files changed, 262 insertions(+), 89 deletions(-) create mode 100644 packages/components/src/components/MessageThread/MessageThread.module.scss create mode 100644 packages/components/src/components/MessageThread/MessageThread.tsx create mode 100644 packages/components/src/components/MessageThread/index.ts create mode 100644 packages/components/src/components/MessageThread/stories/Default.stories.tsx create mode 100644 packages/design-tokens/src/content/messageThread.yml delete mode 100644 packages/docs/src/content/03-components/content/message/examples/right.tsx rename packages/docs/src/content/03-components/content/message/examples/{responder.tsx => sender.tsx} (98%) create mode 100644 packages/docs/src/content/03-components/content/messageThread/develop.mdx create mode 100644 packages/docs/src/content/03-components/content/messageThread/examples/default.tsx create mode 100644 packages/docs/src/content/03-components/content/messageThread/examples/intro.tsx create mode 100644 packages/docs/src/content/03-components/content/messageThread/index.mdx create mode 100644 packages/docs/src/content/03-components/content/messageThread/overview.mdx diff --git a/packages/components/package.json b/packages/components/package.json index 52222bd0f..4a6a0d0eb 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -257,6 +257,11 @@ "types": "./dist/js/types/components/Message/index.d.ts", "import": "./dist/js/Message.js" }, + "./MessageThread/styles.css": "./dist/css/MessageThread.css", + "./MessageThread": { + "types": "./dist/js/types/components/MessageThread/index.d.ts", + "import": "./dist/js/MessageThread.js" + }, "./Modal/styles.css": "./dist/css/Modal.css", "./Modal": { "types": "./dist/js/types/components/Modal/index.d.ts", diff --git a/packages/components/src/components/Message/Message.module.scss b/packages/components/src/components/Message/Message.module.scss index 8943d6ede..49de0cfd1 100644 --- a/packages/components/src/components/Message/Message.module.scss +++ b/packages/components/src/components/Message/Message.module.scss @@ -3,18 +3,33 @@ flex-direction: column; row-gap: var(--message--spacing-y); width: max-content; - max-width: 100%; + max-width: min(100%, var(--text--max-width)); .content { grid-area: content; border-radius: var(--message--corner-radius); padding-inline: var(--message--padding-x); padding-block: var(--message--padding-y); - background-color: var(--message--background-color-sender); + background-color: var(--message--background-color-responder); } - &.responder .content { - background-color: var(--message--background-color-responder); + &.sender { + align-self: flex-end; + .header { + flex-direction: row-reverse; + + .user { + flex-direction: row-reverse; + + :global(.flow--text) { + text-align: end; + } + } + } + + .content { + background-color: var(--message--background-color-sender); + } } .header { @@ -39,18 +54,4 @@ order: 3; } } - - &.right { - .header { - flex-direction: row-reverse; - - .user { - flex-direction: row-reverse; - - :global(.flow--text) { - text-align: end; - } - } - } - } } diff --git a/packages/components/src/components/Message/Message.tsx b/packages/components/src/components/Message/Message.tsx index b02814b43..bd65a20bb 100644 --- a/packages/components/src/components/Message/Message.tsx +++ b/packages/components/src/components/Message/Message.tsx @@ -8,21 +8,14 @@ import { IconContextMenu } from "@/components/Icon/components/icons"; import PropsContextProvider from "@/lib/propsContext/PropsContextProvider"; export interface MessageProps extends PropsWithChildren, PropsWithClassName { - /** Determines the color of the message. @default "sender" */ + /** Determines the color and orientation of the message. @default "responder" */ type?: "responder" | "sender"; - /** The orientation of the chat message. */ - orientation?: "left" | "right"; } export const Message: FC = (props) => { - const { type = "sender", children, className, orientation = "left" } = props; + const { type = "responder", children, className } = props; - const rootClassName = clsx( - styles.message, - styles[type], - styles[orientation], - className, - ); + const rootClassName = clsx(styles.message, styles[type], className); const propsContext: PropsContext = { Content: { className: styles.content }, diff --git a/packages/components/src/components/Message/stories/Default.stories.tsx b/packages/components/src/components/Message/stories/Default.stories.tsx index 4a036982a..7ef7cd133 100644 --- a/packages/components/src/components/Message/stories/Default.stories.tsx +++ b/packages/components/src/components/Message/stories/Default.stories.tsx @@ -51,7 +51,7 @@ type Story = StoryObj; export const Default: Story = {}; -export const Responder: Story = { args: { type: "responder" } }; +export const Sender: Story = { args: { type: "sender" } }; export const MessageOnly: Story = { render: (props) => ( @@ -62,5 +62,3 @@ export const MessageOnly: Story = { ), }; - -export const OrientationRight: Story = { args: { orientation: "right" } }; diff --git a/packages/components/src/components/MessageThread/MessageThread.module.scss b/packages/components/src/components/MessageThread/MessageThread.module.scss new file mode 100644 index 000000000..94ef5db38 --- /dev/null +++ b/packages/components/src/components/MessageThread/MessageThread.module.scss @@ -0,0 +1,5 @@ +.messageThread { + display: flex; + flex-direction: column; + row-gap: var(--message-thread--spacing); +} diff --git a/packages/components/src/components/MessageThread/MessageThread.tsx b/packages/components/src/components/MessageThread/MessageThread.tsx new file mode 100644 index 000000000..6be775843 --- /dev/null +++ b/packages/components/src/components/MessageThread/MessageThread.tsx @@ -0,0 +1,15 @@ +import type { FC, PropsWithChildren } from "react"; +import React from "react"; +import type { PropsWithClassName } from "@/lib/types/props"; +import clsx from "clsx"; +import styles from "./MessageThread.module.scss"; + +export type MessageThreadProps = PropsWithChildren & PropsWithClassName; + +export const MessageThread: FC = (props) => { + const { children, className } = props; + + const rootClassName = clsx(styles.messageThread, className); + + return
{children}
; +}; diff --git a/packages/components/src/components/MessageThread/index.ts b/packages/components/src/components/MessageThread/index.ts new file mode 100644 index 000000000..9290d1011 --- /dev/null +++ b/packages/components/src/components/MessageThread/index.ts @@ -0,0 +1,4 @@ +import { MessageThread } from "./MessageThread"; + +export { type MessageThreadProps, MessageThread } from "./MessageThread"; +export default MessageThread; diff --git a/packages/components/src/components/MessageThread/stories/Default.stories.tsx b/packages/components/src/components/MessageThread/stories/Default.stories.tsx new file mode 100644 index 000000000..fcc893953 --- /dev/null +++ b/packages/components/src/components/MessageThread/stories/Default.stories.tsx @@ -0,0 +1,68 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import type { FC } from "react"; +import React from "react"; +import type { MessageProps } from "@/components/Message"; +import { Message } from "@/components/Message"; +import { MessageThread } from "@/components/MessageThread"; +import { Header } from "@/components/Header"; +import { Align } from "@/components/Align"; +import { Avatar } from "@/components/Avatar"; +import { Initials } from "@/components/Initials"; +import { Text } from "@/components/Text"; +import { Content } from "@/components/Content"; +import { dummyText } from "@/lib/dev/dummyText"; + +interface ExampleMessageProps extends Pick { + name: string; + content: string; +} +const ExampleMessage: FC = (props) => { + const { name, content, ...rest } = props; + return ( + +
+ + + {name} + + + {name} + + +
+ + + {content} + +
+ ); +}; + +const meta: Meta = { + title: "Content/MessageThread", + component: MessageThread, + render: (props) => ( + + + + + + ), +}; +export default meta; + +type Story = StoryObj; + +export const Default: Story = {}; diff --git a/packages/components/vite.build.config.base.ts b/packages/components/vite.build.config.base.ts index 4c69a470a..ec58b6c8a 100644 --- a/packages/components/vite.build.config.base.ts +++ b/packages/components/vite.build.config.base.ts @@ -84,6 +84,7 @@ export const buildConfig = (opts: Options) => { Markdown: "./src/components/Markdown/index.ts", MenuItem: "./src/components/MenuItem/index.ts", Message: "./src/components/Message/index.ts", + MessageThread: "./src/components/MessageThread/index.ts", Modal: "./src/components/Modal/index.ts", Navigation: "./src/components/Navigation/index.ts", Notification: "./src/components/Notification/index.ts", diff --git a/packages/design-tokens/src/content/messageThread.yml b/packages/design-tokens/src/content/messageThread.yml new file mode 100644 index 000000000..e4dd7c48e --- /dev/null +++ b/packages/design-tokens/src/content/messageThread.yml @@ -0,0 +1,3 @@ +message-thread: + spacing: + value: "{size-rem.l}" diff --git a/packages/docs/src/content/03-components/content/message/examples/right.tsx b/packages/docs/src/content/03-components/content/message/examples/right.tsx deleted file mode 100644 index 4b3a6a31c..000000000 --- a/packages/docs/src/content/03-components/content/message/examples/right.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { Message } from "@mittwald/flow-react-components/Message"; -import { Header } from "@mittwald/flow-react-components/Header"; -import { - ContextMenu, - ContextMenuTrigger, -} from "@mittwald/flow-react-components/ContextMenu"; -import { Button } from "@mittwald/flow-react-components/Button"; -import MenuItem from "@mittwald/flow-react-components/MenuItem"; -import { Align } from "@mittwald/flow-react-components/Align"; -import { Avatar } from "@mittwald/flow-react-components/Avatar"; -import { Initials } from "@mittwald/flow-react-components/Initials"; -import { Text } from "@mittwald/flow-react-components/Text"; -import { Content } from "@mittwald/flow-react-components/Content"; - - -
- -
- - - - Lorem ipsum dolor sit amet, consetetur sadipscing - elitr, sed diam nonumy eirmod tempor invidunt ut - labore et dolore magna aliquyam erat, sed diam - voluptua. At vero eos et accusam et justo duo dolores - et ea rebum. Stet clita kasd gubergren, no sea - takimata sanctus est Lorem ipsum dolor sit amet. - - -
; diff --git a/packages/docs/src/content/03-components/content/message/examples/responder.tsx b/packages/docs/src/content/03-components/content/message/examples/sender.tsx similarity index 98% rename from packages/docs/src/content/03-components/content/message/examples/responder.tsx rename to packages/docs/src/content/03-components/content/message/examples/sender.tsx index af995fccf..d42ea26ff 100644 --- a/packages/docs/src/content/03-components/content/message/examples/responder.tsx +++ b/packages/docs/src/content/03-components/content/message/examples/sender.tsx @@ -12,7 +12,7 @@ import { Initials } from "@mittwald/flow-react-components/Initials"; import { Text } from "@mittwald/flow-react-components/Text"; import { Content } from "@mittwald/flow-react-components/Content"; - +