@momo-kits/native-kits 0.168.1-beta.11-debug → 0.168.1-beta.13
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/.claude/settings.local.json +185 -0
- package/CLAUDE.md +3 -2
- package/ios/Layout/ScreenLayout.swift +23 -3
- package/ios/Navigation/BottomSheet.swift +150 -22
- package/ios/Navigation/Component/SnackBar.swift +4 -0
- package/ios/Navigation/ModalScreen.swift +7 -3
- package/ios/Popup/PopupDisplay.swift +2 -2
- package/ios/Popup/PopupInput.swift +2 -2
- package/ios/Popup/PopupLayout.swift +15 -8
- package/ios/Popup/PopupNotify.swift +2 -2
- package/ios/native-kits.podspec +1 -1
- package/ios-demo/MoMoUIKitsDemo.podspec +1 -1
- package/package.json +1 -1
- package/build.gradle.kts +0 -11
- package/compose/build.gradle.kts +0 -198
- package/compose/build.gradle.kts.backup +0 -198
- package/compose/compose.podspec +0 -47
- package/compose/src/androidMain/kotlin/vn/momo/kits/const/HostFont.android.kt +0 -20
- package/compose/src/androidMain/kotlin/vn/momo/kits/navigation/ScrollToTop.android.kt +0 -6
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/BackGesture.android.kt +0 -12
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/OsFontScale.android.kt +0 -7
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +0 -153
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/ReservedRegions.android.kt +0 -6
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +0 -110
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/DesignSystemKits.kt +0 -62
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +0 -1071
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Localize.kt +0 -269
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/WidgetContainer.kt +0 -56
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Avatar.kt +0 -157
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +0 -81
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +0 -32
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +0 -338
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +0 -175
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +0 -357
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +0 -115
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +0 -89
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +0 -128
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +0 -209
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +0 -542
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +0 -49
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +0 -86
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +0 -125
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +0 -231
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +0 -189
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +0 -478
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +0 -114
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +0 -265
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +0 -235
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +0 -223
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +0 -265
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +0 -185
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +0 -343
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Loader.kt +0 -108
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +0 -56
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +0 -41
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +0 -84
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +0 -40
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +0 -361
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +0 -108
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +0 -308
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +0 -59
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Rating.kt +0 -87
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +0 -21
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +0 -90
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +0 -330
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +0 -220
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +0 -473
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +0 -122
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +0 -207
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +0 -92
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +0 -560
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +0 -86
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +0 -125
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +0 -207
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +0 -501
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +0 -176
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +0 -182
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +0 -193
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +0 -29
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +0 -236
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +0 -180
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +0 -325
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/HostFont.kt +0 -17
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Radius.kt +0 -12
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +0 -16
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +0 -194
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +0 -287
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +0 -54
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +0 -50
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/ScreenLayout.kt +0 -306
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +0 -41
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +0 -52
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +0 -66
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Conditional.kt +0 -11
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +0 -104
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +0 -48
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Size.kt +0 -51
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +0 -338
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/HostBackGestureBridge.kt +0 -58
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +0 -137
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +0 -116
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +0 -205
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +0 -399
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ScrollToTop.kt +0 -8
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +0 -732
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackTransition.kt +0 -148
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/SwipeBackHaptic.kt +0 -35
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +0 -228
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +0 -217
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +0 -86
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/DuoBarCompression.kt +0 -97
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/DuoTabBar.kt +0 -377
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +0 -169
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +0 -455
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +0 -105
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderJourney.kt +0 -106
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderLocation.kt +0 -74
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +0 -399
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +0 -39
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +0 -363
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SideBar.kt +0 -192
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +0 -133
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +0 -127
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/BackGesture.kt +0 -12
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +0 -91
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/OsFontScale.kt +0 -9
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +0 -74
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ReservedRegions.kt +0 -20
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +0 -1329
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +0 -55
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +0 -15
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +0 -118
- package/compose/src/iosMain/kotlin/vn/momo/kits/const/HostFont.ios.kt +0 -42
- package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/HostBackGesture.ios.kt +0 -45
- package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/ScrollToTop.ios.kt +0 -32
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/BackGesture.ios.kt +0 -38
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/OsFontScale.ios.kt +0 -66
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +0 -218
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/ReservedRegions.ios.kt +0 -138
- package/gradle/libs.versions.toml +0 -69
- package/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/gradle/wrapper/gradle-wrapper.properties +0 -8
- package/gradle.properties +0 -26
- package/gradlew +0 -252
- package/gradlew.bat +0 -94
- package/ios-demo/README.md +0 -120
- package/settings.gradle.kts +0 -64
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(curl -s -o /dev/null -w \"%{http_code}\" \"https://repo.maven.apache.org/maven2/org/jetbrains/skiko/skiko-android/0.144.6/skiko-android-0.144.6.pom\")",
|
|
5
|
+
"Bash(curl -s \"https://repo.maven.apache.org/maven2/org/jetbrains/skiko/skiko-android/maven-metadata.xml\")",
|
|
6
|
+
"Bash(curl -s \"https://repo.maven.apache.org/maven2/org/jetbrains/skiko/skiko/maven-metadata.xml\")",
|
|
7
|
+
"Bash(curl -s \"https://repo.maven.apache.org/maven2/org/jetbrains/skiko/skiko/0.144.6/skiko-0.144.6.module\")",
|
|
8
|
+
"Bash(curl -s -o /dev/null -w '%{http_code}' https://repo.maven.apache.org/maven2/org/jetbrains/skiko/skiko-android/0.144.6/skiko-android-0.144.6.__TRACKED_VAR__)",
|
|
9
|
+
"Bash(curl -s \"https://repo.maven.apache.org/maven2/org/jetbrains/skiko/skiko-android/0.144.6/\")",
|
|
10
|
+
"Bash(curl -s \"https://repo.maven.apache.org/maven2/org/jetbrains/skiko/skiko-android/\")",
|
|
11
|
+
"Bash(curl -s -o /dev/null -w \"%{http_code}\\\\n\" \"https://repo.maven.apache.org/maven2/org/jetbrains/skiko/skiko-android/0.148.1/skiko-android-0.148.1.pom\")",
|
|
12
|
+
"Bash(curl -s -o /dev/null -w \"%{http_code}\\\\n\" \"https://repo.maven.apache.org/maven2/org/jetbrains/skiko/skiko-android/0.144.5/skiko-android-0.144.5.pom\")",
|
|
13
|
+
"Bash(curl -s -o /dev/null -w \"%{http_code}\\\\n\" \"https://dl.google.com/dl/android/maven2/org/jetbrains/skiko/skiko-android/0.144.6/skiko-android-0.144.6.pom\")",
|
|
14
|
+
"Bash(curl -s \"https://search.maven.org/solrsearch/select?q=a:skiko-android&rows=5&wt=json\")",
|
|
15
|
+
"Bash(curl -sL -o /dev/null -w \"%{http_code} %{url_effective}\\\\n\" \"https://repo1.maven.org/maven2/org/jetbrains/skiko/skiko-android/0.144.6/skiko-android-0.144.6.pom\")",
|
|
16
|
+
"Bash(curl *)",
|
|
17
|
+
"Bash(./gradlew :sample:androidApp:dependencies --configuration debugRuntimeClasspath)",
|
|
18
|
+
"Bash(./gradlew :sample:shared:compileDebugKotlinAndroid)",
|
|
19
|
+
"Bash(./gradlew :sample:androidApp:compileDebugKotlin)",
|
|
20
|
+
"Bash(ls -d *.xcodeproj)",
|
|
21
|
+
"Bash(grep -c ChipDemo.swift __TRACKED_VAR__/project.pbxproj)",
|
|
22
|
+
"Bash(grep -c PBXFileSystemSynchronizedRootGroup __TRACKED_VAR__/project.pbxproj)",
|
|
23
|
+
"Bash(grep -c InformationDemo.swift __TRACKED_VAR__/project.pbxproj)",
|
|
24
|
+
"Bash(plutil -lint project.pbxproj)",
|
|
25
|
+
"Bash(xcode-select -p)",
|
|
26
|
+
"Bash(/usr/bin/xcrun xcodebuild *)",
|
|
27
|
+
"Bash(echo \"exit: $?\")",
|
|
28
|
+
"Bash(/Applications/Xcode26.app/Contents/Developer/usr/bin/xcodebuild -version)",
|
|
29
|
+
"Bash(./gradlew :compose:tasks --all)",
|
|
30
|
+
"Bash(grep -n \"vanniktech\\\\|mavenPublishing\\\\|^publishing\\\\|version = gitlabVersion\\\\|namespace =\\\\|compileSdk =\\\\|minSdk =\\\\|GitLabPackages\\\\|name = \\\\\"\\\\${gitlabRepo}Packages\\\\\"\")",
|
|
31
|
+
"Bash(git checkout *)",
|
|
32
|
+
"Bash(./gradlew :compose:publishAllPublicationsToGitLabPackagesRepository --dry-run)",
|
|
33
|
+
"Bash(git fetch *)",
|
|
34
|
+
"Bash(git pull *)",
|
|
35
|
+
"Bash(git push *)",
|
|
36
|
+
"Bash(git branch *)",
|
|
37
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -list)",
|
|
38
|
+
"Bash(xcrun simctl *)",
|
|
39
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 14 Pro' -configuration Debug build CODE_SIGNING_ALLOWED=NO)",
|
|
40
|
+
"Bash(pod install *)",
|
|
41
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'id=1E6F9A79-5E64-4590-BEA2-828D75D99393' -configuration Debug build CODE_SIGNING_ALLOWED=NO)",
|
|
42
|
+
"Bash(xcrun swiftc *)",
|
|
43
|
+
"Bash(echo \"=== exit: $? \\(1=none found\\) ===\")",
|
|
44
|
+
"Bash(cat Radius.swift)",
|
|
45
|
+
"Bash(cat Spacing.swift)",
|
|
46
|
+
"Bash(echo \"exit=$?\")",
|
|
47
|
+
"Bash(ruby *)",
|
|
48
|
+
"Bash(xcodebuild -list -workspace iosApp.xcworkspace)",
|
|
49
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme MoMoUIKits -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 14 Pro' build)",
|
|
50
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme MoMoUIKits -sdk iphonesimulator -destination 'platform=iOS Simulator,id=E6A899C0-098E-473A-95B8-A2BBD2D42A92' build)",
|
|
51
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'platform=iOS Simulator,id=E6A899C0-098E-473A-95B8-A2BBD2D42A92' build)",
|
|
52
|
+
"Bash(xcodebuild build *)",
|
|
53
|
+
"Bash(git stash *)",
|
|
54
|
+
"Bash(plutil -lint sample/iosApp/iosApp.xcodeproj/project.pbxproj)",
|
|
55
|
+
"Bash(git add *)",
|
|
56
|
+
"Bash(git commit -m 'feat: DS-646 [ci build] *)",
|
|
57
|
+
"Bash(git commit -q -m 'fix: DS-656 [ci build] *)",
|
|
58
|
+
"Bash(xargs git log --oneline -1)",
|
|
59
|
+
"Bash(git rev-list *)",
|
|
60
|
+
"Bash(git status *)",
|
|
61
|
+
"Bash(git rebase *)",
|
|
62
|
+
"Bash(git merge *)",
|
|
63
|
+
"Bash(git reset *)",
|
|
64
|
+
"Bash(awk '/^ *)",
|
|
65
|
+
"Bash(git ls-tree *)",
|
|
66
|
+
"Bash(awk *)",
|
|
67
|
+
"Read(//Users/sophia/Workspace/momo/momo-app/**)",
|
|
68
|
+
"Bash(git log *)",
|
|
69
|
+
"Bash(xcodebuild -version)",
|
|
70
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -configuration Debug build CODE_SIGNING_ALLOWED=NO)",
|
|
71
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme MoMoUIKits -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -configuration Debug build CODE_SIGNING_ALLOWED=NO)",
|
|
72
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme MoMoUIKits -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -configuration Debug clean build CODE_SIGNING_ALLOWED=NO)",
|
|
73
|
+
"Bash(git commit *)",
|
|
74
|
+
"Bash(npm view *)",
|
|
75
|
+
"Bash(echo \"EXIT=$? -> not resolvable\")",
|
|
76
|
+
"Bash(yarn install *)",
|
|
77
|
+
"Bash(RCT_NEW_ARCH_ENABLED=1 pod install)",
|
|
78
|
+
"Bash(xcodebuild -workspace MoMoPlatform.xcworkspace -list)",
|
|
79
|
+
"Bash(git --no-pager diff --stat ios/Application/Localize.swift ios/Application/Navigation/NavigationContainer.swift ios/Popup/PopupDisplay.swift ios/Popup/PopupNotify.swift ios/Template/TrustBanner/TrustBanner.swift)",
|
|
80
|
+
"Bash(git rm *)",
|
|
81
|
+
"Bash(echo \"EXIT=$?\")",
|
|
82
|
+
"Bash(git -C /Users/sophia/Workspace/momo/momo-native-kits diff sample/iosApp/iosApp/Demo/ButtonDemo.swift)",
|
|
83
|
+
"Bash(python3 *)",
|
|
84
|
+
"Bash(git -C /Users/sophia/Workspace/momo/momo-native-kits status --short)",
|
|
85
|
+
"Bash(git -C /Users/sophia/Workspace/momo/momo-native-kits log --oneline -3)",
|
|
86
|
+
"Bash(git -C /Users/sophia/Workspace/momo/momo-native-kits log --oneline -5 -- ios/Button/Button.swift)",
|
|
87
|
+
"Bash(git -C /Users/sophia/Workspace/momo/momo-native-kits diff ios/native-kits.podspec compose/compose.podspec gradle.properties package.json)",
|
|
88
|
+
"Bash(git -C /Users/sophia/Workspace/momo/momo-native-kits show HEAD:ios/Button/Button.swift)",
|
|
89
|
+
"Bash(git -C /Users/sophia/Workspace/momo/momo-native-kits diff package.json ios/native-kits.podspec)",
|
|
90
|
+
"Bash(grep -n \"must be a \\\\`.background\\\\` of the label\" /Users/sophia/Workspace/momo/momo-app/node_modules/@momo-kits/native-kits/ios/Button/Button.swift)",
|
|
91
|
+
"Bash(git -C /Users/sophia/Workspace/momo/momo-native-kits show -s --format=\"%h %ci %s\" 953b234d)",
|
|
92
|
+
"Bash(git -C /Users/sophia/Workspace/momo/momo-app show -s --format=\"%h %ci %s\" f8757a14437)",
|
|
93
|
+
"Bash(git -C /Users/sophia/Workspace/momo/momo-app log -S '\"@momo-kits/native-kits\": \"0.163.1-beta.18\"' --format=\"%h %ci %s\" -- package.json)",
|
|
94
|
+
"Bash(swiftc -O repro_isfull.swift -o repro_isfull)",
|
|
95
|
+
"Bash(./repro_isfull)",
|
|
96
|
+
"Bash(grep -n '^\\\\[32;1m$\\\\|section_start\\\\|xcodebuild.*-workspace\\\\|xcodebuild.*archive\\\\|Prebuilt\\\\|prebuilt\\\\|framework.*download\\\\|rugby\\\\|Rugby' /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/7e2b5bd7-f8b3-42f7-b242-127fa8eabd12/scratchpad/job_trace.log)",
|
|
97
|
+
"Bash(grep -n '\\\\[32;1m\\\\$' /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/7e2b5bd7-f8b3-42f7-b242-127fa8eabd12/scratchpad/job_trace.log)",
|
|
98
|
+
"Bash(npm pack *)",
|
|
99
|
+
"Bash(mkdir -p b13 b18)",
|
|
100
|
+
"Bash(tar xzf *)",
|
|
101
|
+
"Bash(git *)",
|
|
102
|
+
"Bash(tar -tzf momo-kits-native-kits-0.163.1-beta.18.tgz)",
|
|
103
|
+
"Bash(tar -xzf momo-kits-native-kits-0.163.1-beta.18.tgz package/ios/Button/Button.swift)",
|
|
104
|
+
"Bash(tar -xzf momo-kits-native-kits-0.162.28.tgz package/ios/Button/Button.swift -C .)",
|
|
105
|
+
"Bash(mkdir -p old)",
|
|
106
|
+
"Bash(tar -xzf momo-kits-native-kits-0.162.28.tgz -C old package/ios/Button/Button.swift)",
|
|
107
|
+
"Bash(nm '/private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/7e2b5bd7-f8b3-42f7-b242-127fa8eabd12/scratchpad/ipa_extract/Payload/MoMoPlatform UAT.app/MoMoPlatform UAT')",
|
|
108
|
+
"Bash(xcodebuild -workspace /Users/sophia/Workspace/momo/momo-native-kits/sample/iosApp/iosApp.xcworkspace -list)",
|
|
109
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme MoMoUIKits -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' build)",
|
|
110
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -derivedDataPath build-verify build)",
|
|
111
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme MoMoUIKits -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -derivedDataPath build-verify build)",
|
|
112
|
+
"Bash(./gradlew :sample:shared:syncComposeResourcesForIos)",
|
|
113
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'platform=iOS Simulator,id=E6A899C0-098E-473A-95B8-A2BBD2D42A92' -derivedDataPath build-verify build)",
|
|
114
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme MoMoUIKits -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -quiet build)",
|
|
115
|
+
"Bash(xcodebuild -workspace sample/iosApp/iosApp.xcworkspace -list)",
|
|
116
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -destination 'id=0228A4B2-57E0-4E56-BFAD-DB9E95044AD9' -derivedDataPath /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/6986983a-795d-419d-9d78-fcc100e87876/scratchpad/dd build)",
|
|
117
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -destination 'id=1E6F9A79-5E64-4590-BEA2-828D75D99393' -derivedDataPath /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/6986983a-795d-419d-9d78-fcc100e87876/scratchpad/dd build)",
|
|
118
|
+
"Bash([ -s $S/kb.png ])",
|
|
119
|
+
"Bash(sips -g pixelWidth -g pixelHeight /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/6986983a-795d-419d-9d78-fcc100e87876/scratchpad/kb.png)",
|
|
120
|
+
"Bash(defaults read *)",
|
|
121
|
+
"Bash(defaults write *)",
|
|
122
|
+
"Bash(xcrun xcodebuild *)",
|
|
123
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -quiet build)",
|
|
124
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'platform=iOS Simulator,id=E6A899C0-098E-473A-95B8-A2BBD2D42A92' -quiet build)",
|
|
125
|
+
"Read(//tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/3e8adc08-a7e7-4169-aee6-8b22a6996f38/scratchpad/**)",
|
|
126
|
+
"Bash(echo \"parse-exit=$?\")",
|
|
127
|
+
"Bash(echo \"=== exit $?\")",
|
|
128
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -configuration Debug build)",
|
|
129
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'platform=iOS Simulator,id=E6A899C0-098E-473A-95B8-A2BBD2D42A92' -configuration Debug build)",
|
|
130
|
+
"Bash(./gradlew :sample:shared:compileCommonMainKotlinMetadata -q)",
|
|
131
|
+
"Bash(echo \"gradle=$?\")",
|
|
132
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -sdk iphonesimulator -destination 'id=0228A4B2-57E0-4E56-BFAD-DB9E95044AD9' -derivedDataPath build/dd build)",
|
|
133
|
+
"Bash(osascript *)",
|
|
134
|
+
"Bash(screencapture -x -R253,53,452,950 win.png)",
|
|
135
|
+
"Bash(sips -g pixelWidth -g pixelHeight win.png)",
|
|
136
|
+
"Bash(screencapture -x -R\"253,53,452,950\" win.png)",
|
|
137
|
+
"Bash(screencapture -x full.png)",
|
|
138
|
+
"Bash(sips -g pixelWidth -g pixelHeight full.png)",
|
|
139
|
+
"Bash(sips -c 1900 904 --cropOffset 106 506 full.png --out crop.png)",
|
|
140
|
+
"Bash(swiftc -O mouse.swift -o mouse)",
|
|
141
|
+
"Bash(./mouse click *)",
|
|
142
|
+
"Bash(./mouse drag *)",
|
|
143
|
+
"Bash(sips -c 900 924 --cropOffset 0 0 s12.png --out s12crop.png)",
|
|
144
|
+
"Bash(sips -c 300 1170 --cropOffset 300 0 s12.png --out s12top.png)",
|
|
145
|
+
"Bash(sips -c 700 1170 --cropOffset 250 0 t1.png --out t1c.png)",
|
|
146
|
+
"Bash(sips -c 700 1170 --cropOffset 250 0 t2.png --out t2c.png)",
|
|
147
|
+
"Bash(sips -c 700 1170 --cropOffset 150 0 t3.png --out t3c.png)",
|
|
148
|
+
"Bash(sips -c 1200 1170 --cropOffset 600 0 t4.png --out t4c.png)",
|
|
149
|
+
"Bash(sips -c 600 1170 --cropOffset 150 0 t5.png --out t5c.png)",
|
|
150
|
+
"Bash(sips -c 500 1170 --cropOffset 150 0 u1.png --out u1c.png)",
|
|
151
|
+
"Bash(cp /Users/sophia/Workspace/momo/momo-native-kits/ios/Application/Navigation/NavigationContainer.swift /Users/sophia/Workspace/momo/momo-app/node_modules/@momo-kits/native-kits/ios/Application/Navigation/NavigationContainer.swift)",
|
|
152
|
+
"Bash(cp /Users/sophia/Workspace/momo/momo-native-kits/ios/Application/Navigation/Navigator.swift /Users/sophia/Workspace/momo/momo-app/node_modules/@momo-kits/native-kits/ios/Application/Navigation/Navigator.swift)",
|
|
153
|
+
"Bash(cp /Users/sophia/Workspace/momo/momo-native-kits/ios/Application/Navigation/NavigatorManager.swift /Users/sophia/Workspace/momo/momo-app/node_modules/@momo-kits/native-kits/ios/Application/Navigation/NavigatorManager.swift)",
|
|
154
|
+
"Bash(cp /Users/sophia/Workspace/momo/momo-native-kits/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift /Users/sophia/Workspace/momo/momo-app/node_modules/@momo-kits/native-kits/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift)",
|
|
155
|
+
"Bash(xcodebuild -workspace MoMoPlatform.xcworkspace -scheme MoMoPlatform-UAT -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -derivedDataPath build/DerivedData build)",
|
|
156
|
+
"Bash(cp android/gradle/libs.versions.toml /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/bfb380ee-54cb-4a02-bc5f-d152cce4b727/scratchpad/libs.versions.toml.bak)",
|
|
157
|
+
"Bash(sed -i '' 's/kits = \"0.163.1-sp.8\"/kits = \"0.163.1-sp.7\"/' android/gradle/libs.versions.toml)",
|
|
158
|
+
"Bash(xcrun --sdk iphonesimulator --show-sdk-path)",
|
|
159
|
+
"Bash(chmod +x /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/62b6dcd2-247f-4111-98ef-3847c8914676/scratchpad/tc.sh)",
|
|
160
|
+
"Bash(/private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/62b6dcd2-247f-4111-98ef-3847c8914676/scratchpad/tc.sh)",
|
|
161
|
+
"Bash(perl -0pi -e 's{^ static let \\(\\\\w+\\) = \\(appFont\\\\\\(size: [\\\\d.]+\\\\\\)\\(?:\\\\.weight\\\\\\(\\\\.\\\\w+\\\\\\)\\)?\\)\\(\\\\s*//.*\\)?$}{ static var $1: Font { $2 }$3}mg' ios/Typography/Typography.swift)",
|
|
162
|
+
"Bash(perl -0pi -e 's{\\(\\\\s*\\)// AI-GENERATED START: route Localize injection through the observing modifier\\\\n\\(\\\\s*\\)\\\\.momoLocalize\\\\\\(localize\\\\\\)\\\\n\\(\\\\s*\\)// AI-GENERATED END: route Localize injection through the observing modifier}{$1// AI-GENERATED START: route Localize + font-scale injection through the observing modifiers\\\\n$2.momoLocalize\\(localize\\)\\\\n$2.momoFontScale\\(\\)\\\\n$3// AI-GENERATED END: route Localize + font-scale injection through the observing modifiers}g' ios/Application/Navigation/NavigationContainer.swift)",
|
|
163
|
+
"Bash(perl -pi -e 's/Mirrors Compose.s `fontScale\\\\\\(\\\\.\\\\.\\\\.\\\\\\)`/Mirrors Compose'\"'\"'s `scaleSize\\(...\\)`/' ios/Chip/Chip.swift)",
|
|
164
|
+
"Bash(perl -pi -e 's/fontScale\\\\\\(\\(size == \\\\.small \\\\? 48 : 56\\), 1\\\\.1\\\\\\)/fontScale\\($1\\)/' ios/Input/Input.swift ios/Input/InputPhoneNumber.swift)",
|
|
165
|
+
"Bash(perl -pi -e 's/^\\(\\\\s*\\)\\\\.momoFontScale\\\\\\(\\\\\\)$/$1.momoFontScale\\(context: applicationEnvironment.applicationContext\\)/' ios/Application/Navigation/NavigationContainer.swift)",
|
|
166
|
+
"Bash(chmod +x /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/62b6dcd2-247f-4111-98ef-3847c8914676/scratchpad/tcdemo.sh)",
|
|
167
|
+
"Bash(/private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/62b6dcd2-247f-4111-98ef-3847c8914676/scratchpad/tcdemo.sh)",
|
|
168
|
+
"Bash(\"/Users/sophia/Workspace/momo-glab/momo-agent-flows/momo-agent/scripts/repo.sh\" find *)",
|
|
169
|
+
"Read(//Users/sophia/.momo-agent/**)",
|
|
170
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -configuration Debug -destination 'platform=iOS Simulator,name=iPhone 16 Pro' -derivedDataPath /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/62b6dcd2-247f-4111-98ef-3847c8914676/scratchpad/dd build)",
|
|
171
|
+
"Bash(\"/Users/sophia/Workspace/momo-glab/momo-agent-flows/momo-agent/scripts/repo.sh\" prep *)",
|
|
172
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -configuration Debug -destination id=1E6F9A79-5E64-4590-BEA2-828D75D99393 -derivedDataPath /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/62b6dcd2-247f-4111-98ef-3847c8914676/scratchpad/dd build)",
|
|
173
|
+
"Bash(find /private/tmp/claude-503/-Users-sophia-Workspace-momo-momo-native-kits/62b6dcd2-247f-4111-98ef-3847c8914676/scratchpad/dd/Build/Products -maxdepth 2 -name *.app)",
|
|
174
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -configuration Debug -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -derivedDataPath build/dd build)",
|
|
175
|
+
"Bash(xcodebuild -workspace iosApp.xcworkspace -scheme iosApp -configuration Debug -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -derivedDataPath build/dd ARCHS=arm64 ONLY_ACTIVE_ARCH=YES build)",
|
|
176
|
+
"Bash(./gradlew :compose:generateDummyFramework)",
|
|
177
|
+
"Bash(break)",
|
|
178
|
+
"Bash(\"/Users/sophia/Workspace/momo-glab/momo-agent-flows/momo-agent/scripts/gitlab.sh\" mr-view *)",
|
|
179
|
+
"Bash(\"/Users/sophia/Workspace/momo-glab/momo-agent-flows/momo-agent/scripts/gitlab.sh\" mr-discussions *)",
|
|
180
|
+
"Bash(command -v glab)",
|
|
181
|
+
"Bash(glab --version)",
|
|
182
|
+
"Bash(/Users/sophia/Workspace/momo-glab/momo-agent-flows/momo-agent/scripts/jira.sh transitions *)"
|
|
183
|
+
]
|
|
184
|
+
}
|
|
185
|
+
}
|
package/CLAUDE.md
CHANGED
|
@@ -71,7 +71,7 @@ Publishing is automated (`publish.sh` + GitLab CI on `[ci build]` / `main`). Do
|
|
|
71
71
|
## Screen layout / iPhone Duo (port of RN `useScreenLayout`, momo-kits !664)
|
|
72
72
|
|
|
73
73
|
- `layout/ScreenLayout.kt`: `getScreenLayout()` returns window size, raw top/bottom + side insets, `contentWidth`, header geometry, the iPhone Duo `sideBar` and `duoTopInset`. `NavigationContainer` computes it once and provides `LocalScreenLayout`; reactive to fold/unfold and rotation (window size + `WindowInsets`). Metrics (`DuoMetrics`, 72pt iPhone header floor, 20pt status-bar threshold) mirror RN `Layout/utils.ts` — change both together.
|
|
74
|
-
- iPhone-only: everything gates on `isPhoneIdiom()` (`platform/`), never on "iOS", so iPad windows keep the regular layout. Two detectors, as in RN: `isIPhoneDuo` (window aspect < 1.6 or asymmetric side insets) drives layout; `isIPhoneDuoDevice` (Apple's foldable check: a `.division` reserved region, queried with include-inactive; Swift also latches on `UIHingeInteraction
|
|
74
|
+
- iPhone-only: everything gates on `isPhoneIdiom()` (`platform/`), never on "iOS", so iPad windows keep the regular layout. Two detectors, as in RN: `isIPhoneDuo` (window aspect < 1.6 or asymmetric side insets) drives layout; `isIPhoneDuoDevice` (Apple's foldable check: a `.division` reserved region, queried with include-inactive; Swift also latches on `UIHingeInteraction`; or asymmetric side insets, since the outer display reports no hinge) drives popups, modal and bottom sheet.
|
|
75
75
|
- Header height is `headerHeight` (not `AppStatusBar + HEADER_HEIGHT`); the bar row is `headerBarHeight` and starts `headerStatusBarHeight` below the window top. When the status bar is off the top edge (iPhone landscape, iPhone Duo) `headerStatusBarHeight` is 0 so the title stays centered — except on the Duo outer display: in portrait the header is 76pt and the row starts at 14pt so the title centers on the camera punchout; in landscape the row centers on the camera when it sits at the top end of the strip (else on the back button) and the header reaches 8pt below the back button.
|
|
76
76
|
- iPhone Duo inner display in portrait (status bar on top): the header row shares the status bar band — `headerHeight` 94pt (2 × the clock digits' y 47), `headerStatusBarHeight` 0 — and `ScreenLayout.statusBarClearance` keeps it between the clock / battery clusters (from reserved regions, else 128pt on the right). Back and toolkit use the 48pt side bar controls laid out horizontally (`ToolkitLayout.SideBarRow`); the collapsed search and a centered title stay clear of the clusters. Port of momo-kits `90af33ba2`.
|
|
77
77
|
- iPhone Duo with a side strip ≥ 60pt: back + toolkit leave the bar for `HeaderSideBar` (`navigation/component/SideBar.kt`, 48pt glass controls); custom header-right stays in the bar. `sideBar.top` is 170pt in portrait, 120pt on the inner display in landscape (height ≥ 600), 24pt on the outer display in landscape, or below the header when the status bar is on top; UIKit's `statusBarFrame` is useless on Duo. Unlike RN the column is clamped above footer (24pt gap) / rail (12pt gap).
|
|
@@ -80,7 +80,8 @@ Publishing is automated (`publish.sh` + GitLab CI on `[ci build]` / `main`). Do
|
|
|
80
80
|
- Bar compression (`bottomtab/DuoBarCompression.kt`, HIG "Vertical controls"): when toolbar + rail don't fit in the strip, one is compressed — the toolkit into a `navigation_menu` button, the rail into one button showing the current tab — and tapping it swaps them; `BottomTab(compressionBehavior)` picks which starts compressed. If neither fits beside the other compressed, both rest compressed and a tap opens one for a moment. Side bar columns report their full height (0 when the screen puts nothing there) so the decision follows each screen's toolkit.
|
|
81
81
|
- Glass header: on Duo with a side bar, Default/Extended headers without search and with a `ScrollState` let content scroll under the bar (`usesDuoGlassHeader`); the bar fades in a translucent surface + hairline over 16pt (Compose has no backdrop blur — RN's fallback look), the gradient leaves with the content.
|
|
82
82
|
- Quick return header: glass headers and Animated headers (with a `ScrollState`) on the Duo side bar layout slide out with the content and back in on a reverse scroll; a half-shown header settles in or out once the scroll stops. The side bar is drawn apart from the header, so it stays put.
|
|
83
|
-
- Overlays on Duo:
|
|
83
|
+
- Overlays on Duo: the modal sits inside the safe area (all four insets, so clear of the side toolbar strip) and caps its content at `duoModalMaxWidth` / `duoModalMaxHeight` (440 × 640pt, at least XL off the safe area); popups fill that width with radius XL and drop their own side padding (body scrolls, actions stay). Snackbars keep clear of the strip.
|
|
84
|
+
- Bottom sheet on Duo: radius XL, window height, centered at width ≥ 600 (inner display, buttons stay in the header row). Below that (outer display) it floats `Spacing.M` off the side edges, pads header/content/footer by `inset − M`, and a `Title` header moves back / close into 48pt side bar buttons on the strip part of the sheet (HIG: sheet controls go vertical on the outer display) when the strip fits one; they follow the header row while the sheet is short and stay below `sideBar.top` when it is tall. `BottomHeader.Title(onBack)` / `.title(onBack:)` closes the sheet, then runs (RN `leftOptions.onPressIconLeft`).
|
|
84
85
|
- Font scale deliberately uses the short side (`min(w, h)`), unlike RN which reads the window width — landscape must not inflate every font.
|
|
85
86
|
- Font scale measures the **window**, never `UIScreen.main`: on iPhone Duo the main screen stays on one display while the window follows the one in use. Compose iOS `getScreenDimensions()` reads `LocalWindowInfo.containerSize` (recomposes on fold/unfold); SwiftUI `DesignSystemKits` KVO-observes each `UIWindowScene.effectiveGeometry` and republishes `windowShortSide`.
|
|
86
87
|
- `StackScreen` pads content/footer/search/FAB by the side insets and provides an inset-consumed layout to its content; a bottom-tab root stays full width (tab bar + each tab's StackScreen handle insets). Grid columns use `contentWidth`.
|
|
@@ -32,7 +32,8 @@ public struct ScreenLayout: Equatable {
|
|
|
32
32
|
public let width: CGFloat
|
|
33
33
|
public let height: CGFloat
|
|
34
34
|
public let isIPhoneDuo: Bool
|
|
35
|
-
///
|
|
35
|
+
/// iPhone Duo folded or not, whatever the window size (its hinge, or the outer display's one-sided strip);
|
|
36
|
+
/// drives popups, modal and bottom sheet.
|
|
36
37
|
public let isDuoDevice: Bool
|
|
37
38
|
public let insets: EdgeInsets
|
|
38
39
|
public let insetLeft: CGFloat
|
|
@@ -75,6 +76,11 @@ enum DuoMetrics {
|
|
|
75
76
|
static let floatingTabBarHeight: CGFloat = 62
|
|
76
77
|
static let floatingTabBarMargin: CGFloat = 20
|
|
77
78
|
static let floatingTabBarInsetOverlap: CGFloat = 13
|
|
79
|
+
// Width of a system alert on the inner display, in both orientations.
|
|
80
|
+
static let modalMaxWidth: CGFloat = 440
|
|
81
|
+
// Fits a PopupNotify with image, scrolled description and actions at the max width (RN
|
|
82
|
+
// Application/device.ts); taller content scrolls instead of filling the inner display.
|
|
83
|
+
static let modalMaxHeight: CGFloat = 640
|
|
78
84
|
}
|
|
79
85
|
|
|
80
86
|
enum HeaderMetrics {
|
|
@@ -178,8 +184,10 @@ extension ScreenLayout {
|
|
|
178
184
|
)
|
|
179
185
|
}
|
|
180
186
|
|
|
187
|
+
// the outer display reports no hinge; its one-sided strip still gives it away
|
|
181
188
|
return ScreenLayout(
|
|
182
|
-
width: width, height: height, isIPhoneDuo: true,
|
|
189
|
+
width: width, height: height, isIPhoneDuo: true,
|
|
190
|
+
isDuoDevice: isDuoDevice || insets.leading != insets.trailing, insets: insets,
|
|
183
191
|
insetLeft: insets.leading, insetRight: insets.trailing,
|
|
184
192
|
contentWidth: width - insets.leading - insets.trailing,
|
|
185
193
|
headerHeight: headerHeight, headerStatusBarHeight: headerStatusBarHeight, sideBar: sideBar,
|
|
@@ -256,12 +264,24 @@ extension ScreenLayout {
|
|
|
256
264
|
public var duoTopInset: CGFloat {
|
|
257
265
|
max(insets.top, height > width ? max(insets.leading, insets.trailing) * 2 : 0)
|
|
258
266
|
}
|
|
267
|
+
|
|
268
|
+
/// Room for a dialog on iPhone Duo: inside the safe area, so clear of the side toolbar strip, and
|
|
269
|
+
/// capped so it stays a dialog on the inner display.
|
|
270
|
+
var duoModalMaxWidth: CGFloat {
|
|
271
|
+
min(width - insets.leading - insets.trailing - Spacing.XL * 2, DuoMetrics.modalMaxWidth)
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
var duoModalMaxHeight: CGFloat {
|
|
275
|
+
min(height - insets.top - insets.bottom - Spacing.XL * 2, DuoMetrics.modalMaxHeight)
|
|
276
|
+
}
|
|
259
277
|
}
|
|
260
278
|
|
|
261
279
|
/// Snapshot for call sites without `\.screenLayout`; not reactive. `windowSize` is ignored,
|
|
262
280
|
/// kept for host call sites.
|
|
263
281
|
public func isIPhoneDuoDevice(windowSize: CGSize? = nil) -> Bool {
|
|
264
|
-
isPhoneIdiom
|
|
282
|
+
guard isPhoneIdiom else { return false }
|
|
283
|
+
let insets = keyWindow?.safeAreaInsets
|
|
284
|
+
return FoldableDevice.isFoldable(measuredIn: keyWindow) || insets.map { $0.left != $0.right } == true
|
|
265
285
|
}
|
|
266
286
|
|
|
267
287
|
/// Apple's foldable check (as the host's `SideTabRailView.isFoldableDevice`): only a device with a
|
|
@@ -15,16 +15,25 @@ import SwiftUI
|
|
|
15
15
|
|
|
16
16
|
/// Mirrors Compose's `sealed class BottomHeader` (Title / Custom).
|
|
17
17
|
public struct BottomSheetHeader {
|
|
18
|
+
struct Back {
|
|
19
|
+
let icon: String
|
|
20
|
+
let action: () -> Void
|
|
21
|
+
}
|
|
22
|
+
|
|
18
23
|
enum Style {
|
|
19
|
-
case title(String)
|
|
24
|
+
case title(String, back: Back?)
|
|
20
25
|
case custom(() -> AnyView)
|
|
21
26
|
}
|
|
22
27
|
|
|
23
28
|
let style: Style
|
|
24
29
|
|
|
25
|
-
/// Mirrors `BottomHeader.Title`.
|
|
26
|
-
public static func title(
|
|
27
|
-
|
|
30
|
+
/// Mirrors `BottomHeader.Title`. `onBack` shows a back button; the sheet closes, then it runs.
|
|
31
|
+
public static func title(
|
|
32
|
+
_ text: String = "Bottom Sheet Title",
|
|
33
|
+
backIcon: String = "arrow-back",
|
|
34
|
+
onBack: (() -> Void)? = nil
|
|
35
|
+
) -> BottomSheetHeader {
|
|
36
|
+
BottomSheetHeader(style: .title(text, back: onBack.map { Back(icon: backIcon, action: $0) }))
|
|
28
37
|
}
|
|
29
38
|
|
|
30
39
|
/// Mirrors `BottomHeader.Custom`.
|
|
@@ -68,6 +77,9 @@ struct BottomSheetView<Content: View>: View {
|
|
|
68
77
|
/// Mirrors Compose's `sheetCloseOffset` (100dp drag threshold to dismiss).
|
|
69
78
|
private let closeThreshold: CGFloat = 100
|
|
70
79
|
|
|
80
|
+
private let indicatorHeight: CGFloat = 16
|
|
81
|
+
private let headerRowHeight: CGFloat = 56
|
|
82
|
+
|
|
71
83
|
/// Mirrors Compose's per-term peak (0.3f). Combined with `backgroundAlpha` the
|
|
72
84
|
/// steady-state (fully open) scrim peaks at 0.6, matching ModalScreen's peak.
|
|
73
85
|
private let maxDynamicAlpha: CGFloat = 0.3
|
|
@@ -78,6 +90,21 @@ struct BottomSheetView<Content: View>: View {
|
|
|
78
90
|
private var isDuo: Bool { layout.isDuoDevice }
|
|
79
91
|
// iPhone Duo inner display: center the sheet instead of spanning the width
|
|
80
92
|
private var isDuoCentered: Bool { isDuo && layout.width >= 600 }
|
|
93
|
+
/// Outer display: the sheet floats Spacing.M off the side edges like system sheets, its content
|
|
94
|
+
/// stays in the safe area and its buttons move to the side bar column (HIG).
|
|
95
|
+
private var isDuoFloating: Bool { isDuo && !isDuoCentered }
|
|
96
|
+
|
|
97
|
+
private var titleBack: BottomSheetHeader.Back? {
|
|
98
|
+
if case .title(_, let back) = header.style { return back }
|
|
99
|
+
return nil
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private var sideColumn: SideBarLayout? {
|
|
103
|
+
guard isDuoFloating, case .title = header.style, let sideBar = layout.sideBar,
|
|
104
|
+
sideBar.width - Spacing.M >= DuoMetrics.controlSize + Spacing.M
|
|
105
|
+
else { return nil }
|
|
106
|
+
return sideBar
|
|
107
|
+
}
|
|
81
108
|
|
|
82
109
|
/// Keeps the portrait width in landscape, like system sheets.
|
|
83
110
|
private var duoCenteredWidth: CGFloat {
|
|
@@ -87,18 +114,19 @@ struct BottomSheetView<Content: View>: View {
|
|
|
87
114
|
)
|
|
88
115
|
}
|
|
89
116
|
|
|
90
|
-
///
|
|
91
|
-
/// side status bar only covers the top corner.
|
|
117
|
+
/// The floating sheet spans the side safe area, its content stays clear of it.
|
|
92
118
|
private var sideInsetLeading: CGFloat {
|
|
93
|
-
|
|
119
|
+
isDuoFloating ? max(layout.insets.leading - Spacing.M, 0) : 0
|
|
94
120
|
}
|
|
95
121
|
|
|
96
122
|
private var sideInsetTrailing: CGFloat {
|
|
97
|
-
|
|
123
|
+
isDuoFloating ? max(layout.insets.trailing - Spacing.M, 0) : 0
|
|
98
124
|
}
|
|
99
125
|
|
|
100
126
|
private var maxHeight: CGFloat {
|
|
101
|
-
isDuo
|
|
127
|
+
guard isDuo else { return screenHeight - 90 }
|
|
128
|
+
// with its buttons in the side column the sheet can pass the side status bar
|
|
129
|
+
return layout.height - max(sideColumn != nil ? layout.insets.top : layout.duoTopInset, Spacing.XL)
|
|
102
130
|
}
|
|
103
131
|
private var bottomInset: CGFloat { useBottomInset ? safeAreaBottomInset() : 0 }
|
|
104
132
|
/// While the keyboard is up, it already covers the home-indicator area, so it
|
|
@@ -170,19 +198,21 @@ struct BottomSheetView<Content: View>: View {
|
|
|
170
198
|
.frame(width: 40, height: 4)
|
|
171
199
|
Spacer().frame(height: 4)
|
|
172
200
|
headerView
|
|
173
|
-
.frame(height:
|
|
201
|
+
.frame(height: headerRowHeight)
|
|
174
202
|
.padding(.horizontal, Spacing.M)
|
|
175
|
-
.padding(.leading, sideInsetLeading)
|
|
176
|
-
.padding(.trailing, sideInsetTrailing)
|
|
177
203
|
}
|
|
204
|
+
.padding(.leading, sideInsetLeading)
|
|
205
|
+
.padding(.trailing, sideInsetTrailing)
|
|
178
206
|
.frame(maxWidth: .infinity)
|
|
179
|
-
.frame(height:
|
|
207
|
+
.frame(height: indicatorHeight + headerRowHeight)
|
|
180
208
|
.contentShape(Rectangle())
|
|
181
209
|
.gesture(dragGesture, including: draggable ? .all : .subviews)
|
|
182
210
|
|
|
183
211
|
Rectangle()
|
|
184
212
|
.fill(theme.colors.border.default)
|
|
185
213
|
.frame(height: 1)
|
|
214
|
+
.padding(.leading, sideInsetLeading)
|
|
215
|
+
.padding(.trailing, sideInsetTrailing)
|
|
186
216
|
|
|
187
217
|
content()
|
|
188
218
|
.padding(.leading, sideInsetLeading)
|
|
@@ -191,7 +221,7 @@ struct BottomSheetView<Content: View>: View {
|
|
|
191
221
|
.layoutPriority(-1)
|
|
192
222
|
|
|
193
223
|
if let footer {
|
|
194
|
-
BottomSheetFooter(content: footer)
|
|
224
|
+
BottomSheetFooter(content: footer, leadingInset: sideInsetLeading, trailingInset: sideInsetTrailing)
|
|
195
225
|
}
|
|
196
226
|
}
|
|
197
227
|
// The filler stays outside the cap, which shrinks by it instead: the sheet still ends at
|
|
@@ -209,27 +239,61 @@ struct BottomSheetView<Content: View>: View {
|
|
|
209
239
|
}
|
|
210
240
|
)
|
|
211
241
|
.background(backgroundColor)
|
|
212
|
-
.
|
|
242
|
+
.overlay {
|
|
243
|
+
if let sideColumn {
|
|
244
|
+
BottomSheetSideColumn(
|
|
245
|
+
sideBar: sideColumn,
|
|
246
|
+
windowHeight: layout.height,
|
|
247
|
+
topOffset: indicatorHeight + (headerRowHeight - DuoMetrics.controlSize) / 2,
|
|
248
|
+
back: titleBack,
|
|
249
|
+
onBack: goBack,
|
|
250
|
+
onClose: { close() }
|
|
251
|
+
)
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
.clipShape(RoundedCorner(radius: isDuo ? Radius.XL : Radius.M, corners: [.topLeft, .topRight]))
|
|
255
|
+
.padding(.horizontal, isDuoFloating ? Spacing.M : 0)
|
|
213
256
|
}
|
|
214
257
|
|
|
215
258
|
@ViewBuilder
|
|
216
259
|
private var headerView: some View {
|
|
217
260
|
switch header.style {
|
|
218
|
-
case .title(let text):
|
|
261
|
+
case .title(let text, let back):
|
|
262
|
+
// the side column holds back and close, the row keeps only the title
|
|
263
|
+
let showsButtons = sideColumn == nil
|
|
219
264
|
HStack(spacing: 0) {
|
|
220
|
-
|
|
265
|
+
if showsButtons {
|
|
266
|
+
if let back {
|
|
267
|
+
headerButton(icon: back.icon, accessibilityId: "btn_bottom_sheet_back") { goBack(back) }
|
|
268
|
+
} else {
|
|
269
|
+
Color.clear.frame(width: 24, height: 24)
|
|
270
|
+
}
|
|
271
|
+
}
|
|
221
272
|
MomoText(text, typography: .headerDefaultBold, color: Colors.black17)
|
|
222
273
|
.frame(maxWidth: .infinity, alignment: .center)
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
274
|
+
.padding(.horizontal, showsButtons ? 0 : Spacing.M)
|
|
275
|
+
if showsButtons {
|
|
276
|
+
headerButton(icon: "navigation_close", accessibilityId: "btn_bottom_sheet_close") { close() }
|
|
277
|
+
}
|
|
227
278
|
}
|
|
228
279
|
case .custom(let builder):
|
|
229
280
|
builder()
|
|
230
281
|
}
|
|
231
282
|
}
|
|
232
283
|
|
|
284
|
+
private func headerButton(icon: String, accessibilityId: String, action: @escaping () -> Void) -> some View {
|
|
285
|
+
Icon(source: icon, size: 24, color: Colors.black17)
|
|
286
|
+
.frame(width: 24, height: 24)
|
|
287
|
+
.contentShape(Rectangle())
|
|
288
|
+
.onTapGesture(perform: action)
|
|
289
|
+
.accessibilityIdentifier(accessibilityId)
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/// RN `leftOptions.onPressIconLeft`: the sheet closes first, then the back runs.
|
|
293
|
+
private func goBack(_ back: BottomSheetHeader.Back) {
|
|
294
|
+
close(then: back.action)
|
|
295
|
+
}
|
|
296
|
+
|
|
233
297
|
// MARK: - Drag handling (mirrors Compose's detectDragGestures)
|
|
234
298
|
|
|
235
299
|
private var dragGesture: some Gesture {
|
|
@@ -282,7 +346,7 @@ struct BottomSheetView<Content: View>: View {
|
|
|
282
346
|
|
|
283
347
|
/// Mirrors Compose's `closeEvent`: slide out over 200ms, then fade the scrim
|
|
284
348
|
/// out over 100ms only after the slide finishes, then dismiss.
|
|
285
|
-
private func close() {
|
|
349
|
+
private func close(then onClosed: (() -> Void)? = nil) {
|
|
286
350
|
guard !isClosing else { return }
|
|
287
351
|
isClosing = true
|
|
288
352
|
withAnimation(.timingCurve(0.3, 0, 0.8, 0.15, duration: 0.2)) {
|
|
@@ -294,7 +358,67 @@ struct BottomSheetView<Content: View>: View {
|
|
|
294
358
|
}
|
|
295
359
|
}
|
|
296
360
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
|
|
361
|
+
// a newer overlay replaced this one: it stays, and this sheet's back is dropped
|
|
362
|
+
guard navigator.overplay?.id == overplayId else { return }
|
|
297
363
|
navigator.finishOverplayDismiss(id: overplayId)
|
|
364
|
+
onClosed?()
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/// iPhone Duo outer display: back and close sit on the part of the sheet under the side safe area,
|
|
370
|
+
/// 12pt from the strip's inner edge like the screen side bar. They follow the header row while the
|
|
371
|
+
/// sheet is short and stay below the status bar cluster while it is tall.
|
|
372
|
+
private struct BottomSheetSideColumn: View {
|
|
373
|
+
let sideBar: SideBarLayout
|
|
374
|
+
let windowHeight: CGFloat
|
|
375
|
+
/// Lines the controls up with the header row.
|
|
376
|
+
let topOffset: CGFloat
|
|
377
|
+
let back: BottomSheetHeader.Back?
|
|
378
|
+
let onBack: (BottomSheetHeader.Back) -> Void
|
|
379
|
+
let onClose: () -> Void
|
|
380
|
+
|
|
381
|
+
@Environment(\.appTheme) private var theme
|
|
382
|
+
|
|
383
|
+
private var isRight: Bool { sideBar.edge == .right }
|
|
384
|
+
|
|
385
|
+
private var columnHeight: CGFloat {
|
|
386
|
+
let count: CGFloat = back != nil ? 2 : 1
|
|
387
|
+
return count * DuoMetrics.controlSize + (count - 1) * Spacing.M
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
private var headerColor: HeaderColor {
|
|
391
|
+
getHeaderColor(isAnimated: false, isSurface: true, opacity: 1, tintColor: nil, defaultColor: theme.colors.text.default)
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
var body: some View {
|
|
395
|
+
GeometryReader { proxy in
|
|
396
|
+
let sheetHeight = proxy.size.height
|
|
397
|
+
// the sheet rests on the window bottom; its slide is an offset outside this layout
|
|
398
|
+
let sheetTop = windowHeight - sheetHeight
|
|
399
|
+
// clear of a camera at the bottom end of the strip when it can
|
|
400
|
+
let lowest = sheetHeight - sideBar.bottom - columnHeight
|
|
401
|
+
let top = max(min(max(sideBar.top - sheetTop, topOffset), lowest), 0)
|
|
402
|
+
VStack(alignment: isRight ? .leading : .trailing, spacing: Spacing.M) {
|
|
403
|
+
if let back {
|
|
404
|
+
SideBarButton(
|
|
405
|
+
icon: back.icon,
|
|
406
|
+
headerColor: headerColor,
|
|
407
|
+
accessibilityId: "btn_bottom_sheet_back",
|
|
408
|
+
action: { onBack(back) }
|
|
409
|
+
)
|
|
410
|
+
}
|
|
411
|
+
SideBarButton(
|
|
412
|
+
icon: "navigation_close",
|
|
413
|
+
headerColor: headerColor,
|
|
414
|
+
accessibilityId: "btn_bottom_sheet_close",
|
|
415
|
+
action: onClose
|
|
416
|
+
)
|
|
417
|
+
}
|
|
418
|
+
.padding(isRight ? .leading : .trailing, Spacing.M)
|
|
419
|
+
.frame(width: sideBar.width - Spacing.M, alignment: isRight ? .leading : .trailing)
|
|
420
|
+
.padding(.top, top)
|
|
421
|
+
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: isRight ? .topTrailing : .topLeading)
|
|
298
422
|
}
|
|
299
423
|
}
|
|
300
424
|
}
|
|
@@ -371,12 +495,16 @@ private struct CapHeightLayout: Layout {
|
|
|
371
495
|
/// Mirrors Compose's `BottomSheetFooter`: a surface band with a soft shadow cast on the content.
|
|
372
496
|
private struct BottomSheetFooter: View {
|
|
373
497
|
let content: () -> AnyView
|
|
498
|
+
var leadingInset: CGFloat = 0
|
|
499
|
+
var trailingInset: CGFloat = 0
|
|
374
500
|
|
|
375
501
|
@Environment(\.appTheme) private var theme
|
|
376
502
|
|
|
377
503
|
var body: some View {
|
|
378
504
|
content()
|
|
379
505
|
.frame(maxWidth: .infinity)
|
|
506
|
+
.padding(.leading, leadingInset)
|
|
507
|
+
.padding(.trailing, trailingInset)
|
|
380
508
|
.padding(.vertical, Spacing.S)
|
|
381
509
|
.background(theme.colors.background.surface)
|
|
382
510
|
.overlay(alignment: .top) {
|
|
@@ -57,6 +57,7 @@ struct SnackBarView: View {
|
|
|
57
57
|
let bottomInset: CGFloat
|
|
58
58
|
|
|
59
59
|
@EnvironmentObject private var navigator: Navigator
|
|
60
|
+
@Environment(\.screenLayout) private var layout
|
|
60
61
|
|
|
61
62
|
@State private var contentHeight: CGFloat = 0
|
|
62
63
|
@State private var offsetY: CGFloat = 0
|
|
@@ -75,6 +76,9 @@ struct SnackBarView: View {
|
|
|
75
76
|
)
|
|
76
77
|
.offset(y: offsetY)
|
|
77
78
|
.padding(.bottom, bottomInset)
|
|
79
|
+
// iPhone Duo: clear of the side toolbar strip, like the screen content (0 elsewhere)
|
|
80
|
+
.padding(.leading, layout.insetLeft)
|
|
81
|
+
.padding(.trailing, layout.insetRight)
|
|
78
82
|
}
|
|
79
83
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
80
84
|
.ignoresSafeArea()
|
|
@@ -34,11 +34,15 @@ struct ModalScreen<Content: View>: View {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
content()
|
|
37
|
+
// iPhone Duo: capped so it stays a dialog on the inner display; nil leaves the size alone
|
|
38
|
+
.frame(
|
|
39
|
+
maxWidth: layout.isDuoDevice ? layout.duoModalMaxWidth : nil,
|
|
40
|
+
maxHeight: layout.isDuoDevice ? layout.duoModalMaxHeight : nil
|
|
41
|
+
)
|
|
37
42
|
.scaleEffect(contentScale)
|
|
38
43
|
.opacity(contentOpacity)
|
|
39
|
-
// iPhone Duo: center
|
|
40
|
-
.padding(
|
|
41
|
-
.padding(.bottom, layout.isDuoDevice ? layout.insets.bottom : 0)
|
|
44
|
+
// iPhone Duo: center in the safe area, clear of the side toolbar strip and the home indicator
|
|
45
|
+
.padding(layout.isDuoDevice ? layout.insets : EdgeInsets())
|
|
42
46
|
}
|
|
43
47
|
// Full screen like RN's Modal, so asymmetric landscape insets don't shift the content sideways.
|
|
44
48
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
@@ -107,7 +107,7 @@ public struct PopupDisplay: View {
|
|
|
107
107
|
}
|
|
108
108
|
.fixedSize(horizontal: false, vertical: true)
|
|
109
109
|
.background(theme.colors.background.surface)
|
|
110
|
-
.clipShape(RoundedRectangle(cornerRadius:
|
|
110
|
+
.clipShape(RoundedRectangle(cornerRadius: layout.popupRadius()))
|
|
111
111
|
|
|
112
112
|
if isShowCloseIcon {
|
|
113
113
|
PopupCloseButton(action: onClose)
|
|
@@ -115,7 +115,7 @@ public struct PopupDisplay: View {
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
.frame(maxWidth: layout.popupMaxWidth)
|
|
118
|
-
.padding(.horizontal, 12)
|
|
118
|
+
.padding(.horizontal, layout.popupHorizontalPadding(12))
|
|
119
119
|
.accessibilityElement(children: .contain)
|
|
120
120
|
.accessibilityIdentifier("popup_notify")
|
|
121
121
|
}
|
|
@@ -59,11 +59,11 @@ public struct PopupInput: View {
|
|
|
59
59
|
.offset(x: 11, y: -11)
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
-
.background(theme.colors.background.surface.cornerRadius(8))
|
|
62
|
+
.background(theme.colors.background.surface.cornerRadius(layout.popupRadius(8)))
|
|
63
63
|
.shadow(color: .black.opacity(0.08), radius: 2, x: 0, y: 0)
|
|
64
64
|
.shadow(color: .black.opacity(0.16), radius: 24, x: 0, y: 0)
|
|
65
65
|
.frame(maxWidth: layout.popupMaxWidth)
|
|
66
|
-
.padding(.horizontal, 40)
|
|
66
|
+
.padding(.horizontal, layout.popupHorizontalPadding(40))
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
// MARK: Internal
|