craft-native 0.0.387 → 0.0.392
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/README.md +41 -0
- package/dist/android/templates/CraftNativeCapabilities.kt.template +107 -39
- package/dist/android/templates/MainActivityNative.kt.template +2 -0
- package/dist/browser/checkpoints.d.ts +6 -0
- package/dist/browser.js +186 -26
- package/dist/cli.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/ios/templates/CraftHybrid.swift +16 -3
- package/dist/ios/templates/CraftNativeActions.swift +4 -3
- package/dist/ios/templates/CraftNativeFiles.swift +227 -94
- package/dist/ios/templates/CraftNativeScreen.swift +39 -12
- package/dist/types.d.ts +4 -0
- package/package.json +1 -1
|
@@ -7367,6 +7367,7 @@ final class CraftNativeScreenController: UIViewController, UIScrollViewDelegate,
|
|
|
7367
7367
|
}
|
|
7368
7368
|
if options.keys.contains("backgroundColor") || options.keys.contains("navigationBarSolid") {
|
|
7369
7369
|
applyNavigationBarAppearance()
|
|
7370
|
+
trackContentScrollView()
|
|
7370
7371
|
}
|
|
7371
7372
|
// Asked for after the bar was hidden for a bare root screen.
|
|
7372
7373
|
if navigationBarHidden == nil, wantsNavigationBar, navigationController?.topViewController === self,
|
|
@@ -7589,7 +7590,14 @@ final class CraftNativeScreenController: UIViewController, UIScrollViewDelegate,
|
|
|
7589
7590
|
/// title collapses as it scrolls, and the bar's background follows it.
|
|
7590
7591
|
private func trackContentScrollView() {
|
|
7591
7592
|
guard let renderedRoot else { return }
|
|
7593
|
+
// UIKit can resize the root before nested flex wrappers lay out.
|
|
7594
|
+
// Resolve their frames before checking empty siblings or edges so
|
|
7595
|
+
// old child frames cannot toggle the root constraints each pass.
|
|
7596
|
+
rootStack.layoutIfNeeded()
|
|
7592
7597
|
func find(_ node: RenderedNode) -> UIScrollView? {
|
|
7598
|
+
// Modal content belongs to a separate presentation. Hidden
|
|
7599
|
+
// branches must not steal tracking from the visible screen.
|
|
7600
|
+
guard node.type != "Modal", !node.view.isHidden else { return nil }
|
|
7593
7601
|
if let scroll = node.view as? CraftNativeScrollView, scroll.isVertical, scroll.isScrollEnabled { return scroll }
|
|
7594
7602
|
if let list = node.view as? CraftNativeFlatList, list.isScrollEnabled,
|
|
7595
7603
|
(list.collectionViewLayout as? UICollectionViewFlowLayout)?.scrollDirection != .horizontal { return list }
|
|
@@ -7606,12 +7614,12 @@ final class CraftNativeScreenController: UIViewController, UIScrollViewDelegate,
|
|
|
7606
7614
|
return list.isScrollEnabled && (list.collectionViewLayout as? UICollectionViewFlowLayout)?.scrollDirection != .horizontal ? node : nil
|
|
7607
7615
|
}
|
|
7608
7616
|
guard paddingInsets(node.style).top == 0,
|
|
7609
|
-
let first = node.children.first(where: { $0.type != "Modal" && !$0.view.isHidden }) else { return nil }
|
|
7617
|
+
let first = node.children.first(where: { $0.type != "Modal" && !$0.view.isHidden && $0.view.bounds.height > 0 }) else { return nil }
|
|
7610
7618
|
return leading(first)
|
|
7611
7619
|
}
|
|
7612
7620
|
let scroll = find(renderedRoot)
|
|
7613
7621
|
let leadingScroll = leading(renderedRoot)
|
|
7614
|
-
//
|
|
7622
|
+
// The leading scroller may overflow beneath navigation chrome.
|
|
7615
7623
|
// A bounded list inside a form must clip its rows to its viewport.
|
|
7616
7624
|
if let leadingScroll, leadingScroll.style["overflow"] as? String != "hidden" {
|
|
7617
7625
|
leadingScroll.view.clipsToBounds = false
|
|
@@ -7626,13 +7634,16 @@ final class CraftNativeScreenController: UIViewController, UIScrollViewDelegate,
|
|
|
7626
7634
|
let edgeToEdge = scroll != nil && (prefersLargeTitle == true || scroll === leadingScroll?.view)
|
|
7627
7635
|
let fullEdgeToEdge = rootIsSafeAreaView
|
|
7628
7636
|
let topEdgeToEdge = fullEdgeToEdge || edgeToEdge
|
|
7629
|
-
//
|
|
7630
|
-
//
|
|
7631
|
-
//
|
|
7637
|
+
// Bottom clearance does not depend on the leading-scroll rule for
|
|
7638
|
+
// navigation titles. Follow the visible scroller through wrappers,
|
|
7639
|
+
// even after a header or empty sibling. Its laid-out viewport must
|
|
7640
|
+
// reach the root's bottom; zero-size/hidden siblings do not shorten
|
|
7641
|
+
// it. A bounded list, fixed footer, plain screen or presented sheet
|
|
7642
|
+
// must retain its safe-area bottom.
|
|
7632
7643
|
// Use UIKit's automatic inset for tab/accessory clearance, rather
|
|
7633
7644
|
// than adding a second explicit inset (also owned by keyboard code).
|
|
7634
7645
|
var tabbedScroll = false
|
|
7635
|
-
if let scroll, scroll
|
|
7646
|
+
if let scroll, scroll.bounds.height > 0,
|
|
7636
7647
|
let tabBar = tabBarController?.tabBar, !tabBar.isHidden, tabBar.alpha > 0,
|
|
7637
7648
|
let window = view.window, tabBar.window === window,
|
|
7638
7649
|
tabBar.convert(tabBar.bounds, to: view).intersects(view.bounds) {
|
|
@@ -7653,12 +7664,28 @@ final class CraftNativeScreenController: UIViewController, UIScrollViewDelegate,
|
|
|
7653
7664
|
rootLeadingToView?.isActive = fullEdgeToEdge
|
|
7654
7665
|
rootTrailingToSafeArea?.isActive = !fullEdgeToEdge
|
|
7655
7666
|
rootTrailingToView?.isActive = fullEdgeToEdge
|
|
7656
|
-
scroll?.contentInsetAdjustmentBehavior = edgeToEdge ? .automatic : .never
|
|
7657
|
-
|
|
7658
|
-
|
|
7659
|
-
|
|
7660
|
-
|
|
7661
|
-
|
|
7667
|
+
scroll?.contentInsetAdjustmentBehavior = (edgeToEdge || tabbedScroll) ? .automatic : .never
|
|
7668
|
+
if scroll !== trackedScrollView {
|
|
7669
|
+
#if compiler(>=6.2)
|
|
7670
|
+
if #available(iOS 26.0, *) {
|
|
7671
|
+
trackedScrollView?.topEdgeEffect.isHidden = false
|
|
7672
|
+
trackedScrollView?.bottomEdgeEffect.isHidden = false
|
|
7673
|
+
}
|
|
7674
|
+
#endif
|
|
7675
|
+
trackedScrollView = scroll
|
|
7676
|
+
// Keep UIKit's title collapse, tab selection and minimization
|
|
7677
|
+
// tracking; only the full-width edge backdrop changes below.
|
|
7678
|
+
setContentScrollView(scroll, for: [.top, .bottom])
|
|
7679
|
+
}
|
|
7680
|
+
#if compiler(>=6.2)
|
|
7681
|
+
if #available(iOS 26.0, *) {
|
|
7682
|
+
// Floating button groups carry their own material. UIKit's
|
|
7683
|
+
// separate scroll-edge wash would cover the content behind
|
|
7684
|
+
// and beyond them even with a transparent bar appearance.
|
|
7685
|
+
scroll?.topEdgeEffect.isHidden = topEdgeToEdge && !navigationBarSolid
|
|
7686
|
+
scroll?.bottomEdgeEffect.isHidden = tabbedScroll
|
|
7687
|
+
}
|
|
7688
|
+
#endif
|
|
7662
7689
|
}
|
|
7663
7690
|
|
|
7664
7691
|
private func observeNativeEvents() {
|
package/dist/types.d.ts
CHANGED
|
@@ -2397,5 +2397,9 @@ export interface MenubarState {
|
|
|
2397
2397
|
hiddenSystemItemCount?: number;
|
|
2398
2398
|
preserveSystemItems?: boolean;
|
|
2399
2399
|
markerWidth?: number;
|
|
2400
|
+
/** Read-only access to the macOS 27 menu bar arrangement. */
|
|
2401
|
+
layoutAuthorized?: boolean;
|
|
2402
|
+
/** Saved native control position, or -1 before an arrangement is available. */
|
|
2403
|
+
layoutPosition?: number;
|
|
2400
2404
|
error?: 'unavailable' | 'permissionRequired' | 'layoutUnavailable' | 'emptyGroup' | 'visibilityMismatch' | 'activationFailed' | 'activationTimeout' | null;
|
|
2401
2405
|
}
|