Skip to content

Commit b22a52c

Browse files
keandcalhoun
andauthored
Native Inserter: Add support for block variants (#204)
* Add support for block variants * Rename BlockType * Capitlize ID * Update src/components/native-block-inserter-button/index.jsx Co-authored-by: David Calhoun <[email protected]> * Native Inserter: Improve ordering of blocks and more (#206) * Add a note about serializeBlocksForNative * Remove now redundant core/missing check * Move ordering to the JS land * Further refactoring * Pass displayName for Text * Localize categories * Extend most used blocks * Add gbk-most-used as a separate section * Add support for disabling blocks * Collapse long sections * Update the order of embeds * Fix linter errors --------- Co-authored-by: David Calhoun <[email protected]>
1 parent e172317 commit b22a52c

File tree

13 files changed

+398
-216
lines changed

13 files changed

+398
-216
lines changed

ios/Sources/GutenbergKit/Sources/EditorJSMessage.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ struct EditorJSMessage {
6767
}
6868

6969
struct ShowBlockInserterBody: Decodable {
70-
let blocks: [EditorBlock]
71-
let destinationBlockName: String?
70+
let sections: [BlockInserterSection]
7271
}
7372
}

ios/Sources/GutenbergKit/Sources/EditorViewController.swift

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,12 @@ public final class EditorViewController: UIViewController, GutenbergEditorContro
174174
try await webView.evaluateJavaScript("editor.getContent();") as! String
175175
}
176176

177+
public struct EditorTitleAndContent: Decodable {
178+
public let title: String
179+
public let content: String
180+
public let changed: Bool
181+
}
182+
177183
/// Returns the current editor title and content.
178184
public func getTitleAndContent() async throws -> EditorTitleAndContent {
179185
let result = try await webView.evaluateJavaScript("editor.getTitleAndContent();")
@@ -250,12 +256,11 @@ public final class EditorViewController: UIViewController, GutenbergEditorContro
250256

251257
let host = UIHostingController(rootView: NavigationStack {
252258
BlockInserterView(
253-
blocks: data.blocks,
254-
destinationBlockName: data.destinationBlockName,
259+
sections: data.sections,
255260
mediaPicker: mediaPicker,
256261
presentationContext: context,
257262
onBlockSelected: { [weak self] block in
258-
self?.insertBlockFromInserter(block.name)
263+
self?.insertBlockFromInserter(block.id)
259264
},
260265
onMediaSelected: {
261266
print("insert media:", $0)
@@ -268,8 +273,8 @@ public final class EditorViewController: UIViewController, GutenbergEditorContro
268273
present(host, animated: true)
269274
}
270275

271-
private func insertBlockFromInserter(_ blockName: String) {
272-
evaluate("window.blockInserter.insertBlock('\(blockName)')")
276+
private func insertBlockFromInserter(_ blockID: String) {
277+
evaluate("window.blockInserter.insertBlock('\(blockID)')")
273278
}
274279

275280
private func openMediaLibrary(_ config: OpenMediaLibraryAction) {

ios/Sources/GutenbergKit/Sources/Helpers/BlockIconCache.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import SVGKit
55
final class BlockIconCache: ObservableObject {
66
var icons: [String: Result<SVGKImage, Error>] = [:]
77

8-
func getIcon(for block: EditorBlock) -> SVGKImage? {
8+
func getIcon(for block: BlockType) -> SVGKImage? {
99
if let result = icons[block.id] {
1010
return try? result.get()
1111
}
@@ -14,7 +14,7 @@ final class BlockIconCache: ObservableObject {
1414
return try? result.get()
1515
}
1616

17-
private func _getIcon(for block: EditorBlock) throws -> SVGKImage {
17+
private func _getIcon(for block: BlockType) throws -> SVGKImage {
1818
guard let svg = block.icon,
1919
!svg.isEmpty,
2020
let source = SVGKSourceString.source(fromContentsOf: svg),

ios/Sources/GutenbergKit/Sources/Views/BlockInserter/BlockIconView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import SwiftUI
22
import SVGKit
33

44
struct BlockIconView: View {
5-
let block: EditorBlock
5+
let block: BlockType
66
let size: CGFloat
77

88
@EnvironmentObject private var cache: BlockIconCache

ios/Sources/GutenbergKit/Sources/Views/BlockInserter/BlockInserterBlockView.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import SwiftUI
22
import SVGKit
33

44
struct BlockInserterBlockView: View {
5-
let block: EditorBlock
5+
let block: BlockType
66
let action: () -> Void
77

88
@State private var isPressed = false
@@ -29,6 +29,7 @@ struct BlockInserterBlockView: View {
2929
.padding(.horizontal, 4)
3030
}
3131
.buttonStyle(.plain)
32+
.disabled(block.isDisabled)
3233
.frame(maxWidth: .infinity, alignment: .center)
3334
.contextMenu {
3435
Button {
@@ -57,7 +58,7 @@ struct BlockInserterBlockView: View {
5758
}
5859

5960
private struct BlockDetailedView: View {
60-
let block: EditorBlock
61+
let block: BlockType
6162

6263
var body: some View {
6364
HStack(spacing: 16) {

ios/Sources/GutenbergKit/Sources/Views/BlockInserter/BlockInserterSectionView.swift

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,32 @@
11
import SwiftUI
22

3-
struct BlockInserterSection: Identifiable {
3+
struct BlockInserterSection: Identifiable, Decodable {
44
var id: String { category }
55
let category: String
66
let name: String?
7-
let blocks: [EditorBlock]
7+
let blocks: [BlockType]
88
}
99

1010
struct BlockInserterSectionView: View {
1111
let section: BlockInserterSection
12-
let onBlockSelected: (EditorBlock) -> Void
12+
let onBlockSelected: (BlockType) -> Void
1313

1414
@ScaledMetric(relativeTo: .largeTitle) private var miniumSize = 80
1515
@ScaledMetric(relativeTo: .largeTitle) private var padding = 20
16+
@State private var isExpanded = false
17+
18+
private let initialDisplayCount = 16
19+
20+
private var displayedBlocks: [BlockType] {
21+
if !isExpanded && section.blocks.count > initialDisplayCount {
22+
return Array(section.blocks.prefix(initialDisplayCount))
23+
}
24+
return section.blocks
25+
}
26+
27+
private var hasMoreBlocks: Bool {
28+
section.blocks.count > initialDisplayCount
29+
}
1630

1731
var body: some View {
1832
VStack(alignment: .leading, spacing: 20) {
@@ -24,6 +38,9 @@ struct BlockInserterSectionView: View {
2438
.frame(maxWidth: .infinity, alignment: .leading)
2539
}
2640
grid
41+
if hasMoreBlocks {
42+
toggleButton
43+
}
2744
}
2845
.padding(.top, section.name != nil ? 20 : 24)
2946
.padding(.bottom, 10)
@@ -32,12 +49,35 @@ struct BlockInserterSectionView: View {
3249

3350
private var grid: some View {
3451
LazyVGrid(columns: [GridItem(.adaptive(minimum: miniumSize, maximum: miniumSize * 1.5), spacing: 0)]) {
35-
ForEach(section.blocks) { block in
52+
ForEach(displayedBlocks) { block in
3653
BlockInserterBlockView(block: block) {
3754
onBlockSelected(block)
3855
}
3956
}
4057
}
4158
.padding(.horizontal, 12)
4259
}
60+
61+
private var toggleButton: some View {
62+
Button {
63+
withAnimation {
64+
isExpanded.toggle()
65+
}
66+
} label: {
67+
HStack {
68+
// TODO: CMM-874 add localization
69+
Text(isExpanded ? "Show Less" : "Show More")
70+
.font(.subheadline)
71+
.fontWeight(.medium)
72+
.foregroundStyle(Color.secondary)
73+
Image(systemName: isExpanded ? "chevron.up" : "chevron.down")
74+
.font(.caption)
75+
.foregroundStyle(Color.primary)
76+
}
77+
.frame(maxWidth: .infinity)
78+
.padding(.vertical, 8)
79+
}
80+
.buttonStyle(.plain)
81+
.padding(.horizontal, 12)
82+
}
4383
}

0 commit comments

Comments
 (0)