Skip to content

Commit

Permalink
Add experimental onSelection callback
Browse files Browse the repository at this point in the history
  • Loading branch information
Matías Surdi committed Jun 21, 2022
1 parent 7ae945e commit 94d9e69
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 30 deletions.
65 changes: 37 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Repackages Gutenberg's editor playground as a full-featured multi-instance editor that does not require WordPress.

The key features are:

- Extends the Gutenberg playground editor to match a full editor
- Allows multiple onscreen instances with seperate data stores and keyboard handlers
- Undo history
Expand All @@ -26,13 +27,15 @@ And a full list of features:
- Re-routing of WordPress API requests

The Isolated Block Editor is provided in three forms:

- ES6 module
- CommonJS module
- Standalone JavaScript file, for inclusion on any browser page

Requires: Gutenberg 13.3.0

Examples:

- [Plain Text Editor](https://github.com/Automattic/isolated-block-editor/blob/trunk/src/browser/README.md) - standalone JS and CSS file that can replace any `textarea` on any page with a full Gutenberg editor
- [Gutenberg Everywhere](https://github.com/Automattic/gutenberg-everywhere/) - a WordPress plugin to add Gutenberg to comments, WP admin pages, bbPress, and BuddyPress
- [Gutenberg Chrome Extension](https://github.com/Automattic/gutenberg-everywhere-chrome/) - a Chrome extension that allows Gutenberg to be used on any page
Expand Down Expand Up @@ -65,7 +68,7 @@ They key difference is in the Webpack config. If you don't want to bundle Gutenb

```js
plugins: [
new DependencyExtractionWebpackPlugin( { injectPolyfill: true } )
new DependencyExtractionWebpackPlugin( { injectPolyfill: true } )
]
```

Expand All @@ -87,11 +90,11 @@ You can use the provided `isolated-block-editor.js`, `core.css`, and `isolated-b
<link rel="stylesheet" href="isolated-block-editor.css" />

<body>
<textarea id="editor" />
<textarea id="editor" />

<script>
wp.attachEditor( document.getElementById( 'editor' ) );
</script>
<script>
wp.attachEditor( document.getElementById( 'editor' ) );
</script>
</body>

```
Expand Down Expand Up @@ -135,6 +138,7 @@ The module is currently only available on Github and can be added with:
## Future

The code here deals with two kinds of problems:

- Adding features to the Gutenberg playground - these are already provided by Gutenberg, but are packaged up here for you
- Adding workarounds to Gutenberg - these are situations where Gutenberg doesn't provide a feature, or doesn't export a feature, and so a workaround is needed.

Expand All @@ -153,14 +157,14 @@ Include the `IsolatedBlockEditor` module and then create an instance:
import IsolatedBlockEditor from 'isolated-block-editor';

render(
<IsolatedBlockEditor
settings={ settings }
onSaveContent={ ( html ) => saveContent( html ) }
onLoad={ ( parse ) => loadInitialContent( parse ) }
onError={ () => document.location.reload() }
>
</IsolatedBlockEditor>,
document.querySelector( '#editor' )
<IsolatedBlockEditor
settings={ settings }
onSaveContent={ ( html ) => saveContent( html ) }
onLoad={ ( parse ) => loadInitialContent( parse ) }
onError={ () => document.location.reload() }
>
</IsolatedBlockEditor>,
document.querySelector( '#editor' )
);
```

Expand All @@ -178,21 +182,21 @@ The `IsolatedBlockEditor` also exports the following support components:
import IsolatedBlockEditor, { EditorLoaded, DocumentSection, ToolbarSlot, CollaborativeEditing } from 'isolated-block-editor';

render(
<IsolatedBlockEditor
settings={ settings }
onSaveContent={ ( html ) => saveContent( html ) }
onLoad={ ( parse ) => loadInitialContent( parse ) }
onError={ () => document.location.reload() }
>
<EditorLoaded onLoaded={ () => {} } onLoading={ () => {} } />
<DocumentSection>Extra Information</DocumentSection>
<CollaborativeEditing settings={ collabSettings } />

<ToolbarSlot>
<button>Beep!</button>
</ToolbarSlot>
</IsolatedBlockEditor>,
document.querySelector( '#editor' )
<IsolatedBlockEditor
settings={ settings }
onSaveContent={ ( html ) => saveContent( html ) }
onLoad={ ( parse ) => loadInitialContent( parse ) }
onError={ () => document.location.reload() }
>
<EditorLoaded onLoaded={ () => {} } onLoading={ () => {} } />
<DocumentSection>Extra Information</DocumentSection>
<CollaborativeEditing settings={ collabSettings } />

<ToolbarSlot>
<button>Beep!</button>
</ToolbarSlot>
</IsolatedBlockEditor>,
document.querySelector( '#editor' )
);
```

Expand Down Expand Up @@ -234,6 +238,7 @@ The following function is also provided:
A settings object that contains all settings for the IsolatedBlockEditor, as well as for Gutenberg. Any settings not provided will use defaults.

The block allow and disallow list works as follows:

- All blocks are allowed, unless the `allowBlocks` option is set which defines the list of allowed blocks
- Anything in the `disallowBlocks` list is removed from the list of allowed blocks.

Expand Down Expand Up @@ -274,6 +279,10 @@ An optional callback that will be passed down to the Gutenberg editor if provide

An optional value (blocks) for the editor to show. If provided, it will be used as the internal value/blocks to display.This property is experimental and can change or be removed at any time.

#### __experimentalOnSelection

An optional callback that will be called when the selection changes in the editor. The only parameter passed to the callback will be the new selection value.

#### onError

Callback if an error occurs.
Expand Down
23 changes: 22 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { SlotFillProvider } from '@wordpress/components';
import { MediaUpload } from '@wordpress/media-utils';
import { registerCoreBlocks } from '@wordpress/block-library';
import { addFilter } from '@wordpress/hooks';
import { use, useDispatch } from '@wordpress/data';
import { use, useDispatch, useSelect } from '@wordpress/data';
import '@wordpress/format-library';
import { ShortcutProvider } from '@wordpress/keyboard-shortcuts';

Expand Down Expand Up @@ -126,6 +126,13 @@ import './style.scss';
* @property {object[]} defaultEditorStyles
*/

/**
* OnSelect callback
*
* @callback OnSelect
* @param {Object} selection - Editor content to save
*/

/**
* Initialize Gutenberg
*/
Expand Down Expand Up @@ -224,6 +231,7 @@ export function useInitializeIsoEditor( { undoManager } = {} ) {
* @param {UndoManager} [props.__experimentalUndoManager] - Undo manager
* @param {OnUpdate} [props.__experimentalOnInput] - Gutenberg's onInput callback
* @param {OnUpdate} [props.__experimentalOnChange] - Gutenberg's onChange callback
* @param {OnSelect} [props.__experimentalOnSelection] - Callback to run when the editor selection changes
* @param {object[]} [props.__experimentalValue] - Gutenberg's value
*/
function IsolatedBlockEditor( props ) {
Expand All @@ -236,11 +244,24 @@ function IsolatedBlockEditor( props ) {
__experimentalOnInput,
__experimentalOnChange,
__experimentalValue,
__experimentalOnSelection,
...params
} = props;

useInitializeIsoEditor( { undoManager: __experimentalUndoManager } );

const editorSelection = useSelect(
( select ) => ( {
start: select( 'core/block-editor' ).getSelectionStart(),
end: select( 'core/block-editor' ).getSelectionEnd(),
} ),
[]
);

useEffect( () => {
__experimentalOnSelection?.( editorSelection );
}, [ editorSelection ] );

return (
<StrictMode>
<ShortcutProvider>
Expand Down
4 changes: 3 additions & 1 deletion stories/IsolatedBlockEditor.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const Default = () => {
return <IsolatedBlockEditor settings={ {} } />;
};

export const Controlled = ( { onInput, onChange, onUndo, onRedo } ) => {
export const Controlled = ( { onInput, onChange, onUndo, onRedo, onSelection } ) => {
const [ blocks, setBlocks ] = useState( [] );

const handleOnInput = ( newBlocks ) => {
Expand All @@ -41,6 +41,7 @@ export const Controlled = ( { onInput, onChange, onUndo, onRedo } ) => {

return (
<IsolatedBlockEditor
__experimentalOnSelection={ onSelection }
__experimentalValue={ blocks }
__experimentalOnInput={ handleOnInput }
__experimentalOnChange={ handleOnChange }
Expand All @@ -63,6 +64,7 @@ Controlled.argTypes = {
onChange: { action: 'change' },
onUndo: { action: 'undo' },
onRedo: { action: 'redo' },
onSelection: { action: 'selection' },
};

export const ToolbarSettings = ( toolbarSettings ) => {
Expand Down

0 comments on commit 94d9e69

Please sign in to comment.