Skip to content

Commit f2c5967

Browse files
committed
docs(CodeEditor): add configuration example from OCP
1 parent 263c485 commit f2c5967

File tree

2 files changed

+167
-0
lines changed

2 files changed

+167
-0
lines changed

packages/react-code-editor/src/components/CodeEditor/examples/CodeEditor.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ Note: Code editor lives in its own package at [@patternfly/react-code-editor](ht
99

1010
import { Fragment, useState } from 'react';
1111
import { CodeEditor, CodeEditorControl, Language } from '@patternfly/react-code-editor';
12+
import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon';
13+
import HashtagIcon from '@patternfly/react-icons/dist/esm/icons/hashtag-icon';
14+
import MapIcon from '@patternfly/react-icons/dist/esm/icons/map-icon';
15+
import MoonIcon from '@patternfly/react-icons/dist/esm/icons/moon-icon';
1216
import PlayIcon from '@patternfly/react-icons/dist/esm/icons/play-icon';
1317

1418
## Examples
@@ -50,3 +54,9 @@ These examples below are the shortcuts that we recommend describing in the popov
5054
```ts file="CodeEditorCustomControl.tsx"
5155

5256
```
57+
58+
### With configuration modal
59+
60+
```ts file="CodeEditorConfigurationModal.tsx"
61+
62+
```
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon';
2+
import MapIcon from '@patternfly/react-icons/dist/esm/icons/map-icon';
3+
import MoonIcon from '@patternfly/react-icons/dist/esm/icons/moon-icon';
4+
import HashtagIcon from '@patternfly/react-icons/dist/esm/icons/hashtag-icon';
5+
import { CodeEditor, CodeEditorControl } from '@patternfly/react-code-editor';
6+
import {
7+
Content,
8+
Flex,
9+
FlexItem,
10+
Modal,
11+
ModalBody,
12+
ModalHeader,
13+
Split,
14+
SplitItem,
15+
Switch,
16+
SwitchProps
17+
} from '@patternfly/react-core';
18+
import { useState } from 'react';
19+
20+
interface ConfigModalItemProps {
21+
Icon?: React.ComponentType;
22+
description: string;
23+
isChecked?: SwitchProps['isChecked'];
24+
onChange?: SwitchProps['onChange'];
25+
title: string;
26+
labels?: {
27+
enabled: string;
28+
disabled: string;
29+
};
30+
}
31+
32+
const ConfigModalItem: React.FunctionComponent<ConfigModalItemProps> = ({
33+
Icon = CogIcon,
34+
description,
35+
isChecked = false,
36+
labels = { enabled: 'Enabled', disabled: 'Disabled' },
37+
onChange,
38+
title
39+
}) => (
40+
<Split hasGutter>
41+
<SplitItem isFilled>
42+
<Flex alignItems={{ default: 'alignItemsCenter' }} spaceItems={{ default: 'spaceItemsMd' }}>
43+
<FlexItem>
44+
<Icon />
45+
</FlexItem>
46+
<FlexItem>
47+
<strong className="pf-v6-u-font-weight-bold">{title}</strong>
48+
<Content component="p">{description}</Content>
49+
</FlexItem>
50+
</Flex>
51+
</SplitItem>
52+
<SplitItem>
53+
<Switch
54+
aria-label={title}
55+
id={title}
56+
isChecked={isChecked}
57+
isReversed
58+
label={isChecked ? labels.enabled : labels.disabled}
59+
onChange={onChange}
60+
/>
61+
</SplitItem>
62+
</Split>
63+
);
64+
65+
interface ConfigModalControlProps {
66+
controls: ConfigModalItemProps[];
67+
modalTitle?: string;
68+
ouiaId?: string;
69+
}
70+
71+
const ConfigModalControl: React.FunctionComponent<ConfigModalControlProps> = ({
72+
controls,
73+
modalTitle = 'Editor settings',
74+
ouiaId = 'CodeEditorConfigurationModal'
75+
}) => {
76+
const [isModalOpen, setIsModalOpen] = useState(false);
77+
78+
return (
79+
<>
80+
<Modal
81+
aria-describedby={`${ouiaId}-body`}
82+
aria-labelledby={`${ouiaId}-title`}
83+
isOpen={isModalOpen}
84+
onClose={() => setIsModalOpen(!isModalOpen)}
85+
ouiaId={ouiaId}
86+
variant="small"
87+
>
88+
<ModalHeader title={modalTitle} labelId={`${ouiaId}-title`} />
89+
<ModalBody id={`${ouiaId}-body`}>
90+
<Flex direction={{ default: 'column' }} spaceItems={{ default: 'spaceItemsMd' }}>
91+
{controls.map((control) => (
92+
<ConfigModalItem key={control.title} {...control} />
93+
))}
94+
</Flex>
95+
</ModalBody>
96+
</Modal>
97+
<CodeEditorControl
98+
aria-label={modalTitle}
99+
icon={<CogIcon />}
100+
onClick={() => setIsModalOpen(true)}
101+
tooltipProps={{ content: modalTitle }}
102+
/>
103+
</>
104+
);
105+
};
106+
107+
export const CodeEditorConfigurationModal: React.FunctionComponent = () => {
108+
const [code, setCode] = useState('Some example content');
109+
110+
const [isMinimapVisible, setIsMinimapVisible] = useState(true);
111+
const [isDarkTheme, setIsDarkTheme] = useState(false);
112+
const [isLineNumbersVisible, setIsLineNumbersVisible] = useState(true);
113+
114+
const onChange = (code: string) => {
115+
setCode(code);
116+
};
117+
118+
const customControl = (
119+
<ConfigModalControl
120+
controls={[
121+
{
122+
title: 'Minimap',
123+
description: 'Show a preview of the full code on the side of the editor',
124+
isChecked: isMinimapVisible,
125+
onChange: (_e, checked) => setIsMinimapVisible(checked),
126+
Icon: MapIcon
127+
},
128+
{
129+
title: 'Dark theme',
130+
description: 'Switch the editor to a dark color theme',
131+
isChecked: isDarkTheme,
132+
onChange: (_e, checked) => setIsDarkTheme(checked),
133+
Icon: MoonIcon
134+
},
135+
{
136+
title: 'Line numbers',
137+
description: 'Show line numbers to the left of each line of code',
138+
isChecked: isLineNumbersVisible,
139+
onChange: (_e, checked) => setIsLineNumbersVisible(checked),
140+
Icon: HashtagIcon
141+
}
142+
]}
143+
/>
144+
);
145+
146+
return (
147+
<CodeEditor
148+
code={code}
149+
customControls={customControl}
150+
height="400px"
151+
isDarkTheme={isDarkTheme}
152+
isLineNumbersVisible={isLineNumbersVisible}
153+
isMinimapVisible={isMinimapVisible}
154+
onChange={onChange}
155+
/>
156+
);
157+
};

0 commit comments

Comments
 (0)