PluginProbe
Code Block Pro – Beautiful Syntax Highlighting / 1.27.7
Code Block Pro – Beautiful Syntax Highlighting v1.27.7
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.7, at src/editor/controls/Sidebar.tsx

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