@expo/ui 58.0.8 → 58.0.10
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/CHANGELOG.md +14 -5
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/ui/AnimatedVisibilityView.kt +40 -8
- package/android/src/main/java/expo/modules/ui/ComposeViews.kt +21 -3
- package/android/src/main/java/expo/modules/ui/DatePickerView.kt +12 -4
- package/android/src/main/java/expo/modules/ui/ExpoUIModule.kt +5 -1
- package/android/src/main/java/expo/modules/ui/HorizontalPagerView.kt +3 -1
- package/android/src/main/java/expo/modules/ui/HostView.kt +64 -12
- package/android/src/main/java/expo/modules/ui/LazyItemsView.kt +14 -2
- package/android/src/main/java/expo/modules/ui/ModalBottomSheetView.kt +5 -1
- package/android/src/main/java/expo/modules/ui/ModifierRegistry.kt +29 -4
- package/android/src/main/java/expo/modules/ui/RNHostView.kt +68 -17
- package/android/src/main/java/expo/modules/ui/ShapeView.kt +3 -1
- package/android/src/main/java/expo/modules/ui/SlotView.kt +3 -1
- package/android/src/main/java/expo/modules/ui/SnackbarView.kt +5 -1
- package/android/src/main/java/expo/modules/ui/TextView.kt +3 -1
- package/android/src/main/java/expo/modules/ui/Utils.kt +3 -1
- package/android/src/main/java/expo/modules/ui/colors/MaterialColors.kt +5 -1
- package/android/src/main/java/expo/modules/ui/convertibles/AnimationSpecParams.kt +3 -1
- package/android/src/main/java/expo/modules/ui/graphics/ImageLoader.kt +6 -2
- package/android/src/main/java/expo/modules/ui/icon/IconView.kt +5 -1
- package/android/src/main/java/expo/modules/ui/state/ObservableState.kt +3 -1
- package/android/src/main/java/expo/modules/ui/textfield/BasicTextField.kt +10 -2
- package/android/src/main/java/expo/modules/ui/textfield/TextField.kt +20 -4
- package/android/src/main/java/expo/modules/ui/textfield/TextFieldShared.kt +3 -1
- package/build/community/picker/Picker.android.js +7 -0
- package/build/community/picker/Picker.android.js.map +1 -1
- package/build/jetpack-compose/LazyColumn/index.d.ts +2 -1
- package/build/jetpack-compose/LazyColumn/index.js +1 -0
- package/build/jetpack-compose/LazyColumn/index.js.map +1 -1
- package/build/jetpack-compose/LazyItems/index.d.ts +19 -18
- package/build/jetpack-compose/LazyItems/index.js +1 -2
- package/build/jetpack-compose/LazyItems/index.js.map +1 -1
- package/build/jetpack-compose/LazyRow/index.d.ts +2 -1
- package/build/jetpack-compose/LazyRow/index.js +1 -0
- package/build/jetpack-compose/LazyRow/index.js.map +1 -1
- package/build/jetpack-compose/RNHostView/index.d.ts +6 -1
- package/build/jetpack-compose/RNHostView/index.js +9 -4
- package/build/jetpack-compose/RNHostView/index.js.map +1 -1
- package/build/jetpack-compose/index.d.ts +0 -1
- package/build/jetpack-compose/index.js.map +1 -1
- package/build/jetpack-compose/modifiers/index.d.ts +18 -3
- package/build/jetpack-compose/modifiers/index.js +15 -2
- package/build/jetpack-compose/modifiers/index.js.map +1 -1
- package/build/swift-ui/LazyHStack/index.d.ts +45 -0
- package/build/swift-ui/LazyHStack/index.js +9 -0
- package/build/swift-ui/LazyHStack/index.js.map +1 -1
- package/build/swift-ui/LazyStackForEach/index.d.ts +44 -0
- package/build/swift-ui/LazyStackForEach/index.js +54 -0
- package/build/swift-ui/LazyStackForEach/index.js.map +1 -0
- package/build/swift-ui/LazyVStack/index.d.ts +45 -0
- package/build/swift-ui/LazyVStack/index.js +9 -0
- package/build/swift-ui/LazyVStack/index.js.map +1 -1
- package/build/swift-ui/List/DataListForEach.d.ts +6 -7
- package/build/swift-ui/List/DataListForEach.js.map +1 -1
- package/build/swift-ui/List/ListForEach.d.ts +7 -1
- package/build/swift-ui/List/ListForEach.js +1 -5
- package/build/swift-ui/List/ListForEach.js.map +1 -1
- package/build/swift-ui/RNHostView.d.ts +7 -2
- package/build/swift-ui/RNHostView.js +7 -3
- package/build/swift-ui/RNHostView.js.map +1 -1
- package/build/swift-ui/index.d.ts +1 -0
- package/build/swift-ui/index.js.map +1 -1
- package/build/swift-ui/modifiers/containerBackground.d.ts +2 -2
- package/build/swift-ui/modifiers/containerBackground.js +2 -2
- package/build/swift-ui/modifiers/index.d.ts +9 -1
- package/build/swift-ui/modifiers/index.js +9 -0
- package/build/swift-ui/modifiers/index.js.map +1 -1
- package/build/universal/ListItem/ListItem.js +11 -2
- package/build/universal/ListItem/ListItem.js.map +1 -1
- package/build/universal/RNHostView/index.js +12 -5
- package/build/universal/RNHostView/index.js.map +1 -1
- package/build/universal/RNHostView/types.d.ts +9 -4
- package/build/universal/RNHostView/types.js.map +1 -1
- package/build/universal/Switch/index.android.js +5 -1
- package/build/universal/Switch/index.android.js.map +1 -1
- package/build/utils/matchContents.d.ts +10 -0
- package/build/utils/matchContents.js +16 -0
- package/build/utils/matchContents.js.map +1 -0
- package/expo-module.config.json +0 -1
- package/ios/DataListForEachView.swift +65 -28
- package/ios/ExpoUIModule.swift +0 -1
- package/ios/LazyHStackView.swift +3 -0
- package/ios/LazyVStackView.swift +3 -0
- package/ios/ListView.swift +8 -0
- package/ios/Modifiers/ContainerBackgroundModifier.swift +23 -16
- package/ios/Modifiers/PreferredColorSchemeModifier.swift +12 -0
- package/ios/Modifiers/View+ModifierArray.swift +3 -3
- package/ios/Modifiers/ViewModifierRegistry.swift +11 -9
- package/ios/Modifiers/WidgetKitModifiers.swift +13 -0
- package/ios/RNHostView.swift +55 -9
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.10/expo.modules.ui-58.0.10-sources.jar +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.10/expo.modules.ui-58.0.10-sources.jar.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.10/expo.modules.ui-58.0.10-sources.jar.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.10/expo.modules.ui-58.0.10-sources.jar.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.10/expo.modules.ui-58.0.10-sources.jar.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.10/expo.modules.ui-58.0.10.aar +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.10/expo.modules.ui-58.0.10.aar.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.10/expo.modules.ui-58.0.10.aar.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.10/expo.modules.ui-58.0.10.aar.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.10/expo.modules.ui-58.0.10.aar.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/{58.0.8/expo.modules.ui-58.0.8.module → 58.0.10/expo.modules.ui-58.0.10.module} +22 -22
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.10/expo.modules.ui-58.0.10.module.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.10/expo.modules.ui-58.0.10.module.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.10/expo.modules.ui-58.0.10.module.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.10/expo.modules.ui-58.0.10.module.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/{58.0.8/expo.modules.ui-58.0.8.pom → 58.0.10/expo.modules.ui-58.0.10.pom} +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.10/expo.modules.ui-58.0.10.pom.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.10/expo.modules.ui-58.0.10.pom.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.10/expo.modules.ui-58.0.10.pom.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.10/expo.modules.ui-58.0.10.pom.sha512 +1 -0
- package/package.json +3 -3
- package/prebuilds/output/debug/xcframeworks/ExpoUI.tar.gz +0 -0
- package/prebuilds/output/release/xcframeworks/ExpoUI.tar.gz +0 -0
- package/src/community/picker/Picker.android.tsx +5 -0
- package/src/jetpack-compose/LazyColumn/index.tsx +2 -0
- package/src/jetpack-compose/LazyItems/index.tsx +18 -21
- package/src/jetpack-compose/LazyRow/index.tsx +2 -0
- package/src/jetpack-compose/RNHostView/index.tsx +17 -6
- package/src/jetpack-compose/index.ts +0 -1
- package/src/jetpack-compose/modifiers/index.ts +16 -3
- package/src/swift-ui/LazyHStack/index.tsx +45 -0
- package/src/swift-ui/LazyStackForEach/index.tsx +110 -0
- package/src/swift-ui/LazyVStack/index.tsx +45 -0
- package/src/swift-ui/List/DataListForEach.tsx +7 -8
- package/src/swift-ui/List/ListForEach.tsx +10 -3
- package/src/swift-ui/RNHostView.tsx +11 -4
- package/src/swift-ui/index.tsx +1 -0
- package/src/swift-ui/modifiers/containerBackground.ts +2 -2
- package/src/swift-ui/modifiers/index.ts +11 -0
- package/src/universal/ListItem/ListItem.tsx +10 -1
- package/src/universal/RNHostView/index.tsx +8 -3
- package/src/universal/RNHostView/types.ts +6 -4
- package/src/universal/Switch/index.android.tsx +11 -2
- package/src/utils/matchContents.ts +14 -0
- package/ios/AccessoryWidgetBackgroundView.swift +0 -27
- package/ios/Modifiers/WidgetModifiers.swift +0 -70
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.8/expo.modules.ui-58.0.8-sources.jar +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.8/expo.modules.ui-58.0.8-sources.jar.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.8/expo.modules.ui-58.0.8-sources.jar.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.8/expo.modules.ui-58.0.8-sources.jar.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.8/expo.modules.ui-58.0.8-sources.jar.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.8/expo.modules.ui-58.0.8.aar +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.8/expo.modules.ui-58.0.8.aar.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.8/expo.modules.ui-58.0.8.aar.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.8/expo.modules.ui-58.0.8.aar.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.8/expo.modules.ui-58.0.8.aar.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.8/expo.modules.ui-58.0.8.module.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.8/expo.modules.ui-58.0.8.module.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.8/expo.modules.ui-58.0.8.module.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.8/expo.modules.ui-58.0.8.module.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.8/expo.modules.ui-58.0.8.pom.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.8/expo.modules.ui-58.0.8.pom.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.8/expo.modules.ui-58.0.8.pom.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.8/expo.modules.ui-58.0.8.pom.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +0 -13
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +0 -1
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { StyleSheet, View } from 'react-native';
|
|
3
|
+
import { resolveMatchContents } from '../../utils/matchContents';
|
|
3
4
|
import { useUniversalLifecycle } from '../hooks';
|
|
4
5
|
const styles = StyleSheet.create({
|
|
5
|
-
|
|
6
|
-
width: '100%'
|
|
6
|
+
fillWidth: {
|
|
7
|
+
width: '100%'
|
|
8
|
+
},
|
|
9
|
+
fillHeight: {
|
|
7
10
|
height: '100%'
|
|
8
11
|
},
|
|
9
|
-
|
|
10
|
-
width: 'fit-content'
|
|
12
|
+
fitWidth: {
|
|
13
|
+
width: 'fit-content'
|
|
14
|
+
},
|
|
15
|
+
fitHeight: {
|
|
11
16
|
height: 'fit-content'
|
|
12
17
|
},
|
|
13
18
|
hidden: {
|
|
@@ -18,11 +23,13 @@ const styles = StyleSheet.create({
|
|
|
18
23
|
* Hosts React Native views inside Jetpack Compose or SwiftUI views.
|
|
19
24
|
*/ export function RNHostView({ children, style, onAppear, onDisappear, hidden = false, testID, matchContents = false, onLayout }) {
|
|
20
25
|
useUniversalLifecycle(onAppear, onDisappear);
|
|
26
|
+
const { horizontal, vertical } = resolveMatchContents(matchContents);
|
|
21
27
|
return /*#__PURE__*/ _jsx(View, {
|
|
22
28
|
testID: testID,
|
|
23
29
|
onLayout: onLayout,
|
|
24
30
|
style: [
|
|
25
|
-
|
|
31
|
+
horizontal ? styles.fitWidth : styles.fillWidth,
|
|
32
|
+
vertical ? styles.fitHeight : styles.fillHeight,
|
|
26
33
|
style,
|
|
27
34
|
hidden && styles.hidden
|
|
28
35
|
],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["universal/RNHostView/index.tsx"],"sourcesContent":[null],"names":["StyleSheet","View","useUniversalLifecycle","styles","create","
|
|
1
|
+
{"version":3,"sources":["universal/RNHostView/index.tsx"],"sourcesContent":[null],"names":["StyleSheet","View","resolveMatchContents","useUniversalLifecycle","styles","create","fillWidth","width","fillHeight","height","fitWidth","fitHeight","hidden","display","RNHostView","children","style","onAppear","onDisappear","testID","matchContents","onLayout","horizontal","vertical"],"mappings":";AAAA,SAASA,UAAU,EAAEC,IAAI,QAAQ,eAAe;AAEhD,SAASC,oBAAoB,QAAQ,4BAA4B;AACjE,SAASC,qBAAqB,QAAQ,WAAW;AAGjD,MAAMC,SAASJ,WAAWK,MAAM,CAAC;IAC/BC,WAAW;QAAEC,OAAO;IAAO;IAC3BC,YAAY;QAAEC,QAAQ;IAAO;IAC7BC,UAAU;QAAEH,OAAO;IAAc;IACjCI,WAAW;QAAEF,QAAQ;IAAc;IACnCG,QAAQ;QAAEC,SAAS;IAAO;AAC5B;AAEA;;CAEC,GACD,OAAO,SAASC,WAAW,EACzBC,QAAQ,EACRC,KAAK,EACLC,QAAQ,EACRC,WAAW,EACXN,SAAS,KAAK,EACdO,MAAM,EACNC,gBAAgB,KAAK,EACrBC,QAAQ,EACQ;IAChBlB,sBAAsBc,UAAUC;IAChC,MAAM,EAAEI,UAAU,EAAEC,QAAQ,EAAE,GAAGrB,qBAAqBkB;IAEtD,qBACE,KAACnB;QACCkB,QAAQA;QACRE,UAAUA;QACVL,OAAO;YACLM,aAAalB,OAAOM,QAAQ,GAAGN,OAAOE,SAAS;YAC/CiB,WAAWnB,OAAOO,SAAS,GAAGP,OAAOI,UAAU;YAC/CQ;YACAJ,UAAUR,OAAOQ,MAAM;SACxB;kBACAG;;AAGP;AAEA,cAAc,UAAU"}
|
|
@@ -6,16 +6,21 @@ import type { UniversalBaseProps } from '../types';
|
|
|
6
6
|
*/
|
|
7
7
|
export interface RNHostViewProps extends UniversalBaseProps {
|
|
8
8
|
/**
|
|
9
|
-
* When `true`, the host updates its size in the
|
|
10
|
-
* the children's size. When `false`, the host uses the size of the parent
|
|
11
|
-
*
|
|
9
|
+
* When `true`, the host updates its size in the SwiftUI or Compose view tree to
|
|
10
|
+
* match the children's size. When `false`, the host uses the size of the parent
|
|
11
|
+
* SwiftUI or Compose view. Pass an object to choose per axis. For example,
|
|
12
|
+
* `{ vertical: true }` takes the width from the parent and the height from the
|
|
13
|
+
* children, so text wraps and grows vertically.
|
|
12
14
|
*
|
|
13
15
|
* Can only be set once on mount; changing it remounts the component.
|
|
14
16
|
* @default false
|
|
15
17
|
* @platform android
|
|
16
18
|
* @platform ios
|
|
17
19
|
*/
|
|
18
|
-
matchContents?: boolean
|
|
20
|
+
matchContents?: boolean | {
|
|
21
|
+
vertical?: boolean;
|
|
22
|
+
horizontal?: boolean;
|
|
23
|
+
};
|
|
19
24
|
onLayout?: (event: LayoutChangeEvent) => void;
|
|
20
25
|
/**
|
|
21
26
|
* The React Native view to host.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["universal/RNHostView/types.ts"],"sourcesContent":[null],"names":[],"mappings":"AAKA;;CAEC,GACD,
|
|
1
|
+
{"version":3,"sources":["universal/RNHostView/types.ts"],"sourcesContent":[null],"names":[],"mappings":"AAKA;;CAEC,GACD,WAqBC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Row, Switch as ComposeSwitch, Text } from '@expo/ui/jetpack-compose';
|
|
3
|
-
import { testID as testIDModifier, weight } from '@expo/ui/jetpack-compose/modifiers';
|
|
3
|
+
import { fillMaxWidth, IntrinsicSize, testID as testIDModifier, weight, width } from '@expo/ui/jetpack-compose/modifiers';
|
|
4
4
|
export function Switch({ value, onValueChange, label, disabled, testID, modifiers }) {
|
|
5
5
|
const toggle = /*#__PURE__*/ _jsx(ComposeSwitch, {
|
|
6
6
|
value: value,
|
|
@@ -19,6 +19,10 @@ export function Switch({ value, onValueChange, label, disabled, testID, modifier
|
|
|
19
19
|
horizontalArrangement: {
|
|
20
20
|
spacedBy: 8
|
|
21
21
|
},
|
|
22
|
+
modifiers: [
|
|
23
|
+
fillMaxWidth(),
|
|
24
|
+
width(IntrinsicSize.Max)
|
|
25
|
+
],
|
|
22
26
|
children: [
|
|
23
27
|
/*#__PURE__*/ _jsx(Text, {
|
|
24
28
|
modifiers: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["universal/Switch/index.android.tsx"],"sourcesContent":[null],"names":["Row","Switch","ComposeSwitch","Text","testID","testIDModifier","weight","value","onValueChange","label","disabled","modifiers","toggle","onCheckedChange","undefined","enabled","verticalAlignment","horizontalArrangement","spacedBy"],"mappings":";AAAA,SAASA,GAAG,EAAEC,UAAUC,aAAa,EAAEC,IAAI,QAAQ,2BAA2B;AAC9E,
|
|
1
|
+
{"version":3,"sources":["universal/Switch/index.android.tsx"],"sourcesContent":[null],"names":["Row","Switch","ComposeSwitch","Text","fillMaxWidth","IntrinsicSize","testID","testIDModifier","weight","width","value","onValueChange","label","disabled","modifiers","toggle","onCheckedChange","undefined","enabled","verticalAlignment","horizontalArrangement","spacedBy","Max"],"mappings":";AAAA,SAASA,GAAG,EAAEC,UAAUC,aAAa,EAAEC,IAAI,QAAQ,2BAA2B;AAC9E,SACEC,YAAY,EACZC,aAAa,EACbC,UAAUC,cAAc,EACxBC,MAAM,EACNC,KAAK,QACA,qCAAqC;AAI5C,OAAO,SAASR,OAAO,EAAES,KAAK,EAAEC,aAAa,EAAEC,KAAK,EAAEC,QAAQ,EAAEP,MAAM,EAAEQ,SAAS,EAAe;IAC9F,MAAMC,uBACJ,KAACb;QACCQ,OAAOA;QACPM,iBAAiBH,WAAWI,YAAYN;QACxCO,SAAS,CAACL;QACVC,WAAW;eAAKA,aAAa,EAAE;eAAOR,SAAS;gBAACC,eAAeD;aAAQ,GAAG,EAAE;SAAE;;IAIlF,IAAIM,SAAS,MAAM,OAAOG;IAE1B,qBACE,MAACf;QACCmB,mBAAkB;QAClBC,uBAAuB;YAAEC,UAAU;QAAE;QACrCP,WAAW;YAACV;YAAgBK,MAAMJ,cAAciB,GAAG;SAAE;;0BACrD,KAACnB;gBAAKW,WAAW;oBAACN,OAAO;iBAAG;0BAAGI;;YAC9BG;;;AAGP;AAEA,cAAc,UAAU"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves `RNHostView`'s `matchContents` prop to one flag per axis.
|
|
3
|
+
*/
|
|
4
|
+
export declare function resolveMatchContents(matchContents: boolean | {
|
|
5
|
+
vertical?: boolean;
|
|
6
|
+
horizontal?: boolean;
|
|
7
|
+
} | null | undefined): {
|
|
8
|
+
horizontal: boolean;
|
|
9
|
+
vertical: boolean;
|
|
10
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves `RNHostView`'s `matchContents` prop to one flag per axis.
|
|
3
|
+
*/ export function resolveMatchContents(matchContents) {
|
|
4
|
+
if (matchContents != null && typeof matchContents === 'object') {
|
|
5
|
+
return {
|
|
6
|
+
horizontal: matchContents.horizontal ?? false,
|
|
7
|
+
vertical: matchContents.vertical ?? false
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
return {
|
|
11
|
+
horizontal: matchContents ?? false,
|
|
12
|
+
vertical: matchContents ?? false
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=matchContents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["utils/matchContents.ts"],"sourcesContent":[null],"names":["resolveMatchContents","matchContents","horizontal","vertical"],"mappings":"AAAA;;CAEC,GACD,OAAO,SAASA,qBACdC,aAAwF;IAExF,IAAIA,iBAAiB,QAAQ,OAAOA,kBAAkB,UAAU;QAC9D,OAAO;YACLC,YAAYD,cAAcC,UAAU,IAAI;YACxCC,UAAUF,cAAcE,QAAQ,IAAI;QACtC;IACF;IACA,OAAO;QAAED,YAAYD,iBAAiB;QAAOE,UAAUF,iBAAiB;IAAM;AAChF"}
|
package/expo-module.config.json
CHANGED
|
@@ -3,7 +3,26 @@
|
|
|
3
3
|
import ExpoModulesCore
|
|
4
4
|
import SwiftUI
|
|
5
5
|
|
|
6
|
+
// The axis the rows scroll along: vertical in `List` and `LazyVStack`, horizontal in `LazyHStack`.
|
|
7
|
+
enum DataListForEachAxis: String, Enumerable {
|
|
8
|
+
case vertical
|
|
9
|
+
case horizontal
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
private struct ContainerCrossAxisSizeKey: EnvironmentKey {
|
|
13
|
+
static let defaultValue: CGFloat = 0
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
extension EnvironmentValues {
|
|
17
|
+
// Set by `ListView`, `LazyVStackView` and `LazyHStackView`, so recycled rows reset their cached sizes when it changes.
|
|
18
|
+
var containerCrossAxisSize: CGFloat {
|
|
19
|
+
get { self[ContainerCrossAxisSizeKey.self] }
|
|
20
|
+
set { self[ContainerCrossAxisSizeKey.self] = newValue }
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
6
24
|
final class DataListForEachProps: UIBaseViewProps {
|
|
25
|
+
@Field var axis: DataListForEachAxis = .vertical
|
|
7
26
|
@Field var itemKeys: [String] = []
|
|
8
27
|
@Field var revision: Int = 0
|
|
9
28
|
@Field var estimatedItemSize: Double = 64
|
|
@@ -79,6 +98,7 @@ private struct DataListForEachRow: View {
|
|
|
79
98
|
@ObservedObject var listProps: DataListForEachProps
|
|
80
99
|
@ObservedObject var poolProps: DataListForEachPoolProps
|
|
81
100
|
let window: DataListForEachWindow
|
|
101
|
+
@Environment(\.containerCrossAxisSize) private var crossAxisSize
|
|
82
102
|
@State private var appeared = false
|
|
83
103
|
@State private var visibilityID = UUID()
|
|
84
104
|
|
|
@@ -99,27 +119,27 @@ private struct DataListForEachRow: View {
|
|
|
99
119
|
itemKey: itemKey,
|
|
100
120
|
index: index,
|
|
101
121
|
revision: listProps.revision,
|
|
102
|
-
|
|
122
|
+
estimatedSize: CGFloat(listProps.estimatedItemSize),
|
|
123
|
+
axis: listProps.axis,
|
|
103
124
|
window: window
|
|
104
125
|
)
|
|
105
126
|
} else {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
.
|
|
127
|
+
DataListForEachPlaceholder(
|
|
128
|
+
size: window.size(for: itemKey, fallback: listProps.estimatedItemSize),
|
|
129
|
+
axis: listProps.axis
|
|
130
|
+
)
|
|
109
131
|
}
|
|
110
132
|
}
|
|
111
|
-
.frame(maxWidth: .infinity, alignment: .leading)
|
|
112
133
|
.onAppear {
|
|
113
134
|
appeared = true
|
|
135
|
+
window.updateCrossAxisSize(crossAxisSize)
|
|
114
136
|
window.appear(itemKey, index: index, token: visibilityID, props: listProps)
|
|
115
137
|
}
|
|
138
|
+
.onChange(of: crossAxisSize) { window.updateCrossAxisSize($0) }
|
|
116
139
|
.onChange(of: listProps.revision) { _ in
|
|
117
140
|
window.reset(listProps)
|
|
118
141
|
if appeared { window.appear(itemKey, index: index, token: visibilityID, props: listProps) }
|
|
119
142
|
}
|
|
120
|
-
.onGeometryChange(for: CGFloat.self, of: { $0.size.width }, action: { width in
|
|
121
|
-
window.updateWidth(width)
|
|
122
|
-
})
|
|
123
143
|
.onDisappear {
|
|
124
144
|
appeared = false
|
|
125
145
|
window.disappear(itemKey, token: visibilityID)
|
|
@@ -127,12 +147,25 @@ private struct DataListForEachRow: View {
|
|
|
127
147
|
}
|
|
128
148
|
}
|
|
129
149
|
|
|
150
|
+
private struct DataListForEachPlaceholder: View {
|
|
151
|
+
let size: CGFloat
|
|
152
|
+
let axis: DataListForEachAxis
|
|
153
|
+
|
|
154
|
+
// Sized along the scroll axis only, so it never stretches a lazy stack across it.
|
|
155
|
+
var body: some View {
|
|
156
|
+
Color.clear
|
|
157
|
+
.frame(width: axis == .horizontal ? size : 0, height: axis == .horizontal ? 0 : size)
|
|
158
|
+
.accessibilityHidden(true)
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
130
162
|
private struct DataListForEachSlotContent: View {
|
|
131
163
|
@ObservedObject var props: DataListForEachItemProps
|
|
132
164
|
let itemKey: String
|
|
133
165
|
let index: Int
|
|
134
166
|
let revision: Int
|
|
135
|
-
let
|
|
167
|
+
let estimatedSize: CGFloat
|
|
168
|
+
let axis: DataListForEachAxis
|
|
136
169
|
let window: DataListForEachWindow
|
|
137
170
|
// we use this state so swiftui re-layouts when the slot is reused for a different item
|
|
138
171
|
@State private var showsContent = false
|
|
@@ -146,14 +179,17 @@ private struct DataListForEachSlotContent: View {
|
|
|
146
179
|
if showsContent {
|
|
147
180
|
DataListForEachItemView(props: props)
|
|
148
181
|
.id(itemKey)
|
|
149
|
-
.onGeometryChange(
|
|
150
|
-
|
|
151
|
-
|
|
182
|
+
.onGeometryChange(
|
|
183
|
+
for: CGFloat.self,
|
|
184
|
+
of: { axis == .horizontal ? $0.size.width : $0.size.height },
|
|
185
|
+
action: { size in window.measure(size, for: itemKey, revision: revision) }
|
|
186
|
+
)
|
|
152
187
|
} else {
|
|
153
188
|
// Hide the previous item while JS updates this slot.
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
189
|
+
DataListForEachPlaceholder(
|
|
190
|
+
size: window.size(for: itemKey, fallback: Double(estimatedSize)),
|
|
191
|
+
axis: axis
|
|
192
|
+
)
|
|
157
193
|
}
|
|
158
194
|
}
|
|
159
195
|
.onAppear { showsContent = matches }
|
|
@@ -166,8 +202,9 @@ private final class DataListForEachWindow: ObservableObject {
|
|
|
166
202
|
private weak var props: DataListForEachProps?
|
|
167
203
|
private var appeared: [String: Int] = [:]
|
|
168
204
|
private var visibilityTokens: [String: UUID] = [:]
|
|
169
|
-
|
|
170
|
-
private var
|
|
205
|
+
// Row sizes along the scroll axis.
|
|
206
|
+
private var sizes: [String: CGFloat] = [:]
|
|
207
|
+
private var crossAxisSize: CGFloat = 0
|
|
171
208
|
private var revision = -1
|
|
172
209
|
private var pending: DispatchWorkItem?
|
|
173
210
|
private var lastSent: [Int] = []
|
|
@@ -182,7 +219,7 @@ private final class DataListForEachWindow: ObservableObject {
|
|
|
182
219
|
return
|
|
183
220
|
}
|
|
184
221
|
revision = props.revision
|
|
185
|
-
|
|
222
|
+
sizes.removeAll()
|
|
186
223
|
let positions = Dictionary(uniqueKeysWithValues: props.itemKeys.enumerated().map { ($0.element, $0.offset) })
|
|
187
224
|
appeared = positions.filter { appeared[$0.key] != nil }
|
|
188
225
|
visibilityTokens = visibilityTokens.filter { positions[$0.key] != nil }
|
|
@@ -190,12 +227,12 @@ private final class DataListForEachWindow: ObservableObject {
|
|
|
190
227
|
schedule()
|
|
191
228
|
}
|
|
192
229
|
|
|
193
|
-
func
|
|
194
|
-
if
|
|
195
|
-
if
|
|
196
|
-
|
|
230
|
+
func updateCrossAxisSize(_ newSize: CGFloat) {
|
|
231
|
+
if crossAxisSize != newSize {
|
|
232
|
+
if crossAxisSize > 0 {
|
|
233
|
+
sizes.removeAll()
|
|
197
234
|
}
|
|
198
|
-
|
|
235
|
+
crossAxisSize = newSize
|
|
199
236
|
}
|
|
200
237
|
}
|
|
201
238
|
|
|
@@ -220,15 +257,15 @@ private final class DataListForEachWindow: ObservableObject {
|
|
|
220
257
|
schedule()
|
|
221
258
|
}
|
|
222
259
|
|
|
223
|
-
func
|
|
224
|
-
|
|
260
|
+
func size(for key: String, fallback: Double) -> CGFloat {
|
|
261
|
+
sizes[key] ?? CGFloat(fallback)
|
|
225
262
|
}
|
|
226
263
|
|
|
227
|
-
func measure(_
|
|
228
|
-
guard revision == self.revision,
|
|
264
|
+
func measure(_ size: CGFloat, for key: String, revision: Int) {
|
|
265
|
+
guard revision == self.revision, size.isFinite, size > 0 else {
|
|
229
266
|
return
|
|
230
267
|
}
|
|
231
|
-
|
|
268
|
+
sizes[key] = size
|
|
232
269
|
}
|
|
233
270
|
|
|
234
271
|
private func schedule() {
|
package/ios/ExpoUIModule.swift
CHANGED
|
@@ -204,7 +204,6 @@ public final class ExpoUIModule: Module {
|
|
|
204
204
|
ExpoUIView(BackgroundView.self)
|
|
205
205
|
ExpoUIView(MaskView.self)
|
|
206
206
|
ExpoUIView(GridView.self)
|
|
207
|
-
ExpoUIView(AccessoryWidgetBackgroundView.self)
|
|
208
207
|
ExpoUIView(LinkView.self)
|
|
209
208
|
ExpoUIView(TabView.self)
|
|
210
209
|
ExpoUIView(Tab.self)
|
package/ios/LazyHStackView.swift
CHANGED
|
@@ -10,6 +10,7 @@ public final class LazyHStackViewProps: UIBaseViewProps {
|
|
|
10
10
|
|
|
11
11
|
public struct LazyHStackView: ExpoSwiftUI.View {
|
|
12
12
|
@ObservedObject public var props: LazyHStackViewProps
|
|
13
|
+
@State private var crossAxisSize: CGFloat = 0
|
|
13
14
|
|
|
14
15
|
public init(props: LazyHStackViewProps) {
|
|
15
16
|
self.props = props
|
|
@@ -21,5 +22,7 @@ public struct LazyHStackView: ExpoSwiftUI.View {
|
|
|
21
22
|
spacing: props.spacing.map { CGFloat($0) }) {
|
|
22
23
|
Children()
|
|
23
24
|
}
|
|
25
|
+
.onGeometryChange(for: CGFloat.self, of: { $0.size.height }, action: { crossAxisSize = $0 })
|
|
26
|
+
.environment(\.containerCrossAxisSize, crossAxisSize)
|
|
24
27
|
}
|
|
25
28
|
}
|
package/ios/LazyVStackView.swift
CHANGED
|
@@ -10,6 +10,7 @@ public final class LazyVStackViewProps: UIBaseViewProps {
|
|
|
10
10
|
|
|
11
11
|
public struct LazyVStackView: ExpoSwiftUI.View {
|
|
12
12
|
@ObservedObject public var props: LazyVStackViewProps
|
|
13
|
+
@State private var crossAxisSize: CGFloat = 0
|
|
13
14
|
|
|
14
15
|
public init(props: LazyVStackViewProps) {
|
|
15
16
|
self.props = props
|
|
@@ -21,5 +22,7 @@ public struct LazyVStackView: ExpoSwiftUI.View {
|
|
|
21
22
|
spacing: props.spacing.map { CGFloat($0) }) {
|
|
22
23
|
Children()
|
|
23
24
|
}
|
|
25
|
+
.onGeometryChange(for: CGFloat.self, of: { $0.size.width }, action: { crossAxisSize = $0 })
|
|
26
|
+
.environment(\.containerCrossAxisSize, crossAxisSize)
|
|
24
27
|
}
|
|
25
28
|
}
|
package/ios/ListView.swift
CHANGED
|
@@ -11,8 +11,16 @@ final class ListProps: UIBaseViewProps {
|
|
|
11
11
|
struct ListView: ExpoSwiftUI.View {
|
|
12
12
|
@ObservedObject var props: ListProps
|
|
13
13
|
@State private var selection = Set<AnyHashable>()
|
|
14
|
+
@State private var crossAxisSize: CGFloat = 0
|
|
14
15
|
|
|
15
16
|
var body: some View {
|
|
17
|
+
list
|
|
18
|
+
.onGeometryChange(for: CGFloat.self, of: { $0.size.width }, action: { crossAxisSize = $0 })
|
|
19
|
+
.environment(\.containerCrossAxisSize, crossAxisSize)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@ViewBuilder
|
|
23
|
+
private var list: some View {
|
|
16
24
|
if props.selection != nil {
|
|
17
25
|
List(selection: $selection) {
|
|
18
26
|
Children()
|
|
@@ -2,9 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import ExpoModulesCore
|
|
4
4
|
import SwiftUI
|
|
5
|
-
#if !os(tvOS)
|
|
6
|
-
import WidgetKit
|
|
7
|
-
#endif
|
|
8
5
|
|
|
9
6
|
internal enum ContainerBackgroundPlacementOptions: String, Enumerable {
|
|
10
7
|
case widget
|
|
@@ -12,10 +9,11 @@ internal enum ContainerBackgroundPlacementOptions: String, Enumerable {
|
|
|
12
9
|
case navigationSplitView
|
|
13
10
|
|
|
14
11
|
#if !os(tvOS) && !os(macOS)
|
|
12
|
+
// `widget` is declared in WidgetKit, so expo-widgets applies it through `ViewModifierRegistry.widgetKit`.
|
|
15
13
|
@available(iOS 18.0, *)
|
|
16
|
-
var toContainerBackgroundPlacement: ContainerBackgroundPlacement {
|
|
14
|
+
var toContainerBackgroundPlacement: ContainerBackgroundPlacement? {
|
|
17
15
|
switch self {
|
|
18
|
-
case .widget: return
|
|
16
|
+
case .widget: return nil
|
|
19
17
|
case .navigation: return .navigation
|
|
20
18
|
case .navigationSplitView: return .navigationSplitView
|
|
21
19
|
}
|
|
@@ -28,20 +26,17 @@ internal struct ContainerBackgroundModifier: ViewModifier, Record {
|
|
|
28
26
|
@Field var container: ContainerBackgroundPlacementOptions?
|
|
29
27
|
|
|
30
28
|
func body(content: Content) -> some View {
|
|
31
|
-
#if os(tvOS)
|
|
29
|
+
#if os(tvOS) || os(macOS)
|
|
32
30
|
content
|
|
33
|
-
#elseif os(macOS)
|
|
34
|
-
if let shapeStyle = style?.toAnyShapeStyle(), container == .widget {
|
|
35
|
-
content.containerBackground(shapeStyle, for: .widget)
|
|
36
|
-
} else {
|
|
37
|
-
content
|
|
38
|
-
}
|
|
39
31
|
#else
|
|
40
32
|
if let shapeStyle = style?.toAnyShapeStyle(), let container {
|
|
41
|
-
if
|
|
42
|
-
|
|
43
|
-
} else if #available(iOS
|
|
44
|
-
content.containerBackground(shapeStyle, for:
|
|
33
|
+
if container == .widget, let widgetKit = ViewModifierRegistry.widgetKit {
|
|
34
|
+
widgetKit.containerBackground(AnyView(content), style: shapeStyle)
|
|
35
|
+
} else if #available(iOS 18.0, *), let placement = container.toContainerBackgroundPlacement {
|
|
36
|
+
content.containerBackground(shapeStyle, for: placement)
|
|
37
|
+
} else if let widgetKit = ViewModifierRegistry.widgetKit {
|
|
38
|
+
// On iOS 17, the other placements fall back to `widget`.
|
|
39
|
+
widgetKit.containerBackground(AnyView(content), style: shapeStyle)
|
|
45
40
|
} else {
|
|
46
41
|
content
|
|
47
42
|
}
|
|
@@ -50,4 +45,16 @@ internal struct ContainerBackgroundModifier: ViewModifier, Record {
|
|
|
50
45
|
}
|
|
51
46
|
#endif
|
|
52
47
|
}
|
|
48
|
+
|
|
49
|
+
#if DEBUG
|
|
50
|
+
private static var didWarnAboutWidgetPlacement = false
|
|
51
|
+
|
|
52
|
+
func warnIfWidgetPlacementIsUnavailable() {
|
|
53
|
+
guard container == .widget, ViewModifierRegistry.widgetKit == nil, !Self.didWarnAboutWidgetPlacement else {
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
Self.didWarnAboutWidgetPlacement = true
|
|
57
|
+
log.warn("containerBackground with the 'widget' placement has no effect here, because it only applies inside widgets rendered by expo-widgets. Use the 'navigation' or 'navigationSplitView' placement in app screens.")
|
|
58
|
+
}
|
|
59
|
+
#endif
|
|
53
60
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Copyright 2025-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
import ExpoModulesCore
|
|
4
|
+
import SwiftUI
|
|
5
|
+
|
|
6
|
+
internal struct PreferredColorSchemeModifier: ViewModifier, Record {
|
|
7
|
+
@Field var colorScheme: ColorSchemeType?
|
|
8
|
+
|
|
9
|
+
func body(content: Content) -> some View {
|
|
10
|
+
content.preferredColorScheme(colorScheme?.toNativeColorScheme())
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -67,10 +67,10 @@ internal extension Image {
|
|
|
67
67
|
)
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
if
|
|
70
|
+
if let widgetKit = ViewModifierRegistry.widgetKit,
|
|
71
71
|
let modifierConfig = modifiers.first(where: { $0["$type"] as? String == "widgetAccentedRenderingMode" }),
|
|
72
|
-
let
|
|
73
|
-
|
|
72
|
+
let view = widgetKit.widgetAccentedRenderingMode(image, params: modifierConfig, appContext: appContext) {
|
|
73
|
+
view
|
|
74
74
|
} else {
|
|
75
75
|
image
|
|
76
76
|
}
|
|
@@ -1533,6 +1533,8 @@ public class ViewModifierRegistry {
|
|
|
1533
1533
|
public typealias ModifierFactory = ([String: Any], AppContext, EventDispatcher) throws -> any ViewModifier
|
|
1534
1534
|
private(set) internal var modifierFactories: [String: ModifierFactory] = [:]
|
|
1535
1535
|
|
|
1536
|
+
public static var widgetKit: WidgetKitModifiers?
|
|
1537
|
+
|
|
1536
1538
|
private init() {
|
|
1537
1539
|
registerBuiltInModifiers()
|
|
1538
1540
|
}
|
|
@@ -2309,6 +2311,10 @@ extension ViewModifierRegistry {
|
|
|
2309
2311
|
return try ScrollDisabledModifier(from: params, appContext: appContext)
|
|
2310
2312
|
}
|
|
2311
2313
|
|
|
2314
|
+
register("preferredColorScheme") { params, appContext, _ in
|
|
2315
|
+
return try PreferredColorSchemeModifier(from: params, appContext: appContext)
|
|
2316
|
+
}
|
|
2317
|
+
|
|
2312
2318
|
register("scrollClipDisabled") { params, appContext, _ in
|
|
2313
2319
|
return try ScrollClipDisabledModifier(from: params, appContext: appContext)
|
|
2314
2320
|
}
|
|
@@ -2393,14 +2399,6 @@ extension ViewModifierRegistry {
|
|
|
2393
2399
|
return try ContentTransitionModifier(from: params, appContext: appContext)
|
|
2394
2400
|
}
|
|
2395
2401
|
|
|
2396
|
-
register("widgetURL") { params, appContext, _ in
|
|
2397
|
-
return try WidgetURLModifier(from: params, appContext: appContext)
|
|
2398
|
-
}
|
|
2399
|
-
|
|
2400
|
-
register("activityBackgroundTint") { params, appContext, _ in
|
|
2401
|
-
return try ActivityBackgroundTintModifier(from: params, appContext: appContext)
|
|
2402
|
-
}
|
|
2403
|
-
|
|
2404
2402
|
register("keyboardType") { params, appContext, _ in
|
|
2405
2403
|
return try KeyboardTypeModifier(from: params, appContext: appContext)
|
|
2406
2404
|
}
|
|
@@ -2414,7 +2412,11 @@ extension ViewModifierRegistry {
|
|
|
2414
2412
|
}
|
|
2415
2413
|
|
|
2416
2414
|
register("containerBackground") { params, appContext, _ in
|
|
2417
|
-
|
|
2415
|
+
let modifier = try ContainerBackgroundModifier(from: params, appContext: appContext)
|
|
2416
|
+
#if DEBUG
|
|
2417
|
+
modifier.warnIfWidgetPlacementIsUnavailable()
|
|
2418
|
+
#endif
|
|
2419
|
+
return modifier
|
|
2418
2420
|
}
|
|
2419
2421
|
|
|
2420
2422
|
register("symbolEffect") { params, appContext, _ in
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Copyright 2026-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
import ExpoModulesCore
|
|
4
|
+
import SwiftUI
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The parts of SwiftUI that are declared in WidgetKit. expo-widgets sets
|
|
8
|
+
* `ViewModifierRegistry.widgetKit`, so ExpoUI does not link WidgetKit.
|
|
9
|
+
*/
|
|
10
|
+
public protocol WidgetKitModifiers {
|
|
11
|
+
func containerBackground(_ view: AnyView, style: AnyShapeStyle) -> AnyView
|
|
12
|
+
func widgetAccentedRenderingMode(_ image: Image, params: [String: Any], appContext: AppContext) -> AnyView?
|
|
13
|
+
}
|
package/ios/RNHostView.swift
CHANGED
|
@@ -4,7 +4,8 @@ import SwiftUI
|
|
|
4
4
|
import ExpoModulesCore
|
|
5
5
|
|
|
6
6
|
internal final class RNHostViewProps: ExpoSwiftUI.ViewProps {
|
|
7
|
-
@Field var
|
|
7
|
+
@Field var matchContentsHorizontal: Bool = false
|
|
8
|
+
@Field var matchContentsVertical: Bool = false
|
|
8
9
|
/**
|
|
9
10
|
Adds LeafNode and MeasurableYogaNode trait in Shadow node
|
|
10
11
|
*/
|
|
@@ -50,8 +51,13 @@ struct RNHostView: ExpoSwiftUI.View {
|
|
|
50
51
|
|
|
51
52
|
@ViewBuilder
|
|
52
53
|
private var hostedContent: some View {
|
|
53
|
-
if
|
|
54
|
-
ApplySizeFromYogaNode(
|
|
54
|
+
if matchesContents, let childUIView = firstChildUIView {
|
|
55
|
+
ApplySizeFromYogaNode(
|
|
56
|
+
childUIView: childUIView,
|
|
57
|
+
horizontal: props.matchContentsHorizontal,
|
|
58
|
+
vertical: props.matchContentsVertical,
|
|
59
|
+
shadowNodeProxy: props.shadowNodeProxy
|
|
60
|
+
) {
|
|
55
61
|
Children()
|
|
56
62
|
}
|
|
57
63
|
.onAppear {
|
|
@@ -62,7 +68,7 @@ struct RNHostView: ExpoSwiftUI.View {
|
|
|
62
68
|
.onDisappear {
|
|
63
69
|
touchHandler.detach()
|
|
64
70
|
}
|
|
65
|
-
} else if
|
|
71
|
+
} else if matchesContents {
|
|
66
72
|
// No hosted UIView (a pure SwiftUI child, e.g. Text/Image). Render it at its
|
|
67
73
|
// natural size instead of falling into the fill branch below, which would
|
|
68
74
|
// stretch a self-sizing SwiftUI view to fill its container.
|
|
@@ -87,6 +93,10 @@ struct RNHostView: ExpoSwiftUI.View {
|
|
|
87
93
|
}
|
|
88
94
|
}
|
|
89
95
|
|
|
96
|
+
private var matchesContents: Bool {
|
|
97
|
+
props.matchContentsHorizontal || props.matchContentsVertical
|
|
98
|
+
}
|
|
99
|
+
|
|
90
100
|
private var firstChildUIView: UIView? {
|
|
91
101
|
props.children?.first?.uiView
|
|
92
102
|
}
|
|
@@ -143,20 +153,52 @@ private final class RNHostTouchHandler: ObservableObject {
|
|
|
143
153
|
}
|
|
144
154
|
}
|
|
145
155
|
|
|
146
|
-
// Sets SwiftUI view size from Yoga node size
|
|
156
|
+
// Sets SwiftUI view size from Yoga node size on the matched axes
|
|
147
157
|
// Listens to Yoga node size changes and updates the SwiftUI view size
|
|
158
|
+
// An axis that is not matched fills the parent and reports its size to the Yoga node instead
|
|
148
159
|
private struct ApplySizeFromYogaNode<Content: SwiftUI.View>: SwiftUI.View {
|
|
149
160
|
@StateObject private var observer: Observer
|
|
161
|
+
let horizontal: Bool
|
|
162
|
+
let vertical: Bool
|
|
163
|
+
let shadowNodeProxy: ExpoSwiftUI.ShadowNodeProxy
|
|
150
164
|
let content: Content
|
|
151
165
|
|
|
152
|
-
init(
|
|
166
|
+
init(
|
|
167
|
+
childUIView: UIView,
|
|
168
|
+
horizontal: Bool,
|
|
169
|
+
vertical: Bool,
|
|
170
|
+
shadowNodeProxy: ExpoSwiftUI.ShadowNodeProxy,
|
|
171
|
+
@ViewBuilder content: () -> Content
|
|
172
|
+
) {
|
|
153
173
|
_observer = StateObject(wrappedValue: Observer(view: childUIView))
|
|
174
|
+
self.horizontal = horizontal
|
|
175
|
+
self.vertical = vertical
|
|
176
|
+
self.shadowNodeProxy = shadowNodeProxy
|
|
154
177
|
self.content = content()
|
|
155
178
|
}
|
|
156
179
|
|
|
157
180
|
var body: some SwiftUI.View {
|
|
158
|
-
|
|
159
|
-
|
|
181
|
+
if horizontal && vertical {
|
|
182
|
+
content
|
|
183
|
+
.frame(width: observer.size.width, height: observer.size.height)
|
|
184
|
+
} else {
|
|
185
|
+
content
|
|
186
|
+
.frame(
|
|
187
|
+
width: horizontal ? observer.size.width : nil,
|
|
188
|
+
height: vertical ? observer.size.height : nil
|
|
189
|
+
)
|
|
190
|
+
.frame(
|
|
191
|
+
maxWidth: horizontal ? nil : .infinity,
|
|
192
|
+
maxHeight: vertical ? nil : .infinity
|
|
193
|
+
)
|
|
194
|
+
.modifier(
|
|
195
|
+
ReportSizeToYogaNodeModifier(
|
|
196
|
+
shadowNodeProxy: shadowNodeProxy,
|
|
197
|
+
reportWidth: !horizontal,
|
|
198
|
+
reportHeight: !vertical
|
|
199
|
+
)
|
|
200
|
+
)
|
|
201
|
+
}
|
|
160
202
|
}
|
|
161
203
|
|
|
162
204
|
@MainActor
|
|
@@ -183,9 +225,13 @@ private struct ApplySizeFromYogaNode<Content: SwiftUI.View>: SwiftUI.View {
|
|
|
183
225
|
// Listens to SwiftUI view size changes and updates the Yoga node size
|
|
184
226
|
private struct ReportSizeToYogaNodeModifier: ViewModifier {
|
|
185
227
|
let shadowNodeProxy: ExpoSwiftUI.ShadowNodeProxy
|
|
228
|
+
var reportWidth = true
|
|
229
|
+
var reportHeight = true
|
|
186
230
|
|
|
187
231
|
private func handleSizeChange(_ size: CGSize) {
|
|
188
|
-
shadowNodeProxy.setViewSize?(
|
|
232
|
+
shadowNodeProxy.setViewSize?(
|
|
233
|
+
CGSize(width: reportWidth ? size.width : .nan, height: reportHeight ? size.height : .nan)
|
|
234
|
+
)
|
|
189
235
|
}
|
|
190
236
|
|
|
191
237
|
func body(content: Content) -> some View {
|