Skip to content

Commit

Permalink
Merge pull request #403 from rebeccaalpert/quick-response-color
Browse files Browse the repository at this point in the history
feat(QuickResponse): Add active and selected states
  • Loading branch information
nicolethoen authored Jan 10, 2025
2 parents fd79b8d + 99372a4 commit 1bc43c2
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ You can apply a `clickedAriaLabel` and `clickedTooltipContent` once a button is

### Messages with quick responses

You can offer convenient, clickable responses to messages in the form of quick actions. Quick actions are [PatternFly labels](/components/label/) in a label group, configured to display up to 5 visible labels.
You can offer convenient, clickable responses to messages in the form of quick actions. Quick actions are [PatternFly labels](/components/label/) in a label group, configured to display up to 5 visible labels. Only 1 response can be selected at a time.

To add quick actions, pass `quickResponses` to `<Message>`. This can be overridden by passing additional `<LabelGroup>` props to `quickResponseContainerProps`, or additional `<Label>` props to `quickResponses`.

Expand Down
14 changes: 0 additions & 14 deletions packages/module/src/Message/Message.scss
Original file line number Diff line number Diff line change
Expand Up @@ -95,20 +95,6 @@
display: grid;
gap: var(--pf-t--global--spacer--sm);
}

&-quick-response {
.pf-v6-c-label {
--pf-v6-c-label--FontSize: var(--pf-t--global--font--size--md);

@media screen and (min-width: 401px) and (max-width: 600px) {
--pf-v6-c-label__text--MaxWidth: 20ch;
}

@media screen and (max-width: 400px) {
--pf-v6-c-label__text--MaxWidth: 15ch;
}
}
}
}

// Attachments
Expand Down
32 changes: 7 additions & 25 deletions packages/module/src/Message/Message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,7 @@ import React from 'react';

import Markdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import {
Avatar,
AvatarProps,
Label,
LabelGroup,
LabelGroupProps,
LabelProps,
Timestamp,
Truncate
} from '@patternfly/react-core';
import { Avatar, AvatarProps, Label, LabelGroupProps, Timestamp, Truncate } from '@patternfly/react-core';
import MessageLoading from './MessageLoading';
import CodeBlockMessage from './CodeBlockMessage/CodeBlockMessage';
import TextMessage from './TextMessage/TextMessage';
Expand All @@ -27,12 +18,8 @@ import UnorderedListMessage from './ListMessage/UnorderedListMessage';
import OrderedListMessage from './ListMessage/OrderedListMessage';
import QuickStartTile from './QuickStarts/QuickStartTile';
import { QuickStart, QuickstartAction } from './QuickStarts/types';
import QuickResponse from './QuickResponse/QuickResponse';

export interface QuickResponse extends Omit<LabelProps, 'children'> {
content: string;
id: string;
onClick: () => void;
}
export interface MessageAttachment {
/** Name of file attached to the message */
name: string;
Expand Down Expand Up @@ -135,6 +122,7 @@ export const Message: React.FunctionComponent<MessageProps> = ({
// Keep timestamps consistent between Timestamp component and aria-label
const date = new Date();
const dateString = timestamp ?? `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;

return (
<section
aria-label={`Message from ${role} - ${dateString}`}
Expand Down Expand Up @@ -194,16 +182,10 @@ export const Message: React.FunctionComponent<MessageProps> = ({
)}
{!isLoading && actions && <ResponseActions actions={actions} />}
{!isLoading && quickResponses && (
<LabelGroup
className={`pf-chatbot__message-quick-response ${quickResponseContainerProps?.className}`}
{...quickResponseContainerProps}
>
{quickResponses.map(({ id, onClick, content, ...props }: QuickResponse) => (
<Label variant="outline" color="blue" key={id} onClick={onClick} {...props}>
{content}
</Label>
))}
</LabelGroup>
<QuickResponse
quickResponses={quickResponses}
quickResponseContainerProps={quickResponseContainerProps}
/>
)}
</div>
{attachments && (
Expand Down
33 changes: 33 additions & 0 deletions packages/module/src/Message/QuickResponse/QuickResponse.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
.pf-chatbot__message-quick-response {
.pf-v6-c-label {
--pf-v6-c-label--FontSize: var(--pf-t--global--font--size--md);

@media screen and (min-width: 401px) and (max-width: 600px) {
--pf-v6-c-label__text--MaxWidth: 20ch;
}

@media screen and (max-width: 400px) {
--pf-v6-c-label__text--MaxWidth: 15ch;
}
}

.pf-chatbot__message-quick-response--selected {
.pf-v6-c-label__content:is(:hover, :focus) {
--pf-v6-c-label--m-clickable--hover--BorderWidth: 0;
--pf-v6-c-label--BackgroundColor: var(--pf-v6-c-label--m-blue--BackgroundColor);
}
}

.pf-chatbot__message-quick-response--selected:hover,
.pf-chatbot__message-quick-response--selected:focus {
--pf-v6-c-label--m-clickable--hover--BorderWidth: 0;
--pf-v6-c-label--BackgroundColor: var(--pf-v6-c-label--m-blue--BackgroundColor);
}

// active state right before selection
.pf-v6-c-label.pf-m-blue.pf-m-clickable .pf-v6-c-label__content:is(:active) {
--pf-v6-c-label--BackgroundColor: var(--pf-v6-c-label--m-blue--BackgroundColor);
--pf-v6-c-label--m-clickable--hover--BackgroundColor: var(--pf-v6-c-label--m-blue--BackgroundColor);
--pf-v6-c-label--m-clickable--hover--BorderWidth: 0;
}
}
50 changes: 50 additions & 0 deletions packages/module/src/Message/QuickResponse/QuickResponse.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from 'react';
import { Label, LabelGroup, LabelGroupProps, LabelProps } from '@patternfly/react-core';
import { CheckIcon } from '@patternfly/react-icons';

export interface QuickResponse extends Omit<LabelProps, 'children'> {
content: string;
id: string;
onClick: () => void;
}

export interface QuickResponseProps {
/** Props for quick responses */
quickResponses: QuickResponse[];
/** Props for quick responses container */
quickResponseContainerProps?: Omit<LabelGroupProps, 'ref'>;
}

export const QuickResponse: React.FunctionComponent<QuickResponseProps> = ({
quickResponses,
quickResponseContainerProps = { numLabels: 5 }
}: QuickResponseProps) => {
const [selectedQuickResponse, setSelectedQuickResponse] = React.useState<string>();

const handleQuickResponseClick = (id: string, onClick?: () => void) => {
setSelectedQuickResponse(id);
onClick && onClick();
};
return (
<LabelGroup
className={`pf-chatbot__message-quick-response ${quickResponseContainerProps?.className}`}
{...quickResponseContainerProps}
>
{quickResponses.map(({ id, onClick, content, className, ...props }: QuickResponse) => (
<Label
variant={id === selectedQuickResponse ? undefined : 'outline'}
icon={id === selectedQuickResponse ? <CheckIcon /> : undefined}
color="blue"
key={id}
onClick={() => handleQuickResponseClick(id, onClick)}
className={`${id === selectedQuickResponse ? 'pf-chatbot__message-quick-response--selected' : ''} ${className ? className : ''}`}
{...props}
>
{content}
</Label>
))}
</LabelGroup>
);
};

export default QuickResponse;
1 change: 1 addition & 0 deletions packages/module/src/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
@import './Message/ListMessage/ListMessage';
@import './Message/MessageLoading';
@import './Message/QuickStarts/QuickStartTile';
@import './Message/QuickResponse/QuickResponse';
@import './MessageBar/MessageBar';
@import './MessageBox/MessageBox';
@import './MessageBox/JumpButton';
Expand Down

0 comments on commit 1bc43c2

Please sign in to comment.