Native Sidebar
This commit is contained in:
88
native-sidebar/ios/Plugin/NativeSidebarPlugin.swift
Normal file
88
native-sidebar/ios/Plugin/NativeSidebarPlugin.swift
Normal file
@@ -0,0 +1,88 @@
|
||||
import Foundation
|
||||
import Capacitor
|
||||
|
||||
/// Hosts a native left-edge drawer (the "sidebar") that floats above the
|
||||
/// Capacitor web view. The drawer's *content* is a second, transparent
|
||||
/// WKWebView that renders the existing `Sidebar.js` from data pushed in via
|
||||
/// `setData`. Taps inside that content web view are forwarded back to the main
|
||||
/// app as an `action` event, mirroring how the NativeInput plugin works.
|
||||
@objc(NativeSidebarPlugin)
|
||||
public class NativeSidebarPlugin: CAPPlugin {
|
||||
|
||||
private var drawer: SidebarDrawer?
|
||||
|
||||
// MARK: Helpers
|
||||
|
||||
private func hostView() -> UIView? {
|
||||
// Pin the drawer as a sibling of the web view inside the same parent so
|
||||
// it can float above the web content (same pattern as NativeInput).
|
||||
return webView?.superview ?? webView
|
||||
}
|
||||
|
||||
private func ensureDrawer() -> SidebarDrawer? {
|
||||
if let drawer = drawer { return drawer }
|
||||
guard let host = hostView() else { return nil }
|
||||
let drawer = SidebarDrawer(hostView: host, mainWebView: webView, parentVC: bridge?.viewController)
|
||||
drawer.onAction = { [weak self] data in
|
||||
self?.notifyListeners("action", data: data)
|
||||
}
|
||||
drawer.onStateChange = { [weak self] open in
|
||||
self?.notifyListeners("stateChange", data: ["open": open])
|
||||
}
|
||||
drawer.attach()
|
||||
self.drawer = drawer
|
||||
return drawer
|
||||
}
|
||||
|
||||
// MARK: Plugin methods
|
||||
|
||||
@objc func setData(_ call: CAPPluginCall) {
|
||||
// Forward the whole options object (minus Capacitor's callbackId) to the
|
||||
// content web view as the sidebar payload.
|
||||
var payload = (call.options as? [String: Any]) ?? [:]
|
||||
payload.removeValue(forKey: "callbackId")
|
||||
DispatchQueue.main.async {
|
||||
guard let drawer = self.ensureDrawer() else { call.reject("No host view"); return }
|
||||
drawer.setData(payload)
|
||||
call.resolve()
|
||||
}
|
||||
}
|
||||
|
||||
@objc func setTheme(_ call: CAPPluginCall) {
|
||||
let theme = call.getString("theme") ?? ""
|
||||
DispatchQueue.main.async {
|
||||
self.drawer?.setTheme(theme)
|
||||
call.resolve()
|
||||
}
|
||||
}
|
||||
|
||||
@objc func open(_ call: CAPPluginCall) {
|
||||
DispatchQueue.main.async {
|
||||
self.ensureDrawer()?.open()
|
||||
call.resolve()
|
||||
}
|
||||
}
|
||||
|
||||
@objc func close(_ call: CAPPluginCall) {
|
||||
DispatchQueue.main.async {
|
||||
self.drawer?.close()
|
||||
call.resolve()
|
||||
}
|
||||
}
|
||||
|
||||
@objc func setEnabled(_ call: CAPPluginCall) {
|
||||
let enabled = call.getBool("enabled") ?? true
|
||||
DispatchQueue.main.async {
|
||||
self.drawer?.setEnabled(enabled)
|
||||
call.resolve()
|
||||
}
|
||||
}
|
||||
|
||||
@objc func dismiss(_ call: CAPPluginCall) {
|
||||
DispatchQueue.main.async {
|
||||
self.drawer?.removeFromHost()
|
||||
self.drawer = nil
|
||||
call.resolve()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user