@patternfly/react-code-editor 6.0.0-alpha.5 → 6.0.0-alpha.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +550 -0
- package/README.md +20 -24
- package/dist/esm/components/CodeEditor/CodeEditor.d.ts +7 -1
- package/dist/esm/components/CodeEditor/CodeEditor.d.ts.map +1 -1
- package/dist/esm/components/CodeEditor/CodeEditor.js +23 -17
- package/dist/esm/components/CodeEditor/CodeEditor.js.map +1 -1
- package/dist/esm/components/CodeEditor/CodeEditorControl.js +1 -1
- package/dist/esm/components/CodeEditor/CodeEditorControl.js.map +1 -1
- package/dist/js/components/CodeEditor/CodeEditor.d.ts +7 -1
- package/dist/js/components/CodeEditor/CodeEditor.d.ts.map +1 -1
- package/dist/js/components/CodeEditor/CodeEditor.js +22 -16
- package/dist/js/components/CodeEditor/CodeEditor.js.map +1 -1
- package/dist/js/components/CodeEditor/CodeEditorControl.js +1 -1
- package/dist/js/components/CodeEditor/CodeEditorControl.js.map +1 -1
- package/package.json +7 -7
- package/src/components/CodeEditor/CodeEditor.tsx +76 -64
- package/src/components/CodeEditor/CodeEditorControl.tsx +1 -1
- package/src/components/CodeEditor/__test__/CodeEditor.test.tsx +69 -39
- package/src/components/CodeEditor/__test__/CodeEditorControl.test.tsx +18 -0
- package/src/components/CodeEditor/__test__/__snapshots__/CodeEditor.test.tsx.snap +104 -536
- package/src/components/CodeEditor/__test__/__snapshots__/CodeEditorControl.test.tsx.snap +22 -0
- package/src/components/CodeEditor/examples/CodeEditor.md +5 -0
- package/src/components/CodeEditor/examples/CodeEditorCustomControl.tsx +2 -1
- package/src/components/CodeEditor/examples/CodeEditorShortcutMainHeader.tsx +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-code-editor",
|
|
3
|
-
"version": "6.0.0-alpha.
|
|
3
|
+
"version": "6.0.0-alpha.50",
|
|
4
4
|
"description": "This package provides a PatternFly wrapper for the Monaco code editor\n",
|
|
5
5
|
"main": "dist/js/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -30,20 +30,20 @@
|
|
|
30
30
|
"clean": "rimraf dist"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@
|
|
34
|
-
"@patternfly/react-
|
|
35
|
-
"@patternfly/react-
|
|
33
|
+
"@monaco-editor/react": "^4.6.0",
|
|
34
|
+
"@patternfly/react-core": "^6.0.0-alpha.50",
|
|
35
|
+
"@patternfly/react-icons": "^6.0.0-alpha.19",
|
|
36
|
+
"@patternfly/react-styles": "^6.0.0-alpha.19",
|
|
36
37
|
"react-dropzone": "14.2.3",
|
|
37
38
|
"tslib": "^2.5.0"
|
|
38
39
|
},
|
|
39
40
|
"peerDependencies": {
|
|
40
41
|
"react": "^17 || ^18",
|
|
41
|
-
"react-dom": "^17 || ^18"
|
|
42
|
-
"react-monaco-editor": "^0.51.0"
|
|
42
|
+
"react-dom": "^17 || ^18"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"rimraf": "^2.6.2",
|
|
46
46
|
"typescript": "^4.7.4"
|
|
47
47
|
},
|
|
48
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "ef6f95d064bfbb8f5aaa134ab6941f63ccf36111"
|
|
49
49
|
}
|
|
@@ -7,17 +7,15 @@ import {
|
|
|
7
7
|
ButtonVariant,
|
|
8
8
|
EmptyState,
|
|
9
9
|
EmptyStateBody,
|
|
10
|
-
EmptyStateIcon,
|
|
11
10
|
EmptyStateActions,
|
|
12
11
|
EmptyStateVariant,
|
|
13
12
|
EmptyStateFooter,
|
|
14
13
|
getResizeObserver,
|
|
15
14
|
Popover,
|
|
16
15
|
PopoverProps,
|
|
17
|
-
TooltipPosition
|
|
18
|
-
EmptyStateHeader
|
|
16
|
+
TooltipPosition
|
|
19
17
|
} from '@patternfly/react-core';
|
|
20
|
-
import
|
|
18
|
+
import Editor, { EditorProps, Monaco } from '@monaco-editor/react';
|
|
21
19
|
import { editor } from 'monaco-editor/esm/vs/editor/editor.api';
|
|
22
20
|
import CopyIcon from '@patternfly/react-icons/dist/esm/icons/copy-icon';
|
|
23
21
|
import UploadIcon from '@patternfly/react-icons/dist/esm/icons/upload-icon';
|
|
@@ -28,6 +26,9 @@ import Dropzone, { FileRejection } from 'react-dropzone';
|
|
|
28
26
|
import { CodeEditorContext } from './CodeEditorUtils';
|
|
29
27
|
import { CodeEditorControl } from './CodeEditorControl';
|
|
30
28
|
|
|
29
|
+
export type ChangeHandler = (value: string, event: editor.IModelContentChangedEvent) => void;
|
|
30
|
+
export type EditorDidMount = (editor: editor.IStandaloneCodeEditor, monaco: Monaco) => void;
|
|
31
|
+
|
|
31
32
|
export interface Shortcut {
|
|
32
33
|
description: string;
|
|
33
34
|
keys: string[];
|
|
@@ -134,6 +135,8 @@ export interface CodeEditorProps extends Omit<React.HTMLProps<HTMLDivElement>, '
|
|
|
134
135
|
downloadButtonToolTipText?: string;
|
|
135
136
|
/** Name of the file if user downloads code to local file. */
|
|
136
137
|
downloadFileName?: string;
|
|
138
|
+
/** Additional props to pass to the monaco editor. */
|
|
139
|
+
editorProps?: EditorProps;
|
|
137
140
|
/** Content to display in space of the code editor when there is no code to display. */
|
|
138
141
|
emptyState?: React.ReactNode;
|
|
139
142
|
/** Override default empty state body text. */
|
|
@@ -154,6 +157,8 @@ export interface CodeEditorProps extends Omit<React.HTMLProps<HTMLDivElement>, '
|
|
|
154
157
|
isCopyEnabled?: boolean;
|
|
155
158
|
/** Flag indicating the editor is styled using monaco's dark theme. */
|
|
156
159
|
isDarkTheme?: boolean;
|
|
160
|
+
/** Flag indicating the editor has a plain header. */
|
|
161
|
+
isHeaderPlain?: boolean;
|
|
157
162
|
/** Flag to add download button to code editor actions. */
|
|
158
163
|
isDownloadEnabled?: boolean;
|
|
159
164
|
/** Flag to include a label indicating the currently configured editor language. */
|
|
@@ -260,6 +265,7 @@ class CodeEditor extends React.Component<CodeEditorProps, CodeEditorState> {
|
|
|
260
265
|
isUploadEnabled: false,
|
|
261
266
|
isDownloadEnabled: false,
|
|
262
267
|
isCopyEnabled: false,
|
|
268
|
+
isHeaderPlain: false,
|
|
263
269
|
copyButtonAriaLabel: 'Copy code to clipboard',
|
|
264
270
|
uploadButtonAriaLabel: 'Upload code',
|
|
265
271
|
downloadButtonAriaLabel: 'Download code',
|
|
@@ -491,12 +497,14 @@ class CodeEditor extends React.Component<CodeEditorProps, CodeEditorState> {
|
|
|
491
497
|
emptyStateLink,
|
|
492
498
|
customControls,
|
|
493
499
|
isMinimapVisible,
|
|
500
|
+
isHeaderPlain,
|
|
494
501
|
headerMainContent,
|
|
495
502
|
shortcutsPopoverButtonText,
|
|
496
503
|
shortcutsPopoverProps: shortcutsPopoverPropsProp,
|
|
497
504
|
showEditor,
|
|
498
505
|
options: optionsProp,
|
|
499
|
-
overrideServices
|
|
506
|
+
overrideServices,
|
|
507
|
+
editorProps
|
|
500
508
|
} = this.props;
|
|
501
509
|
const shortcutsPopoverProps: PopoverProps = {
|
|
502
510
|
...CodeEditor.defaultProps.shortcutsPopoverProps,
|
|
@@ -520,12 +528,7 @@ class CodeEditor extends React.Component<CodeEditorProps, CodeEditorState> {
|
|
|
520
528
|
const emptyState =
|
|
521
529
|
providedEmptyState ||
|
|
522
530
|
(isUploadEnabled ? (
|
|
523
|
-
<EmptyState variant={EmptyStateVariant.sm}>
|
|
524
|
-
<EmptyStateHeader
|
|
525
|
-
titleText={emptyStateTitle}
|
|
526
|
-
icon={<EmptyStateIcon icon={CodeIcon} />}
|
|
527
|
-
headingLevel="h4"
|
|
528
|
-
/>
|
|
531
|
+
<EmptyState variant={EmptyStateVariant.sm} titleText={emptyStateTitle} icon={CodeIcon} headingLevel="h4">
|
|
529
532
|
<EmptyStateBody>{emptyStateBody}</EmptyStateBody>
|
|
530
533
|
{!isReadOnly && (
|
|
531
534
|
<EmptyStateFooter>
|
|
@@ -543,12 +546,7 @@ class CodeEditor extends React.Component<CodeEditorProps, CodeEditorState> {
|
|
|
543
546
|
)}
|
|
544
547
|
</EmptyState>
|
|
545
548
|
) : (
|
|
546
|
-
<EmptyState variant={EmptyStateVariant.sm}>
|
|
547
|
-
<EmptyStateHeader
|
|
548
|
-
titleText={emptyStateTitle}
|
|
549
|
-
icon={<EmptyStateIcon icon={CodeIcon} />}
|
|
550
|
-
headingLevel="h4"
|
|
551
|
-
/>
|
|
549
|
+
<EmptyState variant={EmptyStateVariant.sm} titleText={emptyStateTitle} icon={CodeIcon} headingLevel="h4">
|
|
552
550
|
{!isReadOnly && (
|
|
553
551
|
<EmptyStateFooter>
|
|
554
552
|
<EmptyStateActions>
|
|
@@ -569,45 +567,50 @@ class CodeEditor extends React.Component<CodeEditorProps, CodeEditorState> {
|
|
|
569
567
|
trigger: 'mouseenter focus'
|
|
570
568
|
};
|
|
571
569
|
|
|
572
|
-
const
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
570
|
+
const hasEditorHeaderContent =
|
|
571
|
+
((isCopyEnabled || isDownloadEnabled) && (!showEmptyState || !!value)) ||
|
|
572
|
+
isUploadEnabled ||
|
|
573
|
+
customControls ||
|
|
574
|
+
headerMainContent ||
|
|
575
|
+
!!shortcutsPopoverProps.bodyContent;
|
|
576
|
+
|
|
577
|
+
const editorHeaderContent = (
|
|
578
|
+
<React.Fragment>
|
|
579
|
+
<div className={css(styles.codeEditorControls)}>
|
|
580
|
+
<CodeEditorContext.Provider value={{ code: value }}>
|
|
581
|
+
{isCopyEnabled && (!showEmptyState || !!value) && (
|
|
582
|
+
<CodeEditorControl
|
|
583
|
+
icon={<CopyIcon />}
|
|
584
|
+
aria-label={copyButtonAriaLabel}
|
|
585
|
+
tooltipProps={{
|
|
586
|
+
...tooltipProps,
|
|
587
|
+
'aria-live': 'polite',
|
|
588
|
+
content: <div>{copied ? copyButtonSuccessTooltipText : copyButtonToolTipText}</div>,
|
|
589
|
+
exitDelay: copied ? toolTipCopyExitDelay : toolTipDelay,
|
|
590
|
+
onTooltipHidden: () => this.setState({ copied: false })
|
|
591
|
+
}}
|
|
592
|
+
onClick={this.copyCode}
|
|
593
|
+
/>
|
|
594
|
+
)}
|
|
595
|
+
{isUploadEnabled && (
|
|
596
|
+
<CodeEditorControl
|
|
597
|
+
icon={<UploadIcon />}
|
|
598
|
+
aria-label={uploadButtonAriaLabel}
|
|
599
|
+
tooltipProps={{ content: <div>{uploadButtonToolTipText}</div>, ...tooltipProps }}
|
|
600
|
+
onClick={open}
|
|
601
|
+
/>
|
|
602
|
+
)}
|
|
603
|
+
{isDownloadEnabled && (!showEmptyState || !!value) && (
|
|
604
|
+
<CodeEditorControl
|
|
605
|
+
icon={<DownloadIcon />}
|
|
606
|
+
aria-label={downloadButtonAriaLabel}
|
|
607
|
+
tooltipProps={{ content: <div>{downloadButtonToolTipText}</div>, ...tooltipProps }}
|
|
608
|
+
onClick={this.download}
|
|
609
|
+
/>
|
|
610
|
+
)}
|
|
611
|
+
{customControls && customControls}
|
|
612
|
+
</CodeEditorContext.Provider>
|
|
613
|
+
</div>
|
|
611
614
|
{<div className={css(styles.codeEditorHeaderMain)}>{headerMainContent}</div>}
|
|
612
615
|
{!!shortcutsPopoverProps.bodyContent && (
|
|
613
616
|
<div className={`${styles.codeEditor}__keyboard-shortcuts`}>
|
|
@@ -618,6 +621,14 @@ class CodeEditor extends React.Component<CodeEditorProps, CodeEditorState> {
|
|
|
618
621
|
</Popover>
|
|
619
622
|
</div>
|
|
620
623
|
)}
|
|
624
|
+
</React.Fragment>
|
|
625
|
+
);
|
|
626
|
+
|
|
627
|
+
const editorHeader = (
|
|
628
|
+
<div className={css(styles.codeEditorHeader, isHeaderPlain && styles.modifiers.plain)}>
|
|
629
|
+
{hasEditorHeaderContent && (
|
|
630
|
+
<div className={css(styles.codeEditorHeaderContent)}>{editorHeaderContent}</div>
|
|
631
|
+
)}
|
|
621
632
|
{isLanguageLabelVisible && (
|
|
622
633
|
<div className={css(styles.codeEditorTab)}>
|
|
623
634
|
<span className={css(styles.codeEditorTabIcon)}>
|
|
@@ -631,7 +642,7 @@ class CodeEditor extends React.Component<CodeEditorProps, CodeEditorState> {
|
|
|
631
642
|
|
|
632
643
|
const editor = (
|
|
633
644
|
<div className={css(styles.codeEditorCode)} ref={this.wrapperRef} tabIndex={0} dir="ltr">
|
|
634
|
-
<
|
|
645
|
+
<Editor
|
|
635
646
|
height={height}
|
|
636
647
|
width={width}
|
|
637
648
|
language={language}
|
|
@@ -639,8 +650,9 @@ class CodeEditor extends React.Component<CodeEditorProps, CodeEditorState> {
|
|
|
639
650
|
options={options}
|
|
640
651
|
overrideServices={overrideServices}
|
|
641
652
|
onChange={this.onChange}
|
|
642
|
-
|
|
653
|
+
onMount={this.editorDidMount}
|
|
643
654
|
theme={isDarkTheme ? 'vs-dark' : 'vs-light'}
|
|
655
|
+
{...editorProps}
|
|
644
656
|
/>
|
|
645
657
|
</div>
|
|
646
658
|
);
|
|
@@ -652,14 +664,14 @@ class CodeEditor extends React.Component<CodeEditorProps, CodeEditorState> {
|
|
|
652
664
|
{...getRootProps({
|
|
653
665
|
onClick: (event) => event.stopPropagation() // Prevents clicking TextArea from opening file dialog
|
|
654
666
|
})}
|
|
655
|
-
className={
|
|
656
|
-
isLoading && fileUploadStyles.modifiers.loading
|
|
657
|
-
}`}
|
|
667
|
+
className={css(isLoading && fileUploadStyles.modifiers.loading)}
|
|
658
668
|
>
|
|
659
669
|
{editorHeader}
|
|
660
|
-
<div className={css(styles.codeEditorMain)}>
|
|
661
|
-
<
|
|
662
|
-
|
|
670
|
+
<div className={css(styles.codeEditorMain, isDragActive && styles.modifiers.dragHover)}>
|
|
671
|
+
<div className={css(styles.codeEditorUpload)}>
|
|
672
|
+
<input {...getInputProps()} /* hidden, necessary for react-dropzone */ />
|
|
673
|
+
{(showEmptyState || providedEmptyState) && !value ? emptyState : editor}
|
|
674
|
+
</div>
|
|
663
675
|
</div>
|
|
664
676
|
</div>
|
|
665
677
|
) : (
|
|
@@ -38,7 +38,7 @@ export const CodeEditorControl: React.FunctionComponent<CodeEditorControlProps>
|
|
|
38
38
|
|
|
39
39
|
return isVisible ? (
|
|
40
40
|
<Tooltip {...tooltipProps}>
|
|
41
|
-
<Button className={className} onClick={onCustomClick} variant="
|
|
41
|
+
<Button className={className} onClick={onCustomClick} variant="plain" aria-label={ariaLabel} {...props}>
|
|
42
42
|
{icon}
|
|
43
43
|
</Button>
|
|
44
44
|
</Tooltip>
|
|
@@ -1,46 +1,76 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { render } from '@testing-library/react';
|
|
2
|
+
import { render, screen, act } from '@testing-library/react';
|
|
3
3
|
import { CodeEditor, Language } from '../CodeEditor';
|
|
4
|
+
import styles from '@patternfly/react-styles/css/components/CodeEditor/code-editor';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
writable: true,
|
|
7
|
-
value: jest.fn().mockImplementation((query) => ({
|
|
8
|
-
matches: false,
|
|
9
|
-
media: query,
|
|
10
|
-
onchange: null,
|
|
11
|
-
addListener: jest.fn(), // Deprecated
|
|
12
|
-
removeListener: jest.fn(), // Deprecated
|
|
13
|
-
addEventListener: jest.fn(),
|
|
14
|
-
removeEventListener: jest.fn(),
|
|
15
|
-
dispatchEvent: jest.fn()
|
|
16
|
-
}))
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
describe('CodeEditor', () => {
|
|
20
|
-
beforeAll(() => {
|
|
21
|
-
window.HTMLCanvasElement.prototype.getContext = () => ({}) as any;
|
|
22
|
-
});
|
|
6
|
+
jest.mock('@monaco-editor/react', () => jest.fn(() => <div data-testid="mock-editor"></div>));
|
|
23
7
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
8
|
+
test('Matches snapshot without props', () => {
|
|
9
|
+
const { asFragment } = render(<CodeEditor code="test" />);
|
|
10
|
+
expect(asFragment()).toMatchSnapshot();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('Matches snapshot with control buttons enabled', () => {
|
|
14
|
+
const { asFragment } = render(<CodeEditor isUploadEnabled isDownloadEnabled isCopyEnabled code="test" />);
|
|
15
|
+
expect(asFragment()).toMatchSnapshot();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test(`Renders with default classes ${styles.codeEditor}, ${styles.codeEditorMain}, ${styles.codeEditorCode}`, () => {
|
|
19
|
+
render(<CodeEditor />);
|
|
20
|
+
expect(screen.getByTestId('mock-editor').parentElement).toHaveClass(styles.codeEditorCode);
|
|
21
|
+
expect(screen.getByTestId('mock-editor').parentElement?.parentElement).toHaveClass(styles.codeEditorMain);
|
|
22
|
+
expect(screen.getByTestId('mock-editor').parentElement?.parentElement?.parentElement).toHaveClass(styles.codeEditor);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('Renders custom class when className is passed', () => {
|
|
26
|
+
render(<CodeEditor className="custom" />);
|
|
27
|
+
expect(screen.getByTestId('mock-editor').parentElement?.parentElement?.parentElement).toHaveClass('custom');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test(`Renders with ${styles.modifiers.readOnly} when isReadOnly = true`, () => {
|
|
31
|
+
render(<CodeEditor isReadOnly />);
|
|
32
|
+
expect(screen.getByTestId('mock-editor').parentElement?.parentElement?.parentElement).toHaveClass(
|
|
33
|
+
styles.modifiers.readOnly
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test(`Renders with ${styles.codeEditorUpload} when isUploadEnabled = true`, () => {
|
|
38
|
+
render(<CodeEditor isUploadEnabled code="test" />);
|
|
39
|
+
expect(screen.getByTestId('mock-editor').parentElement?.parentElement).toHaveClass(styles.codeEditorUpload);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test(`Renders with empty state when code = undefined`, () => {
|
|
43
|
+
render(<CodeEditor emptyState={<div>empty</div>} />);
|
|
44
|
+
expect(screen.getByText('empty')).toBeInTheDocument();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test(`Renders with empty state when isUploadEnabled = true and code = undefined`, () => {
|
|
48
|
+
render(<CodeEditor emptyState={<div>empty</div>} isUploadEnabled />);
|
|
49
|
+
expect(screen.getByText('empty')).toBeInTheDocument();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test(`Renders with language label when isLanguageLabelVisible`, () => {
|
|
53
|
+
render(<CodeEditor isLanguageLabelVisible language={Language.java} />);
|
|
54
|
+
expect(screen.getByText('JAVA')).toBeInTheDocument();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test(`Renders with custom controls when customControls is passed`, () => {
|
|
58
|
+
render(<CodeEditor customControls={<div>control</div>} />);
|
|
59
|
+
expect(screen.getByText('control')).toBeInTheDocument();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test(`Renders with custom header content when headerMainContent is passed`, () => {
|
|
63
|
+
render(<CodeEditor headerMainContent="header content" />);
|
|
64
|
+
expect(screen.getByText('header content')).toBeInTheDocument();
|
|
65
|
+
});
|
|
28
66
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
isLanguageLabelVisible
|
|
37
|
-
isDownloadEnabled
|
|
38
|
-
isCopyEnabled
|
|
39
|
-
height="400px"
|
|
40
|
-
code={'test'}
|
|
41
|
-
language={Language.javascript}
|
|
42
|
-
/>
|
|
43
|
-
);
|
|
44
|
-
expect(asFragment()).toMatchSnapshot();
|
|
67
|
+
test(`Renders with shortcuts when shortcutsPopoverButtonText is passed`, () => {
|
|
68
|
+
render(
|
|
69
|
+
<CodeEditor shortcutsPopoverButtonText="shortcuts-button" shortcutsPopoverProps={{ bodyContent: 'shortcuts' }} />
|
|
70
|
+
);
|
|
71
|
+
expect(screen.getByText('shortcuts-button')).toBeInTheDocument();
|
|
72
|
+
act(() => {
|
|
73
|
+
screen.getByText('shortcuts-button').click();
|
|
45
74
|
});
|
|
75
|
+
expect(screen.getByText('shortcuts')).toBeInTheDocument();
|
|
46
76
|
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import { CodeEditorControl } from '../CodeEditorControl';
|
|
4
|
+
|
|
5
|
+
test('Matches snapshot', () => {
|
|
6
|
+
const { asFragment } = render(<CodeEditorControl icon={<div>icon</div>} onClick={jest.fn()} />);
|
|
7
|
+
expect(asFragment()).toMatchSnapshot();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('Renders with custom class when className is passed', () => {
|
|
11
|
+
render(<CodeEditorControl className="custom" icon={<div>icon</div>} onClick={jest.fn()} />);
|
|
12
|
+
expect(screen.getByText('icon').parentElement).toHaveClass('custom');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test('Renders with accessible name when aria-label is passed', () => {
|
|
16
|
+
render(<CodeEditorControl aria-label="aria-test" icon={<div>icon</div>} onClick={jest.fn()} />);
|
|
17
|
+
expect(screen.getByLabelText('aria-test'));
|
|
18
|
+
});
|