@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.
Files changed (399) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -4
  3. package/ai-codex.ts +1 -0
  4. package/ai.ts +1 -0
  5. package/app-documents.ts +1 -0
  6. package/config-plugin.d.cts +2 -0
  7. package/contracts.ts +2 -0
  8. package/diagnostics.ts +1 -0
  9. package/expo-config.d.cts +1 -0
  10. package/metro.cjs +4 -1
  11. package/metro.d.cts +12 -0
  12. package/native.cjs +3 -1
  13. package/native.d.cts +6 -0
  14. package/package.json +82 -14
  15. package/schema.json +276 -58
  16. package/settings-observable.ts +1 -0
  17. package/settings-window.ts +1 -0
  18. package/shortcuts-commands.ts +1 -0
  19. package/shortcuts-keyboard.ts +3 -0
  20. package/ui-classnames.ts +1 -0
  21. package/ui-glass.ts +1 -0
  22. package/ui-search.ts +1 -0
  23. package/ui-sidebar.ts +1 -0
  24. package/ui-split-view.ts +1 -0
  25. package/ui-symbol.ts +1 -0
  26. package/vendor/node_modules/@legendapp/spark-ai/package.json +19 -0
  27. package/vendor/node_modules/@legendapp/spark-ai/src/availability.ts +17 -0
  28. package/vendor/node_modules/@legendapp/spark-ai/src/index.ts +15 -0
  29. package/vendor/node_modules/@legendapp/spark-ai/src/invocations.ts +34 -0
  30. package/vendor/node_modules/@legendapp/spark-ai/src/output.ts +62 -0
  31. package/vendor/node_modules/@legendapp/spark-ai/src/run.ts +12 -0
  32. package/vendor/node_modules/@legendapp/spark-ai/src/types.ts +16 -0
  33. package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.h +2 -1
  34. package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.mm +126 -24
  35. package/vendor/node_modules/@legendapp/spark-audio/package.json +5 -2
  36. package/vendor/node_modules/@legendapp/spark-audio/src/NativeSparkAudio.ts +5 -1
  37. package/vendor/node_modules/@legendapp/spark-audio/src/desktop.ts +36 -32
  38. package/vendor/node_modules/@legendapp/spark-audio/src/events.ts +11 -0
  39. package/vendor/node_modules/@legendapp/spark-audio/src/hooks.ts +65 -0
  40. package/vendor/node_modules/@legendapp/spark-audio/src/index.web.ts +92 -33
  41. package/vendor/node_modules/@legendapp/spark-audio/src/media-session-unavailable.ts +6 -4
  42. package/vendor/node_modules/@legendapp/spark-audio/src/media-session.ts +52 -19
  43. package/vendor/node_modules/@legendapp/spark-audio/src/media-session.web.ts +18 -10
  44. package/vendor/node_modules/@legendapp/spark-audio/src/media-types.ts +40 -13
  45. package/vendor/node_modules/@legendapp/spark-audio/src/mobile.ts +40 -32
  46. package/vendor/node_modules/@legendapp/spark-audio/src/player.ts +97 -0
  47. package/vendor/node_modules/@legendapp/spark-audio/src/status-listeners.ts +21 -15
  48. package/vendor/node_modules/@legendapp/spark-audio/src/types.ts +9 -4
  49. package/vendor/node_modules/@legendapp/spark-audio/windows/SparkAudio/SparkAudio.h +67 -20
  50. package/vendor/node_modules/@legendapp/spark-auth-session/package.json +4 -3
  51. package/vendor/node_modules/@legendapp/spark-auth-session/src/core.ts +60 -42
  52. package/vendor/node_modules/@legendapp/spark-auth-session/src/index.ts +28 -12
  53. package/vendor/node_modules/@legendapp/spark-auth-session/src/mobile.ts +97 -41
  54. package/vendor/node_modules/@legendapp/spark-auth-session/src/types.ts +20 -9
  55. package/vendor/node_modules/@legendapp/spark-cli/dist/add-desktop.js +50 -7
  56. package/vendor/node_modules/@legendapp/spark-cli/dist/build-mode.js +1 -1
  57. package/vendor/node_modules/@legendapp/spark-cli/dist/build.js +83 -48
  58. package/vendor/node_modules/@legendapp/spark-cli/dist/cli-arguments.js +60 -0
  59. package/vendor/node_modules/@legendapp/spark-cli/dist/commands.js +7 -2
  60. package/vendor/node_modules/@legendapp/spark-cli/dist/create.js +31 -5
  61. package/vendor/node_modules/@legendapp/spark-cli/dist/credentials.js +69 -23
  62. package/vendor/node_modules/@legendapp/spark-cli/dist/dev-command.js +12 -3
  63. package/vendor/node_modules/@legendapp/spark-cli/dist/dev.js +12 -9
  64. package/vendor/node_modules/@legendapp/spark-cli/dist/examples.js +1 -1
  65. package/vendor/node_modules/@legendapp/spark-cli/dist/expo-dev-patch.cjs +4 -2
  66. package/vendor/node_modules/@legendapp/spark-cli/dist/expo-metro.cjs +1 -1
  67. package/vendor/node_modules/@legendapp/spark-cli/dist/expo-node.js +3 -3
  68. package/vendor/node_modules/@legendapp/spark-cli/dist/index.js +10 -38
  69. package/vendor/node_modules/@legendapp/spark-cli/dist/local.js +1 -1
  70. package/vendor/node_modules/@legendapp/spark-cli/dist/metro.cjs +26 -5
  71. package/vendor/node_modules/@legendapp/spark-cli/dist/native-metadata.js +26 -0
  72. package/vendor/node_modules/@legendapp/spark-cli/dist/native-patch-preflight.js +84 -0
  73. package/vendor/node_modules/@legendapp/spark-cli/dist/native-preparation.js +88 -0
  74. package/vendor/node_modules/@legendapp/spark-cli/dist/notary-profiles.js +75 -0
  75. package/vendor/node_modules/@legendapp/spark-cli/dist/package.js +4 -2
  76. package/vendor/node_modules/@legendapp/spark-cli/dist/platform.js +16 -2
  77. package/vendor/node_modules/@legendapp/spark-cli/dist/project.js +66 -13
  78. package/vendor/node_modules/@legendapp/spark-cli/dist/release.js +84 -4
  79. package/vendor/node_modules/@legendapp/spark-cli/dist/release.json +23 -18
  80. package/vendor/node_modules/@legendapp/spark-cli/dist/runner-install.js +145 -31
  81. package/vendor/node_modules/@legendapp/spark-cli/dist/signing.js +4 -3
  82. package/vendor/node_modules/@legendapp/spark-cli/dist/updates.js +41 -4
  83. package/vendor/node_modules/@legendapp/spark-cli/dist/windows.js +4 -1
  84. package/vendor/node_modules/@legendapp/spark-cli/package.json +7 -6
  85. package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/App.tsx +6 -12
  86. package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/desktop.config.json +5 -3
  87. package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/package.json +11 -9
  88. package/vendor/node_modules/@legendapp/spark-cli/templates/diff-lite/Git.macos.tsx +2 -2
  89. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.macos.tsx +23 -21
  90. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.windows.tsx +23 -21
  91. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.desktop.ts +11 -8
  92. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.macos.ts +3 -3
  93. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/Lifecycle.desktop.tsx +8 -14
  94. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/OpenFiles.desktop.tsx +5 -10
  95. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.desktop.ts +11 -8
  96. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.macos.ts +3 -3
  97. package/vendor/node_modules/@legendapp/spark-cli/templates/music-lite/assets.desktop.ts +2 -2
  98. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Activation.desktop.tsx +2 -2
  99. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Desktop.desktop.ts +37 -15
  100. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/session.ts +5 -6
  101. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/window-session.ts +5 -4
  102. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/desktop.config.json +5 -3
  103. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/metro.config.js +1 -1
  104. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/package.json +13 -11
  105. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/react-native.config.js +1 -1
  106. package/vendor/node_modules/@legendapp/spark-cli/templates/windows/package.json +13 -11
  107. package/vendor/node_modules/@legendapp/spark-cli/templates/windows/react-native.config.js +1 -1
  108. package/vendor/node_modules/@legendapp/spark-clipboard/macos/RNDesktopClipboard.mm +10 -16
  109. package/vendor/node_modules/@legendapp/spark-clipboard/package.json +2 -2
  110. package/vendor/node_modules/@legendapp/spark-clipboard/src/NativeDesktopClipboard.ts +1 -1
  111. package/vendor/node_modules/@legendapp/spark-clipboard/src/desktop.ts +55 -31
  112. package/vendor/node_modules/@legendapp/spark-clipboard/src/expo.ts +21 -11
  113. package/vendor/node_modules/@legendapp/spark-clipboard/src/options.ts +8 -0
  114. package/vendor/node_modules/@legendapp/spark-clipboard/src/types.ts +10 -0
  115. package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.h +38 -15
  116. package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.vcxproj +2 -0
  117. package/vendor/node_modules/@legendapp/spark-codex/RNCodex.podspec +22 -0
  118. package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.hpp +23 -0
  119. package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.mm +1529 -0
  120. package/vendor/node_modules/@legendapp/spark-codex/nitro.json +21 -0
  121. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/.gitattributes +1 -0
  122. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex+autolinking.rb +62 -0
  123. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.cpp +17 -0
  124. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.hpp +27 -0
  125. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Umbrella.hpp +38 -0
  126. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.mm +35 -0
  127. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.swift +16 -0
  128. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexAvailability.hpp +95 -0
  129. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexRunResult.hpp +99 -0
  130. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.cpp +24 -0
  131. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.hpp +71 -0
  132. package/vendor/node_modules/@legendapp/spark-codex/package.json +35 -0
  133. package/vendor/node_modules/@legendapp/spark-codex/react-native.config.js +11 -0
  134. package/vendor/node_modules/@legendapp/spark-codex/src/Codex.nitro.ts +30 -0
  135. package/vendor/node_modules/@legendapp/spark-codex/src/index.ts +65 -0
  136. package/vendor/node_modules/@legendapp/spark-codex/src/native.ts +6 -0
  137. package/vendor/node_modules/@legendapp/spark-commands/package.json +21 -0
  138. package/vendor/node_modules/@legendapp/spark-commands/src/bindings.ts +90 -0
  139. package/vendor/node_modules/@legendapp/spark-commands/src/index.tsx +400 -0
  140. package/vendor/node_modules/@legendapp/spark-commands/src/router.ts +138 -0
  141. package/vendor/node_modules/@legendapp/spark-commands/src/storage.ts +20 -0
  142. package/vendor/node_modules/@legendapp/spark-context-menu/macos/RNContextMenu.mm +7 -8
  143. package/vendor/node_modules/@legendapp/spark-context-menu/package.json +4 -3
  144. package/vendor/node_modules/@legendapp/spark-context-menu/src/NativeContextMenu.ts +1 -1
  145. package/vendor/node_modules/@legendapp/spark-context-menu/src/index.ts +26 -26
  146. package/vendor/node_modules/@legendapp/spark-context-menu/windows/SparkContextMenu/SparkContextMenu.h +3 -2
  147. package/vendor/node_modules/@legendapp/spark-desktop-app/RNDesktopApp.podspec +2 -1
  148. package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryJSI.hpp +89 -0
  149. package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryWindows.hpp +22 -0
  150. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/RNDesktopApp.mm +13 -7
  151. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkBinaryJSI.h +48 -0
  152. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.h +4 -0
  153. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.mm +33 -33
  154. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktopError.h +20 -0
  155. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.h +26 -0
  156. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.mm +49 -0
  157. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.h +9 -0
  158. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.mm +70 -0
  159. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkWindow.mm +9 -6
  160. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/recent-documents/RNRecentDocumentController.mm +55 -0
  161. package/vendor/node_modules/@legendapp/spark-desktop-app/package.json +5 -3
  162. package/vendor/node_modules/@legendapp/spark-desktop-app/src/NativeDesktopApp.ts +1 -1
  163. package/vendor/node_modules/@legendapp/spark-desktop-app/src/api.ts +86 -40
  164. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/accelerator.ts +40 -0
  165. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/index.ts +56 -0
  166. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/menu.ts +114 -0
  167. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/native-buffer.ts +22 -0
  168. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/path.ts +24 -0
  169. package/vendor/node_modules/@legendapp/spark-desktop-app/src/events.ts +75 -0
  170. package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.ts +2 -0
  171. package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.windows.ts +2 -0
  172. package/vendor/node_modules/@legendapp/spark-desktop-app/src/open-requests.ts +43 -0
  173. package/vendor/node_modules/@legendapp/spark-desktop-app/src/restoration.ts +11 -0
  174. package/vendor/node_modules/@legendapp/spark-desktop-app/src/transport.ts +10 -0
  175. package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.cjs +10 -5
  176. package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.d.cts +3 -0
  177. package/vendor/node_modules/@legendapp/spark-desktop-config/autolinking.cjs +35 -0
  178. package/vendor/node_modules/@legendapp/spark-desktop-config/config.cjs +16 -3
  179. package/vendor/node_modules/@legendapp/spark-desktop-config/config.d.cts +89 -9
  180. package/vendor/node_modules/@legendapp/spark-desktop-config/expo.d.cts +3 -0
  181. package/vendor/node_modules/@legendapp/spark-desktop-config/identity.cjs +3 -2
  182. package/vendor/node_modules/@legendapp/spark-desktop-config/lifecycle.cjs +20 -0
  183. package/vendor/node_modules/@legendapp/spark-desktop-config/package.json +6 -5
  184. package/vendor/node_modules/@legendapp/spark-desktop-config/schema.json +276 -58
  185. package/vendor/node_modules/@legendapp/spark-desktop-config/updates.cjs +1 -0
  186. package/vendor/node_modules/@legendapp/spark-desktop-config/validation.cjs +35 -0
  187. package/vendor/node_modules/@legendapp/spark-desktop-config/windows.plugin.cjs +2 -1
  188. package/vendor/node_modules/@legendapp/spark-desktop-host/AppDelegate.mm +129 -11
  189. package/vendor/node_modules/@legendapp/spark-desktop-host/package.json +2 -2
  190. package/vendor/node_modules/@legendapp/spark-desktop-host/windows/application.inc +277 -121
  191. package/vendor/node_modules/@legendapp/spark-desktop-links/common/AuthLoopback.h +5 -7
  192. package/vendor/node_modules/@legendapp/spark-desktop-links/macos/RNDesktopLinks.mm +10 -9
  193. package/vendor/node_modules/@legendapp/spark-desktop-links/package.json +2 -2
  194. package/vendor/node_modules/@legendapp/spark-desktop-links/src/NativeDesktopLinks.ts +1 -1
  195. package/vendor/node_modules/@legendapp/spark-desktop-links/src/api.ts +27 -33
  196. package/vendor/node_modules/@legendapp/spark-desktop-links/src/expo.ts +3 -4
  197. package/vendor/node_modules/@legendapp/spark-desktop-links/src/native.ts +9 -0
  198. package/vendor/node_modules/@legendapp/spark-desktop-links/windows/SparkLinks/SparkLinks.h +22 -22
  199. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/RNDesktopShortcuts.podspec +1 -0
  200. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/RNDesktopShortcuts.mm +1 -1
  201. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.h +9 -0
  202. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.mm +307 -0
  203. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/package.json +8 -5
  204. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/NativeDesktopShortcuts.ts +1 -1
  205. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/api.ts +39 -14
  206. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/NativeKeyboardManager.ts +12 -0
  207. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/codes.ts +108 -0
  208. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/index.ts +99 -0
  209. package/vendor/node_modules/@legendapp/spark-desktop-windows/RNDesktopWindows.podspec +2 -0
  210. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/RNDesktopWindows.mm +229 -103
  211. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/SparkWindowGeometry.h +63 -0
  212. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.h +20 -0
  213. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.mm +27 -0
  214. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.h +12 -0
  215. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.mm +3130 -0
  216. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManagerStartup.mm +31 -0
  217. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/SidebarStartupFallbacks.mm +14 -0
  218. package/vendor/node_modules/@legendapp/spark-desktop-windows/package.json +10 -6
  219. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/NativeDesktopWindowManager.ts +1 -1
  220. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/api.ts +144 -70
  221. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/diagnostics.ts +17 -0
  222. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.ts +3 -1
  223. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.windows.ts +3 -1
  224. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos-adapter.ts +53 -0
  225. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos.ts +51 -0
  226. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/transport.ts +41 -0
  227. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/types.ts +140 -0
  228. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/validation.ts +162 -0
  229. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/window-manager/NativeWindowManager.ts +28 -0
  230. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/WindowProvider.tsx +20 -0
  231. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/createWindowsNavigator.tsx +78 -0
  232. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/index.ts +6 -0
  233. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/primaryWindowLifecycle.ts +34 -0
  234. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/types.ts +11 -0
  235. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/usePrimaryWindowLifecycle.ts +18 -0
  236. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/useWindowFocusEffect.ts +17 -0
  237. package/vendor/node_modules/@legendapp/spark-documents/package.json +22 -0
  238. package/vendor/node_modules/@legendapp/spark-documents/src/controller.ts +97 -0
  239. package/vendor/node_modules/@legendapp/spark-documents/src/documentTransition.ts +13 -0
  240. package/vendor/node_modules/@legendapp/spark-documents/src/hooks.ts +139 -0
  241. package/vendor/node_modules/@legendapp/spark-documents/src/index.tsx +50 -0
  242. package/vendor/node_modules/@legendapp/spark-documents/src/reload.ts +39 -0
  243. package/vendor/node_modules/@legendapp/spark-documents/src/requests.ts +15 -0
  244. package/vendor/node_modules/@legendapp/spark-drag-drop/package.json +4 -3
  245. package/vendor/node_modules/@legendapp/spark-drag-drop/src/DesktopDragViewNativeComponent.ts +1 -1
  246. package/vendor/node_modules/@legendapp/spark-drag-drop/src/contracts.ts +73 -18
  247. package/vendor/node_modules/@legendapp/spark-drag-drop/src/index.tsx +58 -15
  248. package/vendor/node_modules/@legendapp/spark-drag-drop/windows/SparkDragDrop/SparkDragDrop.h +14 -8
  249. package/vendor/node_modules/@legendapp/spark-file-dialog/ios/RNFileDialog.mm +34 -121
  250. package/vendor/node_modules/@legendapp/spark-file-dialog/package.json +12 -5
  251. package/vendor/node_modules/@legendapp/spark-file-dialog/src/NativeFileDialog.ts +1 -5
  252. package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.ts +19 -84
  253. package/vendor/node_modules/@legendapp/spark-file-dialog/src/native.ts +12 -0
  254. package/vendor/node_modules/@legendapp/spark-file-dialog/src/options.ts +34 -14
  255. package/vendor/node_modules/@legendapp/spark-file-dialog/src/types.ts +26 -0
  256. package/vendor/node_modules/@legendapp/spark-file-dialog/windows/SparkFileDialog/SparkFileDialog.h +42 -58
  257. package/vendor/node_modules/@legendapp/spark-file-system/RNDesktopFileSystem.podspec +1 -0
  258. package/vendor/node_modules/@legendapp/spark-file-system/macos/RNDesktopFileSystem.mm +32 -21
  259. package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.h +24 -0
  260. package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.mm +215 -0
  261. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.h +9 -0
  262. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.mm +82 -0
  263. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.h +47 -0
  264. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.mm +306 -0
  265. package/vendor/node_modules/@legendapp/spark-file-system/package.json +8 -6
  266. package/vendor/node_modules/@legendapp/spark-file-system/src/NativeDesktopFileSystem.ts +1 -1
  267. package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/NativeFileScanner.ts +11 -0
  268. package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/index.ts +93 -0
  269. package/vendor/node_modules/@legendapp/spark-file-system/src/handles.ts +48 -14
  270. package/vendor/node_modules/@legendapp/spark-file-system/src/index.ts +134 -45
  271. package/vendor/node_modules/@legendapp/spark-file-system/src/path.ts +1 -9
  272. package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.h +102 -26
  273. package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.vcxproj +2 -0
  274. package/vendor/node_modules/@legendapp/spark-global-shortcuts/RNDesktopGlobalShortcuts.podspec +1 -0
  275. package/vendor/node_modules/@legendapp/spark-global-shortcuts/macos/RNDesktopGlobalShortcuts.mm +7 -4
  276. package/vendor/node_modules/@legendapp/spark-global-shortcuts/package.json +4 -3
  277. package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/NativeDesktopGlobalShortcuts.ts +1 -1
  278. package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/index.ts +39 -10
  279. package/vendor/node_modules/@legendapp/spark-global-shortcuts/windows/SparkGlobalShortcuts/SparkGlobalShortcuts.h +5 -4
  280. package/vendor/node_modules/@legendapp/spark-message-dialog/macos/RNDesktopMessageDialog.mm +2 -2
  281. package/vendor/node_modules/@legendapp/spark-message-dialog/package.json +2 -2
  282. package/vendor/node_modules/@legendapp/spark-message-dialog/src/NativeDesktopMessageDialog.ts +1 -1
  283. package/vendor/node_modules/@legendapp/spark-message-dialog/src/index.ts +48 -11
  284. package/vendor/node_modules/@legendapp/spark-native-menu/ios/RNNativeMenu.mm +141 -609
  285. package/vendor/node_modules/@legendapp/spark-native-menu/package.json +9 -4
  286. package/vendor/node_modules/@legendapp/spark-native-menu/src/NativeMenu.ts +2 -7
  287. package/vendor/node_modules/@legendapp/spark-native-menu/src/api.ts +76 -121
  288. package/vendor/node_modules/@legendapp/spark-native-menu/src/hooks.ts +97 -0
  289. package/vendor/node_modules/@legendapp/spark-native-menu/src/windows-menus.ts +43 -37
  290. package/vendor/node_modules/@legendapp/spark-notifications/macos/RNDesktopNotifications.mm +75 -30
  291. package/vendor/node_modules/@legendapp/spark-notifications/package.json +2 -2
  292. package/vendor/node_modules/@legendapp/spark-notifications/src/NativeDesktopNotifications.ts +1 -1
  293. package/vendor/node_modules/@legendapp/spark-notifications/src/index.ts +130 -42
  294. package/vendor/node_modules/@legendapp/spark-notifications/windows/SparkNotifications/SparkNotifications.h +46 -8
  295. package/vendor/node_modules/@legendapp/spark-processes/macos/RNDesktopProcesses.mm +94 -21
  296. package/vendor/node_modules/@legendapp/spark-processes/package.json +4 -3
  297. package/vendor/node_modules/@legendapp/spark-processes/src/NativeDesktopProcesses.ts +1 -1
  298. package/vendor/node_modules/@legendapp/spark-processes/src/index.ts +124 -28
  299. package/vendor/node_modules/@legendapp/spark-processes/src/types.ts +34 -0
  300. package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.h +83 -34
  301. package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.vcxproj +2 -0
  302. package/vendor/node_modules/@legendapp/spark-secure-storage/macos/RNDesktopSecureStorage.mm +49 -40
  303. package/vendor/node_modules/@legendapp/spark-secure-storage/package.json +2 -2
  304. package/vendor/node_modules/@legendapp/spark-secure-storage/src/NativeDesktopSecureStorage.ts +1 -1
  305. package/vendor/node_modules/@legendapp/spark-secure-storage/src/desktop.ts +16 -14
  306. package/vendor/node_modules/@legendapp/spark-secure-storage/src/expo.ts +0 -1
  307. package/vendor/node_modules/@legendapp/spark-secure-storage/src/options.ts +3 -2
  308. package/vendor/node_modules/@legendapp/spark-secure-storage/src/unavailable.ts +6 -3
  309. package/vendor/node_modules/@legendapp/spark-settings/package.json +10 -3
  310. package/vendor/node_modules/@legendapp/spark-settings/src/fileStorage.ts +11 -0
  311. package/vendor/node_modules/@legendapp/spark-settings/src/index.ts +7 -9
  312. package/vendor/node_modules/@legendapp/spark-settings/src/storage/index.ts +142 -0
  313. package/vendor/node_modules/@legendapp/spark-settings/src/store.ts +63 -21
  314. package/vendor/node_modules/@legendapp/spark-settings-ui/package.json +20 -0
  315. package/vendor/node_modules/@legendapp/spark-settings-ui/src/index.tsx +436 -0
  316. package/vendor/node_modules/@legendapp/spark-settings-ui/src/options.ts +10 -0
  317. package/vendor/node_modules/@legendapp/spark-sqlite/package.json +3 -3
  318. package/vendor/node_modules/@legendapp/spark-sqlite/src/database.ts +182 -0
  319. package/vendor/node_modules/@legendapp/spark-sqlite/src/index.ts +19 -6
  320. package/vendor/node_modules/@legendapp/spark-sqlite/src/types.ts +22 -0
  321. package/vendor/node_modules/@legendapp/spark-system/macos/RNDesktopSystem.mm +36 -11
  322. package/vendor/node_modules/@legendapp/spark-system/package.json +2 -2
  323. package/vendor/node_modules/@legendapp/spark-system/src/NativeDesktopSystem.ts +1 -1
  324. package/vendor/node_modules/@legendapp/spark-system/src/index.ts +89 -32
  325. package/vendor/node_modules/@legendapp/spark-system/windows/SparkSystem/SparkSystem.h +8 -4
  326. package/vendor/node_modules/@legendapp/spark-tray/macos/RNDesktopTray.mm +20 -8
  327. package/vendor/node_modules/@legendapp/spark-tray/package.json +2 -2
  328. package/vendor/node_modules/@legendapp/spark-tray/src/NativeDesktopTray.ts +1 -1
  329. package/vendor/node_modules/@legendapp/spark-tray/src/index.ts +91 -34
  330. package/vendor/node_modules/@legendapp/spark-tray/windows/SparkTray/SparkTray.h +45 -15
  331. package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkButton.mm +2 -1
  332. package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkTextInput.mm +10 -2
  333. package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.h +15 -0
  334. package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.mm +1182 -0
  335. package/vendor/node_modules/@legendapp/spark-ui/macos/glass-effect-view/RNGlassEffectView.mm +72 -0
  336. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.h +15 -0
  337. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.mm +194 -0
  338. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.h +15 -0
  339. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.mm +180 -0
  340. package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.h +15 -0
  341. package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.mm +155 -0
  342. package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.h +18 -0
  343. package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.mm +645 -0
  344. package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.h +15 -0
  345. package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.mm +164 -0
  346. package/vendor/node_modules/@legendapp/spark-ui/package.json +16 -4
  347. package/vendor/node_modules/@legendapp/spark-ui/src/SparkSelectNativeComponent.ts +3 -1
  348. package/vendor/node_modules/@legendapp/spark-ui/src/SparkTextInputNativeComponent.ts +6 -2
  349. package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/SidebarSplitViewNativeComponent.ts +31 -0
  350. package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/index.tsx +77 -0
  351. package/vendor/node_modules/@legendapp/spark-ui/src/availability.ts +10 -0
  352. package/vendor/node_modules/@legendapp/spark-ui/src/classnames/index.ts +8 -0
  353. package/vendor/node_modules/@legendapp/spark-ui/src/control.ts +42 -0
  354. package/vendor/node_modules/@legendapp/spark-ui/src/desktop.tsx +56 -0
  355. package/vendor/node_modules/@legendapp/spark-ui/src/glass-effect-view/index.tsx +15 -0
  356. package/vendor/node_modules/@legendapp/spark-ui/src/index.android.tsx +35 -21
  357. package/vendor/node_modules/@legendapp/spark-ui/src/index.ios.tsx +55 -26
  358. package/vendor/node_modules/@legendapp/spark-ui/src/index.tsx +1 -27
  359. package/vendor/node_modules/@legendapp/spark-ui/src/index.web.tsx +45 -14
  360. package/vendor/node_modules/@legendapp/spark-ui/src/index.windows.tsx +1 -42
  361. package/vendor/node_modules/@legendapp/spark-ui/src/mobile-input.tsx +11 -0
  362. package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSegmentedControlNativeComponent.ts +17 -0
  363. package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSelectNativeComponent.ts +17 -0
  364. package/vendor/node_modules/@legendapp/spark-ui/src/select.ts +5 -3
  365. package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/SFSymbolNativeComponent.ts +13 -0
  366. package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/index.tsx +27 -0
  367. package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarItemNativeComponent.ts +25 -0
  368. package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarNativeComponent.ts +24 -0
  369. package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/index.tsx +104 -0
  370. package/vendor/node_modules/@legendapp/spark-ui/src/specialized.ts +22 -0
  371. package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/TextInputSearchNativeComponent.ts +33 -0
  372. package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/index.tsx +34 -0
  373. package/vendor/node_modules/@legendapp/spark-ui/src/types.ts +30 -19
  374. package/vendor/node_modules/@legendapp/spark-ui/uniwind.ts +3 -1
  375. package/vendor/node_modules/@legendapp/spark-ui/uniwind.web.ts +3 -1
  376. package/vendor/node_modules/@legendapp/spark-ui/windows/SparkUI/SparkUI.h +16 -11
  377. package/vendor/node_modules/@legendapp/spark-updates/macos/RNDesktopUpdates.mm +21 -8
  378. package/vendor/node_modules/@legendapp/spark-updates/package.json +2 -2
  379. package/vendor/node_modules/@legendapp/spark-updates/src/NativeDesktopUpdates.ts +3 -2
  380. package/vendor/node_modules/@legendapp/spark-updates/src/index.ts +71 -15
  381. package/vendor/node_modules/@legendapp/spark-webview/package.json +2 -2
  382. package/vendor/node_modules/@legendapp/spark-webview/src/WebView.tsx +11 -0
  383. package/vendor/node_modules/@legendapp/spark-webview/src/adapter.ts +55 -0
  384. package/vendor/node_modules/@legendapp/spark-webview/src/index.ts +2 -2
  385. package/vendor/node_modules/@legendapp/spark-webview/src/types.ts +32 -0
  386. package/vendor/node_modules/@legendapp/spark-webview/src/view-props.ts +28 -0
  387. package/vendor/node_modules/@legendapp/spark-window-options/index.cjs +51 -14
  388. package/vendor/node_modules/@legendapp/spark-window-options/index.d.ts +21 -8
  389. package/vendor/node_modules/@legendapp/spark-window-options/package.json +1 -1
  390. package/windows-macos.ts +1 -0
  391. package/expo-metro.cjs +0 -1
  392. package/message-dialog.ts +0 -1
  393. package/universal.cjs +0 -1
  394. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/accelerator.ts +0 -22
  395. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows-options.ts +0 -11
  396. package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.windows.ts +0 -15
  397. package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/accelerator.ts +0 -22
  398. package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkSelect.h +0 -4
  399. 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