@swiftbrowser/swift 0.1.0 → 0.3.0

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 (393) hide show
  1. package/Package.swift +200 -9
  2. package/README.md +7 -9
  3. package/Sources/AVFoundation/AVFoundation.swift +131 -0
  4. package/Sources/AVFoundation/Asset.swift +487 -0
  5. package/Sources/AVFoundation/AudioSession.swift +144 -0
  6. package/Sources/AVFoundation/CMTime.swift +303 -0
  7. package/Sources/AVFoundation/Capture.swift +688 -0
  8. package/Sources/AVFoundation/Player.swift +749 -0
  9. package/Sources/AVFoundation/PlayerView.swift +117 -0
  10. package/Sources/AVKit/AVKit.swift +132 -0
  11. package/Sources/Accelerate/Accelerate.swift +122 -0
  12. package/Sources/AppIntents/AppIntents.swift +144 -0
  13. package/Sources/AppIntents/Parameters.swift +220 -0
  14. package/Sources/AppIntents/Shortcuts.swift +159 -0
  15. package/Sources/AudioToolbox/AudioToolbox.swift +55 -0
  16. package/Sources/AuthenticationServices/AuthenticationServices.swift +257 -0
  17. package/Sources/AuthenticationServices/Authorization.swift +251 -0
  18. package/Sources/Charts/Charts.swift +0 -4
  19. package/Sources/Combine/AnyCancellable.swift +65 -0
  20. package/Sources/Combine/AnyPublisher.swift +148 -0
  21. package/Sources/Combine/AnySubscriber.swift +230 -0
  22. package/Sources/Combine/Cancellable.swift +35 -0
  23. package/Sources/Combine/Codable.swift +29 -0
  24. package/Sources/Combine/CombineIdentifier.swift +45 -0
  25. package/Sources/Combine/Concurrency/ConcurrencyHelpers.swift +24 -0
  26. package/Sources/Combine/Concurrency/Future+Concurrency.swift +136 -0
  27. package/Sources/Combine/Concurrency/GENERATED-Publisher+Concurrency.swift +397 -0
  28. package/Sources/Combine/CurrentValueSubject.swift +252 -0
  29. package/Sources/Combine/CustomCombineIdentifierConvertible.swift +28 -0
  30. package/Sources/Combine/Future.swift +228 -0
  31. package/Sources/Combine/GENERATED-RootProtocols.swift +426 -0
  32. package/Sources/Combine/Helpers/ConduitBase.swift +40 -0
  33. package/Sources/Combine/Helpers/ConduitList.swift +59 -0
  34. package/Sources/Combine/Helpers/DebugHook.swift +177 -0
  35. package/Sources/Combine/Helpers/FilterProducer.swift +174 -0
  36. package/Sources/Combine/Helpers/Locking.swift +30 -0
  37. package/Sources/Combine/Helpers/PartialCompletion.swift +26 -0
  38. package/Sources/Combine/Helpers/ReduceProducer.swift +249 -0
  39. package/Sources/Combine/Helpers/SubjectSubscriber.swift +96 -0
  40. package/Sources/Combine/Helpers/SubscriberTap.swift +69 -0
  41. package/Sources/Combine/Helpers/SubscriptionStatus.swift +33 -0
  42. package/Sources/Combine/Helpers/SubscriptionTap.swift +33 -0
  43. package/Sources/Combine/Helpers/Utils.swift +30 -0
  44. package/Sources/Combine/Helpers/Violations.swift +33 -0
  45. package/Sources/Combine/ImmediateScheduler.swift +178 -0
  46. package/Sources/Combine/LICENSE +21 -0
  47. package/Sources/Combine/NotificationPublisher.swift +48 -0
  48. package/Sources/Combine/ObjectWillChange.swift +46 -0
  49. package/Sources/Combine/PassthroughSubject.swift +222 -0
  50. package/Sources/Combine/Publisher+Subscribe.swift +53 -0
  51. package/Sources/Combine/Publishers/Deferred.swift +48 -0
  52. package/Sources/Combine/Publishers/Empty.swift +54 -0
  53. package/Sources/Combine/Publishers/Fail.swift +42 -0
  54. package/Sources/Combine/Publishers/GENERATED-Publishers.Catch.swift +673 -0
  55. package/Sources/Combine/Publishers/GENERATED-Publishers.Encode.swift +388 -0
  56. package/Sources/Combine/Publishers/GENERATED-Publishers.MapKeyPath.swift +384 -0
  57. package/Sources/Combine/Publishers/Just.swift +313 -0
  58. package/Sources/Combine/Publishers/Optional.Publisher.swift +315 -0
  59. package/Sources/Combine/Publishers/Publishers.AllSatisfy.swift +217 -0
  60. package/Sources/Combine/Publishers/Publishers.AssertNoFailure.swift +158 -0
  61. package/Sources/Combine/Publishers/Publishers.Autoconnect.swift +193 -0
  62. package/Sources/Combine/Publishers/Publishers.Breakpoint.swift +231 -0
  63. package/Sources/Combine/Publishers/Publishers.Buffer.swift +356 -0
  64. package/Sources/Combine/Publishers/Publishers.Collect.swift +102 -0
  65. package/Sources/Combine/Publishers/Publishers.CollectByCount.swift +195 -0
  66. package/Sources/Combine/Publishers/Publishers.CompactMap.swift +241 -0
  67. package/Sources/Combine/Publishers/Publishers.Comparison.swift +371 -0
  68. package/Sources/Combine/Publishers/Publishers.Concatenate.swift +474 -0
  69. package/Sources/Combine/Publishers/Publishers.Contains.swift +293 -0
  70. package/Sources/Combine/Publishers/Publishers.Count.swift +87 -0
  71. package/Sources/Combine/Publishers/Publishers.Debounce.swift +332 -0
  72. package/Sources/Combine/Publishers/Publishers.Delay.swift +269 -0
  73. package/Sources/Combine/Publishers/Publishers.Drop.swift +155 -0
  74. package/Sources/Combine/Publishers/Publishers.DropUntilOutput.swift +283 -0
  75. package/Sources/Combine/Publishers/Publishers.DropWhile.swift +378 -0
  76. package/Sources/Combine/Publishers/Publishers.Filter.swift +248 -0
  77. package/Sources/Combine/Publishers/Publishers.First.swift +261 -0
  78. package/Sources/Combine/Publishers/Publishers.FlatMap.swift +533 -0
  79. package/Sources/Combine/Publishers/Publishers.HandleEvents.swift +260 -0
  80. package/Sources/Combine/Publishers/Publishers.IgnoreOutput.swift +109 -0
  81. package/Sources/Combine/Publishers/Publishers.Last.swift +252 -0
  82. package/Sources/Combine/Publishers/Publishers.MakeConnectable.swift +82 -0
  83. package/Sources/Combine/Publishers/Publishers.Map.swift +351 -0
  84. package/Sources/Combine/Publishers/Publishers.MapError.swift +140 -0
  85. package/Sources/Combine/Publishers/Publishers.MeasureInterval.swift +187 -0
  86. package/Sources/Combine/Publishers/Publishers.Multicast.swift +284 -0
  87. package/Sources/Combine/Publishers/Publishers.Output.swift +241 -0
  88. package/Sources/Combine/Publishers/Publishers.PrefixUntilOutput.swift +197 -0
  89. package/Sources/Combine/Publishers/Publishers.PrefixWhile.swift +176 -0
  90. package/Sources/Combine/Publishers/Publishers.Print.swift +206 -0
  91. package/Sources/Combine/Publishers/Publishers.ReceiveOn.swift +227 -0
  92. package/Sources/Combine/Publishers/Publishers.Reduce.swift +204 -0
  93. package/Sources/Combine/Publishers/Publishers.RemoveDuplicates.swift +264 -0
  94. package/Sources/Combine/Publishers/Publishers.ReplaceEmpty.swift +201 -0
  95. package/Sources/Combine/Publishers/Publishers.ReplaceError.swift +211 -0
  96. package/Sources/Combine/Publishers/Publishers.Retry.swift +274 -0
  97. package/Sources/Combine/Publishers/Publishers.Scan.swift +331 -0
  98. package/Sources/Combine/Publishers/Publishers.Sequence.swift +437 -0
  99. package/Sources/Combine/Publishers/Publishers.SetFailureType.swift +120 -0
  100. package/Sources/Combine/Publishers/Publishers.Share.swift +104 -0
  101. package/Sources/Combine/Publishers/Publishers.SubscribeOn.swift +197 -0
  102. package/Sources/Combine/Publishers/Publishers.SwitchToLatest.swift +444 -0
  103. package/Sources/Combine/Publishers/Publishers.Throttle.swift +359 -0
  104. package/Sources/Combine/Publishers/Publishers.Timeout.swift +301 -0
  105. package/Sources/Combine/Publishers/Publishers.Zip.swift +720 -0
  106. package/Sources/Combine/Publishers/Publishers.swift +13 -0
  107. package/Sources/Combine/Publishers/Record.swift +237 -0
  108. package/Sources/Combine/Publishers/Result.Publisher.swift +337 -0
  109. package/Sources/Combine/Result.swift +46 -0
  110. package/Sources/Combine/Scheduler.swift +89 -0
  111. package/Sources/Combine/Schedulers.swift +211 -0
  112. package/Sources/Combine/Subject+Void.swift +17 -0
  113. package/Sources/Combine/Subscriber+Void.swift +20 -0
  114. package/Sources/Combine/Subscribers/Subscribers.Assign.swift +175 -0
  115. package/Sources/Combine/Subscribers/Subscribers.Completion.swift +90 -0
  116. package/Sources/Combine/Subscribers/Subscribers.Demand.swift +476 -0
  117. package/Sources/Combine/Subscribers/Subscribers.Sink.swift +206 -0
  118. package/Sources/Combine/Subscribers/Subscribers.swift +9 -0
  119. package/Sources/Combine/Subscription.swift +22 -0
  120. package/Sources/Combine/Subscriptions.swift +42 -0
  121. package/Sources/Combine/SwiftUIObservation.swift +10 -0
  122. package/Sources/Combine/_Introspection.swift +107 -0
  123. package/Sources/CommonCrypto/CommonCrypto.swift +80 -0
  124. package/Sources/Compression/Compression.swift +365 -0
  125. package/Sources/Compression/Deflate.swift +407 -0
  126. package/Sources/Compression/Zlib.swift +179 -0
  127. package/Sources/CoreFoundationTypes/CoreFoundationTypes.swift +101 -0
  128. package/Sources/CoreGraphics/CoreGraphics.swift +411 -0
  129. package/Sources/CoreGraphics/ProjectionTransforms.swift +28 -0
  130. package/Sources/CoreHaptics/CoreHaptics.swift +399 -0
  131. package/Sources/CoreImage/CIColor.swift +41 -0
  132. package/Sources/CoreImage/CIContext.swift +31 -0
  133. package/Sources/CoreImage/CIDetector.swift +57 -0
  134. package/Sources/CoreImage/CIFilter.swift +243 -0
  135. package/Sources/CoreImage/CIFilterBuiltins.swift +136 -0
  136. package/Sources/CoreImage/CIImage.swift +162 -0
  137. package/Sources/CoreImage/QRCode.swift +393 -0
  138. package/Sources/CoreLocation/Coordinate.swift +30 -0
  139. package/Sources/CoreLocation/Location.swift +65 -0
  140. package/Sources/CoreML/Evaluation.swift +414 -0
  141. package/Sources/CoreML/FeatureValue.swift +266 -0
  142. package/Sources/CoreML/Model.swift +269 -0
  143. package/Sources/CoreML/MultiArray.swift +92 -0
  144. package/Sources/CoreML/Specification.swift +233 -0
  145. package/Sources/CoreText/CoreText.swift +64 -0
  146. package/Sources/CoreTransferable/CoreTransferable.swift +606 -0
  147. package/Sources/CryptoKit/ChaChaPoly.swift +258 -0
  148. package/Sources/CryptoKit/CryptoKit.swift +375 -0
  149. package/Sources/CryptoKit/Curve25519.swift +317 -0
  150. package/Sources/CryptoKit/P256.swift +321 -0
  151. package/Sources/FoundationBridge/AppStorage.swift +165 -0
  152. package/Sources/FoundationBridge/AssetResources.swift +90 -0
  153. package/Sources/FoundationBridge/AsyncBytes.swift +128 -0
  154. package/Sources/FoundationBridge/AsyncImage.swift +116 -0
  155. package/Sources/FoundationBridge/AttributedStrings.swift +16 -0
  156. package/Sources/{_FoundationCommon → FoundationBridge}/Bundle.swift +41 -4
  157. package/Sources/FoundationBridge/CombineExports.swift +8 -0
  158. package/Sources/FoundationBridge/CoreFoundation.swift +77 -0
  159. package/Sources/FoundationBridge/Dispatch.swift +458 -0
  160. package/Sources/FoundationBridge/EnvironmentFoundation.swift +41 -0
  161. package/Sources/FoundationBridge/FileImporter.swift +128 -0
  162. package/Sources/FoundationBridge/FileSystem.swift +68 -0
  163. package/Sources/FoundationBridge/FoundationBridge.swift +24 -72
  164. package/Sources/FoundationBridge/HostResolution.swift +31 -0
  165. package/Sources/FoundationBridge/ItemProvider.swift +655 -0
  166. package/Sources/FoundationBridge/KeyValueObserving.swift +138 -0
  167. package/Sources/FoundationBridge/Links.swift +127 -0
  168. package/Sources/FoundationBridge/ListFormatter.swift +32 -0
  169. package/Sources/FoundationBridge/Localization.swift +149 -0
  170. package/Sources/FoundationBridge/Locks.swift +50 -0
  171. package/Sources/FoundationBridge/Markdown.swift +527 -0
  172. package/Sources/FoundationBridge/MeasurementFormat.swift +95 -0
  173. package/Sources/FoundationBridge/NotificationCenter.swift +154 -0
  174. package/Sources/FoundationBridge/OpenURLHandlers.swift +60 -0
  175. package/Sources/FoundationBridge/Operation.swift +195 -0
  176. package/Sources/FoundationBridge/ProcessInfo.swift +32 -0
  177. package/Sources/FoundationBridge/RelativeDateTimeFormatter.swift +136 -0
  178. package/Sources/FoundationBridge/SceneStorage.swift +78 -0
  179. package/Sources/FoundationBridge/SecurityExports.swift +8 -0
  180. package/Sources/FoundationBridge/Selector.swift +226 -0
  181. package/Sources/FoundationBridge/StringComparators.swift +17 -0
  182. package/Sources/FoundationBridge/Table.swift +211 -0
  183. package/Sources/FoundationBridge/TextAttributes.swift +42 -0
  184. package/Sources/FoundationBridge/Timer.swift +6 -1
  185. package/Sources/FoundationBridge/URLSession.swift +718 -0
  186. package/Sources/{_FoundationCommon → FoundationBridge}/UserDefaults.swift +17 -4
  187. package/Sources/FoundationBridge/WebAuthRedirects.swift +227 -0
  188. package/Sources/FoundationBridge/WebSocket.swift +187 -0
  189. package/Sources/FoundationModels/FoundationModels.swift +1098 -0
  190. package/Sources/ImageIO/GIF.swift +72 -0
  191. package/Sources/ImageIO/ImageIO.swift +248 -0
  192. package/Sources/ImageIO/ImageTypes.swift +28 -0
  193. package/Sources/LinkPresentation/LinkPresentation.swift +249 -0
  194. package/Sources/LocalAuthentication/LAContext.swift +86 -0
  195. package/Sources/MapKit/Geometry.swift +223 -0
  196. package/Sources/MapKit/Map.swift +638 -0
  197. package/Sources/MapKit/MapView.swift +229 -0
  198. package/Sources/MobileCoreServices/MobileCoreServices.swift +28 -0
  199. package/Sources/NaturalLanguage/LanguageIdentifier.swift +317 -0
  200. package/Sources/NaturalLanguage/NaturalLanguage.swift +135 -0
  201. package/Sources/OSLog/OSLog.swift +6 -0
  202. package/Sources/Photos/Photos.swift +572 -0
  203. package/Sources/PhotosUI/PhotosPicker.swift +248 -0
  204. package/Sources/PhotosUI/PhotosPickerItem.swift +261 -0
  205. package/Sources/QuickLook/QuickLook.swift +168 -0
  206. package/Sources/SafariServices/SafariServices.swift +106 -0
  207. package/Sources/Security/Security.swift +332 -0
  208. package/Sources/StoreKit/AppStore.swift +207 -0
  209. package/Sources/StoreKit/Products.swift +280 -0
  210. package/Sources/StoreKit/RequestReview.swift +28 -0
  211. package/Sources/StoreKit/StoreKit1.swift +486 -0
  212. package/Sources/StoreKit/StoreViews.swift +428 -0
  213. package/Sources/StoreKit/Transactions.swift +197 -0
  214. package/Sources/SwiftData/Macros.swift +58 -0
  215. package/Sources/SwiftData/ModelActor.swift +38 -0
  216. package/Sources/SwiftData/ModelContainer.swift +129 -0
  217. package/Sources/SwiftData/ModelContext.swift +451 -0
  218. package/Sources/SwiftData/PersistentModel.swift +238 -0
  219. package/Sources/SwiftData/Properties.swift +261 -0
  220. package/Sources/SwiftData/Query.swift +256 -0
  221. package/Sources/SwiftData/Schema.swift +192 -0
  222. package/Sources/SwiftData/Store.swift +146 -0
  223. package/Sources/SwiftData/StringPredicates.swift +125 -0
  224. package/Sources/SwiftDataMacros/EntryMacro.swift +82 -0
  225. package/Sources/SwiftDataMacros/GenerableMacro.swift +183 -0
  226. package/Sources/SwiftDataMacros/ModelActorMacro.swift +46 -0
  227. package/Sources/SwiftDataMacros/ModelMacro.swift +260 -0
  228. package/Sources/SwiftDataMacros/Plugin.swift +18 -0
  229. package/Sources/SwiftDataMacros/PredicateMacro.swift +1244 -0
  230. package/Sources/SwiftUI/API/Accessibility.swift +55 -6
  231. package/Sources/SwiftUI/API/AccessibilityExtras.swift +33 -0
  232. package/Sources/SwiftUI/API/AccessibilityFocus.swift +63 -0
  233. package/Sources/SwiftUI/API/Alert.swift +1 -1
  234. package/Sources/SwiftUI/API/AlignmentGuides.swift +68 -0
  235. package/Sources/SwiftUI/API/Animation.swift +37 -5
  236. package/Sources/SwiftUI/API/App.swift +31 -1
  237. package/Sources/SwiftUI/API/BindingCollections.swift +35 -0
  238. package/Sources/SwiftUI/API/BindingForEach.swift +27 -0
  239. package/Sources/SwiftUI/API/Bitmaps.swift +254 -0
  240. package/Sources/SwiftUI/API/ButtonStyles.swift +96 -0
  241. package/Sources/SwiftUI/API/Canvas.swift +337 -0
  242. package/Sources/SwiftUI/API/Color.swift +104 -28
  243. package/Sources/SwiftUI/API/ColorEffects.swift +52 -0
  244. package/Sources/SwiftUI/API/ColorPickerAndLabeledContent.swift +138 -0
  245. package/Sources/SwiftUI/API/ColorSpaces.swift +161 -0
  246. package/Sources/SwiftUI/API/Commands.swift +106 -0
  247. package/Sources/SwiftUI/API/ContainerBackground.swift +28 -0
  248. package/Sources/SwiftUI/API/ContentShape.swift +33 -0
  249. package/Sources/SwiftUI/API/ContentSizeCategory.swift +35 -0
  250. package/Sources/SwiftUI/API/ContentUnavailable.swift +101 -0
  251. package/Sources/SwiftUI/API/Controls.swift +59 -27
  252. package/Sources/SwiftUI/API/CustomLayout.swift +49 -10
  253. package/Sources/SwiftUI/API/CustomToolbarContent.swift +46 -0
  254. package/Sources/SwiftUI/API/Decorations.swift +1 -1
  255. package/Sources/SwiftUI/API/EditMode.swift +25 -82
  256. package/Sources/SwiftUI/API/Effects.swift +125 -10
  257. package/Sources/SwiftUI/API/Entry.swift +8 -0
  258. package/Sources/SwiftUI/API/Environment.swift +100 -9
  259. package/Sources/SwiftUI/API/EnvironmentSendable.swift +6 -0
  260. package/Sources/SwiftUI/API/Focus.swift +11 -3
  261. package/Sources/SwiftUI/API/Gauge.swift +26 -10
  262. package/Sources/SwiftUI/API/GeometryEffects.swift +232 -0
  263. package/Sources/SwiftUI/API/GeometryReader.swift +13 -2
  264. package/Sources/SwiftUI/API/GestureState.swift +65 -0
  265. package/Sources/SwiftUI/API/Gestures.swift +1 -1
  266. package/Sources/SwiftUI/API/Glass.swift +127 -0
  267. package/Sources/SwiftUI/API/Grid.swift +1 -1
  268. package/Sources/SwiftUI/API/GroupBoxAndControlGroup.swift +130 -0
  269. package/Sources/SwiftUI/API/KeyPress.swift +54 -0
  270. package/Sources/SwiftUI/API/LabelStyle.swift +13 -6
  271. package/Sources/SwiftUI/API/Layout.swift +71 -12
  272. package/Sources/SwiftUI/API/LazyStacks.swift +49 -0
  273. package/Sources/SwiftUI/API/LegacyAlert.swift +97 -0
  274. package/Sources/SwiftUI/API/Lists.swift +61 -6
  275. package/Sources/SwiftUI/API/Menu.swift +8 -1
  276. package/Sources/SwiftUI/API/Modifiers.swift +88 -12
  277. package/Sources/SwiftUI/API/MoreModifiers.swift +100 -0
  278. package/Sources/SwiftUI/API/Namespace.swift +44 -0
  279. package/Sources/SwiftUI/API/Navigation.swift +24 -9
  280. package/Sources/SwiftUI/API/NavigationDestinationBindings.swift +55 -0
  281. package/Sources/SwiftUI/API/ObservableObject.swift +16 -2
  282. package/Sources/SwiftUI/API/Path.swift +543 -0
  283. package/Sources/SwiftUI/API/Phase8Controls.swift +48 -31
  284. package/Sources/SwiftUI/API/PhaseAnimator.swift +130 -0
  285. package/Sources/SwiftUI/API/Picker.swift +14 -4
  286. package/Sources/SwiftUI/API/PointerAndKeyboard.swift +77 -0
  287. package/Sources/SwiftUI/API/Popover.swift +41 -0
  288. package/Sources/SwiftUI/API/Preferences.swift +262 -0
  289. package/Sources/SwiftUI/API/Presentation.swift +17 -4
  290. package/Sources/SwiftUI/API/PresentationExtras.swift +60 -0
  291. package/Sources/SwiftUI/API/Primitives.swift +168 -39
  292. package/Sources/SwiftUI/API/Publishers.swift +4 -4
  293. package/Sources/SwiftUI/API/Redaction.swift +75 -0
  294. package/Sources/SwiftUI/API/RowActions.swift +3 -2
  295. package/Sources/SwiftUI/API/Scenes.swift +131 -0
  296. package/Sources/SwiftUI/API/ScrollModifiers.swift +132 -0
  297. package/Sources/SwiftUI/API/ScrollTargets.swift +3 -3
  298. package/Sources/SwiftUI/API/ScrollViewReader.swift +144 -0
  299. package/Sources/SwiftUI/API/SectionSupplements.swift +86 -0
  300. package/Sources/SwiftUI/API/Shape.swift +214 -0
  301. package/Sources/SwiftUI/API/ShapeStyle.swift +187 -8
  302. package/Sources/SwiftUI/API/ShapeTrim.swift +78 -0
  303. package/Sources/SwiftUI/API/Sharing.swift +193 -0
  304. package/Sources/SwiftUI/API/StackLayouts.swift +199 -0
  305. package/Sources/SwiftUI/API/State.swift +18 -1
  306. package/Sources/SwiftUI/API/StatusGaps.swift +121 -0
  307. package/Sources/SwiftUI/API/SymbolEffects.swift +203 -0
  308. package/Sources/SwiftUI/API/TabContent.swift +841 -0
  309. package/Sources/SwiftUI/API/Table.swift +382 -0
  310. package/Sources/SwiftUI/API/Tabs.swift +148 -4
  311. package/Sources/SwiftUI/API/Tasks.swift +2 -2
  312. package/Sources/SwiftUI/API/Text.swift +386 -0
  313. package/Sources/SwiftUI/API/TextDates.swift +61 -0
  314. package/Sources/SwiftUI/API/TextDecorations.swift +52 -0
  315. package/Sources/SwiftUI/API/TextFieldAxis.swift +103 -0
  316. package/Sources/SwiftUI/API/TextFieldCommit.swift +52 -0
  317. package/Sources/SwiftUI/API/Toolbar.swift +52 -16
  318. package/Sources/SwiftUI/API/Transfer.swift +145 -0
  319. package/Sources/SwiftUI/API/UnevenRoundedRectangle.swift +66 -0
  320. package/Sources/SwiftUI/API/Video.swift +64 -0
  321. package/Sources/SwiftUI/API/View.swift +46 -2
  322. package/Sources/SwiftUI/API/ViewModifier.swift +4 -1
  323. package/Sources/SwiftUI/API/VisualEffect.swift +74 -1
  324. package/Sources/SwiftUI/API/Windows.swift +25 -0
  325. package/Sources/SwiftUI/Charts/Axis.swift +7 -1
  326. package/Sources/SwiftUI/Charts/AxisFormatsAndRanges.swift +68 -0
  327. package/Sources/SwiftUI/Charts/Chart.swift +17 -3
  328. package/Sources/SwiftUI/Charts/ChartProxy.swift +57 -0
  329. package/Sources/SwiftUI/Localization/Localization.swift +524 -0
  330. package/Sources/SwiftUI/Localization/PluralRules.swift +127 -0
  331. package/Sources/SwiftUI/Runtime/Executor.swift +2 -0
  332. package/Sources/SwiftUI/Runtime/Exports.swift +37 -1
  333. package/Sources/SwiftUI/Runtime/ImageSource.swift +310 -0
  334. package/Sources/SwiftUI/Runtime/JSON.swift +76 -4
  335. package/Sources/SwiftUI/Runtime/LazyRows.swift +99 -0
  336. package/Sources/SwiftUI/Runtime/Measurements.swift +140 -0
  337. package/Sources/SwiftUI/Runtime/Ops.swift +58 -12
  338. package/Sources/SwiftUI/Runtime/Reconciler.swift +10 -1
  339. package/Sources/SwiftUI/Runtime/Replay.swift +382 -0
  340. package/Sources/SwiftUI/Runtime/Runtime.swift +977 -198
  341. package/Sources/SwiftUI/Runtime/Sameness.swift +152 -0
  342. package/Sources/SwiftUI/Runtime/ViewPath.swift +89 -0
  343. package/Sources/SwiftUI/Runtime/ViewTraits.swift +175 -0
  344. package/Sources/SwiftUI/Runtime/WebAuthHeadless.swift +49 -0
  345. package/Sources/Symbols/Symbols.swift +25 -0
  346. package/Sources/Translation/Translation.swift +423 -0
  347. package/Sources/UIKit/Activity.swift +213 -0
  348. package/Sources/UIKit/Alerts.swift +69 -0
  349. package/Sources/UIKit/AppDelegate.swift +222 -0
  350. package/Sources/UIKit/Appearance.swift +84 -0
  351. package/Sources/UIKit/ColorConversions.swift +70 -0
  352. package/Sources/UIKit/Controls.swift +225 -0
  353. package/Sources/UIKit/Device.swift +200 -0
  354. package/Sources/UIKit/Feedback.swift +65 -0
  355. package/Sources/UIKit/Font.swift +307 -0
  356. package/Sources/UIKit/Graphics.swift +204 -0
  357. package/Sources/UIKit/HostingController.swift +185 -0
  358. package/Sources/UIKit/Identity.swift +24 -0
  359. package/Sources/UIKit/Introspectable.swift +510 -0
  360. package/Sources/UIKit/Pasteboard.swift +363 -0
  361. package/Sources/UIKit/PhotoAlbum.swift +81 -0
  362. package/Sources/UIKit/RemoteNotifications.swift +15 -0
  363. package/Sources/UIKit/Representable.swift +288 -0
  364. package/Sources/UIKit/SafeArea.swift +12 -0
  365. package/Sources/UIKit/SceneDelegates.swift +132 -0
  366. package/Sources/UIKit/Scenes.swift +40 -0
  367. package/Sources/UIKit/ScrollView.swift +157 -0
  368. package/Sources/UIKit/ShortcutItems.swift +67 -0
  369. package/Sources/UIKit/SymbolConfiguration.swift +124 -0
  370. package/Sources/UIKit/TargetAction.swift +123 -0
  371. package/Sources/UIKit/TextPaste.swift +161 -0
  372. package/Sources/UIKit/TextView.swift +538 -0
  373. package/Sources/UIKit/UIKit.swift +292 -0
  374. package/Sources/UIKit/UIView.swift +855 -0
  375. package/Sources/UIKit/ViewTranslation.swift +311 -0
  376. package/Sources/UniformTypeIdentifiers/UTType.swift +196 -0
  377. package/Sources/UserNotifications/Content.swift +370 -0
  378. package/Sources/UserNotifications/NotificationCenter.swift +309 -0
  379. package/Sources/WeatherKit/WeatherKit.swift +228 -0
  380. package/Sources/WebKit/WebKit.swift +245 -0
  381. package/Sources/os/os.swift +376 -0
  382. package/Sources/zlib/zlib.swift +6 -0
  383. package/index.d.ts +1 -1
  384. package/index.mjs +2 -2
  385. package/manifest.d.mts +2 -0
  386. package/manifest.mjs +41 -0
  387. package/package.json +5 -3
  388. package/sync-sources.mjs +21 -7
  389. package/Sources/FoundationLite/Common.swift +0 -3
  390. package/Sources/FoundationLite/FoundationLite.swift +0 -171
  391. package/Sources/FoundationLite/Interaction.swift +0 -146
  392. package/Sources/FoundationLite/Timer.swift +0 -48
  393. package/Sources/_FoundationCommon/_FoundationCommon.swift +0 -10
@@ -1,42 +1,99 @@
1
+ import Foundation
2
+
1
3
  // MARK: - Text
2
4
 
3
- /// A localization key. Without localization tables the key is the text;
4
- /// interpolations are rendered into it.
5
+ /// A localization key, as Xcode writes it in a string catalog: the literal
6
+ /// text with a specifier for each interpolation (`"\(count) posts"` is the
7
+ /// key `"%lld posts"` with the argument `count`), looked up in the app's string
8
+ /// tables when shown (Localization/Localization.swift). A key the tables lack
9
+ /// is its own text.
5
10
  public struct LocalizedStringKey: Equatable, Sendable, ExpressibleByStringInterpolation {
6
- public let key: String
11
+ /// The key, with `%%` for a literal percent sign when it has arguments.
12
+ let formatKey: String
13
+ let arguments: [Argument]
14
+
15
+ /// An interpolated value: one a specifier formats, or a view in the text.
16
+ enum Argument: Equatable, Sendable {
17
+ case value(_LocalizationArgument)
18
+ case image(Image)
19
+ case text(Text)
20
+
21
+ var formatted: _LocalizationArgument? {
22
+ if case .value(let value) = self { return value }
23
+ return nil
24
+ }
25
+ }
26
+
27
+ public init(_ value: String) { formatKey = value; arguments = [] }
28
+ public init(stringLiteral value: String) { formatKey = value; arguments = [] }
29
+ public init(stringInterpolation: StringInterpolation) {
30
+ formatKey = stringInterpolation.key
31
+ arguments = stringInterpolation.arguments
32
+ }
33
+
34
+ /// The localized text, views left out: what titles, labels and placeholders show.
35
+ public var key: String { _resolved(table: nil, bundlePath: nil) }
7
36
 
8
- public init(_ value: String) { key = value }
9
- public init(stringLiteral value: String) { key = value }
10
- public init(stringInterpolation: StringInterpolation) { key = stringInterpolation.text }
37
+ /// The localized text from `table` in the bundle at `bundlePath` (the main bundle when nil).
38
+ public func _resolved(table: String?, bundlePath: String?) -> String {
39
+ _Localization.string(key: formatKey, arguments: arguments.map(\.formatted), table: table, bundlePath: bundlePath)
40
+ }
41
+
42
+ /// The localized pieces, with the views in their places.
43
+ func _pieces(table: String?, bundlePath: String?) -> [_LocalizedPiece] {
44
+ _Localization.resolve(key: formatKey, arguments: arguments.map(\.formatted), table: table, bundlePath: bundlePath)
45
+ }
11
46
 
47
+ /// Builds the key as SwiftUI does: each interpolation adds the specifier of
48
+ /// its type (`%@` for strings and views, `%lld` for `Int`, `%lf` for
49
+ /// `Double`…) and an argument; literal percent signs are doubled.
12
50
  public struct StringInterpolation: StringInterpolationProtocol {
13
- var text = ""
51
+ var key = ""
52
+ var arguments: [Argument] = []
14
53
  public init(literalCapacity: Int, interpolationCount: Int) {}
15
- public mutating func appendLiteral(_ literal: String) { text += literal }
16
- public mutating func appendInterpolation<T>(_ value: T) { text += String(describing: value) }
17
- public mutating func appendInterpolation<T>(_ value: T, specifier: String) { text += String(describing: value) }
18
- }
19
- }
20
54
 
21
- public struct Text: Equatable, Sendable {
22
- let content: String
55
+ public mutating func appendLiteral(_ literal: String) {
56
+ key += literal.replacingOccurrences(of: "%", with: "%%")
57
+ }
23
58
 
24
- public init(verbatim content: String) { self.content = content }
25
- public init(_ key: LocalizedStringKey) { self.content = key.key }
26
- @_disfavoredOverload
27
- public init<S: StringProtocol>(_ content: S) { self.content = String(content) }
59
+ /// An argument with its specifier: for the shim's own interpolations (a date with a style).
60
+ public mutating func _append(_ argument: _LocalizationArgument, specifier: String) {
61
+ key += specifier
62
+ arguments.append(.value(argument))
63
+ }
28
64
 
29
- /// A value formatted by `format` (`FoundationLite` supplies the formats;
30
- /// FoundationBridge adds Foundation's `FormatStyle`).
31
- public init<F: _TextFormat>(_ input: F.Input, format: F) { content = format._formatText(input) }
65
+ /// A string the shim made (a formatted value): `%@`.
66
+ mutating func append(_ string: String) { _append(.string(string), specifier: "%@") }
32
67
 
33
- /// The text as a string, for bridge modules (a `prompt` becomes a placeholder).
34
- public var _content: String { content }
35
- }
36
- extension Text: _PrimitiveView {}
37
- extension Text: _HostView {
38
- var _kind: String { "text" }
39
- func _props(in environment: EnvironmentValues) -> _JSON { .object(["text": .string(content)]) }
68
+ public mutating func appendInterpolation(_ string: String) { append(string) }
69
+ public mutating func appendInterpolation<T>(_ value: T) { append(String(describing: value)) }
70
+ /// A number, with its type's specifier (`%lld` for `Int`, `%lf` for `Double`…).
71
+ public mutating func appendInterpolation<T: _FormatSpecifiable>(_ value: T) {
72
+ _append(value._localizationArgument, specifier: T._specifier)
73
+ }
74
+
75
+ /// `"\(value, specifier: "%.1f")"`: the key holds the given specifier.
76
+ public mutating func appendInterpolation<T>(_ value: T, specifier: String) {
77
+ _append((value as? any _FormatSpecifiable)?._localizationArgument ?? .string(String(describing: value)), specifier: specifier)
78
+ }
79
+
80
+ /// `"\(price, format: .currency(code: "USD"))"`: `%@`, the formatted value.
81
+ public mutating func appendInterpolation<F: FormatStyle>(_ value: F.FormatInput, format: F) where F.FormatOutput == String {
82
+ append(format.format(value))
83
+ }
84
+
85
+ /// An image inline in the text: `Text("\(Image(systemName: "star")) Favorites")`.
86
+ public mutating func appendInterpolation(_ image: Image) {
87
+ key += "%@"
88
+ arguments.append(.image(image))
89
+ }
90
+
91
+ /// A styled text inline: `Text("Hello \(Text("world").bold())")`.
92
+ public mutating func appendInterpolation(_ text: Text) {
93
+ key += "%@"
94
+ arguments.append(.text(text))
95
+ }
96
+ }
40
97
  }
41
98
 
42
99
  // MARK: - Image
@@ -49,26 +106,36 @@ public struct Image: Equatable, Sendable {
49
106
  enum Source: Equatable, Sendable {
50
107
  case system(String)
51
108
  case named(String)
109
+ /// Phase 13: a remote image the browser loads itself (`AsyncImage`);
110
+ /// `width` and `height` are its intrinsic size in points.
111
+ case url(String, width: Double, height: Double)
112
+ /// A `UIImage` or `CGImage` bitmap the page draws from its recipe
113
+ /// (Bitmaps.swift); `width` and `height` are its size in points.
114
+ case bitmap(_ImageRecipe, width: Double, height: Double)
52
115
  }
53
116
 
54
117
  let source: Source
55
118
  /// `.resizable()`: fill the proposed size instead of the intrinsic one.
56
119
  let isResizable: Bool
120
+ /// `.interpolation(.none)`: scaled without smoothing (a QR code's modules
121
+ /// stay square). The other levels draw as the browser smooths.
122
+ var interpolation: Interpolation = .high
57
123
 
58
124
  public init(systemName: String) {
59
125
  source = .system(systemName)
60
126
  isResizable = false
61
127
  }
62
128
 
63
- /// An image from the asset catalog. SwiftUI's `bundle:` parameter is not
64
- /// offered: a Wasm app has no bundles, the catalog is the whole app's.
129
+ /// An image from the asset catalog, which is the whole app's: packages'
130
+ /// catalogs included. `Image(_:bundle:)` (FoundationBridge, which has
131
+ /// `Bundle`) draws the same image.
65
132
  public init(_ name: String) {
66
133
  source = .named(name)
67
134
  isResizable = false
68
135
  }
69
136
 
70
137
  /// A catalog image hidden from assistive technology (no bridge in the
71
- /// browser, so it draws like `Image(_:)`). As for `Image(_:)`, no `bundle:`.
138
+ /// browser, so it draws like `Image(_:)`). `bundle:` as for `Image(_:)`.
72
139
  public init(decorative name: String) {
73
140
  source = .named(name)
74
141
  isResizable = false
@@ -79,6 +146,14 @@ public struct Image: Equatable, Sendable {
79
146
  self.isResizable = isResizable
80
147
  }
81
148
 
149
+ /// An image at a URL the host has already loaded (`AsyncImage` asks it
150
+ /// to, and learns the pixel size); `scale` turns pixels into points.
151
+ public init(_url url: String, pixelWidth: Double, pixelHeight: Double, scale: Double) {
152
+ let factor = scale > 0 ? scale : 1
153
+ source = .url(url, width: pixelWidth / factor, height: pixelHeight / factor)
154
+ isResizable = false
155
+ }
156
+
82
157
  /// The SF Symbol name, for labels that render the icon as a glyph (tab
83
158
  /// items, menu pickers); nil for catalog images.
84
159
  var systemName: String? {
@@ -86,26 +161,64 @@ public struct Image: Equatable, Sendable {
86
161
  return nil
87
162
  }
88
163
 
89
- public func resizable() -> Image { Image(source: source, isResizable: true) }
164
+ public func resizable() -> Image {
165
+ var copy = Image(source: source, isResizable: true)
166
+ copy.interpolation = interpolation
167
+ return copy
168
+ }
90
169
 
91
- /// Accepted for source compatibility; the browser picks the interpolation.
170
+ /// `.none` draws without smoothing; the other levels are the browser's.
92
171
  public enum Interpolation: Hashable, Sendable {
93
172
  case none, low, medium, high
94
173
  }
95
174
 
96
- public func interpolation(_ interpolation: Interpolation) -> Image { self }
175
+ public func interpolation(_ interpolation: Interpolation) -> Image {
176
+ var copy = self
177
+ copy.interpolation = interpolation
178
+ return copy
179
+ }
97
180
  public func antialiased(_ isAntialiased: Bool) -> Image { self }
181
+
182
+ /// Whether an image draws its own colors or, as a template, the foreground
183
+ /// color through its shape. SF Symbols are templates already.
184
+ public enum TemplateRenderingMode: Hashable, Sendable {
185
+ case template, original
186
+ }
187
+
188
+ /// Approximation: a bitmap draws its own colors either way (tint one with
189
+ /// `UIImage.withTintColor(_:)`); symbols take the foreground color as before.
190
+ public func renderingMode(_ renderingMode: TemplateRenderingMode?) -> Image { self }
191
+
192
+ /// Symbols draw in one color here, whatever the mode (as the View modifier).
193
+ public func symbolRenderingMode(_ mode: SymbolRenderingMode?) -> Image { self }
194
+
195
+ /// The page draws images in the browser's range.
196
+ public func allowedDynamicRange(_ range: DynamicRange?) -> Image { self }
197
+
198
+ public struct DynamicRange: Hashable, Sendable {
199
+ let name: String
200
+ public static let standard = DynamicRange(name: "standard")
201
+ public static let constrainedHigh = DynamicRange(name: "constrainedHigh")
202
+ public static let high = DynamicRange(name: "high")
203
+ }
98
204
  }
99
205
  extension Image: _PrimitiveView {}
100
206
  extension Image: _HostView {
101
207
  var _kind: String { "image" }
102
208
  func _props(in environment: EnvironmentValues) -> _JSON {
209
+ var props: [String: _JSON]
103
210
  switch source {
104
211
  case .system(let name):
105
212
  return .object(["systemName": .string(name)])
106
213
  case .named(let name):
107
- return .object(["name": .string(name), "resizable": .bool(isResizable)])
214
+ props = ["name": .string(name), "resizable": .bool(isResizable)]
215
+ case .url(let url, let width, let height):
216
+ props = ["url": .string(url), "resizable": .bool(isResizable), "width": .number(width), "height": .number(height)]
217
+ case .bitmap(let recipe, let width, let height):
218
+ props = ["bitmap": recipe.json, "resizable": .bool(isResizable), "width": .number(width), "height": .number(height)]
108
219
  }
220
+ if interpolation == .none { props["interpolation"] = .string("none") }
221
+ return .object(props)
109
222
  }
110
223
  }
111
224
 
@@ -248,10 +361,19 @@ extension ScrollView: _HostView {
248
361
  var props: [String: _JSON] = ["axes": .string(axes._name)]
249
362
  _refresh(in: environment).addProps(to: &props)
250
363
  if let snap = environment._scrollTargetBehavior { props["snap"] = .string(snap) }
364
+ // `.scrollDismissesKeyboard` (ScrollModifiers.swift).
365
+ if environment._scrollDismissesKeyboard { props["dismissesKeyboard"] = .bool(true) }
251
366
  return .object(props)
252
367
  }
253
368
  var _content: [any View] { [content] }
254
369
  }
370
+ extension ScrollView: _EnvironmentContent {
371
+ /// `.contentMargins` above (ScrollModifiers.swift): padding inside the scroll view.
372
+ func _content(in environment: EnvironmentValues) -> [any View] {
373
+ guard let margins = environment._scrollContentMargins else { return [content] }
374
+ return [content.padding(margins)]
375
+ }
376
+ }
255
377
  extension ScrollView: _Refreshing {
256
378
  func _refresh(in environment: EnvironmentValues) -> _Refresh {
257
379
  _Refresh(action: environment._refreshAction, refreshing: $refreshing)
@@ -286,10 +408,12 @@ public struct Button<Label: View> {
286
408
  }
287
409
 
288
410
  extension Button where Label == Text {
411
+ @_disfavoredOverload
289
412
  public init<S: StringProtocol>(_ title: S, action: @escaping @MainActor () -> Void) {
290
413
  self.init(action: action) { Text(title) }
291
414
  }
292
415
 
416
+ @_disfavoredOverload
293
417
  public init<S: StringProtocol>(_ title: S, role: ButtonRole?, action: @escaping @MainActor () -> Void) {
294
418
  self.init(role: role, action: action) { Text(title) }
295
419
  }
@@ -304,11 +428,13 @@ extension Button where Label == Text {
304
428
  }
305
429
 
306
430
  extension Button where Label == SwiftUI.Label<Text, Image> {
431
+ @_disfavoredOverload
307
432
  public init<S: StringProtocol>(_ title: S, systemImage: String, action: @escaping @MainActor () -> Void) {
308
433
  let title = String(title)
309
434
  self.init(action: action) { SwiftUI.Label(title, systemImage: systemImage) }
310
435
  }
311
436
 
437
+ @_disfavoredOverload
312
438
  public init<S: StringProtocol>(_ title: S, systemImage: String, role: ButtonRole?,
313
439
  action: @escaping @MainActor () -> Void) {
314
440
  let title = String(title)
@@ -328,10 +454,13 @@ extension Button: _PrimitiveView {}
328
454
  extension Button: _HostView {
329
455
  var _kind: String { "button" }
330
456
  func _props(in environment: EnvironmentValues) -> _JSON {
331
- .object([
332
- "style": .string(environment._buttonStyle),
457
+ var props: [String: _JSON] = [
458
+ // A custom `ButtonStyle` draws its own look: `plain` (ButtonStyles.swift).
459
+ "style": .string(environment._buttonStyle == _CustomButtonStyle.marker ? "plain" : environment._buttonStyle),
333
460
  "role": role.map { .string($0.name) } ?? .null,
334
- ])
461
+ ]
462
+ if environment.controlSize != .regular { props["controlSize"] = .string(environment.controlSize._name) }
463
+ return .object(props)
335
464
  }
336
465
  var _content: [any View] { [label] }
337
466
  var _handler: ((_JSON) -> Void)? {
@@ -383,7 +512,7 @@ extension PrimitiveButtonStyle where Self == BorderedProminentButtonStyle {
383
512
  public static var borderedProminent: BorderedProminentButtonStyle { BorderedProminentButtonStyle() }
384
513
  }
385
514
 
386
- extension View {
515
+ nonisolated extension View {
387
516
  public func buttonStyle<S: PrimitiveButtonStyle>(_ style: S) -> some View {
388
517
  environment(\._buttonStyle, style._name)
389
518
  }
@@ -20,9 +20,8 @@ public struct _TaskCancellable: _Cancellable {
20
20
  }
21
21
 
22
22
  /// Emits `make()` every `interval` seconds, from the executor's clock (the same
23
- /// clock as `.task` sleeps, so headless runs stay deterministic). The shim
24
- /// cannot name `Date`, so `Timer.publish` in FoundationLite and FoundationBridge
25
- /// wraps this with `{ Date() }`.
23
+ /// clock as `.task` sleeps, so headless runs stay deterministic).
24
+ /// `Timer.publish` in FoundationBridge wraps this with `{ Date() }`.
26
25
  public struct _IntervalPublisher<Output: Sendable>: _Publisher, Sendable {
27
26
  public let interval: Double
28
27
  let make: @Sendable () -> Output
@@ -99,8 +98,9 @@ struct _OnReceiveView<Content: View, P: _Publisher>: View {
99
98
  }
100
99
  }
101
100
 
102
- extension View {
101
+ nonisolated extension View {
103
102
  /// Calls `action` with every value `publisher` emits while the view is shown.
103
+ @MainActor
104
104
  public func onReceive<P: _Publisher>(_ publisher: P, perform action: @escaping @MainActor (P.Output) -> Void) -> some View {
105
105
  _OnReceiveView(content: self, publisher: publisher, action: action)
106
106
  }
@@ -0,0 +1,75 @@
1
+ // Redaction (`.redacted(reason:)`, `@Environment(\.redactionReasons)`) and
2
+ // list separators' visibility. Redaction reasons pass down the environment,
3
+ // so views that check them (to show placeholder content) adapt; the page
4
+ // does not paint redacted text as grey boxes. The page draws a list's
5
+ // separators itself, so `.listRowSeparator` and `.listSectionSeparator`
6
+ // are accepted and leave the separators as they are.
7
+
8
+ public struct RedactionReasons: OptionSet, Hashable, Sendable {
9
+ public let rawValue: Int
10
+ public init(rawValue: Int) { self.rawValue = rawValue }
11
+ public static let placeholder = RedactionReasons(rawValue: 1 << 0)
12
+ public static let privacy = RedactionReasons(rawValue: 1 << 1)
13
+ public static let invalidated = RedactionReasons(rawValue: 1 << 2)
14
+ }
15
+
16
+ struct _RedactionReasonsKey: EnvironmentKey {
17
+ static var defaultValue: RedactionReasons { [] }
18
+ }
19
+
20
+ extension EnvironmentValues {
21
+ /// Why the content is redacted; empty unless an ancestor is `.redacted(reason:)`.
22
+ public var redactionReasons: RedactionReasons {
23
+ get { self[_RedactionReasonsKey.self] }
24
+ set { self[_RedactionReasonsKey.self] = newValue }
25
+ }
26
+ }
27
+
28
+ public enum VerticalEdge: Int8, CaseIterable, Hashable, Sendable {
29
+ case top, bottom
30
+
31
+ public struct Set: OptionSet, Hashable, Sendable {
32
+ public let rawValue: Int8
33
+ public init(rawValue: Int8) { self.rawValue = rawValue }
34
+ public init(_ edge: VerticalEdge) { rawValue = 1 << edge.rawValue }
35
+ public static let top = Set(.top)
36
+ public static let bottom = Set(.bottom)
37
+ public static let all: Set = [.top, .bottom]
38
+ }
39
+ }
40
+
41
+ nonisolated extension View {
42
+ /// Adds `reason` to the environment's `redactionReasons` for the views below.
43
+ public func redacted(reason: RedactionReasons) -> some View {
44
+ _EnvironmentView(content: self) { $0.redactionReasons.formUnion(reason) }
45
+ }
46
+
47
+ /// Clears `redactionReasons` for the views below.
48
+ public func unredacted() -> some View {
49
+ _EnvironmentView(content: self) { $0.redactionReasons = [] }
50
+ }
51
+
52
+ /// Changes an environment value for the views below.
53
+ public func transformEnvironment<V>(_ keyPath: WritableKeyPath<EnvironmentValues, V>,
54
+ transform: @escaping (inout V) -> Void) -> some View {
55
+ _EnvironmentView(content: self) { transform(&$0[keyPath: keyPath]) }
56
+ }
57
+
58
+ /// Hides the separators at the row's `edges` (the page draws list
59
+ /// separators; a row hiding its bottom one, or the next row hiding its
60
+ /// top one, leaves the line between them out). `.visible` and
61
+ /// `.automatic` leave them as they are.
62
+ public func listRowSeparator(_ visibility: Visibility, edges: VerticalEdge.Set = .all) -> some View {
63
+ _styled {
64
+ guard visibility == .hidden else { return }
65
+ $0.extras["listRowSeparator"] = .object([
66
+ "top": .bool(edges.contains(.top)),
67
+ "bottom": .bool(edges.contains(.bottom)),
68
+ ])
69
+ }
70
+ }
71
+ /// The view unchanged: separators take the system color.
72
+ public func listRowSeparatorTint(_ color: Color?, edges: VerticalEdge.Set = .all) -> some View { self }
73
+ public func listSectionSeparator(_ visibility: Visibility, edges: VerticalEdge.Set = .all) -> some View { self }
74
+ public func listSectionSeparatorTint(_ color: Color?, edges: VerticalEdge.Set = .all) -> some View { self }
75
+ }
@@ -44,9 +44,10 @@ extension _SwipeActionsView: _HostView {
44
44
  var _content: [any View] { [content] + trailing + leading }
45
45
  }
46
46
 
47
- extension View {
47
+ nonisolated extension View {
48
48
  /// Buttons revealed by swiping the row horizontally. The first declared
49
49
  /// action is nearest the content and is the one a full swipe performs.
50
+ @MainActor
50
51
  public func swipeActions<T: View>(edge: HorizontalEdge = .trailing, allowsFullSwipe: Bool = true,
51
52
  @ViewBuilder content: () -> T) -> _SwipeActionsView {
52
53
  var view = (self as? _SwipeActionsView) ?? _SwipeActionsView(content: self)
@@ -69,7 +70,7 @@ extension _ContextMenuView: _HostView {
69
70
  var _content: [any View] { [content, items] }
70
71
  }
71
72
 
72
- extension View {
73
+ nonisolated extension View {
73
74
  /// Items shown in a popover on a long press or right click.
74
75
  public func contextMenu<M: View>(@ViewBuilder menuItems: () -> M) -> some View {
75
76
  _ContextMenuView(content: self, items: menuItems())
@@ -0,0 +1,131 @@
1
+ /// More of an app's scenes: several scenes in one `body`, window groups
2
+ /// with an identifier or for a presented value, and the scene modifiers.
3
+ ///
4
+ /// The page is the app's one window. An app whose `body` lists several
5
+ /// scenes shows the first window group that is not for a value (a value's
6
+ /// window opens only through `openWindow`, which does nothing, Windows.swift).
7
+ /// `.onChange(of:)` on a scene watches the value from the window's root view.
8
+ /// Window sizes, resizability, styles and the menu bar's `.commands` are
9
+ /// accepted and do nothing: there is no window to size and no menu bar.
10
+
11
+ /// The scenes of a `body` that lists several.
12
+ public struct _TupleScene: Scene {
13
+ let parts: [any Scene]
14
+ public typealias Body = Never
15
+ public var body: Never { fatalError("_TupleScene is a primitive scene") }
16
+ }
17
+
18
+ extension _TupleScene: _RootScene {
19
+ var _rootView: any View {
20
+ let roots = parts.compactMap { $0 as? any _RootScene }
21
+ guard let root = roots.first(where: { !($0 is any _ValueWindowScene) }) ?? roots.first else {
22
+ fatalError("No scene the runtime can present. Use WindowGroup.")
23
+ }
24
+ return root._rootView
25
+ }
26
+ }
27
+
28
+ @MainActor
29
+ extension SceneBuilder {
30
+ public static func buildBlock<each Content: Scene>(_ content: repeat each Content) -> _TupleScene {
31
+ var parts: [any Scene] = []
32
+ for part in repeat each content { parts.append(part) }
33
+ return _TupleScene(parts: parts)
34
+ }
35
+
36
+ public static func buildOptional<Content: Scene>(_ content: Content?) -> _TupleScene {
37
+ _TupleScene(parts: content.map { [$0] } ?? [])
38
+ }
39
+
40
+ public static func buildEither<Content: Scene>(first content: Content) -> _TupleScene {
41
+ _TupleScene(parts: [content])
42
+ }
43
+
44
+ public static func buildEither<Content: Scene>(second content: Content) -> _TupleScene {
45
+ _TupleScene(parts: [content])
46
+ }
47
+
48
+ public static func buildLimitedAvailability<Content: Scene>(_ content: Content) -> _TupleScene {
49
+ _TupleScene(parts: [content])
50
+ }
51
+ }
52
+
53
+ extension WindowGroup {
54
+ /// A window group with an identifier (`openWindow(id:)` names it).
55
+ public init(id: String, @ViewBuilder content: () -> Content) {
56
+ self.init(content: content)
57
+ }
58
+
59
+ public init(_ title: String, id: String, @ViewBuilder content: () -> Content) {
60
+ self.init(content: content)
61
+ }
62
+
63
+ public init(_ titleKey: LocalizedStringKey, id: String, @ViewBuilder content: () -> Content) {
64
+ self.init(content: content)
65
+ }
66
+ }
67
+
68
+ /// The content of a `WindowGroup(for:)`: made with no value.
69
+ public struct _ValueWindowContent<Value: Codable & Hashable, Content: View>: View {
70
+ let make: (Binding<Value?>) -> Content
71
+ public var body: Content { make(.constant(nil)) }
72
+ }
73
+
74
+ /// A window group for presented values: never opened in the browser.
75
+ protocol _ValueWindowScene {}
76
+ extension WindowGroup: _ValueWindowScene where Content: _ValueWindowContentMarker {}
77
+ protocol _ValueWindowContentMarker {}
78
+ extension _ValueWindowContent: _ValueWindowContentMarker {}
79
+
80
+ @MainActor
81
+ extension WindowGroup {
82
+ /// A window per presented value (`openWindow(value:)`). The page opens no
83
+ /// other window, so the group is declared and never shown.
84
+ public init<D: Codable & Hashable, C: View>(for type: D.Type, @ViewBuilder content: @escaping (Binding<D?>) -> C)
85
+ where Content == _ValueWindowContent<D, C> {
86
+ self.init { _ValueWindowContent(make: content) }
87
+ }
88
+
89
+ public init<D: Codable & Hashable, C: View>(_ title: String, for type: D.Type,
90
+ @ViewBuilder content: @escaping (Binding<D?>) -> C)
91
+ where Content == _ValueWindowContent<D, C> {
92
+ self.init { _ValueWindowContent(make: content) }
93
+ }
94
+ }
95
+
96
+ /// How a window may be resized; accepted.
97
+ public struct WindowResizability: Hashable, Sendable {
98
+ let name: String
99
+ public static let automatic = WindowResizability(name: "automatic")
100
+ public static let contentSize = WindowResizability(name: "contentSize")
101
+ public static let contentMinSize = WindowResizability(name: "contentMinSize")
102
+ }
103
+
104
+ /// `.onChange(of:)` on a scene: the root view watches the value.
105
+ struct _SceneOnChange<Value: Equatable>: ViewModifier {
106
+ let value: Value
107
+ let initial: Bool
108
+ let action: (Value, Value) -> Void
109
+
110
+ func body(content: Content) -> some View {
111
+ content.onChange(of: value, initial: initial, action)
112
+ }
113
+ }
114
+
115
+ extension Scene {
116
+ /// Accepted: the page is not a resizable window.
117
+ public func defaultSize(width: CGFloat, height: CGFloat) -> some Scene { self }
118
+ public func defaultSize(_ size: CGSize) -> some Scene { self }
119
+ public func windowResizability(_ resizability: WindowResizability) -> some Scene { self }
120
+ public func handlesExternalEvents(matching conditions: Set<String>) -> some Scene { self }
121
+
122
+ /// Runs `action` when `value` changes, from the window's root view.
123
+ public func onChange<V: Equatable>(of value: V, initial: Bool = false,
124
+ _ action: @escaping (_ oldValue: V, _ newValue: V) -> Void) -> some Scene {
125
+ _modifyingRootView(_SceneOnChange(value: value, initial: initial, action: action))
126
+ }
127
+
128
+ public func onChange<V: Equatable>(of value: V, initial: Bool = false, _ action: @escaping () -> Void) -> some Scene {
129
+ _modifyingRootView(_SceneOnChange(value: value, initial: initial) { _, _ in action() })
130
+ }
131
+ }