@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,841 @@
1
+ // The iOS 18 tab API: `Tab`, `TabSection`, `TabContent` and its result
2
+ // builder, `TabRole`, placements, styles and customization.
3
+ //
4
+ // Tab content resolves to `_TabEntry`s, one per `Tab`, in declaration order
5
+ // (sections flattened, a `.search` tab moved to the trailing end). Each entry
6
+ // becomes a `_TabEntryView`, which is to the runtime exactly what
7
+ // `content.tabItem { label }.tag(value)` is, so a `TabView` of `Tab`s emits the
8
+ // same `tabview` / `tab` elements as the `.tabItem` API, plus a `tab`'s
9
+ // `badge` and `role` props when they are set. In a regular-width
10
+ // `.sidebarAdaptable` tab view the tabs are a sidebar instead (see
11
+ // `_tabSidebar` in Tabs.swift). See docs/ops-protocol.md, "Tabs (iOS 18)".
12
+
13
+ import Foundation
14
+
15
+ /// The content of a `TabView` built with `Tab`s: tabs, sections of tabs,
16
+ /// `ForEach` over them, or a type with a `body`. Like `ChartContent` it is not
17
+ /// main-actor isolated: tabs are created in nonisolated initializers (as in
18
+ /// SwiftUI, where `Tab`'s initializers are `nonisolated`).
19
+ public protocol TabContent<TabValue> {
20
+ associatedtype TabValue: Hashable
21
+ associatedtype Body: TabContent
22
+ @TabContentBuilder<TabValue> var body: Self.Body { get }
23
+ }
24
+
25
+ extension Never: @preconcurrency TabContent {
26
+ public typealias TabValue = Never
27
+ }
28
+
29
+ /// Tab content the runtime reads directly instead of evaluating `body`.
30
+ public protocol _PrimitiveTabContent: TabContent where Body == Never {}
31
+
32
+ extension _PrimitiveTabContent {
33
+ public var body: Never { fatalError("\(Self.self) is primitive tab content and has no body") }
34
+ }
35
+
36
+ // MARK: - Entries
37
+
38
+ /// What the modifiers on tab content set; an inner modifier overrides an outer one.
39
+ struct _TabModifiers {
40
+ var badge: String?
41
+ var hidden = false
42
+ var placement: TabPlacement?
43
+ var customizationID: String?
44
+ var hiddenIn: Set<TabBarPlacement> = []
45
+ }
46
+
47
+ /// One `Tab`, resolved.
48
+ struct _TabEntry {
49
+ let content: any View
50
+ let label: any View
51
+ let value: AnyHashable?
52
+ let role: TabRole?
53
+ let modifiers: _TabModifiers
54
+ /// Index of the enclosing `TabSection` in `_TabCollector.sections`.
55
+ let section: Int?
56
+ }
57
+
58
+ struct _TabCollector {
59
+ var entries: [_TabEntry] = []
60
+ /// The sections' headers, in declaration order.
61
+ var sections: [any View] = []
62
+ var section: Int?
63
+ }
64
+
65
+ /// Internal: contributes tab entries.
66
+ protocol _TabContentNode {
67
+ func _collect(into collector: inout _TabCollector, modifiers: _TabModifiers)
68
+ }
69
+
70
+ extension TabContent {
71
+ func _collectAny(into collector: inout _TabCollector, modifiers: _TabModifiers) {
72
+ if let node = self as? any _TabContentNode {
73
+ node._collect(into: &collector, modifiers: modifiers)
74
+ } else {
75
+ body._collectAny(into: &collector, modifiers: modifiers)
76
+ }
77
+ }
78
+ }
79
+
80
+ /// One tab as a view: to the runtime it is `content.tabItem { label }.tag(value)`
81
+ /// (a `_TabItemProviding` and `_TagProviding` group of the content), and it
82
+ /// carries the badge, role and section for the `tab` element and the sidebar.
83
+ struct _TabEntryView {
84
+ let entry: _TabEntry
85
+ /// The section's header, when the tab is in a `TabSection`.
86
+ let sectionHeader: (any View)?
87
+ /// The position of the tab in declaration order (the sidebar's row order).
88
+ let order: Int
89
+ }
90
+ extension _TabEntryView: _PrimitiveView {}
91
+ extension _TabEntryView: _GroupView {
92
+ var _children: [any View] { [entry.content] }
93
+ }
94
+ extension _TabEntryView: _TabItemProviding {
95
+ var _tabLabel: any View { entry.label }
96
+ var _tabContent: any View { entry.content }
97
+ }
98
+ extension _TabEntryView: _TagProviding {
99
+ /// A tab without a value (`Value == Never`) is only selected by index.
100
+ var _tag: AnyHashable { entry.value ?? AnyHashable(_UntaggedTab()) }
101
+ var _tagged: any View { entry.content }
102
+ }
103
+
104
+ struct _UntaggedTab: Hashable {}
105
+
106
+ // MARK: - Tab
107
+
108
+ /// The semantic role of a tab. A `.search` tab sits at the trailing end of the
109
+ /// tab bar; without a title or image of its own it is "Search" with a
110
+ /// magnifying glass.
111
+ public struct TabRole: Hashable, Sendable {
112
+ let name: String
113
+ public static let search = TabRole(name: "search")
114
+ }
115
+
116
+ /// The label of a tab made from a title and an image.
117
+ public struct DefaultTabLabel {
118
+ let title: Text
119
+ let systemImage: String?
120
+ let image: String?
121
+ }
122
+ extension DefaultTabLabel: View {
123
+ public var body: some View {
124
+ if let systemImage {
125
+ Label { title } icon: { Image(systemName: systemImage) }
126
+ } else if let image {
127
+ Label { title } icon: { Image(image) }
128
+ } else {
129
+ title
130
+ }
131
+ }
132
+ }
133
+
134
+ /// A tab of a `TabView`: its content, a label for the tab bar (or sidebar),
135
+ /// and the `value` the tab view's `selection` takes when it is selected.
136
+ public struct Tab<Value: Hashable, Content: View, Label: View> {
137
+ let value: Value?
138
+ let role: TabRole?
139
+ let content: Content
140
+ let label: Label
141
+
142
+ init(_value value: Value?, role: TabRole?, content: Content, label: Label) {
143
+ self.value = value
144
+ self.role = role
145
+ self.content = content
146
+ self.label = label
147
+ }
148
+ }
149
+ extension Tab: _PrimitiveTabContent {
150
+ public typealias TabValue = Value
151
+ }
152
+ extension Tab: _TabContentNode {
153
+ func _collect(into collector: inout _TabCollector, modifiers: _TabModifiers) {
154
+ collector.entries.append(_TabEntry(
155
+ content: content, label: label, value: value.map { AnyHashable($0) },
156
+ role: role, modifiers: modifiers, section: collector.section))
157
+ }
158
+ }
159
+
160
+ extension DefaultTabLabel {
161
+ init(_ title: Text, systemImage: String? = nil, image: String? = nil) {
162
+ self.title = title
163
+ self.systemImage = systemImage
164
+ self.image = image
165
+ }
166
+ }
167
+
168
+ // Titles, as SwiftUI takes them: a string, a localized key or a resource.
169
+ // `LocalizedStringResource` is declared in FoundationBridge, which depends on
170
+ // this module, so the resource initializers take any `CustomStringConvertible`
171
+ // (disfavored, so strings and keys pick their own overloads): a resource's
172
+ // `description` is its localized text.
173
+ extension Text {
174
+ init<R: CustomStringConvertible>(_tabResource resource: R) {
175
+ self.init(verbatim: resource.description)
176
+ }
177
+ }
178
+
179
+ extension Tab where Label == DefaultTabLabel {
180
+ // With a value.
181
+
182
+ public nonisolated init<S: StringProtocol>(_ title: S, systemImage: String, value: Value,
183
+ @ViewBuilder content: () -> Content) {
184
+ self.init(_value: value, role: nil, content: content(), label: DefaultTabLabel(Text(title), systemImage: systemImage))
185
+ }
186
+
187
+ public nonisolated init<S: StringProtocol>(_ title: S, systemImage: String, value: Value, role: TabRole?,
188
+ @ViewBuilder content: () -> Content) {
189
+ self.init(_value: value, role: role, content: content(), label: DefaultTabLabel(Text(title), systemImage: systemImage))
190
+ }
191
+
192
+ public nonisolated init(_ titleKey: LocalizedStringKey, systemImage: String, value: Value,
193
+ @ViewBuilder content: () -> Content) {
194
+ self.init(_value: value, role: nil, content: content(), label: DefaultTabLabel(Text(titleKey), systemImage: systemImage))
195
+ }
196
+
197
+ public nonisolated init(_ titleKey: LocalizedStringKey, systemImage: String, value: Value, role: TabRole?,
198
+ @ViewBuilder content: () -> Content) {
199
+ self.init(_value: value, role: role, content: content(), label: DefaultTabLabel(Text(titleKey), systemImage: systemImage))
200
+ }
201
+
202
+ @_disfavoredOverload
203
+ public nonisolated init<R: CustomStringConvertible>(_ titleResource: R, systemImage: String, value: Value,
204
+ @ViewBuilder content: () -> Content) {
205
+ self.init(_value: value, role: nil, content: content(),
206
+ label: DefaultTabLabel(Text(_tabResource: titleResource), systemImage: systemImage))
207
+ }
208
+
209
+ @_disfavoredOverload
210
+ public nonisolated init<R: CustomStringConvertible>(_ titleResource: R, systemImage: String, value: Value, role: TabRole?,
211
+ @ViewBuilder content: () -> Content) {
212
+ self.init(_value: value, role: role, content: content(),
213
+ label: DefaultTabLabel(Text(_tabResource: titleResource), systemImage: systemImage))
214
+ }
215
+
216
+ public nonisolated init<S: StringProtocol>(_ title: S, image: String, value: Value, role: TabRole? = nil,
217
+ @ViewBuilder content: () -> Content) {
218
+ self.init(_value: value, role: role, content: content(), label: DefaultTabLabel(Text(title), image: image))
219
+ }
220
+
221
+ public nonisolated init(_ titleKey: LocalizedStringKey, image: String, value: Value, role: TabRole? = nil,
222
+ @ViewBuilder content: () -> Content) {
223
+ self.init(_value: value, role: role, content: content(), label: DefaultTabLabel(Text(titleKey), image: image))
224
+ }
225
+
226
+ /// A tab with only a role (`Tab(value: .search, role: .search) { … }`):
227
+ /// its label comes from the role.
228
+ public nonisolated init(value: Value, role: TabRole, @ViewBuilder content: () -> Content) {
229
+ self.init(_value: value, role: role, content: content(), label: DefaultTabLabel(Text(verbatim: "")))
230
+ }
231
+
232
+ // With an optional value (`TabView(selection: Binding<T?>)`).
233
+
234
+ public nonisolated init<S: StringProtocol, T: Hashable>(_ title: S, systemImage: String, value: T,
235
+ @ViewBuilder content: () -> Content) where Value == T? {
236
+ self.init(_value: Optional(value), role: nil, content: content(), label: DefaultTabLabel(Text(title), systemImage: systemImage))
237
+ }
238
+
239
+ public nonisolated init<S: StringProtocol, T: Hashable>(_ title: S, systemImage: String, value: T, role: TabRole?,
240
+ @ViewBuilder content: () -> Content) where Value == T? {
241
+ self.init(_value: Optional(value), role: role, content: content(), label: DefaultTabLabel(Text(title), systemImage: systemImage))
242
+ }
243
+
244
+ public nonisolated init<T: Hashable>(_ titleKey: LocalizedStringKey, systemImage: String, value: T,
245
+ @ViewBuilder content: () -> Content) where Value == T? {
246
+ self.init(_value: Optional(value), role: nil, content: content(), label: DefaultTabLabel(Text(titleKey), systemImage: systemImage))
247
+ }
248
+
249
+ public nonisolated init<T: Hashable>(_ titleKey: LocalizedStringKey, systemImage: String, value: T, role: TabRole?,
250
+ @ViewBuilder content: () -> Content) where Value == T? {
251
+ self.init(_value: Optional(value), role: role, content: content(), label: DefaultTabLabel(Text(titleKey), systemImage: systemImage))
252
+ }
253
+
254
+ @_disfavoredOverload
255
+ public nonisolated init<R: CustomStringConvertible, T: Hashable>(_ titleResource: R, systemImage: String, value: T,
256
+ @ViewBuilder content: () -> Content) where Value == T? {
257
+ self.init(_value: Optional(value), role: nil, content: content(),
258
+ label: DefaultTabLabel(Text(_tabResource: titleResource), systemImage: systemImage))
259
+ }
260
+
261
+ @_disfavoredOverload
262
+ public nonisolated init<R: CustomStringConvertible, T: Hashable>(_ titleResource: R, systemImage: String, value: T,
263
+ role: TabRole?, @ViewBuilder content: () -> Content) where Value == T? {
264
+ self.init(_value: Optional(value), role: role, content: content(),
265
+ label: DefaultTabLabel(Text(_tabResource: titleResource), systemImage: systemImage))
266
+ }
267
+ }
268
+
269
+ extension Tab {
270
+ /// A tab with a custom label.
271
+ public nonisolated init(value: Value, @ViewBuilder content: () -> Content, @ViewBuilder label: () -> Label) {
272
+ self.init(_value: value, role: nil, content: content(), label: label())
273
+ }
274
+
275
+ public nonisolated init(value: Value, role: TabRole?, @ViewBuilder content: () -> Content,
276
+ @ViewBuilder label: () -> Label) {
277
+ self.init(_value: value, role: role, content: content(), label: label())
278
+ }
279
+
280
+ public nonisolated init<T: Hashable>(value: T, @ViewBuilder content: () -> Content,
281
+ @ViewBuilder label: () -> Label) where Value == T? {
282
+ self.init(_value: Optional(value), role: nil, content: content(), label: label())
283
+ }
284
+
285
+ public nonisolated init<T: Hashable>(value: T, role: TabRole?, @ViewBuilder content: () -> Content,
286
+ @ViewBuilder label: () -> Label) where Value == T? {
287
+ self.init(_value: Optional(value), role: role, content: content(), label: label())
288
+ }
289
+ }
290
+
291
+ // Tabs without a value (a `TabView` without a selection binding).
292
+
293
+ extension Tab where Value == Never, Label == DefaultTabLabel {
294
+ public nonisolated init<S: StringProtocol>(_ title: S, systemImage: String, @ViewBuilder content: () -> Content) {
295
+ self.init(_value: nil, role: nil, content: content(), label: DefaultTabLabel(Text(title), systemImage: systemImage))
296
+ }
297
+
298
+ public nonisolated init<S: StringProtocol>(_ title: S, systemImage: String, role: TabRole?,
299
+ @ViewBuilder content: () -> Content) {
300
+ self.init(_value: nil, role: role, content: content(), label: DefaultTabLabel(Text(title), systemImage: systemImage))
301
+ }
302
+
303
+ public nonisolated init(_ titleKey: LocalizedStringKey, systemImage: String, @ViewBuilder content: () -> Content) {
304
+ self.init(_value: nil, role: nil, content: content(), label: DefaultTabLabel(Text(titleKey), systemImage: systemImage))
305
+ }
306
+
307
+ public nonisolated init(_ titleKey: LocalizedStringKey, systemImage: String, role: TabRole?,
308
+ @ViewBuilder content: () -> Content) {
309
+ self.init(_value: nil, role: role, content: content(), label: DefaultTabLabel(Text(titleKey), systemImage: systemImage))
310
+ }
311
+
312
+ @_disfavoredOverload
313
+ public nonisolated init<R: CustomStringConvertible>(_ titleResource: R, systemImage: String,
314
+ @ViewBuilder content: () -> Content) {
315
+ self.init(_value: nil, role: nil, content: content(),
316
+ label: DefaultTabLabel(Text(_tabResource: titleResource), systemImage: systemImage))
317
+ }
318
+
319
+ @_disfavoredOverload
320
+ public nonisolated init<R: CustomStringConvertible>(_ titleResource: R, systemImage: String, role: TabRole?,
321
+ @ViewBuilder content: () -> Content) {
322
+ self.init(_value: nil, role: role, content: content(),
323
+ label: DefaultTabLabel(Text(_tabResource: titleResource), systemImage: systemImage))
324
+ }
325
+
326
+ public nonisolated init<S: StringProtocol>(_ title: S, image: String, role: TabRole? = nil,
327
+ @ViewBuilder content: () -> Content) {
328
+ self.init(_value: nil, role: role, content: content(), label: DefaultTabLabel(Text(title), image: image))
329
+ }
330
+
331
+ public nonisolated init(role: TabRole, @ViewBuilder content: () -> Content) {
332
+ self.init(_value: nil, role: role, content: content(), label: DefaultTabLabel(Text(verbatim: "")))
333
+ }
334
+ }
335
+
336
+ extension Tab where Value == Never {
337
+ public nonisolated init(@ViewBuilder content: () -> Content, @ViewBuilder label: () -> Label) {
338
+ self.init(_value: nil, role: nil, content: content(), label: label())
339
+ }
340
+
341
+ public nonisolated init(role: TabRole?, @ViewBuilder content: () -> Content, @ViewBuilder label: () -> Label) {
342
+ self.init(_value: nil, role: role, content: content(), label: label())
343
+ }
344
+ }
345
+
346
+ // MARK: - TabSection
347
+
348
+ /// A group of tabs. In a tab bar the section's tabs are tabs of their own
349
+ /// (flattened in order); in a regular-width `.sidebarAdaptable` sidebar they
350
+ /// are a list section under the header.
351
+ public struct TabSection<Header: View, Content: TabContent, Footer: View> {
352
+ let header: Header
353
+ let content: Content
354
+ let footer: Footer
355
+ }
356
+ extension TabSection: _PrimitiveTabContent {
357
+ public typealias TabValue = Content.TabValue
358
+ }
359
+ extension TabSection: _TabContentNode {
360
+ func _collect(into collector: inout _TabCollector, modifiers: _TabModifiers) {
361
+ let outer = collector.section
362
+ collector.sections.append(header)
363
+ collector.section = collector.sections.count - 1
364
+ content._collectAny(into: &collector, modifiers: modifiers)
365
+ collector.section = outer
366
+ }
367
+ }
368
+
369
+ extension TabSection where Header == Text, Footer == EmptyView {
370
+ public nonisolated init<V>(_ titleKey: LocalizedStringKey, @TabContentBuilder<V> content: () -> Content)
371
+ where V == Content.TabValue {
372
+ self.init(header: Text(titleKey), content: content(), footer: EmptyView())
373
+ }
374
+
375
+ @_disfavoredOverload
376
+ public nonisolated init<S: StringProtocol, V>(_ title: S, @TabContentBuilder<V> content: () -> Content)
377
+ where V == Content.TabValue {
378
+ self.init(header: Text(title), content: content(), footer: EmptyView())
379
+ }
380
+
381
+ @_disfavoredOverload
382
+ public nonisolated init<R: CustomStringConvertible, V>(_ titleResource: R,
383
+ @TabContentBuilder<V> content: () -> Content)
384
+ where V == Content.TabValue {
385
+ self.init(header: Text(_tabResource: titleResource), content: content(), footer: EmptyView())
386
+ }
387
+ }
388
+
389
+ extension TabSection where Header == EmptyView, Footer == EmptyView {
390
+ public nonisolated init<V>(@TabContentBuilder<V> content: () -> Content) where V == Content.TabValue {
391
+ self.init(header: EmptyView(), content: content(), footer: EmptyView())
392
+ }
393
+ }
394
+
395
+ extension TabSection where Footer == EmptyView {
396
+ public nonisolated init<V>(@TabContentBuilder<V> content: () -> Content, @ViewBuilder header: () -> Header)
397
+ where V == Content.TabValue {
398
+ self.init(header: header(), content: content(), footer: EmptyView())
399
+ }
400
+ }
401
+
402
+ extension TabSection {
403
+ public nonisolated init<V>(@TabContentBuilder<V> content: () -> Content,
404
+ @ViewBuilder header: () -> Header, @ViewBuilder footer: () -> Footer)
405
+ where V == Content.TabValue {
406
+ self.init(header: header(), content: content(), footer: footer())
407
+ }
408
+
409
+ /// Actions for the section's header in an iPadOS sidebar: accepted, not shown.
410
+ public nonisolated func sectionActions<A: View>(@ViewBuilder content: () -> A) -> some TabContent<TabValue> {
411
+ self
412
+ }
413
+ }
414
+
415
+ // MARK: - Structural content
416
+
417
+ public struct _EmptyTabContent<TabValue: Hashable> {
418
+ public init() {}
419
+ }
420
+ extension _EmptyTabContent: _PrimitiveTabContent {}
421
+ extension _EmptyTabContent: _TabContentNode {
422
+ func _collect(into collector: inout _TabCollector, modifiers: _TabModifiers) {}
423
+ }
424
+
425
+ public struct _TupleTabContent<TabValue: Hashable, T> {
426
+ let children: [any TabContent]
427
+ }
428
+ extension _TupleTabContent: _PrimitiveTabContent {}
429
+ extension _TupleTabContent: _TabContentNode {
430
+ func _collect(into collector: inout _TabCollector, modifiers: _TabModifiers) {
431
+ for child in children { child._collectAny(into: &collector, modifiers: modifiers) }
432
+ }
433
+ }
434
+
435
+ public struct _ConditionalTabContent<TrueContent: TabContent, FalseContent: TabContent>
436
+ where TrueContent.TabValue == FalseContent.TabValue {
437
+ enum Storage {
438
+ case trueContent(TrueContent)
439
+ case falseContent(FalseContent)
440
+ }
441
+ let storage: Storage
442
+ }
443
+ extension _ConditionalTabContent: _PrimitiveTabContent {
444
+ public typealias TabValue = TrueContent.TabValue
445
+ }
446
+ extension _ConditionalTabContent: _TabContentNode {
447
+ func _collect(into collector: inout _TabCollector, modifiers: _TabModifiers) {
448
+ switch storage {
449
+ case .trueContent(let content): content._collectAny(into: &collector, modifiers: modifiers)
450
+ case .falseContent(let content): content._collectAny(into: &collector, modifiers: modifiers)
451
+ }
452
+ }
453
+ }
454
+
455
+ extension Optional: TabContent where Wrapped: TabContent {
456
+ public typealias TabValue = Wrapped.TabValue
457
+ public typealias Body = Never
458
+ public var body: Never { return fatalError("Optional is primitive tab content and has no body") }
459
+ }
460
+ extension Optional: _TabContentNode where Wrapped: TabContent {
461
+ func _collect(into collector: inout _TabCollector, modifiers: _TabModifiers) {
462
+ if case .some(let content) = self { content._collectAny(into: &collector, modifiers: modifiers) }
463
+ }
464
+ }
465
+
466
+ public struct _ArrayTabContent<Element: TabContent> {
467
+ let elements: [Element]
468
+ }
469
+ extension _ArrayTabContent: _PrimitiveTabContent {
470
+ public typealias TabValue = Element.TabValue
471
+ }
472
+ extension _ArrayTabContent: _TabContentNode {
473
+ func _collect(into collector: inout _TabCollector, modifiers: _TabModifiers) {
474
+ for element in elements { element._collectAny(into: &collector, modifiers: modifiers) }
475
+ }
476
+ }
477
+
478
+ /// Type-erased tab content.
479
+ public struct AnyTabContent<TabValue: Hashable> {
480
+ let storage: any TabContent
481
+ public init<C: TabContent>(_ content: C) where C.TabValue == TabValue { storage = content }
482
+ public init<C: TabContent>(erasing content: C) where C.TabValue == TabValue { storage = content }
483
+ }
484
+ extension AnyTabContent: _PrimitiveTabContent {}
485
+ extension AnyTabContent: _TabContentNode {
486
+ func _collect(into collector: inout _TabCollector, modifiers: _TabModifiers) {
487
+ storage._collectAny(into: &collector, modifiers: modifiers)
488
+ }
489
+ }
490
+
491
+ /// `ForEach` over tab content: the tabs of every element, in order.
492
+ extension ForEach: TabContent where Content: TabContent {
493
+ public typealias TabValue = Content.TabValue
494
+ public typealias Body = Never
495
+ public var body: Never { return fatalError("ForEach is primitive tab content and has no body") }
496
+ }
497
+ extension ForEach: _TabContentNode where Content: TabContent {
498
+ func _collect(into collector: inout _TabCollector, modifiers: _TabModifiers) {
499
+ for element in data { content(element)._collectAny(into: &collector, modifiers: modifiers) }
500
+ }
501
+ }
502
+
503
+ extension ForEach where Content: TabContent {
504
+ public init<V>(_ data: Data, id: KeyPath<Data.Element, ID>,
505
+ @TabContentBuilder<V> content: @escaping (Data.Element) -> Content) where V == Content.TabValue {
506
+ self.init(_data: data, id: { $0[keyPath: id] }, content: content)
507
+ }
508
+ }
509
+
510
+ extension ForEach where Content: TabContent, Data.Element: Identifiable, ID == Data.Element.ID {
511
+ public init<V>(_ data: Data, @TabContentBuilder<V> content: @escaping (Data.Element) -> Content)
512
+ where V == Content.TabValue {
513
+ self.init(_data: data, id: { $0.id }, content: content)
514
+ }
515
+ }
516
+
517
+ extension ForEach where Content: TabContent, Data == Range<Int>, ID == Int {
518
+ public init<V>(_ data: Range<Int>, @TabContentBuilder<V> content: @escaping (Int) -> Content)
519
+ where V == Content.TabValue {
520
+ self.init(_data: data, id: { $0 }, content: content)
521
+ }
522
+ }
523
+
524
+ // MARK: - TabContentBuilder
525
+
526
+ @resultBuilder
527
+ public struct TabContentBuilder<SelectionValue: Hashable> {
528
+ public static func buildBlock() -> _EmptyTabContent<SelectionValue> { _EmptyTabContent() }
529
+
530
+ public static func buildBlock<C: TabContent>(_ content: C) -> C where C.TabValue == SelectionValue { content }
531
+
532
+ public static func buildBlock<each C: TabContent>(
533
+ _ content: repeat each C
534
+ ) -> _TupleTabContent<SelectionValue, (repeat each C)> {
535
+ var children: [any TabContent] = []
536
+ for child in repeat each content { children.append(child) }
537
+ return _TupleTabContent(children: children)
538
+ }
539
+
540
+ public static func buildExpression<C: TabContent>(_ content: C) -> C where C.TabValue == SelectionValue { content }
541
+
542
+ public static func buildOptional<C: TabContent>(_ content: C?) -> C? where C.TabValue == SelectionValue { content }
543
+
544
+ public static func buildEither<TrueContent: TabContent, FalseContent: TabContent>(
545
+ first: TrueContent
546
+ ) -> _ConditionalTabContent<TrueContent, FalseContent>
547
+ where TrueContent.TabValue == SelectionValue, FalseContent.TabValue == SelectionValue {
548
+ _ConditionalTabContent(storage: .trueContent(first))
549
+ }
550
+
551
+ public static func buildEither<TrueContent: TabContent, FalseContent: TabContent>(
552
+ second: FalseContent
553
+ ) -> _ConditionalTabContent<TrueContent, FalseContent>
554
+ where TrueContent.TabValue == SelectionValue, FalseContent.TabValue == SelectionValue {
555
+ _ConditionalTabContent(storage: .falseContent(second))
556
+ }
557
+
558
+ public static func buildArray<C: TabContent>(_ components: [C]) -> _ArrayTabContent<C> where C.TabValue == SelectionValue {
559
+ _ArrayTabContent(elements: components)
560
+ }
561
+
562
+ public static func buildLimitedAvailability<C: TabContent>(_ content: C) -> AnyTabContent<SelectionValue>
563
+ where C.TabValue == SelectionValue {
564
+ AnyTabContent(content)
565
+ }
566
+
567
+ /// A `TabView`'s content: the tab entries of `C` as `_TabEntryView`s.
568
+ public struct Content<C: TabContent> where C.TabValue == SelectionValue {
569
+ let content: C
570
+ }
571
+ }
572
+ extension TabContentBuilder.Content: _PrimitiveView {}
573
+ extension TabContentBuilder.Content: _GroupView {
574
+ /// The tabs in tab bar order: hidden tabs dropped and `.search` tabs moved
575
+ /// to the trailing end (where iOS puts the search tab).
576
+ var _children: [any View] {
577
+ var collector = _TabCollector()
578
+ content._collectAny(into: &collector, modifiers: _TabModifiers())
579
+ let declared = collector.entries.enumerated().filter { !$0.element.modifiers.hidden }
580
+ let ordered = declared.filter { $0.element.role != .search } + declared.filter { $0.element.role == .search }
581
+ return ordered.map { order, entry in
582
+ _TabEntryView(entry: entry, sectionHeader: entry.section.map { collector.sections[$0] }, order: order)
583
+ }
584
+ }
585
+ }
586
+
587
+ // MARK: - Modifiers
588
+
589
+ /// Tab content with a modifier applied to every tab beneath it.
590
+ public struct _ModifiedTabContent<Content: TabContent> {
591
+ let content: Content
592
+ let transform: (inout _TabModifiers) -> Void
593
+ }
594
+ extension _ModifiedTabContent: _PrimitiveTabContent {
595
+ public typealias TabValue = Content.TabValue
596
+ }
597
+ extension _ModifiedTabContent: _TabContentNode {
598
+ func _collect(into collector: inout _TabCollector, modifiers: _TabModifiers) {
599
+ // Outer modifiers run first so that the tab's own (inner) ones win.
600
+ var modified = modifiers
601
+ transform(&modified)
602
+ content._collectAny(into: &collector, modifiers: modified)
603
+ }
604
+ }
605
+
606
+ /// Where a tab may appear when the tab bar and sidebar are customizable.
607
+ /// Recorded only: every tab appears in the tab bar (compact) and the sidebar
608
+ /// (regular `.sidebarAdaptable`).
609
+ public struct TabPlacement: Hashable, Sendable {
610
+ let name: String
611
+ public static let automatic = TabPlacement(name: "automatic")
612
+ public static let pinned = TabPlacement(name: "pinned")
613
+ public static let sidebarOnly = TabPlacement(name: "sidebarOnly")
614
+ }
615
+
616
+ /// The bar a `TabView` shows its tabs in.
617
+ public struct TabBarPlacement: Hashable, Sendable {
618
+ let name: String
619
+ public static let automatic = TabBarPlacement(name: "automatic")
620
+ public static let tabBar = TabBarPlacement(name: "tabBar")
621
+ public static let sidebar = TabBarPlacement(name: "sidebar")
622
+ public static let ornament = TabBarPlacement(name: "ornament")
623
+ public static let topBar = TabBarPlacement(name: "topBar")
624
+ public static let bottomBar = TabBarPlacement(name: "bottomBar")
625
+ }
626
+
627
+ /// The placement a `.sidebarAdaptable` tab view starts in.
628
+ public struct AdaptableTabBarPlacement: Hashable, Sendable {
629
+ let name: String
630
+ public static let automatic = AdaptableTabBarPlacement(name: "automatic")
631
+ public static let tabBar = AdaptableTabBarPlacement(name: "tabBar")
632
+ public static let sidebar = AdaptableTabBarPlacement(name: "sidebar")
633
+ }
634
+
635
+ /// Whether the user may reorder or hide a tab or section (recorded only).
636
+ public struct TabCustomizationBehavior: Hashable, Sendable {
637
+ let name: String
638
+ public static let automatic = TabCustomizationBehavior(name: "automatic")
639
+ public static let reorderable = TabCustomizationBehavior(name: "reorderable")
640
+ public static let disabled = TabCustomizationBehavior(name: "disabled")
641
+ }
642
+
643
+ extension TabContent {
644
+ /// A badge on the tab's bar item (a count of 0 shows none).
645
+ public nonisolated func badge(_ count: Int) -> some TabContent<TabValue> {
646
+ _ModifiedTabContent(content: self) { $0.badge = count == 0 ? nil : String(count) }
647
+ }
648
+
649
+ public nonisolated func badge(_ label: Text?) -> some TabContent<TabValue> {
650
+ _ModifiedTabContent(content: self) { $0.badge = label.flatMap { $0.content.isEmpty ? nil : $0.content } }
651
+ }
652
+
653
+ @_disfavoredOverload
654
+ public nonisolated func badge<S: StringProtocol>(_ label: S?) -> some TabContent<TabValue> {
655
+ _ModifiedTabContent(content: self) { $0.badge = label.flatMap { $0.isEmpty ? nil : String($0) } }
656
+ }
657
+
658
+ public nonisolated func badge(_ key: LocalizedStringKey?) -> some TabContent<TabValue> {
659
+ _ModifiedTabContent(content: self) { modifiers in
660
+ modifiers.badge = key.flatMap { Text($0).content.isEmpty ? nil : Text($0).content }
661
+ }
662
+ }
663
+
664
+ /// Hides the tab (it is not in the tab bar or the sidebar).
665
+ public nonisolated func hidden(_ hidden: Bool = true) -> some TabContent<TabValue> {
666
+ _ModifiedTabContent(content: self) { if hidden { $0.hidden = true } }
667
+ }
668
+
669
+ /// Recorded only (see `TabPlacement`).
670
+ public nonisolated func tabPlacement(_ placement: TabPlacement) -> some TabContent<TabValue> {
671
+ _ModifiedTabContent(content: self) { $0.placement = placement }
672
+ }
673
+
674
+ /// The identity of the tab in a `TabViewCustomization` (recorded only).
675
+ public nonisolated func customizationID(_ id: String) -> some TabContent<TabValue> {
676
+ _ModifiedTabContent(content: self) { $0.customizationID = id }
677
+ }
678
+
679
+ /// Recorded only: tabs show in the tab bar and the sidebar regardless.
680
+ public nonisolated func defaultVisibility(_ visibility: Visibility,
681
+ for placements: TabBarPlacement...) -> some TabContent<TabValue> {
682
+ _ModifiedTabContent(content: self) { modifiers in
683
+ for placement in placements {
684
+ if visibility == .hidden {
685
+ modifiers.hiddenIn.insert(placement)
686
+ } else {
687
+ modifiers.hiddenIn.remove(placement)
688
+ }
689
+ }
690
+ }
691
+ }
692
+
693
+ /// Accepted; tabs cannot be reordered or hidden by the user.
694
+ public nonisolated func customizationBehavior(_ behavior: TabCustomizationBehavior,
695
+ for placements: TabBarPlacement...) -> some TabContent<TabValue> {
696
+ self
697
+ }
698
+
699
+ public nonisolated func accessibilityIdentifier(_ identifier: String) -> some TabContent<TabValue> { self }
700
+ public nonisolated func accessibilityLabel(_ label: Text) -> some TabContent<TabValue> { self }
701
+ public nonisolated func springLoadingBehavior(_ behavior: SpringLoadingBehavior) -> some TabContent<TabValue> { self }
702
+ }
703
+
704
+ /// Whether drags spring-load a tab (accepted; there is no drag and drop onto tabs).
705
+ public struct SpringLoadingBehavior: Hashable, Sendable {
706
+ let name: String
707
+ public static let automatic = SpringLoadingBehavior(name: "automatic")
708
+ public static let enabled = SpringLoadingBehavior(name: "enabled")
709
+ public static let disabled = SpringLoadingBehavior(name: "disabled")
710
+ }
711
+
712
+ // MARK: - Customization
713
+
714
+ /// The user's customization of a tab view's tabs and sections (visibility and
715
+ /// order). The browser has no customization UI: the value is kept as state
716
+ /// (it is `Codable`, so `@AppStorage` round-trips it) and a tab view shows its
717
+ /// tabs as declared.
718
+ public struct TabViewCustomization: Equatable, Codable, Sendable {
719
+ var visibility: [String: String] = [:]
720
+
721
+ public init() {}
722
+
723
+ public subscript(visibility id: String) -> Visibility {
724
+ get {
725
+ switch visibility[id] {
726
+ case "visible": .visible
727
+ case "hidden": .hidden
728
+ default: .automatic
729
+ }
730
+ }
731
+ set {
732
+ switch newValue {
733
+ case .visible: visibility[id] = "visible"
734
+ case .hidden: visibility[id] = "hidden"
735
+ case .automatic: visibility[id] = nil
736
+ }
737
+ }
738
+ }
739
+
740
+ public mutating func resetVisibility() { visibility = [:] }
741
+ public mutating func resetTabOrder() {}
742
+ public mutating func resetSectionOrder(forIdentifier id: String) {}
743
+ }
744
+
745
+ // MARK: - Styles
746
+
747
+ /// How a `TabView` presents its tabs.
748
+ public protocol TabViewStyle {
749
+ var _name: String { get }
750
+ }
751
+ public struct DefaultTabViewStyle: TabViewStyle {
752
+ public init() {}
753
+ public var _name: String { "automatic" }
754
+ }
755
+ /// A tab bar in compact width; a sidebar in regular width.
756
+ public struct SidebarAdaptableTabViewStyle: TabViewStyle {
757
+ public init() {}
758
+ public var _name: String { "sidebarAdaptable" }
759
+ }
760
+ public struct TabBarOnlyTabViewStyle: TabViewStyle {
761
+ public init() {}
762
+ public var _name: String { "tabBarOnly" }
763
+ }
764
+ /// Accepted; the tabs are still shown with a tab bar.
765
+ public struct PageTabViewStyle: TabViewStyle {
766
+ public struct IndexDisplayMode: Hashable, Sendable {
767
+ let name: String
768
+ public static let automatic = IndexDisplayMode(name: "automatic")
769
+ public static let always = IndexDisplayMode(name: "always")
770
+ public static let never = IndexDisplayMode(name: "never")
771
+ }
772
+ public init(indexDisplayMode: IndexDisplayMode = .automatic) {}
773
+ public var _name: String { "page" }
774
+ }
775
+ extension TabViewStyle where Self == DefaultTabViewStyle {
776
+ public static var automatic: DefaultTabViewStyle { DefaultTabViewStyle() }
777
+ }
778
+ extension TabViewStyle where Self == SidebarAdaptableTabViewStyle {
779
+ public static var sidebarAdaptable: SidebarAdaptableTabViewStyle { SidebarAdaptableTabViewStyle() }
780
+ }
781
+ extension TabViewStyle where Self == TabBarOnlyTabViewStyle {
782
+ public static var tabBarOnly: TabBarOnlyTabViewStyle { TabBarOnlyTabViewStyle() }
783
+ }
784
+ extension TabViewStyle where Self == PageTabViewStyle {
785
+ public static var page: PageTabViewStyle { PageTabViewStyle() }
786
+ public static func page(indexDisplayMode: PageTabViewStyle.IndexDisplayMode) -> PageTabViewStyle {
787
+ PageTabViewStyle(indexDisplayMode: indexDisplayMode)
788
+ }
789
+ }
790
+
791
+ enum _TabViewStyleKey: EnvironmentKey { static let defaultValue = "automatic" }
792
+ enum _TabBarPlacementKey: EnvironmentKey { static let defaultValue = "automatic" }
793
+
794
+ extension EnvironmentValues {
795
+ var _tabViewStyle: String {
796
+ get { self[_TabViewStyleKey.self] }
797
+ set { self[_TabViewStyleKey.self] = newValue }
798
+ }
799
+
800
+ /// The `defaultAdaptableTabBarPlacement` / `defaultTabBarPlacement` name.
801
+ var _tabBarPlacement: String {
802
+ get { self[_TabBarPlacementKey.self] }
803
+ set { self[_TabBarPlacementKey.self] = newValue }
804
+ }
805
+ }
806
+
807
+ nonisolated extension View {
808
+ public func tabViewStyle<S: TabViewStyle>(_ style: S) -> some View {
809
+ environment(\._tabViewStyle, style._name)
810
+ }
811
+
812
+ /// Where a `.sidebarAdaptable` tab view shows its tabs in regular width:
813
+ /// `.tabBar` keeps the tab bar, anything else is the sidebar.
814
+ public func defaultAdaptableTabBarPlacement(_ placement: AdaptableTabBarPlacement = .automatic) -> some View {
815
+ environment(\._tabBarPlacement, placement.name)
816
+ }
817
+
818
+ public func defaultTabBarPlacement(_ placement: TabBarPlacement) -> some View {
819
+ environment(\._tabBarPlacement, placement.name)
820
+ }
821
+
822
+ /// Accepted; the customization is kept by the app but not applied.
823
+ public func tabViewCustomization(_ customization: Binding<TabViewCustomization>?) -> some View { self }
824
+
825
+ public func tabViewSidebarHeader<V: View>(@ViewBuilder content: () -> V) -> some View { self }
826
+ public func tabViewSidebarFooter<V: View>(@ViewBuilder content: () -> V) -> some View { self }
827
+ public func tabViewSidebarBottomBar<V: View>(@ViewBuilder content: () -> V) -> some View { self }
828
+ }
829
+
830
+ // MARK: - Symbol variants
831
+
832
+ enum _SymbolVariantsKey: EnvironmentKey { static let defaultValue = SymbolVariants.none }
833
+
834
+ extension EnvironmentValues {
835
+ /// The symbol variant the subtree asked for (tab labels set `.fill` on the
836
+ /// selected tab). Kept for views that read it; symbols draw as named.
837
+ public var symbolVariants: SymbolVariants {
838
+ get { self[_SymbolVariantsKey.self] }
839
+ set { self[_SymbolVariantsKey.self] = newValue }
840
+ }
841
+ }