@legendapp/spark 0.0.1-next.2 → 0.0.1-next.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +10 -4
- package/ai-codex.ts +1 -0
- package/ai.ts +1 -0
- package/app-documents.ts +1 -0
- package/config-plugin.d.cts +2 -0
- package/contracts.ts +2 -0
- package/diagnostics.ts +1 -0
- package/expo-config.d.cts +1 -0
- package/metro.cjs +4 -1
- package/metro.d.cts +12 -0
- package/native.cjs +3 -1
- package/native.d.cts +6 -0
- package/package.json +82 -14
- package/schema.json +276 -58
- package/settings-observable.ts +1 -0
- package/settings-window.ts +1 -0
- package/shortcuts-commands.ts +1 -0
- package/shortcuts-keyboard.ts +3 -0
- package/ui-classnames.ts +1 -0
- package/ui-glass.ts +1 -0
- package/ui-search.ts +1 -0
- package/ui-sidebar.ts +1 -0
- package/ui-split-view.ts +1 -0
- package/ui-symbol.ts +1 -0
- package/vendor/node_modules/@legendapp/spark-ai/package.json +19 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/availability.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/index.ts +15 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/invocations.ts +34 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/output.ts +62 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/run.ts +12 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/types.ts +16 -0
- package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.h +2 -1
- package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.mm +126 -24
- package/vendor/node_modules/@legendapp/spark-audio/package.json +5 -2
- package/vendor/node_modules/@legendapp/spark-audio/src/NativeSparkAudio.ts +5 -1
- package/vendor/node_modules/@legendapp/spark-audio/src/desktop.ts +36 -32
- package/vendor/node_modules/@legendapp/spark-audio/src/events.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-audio/src/hooks.ts +65 -0
- package/vendor/node_modules/@legendapp/spark-audio/src/index.web.ts +92 -33
- package/vendor/node_modules/@legendapp/spark-audio/src/media-session-unavailable.ts +6 -4
- package/vendor/node_modules/@legendapp/spark-audio/src/media-session.ts +52 -19
- package/vendor/node_modules/@legendapp/spark-audio/src/media-session.web.ts +18 -10
- package/vendor/node_modules/@legendapp/spark-audio/src/media-types.ts +40 -13
- package/vendor/node_modules/@legendapp/spark-audio/src/mobile.ts +40 -32
- package/vendor/node_modules/@legendapp/spark-audio/src/player.ts +97 -0
- package/vendor/node_modules/@legendapp/spark-audio/src/status-listeners.ts +21 -15
- package/vendor/node_modules/@legendapp/spark-audio/src/types.ts +9 -4
- package/vendor/node_modules/@legendapp/spark-audio/windows/SparkAudio/SparkAudio.h +67 -20
- package/vendor/node_modules/@legendapp/spark-auth-session/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-auth-session/src/core.ts +60 -42
- package/vendor/node_modules/@legendapp/spark-auth-session/src/index.ts +28 -12
- package/vendor/node_modules/@legendapp/spark-auth-session/src/mobile.ts +97 -41
- package/vendor/node_modules/@legendapp/spark-auth-session/src/types.ts +20 -9
- package/vendor/node_modules/@legendapp/spark-cli/dist/add-desktop.js +50 -7
- package/vendor/node_modules/@legendapp/spark-cli/dist/build-mode.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/build.js +83 -48
- package/vendor/node_modules/@legendapp/spark-cli/dist/cli-arguments.js +60 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/commands.js +7 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/create.js +31 -5
- package/vendor/node_modules/@legendapp/spark-cli/dist/credentials.js +69 -23
- package/vendor/node_modules/@legendapp/spark-cli/dist/dev-command.js +12 -3
- package/vendor/node_modules/@legendapp/spark-cli/dist/dev.js +12 -9
- package/vendor/node_modules/@legendapp/spark-cli/dist/examples.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/expo-dev-patch.cjs +4 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/expo-metro.cjs +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/expo-node.js +3 -3
- package/vendor/node_modules/@legendapp/spark-cli/dist/index.js +10 -38
- package/vendor/node_modules/@legendapp/spark-cli/dist/local.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/metro.cjs +26 -5
- package/vendor/node_modules/@legendapp/spark-cli/dist/native-metadata.js +26 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/native-patch-preflight.js +84 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/native-preparation.js +88 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/notary-profiles.js +75 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/package.js +4 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/platform.js +16 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/project.js +66 -13
- package/vendor/node_modules/@legendapp/spark-cli/dist/release.js +84 -4
- package/vendor/node_modules/@legendapp/spark-cli/dist/release.json +23 -18
- package/vendor/node_modules/@legendapp/spark-cli/dist/runner-install.js +145 -31
- package/vendor/node_modules/@legendapp/spark-cli/dist/signing.js +4 -3
- package/vendor/node_modules/@legendapp/spark-cli/dist/updates.js +41 -4
- package/vendor/node_modules/@legendapp/spark-cli/dist/windows.js +4 -1
- package/vendor/node_modules/@legendapp/spark-cli/package.json +7 -6
- package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/App.tsx +6 -12
- package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/desktop.config.json +5 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/package.json +11 -9
- package/vendor/node_modules/@legendapp/spark-cli/templates/diff-lite/Git.macos.tsx +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.macos.tsx +23 -21
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.windows.tsx +23 -21
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.desktop.ts +11 -8
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.macos.ts +3 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/Lifecycle.desktop.tsx +8 -14
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/OpenFiles.desktop.tsx +5 -10
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.desktop.ts +11 -8
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.macos.ts +3 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/music-lite/assets.desktop.ts +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Activation.desktop.tsx +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Desktop.desktop.ts +37 -15
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/session.ts +5 -6
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/window-session.ts +5 -4
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/desktop.config.json +5 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/metro.config.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/package.json +13 -11
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/react-native.config.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/templates/windows/package.json +13 -11
- package/vendor/node_modules/@legendapp/spark-cli/templates/windows/react-native.config.js +1 -1
- package/vendor/node_modules/@legendapp/spark-clipboard/macos/RNDesktopClipboard.mm +10 -16
- package/vendor/node_modules/@legendapp/spark-clipboard/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-clipboard/src/NativeDesktopClipboard.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-clipboard/src/desktop.ts +55 -31
- package/vendor/node_modules/@legendapp/spark-clipboard/src/expo.ts +21 -11
- package/vendor/node_modules/@legendapp/spark-clipboard/src/options.ts +8 -0
- package/vendor/node_modules/@legendapp/spark-clipboard/src/types.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.h +38 -15
- package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.vcxproj +2 -0
- package/vendor/node_modules/@legendapp/spark-codex/RNCodex.podspec +22 -0
- package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.hpp +23 -0
- package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.mm +1529 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitro.json +21 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/.gitattributes +1 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex+autolinking.rb +62 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.cpp +17 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.hpp +27 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Umbrella.hpp +38 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.mm +35 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.swift +16 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexAvailability.hpp +95 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexRunResult.hpp +99 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.cpp +24 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.hpp +71 -0
- package/vendor/node_modules/@legendapp/spark-codex/package.json +35 -0
- package/vendor/node_modules/@legendapp/spark-codex/react-native.config.js +11 -0
- package/vendor/node_modules/@legendapp/spark-codex/src/Codex.nitro.ts +30 -0
- package/vendor/node_modules/@legendapp/spark-codex/src/index.ts +65 -0
- package/vendor/node_modules/@legendapp/spark-codex/src/native.ts +6 -0
- package/vendor/node_modules/@legendapp/spark-commands/package.json +21 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/bindings.ts +90 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/index.tsx +400 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/router.ts +138 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/storage.ts +20 -0
- package/vendor/node_modules/@legendapp/spark-context-menu/macos/RNContextMenu.mm +7 -8
- package/vendor/node_modules/@legendapp/spark-context-menu/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-context-menu/src/NativeContextMenu.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-context-menu/src/index.ts +26 -26
- package/vendor/node_modules/@legendapp/spark-context-menu/windows/SparkContextMenu/SparkContextMenu.h +3 -2
- package/vendor/node_modules/@legendapp/spark-desktop-app/RNDesktopApp.podspec +2 -1
- package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryJSI.hpp +89 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryWindows.hpp +22 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/RNDesktopApp.mm +13 -7
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkBinaryJSI.h +48 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.h +4 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.mm +33 -33
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktopError.h +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.h +26 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.mm +49 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.h +9 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.mm +70 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkWindow.mm +9 -6
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/recent-documents/RNRecentDocumentController.mm +55 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/package.json +5 -3
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/NativeDesktopApp.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/api.ts +86 -40
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/accelerator.ts +40 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/index.ts +56 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/menu.ts +114 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/native-buffer.ts +22 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/path.ts +24 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/events.ts +75 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.ts +2 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.windows.ts +2 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/open-requests.ts +43 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/restoration.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/transport.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.cjs +10 -5
- package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.d.cts +3 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/autolinking.cjs +35 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/config.cjs +16 -3
- package/vendor/node_modules/@legendapp/spark-desktop-config/config.d.cts +89 -9
- package/vendor/node_modules/@legendapp/spark-desktop-config/expo.d.cts +3 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/identity.cjs +3 -2
- package/vendor/node_modules/@legendapp/spark-desktop-config/lifecycle.cjs +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/package.json +6 -5
- package/vendor/node_modules/@legendapp/spark-desktop-config/schema.json +276 -58
- package/vendor/node_modules/@legendapp/spark-desktop-config/updates.cjs +1 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/validation.cjs +35 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/windows.plugin.cjs +2 -1
- package/vendor/node_modules/@legendapp/spark-desktop-host/AppDelegate.mm +129 -11
- package/vendor/node_modules/@legendapp/spark-desktop-host/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-desktop-host/windows/application.inc +277 -121
- package/vendor/node_modules/@legendapp/spark-desktop-links/common/AuthLoopback.h +5 -7
- package/vendor/node_modules/@legendapp/spark-desktop-links/macos/RNDesktopLinks.mm +10 -9
- package/vendor/node_modules/@legendapp/spark-desktop-links/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/NativeDesktopLinks.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/api.ts +27 -33
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/expo.ts +3 -4
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/native.ts +9 -0
- package/vendor/node_modules/@legendapp/spark-desktop-links/windows/SparkLinks/SparkLinks.h +22 -22
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/RNDesktopShortcuts.podspec +1 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/RNDesktopShortcuts.mm +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.h +9 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.mm +307 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/package.json +8 -5
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/NativeDesktopShortcuts.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/api.ts +39 -14
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/NativeKeyboardManager.ts +12 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/codes.ts +108 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/index.ts +99 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/RNDesktopWindows.podspec +2 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/RNDesktopWindows.mm +229 -103
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/SparkWindowGeometry.h +63 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.h +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.mm +27 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.h +12 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.mm +3130 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManagerStartup.mm +31 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/SidebarStartupFallbacks.mm +14 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/package.json +10 -6
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/NativeDesktopWindowManager.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/api.ts +144 -70
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/diagnostics.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.windows.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos-adapter.ts +53 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos.ts +51 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/transport.ts +41 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/types.ts +140 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/validation.ts +162 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/window-manager/NativeWindowManager.ts +28 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/WindowProvider.tsx +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/createWindowsNavigator.tsx +78 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/index.ts +6 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/primaryWindowLifecycle.ts +34 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/types.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/usePrimaryWindowLifecycle.ts +18 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/useWindowFocusEffect.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-documents/package.json +22 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/controller.ts +97 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/documentTransition.ts +13 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/hooks.ts +139 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/index.tsx +50 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/reload.ts +39 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/requests.ts +15 -0
- package/vendor/node_modules/@legendapp/spark-drag-drop/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-drag-drop/src/DesktopDragViewNativeComponent.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-drag-drop/src/contracts.ts +73 -18
- package/vendor/node_modules/@legendapp/spark-drag-drop/src/index.tsx +58 -15
- package/vendor/node_modules/@legendapp/spark-drag-drop/windows/SparkDragDrop/SparkDragDrop.h +14 -8
- package/vendor/node_modules/@legendapp/spark-file-dialog/ios/RNFileDialog.mm +34 -121
- package/vendor/node_modules/@legendapp/spark-file-dialog/package.json +12 -5
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/NativeFileDialog.ts +1 -5
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.ts +19 -84
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/native.ts +12 -0
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/options.ts +34 -14
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/types.ts +26 -0
- package/vendor/node_modules/@legendapp/spark-file-dialog/windows/SparkFileDialog/SparkFileDialog.h +42 -58
- package/vendor/node_modules/@legendapp/spark-file-system/RNDesktopFileSystem.podspec +1 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/RNDesktopFileSystem.mm +32 -21
- package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.h +24 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.mm +215 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.h +9 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.mm +82 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.h +47 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.mm +306 -0
- package/vendor/node_modules/@legendapp/spark-file-system/package.json +8 -6
- package/vendor/node_modules/@legendapp/spark-file-system/src/NativeDesktopFileSystem.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/NativeFileScanner.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/index.ts +93 -0
- package/vendor/node_modules/@legendapp/spark-file-system/src/handles.ts +48 -14
- package/vendor/node_modules/@legendapp/spark-file-system/src/index.ts +134 -45
- package/vendor/node_modules/@legendapp/spark-file-system/src/path.ts +1 -9
- package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.h +102 -26
- package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.vcxproj +2 -0
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/RNDesktopGlobalShortcuts.podspec +1 -0
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/macos/RNDesktopGlobalShortcuts.mm +7 -4
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/NativeDesktopGlobalShortcuts.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/index.ts +39 -10
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/windows/SparkGlobalShortcuts/SparkGlobalShortcuts.h +5 -4
- package/vendor/node_modules/@legendapp/spark-message-dialog/macos/RNDesktopMessageDialog.mm +2 -2
- package/vendor/node_modules/@legendapp/spark-message-dialog/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-message-dialog/src/NativeDesktopMessageDialog.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-message-dialog/src/index.ts +48 -11
- package/vendor/node_modules/@legendapp/spark-native-menu/ios/RNNativeMenu.mm +141 -609
- package/vendor/node_modules/@legendapp/spark-native-menu/package.json +9 -4
- package/vendor/node_modules/@legendapp/spark-native-menu/src/NativeMenu.ts +2 -7
- package/vendor/node_modules/@legendapp/spark-native-menu/src/api.ts +76 -121
- package/vendor/node_modules/@legendapp/spark-native-menu/src/hooks.ts +97 -0
- package/vendor/node_modules/@legendapp/spark-native-menu/src/windows-menus.ts +43 -37
- package/vendor/node_modules/@legendapp/spark-notifications/macos/RNDesktopNotifications.mm +75 -30
- package/vendor/node_modules/@legendapp/spark-notifications/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-notifications/src/NativeDesktopNotifications.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-notifications/src/index.ts +130 -42
- package/vendor/node_modules/@legendapp/spark-notifications/windows/SparkNotifications/SparkNotifications.h +46 -8
- package/vendor/node_modules/@legendapp/spark-processes/macos/RNDesktopProcesses.mm +94 -21
- package/vendor/node_modules/@legendapp/spark-processes/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-processes/src/NativeDesktopProcesses.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-processes/src/index.ts +124 -28
- package/vendor/node_modules/@legendapp/spark-processes/src/types.ts +34 -0
- package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.h +83 -34
- package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.vcxproj +2 -0
- package/vendor/node_modules/@legendapp/spark-secure-storage/macos/RNDesktopSecureStorage.mm +49 -40
- package/vendor/node_modules/@legendapp/spark-secure-storage/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/NativeDesktopSecureStorage.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/desktop.ts +16 -14
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/expo.ts +0 -1
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/options.ts +3 -2
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/unavailable.ts +6 -3
- package/vendor/node_modules/@legendapp/spark-settings/package.json +10 -3
- package/vendor/node_modules/@legendapp/spark-settings/src/fileStorage.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-settings/src/index.ts +7 -9
- package/vendor/node_modules/@legendapp/spark-settings/src/storage/index.ts +142 -0
- package/vendor/node_modules/@legendapp/spark-settings/src/store.ts +63 -21
- package/vendor/node_modules/@legendapp/spark-settings-ui/package.json +20 -0
- package/vendor/node_modules/@legendapp/spark-settings-ui/src/index.tsx +436 -0
- package/vendor/node_modules/@legendapp/spark-settings-ui/src/options.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-sqlite/package.json +3 -3
- package/vendor/node_modules/@legendapp/spark-sqlite/src/database.ts +182 -0
- package/vendor/node_modules/@legendapp/spark-sqlite/src/index.ts +19 -6
- package/vendor/node_modules/@legendapp/spark-sqlite/src/types.ts +22 -0
- package/vendor/node_modules/@legendapp/spark-system/macos/RNDesktopSystem.mm +36 -11
- package/vendor/node_modules/@legendapp/spark-system/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-system/src/NativeDesktopSystem.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-system/src/index.ts +89 -32
- package/vendor/node_modules/@legendapp/spark-system/windows/SparkSystem/SparkSystem.h +8 -4
- package/vendor/node_modules/@legendapp/spark-tray/macos/RNDesktopTray.mm +20 -8
- package/vendor/node_modules/@legendapp/spark-tray/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-tray/src/NativeDesktopTray.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-tray/src/index.ts +91 -34
- package/vendor/node_modules/@legendapp/spark-tray/windows/SparkTray/SparkTray.h +45 -15
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkButton.mm +2 -1
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkTextInput.mm +10 -2
- package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.mm +1182 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/glass-effect-view/RNGlassEffectView.mm +72 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.mm +194 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.mm +180 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.mm +155 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.h +18 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.mm +645 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.mm +164 -0
- package/vendor/node_modules/@legendapp/spark-ui/package.json +16 -4
- package/vendor/node_modules/@legendapp/spark-ui/src/SparkSelectNativeComponent.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-ui/src/SparkTextInputNativeComponent.ts +6 -2
- package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/SidebarSplitViewNativeComponent.ts +31 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/index.tsx +77 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/availability.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/classnames/index.ts +8 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/control.ts +42 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/desktop.tsx +56 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/glass-effect-view/index.tsx +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/index.android.tsx +35 -21
- package/vendor/node_modules/@legendapp/spark-ui/src/index.ios.tsx +55 -26
- package/vendor/node_modules/@legendapp/spark-ui/src/index.tsx +1 -27
- package/vendor/node_modules/@legendapp/spark-ui/src/index.web.tsx +45 -14
- package/vendor/node_modules/@legendapp/spark-ui/src/index.windows.tsx +1 -42
- package/vendor/node_modules/@legendapp/spark-ui/src/mobile-input.tsx +11 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSegmentedControlNativeComponent.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSelectNativeComponent.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/select.ts +5 -3
- package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/SFSymbolNativeComponent.ts +13 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/index.tsx +27 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarItemNativeComponent.ts +25 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarNativeComponent.ts +24 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/index.tsx +104 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/specialized.ts +22 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/TextInputSearchNativeComponent.ts +33 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/index.tsx +34 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/types.ts +30 -19
- package/vendor/node_modules/@legendapp/spark-ui/uniwind.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-ui/uniwind.web.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-ui/windows/SparkUI/SparkUI.h +16 -11
- package/vendor/node_modules/@legendapp/spark-updates/macos/RNDesktopUpdates.mm +21 -8
- package/vendor/node_modules/@legendapp/spark-updates/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-updates/src/NativeDesktopUpdates.ts +3 -2
- package/vendor/node_modules/@legendapp/spark-updates/src/index.ts +71 -15
- package/vendor/node_modules/@legendapp/spark-webview/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-webview/src/WebView.tsx +11 -0
- package/vendor/node_modules/@legendapp/spark-webview/src/adapter.ts +55 -0
- package/vendor/node_modules/@legendapp/spark-webview/src/index.ts +2 -2
- package/vendor/node_modules/@legendapp/spark-webview/src/types.ts +32 -0
- package/vendor/node_modules/@legendapp/spark-webview/src/view-props.ts +28 -0
- package/vendor/node_modules/@legendapp/spark-window-options/index.cjs +51 -14
- package/vendor/node_modules/@legendapp/spark-window-options/index.d.ts +21 -8
- package/vendor/node_modules/@legendapp/spark-window-options/package.json +1 -1
- package/windows-macos.ts +1 -0
- package/expo-metro.cjs +0 -1
- package/message-dialog.ts +0 -1
- package/universal.cjs +0 -1
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/accelerator.ts +0 -22
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows-options.ts +0 -11
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.windows.ts +0 -15
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/accelerator.ts +0 -22
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkSelect.h +0 -4
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkSelect.mm +0 -53
|
@@ -0,0 +1,1182 @@
|
|
|
1
|
+
#import "RNSidebarSplitViewComponent.h"
|
|
2
|
+
|
|
3
|
+
#import <react/renderer/components/RNSparkUISpec/ComponentDescriptors.h>
|
|
4
|
+
#import <react/renderer/components/RNSparkUISpec/EventEmitters.h>
|
|
5
|
+
#import <react/renderer/components/RNSparkUISpec/Props.h>
|
|
6
|
+
#import <react/renderer/components/RNSparkUISpec/RCTComponentViewHelpers.h>
|
|
7
|
+
|
|
8
|
+
#if TARGET_OS_OSX
|
|
9
|
+
#import <CoreImage/CoreImage.h>
|
|
10
|
+
#import <QuartzCore/QuartzCore.h>
|
|
11
|
+
#import <objc/runtime.h>
|
|
12
|
+
#endif
|
|
13
|
+
|
|
14
|
+
using namespace facebook::react;
|
|
15
|
+
|
|
16
|
+
#if TARGET_OS_OSX
|
|
17
|
+
@interface RNSidebarSplitViewTitlebarMaterialContainerView : NSView
|
|
18
|
+
@end
|
|
19
|
+
|
|
20
|
+
@implementation RNSidebarSplitViewTitlebarMaterialContainerView
|
|
21
|
+
- (nullable NSView *)hitTest:(NSPoint)point
|
|
22
|
+
{
|
|
23
|
+
return nil;
|
|
24
|
+
}
|
|
25
|
+
@end
|
|
26
|
+
|
|
27
|
+
static NSAppearance *RNSidebarSplitViewAppearanceForName(NSString *appearanceName)
|
|
28
|
+
{
|
|
29
|
+
if ([appearanceName isEqualToString:@"light"]) {
|
|
30
|
+
return [NSAppearance appearanceNamed:NSAppearanceNameAqua];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if ([appearanceName isEqualToString:@"dark"]) {
|
|
34
|
+
return [NSAppearance appearanceNamed:NSAppearanceNameDarkAqua];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return nil;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static NSColor *RNSidebarSplitViewColorFromHexString(NSString *value)
|
|
41
|
+
{
|
|
42
|
+
if (![value isKindOfClass:NSString.class] || value.length == 0) {
|
|
43
|
+
return nil;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
NSString *hex = [value hasPrefix:@"#"] ? [value substringFromIndex:1] : value;
|
|
47
|
+
if (hex.length != 6 && hex.length != 8) {
|
|
48
|
+
return nil;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
unsigned long long raw = 0;
|
|
52
|
+
NSScanner *scanner = [NSScanner scannerWithString:hex];
|
|
53
|
+
if (![scanner scanHexLongLong:&raw]) {
|
|
54
|
+
return nil;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
CGFloat red = 0;
|
|
58
|
+
CGFloat green = 0;
|
|
59
|
+
CGFloat blue = 0;
|
|
60
|
+
CGFloat alpha = 1;
|
|
61
|
+
if (hex.length == 8) {
|
|
62
|
+
red = ((raw >> 24) & 0xff) / 255.0;
|
|
63
|
+
green = ((raw >> 16) & 0xff) / 255.0;
|
|
64
|
+
blue = ((raw >> 8) & 0xff) / 255.0;
|
|
65
|
+
alpha = (raw & 0xff) / 255.0;
|
|
66
|
+
} else {
|
|
67
|
+
red = ((raw >> 16) & 0xff) / 255.0;
|
|
68
|
+
green = ((raw >> 8) & 0xff) / 255.0;
|
|
69
|
+
blue = (raw & 0xff) / 255.0;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return [NSColor colorWithSRGBRed:red green:green blue:blue alpha:alpha];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static CGFloat RNSidebarSplitViewClampedUnitValue(CGFloat value)
|
|
76
|
+
{
|
|
77
|
+
return MIN(MAX(0, value), 1);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
static NSVisualEffectMaterial RNSidebarSplitViewMaterialForName(NSString *value)
|
|
81
|
+
{
|
|
82
|
+
if ([value isEqualToString:@"hudWindow"]) {
|
|
83
|
+
return NSVisualEffectMaterialHUDWindow;
|
|
84
|
+
}
|
|
85
|
+
if ([value isEqualToString:@"sidebar"]) {
|
|
86
|
+
return NSVisualEffectMaterialSidebar;
|
|
87
|
+
}
|
|
88
|
+
if ([value isEqualToString:@"windowBackground"]) {
|
|
89
|
+
return NSVisualEffectMaterialWindowBackground;
|
|
90
|
+
}
|
|
91
|
+
if ([value isEqualToString:@"titlebar"]) {
|
|
92
|
+
return NSVisualEffectMaterialTitlebar;
|
|
93
|
+
}
|
|
94
|
+
if ([value isEqualToString:@"glass"] || [value isEqualToString:@"headerView"]) {
|
|
95
|
+
if (@available(macOS 10.14, *)) {
|
|
96
|
+
return NSVisualEffectMaterialHeaderView;
|
|
97
|
+
}
|
|
98
|
+
return NSVisualEffectMaterialTitlebar;
|
|
99
|
+
}
|
|
100
|
+
return NSVisualEffectMaterialTitlebar;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
static NSView *RNSidebarSplitViewCreateColorOverlay(NSRect frame, NSColor *color, CGFloat opacity)
|
|
104
|
+
{
|
|
105
|
+
NSView *overlayView = [[NSView alloc] initWithFrame:frame];
|
|
106
|
+
overlayView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
|
107
|
+
overlayView.wantsLayer = YES;
|
|
108
|
+
overlayView.layer.backgroundColor = [color colorWithAlphaComponent:opacity].CGColor;
|
|
109
|
+
return overlayView;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
static NSView *RNSidebarSplitViewCreateMaterialContainer(NSRect frame, NSView *materialView, NSColor *overlayColor, CGFloat overlayOpacity)
|
|
113
|
+
{
|
|
114
|
+
RNSidebarSplitViewTitlebarMaterialContainerView *containerView =
|
|
115
|
+
[[RNSidebarSplitViewTitlebarMaterialContainerView alloc] initWithFrame:frame];
|
|
116
|
+
containerView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
|
117
|
+
containerView.wantsLayer = YES;
|
|
118
|
+
containerView.layer.backgroundColor = NSColor.clearColor.CGColor;
|
|
119
|
+
containerView.layer.masksToBounds = YES;
|
|
120
|
+
|
|
121
|
+
[containerView addSubview:materialView];
|
|
122
|
+
if (overlayColor && overlayOpacity > 0) {
|
|
123
|
+
[containerView addSubview:RNSidebarSplitViewCreateColorOverlay(containerView.bounds, overlayColor, overlayOpacity)];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return containerView;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
API_AVAILABLE(macos(26.0))
|
|
130
|
+
static NSView *RNSidebarSplitViewCreateGlassMaterialView(NSRect frame, NSColor *overlayColor, CGFloat overlayOpacity)
|
|
131
|
+
{
|
|
132
|
+
CGFloat overscan = 48;
|
|
133
|
+
NSRect glassFrame = NSMakeRect(-overscan, 0, NSWidth(frame) + (overscan * 2), NSHeight(frame) + overscan);
|
|
134
|
+
NSGlassEffectView *glassView = [[NSGlassEffectView alloc] initWithFrame:glassFrame];
|
|
135
|
+
glassView.cornerRadius = 0;
|
|
136
|
+
glassView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
|
137
|
+
glassView.wantsLayer = YES;
|
|
138
|
+
glassView.layer.backgroundColor = NSColor.clearColor.CGColor;
|
|
139
|
+
return RNSidebarSplitViewCreateMaterialContainer(frame, glassView, overlayColor, overlayOpacity);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
static NSView *RNSidebarSplitViewCreateTitlebarMaterialView(NSString *materialName,
|
|
143
|
+
NSRect frame,
|
|
144
|
+
NSColor *overlayColor,
|
|
145
|
+
CGFloat overlayOpacity)
|
|
146
|
+
{
|
|
147
|
+
if ([materialName isEqualToString:@"glass"]) {
|
|
148
|
+
if (@available(macOS 26.0, *)) {
|
|
149
|
+
return RNSidebarSplitViewCreateGlassMaterialView(frame, overlayColor, overlayOpacity);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
NSVisualEffectView *effectView = [[NSVisualEffectView alloc] initWithFrame:NSMakeRect(0, 0, NSWidth(frame), NSHeight(frame))];
|
|
154
|
+
effectView.material = RNSidebarSplitViewMaterialForName(materialName);
|
|
155
|
+
effectView.blendingMode = NSVisualEffectBlendingModeWithinWindow;
|
|
156
|
+
effectView.state = NSVisualEffectStateFollowsWindowActiveState;
|
|
157
|
+
effectView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
|
158
|
+
effectView.wantsLayer = YES;
|
|
159
|
+
effectView.layer.backgroundColor = NSColor.clearColor.CGColor;
|
|
160
|
+
return RNSidebarSplitViewCreateMaterialContainer(frame, effectView, overlayColor, overlayOpacity);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
static NSView *RNSidebarSplitViewCreateBackgroundBlurView(NSRect frame, CGFloat radius)
|
|
164
|
+
{
|
|
165
|
+
RNSidebarSplitViewTitlebarMaterialContainerView *blurView =
|
|
166
|
+
[[RNSidebarSplitViewTitlebarMaterialContainerView alloc] initWithFrame:frame];
|
|
167
|
+
blurView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
|
168
|
+
blurView.wantsLayer = YES;
|
|
169
|
+
blurView.layerUsesCoreImageFilters = YES;
|
|
170
|
+
blurView.layer.backgroundColor = NSColor.clearColor.CGColor;
|
|
171
|
+
|
|
172
|
+
CIFilter *blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
|
|
173
|
+
[blurFilter setDefaults];
|
|
174
|
+
[blurFilter setValue:@(radius) forKey:kCIInputRadiusKey];
|
|
175
|
+
blurView.layer.backgroundFilters = @[blurFilter];
|
|
176
|
+
return blurView;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
static void RNSidebarSplitViewApplySoftBottomEdgeMask(NSView *view)
|
|
180
|
+
{
|
|
181
|
+
CAGradientLayer *maskLayer = [CAGradientLayer layer];
|
|
182
|
+
maskLayer.frame = view.bounds;
|
|
183
|
+
maskLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
|
|
184
|
+
maskLayer.colors = @[
|
|
185
|
+
(id)NSColor.whiteColor.CGColor,
|
|
186
|
+
(id)NSColor.whiteColor.CGColor,
|
|
187
|
+
(id)NSColor.clearColor.CGColor,
|
|
188
|
+
];
|
|
189
|
+
maskLayer.locations = @[@0, @0.7, @1];
|
|
190
|
+
maskLayer.startPoint = CGPointMake(0.5, 1);
|
|
191
|
+
maskLayer.endPoint = CGPointMake(0.5, 0);
|
|
192
|
+
view.layer.mask = maskLayer;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
static void RNSidebarSplitViewApplyColorOverlay(NSView *view, NSColor *color, CGFloat opacity)
|
|
196
|
+
{
|
|
197
|
+
if (color && opacity > 0) {
|
|
198
|
+
CALayer *overlayLayer = [CALayer layer];
|
|
199
|
+
overlayLayer.frame = view.bounds;
|
|
200
|
+
overlayLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
|
|
201
|
+
overlayLayer.backgroundColor = [color colorWithAlphaComponent:opacity].CGColor;
|
|
202
|
+
[view.layer addSublayer:overlayLayer];
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
static char RNSidebarSplitViewStartupKey;
|
|
207
|
+
|
|
208
|
+
// Startup must stay entirely in AppKit: constructing a Fabric view here would
|
|
209
|
+
// read React feature flags before RCTReactNativeFactory configures them.
|
|
210
|
+
@interface RNSidebarSplitViewStartupView : NSView
|
|
211
|
+
- (instancetype)initWithFrame:(NSRect)frame configuration:(NSDictionary *)configuration;
|
|
212
|
+
@property (nonatomic, copy) void (^installReactRoot)(void);
|
|
213
|
+
- (void)finish;
|
|
214
|
+
@end
|
|
215
|
+
|
|
216
|
+
@implementation RNSidebarSplitViewStartupView {
|
|
217
|
+
NSSplitViewController *_controller;
|
|
218
|
+
NSView *_sidebar;
|
|
219
|
+
NSView *_content;
|
|
220
|
+
NSView *_titlebarMaterial;
|
|
221
|
+
CGFloat _sidebarWidth;
|
|
222
|
+
CGFloat _contentMinWidth;
|
|
223
|
+
BOOL _layingOut;
|
|
224
|
+
CGFloat _titlebarHeight;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
- (instancetype)initWithFrame:(NSRect)frame configuration:(NSDictionary *)configuration
|
|
228
|
+
{
|
|
229
|
+
if (self = [super initWithFrame:frame]) {
|
|
230
|
+
self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
|
231
|
+
self.appearance = RNSidebarSplitViewAppearanceForName(configuration[@"appearance"]);
|
|
232
|
+
_sidebarWidth = [configuration[@"sidebarWidth"] doubleValue];
|
|
233
|
+
_contentMinWidth = [configuration[@"contentMinWidth"] doubleValue];
|
|
234
|
+
NSColor *background = RNSidebarSplitViewColorFromHexString(configuration[@"backgroundColor"]);
|
|
235
|
+
self.wantsLayer = YES;
|
|
236
|
+
self.layer.backgroundColor = background.CGColor;
|
|
237
|
+
|
|
238
|
+
_sidebar = [NSView new];
|
|
239
|
+
_content = [NSView new];
|
|
240
|
+
_sidebar.wantsLayer = YES;
|
|
241
|
+
_content.wantsLayer = YES;
|
|
242
|
+
// AppKit supplies the sidebar material; an opaque fill hides its backdrop.
|
|
243
|
+
_sidebar.layer.backgroundColor = NSColor.clearColor.CGColor;
|
|
244
|
+
_content.layer.backgroundColor = background.CGColor;
|
|
245
|
+
_sidebar.layer.zPosition = 10;
|
|
246
|
+
NSViewController *sidebarController = [NSViewController new];
|
|
247
|
+
NSViewController *contentController = [NSViewController new];
|
|
248
|
+
sidebarController.view = _sidebar;
|
|
249
|
+
contentController.view = _content;
|
|
250
|
+
NSSplitViewItem *sidebarItem = [NSSplitViewItem sidebarWithViewController:sidebarController];
|
|
251
|
+
NSSplitViewItem *contentItem = [NSSplitViewItem splitViewItemWithViewController:contentController];
|
|
252
|
+
sidebarItem.minimumThickness = [configuration[@"sidebarMinWidth"] doubleValue];
|
|
253
|
+
sidebarItem.preferredThicknessFraction = 0.26;
|
|
254
|
+
sidebarItem.canCollapse = YES;
|
|
255
|
+
sidebarItem.collapsed = [configuration[@"sidebarCollapsed"] boolValue];
|
|
256
|
+
contentItem.minimumThickness = _contentMinWidth;
|
|
257
|
+
contentItem.canCollapse = NO;
|
|
258
|
+
sidebarItem.allowsFullHeightLayout = YES;
|
|
259
|
+
contentItem.allowsFullHeightLayout = YES;
|
|
260
|
+
|
|
261
|
+
_controller = [NSSplitViewController new];
|
|
262
|
+
_controller.minimumThicknessForInlineSidebars = 0;
|
|
263
|
+
_controller.splitView.vertical = YES;
|
|
264
|
+
_controller.splitView.dividerStyle = NSSplitViewDividerStyleThin;
|
|
265
|
+
[_controller addSplitViewItem:sidebarItem];
|
|
266
|
+
[_controller addSplitViewItem:contentItem];
|
|
267
|
+
_controller.view.frame = self.bounds;
|
|
268
|
+
_controller.view.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
|
269
|
+
[self addSubview:_controller.view];
|
|
270
|
+
|
|
271
|
+
_titlebarHeight = [configuration[@"contentTitlebarHeight"] doubleValue];
|
|
272
|
+
if (_titlebarHeight > 0) {
|
|
273
|
+
_titlebarMaterial = RNSidebarSplitViewCreateTitlebarMaterialView(
|
|
274
|
+
@"glass", NSMakeRect(0, 0, NSWidth(frame), _titlebarHeight), background,
|
|
275
|
+
[configuration[@"appearance"] isEqualToString:@"dark"] ? 0 : 0.1);
|
|
276
|
+
[_content addSubview:_titlebarMaterial];
|
|
277
|
+
}
|
|
278
|
+
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(splitViewDidMount:)
|
|
279
|
+
name:@"LegendSidebarSplitViewDidMount" object:nil];
|
|
280
|
+
[self layout];
|
|
281
|
+
}
|
|
282
|
+
return self;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
- (void)layout
|
|
286
|
+
{
|
|
287
|
+
[super layout];
|
|
288
|
+
if (!_controller || _layingOut) {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
_layingOut = YES;
|
|
292
|
+
_controller.view.frame = self.bounds;
|
|
293
|
+
CGFloat sidebarWidth = MIN(_sidebarWidth,
|
|
294
|
+
MAX(0, NSWidth(self.bounds) - _contentMinWidth - _controller.splitView.dividerThickness));
|
|
295
|
+
[_controller.splitView setPosition:sidebarWidth ofDividerAtIndex:0];
|
|
296
|
+
[_controller.splitView adjustSubviews];
|
|
297
|
+
[_controller.view layoutSubtreeIfNeeded];
|
|
298
|
+
NSRect contentFrame = [_controller.view convertRect:_controller.view.bounds toView:_content];
|
|
299
|
+
CGFloat height = MIN(_titlebarHeight, NSHeight(contentFrame));
|
|
300
|
+
_titlebarMaterial.frame = NSMakeRect(NSMinX(contentFrame),
|
|
301
|
+
_content.isFlipped ? NSMinY(contentFrame) : NSMaxY(contentFrame) - height,
|
|
302
|
+
NSWidth(contentFrame), height);
|
|
303
|
+
_layingOut = NO;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
- (void)splitViewDidMount:(NSNotification *)notification
|
|
307
|
+
{
|
|
308
|
+
NSView *mountedView = notification.object;
|
|
309
|
+
if (self.window && mountedView.window == self.window) {
|
|
310
|
+
// Leave the Fabric/AppKit layout transaction before reparenting its root.
|
|
311
|
+
dispatch_async(dispatch_get_main_queue(), ^{ [self finish]; });
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
- (void)finish
|
|
316
|
+
{
|
|
317
|
+
if (!self.installReactRoot) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
NSWindow *window = self.window;
|
|
321
|
+
NSResponder *firstResponder = window.firstResponder;
|
|
322
|
+
void (^installRoot)(void) = self.installReactRoot;
|
|
323
|
+
self.installReactRoot = nil;
|
|
324
|
+
[self removeFromSuperview];
|
|
325
|
+
objc_setAssociatedObject(window, &RNSidebarSplitViewStartupKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
326
|
+
// Removing the placeholder split clears AppKit's sidebar association. Reattach
|
|
327
|
+
// the live root before the next draw so its split registers with the window.
|
|
328
|
+
installRoot();
|
|
329
|
+
// Installing a content view controller in a visible window can focus its first
|
|
330
|
+
// key view. Preserve the previous focus, including an unfocused window, so the
|
|
331
|
+
// handoff does not introduce a focus ring or steal focus from an input.
|
|
332
|
+
if ([firstResponder isKindOfClass:NSView.class] && ((NSView *)firstResponder).window != window) {
|
|
333
|
+
firstResponder = nil;
|
|
334
|
+
}
|
|
335
|
+
[window makeFirstResponder:firstResponder];
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
- (void)dealloc
|
|
339
|
+
{
|
|
340
|
+
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
@end
|
|
344
|
+
#endif
|
|
345
|
+
|
|
346
|
+
#if TARGET_OS_OSX
|
|
347
|
+
@interface RNSidebarSplitViewComponent () <RCTSidebarSplitViewViewProtocol>
|
|
348
|
+
@end
|
|
349
|
+
#else
|
|
350
|
+
@interface RNSidebarSplitViewComponent () <RCTSidebarSplitViewViewProtocol>
|
|
351
|
+
@end
|
|
352
|
+
#endif
|
|
353
|
+
|
|
354
|
+
@implementation RNSidebarSplitViewComponent {
|
|
355
|
+
#if TARGET_OS_OSX
|
|
356
|
+
NSSplitViewController *_splitViewController;
|
|
357
|
+
NSViewController *_sidebarViewController;
|
|
358
|
+
NSViewController *_contentViewController;
|
|
359
|
+
NSSplitViewItem *_sidebarItem;
|
|
360
|
+
NSSplitViewItem *_contentItem;
|
|
361
|
+
NSView *_sidebarContainer;
|
|
362
|
+
NSView *_contentContainer;
|
|
363
|
+
RCTUIView<RCTComponentViewProtocol> *_sidebarReactView;
|
|
364
|
+
RCTUIView<RCTComponentViewProtocol> *_contentReactView;
|
|
365
|
+
id _resizeObserver;
|
|
366
|
+
LayoutMetrics _currentLayoutMetrics;
|
|
367
|
+
LayoutMetrics _sidebarReactLayoutMetrics;
|
|
368
|
+
LayoutMetrics _contentReactLayoutMetrics;
|
|
369
|
+
CGFloat _sidebarMinWidth;
|
|
370
|
+
CGFloat _sidebarWidth;
|
|
371
|
+
CGFloat _contentMinWidth;
|
|
372
|
+
BOOL _sidebarCollapsed;
|
|
373
|
+
CGFloat _lastSidebarWidth;
|
|
374
|
+
CGFloat _lastContentWidth;
|
|
375
|
+
CGFloat _lastHeight;
|
|
376
|
+
BOOL _lastLayoutReady;
|
|
377
|
+
BOOL _didPublishMount;
|
|
378
|
+
NSString *_appearanceName;
|
|
379
|
+
CGFloat _contentTitlebarHeight;
|
|
380
|
+
NSString *_contentTitlebarMaterialName;
|
|
381
|
+
NSString *_contentTitlebarOverlayColorValue;
|
|
382
|
+
CGFloat _contentTitlebarOverlayOpacity;
|
|
383
|
+
NSView *_contentTitlebarMaterialView;
|
|
384
|
+
NSString *_sidebarTitlebarOverlayColorValue;
|
|
385
|
+
CGFloat _sidebarTitlebarOverlayOpacity;
|
|
386
|
+
NSView *_sidebarTitlebarMaterialView;
|
|
387
|
+
NSSplitViewItemAccessoryViewController *_sidebarScrollEdgeAccessory API_AVAILABLE(macos(26.0));
|
|
388
|
+
NSLayoutConstraint *_sidebarScrollEdgeHeight;
|
|
389
|
+
#else
|
|
390
|
+
UIView *_sidebarContainer;
|
|
391
|
+
UIView *_contentContainer;
|
|
392
|
+
#endif
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
- (instancetype)initWithFrame:(CGRect)frame
|
|
396
|
+
{
|
|
397
|
+
if (self = [super initWithFrame:frame]) {
|
|
398
|
+
_props = std::make_shared<const SidebarSplitViewProps>();
|
|
399
|
+
|
|
400
|
+
#if TARGET_OS_OSX
|
|
401
|
+
_currentLayoutMetrics = EmptyLayoutMetrics;
|
|
402
|
+
_sidebarReactLayoutMetrics = EmptyLayoutMetrics;
|
|
403
|
+
_contentReactLayoutMetrics = EmptyLayoutMetrics;
|
|
404
|
+
_sidebarMinWidth = 180;
|
|
405
|
+
_sidebarWidth = 0;
|
|
406
|
+
_contentMinWidth = 320;
|
|
407
|
+
_sidebarCollapsed = NO;
|
|
408
|
+
_lastSidebarWidth = -1;
|
|
409
|
+
_lastContentWidth = -1;
|
|
410
|
+
_lastHeight = -1;
|
|
411
|
+
_lastLayoutReady = NO;
|
|
412
|
+
_appearanceName = @"system";
|
|
413
|
+
_contentTitlebarHeight = 0;
|
|
414
|
+
_contentTitlebarMaterialName = @"none";
|
|
415
|
+
_contentTitlebarOverlayOpacity = 0;
|
|
416
|
+
_sidebarTitlebarOverlayOpacity = 0;
|
|
417
|
+
_sidebarContainer = [NSView new];
|
|
418
|
+
_contentContainer = [NSView new];
|
|
419
|
+
_sidebarContainer.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
|
420
|
+
_contentContainer.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
|
421
|
+
_sidebarContainer.wantsLayer = YES;
|
|
422
|
+
_contentContainer.wantsLayer = YES;
|
|
423
|
+
_sidebarContainer.layer.masksToBounds = NO;
|
|
424
|
+
_contentContainer.layer.masksToBounds = NO;
|
|
425
|
+
_sidebarContainer.layer.zPosition = 10;
|
|
426
|
+
_contentContainer.layer.zPosition = 0;
|
|
427
|
+
|
|
428
|
+
_sidebarViewController = [NSViewController new];
|
|
429
|
+
_contentViewController = [NSViewController new];
|
|
430
|
+
_sidebarViewController.view = _sidebarContainer;
|
|
431
|
+
_contentViewController.view = _contentContainer;
|
|
432
|
+
|
|
433
|
+
_sidebarItem = [NSSplitViewItem sidebarWithViewController:_sidebarViewController];
|
|
434
|
+
_contentItem = [NSSplitViewItem splitViewItemWithViewController:_contentViewController];
|
|
435
|
+
_sidebarItem.canCollapse = YES;
|
|
436
|
+
_contentItem.canCollapse = NO;
|
|
437
|
+
[self updateSplitItemSizing];
|
|
438
|
+
|
|
439
|
+
if (@available(macOS 11.0, *)) {
|
|
440
|
+
_sidebarItem.allowsFullHeightLayout = YES;
|
|
441
|
+
_contentItem.allowsFullHeightLayout = YES;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
_splitViewController = [NSSplitViewController new];
|
|
445
|
+
_splitViewController.minimumThicknessForInlineSidebars = 0;
|
|
446
|
+
_splitViewController.splitView.vertical = YES;
|
|
447
|
+
_splitViewController.splitView.dividerStyle = NSSplitViewDividerStyleThin;
|
|
448
|
+
_splitViewController.view.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
|
449
|
+
[_splitViewController addSplitViewItem:_sidebarItem];
|
|
450
|
+
[_splitViewController addSplitViewItem:_contentItem];
|
|
451
|
+
[self applyAppearance];
|
|
452
|
+
|
|
453
|
+
_resizeObserver = [[NSNotificationCenter defaultCenter]
|
|
454
|
+
addObserverForName:NSSplitViewDidResizeSubviewsNotification
|
|
455
|
+
object:_splitViewController.splitView
|
|
456
|
+
queue:NSOperationQueue.mainQueue
|
|
457
|
+
usingBlock:^(__unused NSNotification *notification) {
|
|
458
|
+
[self publishSplitViewLayoutAllowEstimatedReady:NO];
|
|
459
|
+
}];
|
|
460
|
+
|
|
461
|
+
[self addSubview:_splitViewController.view];
|
|
462
|
+
#else
|
|
463
|
+
_sidebarContainer = [UIView new];
|
|
464
|
+
_contentContainer = [UIView new];
|
|
465
|
+
[self addSubview:_sidebarContainer];
|
|
466
|
+
[self addSubview:_contentContainer];
|
|
467
|
+
#endif
|
|
468
|
+
}
|
|
469
|
+
return self;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
#if TARGET_OS_OSX
|
|
473
|
+
- (BOOL)isFlipped
|
|
474
|
+
{
|
|
475
|
+
return YES;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
- (void)updateSplitItemSizing
|
|
479
|
+
{
|
|
480
|
+
_sidebarItem.minimumThickness = MAX(120, _sidebarMinWidth);
|
|
481
|
+
_sidebarItem.preferredThicknessFraction = 0.26;
|
|
482
|
+
_contentItem.minimumThickness = MAX(240, _contentMinWidth);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
- (CGFloat)preferredSidebarWidthForBounds:(CGRect)bounds
|
|
486
|
+
{
|
|
487
|
+
CGFloat dividerThickness = _splitViewController.splitView.dividerThickness;
|
|
488
|
+
CGFloat maxSidebarWidth = bounds.size.width - _contentMinWidth - dividerThickness;
|
|
489
|
+
CGFloat preferredSidebarWidth = _sidebarWidth > 0 ? _sidebarWidth : _sidebarMinWidth;
|
|
490
|
+
CGFloat sidebarWidth = MIN(MAX(_sidebarMinWidth, preferredSidebarWidth), maxSidebarWidth);
|
|
491
|
+
return MAX(0, sidebarWidth);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
- (void)updateSidebarCollapsed
|
|
495
|
+
{
|
|
496
|
+
if (_sidebarItem.collapsed != _sidebarCollapsed) {
|
|
497
|
+
_sidebarItem.collapsed = _sidebarCollapsed;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
- (void)applyAppearance
|
|
502
|
+
{
|
|
503
|
+
NSAppearance *appearance = RNSidebarSplitViewAppearanceForName(_appearanceName);
|
|
504
|
+
self.appearance = appearance;
|
|
505
|
+
_splitViewController.view.appearance = appearance;
|
|
506
|
+
_splitViewController.splitView.appearance = appearance;
|
|
507
|
+
_sidebarContainer.appearance = appearance;
|
|
508
|
+
_contentContainer.appearance = appearance;
|
|
509
|
+
[_splitViewController.view setNeedsDisplay:YES];
|
|
510
|
+
[_splitViewController.splitView setNeedsDisplay:YES];
|
|
511
|
+
[_sidebarContainer setNeedsDisplay:YES];
|
|
512
|
+
[_contentContainer setNeedsDisplay:YES];
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
- (void)removeContentTitlebarMaterial
|
|
516
|
+
{
|
|
517
|
+
[_contentTitlebarMaterialView removeFromSuperview];
|
|
518
|
+
_contentTitlebarMaterialView = nil;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
- (void)removeSidebarTitlebarMaterial
|
|
522
|
+
{
|
|
523
|
+
[_sidebarTitlebarMaterialView removeFromSuperview];
|
|
524
|
+
_sidebarTitlebarMaterialView = nil;
|
|
525
|
+
if (@available(macOS 26.1, *)) {
|
|
526
|
+
if (_sidebarScrollEdgeAccessory) {
|
|
527
|
+
NSUInteger index = [_sidebarItem.topAlignedAccessoryViewControllers indexOfObject:_sidebarScrollEdgeAccessory];
|
|
528
|
+
if (index != NSNotFound) {
|
|
529
|
+
[_sidebarItem removeTopAlignedAccessoryViewControllerAtIndex:index];
|
|
530
|
+
}
|
|
531
|
+
_sidebarScrollEdgeAccessory = nil;
|
|
532
|
+
_sidebarScrollEdgeHeight = nil;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
- (void)layoutSidebarTitlebarMaterialWithHeight:(CGFloat)titlebarHeight
|
|
538
|
+
{
|
|
539
|
+
NSRect splitFrameInSidebar = [_splitViewController.view convertRect:_splitViewController.view.bounds
|
|
540
|
+
toView:_sidebarContainer];
|
|
541
|
+
if (titlebarHeight <= 0 || NSWidth(splitFrameInSidebar) <= 0) {
|
|
542
|
+
[self removeSidebarTitlebarMaterial];
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
if (@available(macOS 26.1, *)) {
|
|
547
|
+
// AppKit already accounts for the window titlebar above the accessory.
|
|
548
|
+
// Only register any additional header height, not a second full titlebar.
|
|
549
|
+
CGFloat nativeTitlebarHeight = MAX(0, NSHeight(self.window.frame) - NSHeight(self.window.contentLayoutRect));
|
|
550
|
+
CGFloat accessoryHeight = MAX(0, titlebarHeight - nativeTitlebarHeight);
|
|
551
|
+
if (!_sidebarScrollEdgeAccessory) {
|
|
552
|
+
_sidebarScrollEdgeAccessory = [NSSplitViewItemAccessoryViewController new];
|
|
553
|
+
_sidebarScrollEdgeAccessory.automaticallyAppliesContentInsets = NO;
|
|
554
|
+
_sidebarScrollEdgeAccessory.preferredScrollEdgeEffectStyle = NSScrollEdgeEffectStyle.softStyle;
|
|
555
|
+
// Register the existing header region with NSScrollView's native edge
|
|
556
|
+
// effect. React retains ownership of its existing content inset.
|
|
557
|
+
NSView *accessoryView = [RNSidebarSplitViewTitlebarMaterialContainerView new];
|
|
558
|
+
_sidebarScrollEdgeAccessory.view = accessoryView;
|
|
559
|
+
_sidebarScrollEdgeHeight = [accessoryView.heightAnchor constraintEqualToConstant:accessoryHeight];
|
|
560
|
+
_sidebarScrollEdgeHeight.active = YES;
|
|
561
|
+
[_sidebarItem addTopAlignedAccessoryViewController:_sidebarScrollEdgeAccessory];
|
|
562
|
+
}
|
|
563
|
+
_sidebarScrollEdgeHeight.constant = accessoryHeight;
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
CGFloat materialHeight = MIN(titlebarHeight + 10, NSHeight(splitFrameInSidebar));
|
|
568
|
+
CGFloat materialY = _sidebarContainer.isFlipped
|
|
569
|
+
? NSMinY(splitFrameInSidebar)
|
|
570
|
+
: NSMaxY(splitFrameInSidebar) - materialHeight;
|
|
571
|
+
NSRect materialFrame = NSMakeRect(
|
|
572
|
+
NSMinX(splitFrameInSidebar),
|
|
573
|
+
materialY,
|
|
574
|
+
NSWidth(splitFrameInSidebar),
|
|
575
|
+
materialHeight);
|
|
576
|
+
|
|
577
|
+
if (!_sidebarTitlebarMaterialView) {
|
|
578
|
+
_sidebarTitlebarMaterialView = RNSidebarSplitViewCreateBackgroundBlurView(materialFrame, 2);
|
|
579
|
+
RNSidebarSplitViewApplySoftBottomEdgeMask(_sidebarTitlebarMaterialView);
|
|
580
|
+
RNSidebarSplitViewApplyColorOverlay(
|
|
581
|
+
_sidebarTitlebarMaterialView,
|
|
582
|
+
RNSidebarSplitViewColorFromHexString(_sidebarTitlebarOverlayColorValue),
|
|
583
|
+
_sidebarTitlebarOverlayOpacity);
|
|
584
|
+
} else {
|
|
585
|
+
_sidebarTitlebarMaterialView.frame = materialFrame;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
if (_sidebarTitlebarMaterialView.superview != _sidebarContainer) {
|
|
589
|
+
[_sidebarTitlebarMaterialView removeFromSuperview];
|
|
590
|
+
}
|
|
591
|
+
[_sidebarContainer addSubview:_sidebarTitlebarMaterialView
|
|
592
|
+
positioned:NSWindowAbove
|
|
593
|
+
relativeTo:_sidebarReactView];
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
- (void)layoutContentTitlebarMaterial
|
|
597
|
+
{
|
|
598
|
+
if (_contentTitlebarHeight <= 0 ||
|
|
599
|
+
_contentTitlebarMaterialName.length == 0 ||
|
|
600
|
+
[_contentTitlebarMaterialName isEqualToString:@"none"] ||
|
|
601
|
+
!_contentContainer.superview) {
|
|
602
|
+
[self removeContentTitlebarMaterial];
|
|
603
|
+
[self removeSidebarTitlebarMaterial];
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
NSRect splitFrameInContent = [_splitViewController.view convertRect:_splitViewController.view.bounds toView:_contentContainer];
|
|
608
|
+
CGFloat materialHeight = MIN(_contentTitlebarHeight, NSHeight(splitFrameInContent));
|
|
609
|
+
if (materialHeight <= 0 || NSWidth(splitFrameInContent) <= 0) {
|
|
610
|
+
[self removeContentTitlebarMaterial];
|
|
611
|
+
[self removeSidebarTitlebarMaterial];
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
CGFloat materialY = _contentContainer.isFlipped
|
|
616
|
+
? NSMinY(splitFrameInContent)
|
|
617
|
+
: NSMaxY(splitFrameInContent) - materialHeight;
|
|
618
|
+
NSRect materialFrame = NSMakeRect(NSMinX(splitFrameInContent), materialY, NSWidth(splitFrameInContent), materialHeight);
|
|
619
|
+
|
|
620
|
+
if (!_contentTitlebarMaterialView) {
|
|
621
|
+
NSColor *overlayColor = RNSidebarSplitViewColorFromHexString(_contentTitlebarOverlayColorValue);
|
|
622
|
+
CGFloat overlayOpacity = RNSidebarSplitViewClampedUnitValue(_contentTitlebarOverlayOpacity);
|
|
623
|
+
_contentTitlebarMaterialView = RNSidebarSplitViewCreateTitlebarMaterialView(
|
|
624
|
+
_contentTitlebarMaterialName,
|
|
625
|
+
materialFrame,
|
|
626
|
+
overlayColor,
|
|
627
|
+
overlayOpacity);
|
|
628
|
+
} else {
|
|
629
|
+
_contentTitlebarMaterialView.frame = materialFrame;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
if (_contentTitlebarMaterialView.superview != _contentContainer) {
|
|
633
|
+
[_contentTitlebarMaterialView removeFromSuperview];
|
|
634
|
+
[_contentContainer addSubview:_contentTitlebarMaterialView positioned:NSWindowAbove relativeTo:_contentReactView];
|
|
635
|
+
} else {
|
|
636
|
+
[_contentContainer addSubview:_contentTitlebarMaterialView positioned:NSWindowAbove relativeTo:_contentReactView];
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
[self layoutSidebarTitlebarMaterialWithHeight:materialHeight];
|
|
640
|
+
|
|
641
|
+
_sidebarContainer.layer.zPosition = 10;
|
|
642
|
+
_contentContainer.layer.zPosition = 0;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
- (void)syncReactSubviewFrames
|
|
646
|
+
{
|
|
647
|
+
CGRect sidebarBounds = _sidebarContainer.bounds;
|
|
648
|
+
CGRect contentBounds = _contentContainer.bounds;
|
|
649
|
+
|
|
650
|
+
[self syncReactSubview:_sidebarReactView
|
|
651
|
+
nativeBounds:sidebarBounds
|
|
652
|
+
previousLayoutMetrics:&_sidebarReactLayoutMetrics];
|
|
653
|
+
[self syncReactSubview:_contentReactView
|
|
654
|
+
nativeBounds:contentBounds
|
|
655
|
+
previousLayoutMetrics:&_contentReactLayoutMetrics];
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
- (void)syncReactSubview:(nullable RCTUIView<RCTComponentViewProtocol> *)subview
|
|
659
|
+
nativeBounds:(CGRect)nativeBounds
|
|
660
|
+
previousLayoutMetrics:(LayoutMetrics *)previousLayoutMetrics
|
|
661
|
+
{
|
|
662
|
+
if (!subview) {
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
subview.hidden = nativeBounds.size.width <= 0 || nativeBounds.size.height <= 0;
|
|
667
|
+
subview.translatesAutoresizingMaskIntoConstraints = YES;
|
|
668
|
+
subview.frame = nativeBounds;
|
|
669
|
+
LayoutMetrics nextLayoutMetrics = _currentLayoutMetrics;
|
|
670
|
+
if (nextLayoutMetrics == EmptyLayoutMetrics) {
|
|
671
|
+
nextLayoutMetrics = LayoutMetrics{};
|
|
672
|
+
}
|
|
673
|
+
nextLayoutMetrics.frame = facebook::react::Rect{
|
|
674
|
+
facebook::react::Point{0, 0},
|
|
675
|
+
facebook::react::Size{(Float)nativeBounds.size.width, (Float)nativeBounds.size.height},
|
|
676
|
+
};
|
|
677
|
+
nextLayoutMetrics.contentInsets = {};
|
|
678
|
+
nextLayoutMetrics.borderWidth = {};
|
|
679
|
+
nextLayoutMetrics.overflowInset = {};
|
|
680
|
+
|
|
681
|
+
[subview updateLayoutMetrics:nextLayoutMetrics oldLayoutMetrics:*previousLayoutMetrics];
|
|
682
|
+
[subview finalizeUpdates:RNComponentViewUpdateMaskLayoutMetrics];
|
|
683
|
+
*previousLayoutMetrics = nextLayoutMetrics;
|
|
684
|
+
subview.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
|
685
|
+
[subview setNeedsLayout:YES];
|
|
686
|
+
[subview layoutSubtreeIfNeeded];
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
- (void)emitSplitViewDidResizeWithSidebarWidth:(CGFloat)sidebarWidth
|
|
690
|
+
contentWidth:(CGFloat)contentWidth
|
|
691
|
+
contentX:(CGFloat)contentX
|
|
692
|
+
sidebarHeight:(CGFloat)sidebarHeight
|
|
693
|
+
contentHeight:(CGFloat)contentHeight
|
|
694
|
+
height:(CGFloat)height
|
|
695
|
+
layoutReady:(BOOL)layoutReady
|
|
696
|
+
{
|
|
697
|
+
const auto eventEmitter = std::static_pointer_cast<const SidebarSplitViewEventEmitter>(_eventEmitter);
|
|
698
|
+
if (!eventEmitter) {
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
if (contentWidth <= 0 || height <= 0) {
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
BOOL panesReady = layoutReady && _sidebarReactView && _contentReactView;
|
|
707
|
+
if (panesReady && self.window && !_didPublishMount) {
|
|
708
|
+
// This also runs when an already-laid-out Fabric tree joins its window.
|
|
709
|
+
// Keep it before metrics deduplication so the startup cover cannot linger.
|
|
710
|
+
_didPublishMount = YES;
|
|
711
|
+
[[NSNotificationCenter defaultCenter] postNotificationName:@"LegendSidebarSplitViewDidMount"
|
|
712
|
+
object:self];
|
|
713
|
+
}
|
|
714
|
+
if (fabs(sidebarWidth - _lastSidebarWidth) < 0.5 &&
|
|
715
|
+
fabs(contentWidth - _lastContentWidth) < 0.5 &&
|
|
716
|
+
fabs(height - _lastHeight) < 0.5 &&
|
|
717
|
+
panesReady == _lastLayoutReady) {
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
_lastSidebarWidth = sidebarWidth;
|
|
722
|
+
_lastContentWidth = contentWidth;
|
|
723
|
+
_lastHeight = height;
|
|
724
|
+
_lastLayoutReady = panesReady;
|
|
725
|
+
|
|
726
|
+
eventEmitter->onSplitViewDidResize(SidebarSplitViewEventEmitter::OnSplitViewDidResize{
|
|
727
|
+
.contentHeight = contentHeight,
|
|
728
|
+
.contentWidth = contentWidth,
|
|
729
|
+
.contentX = contentX,
|
|
730
|
+
.height = height,
|
|
731
|
+
.isLayoutReady = static_cast<bool>(panesReady),
|
|
732
|
+
.isVertical = true,
|
|
733
|
+
.sidebarHeight = sidebarHeight,
|
|
734
|
+
.sidebarWidth = sidebarWidth,
|
|
735
|
+
});
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
- (BOOL)applyEstimatedSplitViewLayoutForBounds:(CGRect)bounds layoutReady:(BOOL)layoutReady
|
|
739
|
+
{
|
|
740
|
+
if (bounds.size.width <= 0 || bounds.size.height <= 0) {
|
|
741
|
+
return NO;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
CGFloat dividerThickness = _splitViewController.splitView.dividerThickness;
|
|
745
|
+
CGFloat sidebarWidth = 0;
|
|
746
|
+
if (!_sidebarCollapsed) {
|
|
747
|
+
sidebarWidth = [self preferredSidebarWidthForBounds:bounds];
|
|
748
|
+
}
|
|
749
|
+
CGFloat contentX = sidebarWidth > 0 ? sidebarWidth + dividerThickness : 0;
|
|
750
|
+
CGFloat contentWidth = MAX(0, bounds.size.width - contentX);
|
|
751
|
+
if (contentWidth <= 0) {
|
|
752
|
+
contentWidth = bounds.size.width;
|
|
753
|
+
contentX = 0;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
_splitViewController.view.frame = bounds;
|
|
757
|
+
_splitViewController.splitView.frame = bounds;
|
|
758
|
+
_sidebarContainer.frame = CGRectMake(0, 0, sidebarWidth, bounds.size.height);
|
|
759
|
+
_contentContainer.frame = CGRectMake(contentX, 0, contentWidth, bounds.size.height);
|
|
760
|
+
|
|
761
|
+
CGRect sidebarBounds = CGRectMake(0, 0, sidebarWidth, bounds.size.height);
|
|
762
|
+
CGRect contentBounds = CGRectMake(0, 0, contentWidth, bounds.size.height);
|
|
763
|
+
[self syncReactSubview:_sidebarReactView
|
|
764
|
+
nativeBounds:sidebarBounds
|
|
765
|
+
previousLayoutMetrics:&_sidebarReactLayoutMetrics];
|
|
766
|
+
[self syncReactSubview:_contentReactView
|
|
767
|
+
nativeBounds:contentBounds
|
|
768
|
+
previousLayoutMetrics:&_contentReactLayoutMetrics];
|
|
769
|
+
[self layoutContentTitlebarMaterial];
|
|
770
|
+
[self emitSplitViewDidResizeWithSidebarWidth:sidebarWidth
|
|
771
|
+
contentWidth:contentWidth
|
|
772
|
+
contentX:contentX
|
|
773
|
+
sidebarHeight:bounds.size.height
|
|
774
|
+
contentHeight:bounds.size.height
|
|
775
|
+
height:bounds.size.height
|
|
776
|
+
layoutReady:layoutReady];
|
|
777
|
+
|
|
778
|
+
return YES;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
- (void)publishSplitViewLayoutAllowEstimatedReady:(BOOL)allowEstimatedReady
|
|
782
|
+
{
|
|
783
|
+
CGFloat sidebarWidth = _sidebarContainer.bounds.size.width;
|
|
784
|
+
CGFloat contentWidth = _contentContainer.bounds.size.width;
|
|
785
|
+
CGFloat contentX = [_contentContainer convertRect:_contentContainer.bounds toView:self].origin.x;
|
|
786
|
+
CGFloat sidebarHeight = _sidebarContainer.bounds.size.height;
|
|
787
|
+
CGFloat contentHeight = _contentContainer.bounds.size.height;
|
|
788
|
+
CGFloat height = MAX(sidebarHeight, contentHeight);
|
|
789
|
+
CGRect bounds = [self currentLayoutBounds];
|
|
790
|
+
|
|
791
|
+
if (contentWidth <= 0 || height <= 0 ||
|
|
792
|
+
contentX < -0.5 ||
|
|
793
|
+
contentX + contentWidth > bounds.size.width + 0.5 ||
|
|
794
|
+
fabs(_contentContainer.bounds.size.height - bounds.size.height) >= 0.5) {
|
|
795
|
+
[self applyEstimatedSplitViewLayoutForBounds:bounds layoutReady:allowEstimatedReady];
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
[self syncReactSubviewFrames];
|
|
800
|
+
[self layoutContentTitlebarMaterial];
|
|
801
|
+
[self emitSplitViewDidResizeWithSidebarWidth:sidebarWidth
|
|
802
|
+
contentWidth:contentWidth
|
|
803
|
+
contentX:contentX
|
|
804
|
+
sidebarHeight:sidebarHeight
|
|
805
|
+
contentHeight:contentHeight
|
|
806
|
+
height:height
|
|
807
|
+
layoutReady:YES];
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
- (CGRect)currentLayoutBounds
|
|
811
|
+
{
|
|
812
|
+
CGRect bounds = self.bounds;
|
|
813
|
+
if ((bounds.size.width <= 0 || bounds.size.height <= 0) && _currentLayoutMetrics != EmptyLayoutMetrics) {
|
|
814
|
+
bounds = CGRectMake(
|
|
815
|
+
0,
|
|
816
|
+
0,
|
|
817
|
+
_currentLayoutMetrics.frame.size.width,
|
|
818
|
+
_currentLayoutMetrics.frame.size.height);
|
|
819
|
+
}
|
|
820
|
+
return bounds;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
- (void)applyDividerPositionForBounds:(CGRect)bounds
|
|
824
|
+
{
|
|
825
|
+
if (_sidebarCollapsed || bounds.size.width <= 0 || _splitViewController.splitView.subviews.count < 2) {
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
CGFloat sidebarWidth = [self preferredSidebarWidthForBounds:bounds];
|
|
830
|
+
if (sidebarWidth <= 0) {
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
[_splitViewController.splitView setPosition:sidebarWidth ofDividerAtIndex:0];
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
- (void)layoutSplitView
|
|
838
|
+
{
|
|
839
|
+
CGRect bounds = [self currentLayoutBounds];
|
|
840
|
+
_splitViewController.view.frame = bounds;
|
|
841
|
+
_splitViewController.splitView.frame = bounds;
|
|
842
|
+
[self updateSidebarCollapsed];
|
|
843
|
+
if (_contentContainer.bounds.size.width <= 0 ||
|
|
844
|
+
_contentContainer.bounds.size.height <= 0 ||
|
|
845
|
+
fabs(_contentContainer.bounds.size.height - bounds.size.height) >= 0.5) {
|
|
846
|
+
[self applyEstimatedSplitViewLayoutForBounds:bounds layoutReady:NO];
|
|
847
|
+
}
|
|
848
|
+
[self applyDividerPositionForBounds:bounds];
|
|
849
|
+
[_splitViewController.splitView adjustSubviews];
|
|
850
|
+
[_splitViewController.view layoutSubtreeIfNeeded];
|
|
851
|
+
[self layoutContentTitlebarMaterial];
|
|
852
|
+
[self publishSplitViewLayoutAllowEstimatedReady:YES];
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
- (void)updateEventEmitter:(const EventEmitter::Shared &)eventEmitter
|
|
856
|
+
{
|
|
857
|
+
[super updateEventEmitter:eventEmitter];
|
|
858
|
+
|
|
859
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
860
|
+
[self publishSplitViewLayoutAllowEstimatedReady:NO];
|
|
861
|
+
});
|
|
862
|
+
}
|
|
863
|
+
#endif
|
|
864
|
+
|
|
865
|
+
- (void)mountChildComponentView:(RCTUIView<RCTComponentViewProtocol> *)childComponentView
|
|
866
|
+
index:(NSInteger)index
|
|
867
|
+
{
|
|
868
|
+
#if TARGET_OS_OSX
|
|
869
|
+
if (index == 0) {
|
|
870
|
+
[_sidebarReactView removeFromSuperview];
|
|
871
|
+
_sidebarReactView = childComponentView;
|
|
872
|
+
_sidebarReactLayoutMetrics = EmptyLayoutMetrics;
|
|
873
|
+
childComponentView.hidden = YES;
|
|
874
|
+
[_sidebarContainer addSubview:childComponentView];
|
|
875
|
+
if (_sidebarContainer.bounds.size.width <= 0 || _sidebarContainer.bounds.size.height <= 0) {
|
|
876
|
+
[self applyEstimatedSplitViewLayoutForBounds:[self currentLayoutBounds] layoutReady:NO];
|
|
877
|
+
} else {
|
|
878
|
+
[self syncReactSubview:_sidebarReactView
|
|
879
|
+
nativeBounds:_sidebarContainer.bounds
|
|
880
|
+
previousLayoutMetrics:&_sidebarReactLayoutMetrics];
|
|
881
|
+
}
|
|
882
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
883
|
+
[self publishSplitViewLayoutAllowEstimatedReady:NO];
|
|
884
|
+
});
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
if (index == 1) {
|
|
889
|
+
[_contentReactView removeFromSuperview];
|
|
890
|
+
_contentReactView = childComponentView;
|
|
891
|
+
_contentReactLayoutMetrics = EmptyLayoutMetrics;
|
|
892
|
+
childComponentView.hidden = YES;
|
|
893
|
+
[_contentContainer addSubview:childComponentView];
|
|
894
|
+
if (_contentContainer.bounds.size.width <= 0 || _contentContainer.bounds.size.height <= 0) {
|
|
895
|
+
[self applyEstimatedSplitViewLayoutForBounds:[self currentLayoutBounds] layoutReady:NO];
|
|
896
|
+
} else {
|
|
897
|
+
[self syncReactSubview:_contentReactView
|
|
898
|
+
nativeBounds:_contentContainer.bounds
|
|
899
|
+
previousLayoutMetrics:&_contentReactLayoutMetrics];
|
|
900
|
+
}
|
|
901
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
902
|
+
[self publishSplitViewLayoutAllowEstimatedReady:NO];
|
|
903
|
+
});
|
|
904
|
+
return;
|
|
905
|
+
}
|
|
906
|
+
#else
|
|
907
|
+
if (index == 0) {
|
|
908
|
+
[_sidebarContainer addSubview:childComponentView];
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
if (index == 1) {
|
|
913
|
+
[_contentContainer addSubview:childComponentView];
|
|
914
|
+
return;
|
|
915
|
+
}
|
|
916
|
+
#endif
|
|
917
|
+
|
|
918
|
+
[super mountChildComponentView:childComponentView index:index];
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
- (void)unmountChildComponentView:(RCTUIView<RCTComponentViewProtocol> *)childComponentView
|
|
922
|
+
index:(NSInteger)index
|
|
923
|
+
{
|
|
924
|
+
#if TARGET_OS_OSX
|
|
925
|
+
if (childComponentView == _sidebarReactView) {
|
|
926
|
+
_sidebarReactView = nil;
|
|
927
|
+
_sidebarReactLayoutMetrics = EmptyLayoutMetrics;
|
|
928
|
+
[childComponentView removeFromSuperview];
|
|
929
|
+
return;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
if (childComponentView == _contentReactView) {
|
|
933
|
+
_contentReactView = nil;
|
|
934
|
+
_contentReactLayoutMetrics = EmptyLayoutMetrics;
|
|
935
|
+
[childComponentView removeFromSuperview];
|
|
936
|
+
return;
|
|
937
|
+
}
|
|
938
|
+
#else
|
|
939
|
+
if (index == 0 || index == 1) {
|
|
940
|
+
[childComponentView removeFromSuperview];
|
|
941
|
+
return;
|
|
942
|
+
}
|
|
943
|
+
#endif
|
|
944
|
+
|
|
945
|
+
[super unmountChildComponentView:childComponentView index:index];
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
|
|
949
|
+
{
|
|
950
|
+
const auto &newProps = *std::static_pointer_cast<SidebarSplitViewProps const>(props);
|
|
951
|
+
|
|
952
|
+
#if TARGET_OS_OSX
|
|
953
|
+
NSString *nextAppearanceName = [NSString stringWithUTF8String:newProps.appearance.c_str()];
|
|
954
|
+
if (nextAppearanceName.length == 0) {
|
|
955
|
+
nextAppearanceName = @"system";
|
|
956
|
+
}
|
|
957
|
+
BOOL shouldRelayout =
|
|
958
|
+
fabs(_sidebarMinWidth - newProps.sidebarMinWidth) >= 0.5 ||
|
|
959
|
+
fabs(_sidebarWidth - newProps.sidebarWidth) >= 0.5 ||
|
|
960
|
+
fabs(_contentMinWidth - newProps.contentMinWidth) >= 0.5 ||
|
|
961
|
+
_sidebarCollapsed != newProps.sidebarCollapsed ||
|
|
962
|
+
fabs(_contentTitlebarHeight - newProps.contentTitlebarHeight) >= 0.5;
|
|
963
|
+
NSString *nextContentTitlebarMaterialName = [NSString stringWithUTF8String:newProps.contentTitlebarMaterial.c_str()];
|
|
964
|
+
if (nextContentTitlebarMaterialName.length == 0) {
|
|
965
|
+
nextContentTitlebarMaterialName = @"none";
|
|
966
|
+
}
|
|
967
|
+
NSString *nextContentTitlebarOverlayColorValue = [NSString stringWithUTF8String:newProps.contentTitlebarOverlayColor.c_str()];
|
|
968
|
+
if (nextContentTitlebarOverlayColorValue.length == 0) {
|
|
969
|
+
nextContentTitlebarOverlayColorValue = nil;
|
|
970
|
+
}
|
|
971
|
+
CGFloat nextContentTitlebarOverlayOpacity = RNSidebarSplitViewClampedUnitValue(newProps.contentTitlebarOverlayOpacity);
|
|
972
|
+
NSString *nextSidebarTitlebarOverlayColorValue = [NSString stringWithUTF8String:newProps.sidebarTitlebarOverlayColor.c_str()];
|
|
973
|
+
if (nextSidebarTitlebarOverlayColorValue.length == 0) {
|
|
974
|
+
nextSidebarTitlebarOverlayColorValue = nil;
|
|
975
|
+
}
|
|
976
|
+
CGFloat nextSidebarTitlebarOverlayOpacity = RNSidebarSplitViewClampedUnitValue(newProps.sidebarTitlebarOverlayOpacity);
|
|
977
|
+
BOOL shouldRecreateContentTitlebarMaterial =
|
|
978
|
+
![_contentTitlebarMaterialName isEqualToString:nextContentTitlebarMaterialName] ||
|
|
979
|
+
!((_contentTitlebarOverlayColorValue == nextContentTitlebarOverlayColorValue) ||
|
|
980
|
+
[_contentTitlebarOverlayColorValue isEqualToString:nextContentTitlebarOverlayColorValue]) ||
|
|
981
|
+
fabs(_contentTitlebarOverlayOpacity - nextContentTitlebarOverlayOpacity) >= 0.001 ||
|
|
982
|
+
fabs(_contentTitlebarHeight - newProps.contentTitlebarHeight) >= 0.5;
|
|
983
|
+
BOOL shouldRecreateSidebarTitlebarMaterial =
|
|
984
|
+
!((_sidebarTitlebarOverlayColorValue == nextSidebarTitlebarOverlayColorValue) ||
|
|
985
|
+
[_sidebarTitlebarOverlayColorValue isEqualToString:nextSidebarTitlebarOverlayColorValue]) ||
|
|
986
|
+
fabs(_sidebarTitlebarOverlayOpacity - nextSidebarTitlebarOverlayOpacity) >= 0.001 ||
|
|
987
|
+
fabs(_contentTitlebarHeight - newProps.contentTitlebarHeight) >= 0.5;
|
|
988
|
+
_sidebarMinWidth = newProps.sidebarMinWidth;
|
|
989
|
+
_sidebarWidth = newProps.sidebarWidth;
|
|
990
|
+
_contentMinWidth = newProps.contentMinWidth;
|
|
991
|
+
_sidebarCollapsed = newProps.sidebarCollapsed;
|
|
992
|
+
_contentTitlebarHeight = newProps.contentTitlebarHeight;
|
|
993
|
+
_contentTitlebarMaterialName = nextContentTitlebarMaterialName;
|
|
994
|
+
_contentTitlebarOverlayColorValue = nextContentTitlebarOverlayColorValue;
|
|
995
|
+
_contentTitlebarOverlayOpacity = nextContentTitlebarOverlayOpacity;
|
|
996
|
+
_sidebarTitlebarOverlayColorValue = nextSidebarTitlebarOverlayColorValue;
|
|
997
|
+
_sidebarTitlebarOverlayOpacity = nextSidebarTitlebarOverlayOpacity;
|
|
998
|
+
if (shouldRecreateContentTitlebarMaterial) {
|
|
999
|
+
[self removeContentTitlebarMaterial];
|
|
1000
|
+
}
|
|
1001
|
+
if (shouldRecreateSidebarTitlebarMaterial) {
|
|
1002
|
+
[self removeSidebarTitlebarMaterial];
|
|
1003
|
+
}
|
|
1004
|
+
if (![_appearanceName isEqualToString:nextAppearanceName]) {
|
|
1005
|
+
_appearanceName = nextAppearanceName;
|
|
1006
|
+
[self applyAppearance];
|
|
1007
|
+
}
|
|
1008
|
+
[self updateSidebarCollapsed];
|
|
1009
|
+
[self updateSplitItemSizing];
|
|
1010
|
+
#endif
|
|
1011
|
+
|
|
1012
|
+
[super updateProps:props oldProps:oldProps];
|
|
1013
|
+
|
|
1014
|
+
#if TARGET_OS_OSX
|
|
1015
|
+
if (shouldRelayout || shouldRecreateContentTitlebarMaterial || shouldRecreateSidebarTitlebarMaterial) {
|
|
1016
|
+
_lastSidebarWidth = -1;
|
|
1017
|
+
_lastContentWidth = -1;
|
|
1018
|
+
_lastHeight = -1;
|
|
1019
|
+
_lastLayoutReady = NO;
|
|
1020
|
+
[self layoutSplitView];
|
|
1021
|
+
}
|
|
1022
|
+
#endif
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
- (void)updateLayoutMetrics:(const LayoutMetrics &)layoutMetrics
|
|
1026
|
+
oldLayoutMetrics:(const LayoutMetrics &)oldLayoutMetrics
|
|
1027
|
+
{
|
|
1028
|
+
[super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
|
|
1029
|
+
|
|
1030
|
+
#if TARGET_OS_OSX
|
|
1031
|
+
_currentLayoutMetrics = layoutMetrics;
|
|
1032
|
+
[self layoutSplitView];
|
|
1033
|
+
#else
|
|
1034
|
+
CGFloat sidebarWidth = self.bounds.size.width * 0.26;
|
|
1035
|
+
_sidebarContainer.frame = CGRectMake(0, 0, sidebarWidth, self.bounds.size.height);
|
|
1036
|
+
_contentContainer.frame = CGRectMake(sidebarWidth, 0, self.bounds.size.width - sidebarWidth, self.bounds.size.height);
|
|
1037
|
+
#endif
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
#if TARGET_OS_OSX
|
|
1041
|
+
- (void)layout
|
|
1042
|
+
{
|
|
1043
|
+
[super layout];
|
|
1044
|
+
|
|
1045
|
+
[self layoutSplitView];
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
- (void)setFrameSize:(NSSize)newSize
|
|
1049
|
+
{
|
|
1050
|
+
[super setFrameSize:newSize];
|
|
1051
|
+
|
|
1052
|
+
[self layoutSplitView];
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
- (void)viewDidMoveToWindow
|
|
1056
|
+
{
|
|
1057
|
+
[super viewDidMoveToWindow];
|
|
1058
|
+
|
|
1059
|
+
if (self.window) {
|
|
1060
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
1061
|
+
if (self.window) {
|
|
1062
|
+
[self layoutSplitView];
|
|
1063
|
+
}
|
|
1064
|
+
});
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
#endif
|
|
1068
|
+
|
|
1069
|
+
- (void)layoutSubviews
|
|
1070
|
+
{
|
|
1071
|
+
[super layoutSubviews];
|
|
1072
|
+
|
|
1073
|
+
#if TARGET_OS_OSX
|
|
1074
|
+
[self layoutSplitView];
|
|
1075
|
+
#else
|
|
1076
|
+
CGFloat sidebarWidth = self.bounds.size.width * 0.26;
|
|
1077
|
+
_sidebarContainer.frame = CGRectMake(0, 0, sidebarWidth, self.bounds.size.height);
|
|
1078
|
+
_contentContainer.frame = CGRectMake(sidebarWidth, 0, self.bounds.size.width - sidebarWidth, self.bounds.size.height);
|
|
1079
|
+
#endif
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
- (void)prepareForRecycle
|
|
1083
|
+
{
|
|
1084
|
+
[super prepareForRecycle];
|
|
1085
|
+
|
|
1086
|
+
#if TARGET_OS_OSX
|
|
1087
|
+
[_sidebarReactView removeFromSuperview];
|
|
1088
|
+
[_contentReactView removeFromSuperview];
|
|
1089
|
+
_sidebarReactView = nil;
|
|
1090
|
+
_contentReactView = nil;
|
|
1091
|
+
_currentLayoutMetrics = EmptyLayoutMetrics;
|
|
1092
|
+
_sidebarReactLayoutMetrics = EmptyLayoutMetrics;
|
|
1093
|
+
_contentReactLayoutMetrics = EmptyLayoutMetrics;
|
|
1094
|
+
_sidebarMinWidth = 180;
|
|
1095
|
+
_sidebarWidth = 0;
|
|
1096
|
+
_contentMinWidth = 320;
|
|
1097
|
+
_sidebarCollapsed = NO;
|
|
1098
|
+
_lastSidebarWidth = -1;
|
|
1099
|
+
_lastContentWidth = -1;
|
|
1100
|
+
_lastHeight = -1;
|
|
1101
|
+
_lastLayoutReady = NO;
|
|
1102
|
+
_appearanceName = @"system";
|
|
1103
|
+
_didPublishMount = NO;
|
|
1104
|
+
_contentTitlebarHeight = 0;
|
|
1105
|
+
_contentTitlebarMaterialName = @"none";
|
|
1106
|
+
_contentTitlebarOverlayColorValue = nil;
|
|
1107
|
+
_contentTitlebarOverlayOpacity = 0;
|
|
1108
|
+
_sidebarTitlebarOverlayColorValue = nil;
|
|
1109
|
+
_sidebarTitlebarOverlayOpacity = 0;
|
|
1110
|
+
[self removeContentTitlebarMaterial];
|
|
1111
|
+
[self removeSidebarTitlebarMaterial];
|
|
1112
|
+
[self applyAppearance];
|
|
1113
|
+
[self updateSidebarCollapsed];
|
|
1114
|
+
[self updateSplitItemSizing];
|
|
1115
|
+
#else
|
|
1116
|
+
for (UIView *subview in _sidebarContainer.subviews) {
|
|
1117
|
+
[subview removeFromSuperview];
|
|
1118
|
+
}
|
|
1119
|
+
for (UIView *subview in _contentContainer.subviews) {
|
|
1120
|
+
[subview removeFromSuperview];
|
|
1121
|
+
}
|
|
1122
|
+
#endif
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
- (void)dealloc
|
|
1126
|
+
{
|
|
1127
|
+
#if TARGET_OS_OSX
|
|
1128
|
+
if (_resizeObserver) {
|
|
1129
|
+
[[NSNotificationCenter defaultCenter] removeObserver:_resizeObserver];
|
|
1130
|
+
}
|
|
1131
|
+
#endif
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
|
1135
|
+
{
|
|
1136
|
+
return concreteComponentDescriptorProvider<SidebarSplitViewComponentDescriptor>();
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
@end
|
|
1140
|
+
|
|
1141
|
+
#if TARGET_OS_OSX
|
|
1142
|
+
// Optional C entry points let the host and window manager share this lifecycle
|
|
1143
|
+
// without requiring apps that do not use split views to link this package.
|
|
1144
|
+
extern "C" void LegendPrepareSidebarSplitViewStartup(NSWindow *window, NSDictionary *configuration)
|
|
1145
|
+
{
|
|
1146
|
+
if (![configuration isKindOfClass:NSDictionary.class] ||
|
|
1147
|
+
objc_getAssociatedObject(window, &RNSidebarSplitViewStartupKey)) {
|
|
1148
|
+
return;
|
|
1149
|
+
}
|
|
1150
|
+
RNSidebarSplitViewStartupView *view = [[RNSidebarSplitViewStartupView alloc]
|
|
1151
|
+
initWithFrame:window.contentView.bounds configuration:configuration];
|
|
1152
|
+
objc_setAssociatedObject(window, &RNSidebarSplitViewStartupKey, view, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
1153
|
+
window.appearance = view.appearance;
|
|
1154
|
+
[window.contentView addSubview:view];
|
|
1155
|
+
[window.contentView layoutSubtreeIfNeeded];
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
extern "C" BOOL LegendAttachSidebarSplitViewStartupRoot(NSWindow *window, NSView *rootView,
|
|
1159
|
+
void (^installRoot)(void))
|
|
1160
|
+
{
|
|
1161
|
+
RNSidebarSplitViewStartupView *view = objc_getAssociatedObject(window, &RNSidebarSplitViewStartupKey);
|
|
1162
|
+
if (!view) {
|
|
1163
|
+
return NO;
|
|
1164
|
+
}
|
|
1165
|
+
view.installReactRoot = installRoot;
|
|
1166
|
+
// The split panes own their backgrounds. Do not carry the host's temporary
|
|
1167
|
+
// solid startup fill underneath AppKit's floating sidebar after the swap.
|
|
1168
|
+
if ([rootView respondsToSelector:@selector(setBackgroundColor:)]) {
|
|
1169
|
+
[(RCTUIView *)rootView setBackgroundColor:NSColor.clearColor];
|
|
1170
|
+
}
|
|
1171
|
+
rootView.layer.backgroundColor = NSColor.clearColor.CGColor;
|
|
1172
|
+
rootView.frame = window.contentView.bounds;
|
|
1173
|
+
[window.contentView addSubview:rootView positioned:NSWindowBelow relativeTo:view];
|
|
1174
|
+
return YES;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
extern "C" void LegendFinishSidebarSplitViewStartup(NSWindow *window)
|
|
1178
|
+
{
|
|
1179
|
+
RNSidebarSplitViewStartupView *view = objc_getAssociatedObject(window, &RNSidebarSplitViewStartupKey);
|
|
1180
|
+
[view finish];
|
|
1181
|
+
}
|
|
1182
|
+
#endif
|