diff --git a/ios/Demo-iOS/Gutenberg.xcodeproj/xcshareddata/xcschemes/Gutenberg.xcscheme b/ios/Demo-iOS/Gutenberg.xcodeproj/xcshareddata/xcschemes/Gutenberg.xcscheme
index 1a352dfa..6ae6d110 100644
--- a/ios/Demo-iOS/Gutenberg.xcodeproj/xcshareddata/xcschemes/Gutenberg.xcscheme
+++ b/ios/Demo-iOS/Gutenberg.xcodeproj/xcshareddata/xcschemes/Gutenberg.xcscheme
@@ -54,7 +54,7 @@
+ isEnabled = "YES">
EditorConfiguration {
+ configuration
+ .toBuilder()
+ .setNativeInserterEnabled(isNativeInserterEnabled)
+ .build()
+ }
+}
+
+private struct RemoteEditorRow: Identifiable {
+ let id: String
+ let configuration: EditorConfiguration
+
+ var title: String {
+ URL(string: configuration.siteURL)?.host ?? configuration.siteURL
+ }
}
private extension EditorConfiguration {
static var template: Self {
- #warning("1. Update the siteURL and authHeader values below")
- #warning("2. Install the Jetpack plugin to the site")
+ // Steps:
+ // 1. Update the siteURL and authHeader values below
+ // 2. Install the Jetpack plugin to the site
let siteUrl: String = "https://modify-me.com"
let authHeader: String = "Insert the Authorization header value here"
let siteApiRoot: String = "\(siteUrl)/wp-json/"
diff --git a/ios/Demo-iOS/Sources/EditorView.swift b/ios/Demo-iOS/Sources/EditorView.swift
index 6ac49af3..8bf12f6c 100644
--- a/ios/Demo-iOS/Sources/EditorView.swift
+++ b/ios/Demo-iOS/Sources/EditorView.swift
@@ -5,7 +5,6 @@ struct EditorView: View {
private let configuration: EditorConfiguration
@State private var viewModel = EditorViewModel()
- @State private var editorViewController: EditorViewController?
@Environment(\.dismiss) private var dismiss
@@ -15,7 +14,6 @@ struct EditorView: View {
var body: some View {
_EditorView(configuration: configuration, viewModel: viewModel)
- .navigationBarBackButtonHidden(true)
.toolbar { toolbar }
}
diff --git a/ios/Sources/GutenbergKit/Sources/EditorConfiguration.swift b/ios/Sources/GutenbergKit/Sources/EditorConfiguration.swift
index 3284af0b..985715e5 100644
--- a/ios/Sources/GutenbergKit/Sources/EditorConfiguration.swift
+++ b/ios/Sources/GutenbergKit/Sources/EditorConfiguration.swift
@@ -30,6 +30,8 @@ public struct EditorConfiguration: Sendable {
public let editorSettings: String
/// Locale used for translations
public let locale: String
+ /// Enables the native inserter UI in the editor
+ public let isNativeInserterEnabled: Bool
/// Endpoint for loading editor assets, used when enabling `shouldUsePlugins`
public var editorAssetsEndpoint: URL?
@@ -49,6 +51,7 @@ public struct EditorConfiguration: Sendable {
authHeader: String,
editorSettings: String,
locale: String,
+ isNativeInserterEnabled: Bool,
editorAssetsEndpoint: URL? = nil,
) {
self.title = title
@@ -65,6 +68,7 @@ public struct EditorConfiguration: Sendable {
self.authHeader = authHeader
self.editorSettings = editorSettings
self.locale = locale
+ self.isNativeInserterEnabled = isNativeInserterEnabled
self.editorAssetsEndpoint = editorAssetsEndpoint
}
@@ -84,6 +88,7 @@ public struct EditorConfiguration: Sendable {
authHeader: authHeader,
editorSettings: editorSettings,
locale: locale,
+ isNativeInserterEnabled: isNativeInserterEnabled,
editorAssetsEndpoint: editorAssetsEndpoint
)
}
@@ -114,6 +119,7 @@ public struct EditorConfigurationBuilder {
private var authHeader: String
private var editorSettings: String
private var locale: String
+ private var isNativeInserterEnabled: Bool
private var editorAssetsEndpoint: URL?
public init(
@@ -131,6 +137,7 @@ public struct EditorConfigurationBuilder {
authHeader: String = "",
editorSettings: String = "undefined",
locale: String = "en",
+ isNativeInserterEnabled: Bool = false,
editorAssetsEndpoint: URL? = nil
){
self.title = title
@@ -147,6 +154,7 @@ public struct EditorConfigurationBuilder {
self.authHeader = authHeader
self.editorSettings = editorSettings
self.locale = locale
+ self.isNativeInserterEnabled = isNativeInserterEnabled
self.editorAssetsEndpoint = editorAssetsEndpoint
}
@@ -234,6 +242,12 @@ public struct EditorConfigurationBuilder {
return copy
}
+ public func setNativeInserterEnabled(_ isNativeInserterEnabled: Bool = true) -> EditorConfigurationBuilder {
+ var copy = self
+ copy.isNativeInserterEnabled = isNativeInserterEnabled
+ return copy
+ }
+
public func setEditorAssetsEndpoint(_ editorAssetsEndpoint: URL?) -> EditorConfigurationBuilder {
var copy = self
copy.editorAssetsEndpoint = editorAssetsEndpoint
@@ -278,6 +292,7 @@ public struct EditorConfigurationBuilder {
authHeader: authHeader,
editorSettings: editorSettings,
locale: locale,
+ isNativeInserterEnabled: isNativeInserterEnabled,
editorAssetsEndpoint: editorAssetsEndpoint
)
}
@@ -296,3 +311,4 @@ private extension String {
.replacingOccurrences(of: "\u{12}", with: "\\f")
}
}
+
diff --git a/ios/Sources/GutenbergKit/Sources/EditorJSMessage.swift b/ios/Sources/GutenbergKit/Sources/EditorJSMessage.swift
index 7c6a9cf1..febb2dce 100644
--- a/ios/Sources/GutenbergKit/Sources/EditorJSMessage.swift
+++ b/ios/Sources/GutenbergKit/Sources/EditorJSMessage.swift
@@ -34,7 +34,7 @@ struct EditorJSMessage {
/// The editor logged an exception.
case onEditorExceptionLogged
/// The user tapped the inserter button.
- case showBlockPicker
+ case showBlockInserter
/// User requested the Media Library.
case openMediaLibrary
/// The user triggered an autocompleter.
@@ -65,4 +65,8 @@ struct EditorJSMessage {
struct ModalDialogBody: Decodable {
let dialogType: String
}
+
+ struct ShowBlockInserterBody: Decodable {
+ let blocks: [EditorBlock]
+ }
}
diff --git a/ios/Sources/GutenbergKit/Sources/EditorViewController.swift b/ios/Sources/GutenbergKit/Sources/EditorViewController.swift
index 25392ba0..297ce436 100644
--- a/ios/Sources/GutenbergKit/Sources/EditorViewController.swift
+++ b/ios/Sources/GutenbergKit/Sources/EditorViewController.swift
@@ -155,6 +155,7 @@ public final class EditorViewController: UIViewController, GutenbergEditorContro
namespaceExcludedPaths: \(Array(configuration.namespaceExcludedPaths)),
authHeader: '\(configuration.authHeader)',
themeStyles: \(configuration.shouldUseThemeStyles),
+ enableNativeBlockInserter: \(configuration.isNativeInserterEnabled),
hideTitle: \(configuration.shouldHideTitle),
editorSettings: \(configuration.editorSettings),
locale: '\(configuration.locale)',
@@ -265,14 +266,12 @@ public final class EditorViewController: UIViewController, GutenbergEditorContro
// MARK: - Internal (Block Inserter)
- // TODO: wire with JS and pass blocks
- private func showBlockInserter() {
-// let viewModel = EditorBlockPickerViewModel(blockTypes: service.blockTypes)
-// let view = NavigationView {
-// EditorBlockPicker(viewModel: viewModel)
-// }
-// let host = UIHostingController(rootView: view)
-// present(host, animated: true)
+ private func showBlockInserter(blocks: [EditorBlock]) {
+ present(UIHostingController(rootView: NavigationView {
+ List(blocks) {
+ Text($0.name)
+ }
+ }), animated: true)
}
private func openMediaLibrary(_ config: OpenMediaLibraryAction) {
@@ -315,8 +314,9 @@ public final class EditorViewController: UIViewController, GutenbergEditorContro
return
}
delegate?.editor(self, didLogException: editorException)
- case .showBlockPicker:
- showBlockInserter()
+ case .showBlockInserter:
+ let body = try message.decode(EditorJSMessage.ShowBlockInserterBody.self)
+ showBlockInserter(blocks: body.blocks)
case .openMediaLibrary:
let config = try message.decode(OpenMediaLibraryAction.self)
openMediaLibrary(config)
diff --git a/src/components/editor-toolbar/index.jsx b/src/components/editor-toolbar/index.jsx
index a606be03..7c73eca8 100644
--- a/src/components/editor-toolbar/index.jsx
+++ b/src/components/editor-toolbar/index.jsx
@@ -17,7 +17,7 @@ import {
ToolbarButton,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
-import { close, cog } from '@wordpress/icons';
+import { close, cog, plus } from '@wordpress/icons';
import clsx from 'clsx';
import { store as editorStore } from '@wordpress/editor';
@@ -27,6 +27,7 @@ import { store as editorStore } from '@wordpress/editor';
import './style.scss';
import { useModalize } from './use-modalize';
import { useModalDialogState } from '../editor/use-modal-dialog-state';
+import { showBlockInserter, getGBKit } from '../../utils/bridge';
/**
* Renders the editor toolbar containing block-related actions.
@@ -36,6 +37,8 @@ import { useModalDialogState } from '../editor/use-modal-dialog-state';
* @return {JSX.Element} The rendered editor toolbar component.
*/
const EditorToolbar = ( { className } ) => {
+ const { enableNativeBlockInserter } = getGBKit();
+
const [ isBlockInspectorShown, setBlockInspectorShown ] = useState( false );
const { isSelected } = useSelect( ( select ) => {
const { getSelectedBlockClientId } = select( blockEditorStore );
@@ -77,6 +80,29 @@ const EditorToolbar = ( { className } ) => {
const classes = clsx( 'gutenberg-kit-editor-toolbar', className );
+ const addBlockButton = enableNativeBlockInserter ? (
+ {
+ if ( isInserterOpened ) {
+ setIsInserterOpened( false );
+ }
+ showBlockInserter();
+ } }
+ className="gutenberg-kit-add-block-button"
+ />
+ ) : (
+
+ );
+
return (
<>
{
label="Editor toolbar"
variant="unstyled"
>
-
-
-
+ { addBlockButton }
{ isSelected && (
diff --git a/src/components/editor-toolbar/style.scss b/src/components/editor-toolbar/style.scss
index c7d49c8e..311dfc32 100644
--- a/src/components/editor-toolbar/style.scss
+++ b/src/components/editor-toolbar/style.scss
@@ -71,3 +71,19 @@ $min-touch-target-size: 46px;
left: 6px;
right: 6px;
}
+
+// Style the add block button with rounded black background
+.gutenberg-kit-editor-toolbar .gutenberg-kit-add-block-button {
+ svg {
+ background: #eae9ec;
+ border-radius: 18px;
+ color: wordpress.$black;
+ padding: 1px;
+ width: 32px;
+ height: 32px;
+ display: block;
+ }
+
+ // width: 50px;
+ margin-left: 8px;
+}
\ No newline at end of file
diff --git a/src/utils/bridge.js b/src/utils/bridge.js
index c0bb71f0..ce9f36af 100644
--- a/src/utils/bridge.js
+++ b/src/utils/bridge.js
@@ -5,6 +5,7 @@ import parseException from './exception-parser';
import { debug } from './logger';
import { isDevMode } from './dev-mode';
import { basicFetch } from './fetch';
+import { getBlockTypes } from '@wordpress/blocks';
/**
* Generic function to dispatch messages to both Android and iOS bridges.
@@ -91,8 +92,17 @@ export function onBlocksChanged( isEmpty = false ) {
*
* @return {void}
*/
-export function showBlockPicker() {
- dispatchToBridge( 'showBlockPicker', {} );
+export function showBlockInserter() {
+ const blocks = getBlockTypes().map( ( blockType ) => {
+ return {
+ name: blockType.name,
+ title: blockType.title,
+ description: blockType.description,
+ category: blockType.category,
+ keywords: blockType.keywords || [],
+ };
+ } );
+ dispatchToBridge( 'showBlockInserter', { blocks } );
}
/**