Skip to content

Commit e5ed15e

Browse files
authored
Merge pull request #524 from rebeccaalpert/modal-compact
feat(Modals): Add compact variants
2 parents 554104c + d59e1e5 commit e5ed15e

13 files changed

Lines changed: 153 additions & 17 deletions

File tree

packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/AttachmentEdit.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
import React from 'react';
2-
import { Button } from '@patternfly/react-core';
2+
import { Button, Checkbox } from '@patternfly/react-core';
33
import { AttachmentEdit } from '@patternfly/chatbot/dist/dynamic/AttachmentEdit';
44

55
export const AttachmentEditModalExample: React.FunctionComponent = () => {
66
const [isModalOpen, setIsModalOpen] = React.useState(false);
7+
const [isCompact, setIsCompact] = React.useState(false);
78

89
const handleModalToggle = (_event: React.MouseEvent | MouseEvent | KeyboardEvent) => {
910
setIsModalOpen(!isModalOpen);
1011
};
1112

1213
return (
1314
<>
15+
<Checkbox
16+
label="Show compact version"
17+
isChecked={isCompact}
18+
onChange={() => setIsCompact(!isCompact)}
19+
id="modal-compact-edit"
20+
name="modal-compact-edit"
21+
></Checkbox>
1422
<Button onClick={handleModalToggle}>Launch modal</Button>
1523
<AttachmentEdit
1624
code="I am a code snippet"
@@ -20,6 +28,7 @@ export const AttachmentEditModalExample: React.FunctionComponent = () => {
2028
onCancel={() => null}
2129
// eslint-disable-next-line no-console
2230
onSave={(_event, code) => console.log(`The new code is "${code}"`)}
31+
isCompact={isCompact}
2332
/>
2433
</>
2534
);

packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/PreviewAttachment.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
import React from 'react';
2-
import { Button } from '@patternfly/react-core';
2+
import { Button, Checkbox } from '@patternfly/react-core';
33
import { PreviewAttachment } from '@patternfly/chatbot/dist/dynamic/PreviewAttachment';
44

55
export const PreviewAttachmentExample: React.FunctionComponent = () => {
66
const [isModalOpen, setIsModalOpen] = React.useState(false);
7+
const [isCompact, setIsCompact] = React.useState(false);
78

89
const handleModalToggle = (_event: React.MouseEvent | MouseEvent | KeyboardEvent) => {
910
setIsModalOpen(!isModalOpen);
1011
};
1112

1213
return (
1314
<>
15+
<Checkbox
16+
label="Show compact version"
17+
isChecked={isCompact}
18+
onChange={() => setIsCompact(!isCompact)}
19+
id="modal-compact-preview"
20+
name="modal-compact-preview"
21+
></Checkbox>
1422
<Button onClick={handleModalToggle}>Launch modal</Button>
1523
<PreviewAttachment
1624
code="I am a code snippet"
@@ -19,6 +27,7 @@ export const PreviewAttachmentExample: React.FunctionComponent = () => {
1927
isModalOpen={isModalOpen}
2028
onDismiss={() => null}
2129
onEdit={() => null}
30+
isCompact={isCompact}
2231
/>
2332
</>
2433
);

packages/module/src/AttachmentEdit/AttachmentEdit.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ export interface AttachmentEditProps {
2222
title?: string;
2323
/** Display mode for the Chatbot parent; this influences the styles applied */
2424
displayMode?: ChatbotDisplayMode;
25+
/** Sets modal to compact styling. */
26+
isCompact?: boolean;
2527
}
2628

2729
export const AttachmentEdit: React.FunctionComponent<AttachmentEditProps> = ({
@@ -32,7 +34,8 @@ export const AttachmentEdit: React.FunctionComponent<AttachmentEditProps> = ({
3234
onCancel,
3335
onSave,
3436
title = 'Edit attachment',
35-
displayMode = ChatbotDisplayMode.default
37+
displayMode = ChatbotDisplayMode.default,
38+
isCompact
3639
}: AttachmentEditProps) => {
3740
const handleSave = (_event: React.MouseEvent | MouseEvent | KeyboardEvent, code) => {
3841
handleModalToggle(_event);
@@ -56,6 +59,7 @@ export const AttachmentEdit: React.FunctionComponent<AttachmentEditProps> = ({
5659
secondaryActionBtn="Cancel"
5760
title={title}
5861
displayMode={displayMode}
62+
isCompact={isCompact}
5963
/>
6064
);
6165
};

packages/module/src/ChatbotModal/ChatbotModal.scss

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@
1414
.pf-v6-c-modal-box__title {
1515
--pf-v6-c-modal-box__title--FontSize: var(--pf-t--global--font--size--heading--h3);
1616
}
17-
.pf-v6-c-button.pf-m-primary.pf-m-block,
18-
.pf-v6-c-button.pf-m-link.pf-m-block {
19-
--pf-v6-c-button--FontWeight: var(--pf-t--global--font--weight--body--bold);
20-
}
17+
2118
.pf-v6-c-modal-box__footer {
2219
padding-block-start: var(--pf-t--global--spacer--xl);
2320
padding-block-end: var(--pf-t--global--spacer--xl);
@@ -91,3 +88,17 @@
9188
.pf-v6-c-backdrop.pf-chatbot__backdrop {
9289
position: absolute;
9390
}
91+
92+
// ============================================================================
93+
// Compact
94+
// ============================================================================
95+
.pf-chatbot__chatbot-modal.pf-m-compact {
96+
.pf-v6-c-modal-box__header {
97+
padding-block-end: 0;
98+
}
99+
100+
.pf-v6-c-modal-box__footer {
101+
padding-block-start: var(--pf-t--global--spacer--lg);
102+
padding-block-end: var(--pf-t--global--spacer--lg);
103+
}
104+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import React from 'react';
2+
import { render, screen } from '@testing-library/react';
3+
import ChatbotModal from './ChatbotModal';
4+
import '@testing-library/jest-dom';
5+
import { ModalBody, ModalHeader } from '@patternfly/react-core';
6+
7+
describe('ChatbotModal', () => {
8+
it('should render compact modal', () => {
9+
render(
10+
<ChatbotModal data-testid="modal" isCompact isOpen>
11+
<ModalHeader
12+
title="Modal with description"
13+
labelId="modal-with-description-title"
14+
description="A description is used when you want to provide more info about the modal than the title is able to describe. The content in the description is static and will not scroll with the rest of the modal body."
15+
/>
16+
<ModalBody tabIndex={0} id="modal-box-body-with-description">
17+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
18+
magna aliqua. Quis eleifend quam adipiscing vitae proin sagittis nisl rhoncus. Semper auctor neque vitae
19+
tempus. Diam donec adipiscing tristique risus. Augue eget arcu dictum varius duis. Ut enim blandit volutpat
20+
maecenas volutpat blandit aliquam. Sit amet mauris commodo quis imperdiet massa tincidunt. Habitant morbi
21+
tristique senectus et netus. Fames ac turpis egestas sed tempus urna. Neque laoreet suspendisse interdum
22+
consectetur libero id. Volutpat lacus laoreet non curabitur gravida arcu ac tortor. Porta nibh venenatis cras
23+
sed felis eget velit. Nullam non nisi est sit amet facilisis. Nunc mi ipsum faucibus vitae. Lorem sed risus
24+
ultricies tristique nulla aliquet enim tortor at. Egestas sed tempus urna et pharetra pharetra massa massa
25+
ultricies. Lacinia quis vel eros donec ac odio tempor orci. Malesuada fames ac turpis egestas integer eget
26+
aliquet.
27+
<br />
28+
<br />
29+
Neque aliquam vestibulum morbi blandit cursus risus at ultrices. Molestie at elementum eu facilisis sed odio
30+
morbi. Elit pellentesque habitant morbi tristique. Consequat nisl vel pretium lectus quam id leo in vitae.
31+
Quis varius quam quisque id diam vel quam elementum. Viverra nam libero justo laoreet sit amet cursus.
32+
Sollicitudin tempor id eu nisl nunc. Orci nulla pellentesque dignissim enim sit amet venenatis. Dignissim enim
33+
sit amet venenatis urna cursus eget. Iaculis at erat pellentesque adipiscing commodo elit. Faucibus pulvinar
34+
elementum integer enim neque volutpat. Nullam vehicula ipsum a arcu cursus vitae congue mauris. Nunc mattis
35+
enim ut tellus elementum sagittis vitae. Blandit cursus risus at ultrices. Tellus mauris a diam maecenas sed
36+
enim. Non diam phasellus vestibulum lorem sed risus ultricies tristique nulla.
37+
<br />
38+
<br />
39+
Nulla pharetra diam sit amet nisl suscipit adipiscing. Ac tortor vitae purus faucibus ornare suspendisse sed
40+
nisi. Sed felis eget velit aliquet sagittis id consectetur purus. Tincidunt tortor aliquam nulla facilisi cras
41+
fermentum. Volutpat est velit egestas dui id ornare arcu odio. Pharetra magna ac placerat vestibulum. Ultrices
42+
sagittis orci a scelerisque purus semper eget duis at. Nisi est sit amet facilisis magna etiam tempor orci eu.
43+
Convallis tellus id interdum velit. Facilisis sed odio morbi quis commodo odio aenean sed.
44+
<br />
45+
<br />
46+
Eu scelerisque felis imperdiet proin fermentum leo vel orci porta. Facilisi etiam dignissim diam quis enim
47+
lobortis scelerisque fermentum. Eleifend donec pretium vulputate sapien nec sagittis aliquam malesuada. Magna
48+
etiam tempor orci eu lobortis elementum. Quis auctor elit sed vulputate mi sit. Eleifend quam adipiscing vitae
49+
proin sagittis nisl rhoncus mattis rhoncus. Erat velit scelerisque in dictum non. Sit amet nulla facilisi
50+
morbi tempus iaculis urna. Enim ut tellus elementum sagittis vitae et leo duis ut. Lectus arcu bibendum at
51+
varius vel pharetra vel turpis. Morbi tristique senectus et netus et. Eget aliquet nibh praesent tristique
52+
magna sit amet purus gravida. Nisl purus in mollis nunc sed id semper risus. Id neque aliquam vestibulum
53+
morbi. Mauris a diam maecenas sed enim ut sem. Egestas tellus rutrum tellus pellentesque.
54+
</ModalBody>
55+
</ChatbotModal>
56+
);
57+
expect(screen.getByTestId('modal')).toHaveClass('pf-m-compact');
58+
});
59+
});

packages/module/src/ChatbotModal/ChatbotModal.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,18 @@ import { ChatbotDisplayMode } from '../Chatbot';
1010
export interface ChatbotModalProps extends Omit<ModalProps, 'ref'> {
1111
/** Display mode for the Chatbot parent; this influences the styles applied */
1212
displayMode?: ChatbotDisplayMode;
13+
/** Additional className applied to modal */
1314
className?: string;
15+
/** Sets modal to compact styling. */
16+
isCompact?: boolean;
1417
}
1518

1619
export const ChatbotModal: React.FunctionComponent<ChatbotModalProps> = ({
1720
children,
1821
displayMode = ChatbotDisplayMode.default,
1922
className,
2023
isOpen,
24+
isCompact,
2125
...props
2226
}: ChatbotModalProps) => {
2327
const modal = (
@@ -26,7 +30,7 @@ export const ChatbotModal: React.FunctionComponent<ChatbotModalProps> = ({
2630
ouiaId="ChatbotModal"
2731
aria-labelledby="chatbot-modal-title"
2832
aria-describedby="chatbot-modal"
29-
className={`pf-chatbot__chatbot-modal pf-chatbot__chatbot-modal--${displayMode} ${className}`}
33+
className={`pf-chatbot__chatbot-modal pf-chatbot__chatbot-modal--${displayMode} ${isCompact ? 'pf-m-compact' : ''} ${className}`}
3034
backdropClassName="pf-chatbot__chatbot-modal-backdrop"
3135
{...props}
3236
>

packages/module/src/CodeModal/CodeModal.scss

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,10 @@
6161
.pf-v6-c-code-editor__header-main {
6262
display: none;
6363
}
64-
.pf-chatbot__code-modal-file-details {
65-
padding-inline-start: var(--pf-t--global--spacer--md);
64+
.pf-v6-c-modal-box__close {
65+
.pf-v6-c-button.pf-m-plain {
66+
--pf-v6-c-button__icon--Color: var(--pf-t--global--icon--color--subtle);
67+
}
6668
}
6769
}
6870

@@ -78,10 +80,16 @@
7880
}
7981
}
8082

81-
.pf-chatbot__code-modal-body {
83+
.pf-chatbot__code-modal-editor {
8284
flex: 1;
8385
}
8486

8587
.pf-chatbot__code-modal--fullscreen {
8688
height: inherit !important; // override shared modal so code editor works in full screen
8789
}
90+
91+
.pf-chatbot__code-modal.pf-m-compact {
92+
.pf-chatbot__code-modal-body {
93+
gap: var(--pf-t--global--spacer--md);
94+
}
95+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import React from 'react';
2+
import { render, screen } from '@testing-library/react';
3+
import '@testing-library/jest-dom';
4+
import CodeModal from './CodeModal';
5+
6+
describe('ChatbotModal', () => {
7+
it('should render compact modal', () => {
8+
render(
9+
<CodeModal
10+
isCompact
11+
code="Hello world"
12+
fileName="greetings.txt"
13+
isModalOpen={true}
14+
handleModalToggle={jest.fn()}
15+
onPrimaryAction={jest.fn()}
16+
onSecondaryAction={jest.fn()}
17+
title="Preview attachment"
18+
primaryActionBtn="Submit"
19+
secondaryActionBtn="Cancel"
20+
></CodeModal>
21+
);
22+
expect(screen.getByRole('dialog')).toHaveClass('pf-m-compact');
23+
});
24+
});

packages/module/src/CodeModal/CodeModal.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ export interface CodeModalProps {
4040
title: string;
4141
/** Display mode for the Chatbot parent; this influences the styles applied */
4242
displayMode?: ChatbotDisplayMode;
43+
/** Sets modal to compact styling. */
44+
isCompact?: boolean;
4345
}
4446

4547
export const CodeModal: React.FunctionComponent<CodeModalProps> = ({
@@ -57,6 +59,7 @@ export const CodeModal: React.FunctionComponent<CodeModalProps> = ({
5759
secondaryActionBtn,
5860
title,
5961
displayMode = ChatbotDisplayMode.default,
62+
isCompact,
6063
...props
6164
}: CodeModalProps) => {
6265
const [newCode, setNewCode] = React.useState(code);
@@ -94,16 +97,17 @@ export const CodeModal: React.FunctionComponent<CodeModalProps> = ({
9497
ouiaId="CodeModal"
9598
aria-labelledby="code-modal-title"
9699
aria-describedby="code-modal"
97-
className={`pf-chatbot__code-modal pf-chatbot__code-modal--${displayMode}`}
100+
className={`pf-chatbot__code-modal ${isCompact ? 'pf-m-compact' : ''} pf-chatbot__code-modal--${displayMode}`}
98101
displayMode={displayMode}
102+
isCompact={isCompact}
99103
>
100104
<ModalHeader title={title} labelId="code-modal-title" />
101105
<ModalBody id="code-modal-body">
102106
<Stack className="pf-chatbot__code-modal-body">
103107
<StackItem className="pf-chatbot__code-modal-file-details">
104108
<FileDetails fileName={fileName} />
105109
</StackItem>
106-
<StackItem className="pf-chatbot__code-modal-body">
110+
<StackItem className="pf-chatbot__code-modal-editor">
107111
<CodeEditor
108112
isDarkTheme
109113
isLineNumbersVisible={isLineNumbersVisible}

packages/module/src/FileDetails/FileDetails.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -946,7 +946,7 @@ export const FileDetails = ({
946946
}: PropsWithChildren<FileDetailsProps>) => {
947947
const language = extensionToLanguage[path.extname(fileName).slice(1)]?.toUpperCase();
948948
return (
949-
<Flex className={`pf-chatbot__file-details ${className}`} gap={{ default: 'gapSm' }}>
949+
<Flex className={`pf-chatbot__file-details ${className ? className : ''}`} gap={{ default: 'gapSm' }}>
950950
<Flex
951951
className="pf-chatbot__code-icon"
952952
justifyContent={{ default: 'justifyContentCenter' }}

0 commit comments

Comments
 (0)