@expo/ui 56.0.1 → 56.0.3
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 +13 -0
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/ui/ExpoUIModule.kt +7 -1
- package/android/src/main/java/expo/modules/ui/MaskView.kt +56 -0
- package/android/src/main/java/expo/modules/ui/TextFieldView.kt +27 -80
- package/android/src/main/java/expo/modules/ui/icon/IconView.kt +6 -1
- package/build/community/bottom-sheet/BottomSheet.android.d.ts.map +1 -1
- package/build/community/bottom-sheet/BottomSheet.ios.d.ts.map +1 -1
- package/build/community/masked-view/MaskedView.android.d.ts +8 -0
- package/build/community/masked-view/MaskedView.android.d.ts.map +1 -0
- package/build/community/masked-view/MaskedView.d.ts +10 -0
- package/build/community/masked-view/MaskedView.d.ts.map +1 -0
- package/build/community/masked-view/MaskedView.ios.d.ts +8 -0
- package/build/community/masked-view/MaskedView.ios.d.ts.map +1 -0
- package/build/community/masked-view/index.d.ts +4 -0
- package/build/community/masked-view/index.d.ts.map +1 -0
- package/build/community/masked-view/types.d.ts +19 -0
- package/build/community/masked-view/types.d.ts.map +1 -0
- package/build/community/picker/Picker.android.d.ts +10 -2
- package/build/community/picker/Picker.android.d.ts.map +1 -1
- package/build/community/picker/Picker.d.ts +10 -2
- package/build/community/picker/Picker.d.ts.map +1 -1
- package/build/community/picker/Picker.ios.d.ts +10 -2
- package/build/community/picker/Picker.ios.d.ts.map +1 -1
- package/build/community/picker/types.d.ts +12 -10
- package/build/community/picker/types.d.ts.map +1 -1
- package/build/jetpack-compose/DropdownMenu/DropdownMenuItem.d.ts +4 -0
- package/build/jetpack-compose/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
- package/build/jetpack-compose/HorizontalFloatingToolbar/index.d.ts +8 -0
- package/build/jetpack-compose/HorizontalFloatingToolbar/index.d.ts.map +1 -1
- package/build/jetpack-compose/HorizontalPager/index.d.ts +2 -1
- package/build/jetpack-compose/HorizontalPager/index.d.ts.map +1 -1
- package/build/jetpack-compose/Icon/index.d.ts +12 -4
- package/build/jetpack-compose/Icon/index.d.ts.map +1 -1
- package/build/jetpack-compose/TextField/index.d.ts +21 -34
- package/build/jetpack-compose/TextField/index.d.ts.map +1 -1
- package/build/jetpack-compose/index.d.ts +2 -2
- package/build/jetpack-compose/index.d.ts.map +1 -1
- package/build/jetpack-compose/modifiers/index.d.ts +1 -1
- package/build/swift-ui/TextField/index.d.ts +1 -0
- package/build/swift-ui/TextField/index.d.ts.map +1 -1
- package/build/swift-ui/index.d.ts +1 -1
- package/build/swift-ui/index.d.ts.map +1 -1
- package/expo-module.config.json +1 -1
- package/ios/TextFieldView.swift +15 -15
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/{56.0.1/expo.modules.ui-56.0.1-sources.jar → 56.0.3/expo.modules.ui-56.0.3-sources.jar} +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.3/expo.modules.ui-56.0.3-sources.jar.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.3/expo.modules.ui-56.0.3-sources.jar.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.3/expo.modules.ui-56.0.3-sources.jar.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.3/expo.modules.ui-56.0.3-sources.jar.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.3/expo.modules.ui-56.0.3.aar +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.3/expo.modules.ui-56.0.3.aar.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.3/expo.modules.ui-56.0.3.aar.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.3/expo.modules.ui-56.0.3.aar.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.3/expo.modules.ui-56.0.3.aar.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/{56.0.1/expo.modules.ui-56.0.1.module → 56.0.3/expo.modules.ui-56.0.3.module} +23 -23
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.3/expo.modules.ui-56.0.3.module.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.3/expo.modules.ui-56.0.3.module.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.3/expo.modules.ui-56.0.3.module.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.3/expo.modules.ui-56.0.3.module.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/{56.0.1/expo.modules.ui-56.0.1.pom → 56.0.3/expo.modules.ui-56.0.3.pom} +2 -2
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.3/expo.modules.ui-56.0.3.pom.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.3/expo.modules.ui-56.0.3.pom.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.3/expo.modules.ui-56.0.3.pom.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.3/expo.modules.ui-56.0.3.pom.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +4 -4
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +1 -1
- package/package.json +18 -14
- package/src/community/bottom-sheet/BottomSheet.android.tsx +3 -2
- package/src/community/bottom-sheet/BottomSheet.ios.tsx +3 -2
- package/src/community/masked-view/MaskedView.android.tsx +40 -0
- package/src/community/masked-view/MaskedView.ios.tsx +32 -0
- package/src/community/masked-view/MaskedView.tsx +34 -0
- package/src/community/masked-view/index.tsx +3 -0
- package/src/community/masked-view/types.ts +19 -0
- package/src/community/picker/Picker.android.tsx +12 -5
- package/src/community/picker/Picker.ios.tsx +9 -6
- package/src/community/picker/Picker.tsx +3 -4
- package/src/community/picker/types.tsx +24 -18
- package/src/jetpack-compose/DropdownMenu/DropdownMenuItem.tsx +4 -6
- package/src/jetpack-compose/HorizontalFloatingToolbar/index.tsx +8 -8
- package/src/jetpack-compose/HorizontalPager/index.tsx +3 -1
- package/src/jetpack-compose/Icon/index.tsx +18 -5
- package/src/jetpack-compose/TextField/index.tsx +30 -50
- package/src/jetpack-compose/index.ts +17 -2
- package/src/jetpack-compose/modifiers/index.ts +1 -1
- package/src/swift-ui/TextField/index.tsx +3 -0
- package/src/swift-ui/index.tsx +6 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.1/expo.modules.ui-56.0.1-sources.jar.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.1/expo.modules.ui-56.0.1-sources.jar.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.1/expo.modules.ui-56.0.1-sources.jar.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.1/expo.modules.ui-56.0.1-sources.jar.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.1/expo.modules.ui-56.0.1.aar +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.1/expo.modules.ui-56.0.1.aar.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.1/expo.modules.ui-56.0.1.aar.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.1/expo.modules.ui-56.0.1.aar.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.1/expo.modules.ui-56.0.1.aar.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.1/expo.modules.ui-56.0.1.module.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.1/expo.modules.ui-56.0.1.module.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.1/expo.modules.ui-56.0.1.module.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.1/expo.modules.ui-56.0.1.module.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.1/expo.modules.ui-56.0.1.pom.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.1/expo.modules.ui-56.0.1.pom.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.1/expo.modules.ui-56.0.1.pom.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/56.0.1/expo.modules.ui-56.0.1.pom.sha512 +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
|
|
2
|
-
import { View } from 'react-native';
|
|
2
|
+
import { useWindowDimensions, View } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import { BottomSheetContext, BottomSheetInternalContext } from './context';
|
|
5
5
|
import type { BottomSheetMethods, BottomSheetProps } from './types';
|
|
@@ -82,6 +82,7 @@ export function BottomSheet(props: BottomSheetProps) {
|
|
|
82
82
|
handleComponent,
|
|
83
83
|
children,
|
|
84
84
|
} = props;
|
|
85
|
+
const { width } = useWindowDimensions();
|
|
85
86
|
|
|
86
87
|
// Two-state pattern for animated close:
|
|
87
88
|
// - isMounted: whether the native sheet tree exists in the React tree
|
|
@@ -234,7 +235,7 @@ export function BottomSheet(props: BottomSheetProps) {
|
|
|
234
235
|
return (
|
|
235
236
|
<BottomSheetInternalContext.Provider value={internalContextValue}>
|
|
236
237
|
<BottomSheetContext.Provider value={methods}>
|
|
237
|
-
<Host
|
|
238
|
+
<Host style={{ position: 'absolute', width }}>
|
|
238
239
|
<NativeBottomSheet
|
|
239
240
|
isPresented={isPresented}
|
|
240
241
|
onIsPresentedChange={handlePresentedChange}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { requireNativeView } from 'expo';
|
|
2
|
+
import { StyleSheet, View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import type { MaskedViewProps } from './types';
|
|
5
|
+
import { Host } from '../../jetpack-compose/Host';
|
|
6
|
+
import { RNHostView } from '../../jetpack-compose/RNHostView';
|
|
7
|
+
import { Slot } from '../../jetpack-compose/SlotView';
|
|
8
|
+
import { fillMaxSize } from '../../jetpack-compose/modifiers';
|
|
9
|
+
|
|
10
|
+
const MaskNativeView: React.ComponentType<{
|
|
11
|
+
alignment?: 'topStart';
|
|
12
|
+
modifiers?: ReturnType<typeof fillMaxSize>[];
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
}> = requireNativeView('ExpoUI', 'MaskView');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Android implementation of `MaskedView`. Bridges arbitrary React Native children
|
|
18
|
+
* (and `maskElement`) into the Compose `MaskView` primitive via `RNHostView`.
|
|
19
|
+
*/
|
|
20
|
+
export function MaskedView(props: MaskedViewProps) {
|
|
21
|
+
const { maskElement, children, style, ...viewProps } = props;
|
|
22
|
+
return (
|
|
23
|
+
<View {...viewProps} style={style}>
|
|
24
|
+
<Host style={StyleSheet.absoluteFill}>
|
|
25
|
+
<MaskNativeView alignment="topStart" modifiers={[fillMaxSize()]}>
|
|
26
|
+
<RNHostView modifiers={[fillMaxSize()]}>
|
|
27
|
+
<View style={[StyleSheet.absoluteFill, style]}>{children}</View>
|
|
28
|
+
</RNHostView>
|
|
29
|
+
<Slot slotName="content">
|
|
30
|
+
<RNHostView modifiers={[fillMaxSize()]}>
|
|
31
|
+
<View style={[StyleSheet.absoluteFill, style]}>{maskElement}</View>
|
|
32
|
+
</RNHostView>
|
|
33
|
+
</Slot>
|
|
34
|
+
</MaskNativeView>
|
|
35
|
+
</Host>
|
|
36
|
+
</View>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default MaskedView;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { StyleSheet, View } from 'react-native';
|
|
2
|
+
|
|
3
|
+
import type { MaskedViewProps } from './types';
|
|
4
|
+
import { Host } from '../../swift-ui/Host';
|
|
5
|
+
import { Mask } from '../../swift-ui/Mask';
|
|
6
|
+
import { RNHostView } from '../../swift-ui/RNHostView';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* iOS implementation of `MaskedView`. Bridges arbitrary React Native children
|
|
10
|
+
* (and `maskElement`) into the SwiftUI `Mask` primitive via `RNHostView`.
|
|
11
|
+
*/
|
|
12
|
+
export function MaskedView(props: MaskedViewProps) {
|
|
13
|
+
const { maskElement, children, style, ...viewProps } = props;
|
|
14
|
+
return (
|
|
15
|
+
<View {...viewProps} style={style}>
|
|
16
|
+
<Host style={StyleSheet.absoluteFill}>
|
|
17
|
+
<Mask alignment="topLeading">
|
|
18
|
+
<RNHostView>
|
|
19
|
+
<View style={[StyleSheet.absoluteFill, style]}>{children}</View>
|
|
20
|
+
</RNHostView>
|
|
21
|
+
<Mask.Content>
|
|
22
|
+
<RNHostView>
|
|
23
|
+
<View style={[StyleSheet.absoluteFill, style]}>{maskElement}</View>
|
|
24
|
+
</RNHostView>
|
|
25
|
+
</Mask.Content>
|
|
26
|
+
</Mask>
|
|
27
|
+
</Host>
|
|
28
|
+
</View>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default MaskedView;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import type { MaskedViewProps } from './types';
|
|
5
|
+
|
|
6
|
+
let warned = false;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Renders `children` with the alpha channel of `maskElement` applied as a mask:
|
|
10
|
+
* opaque pixels of `maskElement` reveal `children`, transparent pixels hide them.
|
|
11
|
+
*
|
|
12
|
+
* API-compatible with `@react-native-masked-view/masked-view`.
|
|
13
|
+
*/
|
|
14
|
+
// This default file is used on platforms without a `.<platform>.tsx` override
|
|
15
|
+
// (notably web). It renders children unmasked and warns once.
|
|
16
|
+
export function MaskedView(props: MaskedViewProps) {
|
|
17
|
+
const { maskElement: _maskElement, children, style, ...rest } = props;
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (!warned) {
|
|
20
|
+
warned = true;
|
|
21
|
+
console.warn(
|
|
22
|
+
'[@expo/ui/community/masked-view] MaskedView is not implemented on this platform. ' +
|
|
23
|
+
'Children will render without a mask.'
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
}, []);
|
|
27
|
+
return (
|
|
28
|
+
<View {...rest} style={style}>
|
|
29
|
+
{children}
|
|
30
|
+
</View>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default MaskedView;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode } from 'react';
|
|
2
|
+
import type { ViewProps } from 'react-native';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Drop-in props for `@react-native-masked-view/masked-view`'s `MaskedView`.
|
|
6
|
+
*
|
|
7
|
+
* @see https://github.com/callstack/masked-view
|
|
8
|
+
*/
|
|
9
|
+
export interface MaskedViewProps extends ViewProps {
|
|
10
|
+
/**
|
|
11
|
+
* The element used as the mask. Only opaque pixels of `maskElement` make the
|
|
12
|
+
* masked content visible — transparent pixels hide it.
|
|
13
|
+
*/
|
|
14
|
+
maskElement: ReactElement;
|
|
15
|
+
/**
|
|
16
|
+
* Content rendered behind the mask.
|
|
17
|
+
*/
|
|
18
|
+
children?: ReactNode;
|
|
19
|
+
}
|
|
@@ -3,7 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
import {
|
|
4
4
|
extractPickerItems,
|
|
5
5
|
PickerItem,
|
|
6
|
-
type
|
|
6
|
+
type PickerItemProps,
|
|
7
7
|
type PickerItemValue,
|
|
8
8
|
type PickerProps,
|
|
9
9
|
} from './types';
|
|
@@ -22,7 +22,7 @@ import { menuAnchor } from '../../jetpack-compose/modifiers';
|
|
|
22
22
|
* A drop-in replacement for `@react-native-picker/picker` on Android.
|
|
23
23
|
* Renders a Material 3 `ExposedDropdownMenuBox` wrapped in a Host.
|
|
24
24
|
*/
|
|
25
|
-
function
|
|
25
|
+
export function Picker<T extends PickerItemValue>(props: PickerProps<T>) {
|
|
26
26
|
const { selectedValue, onValueChange, enabled, style, children, ref } = props;
|
|
27
27
|
const items = extractPickerItems<T>(children);
|
|
28
28
|
const [expanded, setExpanded] = React.useState(false);
|
|
@@ -52,7 +52,15 @@ function PickerImpl<T extends PickerItemValue>(props: PickerProps<T>) {
|
|
|
52
52
|
setExpanded(false);
|
|
53
53
|
}}>
|
|
54
54
|
<DropdownMenuItem.Text>
|
|
55
|
-
<Text
|
|
55
|
+
<Text
|
|
56
|
+
color={item.color}
|
|
57
|
+
style={{
|
|
58
|
+
fontFamily: item.fontFamily,
|
|
59
|
+
fontSize: item.fontSize,
|
|
60
|
+
background: item.backgroundColor,
|
|
61
|
+
}}>
|
|
62
|
+
{item.label}
|
|
63
|
+
</Text>
|
|
56
64
|
</DropdownMenuItem.Text>
|
|
57
65
|
</DropdownMenuItem>
|
|
58
66
|
))}
|
|
@@ -62,5 +70,4 @@ function PickerImpl<T extends PickerItemValue>(props: PickerProps<T>) {
|
|
|
62
70
|
);
|
|
63
71
|
}
|
|
64
72
|
|
|
65
|
-
|
|
66
|
-
export const Picker: PickerWithItems = Object.assign(PickerImpl, { Item: PickerItem });
|
|
73
|
+
Picker.Item = PickerItem as React.ComponentType<PickerItemProps>;
|
|
@@ -3,7 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
import {
|
|
4
4
|
extractPickerItems,
|
|
5
5
|
PickerItem,
|
|
6
|
-
type
|
|
6
|
+
type PickerItemProps,
|
|
7
7
|
type PickerItemValue,
|
|
8
8
|
type PickerProps,
|
|
9
9
|
} from './types';
|
|
@@ -11,6 +11,7 @@ import { Host } from '../../swift-ui/Host';
|
|
|
11
11
|
import { Picker as SwiftUIPicker } from '../../swift-ui/Picker';
|
|
12
12
|
import { Text } from '../../swift-ui/Text';
|
|
13
13
|
import {
|
|
14
|
+
backgroundOverlay,
|
|
14
15
|
disabled as disabledModifier,
|
|
15
16
|
fixedSize,
|
|
16
17
|
foregroundStyle,
|
|
@@ -24,7 +25,7 @@ import { type ModifierConfig } from '../../types';
|
|
|
24
25
|
* A drop-in replacement for `@react-native-picker/picker` on iOS.
|
|
25
26
|
* Renders a SwiftUI wheel picker wrapped in a Host.
|
|
26
27
|
*/
|
|
27
|
-
function
|
|
28
|
+
export function Picker<T extends PickerItemValue>(props: PickerProps<T>) {
|
|
28
29
|
const { selectedValue, onValueChange, enabled, style, children, ref } = props;
|
|
29
30
|
const items = extractPickerItems<T>(children);
|
|
30
31
|
const modifiers = [
|
|
@@ -55,8 +56,11 @@ function PickerImpl<T extends PickerItemValue>(props: PickerProps<T>) {
|
|
|
55
56
|
if (item.color) {
|
|
56
57
|
itemModifiers.push(foregroundStyle(item.color));
|
|
57
58
|
}
|
|
58
|
-
if (item.fontFamily) {
|
|
59
|
-
itemModifiers.push(font({ family: item.fontFamily }));
|
|
59
|
+
if (item.fontFamily || item.fontSize != null) {
|
|
60
|
+
itemModifiers.push(font({ family: item.fontFamily, size: item.fontSize }));
|
|
61
|
+
}
|
|
62
|
+
if (item.backgroundColor) {
|
|
63
|
+
itemModifiers.push(backgroundOverlay({ color: item.backgroundColor }));
|
|
60
64
|
}
|
|
61
65
|
return (
|
|
62
66
|
<Text key={String(item.value ?? index)} modifiers={itemModifiers}>
|
|
@@ -69,5 +73,4 @@ function PickerImpl<T extends PickerItemValue>(props: PickerProps<T>) {
|
|
|
69
73
|
);
|
|
70
74
|
}
|
|
71
75
|
|
|
72
|
-
|
|
73
|
-
export const Picker: PickerWithItems = Object.assign(PickerImpl, { Item: PickerItem });
|
|
76
|
+
Picker.Item = PickerItem as React.ComponentType<PickerItemProps>;
|
|
@@ -3,7 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
import {
|
|
4
4
|
extractPickerItems,
|
|
5
5
|
PickerItem,
|
|
6
|
-
type
|
|
6
|
+
type PickerItemProps,
|
|
7
7
|
type PickerItemValue,
|
|
8
8
|
type PickerProps,
|
|
9
9
|
} from './types';
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
* A drop-in replacement for `@react-native-picker/picker` on web.
|
|
13
13
|
* Renders a native `<select>` element.
|
|
14
14
|
*/
|
|
15
|
-
function
|
|
15
|
+
export function Picker<T extends PickerItemValue>(props: PickerProps<T>) {
|
|
16
16
|
const { selectedValue, onValueChange, enabled, style, children, ref } = props;
|
|
17
17
|
const items = extractPickerItems<T>(children);
|
|
18
18
|
const selectRef = React.useRef<HTMLSelectElement>(null);
|
|
@@ -47,5 +47,4 @@ function PickerImpl<T extends PickerItemValue>(props: PickerProps<T>) {
|
|
|
47
47
|
);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
export const Picker: PickerWithItems = Object.assign(PickerImpl, { Item: PickerItem });
|
|
50
|
+
Picker.Item = PickerItem as React.ComponentType<PickerItemProps>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Children, isValidElement, type Ref, type ReactNode, type ReactElement } from 'react';
|
|
2
|
-
import type
|
|
2
|
+
import { StyleSheet, type StyleProp, type TextStyle, type ViewStyle } from 'react-native';
|
|
3
3
|
|
|
4
4
|
export type PickerItemValue = string | number | null;
|
|
5
5
|
|
|
@@ -7,7 +7,7 @@ export type PickerItemValue = string | number | null;
|
|
|
7
7
|
* Props for the `Picker.Item` component.
|
|
8
8
|
* Compatible with `@react-native-picker/picker`.
|
|
9
9
|
*/
|
|
10
|
-
export type PickerItemProps<T extends PickerItemValue> = {
|
|
10
|
+
export type PickerItemProps<T extends PickerItemValue = PickerItemValue> = {
|
|
11
11
|
/**
|
|
12
12
|
* Display text for the item.
|
|
13
13
|
*/
|
|
@@ -17,15 +17,19 @@ export type PickerItemProps<T extends PickerItemValue> = {
|
|
|
17
17
|
*/
|
|
18
18
|
value?: T;
|
|
19
19
|
/**
|
|
20
|
-
* Text color for the item.
|
|
21
|
-
* @platform ios
|
|
20
|
+
* Text color for the item. Equivalent to setting `color` in the `style` prop.
|
|
22
21
|
*/
|
|
23
22
|
color?: string;
|
|
24
23
|
/**
|
|
25
|
-
* Custom font family for the item.
|
|
26
|
-
* @platform ios
|
|
24
|
+
* Custom font family for the item. Equivalent to setting `fontFamily` in the `style` prop.
|
|
27
25
|
*/
|
|
28
26
|
fontFamily?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Style applied to the item label. Only the following values take effect:
|
|
29
|
+
* `color`, `backgroundColor`, `fontFamily`, and `fontSize`. When also set
|
|
30
|
+
* via the top-level `color` or `fontFamily` props, values from `style` win.
|
|
31
|
+
*/
|
|
32
|
+
style?: StyleProp<TextStyle>;
|
|
29
33
|
/**
|
|
30
34
|
* Whether the item is enabled.
|
|
31
35
|
* @platform android
|
|
@@ -99,16 +103,13 @@ export type PickerRef = {
|
|
|
99
103
|
blur: () => void;
|
|
100
104
|
};
|
|
101
105
|
|
|
102
|
-
export type PickerWithItems = {
|
|
103
|
-
<T extends PickerItemValue>(props: PickerProps<T>): ReactElement | null;
|
|
104
|
-
Item: typeof PickerItem;
|
|
105
|
-
};
|
|
106
|
-
|
|
107
106
|
export type ExtractedPickerItem<T extends PickerItemValue = PickerItemValue> = {
|
|
108
107
|
label: string;
|
|
109
108
|
value: T;
|
|
110
109
|
color?: string;
|
|
110
|
+
backgroundColor?: string;
|
|
111
111
|
fontFamily?: string;
|
|
112
|
+
fontSize?: number;
|
|
112
113
|
enabled?: boolean;
|
|
113
114
|
};
|
|
114
115
|
|
|
@@ -123,11 +124,16 @@ export function extractPickerItems<T extends PickerItemValue>(
|
|
|
123
124
|
(child): child is ReactElement<PickerItemProps<T>> =>
|
|
124
125
|
isValidElement(child) && child.type === PickerItem
|
|
125
126
|
)
|
|
126
|
-
.map(({ props: { label = '', value, color, fontFamily, enabled } }) =>
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
127
|
+
.map(({ props: { label = '', value, color, fontFamily, style, enabled } }) => {
|
|
128
|
+
const flat = StyleSheet.flatten(style);
|
|
129
|
+
return {
|
|
130
|
+
label,
|
|
131
|
+
value: value as T,
|
|
132
|
+
color: (flat?.color as string | undefined) ?? color,
|
|
133
|
+
backgroundColor: flat?.backgroundColor as string | undefined,
|
|
134
|
+
fontFamily: flat?.fontFamily ?? fontFamily,
|
|
135
|
+
fontSize: flat?.fontSize,
|
|
136
|
+
enabled,
|
|
137
|
+
};
|
|
138
|
+
});
|
|
133
139
|
}
|
|
@@ -22,12 +22,10 @@ export type DropdownMenuItemElementColors = {
|
|
|
22
22
|
textColor?: ColorValue;
|
|
23
23
|
/** Color of the text when the menu item is disabled. */
|
|
24
24
|
disabledTextColor?: ColorValue;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
// disabledLeadingIconColor?: ColorValue;
|
|
30
|
-
// disabledTrailingIconColor?: ColorValue;
|
|
25
|
+
leadingIconColor?: ColorValue;
|
|
26
|
+
trailingIconColor?: ColorValue;
|
|
27
|
+
disabledLeadingIconColor?: ColorValue;
|
|
28
|
+
disabledTrailingIconColor?: ColorValue;
|
|
31
29
|
};
|
|
32
30
|
|
|
33
31
|
/**
|
|
@@ -10,20 +10,20 @@ export type HorizontalFloatingToolbarColors = {
|
|
|
10
10
|
*/
|
|
11
11
|
toolbarContainerColor?: ColorValue;
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Color of the toolbar content (icons/text).
|
|
15
|
+
*/
|
|
16
|
+
toolbarContentColor?: ColorValue;
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Color of the floating action button container (background).
|
|
20
20
|
*/
|
|
21
21
|
fabContainerColor?: ColorValue;
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Color of the floating action button content (icon).
|
|
25
|
+
*/
|
|
26
|
+
fabContentColor?: ColorValue;
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
export type HorizontalFloatingToolbarProps = {
|
|
@@ -2,9 +2,11 @@ import { requireNativeView } from 'expo';
|
|
|
2
2
|
import type { Ref } from 'react';
|
|
3
3
|
|
|
4
4
|
import { type ModifierConfig, type ViewEvent } from '../../types';
|
|
5
|
-
import type
|
|
5
|
+
import { type PaddingValuesRecord } from '../Carousel';
|
|
6
6
|
import { createViewModifierEventListener } from '../modifiers/utils';
|
|
7
7
|
|
|
8
|
+
export type { PaddingValuesRecord };
|
|
9
|
+
|
|
8
10
|
export type HorizontalPagerHandle = {
|
|
9
11
|
/**
|
|
10
12
|
* Mirrors Compose's `PagerState.animateScrollToPage`. Resolves when the
|
|
@@ -23,16 +23,22 @@ export type IconProps = {
|
|
|
23
23
|
source: ImageSourcePropType;
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
* The tint color to apply to the icon.
|
|
27
|
-
*
|
|
26
|
+
* The tint color to apply to the icon. Accepts hex strings, named colors,
|
|
27
|
+
* or RGB arrays.
|
|
28
|
+
*
|
|
29
|
+
* - When omitted, the icon inherits the color from the surrounding
|
|
30
|
+
* `LocalContentColor` (e.g. the toolbar/FAB content color).
|
|
31
|
+
* - When set to `null`, no tint is applied — the icon is drawn with its
|
|
32
|
+
* original colors (`Color.Unspecified`). Use this for multicolored icons.
|
|
28
33
|
*
|
|
29
34
|
* @example
|
|
30
35
|
* ```tsx
|
|
31
36
|
* <Icon source={require('./assets/star.xml')} tint="#007AFF" />
|
|
32
37
|
* <Icon source={require('./assets/star.xml')} tint="blue" />
|
|
38
|
+
* <Icon source={require('./assets/multicolor.xml')} tint={null} />
|
|
33
39
|
* ```
|
|
34
40
|
*/
|
|
35
|
-
tint?: ColorValue;
|
|
41
|
+
tint?: ColorValue | null;
|
|
36
42
|
|
|
37
43
|
/**
|
|
38
44
|
* The size of the icon in density-independent pixels (dp).
|
|
@@ -80,8 +86,10 @@ export type IconProps = {
|
|
|
80
86
|
/**
|
|
81
87
|
* @hidden
|
|
82
88
|
*/
|
|
83
|
-
export type NativeIconProps = Omit<IconProps, 'source'> & {
|
|
89
|
+
export type NativeIconProps = Omit<IconProps, 'source' | 'tint'> & {
|
|
84
90
|
source: ImageResolvedAssetSource;
|
|
91
|
+
tint?: ColorValue;
|
|
92
|
+
inheritTint: boolean;
|
|
85
93
|
};
|
|
86
94
|
|
|
87
95
|
const IconNativeView: React.ComponentType<NativeIconProps> = requireNativeView(
|
|
@@ -90,12 +98,17 @@ const IconNativeView: React.ComponentType<NativeIconProps> = requireNativeView(
|
|
|
90
98
|
);
|
|
91
99
|
|
|
92
100
|
function transformIconProps(props: IconProps): NativeIconProps {
|
|
93
|
-
const { source, modifiers, ...restProps } = props;
|
|
101
|
+
const { source, modifiers, tint, ...restProps } = props;
|
|
102
|
+
// Differentiate "tint not provided" (inherit `LocalContentColor`) from
|
|
103
|
+
// "tint explicitly null" (no tint, draw original colors).
|
|
104
|
+
const tintIsExplicitlyNull = 'tint' in props && tint === null;
|
|
94
105
|
|
|
95
106
|
return {
|
|
96
107
|
modifiers,
|
|
97
108
|
...(modifiers ? createViewModifierEventListener(modifiers) : undefined),
|
|
98
109
|
...restProps,
|
|
110
|
+
tint: tint ?? undefined,
|
|
111
|
+
inheritTint: !tintIsExplicitlyNull,
|
|
99
112
|
source: Image.resolveAssetSource(source),
|
|
100
113
|
};
|
|
101
114
|
}
|
|
@@ -126,23 +126,15 @@ export type TextFieldColors = {
|
|
|
126
126
|
errorSuffixColor?: ColorValue;
|
|
127
127
|
};
|
|
128
128
|
|
|
129
|
-
export type TextFieldValue = {
|
|
130
|
-
text: string;
|
|
131
|
-
selection: { start: number; end: number };
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
export type TextFieldValueLike = string | TextFieldValue;
|
|
135
|
-
|
|
136
129
|
/** Shared props between `TextField` and `OutlinedTextField`. */
|
|
137
|
-
type BaseTextFieldProps
|
|
130
|
+
type BaseTextFieldProps = {
|
|
138
131
|
ref?: Ref<TextFieldRef>;
|
|
139
132
|
/**
|
|
140
|
-
* An observable state that holds the current value. Create one with
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
* If omitted, the field manages its own internal state.
|
|
133
|
+
* An observable state that holds the current text value. Create one with
|
|
134
|
+
* `useNativeState('initial text')`. If omitted, the field manages its own
|
|
135
|
+
* internal state.
|
|
144
136
|
*/
|
|
145
|
-
value?: ObservableState<
|
|
137
|
+
value?: ObservableState<string>;
|
|
146
138
|
/** If true, the text field will be focused automatically when mounted. @default false */
|
|
147
139
|
autoFocus?: boolean;
|
|
148
140
|
/** @default true */
|
|
@@ -173,20 +165,18 @@ type BaseTextFieldProps<T extends TextFieldValueLike = string> = {
|
|
|
173
165
|
};
|
|
174
166
|
|
|
175
167
|
/**
|
|
176
|
-
* Observable state
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
168
|
+
* Observable state holding the current selection range. Create with
|
|
169
|
+
* `useNativeState({ start: 0, end: 0 })`. The field writes user-driven
|
|
170
|
+
* changes back to it, and writes from JS (or a worklet) update the
|
|
171
|
+
* cursor/selection in the field. Use `ref.setSelection(start, end)` for
|
|
172
|
+
* imperative one-shot updates.
|
|
180
173
|
*/
|
|
181
174
|
selection?: ObservableState<{ start: number; end: number }>;
|
|
182
175
|
|
|
183
176
|
/** Maximum number of characters allowed. Truncates natively as the user types. */
|
|
184
177
|
maxLength?: number;
|
|
185
178
|
|
|
186
|
-
/**
|
|
187
|
-
* Called when the selection range changes.
|
|
188
|
-
* @internal
|
|
189
|
-
*/
|
|
179
|
+
/** Called when the selection range changes. */
|
|
190
180
|
onSelectionChange?: (selection: { start: number; end: number }) => void;
|
|
191
181
|
|
|
192
182
|
/**
|
|
@@ -215,15 +205,12 @@ type BaseTextFieldProps<T extends TextFieldValueLike = string> = {
|
|
|
215
205
|
keyboardOptions?: TextFieldKeyboardOptions;
|
|
216
206
|
keyboardActions?: TextFieldKeyboardActions;
|
|
217
207
|
/**
|
|
218
|
-
* Fires whenever the value changes.
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
* If marked with the `'worklet'` directive, runs synchronously on the UI thread;
|
|
224
|
-
* otherwise delivered asynchronously as a regular JS event.
|
|
208
|
+
* Fires whenever the text value changes. If marked with the `'worklet'`
|
|
209
|
+
* directive, runs synchronously on the UI thread; otherwise delivered
|
|
210
|
+
* asynchronously as a regular JS event. Use `onSelectionChange` (or read
|
|
211
|
+
* the `selection` observable) to react to selection-only changes.
|
|
225
212
|
*/
|
|
226
|
-
onValueChange?: (value:
|
|
213
|
+
onValueChange?: (value: string) => void;
|
|
227
214
|
/** A callback triggered when the field gains or loses focus. */
|
|
228
215
|
onFocusChanged?: (focused: boolean) => void;
|
|
229
216
|
shape?: object;
|
|
@@ -232,14 +219,13 @@ type BaseTextFieldProps<T extends TextFieldValueLike = string> = {
|
|
|
232
219
|
children?: React.ReactNode;
|
|
233
220
|
};
|
|
234
221
|
|
|
235
|
-
export type TextFieldProps
|
|
222
|
+
export type TextFieldProps = BaseTextFieldProps & {
|
|
236
223
|
colors?: TextFieldColors;
|
|
237
224
|
};
|
|
238
225
|
|
|
239
|
-
export type OutlinedTextFieldProps
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
};
|
|
226
|
+
export type OutlinedTextFieldProps = BaseTextFieldProps & {
|
|
227
|
+
colors?: TextFieldColors;
|
|
228
|
+
};
|
|
243
229
|
|
|
244
230
|
// endregion Types
|
|
245
231
|
|
|
@@ -263,7 +249,7 @@ type NativeTextFieldProps = Omit<
|
|
|
263
249
|
value?: number | null;
|
|
264
250
|
selection?: number | null;
|
|
265
251
|
onValueChangeSync?: number | null;
|
|
266
|
-
} & ViewEvent<'onValueChange',
|
|
252
|
+
} & ViewEvent<'onValueChange', { text: string; selection: { start: number; end: number } }> &
|
|
267
253
|
ViewEvent<'onFocusChanged', { value: boolean }> &
|
|
268
254
|
ViewEvent<'onSelectionChange', { start: number; end: number }> &
|
|
269
255
|
ViewEvent<'onKeyboardAction', { action: string; value: string }>;
|
|
@@ -273,8 +259,8 @@ const TextFieldNativeView: React.ComponentType<NativeTextFieldProps> = requireNa
|
|
|
273
259
|
'TextFieldView'
|
|
274
260
|
);
|
|
275
261
|
|
|
276
|
-
function useTransformedProps
|
|
277
|
-
props: TextFieldProps
|
|
262
|
+
function useTransformedProps(
|
|
263
|
+
props: TextFieldProps | OutlinedTextFieldProps,
|
|
278
264
|
variant: 'filled' | 'outlined'
|
|
279
265
|
): NativeTextFieldProps {
|
|
280
266
|
const {
|
|
@@ -289,8 +275,6 @@ function useTransformedProps<T extends TextFieldValueLike>(
|
|
|
289
275
|
...restProps
|
|
290
276
|
} = props;
|
|
291
277
|
|
|
292
|
-
const isStringMode = !value || typeof value.value === 'string';
|
|
293
|
-
|
|
294
278
|
const isWorklet = !!onValueChange && !!worklets?.isWorkletFunction?.(onValueChange);
|
|
295
279
|
const workletCallback = useWorkletProp(isWorklet ? onValueChange : undefined, 'onValueChange');
|
|
296
280
|
|
|
@@ -300,16 +284,11 @@ function useTransformedProps<T extends TextFieldValueLike>(
|
|
|
300
284
|
...restProps,
|
|
301
285
|
variant,
|
|
302
286
|
children,
|
|
303
|
-
value: getStateId(value
|
|
287
|
+
value: getStateId(value),
|
|
304
288
|
selection: getStateId(selection),
|
|
305
289
|
onValueChangeSync: getStateId(workletCallback),
|
|
306
290
|
onValueChange:
|
|
307
|
-
!isWorklet && onValueChange
|
|
308
|
-
? (event) => {
|
|
309
|
-
const payload = event.nativeEvent;
|
|
310
|
-
onValueChange((isStringMode ? payload.text : payload) as T);
|
|
311
|
-
}
|
|
312
|
-
: undefined,
|
|
291
|
+
!isWorklet && onValueChange ? (event) => onValueChange(event.nativeEvent.text) : undefined,
|
|
313
292
|
onFocusChanged: onFocusChanged ? (event) => onFocusChanged(event.nativeEvent.value) : undefined,
|
|
314
293
|
onSelectionChange: onSelectionChange
|
|
315
294
|
? (event) => onSelectionChange({ start: event.nativeEvent.start, end: event.nativeEvent.end })
|
|
@@ -370,7 +349,7 @@ function SupportingText(props: { children: React.ReactNode }) {
|
|
|
370
349
|
/**
|
|
371
350
|
* A Material3 `TextField`.
|
|
372
351
|
*/
|
|
373
|
-
function TextFieldComponent
|
|
352
|
+
function TextFieldComponent(props: TextFieldProps) {
|
|
374
353
|
return <TextFieldNativeView {...useTransformedProps(props, 'filled')} />;
|
|
375
354
|
}
|
|
376
355
|
|
|
@@ -385,9 +364,7 @@ TextFieldComponent.SupportingText = SupportingText;
|
|
|
385
364
|
/**
|
|
386
365
|
* A Material3 `OutlinedTextField` with a transparent background and border outline.
|
|
387
366
|
*/
|
|
388
|
-
function OutlinedTextFieldComponent
|
|
389
|
-
props: OutlinedTextFieldProps<T>
|
|
390
|
-
) {
|
|
367
|
+
function OutlinedTextFieldComponent(props: OutlinedTextFieldProps) {
|
|
391
368
|
return <TextFieldNativeView {...useTransformedProps(props, 'outlined')} />;
|
|
392
369
|
}
|
|
393
370
|
|
|
@@ -402,3 +379,6 @@ OutlinedTextFieldComponent.SupportingText = SupportingText;
|
|
|
402
379
|
// endregion Components
|
|
403
380
|
|
|
404
381
|
export { TextFieldComponent as TextField, OutlinedTextFieldComponent as OutlinedTextField };
|
|
382
|
+
|
|
383
|
+
// Exported for docs api data
|
|
384
|
+
export { type ObservableState };
|