diff --git a/Sources/MarkdownText/UI/TableView.swift b/Sources/MarkdownText/UI/TableView.swift index 84579b06..120a0b9e 100644 --- a/Sources/MarkdownText/UI/TableView.swift +++ b/Sources/MarkdownText/UI/TableView.swift @@ -136,7 +136,7 @@ struct TableView: View { var body: some View { VStack(alignment: .leading, spacing: 0) { - if controller != nil { + if controller?.handlesTableActions == true { scrollView.onTapGesture { withAnimation(.easeInOut(duration: 0.2)) { isExpanded.toggle() diff --git a/Sources/MarkdownText/Utilities/MarkdownListener.swift b/Sources/MarkdownText/Utilities/MarkdownListener.swift index e3a75f0d..10e91b86 100644 --- a/Sources/MarkdownText/Utilities/MarkdownListener.swift +++ b/Sources/MarkdownText/Utilities/MarkdownListener.swift @@ -43,6 +43,12 @@ public final class MarkdownController: ObservableObject { self.listener = listener } + /// Whether table copy/download taps reach a listener. `TableView` shows its + /// action controls only when this is `true`. + var handlesTableActions: Bool { + listener != nil + } + /// Request presentation of the full-document text selection modal. func requestTextSelection() { isTextSelectionRequested = true diff --git a/Tests/MarkdownTextTests/TableActionsTests.swift b/Tests/MarkdownTextTests/TableActionsTests.swift new file mode 100644 index 00000000..a46f1498 --- /dev/null +++ b/Tests/MarkdownTextTests/TableActionsTests.swift @@ -0,0 +1,30 @@ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. +// + +@testable import SwiftStreamingMarkdown +import XCTest + +final class TableActionsTests: XCTestCase { + + func test_controller_without_listener_does_not_handle_table_actions() { + let controller = MarkdownController(listener: nil) + XCTAssertFalse(controller.handlesTableActions) + } + + func test_controller_with_listener_handles_table_actions() { + let controller = MarkdownController(listener: NoOpMarkdownListener()) + XCTAssertTrue(controller.handlesTableActions) + } +} + +/// `MarkdownListener` that ignores every event. +private struct NoOpMarkdownListener: MarkdownListener { + func onRender(markdown: RenderableDocument) async {} + func onTableCopyTap(content: String) async {} + func onTableDownloadTap(content: String) async {} + func onContextMenuAppear(id: String, selectedContent: String) async {} + func onContextMenuTap(id: String, selectedContent: String) async {} + func onImageTap(image: MarkdownImage) async {} +}