@expo/ui 58.0.14 → 58.0.16
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 +24 -0
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/ui/DatePickerView.kt +35 -2
- package/android/src/main/java/expo/modules/ui/DateRangePickerView.kt +35 -2
- package/android/src/main/java/expo/modules/ui/ExpoUIModule.kt +3 -0
- package/android/src/main/java/expo/modules/ui/HostView.kt +21 -0
- package/android/src/main/java/expo/modules/ui/ModifierRegistry.kt +2 -2
- package/android/src/main/java/expo/modules/ui/RNHostView.kt +117 -1
- package/android/src/main/java/expo/modules/ui/menu/DropdownMenu.kt +8 -1
- package/android/src/main/java/expo/modules/ui/menu/DropdownMenuRecords.kt +13 -1
- package/build/NativeTreeContext.d.ts +10 -0
- package/build/NativeTreeContext.js +25 -0
- package/build/NativeTreeContext.js.map +1 -0
- package/build/State/useWorkletCallback.d.ts +1 -1
- package/build/community/bottom-sheet/BottomSheet.ios.js +11 -4
- package/build/community/bottom-sheet/BottomSheet.ios.js.map +1 -1
- package/build/community/datetime-picker/DateTimePicker.android.js +4 -0
- package/build/community/datetime-picker/DateTimePicker.android.js.map +1 -1
- package/build/community/menu/MenuView.android.js +6 -0
- package/build/community/menu/MenuView.android.js.map +1 -1
- package/build/jetpack-compose/DatePicker/index.d.ts +38 -0
- package/build/jetpack-compose/DatePicker/index.js.map +1 -1
- package/build/jetpack-compose/DropdownMenu/index.d.ts +8 -1
- package/build/jetpack-compose/DropdownMenu/index.js.map +1 -1
- package/build/jetpack-compose/Host/index.js +8 -2
- package/build/jetpack-compose/Host/index.js.map +1 -1
- package/build/jetpack-compose/RNHostView/index.js +5 -1
- package/build/jetpack-compose/RNHostView/index.js.map +1 -1
- package/build/swift-ui/Chart/index.d.ts +10 -0
- package/build/swift-ui/Chart/index.js.map +1 -1
- package/build/swift-ui/Host/index.js +8 -2
- package/build/swift-ui/Host/index.js.map +1 -1
- package/build/swift-ui/RNHostView.js +5 -1
- package/build/swift-ui/RNHostView.js.map +1 -1
- package/build/swift-ui/Toolbar/index.d.ts +2 -0
- package/build/swift-ui/Toolbar/index.js +2 -0
- package/build/swift-ui/Toolbar/index.js.map +1 -1
- package/build/swift-ui/modifiers/hingeObservation.d.ts +1 -1
- package/build/swift-ui/modifiers/hingeObservation.js +1 -1
- package/build/swift-ui/modifiers/index.d.ts +1 -0
- package/build/swift-ui/modifiers/index.js +1 -0
- package/build/swift-ui/modifiers/index.js.map +1 -1
- package/build/swift-ui/modifiers/presentationModifiers.d.ts +17 -1
- package/build/swift-ui/modifiers/presentationModifiers.js +4 -2
- package/build/swift-ui/modifiers/presentationModifiers.js.map +1 -1
- package/build/swift-ui/modifiers/searchable.d.ts +83 -0
- package/build/swift-ui/modifiers/searchable.js +74 -0
- package/build/swift-ui/modifiers/searchable.js.map +1 -0
- package/build/types.d.ts +27 -0
- package/build/types.js +1 -1
- package/build/types.js.map +1 -1
- package/build/universal/BottomSheet/index.android.js +26 -18
- package/build/universal/BottomSheet/index.android.js.map +1 -1
- package/build/universal/BottomSheet/index.ios.js +20 -12
- package/build/universal/BottomSheet/index.ios.js.map +1 -1
- package/ios/ChartView.swift +15 -10
- package/ios/DataListForEachView.swift +1 -0
- package/ios/GridView.swift +1 -0
- package/ios/HostView.swift +27 -4
- package/ios/Modifiers/PresentationModifiers.swift +20 -4
- package/ios/Modifiers/SearchToolbarBehaviorModifier.swift +35 -0
- package/ios/Modifiers/SearchableModifier.swift +94 -0
- package/ios/Modifiers/ViewModifierRegistry.swift +8 -0
- package/ios/NamespaceView.swift +1 -0
- package/ios/Picker/PickerView.swift +9 -7
- package/ios/RNHostView.swift +19 -4
- package/ios/SlotView.swift +1 -0
- package/ios/TabView/TabView.swift +2 -0
- package/ios/ToolbarView.swift +2 -1
- package/ios/UIBaseView.swift +13 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/{58.0.14/expo.modules.ui-58.0.14-sources.jar → 58.0.16/expo.modules.ui-58.0.16-sources.jar} +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.16/expo.modules.ui-58.0.16-sources.jar.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.16/expo.modules.ui-58.0.16-sources.jar.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.16/expo.modules.ui-58.0.16-sources.jar.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.16/expo.modules.ui-58.0.16-sources.jar.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.16/expo.modules.ui-58.0.16.aar +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.16/expo.modules.ui-58.0.16.aar.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.16/expo.modules.ui-58.0.16.aar.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.16/expo.modules.ui-58.0.16.aar.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.16/expo.modules.ui-58.0.16.aar.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/{58.0.14/expo.modules.ui-58.0.14.module → 58.0.16/expo.modules.ui-58.0.16.module} +22 -22
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.16/expo.modules.ui-58.0.16.module.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.16/expo.modules.ui-58.0.16.module.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.16/expo.modules.ui-58.0.16.module.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.16/expo.modules.ui-58.0.16.module.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/{58.0.14/expo.modules.ui-58.0.14.pom → 58.0.16/expo.modules.ui-58.0.16.pom} +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.16/expo.modules.ui-58.0.16.pom.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.16/expo.modules.ui-58.0.16.pom.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.16/expo.modules.ui-58.0.16.pom.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.16/expo.modules.ui-58.0.16.pom.sha512 +1 -0
- package/package.json +2 -2
- package/prebuilds/output/debug/xcframeworks/ExpoUI.tar.gz +0 -0
- package/prebuilds/output/release/xcframeworks/ExpoUI.tar.gz +0 -0
- package/src/NativeTreeContext.tsx +31 -0
- package/src/State/useWorkletCallback.ts +1 -1
- package/src/community/bottom-sheet/BottomSheet.ios.tsx +7 -6
- package/src/community/datetime-picker/DateTimePicker.android.tsx +4 -0
- package/src/community/menu/MenuView.android.tsx +12 -2
- package/src/jetpack-compose/DatePicker/index.tsx +38 -0
- package/src/jetpack-compose/DropdownMenu/index.tsx +12 -1
- package/src/jetpack-compose/Host/index.tsx +6 -2
- package/src/jetpack-compose/RNHostView/index.tsx +3 -1
- package/src/swift-ui/Chart/index.tsx +10 -0
- package/src/swift-ui/Host/index.tsx +6 -2
- package/src/swift-ui/RNHostView.tsx +3 -1
- package/src/swift-ui/Toolbar/index.tsx +2 -0
- package/src/swift-ui/modifiers/hingeObservation.ts +1 -1
- package/src/swift-ui/modifiers/index.ts +1 -0
- package/src/swift-ui/modifiers/presentationModifiers.ts +18 -2
- package/src/swift-ui/modifiers/searchable.ts +107 -0
- package/src/types.ts +28 -0
- package/src/universal/BottomSheet/index.android.tsx +23 -12
- package/src/universal/BottomSheet/index.ios.tsx +20 -9
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.14/expo.modules.ui-58.0.14-sources.jar.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.14/expo.modules.ui-58.0.14-sources.jar.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.14/expo.modules.ui-58.0.14-sources.jar.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.14/expo.modules.ui-58.0.14-sources.jar.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.14/expo.modules.ui-58.0.14.aar +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.14/expo.modules.ui-58.0.14.aar.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.14/expo.modules.ui-58.0.14.aar.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.14/expo.modules.ui-58.0.14.aar.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.14/expo.modules.ui-58.0.14.aar.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.14/expo.modules.ui-58.0.14.module.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.14/expo.modules.ui-58.0.14.module.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.14/expo.modules.ui-58.0.14.module.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.14/expo.modules.ui-58.0.14.module.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.14/expo.modules.ui-58.0.14.pom.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.14/expo.modules.ui-58.0.14.pom.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.14/expo.modules.ui-58.0.14.pom.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/58.0.14/expo.modules.ui-58.0.14.pom.sha512 +0 -1
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { type ObservableState } from '../../State';
|
|
2
|
+
/**
|
|
3
|
+
* The placement of a search field in a view hierarchy.
|
|
4
|
+
*
|
|
5
|
+
* - `automatic`: SwiftUI places the search field automatically.
|
|
6
|
+
* - `toolbar`: The search field appears in the toolbar. Falls back to `automatic` on tvOS.
|
|
7
|
+
* - `sidebar`: The search field appears in the sidebar of a navigation view. Falls back to
|
|
8
|
+
* `automatic` on tvOS.
|
|
9
|
+
* - `navigationBarDrawer`: The search field appears in the navigation bar. Falls back to
|
|
10
|
+
* `automatic` on macOS and tvOS.
|
|
11
|
+
*/
|
|
12
|
+
export type SearchFieldPlacement = 'automatic' | 'toolbar' | 'sidebar' | 'navigationBarDrawer';
|
|
13
|
+
/**
|
|
14
|
+
* Marks this view as searchable, which configures the display of a search field.
|
|
15
|
+
*
|
|
16
|
+
* @param text - The text to display and edit in the search field. An `ObservableState<string>`
|
|
17
|
+
* created with `useNativeState`.
|
|
18
|
+
* @param options.placement - The preferred placement of the search field within the containing
|
|
19
|
+
* view hierarchy. Defaults to `automatic`.
|
|
20
|
+
* @param options.prompt - The prompt of the search field, which provides users with guidance on
|
|
21
|
+
* what to search for.
|
|
22
|
+
* @param options.onChange - Fires on the JS thread when the user edits or clears the search field.
|
|
23
|
+
* It does not fire for values written from JavaScript.
|
|
24
|
+
*
|
|
25
|
+
* @platform ios
|
|
26
|
+
* @platform tvos
|
|
27
|
+
* @platform macos
|
|
28
|
+
*
|
|
29
|
+
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/searchable(text:placement:prompt:)-18a8f).
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* const query = useNativeState('');
|
|
34
|
+
*
|
|
35
|
+
* <Host>
|
|
36
|
+
* <NavigationStack>
|
|
37
|
+
* <List
|
|
38
|
+
* modifiers={[
|
|
39
|
+
* searchable(query, {
|
|
40
|
+
* prompt: 'Search agents',
|
|
41
|
+
* onChange: (text) => setFilter(text),
|
|
42
|
+
* }),
|
|
43
|
+
* ]}>
|
|
44
|
+
* {rows.map((row) => (
|
|
45
|
+
* <Text key={row.id}>{row.name}</Text>
|
|
46
|
+
* ))}
|
|
47
|
+
* </List>
|
|
48
|
+
* </NavigationStack>
|
|
49
|
+
* </Host>
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare const searchable: (text: ObservableState<string>, options?: {
|
|
53
|
+
placement?: SearchFieldPlacement;
|
|
54
|
+
prompt?: string;
|
|
55
|
+
onChange?: (text: string) => void;
|
|
56
|
+
}) => import("./createModifier").ModifierConfig;
|
|
57
|
+
/**
|
|
58
|
+
* The behavior of a search field in a toolbar.
|
|
59
|
+
*
|
|
60
|
+
* - `automatic`: The automatic behavior.
|
|
61
|
+
* - `minimize`: A search toolbar behavior that prefers rendering a search field as a button-like
|
|
62
|
+
* control. Falls back to `automatic` on macOS and tvOS.
|
|
63
|
+
*/
|
|
64
|
+
export type SearchToolbarBehavior = 'automatic' | 'minimize';
|
|
65
|
+
/**
|
|
66
|
+
* Configures the behavior for search in the toolbar.
|
|
67
|
+
*
|
|
68
|
+
* On iOS below 26.0, the modifier is a no-op.
|
|
69
|
+
*
|
|
70
|
+
* @param behavior - The search field behavior.
|
|
71
|
+
*
|
|
72
|
+
* @platform ios 26.0+
|
|
73
|
+
* @platform tvos 26.0+
|
|
74
|
+
* @platform macos 26.0+
|
|
75
|
+
*
|
|
76
|
+
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/searchtoolbarbehavior(_:)).
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```tsx
|
|
80
|
+
* <List modifiers={[searchable(query), searchToolbarBehavior('minimize')]}>
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export declare const searchToolbarBehavior: (behavior: SearchToolbarBehavior) => import("./createModifier").ModifierConfig;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { getStateId } from '../../State';
|
|
2
|
+
import { createModifier, createModifierWithEventListener } from './createModifier';
|
|
3
|
+
/**
|
|
4
|
+
* Marks this view as searchable, which configures the display of a search field.
|
|
5
|
+
*
|
|
6
|
+
* @param text - The text to display and edit in the search field. An `ObservableState<string>`
|
|
7
|
+
* created with `useNativeState`.
|
|
8
|
+
* @param options.placement - The preferred placement of the search field within the containing
|
|
9
|
+
* view hierarchy. Defaults to `automatic`.
|
|
10
|
+
* @param options.prompt - The prompt of the search field, which provides users with guidance on
|
|
11
|
+
* what to search for.
|
|
12
|
+
* @param options.onChange - Fires on the JS thread when the user edits or clears the search field.
|
|
13
|
+
* It does not fire for values written from JavaScript.
|
|
14
|
+
*
|
|
15
|
+
* @platform ios
|
|
16
|
+
* @platform tvos
|
|
17
|
+
* @platform macos
|
|
18
|
+
*
|
|
19
|
+
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/searchable(text:placement:prompt:)-18a8f).
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```tsx
|
|
23
|
+
* const query = useNativeState('');
|
|
24
|
+
*
|
|
25
|
+
* <Host>
|
|
26
|
+
* <NavigationStack>
|
|
27
|
+
* <List
|
|
28
|
+
* modifiers={[
|
|
29
|
+
* searchable(query, {
|
|
30
|
+
* prompt: 'Search agents',
|
|
31
|
+
* onChange: (text) => setFilter(text),
|
|
32
|
+
* }),
|
|
33
|
+
* ]}>
|
|
34
|
+
* {rows.map((row) => (
|
|
35
|
+
* <Text key={row.id}>{row.name}</Text>
|
|
36
|
+
* ))}
|
|
37
|
+
* </List>
|
|
38
|
+
* </NavigationStack>
|
|
39
|
+
* </Host>
|
|
40
|
+
* ```
|
|
41
|
+
*/ export const searchable = (text, options)=>{
|
|
42
|
+
const params = {
|
|
43
|
+
text: getStateId(text),
|
|
44
|
+
placement: options?.placement,
|
|
45
|
+
prompt: options?.prompt
|
|
46
|
+
};
|
|
47
|
+
const onChange = options?.onChange;
|
|
48
|
+
if (onChange) {
|
|
49
|
+
return createModifierWithEventListener('searchable', (event)=>onChange(event?.text ?? ''), params);
|
|
50
|
+
}
|
|
51
|
+
return createModifier('searchable', params);
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Configures the behavior for search in the toolbar.
|
|
55
|
+
*
|
|
56
|
+
* On iOS below 26.0, the modifier is a no-op.
|
|
57
|
+
*
|
|
58
|
+
* @param behavior - The search field behavior.
|
|
59
|
+
*
|
|
60
|
+
* @platform ios 26.0+
|
|
61
|
+
* @platform tvos 26.0+
|
|
62
|
+
* @platform macos 26.0+
|
|
63
|
+
*
|
|
64
|
+
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/searchtoolbarbehavior(_:)).
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```tsx
|
|
68
|
+
* <List modifiers={[searchable(query), searchToolbarBehavior('minimize')]}>
|
|
69
|
+
* ```
|
|
70
|
+
*/ export const searchToolbarBehavior = (behavior)=>createModifier('searchToolbarBehavior', {
|
|
71
|
+
behavior
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
//# sourceMappingURL=searchable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["swift-ui/modifiers/searchable.ts"],"sourcesContent":[null],"names":["getStateId","createModifier","createModifierWithEventListener","searchable","text","options","params","placement","prompt","onChange","event","searchToolbarBehavior","behavior"],"mappings":"AAAA,SAASA,UAAU,QAA8B,cAAc;AAC/D,SAASC,cAAc,EAAEC,+BAA+B,QAAQ,mBAAmB;AAcnF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCC,GACD,OAAO,MAAMC,aAAa,CACxBC,MACAC;IAMA,MAAMC,SAAS;QACbF,MAAMJ,WAAWI;QACjBG,WAAWF,SAASE;QACpBC,QAAQH,SAASG;IACnB;IACA,MAAMC,WAAWJ,SAASI;IAC1B,IAAIA,UAAU;QACZ,OAAOP,gCACL,cACA,CAACQ,QAA6BD,SAASC,OAAON,QAAQ,KACtDE;IAEJ;IACA,OAAOL,eAAe,cAAcK;AACtC,EAAE;AAWF;;;;;;;;;;;;;;;;;CAiBC,GACD,OAAO,MAAMK,wBAAwB,CAACC,WACpCX,eAAe,yBAAyB;QAAEW;IAAS,GAAG"}
|
package/build/types.d.ts
CHANGED
|
@@ -44,3 +44,30 @@ export type DialogProperties = {
|
|
|
44
44
|
*/
|
|
45
45
|
decorFitsSystemWindows?: boolean;
|
|
46
46
|
};
|
|
47
|
+
/**
|
|
48
|
+
* Properties for the popup window, matching `PopupProperties` in Compose.
|
|
49
|
+
*/
|
|
50
|
+
export type PopupProperties = {
|
|
51
|
+
/**
|
|
52
|
+
* Whether the popup is focusable. When `true`, the popup receives IME events and key presses,
|
|
53
|
+
* such as the back button.
|
|
54
|
+
* @default true
|
|
55
|
+
*/
|
|
56
|
+
focusable?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Whether the popup can be dismissed by pressing the back button. Has no effect when `focusable` is `false`.
|
|
59
|
+
* @default true
|
|
60
|
+
*/
|
|
61
|
+
dismissOnBackPress?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Whether the popup can be dismissed by clicking outside of its bounds.
|
|
64
|
+
* @default true
|
|
65
|
+
*/
|
|
66
|
+
dismissOnClickOutside?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Whether the popup window is clipped to the screen boundaries. Set to `false` to let it extend
|
|
69
|
+
* beyond them, which positions the popup accurately.
|
|
70
|
+
* @default true
|
|
71
|
+
*/
|
|
72
|
+
clippingEnabled?: boolean;
|
|
73
|
+
};
|
package/build/types.js
CHANGED
package/build/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["types.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;;CAEC,
|
|
1
|
+
{"version":3,"sources":["types.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;;CAEC,GAmDD;;CAEC,GACD,WAuBE"}
|
|
@@ -2,6 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { Column, Host, ModalBottomSheet } from '@expo/ui/jetpack-compose';
|
|
3
3
|
import { fillMaxHeight, padding, testID as testIDModifier } from '@expo/ui/jetpack-compose/modifiers';
|
|
4
4
|
import { useEffect, useRef, useState } from 'react';
|
|
5
|
+
import { useIsInsideNativeTree } from '../../NativeTreeContext';
|
|
5
6
|
import { resolveContentPadding } from './utils';
|
|
6
7
|
// M3 `ModalBottomSheet` only has partial/expanded states.
|
|
7
8
|
// Only allow the partial state when the consumer requested a partial-friendly snap point.
|
|
@@ -16,6 +17,7 @@ function shouldFillMaxHeight(snapPoints) {
|
|
|
16
17
|
return snapPoints.some((sp)=>sp === 'full' || typeof sp === 'object' && 'fraction' in sp && sp.fraction >= 1);
|
|
17
18
|
}
|
|
18
19
|
export function BottomSheet({ children, isPresented, onDismiss, showDragIndicator = true, snapPoints, testID, modifiers, shouldDismissOnBackPress = true, shouldDismissOnClickOutside = true, scrimColor, contentPadding, containerColor, contentColor }) {
|
|
20
|
+
const isInsideHost = useIsInsideNativeTree();
|
|
19
21
|
const sheetRef = useRef(null);
|
|
20
22
|
const [mount, setMount] = useState(isPresented);
|
|
21
23
|
useEffect(()=>{
|
|
@@ -49,29 +51,35 @@ export function BottomSheet({ children, isPresented, onDismiss, showDragIndicato
|
|
|
49
51
|
];
|
|
50
52
|
if (shouldFillMaxHeight(snapPoints)) contentModifiers.push(fillMaxHeight());
|
|
51
53
|
if (testID) contentModifiers.push(testIDModifier(testID));
|
|
54
|
+
const sheet = /*#__PURE__*/ _jsx(ModalBottomSheet, {
|
|
55
|
+
ref: sheetRef,
|
|
56
|
+
onDismissRequest: onDismiss,
|
|
57
|
+
showDragHandle: showDragIndicator,
|
|
58
|
+
skipPartiallyExpanded: shouldSkipPartiallyExpanded(snapPoints),
|
|
59
|
+
properties: {
|
|
60
|
+
shouldDismissOnBackPress,
|
|
61
|
+
shouldDismissOnClickOutside
|
|
62
|
+
},
|
|
63
|
+
scrimColor: scrimColor,
|
|
64
|
+
containerColor: containerColor,
|
|
65
|
+
contentColor: contentColor,
|
|
66
|
+
modifiers: modifiers,
|
|
67
|
+
children: /*#__PURE__*/ _jsx(Column, {
|
|
68
|
+
modifiers: contentModifiers,
|
|
69
|
+
children: children
|
|
70
|
+
})
|
|
71
|
+
});
|
|
72
|
+
// Already inside a `Host`, for example nested in another sheet's content: a `Host` of its own
|
|
73
|
+
// would be a `Host` directly inside Compose.
|
|
74
|
+
if (isInsideHost) {
|
|
75
|
+
return sheet;
|
|
76
|
+
}
|
|
52
77
|
return /*#__PURE__*/ _jsx(Host, {
|
|
53
78
|
style: {
|
|
54
79
|
position: 'absolute'
|
|
55
80
|
},
|
|
56
81
|
pointerEvents: "none",
|
|
57
|
-
children:
|
|
58
|
-
ref: sheetRef,
|
|
59
|
-
onDismissRequest: onDismiss,
|
|
60
|
-
showDragHandle: showDragIndicator,
|
|
61
|
-
skipPartiallyExpanded: shouldSkipPartiallyExpanded(snapPoints),
|
|
62
|
-
properties: {
|
|
63
|
-
shouldDismissOnBackPress,
|
|
64
|
-
shouldDismissOnClickOutside
|
|
65
|
-
},
|
|
66
|
-
scrimColor: scrimColor,
|
|
67
|
-
containerColor: containerColor,
|
|
68
|
-
contentColor: contentColor,
|
|
69
|
-
modifiers: modifiers,
|
|
70
|
-
children: /*#__PURE__*/ _jsx(Column, {
|
|
71
|
-
modifiers: contentModifiers,
|
|
72
|
-
children: children
|
|
73
|
-
})
|
|
74
|
-
})
|
|
82
|
+
children: sheet
|
|
75
83
|
});
|
|
76
84
|
}
|
|
77
85
|
export * from './types';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["universal/BottomSheet/index.android.tsx"],"sourcesContent":[null],"names":["Column","Host","ModalBottomSheet","fillMaxHeight","padding","testID","testIDModifier","useEffect","useRef","useState","resolveContentPadding","shouldSkipPartiallyExpanded","snapPoints","length","some","sp","fraction","shouldFillMaxHeight","BottomSheet","children","isPresented","onDismiss","showDragIndicator","modifiers","shouldDismissOnBackPress","shouldDismissOnClickOutside","scrimColor","contentPadding","containerColor","contentColor","sheetRef","mount","setMount","cancelled","current","hide","then","top","bottom","left","right","contentModifiers","push","
|
|
1
|
+
{"version":3,"sources":["universal/BottomSheet/index.android.tsx"],"sourcesContent":[null],"names":["Column","Host","ModalBottomSheet","fillMaxHeight","padding","testID","testIDModifier","useEffect","useRef","useState","useIsInsideNativeTree","resolveContentPadding","shouldSkipPartiallyExpanded","snapPoints","length","some","sp","fraction","shouldFillMaxHeight","BottomSheet","children","isPresented","onDismiss","showDragIndicator","modifiers","shouldDismissOnBackPress","shouldDismissOnClickOutside","scrimColor","contentPadding","containerColor","contentColor","isInsideHost","sheetRef","mount","setMount","cancelled","current","hide","then","top","bottom","left","right","contentModifiers","push","sheet","ref","onDismissRequest","showDragHandle","skipPartiallyExpanded","properties","style","position","pointerEvents"],"mappings":";AAAA,SAASA,MAAM,EAAEC,IAAI,EAAEC,gBAAgB,QAAkC,2BAA2B;AACpG,SACEC,aAAa,EACbC,OAAO,EACPC,UAAUC,cAAc,QAEnB,qCAAqC;AAC5C,SAASC,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAQ;AAEpD,SAASC,qBAAqB,QAAQ,0BAA0B;AAEhE,SAASC,qBAAqB,QAAQ,UAAU;AAEhD,0DAA0D;AAC1D,0FAA0F;AAC1F,SAASC,4BAA4BC,UAAmC;IACtE,IAAI,CAACA,cAAcA,WAAWC,MAAM,KAAK,GAAG,OAAO;IACnD,OAAO,CAACD,WAAWE,IAAI,CACrB,CAACC,KACCA,OAAO,UACN,OAAOA,OAAO,YAAY,cAAcA,MAAMA,GAAGC,QAAQ,GAAG,KAC5D,OAAOD,OAAO,YAAY,YAAYA;AAE7C;AAEA,wCAAwC;AACxC,uGAAuG;AACvG,SAASE,oBAAoBL,UAAmC;IAC9D,IAAI,CAACA,cAAcA,WAAWC,MAAM,KAAK,GAAG,OAAO;IACnD,OAAOD,WAAWE,IAAI,CACpB,CAACC,KAAOA,OAAO,UAAW,OAAOA,OAAO,YAAY,cAAcA,MAAMA,GAAGC,QAAQ,IAAI;AAE3F;AAEA,OAAO,SAASE,YAAY,EAC1BC,QAAQ,EACRC,WAAW,EACXC,SAAS,EACTC,oBAAoB,IAAI,EACxBV,UAAU,EACVR,MAAM,EACNmB,SAAS,EACTC,2BAA2B,IAAI,EAC/BC,8BAA8B,IAAI,EAClCC,UAAU,EACVC,cAAc,EACdC,cAAc,EACdC,YAAY,EACK;IACjB,MAAMC,eAAerB;IACrB,MAAMsB,WAAWxB,OAA4B;IAC7C,MAAM,CAACyB,OAAOC,SAAS,GAAGzB,SAASY;IAEnCd,UAAU;QACR,IAAIc,aAAa;YACfa,SAAS;YACT;QACF;QACA,IAAIC,YAAY;QAChBH,SAASI,OAAO,EAAEC,OAAOC,KAAK;YAC5B,IAAI,CAACH,WAAWD,SAAS;QAC3B;QACA,OAAO;YACLC,YAAY;QACd;IACF,GAAG;QAACd;KAAY;IAEhB,IAAI,CAACY,OAAO;QACV,OAAO;IACT;IAEA,6FAA6F;IAC7F,qCAAqC;IACrC,MAAM,EAAEM,GAAG,EAAEC,MAAM,EAAEC,IAAI,EAAEC,KAAK,EAAE,GAAG/B,sBAAsBiB,gBAAgB;QACzEW,KAAKhB,oBAAoB,IAAI;QAC7BiB,QAAQ;QACRC,MAAM;QACNC,OAAO;IACT;IACA,MAAMC,mBAAqC;QAACvC,QAAQqC,MAAMF,KAAKG,OAAOF;KAAQ;IAC9E,IAAItB,oBAAoBL,aAAa8B,iBAAiBC,IAAI,CAACzC;IAC3D,IAAIE,QAAQsC,iBAAiBC,IAAI,CAACtC,eAAeD;IAEjD,MAAMwC,sBACJ,KAAC3C;QACC4C,KAAKd;QACLe,kBAAkBzB;QAClB0B,gBAAgBzB;QAChB0B,uBAAuBrC,4BAA4BC;QACnDqC,YAAY;YAAEzB;YAA0BC;QAA4B;QACpEC,YAAYA;QACZE,gBAAgBA;QAChBC,cAAcA;QACdN,WAAWA;kBACX,cAAA,KAACxB;YAAOwB,WAAWmB;sBAAmBvB;;;IAI1C,8FAA8F;IAC9F,6CAA6C;IAC7C,IAAIW,cAAc;QAChB,OAAOc;IACT;IACA,qBACE,KAAC5C;QAAKkD,OAAO;YAAEC,UAAU;QAAW;QAAGC,eAAc;kBAClDR;;AAGP;AAEA,cAAc,UAAU"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { BottomSheet as SwiftUIBottomSheet, Group, Host } from '@expo/ui/swift-ui';
|
|
3
3
|
import { frame, padding, presentationBackground, presentationDetents, presentationDragIndicator } from '@expo/ui/swift-ui/modifiers';
|
|
4
|
+
import { useIsInsideNativeTree } from '../../NativeTreeContext';
|
|
4
5
|
import { resolveContentPadding } from './utils';
|
|
5
6
|
function snapPointToDetent(snapPoint) {
|
|
6
7
|
if (snapPoint === 'half') return 'medium';
|
|
@@ -8,6 +9,7 @@ function snapPointToDetent(snapPoint) {
|
|
|
8
9
|
return snapPoint;
|
|
9
10
|
}
|
|
10
11
|
export function BottomSheet({ children, isPresented, onDismiss, showDragIndicator = true, snapPoints, testID, modifiers, contentPadding, containerColor }) {
|
|
12
|
+
const isInsideHost = useIsInsideNativeTree();
|
|
11
13
|
const { top, bottom, left, right } = resolveContentPadding(contentPadding, {
|
|
12
14
|
top: 16,
|
|
13
15
|
bottom: 0,
|
|
@@ -36,23 +38,29 @@ export function BottomSheet({ children, isPresented, onDismiss, showDragIndicato
|
|
|
36
38
|
if (modifiers?.length) {
|
|
37
39
|
presentationModifiers.push(...modifiers);
|
|
38
40
|
}
|
|
41
|
+
const sheet = /*#__PURE__*/ _jsx(SwiftUIBottomSheet, {
|
|
42
|
+
isPresented: isPresented,
|
|
43
|
+
onIsPresentedChange: (presented)=>{
|
|
44
|
+
if (!presented) onDismiss();
|
|
45
|
+
},
|
|
46
|
+
fitToContents: !snapPoints || snapPoints.length === 0,
|
|
47
|
+
testID: testID,
|
|
48
|
+
children: /*#__PURE__*/ _jsx(Group, {
|
|
49
|
+
modifiers: presentationModifiers,
|
|
50
|
+
children: children
|
|
51
|
+
})
|
|
52
|
+
});
|
|
53
|
+
// Already inside a `Host`, for example nested in another sheet's content: a `Host` of its own
|
|
54
|
+
// would be a `Host` directly inside SwiftUI.
|
|
55
|
+
if (isInsideHost) {
|
|
56
|
+
return sheet;
|
|
57
|
+
}
|
|
39
58
|
return /*#__PURE__*/ _jsx(Host, {
|
|
40
59
|
style: {
|
|
41
60
|
position: 'absolute'
|
|
42
61
|
},
|
|
43
62
|
pointerEvents: "none",
|
|
44
|
-
children:
|
|
45
|
-
isPresented: isPresented,
|
|
46
|
-
onIsPresentedChange: (presented)=>{
|
|
47
|
-
if (!presented) onDismiss();
|
|
48
|
-
},
|
|
49
|
-
fitToContents: !snapPoints || snapPoints.length === 0,
|
|
50
|
-
testID: testID,
|
|
51
|
-
children: /*#__PURE__*/ _jsx(Group, {
|
|
52
|
-
modifiers: presentationModifiers,
|
|
53
|
-
children: children
|
|
54
|
-
})
|
|
55
|
-
})
|
|
63
|
+
children: sheet
|
|
56
64
|
});
|
|
57
65
|
}
|
|
58
66
|
export * from './types';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["universal/BottomSheet/index.ios.tsx"],"sourcesContent":[null],"names":["BottomSheet","SwiftUIBottomSheet","Group","Host","frame","padding","presentationBackground","presentationDetents","presentationDragIndicator","resolveContentPadding","snapPointToDetent","snapPoint","children","isPresented","onDismiss","showDragIndicator","snapPoints","testID","modifiers","contentPadding","containerColor","top","bottom","left","right","presentationModifiers","maxWidth","Infinity","alignment","leading","trailing","length","push","map","
|
|
1
|
+
{"version":3,"sources":["universal/BottomSheet/index.ios.tsx"],"sourcesContent":[null],"names":["BottomSheet","SwiftUIBottomSheet","Group","Host","frame","padding","presentationBackground","presentationDetents","presentationDragIndicator","useIsInsideNativeTree","resolveContentPadding","snapPointToDetent","snapPoint","children","isPresented","onDismiss","showDragIndicator","snapPoints","testID","modifiers","contentPadding","containerColor","isInsideHost","top","bottom","left","right","presentationModifiers","maxWidth","Infinity","alignment","leading","trailing","length","push","map","sheet","onIsPresentedChange","presented","fitToContents","style","position","pointerEvents"],"mappings":";AAAA,SAASA,eAAeC,kBAAkB,EAAEC,KAAK,EAAEC,IAAI,QAAQ,oBAAoB;AACnF,SACEC,KAAK,EACLC,OAAO,EACPC,sBAAsB,EACtBC,mBAAmB,EACnBC,yBAAyB,QAGpB,8BAA8B;AAErC,SAASC,qBAAqB,QAAQ,0BAA0B;AAEhE,SAASC,qBAAqB,QAAQ,UAAU;AAEhD,SAASC,kBAAkBC,SAAoB;IAC7C,IAAIA,cAAc,QAAQ,OAAO;IACjC,IAAIA,cAAc,QAAQ,OAAO;IACjC,OAAOA;AACT;AAEA,OAAO,SAASZ,YAAY,EAC1Ba,QAAQ,EACRC,WAAW,EACXC,SAAS,EACTC,oBAAoB,IAAI,EACxBC,UAAU,EACVC,MAAM,EACNC,SAAS,EACTC,cAAc,EACdC,cAAc,EACG;IACjB,MAAMC,eAAeb;IACrB,MAAM,EAAEc,GAAG,EAAEC,MAAM,EAAEC,IAAI,EAAEC,KAAK,EAAE,GAAGhB,sBAAsBU,gBAAgB;QACzEG,KAAK;QACLC,QAAQ;QACRC,MAAM;QACNC,OAAO;IACT;IACA,MAAMC,wBAA0C;QAC9CvB,MAAM;YAAEwB,UAAUC;YAAUC,WAAW;QAAa;QACpDzB,QAAQ;YAAEkB;YAAKC;YAAQO,SAASN;YAAMO,UAAUN;QAAM;QACtDlB,0BAA0BQ,oBAAoB,YAAY;KAC3D;IACD,IAAIC,cAAcA,WAAWgB,MAAM,GAAG,GAAG;QACvCN,sBAAsBO,IAAI,CAAC3B,oBAAoBU,WAAWkB,GAAG,CAACxB;IAChE;IACA,IAAIU,gBAAgB;QAClBM,sBAAsBO,IAAI,CAAC5B,uBAAuBe;IACpD;IACA,IAAIF,WAAWc,QAAQ;QACrBN,sBAAsBO,IAAI,IAAIf;IAChC;IAEA,MAAMiB,sBACJ,KAACnC;QACCa,aAAaA;QACbuB,qBAAqB,CAACC;YACpB,IAAI,CAACA,WAAWvB;QAClB;QACAwB,eAAe,CAACtB,cAAcA,WAAWgB,MAAM,KAAK;QACpDf,QAAQA;kBACR,cAAA,KAAChB;YAAMiB,WAAWQ;sBAAwBd;;;IAI9C,8FAA8F;IAC9F,6CAA6C;IAC7C,IAAIS,cAAc;QAChB,OAAOc;IACT;IACA,qBACE,KAACjC;QAAKqC,OAAO;YAAEC,UAAU;QAAW;QAAGC,eAAc;kBAClDN;;AAGP;AAEA,cAAc,UAAU"}
|
package/ios/ChartView.swift
CHANGED
|
@@ -59,6 +59,8 @@ struct BarChartStyle: Record {
|
|
|
59
59
|
struct PieChartStyle: Record {
|
|
60
60
|
@Field var innerRadius: Double = 0.3
|
|
61
61
|
@Field var angularInset: Double = 2.0
|
|
62
|
+
@Field var cornerRadius: Double = 0.0
|
|
63
|
+
@Field var opacity: Double = 0.8
|
|
62
64
|
}
|
|
63
65
|
|
|
64
66
|
struct PointChartStyle: Record {
|
|
@@ -115,10 +117,11 @@ public struct ChartView: ExpoSwiftUI.View {
|
|
|
115
117
|
|
|
116
118
|
@available(iOS 17.0, tvOS 17.0, *)
|
|
117
119
|
private func createBasePieMark(for dataPoint: ChartDataPoint) -> SectorMark {
|
|
118
|
-
|
|
119
|
-
return SectorMark(angle: .value("Value", dataPoint.y), innerRadius: .ratio(style.innerRadius), angularInset: style.angularInset)
|
|
120
|
+
return SectorMark(angle: .value("Value", dataPoint.y), innerRadius: .ratio(pieStyle.innerRadius), angularInset: pieStyle.angularInset)
|
|
120
121
|
}
|
|
121
122
|
|
|
123
|
+
private var pieStyle: PieChartStyle { props.pieStyle ?? PieChartStyle() }
|
|
124
|
+
|
|
122
125
|
@available(iOS 16.0, tvOS 16.0, *)
|
|
123
126
|
private func createAreaMark(for dataPoint: ChartDataPoint) -> some ChartContent {
|
|
124
127
|
if let numericX = dataPoint.xNumericValue {
|
|
@@ -137,15 +140,13 @@ public struct ChartView: ExpoSwiftUI.View {
|
|
|
137
140
|
.foregroundStyle(props.lineStyle?.color ?? .blue)
|
|
138
141
|
.symbol(getSymbol(props.lineStyle?.pointStyle ?? .circle))
|
|
139
142
|
.symbolSize(CGFloat(props.lineStyle?.pointSize ?? 6.0))
|
|
140
|
-
.lineStyle(getLineStyle(props.lineStyle
|
|
141
|
-
.lineStyle(.init(lineWidth: CGFloat(props.lineStyle?.width ?? 2.0)))
|
|
143
|
+
.lineStyle(getLineStyle(props.lineStyle))
|
|
142
144
|
} else {
|
|
143
145
|
LineMark(x: .value("X", dataPoint.xValue), y: .value("Y", dataPoint.y))
|
|
144
146
|
.foregroundStyle(props.lineStyle?.color ?? .blue)
|
|
145
147
|
.symbol(getSymbol(props.lineStyle?.pointStyle ?? .circle))
|
|
146
148
|
.symbolSize(CGFloat(props.lineStyle?.pointSize ?? 6.0))
|
|
147
|
-
.lineStyle(getLineStyle(props.lineStyle
|
|
148
|
-
.lineStyle(.init(lineWidth: CGFloat(props.lineStyle?.width ?? 2.0)))
|
|
149
|
+
.lineStyle(getLineStyle(props.lineStyle))
|
|
149
150
|
}
|
|
150
151
|
}
|
|
151
152
|
|
|
@@ -214,9 +215,9 @@ public struct ChartView: ExpoSwiftUI.View {
|
|
|
214
215
|
case .pie:
|
|
215
216
|
if #available(iOS 17.0, tvOS 17.0, *) {
|
|
216
217
|
if hasIndividualColors {
|
|
217
|
-
createBasePieMark(for: dataPoint).foregroundStyle(dataPoint.color ?? .blue).opacity(
|
|
218
|
+
createBasePieMark(for: dataPoint).foregroundStyle(dataPoint.color ?? .blue).cornerRadius(CGFloat(pieStyle.cornerRadius)).opacity(pieStyle.opacity)
|
|
218
219
|
} else {
|
|
219
|
-
createBasePieMark(for: dataPoint).foregroundStyle(by: .value("Category", dataPoint.xValue)).opacity(
|
|
220
|
+
createBasePieMark(for: dataPoint).foregroundStyle(by: .value("Category", dataPoint.xValue)).cornerRadius(CGFloat(pieStyle.cornerRadius)).opacity(pieStyle.opacity)
|
|
220
221
|
}
|
|
221
222
|
}
|
|
222
223
|
case .rectangle:
|
|
@@ -254,7 +255,11 @@ public struct ChartView: ExpoSwiftUI.View {
|
|
|
254
255
|
}
|
|
255
256
|
}
|
|
256
257
|
|
|
257
|
-
|
|
258
|
-
|
|
258
|
+
// A single stroke style: chained `.lineStyle` modifiers don't merge, the first one wins.
|
|
259
|
+
private func getLineStyle(_ style: LineChartStyle?) -> StrokeStyle {
|
|
260
|
+
StrokeStyle(
|
|
261
|
+
lineWidth: CGFloat(style?.width ?? 2.0),
|
|
262
|
+
dash: (style?.dashArray ?? []).map { CGFloat($0) }
|
|
263
|
+
)
|
|
259
264
|
}
|
|
260
265
|
}
|
package/ios/GridView.swift
CHANGED
package/ios/HostView.swift
CHANGED
|
@@ -3,11 +3,28 @@
|
|
|
3
3
|
import SwiftUI
|
|
4
4
|
import ExpoModulesCore
|
|
5
5
|
|
|
6
|
-
/// Coordinate space anchored at the `Host
|
|
7
|
-
///
|
|
8
|
-
///
|
|
6
|
+
/// Coordinate space anchored at the `Host`'s SwiftUI root, which macOS measures hosted React Native
|
|
7
|
+
/// views from. iOS uses `HostingViewReference` instead, because this space starts after the
|
|
8
|
+
/// safe-area inset that `UIHostingController` applies to the root.
|
|
9
9
|
internal let expoHostCoordinateSpace = "expo.ui.host"
|
|
10
10
|
|
|
11
|
+
/// The enclosing `Host`'s UIKit view, which Yoga laid out. iOS measures hosted React Native views
|
|
12
|
+
/// from it.
|
|
13
|
+
internal final class HostingViewReference {
|
|
14
|
+
weak var view: UIView?
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
private struct HostingViewEnvironmentKey: EnvironmentKey {
|
|
18
|
+
static let defaultValue: HostingViewReference? = nil
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
extension EnvironmentValues {
|
|
22
|
+
var expoHostingView: HostingViewReference? {
|
|
23
|
+
get { self[HostingViewEnvironmentKey.self] }
|
|
24
|
+
set { self[HostingViewEnvironmentKey.self] = newValue }
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
11
28
|
internal enum ExpoColorScheme: String, Enumerable {
|
|
12
29
|
case light
|
|
13
30
|
case dark
|
|
@@ -46,7 +63,11 @@ internal final class HostViewProps: ExpoSwiftUI.ViewProps, ExpoSwiftUI.SafeAreaC
|
|
|
46
63
|
@Field var ignoreSafeArea: ExpoSwiftUI.IgnoreSafeArea?
|
|
47
64
|
@Field var modifiers: ModifierArray?
|
|
48
65
|
var onLayoutContent = EventDispatcher()
|
|
49
|
-
|
|
66
|
+
let hostingViewReference = HostingViewReference()
|
|
67
|
+
var hostingView: UIView? {
|
|
68
|
+
get { hostingViewReference.view }
|
|
69
|
+
set { hostingViewReference.view = newValue }
|
|
70
|
+
}
|
|
50
71
|
}
|
|
51
72
|
|
|
52
73
|
struct HostView: ExpoSwiftUI.View, ExpoSwiftUI.WithHostingView {
|
|
@@ -68,6 +89,7 @@ struct HostView: ExpoSwiftUI.View, ExpoSwiftUI.WithHostingView {
|
|
|
68
89
|
HostLayout {
|
|
69
90
|
Children()
|
|
70
91
|
}
|
|
92
|
+
.environment(\.expoHostingView, props.hostingViewReference)
|
|
71
93
|
.fixedSize(horizontal: props.matchContentsHorizontal, vertical: props.matchContentsVertical)
|
|
72
94
|
.modifier(LayoutDirectionModifier(layoutDirection: layoutDirection))
|
|
73
95
|
.modifier(ColorSchemeModifier(colorScheme: props.colorScheme?.toColorScheme()))
|
|
@@ -90,6 +112,7 @@ struct HostView: ExpoSwiftUI.View, ExpoSwiftUI.WithHostingView {
|
|
|
90
112
|
ZStack(alignment: alignment) {
|
|
91
113
|
Children()
|
|
92
114
|
}
|
|
115
|
+
.environment(\.expoHostingView, props.hostingViewReference)
|
|
93
116
|
.fixedSize(horizontal: props.matchContentsHorizontal, vertical: props.matchContentsVertical)
|
|
94
117
|
.modifier(LayoutDirectionModifier(layoutDirection: layoutDirection))
|
|
95
118
|
.modifier(ColorSchemeModifier(colorScheme: props.colorScheme?.toColorScheme()))
|
|
@@ -238,23 +238,39 @@ internal enum PresentationSizingOption: String, Enumerable {
|
|
|
238
238
|
case page
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
+
internal struct PresentationSizingFittedAxes: Record {
|
|
242
|
+
@Field var horizontal: Bool = false
|
|
243
|
+
@Field var vertical: Bool = false
|
|
244
|
+
}
|
|
245
|
+
|
|
241
246
|
internal struct PresentationSizingModifier: ViewModifier, Record {
|
|
242
247
|
@Field var sizing: PresentationSizingOption = .automatic
|
|
248
|
+
@Field var fitted: PresentationSizingFittedAxes?
|
|
243
249
|
|
|
244
250
|
func body(content: Content) -> some View {
|
|
245
251
|
if #available(iOS 18.0, tvOS 18.0, macOS 15.0, *) {
|
|
246
252
|
switch sizing {
|
|
247
253
|
case .automatic:
|
|
248
|
-
content.
|
|
254
|
+
applySizing(content, .automatic)
|
|
249
255
|
case .fitted:
|
|
250
|
-
content.
|
|
256
|
+
applySizing(content, .fitted)
|
|
251
257
|
case .form:
|
|
252
|
-
content.
|
|
258
|
+
applySizing(content, .form)
|
|
253
259
|
case .page:
|
|
254
|
-
content.
|
|
260
|
+
applySizing(content, .page)
|
|
255
261
|
}
|
|
256
262
|
} else {
|
|
257
263
|
content
|
|
258
264
|
}
|
|
259
265
|
}
|
|
266
|
+
|
|
267
|
+
@available(iOS 18.0, tvOS 18.0, macOS 15.0, *)
|
|
268
|
+
@ViewBuilder
|
|
269
|
+
private func applySizing(_ content: Content, _ sizing: some PresentationSizing) -> some View {
|
|
270
|
+
if let fitted {
|
|
271
|
+
content.presentationSizing(sizing.fitted(horizontal: fitted.horizontal, vertical: fitted.vertical))
|
|
272
|
+
} else {
|
|
273
|
+
content.presentationSizing(sizing)
|
|
274
|
+
}
|
|
275
|
+
}
|
|
260
276
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Copyright 2026-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
import ExpoModulesCore
|
|
4
|
+
import SwiftUI
|
|
5
|
+
|
|
6
|
+
internal enum SearchToolbarBehaviorType: String, Enumerable {
|
|
7
|
+
case automatic
|
|
8
|
+
case minimize
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
internal struct SearchToolbarBehaviorModifier: ViewModifier, Record {
|
|
12
|
+
@Field var behavior: SearchToolbarBehaviorType = .automatic
|
|
13
|
+
|
|
14
|
+
@ViewBuilder
|
|
15
|
+
func body(content: Content) -> some View {
|
|
16
|
+
if #available(iOS 26.0, macOS 26.0, tvOS 26.0, *) {
|
|
17
|
+
#if compiler(>=6.2) // Xcode 26
|
|
18
|
+
switch behavior {
|
|
19
|
+
case .automatic:
|
|
20
|
+
content.searchToolbarBehavior(.automatic)
|
|
21
|
+
case .minimize:
|
|
22
|
+
#if os(macOS) || os(tvOS)
|
|
23
|
+
content.searchToolbarBehavior(.automatic)
|
|
24
|
+
#else
|
|
25
|
+
content.searchToolbarBehavior(.minimize)
|
|
26
|
+
#endif
|
|
27
|
+
}
|
|
28
|
+
#else
|
|
29
|
+
content
|
|
30
|
+
#endif
|
|
31
|
+
} else {
|
|
32
|
+
content
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|