Skip to content

Commit

Permalink
Adding option to disable and enable line numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
benazeer-ben committed Jan 2, 2025
1 parent faa01e2 commit ca56a6a
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 49 deletions.
2 changes: 1 addition & 1 deletion docs/reference-guides/core-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Display code snippets that respect your spacing and tabs. ([Source](https://gith
- **Name:** core/code
- **Category:** text
- **Supports:** align (wide), anchor, color (background, gradients, text), interactivity (clientNavigation), spacing (margin, padding), typography (fontSize, lineHeight)
- **Attributes:** content
- **Attributes:** content, showLineNumbers

## Column

Expand Down
4 changes: 4 additions & 0 deletions packages/block-library/src/code/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
"source": "rich-text",
"selector": "code",
"__unstablePreserveWhiteSpace": true
},
"showLineNumbers": {
"type": "boolean",
"default": true
}
},
"supports": {
Expand Down
96 changes: 63 additions & 33 deletions packages/block-library/src/code/edit.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
/**
* WordPress dependencies
*/
import { RichText, useBlockProps } from '@wordpress/block-editor';
import { __ } from '@wordpress/i18n';
import {
RichText,
useBlockProps,
InspectorControls,
} from '@wordpress/block-editor';
import { createBlock, getDefaultBlockName } from '@wordpress/blocks';
import { useState, useEffect } from '@wordpress/element';
import { PanelBody, ToggleControl } from '@wordpress/components';

export default function CodeEdit( {
attributes,
Expand All @@ -14,49 +20,73 @@ export default function CodeEdit( {
} ) {
const blockProps = useBlockProps();
const [ lineNumbers, setLineNumbers ] = useState( [] );
const { content, showLineNumbers } = attributes;

// Function to calculate line numbers dynamically
// eslint-disable-next-line no-shadow
const calculateLineNumbers = ( content ) => {
return content.split( '\n' ).map( ( _, index ) => index + 1 );
};

// Update line numbers whenever the content changes
useEffect( () => {
const content =
typeof attributes.content === 'string'
? attributes.content
: attributes.content.toHTMLString( {
const contentString =
typeof content === 'string'
? content
: content.toHTMLString( {
preserveWhiteSpace: true,
} );
setLineNumbers( calculateLineNumbers( content ) );
}, [ attributes.content ] );
setLineNumbers( calculateLineNumbers( contentString ) );
}, [ content ] );

return (
<div { ...blockProps } className="wp-block-code-with-line-numbers">
<div className="line-numbers">
{ lineNumbers.map( ( num ) => (
<div key={ num }>{ num }</div>
) ) }
<>
{ /* Inspector Controls */ }
<InspectorControls>
<PanelBody title={ __( 'Code Block Settings' ) }>
<ToggleControl
label={ __( 'Show Line Numbers' ) }
__nextHasNoMarginBottom
checked={ showLineNumbers }
onChange={ ( value ) =>
setAttributes( { showLineNumbers: value } )
}
/>
</PanelBody>
</InspectorControls>

{ /* Block Content */ }
<div { ...blockProps } className="wp-block-code-with-line-numbers">
{ /* Line Numbers */ }
{ showLineNumbers && (
<div className="line-numbers">
{ lineNumbers.map( ( num ) => (
<div key={ num }>{ num }</div>
) ) }
</div>
) }

{ /* Code Content */ }
<pre className="code-content">
<RichText
tagName="code"
identifier="content"
value={ content }
// eslint-disable-next-line no-shadow
onChange={ ( content ) => setAttributes( { content } ) }
onRemove={ onRemove }
onMerge={ mergeBlocks }
placeholder={ __( 'Write code…' ) }
aria-label={ __( 'Code' ) }
preserveWhiteSpace
__unstablePastePlainText
__unstableOnSplitAtDoubleLineEnd={ () =>
insertBlocksAfter(
createBlock( getDefaultBlockName() )
)
}
/>
</pre>
</div>
<pre className="code-content">
<RichText
tagName="code"
identifier="content"
value={ attributes.content }
onChange={ ( content ) => setAttributes( { content } ) }
onRemove={ onRemove }
onMerge={ mergeBlocks }
placeholder="Write code…"
aria-label="Code"
preserveWhiteSpace
__unstablePastePlainText
__unstableOnSplitAtDoubleLineEnd={ () =>
insertBlocksAfter(
createBlock( getDefaultBlockName() )
)
}
/>
</pre>
</div>
</>
);
}
34 changes: 19 additions & 15 deletions packages/block-library/src/code/save.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,41 @@ import { RichText, useBlockProps } from '@wordpress/block-editor';
import { escape } from './utils';

export default function save( { attributes } ) {
// Calculate the number of lines dynamically
const { content, showLineNumbers } = attributes;

// eslint-disable-next-line no-shadow
const calculateLineNumbers = ( content ) => {
return content.split( '\n' ).map( ( _, index ) => index + 1 );
};

const content =
typeof attributes.content === 'string'
? attributes.content
: attributes.content.toHTMLString( {
const contentString =
typeof content === 'string'
? content
: content.toHTMLString( {
preserveWhiteSpace: true,
} );

const lineNumbers = calculateLineNumbers( content );
const lineNumbers = calculateLineNumbers( contentString );

return (
<div
{ ...useBlockProps.save() }
className="wp-block-code-with-line-numbers"
>
<div className="line-numbers">
{ lineNumbers.map( ( num ) => (
<div key={ num }>{ num }</div>
) ) }
</div>
{ /* Conditionally render line numbers */ }
{ showLineNumbers && (
<div className="line-numbers">
{ lineNumbers.map( ( num ) => (
<div key={ num }>{ num }</div>
) ) }
</div>
) }

{ /* Render code content */ }
<pre className="code-content">
<RichText.Content
tagName="code"
// To do: `escape` encodes characters in shortcodes and URLs to
// prevent embedding in PHP. Ideally checks for the code block,
// or pre/code tags, should be made on the PHP side?
value={ escape( content ) }
value={ escape( contentString ) }
/>
</pre>
</div>
Expand Down

0 comments on commit ca56a6a

Please sign in to comment.