Skip to content

Commit

Permalink
Merge branch 'main' into shaneeze/more-storybook-updates
Browse files Browse the repository at this point in the history
  • Loading branch information
shaneeza authored May 22, 2024
2 parents 0a3e07b + 3273045 commit c14b392
Show file tree
Hide file tree
Showing 53 changed files with 1,311 additions and 93 deletions.
5 changes: 5 additions & 0 deletions .changeset/angry-hornets-pump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@lg-chat/message': minor
---

Adds the links prop which renders link data as rich links after the message content
5 changes: 5 additions & 0 deletions .changeset/clever-laws-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@leafygreen-ui/form-field': patch
---

Correctly sets the `readOnly` prop in the `useFormFieldProps` hook. Previously, `readOnly` was only added to an input if `disabled` was true. Now, passing the `readOnly` prop adds it to the resulting input.
5 changes: 5 additions & 0 deletions .changeset/eight-clocks-laugh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@leafygreen-ui/text-input': patch
---

Passes `readOnly` prop to `<FormField>` so that it correctly sets the `readOnly` prop.
5 changes: 0 additions & 5 deletions .changeset/smooth-lemons-call.md

This file was deleted.

5 changes: 5 additions & 0 deletions .changeset/wicked-ladybugs-happen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@lg-chat/rich-links': major
---

Initial release
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,6 @@ export const WithMessageRating: StoryFn<typeof MessageRating> = args => {
{...args}
value={rating}
onChange={handleRatingChange}
className={css`
margin-bottom: ${spacing[1]}px;
`}
hideThumbsUp={isSubmitted}
/>
{rating === 'disliked' && (!isSubmitted || isDisplayingSubmitted) && (
Expand Down
45 changes: 32 additions & 13 deletions chat/message/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,35 @@ return (

## Properties

| Prop | Type | Description | Default |
| -------------------- | ------------------------------------------------------------------ | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `align` | `'left', 'right'` | Determines whether the message is aligned to the left or right | if `isSender === true`, the message is aligned to the right, and otherwise to the left. This prop overrides that behavior |
| `avatar` | `ReactElement` | Avatar element | |
| `componentOverrides` | `Record<MarkdownComponent, ComponentType>` | Uses value to override key'ed markdown elements in terms of how they are rendered | |
| `children` | `string` | Rendered children; only string children are supported | |
| `isSender` | `boolean` | Indicates if the message is from the current user | `true` |
| `markdownProps` | `LGMarkdownProps` | Props passed to the internal ReactMarkdown instance | |
| `messageRatingProps` | `MessageRatingProps` | Props to MessageRating component | |
| `sourceType` | `'markdown', 'text'` | Determines the rendering method of the message | |
| `messageBody` | `string` | Message body text passed to LGMarkdown | |
| `verified` | `{ verifier?: string; verifiedAt?: Date; learnMoreUrl?: string; }` | Sets if an answer is "verified" and controls the content of the message banner. | |
| `...` | `HTMLElementProps<'div'>` | Props spread on the root element | |
| Prop | Type | Description | Default |
| -------------------- | ---------------------------------------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `align` | `'left', 'right'` | Determines whether the message is aligned to the left or right | if `isSender === true`, the message is aligned to the right, and otherwise to the left. This prop overrides that behavior |
| `avatar` | `ReactElement` | Avatar element | |
| `componentOverrides` | `Record<MarkdownComponent, ComponentType>` | Uses value to override key'ed markdown elements in terms of how they are rendered | |
| `children` | `string` | Rendered children; only string children are supported | |
| `isSender` | `boolean` | Indicates if the message is from the current user | `true` |
| `markdownProps` | `LGMarkdownProps` | Props passed to the internal ReactMarkdown instance | |
| `messageRatingProps` | `MessageRatingProps` | Props to MessageRating component | |
| `sourceType` | `'markdown', 'text'` | Determines the rendering method of the message | |
| `messageBody` | `string` | Message body text passed to LGMarkdown | |
| `verified` | `{ verifier?: string; verifiedAt?: Date; learnMoreUrl?: string; }` | Sets if an answer is "verified" and controls the content of the message banner. | |
| `links` | `{ url: string; text: string; imageUrl?: string; variant: string; }[]` | A list of links to show in a section at the end of the message. | |
| `linksHeading` | `string` | The heading text to display for the links section. | "Related Resources" |
| `...` | `HTMLElementProps<'div'>` | Props spread on the root element | |

### Message Links

The message component includes the following built-in `variant` values for the `links` prop:

- `"Blog"`
- `"Book"`
- `"Code"`
- `"Docs"`
- `"Learn"`
- `"Video"`
- `"Website"`

These map to pre-defined badge glyphs, labels, and colors for specific use
cases. If no variant serves your use case, you can create a custom link by
omitting the `variant` prop and defining the `badgeGlyph`, `badgeLabel`, and
optionally `badgeVariant` props.
3 changes: 2 additions & 1 deletion chat/message/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"@leafygreen-ui/polymorphic": "^1.3.7",
"@leafygreen-ui/tokens": "^2.5.2",
"@leafygreen-ui/typography": "^19.0.0",
"@lg-chat/lg-markdown": "^2.0.2"
"@lg-chat/lg-markdown": "^2.0.2",
"@lg-chat/rich-links": "^0.1.0"
},
"devDependencies": {
"@lg-chat/avatar": "^3.0.1",
Expand Down
153 changes: 100 additions & 53 deletions chat/message/src/Message/Message.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { WithMessageRating as MessageFeedbackStory } from '@lg-chat/message-feed
import { storybookArgTypes, StoryMetaType } from '@lg-tools/storybook-utils';
import { StoryFn } from '@storybook/react';

import { useUpdatedBaseFontSize } from '@leafygreen-ui/typography';

import { Message, MessageSourceType } from '..';

const MarkdownText = `
Expand Down Expand Up @@ -42,25 +44,24 @@ function helloWorld() {
const UserText = `How can I delete a massive amount of documents from a collection?`;

const MongoText = `
To efficiently delete a large number of documents from a MongoDB collection, you
can use the \`deleteMany()\` method. This method allows you to delete multiple
documents that match a specified filter.
To efficiently delete a large number of documents from a MongoDB collection, you can use the \`deleteMany()\` method. This method allows you to delete multiple documents that match a specified filter.
Here's an example of how to use the \`deleteMany()\` method to delete a large
number of documents:
Here's an example of how to use the \`deleteMany()\` method to delete a large number of documents:
\`\`\`javascript
db.collection.deleteMany({ <filter> });
\`\`\`
Keep in mind that deleting a large number of documents can be resource-intensive
and may impact the performance of your MongoDB server. It's recommended to
perform such operations during periods of low activity or to use techniques like
sharding to distribute the load across multiple servers.
Keep in mind that deleting a large number of documents can be resource-intensive and may impact the performance of your MongoDB server. It's recommended to perform such operations during periods of low activity or to use techniques like sharding to distribute the load across multiple servers.
Let me know if you need any further assistance!
`;

const MessageFeedback = () => {
// @ts-ignore onChange is passed in the story itself
return <MessageFeedbackStory />;
};

const meta: StoryMetaType<typeof Message> = {
title: 'Chat/Message',
component: Message,
Expand All @@ -82,10 +83,8 @@ const meta: StoryMetaType<typeof Message> = {
};
export default meta;

// eslint-disable-next-line react/prop-types
const Template: StoryFn<typeof Message> = ({ darkMode, avatar, ...rest }) => {
const Avatar = avatar ? React.cloneElement(avatar, { darkMode }) : undefined;
return <Message avatar={Avatar} darkMode={darkMode} {...rest} />;
const Template: StoryFn<typeof Message> = props => {
return <Message {...props}></Message>;
};

export const Basic: StoryFn<typeof Message> = Template.bind({});
Expand Down Expand Up @@ -117,8 +116,7 @@ WithMessageRating.args = {
isSender: false,
messageBody: MongoText,
avatar: <Avatar variant="mongo" />,
// @ts-ignore onChange is passed in the story itself
children: <MessageFeedbackStory />,
children: <MessageFeedback />,
};

export const VerifiedAnswer: StoryFn<typeof Message> = Template.bind({});
Expand All @@ -130,43 +128,92 @@ VerifiedAnswer.args = {
verifier: 'MongoDB Staff',
verifiedAt: new Date('2023-08-24T16:20:00Z'),
},
// @ts-ignore onChange is passed in the story itself
children: <MessageFeedbackStory />,
children: <MessageFeedback />,
};

export const MultipleUser = () => {
const baseFontSize = useUpdatedBaseFontSize();
return (
<LeafyGreenChatProvider>
<div>
<Basic {...meta.args} {...Basic.args} baseFontSize={baseFontSize} />
<Basic
{...meta.args}
{...Basic.args}
messageBody="Another message!"
baseFontSize={baseFontSize}
/>
</div>
</LeafyGreenChatProvider>
);
};

export const MultipleUser = () => (
<LeafyGreenChatProvider>
<div>
{/* @ts-expect-error baseFontSize is not a number */}
<Basic {...meta.args} {...Basic.args} />
{/* @ts-expect-error baseFontSize is not a number */}
<Basic {...meta.args} {...Basic.args} messageBody="Another message!" />
</div>
</LeafyGreenChatProvider>
);

export const MultipleMongo = () => (
<LeafyGreenChatProvider>
<div>
{/* @ts-expect-error baseFontSize is not a number */}
<Mongo
{...meta.args}
{...Mongo.args}
messageBody="First message! Expect another from me right after this one."
/>
{/* @ts-expect-error baseFontSize is not a number */}
<Mongo {...meta.args} {...Mongo.args} />
</div>
</LeafyGreenChatProvider>
);

export const Alternating = () => (
<LeafyGreenChatProvider>
<div>
{/* @ts-expect-error baseFontSize is not a number */}
<Basic {...meta.args} {...Basic.args} />
{/* @ts-expect-error baseFontSize is not a number */}
<Mongo {...meta.args} {...Mongo.args} />
</div>
</LeafyGreenChatProvider>
);
export const MultipleMongo = () => {
const baseFontSize = useUpdatedBaseFontSize();
return (
<LeafyGreenChatProvider>
<div>
<Mongo
{...meta.args}
{...Mongo.args}
messageBody="First message! Expect another from me right after this one."
baseFontSize={baseFontSize}
/>
<Mongo {...meta.args} {...Mongo.args} baseFontSize={baseFontSize} />
</div>
</LeafyGreenChatProvider>
);
};

export const Alternating = () => {
const baseFontSize = useUpdatedBaseFontSize();
return (
<LeafyGreenChatProvider>
<div>
<Basic {...meta.args} {...Basic.args} baseFontSize={baseFontSize} />
<Mongo {...meta.args} {...Mongo.args} baseFontSize={baseFontSize} />
</div>
</LeafyGreenChatProvider>
);
};

export const WithRichLinks: StoryFn<typeof Message> = Template.bind({});
WithRichLinks.args = {
isSender: false,
messageBody: MongoText,
avatar: <Avatar variant="mongo" />,
children: <MessageFeedback />,
links: [
{
href: 'https://mongodb.design',
children: 'LeafyGreen UI',
variant: 'Website',
},
{
href: 'https://mongodb.github.io/leafygreen-ui/?path=/docs/overview-introduction--docs',
children: 'LeafyGreen UI Docs',
variant: 'Docs',
},
{
href: 'https://learn.mongodb.com/',
children: 'MongoDB University',
variant: 'Learn',
},
{
href: 'https://mongodb.com/docs',
children: 'MongoDB Docs',
variant: 'Docs',
},
{
href: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
children: 'Rick Astley - Never Gonna Give You Up',
variant: 'Video',
imageUrl: 'https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg',
},
{
href: 'https://mongodb.com/',
children: 'MongoDB Homepage',
variant: 'Website',
},
],
};
2 changes: 1 addition & 1 deletion chat/message/src/Message/Message.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const avatarClassName = createUniqueClassName('lg-message-avatar');

export const baseStyles = css`
display: flex;
gap: ${spacing[2]}px;
gap: ${spacing[200]}px;
align-items: flex-end;
width: 100%;
Expand Down
10 changes: 10 additions & 0 deletions chat/message/src/Message/Message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { BaseFontSize, breakpoints } from '@leafygreen-ui/tokens';
import { VerifiedAnswerBanner } from '../MessageBanner';
import { MessageContainer, Variant } from '../MessageContainer';
import { MessageContent } from '../MessageContent';
import { MessageLinks } from '../MessageLinks';

import {
avatarClassName,
Expand Down Expand Up @@ -46,6 +47,8 @@ export const Message = forwardRef(
className,
children,
componentOverrides,
links,
linksHeading,
markdownProps,
verified,
darkMode: darkModeProp,
Expand Down Expand Up @@ -136,6 +139,13 @@ export const Message = forwardRef(
>
{messageBody ?? ''}
</Polymorph>
{links ? (
<Polymorph
as={componentOverrides?.MessageLinks ?? MessageLinks}
headingText={linksHeading}
links={links}
/>
) : null}
{children}
</Polymorph>
</div>
Expand Down
19 changes: 16 additions & 3 deletions chat/message/src/Message/Message.types.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { ReactElement } from 'react';
import { type RichLinkProps } from '@lg-chat/rich-links';

import { DarkModeProps, HTMLElementProps } from '@leafygreen-ui/lib';
import { type DarkModeProps, type HTMLElementProps } from '@leafygreen-ui/lib';
import { BaseFontSize } from '@leafygreen-ui/tokens';

import { MessageContainerProps } from '../MessageContainer';
import { MessageContentProps } from '../MessageContent';
import { type MessageContainerProps } from '../MessageContainer';
import { type MessageContentProps } from '../MessageContent';
import { type MessageLinksProps } from '../MessageLinks';

export const Align = {
Right: 'right',
Expand All @@ -16,6 +18,7 @@ export type Align = (typeof Align)[keyof typeof Align];
export interface ComponentOverrides {
MessageContainer?: (props: MessageContainerProps) => JSX.Element;
MessageContent?: (props: MessageContentProps) => JSX.Element;
MessageLinks?: (props: MessageLinksProps) => JSX.Element;
}

export interface MessageProps
Expand Down Expand Up @@ -57,6 +60,16 @@ export interface MessageProps
* displays information about the message.
*/
verified?: VerificationInfo;

/**
* A list of links to render as rich links for the message.
*/
links?: Array<RichLinkProps>;

/**
* The heading text to display for the links section.
*/
linksHeading?: string;
}

export interface VerificationInfo {
Expand Down
4 changes: 4 additions & 0 deletions chat/message/src/MessageContainer/MessageContainer.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export const baseStyles = css`
box-shadow: 0px 4px 10px -4px ${palette.black}4D; // 4D is 30% opacity
position: relative;
display: flex;
flex-direction: column;
gap: ${spacing[200]}px;
`;

export const variantStyles: Record<Variant, Record<Theme, string>> = {
Expand Down
Loading

0 comments on commit c14b392

Please sign in to comment.