react-native-controlled-input 0.6.0 → 0.9.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 CHANGED
@@ -1,32 +1,95 @@
1
1
  # react-native-controlled-input
2
2
 
3
- React Native Controlled Inputative Controlled Input
3
+ A controlled React Native input for cases where regular `TextInput` can briefly show invalid characters before your filtered `value` is rendered back from JS.
4
4
 
5
- ## Installation
5
+ ## Problem
6
6
 
7
+ With a regular controlled `TextInput`, native input is applied first, then JS receives the change, filters it, and sends the next `value` back.
8
+
9
+ That means invalid characters can still flash in the field for a moment.
10
+
11
+ `react-native-controlled-input` is built for this exact case: you decide what text is valid, and the displayed value stays driven by `value`.
12
+
13
+ ## Install
7
14
 
8
15
  ```sh
9
16
  npm install react-native-controlled-input
10
17
  ```
11
18
 
19
+ Requires React Native New Architecture / Fabric.
20
+
21
+ ## Example
22
+
23
+ ```tsx
24
+ import { useRef, useState } from 'react';
25
+ import { StyleSheet } from 'react-native';
26
+ import {
27
+ ControlledInputView,
28
+ type ControlledInputViewRef,
29
+ } from 'react-native-controlled-input';
30
+
31
+ export function Example() {
32
+ const [value, setValue] = useState('');
33
+ const inputRef = useRef<ControlledInputViewRef>(null);
34
+
35
+ return (
36
+ <ControlledInputView
37
+ ref={inputRef}
38
+ value={value}
39
+ onTextChange={(text) => setValue(text.replace(/\d/g, ''))}
40
+ style={styles.input}
41
+ onFocus={() => {}}
42
+ onBlur={() => {}}
43
+ />
44
+ );
45
+ }
46
+
47
+ const styles = StyleSheet.create({
48
+ input: {
49
+ height: 48,
50
+ borderWidth: 1,
51
+ borderColor: '#ccc',
52
+ borderRadius: 8,
53
+ paddingHorizontal: 12,
54
+ fontSize: 16,
55
+ color: '#111',
56
+ },
57
+ });
58
+ ```
59
+
60
+ ```tsx
61
+ inputRef.current?.focus();
62
+ inputRef.current?.blur();
63
+ ```
64
+
65
+ ## Props
12
66
 
13
- ## Usage
67
+ | Prop | Type | Description |
68
+ |------|------|-------------|
69
+ | `value` | `string` | Current input value. |
70
+ | `onTextChange` | `(value: string) => void` | Called with the next text value. Filter it and update `value`. |
71
+ | `onFocus` | `() => void` | Called on focus. |
72
+ | `onBlur` | `() => void` | Called on blur. |
73
+ | `style` | `StyleProp<ViewStyle>` | Input styles. Same public API on iOS and Android, with platform-specific internal handling. |
14
74
 
75
+ ## Style support
15
76
 
16
- ```js
17
- import { ControlledInputView } from "react-native-controlled-input";
77
+ The same `style` API is supported on both iOS and Android.
18
78
 
19
- // ...
79
+ Commonly used supported styles:
20
80
 
21
- <ControlledInputView color="tomato" />
22
- ```
81
+ - `color`, `fontSize`, `fontFamily`
82
+ - `padding`, `paddingVertical`, `paddingHorizontal`
83
+ - `paddingTop`, `paddingBottom`, `paddingLeft`, `paddingRight`, `paddingStart`, `paddingEnd`
84
+ - `borderWidth`, `borderRadius`, `borderColor`, `backgroundColor`
85
+ - layout styles like `width`, `height`, `margin`, `flex`
23
86
 
87
+ Implementation differs internally between platforms, but usage is the same for library consumers.
24
88
 
25
- ## Contributing
89
+ ## Ref
26
90
 
27
- - [Development workflow](CONTRIBUTING.md#development-workflow)
28
- - [Sending a pull request](CONTRIBUTING.md#sending-a-pull-request)
29
- - [Code of conduct](CODE_OF_CONDUCT.md)
91
+ - `focus()`
92
+ - `blur()`
30
93
 
31
94
  ## License
32
95
 
@@ -56,17 +56,19 @@ class ControlledInputView : LinearLayout {
56
56
  }
57
57
 
58
58
  private fun configureComponent(context: Context) {
59
+ setBackgroundColor(android.graphics.Color.TRANSPARENT)
59
60
 
60
61
  layoutParams = LayoutParams(
61
- LayoutParams.WRAP_CONTENT,
62
- LayoutParams.WRAP_CONTENT
62
+ LayoutParams.MATCH_PARENT,
63
+ LayoutParams.MATCH_PARENT
63
64
  )
64
65
 
65
66
  ComposeView(context).also {
66
67
  it.layoutParams = LayoutParams(
67
- LayoutParams.WRAP_CONTENT,
68
- LayoutParams.WRAP_CONTENT
68
+ LayoutParams.MATCH_PARENT,
69
+ LayoutParams.MATCH_PARENT
69
70
  )
71
+ it.setBackgroundColor(android.graphics.Color.TRANSPARENT)
70
72
 
71
73
  viewModel = JetpackComposeViewModel()
72
74
 
@@ -47,7 +47,6 @@ class ControlledInputViewManager : SimpleViewManager<ControlledInputView>(),
47
47
  color = if (inputStyle.hasKey("color")) inputStyle.getString("color") else null,
48
48
  fontSize = if (inputStyle.hasKey("fontSize")) inputStyle.getDouble("fontSize") else null,
49
49
  fontFamily = if (inputStyle.hasKey("fontFamily")) inputStyle.getString("fontFamily") else null,
50
- height = if (inputStyle.hasKey("height")) inputStyle.getDouble("height") else null,
51
50
  paddingTop = if (inputStyle.hasKey("paddingTop")) inputStyle.getDouble("paddingTop") else null,
52
51
  paddingBottom = if (inputStyle.hasKey("paddingBottom")) inputStyle.getDouble("paddingBottom") else null,
53
52
  paddingLeft = if (inputStyle.hasKey("paddingLeft")) inputStyle.getDouble("paddingLeft") else null,
@@ -55,6 +54,7 @@ class ControlledInputViewManager : SimpleViewManager<ControlledInputView>(),
55
54
  borderWidth = if (inputStyle.hasKey("borderWidth")) inputStyle.getDouble("borderWidth") else null,
56
55
  borderRadius = if (inputStyle.hasKey("borderRadius")) inputStyle.getDouble("borderRadius") else null,
57
56
  borderColor = if (inputStyle.hasKey("borderColor")) inputStyle.getString("borderColor") else null,
57
+ backgroundColor = if (inputStyle.hasKey("backgroundColor")) inputStyle.getString("backgroundColor") else null,
58
58
  )
59
59
  }
60
60
  view.viewModel.setInputStyle(style)
@@ -1,15 +1,15 @@
1
1
  package com.controlledinput
2
2
 
3
+ import androidx.compose.foundation.background
3
4
  import androidx.compose.foundation.border
4
- import androidx.compose.foundation.shape.RoundedCornerShape
5
5
  import androidx.compose.foundation.layout.Box
6
- import androidx.compose.ui.draw.clip
7
- import androidx.compose.foundation.layout.PaddingValues
8
6
  import androidx.compose.foundation.layout.fillMaxSize
9
- import androidx.compose.foundation.layout.fillMaxWidth
10
- import androidx.compose.foundation.layout.height
11
7
  import androidx.compose.foundation.layout.padding
8
+ import androidx.compose.foundation.shape.RoundedCornerShape
9
+ import androidx.compose.ui.Alignment
10
+ import androidx.compose.ui.draw.clip
12
11
  import androidx.compose.foundation.text.BasicTextField
12
+ import androidx.compose.ui.unit.dp
13
13
  import androidx.compose.foundation.text.input.InputTransformation
14
14
  import androidx.compose.foundation.text.input.TextFieldState
15
15
  import androidx.compose.foundation.text.input.byValue
@@ -29,7 +29,6 @@ import androidx.compose.ui.graphics.Color
29
29
  import androidx.compose.ui.platform.LocalContext
30
30
  import androidx.compose.ui.text.TextStyle
31
31
  import androidx.compose.ui.text.font.FontFamily
32
- import androidx.compose.ui.unit.dp
33
32
  import androidx.compose.ui.unit.sp
34
33
  import androidx.lifecycle.ViewModel
35
34
  import com.facebook.react.bridge.Arguments
@@ -42,7 +41,6 @@ data class InputStyle(
42
41
  val color: String? = null,
43
42
  val fontSize: Double? = null,
44
43
  val fontFamily: String? = null,
45
- val height: Double? = null,
46
44
  val paddingTop: Double? = null,
47
45
  val paddingBottom: Double? = null,
48
46
  val paddingLeft: Double? = null,
@@ -50,6 +48,7 @@ data class InputStyle(
50
48
  val borderWidth: Double? = null,
51
49
  val borderRadius: Double? = null,
52
50
  val borderColor: String? = null,
51
+ val backgroundColor: String? = null,
53
52
  )
54
53
 
55
54
  @Composable
@@ -96,23 +95,27 @@ fun JetpackComposeView(
96
95
  }
97
96
  }
98
97
  }
99
- val height = style?.height?.let { it.dp }
100
- val paddingValues = PaddingValues(
101
- start = style?.paddingLeft?.dp ?: 0.dp,
102
- top = style?.paddingTop?.dp ?: 0.dp,
103
- end = style?.paddingRight?.dp ?: 0.dp,
104
- bottom = style?.paddingBottom?.dp ?: 0.dp,
105
- )
98
+
99
+ val paddingTop = style?.paddingTop?.dp ?: 0.dp
100
+ val paddingBottom = style?.paddingBottom?.dp ?: 0.dp
101
+ val paddingLeft = style?.paddingLeft?.dp ?: 0.dp
102
+ val paddingRight = style?.paddingRight?.dp ?: 0.dp
106
103
  val borderWidth = style?.borderWidth?.dp ?: 0.dp
107
104
  val borderRadius = style?.borderRadius?.dp ?: 0.dp
108
- val borderColor = style?.borderColor?.let { Color(android.graphics.Color.parseColor(it)) } ?: Color.Transparent
105
+ val borderColor = style?.borderColor
106
+ ?.let { Color(android.graphics.Color.parseColor(it)) }
107
+ ?: Color.Transparent
108
+ val backgroundColor = style?.backgroundColor
109
+ ?.let { Color(android.graphics.Color.parseColor(it)) }
110
+ ?: Color.Transparent
111
+ val shape = RoundedCornerShape(borderRadius)
109
112
 
110
113
  Box(
111
114
  modifier = Modifier
112
- .fillMaxWidth()
113
- .then(height?.let { Modifier.height(it) } ?: Modifier)
114
- .clip(RoundedCornerShape(borderRadius))
115
- .border(borderWidth, borderColor, RoundedCornerShape(borderRadius))
115
+ .fillMaxSize()
116
+ .clip(shape)
117
+ .background(backgroundColor)
118
+ .border(borderWidth, borderColor, shape),
116
119
  ) {
117
120
  BasicTextField(
118
121
  state,
@@ -121,8 +124,13 @@ fun JetpackComposeView(
121
124
  proposed
122
125
  },
123
126
  modifier = Modifier
124
- .fillMaxWidth()
125
- .padding(paddingValues)
127
+ .fillMaxSize()
128
+ .padding(
129
+ start = paddingLeft,
130
+ top = paddingTop,
131
+ end = paddingRight,
132
+ bottom = paddingBottom,
133
+ )
126
134
  .focusRequester(focusRequester),
127
135
  textStyle = TextStyle(
128
136
  color = textColor,
@@ -130,6 +138,14 @@ fun JetpackComposeView(
130
138
  fontFamily = fontFamily,
131
139
  ),
132
140
  interactionSource = interactionSource,
141
+ decorator = { innerTextField ->
142
+ Box(
143
+ modifier = Modifier.fillMaxSize(),
144
+ contentAlignment = Alignment.CenterStart,
145
+ ) {
146
+ innerTextField()
147
+ }
148
+ },
133
149
  )
134
150
  }
135
151
  }
@@ -10,12 +10,13 @@
10
10
  #import <React/RCTFabricComponentsPlugins.h>
11
11
 
12
12
  #import <react/renderer/components/ControlledInputViewSpec/ComponentDescriptors.h>
13
+ #import <react/renderer/components/ControlledInputViewSpec/EventEmitters.h>
13
14
  #import <react/renderer/components/ControlledInputViewSpec/Props.h>
14
15
  #import <react/renderer/components/ControlledInputViewSpec/RCTComponentViewHelpers.h>
15
16
 
16
17
  using namespace facebook::react;
17
18
 
18
- @interface ControlledInputView () <RCTControlledInputViewViewProtocol>
19
+ @interface ControlledInputView () <RCTControlledInputViewViewProtocol, RNControlledInputDelegate>
19
20
  @end
20
21
 
21
22
  @implementation ControlledInputView {
@@ -34,6 +35,7 @@ using namespace facebook::react;
34
35
  _props = defaultProps;
35
36
 
36
37
  _inputView = [[RNControlledInput alloc] initWithFrame:self.bounds];
38
+ _inputView.delegate = self;
37
39
 
38
40
  self.contentView = _inputView;
39
41
  }
@@ -50,44 +52,20 @@ using namespace facebook::react;
50
52
  _inputView.value = [NSString stringWithUTF8String:newViewProps.value.c_str()];
51
53
  }
52
54
 
53
- // Update inputStyle props
54
55
  const auto &style = newViewProps.inputStyle;
55
56
  const auto &oldStyle = oldViewProps.inputStyle;
56
57
 
57
58
  if (oldStyle.color != style.color) {
58
59
  _inputView.textColor = RCTUIColorFromSharedColor(style.color);
59
60
  }
60
-
61
+
61
62
  if (oldStyle.fontSize != style.fontSize) {
62
63
  _inputView.fontSize = style.fontSize;
63
64
  }
64
-
65
+
65
66
  if (oldStyle.fontFamily != style.fontFamily) {
66
67
  _inputView.fontFamily = style.fontFamily.empty() ? nil : [NSString stringWithUTF8String:style.fontFamily.c_str()];
67
68
  }
68
-
69
- if (oldStyle.height != style.height) {
70
- _inputView.inputHeight = style.height;
71
- }
72
-
73
- if (oldStyle.paddingTop != style.paddingTop ||
74
- oldStyle.paddingBottom != style.paddingBottom ||
75
- oldStyle.paddingLeft != style.paddingLeft ||
76
- oldStyle.paddingRight != style.paddingRight) {
77
- _inputView.padding = UIEdgeInsetsMake(style.paddingTop, style.paddingLeft, style.paddingBottom, style.paddingRight);
78
- }
79
-
80
- if (oldStyle.borderWidth != style.borderWidth) {
81
- _inputView.borderWidth = style.borderWidth;
82
- }
83
-
84
- if (oldStyle.borderRadius != style.borderRadius) {
85
- _inputView.borderRadius = style.borderRadius;
86
- }
87
-
88
- if (oldStyle.borderColor != style.borderColor) {
89
- _inputView.borderColor = RCTUIColorFromSharedColor(style.borderColor);
90
- }
91
69
 
92
70
  [super updateProps:props oldProps:oldProps];
93
71
  }
@@ -109,4 +87,38 @@ using namespace facebook::react;
109
87
  [super handleCommand:commandName args:args];
110
88
  }
111
89
 
90
+ - (void)controlledInputDidChangeText:(RNControlledInput *)input value:(NSString *)value
91
+ {
92
+ if (_eventEmitter == nullptr) {
93
+ return;
94
+ }
95
+
96
+ const auto eventEmitter = std::static_pointer_cast<const ControlledInputViewEventEmitter>(_eventEmitter);
97
+ const char *utf8Value = value.UTF8String ?: "";
98
+
99
+ eventEmitter->onTextChange(ControlledInputViewEventEmitter::OnTextChange {
100
+ .value = std::string(utf8Value),
101
+ });
102
+ }
103
+
104
+ - (void)controlledInputDidFocus:(RNControlledInput *)input
105
+ {
106
+ if (_eventEmitter == nullptr) {
107
+ return;
108
+ }
109
+
110
+ const auto eventEmitter = std::static_pointer_cast<const ControlledInputViewEventEmitter>(_eventEmitter);
111
+ eventEmitter->onFocus(ControlledInputViewEventEmitter::OnFocus {});
112
+ }
113
+
114
+ - (void)controlledInputDidBlur:(RNControlledInput *)input
115
+ {
116
+ if (_eventEmitter == nullptr) {
117
+ return;
118
+ }
119
+
120
+ const auto eventEmitter = std::static_pointer_cast<const ControlledInputViewEventEmitter>(_eventEmitter);
121
+ eventEmitter->onBlur(ControlledInputViewEventEmitter::OnBlur {});
122
+ }
123
+
112
124
  @end
@@ -1,49 +1,95 @@
1
1
  import UIKit
2
2
 
3
+ @objc public protocol RNControlledInputDelegate: AnyObject {
4
+ func controlledInputDidChangeText(_ input: RNControlledInput, value: String)
5
+ func controlledInputDidFocus(_ input: RNControlledInput)
6
+ func controlledInputDidBlur(_ input: RNControlledInput)
7
+ }
8
+
3
9
  @objc(RNControlledInput)
4
- public class RNControlledInput: UIView {
5
-
10
+ public class RNControlledInput: UIView, UITextFieldDelegate {
11
+
12
+ private let textField = UITextField()
13
+ @objc public weak var delegate: RNControlledInputDelegate?
14
+
6
15
  @objc public var value: String? {
7
16
  didSet {
8
- // Update UI
17
+ if textField.text != value {
18
+ textField.text = value
19
+ }
9
20
  }
10
21
  }
11
-
12
- @objc public var textColor: UIColor?
13
- @objc public var fontSize: CGFloat = 16
14
- @objc public var fontFamily: String?
15
- @objc public var inputHeight: CGFloat = 0
16
- @objc public var padding: UIEdgeInsets = .zero
17
- @objc public var borderWidth: CGFloat = 0
18
- @objc public var borderRadius: CGFloat = 0
19
- @objc public var borderColor: UIColor?
20
22
 
21
- public override var canBecomeFirstResponder: Bool {
22
- true
23
+ @objc public var textColor: UIColor? {
24
+ didSet { textField.textColor = textColor }
25
+ }
26
+
27
+ @objc public var fontSize: CGFloat = 16 {
28
+ didSet { applyFont() }
29
+ }
30
+
31
+ @objc public var fontFamily: String? {
32
+ didSet { applyFont() }
23
33
  }
24
34
 
35
+ public override var canBecomeFirstResponder: Bool { true }
36
+
25
37
  @objc public func focus() {
26
- print("[ControlledInputView] RNControlledInput.focus()")
27
- _ = becomeFirstResponder()
38
+ textField.becomeFirstResponder()
28
39
  }
29
40
 
30
41
  @objc public func blur() {
31
- print("[ControlledInputView] RNControlledInput.blur()")
32
- _ = resignFirstResponder()
42
+ textField.resignFirstResponder()
33
43
  }
34
44
 
35
45
  @objc public override init(frame: CGRect) {
36
46
  super.init(frame: frame)
37
- self.backgroundColor = .red
38
- self.translatesAutoresizingMaskIntoConstraints = false
39
-
40
- NSLayoutConstraint.activate([
41
- self.widthAnchor.constraint(equalToConstant: 100),
42
- self.heightAnchor.constraint(equalToConstant: 100)
43
- ])
47
+ setupTextField()
44
48
  }
45
-
49
+
46
50
  required init?(coder: NSCoder) {
47
51
  fatalError("init(coder:) has not been implemented")
48
52
  }
53
+
54
+ private func setupTextField() {
55
+ textField.translatesAutoresizingMaskIntoConstraints = false
56
+ textField.borderStyle = .none
57
+ textField.delegate = self
58
+ addSubview(textField)
59
+
60
+ NSLayoutConstraint.activate([
61
+ textField.topAnchor.constraint(equalTo: topAnchor),
62
+ textField.leadingAnchor.constraint(equalTo: leadingAnchor),
63
+ textField.trailingAnchor.constraint(equalTo: trailingAnchor),
64
+ textField.bottomAnchor.constraint(equalTo: bottomAnchor),
65
+ ])
66
+
67
+ applyFont()
68
+ }
69
+
70
+ public func textFieldDidBeginEditing(_ textField: UITextField) {
71
+ delegate?.controlledInputDidFocus(self)
72
+ }
73
+
74
+ public func textFieldDidEndEditing(_ textField: UITextField) {
75
+ delegate?.controlledInputDidBlur(self)
76
+ }
77
+
78
+ public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
79
+ let currentText = textField.text ?? ""
80
+ guard let stringRange = Range(range, in: currentText) else { return true }
81
+ let newText = currentText.replacingCharacters(in: stringRange, with: string)
82
+
83
+ delegate?.controlledInputDidChangeText(self, value: newText)
84
+
85
+ return false
86
+ }
87
+
88
+ private func applyFont() {
89
+ if let family = fontFamily, let font = UIFont(name: family, size: fontSize) {
90
+ textField.font = font
91
+ } else {
92
+ textField.font = UIFont.systemFont(ofSize: fontSize)
93
+ }
94
+ }
49
95
  }
@@ -26,14 +26,14 @@ interface InputStyle {
26
26
  color?: ColorValue;
27
27
  fontSize?: Double;
28
28
  fontFamily?: string;
29
- height?: Double;
30
29
  paddingTop?: Double;
31
30
  paddingBottom?: Double;
32
31
  paddingLeft?: Double;
33
32
  paddingRight?: Double;
34
33
  borderWidth?: Double;
35
34
  borderRadius?: Double;
36
- borderColor?: ColorValue;
35
+ borderColor?: string;
36
+ backgroundColor?: string;
37
37
  }
38
38
 
39
39
  export interface NativeProps extends ViewProps {
@@ -1,33 +1,76 @@
1
1
  "use strict";
2
2
 
3
3
  import { forwardRef, useImperativeHandle, useRef } from 'react';
4
- import { Platform } from 'react-native';
4
+ import { Platform, processColor, StyleSheet } from 'react-native';
5
5
  import ControlledInputViewNativeComponent, { Commands } from './ControlledInputViewNativeComponent';
6
6
  import { jsx as _jsx } from "react/jsx-runtime";
7
- export const ControlledInputView = /*#__PURE__*/forwardRef((props, ref) => {
7
+ // All style props that Android handles via Compose instead of the native View layer
8
+ const ANDROID_HANDLED_KEYS = ['color', 'fontSize', 'fontFamily', 'padding', 'paddingVertical', 'paddingHorizontal', 'paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight', 'paddingStart', 'paddingEnd', 'borderWidth', 'borderRadius', 'borderColor', 'backgroundColor'];
9
+ function resolveAndroidPadding(flat) {
10
+ const base = flat.padding ?? 0;
11
+ return {
12
+ paddingTop: flat.paddingTop ?? flat.paddingVertical ?? base,
13
+ paddingBottom: flat.paddingBottom ?? flat.paddingVertical ?? base,
14
+ paddingLeft: flat.paddingLeft ?? flat.paddingStart ?? flat.paddingHorizontal ?? base,
15
+ paddingRight: flat.paddingRight ?? flat.paddingEnd ?? flat.paddingHorizontal ?? base
16
+ };
17
+ }
18
+ export const ControlledInputView = /*#__PURE__*/forwardRef(({
19
+ style,
20
+ onTextChange,
21
+ ...rest
22
+ }, ref) => {
8
23
  const nativeRef = useRef(null);
24
+ const flat = StyleSheet.flatten(style) ?? {};
25
+ let viewStyle;
26
+ let inputStyle;
27
+ if (Platform.OS === 'android') {
28
+ viewStyle = Object.fromEntries(Object.entries(flat).filter(([k]) => !ANDROID_HANDLED_KEYS.includes(k)));
29
+ const hasPadding = ANDROID_HANDLED_KEYS.slice(3, 12).some(k => flat[k] != null);
30
+ inputStyle = {
31
+ color: flat.color,
32
+ fontSize: flat.fontSize,
33
+ fontFamily: flat.fontFamily,
34
+ ...(hasPadding ? resolveAndroidPadding(flat) : {}),
35
+ borderWidth: flat.borderWidth,
36
+ borderRadius: flat.borderRadius,
37
+ borderColor: flat.borderColor,
38
+ backgroundColor: flat.backgroundColor
39
+ };
40
+ } else {
41
+ const {
42
+ color,
43
+ fontSize,
44
+ fontFamily,
45
+ ...iosRest
46
+ } = flat;
47
+ viewStyle = iosRest;
48
+ const hasTextStyle = color != null || fontSize != null || fontFamily != null;
49
+ inputStyle = hasTextStyle ? {
50
+ color: color != null ? processColor(color) : undefined,
51
+ fontSize,
52
+ fontFamily
53
+ } : undefined;
54
+ }
9
55
  useImperativeHandle(ref, () => ({
10
56
  blur: () => {
11
- if (!nativeRef.current) {
12
- return;
13
- }
57
+ if (!nativeRef.current) return;
14
58
  if (Platform.OS === 'ios' || Platform.OS === 'android') {
15
- console.log(`[ControlledInputView] ${Platform.OS} blur command -> native`);
16
59
  Commands.blur(nativeRef.current);
17
60
  }
18
61
  },
19
62
  focus: () => {
20
- if (!nativeRef.current) {
21
- return;
22
- }
63
+ if (!nativeRef.current) return;
23
64
  if (Platform.OS === 'ios' || Platform.OS === 'android') {
24
- console.log(`[ControlledInputView] ${Platform.OS} focus command -> native`);
25
65
  Commands.focus(nativeRef.current);
26
66
  }
27
67
  }
28
68
  }));
29
69
  return /*#__PURE__*/_jsx(ControlledInputViewNativeComponent, {
30
- ...props,
70
+ ...rest,
71
+ style: viewStyle,
72
+ inputStyle: inputStyle,
73
+ onTextChange: onTextChange ? e => onTextChange(e.nativeEvent.value) : undefined,
31
74
  ref: nativeRef
32
75
  });
33
76
  });
@@ -1 +1 @@
1
- {"version":3,"names":["forwardRef","useImperativeHandle","useRef","Platform","ControlledInputViewNativeComponent","Commands","jsx","_jsx","ControlledInputView","props","ref","nativeRef","blur","current","OS","console","log","focus"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SACEA,UAAU,EACVC,mBAAmB,EACnBC,MAAM,QAED,OAAO;AACd,SAASC,QAAQ,QAAQ,cAAc;AACvC,OAAOC,kCAAkC,IACvCC,QAAQ,QAEH,sCAAsC;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAO9C,OAAO,MAAMC,mBAAmB,gBAAGR,UAAU,CAG3C,CAACS,KAAK,EAAEC,GAAG,KAAK;EAChB,MAAMC,SAAS,GACbT,MAAM,CAAwD,IAAI,CAAC;EAErED,mBAAmB,CAACS,GAAG,EAAE,OAAO;IAC9BE,IAAI,EAAEA,CAAA,KAAM;MACV,IAAI,CAACD,SAAS,CAACE,OAAO,EAAE;QACtB;MACF;MAEA,IAAIV,QAAQ,CAACW,EAAE,KAAK,KAAK,IAAIX,QAAQ,CAACW,EAAE,KAAK,SAAS,EAAE;QACtDC,OAAO,CAACC,GAAG,CACT,yBAAyBb,QAAQ,CAACW,EAAE,yBACtC,CAAC;QACDT,QAAQ,CAACO,IAAI,CAACD,SAAS,CAACE,OAAO,CAAC;MAClC;IACF,CAAC;IACDI,KAAK,EAAEA,CAAA,KAAM;MACX,IAAI,CAACN,SAAS,CAACE,OAAO,EAAE;QACtB;MACF;MAEA,IAAIV,QAAQ,CAACW,EAAE,KAAK,KAAK,IAAIX,QAAQ,CAACW,EAAE,KAAK,SAAS,EAAE;QACtDC,OAAO,CAACC,GAAG,CACT,yBAAyBb,QAAQ,CAACW,EAAE,0BACtC,CAAC;QACDT,QAAQ,CAACY,KAAK,CAACN,SAAS,CAACE,OAAO,CAAC;MACnC;IACF;EACF,CAAC,CAAC,CAAC;EAEH,oBACEN,IAAA,CAACH,kCAAkC;IAAA,GAAKK,KAAK;IAAEC,GAAG,EAAEC;EAAiB,CAAE,CAAC;AAE5E,CAAC,CAAC;AAEF,cAAc,sCAAsC","ignoreList":[]}
1
+ {"version":3,"names":["forwardRef","useImperativeHandle","useRef","Platform","processColor","StyleSheet","ControlledInputViewNativeComponent","Commands","jsx","_jsx","ANDROID_HANDLED_KEYS","resolveAndroidPadding","flat","base","padding","paddingTop","paddingVertical","paddingBottom","paddingLeft","paddingStart","paddingHorizontal","paddingRight","paddingEnd","ControlledInputView","style","onTextChange","rest","ref","nativeRef","flatten","viewStyle","inputStyle","OS","Object","fromEntries","entries","filter","k","includes","hasPadding","slice","some","color","fontSize","fontFamily","borderWidth","borderRadius","borderColor","backgroundColor","iosRest","hasTextStyle","undefined","blur","current","focus","e","nativeEvent","value"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
@@ -11,14 +11,14 @@ interface InputStyle {
11
11
  color?: ColorValue;
12
12
  fontSize?: Double;
13
13
  fontFamily?: string;
14
- height?: Double;
15
14
  paddingTop?: Double;
16
15
  paddingBottom?: Double;
17
16
  paddingLeft?: Double;
18
17
  paddingRight?: Double;
19
18
  borderWidth?: Double;
20
19
  borderRadius?: Double;
21
- borderColor?: ColorValue;
20
+ borderColor?: string;
21
+ backgroundColor?: string;
22
22
  }
23
23
  export interface NativeProps extends ViewProps {
24
24
  value?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"ControlledInputViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/ControlledInputViewNativeComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,aAAa,EACnB,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EACV,oBAAoB,EACpB,MAAM,EACP,MAAM,2CAA2C,CAAC;AAEnD,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,UAAU;CAEnB;AAED,UAAU,SAAS;CAElB;AAED,UAAU,UAAU;IAClB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,UAAU,CAAC;CAC1B;AAED,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,YAAY,CAAC,EAAE,oBAAoB,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC;IAC/D,OAAO,CAAC,EAAE,oBAAoB,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;IACrD,MAAM,CAAC,EAAE,oBAAoB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;CACpD;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,KAAK,IAAI,CAAC;IACvE,IAAI,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,KAAK,IAAI,CAAC;CACvE;AAED,eAAO,MAAM,QAAQ,EAAE,cAErB,CAAC;;AAEH,wBAA0E"}
1
+ {"version":3,"file":"ControlledInputViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/ControlledInputViewNativeComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,aAAa,EACnB,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EACV,oBAAoB,EACpB,MAAM,EACP,MAAM,2CAA2C,CAAC;AAEnD,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,UAAU;CAEnB;AAED,UAAU,SAAS;CAElB;AAED,UAAU,UAAU;IAClB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,YAAY,CAAC,EAAE,oBAAoB,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC;IAC/D,OAAO,CAAC,EAAE,oBAAoB,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;IACrD,MAAM,CAAC,EAAE,oBAAoB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;CACpD;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,KAAK,IAAI,CAAC;IACvE,IAAI,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,KAAK,IAAI,CAAC;CACvE;AAED,eAAO,MAAM,QAAQ,EAAE,cAErB,CAAC;;AAEH,wBAA0E"}
@@ -3,6 +3,11 @@ export interface ControlledInputViewRef {
3
3
  blur: () => void;
4
4
  focus: () => void;
5
5
  }
6
- export declare const ControlledInputView: import("react").ForwardRefExoticComponent<NativeProps & import("react").RefAttributes<ControlledInputViewRef>>;
6
+ export type ControlledInputViewProps = Omit<NativeProps, 'inputStyle' | 'onTextChange'> & {
7
+ onTextChange?: (value: string) => void;
8
+ };
9
+ export declare const ControlledInputView: import("react").ForwardRefExoticComponent<Omit<NativeProps, "inputStyle" | "onTextChange"> & {
10
+ onTextChange?: (value: string) => void;
11
+ } & import("react").RefAttributes<ControlledInputViewRef>>;
7
12
  export * from './ControlledInputViewNativeComponent';
8
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAOA,OAA2C,EAEzC,KAAK,WAAW,EACjB,MAAM,sCAAsC,CAAC;AAE9C,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,eAAO,MAAM,mBAAmB,gHAqC9B,CAAC;AAEH,cAAc,sCAAsC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAYA,OAA2C,EAEzC,KAAK,WAAW,EACjB,MAAM,sCAAsC,CAAC;AAE9C,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,MAAM,MAAM,wBAAwB,GAAG,IAAI,CACzC,WAAW,EACX,YAAY,GAAG,cAAc,CAC9B,GAAG;IACF,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC,CAAC;AAkCF,eAAO,MAAM,mBAAmB;mBAnCf,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;0DA2GtC,CAAC;AAEH,cAAc,sCAAsC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-controlled-input",
3
- "version": "0.6.0",
3
+ "version": "0.9.0",
4
4
  "description": "React Native Controlled Inputative Controlled Input",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -26,14 +26,14 @@ interface InputStyle {
26
26
  color?: ColorValue;
27
27
  fontSize?: Double;
28
28
  fontFamily?: string;
29
- height?: Double;
30
29
  paddingTop?: Double;
31
30
  paddingBottom?: Double;
32
31
  paddingLeft?: Double;
33
32
  paddingRight?: Double;
34
33
  borderWidth?: Double;
35
34
  borderRadius?: Double;
36
- borderColor?: ColorValue;
35
+ borderColor?: string;
36
+ backgroundColor?: string;
37
37
  }
38
38
 
39
39
  export interface NativeProps extends ViewProps {
package/src/index.tsx CHANGED
@@ -4,7 +4,12 @@ import {
4
4
  useRef,
5
5
  type ElementRef,
6
6
  } from 'react';
7
- import { Platform } from 'react-native';
7
+ import {
8
+ Platform,
9
+ processColor,
10
+ StyleSheet,
11
+ type ViewStyle,
12
+ } from 'react-native';
8
13
  import ControlledInputViewNativeComponent, {
9
14
  Commands,
10
15
  type NativeProps,
@@ -15,42 +20,116 @@ export interface ControlledInputViewRef {
15
20
  focus: () => void;
16
21
  }
17
22
 
23
+ export type ControlledInputViewProps = Omit<
24
+ NativeProps,
25
+ 'inputStyle' | 'onTextChange'
26
+ > & {
27
+ onTextChange?: (value: string) => void;
28
+ };
29
+
30
+ // All style props that Android handles via Compose instead of the native View layer
31
+ const ANDROID_HANDLED_KEYS = [
32
+ 'color',
33
+ 'fontSize',
34
+ 'fontFamily',
35
+ 'padding',
36
+ 'paddingVertical',
37
+ 'paddingHorizontal',
38
+ 'paddingTop',
39
+ 'paddingBottom',
40
+ 'paddingLeft',
41
+ 'paddingRight',
42
+ 'paddingStart',
43
+ 'paddingEnd',
44
+ 'borderWidth',
45
+ 'borderRadius',
46
+ 'borderColor',
47
+ 'backgroundColor',
48
+ ];
49
+
50
+ function resolveAndroidPadding(flat: Record<string, any>) {
51
+ const base = flat.padding ?? 0;
52
+ return {
53
+ paddingTop: flat.paddingTop ?? flat.paddingVertical ?? base,
54
+ paddingBottom: flat.paddingBottom ?? flat.paddingVertical ?? base,
55
+ paddingLeft:
56
+ flat.paddingLeft ?? flat.paddingStart ?? flat.paddingHorizontal ?? base,
57
+ paddingRight:
58
+ flat.paddingRight ?? flat.paddingEnd ?? flat.paddingHorizontal ?? base,
59
+ };
60
+ }
61
+
18
62
  export const ControlledInputView = forwardRef<
19
63
  ControlledInputViewRef,
20
- NativeProps
21
- >((props, ref) => {
64
+ ControlledInputViewProps
65
+ >(({ style, onTextChange, ...rest }, ref) => {
22
66
  const nativeRef =
23
67
  useRef<ElementRef<typeof ControlledInputViewNativeComponent>>(null);
24
68
 
69
+ const flat = (StyleSheet.flatten(style) ?? {}) as Record<string, any>;
70
+
71
+ let viewStyle: ViewStyle;
72
+ let inputStyle: Record<string, any> | undefined;
73
+
74
+ if (Platform.OS === 'android') {
75
+ viewStyle = Object.fromEntries(
76
+ Object.entries(flat).filter(([k]) => !ANDROID_HANDLED_KEYS.includes(k))
77
+ ) as ViewStyle;
78
+
79
+ const hasPadding = ANDROID_HANDLED_KEYS.slice(3, 12).some(
80
+ (k) => flat[k] != null
81
+ );
82
+
83
+ inputStyle = {
84
+ color: flat.color,
85
+ fontSize: flat.fontSize,
86
+ fontFamily: flat.fontFamily,
87
+ ...(hasPadding ? resolveAndroidPadding(flat) : {}),
88
+ borderWidth: flat.borderWidth,
89
+ borderRadius: flat.borderRadius,
90
+ borderColor: flat.borderColor,
91
+ backgroundColor: flat.backgroundColor,
92
+ };
93
+ } else {
94
+ const { color, fontSize, fontFamily, ...iosRest } = flat;
95
+ viewStyle = iosRest as ViewStyle;
96
+
97
+ const hasTextStyle =
98
+ color != null || fontSize != null || fontFamily != null;
99
+ inputStyle = hasTextStyle
100
+ ? {
101
+ color: color != null ? processColor(color) : undefined,
102
+ fontSize,
103
+ fontFamily,
104
+ }
105
+ : undefined;
106
+ }
107
+
25
108
  useImperativeHandle(ref, () => ({
26
109
  blur: () => {
27
- if (!nativeRef.current) {
28
- return;
29
- }
30
-
110
+ if (!nativeRef.current) return;
31
111
  if (Platform.OS === 'ios' || Platform.OS === 'android') {
32
- console.log(
33
- `[ControlledInputView] ${Platform.OS} blur command -> native`
34
- );
35
112
  Commands.blur(nativeRef.current);
36
113
  }
37
114
  },
38
115
  focus: () => {
39
- if (!nativeRef.current) {
40
- return;
41
- }
42
-
116
+ if (!nativeRef.current) return;
43
117
  if (Platform.OS === 'ios' || Platform.OS === 'android') {
44
- console.log(
45
- `[ControlledInputView] ${Platform.OS} focus command -> native`
46
- );
47
118
  Commands.focus(nativeRef.current);
48
119
  }
49
120
  },
50
121
  }));
51
122
 
52
123
  return (
53
- <ControlledInputViewNativeComponent {...props} ref={nativeRef as any} />
124
+ <ControlledInputViewNativeComponent
125
+ {...rest}
126
+ style={viewStyle}
127
+ inputStyle={inputStyle as NativeProps['inputStyle']}
128
+ onTextChange={
129
+ onTextChange ? (e) => onTextChange(e.nativeEvent.value) : undefined
130
+ }
131
+ ref={nativeRef as any}
132
+ />
54
133
  );
55
134
  });
56
135