@tamagui/input 2.7.7 → 3.0.0-beta.643.1
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/dist/cjs/Input.cjs +78 -162
- package/dist/cjs/Input.native.cjs +209 -0
- package/dist/cjs/Input.native.js +186 -282
- package/dist/cjs/Input.native.js.map +1 -1
- package/dist/cjs/InputNativeProps.cjs +10 -11
- package/dist/cjs/InputNativeProps.native.cjs +19 -0
- package/dist/cjs/InputNativeProps.native.js +10 -10
- package/dist/cjs/InputNativeProps.native.js.map +1 -1
- package/dist/cjs/TextArea.cjs +25 -38
- package/dist/cjs/TextArea.native.cjs +41 -0
- package/dist/cjs/TextArea.native.js +25 -37
- package/dist/cjs/TextArea.native.js.map +1 -1
- package/dist/cjs/index.cjs +16 -17
- package/dist/cjs/index.native.cjs +33 -0
- package/dist/cjs/index.native.js +16 -16
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/shared.cjs +115 -122
- package/dist/cjs/shared.native.cjs +144 -0
- package/dist/cjs/shared.native.js +120 -126
- package/dist/cjs/shared.native.js.map +1 -1
- package/dist/cjs/types.cjs +10 -11
- package/dist/cjs/types.native.cjs +19 -0
- package/dist/cjs/types.native.js +10 -10
- package/dist/cjs/types.native.js.map +1 -1
- package/dist/esm/Input.mjs +63 -137
- package/dist/esm/Input.mjs.map +1 -1
- package/dist/esm/Input.native.js +172 -259
- package/dist/esm/Input.native.js.map +1 -1
- package/dist/esm/InputNativeProps.mjs +0 -2
- package/dist/esm/InputNativeProps.native.js +0 -2
- package/dist/esm/TextArea.mjs +12 -20
- package/dist/esm/TextArea.mjs.map +1 -1
- package/dist/esm/TextArea.native.js +12 -20
- package/dist/esm/TextArea.native.js.map +1 -1
- package/dist/esm/index.js +6 -4
- package/dist/esm/index.mjs +6 -4
- package/dist/esm/index.native.js +6 -4
- package/dist/esm/shared.mjs +99 -104
- package/dist/esm/shared.mjs.map +1 -1
- package/dist/esm/shared.native.js +104 -109
- package/dist/esm/shared.native.js.map +1 -1
- package/dist/esm/types.mjs +0 -2
- package/dist/esm/types.native.js +0 -2
- package/dist/jsx/Input.mjs +63 -137
- package/dist/jsx/Input.mjs.map +1 -1
- package/dist/jsx/Input.native.cjs +209 -0
- package/dist/jsx/Input.native.js +186 -282
- package/dist/jsx/Input.native.js.map +1 -1
- package/dist/jsx/InputNativeProps.mjs +0 -2
- package/dist/jsx/InputNativeProps.native.cjs +19 -0
- package/dist/jsx/InputNativeProps.native.js +10 -10
- package/dist/jsx/InputNativeProps.native.js.map +1 -1
- package/dist/jsx/TextArea.mjs +12 -20
- package/dist/jsx/TextArea.mjs.map +1 -1
- package/dist/jsx/TextArea.native.cjs +41 -0
- package/dist/jsx/TextArea.native.js +25 -37
- package/dist/jsx/TextArea.native.js.map +1 -1
- package/dist/jsx/index.js +6 -4
- package/dist/jsx/index.mjs +6 -4
- package/dist/jsx/index.native.cjs +33 -0
- package/dist/jsx/index.native.js +16 -16
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/shared.mjs +99 -104
- package/dist/jsx/shared.mjs.map +1 -1
- package/dist/jsx/shared.native.cjs +144 -0
- package/dist/jsx/shared.native.js +120 -126
- package/dist/jsx/shared.native.js.map +1 -1
- package/dist/jsx/types.mjs +0 -2
- package/dist/jsx/types.native.cjs +19 -0
- package/dist/jsx/types.native.js +10 -10
- package/dist/jsx/types.native.js.map +1 -1
- package/package.json +13 -15
- package/src/Input.native.tsx +263 -240
- package/src/Input.tsx +162 -152
- package/src/TextArea.tsx +6 -14
- package/src/shared.tsx +65 -70
- package/src/types.ts +1 -1
- package/types/Input.d.ts +57 -41
- package/types/Input.d.ts.map +1 -1
- package/types/Input.native.d.ts +57 -41
- package/types/Input.native.d.ts.map +1 -1
- package/types/TextArea.d.ts +172 -24
- package/types/TextArea.d.ts.map +1 -1
- package/types/shared.d.ts +14 -99
- package/types/shared.d.ts.map +1 -1
- package/types/types.d.ts +1 -1
- package/dist/cjs/inputTypes.test-d.cjs +0 -128
- package/dist/cjs/inputTypes.test-d.native.js +0 -131
- package/dist/cjs/inputTypes.test-d.native.js.map +0 -1
- package/dist/cjs/v1/Input.cjs +0 -200
- package/dist/cjs/v1/Input.native.js +0 -183
- package/dist/cjs/v1/Input.native.js.map +0 -1
- package/dist/cjs/v1/TextArea.cjs +0 -52
- package/dist/cjs/v1/TextArea.native.js +0 -55
- package/dist/cjs/v1/TextArea.native.js.map +0 -1
- package/dist/cjs/v1/index.cjs +0 -21
- package/dist/cjs/v1/index.native.js +0 -24
- package/dist/cjs/v1/index.native.js.map +0 -1
- package/dist/cjs/v1/types.cjs +0 -18
- package/dist/cjs/v1/types.native.js +0 -21
- package/dist/cjs/v1/types.native.js.map +0 -1
- package/dist/esm/InputNativeProps.mjs.map +0 -1
- package/dist/esm/InputNativeProps.native.js.map +0 -1
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/index.mjs.map +0 -1
- package/dist/esm/index.native.js.map +0 -1
- package/dist/esm/inputTypes.test-d.mjs +0 -129
- package/dist/esm/inputTypes.test-d.mjs.map +0 -1
- package/dist/esm/inputTypes.test-d.native.js +0 -129
- package/dist/esm/inputTypes.test-d.native.js.map +0 -1
- package/dist/esm/types.mjs.map +0 -1
- package/dist/esm/types.native.js.map +0 -1
- package/dist/esm/v1/Input.mjs +0 -164
- package/dist/esm/v1/Input.mjs.map +0 -1
- package/dist/esm/v1/Input.native.js +0 -144
- package/dist/esm/v1/Input.native.js.map +0 -1
- package/dist/esm/v1/TextArea.mjs +0 -27
- package/dist/esm/v1/TextArea.mjs.map +0 -1
- package/dist/esm/v1/TextArea.native.js +0 -27
- package/dist/esm/v1/TextArea.native.js.map +0 -1
- package/dist/esm/v1/index.mjs +0 -3
- package/dist/esm/v1/index.mjs.map +0 -1
- package/dist/esm/v1/index.native.js +0 -3
- package/dist/esm/v1/index.native.js.map +0 -1
- package/dist/esm/v1/types.mjs +0 -2
- package/dist/esm/v1/types.mjs.map +0 -1
- package/dist/esm/v1/types.native.js +0 -2
- package/dist/esm/v1/types.native.js.map +0 -1
- package/dist/jsx/InputNativeProps.mjs.map +0 -1
- package/dist/jsx/index.js.map +0 -1
- package/dist/jsx/index.mjs.map +0 -1
- package/dist/jsx/inputTypes.test-d.mjs +0 -129
- package/dist/jsx/inputTypes.test-d.mjs.map +0 -1
- package/dist/jsx/inputTypes.test-d.native.js +0 -131
- package/dist/jsx/inputTypes.test-d.native.js.map +0 -1
- package/dist/jsx/types.mjs.map +0 -1
- package/dist/jsx/v1/Input.mjs +0 -164
- package/dist/jsx/v1/Input.mjs.map +0 -1
- package/dist/jsx/v1/Input.native.js +0 -183
- package/dist/jsx/v1/Input.native.js.map +0 -1
- package/dist/jsx/v1/TextArea.mjs +0 -27
- package/dist/jsx/v1/TextArea.mjs.map +0 -1
- package/dist/jsx/v1/TextArea.native.js +0 -55
- package/dist/jsx/v1/TextArea.native.js.map +0 -1
- package/dist/jsx/v1/index.mjs +0 -3
- package/dist/jsx/v1/index.mjs.map +0 -1
- package/dist/jsx/v1/index.native.js +0 -24
- package/dist/jsx/v1/index.native.js.map +0 -1
- package/dist/jsx/v1/types.mjs +0 -2
- package/dist/jsx/v1/types.mjs.map +0 -1
- package/dist/jsx/v1/types.native.js +0 -21
- package/dist/jsx/v1/types.native.js.map +0 -1
- package/src/inputTypes.test-d.ts +0 -245
- package/src/v1/Input.native.tsx +0 -153
- package/src/v1/Input.tsx +0 -190
- package/src/v1/TextArea.tsx +0 -35
- package/src/v1/index.ts +0 -3
- package/src/v1/types.ts +0 -65
- package/types/v1/Input.d.ts +0 -64
- package/types/v1/Input.d.ts.map +0 -1
- package/types/v1/Input.native.d.ts +0 -63
- package/types/v1/Input.native.d.ts.map +0 -1
- package/types/v1/TextArea.d.ts +0 -41
- package/types/v1/TextArea.d.ts.map +0 -1
- package/types/v1/index.d.ts +0 -4
- package/types/v1/index.d.ts.map +0 -1
- package/types/v1/types.d.ts +0 -39
- package/types/v1/types.d.ts.map +0 -1
package/src/inputTypes.test-d.ts
DELETED
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Type tests for Input component.
|
|
3
|
-
*
|
|
4
|
-
* Verifies that:
|
|
5
|
-
* 1. Event handlers are typed with HTMLInputElement (not HTMLDivElement)
|
|
6
|
-
* 2. HTML input-specific props are available (type, placeholder, etc.)
|
|
7
|
-
* 3. Tamagui style props and variants still work
|
|
8
|
-
* 4. Cross-platform props (autoCorrect, autoCapitalize) are present
|
|
9
|
-
* 5. InputRef includes both HTMLInputElement and TextInput
|
|
10
|
-
*
|
|
11
|
-
* Run with: npx vitest typecheck --run
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import { expectTypeOf, describe, test } from 'vitest'
|
|
15
|
-
import type { GetProps } from '@tamagui/web'
|
|
16
|
-
import type { TextInput } from 'react-native'
|
|
17
|
-
import {
|
|
18
|
-
Input,
|
|
19
|
-
type InputProps,
|
|
20
|
-
type InputRef,
|
|
21
|
-
TextArea,
|
|
22
|
-
type TextAreaProps,
|
|
23
|
-
} from './index'
|
|
24
|
-
|
|
25
|
-
// helper: extract event param type
|
|
26
|
-
type EventParam<T> = T extends (event: infer E) => any ? E : never
|
|
27
|
-
type IsAssignable<T, U> = T extends U ? true : false
|
|
28
|
-
|
|
29
|
-
// =============================================================================
|
|
30
|
-
// Test: event handlers are typed with HTMLInputElement
|
|
31
|
-
// =============================================================================
|
|
32
|
-
|
|
33
|
-
describe('Input event handler types', () => {
|
|
34
|
-
test('onChange event uses HTMLInputElement', () => {
|
|
35
|
-
type OnChange = NonNullable<InputProps['onChange']>
|
|
36
|
-
type Event = EventParam<OnChange>
|
|
37
|
-
expectTypeOf<Event['currentTarget']>().toMatchTypeOf<HTMLInputElement>()
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
test('onFocus event uses HTMLInputElement', () => {
|
|
41
|
-
type OnFocus = NonNullable<InputProps['onFocus']>
|
|
42
|
-
type Event = EventParam<OnFocus>
|
|
43
|
-
expectTypeOf<Event['currentTarget']>().toMatchTypeOf<HTMLInputElement>()
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
test('onBlur event uses HTMLInputElement', () => {
|
|
47
|
-
type OnBlur = NonNullable<InputProps['onBlur']>
|
|
48
|
-
type Event = EventParam<OnBlur>
|
|
49
|
-
expectTypeOf<Event['currentTarget']>().toMatchTypeOf<HTMLInputElement>()
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
test('onKeyDown event uses HTMLInputElement', () => {
|
|
53
|
-
type OnKeyDown = NonNullable<InputProps['onKeyDown']>
|
|
54
|
-
type Event = EventParam<OnKeyDown>
|
|
55
|
-
expectTypeOf<Event['currentTarget']>().toMatchTypeOf<HTMLInputElement>()
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
test('onClick event uses HTMLInputElement', () => {
|
|
59
|
-
type OnClick = NonNullable<InputProps['onClick']>
|
|
60
|
-
type Event = EventParam<OnClick>
|
|
61
|
-
expectTypeOf<Event['currentTarget']>().toMatchTypeOf<HTMLInputElement>()
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
test('onChange event is NOT typed with HTMLDivElement', () => {
|
|
65
|
-
type OnChange = NonNullable<InputProps['onChange']>
|
|
66
|
-
type Event = EventParam<OnChange>
|
|
67
|
-
// HTMLDivElement should NOT be assignable to the currentTarget
|
|
68
|
-
type DivMatchesCurrentTarget = IsAssignable<HTMLDivElement, Event['currentTarget']>
|
|
69
|
-
expectTypeOf<DivMatchesCurrentTarget>().toEqualTypeOf<false>()
|
|
70
|
-
})
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
// =============================================================================
|
|
74
|
-
// Test: HTML input-specific props
|
|
75
|
-
// =============================================================================
|
|
76
|
-
|
|
77
|
-
describe('Input HTML props', () => {
|
|
78
|
-
test('accepts type prop', () => {
|
|
79
|
-
expectTypeOf<InputProps>().toHaveProperty('type')
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
test('accepts placeholder prop', () => {
|
|
83
|
-
expectTypeOf<InputProps>().toHaveProperty('placeholder')
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
test('accepts value prop', () => {
|
|
87
|
-
expectTypeOf<InputProps>().toHaveProperty('value')
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
test('accepts defaultValue prop', () => {
|
|
91
|
-
expectTypeOf<InputProps>().toHaveProperty('defaultValue')
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
test('accepts maxLength prop', () => {
|
|
95
|
-
expectTypeOf<InputProps>().toHaveProperty('maxLength')
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
test('accepts pattern prop', () => {
|
|
99
|
-
expectTypeOf<InputProps>().toHaveProperty('pattern')
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
test('accepts required prop', () => {
|
|
103
|
-
expectTypeOf<InputProps>().toHaveProperty('required')
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
test('accepts readOnly prop', () => {
|
|
107
|
-
expectTypeOf<InputProps>().toHaveProperty('readOnly')
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
test('accepts autoComplete prop', () => {
|
|
111
|
-
expectTypeOf<InputProps>().toHaveProperty('autoComplete')
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
test('accepts name prop', () => {
|
|
115
|
-
expectTypeOf<InputProps>().toHaveProperty('name')
|
|
116
|
-
})
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
// =============================================================================
|
|
120
|
-
// Test: Tamagui style props still work
|
|
121
|
-
// =============================================================================
|
|
122
|
-
|
|
123
|
-
describe('Input style props', () => {
|
|
124
|
-
test('accepts padding style prop', () => {
|
|
125
|
-
expectTypeOf<InputProps>().toHaveProperty('padding')
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
test('accepts backgroundColor style prop', () => {
|
|
129
|
-
expectTypeOf<InputProps>().toHaveProperty('backgroundColor')
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
test('accepts borderRadius style prop', () => {
|
|
133
|
-
expectTypeOf<InputProps>().toHaveProperty('borderRadius')
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
test('accepts text style props', () => {
|
|
137
|
-
expectTypeOf<InputProps>().toHaveProperty('fontSize')
|
|
138
|
-
expectTypeOf<InputProps>().toHaveProperty('fontWeight')
|
|
139
|
-
expectTypeOf<InputProps>().toHaveProperty('color')
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
// textAlign must be a real base style prop so the `text` shorthand (text ->
|
|
143
|
-
// textAlign) can resolve to it. the shorthand itself is config-dependent, so
|
|
144
|
-
// it's exercised in kitchen-sink (InputTextShorthandType) where a config with
|
|
145
|
-
// the v4/v5 shorthands is registered.
|
|
146
|
-
test('accepts textAlign longhand', () => {
|
|
147
|
-
expectTypeOf<'center'>().toMatchTypeOf<NonNullable<InputProps['textAlign']>>()
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
test('accepts size variant', () => {
|
|
151
|
-
expectTypeOf<InputProps>().toHaveProperty('size')
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
test('accepts unstyled variant', () => {
|
|
155
|
-
expectTypeOf<InputProps>().toHaveProperty('unstyled')
|
|
156
|
-
})
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
// =============================================================================
|
|
160
|
-
// Test: cross-platform props
|
|
161
|
-
// =============================================================================
|
|
162
|
-
|
|
163
|
-
describe('Input cross-platform props', () => {
|
|
164
|
-
test('autoCorrect accepts boolean and string', () => {
|
|
165
|
-
expectTypeOf<InputProps['autoCorrect']>().toMatchTypeOf<
|
|
166
|
-
boolean | 'on' | 'off' | undefined
|
|
167
|
-
>()
|
|
168
|
-
})
|
|
169
|
-
|
|
170
|
-
test('autoCapitalize accepts native and web values', () => {
|
|
171
|
-
expectTypeOf<InputProps['autoCapitalize']>().toMatchTypeOf<
|
|
172
|
-
'none' | 'sentences' | 'words' | 'characters' | 'off' | 'on' | undefined
|
|
173
|
-
>()
|
|
174
|
-
})
|
|
175
|
-
|
|
176
|
-
test('accepts onChangeText callback', () => {
|
|
177
|
-
expectTypeOf<InputProps>().toHaveProperty('onChangeText')
|
|
178
|
-
expectTypeOf<NonNullable<InputProps['onChangeText']>>().toMatchTypeOf<
|
|
179
|
-
(text: string) => void
|
|
180
|
-
>()
|
|
181
|
-
})
|
|
182
|
-
|
|
183
|
-
test('accepts onSubmitEditing callback', () => {
|
|
184
|
-
expectTypeOf<InputProps>().toHaveProperty('onSubmitEditing')
|
|
185
|
-
})
|
|
186
|
-
|
|
187
|
-
test('accepts placeholderTextColor', () => {
|
|
188
|
-
expectTypeOf<InputProps>().toHaveProperty('placeholderTextColor')
|
|
189
|
-
})
|
|
190
|
-
|
|
191
|
-
test('accepts selection prop', () => {
|
|
192
|
-
expectTypeOf<InputProps>().toHaveProperty('selection')
|
|
193
|
-
})
|
|
194
|
-
})
|
|
195
|
-
|
|
196
|
-
// =============================================================================
|
|
197
|
-
// Test: InputRef type
|
|
198
|
-
// =============================================================================
|
|
199
|
-
|
|
200
|
-
describe('InputRef type', () => {
|
|
201
|
-
test('InputRef accepts TextInput', () => {
|
|
202
|
-
const _ref: InputRef = {} as TextInput
|
|
203
|
-
})
|
|
204
|
-
|
|
205
|
-
test('InputRef rejects plain HTMLDivElement', () => {
|
|
206
|
-
// @ts-expect-error - HTMLDivElement should not be assignable to InputRef
|
|
207
|
-
const _ref: InputRef = {} as HTMLDivElement
|
|
208
|
-
})
|
|
209
|
-
})
|
|
210
|
-
|
|
211
|
-
// =============================================================================
|
|
212
|
-
// Test: TextArea types
|
|
213
|
-
// =============================================================================
|
|
214
|
-
|
|
215
|
-
describe('TextArea types', () => {
|
|
216
|
-
test('TextArea has rows prop', () => {
|
|
217
|
-
expectTypeOf<TextAreaProps>().toHaveProperty('rows')
|
|
218
|
-
})
|
|
219
|
-
|
|
220
|
-
test('TextArea accepts style props', () => {
|
|
221
|
-
expectTypeOf<TextAreaProps>().toHaveProperty('padding')
|
|
222
|
-
expectTypeOf<TextAreaProps>().toHaveProperty('fontSize')
|
|
223
|
-
})
|
|
224
|
-
|
|
225
|
-
test('TextArea accepts HTML input props', () => {
|
|
226
|
-
expectTypeOf<TextAreaProps>().toHaveProperty('placeholder')
|
|
227
|
-
expectTypeOf<TextAreaProps>().toHaveProperty('value')
|
|
228
|
-
})
|
|
229
|
-
})
|
|
230
|
-
|
|
231
|
-
// =============================================================================
|
|
232
|
-
// Test: InputProps derived from GetProps (not manually defined)
|
|
233
|
-
// =============================================================================
|
|
234
|
-
|
|
235
|
-
describe('InputProps derivation', () => {
|
|
236
|
-
test('InputProps equals GetProps<typeof Input>', () => {
|
|
237
|
-
type Derived = GetProps<typeof Input>
|
|
238
|
-
expectTypeOf<InputProps>().toEqualTypeOf<Derived>()
|
|
239
|
-
})
|
|
240
|
-
|
|
241
|
-
test('TextAreaProps equals GetProps<typeof TextArea>', () => {
|
|
242
|
-
type Derived = GetProps<typeof TextArea>
|
|
243
|
-
expectTypeOf<TextAreaProps>().toEqualTypeOf<Derived>()
|
|
244
|
-
})
|
|
245
|
-
})
|
package/src/v1/Input.native.tsx
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { styled } from '@tamagui/core'
|
|
3
|
-
import { registerFocusable } from '@tamagui/focusable'
|
|
4
|
-
import { useNativeInputRef } from '@tamagui/element'
|
|
5
|
-
|
|
6
|
-
import type { NativeSyntheticEvent, TextInputChangeEventData } from 'react-native'
|
|
7
|
-
import { TextInput } from 'react-native'
|
|
8
|
-
import { styledBody } from '../shared'
|
|
9
|
-
import type { InputProps } from './types'
|
|
10
|
-
|
|
11
|
-
const StyledInput = styled(TextInput, styledBody[0], styledBody[1])
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @deprecated Use the new Input from '@tamagui/input' instead
|
|
15
|
-
*/
|
|
16
|
-
export const Input = StyledInput.styleable<InputProps>((inProps, forwardedRef) => {
|
|
17
|
-
const {
|
|
18
|
-
// some of destructed props are just to avoid passing them to ...rest because they are not in native.
|
|
19
|
-
type,
|
|
20
|
-
//@ts-ignore
|
|
21
|
-
dirname,
|
|
22
|
-
max,
|
|
23
|
-
min,
|
|
24
|
-
minLength,
|
|
25
|
-
multiple,
|
|
26
|
-
name,
|
|
27
|
-
required,
|
|
28
|
-
step,
|
|
29
|
-
disabled,
|
|
30
|
-
id,
|
|
31
|
-
// @ts-ignore
|
|
32
|
-
caretColor,
|
|
33
|
-
onChange,
|
|
34
|
-
onInput,
|
|
35
|
-
rows,
|
|
36
|
-
enterKeyHint,
|
|
37
|
-
returnKeyType,
|
|
38
|
-
onKeyDown,
|
|
39
|
-
inputMode,
|
|
40
|
-
render,
|
|
41
|
-
...rest
|
|
42
|
-
} = inProps
|
|
43
|
-
|
|
44
|
-
const { ref, composedRef } = useNativeInputRef(forwardedRef)
|
|
45
|
-
|
|
46
|
-
// TODO: later move most of the logic to the core package
|
|
47
|
-
|
|
48
|
-
let secureTextEntry = false
|
|
49
|
-
let cursorColor = caretColor
|
|
50
|
-
let _returnKeyType = returnKeyType
|
|
51
|
-
let _enterKeyHint = enterKeyHint
|
|
52
|
-
if (enterKeyHint === 'go') {
|
|
53
|
-
_returnKeyType = 'go'
|
|
54
|
-
_enterKeyHint = undefined
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
let _inputMode = inputMode
|
|
58
|
-
if (type === 'email') {
|
|
59
|
-
_inputMode = 'email'
|
|
60
|
-
} else if (type === 'tel') {
|
|
61
|
-
_inputMode = 'tel'
|
|
62
|
-
} else if (type === 'search') {
|
|
63
|
-
_inputMode = 'search'
|
|
64
|
-
} else if (type === 'url') {
|
|
65
|
-
_inputMode = 'url'
|
|
66
|
-
} else if (type === 'password') {
|
|
67
|
-
secureTextEntry = true
|
|
68
|
-
_inputMode = 'text'
|
|
69
|
-
} else if (type === 'number') {
|
|
70
|
-
_inputMode = 'numeric'
|
|
71
|
-
} else {
|
|
72
|
-
_inputMode = 'text'
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
let showSoftInputOnFocus = true
|
|
76
|
-
if (inputMode === 'none') {
|
|
77
|
-
showSoftInputOnFocus = false
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const finalProps = {
|
|
81
|
-
...rest,
|
|
82
|
-
inputMode: _inputMode,
|
|
83
|
-
showSoftInputOnFocus,
|
|
84
|
-
disabled,
|
|
85
|
-
id,
|
|
86
|
-
cursorColor,
|
|
87
|
-
enterKeyHint: _enterKeyHint,
|
|
88
|
-
returnKeyType: _returnKeyType,
|
|
89
|
-
secureTextEntry,
|
|
90
|
-
numberOfLines: rows || rest.numberOfLines,
|
|
91
|
-
} as any
|
|
92
|
-
|
|
93
|
-
if (render === 'textarea') {
|
|
94
|
-
finalProps.multiline = true
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (onKeyDown) {
|
|
98
|
-
finalProps.onKeyPress = (e) => {
|
|
99
|
-
const { key } = e.nativeEvent
|
|
100
|
-
if (
|
|
101
|
-
key === 'Backspace' ||
|
|
102
|
-
(render === 'textarea' && key === 'Enter') ||
|
|
103
|
-
key.length === 1
|
|
104
|
-
) {
|
|
105
|
-
onKeyDown({
|
|
106
|
-
key,
|
|
107
|
-
type: 'keydown',
|
|
108
|
-
} as any)
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
finalProps.onSubmitEditing = (e) => {
|
|
112
|
-
onKeyDown({
|
|
113
|
-
key: 'Enter',
|
|
114
|
-
type: 'keydown',
|
|
115
|
-
} as any)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (onChange || onInput) {
|
|
120
|
-
finalProps.onChange = (e: NativeSyntheticEvent<TextInputChangeEventData>) => {
|
|
121
|
-
const { text } = e.nativeEvent
|
|
122
|
-
if (onChange) {
|
|
123
|
-
onChange({
|
|
124
|
-
target: {
|
|
125
|
-
value: text,
|
|
126
|
-
},
|
|
127
|
-
type: 'change',
|
|
128
|
-
} as any)
|
|
129
|
-
}
|
|
130
|
-
if (onInput != null) {
|
|
131
|
-
onInput({
|
|
132
|
-
target: {
|
|
133
|
-
value: text,
|
|
134
|
-
},
|
|
135
|
-
type: 'input',
|
|
136
|
-
} as any)
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
React.useEffect(() => {
|
|
142
|
-
if (!id) return
|
|
143
|
-
if (disabled) return
|
|
144
|
-
|
|
145
|
-
return registerFocusable(id, {
|
|
146
|
-
focusAndSelect: () => {
|
|
147
|
-
ref.current?.focus()
|
|
148
|
-
},
|
|
149
|
-
focus: () => {},
|
|
150
|
-
})
|
|
151
|
-
}, [id, disabled])
|
|
152
|
-
return <StyledInput onChange={(e) => {}} ref={composedRef} {...finalProps} />
|
|
153
|
-
})
|
package/src/v1/Input.tsx
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
import { View, styled, useEvent, useTheme } from '@tamagui/core'
|
|
2
|
-
import { registerFocusable } from '@tamagui/focusable'
|
|
3
|
-
import { useWebRef } from '@tamagui/element'
|
|
4
|
-
import React, { type HTMLAttributes, type HTMLInputTypeAttribute } from 'react'
|
|
5
|
-
import { styledBody } from '../shared'
|
|
6
|
-
import type { InputProps } from './types'
|
|
7
|
-
|
|
8
|
-
const StyledInput = styled(View, styledBody[0], styledBody[1])
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @deprecated Use the new Input from '@tamagui/input' instead
|
|
12
|
-
* @summary An input is a text field that allows users to enter text.
|
|
13
|
-
* @see — Docs https://tamagui.dev/ui/inputs#input
|
|
14
|
-
*/
|
|
15
|
-
export const Input = StyledInput.styleable<InputProps>((inProps, forwardedRef) => {
|
|
16
|
-
const {
|
|
17
|
-
// some of destructed props are just to avoid passing them to ...rest because they are not in web.
|
|
18
|
-
allowFontScaling,
|
|
19
|
-
selectTextOnFocus,
|
|
20
|
-
showSoftInputOnFocus,
|
|
21
|
-
textContentType,
|
|
22
|
-
passwordRules,
|
|
23
|
-
textBreakStrategy,
|
|
24
|
-
underlineColorAndroid,
|
|
25
|
-
selection,
|
|
26
|
-
lineBreakStrategyIOS,
|
|
27
|
-
returnKeyLabel,
|
|
28
|
-
disabled,
|
|
29
|
-
onSubmitEditing,
|
|
30
|
-
caretHidden,
|
|
31
|
-
clearButtonMode,
|
|
32
|
-
clearTextOnFocus,
|
|
33
|
-
contextMenuHidden,
|
|
34
|
-
dataDetectorTypes,
|
|
35
|
-
id,
|
|
36
|
-
enablesReturnKeyAutomatically,
|
|
37
|
-
importantForAutofill,
|
|
38
|
-
inlineImageLeft,
|
|
39
|
-
inlineImagePadding,
|
|
40
|
-
inputAccessoryViewID,
|
|
41
|
-
keyboardAppearance,
|
|
42
|
-
keyboardType,
|
|
43
|
-
cursorColor,
|
|
44
|
-
disableFullscreenUI,
|
|
45
|
-
editable,
|
|
46
|
-
maxFontSizeMultiplier,
|
|
47
|
-
multiline,
|
|
48
|
-
numberOfLines,
|
|
49
|
-
onChangeText,
|
|
50
|
-
onContentSizeChange,
|
|
51
|
-
onEndEditing,
|
|
52
|
-
onScroll,
|
|
53
|
-
onSelectionChange,
|
|
54
|
-
// @ts-ignore
|
|
55
|
-
caretColor,
|
|
56
|
-
placeholderTextColor,
|
|
57
|
-
blurOnSubmit,
|
|
58
|
-
enterKeyHint,
|
|
59
|
-
returnKeyType,
|
|
60
|
-
rejectResponderTermination,
|
|
61
|
-
scrollEnabled,
|
|
62
|
-
secureTextEntry,
|
|
63
|
-
selectionColor,
|
|
64
|
-
inputMode,
|
|
65
|
-
...rest
|
|
66
|
-
} = inProps
|
|
67
|
-
|
|
68
|
-
const { ref, composedRef } = useWebRef<HTMLInputElement>(forwardedRef)
|
|
69
|
-
const theme = useTheme()
|
|
70
|
-
|
|
71
|
-
const _onSelectionChange = useEvent(() => {
|
|
72
|
-
const start = ref.current?.selectionStart ?? 0
|
|
73
|
-
const end = ref.current?.selectionEnd ?? 0
|
|
74
|
-
onSelectionChange?.({
|
|
75
|
-
nativeEvent: {
|
|
76
|
-
selection: {
|
|
77
|
-
end,
|
|
78
|
-
start,
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
} as any)
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
React.useEffect(() => {
|
|
85
|
-
if (onSelectionChange) {
|
|
86
|
-
ref.current?.addEventListener('selectionchange', _onSelectionChange)
|
|
87
|
-
return () => {
|
|
88
|
-
ref.current?.removeEventListener('selectionchange', _onSelectionChange)
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}, [])
|
|
92
|
-
|
|
93
|
-
React.useEffect(() => {
|
|
94
|
-
if (selection) {
|
|
95
|
-
ref.current?.setSelectionRange(selection.start || null, selection.end || null)
|
|
96
|
-
}
|
|
97
|
-
}, [selection?.start, selection?.end])
|
|
98
|
-
|
|
99
|
-
const finalProps = {
|
|
100
|
-
...rest,
|
|
101
|
-
disabled,
|
|
102
|
-
caretColor,
|
|
103
|
-
id,
|
|
104
|
-
enterKeyHint,
|
|
105
|
-
...(process.env.TAMAGUI_TARGET === 'web'
|
|
106
|
-
? {
|
|
107
|
-
type: (() => {
|
|
108
|
-
if (rest?.type) return rest.type
|
|
109
|
-
if (secureTextEntry) return 'password'
|
|
110
|
-
switch (keyboardType) {
|
|
111
|
-
case 'number-pad':
|
|
112
|
-
case 'numeric':
|
|
113
|
-
return 'number'
|
|
114
|
-
case 'email-address':
|
|
115
|
-
return 'email'
|
|
116
|
-
case 'phone-pad':
|
|
117
|
-
return 'tel'
|
|
118
|
-
case 'url':
|
|
119
|
-
return 'url'
|
|
120
|
-
default:
|
|
121
|
-
return 'text'
|
|
122
|
-
}
|
|
123
|
-
})() satisfies HTMLInputTypeAttribute,
|
|
124
|
-
inputMode: (() => {
|
|
125
|
-
switch (keyboardType) {
|
|
126
|
-
case 'number-pad':
|
|
127
|
-
case 'numeric':
|
|
128
|
-
return 'numeric'
|
|
129
|
-
case 'decimal-pad':
|
|
130
|
-
return 'decimal'
|
|
131
|
-
case 'email-address':
|
|
132
|
-
return 'email'
|
|
133
|
-
case 'phone-pad':
|
|
134
|
-
return 'tel'
|
|
135
|
-
case 'url':
|
|
136
|
-
return 'url'
|
|
137
|
-
default:
|
|
138
|
-
return undefined
|
|
139
|
-
}
|
|
140
|
-
})() satisfies HTMLAttributes<HTMLInputElement>['inputMode'],
|
|
141
|
-
}
|
|
142
|
-
: {
|
|
143
|
-
keyboardType,
|
|
144
|
-
secureTextEntry,
|
|
145
|
-
inputMode,
|
|
146
|
-
}),
|
|
147
|
-
style: {
|
|
148
|
-
...(rest.style as any),
|
|
149
|
-
...(placeholderTextColor && {
|
|
150
|
-
'--t_placeholderColor':
|
|
151
|
-
theme[placeholderTextColor]?.variable || placeholderTextColor,
|
|
152
|
-
}),
|
|
153
|
-
...(selectionColor && {
|
|
154
|
-
'--t_selectionBackground': theme[selectionColor]?.variable || selectionColor,
|
|
155
|
-
}),
|
|
156
|
-
},
|
|
157
|
-
} as any
|
|
158
|
-
|
|
159
|
-
React.useEffect(() => {
|
|
160
|
-
if (!id) return
|
|
161
|
-
if (disabled) return
|
|
162
|
-
|
|
163
|
-
return registerFocusable(id, {
|
|
164
|
-
focusAndSelect: () => {
|
|
165
|
-
ref.current?.focus()
|
|
166
|
-
},
|
|
167
|
-
focus: () => {},
|
|
168
|
-
})
|
|
169
|
-
}, [id, disabled])
|
|
170
|
-
|
|
171
|
-
return (
|
|
172
|
-
<>
|
|
173
|
-
{process.env.TAMAGUI_TARGET === 'web' && (
|
|
174
|
-
<style>
|
|
175
|
-
{`
|
|
176
|
-
input::selection, textarea::selection {
|
|
177
|
-
background-color: var(--t_selectionBackground) !important;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
input::placeholder, textarea::placeholder {
|
|
181
|
-
color: var(--t_placeholderColor) !important;
|
|
182
|
-
}
|
|
183
|
-
`}
|
|
184
|
-
</style>
|
|
185
|
-
)}
|
|
186
|
-
|
|
187
|
-
<StyledInput ref={composedRef} {...finalProps} />
|
|
188
|
-
</>
|
|
189
|
-
)
|
|
190
|
-
})
|
package/src/v1/TextArea.tsx
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { styled } from '@tamagui/web'
|
|
2
|
-
import { Input } from './Input'
|
|
3
|
-
import { defaultStyles, textAreaSizeVariant } from '../shared'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @deprecated Use the new TextArea from '@tamagui/input' instead
|
|
7
|
-
* @summary A text area is a multi-line input field that allows users to enter text.
|
|
8
|
-
* @see — Docs https://tamagui.dev/ui/inputs#textarea
|
|
9
|
-
*/
|
|
10
|
-
export const TextArea = styled(Input, {
|
|
11
|
-
name: 'TextArea',
|
|
12
|
-
render: 'textarea',
|
|
13
|
-
|
|
14
|
-
// this attribute fixes firefox newline issue
|
|
15
|
-
// @ts-ignore
|
|
16
|
-
whiteSpace: 'pre-wrap',
|
|
17
|
-
|
|
18
|
-
variants: {
|
|
19
|
-
unstyled: {
|
|
20
|
-
false: {
|
|
21
|
-
height: 'auto',
|
|
22
|
-
...defaultStyles,
|
|
23
|
-
numberOfLines: 3,
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
|
|
27
|
-
size: {
|
|
28
|
-
'...size': textAreaSizeVariant,
|
|
29
|
-
},
|
|
30
|
-
} as const,
|
|
31
|
-
|
|
32
|
-
defaultVariants: {
|
|
33
|
-
unstyled: process.env.TAMAGUI_HEADLESS === '1',
|
|
34
|
-
},
|
|
35
|
-
})
|
package/src/v1/index.ts
DELETED
package/src/v1/types.ts
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ColorTokens,
|
|
3
|
-
ViewProps,
|
|
4
|
-
TamaguiComponentPropsBase,
|
|
5
|
-
TextProps,
|
|
6
|
-
} from '@tamagui/web'
|
|
7
|
-
import type { TextInputProps, InputModeOptions } from 'react-native'
|
|
8
|
-
|
|
9
|
-
type DetailedInputProps = React.DetailedHTMLProps<
|
|
10
|
-
React.HTMLProps<HTMLInputElement>,
|
|
11
|
-
HTMLInputElement
|
|
12
|
-
>
|
|
13
|
-
|
|
14
|
-
export type InputProps = ViewProps &
|
|
15
|
-
Omit<
|
|
16
|
-
DetailedInputProps,
|
|
17
|
-
'className' | 'children' | 'value' | 'size' | keyof ViewProps
|
|
18
|
-
> &
|
|
19
|
-
Pick<TextProps, 'color'> &
|
|
20
|
-
Omit<DetailedInputProps['style'], 'color'> &
|
|
21
|
-
Omit<
|
|
22
|
-
TextInputProps,
|
|
23
|
-
| 'inputMode'
|
|
24
|
-
| 'secureTextEntry'
|
|
25
|
-
| 'onChangeText'
|
|
26
|
-
| 'editable'
|
|
27
|
-
| 'enterKeyHint'
|
|
28
|
-
| 'keyboardType'
|
|
29
|
-
| 'placeholderTextColor'
|
|
30
|
-
| 'selectionColor'
|
|
31
|
-
| 'numberOfLines'
|
|
32
|
-
> & {
|
|
33
|
-
/**
|
|
34
|
-
* @deprecated - use `type="password"` instead
|
|
35
|
-
*/
|
|
36
|
-
secureTextEntry?: TextInputProps['secureTextEntry']
|
|
37
|
-
/**
|
|
38
|
-
* @deprecated - use `onChange` instead
|
|
39
|
-
*/
|
|
40
|
-
onChangeText?: TextInputProps['onChangeText']
|
|
41
|
-
/**
|
|
42
|
-
* @deprecated - use `readOnly` instead
|
|
43
|
-
*/
|
|
44
|
-
editable?: TextInputProps['editable']
|
|
45
|
-
enterKeyHint?: 'done' | 'go' | 'next' | 'search' | 'send' | 'enter' | 'previous'
|
|
46
|
-
/**
|
|
47
|
-
* @deprecated - use `type` instead
|
|
48
|
-
*/
|
|
49
|
-
keyboardType?: TextInputProps['keyboardType']
|
|
50
|
-
/**
|
|
51
|
-
* use `type` instead of inputMode for most cases, use `inputMode="none"` to disable the soft keyboard
|
|
52
|
-
*/
|
|
53
|
-
inputMode?: InputModeOptions
|
|
54
|
-
placeholderTextColor?: ColorTokens
|
|
55
|
-
selectionColor?: ColorTokens
|
|
56
|
-
render?: TamaguiComponentPropsBase['render']
|
|
57
|
-
/**
|
|
58
|
-
* @deprecated - use `render='textarea'` instead
|
|
59
|
-
*/
|
|
60
|
-
multiline?: boolean
|
|
61
|
-
/**
|
|
62
|
-
* @deprecated - use `rows` instead
|
|
63
|
-
*/
|
|
64
|
-
numberOfLines?: number
|
|
65
|
-
}
|