PluginProbe
Code Block Pro – Beautiful Syntax Highlighting / 1.27.4
Code Block Pro – Beautiful Syntax Highlighting v1.27.4
1.27.1 1.27.2 1.27.3 1.27.4 1.27.5 1.27.6 1.27.7 1.28.0 1.3.0 1.4.0 1.5.0 1.5.1 1.5.2 1.6.0 1.7.0 1.8.0 1.9.0 1.9.1 1.9.2 1.9.3 trunk 1.1.0 1.10.0 1.11.0 1.11.1 All 63 releases
code-block-pro / src / editor / controls / Sidebar.tsx

Sidebar.tsx in Code Block Pro – Beautiful Syntax Highlighting 1.27.4, at src/editor/controls/Sidebar.tsx

435 lines 19.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { InspectorControls } from '@wordpress/block-editor';
2 import {
3 PanelBody,
4 TextControl,
5 BaseControl,
6 SelectControl,
7 Button,
8 CheckboxControl,
9 } from '@wordpress/components';
10 import { useDispatch } from '@wordpress/data';
11 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
12 // @ts-ignore-next-line - store is not typed
13 import { store as editPostStore } from '@wordpress/edit-post';
14 import { useEffect, useState } from '@wordpress/element';
15 import { __ } from '@wordpress/i18n';
16 import { useCanEditHTML } from '../../hooks/useCanEditHTML';
17 import { useLanguage } from '../../hooks/useLanguage';
18 import { useGlobalStore } from '../../state/global';
19 import { useLanguageStore } from '../../state/language';
20 import { useThemeStore } from '../../state/theme';
21 import { AttributesPropsAndSetter, Lang } from '../../types';
22 import { languages } from '../../util/languages';
23 import { ButtonsPanel } from '../components/ButtonsPanel';
24 import {
25 FontSizeSelect,
26 FontLineHeightSelect,
27 FontFamilySelect,
28 } from '../components/FontSelect';
29 import { FooterSelect } from '../components/FooterSelect';
30 import { HeaderSelect } from '../components/HeaderSelect';
31 import { HeightPanel } from '../components/HeightPanel';
32 import { SlotFactory } from '../components/SlotFactory';
33 import { ThemesPanel } from '../components/ThemesPanel';
34 import { MissingPermissionsTip } from '../components/misc/MissingPermissions';
35 import { BlurControl } from './BlurControl';
36 import { HighlightingControl } from './HighlightingControl';
37
38 export const SidebarControls = ({
39 attributes,
40 setAttributes,
41 }: AttributesPropsAndSetter) => {
42 const [language, setLanguage] = useLanguage({ attributes, setAttributes });
43 const { recentLanguages } = useLanguageStore();
44 const { updateThemeHistory } = useThemeStore();
45 const { bringAttentionToPanel } = useGlobalStore();
46 const { headerType, footerType } = attributes;
47 const languagesSorted = new Map(
48 Object.entries(languages).sort((a, b) => a[1].localeCompare(b[1])),
49 );
50 const canEdit = useCanEditHTML();
51 const footersNeedingLinks = ['simpleStringEnd', 'simpleStringStart'];
52 const showHeaderTextEdit = [
53 'simpleString',
54 'pillString',
55 'stringSmall',
56 ].includes(headerType);
57 const showFooterTextEdit = footersNeedingLinks.includes(footerType ?? '');
58 const showFooterLinkEdit = footersNeedingLinks.includes(footerType ?? '');
59 const showFooterLinkTargetEdit = footersNeedingLinks.includes(
60 footerType ?? '',
61 );
62 const [bringAttention, setBringAttention] = useState<string | false>(false);
63 const { openGeneralSidebar, closeGeneralSidebar } =
64 useDispatch(editPostStore);
65
66 useEffect(() => {
67 if (!bringAttentionToPanel) return;
68 closeGeneralSidebar('edit-post/block').then(() => {
69 setBringAttention(bringAttentionToPanel);
70 openGeneralSidebar('edit-post/block');
71 });
72 }, [bringAttentionToPanel, closeGeneralSidebar, openGeneralSidebar]);
73
74 if (!canEdit)
75 return (
76 <InspectorControls>
77 {canEdit ? null : <MissingPermissionsTip />}
78 </InspectorControls>
79 );
80
81 return (
82 <InspectorControls>
83 <SlotFactory
84 name="CodeBlockPro.Sidebar.Start"
85 attributes={attributes}
86 setAttributes={setAttributes}
87 />
88 <PanelBody
89 title={__('Line Settings', 'code-block-pro')}
90 initialOpen={false}>
91 <div className="code-block-pro-editor">
92 <BaseControl id="code-block-pro-show-line-numbers">
93 <CheckboxControl
94 data-cy="show-line-numbers"
95 label={__('Line numbers', 'code-block-pro')}
96 help={__(
97 'Enable line numbers and set a starting number.',
98 'code-block-pro',
99 )}
100 checked={attributes.lineNumbers}
101 onChange={(lineNumbers) => {
102 setAttributes({ lineNumbers });
103 updateThemeHistory({ lineNumbers });
104 }}
105 />
106 {attributes.lineNumbers && (
107 <BaseControl id="code-block-pro-line-number-start">
108 <TextControl
109 id="code-block-pro-line-number-start"
110 spellCheck={false}
111 autoComplete="off"
112 label={__('Start from', 'code-block-pro')}
113 onChange={(startingLineNumber) => {
114 setAttributes({ startingLineNumber });
115 }}
116 value={attributes.startingLineNumber}
117 />
118 </BaseControl>
119 )}
120 </BaseControl>
121 <HighlightingControl
122 attributes={attributes}
123 setAttributes={setAttributes}
124 />
125 <BlurControl
126 attributes={attributes}
127 setAttributes={setAttributes}
128 />
129 </div>
130 </PanelBody>
131 <ThemesPanel
132 bringAttentionToThemes={bringAttention === 'theme-select'}
133 attributes={attributes}
134 setAttributes={setAttributes}
135 />
136 <PanelBody
137 title={__('Language', 'code-block-pro')}
138 initialOpen={bringAttention === 'language-select'}>
139 <div className="code-block-pro-editor">
140 <BaseControl id="code-block-pro-language">
141 <SelectControl
142 id="code-block-pro-language"
143 label={__('Code Language', 'code-block-pro')}
144 data-cy-cbp="language-select"
145 value={language}
146 onChange={(v) => setLanguage(v as Lang)}
147 help={
148 language === 'ansi'
149 ? __(
150 'Some code themes may not render ANSI correctly. Control sequences render only on the front.',
151 'code-block-pro',
152 )
153 : null
154 }
155 options={[...languagesSorted.entries()].map(
156 ([value, label]) => ({
157 label: label.replace(
158 'ANSI',
159 'ANSI (experimental)',
160 ),
161 value,
162 }),
163 )}
164 />
165 {recentLanguages?.length > 0 ? (
166 <>
167 <span className="mb-2 block">
168 {__('Recently Used', 'code-block-pro')}
169 </span>
170 <div className="flex flex-col gap-1">
171 {recentLanguages?.map((lang) => (
172 <Button
173 key={lang}
174 variant="link"
175 onClick={() => setLanguage(lang)}>
176 {languages[lang] ?? lang}
177 </Button>
178 ))}
179 </div>
180 </>
181 ) : null}
182 </BaseControl>
183 </div>
184 </PanelBody>
185 <PanelBody
186 title={__('Header Type', 'code-block-pro')}
187 initialOpen={false}>
188 {showHeaderTextEdit && (
189 <BaseControl id="code-block-pro-header-text">
190 <TextControl
191 id="code-block-pro-header-text"
192 spellCheck={false}
193 autoComplete="off"
194 label={__('Header Text', 'code-block-pro')}
195 placeholder={languages[language]}
196 onChange={(headerString) => {
197 setAttributes({ headerString });
198 }}
199 value={attributes.headerString ?? ''}
200 />
201 </BaseControl>
202 )}
203 <HeaderSelect
204 attributes={attributes}
205 onClick={(headerType) => {
206 setAttributes({ headerType });
207 updateThemeHistory({ headerType });
208 }}
209 />
210 </PanelBody>
211 <PanelBody
212 title={__('Footer Type', 'code-block-pro')}
213 initialOpen={false}>
214 {showFooterTextEdit && (
215 <BaseControl id="code-block-pro-footer-text">
216 <TextControl
217 id="code-block-pro-footer-text"
218 spellCheck={false}
219 autoComplete="off"
220 label={__('Footer Text', 'code-block-pro')}
221 placeholder={languages[language]}
222 onChange={(footerString) => {
223 setAttributes({ footerString });
224 }}
225 value={attributes.footerString ?? ''}
226 />
227 </BaseControl>
228 )}
229 {showFooterLinkEdit && (
230 <BaseControl id="code-block-pro-footer-link">
231 <TextControl
232 id="code-block-pro-footer-link"
233 spellCheck={false}
234 type="url"
235 autoComplete="off"
236 label={__('Footer Link', 'code-block-pro')}
237 placeholder="https://example.com"
238 help={__(
239 'Leave blank to disable',
240 'code-block-pro',
241 )}
242 onChange={(footerLink) => {
243 setAttributes({ footerLink });
244 }}
245 value={attributes.footerLink ?? ''}
246 />
247 </BaseControl>
248 )}
249 {showFooterLinkTargetEdit && (
250 <BaseControl id="code-block-pro-footer-link-target">
251 <CheckboxControl
252 id="code-block-pro-footer-link-target"
253 label={__('Open in new tab?', 'code-block-pro')}
254 checked={attributes.footerLinkTarget}
255 onChange={(footerLinkTarget) => {
256 setAttributes({ footerLinkTarget });
257 updateThemeHistory({ footerLinkTarget });
258 }}
259 />
260 </BaseControl>
261 )}
262 <FooterSelect
263 attributes={attributes}
264 onClick={(footerType) => {
265 setAttributes({ footerType });
266 updateThemeHistory({ footerType });
267 }}
268 />
269 </PanelBody>
270 <SlotFactory
271 name="CodeBlockPro.Sidebar.Middle"
272 attributes={attributes}
273 setAttributes={setAttributes}
274 />
275 <ButtonsPanel
276 attributes={attributes}
277 setAttributes={setAttributes}
278 />
279 <PanelBody
280 title={__('Font Styling', 'code-block-pro')}
281 initialOpen={false}>
282 <div
283 className="code-block-pro-editor"
284 data-cy="font-size-select">
285 <h2 className="m-0">{__('Font Size', 'code-block-pro')}</h2>
286 <FontSizeSelect
287 value={attributes.fontSize}
288 onChange={(fontSize) => {
289 setAttributes({ fontSize });
290 updateThemeHistory({ fontSize });
291 }}
292 />
293 </div>
294 <div
295 className="code-block-pro-editor"
296 data-cy="font-line-height-select">
297 <h2 className="m-0">
298 {__('Line Height', 'code-block-pro')}
299 </h2>
300 <FontLineHeightSelect
301 value={attributes.lineHeight}
302 onChange={(lineHeight) => {
303 setAttributes({ lineHeight });
304 updateThemeHistory({ lineHeight });
305 }}
306 />
307 </div>
308 <div
309 className="code-block-pro-editor"
310 data-cy="font-family-select">
311 <FontFamilySelect
312 value={attributes.fontFamily}
313 onChange={(fontFamily) => {
314 setAttributes({ fontFamily });
315 updateThemeHistory({ fontFamily });
316 }}
317 />
318 </div>
319 <div className="code-block-pro-editor" data-cy="clamp-fonts">
320 <div className="mt-6">
321 <CheckboxControl
322 label={__('Clamp Font Sizes', 'code-block-pro')}
323 help={__(
324 'Check this if your font sizes are unusually large or tiny.',
325 'code-block-pro',
326 )}
327 checked={attributes.clampFonts}
328 onChange={(clampFonts) => {
329 setAttributes({ clampFonts });
330 updateThemeHistory({ clampFonts });
331 }}
332 />
333 </div>
334 </div>
335 </PanelBody>
336 <HeightPanel
337 attributes={attributes}
338 setAttributes={setAttributes}
339 />
340 <PanelBody
341 title={__('Extra Settings', 'code-block-pro')}
342 initialOpen={false}>
343 <BaseControl id="code-block-pro-disable-padding">
344 <CheckboxControl
345 data-cy="disable-padding"
346 label={__('Disable Padding', 'code-block-pro')}
347 help={__(
348 'This is useful if you pick a theme that matches your background color, and want the code to line up to the edge of your content. You may need to add your own padding with CSS.',
349 'code-block-pro',
350 )}
351 checked={attributes.disablePadding}
352 onChange={(disablePadding) => {
353 setAttributes({ disablePadding });
354 updateThemeHistory({ disablePadding });
355 }}
356 />
357 </BaseControl>
358 <BaseControl id="code-block-pro-decode-uri">
359 <CheckboxControl
360 data-cy="use-decode-uri"
361 label={__(
362 'Encode special characters',
363 'code-block-pro',
364 )}
365 help={__(
366 'Select this to allow HTML entities such as &lt; and &gt; and others to be displayed. You may need to re-add the code after changing this',
367 'code-block-pro',
368 )}
369 checked={attributes.useDecodeURI}
370 onChange={(useDecodeURI) => {
371 setAttributes({ useDecodeURI });
372 updateThemeHistory({ useDecodeURI });
373 }}
374 />
375 </BaseControl>
376 <BaseControl id="code-block-pro-escape-shortcodes">
377 <CheckboxControl
378 data-cy="use-escape-shortcodes"
379 label={__(
380 'Escape WordPress shortcodes',
381 'code-block-pro',
382 )}
383 help={__(
384 'Select this to prevent php shortcodes from executing.',
385 'code-block-pro',
386 )}
387 checked={attributes.useEscapeShortCodes}
388 onChange={(useEscapeShortCodes) => {
389 setAttributes({ useEscapeShortCodes });
390 updateThemeHistory({ useEscapeShortCodes });
391 }}
392 />
393 </BaseControl>
394 <BaseControl id="code-block-pro-editor-tab-size">
395 <TextControl
396 spellCheck={false}
397 autoComplete="off"
398 type="number"
399 data-cy="editor-tab-size"
400 label={__('Editor tab size', 'code-block-pro')}
401 help={__(
402 'The number of spaces to insert when pressing tab key.',
403 'code-block-pro',
404 )}
405 value={attributes.tabSize}
406 onChange={(size) => {
407 const tabSize = size ? Number(size) : undefined;
408 setAttributes({ tabSize });
409 updateThemeHistory({ tabSize });
410 }}
411 />
412 <CheckboxControl
413 data-cy="use-tabs"
414 label={__('Use real tabs', 'code-block-pro')}
415 help={__(
416 'Inserts an actual tab character instead of a space. The width defined above.',
417 'code-block-pro',
418 )}
419 checked={attributes.useTabs}
420 onChange={(useTabs) => {
421 setAttributes({ useTabs });
422 updateThemeHistory({ useTabs });
423 }}
424 />
425 </BaseControl>
426 </PanelBody>
427 <SlotFactory
428 name="CodeBlockPro.Sidebar.End"
429 attributes={attributes}
430 setAttributes={setAttributes}
431 />
432 </InspectorControls>
433 );
434 };
435