react-native-form-controls 1.0.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 +122 -0
- package/lib/Input.d.ts +34 -0
- package/lib/Input.js +289 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +9 -0
- package/package.json +49 -0
package/README.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# react-native-form-controls
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/react-native-form-controls)
|
|
4
|
+
|
|
5
|
+
A highly customizable input component for React Native that works in **any project**. Use it for text, password, textarea out of the box; optionally add date/time picker and Google Places autocomplete by installing extra packages.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Core types (no extra deps)**: text, password, textarea
|
|
10
|
+
- **Optional date/time**: Install `react-native-date-picker` for date, time, and datetime types
|
|
11
|
+
- **Optional autocomplete**: Install `react-native-google-places-autocomplete` and pass `googleApiKey` for location search
|
|
12
|
+
- **Customizable styles**: container, label, input
|
|
13
|
+
- **Error handling**: error message and error border
|
|
14
|
+
- **Icons**: left and right icons with actions
|
|
15
|
+
- **Controlled/uncontrolled**: Supports `value` and `onChangeText` for all types, including date/time
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
**Base (works in any project):**
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install react-native-form-controls
|
|
23
|
+
# or
|
|
24
|
+
yarn add react-native-form-controls
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Optional – date/time picker** (for `type="date"`, `type="time"`, `type="datetime"`):
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install react-native-date-picker
|
|
31
|
+
# or
|
|
32
|
+
yarn add react-native-date-picker
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Optional – Google Places autocomplete** (for `type="autocomplete"`):
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm install react-native-google-places-autocomplete
|
|
39
|
+
# or
|
|
40
|
+
yarn add react-native-google-places-autocomplete
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
If you don’t install the optional packages, the component still works: text, password, and textarea work as usual; date/time and autocomplete show a fallback message asking you to install the corresponding package.
|
|
44
|
+
|
|
45
|
+
## Example app
|
|
46
|
+
|
|
47
|
+
A runnable example (Expo) is in the [`example/`](./example) folder:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npm run build && cd example && npm install && npm start
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
See [example/README.md](./example/README.md) for details.
|
|
54
|
+
|
|
55
|
+
## Usage
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
import { Input, COLORS } from 'react-native-form-controls';
|
|
59
|
+
|
|
60
|
+
// Text
|
|
61
|
+
<Input type="text" label="Name" placeholder="Enter name" />
|
|
62
|
+
|
|
63
|
+
// Password
|
|
64
|
+
<Input type="password" label="Password" placeholder="Enter password" />
|
|
65
|
+
|
|
66
|
+
// Textarea
|
|
67
|
+
<Input type="textarea" label="Notes" placeholder="Enter notes" />
|
|
68
|
+
|
|
69
|
+
// Date (requires react-native-date-picker)
|
|
70
|
+
<Input type="date" label="Birth date" onChangeText={(iso) => setDate(iso)} />
|
|
71
|
+
|
|
72
|
+
// Time (requires react-native-date-picker)
|
|
73
|
+
<Input type="time" label="Time" onChangeText={(iso) => setTime(iso)} />
|
|
74
|
+
|
|
75
|
+
// Autocomplete (requires react-native-google-places-autocomplete + googleApiKey)
|
|
76
|
+
<Input
|
|
77
|
+
type="autocomplete"
|
|
78
|
+
label="Location"
|
|
79
|
+
googleApiKey="YOUR_GOOGLE_PLACES_API_KEY"
|
|
80
|
+
onChangeText={(place) => console.log(place)}
|
|
81
|
+
/>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Use `COLORS` from the package to match built-in theming (e.g. `labelStyle={{ color: COLORS.primary }}`).
|
|
85
|
+
|
|
86
|
+
## Props
|
|
87
|
+
|
|
88
|
+
| Prop | Type | Description |
|
|
89
|
+
|------|------|-------------|
|
|
90
|
+
| `type` | `'text' \| 'password' \| 'date' \| 'time' \| 'datetime' \| 'textarea' \| 'autocomplete'` | Input type |
|
|
91
|
+
| `label` | `string` | Label above the input |
|
|
92
|
+
| `error` | `string` | Error message (shows below input and error border) |
|
|
93
|
+
| `googleApiKey` | `string` | **Required for `type="autocomplete"`**. Google Places API key. |
|
|
94
|
+
| `containerStyle` | `ViewStyle` | Container style |
|
|
95
|
+
| `labelStyle` | `TextStyle` | Label style |
|
|
96
|
+
| `inputStyle` | `TextStyle` | Input style |
|
|
97
|
+
| `leftIcon` | `ImageSourcePropType` | Left icon image source |
|
|
98
|
+
| `rightIcon` | `ReactNode` | Right icon (e.g. eye for password) |
|
|
99
|
+
| Plus all standard `TextInput` props: `value`, `onChangeText`, `placeholder`, etc. |
|
|
100
|
+
|
|
101
|
+
For date/time/datetime, `onChangeText` receives an ISO date string. For autocomplete, it receives an object with `addresstext`, `latitude`, `longitude`, `location` (e.g. `city`, `country`, `state`, `pincode`).
|
|
102
|
+
|
|
103
|
+
## Publishing to npm
|
|
104
|
+
|
|
105
|
+
From the repository root:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# 1. Build the library
|
|
109
|
+
npm run build
|
|
110
|
+
|
|
111
|
+
# 2. Log in to npm (one-time)
|
|
112
|
+
npm login
|
|
113
|
+
|
|
114
|
+
# 3. Publish
|
|
115
|
+
npm publish
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
To publish a new version, update `version` in `package.json` (e.g. `1.1.1`) then run `npm publish` again. Use `npm version patch` to bump the version automatically.
|
|
119
|
+
|
|
120
|
+
## License
|
|
121
|
+
|
|
122
|
+
MIT
|
package/lib/Input.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ImageSourcePropType, TextInputProps, StyleProp, ViewStyle, TextStyle } from 'react-native';
|
|
3
|
+
export declare const COLORS: {
|
|
4
|
+
black: string;
|
|
5
|
+
white: string;
|
|
6
|
+
background: string;
|
|
7
|
+
darkGray: string;
|
|
8
|
+
lightGray: string;
|
|
9
|
+
primary: string;
|
|
10
|
+
secondary: string;
|
|
11
|
+
success: string;
|
|
12
|
+
tertiary: string;
|
|
13
|
+
danger: string;
|
|
14
|
+
warning: string;
|
|
15
|
+
info: string;
|
|
16
|
+
light: string;
|
|
17
|
+
dark: string;
|
|
18
|
+
link: string;
|
|
19
|
+
error: string;
|
|
20
|
+
};
|
|
21
|
+
interface InputProps extends TextInputProps {
|
|
22
|
+
type: 'text' | 'password' | 'date' | 'time' | 'datetime' | 'textarea' | 'autocomplete';
|
|
23
|
+
leftIcon?: ImageSourcePropType;
|
|
24
|
+
rightIcon?: React.ReactNode;
|
|
25
|
+
label?: string;
|
|
26
|
+
error?: string;
|
|
27
|
+
containerStyle?: StyleProp<ViewStyle>;
|
|
28
|
+
labelStyle?: StyleProp<TextStyle>;
|
|
29
|
+
inputStyle?: StyleProp<TextStyle>;
|
|
30
|
+
/** Required for type="autocomplete". Install react-native-google-places-autocomplete to use. */
|
|
31
|
+
googleApiKey?: string;
|
|
32
|
+
}
|
|
33
|
+
declare const Input: React.FC<InputProps>;
|
|
34
|
+
export default Input;
|
package/lib/Input.js
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
+
var ownKeys = function(o) {
|
|
31
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
+
var ar = [];
|
|
33
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
+
return ar;
|
|
35
|
+
};
|
|
36
|
+
return ownKeys(o);
|
|
37
|
+
};
|
|
38
|
+
return function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
})();
|
|
46
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
47
|
+
var t = {};
|
|
48
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
49
|
+
t[p] = s[p];
|
|
50
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
51
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
52
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
53
|
+
t[p[i]] = s[p[i]];
|
|
54
|
+
}
|
|
55
|
+
return t;
|
|
56
|
+
};
|
|
57
|
+
var _a;
|
|
58
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
59
|
+
exports.COLORS = void 0;
|
|
60
|
+
var react_1 = __importStar(require("react"));
|
|
61
|
+
var react_native_1 = require("react-native");
|
|
62
|
+
// Optional dependencies – only loaded when used; safe for projects that don't install them
|
|
63
|
+
var DatePicker = null;
|
|
64
|
+
var GooglePlacesAutocomplete = null;
|
|
65
|
+
try {
|
|
66
|
+
DatePicker = require('react-native-date-picker').default;
|
|
67
|
+
}
|
|
68
|
+
catch (_b) {
|
|
69
|
+
// react-native-date-picker not installed – date/time/datetime will show fallback
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
var GooglePlaces = require('react-native-google-places-autocomplete');
|
|
73
|
+
GooglePlacesAutocomplete = (_a = GooglePlaces.GooglePlacesAutocomplete) !== null && _a !== void 0 ? _a : GooglePlaces.default;
|
|
74
|
+
}
|
|
75
|
+
catch (_c) {
|
|
76
|
+
// react-native-google-places-autocomplete not installed – autocomplete will show fallback
|
|
77
|
+
}
|
|
78
|
+
exports.COLORS = {
|
|
79
|
+
// text color
|
|
80
|
+
black: '#252F40',
|
|
81
|
+
white: '#FFFFFF',
|
|
82
|
+
background: '#FFFFF',
|
|
83
|
+
darkGray: '#A9A9A9',
|
|
84
|
+
lightGray: '#D3D3D3',
|
|
85
|
+
// base colors
|
|
86
|
+
primary: '#007bff',
|
|
87
|
+
secondary: '#627594',
|
|
88
|
+
success: '#28a745',
|
|
89
|
+
tertiary: '#E8AE4C',
|
|
90
|
+
danger: '#dc3545',
|
|
91
|
+
warning: '#FFC107',
|
|
92
|
+
info: '#17A2B8',
|
|
93
|
+
light: '#F8F9FA',
|
|
94
|
+
dark: '#343A40',
|
|
95
|
+
link: '#007BFF',
|
|
96
|
+
error: '#EB5757',
|
|
97
|
+
};
|
|
98
|
+
var TextInputField = function (_a) {
|
|
99
|
+
var isPasswordVisible = _a.isPasswordVisible, inputStyle = _a.inputStyle, error = _a.error, type = _a.type, props = __rest(_a, ["isPasswordVisible", "inputStyle", "error", "type"]);
|
|
100
|
+
return (react_1.default.createElement(react_native_1.TextInput, __assign({ style: [styles.input, inputStyle, error ? styles.errorBorder : {}], secureTextEntry: type === 'password' && !isPasswordVisible, placeholderTextColor: exports.COLORS.secondary }, props)));
|
|
101
|
+
};
|
|
102
|
+
var TextareaInput = function (_a) {
|
|
103
|
+
var inputStyle = _a.inputStyle, error = _a.error, props = __rest(_a, ["inputStyle", "error"]);
|
|
104
|
+
return (react_1.default.createElement(react_native_1.TextInput, __assign({ style: [styles.textarea, inputStyle, error ? styles.errorBorder : {}], multiline: true, placeholderTextColor: exports.COLORS.secondary }, props)));
|
|
105
|
+
};
|
|
106
|
+
var AutocompleteInput = function (_a) {
|
|
107
|
+
var inputStyle = _a.inputStyle, error = _a.error, googleApiKey = _a.googleApiKey, _b = _a.placeholder, placeholder = _b === void 0 ? 'Search' : _b, props = __rest(_a, ["inputStyle", "error", "googleApiKey", "placeholder"]);
|
|
108
|
+
var getAddress = (0, react_1.useCallback)(function (details) {
|
|
109
|
+
var addressComponent = details === null || details === void 0 ? void 0 : details.address_components;
|
|
110
|
+
var address = {};
|
|
111
|
+
addressComponent === null || addressComponent === void 0 ? void 0 : addressComponent.forEach(function (item) {
|
|
112
|
+
var _a, _b, _c, _d;
|
|
113
|
+
if ((_a = item === null || item === void 0 ? void 0 : item.types) === null || _a === void 0 ? void 0 : _a.includes('locality')) {
|
|
114
|
+
address.city = item === null || item === void 0 ? void 0 : item.long_name;
|
|
115
|
+
}
|
|
116
|
+
if ((_b = item === null || item === void 0 ? void 0 : item.types) === null || _b === void 0 ? void 0 : _b.includes('country')) {
|
|
117
|
+
address.country = item === null || item === void 0 ? void 0 : item.long_name;
|
|
118
|
+
address.countryCode = item === null || item === void 0 ? void 0 : item.short_name;
|
|
119
|
+
}
|
|
120
|
+
if ((_c = item === null || item === void 0 ? void 0 : item.types) === null || _c === void 0 ? void 0 : _c.includes('postal_code')) {
|
|
121
|
+
address.pincode = item === null || item === void 0 ? void 0 : item.long_name;
|
|
122
|
+
}
|
|
123
|
+
if ((_d = item === null || item === void 0 ? void 0 : item.types) === null || _d === void 0 ? void 0 : _d.includes('administrative_area_level_1')) {
|
|
124
|
+
address.state = item === null || item === void 0 ? void 0 : item.long_name;
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
return address;
|
|
128
|
+
}, []);
|
|
129
|
+
var handlePlacePress = (0, react_1.useCallback)(function (data, details) {
|
|
130
|
+
var _a, _b, _c, _d;
|
|
131
|
+
if (props.onChangeText) {
|
|
132
|
+
var addressObj = {
|
|
133
|
+
addresstext: data.description,
|
|
134
|
+
latitude: (_b = (_a = details === null || details === void 0 ? void 0 : details.geometry) === null || _a === void 0 ? void 0 : _a.location) === null || _b === void 0 ? void 0 : _b.lat,
|
|
135
|
+
longitude: (_d = (_c = details === null || details === void 0 ? void 0 : details.geometry) === null || _c === void 0 ? void 0 : _c.location) === null || _d === void 0 ? void 0 : _d.lng,
|
|
136
|
+
location: getAddress(details),
|
|
137
|
+
};
|
|
138
|
+
props.onChangeText(addressObj);
|
|
139
|
+
}
|
|
140
|
+
}, [getAddress, props.onChangeText]);
|
|
141
|
+
if (!GooglePlacesAutocomplete) {
|
|
142
|
+
return (react_1.default.createElement(react_native_1.TextInput, { style: [styles.input, styles.inputContainer, inputStyle, error ? styles.errorBorder : {}], placeholder: "Install react-native-google-places-autocomplete for location search", placeholderTextColor: exports.COLORS.secondary, editable: false }));
|
|
143
|
+
}
|
|
144
|
+
if (!googleApiKey) {
|
|
145
|
+
return (react_1.default.createElement(react_native_1.TextInput, { style: [styles.input, styles.inputContainer, inputStyle, error ? styles.errorBorder : {}], placeholder: "Provide googleApiKey for location search", placeholderTextColor: exports.COLORS.secondary, editable: false }));
|
|
146
|
+
}
|
|
147
|
+
var PlacesComponent = GooglePlacesAutocomplete;
|
|
148
|
+
return (react_1.default.createElement(PlacesComponent, __assign({ placeholder: placeholder, fetchDetails: true, onPress: handlePlacePress, query: {
|
|
149
|
+
key: googleApiKey,
|
|
150
|
+
language: 'en',
|
|
151
|
+
}, textInputProps: {
|
|
152
|
+
placeholderTextColor: exports.COLORS.secondary,
|
|
153
|
+
}, styles: {
|
|
154
|
+
textInput: [
|
|
155
|
+
styles.inputContainer,
|
|
156
|
+
inputStyle,
|
|
157
|
+
error ? styles.errorBorder : {},
|
|
158
|
+
],
|
|
159
|
+
} }, props)));
|
|
160
|
+
};
|
|
161
|
+
function parseDateValue(value) {
|
|
162
|
+
if (value === undefined || value === null || value === '')
|
|
163
|
+
return undefined;
|
|
164
|
+
if (value instanceof Date)
|
|
165
|
+
return value;
|
|
166
|
+
var parsed = new Date(value);
|
|
167
|
+
return isNaN(parsed.getTime()) ? undefined : parsed;
|
|
168
|
+
}
|
|
169
|
+
function formatDateByType(date, type) {
|
|
170
|
+
if (type === 'date')
|
|
171
|
+
return date.toLocaleDateString();
|
|
172
|
+
if (type === 'time')
|
|
173
|
+
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
|
174
|
+
return date.toLocaleString();
|
|
175
|
+
}
|
|
176
|
+
var Input = function (_a) {
|
|
177
|
+
var _b;
|
|
178
|
+
var type = _a.type, leftIcon = _a.leftIcon, rightIcon = _a.rightIcon, label = _a.label, error = _a.error, containerStyle = _a.containerStyle, labelStyle = _a.labelStyle, inputStyle = _a.inputStyle, valueProp = _a.value, props = __rest(_a, ["type", "leftIcon", "rightIcon", "label", "error", "containerStyle", "labelStyle", "inputStyle", "value"]);
|
|
179
|
+
var _c = (0, react_1.useState)(false), isPasswordVisible = _c[0], setIsPasswordVisible = _c[1];
|
|
180
|
+
var initialDate = parseDateValue(valueProp);
|
|
181
|
+
var _d = (0, react_1.useState)(initialDate), date = _d[0], setDate = _d[1];
|
|
182
|
+
var _e = (0, react_1.useState)(false), isDatePickerVisible = _e[0], setIsDatePickerVisible = _e[1];
|
|
183
|
+
var isDateType = type === 'date' || type === 'time' || type === 'datetime';
|
|
184
|
+
var controlledDate = isDateType ? parseDateValue(valueProp) : undefined;
|
|
185
|
+
(0, react_1.useEffect)(function () {
|
|
186
|
+
if (isDateType && controlledDate !== undefined) {
|
|
187
|
+
setDate(controlledDate);
|
|
188
|
+
}
|
|
189
|
+
}, [isDateType, valueProp]);
|
|
190
|
+
var displayDate = (_b = date !== null && date !== void 0 ? date : controlledDate) !== null && _b !== void 0 ? _b : new Date();
|
|
191
|
+
var displayValue = isDateType
|
|
192
|
+
? (date ? formatDateByType(date, type) : valueProp !== null && valueProp !== void 0 ? valueProp : '')
|
|
193
|
+
: valueProp;
|
|
194
|
+
var handleIconPress = function () {
|
|
195
|
+
if (type === 'password') {
|
|
196
|
+
setIsPasswordVisible(!isPasswordVisible);
|
|
197
|
+
}
|
|
198
|
+
else if (isDateType) {
|
|
199
|
+
setIsDatePickerVisible(true);
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
var renderInput = function () {
|
|
203
|
+
switch (type) {
|
|
204
|
+
case 'textarea':
|
|
205
|
+
return (react_1.default.createElement(TextareaInput, __assign({ inputStyle: inputStyle, error: error, value: valueProp }, props)));
|
|
206
|
+
case 'autocomplete':
|
|
207
|
+
return (react_1.default.createElement(AutocompleteInput, __assign({ type: 'text', inputStyle: inputStyle, error: error, googleApiKey: props.googleApiKey }, props)));
|
|
208
|
+
case 'date':
|
|
209
|
+
case 'time':
|
|
210
|
+
case 'datetime':
|
|
211
|
+
if (!DatePicker) {
|
|
212
|
+
return (react_1.default.createElement(react_native_1.TextInput, { style: [styles.input, inputStyle, error ? styles.errorBorder : {}], placeholder: "Install react-native-date-picker for date/time selection", placeholderTextColor: exports.COLORS.secondary, editable: false }));
|
|
213
|
+
}
|
|
214
|
+
return (react_1.default.createElement(TextInputField, __assign({ type: type, value: displayValue, editable: false, inputStyle: inputStyle, error: error }, props)));
|
|
215
|
+
default:
|
|
216
|
+
return (react_1.default.createElement(TextInputField, __assign({ type: type, isPasswordVisible: isPasswordVisible, inputStyle: inputStyle, error: error, value: valueProp }, props)));
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
var renderDatePicker = function () {
|
|
220
|
+
if (!DatePicker || !isDateType || !isDatePickerVisible)
|
|
221
|
+
return null;
|
|
222
|
+
return (react_1.default.createElement(DatePicker, { modal: true, mode: type === 'datetime' ? 'datetime' : type, open: isDatePickerVisible, date: displayDate, onConfirm: function (selectedDate) {
|
|
223
|
+
setIsDatePickerVisible(false);
|
|
224
|
+
setDate(selectedDate);
|
|
225
|
+
if (props.onChangeText) {
|
|
226
|
+
props.onChangeText(selectedDate.toISOString());
|
|
227
|
+
}
|
|
228
|
+
}, onCancel: function () { return setIsDatePickerVisible(false); } }));
|
|
229
|
+
};
|
|
230
|
+
return (react_1.default.createElement(react_native_1.View, { style: [styles.container, containerStyle] },
|
|
231
|
+
label && react_1.default.createElement(react_native_1.Text, { style: [styles.label, labelStyle] }, label),
|
|
232
|
+
react_1.default.createElement(react_native_1.View, { style: [
|
|
233
|
+
type !== 'autocomplete' && styles.inputContainer,
|
|
234
|
+
error ? styles.errorBorder : {},
|
|
235
|
+
] },
|
|
236
|
+
leftIcon && react_1.default.createElement(react_native_1.Image, { source: leftIcon, style: styles.icon }),
|
|
237
|
+
renderInput(),
|
|
238
|
+
rightIcon && (react_1.default.createElement(react_native_1.TouchableOpacity, { onPress: handleIconPress }, rightIcon))),
|
|
239
|
+
error && react_1.default.createElement(react_native_1.Text, { style: styles.errorText }, error),
|
|
240
|
+
renderDatePicker()));
|
|
241
|
+
};
|
|
242
|
+
var styles = react_native_1.StyleSheet.create({
|
|
243
|
+
container: {
|
|
244
|
+
marginVertical: 5,
|
|
245
|
+
},
|
|
246
|
+
label: {
|
|
247
|
+
marginBottom: 4,
|
|
248
|
+
color: exports.COLORS.black,
|
|
249
|
+
fontSize: 16,
|
|
250
|
+
},
|
|
251
|
+
inputContainer: {
|
|
252
|
+
flexDirection: 'row',
|
|
253
|
+
alignItems: 'center',
|
|
254
|
+
borderWidth: 1,
|
|
255
|
+
borderColor: exports.COLORS.secondary,
|
|
256
|
+
borderRadius: 8,
|
|
257
|
+
paddingVertical: 8,
|
|
258
|
+
paddingHorizontal: 12,
|
|
259
|
+
backgroundColor: exports.COLORS.white,
|
|
260
|
+
minHeight: 40,
|
|
261
|
+
},
|
|
262
|
+
input: {
|
|
263
|
+
flex: 1,
|
|
264
|
+
color: exports.COLORS.black,
|
|
265
|
+
padding: 0,
|
|
266
|
+
fontSize: 14,
|
|
267
|
+
},
|
|
268
|
+
textarea: {
|
|
269
|
+
flex: 1,
|
|
270
|
+
color: exports.COLORS.black,
|
|
271
|
+
padding: 0,
|
|
272
|
+
fontSize: 14,
|
|
273
|
+
textAlignVertical: 'top',
|
|
274
|
+
height: 100,
|
|
275
|
+
},
|
|
276
|
+
icon: {
|
|
277
|
+
width: 16,
|
|
278
|
+
height: 16,
|
|
279
|
+
},
|
|
280
|
+
errorBorder: {
|
|
281
|
+
borderColor: exports.COLORS.error,
|
|
282
|
+
},
|
|
283
|
+
errorText: {
|
|
284
|
+
color: exports.COLORS.error,
|
|
285
|
+
fontSize: 12,
|
|
286
|
+
marginTop: 4,
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
exports.default = Input;
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Input, COLORS } from './Input';
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.COLORS = exports.Input = void 0;
|
|
7
|
+
var Input_1 = require("./Input");
|
|
8
|
+
Object.defineProperty(exports, "Input", { enumerable: true, get: function () { return __importDefault(Input_1).default; } });
|
|
9
|
+
Object.defineProperty(exports, "COLORS", { enumerable: true, get: function () { return Input_1.COLORS; } });
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-native-form-controls",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A highly customizable and versatile input component for React Native.",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"types": "lib/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"prepublishOnly": "npm run build"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"lib",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/tarunj116/react-native-smart-input.git"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"react-native",
|
|
21
|
+
"input",
|
|
22
|
+
"component",
|
|
23
|
+
"date-picker",
|
|
24
|
+
"google-places-autocomplete"
|
|
25
|
+
],
|
|
26
|
+
"author": "Tarun Jain",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"react-native": "^0.74.3"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"react-native": ">=0.70.0",
|
|
33
|
+
"react-native-date-picker": "^4.0.0",
|
|
34
|
+
"react-native-google-places-autocomplete": "^2.0.0"
|
|
35
|
+
},
|
|
36
|
+
"peerDependenciesMeta": {
|
|
37
|
+
"react-native-date-picker": {
|
|
38
|
+
"optional": true
|
|
39
|
+
},
|
|
40
|
+
"react-native-google-places-autocomplete": {
|
|
41
|
+
"optional": true
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/react": "^18.3.3",
|
|
46
|
+
"@types/react-native": "^0.73.0",
|
|
47
|
+
"typescript": "^5.5.4"
|
|
48
|
+
}
|
|
49
|
+
}
|