@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
@@ -0,0 +1,130 @@
1
+ /// `GroupBox`, `ControlGroup` and `ImageRenderer`.
2
+ ///
3
+ /// - `GroupBox` is drawn as iOS draws its default style: the label in the
4
+ /// headline font above the content, 8 points apart, inside 16 points of
5
+ /// padding on a secondary-system-background rounded rectangle (radius 8).
6
+ /// `.groupBoxStyle` is accepted; every box uses that look.
7
+ /// - `ControlGroup` groups related controls. On iOS a menu shows them as a
8
+ /// row of compact buttons; here its content is a group: in a menu or a
9
+ /// context menu each control is an item of its own, elsewhere they flow in
10
+ /// the enclosing stack. Its label is not drawn.
11
+ /// - `ImageRenderer` would rasterize a view. Only the page draws views, so
12
+ /// `cgImage` and `uiImage` are nil (a share-as-image feature has nothing
13
+ /// to share); its settings are kept.
14
+
15
+ // MARK: - GroupBox
16
+
17
+ public struct GroupBox<Label: View, Content: View>: View {
18
+ let label: Label
19
+ let content: Content
20
+
21
+ public init(@ViewBuilder content: () -> Content, @ViewBuilder label: () -> Label) {
22
+ self.content = content()
23
+ self.label = label()
24
+ }
25
+
26
+ public init(label: Label, @ViewBuilder content: () -> Content) {
27
+ self.label = label
28
+ self.content = content()
29
+ }
30
+
31
+ public var body: some View {
32
+ VStack(alignment: .leading, spacing: 8) {
33
+ label.font(.headline)
34
+ content
35
+ }
36
+ .padding(16)
37
+ .background(Color(semantic: "secondarySystemBackground"), in: RoundedRectangle(cornerRadius: 8))
38
+ }
39
+ }
40
+
41
+ extension GroupBox where Label == EmptyView {
42
+ public init(@ViewBuilder content: () -> Content) {
43
+ self.init(label: EmptyView(), content: content)
44
+ }
45
+ }
46
+
47
+ extension GroupBox where Label == Text {
48
+ public init(_ titleKey: LocalizedStringKey, @ViewBuilder content: () -> Content) {
49
+ self.init(label: Text(titleKey), content: content)
50
+ }
51
+
52
+ @_disfavoredOverload
53
+ public init<S: StringProtocol>(_ title: S, @ViewBuilder content: () -> Content) {
54
+ self.init(label: Text(title), content: content)
55
+ }
56
+ }
57
+
58
+ /// A group box's look; accepted (see the file comment).
59
+ public protocol GroupBoxStyle {}
60
+ public struct DefaultGroupBoxStyle: GroupBoxStyle { public init() {} }
61
+ extension GroupBoxStyle where Self == DefaultGroupBoxStyle {
62
+ public static var automatic: DefaultGroupBoxStyle { DefaultGroupBoxStyle() }
63
+ }
64
+
65
+ nonisolated extension View {
66
+ public func groupBoxStyle<S: GroupBoxStyle>(_ style: S) -> some View { self }
67
+ }
68
+
69
+ // MARK: - ControlGroup
70
+
71
+ public struct ControlGroup<Content: View> {
72
+ let content: Content
73
+
74
+ public init(@ViewBuilder content: () -> Content) {
75
+ self.content = content()
76
+ }
77
+
78
+ /// The label (shown by a collapsed group on iOS) is not drawn.
79
+ public init<L: View>(@ViewBuilder content: () -> Content, @ViewBuilder label: () -> L) {
80
+ self.content = content()
81
+ }
82
+
83
+ public init(_ titleKey: LocalizedStringKey, @ViewBuilder content: () -> Content) {
84
+ self.content = content()
85
+ }
86
+
87
+ @_disfavoredOverload
88
+ public init<S: StringProtocol>(_ title: S, @ViewBuilder content: () -> Content) {
89
+ self.content = content()
90
+ }
91
+
92
+ public init(_ titleKey: LocalizedStringKey, systemImage: String, @ViewBuilder content: () -> Content) {
93
+ self.content = content()
94
+ }
95
+
96
+ @_disfavoredOverload
97
+ public init<S: StringProtocol>(_ title: S, systemImage: String, @ViewBuilder content: () -> Content) {
98
+ self.content = content()
99
+ }
100
+ }
101
+
102
+ extension ControlGroup: View {
103
+ public typealias Body = Never
104
+ public var body: Never { fatalError("ControlGroup is a primitive view") }
105
+ }
106
+ extension ControlGroup: _PrimitiveView {}
107
+ extension ControlGroup: _GroupView {
108
+ var _children: [any View] { [content] }
109
+ }
110
+
111
+ // MARK: - ImageRenderer
112
+
113
+ /// Renders a view to an image: never, in the browser (see the file comment).
114
+ @MainActor
115
+ public final class ImageRenderer<Content: View>: ObservableObject {
116
+ public var content: Content
117
+ public var label: String?
118
+ public var proposedSize = ProposedViewSize.unspecified
119
+ public var scale: CGFloat = 1
120
+ public var isOpaque = false
121
+
122
+ public init(content: Content) {
123
+ self.content = content
124
+ }
125
+
126
+ /// Nil: only the page draws views.
127
+ public var cgImage: CGImage? { nil }
128
+ /// Nil: only the page draws views.
129
+ public var uiImage: UIImage? { nil }
130
+ }
@@ -0,0 +1,54 @@
1
+ // Focus and key presses for views that are not text fields: `.focusable()`,
2
+ // `.focusEffectDisabled()` and `.onKeyPress`. They serve a hardware
3
+ // keyboard on an iPad or a Mac. The page shows an iPhone and sends the app
4
+ // no key events outside text inputs, so, like the pointer modifiers
5
+ // (PointerAndKeyboard.swift), these are accepted and do nothing: a key-press
6
+ // action is never called (Ice Cubes' media viewer pages with its swipes
7
+ // instead of the arrow keys).
8
+
9
+ /// A key press a view handles.
10
+ public struct KeyPress: Sendable {
11
+ /// Whether the press was dealt with; an ignored one goes to the parent.
12
+ public enum Result: Sendable, Hashable { case handled, ignored }
13
+
14
+ /// The phases of a press an action hears.
15
+ public struct Phases: OptionSet, Hashable, Sendable {
16
+ public let rawValue: Int
17
+ public init(rawValue: Int) { self.rawValue = rawValue }
18
+ public static let down = Phases(rawValue: 1 << 0)
19
+ public static let `repeat` = Phases(rawValue: 1 << 1)
20
+ public static let up = Phases(rawValue: 1 << 2)
21
+ public static let all: Phases = [.down, .repeat, .up]
22
+ }
23
+
24
+ public let phase: Phases
25
+ public let key: KeyEquivalent
26
+ public let characters: String
27
+ public let modifiers: EventModifiers
28
+ }
29
+
30
+ /// How a focusable view is used.
31
+ public struct FocusInteractions: OptionSet, Hashable, Sendable {
32
+ public let rawValue: Int
33
+ public init(rawValue: Int) { self.rawValue = rawValue }
34
+ public static let activate = FocusInteractions(rawValue: 1 << 0)
35
+ public static let edit = FocusInteractions(rawValue: 1 << 1)
36
+ public static let automatic: FocusInteractions = [.activate, .edit]
37
+ }
38
+
39
+ nonisolated extension View {
40
+ /// Accepted: the view takes no keyboard focus on the page.
41
+ public func focusable(_ isFocusable: Bool = true) -> some View { self }
42
+ public func focusable(_ isFocusable: Bool = true, interactions: FocusInteractions) -> some View { self }
43
+ /// Accepted: the page draws no focus ring for such views.
44
+ public func focusEffectDisabled(_ disabled: Bool = true) -> some View { self }
45
+
46
+ /// Accepted; the action is never called (no key events reach the app).
47
+ public func onKeyPress(_ key: KeyEquivalent, action: @escaping () -> KeyPress.Result) -> some View { self }
48
+ public func onKeyPress(_ key: KeyEquivalent, phases: KeyPress.Phases,
49
+ action: @escaping (KeyPress) -> KeyPress.Result) -> some View { self }
50
+ public func onKeyPress(keys: Set<KeyEquivalent>, phases: KeyPress.Phases = [.down, .repeat],
51
+ action: @escaping (KeyPress) -> KeyPress.Result) -> some View { self }
52
+ public func onKeyPress(phases: KeyPress.Phases = [.down, .repeat],
53
+ action: @escaping (KeyPress) -> KeyPress.Result) -> some View { self }
54
+ }
@@ -94,7 +94,8 @@ extension EnvironmentValues {
94
94
  }
95
95
  }
96
96
 
97
- extension View {
97
+ nonisolated extension View {
98
+ @MainActor
98
99
  public func labelStyle<S: LabelStyle>(_ style: S) -> some View {
99
100
  environment(\._labelStyle, _AnyLabelStyle(style))
100
101
  }
@@ -108,10 +109,16 @@ struct _StyledLabel: View {
108
109
  @Environment(\._labelStyle) private var style
109
110
 
110
111
  var body: some View {
111
- let configuration = LabelStyleConfiguration(title: .init(view: title), icon: .init(view: icon))
112
- if let style {
113
- return AnyView(style.make(configuration))
114
- }
115
- return AnyView(DefaultLabelStyle().makeBody(configuration: configuration))
112
+ // The icon is marked so a list row can tint it (the title keeps the
113
+ // row's primary color), as iOS does for labels in lists.
114
+ let markedIcon = AnyView(icon)._styled { $0.extras["labelIcon"] = .bool(true) }
115
+ let configuration = LabelStyleConfiguration(title: .init(view: title), icon: .init(view: markedIcon))
116
+ let styled = style?.make(configuration) ?? DefaultLabelStyle().makeBody(configuration: configuration)
117
+ // As on iOS, the title stays the label's accessibility label when the
118
+ // style shows only the icon (a toolbar button), so an event script
119
+ // can name the button by it.
120
+ let titleText = _textContent(of: title)
121
+ if titleText.isEmpty { return AnyView(styled) }
122
+ return AnyView(AnyView(styled).accessibilityLabel(titleText))
116
123
  }
117
124
  }
@@ -10,7 +10,7 @@ public enum TextAlignment: Hashable, Sendable {
10
10
  }
11
11
  }
12
12
 
13
- extension View {
13
+ nonisolated extension View {
14
14
  /// Sets the priority by which a parent stack hands out space.
15
15
  public func layoutPriority(_ value: Double) -> some View {
16
16
  _styled { $0.layoutPriority = value }
@@ -49,32 +49,66 @@ extension Color: _HostView {
49
49
  }
50
50
 
51
51
  /// A shape drawn as a view, optionally filled or stroked. `inset` strokes
52
- /// (`strokeBorder`) lie inside the shape's bounds.
52
+ /// (`strokeBorder`) lie inside the shape's bounds. A custom shape (`"path"`)
53
+ /// is drawn from its path (Shape.swift), with the fill rule and the whole
54
+ /// stroke style; a built-in shape is drawn by name.
53
55
  public struct _ShapeView<S: Shape> {
54
56
  let shape: S
55
57
  let fill: (any ShapeStyle)?
56
58
  let stroke: (style: any ShapeStyle, lineWidth: CGFloat, inset: Bool)?
59
+ var eoFill = false
60
+ var strokeStyle: StrokeStyle? = nil
57
61
  }
58
62
  extension _ShapeView: _PrimitiveView {}
59
63
  extension _ShapeView: _HostView {
60
64
  var _kind: String { "shape" }
61
65
  func _props(in environment: EnvironmentValues) -> _JSON {
66
+ // A stroked shape filled with a style is its outline in that style.
67
+ if stroke == nil, let stroked = shape as? any _Stroked {
68
+ return stroked._outlineProps(style: fill ?? ForegroundStyle(), in: environment)
69
+ }
70
+ let drawsPath = shape._name == "path"
62
71
  var stroke: _JSON = .null
63
72
  if let s = self.stroke {
64
73
  var object: [String: _JSON] = ["color": s.style._json, "lineWidth": .number(s.lineWidth)]
65
- if s.inset { object["inset"] = .bool(true) }
74
+ // A path is inset by the Swift side (Shape.swift); the page strokes it as is.
75
+ if s.inset && !drawsPath { object["inset"] = .bool(true) }
76
+ if drawsPath, let style = strokeStyle {
77
+ object["lineCap"] = .string(["butt", "round", "square"][Int(style.lineCap.rawValue)])
78
+ object["lineJoin"] = .string(["miter", "round", "bevel"][Int(style.lineJoin.rawValue)])
79
+ object["miterLimit"] = .number(style.miterLimit)
80
+ if !style.dash.isEmpty {
81
+ object["dash"] = .array(style.dash.map(_JSON.number))
82
+ object["dashPhase"] = .number(style.dashPhase)
83
+ }
84
+ } else if let style = strokeStyle, !style.dash.isEmpty {
85
+ // A built-in shape's border can only be dashed or not: the page
86
+ // draws CSS dashes for any pattern.
87
+ object["dash"] = .array(style.dash.map(_JSON.number))
88
+ }
66
89
  stroke = .object(object)
67
90
  }
68
- return .object([
91
+ var props: [String: _JSON] = [
69
92
  "shape": .string(shape._name),
70
- "cornerRadius": .number(shape._cornerRadius),
93
+ "cornerRadius": .number(_resolvedCornerRadius(shape, in: environment)),
71
94
  "fill": fill?._json ?? .null,
72
95
  "stroke": stroke,
73
- ])
96
+ ]
97
+ if drawsPath {
98
+ // The page reports the size the path is drawn for; the runtime
99
+ // adds the path (`_pathProps`).
100
+ props["reportsSize"] = .bool(true)
101
+ if eoFill { props["fillRule"] = .string("evenodd") }
102
+ } else if let trimmed = shape as? _TrimmedShape {
103
+ // `.trim(from:to:)` of a built-in shape (ShapeTrim.swift); a path is trimmed itself.
104
+ props["trim"] = trimmed._trimJSON
105
+ }
106
+ return .object(props)
74
107
  }
75
108
  }
76
109
 
77
- /// Options for `fill`; accepted for source compatibility.
110
+ /// How a shape is filled: `eoFill` uses the even-odd rule (a path's
111
+ /// overlapping parts cancel out) rather than the non-zero winding rule.
78
112
  public struct FillStyle: Equatable, Sendable {
79
113
  public var isEOFilled: Bool
80
114
  public var isAntialiased: Bool
@@ -85,22 +119,25 @@ public struct FillStyle: Equatable, Sendable {
85
119
  }
86
120
  }
87
121
 
88
- extension Shape {
122
+ nonisolated extension Shape {
89
123
  public func fill<S: ShapeStyle>(_ style: S, style fillStyle: FillStyle = FillStyle()) -> some View {
90
- _ShapeView(shape: self, fill: style, stroke: nil)
124
+ _ShapeView(shape: self, fill: style, stroke: nil, eoFill: fillStyle.isEOFilled)
91
125
  }
92
126
 
93
127
  /// Filled with the foreground style.
94
128
  public func fill(style: FillStyle = FillStyle()) -> some View {
95
- _ShapeView(shape: self, fill: ForegroundStyle(), stroke: nil)
129
+ _ShapeView(shape: self, fill: ForegroundStyle(), stroke: nil, eoFill: style.isEOFilled)
96
130
  }
97
131
 
98
132
  public func stroke<S: ShapeStyle>(_ style: S, lineWidth: CGFloat = 1) -> some View {
99
133
  _ShapeView(shape: self, fill: nil, stroke: (style, lineWidth, false))
100
134
  }
101
135
 
102
- public func stroke(lineWidth: CGFloat = 1) -> some View {
103
- _ShapeView(shape: self, fill: nil, stroke: (ForegroundStyle(), lineWidth, false))
136
+ /// The outline as a shape (iOS 17), so it can be filled or passed where a
137
+ /// shape goes (`.overlay(.bar, in: .capsule.stroke())`); as a view it is
138
+ /// the outline in the foreground style.
139
+ public func stroke(lineWidth: CGFloat = 1, antialiased: Bool = true) -> _StrokedShape<Self> {
140
+ _StrokedShape(base: self, lineWidth: lineWidth)
104
141
  }
105
142
 
106
143
  /// A stroke drawn inside the shape's bounds.
@@ -163,3 +200,25 @@ private func _shapeProps(_ shape: some Shape) -> _JSON {
163
200
  "stroke": .null,
164
201
  ])
165
202
  }
203
+
204
+ /// A shape's outline as a shape (`shape.stroke(lineWidth:)`, iOS 17): drawn,
205
+ /// or filled with a style, as the base shape stroked with that style.
206
+ nonisolated public struct _StrokedShape<Base: Shape>: Shape {
207
+ let base: Base
208
+ let lineWidth: CGFloat
209
+
210
+ public var _name: String { base._name }
211
+ public var _cornerRadius: CGFloat { base._cornerRadius }
212
+ /// The base's path: a custom shape's outline is drawn from it.
213
+ public func path(in rect: CGRect) -> Path { base.path(in: rect) }
214
+ }
215
+
216
+ protocol _Stroked {
217
+ func _outlineProps(style: any ShapeStyle, in environment: EnvironmentValues) -> _JSON
218
+ }
219
+
220
+ extension _StrokedShape: _Stroked {
221
+ func _outlineProps(style: any ShapeStyle, in environment: EnvironmentValues) -> _JSON {
222
+ _ShapeView(shape: base, fill: nil, stroke: (style, lineWidth, false))._props(in: environment)
223
+ }
224
+ }
@@ -0,0 +1,49 @@
1
+ // `LazyVStack` and `LazyHStack`: the same `vstack` / `hstack` elements as
2
+ // `VStack` and `HStack`, whose `ForEach` rows are built as they come near the
3
+ // visible area (Runtime/LazyRows.swift), as a `List`'s are.
4
+ // `pinnedViews` is accepted: section headers and footers scroll with their
5
+ // rows instead of sticking to the scroll view's edge.
6
+
7
+ public struct LazyVStack<Content: View> {
8
+ let alignment: HorizontalAlignment
9
+ let spacing: CGFloat?
10
+ let content: Content
11
+
12
+ public init(alignment: HorizontalAlignment = .center, spacing: CGFloat? = nil,
13
+ pinnedViews: PinnedScrollableViews = .init(), @ViewBuilder content: () -> Content) {
14
+ self.alignment = alignment
15
+ self.spacing = spacing
16
+ self.content = content()
17
+ }
18
+ }
19
+ extension LazyVStack: _PrimitiveView {}
20
+ extension LazyVStack: _HostView {
21
+ var _kind: String { "vstack" }
22
+ func _props(in environment: EnvironmentValues) -> _JSON {
23
+ .object(["spacing": spacing.map(_JSON.number) ?? .null, "alignment": .string(alignment.name)])
24
+ }
25
+ var _content: [any View] { [content] }
26
+ }
27
+ extension LazyVStack: _ScrollTargetContainer {}
28
+
29
+ public struct LazyHStack<Content: View> {
30
+ let alignment: VerticalAlignment
31
+ let spacing: CGFloat?
32
+ let content: Content
33
+
34
+ public init(alignment: VerticalAlignment = .center, spacing: CGFloat? = nil,
35
+ pinnedViews: PinnedScrollableViews = .init(), @ViewBuilder content: () -> Content) {
36
+ self.alignment = alignment
37
+ self.spacing = spacing
38
+ self.content = content()
39
+ }
40
+ }
41
+ extension LazyHStack: _PrimitiveView {}
42
+ extension LazyHStack: _HostView {
43
+ var _kind: String { "hstack" }
44
+ func _props(in environment: EnvironmentValues) -> _JSON {
45
+ .object(["spacing": spacing.map(_JSON.number) ?? .null, "alignment": .string(alignment.name)])
46
+ }
47
+ var _content: [any View] { [content] }
48
+ }
49
+ extension LazyHStack: _ScrollTargetContainer {}
@@ -0,0 +1,97 @@
1
+ // SwiftUI's first alert API, still common in packages: `Alert` values with
2
+ // `Alert.Button`s, shown by `.alert(isPresented:content:)` or
3
+ // `.alert(item:content:)`, and `@Environment(\.presentationMode)`. An
4
+ // `Alert` becomes the same `alert` element as the newer `.alert(_:isPresented:
5
+ // actions:message:)` (Alert.swift): each button is a `Button` with its role.
6
+
7
+ /// An alert: a title, an optional message and up to two buttons.
8
+ public struct Alert {
9
+ let title: Text
10
+ let message: Text?
11
+ let buttons: [Button]
12
+
13
+ public init(title: Text, message: Text? = nil, dismissButton: Button? = nil) {
14
+ self.title = title
15
+ self.message = message
16
+ buttons = dismissButton.map { [$0] } ?? []
17
+ }
18
+
19
+ public init(title: Text, message: Text? = nil, primaryButton: Button, secondaryButton: Button) {
20
+ self.title = title
21
+ self.message = message
22
+ buttons = [primaryButton, secondaryButton]
23
+ }
24
+
25
+ /// An alert button: a label, a role and an action.
26
+ public struct Button {
27
+ let label: Text
28
+ let role: ButtonRole?
29
+ let action: (() -> Void)?
30
+
31
+ public static func `default`(_ label: Text, action: (() -> Void)? = {}) -> Button {
32
+ Button(label: label, role: nil, action: action)
33
+ }
34
+
35
+ public static func cancel(_ label: Text, action: (() -> Void)? = {}) -> Button {
36
+ Button(label: label, role: .cancel, action: action)
37
+ }
38
+
39
+ /// "Cancel".
40
+ public static func cancel(_ action: (() -> Void)? = {}) -> Button {
41
+ Button(label: Text("Cancel"), role: .cancel, action: action)
42
+ }
43
+
44
+ public static func destructive(_ label: Text, action: (() -> Void)? = {}) -> Button {
45
+ Button(label: label, role: .destructive, action: action)
46
+ }
47
+ }
48
+
49
+ /// The buttons as views; "OK" when the alert has none, as SwiftUI shows.
50
+ @MainActor var actions: [SwiftUI.Button<Text>] {
51
+ let buttons = self.buttons.isEmpty ? [Button.default(Text("OK"))] : self.buttons
52
+ return buttons.map { button in
53
+ let action = button.action
54
+ return SwiftUI.Button(role: button.role, action: { action?() }) { button.label }
55
+ }
56
+ }
57
+ }
58
+
59
+ extension View {
60
+ /// Shows the alert `content` makes while `isPresented` is true.
61
+ public func alert(isPresented: Binding<Bool>, content: () -> Alert) -> some View {
62
+ let alert = content()
63
+ return _AlertView(base: self, isPresented: isPresented, title: alert.title.content,
64
+ message: alert.message?.content, style: "alert",
65
+ actions: ForEach(Array(alert.actions.enumerated()), id: \.offset) { $0.element })
66
+ }
67
+
68
+ /// Shows the alert `content` makes from `item` while it is non-nil;
69
+ /// dismissing sets it back to nil.
70
+ public func alert<Item: Identifiable>(item: Binding<Item?>, content: (Item) -> Alert) -> some View {
71
+ let presented = Binding(get: { item.wrappedValue != nil }, set: { if !$0 { item.wrappedValue = nil } })
72
+ let alert = item.wrappedValue.map(content) ?? Alert(title: Text(""))
73
+ return _AlertView(base: self, isPresented: presented, title: alert.title.content,
74
+ message: alert.message?.content, style: "alert",
75
+ actions: ForEach(Array(alert.actions.enumerated()), id: \.offset) { $0.element })
76
+ }
77
+ }
78
+
79
+ // MARK: - Presentation mode
80
+
81
+ /// Whether the view is presented, and how to dismiss it: `dismiss()` is the
82
+ /// environment's `dismiss` action.
83
+ public struct PresentationMode {
84
+ let dismissAction: DismissAction
85
+
86
+ /// True: the shim does not track this for the view.
87
+ public var isPresented: Bool { true }
88
+
89
+ @MainActor public mutating func dismiss() { dismissAction() }
90
+ }
91
+
92
+ extension EnvironmentValues {
93
+ public var presentationMode: Binding<PresentationMode> {
94
+ let mode = PresentationMode(dismissAction: dismiss)
95
+ return Binding(get: { mode }, set: { _ in })
96
+ }
97
+ }
@@ -32,7 +32,7 @@ extension ListStyle where Self == GroupedListStyle {
32
32
  public static var grouped: GroupedListStyle { GroupedListStyle() }
33
33
  }
34
34
 
35
- extension View {
35
+ nonisolated extension View {
36
36
  public func listStyle<S: ListStyle>(_ style: S) -> some View {
37
37
  environment(\._listStyle, style._name)
38
38
  }
@@ -53,6 +53,12 @@ struct _ListSelection {
53
53
  let accepts: (AnyHashable) -> Bool
54
54
  /// `Set<Value>` selections toggle on tap; `Value?` selections set.
55
55
  let isMultiple: Bool
56
+ /// The whole current selection, for the identity below.
57
+ let snapshot: () -> AnyHashable
58
+ /// Set by the runtime: the list and the selection the pass carried, so the
59
+ /// environments of two passes compare equal while the selection is unchanged
60
+ /// (the binding is re-created by every pass; see `_Sameness`).
61
+ var identity: _RuntimeKey?
56
62
 
57
63
  init<Value: Hashable>(_ binding: Binding<Value?>) {
58
64
  get = { binding.wrappedValue.map { AnyHashable($0) } }
@@ -67,6 +73,7 @@ struct _ListSelection {
67
73
  }
68
74
  accepts = { $0.base is Value }
69
75
  isMultiple = false
76
+ snapshot = { AnyHashable(binding.wrappedValue) }
70
77
  }
71
78
 
72
79
  /// `get` / `set` reduce a multiple selection to one value: the first of the set.
@@ -93,11 +100,12 @@ struct _ListSelection {
93
100
  }
94
101
  accepts = { $0.base is Value }
95
102
  isMultiple = true
103
+ snapshot = { AnyHashable(binding.wrappedValue) }
96
104
  }
97
105
  }
98
106
 
99
107
  /// Lists that carry a selection binding; the runtime puts it in the rows' environment.
100
- protocol _ListSelectionProviding {
108
+ protocol _ListSelectionProviding: _TraitBearing {
101
109
  var _selection: _ListSelection? { get }
102
110
  }
103
111
 
@@ -198,6 +206,12 @@ extension List: _HostView {
198
206
  var props: [String: _JSON] = ["style": .string(environment._listStyle)]
199
207
  if environment.editMode?.wrappedValue.isEditing == true { props["editing"] = .bool(true) }
200
208
  _refresh(in: environment).addProps(to: &props)
209
+ // `.scrollDismissesKeyboard` (ScrollModifiers.swift).
210
+ if environment._scrollDismissesKeyboard { props["dismissesKeyboard"] = .bool(true) }
211
+ // `.scrollContentBackground(.hidden)` (ScrollViewReader.swift).
212
+ if environment._scrollContentBackground == .hidden { props["background"] = .string("hidden") }
213
+ // `.environment(\.defaultMinListRowHeight, 1)`: rows as short as their content.
214
+ if environment.defaultMinListRowHeight != 44 { props["minRowHeight"] = .number(Double(max(0, environment.defaultMinListRowHeight))) }
201
215
  return .object(props)
202
216
  }
203
217
  var _content: [any View] { [content] }
@@ -211,7 +225,7 @@ extension List: _Refreshing {}
211
225
 
212
226
  /// `List` and `ScrollView`: hosts whose `refresh` handler the runtime takes
213
227
  /// from `_refresh(in:)` (the handler depends on the environment).
214
- protocol _Refreshing {
228
+ protocol _Refreshing: _TraitBearing {
215
229
  func _refresh(in environment: EnvironmentValues) -> _Refresh
216
230
  }
217
231
  extension List: _ListSelectionProviding {
@@ -224,6 +238,10 @@ public struct Section<Content: View> {
224
238
  let header: String?
225
239
  let footer: String?
226
240
  let content: Content
241
+ /// Modifiers applied to the section itself (`Section { … }.disabled(x)`)
242
+ /// style each of its rows, as in SwiftUI, instead of boxing the section
243
+ /// (a `styled` around a `section` is not a section to the list layout).
244
+ var rowStyles: [_Style] = []
227
245
 
228
246
  public init(@ViewBuilder content: () -> Content) {
229
247
  self.header = nil
@@ -231,6 +249,14 @@ public struct Section<Content: View> {
231
249
  self.content = content()
232
250
  }
233
251
 
252
+ /// A header from a localized key.
253
+ public init(_ titleKey: LocalizedStringKey, @ViewBuilder content: () -> Content) {
254
+ self.header = titleKey.key
255
+ self.footer = nil
256
+ self.content = content()
257
+ }
258
+
259
+ @_disfavoredOverload
234
260
  public init<S: StringProtocol>(_ title: S, @ViewBuilder content: () -> Content) {
235
261
  self.header = String(title)
236
262
  self.footer = nil
@@ -256,14 +282,27 @@ public struct Section<Content: View> {
256
282
  self.footer = footer().content
257
283
  self.content = content()
258
284
  }
285
+
286
+ /// A header or footer that is a `Text` (or an optional one) is a string
287
+ /// prop, as above; any other view is a `sectionheader` / `sectionfooter`
288
+ /// child (SectionSupplements.swift).
289
+ var headerView: (any View)?
290
+ var footerView: (any View)?
259
291
  }
260
- /// Lets pickers look through sections for their options.
261
- protocol _SectionView {
292
+ /// Lets pickers look through sections for their options, and modifiers
293
+ /// style a section's rows.
294
+ protocol _SectionView: _TraitBearing {
262
295
  var _sectionContent: any View { get }
296
+ func _stylingRows(_ style: _Style) -> any View
263
297
  }
264
298
 
265
299
  extension Section: _SectionView {
266
300
  var _sectionContent: any View { content }
301
+ func _stylingRows(_ style: _Style) -> any View {
302
+ var copy = self
303
+ copy.rowStyles.append(style)
304
+ return copy
305
+ }
267
306
  }
268
307
 
269
308
  extension Section: _PrimitiveView {}
@@ -272,5 +311,21 @@ extension Section: _HostView {
272
311
  func _props(in environment: EnvironmentValues) -> _JSON {
273
312
  .object(["header": header.map(_JSON.string) ?? .null, "footer": footer.map(_JSON.string) ?? .null])
274
313
  }
275
- var _content: [any View] { [content] }
314
+ var _content: [any View] {
315
+ // Each style distributes over the rows (`_StyledGroup`); a second one
316
+ // wraps the already styled rows again.
317
+ var view: any View = content
318
+ for style in rowStyles { view = _styledGroup(view, style) }
319
+ // View headers and footers come first and last, outside the row styles.
320
+ var children: [any View] = [view]
321
+ if let headerView { children.insert(_SectionSupplement(kind: "sectionheader", content: headerView), at: 0) }
322
+ if let footerView { children.append(_SectionSupplement(kind: "sectionfooter", content: footerView)) }
323
+ return children
324
+ }
325
+ }
326
+
327
+ /// `_StyledGroup(content: view, style: style)` for an existential view.
328
+ func _styledGroup(_ view: any View, _ style: _Style) -> any View {
329
+ func open<V: View>(_ content: V) -> any View { _StyledGroup(content: content, style: style) }
330
+ return open(view)
276
331
  }