@swiftbrowser/swift 0.1.0 → 0.2.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 +65 -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 +105 -7
  257. package/Sources/SwiftUI/API/Entry.swift +8 -0
  258. package/Sources/SwiftUI/API/Environment.swift +93 -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 +3 -2
  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 +67 -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 +80 -10
  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 +11 -2
  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 +164 -37
  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 +96 -0
  300. package/Sources/SwiftUI/API/Shape.swift +214 -0
  301. package/Sources/SwiftUI/API/ShapeStyle.swift +105 -7
  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 +10 -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 +498 -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 +39 -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,28 @@
1
+ // `.containerBackground(for:)` (iOS 17): a background for the container a
2
+ // view is placed in (a navigation stack, a widget, StoreKit's subscription
3
+ // store). The browser draws it behind the view itself, which is where it
4
+ // shows for a view that fills its container.
5
+
6
+ /// Where a container background goes. Frameworks add their own placements
7
+ /// (StoreKit's `.subscriptionStore`) through `init(_name:)`.
8
+ public struct ContainerBackgroundPlacement: Hashable, Sendable {
9
+ public let _name: String
10
+ public init(_name: String) { self._name = _name }
11
+
12
+ public static let navigation = ContainerBackgroundPlacement(_name: "navigation")
13
+ public static let navigationSplitView = ContainerBackgroundPlacement(_name: "navigationSplitView")
14
+ public static let tabView = ContainerBackgroundPlacement(_name: "tabView")
15
+ public static let widget = ContainerBackgroundPlacement(_name: "widget")
16
+ }
17
+
18
+ extension View {
19
+ /// Draws `content` behind the view.
20
+ public func containerBackground<V: View>(for container: ContainerBackgroundPlacement, alignment: Alignment = .center, @ViewBuilder content: () -> V) -> some View {
21
+ background(alignment: alignment, content: content)
22
+ }
23
+
24
+ /// Fills the area behind the view with `style`.
25
+ public func containerBackground<S: ShapeStyle>(_ style: S, for container: ContainerBackgroundPlacement) -> some View {
26
+ background(style)
27
+ }
28
+ }
@@ -0,0 +1,33 @@
1
+ // `.contentShape(_:)`: on iOS it makes the whole shape hit-testable (a tap
2
+ // on the gap of an `HStack` with a `Spacer` reaches its gesture). On the page
3
+ // every element's hit area is already its whole box, so the modifier is
4
+ // accepted without adding to the tree; a non-rectangular shape (`Circle()`)
5
+ // still hits as its bounding box (an approximation).
6
+
7
+ public struct ContentShapeKinds: OptionSet, Hashable, Sendable {
8
+ public let rawValue: Int
9
+ public init(rawValue: Int) { self.rawValue = rawValue }
10
+ public static let interaction = ContentShapeKinds(rawValue: 1 << 0)
11
+ public static let dragPreview = ContentShapeKinds(rawValue: 1 << 1)
12
+ public static let contextMenuPreview = ContentShapeKinds(rawValue: 1 << 2)
13
+ public static let hoverEffect = ContentShapeKinds(rawValue: 1 << 3)
14
+ public static let focusEffect = ContentShapeKinds(rawValue: 1 << 4)
15
+ public static let accessibility = ContentShapeKinds(rawValue: 1 << 5)
16
+ }
17
+
18
+ nonisolated extension View {
19
+ public func contentShape<S: Shape>(_ shape: S, eoFill: Bool = false) -> some View { self }
20
+
21
+ public func contentShape<S: Shape>(_ kind: ContentShapeKinds, _ shape: S, eoFill: Bool = false) -> some View { self }
22
+ }
23
+
24
+ nonisolated extension View {
25
+ /// The iOS 17 tap with its location: the point in the view's own
26
+ /// coordinates, which the page sends with the tap (a named or global
27
+ /// space gets the local point too). `count` is ignored as for
28
+ /// `onTapGesture(count:perform:)`.
29
+ public func onTapGesture(count: Int = 1, coordinateSpace: CoordinateSpace = .local,
30
+ perform action: @escaping @MainActor (CGPoint) -> Void) -> some View {
31
+ _TapGestureView(content: self, locatedAction: action)
32
+ }
33
+ }
@@ -0,0 +1,35 @@
1
+ // `ContentSizeCategory` and `EnvironmentValues.sizeCategory`: SwiftUI's
2
+ // Dynamic Type sizes before `DynamicTypeSize` (iOS 15), still read by UIKit
3
+ // code that scales its fonts (Ice Cubes' composer). The value is the
4
+ // environment's `dynamicTypeSize` under its old names.
5
+
6
+ /// A Dynamic Type size, by its pre-iOS 15 name.
7
+ public enum ContentSizeCategory: Hashable, CaseIterable, Sendable {
8
+ case extraSmall, small, medium, large, extraLarge, extraExtraLarge, extraExtraExtraLarge
9
+ case accessibilityMedium, accessibilityLarge, accessibilityExtraLarge
10
+ case accessibilityExtraExtraLarge, accessibilityExtraExtraExtraLarge
11
+
12
+ public var isAccessibilityCategory: Bool { DynamicTypeSize(self).isAccessibilitySize }
13
+ }
14
+
15
+ extension DynamicTypeSize {
16
+ /// The size a `ContentSizeCategory` names.
17
+ public init(_ category: ContentSizeCategory) {
18
+ self = DynamicTypeSize.allCases[ContentSizeCategory.allCases.firstIndex(of: category) ?? 3]
19
+ }
20
+ }
21
+
22
+ extension ContentSizeCategory {
23
+ /// The category of a `DynamicTypeSize`.
24
+ public init(_ size: DynamicTypeSize) {
25
+ self = ContentSizeCategory.allCases[size.rawValue]
26
+ }
27
+ }
28
+
29
+ extension EnvironmentValues {
30
+ /// `dynamicTypeSize` as a `ContentSizeCategory`.
31
+ public var sizeCategory: ContentSizeCategory {
32
+ get { ContentSizeCategory(dynamicTypeSize) }
33
+ set { dynamicTypeSize = DynamicTypeSize(newValue) }
34
+ }
35
+ }
@@ -0,0 +1,101 @@
1
+ // `ContentUnavailableView`: the centered icon, title, description and
2
+ // actions iOS shows for an empty or failed state, built from the shim's
3
+ // own views (a large secondary icon over a bold title, a secondary
4
+ // description, then the actions), filling the space it is given.
5
+
6
+ public struct ContentUnavailableView<Label: View, Description: View, Actions: View>: View {
7
+ let label: Label
8
+ let description: Description
9
+ let actions: Actions
10
+
11
+ public init(@ViewBuilder label: () -> Label,
12
+ @ViewBuilder description: () -> Description = { EmptyView() },
13
+ @ViewBuilder actions: () -> Actions = { EmptyView() }) {
14
+ self.label = label()
15
+ self.description = description()
16
+ self.actions = actions()
17
+ }
18
+
19
+ public var body: some View {
20
+ VStack(spacing: 16) {
21
+ VStack(spacing: 8) {
22
+ label.labelStyle(_ContentUnavailableLabelStyle())
23
+ description
24
+ .font(.callout)
25
+ .foregroundStyle(.secondary)
26
+ .multilineTextAlignment(.center)
27
+ }
28
+ actions
29
+ }
30
+ .padding(.horizontal, 32)
31
+ .frame(maxWidth: .infinity, maxHeight: .infinity)
32
+ }
33
+ }
34
+
35
+ extension ContentUnavailableView where Label == SwiftUI.Label<Text, Image>, Description == Text?, Actions == EmptyView {
36
+ public init(_ titleKey: LocalizedStringKey, systemImage name: String, description: Text? = nil) {
37
+ self.init(label: { SwiftUI.Label(titleKey, systemImage: name) }, description: { description })
38
+ }
39
+
40
+ public init(_ titleKey: LocalizedStringKey, image name: String, description: Text? = nil) {
41
+ self.init(label: { SwiftUI.Label(Text(titleKey).content, image: name) }, description: { description })
42
+ }
43
+
44
+ @_disfavoredOverload
45
+ public init<S: StringProtocol>(_ title: S, systemImage name: String, description: Text? = nil) {
46
+ self.init(label: { SwiftUI.Label(title, systemImage: name) }, description: { description })
47
+ }
48
+
49
+ @_disfavoredOverload
50
+ public init<S: StringProtocol>(_ title: S, image name: String, description: Text? = nil) {
51
+ self.init(label: { SwiftUI.Label(title, image: name) }, description: { description })
52
+ }
53
+ }
54
+
55
+ /// The content of `ContentUnavailableView.search`.
56
+ public enum SearchUnavailableContent {
57
+ public struct Label: View {
58
+ let text: String?
59
+ public var body: some View {
60
+ SwiftUI.Label(text.map { "No Results for \u{201C}\($0)\u{201D}" } ?? "No Results", systemImage: "magnifyingglass")
61
+ }
62
+ }
63
+
64
+ public struct Description: View {
65
+ public var body: some View { Text("Check the spelling or try a new search.") }
66
+ }
67
+
68
+ public struct Actions: View {
69
+ public var body: some View { EmptyView() }
70
+ }
71
+ }
72
+
73
+ extension ContentUnavailableView where Label == SearchUnavailableContent.Label,
74
+ Description == SearchUnavailableContent.Description,
75
+ Actions == SearchUnavailableContent.Actions {
76
+ /// "No Results" for a search.
77
+ public static var search: ContentUnavailableView { search(nil) }
78
+
79
+ /// "No Results for “text”" for a search.
80
+ public static func search(text: String) -> ContentUnavailableView { search(text) }
81
+
82
+ private static func search(_ text: String?) -> ContentUnavailableView {
83
+ ContentUnavailableView(label: { SearchUnavailableContent.Label(text: text) },
84
+ description: { SearchUnavailableContent.Description() },
85
+ actions: { SearchUnavailableContent.Actions() })
86
+ }
87
+ }
88
+
89
+ /// The icon large and secondary above a bold title.
90
+ struct _ContentUnavailableLabelStyle: LabelStyle {
91
+ func makeBody(configuration: Configuration) -> some View {
92
+ VStack(spacing: 12) {
93
+ configuration.icon
94
+ .font(.system(size: 48))
95
+ .foregroundStyle(.secondary)
96
+ configuration.title
97
+ .font(.title2.bold())
98
+ .multilineTextAlignment(.center)
99
+ }
100
+ }
101
+ }
@@ -1,3 +1,5 @@
1
+ import Foundation
2
+
1
3
  // MARK: - TextField
2
4
 
3
5
  public protocol TextFieldStyle {
@@ -25,21 +27,12 @@ extension TextFieldStyle where Self == RoundedBorderTextFieldStyle {
25
27
  public static var roundedBorder: RoundedBorderTextFieldStyle { RoundedBorderTextFieldStyle() }
26
28
  }
27
29
 
28
- extension View {
30
+ nonisolated extension View {
29
31
  public func textFieldStyle<S: TextFieldStyle>(_ style: S) -> some View {
30
32
  environment(\._textFieldStyle, style._name)
31
33
  }
32
34
  }
33
35
 
34
- /// Formats a value as text and parses text back (`Text(_:format:)`,
35
- /// `TextField(_:value:format:)`). `FoundationLite` conforms its format styles
36
- /// (`.number`, `.currency(code:)`); the shim itself has none.
37
- public protocol _TextFormat {
38
- associatedtype Input
39
- func _formatText(_ value: Input) -> String
40
- func _parseText(_ text: String) -> Input?
41
- }
42
-
43
36
  /// What the user typed into a formatted field, and the formatted form of the
44
37
  /// value it parsed to. The field shows the typed text while the bound value
45
38
  /// still formats to that form; an outside change to the value replaces it.
@@ -55,6 +48,11 @@ public struct TextField<Label: View> {
55
48
  /// Persistent storage for `TextField(_:value:format:)` (unused otherwise);
56
49
  /// a `State` so the runtime keeps it across re-renders.
57
50
  let draft: State<_TextDraft?>
51
+ /// `TextField(_:text:axis: .vertical)`: a multi-line field that grows
52
+ /// with its text (TextFieldAxis.swift).
53
+ var axis: Axis = .horizontal
54
+ /// The iOS 13 `onCommit:` action (TextFieldCommit.swift): run on Return, like `.onSubmit`.
55
+ var onCommit: (() -> Void)?
58
56
 
59
57
  init(placeholder: String, text: Binding<String>, secure: Bool) {
60
58
  self.placeholder = placeholder
@@ -65,11 +63,13 @@ public struct TextField<Label: View> {
65
63
  }
66
64
 
67
65
  extension TextField where Label == Text {
66
+ @_disfavoredOverload
68
67
  public init<S: StringProtocol>(_ title: S, text: Binding<String>) {
69
68
  self.init(placeholder: String(title), text: text, secure: false)
70
69
  }
71
70
 
72
71
  /// The prompt, when given, is the placeholder; the title names the field.
72
+ @_disfavoredOverload
73
73
  public init<S: StringProtocol>(_ title: S, text: Binding<String>, prompt: Text?) {
74
74
  self.init(placeholder: prompt?.content ?? String(title), text: text, secure: false)
75
75
  }
@@ -81,34 +81,32 @@ extension TextField where Label == Text {
81
81
  /// A field bound to a value through a format: it shows the formatted value
82
82
  /// and, as the user types, parses the text and sets the value when parsing
83
83
  /// succeeds. The typed text stays visible while the value matches it.
84
- public init<S: StringProtocol, F: _TextFormat>(_ title: S, value: Binding<F.Input>, format: F,
85
- prompt: Text? = nil) {
86
- self.init(_placeholder: prompt?.content ?? String(title), value: value, format: format)
84
+ public init<S: StringProtocol, F: ParseableFormatStyle>(_ title: S, value: Binding<F.FormatInput>, format: F, prompt: Text? = nil)
85
+ where F.FormatOutput == String, F.Strategy.ParseInput == String {
86
+ self.init(placeholder: prompt?.content ?? String(title), value: value, format: format)
87
87
  }
88
88
 
89
- public init<F: _TextFormat>(_ titleKey: LocalizedStringKey, value: Binding<F.Input>, format: F,
90
- prompt: Text? = nil) {
91
- self.init(_placeholder: prompt?.content ?? titleKey.key, value: value, format: format)
89
+ public init<F: ParseableFormatStyle>(_ titleKey: LocalizedStringKey, value: Binding<F.FormatInput>, format: F, prompt: Text? = nil)
90
+ where F.FormatOutput == String, F.Strategy.ParseInput == String {
91
+ self.init(placeholder: prompt?.content ?? titleKey.key, value: value, format: format)
92
92
  }
93
93
 
94
- /// The formatted field with its placeholder resolved; public so a bridge
95
- /// module can wrap other format protocols (FoundationBridge wraps
96
- /// Foundation's `ParseableFormatStyle`) without re-entering the public
97
- /// initializers above.
98
- public init<F: _TextFormat>(_placeholder placeholder: String, value: Binding<F.Input>, format: F) {
94
+ /// The formatted field with its placeholder resolved.
95
+ init<F: ParseableFormatStyle>(placeholder: String, value: Binding<F.FormatInput>, format: F)
96
+ where F.FormatOutput == String, F.Strategy.ParseInput == String {
99
97
  let draft = State<_TextDraft?>(wrappedValue: nil)
100
98
  let text = Binding<String>(
101
99
  get: {
102
- let formatted = format._formatText(value.wrappedValue)
100
+ let formatted = format.format(value.wrappedValue)
103
101
  if let current = draft.wrappedValue, current.formatted == formatted { return current.typed }
104
102
  return formatted
105
103
  },
106
104
  set: { typed in
107
- if let parsed = format._parseText(typed) {
108
- draft.wrappedValue = _TextDraft(typed: typed, formatted: format._formatText(parsed))
105
+ if let parsed = try? format.parseStrategy.parse(typed) {
106
+ draft.wrappedValue = _TextDraft(typed: typed, formatted: format.format(parsed))
109
107
  value.wrappedValue = parsed
110
108
  } else {
111
- let formatted = draft.wrappedValue?.formatted ?? format._formatText(value.wrappedValue)
109
+ let formatted = draft.wrappedValue?.formatted ?? format.format(value.wrappedValue)
112
110
  draft.wrappedValue = _TextDraft(typed: typed, formatted: formatted)
113
111
  }
114
112
  }
@@ -132,8 +130,9 @@ extension TextField: _HostView {
132
130
  // Phase 12: `.focused(...)` binds the field's focus; `.onSubmit` wants
133
131
  // the Enter key; `.submitLabel` names the return key.
134
132
  if let focus = environment._focus { props["focused"] = .bool(focus.isFocused()) }
135
- if environment._onSubmit != nil { props["submit"] = .bool(true) }
133
+ if environment._onSubmit != nil || onCommit != nil { props["submit"] = .bool(true) }
136
134
  if let label = environment._submitLabel { props["submitLabel"] = .string(label) }
135
+ if axis == .vertical { props["axis"] = .string("vertical") }
137
136
  return .object(props)
138
137
  }
139
138
  var _handler: ((_JSON) -> Void)? { _handler(in: EnvironmentValues()) }
@@ -144,6 +143,7 @@ extension TextField: _EnvironmentHandling {
144
143
  let text = self.text
145
144
  let focus = environment._focus
146
145
  let onSubmit = environment._onSubmit
146
+ let onCommit = self.onCommit
147
147
  return { payload in
148
148
  switch payload {
149
149
  case .string(let value):
@@ -153,6 +153,7 @@ extension TextField: _EnvironmentHandling {
153
153
  case .string("focus")?:
154
154
  if case .bool(let focused)? = fields["value"] { focus?.setFocused(focused) }
155
155
  case .string("submit")?:
156
+ onCommit?()
156
157
  onSubmit?()
157
158
  default:
158
159
  break
@@ -168,6 +169,11 @@ public struct SecureField<Label: View> {
168
169
  let field: TextField<Label>
169
170
  }
170
171
  extension SecureField where Label == Text {
172
+ public init(_ titleKey: LocalizedStringKey, text: Binding<String>) {
173
+ field = TextField(placeholder: titleKey.key, text: text, secure: true)
174
+ }
175
+
176
+ @_disfavoredOverload
171
177
  public init<S: StringProtocol>(_ title: S, text: Binding<String>) {
172
178
  field = TextField(placeholder: String(title), text: text, secure: true)
173
179
  }
@@ -194,6 +200,11 @@ public struct Toggle<Label: View> {
194
200
  }
195
201
  }
196
202
  extension Toggle where Label == Text {
203
+ public init(_ titleKey: LocalizedStringKey, isOn: Binding<Bool>) {
204
+ self.init(isOn: isOn) { Text(titleKey) }
205
+ }
206
+
207
+ @_disfavoredOverload
197
208
  public init<S: StringProtocol>(_ title: S, isOn: Binding<Bool>) {
198
209
  self.init(isOn: isOn) { Text(title) }
199
210
  }
@@ -229,6 +240,7 @@ public struct Label<Title: View, Icon: View>: View {
229
240
  }
230
241
 
231
242
  extension Label where Title == Text, Icon == Image {
243
+ @_disfavoredOverload
232
244
  public init<S: StringProtocol>(_ title: S, systemImage: String) {
233
245
  self.title = Text(title)
234
246
  self.icon = Image(systemName: systemImage)
@@ -239,15 +251,21 @@ extension Label where Title == Text, Icon == Image {
239
251
  self.icon = Image(systemName: systemImage)
240
252
  }
241
253
 
254
+ @_disfavoredOverload
242
255
  public init<S: StringProtocol>(_ title: S, image name: String) {
243
256
  self.title = Text(title)
244
257
  self.icon = Image(name)
245
258
  }
259
+
260
+ public init(_ titleKey: LocalizedStringKey, image name: String) {
261
+ self.title = Text(titleKey)
262
+ self.icon = Image(name)
263
+ }
246
264
  }
247
265
 
248
266
  // MARK: - Enabling
249
267
 
250
- extension View {
268
+ nonisolated extension View {
251
269
  public func disabled(_ disabled: Bool) -> some View {
252
270
  _styled { $0.disabled = disabled ? true : nil }
253
271
  }
@@ -256,6 +274,20 @@ extension View {
256
274
  public func onAppear(perform action: (@MainActor () -> Void)? = nil) -> some View {
257
275
  _OnAppearView(content: self, action: action)
258
276
  }
277
+
278
+ /// Runs `action` once the view has left the screen (after the render that removed it).
279
+ public func onDisappear(perform action: (@MainActor () -> Void)? = nil) -> some View {
280
+ _OnDisappearView(content: self, action: action)
281
+ }
282
+ }
283
+
284
+ struct _OnDisappearView<Content: View> {
285
+ let content: Content
286
+ let action: (@MainActor () -> Void)?
287
+ }
288
+ extension _OnDisappearView: _PrimitiveView {}
289
+ extension _OnDisappearView: _GroupView {
290
+ var _children: [any View] { [content] }
259
291
  }
260
292
 
261
293
  struct _OnAppearView<Content: View> {
@@ -79,15 +79,41 @@ public struct LayoutProperties: Sendable {
79
79
  }
80
80
 
81
81
  /// A key for values a subview exposes to its layout via `layoutValue(key:value:)`.
82
- /// The shim does not propagate such values; the layout always sees the default.
83
82
  public protocol LayoutValueKey {
84
83
  associatedtype Value
85
84
  static var defaultValue: Value { get }
86
85
  }
87
86
 
88
- extension View {
89
- /// Accepted for source compatibility: custom layouts read `K.defaultValue`.
90
- public func layoutValue<K: LayoutValueKey>(key: K.Type, value: K.Value) -> some View { self }
87
+ nonisolated extension View {
88
+ /// A value the custom layout around this view reads from its subview
89
+ /// (`subview[K.self]`). It travels up with the view's elements; the
90
+ /// value set closest to the view wins.
91
+ public func layoutValue<K: LayoutValueKey>(key: K.Type, value: K.Value) -> some View {
92
+ _LayoutValueView(content: self, key: ObjectIdentifier(K.self), value: value)
93
+ }
94
+ }
95
+
96
+ /// `.layoutValue(key:value:)`: its content, with the value marked on its elements.
97
+ struct _LayoutValueView<Content: View> {
98
+ let content: Content
99
+ let key: ObjectIdentifier
100
+ let value: Any
101
+ }
102
+ extension _LayoutValueView: _PrimitiveView {}
103
+ extension _LayoutValueView: _GroupView {
104
+ var _children: [any View] { [content] }
105
+ }
106
+
107
+ protocol _LayoutValueProviding: _TraitBearing {
108
+ var _layoutValue: (key: ObjectIdentifier, value: Any) { get }
109
+ }
110
+ extension _LayoutValueView: _LayoutValueProviding {
111
+ var _layoutValue: (key: ObjectIdentifier, value: Any) { (key, value) }
112
+ }
113
+
114
+ /// A custom layout's element learns its children's layout values as it is produced.
115
+ protocol _LayoutValuesReceiving {
116
+ func _receive(childLayoutValues: [[ObjectIdentifier: Any]])
91
117
  }
92
118
 
93
119
  /// A proxy for one child of a custom layout.
@@ -102,6 +128,8 @@ public struct LayoutSubview {
102
128
  let ideal: CGSize
103
129
  let max: CGSize
104
130
  let placements: _LayoutPlacements
131
+ /// The child's `.layoutValue`s, by key type.
132
+ var values: [ObjectIdentifier: Any] = [:]
105
133
 
106
134
  public func sizeThatFits(_ proposal: ProposedViewSize) -> CGSize {
107
135
  CGSize(
@@ -125,7 +153,9 @@ public struct LayoutSubview {
125
153
 
126
154
  public var priority: Double { 0 }
127
155
 
128
- public subscript<K: LayoutValueKey>(key: K.Type) -> K.Value { K.defaultValue }
156
+ public subscript<K: LayoutValueKey>(key: K.Type) -> K.Value {
157
+ values[ObjectIdentifier(key)] as? K.Value ?? K.defaultValue
158
+ }
129
159
 
130
160
  /// Records where the child goes. Its size is `sizeThatFits(proposal)` and
131
161
  /// `anchor` says which point of that size sits at `position`.
@@ -272,9 +302,11 @@ struct _LayoutSizes: Equatable {
272
302
  }
273
303
  }
274
304
 
275
- /// Holds a layout's cache across measurements without triggering renders.
305
+ /// Holds a layout's cache across measurements without triggering renders,
306
+ /// and its children's layout values as last produced.
276
307
  final class _LayoutCacheBox {
277
308
  var cache: Any?
309
+ var childValues: [[ObjectIdentifier: Any]] = []
278
310
  }
279
311
 
280
312
  /// The element a custom layout renders as: kind `layout`, the children
@@ -307,15 +339,22 @@ extension _LayoutView: _HostView {
307
339
  let resultBox = _result.box
308
340
  let cacheBox = self.cacheBox
309
341
  return { event in
310
- guard let (proposal, subviews) = _parseLayoutEvent(event) else { return }
342
+ guard let (proposal, subviews) = _parseLayoutEvent(event, values: cacheBox.childValues) else { return }
311
343
  let computed = _runLayout(layout, proposal: proposal, subviews: subviews, cacheBox: cacheBox)
312
344
  if computed != resultBox.value { resultBox.value = computed }
313
345
  }
314
346
  }
315
347
  }
316
348
 
317
- /// Parses `{"proposal": {...}, "children": [{"min", "ideal", "max"}]}`.
318
- func _parseLayoutEvent(_ event: _JSON) -> (ProposedViewSize, LayoutSubviews)? {
349
+ extension _LayoutView: _LayoutValuesReceiving {
350
+ func _receive(childLayoutValues: [[ObjectIdentifier: Any]]) {
351
+ cacheBox.childValues = childLayoutValues
352
+ }
353
+ }
354
+
355
+ /// Parses `{"proposal": {...}, "children": [{"min", "ideal", "max"}]}`;
356
+ /// `values` are the children's layout values, in order.
357
+ func _parseLayoutEvent(_ event: _JSON, values: [[ObjectIdentifier: Any]] = []) -> (ProposedViewSize, LayoutSubviews)? {
319
358
  guard case .object(let fields) = event else { return nil }
320
359
  let proposal: ProposedViewSize
321
360
  if case .object(let p)? = fields["proposal"] {
@@ -331,7 +370,7 @@ func _parseLayoutEvent(_ event: _JSON) -> (ProposedViewSize, LayoutSubviews)? {
331
370
  return CGSize(width: _dimension(s["width"]) ?? 0, height: _dimension(s["height"]) ?? 0)
332
371
  }
333
372
  return LayoutSubview(index: index, min: size("min"), ideal: size("ideal"), max: size("max"),
334
- placements: placements)
373
+ placements: placements, values: index < values.count ? values[index] : [:])
335
374
  }
336
375
  return (proposal, LayoutSubviews(subviews))
337
376
  }
@@ -0,0 +1,46 @@
1
+ // Toolbar content types of the app's own, with a `body` (Ice Cubes'
2
+ // `CancelToolbarItem` reads `@Environment(\.dismiss)` and returns a
3
+ // `ToolbarItem`). Such content becomes a view in the toolbar: when it is
4
+ // rendered, its `@Environment` properties are resolved from the environment
5
+ // where the toolbar is, its `body` runs, and the items it makes are placed
6
+ // like any others.
7
+
8
+ extension Never: ToolbarContent {
9
+ nonisolated public var _toolbarItems: [any View] { [] }
10
+ }
11
+
12
+ /// Content the toolbar reads directly instead of evaluating `body`.
13
+ extension ToolbarContent where Body == Never {
14
+ public var body: Never { fatalError("\(Self.self) is primitive toolbar content and has no body") }
15
+ }
16
+
17
+ extension ToolbarContent {
18
+ /// A view that evaluates `body` in the toolbar's environment.
19
+ nonisolated public var _toolbarItems: [any View] { [_CustomToolbarContentView(content: self)] }
20
+ }
21
+
22
+ struct _CustomToolbarContentView<Content: ToolbarContent> {
23
+ let content: Content
24
+ @Environment(\.self) private var environment
25
+ }
26
+
27
+ extension _CustomToolbarContentView: View {
28
+ var body: some View {
29
+ // The content is not a view, so the runtime does not resolve its
30
+ // properties: do it here, with this view's environment.
31
+ for child in Mirror(reflecting: content).children {
32
+ (child.value as? any _EnvironmentProperty)?._resolve(in: environment)
33
+ (child.value as? any _EnvironmentReading)?._resolve(in: environment)
34
+ }
35
+ return _ToolbarItemsView(items: content.body._toolbarItems)
36
+ }
37
+ }
38
+
39
+ /// The toolbar groups a custom content made, as siblings.
40
+ struct _ToolbarItemsView {
41
+ let items: [any View]
42
+ }
43
+ extension _ToolbarItemsView: _PrimitiveView {}
44
+ extension _ToolbarItemsView: _GroupView {
45
+ var _children: [any View] { items }
46
+ }
@@ -47,7 +47,7 @@ extension _EnvironmentBackgroundShape: _HostView {
47
47
  }
48
48
  }
49
49
 
50
- extension View {
50
+ nonisolated extension View {
51
51
  public func overlay<V: View>(alignment: Alignment = .center, @ViewBuilder content: () -> V) -> some View {
52
52
  _DecoratedView(content: self, decoration: content(), role: "overlay", alignment: alignment)
53
53
  }