@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.
- package/Package.swift +200 -9
- package/README.md +7 -9
- package/Sources/AVFoundation/AVFoundation.swift +131 -0
- package/Sources/AVFoundation/Asset.swift +487 -0
- package/Sources/AVFoundation/AudioSession.swift +144 -0
- package/Sources/AVFoundation/CMTime.swift +303 -0
- package/Sources/AVFoundation/Capture.swift +688 -0
- package/Sources/AVFoundation/Player.swift +749 -0
- package/Sources/AVFoundation/PlayerView.swift +117 -0
- package/Sources/AVKit/AVKit.swift +132 -0
- package/Sources/Accelerate/Accelerate.swift +122 -0
- package/Sources/AppIntents/AppIntents.swift +144 -0
- package/Sources/AppIntents/Parameters.swift +220 -0
- package/Sources/AppIntents/Shortcuts.swift +159 -0
- package/Sources/AudioToolbox/AudioToolbox.swift +55 -0
- package/Sources/AuthenticationServices/AuthenticationServices.swift +257 -0
- package/Sources/AuthenticationServices/Authorization.swift +251 -0
- package/Sources/Charts/Charts.swift +0 -4
- package/Sources/Combine/AnyCancellable.swift +65 -0
- package/Sources/Combine/AnyPublisher.swift +148 -0
- package/Sources/Combine/AnySubscriber.swift +230 -0
- package/Sources/Combine/Cancellable.swift +35 -0
- package/Sources/Combine/Codable.swift +29 -0
- package/Sources/Combine/CombineIdentifier.swift +45 -0
- package/Sources/Combine/Concurrency/ConcurrencyHelpers.swift +24 -0
- package/Sources/Combine/Concurrency/Future+Concurrency.swift +136 -0
- package/Sources/Combine/Concurrency/GENERATED-Publisher+Concurrency.swift +397 -0
- package/Sources/Combine/CurrentValueSubject.swift +252 -0
- package/Sources/Combine/CustomCombineIdentifierConvertible.swift +28 -0
- package/Sources/Combine/Future.swift +228 -0
- package/Sources/Combine/GENERATED-RootProtocols.swift +426 -0
- package/Sources/Combine/Helpers/ConduitBase.swift +40 -0
- package/Sources/Combine/Helpers/ConduitList.swift +59 -0
- package/Sources/Combine/Helpers/DebugHook.swift +177 -0
- package/Sources/Combine/Helpers/FilterProducer.swift +174 -0
- package/Sources/Combine/Helpers/Locking.swift +30 -0
- package/Sources/Combine/Helpers/PartialCompletion.swift +26 -0
- package/Sources/Combine/Helpers/ReduceProducer.swift +249 -0
- package/Sources/Combine/Helpers/SubjectSubscriber.swift +96 -0
- package/Sources/Combine/Helpers/SubscriberTap.swift +69 -0
- package/Sources/Combine/Helpers/SubscriptionStatus.swift +33 -0
- package/Sources/Combine/Helpers/SubscriptionTap.swift +33 -0
- package/Sources/Combine/Helpers/Utils.swift +30 -0
- package/Sources/Combine/Helpers/Violations.swift +33 -0
- package/Sources/Combine/ImmediateScheduler.swift +178 -0
- package/Sources/Combine/LICENSE +21 -0
- package/Sources/Combine/NotificationPublisher.swift +48 -0
- package/Sources/Combine/ObjectWillChange.swift +46 -0
- package/Sources/Combine/PassthroughSubject.swift +222 -0
- package/Sources/Combine/Publisher+Subscribe.swift +53 -0
- package/Sources/Combine/Publishers/Deferred.swift +48 -0
- package/Sources/Combine/Publishers/Empty.swift +54 -0
- package/Sources/Combine/Publishers/Fail.swift +42 -0
- package/Sources/Combine/Publishers/GENERATED-Publishers.Catch.swift +673 -0
- package/Sources/Combine/Publishers/GENERATED-Publishers.Encode.swift +388 -0
- package/Sources/Combine/Publishers/GENERATED-Publishers.MapKeyPath.swift +384 -0
- package/Sources/Combine/Publishers/Just.swift +313 -0
- package/Sources/Combine/Publishers/Optional.Publisher.swift +315 -0
- package/Sources/Combine/Publishers/Publishers.AllSatisfy.swift +217 -0
- package/Sources/Combine/Publishers/Publishers.AssertNoFailure.swift +158 -0
- package/Sources/Combine/Publishers/Publishers.Autoconnect.swift +193 -0
- package/Sources/Combine/Publishers/Publishers.Breakpoint.swift +231 -0
- package/Sources/Combine/Publishers/Publishers.Buffer.swift +356 -0
- package/Sources/Combine/Publishers/Publishers.Collect.swift +102 -0
- package/Sources/Combine/Publishers/Publishers.CollectByCount.swift +195 -0
- package/Sources/Combine/Publishers/Publishers.CompactMap.swift +241 -0
- package/Sources/Combine/Publishers/Publishers.Comparison.swift +371 -0
- package/Sources/Combine/Publishers/Publishers.Concatenate.swift +474 -0
- package/Sources/Combine/Publishers/Publishers.Contains.swift +293 -0
- package/Sources/Combine/Publishers/Publishers.Count.swift +87 -0
- package/Sources/Combine/Publishers/Publishers.Debounce.swift +332 -0
- package/Sources/Combine/Publishers/Publishers.Delay.swift +269 -0
- package/Sources/Combine/Publishers/Publishers.Drop.swift +155 -0
- package/Sources/Combine/Publishers/Publishers.DropUntilOutput.swift +283 -0
- package/Sources/Combine/Publishers/Publishers.DropWhile.swift +378 -0
- package/Sources/Combine/Publishers/Publishers.Filter.swift +248 -0
- package/Sources/Combine/Publishers/Publishers.First.swift +261 -0
- package/Sources/Combine/Publishers/Publishers.FlatMap.swift +533 -0
- package/Sources/Combine/Publishers/Publishers.HandleEvents.swift +260 -0
- package/Sources/Combine/Publishers/Publishers.IgnoreOutput.swift +109 -0
- package/Sources/Combine/Publishers/Publishers.Last.swift +252 -0
- package/Sources/Combine/Publishers/Publishers.MakeConnectable.swift +82 -0
- package/Sources/Combine/Publishers/Publishers.Map.swift +351 -0
- package/Sources/Combine/Publishers/Publishers.MapError.swift +140 -0
- package/Sources/Combine/Publishers/Publishers.MeasureInterval.swift +187 -0
- package/Sources/Combine/Publishers/Publishers.Multicast.swift +284 -0
- package/Sources/Combine/Publishers/Publishers.Output.swift +241 -0
- package/Sources/Combine/Publishers/Publishers.PrefixUntilOutput.swift +197 -0
- package/Sources/Combine/Publishers/Publishers.PrefixWhile.swift +176 -0
- package/Sources/Combine/Publishers/Publishers.Print.swift +206 -0
- package/Sources/Combine/Publishers/Publishers.ReceiveOn.swift +227 -0
- package/Sources/Combine/Publishers/Publishers.Reduce.swift +204 -0
- package/Sources/Combine/Publishers/Publishers.RemoveDuplicates.swift +264 -0
- package/Sources/Combine/Publishers/Publishers.ReplaceEmpty.swift +201 -0
- package/Sources/Combine/Publishers/Publishers.ReplaceError.swift +211 -0
- package/Sources/Combine/Publishers/Publishers.Retry.swift +274 -0
- package/Sources/Combine/Publishers/Publishers.Scan.swift +331 -0
- package/Sources/Combine/Publishers/Publishers.Sequence.swift +437 -0
- package/Sources/Combine/Publishers/Publishers.SetFailureType.swift +120 -0
- package/Sources/Combine/Publishers/Publishers.Share.swift +104 -0
- package/Sources/Combine/Publishers/Publishers.SubscribeOn.swift +197 -0
- package/Sources/Combine/Publishers/Publishers.SwitchToLatest.swift +444 -0
- package/Sources/Combine/Publishers/Publishers.Throttle.swift +359 -0
- package/Sources/Combine/Publishers/Publishers.Timeout.swift +301 -0
- package/Sources/Combine/Publishers/Publishers.Zip.swift +720 -0
- package/Sources/Combine/Publishers/Publishers.swift +13 -0
- package/Sources/Combine/Publishers/Record.swift +237 -0
- package/Sources/Combine/Publishers/Result.Publisher.swift +337 -0
- package/Sources/Combine/Result.swift +46 -0
- package/Sources/Combine/Scheduler.swift +89 -0
- package/Sources/Combine/Schedulers.swift +211 -0
- package/Sources/Combine/Subject+Void.swift +17 -0
- package/Sources/Combine/Subscriber+Void.swift +20 -0
- package/Sources/Combine/Subscribers/Subscribers.Assign.swift +175 -0
- package/Sources/Combine/Subscribers/Subscribers.Completion.swift +90 -0
- package/Sources/Combine/Subscribers/Subscribers.Demand.swift +476 -0
- package/Sources/Combine/Subscribers/Subscribers.Sink.swift +206 -0
- package/Sources/Combine/Subscribers/Subscribers.swift +9 -0
- package/Sources/Combine/Subscription.swift +22 -0
- package/Sources/Combine/Subscriptions.swift +42 -0
- package/Sources/Combine/SwiftUIObservation.swift +10 -0
- package/Sources/Combine/_Introspection.swift +107 -0
- package/Sources/CommonCrypto/CommonCrypto.swift +80 -0
- package/Sources/Compression/Compression.swift +365 -0
- package/Sources/Compression/Deflate.swift +407 -0
- package/Sources/Compression/Zlib.swift +179 -0
- package/Sources/CoreFoundationTypes/CoreFoundationTypes.swift +101 -0
- package/Sources/CoreGraphics/CoreGraphics.swift +411 -0
- package/Sources/CoreGraphics/ProjectionTransforms.swift +28 -0
- package/Sources/CoreHaptics/CoreHaptics.swift +399 -0
- package/Sources/CoreImage/CIColor.swift +41 -0
- package/Sources/CoreImage/CIContext.swift +31 -0
- package/Sources/CoreImage/CIDetector.swift +57 -0
- package/Sources/CoreImage/CIFilter.swift +243 -0
- package/Sources/CoreImage/CIFilterBuiltins.swift +136 -0
- package/Sources/CoreImage/CIImage.swift +162 -0
- package/Sources/CoreImage/QRCode.swift +393 -0
- package/Sources/CoreLocation/Coordinate.swift +30 -0
- package/Sources/CoreLocation/Location.swift +65 -0
- package/Sources/CoreML/Evaluation.swift +414 -0
- package/Sources/CoreML/FeatureValue.swift +266 -0
- package/Sources/CoreML/Model.swift +269 -0
- package/Sources/CoreML/MultiArray.swift +92 -0
- package/Sources/CoreML/Specification.swift +233 -0
- package/Sources/CoreText/CoreText.swift +64 -0
- package/Sources/CoreTransferable/CoreTransferable.swift +606 -0
- package/Sources/CryptoKit/ChaChaPoly.swift +258 -0
- package/Sources/CryptoKit/CryptoKit.swift +375 -0
- package/Sources/CryptoKit/Curve25519.swift +317 -0
- package/Sources/CryptoKit/P256.swift +321 -0
- package/Sources/FoundationBridge/AppStorage.swift +165 -0
- package/Sources/FoundationBridge/AssetResources.swift +90 -0
- package/Sources/FoundationBridge/AsyncBytes.swift +128 -0
- package/Sources/FoundationBridge/AsyncImage.swift +116 -0
- package/Sources/FoundationBridge/AttributedStrings.swift +16 -0
- package/Sources/{_FoundationCommon → FoundationBridge}/Bundle.swift +41 -4
- package/Sources/FoundationBridge/CombineExports.swift +8 -0
- package/Sources/FoundationBridge/CoreFoundation.swift +77 -0
- package/Sources/FoundationBridge/Dispatch.swift +458 -0
- package/Sources/FoundationBridge/EnvironmentFoundation.swift +41 -0
- package/Sources/FoundationBridge/FileImporter.swift +128 -0
- package/Sources/FoundationBridge/FileSystem.swift +68 -0
- package/Sources/FoundationBridge/FoundationBridge.swift +24 -72
- package/Sources/FoundationBridge/HostResolution.swift +31 -0
- package/Sources/FoundationBridge/ItemProvider.swift +655 -0
- package/Sources/FoundationBridge/KeyValueObserving.swift +138 -0
- package/Sources/FoundationBridge/Links.swift +127 -0
- package/Sources/FoundationBridge/ListFormatter.swift +32 -0
- package/Sources/FoundationBridge/Localization.swift +149 -0
- package/Sources/FoundationBridge/Locks.swift +50 -0
- package/Sources/FoundationBridge/Markdown.swift +527 -0
- package/Sources/FoundationBridge/MeasurementFormat.swift +95 -0
- package/Sources/FoundationBridge/NotificationCenter.swift +154 -0
- package/Sources/FoundationBridge/OpenURLHandlers.swift +60 -0
- package/Sources/FoundationBridge/Operation.swift +195 -0
- package/Sources/FoundationBridge/ProcessInfo.swift +32 -0
- package/Sources/FoundationBridge/RelativeDateTimeFormatter.swift +136 -0
- package/Sources/FoundationBridge/SceneStorage.swift +78 -0
- package/Sources/FoundationBridge/SecurityExports.swift +8 -0
- package/Sources/FoundationBridge/Selector.swift +226 -0
- package/Sources/FoundationBridge/StringComparators.swift +17 -0
- package/Sources/FoundationBridge/Table.swift +211 -0
- package/Sources/FoundationBridge/TextAttributes.swift +42 -0
- package/Sources/FoundationBridge/Timer.swift +6 -1
- package/Sources/FoundationBridge/URLSession.swift +718 -0
- package/Sources/{_FoundationCommon → FoundationBridge}/UserDefaults.swift +17 -4
- package/Sources/FoundationBridge/WebAuthRedirects.swift +227 -0
- package/Sources/FoundationBridge/WebSocket.swift +187 -0
- package/Sources/FoundationModels/FoundationModels.swift +1098 -0
- package/Sources/ImageIO/GIF.swift +72 -0
- package/Sources/ImageIO/ImageIO.swift +248 -0
- package/Sources/ImageIO/ImageTypes.swift +28 -0
- package/Sources/LinkPresentation/LinkPresentation.swift +249 -0
- package/Sources/LocalAuthentication/LAContext.swift +86 -0
- package/Sources/MapKit/Geometry.swift +223 -0
- package/Sources/MapKit/Map.swift +638 -0
- package/Sources/MapKit/MapView.swift +229 -0
- package/Sources/MobileCoreServices/MobileCoreServices.swift +28 -0
- package/Sources/NaturalLanguage/LanguageIdentifier.swift +317 -0
- package/Sources/NaturalLanguage/NaturalLanguage.swift +135 -0
- package/Sources/OSLog/OSLog.swift +6 -0
- package/Sources/Photos/Photos.swift +572 -0
- package/Sources/PhotosUI/PhotosPicker.swift +248 -0
- package/Sources/PhotosUI/PhotosPickerItem.swift +261 -0
- package/Sources/QuickLook/QuickLook.swift +168 -0
- package/Sources/SafariServices/SafariServices.swift +106 -0
- package/Sources/Security/Security.swift +332 -0
- package/Sources/StoreKit/AppStore.swift +207 -0
- package/Sources/StoreKit/Products.swift +280 -0
- package/Sources/StoreKit/RequestReview.swift +28 -0
- package/Sources/StoreKit/StoreKit1.swift +486 -0
- package/Sources/StoreKit/StoreViews.swift +428 -0
- package/Sources/StoreKit/Transactions.swift +197 -0
- package/Sources/SwiftData/Macros.swift +58 -0
- package/Sources/SwiftData/ModelActor.swift +38 -0
- package/Sources/SwiftData/ModelContainer.swift +129 -0
- package/Sources/SwiftData/ModelContext.swift +451 -0
- package/Sources/SwiftData/PersistentModel.swift +238 -0
- package/Sources/SwiftData/Properties.swift +261 -0
- package/Sources/SwiftData/Query.swift +256 -0
- package/Sources/SwiftData/Schema.swift +192 -0
- package/Sources/SwiftData/Store.swift +146 -0
- package/Sources/SwiftData/StringPredicates.swift +125 -0
- package/Sources/SwiftDataMacros/EntryMacro.swift +82 -0
- package/Sources/SwiftDataMacros/GenerableMacro.swift +183 -0
- package/Sources/SwiftDataMacros/ModelActorMacro.swift +46 -0
- package/Sources/SwiftDataMacros/ModelMacro.swift +260 -0
- package/Sources/SwiftDataMacros/Plugin.swift +18 -0
- package/Sources/SwiftDataMacros/PredicateMacro.swift +1244 -0
- package/Sources/SwiftUI/API/Accessibility.swift +55 -6
- package/Sources/SwiftUI/API/AccessibilityExtras.swift +33 -0
- package/Sources/SwiftUI/API/AccessibilityFocus.swift +63 -0
- package/Sources/SwiftUI/API/Alert.swift +1 -1
- package/Sources/SwiftUI/API/AlignmentGuides.swift +65 -0
- package/Sources/SwiftUI/API/Animation.swift +37 -5
- package/Sources/SwiftUI/API/App.swift +31 -1
- package/Sources/SwiftUI/API/BindingCollections.swift +35 -0
- package/Sources/SwiftUI/API/BindingForEach.swift +27 -0
- package/Sources/SwiftUI/API/Bitmaps.swift +254 -0
- package/Sources/SwiftUI/API/ButtonStyles.swift +96 -0
- package/Sources/SwiftUI/API/Canvas.swift +337 -0
- package/Sources/SwiftUI/API/Color.swift +104 -28
- package/Sources/SwiftUI/API/ColorEffects.swift +52 -0
- package/Sources/SwiftUI/API/ColorPickerAndLabeledContent.swift +138 -0
- package/Sources/SwiftUI/API/ColorSpaces.swift +161 -0
- package/Sources/SwiftUI/API/Commands.swift +106 -0
- package/Sources/SwiftUI/API/ContainerBackground.swift +28 -0
- package/Sources/SwiftUI/API/ContentShape.swift +33 -0
- package/Sources/SwiftUI/API/ContentSizeCategory.swift +35 -0
- package/Sources/SwiftUI/API/ContentUnavailable.swift +101 -0
- package/Sources/SwiftUI/API/Controls.swift +59 -27
- package/Sources/SwiftUI/API/CustomLayout.swift +49 -10
- package/Sources/SwiftUI/API/CustomToolbarContent.swift +46 -0
- package/Sources/SwiftUI/API/Decorations.swift +1 -1
- package/Sources/SwiftUI/API/EditMode.swift +25 -82
- package/Sources/SwiftUI/API/Effects.swift +105 -7
- package/Sources/SwiftUI/API/Entry.swift +8 -0
- package/Sources/SwiftUI/API/Environment.swift +93 -9
- package/Sources/SwiftUI/API/EnvironmentSendable.swift +6 -0
- package/Sources/SwiftUI/API/Focus.swift +11 -3
- package/Sources/SwiftUI/API/Gauge.swift +3 -2
- package/Sources/SwiftUI/API/GeometryEffects.swift +232 -0
- package/Sources/SwiftUI/API/GeometryReader.swift +13 -2
- package/Sources/SwiftUI/API/GestureState.swift +65 -0
- package/Sources/SwiftUI/API/Gestures.swift +1 -1
- package/Sources/SwiftUI/API/Glass.swift +127 -0
- package/Sources/SwiftUI/API/Grid.swift +1 -1
- package/Sources/SwiftUI/API/GroupBoxAndControlGroup.swift +130 -0
- package/Sources/SwiftUI/API/KeyPress.swift +54 -0
- package/Sources/SwiftUI/API/LabelStyle.swift +13 -6
- package/Sources/SwiftUI/API/Layout.swift +67 -12
- package/Sources/SwiftUI/API/LazyStacks.swift +49 -0
- package/Sources/SwiftUI/API/LegacyAlert.swift +97 -0
- package/Sources/SwiftUI/API/Lists.swift +61 -6
- package/Sources/SwiftUI/API/Menu.swift +8 -1
- package/Sources/SwiftUI/API/Modifiers.swift +80 -10
- package/Sources/SwiftUI/API/MoreModifiers.swift +100 -0
- package/Sources/SwiftUI/API/Namespace.swift +44 -0
- package/Sources/SwiftUI/API/Navigation.swift +24 -9
- package/Sources/SwiftUI/API/NavigationDestinationBindings.swift +55 -0
- package/Sources/SwiftUI/API/ObservableObject.swift +16 -2
- package/Sources/SwiftUI/API/Path.swift +543 -0
- package/Sources/SwiftUI/API/Phase8Controls.swift +48 -31
- package/Sources/SwiftUI/API/PhaseAnimator.swift +130 -0
- package/Sources/SwiftUI/API/Picker.swift +11 -2
- package/Sources/SwiftUI/API/PointerAndKeyboard.swift +77 -0
- package/Sources/SwiftUI/API/Popover.swift +41 -0
- package/Sources/SwiftUI/API/Preferences.swift +262 -0
- package/Sources/SwiftUI/API/Presentation.swift +17 -4
- package/Sources/SwiftUI/API/PresentationExtras.swift +60 -0
- package/Sources/SwiftUI/API/Primitives.swift +164 -37
- package/Sources/SwiftUI/API/Publishers.swift +4 -4
- package/Sources/SwiftUI/API/Redaction.swift +75 -0
- package/Sources/SwiftUI/API/RowActions.swift +3 -2
- package/Sources/SwiftUI/API/Scenes.swift +131 -0
- package/Sources/SwiftUI/API/ScrollModifiers.swift +132 -0
- package/Sources/SwiftUI/API/ScrollTargets.swift +3 -3
- package/Sources/SwiftUI/API/ScrollViewReader.swift +144 -0
- package/Sources/SwiftUI/API/SectionSupplements.swift +96 -0
- package/Sources/SwiftUI/API/Shape.swift +214 -0
- package/Sources/SwiftUI/API/ShapeStyle.swift +105 -7
- package/Sources/SwiftUI/API/ShapeTrim.swift +78 -0
- package/Sources/SwiftUI/API/Sharing.swift +193 -0
- package/Sources/SwiftUI/API/StackLayouts.swift +199 -0
- package/Sources/SwiftUI/API/State.swift +18 -1
- package/Sources/SwiftUI/API/StatusGaps.swift +121 -0
- package/Sources/SwiftUI/API/SymbolEffects.swift +203 -0
- package/Sources/SwiftUI/API/TabContent.swift +841 -0
- package/Sources/SwiftUI/API/Table.swift +382 -0
- package/Sources/SwiftUI/API/Tabs.swift +148 -4
- package/Sources/SwiftUI/API/Tasks.swift +2 -2
- package/Sources/SwiftUI/API/Text.swift +386 -0
- package/Sources/SwiftUI/API/TextDates.swift +61 -0
- package/Sources/SwiftUI/API/TextDecorations.swift +52 -0
- package/Sources/SwiftUI/API/TextFieldAxis.swift +103 -0
- package/Sources/SwiftUI/API/TextFieldCommit.swift +52 -0
- package/Sources/SwiftUI/API/Toolbar.swift +52 -16
- package/Sources/SwiftUI/API/Transfer.swift +145 -0
- package/Sources/SwiftUI/API/UnevenRoundedRectangle.swift +66 -0
- package/Sources/SwiftUI/API/Video.swift +64 -0
- package/Sources/SwiftUI/API/View.swift +10 -2
- package/Sources/SwiftUI/API/ViewModifier.swift +4 -1
- package/Sources/SwiftUI/API/VisualEffect.swift +74 -1
- package/Sources/SwiftUI/API/Windows.swift +25 -0
- package/Sources/SwiftUI/Charts/Axis.swift +7 -1
- package/Sources/SwiftUI/Charts/AxisFormatsAndRanges.swift +68 -0
- package/Sources/SwiftUI/Charts/Chart.swift +17 -3
- package/Sources/SwiftUI/Charts/ChartProxy.swift +57 -0
- package/Sources/SwiftUI/Localization/Localization.swift +498 -0
- package/Sources/SwiftUI/Localization/PluralRules.swift +127 -0
- package/Sources/SwiftUI/Runtime/Executor.swift +2 -0
- package/Sources/SwiftUI/Runtime/Exports.swift +37 -1
- package/Sources/SwiftUI/Runtime/ImageSource.swift +310 -0
- package/Sources/SwiftUI/Runtime/JSON.swift +76 -4
- package/Sources/SwiftUI/Runtime/LazyRows.swift +99 -0
- package/Sources/SwiftUI/Runtime/Measurements.swift +140 -0
- package/Sources/SwiftUI/Runtime/Ops.swift +58 -12
- package/Sources/SwiftUI/Runtime/Reconciler.swift +10 -1
- package/Sources/SwiftUI/Runtime/Replay.swift +382 -0
- package/Sources/SwiftUI/Runtime/Runtime.swift +977 -198
- package/Sources/SwiftUI/Runtime/Sameness.swift +152 -0
- package/Sources/SwiftUI/Runtime/ViewPath.swift +89 -0
- package/Sources/SwiftUI/Runtime/ViewTraits.swift +175 -0
- package/Sources/SwiftUI/Runtime/WebAuthHeadless.swift +49 -0
- package/Sources/Symbols/Symbols.swift +25 -0
- package/Sources/Translation/Translation.swift +423 -0
- package/Sources/UIKit/Activity.swift +213 -0
- package/Sources/UIKit/Alerts.swift +69 -0
- package/Sources/UIKit/AppDelegate.swift +222 -0
- package/Sources/UIKit/Appearance.swift +84 -0
- package/Sources/UIKit/ColorConversions.swift +70 -0
- package/Sources/UIKit/Controls.swift +225 -0
- package/Sources/UIKit/Device.swift +200 -0
- package/Sources/UIKit/Feedback.swift +65 -0
- package/Sources/UIKit/Font.swift +307 -0
- package/Sources/UIKit/Graphics.swift +204 -0
- package/Sources/UIKit/HostingController.swift +185 -0
- package/Sources/UIKit/Identity.swift +24 -0
- package/Sources/UIKit/Introspectable.swift +510 -0
- package/Sources/UIKit/Pasteboard.swift +363 -0
- package/Sources/UIKit/PhotoAlbum.swift +81 -0
- package/Sources/UIKit/RemoteNotifications.swift +15 -0
- package/Sources/UIKit/Representable.swift +288 -0
- package/Sources/UIKit/SafeArea.swift +12 -0
- package/Sources/UIKit/SceneDelegates.swift +132 -0
- package/Sources/UIKit/Scenes.swift +40 -0
- package/Sources/UIKit/ScrollView.swift +157 -0
- package/Sources/UIKit/ShortcutItems.swift +67 -0
- package/Sources/UIKit/SymbolConfiguration.swift +124 -0
- package/Sources/UIKit/TargetAction.swift +123 -0
- package/Sources/UIKit/TextPaste.swift +161 -0
- package/Sources/UIKit/TextView.swift +538 -0
- package/Sources/UIKit/UIKit.swift +292 -0
- package/Sources/UIKit/UIView.swift +855 -0
- package/Sources/UIKit/ViewTranslation.swift +311 -0
- package/Sources/UniformTypeIdentifiers/UTType.swift +196 -0
- package/Sources/UserNotifications/Content.swift +370 -0
- package/Sources/UserNotifications/NotificationCenter.swift +309 -0
- package/Sources/WeatherKit/WeatherKit.swift +228 -0
- package/Sources/WebKit/WebKit.swift +245 -0
- package/Sources/os/os.swift +376 -0
- package/Sources/zlib/zlib.swift +6 -0
- package/index.d.ts +1 -1
- package/index.mjs +2 -2
- package/manifest.d.mts +2 -0
- package/manifest.mjs +39 -0
- package/package.json +5 -3
- package/sync-sources.mjs +21 -7
- package/Sources/FoundationLite/Common.swift +0 -3
- package/Sources/FoundationLite/FoundationLite.swift +0 -171
- package/Sources/FoundationLite/Interaction.swift +0 -146
- package/Sources/FoundationLite/Timer.swift +0 -48
- package/Sources/_FoundationCommon/_FoundationCommon.swift +0 -10
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
// `Table`, drawn as iOS draws one: a list. In a compact width (an iPhone)
|
|
2
|
+
// each row shows the table's first column only, as on iOS; in a regular
|
|
3
|
+
// width the rows show every column side by side under a row of the column
|
|
4
|
+
// titles, and tapping a sortable column's title sorts by it (the app sorts
|
|
5
|
+
// its rows by the `sortOrder` binding, as with SwiftUI's table). Selection is
|
|
6
|
+
// the list's. A column's `width(_:)` fixes its width; the other columns share
|
|
7
|
+
// the rest.
|
|
8
|
+
//
|
|
9
|
+
// The rows are views (`TableRow`, in `ForEach` and `Section` as in SwiftUI);
|
|
10
|
+
// a row draws the columns the table puts in its environment. Sortable columns
|
|
11
|
+
// and the `sortOrder` forms of `Table` need Foundation's `KeyPathComparator`,
|
|
12
|
+
// so they are FoundationBridge's (Table.swift there).
|
|
13
|
+
|
|
14
|
+
// MARK: - Columns
|
|
15
|
+
|
|
16
|
+
/// Columns of a table, made with `TableColumnBuilder`.
|
|
17
|
+
public protocol TableColumnContent<TableRowValue, TableColumnSortComparator> {
|
|
18
|
+
associatedtype TableRowValue: Identifiable
|
|
19
|
+
associatedtype TableColumnSortComparator
|
|
20
|
+
var _tableColumns: [_TableColumn<TableRowValue>] { get }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/// One column: its title, the view it draws for a row, its width and, for a
|
|
24
|
+
/// sortable column, the comparator (a `KeyPathComparator`) its title sorts by.
|
|
25
|
+
public struct _TableColumn<RowValue> {
|
|
26
|
+
public var title: Text
|
|
27
|
+
public var content: (RowValue) -> AnyView
|
|
28
|
+
public var sortComparator: Any?
|
|
29
|
+
var width: CGFloat?
|
|
30
|
+
var minWidth: CGFloat?
|
|
31
|
+
var maxWidth: CGFloat?
|
|
32
|
+
|
|
33
|
+
public init(title: Text, sortComparator: Any? = nil, content: @escaping (RowValue) -> AnyView) {
|
|
34
|
+
self.title = title
|
|
35
|
+
self.sortComparator = sortComparator
|
|
36
|
+
self.content = content
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public struct TableColumn<RowValue: Identifiable, Sort, Content: View, Label: View>: TableColumnContent {
|
|
41
|
+
public typealias TableRowValue = RowValue
|
|
42
|
+
public typealias TableColumnSortComparator = Sort
|
|
43
|
+
|
|
44
|
+
var column: _TableColumn<RowValue>
|
|
45
|
+
public var _tableColumns: [_TableColumn<RowValue>] { [column] }
|
|
46
|
+
|
|
47
|
+
/// A column made elsewhere (FoundationBridge's sortable columns).
|
|
48
|
+
public init(_column: _TableColumn<RowValue>) { column = _column }
|
|
49
|
+
|
|
50
|
+
/// A fixed width (nil: shares the rest of the row).
|
|
51
|
+
public func width(_ width: CGFloat?) -> TableColumn {
|
|
52
|
+
var copy = self
|
|
53
|
+
copy.column.width = width
|
|
54
|
+
return copy
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/// Limits on the width; the ideal width is the column's when given.
|
|
58
|
+
public func width(min: CGFloat? = nil, ideal: CGFloat? = nil, max: CGFloat? = nil) -> TableColumn {
|
|
59
|
+
var copy = self
|
|
60
|
+
copy.column.minWidth = min
|
|
61
|
+
copy.column.maxWidth = max
|
|
62
|
+
if let ideal, min == nil, max == nil { copy.column.width = ideal }
|
|
63
|
+
return copy
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/// Accepted: columns line up with the start of their titles.
|
|
67
|
+
public func alignment(_ alignment: TableColumnAlignment) -> TableColumn { self }
|
|
68
|
+
/// Accepted: the browser's table has no column customization.
|
|
69
|
+
public func customizationID(_ id: String) -> TableColumn { self }
|
|
70
|
+
public func defaultVisibility(_ visibility: Visibility) -> TableColumn { self }
|
|
71
|
+
public func disabledCustomizationBehavior(_ behavior: TableColumnCustomizationBehavior) -> TableColumn { self }
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
extension TableColumn where Sort == Never, Label == Text {
|
|
75
|
+
public init(_ titleKey: LocalizedStringKey, @ViewBuilder content: @escaping (RowValue) -> Content) {
|
|
76
|
+
self.init(_column: _TableColumn(title: Text(titleKey)) { AnyView(content($0)) })
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@_disfavoredOverload
|
|
80
|
+
public init<S: StringProtocol>(_ title: S, @ViewBuilder content: @escaping (RowValue) -> Content) {
|
|
81
|
+
self.init(_column: _TableColumn(title: Text(String(title))) { AnyView(content($0)) })
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public init(_ text: Text, @ViewBuilder content: @escaping (RowValue) -> Content) {
|
|
85
|
+
self.init(_column: _TableColumn(title: text) { AnyView(content($0)) })
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public struct TableColumnAlignment: Hashable, Sendable {
|
|
90
|
+
let name: String
|
|
91
|
+
public static let automatic = TableColumnAlignment(name: "automatic")
|
|
92
|
+
public static let leading = TableColumnAlignment(name: "leading")
|
|
93
|
+
public static let center = TableColumnAlignment(name: "center")
|
|
94
|
+
public static let trailing = TableColumnAlignment(name: "trailing")
|
|
95
|
+
public static let numeric = TableColumnAlignment(name: "numeric")
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public struct TableColumnCustomizationBehavior: Hashable, Sendable {
|
|
99
|
+
let name: String
|
|
100
|
+
public static let all = TableColumnCustomizationBehavior(name: "all")
|
|
101
|
+
public static let resize = TableColumnCustomizationBehavior(name: "resize")
|
|
102
|
+
public static let reorder = TableColumnCustomizationBehavior(name: "reorder")
|
|
103
|
+
public static let visibility = TableColumnCustomizationBehavior(name: "visibility")
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/// The columns a `TableColumnBuilder` made.
|
|
107
|
+
public struct _TableColumnGroup<RowValue: Identifiable, Sort>: TableColumnContent {
|
|
108
|
+
public typealias TableRowValue = RowValue
|
|
109
|
+
public typealias TableColumnSortComparator = Sort
|
|
110
|
+
public let _tableColumns: [_TableColumn<RowValue>]
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
@resultBuilder
|
|
114
|
+
public struct TableColumnBuilder<RowValue: Identifiable, Sort> {
|
|
115
|
+
/// A column, whose row type is the table's (so its closure's parameter is inferred).
|
|
116
|
+
public static func buildExpression<ColumnSort, Content, Label>(_ column: TableColumn<RowValue, ColumnSort, Content, Label>)
|
|
117
|
+
-> [_TableColumn<RowValue>] {
|
|
118
|
+
column._tableColumns
|
|
119
|
+
}
|
|
120
|
+
@_disfavoredOverload
|
|
121
|
+
public static func buildExpression<Column: TableColumnContent>(_ column: Column) -> [_TableColumn<RowValue>]
|
|
122
|
+
where Column.TableRowValue == RowValue {
|
|
123
|
+
column._tableColumns
|
|
124
|
+
}
|
|
125
|
+
public static func buildBlock(_ components: [_TableColumn<RowValue>]...) -> [_TableColumn<RowValue>] { components.flatMap { $0 } }
|
|
126
|
+
public static func buildOptional(_ component: [_TableColumn<RowValue>]?) -> [_TableColumn<RowValue>] { component ?? [] }
|
|
127
|
+
public static func buildEither(first component: [_TableColumn<RowValue>]) -> [_TableColumn<RowValue>] { component }
|
|
128
|
+
public static func buildEither(second component: [_TableColumn<RowValue>]) -> [_TableColumn<RowValue>] { component }
|
|
129
|
+
public static func buildLimitedAvailability(_ component: [_TableColumn<RowValue>]) -> [_TableColumn<RowValue>] { component }
|
|
130
|
+
public static func buildFinalResult(_ component: [_TableColumn<RowValue>]) -> _TableColumnGroup<RowValue, Sort> {
|
|
131
|
+
_TableColumnGroup(_tableColumns: component)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// MARK: - Rows
|
|
136
|
+
|
|
137
|
+
/// Rows of a table.
|
|
138
|
+
public protocol TableRowContent<TableRowValue> {
|
|
139
|
+
associatedtype TableRowValue: Identifiable
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/// A row of a table: the table's columns drawn for `value`.
|
|
143
|
+
public struct TableRow<Value: Identifiable>: View, TableRowContent {
|
|
144
|
+
public typealias TableRowValue = Value
|
|
145
|
+
let value: Value
|
|
146
|
+
@Environment(\._tableLayout) private var layout
|
|
147
|
+
|
|
148
|
+
public init(_ value: Value) { self.value = value }
|
|
149
|
+
|
|
150
|
+
public var body: some View {
|
|
151
|
+
if let layout { layout.row(value) }
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/// The rows of a table made from a collection (`Table(data) { … }`): a
|
|
156
|
+
/// `TableRow` for each element.
|
|
157
|
+
public struct TableForEachContent<Data: RandomAccessCollection>: TableRowContent where Data.Element: Identifiable {
|
|
158
|
+
public typealias TableRowValue = Data.Element
|
|
159
|
+
let data: Data
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/// What a row draws: the table's columns, all of them or the first.
|
|
163
|
+
struct _TableLayout {
|
|
164
|
+
struct Column {
|
|
165
|
+
let width: CGFloat?
|
|
166
|
+
let minWidth: CGFloat?
|
|
167
|
+
let maxWidth: CGFloat?
|
|
168
|
+
let content: (Any) -> AnyView
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
let columns: [Column]
|
|
172
|
+
let compact: Bool
|
|
173
|
+
|
|
174
|
+
@MainActor
|
|
175
|
+
func row(_ value: Any) -> AnyView {
|
|
176
|
+
guard let first = columns.first else { return AnyView(EmptyView()) }
|
|
177
|
+
if compact { return first.content(value) }
|
|
178
|
+
return AnyView(HStack(spacing: _tableColumnSpacing) {
|
|
179
|
+
ForEach(columns.indices, id: \.self) { index in
|
|
180
|
+
_tableCell(columns[index], columns[index].content(value))
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
let _tableColumnSpacing: CGFloat = 12
|
|
187
|
+
|
|
188
|
+
/// A cell at its column's width: fixed, or a share of the row. Its own
|
|
189
|
+
/// priority is 0, so a `layoutPriority` inside a cell (Food Truck's first
|
|
190
|
+
/// column has one) does not take the row from the other columns.
|
|
191
|
+
@MainActor
|
|
192
|
+
func _tableCell(_ column: _TableLayout.Column, _ content: some View) -> AnyView {
|
|
193
|
+
if let width = column.width {
|
|
194
|
+
return AnyView(content.frame(width: width, alignment: .leading).layoutPriority(0))
|
|
195
|
+
}
|
|
196
|
+
return AnyView(content.frame(minWidth: column.minWidth ?? 0, maxWidth: column.maxWidth ?? .infinity, alignment: .leading)
|
|
197
|
+
.layoutPriority(0))
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private struct _TableLayoutKey: EnvironmentKey {
|
|
201
|
+
static var defaultValue: _TableLayout? { nil }
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
extension EnvironmentValues {
|
|
205
|
+
var _tableLayout: _TableLayout? {
|
|
206
|
+
get { self[_TableLayoutKey.self] }
|
|
207
|
+
set { self[_TableLayoutKey.self] = newValue }
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// MARK: - Table
|
|
212
|
+
|
|
213
|
+
/// How a table's column titles sort it: which column sorts it, ascending or
|
|
214
|
+
/// not, and what tapping a title does (FoundationBridge makes one from a
|
|
215
|
+
/// `sortOrder` binding).
|
|
216
|
+
public struct _TableSort {
|
|
217
|
+
let order: (Int) -> Bool?
|
|
218
|
+
let tap: (Int) -> Void
|
|
219
|
+
|
|
220
|
+
/// `order(i)`: nil when column `i` does not sort the table, else whether it sorts ascending.
|
|
221
|
+
public init(order: @escaping (Int) -> Bool?, tap: @escaping (Int) -> Void) {
|
|
222
|
+
self.order = order
|
|
223
|
+
self.tap = tap
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/// Rows with columns, drawn as a list (see the top of the file).
|
|
228
|
+
public struct Table<Value: Identifiable, Rows, Columns: TableColumnContent>: View where Columns.TableRowValue == Value {
|
|
229
|
+
let columns: [_TableColumn<Value>]
|
|
230
|
+
let rows: AnyView
|
|
231
|
+
let selection: _ListSelection?
|
|
232
|
+
let sort: _TableSort?
|
|
233
|
+
@Environment(\.horizontalSizeClass) private var sizeClass
|
|
234
|
+
|
|
235
|
+
init(columns: Columns, rows: AnyView, selection: _ListSelection?, sort: _TableSort?) {
|
|
236
|
+
self.columns = columns._tableColumns
|
|
237
|
+
self.rows = rows
|
|
238
|
+
self.selection = selection
|
|
239
|
+
self.sort = sort
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/// A table of `rows`, without selection or with one (FoundationBridge's `sortOrder` forms).
|
|
243
|
+
public init(_columns columns: Columns, rows: some View, sort: _TableSort?) {
|
|
244
|
+
self.init(columns: columns, rows: AnyView(rows), selection: nil, sort: sort)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
public init(_columns columns: Columns, rows: some View, selection: Binding<Value.ID?>, sort: _TableSort?) {
|
|
248
|
+
self.init(columns: columns, rows: AnyView(rows), selection: _ListSelection(selection), sort: sort)
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
public init(_columns columns: Columns, rows: some View, selection: Binding<Set<Value.ID>>, sort: _TableSort?) {
|
|
252
|
+
self.init(columns: columns, rows: AnyView(rows), selection: _ListSelection(selection), sort: sort)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
public var body: some View {
|
|
256
|
+
let compact = sizeClass != .regular
|
|
257
|
+
let layout = _TableLayout(columns: columns.map { column in
|
|
258
|
+
_TableLayout.Column(width: column.width, minWidth: column.minWidth, maxWidth: column.maxWidth) { value in
|
|
259
|
+
column.content(value as! Value)
|
|
260
|
+
}
|
|
261
|
+
}, compact: compact)
|
|
262
|
+
VStack(spacing: 0) {
|
|
263
|
+
if !compact { header(layout) }
|
|
264
|
+
List(_selection: selection) { rows }
|
|
265
|
+
.environment(\._tableLayout, layout)
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/// The column titles, a sortable one a button with the sort's chevron.
|
|
270
|
+
private func header(_ layout: _TableLayout) -> some View {
|
|
271
|
+
HStack(spacing: _tableColumnSpacing) {
|
|
272
|
+
ForEach(columns.indices, id: \.self) { index in
|
|
273
|
+
_tableCell(layout.columns[index], title(index))
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
.font(.subheadline.weight(.semibold))
|
|
277
|
+
.foregroundStyle(.secondary)
|
|
278
|
+
.padding(.horizontal, 20)
|
|
279
|
+
.padding(.vertical, 8)
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
@ViewBuilder
|
|
283
|
+
private func title(_ index: Int) -> some View {
|
|
284
|
+
let column = columns[index]
|
|
285
|
+
if let sort, column.sortComparator != nil {
|
|
286
|
+
Button { sort.tap(index) } label: {
|
|
287
|
+
HStack(spacing: 4) {
|
|
288
|
+
column.title
|
|
289
|
+
if let ascending = sort.order(index) {
|
|
290
|
+
Image(systemName: ascending ? "chevron.up" : "chevron.down").font(.caption2.weight(.bold))
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
.buttonStyle(.plain)
|
|
295
|
+
} else {
|
|
296
|
+
column.title
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
extension Table {
|
|
302
|
+
public init(_ data: [Value], @TableColumnBuilder<Value, Never> columns: () -> Columns)
|
|
303
|
+
where Rows == TableForEachContent<[Value]> {
|
|
304
|
+
self.init(columns: columns(), rows: AnyView(ForEach(data) { TableRow($0) }), selection: nil, sort: nil)
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
@_disfavoredOverload
|
|
308
|
+
public init<Data: RandomAccessCollection>(_ data: Data, @TableColumnBuilder<Data.Element, Never> columns: () -> Columns)
|
|
309
|
+
where Rows == TableForEachContent<Data>, Data.Element == Value {
|
|
310
|
+
self.init(columns: columns(), rows: AnyView(ForEach(data) { TableRow($0) }), selection: nil, sort: nil)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
public init(_ data: [Value], selection: Binding<Value.ID?>,
|
|
314
|
+
@TableColumnBuilder<Value, Never> columns: () -> Columns)
|
|
315
|
+
where Rows == TableForEachContent<[Value]> {
|
|
316
|
+
self.init(columns: columns(), rows: AnyView(ForEach(data) { TableRow($0) }), selection: _ListSelection(selection), sort: nil)
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
@_disfavoredOverload
|
|
320
|
+
public init<Data: RandomAccessCollection>(_ data: Data, selection: Binding<Value.ID?>,
|
|
321
|
+
@TableColumnBuilder<Data.Element, Never> columns: () -> Columns)
|
|
322
|
+
where Rows == TableForEachContent<Data>, Data.Element == Value {
|
|
323
|
+
self.init(columns: columns(), rows: AnyView(ForEach(data) { TableRow($0) }), selection: _ListSelection(selection), sort: nil)
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
public init(_ data: [Value], selection: Binding<Set<Value.ID>>,
|
|
327
|
+
@TableColumnBuilder<Value, Never> columns: () -> Columns)
|
|
328
|
+
where Rows == TableForEachContent<[Value]> {
|
|
329
|
+
self.init(columns: columns(), rows: AnyView(ForEach(data) { TableRow($0) }), selection: _ListSelection(selection), sort: nil)
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
@_disfavoredOverload
|
|
333
|
+
public init<Data: RandomAccessCollection>(_ data: Data, selection: Binding<Set<Value.ID>>,
|
|
334
|
+
@TableColumnBuilder<Data.Element, Never> columns: () -> Columns)
|
|
335
|
+
where Rows == TableForEachContent<Data>, Data.Element == Value {
|
|
336
|
+
self.init(columns: columns(), rows: AnyView(ForEach(data) { TableRow($0) }), selection: _ListSelection(selection), sort: nil)
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
public init(of valueType: Value.Type, @TableColumnBuilder<Value, Never> columns: () -> Columns,
|
|
340
|
+
@ViewBuilder rows: () -> Rows) where Rows: View {
|
|
341
|
+
self.init(columns: columns(), rows: AnyView(rows()), selection: nil, sort: nil)
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
public init(of valueType: Value.Type, selection: Binding<Value.ID?>, @TableColumnBuilder<Value, Never> columns: () -> Columns,
|
|
345
|
+
@ViewBuilder rows: () -> Rows) where Rows: View {
|
|
346
|
+
self.init(columns: columns(), rows: AnyView(rows()), selection: _ListSelection(selection), sort: nil)
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
public init(of valueType: Value.Type, selection: Binding<Set<Value.ID>>, @TableColumnBuilder<Value, Never> columns: () -> Columns,
|
|
350
|
+
@ViewBuilder rows: () -> Rows) where Rows: View {
|
|
351
|
+
self.init(columns: columns(), rows: AnyView(rows()), selection: _ListSelection(selection), sort: nil)
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
extension List {
|
|
356
|
+
/// A list with a selection made already (a table's).
|
|
357
|
+
init(_selection: _ListSelection?, @ViewBuilder content: () -> Content) {
|
|
358
|
+
self.content = content()
|
|
359
|
+
self.selection = _selection
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// MARK: - Styles
|
|
364
|
+
|
|
365
|
+
public protocol TableStyle {}
|
|
366
|
+
public struct AutomaticTableStyle: TableStyle { public init() {} }
|
|
367
|
+
public struct InsetTableStyle: TableStyle { public init() {} }
|
|
368
|
+
|
|
369
|
+
extension TableStyle where Self == AutomaticTableStyle {
|
|
370
|
+
public static var automatic: AutomaticTableStyle { AutomaticTableStyle() }
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
extension TableStyle where Self == InsetTableStyle {
|
|
374
|
+
public static var inset: InsetTableStyle { InsetTableStyle() }
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
nonisolated extension View {
|
|
378
|
+
/// Accepted: a table is drawn as a list.
|
|
379
|
+
public func tableStyle<S: TableStyle>(_ style: S) -> some View { self }
|
|
380
|
+
/// Accepted: the titles show in a regular width only, as on iOS.
|
|
381
|
+
public func tableColumnHeaders(_ visibility: Visibility) -> some View { self }
|
|
382
|
+
}
|
|
@@ -17,7 +17,25 @@ extension TabView where SelectionValue == Int {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
// The iOS 18 API: `Tab`s (see TabContent.swift) select by their `value`.
|
|
21
|
+
extension TabView {
|
|
22
|
+
public init<C: TabContent>(selection: Binding<SelectionValue>,
|
|
23
|
+
@TabContentBuilder<SelectionValue> content: () -> C)
|
|
24
|
+
where Content == TabContentBuilder<SelectionValue>.Content<C> {
|
|
25
|
+
self.selection = selection
|
|
26
|
+
self.content = TabContentBuilder<SelectionValue>.Content(content: content())
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
extension TabView where SelectionValue == Never {
|
|
31
|
+
public init<C: TabContent>(@TabContentBuilder<Never> content: () -> C)
|
|
32
|
+
where Content == TabContentBuilder<Never>.Content<C> {
|
|
33
|
+
self.selection = nil
|
|
34
|
+
self.content = TabContentBuilder<Never>.Content(content: content())
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
protocol _TabViewHost: _TraitBearing {
|
|
21
39
|
var _tabContent: any View { get }
|
|
22
40
|
/// Index of the selected tab given the tabs' tags, and a setter.
|
|
23
41
|
func _selectedIndex(tags: [AnyHashable?]) -> Int
|
|
@@ -60,16 +78,44 @@ struct _TabScreenView {
|
|
|
60
78
|
/// Only the selected tab's `navigationTitle` and `.toolbar` reach the
|
|
61
79
|
/// enclosing screen (a tab's own `NavigationStack` is flattened into it).
|
|
62
80
|
var isSelected = true
|
|
81
|
+
/// A `Tab`'s `.badge` (never set by the `.tabItem` API).
|
|
82
|
+
var badge: String?
|
|
83
|
+
/// A `Tab`'s role (`"search"`).
|
|
84
|
+
var role: String?
|
|
63
85
|
}
|
|
64
86
|
extension _TabScreenView: _PrimitiveView {}
|
|
65
87
|
extension _TabScreenView: _HostView {
|
|
66
88
|
var _kind: String { "tab" }
|
|
67
89
|
func _props(in environment: EnvironmentValues) -> _JSON {
|
|
68
|
-
|
|
90
|
+
var props: [String: _JSON] = ["title": .string(title), "systemImage": systemImage.map(_JSON.string) ?? .null]
|
|
91
|
+
// Only present when set, so `.tabItem` tabs keep their exact props.
|
|
92
|
+
if let badge { props["badge"] = .string(badge) }
|
|
93
|
+
if let role { props["role"] = .string(role) }
|
|
94
|
+
return .object(props)
|
|
69
95
|
}
|
|
70
96
|
var _content: [any View] { [content] }
|
|
71
97
|
}
|
|
72
98
|
|
|
99
|
+
extension _TabScreenView {
|
|
100
|
+
/// The tab for one of a tab view's flattened children: its `.tabItem` /
|
|
101
|
+
/// `Tab` label gives the title and symbol; a `Tab` adds its badge and role,
|
|
102
|
+
/// and a search tab without a title or symbol is "Search" with a
|
|
103
|
+
/// magnifying glass.
|
|
104
|
+
@MainActor
|
|
105
|
+
init(root: any View, isSelected: Bool) {
|
|
106
|
+
let label = _tabLabel(of: root)
|
|
107
|
+
var title = label.map { _textContent(of: $0) } ?? ""
|
|
108
|
+
var systemImage = label.flatMap { _systemImage(of: $0) }
|
|
109
|
+
let entry = (root as? _TabEntryView)?.entry
|
|
110
|
+
if entry?.role == .search {
|
|
111
|
+
if title.isEmpty { title = "Search" }
|
|
112
|
+
if systemImage == nil { systemImage = "magnifyingglass" }
|
|
113
|
+
}
|
|
114
|
+
self.init(content: root, title: title, systemImage: systemImage, isSelected: isSelected,
|
|
115
|
+
badge: entry?.modifiers.badge, role: entry?.role?.name)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
73
119
|
// MARK: - .tabItem and .tag
|
|
74
120
|
|
|
75
121
|
protocol _TabItemProviding {
|
|
@@ -90,7 +136,7 @@ extension _TabItemView: _TabItemProviding {
|
|
|
90
136
|
var _tabContent: any View { content }
|
|
91
137
|
}
|
|
92
138
|
|
|
93
|
-
protocol _TagProviding {
|
|
139
|
+
protocol _TagProviding: _TraitBearing {
|
|
94
140
|
var _tag: AnyHashable { get }
|
|
95
141
|
var _tagged: any View { get }
|
|
96
142
|
}
|
|
@@ -108,7 +154,7 @@ extension _TagView: _TagProviding {
|
|
|
108
154
|
var _tagged: any View { content }
|
|
109
155
|
}
|
|
110
156
|
|
|
111
|
-
extension View {
|
|
157
|
+
nonisolated extension View {
|
|
112
158
|
public func tabItem<Label: View>(@ViewBuilder _ label: () -> Label) -> some View {
|
|
113
159
|
_TabItemView(content: self, label: label())
|
|
114
160
|
}
|
|
@@ -117,3 +163,101 @@ extension View {
|
|
|
117
163
|
_TagView(content: self, tag: tag)
|
|
118
164
|
}
|
|
119
165
|
}
|
|
166
|
+
|
|
167
|
+
// MARK: - Sidebar (regular-width `.sidebarAdaptable`)
|
|
168
|
+
|
|
169
|
+
/// Whether a tab view shows its tabs as a sidebar: `.sidebarAdaptable` in
|
|
170
|
+
/// regular width, unless its default placement is `.tabBar`.
|
|
171
|
+
func _tabViewIsSidebar(_ environment: EnvironmentValues) -> Bool {
|
|
172
|
+
environment._tabViewStyle == "sidebarAdaptable" && environment.horizontalSizeClass == .regular
|
|
173
|
+
&& environment._tabBarPlacement != "tabBar"
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/// One sidebar row: a tab, by its index among the tab view's children.
|
|
177
|
+
struct _TabSidebarRow {
|
|
178
|
+
let index: Int
|
|
179
|
+
let title: String
|
|
180
|
+
let systemImage: String?
|
|
181
|
+
let badge: String?
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/// The rows of one `TabSection` (or of consecutive tabs outside sections).
|
|
185
|
+
struct _TabSidebarGroup {
|
|
186
|
+
let header: String?
|
|
187
|
+
let rows: [_TabSidebarRow]
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/// A regular-width `.sidebarAdaptable` tab view: a `NavigationSplitView` whose
|
|
191
|
+
/// sidebar is a `List(selection:)` of the tabs in declaration order (a section
|
|
192
|
+
/// per `TabSection`, under its header) and whose detail is the selected tab's
|
|
193
|
+
/// content. Selecting a row selects the tab as a bar item would.
|
|
194
|
+
@MainActor
|
|
195
|
+
func _tabSidebar(roots: [any View], selected: Int, select: @escaping (Int) -> Void) -> any View {
|
|
196
|
+
let rows = roots.enumerated().map { index, root in
|
|
197
|
+
let entry = root as? _TabEntryView
|
|
198
|
+
let tab = _TabScreenView(root: root, isSelected: false)
|
|
199
|
+
return (order: entry?.order ?? index, section: entry?.entry.section, header: entry?.sectionHeader,
|
|
200
|
+
row: _TabSidebarRow(index: index, title: tab.title, systemImage: tab.systemImage, badge: tab.badge))
|
|
201
|
+
}.sorted { $0.order < $1.order }
|
|
202
|
+
var groups: [_TabSidebarGroup] = []
|
|
203
|
+
var start = 0
|
|
204
|
+
while start < rows.count {
|
|
205
|
+
var end = start + 1
|
|
206
|
+
while end < rows.count, rows[end].section == rows[start].section { end += 1 }
|
|
207
|
+
let header = rows[start].header.map { _textContent(of: $0) }
|
|
208
|
+
groups.append(_TabSidebarGroup(header: header?.isEmpty == false ? header : nil,
|
|
209
|
+
rows: rows[start..<end].map(\.row)))
|
|
210
|
+
start = end
|
|
211
|
+
}
|
|
212
|
+
let detail = roots.indices.contains(selected) ? roots[selected] : EmptyView()
|
|
213
|
+
return NavigationSplitView {
|
|
214
|
+
_TabSidebarList(groups: groups, selection: Binding(get: { selected }, set: { if let index = $0 { select(index) } }))
|
|
215
|
+
} detail: {
|
|
216
|
+
// Keyed by the tab, so each tab's content has its own state.
|
|
217
|
+
ForEach([selected], id: \.self) { _ in _TabSidebarDetail(content: detail) }
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
struct _TabSidebarList: View {
|
|
222
|
+
let groups: [_TabSidebarGroup]
|
|
223
|
+
let selection: Binding<Int?>
|
|
224
|
+
|
|
225
|
+
var body: some View {
|
|
226
|
+
List(selection: selection) {
|
|
227
|
+
ForEach(groups.indices, id: \.self) { index in
|
|
228
|
+
if let header = groups[index].header {
|
|
229
|
+
Section(header) { _TabSidebarRows(rows: groups[index].rows) }
|
|
230
|
+
} else {
|
|
231
|
+
_TabSidebarRows(rows: groups[index].rows)
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
struct _TabSidebarRows: View {
|
|
239
|
+
let rows: [_TabSidebarRow]
|
|
240
|
+
|
|
241
|
+
var body: some View {
|
|
242
|
+
ForEach(rows, id: \.index) { row in
|
|
243
|
+
Group {
|
|
244
|
+
if let systemImage = row.systemImage {
|
|
245
|
+
Label(row.title, systemImage: systemImage)
|
|
246
|
+
} else {
|
|
247
|
+
Text(row.title)
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
.badge(row.badge)
|
|
251
|
+
.tag(row.index)
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/// The selected tab's content in the detail column.
|
|
257
|
+
struct _TabSidebarDetail {
|
|
258
|
+
let content: any View
|
|
259
|
+
}
|
|
260
|
+
extension _TabSidebarDetail: _PrimitiveView {}
|
|
261
|
+
extension _TabSidebarDetail: _GroupView {
|
|
262
|
+
var _children: [any View] { [content] }
|
|
263
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// Views that start an asynchronous task when they appear.
|
|
2
|
-
protocol _TaskStarting {
|
|
2
|
+
protocol _TaskStarting: _TraitBearing {
|
|
3
3
|
/// Identity of the task; when it changes the task restarts.
|
|
4
4
|
var _taskID: AnyHashable? { get }
|
|
5
5
|
var _taskAction: @Sendable () async -> Void { get }
|
|
@@ -19,7 +19,7 @@ extension _TaskView: _TaskStarting {
|
|
|
19
19
|
var _taskAction: @Sendable () async -> Void { action }
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
extension View {
|
|
22
|
+
nonisolated extension View {
|
|
23
23
|
/// Runs `action` in a task when the view appears, cancelling it when the
|
|
24
24
|
/// view disappears.
|
|
25
25
|
public func task(priority: TaskPriority = .userInitiated,
|