@legendapp/spark 0.0.1-next.2 → 0.0.1-next.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +10 -4
- package/ai-codex.ts +1 -0
- package/ai.ts +1 -0
- package/app-documents.ts +1 -0
- package/config-plugin.d.cts +2 -0
- package/contracts.ts +2 -0
- package/diagnostics.ts +1 -0
- package/expo-config.d.cts +1 -0
- package/metro.cjs +4 -1
- package/metro.d.cts +12 -0
- package/native.cjs +3 -1
- package/native.d.cts +6 -0
- package/package.json +82 -14
- package/schema.json +276 -58
- package/settings-observable.ts +1 -0
- package/settings-window.ts +1 -0
- package/shortcuts-commands.ts +1 -0
- package/shortcuts-keyboard.ts +3 -0
- package/ui-classnames.ts +1 -0
- package/ui-glass.ts +1 -0
- package/ui-search.ts +1 -0
- package/ui-sidebar.ts +1 -0
- package/ui-split-view.ts +1 -0
- package/ui-symbol.ts +1 -0
- package/vendor/node_modules/@legendapp/spark-ai/package.json +19 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/availability.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/index.ts +15 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/invocations.ts +34 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/output.ts +62 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/run.ts +12 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/types.ts +16 -0
- package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.h +2 -1
- package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.mm +126 -24
- package/vendor/node_modules/@legendapp/spark-audio/package.json +5 -2
- package/vendor/node_modules/@legendapp/spark-audio/src/NativeSparkAudio.ts +5 -1
- package/vendor/node_modules/@legendapp/spark-audio/src/desktop.ts +36 -32
- package/vendor/node_modules/@legendapp/spark-audio/src/events.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-audio/src/hooks.ts +65 -0
- package/vendor/node_modules/@legendapp/spark-audio/src/index.web.ts +92 -33
- package/vendor/node_modules/@legendapp/spark-audio/src/media-session-unavailable.ts +6 -4
- package/vendor/node_modules/@legendapp/spark-audio/src/media-session.ts +52 -19
- package/vendor/node_modules/@legendapp/spark-audio/src/media-session.web.ts +18 -10
- package/vendor/node_modules/@legendapp/spark-audio/src/media-types.ts +40 -13
- package/vendor/node_modules/@legendapp/spark-audio/src/mobile.ts +40 -32
- package/vendor/node_modules/@legendapp/spark-audio/src/player.ts +97 -0
- package/vendor/node_modules/@legendapp/spark-audio/src/status-listeners.ts +21 -15
- package/vendor/node_modules/@legendapp/spark-audio/src/types.ts +9 -4
- package/vendor/node_modules/@legendapp/spark-audio/windows/SparkAudio/SparkAudio.h +67 -20
- package/vendor/node_modules/@legendapp/spark-auth-session/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-auth-session/src/core.ts +60 -42
- package/vendor/node_modules/@legendapp/spark-auth-session/src/index.ts +28 -12
- package/vendor/node_modules/@legendapp/spark-auth-session/src/mobile.ts +97 -41
- package/vendor/node_modules/@legendapp/spark-auth-session/src/types.ts +20 -9
- package/vendor/node_modules/@legendapp/spark-cli/dist/add-desktop.js +50 -7
- package/vendor/node_modules/@legendapp/spark-cli/dist/build-mode.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/build.js +83 -48
- package/vendor/node_modules/@legendapp/spark-cli/dist/cli-arguments.js +60 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/commands.js +7 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/create.js +31 -5
- package/vendor/node_modules/@legendapp/spark-cli/dist/credentials.js +69 -23
- package/vendor/node_modules/@legendapp/spark-cli/dist/dev-command.js +12 -3
- package/vendor/node_modules/@legendapp/spark-cli/dist/dev.js +12 -9
- package/vendor/node_modules/@legendapp/spark-cli/dist/examples.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/expo-dev-patch.cjs +4 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/expo-metro.cjs +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/expo-node.js +3 -3
- package/vendor/node_modules/@legendapp/spark-cli/dist/index.js +10 -38
- package/vendor/node_modules/@legendapp/spark-cli/dist/local.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/metro.cjs +26 -5
- package/vendor/node_modules/@legendapp/spark-cli/dist/native-metadata.js +26 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/native-patch-preflight.js +84 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/native-preparation.js +88 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/notary-profiles.js +75 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/package.js +4 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/platform.js +16 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/project.js +66 -13
- package/vendor/node_modules/@legendapp/spark-cli/dist/release.js +84 -4
- package/vendor/node_modules/@legendapp/spark-cli/dist/release.json +23 -18
- package/vendor/node_modules/@legendapp/spark-cli/dist/runner-install.js +145 -31
- package/vendor/node_modules/@legendapp/spark-cli/dist/signing.js +4 -3
- package/vendor/node_modules/@legendapp/spark-cli/dist/updates.js +41 -4
- package/vendor/node_modules/@legendapp/spark-cli/dist/windows.js +4 -1
- package/vendor/node_modules/@legendapp/spark-cli/package.json +7 -6
- package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/App.tsx +6 -12
- package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/desktop.config.json +5 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/package.json +11 -9
- package/vendor/node_modules/@legendapp/spark-cli/templates/diff-lite/Git.macos.tsx +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.macos.tsx +23 -21
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.windows.tsx +23 -21
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.desktop.ts +11 -8
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.macos.ts +3 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/Lifecycle.desktop.tsx +8 -14
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/OpenFiles.desktop.tsx +5 -10
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.desktop.ts +11 -8
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.macos.ts +3 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/music-lite/assets.desktop.ts +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Activation.desktop.tsx +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Desktop.desktop.ts +37 -15
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/session.ts +5 -6
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/window-session.ts +5 -4
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/desktop.config.json +5 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/metro.config.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/package.json +13 -11
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/react-native.config.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/templates/windows/package.json +13 -11
- package/vendor/node_modules/@legendapp/spark-cli/templates/windows/react-native.config.js +1 -1
- package/vendor/node_modules/@legendapp/spark-clipboard/macos/RNDesktopClipboard.mm +10 -16
- package/vendor/node_modules/@legendapp/spark-clipboard/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-clipboard/src/NativeDesktopClipboard.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-clipboard/src/desktop.ts +55 -31
- package/vendor/node_modules/@legendapp/spark-clipboard/src/expo.ts +21 -11
- package/vendor/node_modules/@legendapp/spark-clipboard/src/options.ts +8 -0
- package/vendor/node_modules/@legendapp/spark-clipboard/src/types.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.h +38 -15
- package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.vcxproj +2 -0
- package/vendor/node_modules/@legendapp/spark-codex/RNCodex.podspec +22 -0
- package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.hpp +23 -0
- package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.mm +1529 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitro.json +21 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/.gitattributes +1 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex+autolinking.rb +62 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.cpp +17 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.hpp +27 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Umbrella.hpp +38 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.mm +35 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.swift +16 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexAvailability.hpp +95 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexRunResult.hpp +99 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.cpp +24 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.hpp +71 -0
- package/vendor/node_modules/@legendapp/spark-codex/package.json +35 -0
- package/vendor/node_modules/@legendapp/spark-codex/react-native.config.js +11 -0
- package/vendor/node_modules/@legendapp/spark-codex/src/Codex.nitro.ts +30 -0
- package/vendor/node_modules/@legendapp/spark-codex/src/index.ts +65 -0
- package/vendor/node_modules/@legendapp/spark-codex/src/native.ts +6 -0
- package/vendor/node_modules/@legendapp/spark-commands/package.json +21 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/bindings.ts +90 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/index.tsx +400 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/router.ts +138 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/storage.ts +20 -0
- package/vendor/node_modules/@legendapp/spark-context-menu/macos/RNContextMenu.mm +7 -8
- package/vendor/node_modules/@legendapp/spark-context-menu/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-context-menu/src/NativeContextMenu.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-context-menu/src/index.ts +26 -26
- package/vendor/node_modules/@legendapp/spark-context-menu/windows/SparkContextMenu/SparkContextMenu.h +3 -2
- package/vendor/node_modules/@legendapp/spark-desktop-app/RNDesktopApp.podspec +2 -1
- package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryJSI.hpp +89 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryWindows.hpp +22 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/RNDesktopApp.mm +13 -7
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkBinaryJSI.h +48 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.h +4 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.mm +33 -33
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktopError.h +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.h +26 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.mm +49 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.h +9 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.mm +70 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkWindow.mm +9 -6
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/recent-documents/RNRecentDocumentController.mm +55 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/package.json +5 -3
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/NativeDesktopApp.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/api.ts +86 -40
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/accelerator.ts +40 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/index.ts +56 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/menu.ts +114 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/native-buffer.ts +22 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/path.ts +24 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/events.ts +75 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.ts +2 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.windows.ts +2 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/open-requests.ts +43 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/restoration.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/transport.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.cjs +10 -5
- package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.d.cts +3 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/autolinking.cjs +35 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/config.cjs +16 -3
- package/vendor/node_modules/@legendapp/spark-desktop-config/config.d.cts +89 -9
- package/vendor/node_modules/@legendapp/spark-desktop-config/expo.d.cts +3 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/identity.cjs +3 -2
- package/vendor/node_modules/@legendapp/spark-desktop-config/lifecycle.cjs +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/package.json +6 -5
- package/vendor/node_modules/@legendapp/spark-desktop-config/schema.json +276 -58
- package/vendor/node_modules/@legendapp/spark-desktop-config/updates.cjs +1 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/validation.cjs +35 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/windows.plugin.cjs +2 -1
- package/vendor/node_modules/@legendapp/spark-desktop-host/AppDelegate.mm +129 -11
- package/vendor/node_modules/@legendapp/spark-desktop-host/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-desktop-host/windows/application.inc +277 -121
- package/vendor/node_modules/@legendapp/spark-desktop-links/common/AuthLoopback.h +5 -7
- package/vendor/node_modules/@legendapp/spark-desktop-links/macos/RNDesktopLinks.mm +10 -9
- package/vendor/node_modules/@legendapp/spark-desktop-links/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/NativeDesktopLinks.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/api.ts +27 -33
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/expo.ts +3 -4
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/native.ts +9 -0
- package/vendor/node_modules/@legendapp/spark-desktop-links/windows/SparkLinks/SparkLinks.h +22 -22
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/RNDesktopShortcuts.podspec +1 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/RNDesktopShortcuts.mm +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.h +9 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.mm +307 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/package.json +8 -5
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/NativeDesktopShortcuts.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/api.ts +39 -14
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/NativeKeyboardManager.ts +12 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/codes.ts +108 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/index.ts +99 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/RNDesktopWindows.podspec +2 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/RNDesktopWindows.mm +229 -103
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/SparkWindowGeometry.h +63 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.h +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.mm +27 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.h +12 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.mm +3130 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManagerStartup.mm +31 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/SidebarStartupFallbacks.mm +14 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/package.json +10 -6
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/NativeDesktopWindowManager.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/api.ts +144 -70
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/diagnostics.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.windows.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos-adapter.ts +53 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos.ts +51 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/transport.ts +41 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/types.ts +140 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/validation.ts +162 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/window-manager/NativeWindowManager.ts +28 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/WindowProvider.tsx +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/createWindowsNavigator.tsx +78 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/index.ts +6 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/primaryWindowLifecycle.ts +34 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/types.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/usePrimaryWindowLifecycle.ts +18 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/useWindowFocusEffect.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-documents/package.json +22 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/controller.ts +97 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/documentTransition.ts +13 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/hooks.ts +139 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/index.tsx +50 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/reload.ts +39 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/requests.ts +15 -0
- package/vendor/node_modules/@legendapp/spark-drag-drop/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-drag-drop/src/DesktopDragViewNativeComponent.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-drag-drop/src/contracts.ts +73 -18
- package/vendor/node_modules/@legendapp/spark-drag-drop/src/index.tsx +58 -15
- package/vendor/node_modules/@legendapp/spark-drag-drop/windows/SparkDragDrop/SparkDragDrop.h +14 -8
- package/vendor/node_modules/@legendapp/spark-file-dialog/ios/RNFileDialog.mm +34 -121
- package/vendor/node_modules/@legendapp/spark-file-dialog/package.json +12 -5
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/NativeFileDialog.ts +1 -5
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.ts +19 -84
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/native.ts +12 -0
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/options.ts +34 -14
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/types.ts +26 -0
- package/vendor/node_modules/@legendapp/spark-file-dialog/windows/SparkFileDialog/SparkFileDialog.h +42 -58
- package/vendor/node_modules/@legendapp/spark-file-system/RNDesktopFileSystem.podspec +1 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/RNDesktopFileSystem.mm +32 -21
- package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.h +24 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.mm +215 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.h +9 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.mm +82 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.h +47 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.mm +306 -0
- package/vendor/node_modules/@legendapp/spark-file-system/package.json +8 -6
- package/vendor/node_modules/@legendapp/spark-file-system/src/NativeDesktopFileSystem.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/NativeFileScanner.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/index.ts +93 -0
- package/vendor/node_modules/@legendapp/spark-file-system/src/handles.ts +48 -14
- package/vendor/node_modules/@legendapp/spark-file-system/src/index.ts +134 -45
- package/vendor/node_modules/@legendapp/spark-file-system/src/path.ts +1 -9
- package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.h +102 -26
- package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.vcxproj +2 -0
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/RNDesktopGlobalShortcuts.podspec +1 -0
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/macos/RNDesktopGlobalShortcuts.mm +7 -4
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/NativeDesktopGlobalShortcuts.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/index.ts +39 -10
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/windows/SparkGlobalShortcuts/SparkGlobalShortcuts.h +5 -4
- package/vendor/node_modules/@legendapp/spark-message-dialog/macos/RNDesktopMessageDialog.mm +2 -2
- package/vendor/node_modules/@legendapp/spark-message-dialog/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-message-dialog/src/NativeDesktopMessageDialog.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-message-dialog/src/index.ts +48 -11
- package/vendor/node_modules/@legendapp/spark-native-menu/ios/RNNativeMenu.mm +141 -609
- package/vendor/node_modules/@legendapp/spark-native-menu/package.json +9 -4
- package/vendor/node_modules/@legendapp/spark-native-menu/src/NativeMenu.ts +2 -7
- package/vendor/node_modules/@legendapp/spark-native-menu/src/api.ts +76 -121
- package/vendor/node_modules/@legendapp/spark-native-menu/src/hooks.ts +97 -0
- package/vendor/node_modules/@legendapp/spark-native-menu/src/windows-menus.ts +43 -37
- package/vendor/node_modules/@legendapp/spark-notifications/macos/RNDesktopNotifications.mm +75 -30
- package/vendor/node_modules/@legendapp/spark-notifications/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-notifications/src/NativeDesktopNotifications.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-notifications/src/index.ts +130 -42
- package/vendor/node_modules/@legendapp/spark-notifications/windows/SparkNotifications/SparkNotifications.h +46 -8
- package/vendor/node_modules/@legendapp/spark-processes/macos/RNDesktopProcesses.mm +94 -21
- package/vendor/node_modules/@legendapp/spark-processes/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-processes/src/NativeDesktopProcesses.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-processes/src/index.ts +124 -28
- package/vendor/node_modules/@legendapp/spark-processes/src/types.ts +34 -0
- package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.h +83 -34
- package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.vcxproj +2 -0
- package/vendor/node_modules/@legendapp/spark-secure-storage/macos/RNDesktopSecureStorage.mm +49 -40
- package/vendor/node_modules/@legendapp/spark-secure-storage/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/NativeDesktopSecureStorage.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/desktop.ts +16 -14
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/expo.ts +0 -1
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/options.ts +3 -2
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/unavailable.ts +6 -3
- package/vendor/node_modules/@legendapp/spark-settings/package.json +10 -3
- package/vendor/node_modules/@legendapp/spark-settings/src/fileStorage.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-settings/src/index.ts +7 -9
- package/vendor/node_modules/@legendapp/spark-settings/src/storage/index.ts +142 -0
- package/vendor/node_modules/@legendapp/spark-settings/src/store.ts +63 -21
- package/vendor/node_modules/@legendapp/spark-settings-ui/package.json +20 -0
- package/vendor/node_modules/@legendapp/spark-settings-ui/src/index.tsx +436 -0
- package/vendor/node_modules/@legendapp/spark-settings-ui/src/options.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-sqlite/package.json +3 -3
- package/vendor/node_modules/@legendapp/spark-sqlite/src/database.ts +182 -0
- package/vendor/node_modules/@legendapp/spark-sqlite/src/index.ts +19 -6
- package/vendor/node_modules/@legendapp/spark-sqlite/src/types.ts +22 -0
- package/vendor/node_modules/@legendapp/spark-system/macos/RNDesktopSystem.mm +36 -11
- package/vendor/node_modules/@legendapp/spark-system/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-system/src/NativeDesktopSystem.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-system/src/index.ts +89 -32
- package/vendor/node_modules/@legendapp/spark-system/windows/SparkSystem/SparkSystem.h +8 -4
- package/vendor/node_modules/@legendapp/spark-tray/macos/RNDesktopTray.mm +20 -8
- package/vendor/node_modules/@legendapp/spark-tray/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-tray/src/NativeDesktopTray.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-tray/src/index.ts +91 -34
- package/vendor/node_modules/@legendapp/spark-tray/windows/SparkTray/SparkTray.h +45 -15
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkButton.mm +2 -1
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkTextInput.mm +10 -2
- package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.mm +1182 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/glass-effect-view/RNGlassEffectView.mm +72 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.mm +194 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.mm +180 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.mm +155 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.h +18 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.mm +645 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.mm +164 -0
- package/vendor/node_modules/@legendapp/spark-ui/package.json +16 -4
- package/vendor/node_modules/@legendapp/spark-ui/src/SparkSelectNativeComponent.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-ui/src/SparkTextInputNativeComponent.ts +6 -2
- package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/SidebarSplitViewNativeComponent.ts +31 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/index.tsx +77 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/availability.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/classnames/index.ts +8 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/control.ts +42 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/desktop.tsx +56 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/glass-effect-view/index.tsx +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/index.android.tsx +35 -21
- package/vendor/node_modules/@legendapp/spark-ui/src/index.ios.tsx +55 -26
- package/vendor/node_modules/@legendapp/spark-ui/src/index.tsx +1 -27
- package/vendor/node_modules/@legendapp/spark-ui/src/index.web.tsx +45 -14
- package/vendor/node_modules/@legendapp/spark-ui/src/index.windows.tsx +1 -42
- package/vendor/node_modules/@legendapp/spark-ui/src/mobile-input.tsx +11 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSegmentedControlNativeComponent.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSelectNativeComponent.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/select.ts +5 -3
- package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/SFSymbolNativeComponent.ts +13 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/index.tsx +27 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarItemNativeComponent.ts +25 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarNativeComponent.ts +24 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/index.tsx +104 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/specialized.ts +22 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/TextInputSearchNativeComponent.ts +33 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/index.tsx +34 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/types.ts +30 -19
- package/vendor/node_modules/@legendapp/spark-ui/uniwind.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-ui/uniwind.web.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-ui/windows/SparkUI/SparkUI.h +16 -11
- package/vendor/node_modules/@legendapp/spark-updates/macos/RNDesktopUpdates.mm +21 -8
- package/vendor/node_modules/@legendapp/spark-updates/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-updates/src/NativeDesktopUpdates.ts +3 -2
- package/vendor/node_modules/@legendapp/spark-updates/src/index.ts +71 -15
- package/vendor/node_modules/@legendapp/spark-webview/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-webview/src/WebView.tsx +11 -0
- package/vendor/node_modules/@legendapp/spark-webview/src/adapter.ts +55 -0
- package/vendor/node_modules/@legendapp/spark-webview/src/index.ts +2 -2
- package/vendor/node_modules/@legendapp/spark-webview/src/types.ts +32 -0
- package/vendor/node_modules/@legendapp/spark-webview/src/view-props.ts +28 -0
- package/vendor/node_modules/@legendapp/spark-window-options/index.cjs +51 -14
- package/vendor/node_modules/@legendapp/spark-window-options/index.d.ts +21 -8
- package/vendor/node_modules/@legendapp/spark-window-options/package.json +1 -1
- package/windows-macos.ts +1 -0
- package/expo-metro.cjs +0 -1
- package/message-dialog.ts +0 -1
- package/universal.cjs +0 -1
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/accelerator.ts +0 -22
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows-options.ts +0 -11
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.windows.ts +0 -15
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/accelerator.ts +0 -22
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkSelect.h +0 -4
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkSelect.mm +0 -53
|
@@ -1,28 +1,39 @@
|
|
|
1
|
+
import type { Ref } from "react";
|
|
1
2
|
import type { StyleProp, ViewStyle } from "react-native";
|
|
2
|
-
|
|
3
|
+
import type { SparkError } from "@legendapp/spark-desktop-app/src/contracts";
|
|
4
|
+
/** A layout-only ref; backend objects and native control methods stay internal. */
|
|
5
|
+
export interface ControlRef { measureInWindow(callback: (x: number, y: number, width: number, height: number) => void): void }
|
|
6
|
+
export interface ControlProps {
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
accessibilityLabel?: string;
|
|
9
|
+
style?: StyleProp<ViewStyle>;
|
|
10
|
+
testID?: string;
|
|
11
|
+
ref?: Ref<ControlRef>;
|
|
12
|
+
onError?: (error: SparkError) => void;
|
|
13
|
+
}
|
|
3
14
|
/** A native text button. Layout styles affect its frame, not OS-managed chrome. */
|
|
4
|
-
export
|
|
15
|
+
export interface ButtonProps extends ControlProps {
|
|
5
16
|
children: string;
|
|
6
17
|
onPress?: () => void;
|
|
7
|
-
disabled?: boolean;
|
|
8
18
|
variant?: "default" | "bordered" | "borderless";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
19
|
+
}
|
|
20
|
+
export interface ControlledTextInputProps extends ControlProps {
|
|
21
|
+
value: string;
|
|
22
|
+
defaultValue?: never;
|
|
23
|
+
onChangeText?: (text: string) => void;
|
|
24
|
+
}
|
|
25
|
+
export interface UncontrolledTextInputProps extends ControlProps {
|
|
26
|
+
value?: never;
|
|
27
|
+
/** Read only on mount. Remount to reset an uncontrolled input. */
|
|
15
28
|
defaultValue?: string;
|
|
16
29
|
onChangeText?: (text: string) => void;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
options: readonly { label: string; value: string }[];
|
|
30
|
+
}
|
|
31
|
+
export type TextInputProps = ControlledTextInputProps | UncontrolledTextInputProps;
|
|
32
|
+
export interface SelectOption { label: string; value: string }
|
|
33
|
+
export interface SelectProps extends ControlProps {
|
|
34
|
+
options: readonly SelectOption[];
|
|
23
35
|
value: string;
|
|
24
36
|
onValueChange: (value: string) => void;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
};
|
|
37
|
+
}
|
|
38
|
+
export interface SegmentedControlProps extends SelectProps {}
|
|
39
|
+
export type ControlKind = "button" | "text-input" | "select" | "segmented-control";
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { withUniwind } from "uniwind";
|
|
2
|
-
import { Button as NativeButton, TextInput as NativeTextInput, Select as NativeSelect } from "./src/index";
|
|
2
|
+
import { Button as NativeButton, TextInput as NativeTextInput, Select as NativeSelect, SegmentedControl as NativeSegmentedControl } from "./src/index";
|
|
3
3
|
|
|
4
4
|
// Optional, module-level bindings preserve each platform's native implementation.
|
|
5
5
|
// className maps to the existing layout style; explicit style wins on conflicts.
|
|
6
6
|
export const Button = withUniwind(NativeButton);
|
|
7
7
|
export const TextInput = withUniwind(NativeTextInput);
|
|
8
8
|
export const Select = withUniwind(NativeSelect);
|
|
9
|
+
|
|
10
|
+
export const SegmentedControl = withUniwind(NativeSegmentedControl);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createElement, type ComponentType } from "react";
|
|
2
2
|
import type { StyleProp, ViewStyle } from "react-native";
|
|
3
3
|
import { useResolveClassNames } from "uniwind";
|
|
4
|
-
import { Button as NativeButton, TextInput as NativeTextInput, Select as NativeSelect } from "./src/index";
|
|
4
|
+
import { Button as NativeButton, TextInput as NativeTextInput, Select as NativeSelect, SegmentedControl as NativeSegmentedControl } from "./src/index";
|
|
5
5
|
|
|
6
6
|
function withSparkClasses<Props extends { style?: StyleProp<ViewStyle> }>(Component: ComponentType<Props>) {
|
|
7
7
|
return function UniwindControl({ className = "", style, ...props }: Props & { className?: string }) {
|
|
@@ -15,3 +15,5 @@ function withSparkClasses<Props extends { style?: StyleProp<ViewStyle> }>(Compon
|
|
|
15
15
|
export const Button = withSparkClasses(NativeButton);
|
|
16
16
|
export const TextInput = withSparkClasses(NativeTextInput);
|
|
17
17
|
export const Select = withSparkClasses(NativeSelect);
|
|
18
|
+
|
|
19
|
+
export const SegmentedControl = withSparkClasses(NativeSegmentedControl);
|
|
@@ -16,18 +16,17 @@ namespace React = Microsoft::ReactNative;
|
|
|
16
16
|
namespace Composition = Microsoft::ReactNative::Composition;
|
|
17
17
|
namespace Xaml = Microsoft::UI::Xaml;
|
|
18
18
|
namespace Json = Windows::Data::Json;
|
|
19
|
-
REACT_MODULE(SparkUIAvailability, L"NativeSparkUI")
|
|
20
|
-
struct SparkUIAvailability {
|
|
21
|
-
REACT_SYNC_METHOD(isAvailable)
|
|
22
|
-
bool isAvailable() noexcept { return true; }
|
|
23
|
-
};
|
|
24
19
|
struct Props : implements<Props, React::IComponentProps> {
|
|
25
20
|
React::ViewProps view{nullptr};
|
|
26
|
-
std::string title, defaultText, itemsJson = "[]", value, variant = "default";
|
|
27
|
-
bool disabled = false;
|
|
21
|
+
std::string title, defaultText, text, itemsJson = "[]", value, variant = "default";
|
|
22
|
+
bool disabled = false, controlled = false;
|
|
23
|
+
int32_t eventCount = 0;
|
|
28
24
|
void SetProp(uint32_t, hstring const &name, React::IJSValueReader const &reader) noexcept {
|
|
29
25
|
if (name == L"title") React::ReadValue(reader, title);
|
|
30
26
|
else if (name == L"defaultText") React::ReadValue(reader, defaultText);
|
|
27
|
+
else if (name == L"text") React::ReadValue(reader, text);
|
|
28
|
+
else if (name == L"controlled") React::ReadValue(reader, controlled);
|
|
29
|
+
else if (name == L"eventCount") React::ReadValue(reader, eventCount);
|
|
31
30
|
else if (name == L"itemsJson") React::ReadValue(reader, itemsJson);
|
|
32
31
|
else if (name == L"value") React::ReadValue(reader, value);
|
|
33
32
|
else if (name == L"variant") React::ReadValue(reader, variant);
|
|
@@ -56,10 +55,13 @@ struct Control : implements<Control, Windows::Foundation::IInspectable> {
|
|
|
56
55
|
std::string kind, failure, items;
|
|
57
56
|
std::vector<std::string> values;
|
|
58
57
|
bool initialized = false, updating = false;
|
|
58
|
+
int32_t eventCount = 0;
|
|
59
59
|
void Emit(hstring const &name, std::string const &key = "", std::string const &value = "") {
|
|
60
|
-
|
|
60
|
+
const auto count = eventCount;
|
|
61
|
+
if (emitter) emitter.DispatchEvent(name, [key, value, name, count](React::IJSValueWriter const &writer) {
|
|
61
62
|
writer.WriteObjectBegin();
|
|
62
63
|
if (!key.empty()) { writer.WritePropertyName(to_hstring(key)); writer.WriteString(to_hstring(value)); }
|
|
64
|
+
if (name == L"textChange") { writer.WritePropertyName(L"eventCount"); writer.WriteInt64(count); }
|
|
63
65
|
writer.WriteObjectEnd();
|
|
64
66
|
});
|
|
65
67
|
}
|
|
@@ -78,7 +80,7 @@ struct Control : implements<Control, Windows::Foundation::IInspectable> {
|
|
|
78
80
|
} else if (kind == "TextInput") {
|
|
79
81
|
Xaml::Controls::TextBox input;
|
|
80
82
|
input.TextChanged([weak](auto const &sender, auto const &) {
|
|
81
|
-
if (auto self = weak.get(); self && !self->updating) self->Emit(L"textChange", "text", to_string(sender.template as<Xaml::Controls::TextBox>().Text()));
|
|
83
|
+
if (auto self = weak.get(); self && !self->updating && self->control.IsEnabled()) { ++self->eventCount; self->Emit(L"textChange", "text", to_string(sender.template as<Xaml::Controls::TextBox>().Text())); }
|
|
82
84
|
});
|
|
83
85
|
control = input;
|
|
84
86
|
} else {
|
|
@@ -113,14 +115,16 @@ struct Control : implements<Control, Windows::Foundation::IInspectable> {
|
|
|
113
115
|
updating = true;
|
|
114
116
|
control.IsEnabled(!props.disabled);
|
|
115
117
|
Xaml::Automation::AutomationProperties::SetAutomationId(control, props.view.TestId());
|
|
116
|
-
Xaml::Automation::AutomationProperties::SetName(control, kind == "Button" ? to_hstring(props.title) : props.view.AccessibilityLabel());
|
|
118
|
+
Xaml::Automation::AutomationProperties::SetName(control, props.view.AccessibilityLabel().empty() && kind == "Button" ? to_hstring(props.title) : props.view.AccessibilityLabel());
|
|
117
119
|
if (kind == "Button") {
|
|
118
120
|
auto button = control.as<Xaml::Controls::Button>();
|
|
119
121
|
button.Content(box_value(to_hstring(props.title)));
|
|
120
122
|
// WinUI owns hover, pressed, keyboard, disabled, and accessibility states.
|
|
121
123
|
button.BorderThickness(props.variant == "borderless" ? Xaml::Thickness{0, 0, 0, 0} : Xaml::Thickness{1, 1, 1, 1});
|
|
122
124
|
} else if (kind == "TextInput") {
|
|
123
|
-
|
|
125
|
+
auto input = control.as<Xaml::Controls::TextBox>();
|
|
126
|
+
if (!initialized) input.Text(to_hstring(props.defaultText));
|
|
127
|
+
if (props.controlled && props.eventCount >= eventCount && input.Text() != to_hstring(props.text)) input.Text(to_hstring(props.text));
|
|
124
128
|
} else {
|
|
125
129
|
auto select = control.as<Xaml::Controls::ComboBox>();
|
|
126
130
|
if (items != props.itemsJson) {
|
|
@@ -153,6 +157,7 @@ inline void RegisterControls(React::IReactPackageBuilder const &package) {
|
|
|
153
157
|
if (previous) {
|
|
154
158
|
auto old = get_self<Props>(previous);
|
|
155
159
|
props->title = old->title; props->defaultText = old->defaultText; props->itemsJson = old->itemsJson;
|
|
160
|
+
props->text = old->text; props->controlled = old->controlled; props->eventCount = old->eventCount;
|
|
156
161
|
props->value = old->value; props->variant = old->variant; props->disabled = old->disabled;
|
|
157
162
|
}
|
|
158
163
|
props->view = view; return props.as<React::IComponentProps>();
|
|
@@ -22,7 +22,7 @@ static NSString *UnavailableReason(void) {
|
|
|
22
22
|
+ (instancetype)shared { static SparkUpdater *updater; static dispatch_once_t once; dispatch_once(&once, ^{ updater = [SparkUpdater new]; }); return updater; }
|
|
23
23
|
- (NSDictionary *)status {
|
|
24
24
|
NSString *reason = UnavailableReason();
|
|
25
|
-
NSMutableDictionary *result = [@{ @"available": @(!reason), @"started": @(self.started), @"canCheck": @(self.started && self.controller.updater.canCheckForUpdates), @"automaticallyChecks": @(self.started && self.controller.updater.automaticallyChecksForUpdates) } mutableCopy];
|
|
25
|
+
NSMutableDictionary *result = [@{ @"available": @(!reason), @"started": @(self.started), @"canCheck": @(self.started && self.controller.updater.canCheckForUpdates), @"automaticallyChecks": @(self.started && self.controller.updater.automaticallyChecksForUpdates), @"checkIntervalSeconds": reason ? NSNull.null : @(self.started ? self.controller.updater.updateCheckInterval : 3600) } mutableCopy];
|
|
26
26
|
if (reason) result[@"reason"] = reason;
|
|
27
27
|
if (!reason) result[@"feedURL"] = [NSBundle.mainBundle objectForInfoDictionaryKey:@"SUFeedURL"];
|
|
28
28
|
return result;
|
|
@@ -55,17 +55,30 @@ RCT_EXPORT_MODULE(NativeDesktopUpdates)
|
|
|
55
55
|
[NSRunLoop.mainRunLoop performBlock:^{
|
|
56
56
|
SparkUpdater *updater = [SparkUpdater shared];
|
|
57
57
|
if ([method isEqual:@"status"]) { resolve(SparkJSON([updater status])); return; }
|
|
58
|
-
if (![@[@"start", @"check", @"
|
|
58
|
+
if (![@[@"start", @"check", @"background", @"configure"] containsObject:method]) { SparkInvalid(reject, @"Unknown update operation"); return; }
|
|
59
|
+
NSDictionary *args = SparkArgs(json);
|
|
60
|
+
if ([method isEqual:@"configure"]) {
|
|
61
|
+
id enabled = args[@"automaticallyChecks"], interval = args[@"checkIntervalSeconds"];
|
|
62
|
+
if ((enabled && (![enabled isKindOfClass:NSNumber.class] || CFGetTypeID((__bridge CFTypeRef)enabled) != CFBooleanGetTypeID())) ||
|
|
63
|
+
(interval && (![interval isKindOfClass:NSNumber.class] || CFGetTypeID((__bridge CFTypeRef)interval) == CFBooleanGetTypeID() || !isfinite([interval doubleValue]) || [interval doubleValue] <= 0))) {
|
|
64
|
+
SparkInvalid(reject, @"Invalid updater configuration"); return;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
59
67
|
NSString *reason = UnavailableReason();
|
|
60
|
-
if (reason) { reject(@"
|
|
68
|
+
if (reason) { reject(@"E_UNAVAILABLE", [@"Updates require a configured standalone release app; current state: " stringByAppendingString:reason], nil); return; }
|
|
61
69
|
NSError *error = nil;
|
|
62
|
-
if (![updater start:&error]) { reject(@"
|
|
70
|
+
if (![updater start:&error]) { reject(@"E_NATIVE", error.localizedDescription ?: @"Could not start updater", error); return; }
|
|
63
71
|
if ([method isEqual:@"check"]) {
|
|
64
|
-
if (!updater.controller.updater.canCheckForUpdates) { reject(@"
|
|
72
|
+
if (!updater.controller.updater.canCheckForUpdates) { reject(@"E_BUSY", @"An update session is already running", nil); return; }
|
|
65
73
|
[updater.controller checkForUpdates:nil]; resolve(@"null");
|
|
66
|
-
} else if ([method isEqual:@"
|
|
67
|
-
updater.controller.updater.
|
|
68
|
-
|
|
74
|
+
} else if ([method isEqual:@"background"]) {
|
|
75
|
+
if (!updater.controller.updater.canCheckForUpdates) { reject(@"E_BUSY", @"An update session is already running", nil); return; }
|
|
76
|
+
[updater.controller.updater checkForUpdatesInBackground]; resolve(@"null");
|
|
77
|
+
} else if ([method isEqual:@"configure"]) {
|
|
78
|
+
if (args[@"automaticallyChecks"]) updater.controller.updater.automaticallyChecksForUpdates = [args[@"automaticallyChecks"] boolValue];
|
|
79
|
+
if (args[@"checkIntervalSeconds"]) updater.controller.updater.updateCheckInterval = [args[@"checkIntervalSeconds"] doubleValue];
|
|
80
|
+
resolve(@"null");
|
|
81
|
+
} else resolve(@"null");
|
|
69
82
|
}];
|
|
70
83
|
}
|
|
71
84
|
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params { return std::make_shared<facebook::react::NativeDesktopUpdatesSpecJSI>(params); }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-updates",
|
|
3
|
-
"version": "0.0.1-next.
|
|
3
|
+
"version": "0.0.1-next.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"react-native": "src/index.ts",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
]
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@legendapp/spark-desktop-app": "0.0.1-next.
|
|
41
|
+
"@legendapp/spark-desktop-app": "0.0.1-next.3"
|
|
42
42
|
},
|
|
43
43
|
"private": true
|
|
44
44
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { TurboModule } from "react-native";
|
|
2
2
|
import { TurboModuleRegistry } from "react-native";
|
|
3
|
-
export interface Spec extends TurboModule {
|
|
4
|
-
|
|
3
|
+
export interface Spec extends TurboModule {
|
|
4
|
+
call(method: string, args: string): Promise<string>; }
|
|
5
|
+
export default TurboModuleRegistry.get<Spec>("NativeDesktopUpdates");
|
|
@@ -1,23 +1,79 @@
|
|
|
1
|
+
import { Platform } from "react-native";
|
|
1
2
|
import Native from "./NativeDesktopUpdates";
|
|
2
|
-
import { onDesktopEvent } from "@legendapp/spark-desktop-app";
|
|
3
|
+
import { onDesktopEvent } from "@legendapp/spark-desktop-app/src/events";
|
|
4
|
+
import { SparkError, invokeNative, parseNativeResult, type Subscription } from "@legendapp/spark-desktop-app/src/contracts";
|
|
5
|
+
export type { Subscription } from "@legendapp/spark-desktop-app/src/contracts";
|
|
3
6
|
|
|
7
|
+
export type UpdateUnavailableReason = "unsupported-platform" | "missing-module" | "go" | "development" | "unconfigured";
|
|
4
8
|
export type UpdateStatus = {
|
|
5
|
-
available:
|
|
6
|
-
reason?: "go" | "development" | "unconfigured";
|
|
9
|
+
available: true;
|
|
7
10
|
started: boolean;
|
|
8
11
|
canCheck: boolean;
|
|
9
12
|
automaticallyChecks: boolean;
|
|
10
|
-
|
|
13
|
+
checkIntervalSeconds: number;
|
|
14
|
+
feedURL: string;
|
|
15
|
+
} | {
|
|
16
|
+
available: false;
|
|
17
|
+
reason: UpdateUnavailableReason;
|
|
18
|
+
started: false;
|
|
19
|
+
canCheck: false;
|
|
20
|
+
automaticallyChecks: false;
|
|
21
|
+
checkIntervalSeconds: null;
|
|
11
22
|
};
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
export
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
export interface UpdateConfiguration { automaticallyChecks?: boolean; checkIntervalSeconds?: number }
|
|
24
|
+
export interface CheckForUpdatesOptions { mode?: "interactive" | "background" }
|
|
25
|
+
export type UpdateEvent =
|
|
26
|
+
| { type: "update"; state: "checking" | "notAvailable" }
|
|
27
|
+
| { type: "update"; state: "available" | "downloading" | "downloaded" | "installing"; version: string }
|
|
28
|
+
| { type: "update"; state: "error"; message: string };
|
|
29
|
+
function native() {
|
|
30
|
+
if (Platform.OS !== "macos") throw new SparkError("E_UNSUPPORTED_PLATFORM", "Native app updates require macOS");
|
|
31
|
+
if (!Native) throw new SparkError("E_MODULE_UNAVAILABLE", "Native app updater is not installed");
|
|
32
|
+
return Native;
|
|
33
|
+
}
|
|
34
|
+
const unavailable = (reason: UpdateUnavailableReason): UpdateStatus => ({ available: false, reason, started: false, canCheck: false, automaticallyChecks: false, checkIntervalSeconds: null });
|
|
35
|
+
function validStatus(value: unknown): value is UpdateStatus {
|
|
36
|
+
if (!value || typeof value !== "object") return false;
|
|
37
|
+
const status = value as UpdateStatus;
|
|
38
|
+
if (status.available === false) return ["go", "development", "unconfigured"].includes(status.reason) && status.started === false && status.canCheck === false && status.automaticallyChecks === false && status.checkIntervalSeconds === null;
|
|
39
|
+
return status.available === true && typeof status.started === "boolean" && typeof status.canCheck === "boolean" && typeof status.automaticallyChecks === "boolean" && Number.isFinite(status.checkIntervalSeconds) && status.checkIntervalSeconds > 0 && typeof status.feedURL === "string" && status.feedURL.startsWith("https://");
|
|
40
|
+
}
|
|
41
|
+
async function command(method: string, args: object = {}): Promise<void> {
|
|
42
|
+
parseNativeResult(await invokeNative(() => native().call(method, JSON.stringify(args))), (value): value is null => value === null);
|
|
43
|
+
}
|
|
44
|
+
/** Querying never starts the updater. Missing modules and unsupported targets are reported. */
|
|
45
|
+
export async function getUpdateStatus(): Promise<UpdateStatus> {
|
|
46
|
+
if (Platform.OS !== "macos") return unavailable("unsupported-platform");
|
|
47
|
+
if (!Native) return unavailable("missing-module");
|
|
48
|
+
return parseNativeResult(await invokeNative(() => native().call("status", "{}")), validStatus);
|
|
49
|
+
}
|
|
50
|
+
/** Start the scheduler after app readiness. Repeated starts are safe. */
|
|
51
|
+
export async function startUpdates(): Promise<void> { await command("start"); }
|
|
52
|
+
function options(value: unknown, keys: string[]) {
|
|
53
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new SparkError("E_INVALID_ARGUMENT", "Expected update options");
|
|
54
|
+
for (const key of Object.keys(value)) if (!keys.includes(key)) throw new SparkError("E_UNSUPPORTED_OPTION", `Unsupported update option: ${key}`);
|
|
55
|
+
}
|
|
56
|
+
/** Resolves when initiated. Events describe progress, not the returned promise. */
|
|
57
|
+
export async function checkForUpdates(config: CheckForUpdatesOptions = {}): Promise<void> {
|
|
58
|
+
options(config, ["mode"]);
|
|
59
|
+
const mode = config.mode ?? "interactive";
|
|
60
|
+
if (!["interactive", "background"].includes(mode)) throw new SparkError("E_INVALID_ARGUMENT", "Invalid update check mode");
|
|
61
|
+
await command(mode === "interactive" ? "check" : "background");
|
|
62
|
+
}
|
|
63
|
+
/** Omission keeps a preference unchanged. Sparkle persists the user's choices. */
|
|
64
|
+
export async function configureUpdates(config: UpdateConfiguration): Promise<void> {
|
|
65
|
+
options(config, ["automaticallyChecks", "checkIntervalSeconds"]);
|
|
66
|
+
if (config.automaticallyChecks !== undefined && typeof config.automaticallyChecks !== "boolean") throw new SparkError("E_INVALID_ARGUMENT", "automaticallyChecks must be boolean");
|
|
67
|
+
if (config.checkIntervalSeconds !== undefined && (!Number.isFinite(config.checkIntervalSeconds) || config.checkIntervalSeconds <= 0)) throw new SparkError("E_INVALID_ARGUMENT", "Update interval must be positive finite seconds");
|
|
68
|
+
await command("configure", config);
|
|
69
|
+
}
|
|
70
|
+
export function onUpdateEvent(listener: (event: UpdateEvent) => void): Subscription {
|
|
71
|
+
if (typeof listener !== "function") throw new SparkError("E_INVALID_ARGUMENT", "Expected an update listener");
|
|
72
|
+
native();
|
|
73
|
+
return onDesktopEvent(event => {
|
|
74
|
+
if (event.type !== "update" || typeof event.state !== "string") return;
|
|
75
|
+
const version = typeof event.version === "string", message = typeof event.message === "string";
|
|
76
|
+
const valid = ["checking", "notAvailable"].includes(event.state) || (["available", "downloading", "downloaded", "installing"].includes(event.state) && version) || (event.state === "error" && message);
|
|
77
|
+
if (valid) listener(event as unknown as UpdateEvent);
|
|
78
|
+
}, { types: ["update"] });
|
|
23
79
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-webview",
|
|
3
|
-
"version": "0.0.1-next.
|
|
3
|
+
"version": "0.0.1-next.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"react-native": "src/index.ts",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
],
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"react-native-webview": "16.0.0",
|
|
12
|
-
"@legendapp/spark-desktop-app": "0.0.1-next.
|
|
12
|
+
"@legendapp/spark-desktop-app": "0.0.1-next.3"
|
|
13
13
|
},
|
|
14
14
|
"private": true
|
|
15
15
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { forwardRef, useImperativeHandle, useRef } from "react";
|
|
2
|
+
import { WebView as BackendWebView } from "react-native-webview";
|
|
3
|
+
import { backendProps, webViewRef } from "./adapter";
|
|
4
|
+
import type { WebViewProps, WebViewRef } from "./types";
|
|
5
|
+
|
|
6
|
+
/** Spark-owned props, events and ref; backend-specific APIs remain private. */
|
|
7
|
+
export const WebView = forwardRef<WebViewRef, WebViewProps>(function WebView(props, ref) {
|
|
8
|
+
const native = useRef<BackendWebView>(null);
|
|
9
|
+
useImperativeHandle(ref, () => webViewRef(() => native.current), []);
|
|
10
|
+
return <BackendWebView {...backendProps(props)} ref={native} />;
|
|
11
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { SparkError } from "@legendapp/spark-desktop-app/src/contracts";
|
|
2
|
+
import type { WebViewProps as BackendProps } from "react-native-webview";
|
|
3
|
+
import { viewPropKeys } from "./view-props";
|
|
4
|
+
import type { ViewPropKey } from "./view-props";
|
|
5
|
+
import type { WebViewProps, WebViewRef } from "./types";
|
|
6
|
+
|
|
7
|
+
const ownedProps = new Set(["source", "javaScriptEnabled", "injectedJavaScript", "allowedOrigins", "onMessage", "onLoad", "onError", "onNavigationChange", "onNavigationRequest"]);
|
|
8
|
+
/** React Native view props pass through; upstream WebView's specialized surface stays private. */
|
|
9
|
+
const forwardedProps = new Set<string>(viewPropKeys);
|
|
10
|
+
export function backendProps(props: WebViewProps): BackendProps {
|
|
11
|
+
for (const key of Object.keys(props)) {
|
|
12
|
+
if (!ownedProps.has(key) && !forwardedProps.has(key)) throw new SparkError("E_UNSUPPORTED_OPTION", `Unsupported WebView prop: ${key}`);
|
|
13
|
+
}
|
|
14
|
+
const { source } = props;
|
|
15
|
+
if (!source || (typeof source.uri === "string") === (typeof source.html === "string")) {
|
|
16
|
+
throw new SparkError("E_INVALID_ARGUMENT", "WebView source must specify either uri or html");
|
|
17
|
+
}
|
|
18
|
+
const view: Record<string, unknown> = {};
|
|
19
|
+
for (const key of viewPropKeys) {
|
|
20
|
+
const value = props[key as ViewPropKey];
|
|
21
|
+
if (value !== undefined) view[key] = value;
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
...view,
|
|
25
|
+
source: typeof source.html === "string" ? { html: source.html, baseUrl: source.baseUri } : { uri: source.uri!, headers: source.headers },
|
|
26
|
+
javaScriptEnabled: props.javaScriptEnabled ?? true,
|
|
27
|
+
injectedJavaScript: props.injectedJavaScript,
|
|
28
|
+
originWhitelist: props.allowedOrigins ? [...props.allowedOrigins] : typeof source.html === "string" ? ["*"] : ["http://*", "https://*"],
|
|
29
|
+
onMessage: props.onMessage ? ({ nativeEvent: event }) => props.onMessage!({ data: event.data, uri: event.url }) : undefined,
|
|
30
|
+
onLoad: props.onLoad ? ({ nativeEvent: event }) => props.onLoad!({ uri: event.url }) : undefined,
|
|
31
|
+
onError: props.onError ? ({ nativeEvent: event }) => props.onError!({ type: "load", uri: event.url, code: event.code, message: event.description }) : undefined,
|
|
32
|
+
onHttpError: props.onError ? ({ nativeEvent: event }) => props.onError!({ type: "http", uri: event.url, status: event.statusCode, message: event.description }) : undefined,
|
|
33
|
+
onNavigationStateChange: props.onNavigationChange ? event => props.onNavigationChange!({ uri: event.url, title: event.title, loading: event.loading, canGoBack: event.canGoBack, canGoForward: event.canGoForward }) : undefined,
|
|
34
|
+
onShouldStartLoadWithRequest: props.onNavigationRequest ? event => props.onNavigationRequest!({ uri: event.url, mainFrame: typeof event.isTopFrame === "boolean" ? event.isTopFrame : null }) : undefined,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function webViewRef(current: () => WebViewRef | null): WebViewRef {
|
|
39
|
+
function view() {
|
|
40
|
+
const value = current();
|
|
41
|
+
if (!value) throw new SparkError("E_CLOSED", "WebView is not mounted");
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
reload: () => view().reload(), goBack: () => view().goBack(), goForward: () => view().goForward(),
|
|
46
|
+
postMessage(message) {
|
|
47
|
+
if (typeof message !== "string") throw new SparkError("E_INVALID_ARGUMENT", "WebView messages must be strings");
|
|
48
|
+
view().postMessage(message);
|
|
49
|
+
},
|
|
50
|
+
injectJavaScript(script) {
|
|
51
|
+
if (typeof script !== "string") throw new SparkError("E_INVALID_ARGUMENT", "WebView scripts must be strings");
|
|
52
|
+
view().injectJavaScript(script);
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { WebView } from "
|
|
2
|
-
export type { WebViewProps, WebViewMessageEvent, WebViewNavigation } from "
|
|
1
|
+
export { WebView } from "./WebView";
|
|
2
|
+
export type { WebViewProps, WebViewRef, WebViewSource, WebViewMessageEvent, WebViewNavigation, WebViewNavigationRequest, WebViewErrorEvent } from "./types";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ViewProps } from "react-native";
|
|
2
|
+
export type WebViewSource =
|
|
3
|
+
| { uri: string; headers?: Record<string, string>; html?: never; baseUri?: never }
|
|
4
|
+
| { html: string; baseUri?: string; uri?: never; headers?: never };
|
|
5
|
+
export type WebViewMessageEvent = { data: string; uri: string };
|
|
6
|
+
export type WebViewNavigation = { uri: string; title: string; loading: boolean; canGoBack: boolean; canGoForward: boolean };
|
|
7
|
+
export type WebViewNavigationRequest = { uri: string; mainFrame: boolean | null };
|
|
8
|
+
export type WebViewErrorEvent =
|
|
9
|
+
| { type: "load"; uri: string; code: number; message: string }
|
|
10
|
+
| { type: "http"; uri: string; status: number; message: string };
|
|
11
|
+
/** React Native's view props are accepted; WebView-specific behavior is owned here. Children are not: the rendered content is the source document. */
|
|
12
|
+
export interface WebViewProps extends Omit<ViewProps, "children"> {
|
|
13
|
+
source: WebViewSource;
|
|
14
|
+
javaScriptEnabled?: boolean;
|
|
15
|
+
/** Script executed after page load. Applies to trusted document content. */
|
|
16
|
+
injectedJavaScript?: string;
|
|
17
|
+
/** Origin patterns accepted by the current adapter; default is HTTP/HTTPS. Inline HTML permits all origins. */
|
|
18
|
+
allowedOrigins?: readonly string[];
|
|
19
|
+
onMessage?: (event: WebViewMessageEvent) => void;
|
|
20
|
+
onLoad?: (event: { uri: string }) => void;
|
|
21
|
+
onError?: (event: WebViewErrorEvent) => void;
|
|
22
|
+
onNavigationChange?: (event: WebViewNavigation) => void;
|
|
23
|
+
/** Synchronous native navigation decision where emitted; not a network security boundary. */
|
|
24
|
+
onNavigationRequest?: (event: WebViewNavigationRequest) => boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface WebViewRef {
|
|
27
|
+
reload(): void;
|
|
28
|
+
goBack(): void;
|
|
29
|
+
goForward(): void;
|
|
30
|
+
postMessage(message: string): void;
|
|
31
|
+
injectJavaScript(script: string): void;
|
|
32
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ViewProps } from "react-native";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* React Native's own view props, forwarded to the backend view. `children` is omitted:
|
|
5
|
+
* a WebView renders a document, not React children. The `satisfies` clause makes the
|
|
6
|
+
* list fail to compile if it names something React Native does not accept.
|
|
7
|
+
*/
|
|
8
|
+
export const viewPropKeys = [
|
|
9
|
+
"accessibilityActions", "accessibilityElementsHidden", "accessibilityHint", "accessibilityIgnoresInvertColors",
|
|
10
|
+
"accessibilityLabel", "accessibilityLabelledBy", "accessibilityLanguage", "accessibilityLargeContentTitle",
|
|
11
|
+
"accessibilityLiveRegion", "accessibilityRespondsToUserInteraction", "accessibilityRole",
|
|
12
|
+
"accessibilityShowsLargeContentViewer", "accessibilityState", "accessibilityValue", "accessibilityViewIsModal",
|
|
13
|
+
"accessible", "aria-busy", "aria-checked", "aria-disabled", "aria-expanded", "aria-hidden", "aria-label",
|
|
14
|
+
"aria-labelledby", "aria-live", "aria-modal", "aria-selected", "aria-valuemax", "aria-valuemin", "aria-valuenow",
|
|
15
|
+
"aria-valuetext", "collapsable", "collapsableChildren", "focusable", "hasTVPreferredFocus", "hitSlop", "id",
|
|
16
|
+
"importantForAccessibility", "isTVSelectable", "nativeID", "needsOffscreenAlphaCompositing",
|
|
17
|
+
"onAccessibilityAction", "onAccessibilityEscape", "onAccessibilityTap", "onBlur", "onFocus", "onLayout",
|
|
18
|
+
"onMagicTap", "onMoveShouldSetResponder", "onMoveShouldSetResponderCapture", "onPointerCancel",
|
|
19
|
+
"onPointerCancelCapture", "onPointerDown", "onPointerDownCapture", "onPointerEnter", "onPointerEnterCapture",
|
|
20
|
+
"onPointerLeave", "onPointerLeaveCapture", "onPointerMove", "onPointerMoveCapture", "onPointerUp",
|
|
21
|
+
"onPointerUpCapture", "onResponderEnd", "onResponderGrant", "onResponderMove", "onResponderReject",
|
|
22
|
+
"onResponderRelease", "onResponderStart", "onResponderTerminate", "onResponderTerminationRequest",
|
|
23
|
+
"onStartShouldSetResponder", "onStartShouldSetResponderCapture", "onTouchCancel", "onTouchEnd",
|
|
24
|
+
"onTouchEndCapture", "onTouchMove", "onTouchStart", "pointerEvents", "removeClippedSubviews",
|
|
25
|
+
"renderToHardwareTextureAndroid", "role", "screenReaderFocusable", "shouldRasterizeIOS", "style", "tabIndex",
|
|
26
|
+
"testID", "tvParallaxMagnification", "tvParallaxShiftDistanceX", "tvParallaxShiftDistanceY", "tvParallaxTiltAngle",
|
|
27
|
+
] as const satisfies readonly (keyof Omit<ViewProps, "children">)[];
|
|
28
|
+
export type ViewPropKey = (typeof viewPropKeys)[number];
|
|
@@ -1,25 +1,62 @@
|
|
|
1
1
|
const enums = {
|
|
2
2
|
titleBarStyle: ["default", "overlay", "hidden", "borderless"],
|
|
3
3
|
appearance: ["system", "light", "dark"],
|
|
4
|
-
material: ["none", "sidebar", "windowBackground", "hudWindow", "popover"],
|
|
5
4
|
};
|
|
6
|
-
const
|
|
7
|
-
const
|
|
5
|
+
const booleans = ["resizable", "closable", "minimizable", "alwaysOnTop", "transparent", "hasShadow", "restoreBounds"];
|
|
6
|
+
const dimension = { type: "number", minimum: 100, maximum: 20000 };
|
|
7
|
+
const size = { type: "object", required: ["width", "height"], additionalProperties: false, properties: { width: dimension, height: dimension } };
|
|
8
|
+
const materials = ["none", "sidebar", "windowBackground", "hudWindow", "popover"];
|
|
9
|
+
const schema = {
|
|
10
|
+
type: "object", additionalProperties: false,
|
|
11
|
+
properties: {
|
|
12
|
+
size, minSize: { anyOf: [size, { type: "null" }] }, maxSize: { anyOf: [size, { type: "null" }] },
|
|
13
|
+
...Object.fromEntries(booleans.map(key => [key, { type: "boolean" }])),
|
|
14
|
+
...Object.fromEntries(Object.entries(enums).map(([key, values]) => [key, { enum: values }])),
|
|
15
|
+
title: { type: "string" }, backgroundColor: { type: "string", pattern: "^#[0-9a-fA-F]{6}([0-9a-fA-F]{2})?$" },
|
|
16
|
+
macos: { type: "object", additionalProperties: false, properties: {
|
|
17
|
+
backgroundMaterial: { enum: materials },
|
|
18
|
+
titleBar: { type: "object", additionalProperties: false, properties: { trafficLights: { type: "boolean" } } },
|
|
19
|
+
} },
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
function object(value, allowed, name) {
|
|
23
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${name} must be an object`);
|
|
24
|
+
for (const key of Object.keys(value)) if (!allowed.includes(key)) throw new Error(`Unknown ${name} option: ${key}`);
|
|
25
|
+
}
|
|
8
26
|
function validateWindow(options) {
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if (size
|
|
27
|
+
object(options, Object.keys(schema.properties), "window");
|
|
28
|
+
for (const key of ["size", "minSize", "maxSize"]) if (options[key] !== undefined && !(key !== "size" && options[key] === null)) {
|
|
29
|
+
object(options[key], ["width", "height"], key);
|
|
30
|
+
for (const axis of ["width", "height"]) if (!Number.isFinite(options[key][axis]) || options[key][axis] < 100 || options[key][axis] > 20000) throw new Error(`${key}.${axis} must be between 100 and 20000 logical units`);
|
|
31
|
+
}
|
|
32
|
+
for (const axis of ["width", "height"]) {
|
|
33
|
+
const min = options.minSize?.[axis] ?? 100, max = options.maxSize?.[axis] ?? 20000;
|
|
34
|
+
if (min > max) throw new Error(`minSize.${axis} exceeds maxSize.${axis}`);
|
|
35
|
+
if (options.size && (options.size[axis] < min || options.size[axis] > max)) throw new Error(`size.${axis} is outside its constraints`);
|
|
18
36
|
}
|
|
19
37
|
for (const key of booleans) if (options[key] !== undefined && typeof options[key] !== "boolean") throw new Error(`${key} must be a boolean`);
|
|
20
38
|
for (const [key, values] of Object.entries(enums)) if (options[key] !== undefined && !values.includes(options[key])) throw new Error(`Invalid ${key}`);
|
|
21
39
|
if (options.title !== undefined && typeof options.title !== "string") throw new Error("title must be a string");
|
|
22
|
-
if (options.backgroundColor !== undefined &&
|
|
40
|
+
if (options.backgroundColor !== undefined && (typeof options.backgroundColor !== "string" || !new RegExp(schema.properties.backgroundColor.pattern).test(options.backgroundColor))) throw new Error("backgroundColor must be #RRGGBB or #RRGGBBAA");
|
|
41
|
+
if (options.macos !== undefined) {
|
|
42
|
+
object(options.macos, ["backgroundMaterial", "titleBar"], "macos");
|
|
43
|
+
if (options.macos.backgroundMaterial !== undefined && !materials.includes(options.macos.backgroundMaterial)) throw new Error("Invalid macos.backgroundMaterial");
|
|
44
|
+
if (options.macos.titleBar !== undefined) {
|
|
45
|
+
object(options.macos.titleBar, ["trafficLights"], "macos.titleBar");
|
|
46
|
+
if (options.macos.titleBar.trafficLights !== undefined && typeof options.macos.titleBar.trafficLights !== "boolean") throw new Error("trafficLights must be a boolean");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
23
49
|
return options;
|
|
24
50
|
}
|
|
25
|
-
|
|
51
|
+
// Private host transport. Consumers only author the grouped configuration above.
|
|
52
|
+
function nativeWindowOptions(value) {
|
|
53
|
+
const { size, minSize, maxSize, restoreBounds, macos, ...result } = validateWindow(value);
|
|
54
|
+
for (const [prefix, dimensions] of [["", size], ["min", minSize], ["max", maxSize]]) if (dimensions) {
|
|
55
|
+
for (const axis of ["width", "height"]) result[prefix ? prefix + axis[0].toUpperCase() + axis.slice(1) : axis] = dimensions[axis];
|
|
56
|
+
}
|
|
57
|
+
if (restoreBounds !== undefined) result.restoreFrame = restoreBounds;
|
|
58
|
+
if (macos?.backgroundMaterial !== undefined) result.material = macos.backgroundMaterial;
|
|
59
|
+
if (macos?.titleBar?.trafficLights !== undefined) result.trafficLights = macos.titleBar.trafficLights;
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
module.exports = { validateWindow, nativeWindowOptions, schema };
|
|
@@ -1,12 +1,25 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface WindowSize { width: number; height: number }
|
|
2
|
+
/** Initial outer frame dimensions in logical units, matching the runtime window API. */
|
|
3
|
+
export interface WindowConfiguration {
|
|
2
4
|
title?: string;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
size?: WindowSize;
|
|
6
|
+
minSize?: WindowSize | null;
|
|
7
|
+
maxSize?: WindowSize | null;
|
|
8
|
+
resizable?: boolean;
|
|
9
|
+
closable?: boolean;
|
|
10
|
+
minimizable?: boolean;
|
|
11
|
+
alwaysOnTop?: boolean;
|
|
12
|
+
transparent?: boolean;
|
|
13
|
+
hasShadow?: boolean;
|
|
14
|
+
restoreBounds?: boolean;
|
|
7
15
|
titleBarStyle?: "default" | "overlay" | "hidden" | "borderless";
|
|
8
16
|
appearance?: "system" | "light" | "dark";
|
|
9
|
-
material?: "none" | "sidebar" | "windowBackground" | "hudWindow" | "popover";
|
|
10
17
|
backgroundColor?: string;
|
|
11
|
-
|
|
12
|
-
|
|
18
|
+
macos?: {
|
|
19
|
+
backgroundMaterial?: "none" | "sidebar" | "windowBackground" | "hudWindow" | "popover";
|
|
20
|
+
titleBar?: { trafficLights?: boolean };
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export function validateWindow(options: unknown): WindowConfiguration;
|
|
24
|
+
export function nativeWindowOptions(options: unknown): Record<string, string | number | boolean>;
|
|
25
|
+
export const schema: Record<string, unknown>;
|