@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,164 @@
1
+ #import "RNTextInputSearch.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
+ using namespace facebook::react;
9
+
10
+ #if TARGET_OS_OSX
11
+ static NSAppearance *RNTextInputSearchAppearanceForName(NSString *appearanceName)
12
+ {
13
+ if ([appearanceName isEqualToString:@"light"]) {
14
+ return [NSAppearance appearanceNamed:NSAppearanceNameAqua];
15
+ }
16
+
17
+ if ([appearanceName isEqualToString:@"dark"]) {
18
+ return [NSAppearance appearanceNamed:NSAppearanceNameDarkAqua];
19
+ }
20
+
21
+ return nil;
22
+ }
23
+
24
+ #endif
25
+
26
+ @interface RNTextInputSearch () <
27
+ #if TARGET_OS_OSX
28
+ NSSearchFieldDelegate,
29
+ #endif
30
+ RCTTextInputSearchViewProtocol
31
+ >
32
+ @end
33
+
34
+ @implementation RNTextInputSearch {
35
+ #if TARGET_OS_OSX
36
+ NSSearchField *_textField;
37
+ BOOL _hasSetDefaultText;
38
+ int _eventCount;
39
+ #else
40
+ UIView *_textField;
41
+ #endif
42
+ }
43
+
44
+ - (instancetype)init
45
+ {
46
+ if (self = [super init]) {
47
+ _props = std::make_shared<const TextInputSearchProps>();
48
+ #if TARGET_OS_OSX
49
+ _textField = [NSSearchField new];
50
+ _textField.delegate = self;
51
+ _textField.focusRingType = NSFocusRingTypeNone;
52
+ _textField.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
53
+ [self addSubview:_textField];
54
+ #else
55
+ _textField = [UIView new];
56
+ [self addSubview:_textField];
57
+ #endif
58
+ }
59
+ return self;
60
+ }
61
+
62
+ #if TARGET_OS_OSX
63
+ - (BOOL)isFlipped
64
+ {
65
+ return YES;
66
+ }
67
+
68
+ - (void)controlTextDidChange:(NSNotification *)notification
69
+ {
70
+ if (notification.object != _textField || !_textField.enabled) {
71
+ return;
72
+ }
73
+ ++_eventCount;
74
+ const auto eventEmitter = std::static_pointer_cast<const TextInputSearchEventEmitter>(_eventEmitter);
75
+ if (eventEmitter) {
76
+ eventEmitter->onChangeText(TextInputSearchEventEmitter::OnChangeText{
77
+ .text = _textField.stringValue.UTF8String ?: "",
78
+ .eventCount = _eventCount,
79
+ });
80
+ }
81
+ }
82
+ #endif
83
+
84
+ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
85
+ {
86
+ const auto &newProps = *std::static_pointer_cast<TextInputSearchProps const>(props);
87
+ #if TARGET_OS_OSX
88
+ NSString *appearanceName = [NSString stringWithUTF8String:newProps.appearance.c_str()];
89
+ NSAppearance *appearance = RNTextInputSearchAppearanceForName(appearanceName);
90
+ self.appearance = appearance;
91
+ _textField.appearance = appearance;
92
+
93
+ _textField.enabled = !newProps.disabled;
94
+ _textField.accessibilityLabel = [NSString stringWithUTF8String:newProps.accessibilityLabel.c_str()];
95
+ _textField.accessibilityIdentifier = [NSString stringWithUTF8String:newProps.testId.c_str()];
96
+ NSString *placeholder = [NSString stringWithUTF8String:newProps.placeholder.c_str()];
97
+ _textField.placeholderString = placeholder;
98
+
99
+ if (!_hasSetDefaultText) {
100
+ _textField.stringValue = [NSString stringWithUTF8String:newProps.defaultText.c_str()];
101
+ _hasSetDefaultText = YES;
102
+ }
103
+
104
+ if (newProps.controlled && newProps.eventCount >= _eventCount) {
105
+ NSString *text = [NSString stringWithUTF8String:newProps.text.c_str()];
106
+ if (![_textField.stringValue isEqualToString:text]) {
107
+ _textField.stringValue = text;
108
+ }
109
+ }
110
+ #endif
111
+ [super updateProps:props oldProps:oldProps];
112
+ }
113
+
114
+ - (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args
115
+ {
116
+ RCTTextInputSearchHandleCommand(self, commandName, args);
117
+ }
118
+
119
+ - (void)focus
120
+ {
121
+ #if TARGET_OS_OSX
122
+ if (_textField.enabled) [self.window makeFirstResponder:_textField];
123
+ #endif
124
+ }
125
+
126
+ - (void)blur
127
+ {
128
+ #if TARGET_OS_OSX
129
+ if (self.window.firstResponder == _textField || _textField.currentEditor == self.window.firstResponder) [self.window makeFirstResponder:nil];
130
+ #endif
131
+ }
132
+
133
+ - (void)prepareForRecycle
134
+ {
135
+ [super prepareForRecycle];
136
+ #if TARGET_OS_OSX
137
+ _textField.stringValue = @"";
138
+ _textField.placeholderString = @"";
139
+ [_textField abortEditing];
140
+ _hasSetDefaultText = NO; _eventCount = 0; _textField.enabled = YES;
141
+ _textField.accessibilityLabel = nil; _textField.accessibilityIdentifier = nil;
142
+ self.appearance = nil; _textField.appearance = nil;
143
+ #endif
144
+ }
145
+
146
+ - (void)layoutSubviews
147
+ {
148
+ [super layoutSubviews];
149
+ _textField.frame = self.bounds;
150
+ }
151
+
152
+ - (void)updateLayoutMetrics:(const LayoutMetrics &)layoutMetrics
153
+ oldLayoutMetrics:(const LayoutMetrics &)oldLayoutMetrics
154
+ {
155
+ [super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
156
+ [self layoutSubviews];
157
+ }
158
+
159
+ + (ComponentDescriptorProvider)componentDescriptorProvider
160
+ {
161
+ return concreteComponentDescriptorProvider<TextInputSearchComponentDescriptor>();
162
+ }
163
+
164
+ @end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/spark-ui",
3
- "version": "0.0.1-next.2",
3
+ "version": "0.0.1-next.3",
4
4
  "license": "MIT",
5
5
  "main": "src/index",
6
6
  "react-native": "src/index",
@@ -39,8 +39,15 @@
39
39
  "componentProvider": {
40
40
  "SparkButton": "RNSparkButton",
41
41
  "SparkTextInput": "RNSparkTextInput",
42
- "SparkSelect": "RNSparkSelect"
43
- }
42
+ "SidebarSplitView": "RNSidebarSplitViewComponent",
43
+ "Sidebar": "RNSidebar",
44
+ "SidebarItem": "RNSidebarItem",
45
+ "SFSymbol": "RNSFSymbol",
46
+ "NativeSelect": "RNNativeSelect",
47
+ "NativeSegmentedControl": "RNNativeSegmentedControl",
48
+ "TextInputSearch": "RNTextInputSearch"
49
+ },
50
+ "modulesProvider": {}
44
51
  },
45
52
  "windows": {
46
53
  "namespace": "FrameUICodegen",
@@ -57,5 +64,10 @@
57
64
  "windows"
58
65
  ]
59
66
  },
60
- "private": true
67
+ "private": true,
68
+ "dependencies": {
69
+ "clsx": "^2.1.1",
70
+ "tailwind-merge": "^3.4.0",
71
+ "@legendapp/spark-desktop-app": "0.0.1-next.3"
72
+ }
61
73
  }
@@ -1,9 +1,11 @@
1
1
  import type { HostComponent, ViewProps } from "react-native";
2
- import type { DirectEventHandler } from "react-native/Libraries/Types/CodegenTypes";
2
+ import type { DirectEventHandler, WithDefault, Int32 } from "react-native/Libraries/Types/CodegenTypes";
3
3
  import codegenNativeComponent from "react-native/Libraries/Utilities/codegenNativeComponent";
4
4
  export interface NativeProps extends ViewProps {
5
5
  onUnavailable?: DirectEventHandler<Readonly<{ message: string }>>;
6
6
  itemsJson: string;
7
+ disabled?: WithDefault<boolean, false>;
8
+ selectionRevision?: Int32;
7
9
  value: string;
8
10
  onSelectionChange?: DirectEventHandler<Readonly<{ value: string }>>;
9
11
  }
@@ -1,9 +1,13 @@
1
1
  import type { HostComponent, ViewProps } from "react-native";
2
- import type { DirectEventHandler } from "react-native/Libraries/Types/CodegenTypes";
2
+ import type { DirectEventHandler, WithDefault, Int32 } from "react-native/Libraries/Types/CodegenTypes";
3
3
  import codegenNativeComponent from "react-native/Libraries/Utilities/codegenNativeComponent";
4
4
  export interface NativeProps extends ViewProps {
5
5
  onUnavailable?: DirectEventHandler<Readonly<{ message: string }>>;
6
6
  defaultText?: string;
7
- onTextChange?: DirectEventHandler<Readonly<{ text: string }>>;
7
+ text?: string;
8
+ controlled?: WithDefault<boolean, false>;
9
+ disabled?: WithDefault<boolean, false>;
10
+ eventCount?: Int32;
11
+ onTextChange?: DirectEventHandler<Readonly<{ text: string; eventCount: Int32 }>>;
8
12
  }
9
13
  export default codegenNativeComponent<NativeProps>("SparkTextInput") as HostComponent<NativeProps>;
@@ -0,0 +1,31 @@
1
+ import type { HostComponent, ViewProps } from "react-native";
2
+ import { codegenNativeComponent } from "react-native";
3
+ import type { DirectEventHandler, Double } from "react-native/Libraries/Types/CodegenTypes";
4
+
5
+ export type SidebarSplitViewResizeEvent = Readonly<{
6
+ contentHeight: Double;
7
+ contentWidth: Double;
8
+ contentX: Double;
9
+ height: Double;
10
+ isLayoutReady: boolean;
11
+ isVertical: boolean;
12
+ sidebarHeight: Double;
13
+ sidebarWidth: Double;
14
+ }>;
15
+
16
+ export interface NativeProps extends ViewProps {
17
+ appearance?: string;
18
+ contentTitlebarHeight?: Double;
19
+ contentTitlebarMaterial?: string;
20
+ contentTitlebarOverlayColor?: string;
21
+ contentTitlebarOverlayOpacity?: Double;
22
+ contentMinWidth?: Double;
23
+ onSplitViewDidResize?: DirectEventHandler<SidebarSplitViewResizeEvent>;
24
+ sidebarCollapsed?: boolean;
25
+ sidebarMinWidth?: Double;
26
+ sidebarTitlebarOverlayColor?: string;
27
+ sidebarTitlebarOverlayOpacity?: Double;
28
+ sidebarWidth?: Double;
29
+ }
30
+
31
+ export default codegenNativeComponent<NativeProps>("SidebarSplitView") as HostComponent<NativeProps>;
@@ -0,0 +1,77 @@
1
+ import { useState, type ReactNode } from "react";
2
+ import { View, type NativeSyntheticEvent } from "react-native";
3
+ import { SparkError } from "@legendapp/spark-desktop-app/src/contracts";
4
+ import { useControl } from "../control";
5
+ import { appearance, callback, finite, macosViewAvailability, type SpecializedViewProps } from "../specialized";
6
+ import NativeSplitView from "./SidebarSplitViewNativeComponent";
7
+ export type SidebarSplitViewAppearance = "system" | "light" | "dark";
8
+ export type SidebarSplitViewTitlebarMaterial = "none" | "glass" | "titlebar" | "headerView" | "hudWindow" | "sidebar" | "windowBackground";
9
+ export interface SidebarSplitViewPaneMetrics { contentHeight: number; contentWidth: number; sidebarHeight: number; sidebarWidth: number }
10
+ export interface SidebarSplitViewResizeEvent extends SidebarSplitViewPaneMetrics { contentX: number; height: number; phase: "provisional" | "ready" }
11
+ export interface SplitViewTitleBarOverlay { color: string; opacity?: number }
12
+ export interface SplitViewTitleBarOptions {
13
+ content?: { height?: number; material?: SidebarSplitViewTitlebarMaterial; overlay?: SplitViewTitleBarOverlay };
14
+ sidebar?: { overlay?: SplitViewTitleBarOverlay };
15
+ }
16
+ export interface SidebarSplitViewProps extends Omit<SpecializedViewProps, "children"> {
17
+ sidebar: ReactNode;
18
+ content: ReactNode;
19
+ children?: never;
20
+ appearance?: SidebarSplitViewAppearance;
21
+ contentMinWidth?: number;
22
+ sidebarMinWidth?: number;
23
+ sidebarWidth?: number;
24
+ sidebarCollapsed?: boolean;
25
+ /** Used only for initial layout, before native measurements arrive. */
26
+ initialPaneMetrics?: SidebarSplitViewPaneMetrics;
27
+ titleBar?: SplitViewTitleBarOptions;
28
+ onResize?: (event: SidebarSplitViewResizeEvent) => void;
29
+ }
30
+ export function getSplitViewAvailability() { return macosViewAvailability("SidebarSplitView"); }
31
+ function metrics(value: SidebarSplitViewPaneMetrics) {
32
+ if (!value || typeof value !== "object") throw new SparkError("E_INVALID_ARGUMENT", "Expected pane metrics");
33
+ for (const key of ["contentHeight", "contentWidth", "sidebarHeight", "sidebarWidth"] as const) finite(value[key], key);
34
+ }
35
+ function keys(value: unknown, allowed: readonly string[]) {
36
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new SparkError("E_INVALID_ARGUMENT", "Expected title-bar options");
37
+ for (const key of Object.keys(value)) if (!allowed.includes(key)) throw new SparkError("E_UNSUPPORTED_OPTION", `Unknown title-bar option: ${key}`);
38
+ }
39
+ function overlay(value?: SplitViewTitleBarOverlay) {
40
+ if (value === undefined) return;
41
+ keys(value, ["color", "opacity"]);
42
+ if (typeof value.color !== "string" || !/^#(?:[\da-f]{6}|[\da-f]{8})$/i.test(value.color)) throw new SparkError("E_INVALID_ARGUMENT", "Expected #RRGGBB or #RRGGBBAA title-bar color");
43
+ if (value.opacity !== undefined) finite(value.opacity, "overlay opacity", 0, 1);
44
+ }
45
+ export function SidebarSplitView({ sidebar, content, children, appearance: theme = "system", contentMinWidth = 320, sidebarMinWidth = 180, sidebarWidth, sidebarCollapsed = false, initialPaneMetrics, titleBar = {}, onResize, ref, onError, ...props }: SidebarSplitViewProps) {
46
+ appearance(theme); finite(contentMinWidth, "minimum content width"); finite(sidebarMinWidth, "minimum sidebar width");
47
+ if (sidebarWidth !== undefined) finite(sidebarWidth, "sidebar width", sidebarMinWidth);
48
+ if (typeof sidebarCollapsed !== "boolean" || children !== undefined) throw new SparkError("E_INVALID_ARGUMENT", "Use named sidebar/content panes and a boolean collapsed state");
49
+ if (initialPaneMetrics !== undefined) metrics(initialPaneMetrics);
50
+ keys(titleBar, ["content", "sidebar"]);
51
+ if (titleBar.content !== undefined) { keys(titleBar.content, ["height", "material", "overlay"]); if (titleBar.content.height !== undefined) finite(titleBar.content.height, "title-bar height"); }
52
+ if (titleBar.sidebar !== undefined) keys(titleBar.sidebar, ["overlay"]);
53
+ overlay(titleBar.content?.overlay); overlay(titleBar.sidebar?.overlay);
54
+ const material = titleBar.content?.material ?? "none";
55
+ if (!["none", "glass", "titlebar", "headerView", "hudWindow", "sidebar", "windowBackground"].includes(material)) throw new SparkError("E_INVALID_ARGUMENT", "Invalid title-bar material");
56
+ callback(onResize, "resize");
57
+ const control = useControl({ ref, onError }, getSplitViewAvailability());
58
+ const [paneMetrics, setPaneMetrics] = useState<SidebarSplitViewPaneMetrics | undefined>(() => initialPaneMetrics ? { ...initialPaneMetrics } : undefined);
59
+ function resize(event: NativeSyntheticEvent<SidebarSplitViewPaneMetrics & { contentX: number; height: number; isLayoutReady: boolean }>) {
60
+ if (!control.active()) return;
61
+ let value: SidebarSplitViewResizeEvent;
62
+ try {
63
+ const data = event?.nativeEvent; metrics(data); finite(data.contentX, "content x", -Infinity); finite(data.height, "height");
64
+ if (typeof data.isLayoutReady !== "boolean") throw new Error("Expected layout readiness");
65
+ value = { contentHeight: data.contentHeight, contentWidth: data.contentWidth, sidebarHeight: data.sidebarHeight, sidebarWidth: data.sidebarWidth, contentX: data.contentX, height: data.height, phase: data.isLayoutReady ? "ready" : "provisional" };
66
+ } catch (cause) { control.error(new SparkError("E_INVALID_DATA", "Invalid split-view layout", { cause })); return; }
67
+ setPaneMetrics(current => current && ["contentHeight", "contentWidth", "sidebarHeight", "sidebarWidth"].every(key => current[key as keyof SidebarSplitViewPaneMetrics] === value[key as keyof SidebarSplitViewPaneMetrics]) ? current : value);
68
+ onResize?.(value);
69
+ }
70
+ if (control.failed) return <View {...props} ref={control.ref} style={[{ flexDirection: "row" }, props.style]}>{sidebarCollapsed ? null : sidebar}{content}</View>;
71
+ return <NativeSplitView {...props} ref={control.ref} appearance={theme} contentMinWidth={contentMinWidth} sidebarMinWidth={sidebarMinWidth} sidebarWidth={sidebarWidth} sidebarCollapsed={sidebarCollapsed} onSplitViewDidResize={resize}
72
+ contentTitlebarHeight={titleBar.content?.height ?? 0} contentTitlebarMaterial={material} contentTitlebarOverlayColor={titleBar.content?.overlay?.color} contentTitlebarOverlayOpacity={titleBar.content?.overlay?.opacity ?? (titleBar.content?.overlay ? 1 : 0)}
73
+ sidebarTitlebarOverlayColor={titleBar.sidebar?.overlay?.color} sidebarTitlebarOverlayOpacity={titleBar.sidebar?.overlay?.opacity ?? (titleBar.sidebar?.overlay ? 1 : 0)}>
74
+ <View key="sidebar" style={{ position: "absolute", top: 0, left: 0, minWidth: 0, height: paneMetrics?.sidebarHeight, width: sidebarCollapsed ? 0 : paneMetrics?.sidebarWidth ?? sidebarWidth ?? sidebarMinWidth }}>{sidebar}</View>
75
+ <View key="content" style={{ position: "absolute", top: 0, left: 0, minWidth: 0, height: paneMetrics?.contentHeight, width: paneMetrics?.contentWidth }}>{content}</View>
76
+ </NativeSplitView>;
77
+ }
@@ -0,0 +1,10 @@
1
+ import { Platform, UIManager } from "react-native";
2
+ import { SparkError, type Availability } from "@legendapp/spark-desktop-app/src/contracts";
3
+ import type { ControlKind } from "./types";
4
+ export function getControlAvailability(control: ControlKind): Availability {
5
+ const names: Record<ControlKind, string> = { button: "SparkButton", "text-input": "SparkTextInput", select: Platform.OS === "windows" ? "SparkSelect" : "NativeSelect", "segmented-control": "NativeSegmentedControl" };
6
+ if (!Object.hasOwn(names, control)) throw new SparkError("E_INVALID_ARGUMENT", "Unknown control kind");
7
+ if (Platform.OS !== "macos" && Platform.OS !== "windows") return { available: false, reason: "unsupported-platform" };
8
+ if (Platform.OS === "windows" && control === "segmented-control") return { available: false, reason: "unsupported-platform" };
9
+ return UIManager.hasViewManagerConfig(names[control]) ? { available: true } : { available: false, reason: "missing-module" };
10
+ }
@@ -0,0 +1,8 @@
1
+ import { type ClassValue, clsx } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs));
6
+ }
7
+
8
+ export { type ClassValue };
@@ -0,0 +1,42 @@
1
+ import { useCallback, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState } from "react";
2
+ import { SparkError, type Availability } from "@legendapp/spark-desktop-app/src/contracts";
3
+ import type { ButtonProps, ControlProps, ControlRef, TextInputProps } from "./types";
4
+ export type MeasureTarget = ControlRef | null;
5
+ export function useControl(props: ControlProps, availability: Availability = { available: true }) {
6
+ const { disabled = false, onError = console.error } = props;
7
+ if (typeof disabled !== "boolean" || typeof onError !== "function" || (props.accessibilityLabel !== undefined && typeof props.accessibilityLabel !== "string") || (props.testID !== undefined && typeof props.testID !== "string")) throw new SparkError("E_INVALID_ARGUMENT", "Invalid control options");
8
+ const target = useRef<MeasureTarget>(null), mounted = useRef(false), reported = useRef<string | undefined>(undefined);
9
+ const [failed, setFailed] = useState(false);
10
+ useLayoutEffect(() => { mounted.current = true; return () => { mounted.current = false; }; }, []);
11
+ const reason = availability.available ? undefined : availability.reason;
12
+ useEffect(() => {
13
+ if (reason && reported.current !== reason) {
14
+ reported.current = reason;
15
+ onError(new SparkError(reason === "unsupported-platform" ? "E_UNSUPPORTED_PLATFORM" : reason === "missing-module" ? "E_MODULE_UNAVAILABLE" : "E_UNAVAILABLE", "Native control is unavailable"));
16
+ }
17
+ }, [reason, onError]);
18
+ useImperativeHandle(props.ref, () => ({ measureInWindow(callback) {
19
+ if (typeof callback !== "function") throw new SparkError("E_INVALID_ARGUMENT", "Expected a measurement callback");
20
+ if (!target.current || !mounted.current) throw new SparkError("E_CLOSED", "Control is not mounted");
21
+ target.current.measureInWindow((...bounds) => { if (mounted.current) callback(...bounds); });
22
+ } }), []);
23
+ function error(error: SparkError) { if (mounted.current) onError(error); }
24
+ function unavailable(event: { nativeEvent: { message: string } }) {
25
+ if (!mounted.current) return;
26
+ if (typeof event?.nativeEvent?.message !== "string") { error(new SparkError("E_INVALID_DATA", "Invalid native control error")); return; }
27
+ setFailed(true); error(new SparkError("E_UNAVAILABLE", event.nativeEvent.message));
28
+ }
29
+ const ref = useCallback((value: MeasureTarget) => { target.current = value; }, []);
30
+ return { ref, disabled, failed: failed || !availability.available, error, unavailable, active: () => mounted.current && !disabled && !failed && availability.available };
31
+ }
32
+ export function validateButton(props: ButtonProps) {
33
+ if (typeof props.children !== "string" || !props.children.length || (props.onPress !== undefined && typeof props.onPress !== "function") || (props.variant !== undefined && !["default", "bordered", "borderless"].includes(props.variant))) throw new SparkError("E_INVALID_ARGUMENT", "Invalid button options");
34
+ }
35
+ export function useTextValue(props: TextInputProps) {
36
+ const controlled = props.value !== undefined;
37
+ const initialMode = useRef(controlled), initialText = useRef(props.defaultValue ?? ""), latestCount = useRef(0);
38
+ if (initialMode.current !== controlled) throw new SparkError("E_INVALID_ARGUMENT", "TextInput cannot switch controlled mode; remount it instead");
39
+ if ((controlled && (typeof props.value !== "string" || props.defaultValue !== undefined)) || (props.defaultValue !== undefined && typeof props.defaultValue !== "string") || (props.onChangeText !== undefined && typeof props.onChangeText !== "function")) throw new SparkError("E_INVALID_ARGUMENT", "TextInput requires a string value or defaultValue, not both");
40
+ const [eventCount, setEventCount] = useState(0);
41
+ return { controlled, text: props.value ?? "", defaultText: initialText.current, eventCount, acknowledge(count: number) { if (count <= latestCount.current) return false; latestCount.current = count; if (controlled) setEventCount(count); return true; } };
42
+ }
@@ -0,0 +1,56 @@
1
+ import { useState } from "react";
2
+ import { Platform, Text, View, type NativeSyntheticEvent } from "react-native";
3
+ import NativeTextInput from "./SparkTextInputNativeComponent";
4
+ import NativeButton from "./SparkButtonNativeComponent";
5
+ import NativeSelect from "./native-select/NativeSelectNativeComponent";
6
+ import WindowsSelect from "./SparkSelectNativeComponent";
7
+ import NativeSegmentedControl from "./native-select/NativeSegmentedControlNativeComponent";
8
+ import { SparkError } from "@legendapp/spark-desktop-app/src/contracts";
9
+ import { useControl, useTextValue, validateButton } from "./control";
10
+ import { getControlAvailability } from "./availability";
11
+ import { selectionIndex } from "./select";
12
+ import type { ButtonProps, TextInputProps, SelectProps, SegmentedControlProps } from "./types";
13
+ export type { ButtonProps, TextInputProps, ControlledTextInputProps, UncontrolledTextInputProps, SelectProps, SelectOption, SegmentedControlProps, ControlProps, ControlRef, ControlKind } from "./types";
14
+ export { getControlAvailability } from "./availability";
15
+
16
+ export function Button(props: ButtonProps) {
17
+ validateButton(props);
18
+ const control = useControl(props, getControlAvailability("button"));
19
+ const { children, variant = "default", onPress, accessibilityLabel = children, style, testID } = props;
20
+ if (control.failed) return <View ref={control.ref} style={[{ width: 160, height: 36 }, style]} testID={testID} accessible accessibilityLabel={accessibilityLabel} accessibilityState={{ disabled: true }}><Text>{children}</Text></View>;
21
+ return <NativeButton ref={control.ref} title={children} disabled={control.disabled} variant={variant} accessibilityLabel={accessibilityLabel}
22
+ onButtonPress={() => { if (control.active()) onPress?.(); }} onUnavailable={control.unavailable} testID={testID} style={[{ width: 160, height: 36 }, style]} />;
23
+ }
24
+ export function TextInput(props: TextInputProps) {
25
+ const control = useControl(props, getControlAvailability("text-input"));
26
+ const value = useTextValue(props);
27
+ function changed(event: NativeSyntheticEvent<{ text: string; eventCount: number }>) {
28
+ if (!control.active()) return;
29
+ const data = event?.nativeEvent;
30
+ if (typeof data?.text !== "string" || !Number.isSafeInteger(data.eventCount) || data.eventCount < 1 || data.eventCount > 2147483647) { control.error(new SparkError("E_INVALID_DATA", "Invalid native text change")); return; }
31
+ if (value.acknowledge(data.eventCount)) props.onChangeText?.(data.text);
32
+ }
33
+ const { accessibilityLabel, style, testID } = props;
34
+ if (control.failed) return <View ref={control.ref} style={[{ width: 240, height: 36 }, style]} testID={testID} accessible accessibilityLabel={accessibilityLabel} accessibilityState={{ disabled: true }}><Text>{value.controlled ? value.text : value.defaultText}</Text></View>;
35
+ return <NativeTextInput ref={control.ref} text={value.text} defaultText={value.defaultText} controlled={value.controlled} eventCount={value.eventCount} disabled={control.disabled} onTextChange={changed} onUnavailable={control.unavailable} accessibilityLabel={accessibilityLabel} testID={testID} style={[{ width: 240, height: 36 }, style]} />;
36
+ }
37
+ function Selection({ segmented, ...props }: SelectProps & { segmented: boolean }) {
38
+ selectionIndex(props.options, props.value);
39
+ if (typeof props.onValueChange !== "function") throw new SparkError("E_INVALID_ARGUMENT", "Expected onValueChange");
40
+ const control = useControl(props, getControlAvailability(segmented ? "segmented-control" : "select"));
41
+ const [selectionRevision, revise] = useState(0);
42
+ const { options, value, onValueChange, accessibilityLabel, style, testID } = props;
43
+ function changed(event: NativeSyntheticEvent<{ value: string }>) {
44
+ if (!control.active()) return;
45
+ const next = event?.nativeEvent?.value;
46
+ if (!options.some(option => option.value === next)) { control.error(new SparkError("E_INVALID_DATA", "Native selection is not an option")); return; }
47
+ revise(revision => revision + 1); onValueChange(next);
48
+ }
49
+ const common = { ref: control.ref, value, accessibilityLabel, testID, style: [{ width: 240, height: 36 }, style], selectionRevision };
50
+ if (control.failed) return <View ref={control.ref} style={common.style} testID={testID} accessible accessibilityLabel={accessibilityLabel} accessibilityState={{ disabled: true }}><Text>{options.find(option => option.value === value)!.label}</Text></View>;
51
+ if (segmented) return <NativeSegmentedControl {...common} segmentsJson={JSON.stringify(options)} enabled={!control.disabled} onValueChange={changed} />;
52
+ if (Platform.OS === "windows") return <WindowsSelect {...common} itemsJson={JSON.stringify(options)} disabled={control.disabled} onSelectionChange={changed} onUnavailable={control.unavailable} />;
53
+ return <NativeSelect {...common} itemsJson={JSON.stringify(options)} enabled={!control.disabled} onValueChange={changed} />;
54
+ }
55
+ export function Select(props: SelectProps) { return <Selection {...props} segmented={false} />; }
56
+ export function SegmentedControl(props: SegmentedControlProps) { return <Selection {...props} segmented />; }
@@ -0,0 +1,15 @@
1
+ import { requireNativeComponent, View, type ColorValue } from "react-native";
2
+ import { SparkError } from "@legendapp/spark-desktop-app/src/contracts";
3
+ import { useControl } from "../control";
4
+ import { macosViewAvailability, type SpecializedViewProps } from "../specialized";
5
+ export type GlassStyle = "regular" | "clear";
6
+ export interface GlassViewProps extends SpecializedViewProps { glassStyle?: GlassStyle; tintColor?: ColorValue }
7
+ const NativeGlass = requireNativeComponent<GlassViewProps>("RNGlassEffectView");
8
+ export function getGlassAvailability() { return macosViewAvailability("RNGlassEffectView", 26); }
9
+ /** Native glass hosts its children; unsupported hosts preserve them without an effect. */
10
+ export function GlassView({ glassStyle = "regular", tintColor, ref, onError, ...props }: GlassViewProps) {
11
+ if (glassStyle !== "regular" && glassStyle !== "clear") throw new SparkError("E_INVALID_ARGUMENT", "Invalid glass style");
12
+ const control = useControl({ ref, onError }, getGlassAvailability());
13
+ if (control.failed) return <View {...props} ref={control.ref} />;
14
+ return <NativeGlass {...props} ref={control.ref} glassStyle={glassStyle} tintColor={tintColor} />;
15
+ }
@@ -1,25 +1,39 @@
1
- import { useCallback, useMemo } from "react";
1
+ import type { ComponentProps } from "react";
2
+ function ExpoButton(props: ComponentProps<typeof import("@expo/ui/jetpack-compose").Button>) {
3
+ const Component = (require("@expo/ui/jetpack-compose") as typeof import("@expo/ui/jetpack-compose")).Button;
4
+ return <Component {...props} />;
5
+ }
6
+ import { View, Text } from "react-native";
7
+ import { requireOptionalNativeModule } from "expo-modules-core";
8
+ import { SparkError, type Availability } from "@legendapp/spark-desktop-app/src/contracts";
2
9
  import { selectionIndex } from "./select";
3
- import { Button as ExpoButton, TextInput as ExpoTextInput, Picker } from "@expo/ui/jetpack-compose";
4
- import { StyleSheet, View } from "react-native";
5
- import type { ButtonProps, TextInputProps, SelectProps } from "./types";
6
- export type { ButtonProps, TextInputProps, SelectProps } from "./types";
7
-
8
- export function Button({ children, onPress, disabled = false, variant = "default", style, testID }: ButtonProps) {
9
- return <View style={[styles.button, style]} testID={testID}>
10
- <ExpoButton style={styles.content} onPress={disabled ? undefined : onPress}
11
- disabled={disabled} variant={variant}>{children}</ExpoButton>
12
- </View>;
10
+ import { useControl, validateButton } from "./control";
11
+ import type { ButtonProps, SelectProps, SegmentedControlProps, ControlKind } from "./types";
12
+ export type { ButtonProps, TextInputProps, ControlledTextInputProps, UncontrolledTextInputProps, SelectProps, SelectOption, SegmentedControlProps, ControlProps, ControlRef, ControlKind } from "./types";
13
+ export { TextInput } from "./mobile-input";
14
+ export function getControlAvailability(control: ControlKind): Availability {
15
+ if (!["button", "text-input", "select", "segmented-control"].includes(control)) throw new SparkError("E_INVALID_ARGUMENT", "Unknown control kind");
16
+ return control === "text-input" || requireOptionalNativeModule("ExpoUI") ? { available: true } : { available: false, reason: "missing-module" };
13
17
  }
14
- const styles = StyleSheet.create({ button: { width: 160, height: 48 }, content: { flex: 1 } });
15
-
16
- const ignoreText = (_value: string) => {};
17
- export function TextInput({ defaultValue, onChangeText, accessibilityLabel, style, testID }: TextInputProps) {
18
- return <View style={[{ width: 240, height: 56 }, style]} testID={testID}><ExpoTextInput defaultValue={defaultValue} onChangeText={onChangeText ?? ignoreText} style={styles.content} {...{ accessibilityLabel }} /></View>;
18
+ export function Button(props: ButtonProps) {
19
+ validateButton(props); const control = useControl(props, getControlAvailability("button"));
20
+ const { children, onPress, variant = "default", style, testID, accessibilityLabel = children } = props;
21
+ return <View ref={control.ref} style={[{ width: 160, height: 48 }, style]} testID={testID}>
22
+ {control.failed ? <Text accessibilityLabel={accessibilityLabel} accessibilityState={{ disabled: true }}>{children}</Text> :
23
+ <ExpoButton style={{ flex: 1 }} onPress={() => { if (control.active()) onPress?.(); }} disabled={control.disabled} variant={variant} {...{ accessibilityLabel }}>{children}</ExpoButton>}
24
+ </View>;
19
25
  }
20
- export function Select({ options, value, onValueChange, accessibilityLabel, style, testID }: SelectProps) {
21
- const selectedIndex = selectionIndex(options, value);
22
- const labels = useMemo(() => options.map(option => option.label), [options]);
23
- const changed = useCallback((event: { nativeEvent: { index: number } }) => { const option = options[event.nativeEvent.index]; if (option) onValueChange(option.value); }, [options, onValueChange]);
24
- return <View style={[{ width: 280, height: 48 }, style]} testID={testID}><Picker variant="segmented" options={labels} selectedIndex={selectedIndex} onOptionSelected={changed} style={styles.content} {...{ accessibilityLabel }} /></View>;
26
+ function Selection(props: SelectProps) {
27
+ const selected = selectionIndex(props.options, props.value);
28
+ if (typeof props.onValueChange !== "function") throw new SparkError("E_INVALID_ARGUMENT", "Expected onValueChange");
29
+ const control = useControl(props, getControlAvailability("select"));
30
+ return <View ref={control.ref} style={[{ width: 280, minHeight: 48, flexDirection: "row" }, props.style]} testID={props.testID} accessibilityLabel={props.accessibilityLabel}>
31
+ {control.failed ? <Text accessibilityState={{ disabled: true }}>{props.options[selected].label}</Text> : props.options.map(option =>
32
+ <ExpoButton key={option.value} disabled={control.disabled} variant={option.value === props.value ? "bordered" : "borderless"} style={{ flex: 1 }}
33
+ {...{ accessibilityRole: "radio", accessibilityState: { checked: option.value === props.value, disabled: control.disabled } }}
34
+ onPress={() => { if (control.active()) props.onValueChange(option.value); }}>{option.label}</ExpoButton>)}
35
+ </View>;
25
36
  }
37
+ /** Android presents its choices inline; there is no dropdown backend in the pinned Expo UI. */
38
+ export function Select(props: SelectProps) { return <Selection {...props} />; }
39
+ export function SegmentedControl(props: SegmentedControlProps) { return <Selection {...props} />; }