@swiftbrowser/swift 0.0.0-stage → 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 (400) hide show
  1. package/Package.swift +214 -0
  2. package/README.md +10 -2
  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 +61 -0
  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/FoundationBridge/Bundle.swift +119 -0
  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 +29 -0
  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/Locale.swift +86 -0
  170. package/Sources/FoundationBridge/Localization.swift +149 -0
  171. package/Sources/FoundationBridge/Locks.swift +50 -0
  172. package/Sources/FoundationBridge/Markdown.swift +527 -0
  173. package/Sources/FoundationBridge/MeasurementFormat.swift +95 -0
  174. package/Sources/FoundationBridge/NotificationCenter.swift +154 -0
  175. package/Sources/FoundationBridge/OpenURLHandlers.swift +60 -0
  176. package/Sources/FoundationBridge/Operation.swift +195 -0
  177. package/Sources/FoundationBridge/ProcessInfo.swift +32 -0
  178. package/Sources/FoundationBridge/RelativeDateTimeFormatter.swift +136 -0
  179. package/Sources/FoundationBridge/SceneStorage.swift +78 -0
  180. package/Sources/FoundationBridge/SecurityExports.swift +8 -0
  181. package/Sources/FoundationBridge/Selector.swift +226 -0
  182. package/Sources/FoundationBridge/StringComparators.swift +17 -0
  183. package/Sources/FoundationBridge/Table.swift +211 -0
  184. package/Sources/FoundationBridge/TextAttributes.swift +42 -0
  185. package/Sources/FoundationBridge/Timer.swift +53 -0
  186. package/Sources/FoundationBridge/UITextChecker.swift +30 -0
  187. package/Sources/FoundationBridge/URLSession.swift +718 -0
  188. package/Sources/FoundationBridge/UserDefaults.swift +183 -0
  189. package/Sources/FoundationBridge/WebAuthRedirects.swift +227 -0
  190. package/Sources/FoundationBridge/WebSocket.swift +187 -0
  191. package/Sources/FoundationModels/FoundationModels.swift +1098 -0
  192. package/Sources/ImageIO/GIF.swift +72 -0
  193. package/Sources/ImageIO/ImageIO.swift +248 -0
  194. package/Sources/ImageIO/ImageTypes.swift +28 -0
  195. package/Sources/LinkPresentation/LinkPresentation.swift +249 -0
  196. package/Sources/LocalAuthentication/LAContext.swift +86 -0
  197. package/Sources/MapKit/Geometry.swift +223 -0
  198. package/Sources/MapKit/Map.swift +638 -0
  199. package/Sources/MapKit/MapView.swift +229 -0
  200. package/Sources/MobileCoreServices/MobileCoreServices.swift +28 -0
  201. package/Sources/NaturalLanguage/LanguageIdentifier.swift +317 -0
  202. package/Sources/NaturalLanguage/NaturalLanguage.swift +135 -0
  203. package/Sources/OSLog/OSLog.swift +6 -0
  204. package/Sources/Photos/Photos.swift +572 -0
  205. package/Sources/PhotosUI/PhotosPicker.swift +248 -0
  206. package/Sources/PhotosUI/PhotosPickerItem.swift +261 -0
  207. package/Sources/QuickLook/QuickLook.swift +168 -0
  208. package/Sources/SafariServices/SafariServices.swift +106 -0
  209. package/Sources/Security/Security.swift +332 -0
  210. package/Sources/StoreKit/AppStore.swift +207 -0
  211. package/Sources/StoreKit/Products.swift +280 -0
  212. package/Sources/StoreKit/RequestReview.swift +28 -0
  213. package/Sources/StoreKit/StoreKit1.swift +486 -0
  214. package/Sources/StoreKit/StoreViews.swift +428 -0
  215. package/Sources/StoreKit/Transactions.swift +197 -0
  216. package/Sources/SwiftData/Macros.swift +58 -0
  217. package/Sources/SwiftData/ModelActor.swift +38 -0
  218. package/Sources/SwiftData/ModelContainer.swift +129 -0
  219. package/Sources/SwiftData/ModelContext.swift +451 -0
  220. package/Sources/SwiftData/PersistentModel.swift +238 -0
  221. package/Sources/SwiftData/Properties.swift +261 -0
  222. package/Sources/SwiftData/Query.swift +256 -0
  223. package/Sources/SwiftData/Schema.swift +192 -0
  224. package/Sources/SwiftData/Store.swift +146 -0
  225. package/Sources/SwiftData/StringPredicates.swift +125 -0
  226. package/Sources/SwiftDataMacros/EntryMacro.swift +82 -0
  227. package/Sources/SwiftDataMacros/GenerableMacro.swift +183 -0
  228. package/Sources/SwiftDataMacros/ModelActorMacro.swift +46 -0
  229. package/Sources/SwiftDataMacros/ModelMacro.swift +260 -0
  230. package/Sources/SwiftDataMacros/Plugin.swift +18 -0
  231. package/Sources/SwiftDataMacros/PredicateMacro.swift +1244 -0
  232. package/Sources/SwiftUI/API/Accessibility.swift +181 -0
  233. package/Sources/SwiftUI/API/AccessibilityExtras.swift +33 -0
  234. package/Sources/SwiftUI/API/AccessibilityFocus.swift +63 -0
  235. package/Sources/SwiftUI/API/Alert.swift +221 -0
  236. package/Sources/SwiftUI/API/AlignmentGuides.swift +65 -0
  237. package/Sources/SwiftUI/API/Animation.swift +285 -0
  238. package/Sources/SwiftUI/API/App.swift +87 -0
  239. package/Sources/SwiftUI/API/BindingCollections.swift +35 -0
  240. package/Sources/SwiftUI/API/BindingForEach.swift +27 -0
  241. package/Sources/SwiftUI/API/Bitmaps.swift +254 -0
  242. package/Sources/SwiftUI/API/ButtonStyles.swift +96 -0
  243. package/Sources/SwiftUI/API/Canvas.swift +337 -0
  244. package/Sources/SwiftUI/API/Color.swift +237 -0
  245. package/Sources/SwiftUI/API/ColorEffects.swift +52 -0
  246. package/Sources/SwiftUI/API/ColorPickerAndLabeledContent.swift +138 -0
  247. package/Sources/SwiftUI/API/ColorSpaces.swift +161 -0
  248. package/Sources/SwiftUI/API/Commands.swift +106 -0
  249. package/Sources/SwiftUI/API/ContainerBackground.swift +28 -0
  250. package/Sources/SwiftUI/API/ContentShape.swift +33 -0
  251. package/Sources/SwiftUI/API/ContentSizeCategory.swift +35 -0
  252. package/Sources/SwiftUI/API/ContentUnavailable.swift +101 -0
  253. package/Sources/SwiftUI/API/Controls.swift +300 -0
  254. package/Sources/SwiftUI/API/CustomLayout.swift +442 -0
  255. package/Sources/SwiftUI/API/CustomToolbarContent.swift +46 -0
  256. package/Sources/SwiftUI/API/Decorations.swift +92 -0
  257. package/Sources/SwiftUI/API/EditMode.swift +212 -0
  258. package/Sources/SwiftUI/API/Effects.swift +388 -0
  259. package/Sources/SwiftUI/API/Entry.swift +8 -0
  260. package/Sources/SwiftUI/API/Environment.swift +439 -0
  261. package/Sources/SwiftUI/API/EnvironmentSendable.swift +6 -0
  262. package/Sources/SwiftUI/API/Focus.swift +137 -0
  263. package/Sources/SwiftUI/API/Font.swift +131 -0
  264. package/Sources/SwiftUI/API/Gauge.swift +290 -0
  265. package/Sources/SwiftUI/API/Geometry.swift +89 -0
  266. package/Sources/SwiftUI/API/GeometryEffects.swift +232 -0
  267. package/Sources/SwiftUI/API/GeometryReader.swift +135 -0
  268. package/Sources/SwiftUI/API/GestureState.swift +65 -0
  269. package/Sources/SwiftUI/API/Gestures.swift +342 -0
  270. package/Sources/SwiftUI/API/Glass.swift +127 -0
  271. package/Sources/SwiftUI/API/Grid.swift +188 -0
  272. package/Sources/SwiftUI/API/GroupBoxAndControlGroup.swift +130 -0
  273. package/Sources/SwiftUI/API/KeyPress.swift +54 -0
  274. package/Sources/SwiftUI/API/LabelStyle.swift +124 -0
  275. package/Sources/SwiftUI/API/Layout.swift +220 -0
  276. package/Sources/SwiftUI/API/LazyStacks.swift +49 -0
  277. package/Sources/SwiftUI/API/LegacyAlert.swift +97 -0
  278. package/Sources/SwiftUI/API/Lists.swift +331 -0
  279. package/Sources/SwiftUI/API/Menu.swift +58 -0
  280. package/Sources/SwiftUI/API/Modifiers.swift +313 -0
  281. package/Sources/SwiftUI/API/MoreModifiers.swift +100 -0
  282. package/Sources/SwiftUI/API/Namespace.swift +44 -0
  283. package/Sources/SwiftUI/API/Navigation.swift +386 -0
  284. package/Sources/SwiftUI/API/NavigationDestinationBindings.swift +55 -0
  285. package/Sources/SwiftUI/API/ObservableObject.swift +293 -0
  286. package/Sources/SwiftUI/API/OnChange.swift +48 -0
  287. package/Sources/SwiftUI/API/Path.swift +543 -0
  288. package/Sources/SwiftUI/API/Phase8Controls.swift +411 -0
  289. package/Sources/SwiftUI/API/PhaseAnimator.swift +130 -0
  290. package/Sources/SwiftUI/API/Picker.swift +185 -0
  291. package/Sources/SwiftUI/API/PointerAndKeyboard.swift +77 -0
  292. package/Sources/SwiftUI/API/Popover.swift +41 -0
  293. package/Sources/SwiftUI/API/Preferences.swift +262 -0
  294. package/Sources/SwiftUI/API/Presentation.swift +122 -0
  295. package/Sources/SwiftUI/API/PresentationExtras.swift +60 -0
  296. package/Sources/SwiftUI/API/Primitives.swift +517 -0
  297. package/Sources/SwiftUI/API/Publishers.swift +107 -0
  298. package/Sources/SwiftUI/API/Redaction.swift +75 -0
  299. package/Sources/SwiftUI/API/RowActions.swift +84 -0
  300. package/Sources/SwiftUI/API/Scenes.swift +131 -0
  301. package/Sources/SwiftUI/API/ScrollModifiers.swift +132 -0
  302. package/Sources/SwiftUI/API/ScrollTargets.swift +104 -0
  303. package/Sources/SwiftUI/API/ScrollViewReader.swift +144 -0
  304. package/Sources/SwiftUI/API/SectionSupplements.swift +96 -0
  305. package/Sources/SwiftUI/API/Shape.swift +214 -0
  306. package/Sources/SwiftUI/API/ShapeStyle.swift +409 -0
  307. package/Sources/SwiftUI/API/ShapeTrim.swift +78 -0
  308. package/Sources/SwiftUI/API/Sharing.swift +193 -0
  309. package/Sources/SwiftUI/API/StackLayouts.swift +199 -0
  310. package/Sources/SwiftUI/API/State.swift +144 -0
  311. package/Sources/SwiftUI/API/StatusGaps.swift +121 -0
  312. package/Sources/SwiftUI/API/StrokeStyle.swift +30 -0
  313. package/Sources/SwiftUI/API/SymbolEffects.swift +203 -0
  314. package/Sources/SwiftUI/API/TabContent.swift +841 -0
  315. package/Sources/SwiftUI/API/Table.swift +382 -0
  316. package/Sources/SwiftUI/API/Tabs.swift +263 -0
  317. package/Sources/SwiftUI/API/Tasks.swift +35 -0
  318. package/Sources/SwiftUI/API/Text.swift +386 -0
  319. package/Sources/SwiftUI/API/TextDates.swift +61 -0
  320. package/Sources/SwiftUI/API/TextDecorations.swift +52 -0
  321. package/Sources/SwiftUI/API/TextFieldAxis.swift +103 -0
  322. package/Sources/SwiftUI/API/TextFieldCommit.swift +52 -0
  323. package/Sources/SwiftUI/API/Timeline.swift +212 -0
  324. package/Sources/SwiftUI/API/Toolbar.swift +251 -0
  325. package/Sources/SwiftUI/API/Transfer.swift +145 -0
  326. package/Sources/SwiftUI/API/UnevenRoundedRectangle.swift +66 -0
  327. package/Sources/SwiftUI/API/Video.swift +64 -0
  328. package/Sources/SwiftUI/API/View.swift +215 -0
  329. package/Sources/SwiftUI/API/ViewModifier.swift +43 -0
  330. package/Sources/SwiftUI/API/VisualEffect.swift +155 -0
  331. package/Sources/SwiftUI/API/Windows.swift +25 -0
  332. package/Sources/SwiftUI/Charts/Axis.swift +325 -0
  333. package/Sources/SwiftUI/Charts/AxisFormatsAndRanges.swift +68 -0
  334. package/Sources/SwiftUI/Charts/Chart.swift +660 -0
  335. package/Sources/SwiftUI/Charts/ChartContent.swift +376 -0
  336. package/Sources/SwiftUI/Charts/ChartProxy.swift +57 -0
  337. package/Sources/SwiftUI/Charts/Marks.swift +204 -0
  338. package/Sources/SwiftUI/Charts/Plottable.swift +99 -0
  339. package/Sources/SwiftUI/Charts/Scales.swift +326 -0
  340. package/Sources/SwiftUI/Localization/Localization.swift +498 -0
  341. package/Sources/SwiftUI/Localization/PluralRules.swift +127 -0
  342. package/Sources/SwiftUI/Runtime/Executor.swift +85 -0
  343. package/Sources/SwiftUI/Runtime/Exports.swift +101 -0
  344. package/Sources/SwiftUI/Runtime/ImageSource.swift +310 -0
  345. package/Sources/SwiftUI/Runtime/JSON.swift +143 -0
  346. package/Sources/SwiftUI/Runtime/JSONParser.swift +443 -0
  347. package/Sources/SwiftUI/Runtime/LazyRows.swift +99 -0
  348. package/Sources/SwiftUI/Runtime/Measurements.swift +140 -0
  349. package/Sources/SwiftUI/Runtime/Ops.swift +152 -0
  350. package/Sources/SwiftUI/Runtime/Reconciler.swift +219 -0
  351. package/Sources/SwiftUI/Runtime/Replay.swift +382 -0
  352. package/Sources/SwiftUI/Runtime/Runtime.swift +2146 -0
  353. package/Sources/SwiftUI/Runtime/Sameness.swift +152 -0
  354. package/Sources/SwiftUI/Runtime/ViewPath.swift +89 -0
  355. package/Sources/SwiftUI/Runtime/ViewTraits.swift +175 -0
  356. package/Sources/SwiftUI/Runtime/WebAuthHeadless.swift +49 -0
  357. package/Sources/Symbols/Symbols.swift +25 -0
  358. package/Sources/Translation/Translation.swift +423 -0
  359. package/Sources/UIKit/Activity.swift +213 -0
  360. package/Sources/UIKit/Alerts.swift +69 -0
  361. package/Sources/UIKit/AppDelegate.swift +222 -0
  362. package/Sources/UIKit/Appearance.swift +84 -0
  363. package/Sources/UIKit/ColorConversions.swift +70 -0
  364. package/Sources/UIKit/Controls.swift +225 -0
  365. package/Sources/UIKit/Device.swift +200 -0
  366. package/Sources/UIKit/Feedback.swift +65 -0
  367. package/Sources/UIKit/Font.swift +307 -0
  368. package/Sources/UIKit/Graphics.swift +204 -0
  369. package/Sources/UIKit/HostingController.swift +185 -0
  370. package/Sources/UIKit/Identity.swift +24 -0
  371. package/Sources/UIKit/Introspectable.swift +510 -0
  372. package/Sources/UIKit/Pasteboard.swift +363 -0
  373. package/Sources/UIKit/PhotoAlbum.swift +81 -0
  374. package/Sources/UIKit/RemoteNotifications.swift +15 -0
  375. package/Sources/UIKit/Representable.swift +288 -0
  376. package/Sources/UIKit/SafeArea.swift +12 -0
  377. package/Sources/UIKit/SceneDelegates.swift +132 -0
  378. package/Sources/UIKit/Scenes.swift +40 -0
  379. package/Sources/UIKit/ScrollView.swift +157 -0
  380. package/Sources/UIKit/ShortcutItems.swift +67 -0
  381. package/Sources/UIKit/SymbolConfiguration.swift +124 -0
  382. package/Sources/UIKit/TargetAction.swift +123 -0
  383. package/Sources/UIKit/TextPaste.swift +161 -0
  384. package/Sources/UIKit/TextView.swift +538 -0
  385. package/Sources/UIKit/UIKit.swift +292 -0
  386. package/Sources/UIKit/UIView.swift +855 -0
  387. package/Sources/UIKit/ViewTranslation.swift +311 -0
  388. package/Sources/UniformTypeIdentifiers/UTType.swift +196 -0
  389. package/Sources/UserNotifications/Content.swift +370 -0
  390. package/Sources/UserNotifications/NotificationCenter.swift +309 -0
  391. package/Sources/WeatherKit/WeatherKit.swift +228 -0
  392. package/Sources/WebKit/WebKit.swift +245 -0
  393. package/Sources/os/os.swift +376 -0
  394. package/Sources/zlib/zlib.swift +6 -0
  395. package/index.d.ts +2 -0
  396. package/index.mjs +16 -0
  397. package/manifest.d.mts +2 -0
  398. package/manifest.mjs +39 -0
  399. package/package.json +30 -4
  400. package/sync-sources.mjs +33 -0
@@ -0,0 +1,386 @@
1
+ // `Text`: a string, or styled runs of strings and images.
2
+ //
3
+ // A `Text` is a list of segments, each with its own style. `Text + Text`
4
+ // joins segments; the modifiers that return `Text` (`bold()`, `italic()`,
5
+ // `font(_:)`, `foregroundColor(_:)`, `strikethrough()`, `underline()`,
6
+ // `kerning(_:)`, `baselineOffset(_:)`…) style every segment, and the style a
7
+ // segment already has wins (as in SwiftUI, an inner modifier overrides an
8
+ // outer one). An image interpolated into a `LocalizedStringKey`
9
+ // (`Text("\(Image(systemName: "star")) Favorites")`) is a segment of its own.
10
+ //
11
+ // What reaches the page depends on what the text needs:
12
+ //
13
+ // - A single string styled only by `font`, `fontWeight`, `bold` and the
14
+ // foreground is the `text` element it always was, inside the same `styled`
15
+ // elements the View modifiers make (so existing apps render unchanged).
16
+ // - Anything else (several segments, images, links, italic, strikethrough,
17
+ // underline, kerning, baseline offsets) is one `text` element whose `runs`
18
+ // prop lists each segment with its style; the page lays the runs out as one
19
+ // paragraph (docs/ops-protocol.md, "Rich text").
20
+ //
21
+ // A run with a link sends a `link` event when tapped; the environment's link
22
+ // handler opens it (FoundationBridge's `openURL` sets it).
23
+
24
+ import Foundation
25
+
26
+ public struct Text: Equatable, Sendable {
27
+ /// The whole text as a string (images contribute nothing).
28
+ let content: String
29
+ let segments: [_TextSegment]
30
+ /// The modifiers applied to the whole text, in order, while it is one
31
+ /// plain string: they become the View modifiers they always were.
32
+ let applied: [_TextModifier]
33
+
34
+ init(segments: [_TextSegment], applied: [_TextModifier] = []) {
35
+ self.segments = segments
36
+ self.applied = applied
37
+ content = segments.map { if case .string(let s) = $0.content { s } else { "" } }.joined()
38
+ }
39
+
40
+ public init(verbatim content: String) {
41
+ self.init(segments: [_TextSegment(content: .string(content))])
42
+ }
43
+
44
+ public init(_ key: LocalizedStringKey) {
45
+ self.init(segments: key.segments)
46
+ }
47
+
48
+ /// A key from a table other than `Localizable`, or another bundle's
49
+ /// (FoundationBridge's `Text(_:tableName:bundle:comment:)` passes its path).
50
+ public init(_ key: LocalizedStringKey, _table table: String?, bundlePath: String?) {
51
+ self.init(segments: key._segments(table: table, bundlePath: bundlePath))
52
+ }
53
+
54
+ @_disfavoredOverload
55
+ public init<S: StringProtocol>(_ content: S) {
56
+ self.init(verbatim: String(content))
57
+ }
58
+
59
+ /// `Text(price, format: .currency(code: "USD"))`, `Text(date, format: .dateTime.year())`.
60
+ public init<F: FormatStyle>(_ input: F.FormatInput, format: F) where F.FormatOutput == String {
61
+ self.init(verbatim: format.format(input))
62
+ }
63
+
64
+ /// An image inline in text (`Text(Image(systemName: "star"))`).
65
+ public init(_ image: Image) {
66
+ self.init(segments: [_TextSegment(content: .image(image))])
67
+ }
68
+
69
+ /// The text as a string, for bridge modules (a `prompt` becomes a placeholder).
70
+ public var _content: String { content }
71
+
72
+ public static func + (lhs: Text, rhs: Text) -> Text {
73
+ Text(segments: lhs.segments + rhs.segments)
74
+ }
75
+
76
+ /// Whether the page gets the plain `text` element the shim has always made.
77
+ var isPlain: Bool {
78
+ guard segments.count == 1, case .string = segments[0].content else { return false }
79
+ return applied.allSatisfy(\.isLegacy) && segments[0].style.isLegacyOnly
80
+ }
81
+
82
+ /// Applies `modifier` to every segment where it is not set yet.
83
+ func modified(_ modifier: _TextModifier) -> Text {
84
+ Text(segments: segments.map { segment in
85
+ var segment = segment
86
+ modifier.apply(to: &segment.style)
87
+ return segment
88
+ }, applied: applied + [modifier])
89
+ }
90
+
91
+ // MARK: Styling
92
+
93
+ public func font(_ font: Font?) -> Text { modified(.font(font)) }
94
+ public func fontWeight(_ weight: Font.Weight?) -> Text { modified(.weight(weight)) }
95
+ public func bold() -> Text { modified(.weight(.bold)) }
96
+ public func bold(_ isActive: Bool) -> Text { isActive ? bold() : self }
97
+ public func italic() -> Text { modified(.italic) }
98
+ public func italic(_ isActive: Bool) -> Text { isActive ? italic() : self }
99
+ public func monospaced(_ isActive: Bool = true) -> Text { isActive ? modified(.monospaced) : self }
100
+ public func monospacedDigit() -> Text { self }
101
+ public func fontDesign(_ design: Font.Design?) -> Text { design == .monospaced ? modified(.monospaced) : self }
102
+ public func fontWidth(_ width: Font.Width?) -> Text { self }
103
+ public func foregroundColor(_ color: Color?) -> Text { modified(.foreground(color?._json)) }
104
+ public func foregroundStyle<S: ShapeStyle>(_ style: S) -> Text { modified(.foreground(style._json)) }
105
+ public func strikethrough(_ isActive: Bool = true, color: Color? = nil) -> Text {
106
+ isActive ? modified(.strikethrough(color?._json ?? .null)) : self
107
+ }
108
+ public func strikethrough(_ isActive: Bool = true, pattern: Text.LineStyle.Pattern, color: Color? = nil) -> Text {
109
+ strikethrough(isActive, color: color)
110
+ }
111
+ public func underline(_ isActive: Bool = true, color: Color? = nil) -> Text {
112
+ isActive ? modified(.underline(color?._json ?? .null)) : self
113
+ }
114
+ public func underline(_ isActive: Bool = true, pattern: Text.LineStyle.Pattern, color: Color? = nil) -> Text {
115
+ underline(isActive, color: color)
116
+ }
117
+ public func kerning(_ kerning: CGFloat) -> Text { modified(.kerning(kerning)) }
118
+ public func tracking(_ tracking: CGFloat) -> Text { modified(.kerning(tracking)) }
119
+ public func baselineOffset(_ offset: CGFloat) -> Text { modified(.baselineOffset(offset)) }
120
+ public func textScale(_ scale: Text.Scale, isEnabled: Bool = true) -> Text { self }
121
+ public func speechSpellsOutCharacters(_ value: Bool = true) -> Text { self }
122
+ public func accessibilityLabel(_ label: Text) -> Text { self }
123
+ @_disfavoredOverload
124
+ public func accessibilityLabel<S: StringProtocol>(_ label: S) -> Text { self }
125
+ public func accessibilityLabel(_ labelKey: LocalizedStringKey) -> Text { self }
126
+
127
+ /// The segments open `url` when tapped (Foundation's `Text(AttributedString)` uses it).
128
+ public func _link(_ url: String) -> Text { modified(.link(url)) }
129
+
130
+ public struct LineStyle: Hashable, Sendable {
131
+ public struct Pattern: Hashable, Sendable {
132
+ let name: String
133
+ public static let solid = Pattern(name: "solid")
134
+ public static let dot = Pattern(name: "dot")
135
+ public static let dash = Pattern(name: "dash")
136
+ public static let dashDot = Pattern(name: "dashDot")
137
+ public static let dashDotDot = Pattern(name: "dashDotDot")
138
+ }
139
+ public init(pattern: Pattern = .solid, color: Color? = nil) {}
140
+ public static let single = LineStyle()
141
+ }
142
+
143
+ public enum Scale: Hashable, Sendable { case `default`, secondary }
144
+
145
+ public enum Case: Hashable, Sendable { case uppercase, lowercase }
146
+
147
+ public enum TruncationMode: Hashable, Sendable { case head, tail, middle }
148
+ }
149
+
150
+ extension Font {
151
+ public struct Width: Hashable, Sendable {
152
+ let value: CGFloat
153
+ public init(_ value: CGFloat) { self.value = value }
154
+ public static let compressed = Width(-0.3)
155
+ public static let condensed = Width(-0.2)
156
+ public static let standard = Width(0)
157
+ public static let expanded = Width(0.2)
158
+ }
159
+ }
160
+
161
+ /// One stretch of a `Text`: a string or an image, with its style.
162
+ struct _TextSegment: Equatable, Sendable {
163
+ enum Content: Equatable, Sendable {
164
+ case string(String)
165
+ case image(Image)
166
+ }
167
+
168
+ var content: Content
169
+ var style = _TextStyle()
170
+ }
171
+
172
+ /// The style of a segment; nil fields are unset (an outer modifier may set them).
173
+ struct _TextStyle: Equatable, Sendable {
174
+ var font: Font?
175
+ var weight: Font.Weight?
176
+ var italic = false
177
+ var monospaced = false
178
+ var foreground: _JSON?
179
+ /// The line's color, `.null` for the text's own.
180
+ var strikethrough: _JSON?
181
+ var underline: _JSON?
182
+ var kerning: CGFloat?
183
+ var baselineOffset: CGFloat?
184
+ var link: String?
185
+
186
+ /// Only what the View modifiers express (font, weight, foreground).
187
+ var isLegacyOnly: Bool {
188
+ !italic && !monospaced && strikethrough == nil && underline == nil && kerning == nil && baselineOffset == nil && link == nil
189
+ }
190
+
191
+ /// The run's style as the page reads it.
192
+ var json: [String: _JSON] {
193
+ var object: [String: _JSON] = [:]
194
+ if font != nil || weight != nil || monospaced {
195
+ var resolved = font ?? Font(size: nil, weight: nil, design: nil)
196
+ if let weight { resolved.weight = weight }
197
+ if monospaced { resolved.design = .monospaced }
198
+ object["font"] = resolved._json
199
+ }
200
+ if italic { object["italic"] = .bool(true) }
201
+ if let foreground { object["foreground"] = foreground }
202
+ if let strikethrough { object["strikethrough"] = .object(strikethrough == .null ? [:] : ["color": strikethrough]) }
203
+ if let underline { object["underline"] = .object(underline == .null ? [:] : ["color": underline]) }
204
+ if let kerning { object["kerning"] = .number(kerning) }
205
+ if let baselineOffset { object["baselineOffset"] = .number(baselineOffset) }
206
+ if let link { object["link"] = .string(link) }
207
+ return object
208
+ }
209
+ }
210
+
211
+ /// A modifier that returns `Text`, kept to style later segments and, for a
212
+ /// plain text, to become the View modifier it always was.
213
+ enum _TextModifier: Equatable, Sendable {
214
+ case font(Font?)
215
+ case weight(Font.Weight?)
216
+ case italic
217
+ case monospaced
218
+ case foreground(_JSON?)
219
+ case strikethrough(_JSON)
220
+ case underline(_JSON)
221
+ case kerning(CGFloat)
222
+ case baselineOffset(CGFloat)
223
+ case link(String)
224
+
225
+ var isLegacy: Bool {
226
+ switch self {
227
+ case .font, .weight, .foreground: true
228
+ default: false
229
+ }
230
+ }
231
+
232
+ func apply(to style: inout _TextStyle) {
233
+ switch self {
234
+ case .font(let font): if style.font == nil { style.font = font }
235
+ case .weight(let weight): if style.weight == nil { style.weight = weight }
236
+ case .italic: style.italic = true
237
+ case .monospaced: style.monospaced = true
238
+ case .foreground(let paint): if style.foreground == nil { style.foreground = paint }
239
+ case .strikethrough(let color): if style.strikethrough == nil { style.strikethrough = color }
240
+ case .underline(let color): if style.underline == nil { style.underline = color }
241
+ case .kerning(let value): if style.kerning == nil { style.kerning = value }
242
+ case .baselineOffset(let value): if style.baselineOffset == nil { style.baselineOffset = value }
243
+ case .link(let url): if style.link == nil { style.link = url }
244
+ }
245
+ }
246
+ }
247
+
248
+ extension Text: _PrimitiveView {}
249
+ extension Text: _GroupView {
250
+ var _children: [any View] {
251
+ guard isPlain, case .string(let string) = segments[0].content else { return [_RichText(text: self)] }
252
+ var view: any View = _PlainText(content: string)
253
+ for modifier in applied {
254
+ switch modifier {
255
+ case .font(let font): view = _restyle(view) { $0.font = font }
256
+ case .weight(let weight): view = _restyle(view) { $0.font = weight.map { Font(size: nil, weight: $0, design: nil) } }
257
+ case .foreground(let paint): view = _restyle(view) { $0.foreground = paint.map(_JSONShapeStyle.init) }
258
+ default: break
259
+ }
260
+ }
261
+ return [view]
262
+ }
263
+ }
264
+
265
+ /// `view` in a `styled` element, as the View modifiers wrap it.
266
+ private func _restyle(_ view: any View, _ change: (inout _Style) -> Void) -> any View {
267
+ var style = _Style()
268
+ change(&style)
269
+ func open<V: View>(_ view: V) -> any View { _StyledGroup(content: view, style: style) }
270
+ return open(view)
271
+ }
272
+
273
+ /// A paint the page already has as JSON (a `Text`'s foreground).
274
+ struct _JSONShapeStyle: ShapeStyle {
275
+ let json: _JSON
276
+ init(_ json: _JSON) { self.json = json }
277
+ var _json: _JSON { json }
278
+ }
279
+
280
+ /// The page's `text` element for a plain string.
281
+ struct _PlainText: Equatable, Sendable {
282
+ let content: String
283
+ }
284
+ extension _PlainText: _PrimitiveView {}
285
+ extension _PlainText: _HostView {
286
+ var _kind: String { "text" }
287
+ func _props(in environment: EnvironmentValues) -> _JSON {
288
+ .object(["text": .string(environment.textCase?.apply(to: content) ?? content)])
289
+ }
290
+ }
291
+
292
+ /// The page's `text` element with runs.
293
+ struct _RichText: Equatable, Sendable {
294
+ let text: Text
295
+
296
+ var hasLinks: Bool { text.segments.contains { $0.style.link != nil } }
297
+
298
+ /// Sends inline bitmaps' sources to the page before the element.
299
+ @MainActor func _sendBitmapSources(through runtime: _Runtime) {
300
+ for segment in text.segments {
301
+ if case .image(let image) = segment.content { image._sendBitmapSource(through: runtime) }
302
+ }
303
+ }
304
+ }
305
+ extension _RichText: _PrimitiveView {}
306
+ extension _RichText: _HostView {
307
+ var _kind: String { "text" }
308
+ func _props(in environment: EnvironmentValues) -> _JSON {
309
+ let runs: [_JSON] = text.segments.map { segment in
310
+ var run = segment.style.json
311
+ switch segment.content {
312
+ case .string(let string): run["text"] = .string(environment.textCase?.apply(to: string) ?? string)
313
+ case .image(let image): run["image"] = image._props(in: environment)
314
+ }
315
+ return .object(run)
316
+ }
317
+ let content = environment.textCase?.apply(to: text.content) ?? text.content
318
+ return .object(["text": .string(content), "runs": .array(runs)])
319
+ }
320
+ }
321
+ extension _RichText: _EnvironmentHandling {
322
+ /// A tap on a link run: the page sends its URL.
323
+ func _handler(in environment: EnvironmentValues) -> ((_JSON) -> Void)? {
324
+ guard hasLinks else { return nil }
325
+ let open = environment._openLink
326
+ return { payload in
327
+ guard case .string(let url) = payload else { return }
328
+ MainActor.assumeIsolated { (open ?? _Runtime.shared._openLinkOnPage)(url) }
329
+ }
330
+ }
331
+ }
332
+
333
+ // MARK: - Interpolated text
334
+
335
+ extension LocalizedStringKey {
336
+ /// The localized text as segments: its strings, and the images and texts
337
+ /// interpolated into it, where the localized format puts them.
338
+ var segments: [_TextSegment] { _segments(table: nil, bundlePath: nil) }
339
+
340
+ func _segments(table: String?, bundlePath: String?) -> [_TextSegment] {
341
+ var out: [_TextSegment] = []
342
+ for piece in _pieces(table: table, bundlePath: bundlePath) {
343
+ switch piece {
344
+ case .text(let string):
345
+ if case .string(let previous)? = out.last?.content, out.last?.style == _TextStyle() {
346
+ out[out.count - 1].content = .string(previous + string)
347
+ } else {
348
+ out.append(_TextSegment(content: .string(string)))
349
+ }
350
+ case .argument(let index):
351
+ guard index < arguments.count else { continue }
352
+ switch arguments[index] {
353
+ case .image(let image): out.append(_TextSegment(content: .image(image)))
354
+ case .text(let text): out += text.segments
355
+ case .value: continue
356
+ }
357
+ }
358
+ }
359
+ if out.isEmpty { out.append(_TextSegment(content: .string(""))) }
360
+ return out
361
+ }
362
+ }
363
+
364
+ // MARK: - Links
365
+
366
+ private struct _OpenLinkKey: EnvironmentKey {
367
+ static var defaultValue: (@MainActor @Sendable (String) -> Void)? { nil }
368
+ }
369
+
370
+ extension EnvironmentValues {
371
+ /// What a tap on a link in a `Text` calls; FoundationBridge's `openURL`
372
+ /// sets it. Without one, the page opens the link.
373
+ public var _openLink: (@MainActor @Sendable (String) -> Void)? {
374
+ get { self[_OpenLinkKey.self] }
375
+ set { self[_OpenLinkKey.self] = newValue }
376
+ }
377
+ }
378
+
379
+ extension _Runtime {
380
+ /// Asks the page to open `url` (in a new tab; headless runs log the request).
381
+ public func _openLinkOnPage(_ url: String) {
382
+ Task { @MainActor in
383
+ _ = try? await _hostRequest(kind: "openURL", params: .object(["url": .string(url)]))
384
+ }
385
+ }
386
+ }
@@ -0,0 +1,61 @@
1
+ import Foundation
2
+
3
+ // `Text(date, style:)` and `Text(range)` / `Text(interval)`. The date is
4
+ // formatted when the view's body runs, in the viewer's locale, and the text
5
+ // does not update by itself afterwards (on iOS `.relative`, `.offset` and
6
+ // `.timer` count live): an approximation that is exact for `.date` and
7
+ // `.time`, and right until the next render for the others.
8
+
9
+ extension Text {
10
+ public struct DateStyle: Hashable, Sendable {
11
+ let name: String
12
+ /// "June 3, 2024".
13
+ public static let date = DateStyle(name: "date")
14
+ /// "3:04 PM".
15
+ public static let time = DateStyle(name: "time")
16
+ /// "2 hr, 5 min" (from now, either direction).
17
+ public static let relative = DateStyle(name: "relative")
18
+ /// "+2 hr, 5 min" / "-2 hr, 5 min".
19
+ public static let offset = DateStyle(name: "offset")
20
+ /// "2:05:00", the time from or since the date.
21
+ public static let timer = DateStyle(name: "timer")
22
+ }
23
+
24
+ public init(_ date: Date, style: DateStyle) {
25
+ self.init(verbatim: Text._format(date, style: style, now: Date()))
26
+ }
27
+
28
+ public init(_ dates: ClosedRange<Date>) {
29
+ let format = Date.FormatStyle(date: .abbreviated, time: .shortened)
30
+ self.init(verbatim: "\(dates.lowerBound.formatted(format)) – \(dates.upperBound.formatted(format))")
31
+ }
32
+
33
+ public init(_ interval: DateInterval) {
34
+ self.init(interval.start...interval.end)
35
+ }
36
+
37
+ static func _format(_ date: Date, style: DateStyle, now: Date) -> String {
38
+ switch style.name {
39
+ case "date":
40
+ return date.formatted(date: .long, time: .omitted)
41
+ case "time":
42
+ return date.formatted(date: .omitted, time: .shortened)
43
+ case "relative", "offset":
44
+ let seconds = Int(abs(date.timeIntervalSince(now)).rounded())
45
+ let hours = seconds / 3600, minutes = seconds % 3600 / 60, rest = seconds % 60
46
+ var parts: [String] = []
47
+ if hours > 0 { parts.append("\(hours) hr") }
48
+ if minutes > 0 { parts.append("\(minutes) min") }
49
+ if hours == 0 && (rest > 0 || parts.isEmpty) { parts.append("\(rest) sec") }
50
+ let amount = parts.prefix(2).joined(separator: ", ")
51
+ if style.name == "relative" { return amount }
52
+ return (date >= now ? "+" : "-") + amount
53
+ default:
54
+ let seconds = Int(abs(date.timeIntervalSince(now)))
55
+ let hours = seconds / 3600, minutes = seconds % 3600 / 60, rest = seconds % 60
56
+ let mm = minutes < 10 && hours > 0 ? "0\(minutes)" : "\(minutes)"
57
+ let ss = rest < 10 ? "0\(rest)" : "\(rest)"
58
+ return hours > 0 ? "\(hours):\(mm):\(ss)" : "\(mm):\(ss)"
59
+ }
60
+ }
61
+ }
@@ -0,0 +1,52 @@
1
+ /// Text modifiers on any view (iOS 16): `.underline()`, `.strikethrough()`
2
+ /// and `.italic()` style every text inside. Each is a style key of a `styled`
3
+ /// box (`underline`, `strikethrough`, `italic`: true, or false to turn it off
4
+ /// below an ancestor that set it), which the page passes down to the texts
5
+ /// below through inherited CSS (Web/src/renderer.ts `applyStyle`). The line
6
+ /// takes the text's color: `pattern` and `color` are not drawn. Italic text is
7
+ /// measured upright.
8
+ ///
9
+ /// `.fontDesign` and `.monospaced` set the design of the fonts inside, as
10
+ /// `.fontWeight` sets their weight. `.monospacedDigit`, `.fontWidth`,
11
+ /// `.minimumScaleFactor` and `.allowsTightening` are accepted: digits keep the
12
+ /// font's own widths, and the page wraps or truncates text at its size
13
+ /// instead of shrinking it.
14
+
15
+ nonisolated extension View {
16
+ /// Underlines the texts inside.
17
+ public func underline(_ isActive: Bool = true, pattern: Text.LineStyle.Pattern = .solid, color: Color? = nil) -> some View {
18
+ _styled { $0.extras["underline"] = .bool(isActive) }
19
+ }
20
+
21
+ /// Strikes the texts inside through.
22
+ public func strikethrough(_ isActive: Bool = true, pattern: Text.LineStyle.Pattern = .solid, color: Color? = nil) -> some View {
23
+ _styled { $0.extras["strikethrough"] = .bool(isActive) }
24
+ }
25
+
26
+ /// Slants the texts inside.
27
+ public func italic(_ isActive: Bool = true) -> some View {
28
+ _styled { $0.extras["italic"] = .bool(isActive) }
29
+ }
30
+
31
+ /// The design of the fonts inside (nil leaves it as it is).
32
+ public func fontDesign(_ design: Font.Design?) -> some View {
33
+ _styled { $0.font = design.map { Font(size: nil, weight: nil, design: $0) } }
34
+ }
35
+
36
+ /// Monospaced fonts inside.
37
+ public func monospaced(_ isActive: Bool = true) -> some View {
38
+ _styled { $0.font = isActive ? Font(size: nil, weight: nil, design: .monospaced) : nil }
39
+ }
40
+
41
+ /// Accepted: digits keep their proportional widths.
42
+ public func monospacedDigit() -> some View { self }
43
+
44
+ /// Accepted: the page has one width of each font.
45
+ public func fontWidth(_ width: Font.Width?) -> some View { self }
46
+
47
+ /// Accepted: text is not shrunk to fit.
48
+ public func minimumScaleFactor(_ factor: CGFloat) -> some View { self }
49
+
50
+ /// Accepted: letter spacing is not tightened to fit.
51
+ public func allowsTightening(_ flag: Bool) -> some View { self }
52
+ }
@@ -0,0 +1,103 @@
1
+ // Multi-line text fields (`TextField(_:text:axis: .vertical)`), line-limit
2
+ // ranges, and `.textCase(_:)`.
3
+ //
4
+ // A vertical field is the `textfield` element with `"axis": "vertical"`:
5
+ // the page draws a `<textarea>` that grows with its text from the lower
6
+ // bound of the enclosing line-limit range to its upper bound (one line to
7
+ // unlimited by default) and scrolls inside past that. Typing sends `text`
8
+ // events as for a one-line field; Return inserts a line break, except in a
9
+ // field with `.onSubmit`, where Return submits and Shift-Return breaks the
10
+ // line (iOS has no Shift, and submits).
11
+ //
12
+ // `.lineLimit(2...4)` / `.lineLimit(...4)` / `.lineLimit(2...)` set the
13
+ // style's `lineLimit` to the upper bound (null for none) and, when the lower
14
+ // bound is above one, `lineLimitMin`. Text takes the lines it needs up to the
15
+ // upper bound (as with `reservesSpace`, the lower bound reserves nothing for
16
+ // text); a vertical field is at least `lineLimitMin` lines tall.
17
+
18
+ extension TextField where Label == Text {
19
+ @_disfavoredOverload
20
+ public init<S: StringProtocol>(_ title: S, text: Binding<String>, axis: Axis) {
21
+ self.init(placeholder: String(title), text: text, secure: false)
22
+ self.axis = axis
23
+ }
24
+
25
+ @_disfavoredOverload
26
+ public init<S: StringProtocol>(_ title: S, text: Binding<String>, prompt: Text?, axis: Axis) {
27
+ self.init(placeholder: prompt?.content ?? String(title), text: text, secure: false)
28
+ self.axis = axis
29
+ }
30
+
31
+ public init(_ titleKey: LocalizedStringKey, text: Binding<String>, axis: Axis) {
32
+ self.init(placeholder: titleKey.key, text: text, secure: false)
33
+ self.axis = axis
34
+ }
35
+
36
+ public init(_ titleKey: LocalizedStringKey, text: Binding<String>, prompt: Text?, axis: Axis) {
37
+ self.init(placeholder: prompt?.content ?? titleKey.key, text: text, secure: false)
38
+ self.axis = axis
39
+ }
40
+ }
41
+
42
+ extension TextField {
43
+ /// A field labelled by a view: the prompt (or else the label's text) is the placeholder.
44
+ @MainActor
45
+ public init(text: Binding<String>, prompt: Text? = nil, axis: Axis, @ViewBuilder label: () -> Label) {
46
+ self.init(placeholder: prompt?.content ?? _textContent(of: label()), text: text, secure: false)
47
+ self.axis = axis
48
+ }
49
+ }
50
+
51
+ nonisolated extension View {
52
+ /// Text takes up to `limit.upperBound` lines; a vertical text field is
53
+ /// `limit.lowerBound` to `limit.upperBound` lines tall.
54
+ public func lineLimit(_ limit: ClosedRange<Int>) -> some View {
55
+ _lineLimit(min: limit.lowerBound, max: limit.upperBound)
56
+ }
57
+
58
+ public func lineLimit(_ limit: PartialRangeThrough<Int>) -> some View {
59
+ _lineLimit(min: 1, max: limit.upperBound)
60
+ }
61
+
62
+ public func lineLimit(_ limit: PartialRangeFrom<Int>) -> some View {
63
+ _lineLimit(min: limit.lowerBound, max: nil)
64
+ }
65
+
66
+ func _lineLimit(min: Int, max: Int?) -> some View {
67
+ _styled { style in
68
+ style.lineLimit = max ?? -1
69
+ if min > 1 { style.extras["lineLimitMin"] = .number(Double(min)) }
70
+ }
71
+ }
72
+ }
73
+
74
+ // MARK: - textCase
75
+
76
+ enum _TextCaseKey: EnvironmentKey { static let defaultValue: Text.Case? = nil }
77
+
78
+ extension EnvironmentValues {
79
+ /// `.textCase(_:)`: texts below are upper- or lower-cased when emitted
80
+ /// (so the page measures and draws the cased string); nil leaves them.
81
+ public var textCase: Text.Case? {
82
+ get { self[_TextCaseKey.self] }
83
+ set { self[_TextCaseKey.self] = newValue }
84
+ }
85
+ }
86
+
87
+ nonisolated extension View {
88
+ /// Upper- or lower-cases the texts in this view (`nil`: as written, which
89
+ /// also undoes the upper case of a list section header).
90
+ public func textCase(_ textCase: Text.Case?) -> some View {
91
+ environment(\.textCase, textCase)
92
+ }
93
+ }
94
+
95
+ extension Text.Case {
96
+ /// `string` in this case.
97
+ func apply(to string: String) -> String {
98
+ switch self {
99
+ case .uppercase: string.uppercased()
100
+ case .lowercase: string.lowercased()
101
+ }
102
+ }
103
+ }
@@ -0,0 +1,52 @@
1
+ /// iOS 13's text field initializers with `onEditingChanged:` and `onCommit:`.
2
+ /// `onCommit` runs when the viewer presses Return, as `.onSubmit` does (the
3
+ /// field asks the page for submit events). `onEditingChanged` is accepted and
4
+ /// not called: use `.focused` to follow editing.
5
+ extension TextField where Label == Text {
6
+ public init(_ titleKey: LocalizedStringKey, text: Binding<String>,
7
+ onEditingChanged: @escaping (Bool) -> Void = { _ in }, onCommit: @escaping () -> Void) {
8
+ self.init(placeholder: titleKey.key, text: text, secure: false)
9
+ self.onCommit = onCommit
10
+ }
11
+
12
+ @_disfavoredOverload
13
+ public init<S: StringProtocol>(_ title: S, text: Binding<String>,
14
+ onEditingChanged: @escaping (Bool) -> Void = { _ in }, onCommit: @escaping () -> Void) {
15
+ self.init(placeholder: String(title), text: text, secure: false)
16
+ self.onCommit = onCommit
17
+ }
18
+ }
19
+
20
+ extension Menu where Label == Text {
21
+ /// A menu titled with a localized key (the key's text: no string tables are loaded).
22
+ public init(_ titleKey: LocalizedStringKey, @ViewBuilder content: () -> Content) {
23
+ self.init(content: content) { Text(titleKey) }
24
+ }
25
+ }
26
+
27
+ extension Menu where Label == SwiftUI.Label<Text, Image> {
28
+ public init(_ titleKey: LocalizedStringKey, systemImage: String, @ViewBuilder content: () -> Content) {
29
+ self.init(content: content) { SwiftUI.Label(titleKey, systemImage: systemImage) }
30
+ }
31
+ }
32
+
33
+ nonisolated extension View {
34
+ /// Search with a binding to whether the field is active. The page's
35
+ /// search field is always shown: `isPresented` is not changed by the
36
+ /// viewer (approximation).
37
+ public func searchable(text: Binding<String>, isPresented: Binding<Bool>, placement: SearchFieldPlacement = .automatic,
38
+ prompt: Text? = nil) -> some View {
39
+ searchable(text: text, placement: placement, prompt: prompt)
40
+ }
41
+
42
+ public func searchable(text: Binding<String>, isPresented: Binding<Bool>, placement: SearchFieldPlacement = .automatic,
43
+ prompt: LocalizedStringKey) -> some View {
44
+ searchable(text: text, placement: placement, prompt: prompt)
45
+ }
46
+
47
+ @_disfavoredOverload
48
+ public func searchable<S: StringProtocol>(text: Binding<String>, isPresented: Binding<Bool>,
49
+ placement: SearchFieldPlacement = .automatic, prompt: S) -> some View {
50
+ searchable(text: text, placement: placement, prompt: prompt)
51
+ }
52
+ }