react-native-platform-components 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -31
- package/android/src/main/java/com/platformcomponents/PCButtonGroupView.kt +498 -0
- package/android/src/main/java/com/platformcomponents/PCButtonGroupViewManager.kt +191 -0
- package/android/src/main/java/com/platformcomponents/PCButtonSupport.kt +127 -0
- package/android/src/main/java/com/platformcomponents/PCButtonView.kt +345 -0
- package/android/src/main/java/com/platformcomponents/PCButtonViewManager.kt +126 -0
- package/android/src/main/java/com/platformcomponents/PCExpressive.kt +107 -0
- package/android/src/main/java/com/platformcomponents/PCFloatingToolbarView.kt +115 -0
- package/android/src/main/java/com/platformcomponents/PCFloatingToolbarViewManager.kt +65 -0
- package/android/src/main/java/com/platformcomponents/PCNativeThemeModule.kt +3 -0
- package/android/src/main/java/com/platformcomponents/PCSegmentedControlView.kt +13 -5
- package/android/src/main/java/com/platformcomponents/PCSegmentedControlViewManager.kt +6 -1
- package/android/src/main/java/com/platformcomponents/PCTextFieldView.kt +1018 -0
- package/android/src/main/java/com/platformcomponents/PCTextFieldViewManager.kt +248 -0
- package/android/src/main/java/com/platformcomponents/PlatformComponentsPackage.kt +13 -6
- package/android/src/main/jni/CMakeLists.txt +13 -1
- package/android/src/main/res/values/attrs.xml +13 -0
- package/android/src/main/res/values/styles.xml +183 -0
- package/ios/PCButton.h +10 -0
- package/ios/PCButton.mm +196 -0
- package/ios/PCButtonGroup.h +10 -0
- package/ios/PCButtonGroup.mm +256 -0
- package/ios/PCButtonGroupView.swift +254 -0
- package/ios/PCButtonSupport.swift +141 -0
- package/ios/PCButtonView.swift +155 -0
- package/ios/PCFloatingToolbar.h +10 -0
- package/ios/PCFloatingToolbar.mm +76 -0
- package/ios/PCFloatingToolbarView.swift +95 -0
- package/ios/PCNativeThemeModule.mm +13 -0
- package/ios/PCSelectionMenu.swift +9 -1
- package/ios/PCTextField.h +10 -0
- package/ios/PCTextField.mm +391 -0
- package/ios/PCTextFieldView.swift +1012 -0
- package/lib/commonjs/Button.js +77 -0
- package/lib/commonjs/Button.js.map +1 -0
- package/lib/commonjs/ButtonGroup.js +99 -0
- package/lib/commonjs/ButtonGroup.js.map +1 -0
- package/lib/commonjs/ButtonGroupNativeComponent.ts +121 -0
- package/lib/commonjs/ButtonNativeComponent.ts +76 -0
- package/lib/commonjs/ContextMenuNativeComponent.ts +5 -4
- package/lib/commonjs/DatePickerNativeComponent.ts +17 -11
- package/lib/commonjs/FloatingToolbar.js +69 -0
- package/lib/commonjs/FloatingToolbar.js.map +1 -0
- package/lib/commonjs/FloatingToolbarNativeComponent.ts +31 -0
- package/lib/commonjs/LiquidGlass.js +24 -4
- package/lib/commonjs/LiquidGlass.js.map +1 -1
- package/lib/commonjs/LiquidGlassNativeComponent.ts +6 -5
- package/lib/commonjs/NativePlatformComponentsTheme.js.map +1 -1
- package/lib/commonjs/SegmentedControl.js +11 -85
- package/lib/commonjs/SegmentedControl.js.map +1 -1
- package/lib/commonjs/SegmentedControlNativeComponent.ts +15 -11
- package/lib/commonjs/SelectionMenuNativeComponent.ts +6 -5
- package/lib/commonjs/TextField.js +195 -0
- package/lib/commonjs/TextField.js.map +1 -0
- package/lib/commonjs/TextFieldNativeComponent.ts +218 -0
- package/lib/commonjs/codegenTypes.js +6 -0
- package/lib/commonjs/codegenTypes.js.map +1 -0
- package/lib/commonjs/focusRegistry.js +78 -0
- package/lib/commonjs/focusRegistry.js.map +1 -0
- package/lib/commonjs/icons.js +92 -0
- package/lib/commonjs/icons.js.map +1 -0
- package/lib/commonjs/index.js +66 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +32 -2
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/labelStyle.js +27 -0
- package/lib/commonjs/labelStyle.js.map +1 -0
- package/lib/commonjs/reactNativeInternals.d.js +2 -0
- package/lib/commonjs/reactNativeInternals.d.js.map +1 -0
- package/lib/module/Button.js +70 -0
- package/lib/module/Button.js.map +1 -0
- package/lib/module/ButtonGroup.js +92 -0
- package/lib/module/ButtonGroup.js.map +1 -0
- package/lib/module/ButtonGroupNativeComponent.ts +121 -0
- package/lib/module/ButtonNativeComponent.ts +76 -0
- package/lib/module/ContextMenuNativeComponent.ts +5 -4
- package/lib/module/DatePickerNativeComponent.ts +17 -11
- package/lib/module/FloatingToolbar.js +62 -0
- package/lib/module/FloatingToolbar.js.map +1 -0
- package/lib/module/FloatingToolbarNativeComponent.ts +31 -0
- package/lib/module/LiquidGlass.js +24 -4
- package/lib/module/LiquidGlass.js.map +1 -1
- package/lib/module/LiquidGlassNativeComponent.ts +6 -5
- package/lib/module/NativePlatformComponentsTheme.js.map +1 -1
- package/lib/module/SegmentedControl.js +12 -87
- package/lib/module/SegmentedControl.js.map +1 -1
- package/lib/module/SegmentedControlNativeComponent.ts +15 -11
- package/lib/module/SelectionMenuNativeComponent.ts +6 -5
- package/lib/module/TextField.js +189 -0
- package/lib/module/TextField.js.map +1 -0
- package/lib/module/TextFieldNativeComponent.ts +218 -0
- package/lib/module/codegenTypes.js +4 -0
- package/lib/module/codegenTypes.js.map +1 -0
- package/lib/module/focusRegistry.js +74 -0
- package/lib/module/focusRegistry.js.map +1 -0
- package/lib/module/icons.js +87 -0
- package/lib/module/icons.js.map +1 -0
- package/lib/module/index.js +6 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +28 -0
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/labelStyle.js +23 -0
- package/lib/module/labelStyle.js.map +1 -0
- package/lib/module/reactNativeInternals.d.js +2 -0
- package/lib/module/reactNativeInternals.d.js.map +1 -0
- package/lib/typescript/commonjs/docs/sidebars.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/Button.d.ts +76 -0
- package/lib/typescript/commonjs/src/Button.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/ButtonGroup.d.ts +102 -0
- package/lib/typescript/commonjs/src/ButtonGroup.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/ButtonGroupNativeComponent.d.ts +93 -0
- package/lib/typescript/commonjs/src/ButtonGroupNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/ButtonNativeComponent.d.ts +57 -0
- package/lib/typescript/commonjs/src/ButtonNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/ContextMenuNativeComponent.d.ts +5 -4
- package/lib/typescript/commonjs/src/ContextMenuNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/DatePickerNativeComponent.d.ts +12 -11
- package/lib/typescript/commonjs/src/DatePickerNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/FloatingToolbar.d.ts +45 -0
- package/lib/typescript/commonjs/src/FloatingToolbar.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/FloatingToolbarNativeComponent.d.ts +24 -0
- package/lib/typescript/commonjs/src/FloatingToolbarNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/LiquidGlass.d.ts +4 -3
- package/lib/typescript/commonjs/src/LiquidGlass.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/LiquidGlassNativeComponent.d.ts +6 -5
- package/lib/typescript/commonjs/src/LiquidGlassNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/NativePlatformComponentsTheme.d.ts +10 -2
- package/lib/typescript/commonjs/src/NativePlatformComponentsTheme.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/SegmentedControl.d.ts +17 -46
- package/lib/typescript/commonjs/src/SegmentedControl.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/SegmentedControlNativeComponent.d.ts +9 -6
- package/lib/typescript/commonjs/src/SegmentedControlNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/SelectionMenuNativeComponent.d.ts +6 -5
- package/lib/typescript/commonjs/src/SelectionMenuNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/TextField.d.ts +174 -0
- package/lib/typescript/commonjs/src/TextField.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/TextFieldNativeComponent.d.ts +162 -0
- package/lib/typescript/commonjs/src/TextFieldNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/codegenTypes.d.ts +12 -0
- package/lib/typescript/commonjs/src/codegenTypes.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/focusRegistry.d.ts +13 -0
- package/lib/typescript/commonjs/src/focusRegistry.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/icons.d.ts +52 -0
- package/lib/typescript/commonjs/src/icons.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/index.d.ts +6 -0
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/index.web.d.ts +121 -0
- package/lib/typescript/commonjs/src/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/labelStyle.d.ts +20 -0
- package/lib/typescript/commonjs/src/labelStyle.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/sharedTypes.d.ts +8 -3
- package/lib/typescript/commonjs/src/sharedTypes.d.ts.map +1 -1
- package/lib/typescript/module/docs/sidebars.d.ts.map +1 -1
- package/lib/typescript/module/src/Button.d.ts +76 -0
- package/lib/typescript/module/src/Button.d.ts.map +1 -0
- package/lib/typescript/module/src/ButtonGroup.d.ts +102 -0
- package/lib/typescript/module/src/ButtonGroup.d.ts.map +1 -0
- package/lib/typescript/module/src/ButtonGroupNativeComponent.d.ts +93 -0
- package/lib/typescript/module/src/ButtonGroupNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/ButtonNativeComponent.d.ts +57 -0
- package/lib/typescript/module/src/ButtonNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/ContextMenuNativeComponent.d.ts +5 -4
- package/lib/typescript/module/src/ContextMenuNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/DatePickerNativeComponent.d.ts +12 -11
- package/lib/typescript/module/src/DatePickerNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/FloatingToolbar.d.ts +45 -0
- package/lib/typescript/module/src/FloatingToolbar.d.ts.map +1 -0
- package/lib/typescript/module/src/FloatingToolbarNativeComponent.d.ts +24 -0
- package/lib/typescript/module/src/FloatingToolbarNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/LiquidGlass.d.ts +4 -3
- package/lib/typescript/module/src/LiquidGlass.d.ts.map +1 -1
- package/lib/typescript/module/src/LiquidGlassNativeComponent.d.ts +6 -5
- package/lib/typescript/module/src/LiquidGlassNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/NativePlatformComponentsTheme.d.ts +10 -2
- package/lib/typescript/module/src/NativePlatformComponentsTheme.d.ts.map +1 -1
- package/lib/typescript/module/src/SegmentedControl.d.ts +17 -46
- package/lib/typescript/module/src/SegmentedControl.d.ts.map +1 -1
- package/lib/typescript/module/src/SegmentedControlNativeComponent.d.ts +9 -6
- package/lib/typescript/module/src/SegmentedControlNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/SelectionMenuNativeComponent.d.ts +6 -5
- package/lib/typescript/module/src/SelectionMenuNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/TextField.d.ts +174 -0
- package/lib/typescript/module/src/TextField.d.ts.map +1 -0
- package/lib/typescript/module/src/TextFieldNativeComponent.d.ts +162 -0
- package/lib/typescript/module/src/TextFieldNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/codegenTypes.d.ts +12 -0
- package/lib/typescript/module/src/codegenTypes.d.ts.map +1 -0
- package/lib/typescript/module/src/focusRegistry.d.ts +13 -0
- package/lib/typescript/module/src/focusRegistry.d.ts.map +1 -0
- package/lib/typescript/module/src/icons.d.ts +52 -0
- package/lib/typescript/module/src/icons.d.ts.map +1 -0
- package/lib/typescript/module/src/index.d.ts +6 -0
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/index.web.d.ts +121 -0
- package/lib/typescript/module/src/index.web.d.ts.map +1 -1
- package/lib/typescript/module/src/labelStyle.d.ts +20 -0
- package/lib/typescript/module/src/labelStyle.d.ts.map +1 -0
- package/lib/typescript/module/src/sharedTypes.d.ts +8 -3
- package/lib/typescript/module/src/sharedTypes.d.ts.map +1 -1
- package/package.json +28 -6
- package/react-native.config.js +3 -0
- package/shared/PCButtonComponentDescriptors-custom.h +22 -0
- package/shared/PCButtonGroupComponentDescriptors-custom.h +22 -0
- package/shared/PCButtonGroupShadowNode-custom.cpp +48 -0
- package/shared/PCButtonGroupShadowNode-custom.h +55 -0
- package/shared/PCButtonGroupState-custom.h +61 -0
- package/shared/PCButtonShadowNode-custom.cpp +48 -0
- package/shared/PCButtonShadowNode-custom.h +55 -0
- package/shared/PCButtonState-custom.h +61 -0
- package/shared/PCDatePickerState-custom.h +2 -2
- package/shared/PCSegmentedControlState-custom.h +2 -2
- package/shared/PCSelectionMenuState-custom.h +2 -2
- package/shared/PCTextFieldComponentDescriptors-custom.h +22 -0
- package/shared/PCTextFieldShadowNode-custom.cpp +47 -0
- package/shared/PCTextFieldShadowNode-custom.h +55 -0
- package/shared/PCTextFieldState-custom.h +61 -0
- package/shared/react/renderer/components/PlatformComponentsViewSpec/ComponentDescriptors.h +3 -0
- package/src/Button.tsx +144 -0
- package/src/ButtonGroup.tsx +233 -0
- package/src/ButtonGroupNativeComponent.ts +121 -0
- package/src/ButtonNativeComponent.ts +76 -0
- package/src/ContextMenuNativeComponent.ts +5 -4
- package/src/DatePickerNativeComponent.ts +17 -11
- package/src/FloatingToolbar.tsx +113 -0
- package/src/FloatingToolbarNativeComponent.ts +31 -0
- package/src/LiquidGlass.tsx +24 -5
- package/src/LiquidGlassNativeComponent.ts +6 -5
- package/src/NativePlatformComponentsTheme.ts +11 -2
- package/src/SegmentedControl.tsx +26 -118
- package/src/SegmentedControlNativeComponent.ts +15 -11
- package/src/SelectionMenuNativeComponent.ts +6 -5
- package/src/TextField.tsx +494 -0
- package/src/TextFieldNativeComponent.ts +218 -0
- package/src/codegenTypes.ts +40 -0
- package/src/focusRegistry.ts +89 -0
- package/src/icons.ts +116 -0
- package/src/index.tsx +6 -0
- package/src/index.web.tsx +194 -0
- package/src/labelStyle.ts +36 -0
- package/src/reactNativeInternals.d.ts +22 -0
- package/src/sharedTypes.ts +9 -3
- /package/{app.plugin.cjs → app.plugin.js} +0 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// codegenTypes.ts
|
|
2
|
+
//
|
|
3
|
+
// Local mirror of React Native's `CodegenTypes`.
|
|
4
|
+
//
|
|
5
|
+
// Codegen resolves these names lexically — it matches the identifier used in a
|
|
6
|
+
// spec (`Int32`, `WithDefault`, ...) and never follows the import to its
|
|
7
|
+
// source. Declaring them here therefore produces exactly the same schema as
|
|
8
|
+
// importing them from React Native, while staying parseable by the codegen
|
|
9
|
+
// shipped with older releases: the `CodegenTypes.Int32` namespace form is only
|
|
10
|
+
// understood by React Native 0.80+, and the pre-0.80 deep import
|
|
11
|
+
// (`react-native/Libraries/Types/CodegenTypes`) no longer type-checks on 0.86.
|
|
12
|
+
//
|
|
13
|
+
// Keep these definitions in sync with
|
|
14
|
+
// `react-native/Libraries/Types/CodegenTypesNamespace.d.ts`.
|
|
15
|
+
import type { NativeSyntheticEvent } from 'react-native';
|
|
16
|
+
|
|
17
|
+
// Event types. The `_PaperName` parameter is unused by the New Architecture; it
|
|
18
|
+
// is kept so the signatures match React Native's.
|
|
19
|
+
export type BubblingEventHandler<
|
|
20
|
+
T,
|
|
21
|
+
_PaperName extends string | never = never,
|
|
22
|
+
> = (event: NativeSyntheticEvent<T>) => void | Promise<void>;
|
|
23
|
+
|
|
24
|
+
export type DirectEventHandler<T, _PaperName extends string | never = never> = (
|
|
25
|
+
event: NativeSyntheticEvent<T>
|
|
26
|
+
) => void | Promise<void>;
|
|
27
|
+
|
|
28
|
+
// Prop types.
|
|
29
|
+
export type Double = number;
|
|
30
|
+
export type Float = number;
|
|
31
|
+
export type Int32 = number;
|
|
32
|
+
export type UnsafeObject = object;
|
|
33
|
+
export type UnsafeMixed = unknown;
|
|
34
|
+
|
|
35
|
+
type DefaultTypes = number | boolean | string | ReadonlyArray<string>;
|
|
36
|
+
|
|
37
|
+
export type WithDefault<
|
|
38
|
+
Type extends DefaultTypes,
|
|
39
|
+
_Value extends Type | string | undefined | null,
|
|
40
|
+
> = Type | undefined | null;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// focusRegistry.ts
|
|
2
|
+
//
|
|
3
|
+
// TextField's link to React Native's focused-input bookkeeping. The core
|
|
4
|
+
// TextInput registers its host node with `TextInputState`, and that registry is
|
|
5
|
+
// what `Keyboard.dismiss()`, a ScrollView's `keyboardShouldPersistTaps` and
|
|
6
|
+
// `keyboardDismissMode`, and `KeyboardAvoidingView` act on. Registering the
|
|
7
|
+
// same way makes a TextField behave like a TextInput for all of them.
|
|
8
|
+
//
|
|
9
|
+
// `TextInputState` is a stable internal (it has kept this shape since 0.63),
|
|
10
|
+
// but React Native's Babel preset adds a dev-time warning to every static
|
|
11
|
+
// `import` or `require` of a deep path. A dynamic `import()` is resolved by
|
|
12
|
+
// Metro the same way and carries no warning; it settles in a microtask at
|
|
13
|
+
// startup, so a node registered before then is kept and registered once the
|
|
14
|
+
// module arrives. If a future release drops the path, the registry is simply
|
|
15
|
+
// absent and the field falls back to the public `TextInput.State` calls for
|
|
16
|
+
// focus and blur, keeping `Keyboard.dismiss()` working.
|
|
17
|
+
import { TextInput } from 'react-native';
|
|
18
|
+
|
|
19
|
+
type HostNode = object;
|
|
20
|
+
|
|
21
|
+
type Registry = {
|
|
22
|
+
currentlyFocusedInput(): HostNode | null | undefined;
|
|
23
|
+
focusInput(input: HostNode | null | undefined): void;
|
|
24
|
+
blurInput(input: HostNode | null | undefined): void;
|
|
25
|
+
registerInput(input: HostNode): void;
|
|
26
|
+
unregisterInput(input: HostNode): void;
|
|
27
|
+
isTextInput(input: HostNode): boolean;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
let registry: Registry | undefined;
|
|
31
|
+
const pendingRegistrations = new Set<HostNode>();
|
|
32
|
+
|
|
33
|
+
// A stable internal without a public counterpart; see reactNativeInternals.d.ts.
|
|
34
|
+
|
|
35
|
+
import('react-native/Libraries/Components/TextInput/TextInputState')
|
|
36
|
+
.then((module) => {
|
|
37
|
+
registry = module.default;
|
|
38
|
+
pendingRegistrations.forEach((node) => registry?.registerInput(node));
|
|
39
|
+
pendingRegistrations.clear();
|
|
40
|
+
})
|
|
41
|
+
.catch(() => {
|
|
42
|
+
// Not available: focus and blur still go through TextInput.State below.
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
export const focusRegistry = {
|
|
46
|
+
/** Called when the field mounts. */
|
|
47
|
+
register(node: HostNode): void {
|
|
48
|
+
if (registry) {
|
|
49
|
+
registry.registerInput(node);
|
|
50
|
+
} else {
|
|
51
|
+
pendingRegistrations.add(node);
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
/** Called when the field unmounts; drops the focus if the field held it. */
|
|
56
|
+
unregister(node: HostNode): void {
|
|
57
|
+
pendingRegistrations.delete(node);
|
|
58
|
+
if (registry) {
|
|
59
|
+
registry.unregisterInput(node);
|
|
60
|
+
if (registry.currentlyFocusedInput() === node) {
|
|
61
|
+
registry.blurInput(node);
|
|
62
|
+
}
|
|
63
|
+
} else if (TextInput.State.currentlyFocusedInput() === node) {
|
|
64
|
+
TextInput.State.blurTextInput(node as never);
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
/** The field gained focus natively. */
|
|
69
|
+
focused(node: HostNode | null): void {
|
|
70
|
+
if (node == null) return;
|
|
71
|
+
if (registry) {
|
|
72
|
+
registry.focusInput(node);
|
|
73
|
+
} else {
|
|
74
|
+
// Also re-sends the focus command, which the focused field ignores
|
|
75
|
+
TextInput.State.focusTextInput(node as never);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
/** The field lost focus natively. */
|
|
80
|
+
blurred(node: HostNode | null): void {
|
|
81
|
+
if (node == null) return;
|
|
82
|
+
if (registry) {
|
|
83
|
+
registry.blurInput(node);
|
|
84
|
+
} else {
|
|
85
|
+
// Also re-sends the blur command, which the unfocused field ignores
|
|
86
|
+
TextInput.State.blurTextInput(node as never);
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
};
|
package/src/icons.ts
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// icons.ts
|
|
2
|
+
//
|
|
3
|
+
// Icon props shared by SegmentedControl, Button and ButtonGroup. Icons are
|
|
4
|
+
// resolved on the JS side so native only deals with flat strings.
|
|
5
|
+
import {
|
|
6
|
+
Image,
|
|
7
|
+
Platform,
|
|
8
|
+
type ImageRequireSource,
|
|
9
|
+
type ImageURISource,
|
|
10
|
+
} from 'react-native';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A single icon source.
|
|
14
|
+
*
|
|
15
|
+
* - `string`: shorthand for an SF Symbol name on iOS and a drawable resource
|
|
16
|
+
* name on Android.
|
|
17
|
+
* - `{ type: 'sfSymbol' }`: an SF Symbol. iOS only; ignored on Android.
|
|
18
|
+
* - `{ type: 'drawable' }`: a drawable from the app's `res/drawable`.
|
|
19
|
+
* Android only; ignored on iOS.
|
|
20
|
+
* - `{ type: 'image' }`: an image asset (`require('./icon.png')`) or a
|
|
21
|
+
* `{ uri }` source. Works on both platforms. Images are drawn as tinted
|
|
22
|
+
* templates unless `tinted` is `false`.
|
|
23
|
+
*/
|
|
24
|
+
export type PlatformIconSource =
|
|
25
|
+
| string
|
|
26
|
+
| { type: 'sfSymbol'; name: string }
|
|
27
|
+
| { type: 'drawable'; name: string }
|
|
28
|
+
| {
|
|
29
|
+
type: 'image';
|
|
30
|
+
source: ImageRequireSource | ImageURISource;
|
|
31
|
+
tinted?: boolean;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* An icon: a single source used on both platforms, or a per-platform pair so
|
|
36
|
+
* callers don't need to branch on `Platform.OS`.
|
|
37
|
+
*/
|
|
38
|
+
export type PlatformIcon =
|
|
39
|
+
| PlatformIconSource
|
|
40
|
+
| {
|
|
41
|
+
ios?: PlatformIconSource;
|
|
42
|
+
android?: PlatformIconSource;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/** The flat icon fields the native specs expect. */
|
|
46
|
+
export type NativeIconFields = {
|
|
47
|
+
/** '' | 'sfSymbol' | 'drawable' | 'image' */
|
|
48
|
+
iconType: string;
|
|
49
|
+
/** SF Symbol (iOS) or drawable resource name (Android) */
|
|
50
|
+
iconName: string;
|
|
51
|
+
/** Resolved image URI when iconType === 'image' */
|
|
52
|
+
iconUri: string;
|
|
53
|
+
/** Resolved image scale when iconType === 'image' */
|
|
54
|
+
iconScale: number;
|
|
55
|
+
/** 'true' | 'false': draw the image as a tinted template */
|
|
56
|
+
iconTinted: string;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const NO_ICON: NativeIconFields = {
|
|
60
|
+
iconType: '',
|
|
61
|
+
iconName: '',
|
|
62
|
+
iconUri: '',
|
|
63
|
+
iconScale: 1,
|
|
64
|
+
iconTinted: 'true',
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
function pickIconSource(
|
|
68
|
+
icon: PlatformIcon | undefined
|
|
69
|
+
): PlatformIconSource | undefined {
|
|
70
|
+
if (icon === undefined || typeof icon === 'string' || 'type' in icon) {
|
|
71
|
+
return icon;
|
|
72
|
+
}
|
|
73
|
+
return Platform.OS === 'ios' ? icon.ios : icon.android;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Flattens the public icon shape into the strings native expects, dropping
|
|
78
|
+
* sources that don't apply to the current platform.
|
|
79
|
+
*/
|
|
80
|
+
export function resolveIcon(icon: PlatformIcon | undefined): NativeIconFields {
|
|
81
|
+
const source = pickIconSource(icon);
|
|
82
|
+
if (source === undefined) return NO_ICON;
|
|
83
|
+
|
|
84
|
+
if (typeof source === 'string') {
|
|
85
|
+
if (source.length === 0) return NO_ICON;
|
|
86
|
+
return {
|
|
87
|
+
...NO_ICON,
|
|
88
|
+
iconType: Platform.OS === 'ios' ? 'sfSymbol' : 'drawable',
|
|
89
|
+
iconName: source,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
switch (source.type) {
|
|
94
|
+
case 'sfSymbol':
|
|
95
|
+
return Platform.OS === 'ios'
|
|
96
|
+
? { ...NO_ICON, iconType: 'sfSymbol', iconName: source.name }
|
|
97
|
+
: NO_ICON;
|
|
98
|
+
case 'drawable':
|
|
99
|
+
return Platform.OS === 'android'
|
|
100
|
+
? { ...NO_ICON, iconType: 'drawable', iconName: source.name }
|
|
101
|
+
: NO_ICON;
|
|
102
|
+
case 'image': {
|
|
103
|
+
const resolved = Image.resolveAssetSource(source.source);
|
|
104
|
+
if (!resolved?.uri) return NO_ICON;
|
|
105
|
+
return {
|
|
106
|
+
iconType: 'image',
|
|
107
|
+
iconName: '',
|
|
108
|
+
iconUri: resolved.uri,
|
|
109
|
+
iconScale: resolved.scale > 0 ? resolved.scale : 1,
|
|
110
|
+
iconTinted: source.tinted === false ? 'false' : 'true',
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
default:
|
|
114
|
+
return NO_ICON;
|
|
115
|
+
}
|
|
116
|
+
}
|
package/src/index.tsx
CHANGED
|
@@ -2,6 +2,12 @@ export * from './DatePicker';
|
|
|
2
2
|
export * from './SelectionMenu';
|
|
3
3
|
export * from './ContextMenu';
|
|
4
4
|
export * from './SegmentedControl';
|
|
5
|
+
export * from './Button';
|
|
6
|
+
export * from './ButtonGroup';
|
|
7
|
+
export * from './FloatingToolbar';
|
|
5
8
|
export * from './LiquidGlass';
|
|
9
|
+
export * from './TextField';
|
|
10
|
+
export * from './icons';
|
|
11
|
+
export * from './labelStyle';
|
|
6
12
|
export * from './sharedTypes';
|
|
7
13
|
export * from './NativeTheme';
|
package/src/index.web.tsx
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import type { ReactNode } from 'react';
|
|
8
8
|
import type { ColorValue, StyleProp, ViewStyle, ViewProps } from 'react-native';
|
|
9
|
+
import type { PlatformIcon } from './icons';
|
|
10
|
+
import type { LabelStyle } from './labelStyle';
|
|
9
11
|
|
|
10
12
|
// ============================================================================
|
|
11
13
|
// Shared Types (duplicated to avoid importing from files with native deps)
|
|
@@ -164,6 +166,90 @@ export const SegmentedControl = (
|
|
|
164
166
|
_props: SegmentedControlProps
|
|
165
167
|
): React.ReactElement | null => null;
|
|
166
168
|
|
|
169
|
+
// ============================================================================
|
|
170
|
+
// Button, ButtonGroup, FloatingToolbar
|
|
171
|
+
// ============================================================================
|
|
172
|
+
|
|
173
|
+
export type {
|
|
174
|
+
PlatformIcon,
|
|
175
|
+
PlatformIconSource,
|
|
176
|
+
NativeIconFields,
|
|
177
|
+
} from './icons';
|
|
178
|
+
export type { LabelStyle, NativeLabelStyle } from './labelStyle';
|
|
179
|
+
|
|
180
|
+
export type ButtonVariant =
|
|
181
|
+
'filled' | 'tonal' | 'outlined' | 'text' | 'elevated';
|
|
182
|
+
export type ButtonSize = 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge';
|
|
183
|
+
export type ButtonShape = 'round' | 'square';
|
|
184
|
+
|
|
185
|
+
export interface ButtonProps extends ViewProps {
|
|
186
|
+
label?: string;
|
|
187
|
+
icon?: PlatformIcon;
|
|
188
|
+
variant?: ButtonVariant;
|
|
189
|
+
size?: ButtonSize;
|
|
190
|
+
shape?: ButtonShape;
|
|
191
|
+
disabled?: boolean;
|
|
192
|
+
color?: ColorValue;
|
|
193
|
+
tintColor?: ColorValue;
|
|
194
|
+
labelStyle?: LabelStyle;
|
|
195
|
+
accessibilityLabel?: string;
|
|
196
|
+
onPress?: () => void;
|
|
197
|
+
android?: Record<string, unknown>;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export const Button = (_props: ButtonProps): React.ReactElement | null => null;
|
|
201
|
+
|
|
202
|
+
export type ButtonGroupSelection = 'none' | 'single' | 'multiple';
|
|
203
|
+
export type ButtonGroupOverflow = 'none' | 'menu' | 'wrap';
|
|
204
|
+
|
|
205
|
+
export interface ButtonGroupButtonProps {
|
|
206
|
+
label?: string;
|
|
207
|
+
value: string;
|
|
208
|
+
disabled?: boolean;
|
|
209
|
+
icon?: PlatformIcon;
|
|
210
|
+
accessibilityLabel?: string;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export interface ButtonGroupProps extends ViewProps {
|
|
214
|
+
buttons: readonly ButtonGroupButtonProps[];
|
|
215
|
+
variant?: ButtonVariant;
|
|
216
|
+
size?: ButtonSize;
|
|
217
|
+
shape?: ButtonShape;
|
|
218
|
+
connected?: boolean;
|
|
219
|
+
spacing?: number;
|
|
220
|
+
selection?: ButtonGroupSelection;
|
|
221
|
+
selectedValues?: readonly string[];
|
|
222
|
+
selectionRequired?: boolean;
|
|
223
|
+
disabled?: boolean;
|
|
224
|
+
color?: ColorValue;
|
|
225
|
+
tintColor?: ColorValue;
|
|
226
|
+
labelStyle?: LabelStyle;
|
|
227
|
+
onPress?: (value: string, index: number) => void;
|
|
228
|
+
onSelectionChange?: (values: string[]) => void;
|
|
229
|
+
android?: Record<string, unknown>;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export const ButtonGroup = (
|
|
233
|
+
_props: ButtonGroupProps
|
|
234
|
+
): React.ReactElement | null => null;
|
|
235
|
+
|
|
236
|
+
export type FloatingToolbarIOSEffect = 'regular' | 'clear';
|
|
237
|
+
export type FloatingToolbarAndroidVariant = 'standard' | 'vibrant';
|
|
238
|
+
|
|
239
|
+
export interface FloatingToolbarProps extends ViewProps {
|
|
240
|
+
orientation?: 'horizontal' | 'vertical';
|
|
241
|
+
color?: ColorValue;
|
|
242
|
+
ios?: Record<string, unknown>;
|
|
243
|
+
android?: Record<string, unknown>;
|
|
244
|
+
children?: ReactNode;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export const FloatingToolbar = ({
|
|
248
|
+
children,
|
|
249
|
+
}: FloatingToolbarProps): React.ReactElement | null => {
|
|
250
|
+
return <>{children}</>;
|
|
251
|
+
};
|
|
252
|
+
|
|
167
253
|
// ============================================================================
|
|
168
254
|
// LiquidGlass
|
|
169
255
|
// ============================================================================
|
|
@@ -183,6 +269,114 @@ export const LiquidGlass = ({
|
|
|
183
269
|
|
|
184
270
|
export const isLiquidGlassSupported = false;
|
|
185
271
|
|
|
272
|
+
// ============================================================================
|
|
273
|
+
// TextField
|
|
274
|
+
// ============================================================================
|
|
275
|
+
|
|
276
|
+
export type TextFieldKeyboardType =
|
|
277
|
+
| 'default'
|
|
278
|
+
| 'number-pad'
|
|
279
|
+
| 'decimal-pad'
|
|
280
|
+
| 'numeric'
|
|
281
|
+
| 'email-address'
|
|
282
|
+
| 'phone-pad'
|
|
283
|
+
| 'url'
|
|
284
|
+
| 'ascii-capable'
|
|
285
|
+
| 'numbers-and-punctuation'
|
|
286
|
+
| 'name-phone-pad'
|
|
287
|
+
| 'twitter'
|
|
288
|
+
| 'web-search'
|
|
289
|
+
| 'visible-password';
|
|
290
|
+
export type TextFieldReturnKeyType =
|
|
291
|
+
'default' | 'done' | 'go' | 'next' | 'search' | 'send' | 'none' | 'previous';
|
|
292
|
+
export type TextFieldAutoComplete =
|
|
293
|
+
| 'off'
|
|
294
|
+
| 'username'
|
|
295
|
+
| 'password'
|
|
296
|
+
| 'new-password'
|
|
297
|
+
| 'one-time-code'
|
|
298
|
+
| 'email'
|
|
299
|
+
| 'name'
|
|
300
|
+
| 'given-name'
|
|
301
|
+
| 'family-name'
|
|
302
|
+
| 'tel'
|
|
303
|
+
| 'street-address'
|
|
304
|
+
| 'postal-code'
|
|
305
|
+
| 'country'
|
|
306
|
+
| 'cc-number'
|
|
307
|
+
| 'cc-exp'
|
|
308
|
+
| 'cc-csc'
|
|
309
|
+
| 'url';
|
|
310
|
+
export type TextFieldAutoCapitalize =
|
|
311
|
+
'none' | 'sentences' | 'words' | 'characters';
|
|
312
|
+
export type TextFieldClearButtonMode =
|
|
313
|
+
'never' | 'while-editing' | 'unless-editing' | 'always';
|
|
314
|
+
export type TextFieldIOSChoice = 'default' | 'yes' | 'no';
|
|
315
|
+
export type TextFieldEvent = { nativeEvent: { text: string } };
|
|
316
|
+
export type TextFieldChangeEvent = {
|
|
317
|
+
nativeEvent: { text: string; eventCount: number };
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
export interface TextFieldRef {
|
|
321
|
+
focus(): void;
|
|
322
|
+
blur(): void;
|
|
323
|
+
clear(): void;
|
|
324
|
+
isFocused(): boolean;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
export interface TextFieldProps extends Omit<
|
|
328
|
+
ViewProps,
|
|
329
|
+
'onFocus' | 'onBlur' | 'children'
|
|
330
|
+
> {
|
|
331
|
+
value?: string;
|
|
332
|
+
defaultValue?: string;
|
|
333
|
+
onChangeText?: (text: string) => void;
|
|
334
|
+
onChange?: (event: TextFieldChangeEvent) => void;
|
|
335
|
+
onFocus?: (event: TextFieldEvent) => void;
|
|
336
|
+
onBlur?: (event: TextFieldEvent) => void;
|
|
337
|
+
onSubmitEditing?: (event: TextFieldEvent) => void;
|
|
338
|
+
label?: string;
|
|
339
|
+
placeholder?: string;
|
|
340
|
+
supportingText?: string;
|
|
341
|
+
error?: boolean | string;
|
|
342
|
+
prefix?: string;
|
|
343
|
+
suffix?: string;
|
|
344
|
+
leadingIcon?: PlatformIcon;
|
|
345
|
+
trailingIcon?: PlatformIcon;
|
|
346
|
+
onTrailingIconPress?: () => void;
|
|
347
|
+
clearButtonMode?: TextFieldClearButtonMode;
|
|
348
|
+
passwordToggle?: boolean;
|
|
349
|
+
showCharacterCount?: boolean;
|
|
350
|
+
maxLength?: number;
|
|
351
|
+
keyboardType?: TextFieldKeyboardType;
|
|
352
|
+
returnKeyType?: TextFieldReturnKeyType;
|
|
353
|
+
autoCapitalize?: TextFieldAutoCapitalize;
|
|
354
|
+
autoCorrect?: boolean;
|
|
355
|
+
secureTextEntry?: boolean;
|
|
356
|
+
multiline?: boolean;
|
|
357
|
+
editable?: boolean;
|
|
358
|
+
autoFocus?: boolean;
|
|
359
|
+
selectTextOnFocus?: boolean;
|
|
360
|
+
autoComplete?: TextFieldAutoComplete;
|
|
361
|
+
keyboardAppearance?: 'default' | 'light' | 'dark';
|
|
362
|
+
textStyle?: LabelStyle;
|
|
363
|
+
accessibilityLabel?: string;
|
|
364
|
+
ios?: Record<string, unknown>;
|
|
365
|
+
android?: Record<string, unknown>;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
export const TextField = React.forwardRef<TextFieldRef, TextFieldProps>(
|
|
369
|
+
function TextFieldComponent(_props, ref): React.ReactElement | null {
|
|
370
|
+
React.useImperativeHandle(ref, () => ({
|
|
371
|
+
focus: () => {},
|
|
372
|
+
blur: () => {},
|
|
373
|
+
clear: () => {},
|
|
374
|
+
isFocused: () => false,
|
|
375
|
+
}));
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
378
|
+
);
|
|
379
|
+
|
|
186
380
|
// ============================================================================
|
|
187
381
|
// Native theme
|
|
188
382
|
// ============================================================================
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// labelStyle.ts
|
|
2
|
+
//
|
|
3
|
+
// Label font props shared by SegmentedControl, Button and ButtonGroup.
|
|
4
|
+
import type { TextStyle } from 'react-native';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Font for a control's labels. Each field falls back to the platform default.
|
|
8
|
+
*/
|
|
9
|
+
export interface LabelStyle {
|
|
10
|
+
fontFamily?: string;
|
|
11
|
+
fontSize?: number;
|
|
12
|
+
fontWeight?: TextStyle['fontWeight'];
|
|
13
|
+
fontStyle?: 'normal' | 'italic';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** The flat font fields the native specs expect; empty / 0 = default. */
|
|
17
|
+
export type NativeLabelStyle = {
|
|
18
|
+
fontFamily: string;
|
|
19
|
+
fontSize: number;
|
|
20
|
+
fontWeight: string;
|
|
21
|
+
fontStyle: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/** Normalizes a label font for native; `undefined` keeps the platform font. */
|
|
25
|
+
export function normalizeLabelStyle(
|
|
26
|
+
labelStyle: LabelStyle | undefined
|
|
27
|
+
): NativeLabelStyle | undefined {
|
|
28
|
+
if (!labelStyle) return undefined;
|
|
29
|
+
return {
|
|
30
|
+
fontFamily: labelStyle.fontFamily ?? '',
|
|
31
|
+
fontSize: labelStyle.fontSize ?? 0,
|
|
32
|
+
fontWeight:
|
|
33
|
+
labelStyle.fontWeight === undefined ? '' : String(labelStyle.fontWeight),
|
|
34
|
+
fontStyle: labelStyle.fontStyle ?? '',
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// reactNativeInternals.d.ts
|
|
2
|
+
//
|
|
3
|
+
// React Native's focus registry for text inputs. `Keyboard.dismiss()`, a
|
|
4
|
+
// ScrollView's `keyboardShouldPersistTaps` and `KeyboardAvoidingView` all act
|
|
5
|
+
// on the input registered here, so TextField registers itself like the core
|
|
6
|
+
// TextInput does. The module is a stable internal (it has kept this shape
|
|
7
|
+
// since 0.63), but it is not part of the strict API's type exports, hence this
|
|
8
|
+
// declaration.
|
|
9
|
+
declare module 'react-native/Libraries/Components/TextInput/TextInputState' {
|
|
10
|
+
type HostInput = object;
|
|
11
|
+
|
|
12
|
+
const TextInputState: {
|
|
13
|
+
currentlyFocusedInput(): HostInput | null | undefined;
|
|
14
|
+
focusInput(input: HostInput | null | undefined): void;
|
|
15
|
+
blurInput(input: HostInput | null | undefined): void;
|
|
16
|
+
registerInput(input: HostInput): void;
|
|
17
|
+
unregisterInput(input: HostInput): void;
|
|
18
|
+
isTextInput(input: HostInput): boolean;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default TextInputState;
|
|
22
|
+
}
|
package/src/sharedTypes.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SharedTypes.ts
|
|
2
|
-
import type {
|
|
2
|
+
import type { BubblingEventHandler } from './codegenTypes';
|
|
3
3
|
|
|
4
4
|
/** Shared "open/closed" control state. */
|
|
5
5
|
export type Visible = 'open' | 'closed';
|
|
@@ -7,11 +7,17 @@ export type Visible = 'open' | 'closed';
|
|
|
7
7
|
/** Shared presentation mode for pickers/menus. */
|
|
8
8
|
export type Presentation = 'modal' | 'embedded';
|
|
9
9
|
|
|
10
|
-
/** Shared Material preference (Android). */
|
|
10
|
+
/** Shared Material preference (Android): the platform widget or the Material one. */
|
|
11
11
|
export type AndroidMaterialMode = 'system' | 'm3';
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Shared Material style for the Material-only components (Android):
|
|
15
|
+
* Material 3, or Material 3 Expressive (the default).
|
|
16
|
+
*/
|
|
17
|
+
export type AndroidMaterialStyle = 'm3' | 'expressive';
|
|
18
|
+
|
|
13
19
|
/** Common event empty payload type. */
|
|
14
20
|
export type EmptyEvent = Readonly<{}>;
|
|
15
21
|
|
|
16
22
|
/** Convenience alias (optional). */
|
|
17
|
-
export type Bubbling<T> =
|
|
23
|
+
export type Bubbling<T> = BubblingEventHandler<T>;
|
|
File without changes
|