rn-inputforge 0.3.0 → 0.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.
Files changed (196) hide show
  1. package/README.md +224 -19
  2. package/lib/commonjs/components/FieldFlowCheckbox/FieldFlowCheckbox.js +131 -0
  3. package/lib/commonjs/components/FieldFlowCheckbox/FieldFlowCheckbox.js.map +1 -0
  4. package/lib/commonjs/components/FieldFlowCheckbox/index.js +13 -0
  5. package/lib/commonjs/components/FieldFlowCheckbox/index.js.map +1 -0
  6. package/lib/commonjs/components/FieldFlowDateTimePicker/FieldFlowDateTimePicker.js +536 -0
  7. package/lib/commonjs/components/FieldFlowDateTimePicker/FieldFlowDateTimePicker.js.map +1 -0
  8. package/lib/commonjs/components/FieldFlowDateTimePicker/index.js +13 -0
  9. package/lib/commonjs/components/FieldFlowDateTimePicker/index.js.map +1 -0
  10. package/lib/commonjs/components/FieldFlowDateTimePicker/types.js +6 -0
  11. package/lib/commonjs/components/FieldFlowDateTimePicker/types.js.map +1 -0
  12. package/lib/commonjs/components/FieldFlowDropdown/FieldFlowDropdown.js +24 -9
  13. package/lib/commonjs/components/FieldFlowDropdown/FieldFlowDropdown.js.map +1 -1
  14. package/lib/commonjs/components/FieldFlowInput/FieldFlowInput.js +55 -24
  15. package/lib/commonjs/components/FieldFlowInput/FieldFlowInput.js.map +1 -1
  16. package/lib/commonjs/components/FieldFlowInput/styles.js +32 -11
  17. package/lib/commonjs/components/FieldFlowInput/styles.js.map +1 -1
  18. package/lib/commonjs/components/FieldFlowMaskedInput/FieldFlowMaskedInput.js +66 -0
  19. package/lib/commonjs/components/FieldFlowMaskedInput/FieldFlowMaskedInput.js.map +1 -0
  20. package/lib/commonjs/components/FieldFlowMaskedInput/index.js +13 -0
  21. package/lib/commonjs/components/FieldFlowMaskedInput/index.js.map +1 -0
  22. package/lib/commonjs/components/FieldFlowMaskedInput/types.js +6 -0
  23. package/lib/commonjs/components/FieldFlowMaskedInput/types.js.map +1 -0
  24. package/lib/commonjs/components/FieldFlowOTP/FieldFlowOTP.js +255 -0
  25. package/lib/commonjs/components/FieldFlowOTP/FieldFlowOTP.js.map +1 -0
  26. package/lib/commonjs/components/FieldFlowOTP/index.js +13 -0
  27. package/lib/commonjs/components/FieldFlowOTP/index.js.map +1 -0
  28. package/lib/commonjs/components/FieldFlowOTP/types.js +6 -0
  29. package/lib/commonjs/components/FieldFlowOTP/types.js.map +1 -0
  30. package/lib/commonjs/components/FieldFlowRadio/FieldFlowRadio.js +164 -0
  31. package/lib/commonjs/components/FieldFlowRadio/FieldFlowRadio.js.map +1 -0
  32. package/lib/commonjs/components/FieldFlowRadio/index.js +13 -0
  33. package/lib/commonjs/components/FieldFlowRadio/index.js.map +1 -0
  34. package/lib/commonjs/components/FieldFlowSwitch/FieldFlowSwitch.js +152 -0
  35. package/lib/commonjs/components/FieldFlowSwitch/FieldFlowSwitch.js.map +1 -0
  36. package/lib/commonjs/components/FieldFlowSwitch/index.js +13 -0
  37. package/lib/commonjs/components/FieldFlowSwitch/index.js.map +1 -0
  38. package/lib/commonjs/hooks/index.js.map +1 -1
  39. package/lib/commonjs/hooks/useFieldFlowForm.js +146 -31
  40. package/lib/commonjs/hooks/useFieldFlowForm.js.map +1 -1
  41. package/lib/commonjs/icons/Icon.js +719 -30
  42. package/lib/commonjs/icons/Icon.js.map +1 -1
  43. package/lib/commonjs/icons/index.js +7 -0
  44. package/lib/commonjs/icons/index.js.map +1 -1
  45. package/lib/commonjs/icons/renderIcon.js +24 -0
  46. package/lib/commonjs/icons/renderIcon.js.map +1 -0
  47. package/lib/commonjs/index.js +127 -0
  48. package/lib/commonjs/index.js.map +1 -1
  49. package/lib/commonjs/utils/masks.js +130 -0
  50. package/lib/commonjs/utils/masks.js.map +1 -0
  51. package/lib/commonjs/validation/index.js +25 -0
  52. package/lib/commonjs/validation/index.js.map +1 -1
  53. package/lib/commonjs/validation/zodAdapter.js +91 -0
  54. package/lib/commonjs/validation/zodAdapter.js.map +1 -0
  55. package/lib/module/components/FieldFlowCheckbox/FieldFlowCheckbox.js +126 -0
  56. package/lib/module/components/FieldFlowCheckbox/FieldFlowCheckbox.js.map +1 -0
  57. package/lib/module/components/FieldFlowCheckbox/index.js +4 -0
  58. package/lib/module/components/FieldFlowCheckbox/index.js.map +1 -0
  59. package/lib/module/components/FieldFlowDateTimePicker/FieldFlowDateTimePicker.js +531 -0
  60. package/lib/module/components/FieldFlowDateTimePicker/FieldFlowDateTimePicker.js.map +1 -0
  61. package/lib/module/components/FieldFlowDateTimePicker/index.js +4 -0
  62. package/lib/module/components/FieldFlowDateTimePicker/index.js.map +1 -0
  63. package/lib/module/components/FieldFlowDateTimePicker/types.js +4 -0
  64. package/lib/module/components/FieldFlowDateTimePicker/types.js.map +1 -0
  65. package/lib/module/components/FieldFlowDropdown/FieldFlowDropdown.js +24 -9
  66. package/lib/module/components/FieldFlowDropdown/FieldFlowDropdown.js.map +1 -1
  67. package/lib/module/components/FieldFlowInput/FieldFlowInput.js +59 -28
  68. package/lib/module/components/FieldFlowInput/FieldFlowInput.js.map +1 -1
  69. package/lib/module/components/FieldFlowInput/styles.js +32 -11
  70. package/lib/module/components/FieldFlowInput/styles.js.map +1 -1
  71. package/lib/module/components/FieldFlowMaskedInput/FieldFlowMaskedInput.js +61 -0
  72. package/lib/module/components/FieldFlowMaskedInput/FieldFlowMaskedInput.js.map +1 -0
  73. package/lib/module/components/FieldFlowMaskedInput/index.js +4 -0
  74. package/lib/module/components/FieldFlowMaskedInput/index.js.map +1 -0
  75. package/lib/module/components/FieldFlowMaskedInput/types.js +4 -0
  76. package/lib/module/components/FieldFlowMaskedInput/types.js.map +1 -0
  77. package/lib/module/components/FieldFlowOTP/FieldFlowOTP.js +250 -0
  78. package/lib/module/components/FieldFlowOTP/FieldFlowOTP.js.map +1 -0
  79. package/lib/module/components/FieldFlowOTP/index.js +4 -0
  80. package/lib/module/components/FieldFlowOTP/index.js.map +1 -0
  81. package/lib/module/components/FieldFlowOTP/types.js +4 -0
  82. package/lib/module/components/FieldFlowOTP/types.js.map +1 -0
  83. package/lib/module/components/FieldFlowRadio/FieldFlowRadio.js +159 -0
  84. package/lib/module/components/FieldFlowRadio/FieldFlowRadio.js.map +1 -0
  85. package/lib/module/components/FieldFlowRadio/index.js +4 -0
  86. package/lib/module/components/FieldFlowRadio/index.js.map +1 -0
  87. package/lib/module/components/FieldFlowSwitch/FieldFlowSwitch.js +147 -0
  88. package/lib/module/components/FieldFlowSwitch/FieldFlowSwitch.js.map +1 -0
  89. package/lib/module/components/FieldFlowSwitch/index.js +4 -0
  90. package/lib/module/components/FieldFlowSwitch/index.js.map +1 -0
  91. package/lib/module/hooks/index.js.map +1 -1
  92. package/lib/module/hooks/useFieldFlowForm.js +147 -32
  93. package/lib/module/hooks/useFieldFlowForm.js.map +1 -1
  94. package/lib/module/icons/Icon.js +720 -31
  95. package/lib/module/icons/Icon.js.map +1 -1
  96. package/lib/module/icons/index.js +1 -0
  97. package/lib/module/icons/index.js.map +1 -1
  98. package/lib/module/icons/renderIcon.js +19 -0
  99. package/lib/module/icons/renderIcon.js.map +1 -0
  100. package/lib/module/index.js +11 -3
  101. package/lib/module/index.js.map +1 -1
  102. package/lib/module/utils/masks.js +118 -0
  103. package/lib/module/utils/masks.js.map +1 -0
  104. package/lib/module/validation/index.js +1 -0
  105. package/lib/module/validation/index.js.map +1 -1
  106. package/lib/module/validation/zodAdapter.js +84 -0
  107. package/lib/module/validation/zodAdapter.js.map +1 -0
  108. package/lib/typescript/components/FieldFlowCheckbox/FieldFlowCheckbox.d.ts +36 -0
  109. package/lib/typescript/components/FieldFlowCheckbox/FieldFlowCheckbox.d.ts.map +1 -0
  110. package/lib/typescript/components/FieldFlowCheckbox/index.d.ts +3 -0
  111. package/lib/typescript/components/FieldFlowCheckbox/index.d.ts.map +1 -0
  112. package/lib/typescript/components/FieldFlowDateTimePicker/FieldFlowDateTimePicker.d.ts +4 -0
  113. package/lib/typescript/components/FieldFlowDateTimePicker/FieldFlowDateTimePicker.d.ts.map +1 -0
  114. package/lib/typescript/components/FieldFlowDateTimePicker/index.d.ts +3 -0
  115. package/lib/typescript/components/FieldFlowDateTimePicker/index.d.ts.map +1 -0
  116. package/lib/typescript/components/FieldFlowDateTimePicker/types.d.ts +55 -0
  117. package/lib/typescript/components/FieldFlowDateTimePicker/types.d.ts.map +1 -0
  118. package/lib/typescript/components/FieldFlowDropdown/FieldFlowDropdown.d.ts.map +1 -1
  119. package/lib/typescript/components/FieldFlowDropdown/types.d.ts +7 -1
  120. package/lib/typescript/components/FieldFlowDropdown/types.d.ts.map +1 -1
  121. package/lib/typescript/components/FieldFlowInput/FieldFlowInput.d.ts.map +1 -1
  122. package/lib/typescript/components/FieldFlowInput/styles.d.ts +19 -2
  123. package/lib/typescript/components/FieldFlowInput/styles.d.ts.map +1 -1
  124. package/lib/typescript/components/FieldFlowInput/types.d.ts +24 -5
  125. package/lib/typescript/components/FieldFlowInput/types.d.ts.map +1 -1
  126. package/lib/typescript/components/FieldFlowMaskedInput/FieldFlowMaskedInput.d.ts +5 -0
  127. package/lib/typescript/components/FieldFlowMaskedInput/FieldFlowMaskedInput.d.ts.map +1 -0
  128. package/lib/typescript/components/FieldFlowMaskedInput/index.d.ts +3 -0
  129. package/lib/typescript/components/FieldFlowMaskedInput/index.d.ts.map +1 -0
  130. package/lib/typescript/components/FieldFlowMaskedInput/types.d.ts +20 -0
  131. package/lib/typescript/components/FieldFlowMaskedInput/types.d.ts.map +1 -0
  132. package/lib/typescript/components/FieldFlowOTP/FieldFlowOTP.d.ts +4 -0
  133. package/lib/typescript/components/FieldFlowOTP/FieldFlowOTP.d.ts.map +1 -0
  134. package/lib/typescript/components/FieldFlowOTP/index.d.ts +3 -0
  135. package/lib/typescript/components/FieldFlowOTP/index.d.ts.map +1 -0
  136. package/lib/typescript/components/FieldFlowOTP/types.d.ts +52 -0
  137. package/lib/typescript/components/FieldFlowOTP/types.d.ts.map +1 -0
  138. package/lib/typescript/components/FieldFlowRadio/FieldFlowRadio.d.ts +39 -0
  139. package/lib/typescript/components/FieldFlowRadio/FieldFlowRadio.d.ts.map +1 -0
  140. package/lib/typescript/components/FieldFlowRadio/index.d.ts +3 -0
  141. package/lib/typescript/components/FieldFlowRadio/index.d.ts.map +1 -0
  142. package/lib/typescript/components/FieldFlowSwitch/FieldFlowSwitch.d.ts +31 -0
  143. package/lib/typescript/components/FieldFlowSwitch/FieldFlowSwitch.d.ts.map +1 -0
  144. package/lib/typescript/components/FieldFlowSwitch/index.d.ts +3 -0
  145. package/lib/typescript/components/FieldFlowSwitch/index.d.ts.map +1 -0
  146. package/lib/typescript/hooks/index.d.ts +1 -1
  147. package/lib/typescript/hooks/index.d.ts.map +1 -1
  148. package/lib/typescript/hooks/useFieldFlowForm.d.ts +46 -7
  149. package/lib/typescript/hooks/useFieldFlowForm.d.ts.map +1 -1
  150. package/lib/typescript/icons/Icon.d.ts +2 -2
  151. package/lib/typescript/icons/Icon.d.ts.map +1 -1
  152. package/lib/typescript/icons/index.d.ts +2 -0
  153. package/lib/typescript/icons/index.d.ts.map +1 -1
  154. package/lib/typescript/icons/renderIcon.d.ts +6 -0
  155. package/lib/typescript/icons/renderIcon.d.ts.map +1 -0
  156. package/lib/typescript/index.d.ts +20 -6
  157. package/lib/typescript/index.d.ts.map +1 -1
  158. package/lib/typescript/types/index.d.ts +4 -0
  159. package/lib/typescript/types/index.d.ts.map +1 -1
  160. package/lib/typescript/utils/masks.d.ts +37 -0
  161. package/lib/typescript/utils/masks.d.ts.map +1 -0
  162. package/lib/typescript/validation/index.d.ts +2 -0
  163. package/lib/typescript/validation/index.d.ts.map +1 -1
  164. package/lib/typescript/validation/zodAdapter.d.ts +53 -0
  165. package/lib/typescript/validation/zodAdapter.d.ts.map +1 -0
  166. package/package.json +27 -5
  167. package/src/components/FieldFlowCheckbox/FieldFlowCheckbox.tsx +174 -0
  168. package/src/components/FieldFlowCheckbox/index.ts +2 -0
  169. package/src/components/FieldFlowDateTimePicker/FieldFlowDateTimePicker.tsx +585 -0
  170. package/src/components/FieldFlowDateTimePicker/index.ts +2 -0
  171. package/src/components/FieldFlowDateTimePicker/types.ts +57 -0
  172. package/src/components/FieldFlowDropdown/FieldFlowDropdown.tsx +17 -7
  173. package/src/components/FieldFlowDropdown/types.ts +8 -1
  174. package/src/components/FieldFlowInput/FieldFlowInput.tsx +69 -26
  175. package/src/components/FieldFlowInput/styles.ts +41 -6
  176. package/src/components/FieldFlowInput/types.ts +24 -5
  177. package/src/components/FieldFlowMaskedInput/FieldFlowMaskedInput.tsx +76 -0
  178. package/src/components/FieldFlowMaskedInput/index.ts +2 -0
  179. package/src/components/FieldFlowMaskedInput/types.ts +22 -0
  180. package/src/components/FieldFlowOTP/FieldFlowOTP.tsx +305 -0
  181. package/src/components/FieldFlowOTP/index.ts +2 -0
  182. package/src/components/FieldFlowOTP/types.ts +57 -0
  183. package/src/components/FieldFlowRadio/FieldFlowRadio.tsx +215 -0
  184. package/src/components/FieldFlowRadio/index.ts +2 -0
  185. package/src/components/FieldFlowSwitch/FieldFlowSwitch.tsx +172 -0
  186. package/src/components/FieldFlowSwitch/index.ts +2 -0
  187. package/src/hooks/index.ts +3 -0
  188. package/src/hooks/useFieldFlowForm.ts +209 -33
  189. package/src/icons/Icon.tsx +451 -5
  190. package/src/icons/index.ts +2 -0
  191. package/src/icons/renderIcon.tsx +17 -0
  192. package/src/index.ts +47 -4
  193. package/src/types/index.ts +5 -0
  194. package/src/utils/masks.ts +137 -0
  195. package/src/validation/index.ts +7 -0
  196. package/src/validation/zodAdapter.ts +103 -0
@@ -15,6 +15,37 @@ export type FieldFlowIconName =
15
15
  | 'mic'
16
16
  | 'mapPin'
17
17
  | 'chevronDown'
18
+ | 'chevronUp'
19
+ | 'chevronLeft'
20
+ | 'chevronRight'
21
+ | 'calendar'
22
+ | 'clock'
23
+ | 'creditCard'
24
+ | 'currency'
25
+ | 'phone'
26
+ | 'mail'
27
+ | 'lock'
28
+ | 'user'
29
+ | 'key'
30
+ | 'hash'
31
+ | 'otp'
32
+ | 'radio'
33
+ | 'radioFilled'
34
+ | 'switch'
35
+ | 'star'
36
+ | 'plus'
37
+ | 'minus'
38
+ | 'info'
39
+ | 'home'
40
+ | 'settings'
41
+ | 'edit'
42
+ | 'trash'
43
+ | 'link'
44
+ | 'globe'
45
+ | 'file'
46
+ | 'folder'
47
+ | 'bell'
48
+ | 'heart'
18
49
  | 'spinner';
19
50
 
20
51
  export interface FieldFlowIconProps {
@@ -28,7 +59,7 @@ export interface FieldFlowIconProps {
28
59
  * A minimal, dependency-free icon set built out of basic Views. Ships so consumers
29
60
  * don't need to install react-native-svg / vector-icons just to use FieldFlow.
30
61
  * Every icon accepts `size` and `color`, and you can always render your own
31
- * icon via the `leftIcon` / `rightIcon` props on any FieldFlow component instead.
62
+ * icon via the `leftIcon` / `rightIcon` (or component-specific icon) props.
32
63
  */
33
64
  export function FieldFlowIcon({ name, size = 18, color = '#6B7280', style }: FieldFlowIconProps) {
34
65
  if (name === 'spinner') {
@@ -127,6 +158,7 @@ export function FieldFlowIcon({ name, size = 18, color = '#6B7280', style }: Fie
127
158
  </View>
128
159
  );
129
160
  case 'alert':
161
+ case 'info':
130
162
  return (
131
163
  <View style={[box, style]}>
132
164
  <View
@@ -140,8 +172,17 @@ export function FieldFlowIcon({ name, size = 18, color = '#6B7280', style }: Fie
140
172
  justifyContent: 'center',
141
173
  }}
142
174
  >
143
- <View style={{ width: stroke, height: size * 0.32, backgroundColor: color, borderRadius: stroke, marginBottom: size * 0.08 }} />
144
- <View style={{ width: stroke, height: stroke, borderRadius: stroke / 2, backgroundColor: color }} />
175
+ {name === 'info' ? (
176
+ <>
177
+ <View style={{ width: stroke, height: stroke, borderRadius: stroke / 2, backgroundColor: color, marginBottom: size * 0.08 }} />
178
+ <View style={{ width: stroke, height: size * 0.32, backgroundColor: color, borderRadius: stroke }} />
179
+ </>
180
+ ) : (
181
+ <>
182
+ <View style={{ width: stroke, height: size * 0.32, backgroundColor: color, borderRadius: stroke, marginBottom: size * 0.08 }} />
183
+ <View style={{ width: stroke, height: stroke, borderRadius: stroke / 2, backgroundColor: color }} />
184
+ </>
185
+ )}
145
186
  </View>
146
187
  </View>
147
188
  );
@@ -187,7 +228,6 @@ export function FieldFlowIcon({ name, size = 18, color = '#6B7280', style }: Fie
187
228
  borderTopColor: 'transparent',
188
229
  borderBottomColor: 'transparent',
189
230
  borderLeftColor: color,
190
- transform: [{ rotate: '0deg' }],
191
231
  }}
192
232
  />
193
233
  </View>
@@ -298,8 +338,17 @@ export function FieldFlowIcon({ name, size = 18, color = '#6B7280', style }: Fie
298
338
  </View>
299
339
  );
300
340
  case 'chevronDown':
341
+ case 'chevronUp':
342
+ case 'chevronLeft':
343
+ case 'chevronRight': {
344
+ const rotations = {
345
+ chevronDown: '0deg',
346
+ chevronUp: '180deg',
347
+ chevronLeft: '90deg',
348
+ chevronRight: '-90deg',
349
+ } as const;
301
350
  return (
302
- <View style={[box, style]}>
351
+ <View style={[box, style, { transform: [{ rotate: rotations[name] }] }]}>
303
352
  <View
304
353
  style={{
305
354
  width: size * 0.55,
@@ -322,6 +371,403 @@ export function FieldFlowIcon({ name, size = 18, color = '#6B7280', style }: Fie
322
371
  />
323
372
  </View>
324
373
  );
374
+ }
375
+ case 'calendar':
376
+ return (
377
+ <View style={[box, style]}>
378
+ <View
379
+ style={{
380
+ width: size,
381
+ height: size * 0.85,
382
+ borderRadius: size * 0.12,
383
+ borderWidth: stroke,
384
+ borderColor: color,
385
+ marginTop: size * 0.1,
386
+ }}
387
+ >
388
+ <View style={{ height: size * 0.22, backgroundColor: color, opacity: 0.25, borderTopLeftRadius: size * 0.08, borderTopRightRadius: size * 0.08 }} />
389
+ </View>
390
+ <View style={{ position: 'absolute', top: 0, left: size * 0.22, width: stroke, height: size * 0.28, backgroundColor: color, borderRadius: stroke }} />
391
+ <View style={{ position: 'absolute', top: 0, right: size * 0.22, width: stroke, height: size * 0.28, backgroundColor: color, borderRadius: stroke }} />
392
+ </View>
393
+ );
394
+ case 'clock':
395
+ return (
396
+ <View style={[box, style]}>
397
+ <View
398
+ style={{
399
+ width: size,
400
+ height: size,
401
+ borderRadius: size / 2,
402
+ borderWidth: stroke,
403
+ borderColor: color,
404
+ alignItems: 'center',
405
+ justifyContent: 'center',
406
+ }}
407
+ >
408
+ <View style={{ position: 'absolute', width: stroke, height: size * 0.28, backgroundColor: color, bottom: size * 0.42, borderRadius: stroke }} />
409
+ <View style={{ position: 'absolute', width: size * 0.22, height: stroke, backgroundColor: color, left: size * 0.48, borderRadius: stroke }} />
410
+ </View>
411
+ </View>
412
+ );
413
+ case 'creditCard':
414
+ return (
415
+ <View style={[box, style]}>
416
+ <View
417
+ style={{
418
+ width: size,
419
+ height: size * 0.7,
420
+ borderRadius: size * 0.1,
421
+ borderWidth: stroke,
422
+ borderColor: color,
423
+ overflow: 'hidden',
424
+ }}
425
+ >
426
+ <View style={{ marginTop: size * 0.18, height: size * 0.14, backgroundColor: color, opacity: 0.35 }} />
427
+ <View style={{ marginTop: size * 0.12, marginLeft: size * 0.12, width: size * 0.35, height: stroke, backgroundColor: color, borderRadius: stroke }} />
428
+ </View>
429
+ </View>
430
+ );
431
+ case 'currency':
432
+ return (
433
+ <View style={[box, style]}>
434
+ <View style={{ width: stroke * 1.2, height: size * 0.85, backgroundColor: color, borderRadius: stroke, position: 'absolute' }} />
435
+ <View
436
+ style={{
437
+ width: size * 0.7,
438
+ height: size * 0.7,
439
+ borderRadius: size * 0.35,
440
+ borderWidth: stroke * 1.4,
441
+ borderColor: color,
442
+ }}
443
+ />
444
+ </View>
445
+ );
446
+ case 'phone':
447
+ return (
448
+ <View style={[box, style]}>
449
+ <View
450
+ style={{
451
+ width: size * 0.55,
452
+ height: size,
453
+ borderRadius: size * 0.12,
454
+ borderWidth: stroke,
455
+ borderColor: color,
456
+ alignItems: 'center',
457
+ justifyContent: 'flex-end',
458
+ paddingBottom: size * 0.08,
459
+ }}
460
+ >
461
+ <View style={{ width: size * 0.18, height: stroke, backgroundColor: color, borderRadius: stroke }} />
462
+ </View>
463
+ </View>
464
+ );
465
+ case 'mail':
466
+ return (
467
+ <View style={[box, style]}>
468
+ <View
469
+ style={{
470
+ width: size,
471
+ height: size * 0.7,
472
+ borderRadius: size * 0.08,
473
+ borderWidth: stroke,
474
+ borderColor: color,
475
+ overflow: 'hidden',
476
+ }}
477
+ >
478
+ <View
479
+ style={{
480
+ position: 'absolute',
481
+ top: -size * 0.08,
482
+ left: size * 0.08,
483
+ width: size * 0.75,
484
+ height: size * 0.75,
485
+ borderWidth: stroke,
486
+ borderColor: color,
487
+ transform: [{ rotate: '45deg' }],
488
+ }}
489
+ />
490
+ </View>
491
+ </View>
492
+ );
493
+ case 'lock':
494
+ return (
495
+ <View style={[box, style]}>
496
+ <View
497
+ style={{
498
+ width: size * 0.55,
499
+ height: size * 0.4,
500
+ borderTopLeftRadius: size * 0.28,
501
+ borderTopRightRadius: size * 0.28,
502
+ borderWidth: stroke,
503
+ borderBottomWidth: 0,
504
+ borderColor: color,
505
+ marginBottom: -1,
506
+ }}
507
+ />
508
+ <View
509
+ style={{
510
+ width: size * 0.85,
511
+ height: size * 0.55,
512
+ borderRadius: size * 0.1,
513
+ borderWidth: stroke,
514
+ borderColor: color,
515
+ alignItems: 'center',
516
+ justifyContent: 'center',
517
+ }}
518
+ >
519
+ <View style={{ width: size * 0.14, height: size * 0.14, borderRadius: size * 0.07, backgroundColor: color }} />
520
+ </View>
521
+ </View>
522
+ );
523
+ case 'user':
524
+ return (
525
+ <View style={[box, style]}>
526
+ <View
527
+ style={{
528
+ width: size * 0.4,
529
+ height: size * 0.4,
530
+ borderRadius: size * 0.2,
531
+ borderWidth: stroke,
532
+ borderColor: color,
533
+ marginBottom: size * 0.06,
534
+ }}
535
+ />
536
+ <View
537
+ style={{
538
+ width: size * 0.85,
539
+ height: size * 0.35,
540
+ borderTopLeftRadius: size * 0.4,
541
+ borderTopRightRadius: size * 0.4,
542
+ borderWidth: stroke,
543
+ borderBottomWidth: 0,
544
+ borderColor: color,
545
+ }}
546
+ />
547
+ </View>
548
+ );
549
+ case 'key':
550
+ return (
551
+ <View style={[box, style]}>
552
+ <View
553
+ style={{
554
+ width: size * 0.4,
555
+ height: size * 0.4,
556
+ borderRadius: size * 0.2,
557
+ borderWidth: stroke,
558
+ borderColor: color,
559
+ position: 'absolute',
560
+ left: 0,
561
+ }}
562
+ />
563
+ <View
564
+ style={{
565
+ width: size * 0.55,
566
+ height: stroke * 1.4,
567
+ backgroundColor: color,
568
+ position: 'absolute',
569
+ right: 0,
570
+ borderRadius: stroke,
571
+ }}
572
+ />
573
+ </View>
574
+ );
575
+ case 'hash':
576
+ case 'otp':
577
+ return (
578
+ <View style={[box, style]}>
579
+ <View style={{ width: stroke, height: size * 0.85, backgroundColor: color, transform: [{ rotate: '15deg' }, { translateX: -size * 0.12 }], position: 'absolute' }} />
580
+ <View style={{ width: stroke, height: size * 0.85, backgroundColor: color, transform: [{ rotate: '15deg' }, { translateX: size * 0.12 }], position: 'absolute' }} />
581
+ <View style={{ width: size * 0.85, height: stroke, backgroundColor: color, transform: [{ rotate: '-12deg' }, { translateY: -size * 0.15 }], position: 'absolute' }} />
582
+ <View style={{ width: size * 0.85, height: stroke, backgroundColor: color, transform: [{ rotate: '-12deg' }, { translateY: size * 0.15 }], position: 'absolute' }} />
583
+ </View>
584
+ );
585
+ case 'radio':
586
+ return (
587
+ <View style={[box, style]}>
588
+ <View style={{ width: size, height: size, borderRadius: size / 2, borderWidth: stroke, borderColor: color }} />
589
+ </View>
590
+ );
591
+ case 'radioFilled':
592
+ return (
593
+ <View style={[box, style]}>
594
+ <View
595
+ style={{
596
+ width: size,
597
+ height: size,
598
+ borderRadius: size / 2,
599
+ borderWidth: stroke,
600
+ borderColor: color,
601
+ alignItems: 'center',
602
+ justifyContent: 'center',
603
+ }}
604
+ >
605
+ <View style={{ width: size * 0.45, height: size * 0.45, borderRadius: size * 0.225, backgroundColor: color }} />
606
+ </View>
607
+ </View>
608
+ );
609
+ case 'switch':
610
+ return (
611
+ <View style={[box, style]}>
612
+ <View
613
+ style={{
614
+ width: size,
615
+ height: size * 0.55,
616
+ borderRadius: size * 0.275,
617
+ borderWidth: stroke,
618
+ borderColor: color,
619
+ justifyContent: 'center',
620
+ paddingHorizontal: 2,
621
+ }}
622
+ >
623
+ <View style={{ width: size * 0.35, height: size * 0.35, borderRadius: size * 0.175, backgroundColor: color, alignSelf: 'flex-end' }} />
624
+ </View>
625
+ </View>
626
+ );
627
+ case 'star':
628
+ return (
629
+ <View style={[box, style]}>
630
+ <View style={{ width: size * 0.9, height: size * 0.9, borderRadius: size * 0.1, backgroundColor: color, transform: [{ rotate: '45deg' }], opacity: 0.9 }} />
631
+ </View>
632
+ );
633
+ case 'plus':
634
+ case 'minus':
635
+ return (
636
+ <View style={[box, style]}>
637
+ <View style={{ width: size * 0.7, height: stroke * 1.2, backgroundColor: color, borderRadius: stroke, position: 'absolute' }} />
638
+ {name === 'plus' ? (
639
+ <View style={{ width: stroke * 1.2, height: size * 0.7, backgroundColor: color, borderRadius: stroke, position: 'absolute' }} />
640
+ ) : null}
641
+ </View>
642
+ );
643
+ case 'home':
644
+ return (
645
+ <View style={[box, style]}>
646
+ <View
647
+ style={{
648
+ width: 0,
649
+ height: 0,
650
+ borderLeftWidth: size * 0.45,
651
+ borderRightWidth: size * 0.45,
652
+ borderBottomWidth: size * 0.4,
653
+ borderLeftColor: 'transparent',
654
+ borderRightColor: 'transparent',
655
+ borderBottomColor: color,
656
+ marginBottom: -2,
657
+ }}
658
+ />
659
+ <View style={{ width: size * 0.7, height: size * 0.45, borderWidth: stroke, borderTopWidth: 0, borderColor: color }} />
660
+ </View>
661
+ );
662
+ case 'settings':
663
+ return (
664
+ <View style={[box, style]}>
665
+ <View style={{ width: size, height: size, borderRadius: size / 2, borderWidth: stroke * 2, borderColor: color, borderStyle: 'solid', opacity: 0.9 }} />
666
+ <View style={{ position: 'absolute', width: size * 0.35, height: size * 0.35, borderRadius: size * 0.175, backgroundColor: color }} />
667
+ </View>
668
+ );
669
+ case 'edit':
670
+ return (
671
+ <View style={[box, style]}>
672
+ <View
673
+ style={{
674
+ width: size * 0.35,
675
+ height: size * 0.85,
676
+ backgroundColor: color,
677
+ borderRadius: stroke,
678
+ transform: [{ rotate: '-45deg' }],
679
+ }}
680
+ />
681
+ </View>
682
+ );
683
+ case 'trash':
684
+ return (
685
+ <View style={[box, style]}>
686
+ <View style={{ width: size * 0.7, height: stroke, backgroundColor: color, marginBottom: 2, borderRadius: stroke }} />
687
+ <View style={{ width: size * 0.65, height: size * 0.7, borderWidth: stroke, borderColor: color, borderRadius: size * 0.08 }} />
688
+ </View>
689
+ );
690
+ case 'link':
691
+ return (
692
+ <View style={[box, style]}>
693
+ <View
694
+ style={{
695
+ width: size * 0.45,
696
+ height: size * 0.7,
697
+ borderRadius: size * 0.22,
698
+ borderWidth: stroke,
699
+ borderColor: color,
700
+ transform: [{ rotate: '-30deg' }, { translateX: -size * 0.1 }],
701
+ position: 'absolute',
702
+ }}
703
+ />
704
+ <View
705
+ style={{
706
+ width: size * 0.45,
707
+ height: size * 0.7,
708
+ borderRadius: size * 0.22,
709
+ borderWidth: stroke,
710
+ borderColor: color,
711
+ transform: [{ rotate: '-30deg' }, { translateX: size * 0.1 }],
712
+ position: 'absolute',
713
+ }}
714
+ />
715
+ </View>
716
+ );
717
+ case 'globe':
718
+ return (
719
+ <View style={[box, style]}>
720
+ <View style={{ width: size, height: size, borderRadius: size / 2, borderWidth: stroke, borderColor: color }} />
721
+ <View style={{ position: 'absolute', width: size * 0.45, height: size, borderWidth: stroke, borderColor: color, borderRadius: size * 0.22 }} />
722
+ <View style={{ position: 'absolute', width: size * 0.85, height: stroke, backgroundColor: color }} />
723
+ </View>
724
+ );
725
+ case 'file':
726
+ return (
727
+ <View style={[box, style]}>
728
+ <View style={{ width: size * 0.75, height: size, borderWidth: stroke, borderColor: color, borderRadius: size * 0.08 }} />
729
+ </View>
730
+ );
731
+ case 'folder':
732
+ return (
733
+ <View style={[box, style]}>
734
+ <View style={{ width: size * 0.4, height: size * 0.2, backgroundColor: color, borderTopLeftRadius: 3, borderTopRightRadius: 3, alignSelf: 'flex-start', marginLeft: 1, opacity: 0.8 }} />
735
+ <View style={{ width: size, height: size * 0.65, borderWidth: stroke, borderColor: color, borderRadius: size * 0.08 }} />
736
+ </View>
737
+ );
738
+ case 'bell':
739
+ return (
740
+ <View style={[box, style]}>
741
+ <View
742
+ style={{
743
+ width: size * 0.7,
744
+ height: size * 0.65,
745
+ borderTopLeftRadius: size * 0.35,
746
+ borderTopRightRadius: size * 0.35,
747
+ borderWidth: stroke,
748
+ borderColor: color,
749
+ }}
750
+ />
751
+ <View style={{ width: size * 0.2, height: size * 0.15, borderBottomLeftRadius: size * 0.1, borderBottomRightRadius: size * 0.1, backgroundColor: color, marginTop: 1 }} />
752
+ </View>
753
+ );
754
+ case 'heart':
755
+ return (
756
+ <View style={[box, style]}>
757
+ <View style={{ width: size * 0.4, height: size * 0.4, borderRadius: size * 0.2, backgroundColor: color, position: 'absolute', left: size * 0.05, top: size * 0.15 }} />
758
+ <View style={{ width: size * 0.4, height: size * 0.4, borderRadius: size * 0.2, backgroundColor: color, position: 'absolute', right: size * 0.05, top: size * 0.15 }} />
759
+ <View
760
+ style={{
761
+ width: size * 0.55,
762
+ height: size * 0.55,
763
+ backgroundColor: color,
764
+ transform: [{ rotate: '45deg' }],
765
+ position: 'absolute',
766
+ bottom: size * 0.08,
767
+ }}
768
+ />
769
+ </View>
770
+ );
325
771
  default:
326
772
  return <View style={[box, style]} />;
327
773
  }
@@ -1,2 +1,4 @@
1
1
  export { FieldFlowIcon } from './Icon';
2
2
  export type { FieldFlowIconName, FieldFlowIconProps } from './Icon';
3
+ export { renderFieldFlowIcon } from './renderIcon';
4
+ export type { FieldFlowIconSource } from './renderIcon';
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { FieldFlowIcon, type FieldFlowIconName } from './Icon';
3
+
4
+ /** Built-in icon name or any custom React node (vector icons, images, etc.). */
5
+ export type FieldFlowIconSource = FieldFlowIconName | React.ReactNode;
6
+
7
+ export function renderFieldFlowIcon(
8
+ icon: FieldFlowIconSource | undefined,
9
+ color: string,
10
+ size = 18,
11
+ ): React.ReactNode {
12
+ if (icon == null || icon === false) return null;
13
+ if (typeof icon === 'string') {
14
+ return <FieldFlowIcon name={icon as FieldFlowIconName} color={color} size={size} />;
15
+ }
16
+ return icon;
17
+ }
package/src/index.ts CHANGED
@@ -19,6 +19,27 @@ export type {
19
19
  FieldFlowDropdownPresentation,
20
20
  } from './components/FieldFlowDropdown';
21
21
 
22
+ export { FieldFlowOTP } from './components/FieldFlowOTP';
23
+ export type { FieldFlowOTPProps } from './components/FieldFlowOTP';
24
+
25
+ export { FieldFlowMaskedInput } from './components/FieldFlowMaskedInput';
26
+ export type { FieldFlowMaskedInputProps } from './components/FieldFlowMaskedInput';
27
+
28
+ export { FieldFlowCheckbox } from './components/FieldFlowCheckbox';
29
+ export type { FieldFlowCheckboxProps } from './components/FieldFlowCheckbox';
30
+
31
+ export { FieldFlowRadio } from './components/FieldFlowRadio';
32
+ export type { FieldFlowRadioProps } from './components/FieldFlowRadio';
33
+
34
+ export { FieldFlowSwitch } from './components/FieldFlowSwitch';
35
+ export type { FieldFlowSwitchProps } from './components/FieldFlowSwitch';
36
+
37
+ export { FieldFlowDateTimePicker } from './components/FieldFlowDateTimePicker';
38
+ export type {
39
+ FieldFlowDateTimePickerProps,
40
+ FieldFlowDateTimeMode,
41
+ } from './components/FieldFlowDateTimePicker';
42
+
22
43
  // Theming
23
44
  export { FieldFlowThemeProvider, useFieldFlowTheme, defaultTheme, darkTheme } from './theme';
24
45
  export type { FieldFlowThemeProviderProps } from './theme';
@@ -29,6 +50,9 @@ export type {
29
50
  UseFieldFlowFormOptions,
30
51
  UseFieldFlowFormResult,
31
52
  FieldFlowFormRules,
53
+ AsyncFieldValidator,
54
+ AsyncFieldValidators,
55
+ CrossFieldRule,
32
56
  UseKeyboardManagerOptions,
33
57
  UseKeyboardManagerResult,
34
58
  UseFieldStateOptions,
@@ -48,12 +72,30 @@ export {
48
72
  minLengthValidator,
49
73
  maxLengthValidator,
50
74
  patternValidator,
75
+ zodToFormErrors,
76
+ zodFormValidate,
77
+ createZodSubmitGuard,
78
+ fieldRulesFromZodString,
51
79
  } from './validation';
52
- export type { UseValidationResult } from './validation';
80
+ export type { UseValidationResult, ZodSchemaLike, ZodIssueLike, ZodErrorLike } from './validation';
81
+
82
+ // Masks
83
+ export {
84
+ applyMask,
85
+ applyPattern,
86
+ formatMasked,
87
+ unmask,
88
+ digitsOnly,
89
+ applyPhoneMask,
90
+ applyCardMask,
91
+ applyDateMask,
92
+ applyCurrencyMask,
93
+ } from './utils/masks';
94
+ export type { FieldFlowMaskType, MaskResult, ApplyMaskOptions } from './utils/masks';
53
95
 
54
- // Icons (in case consumers want to reuse FieldFlow's built-in icon set elsewhere)
55
- export { FieldFlowIcon } from './icons';
56
- export type { FieldFlowIconName, FieldFlowIconProps } from './icons';
96
+ // Icons
97
+ export { FieldFlowIcon, renderFieldFlowIcon } from './icons';
98
+ export type { FieldFlowIconName, FieldFlowIconProps, FieldFlowIconSource } from './icons';
57
99
 
58
100
  // Types
59
101
  export type {
@@ -61,6 +103,7 @@ export type {
61
103
  FieldFlowState,
62
104
  FieldFlowRules,
63
105
  FieldFlowOption,
106
+ FieldFlowVariant,
64
107
  ValidationResult,
65
108
  Validator,
66
109
  FieldFlowColors,
@@ -7,8 +7,13 @@ export interface FieldFlowOption {
7
7
  disabled?: boolean;
8
8
  /** Optional secondary line of text shown under the label in the option list. */
9
9
  description?: string;
10
+ /** Built-in icon name or a custom React node shown beside the option. */
11
+ icon?: import('../icons').FieldFlowIconSource;
10
12
  }
11
13
 
14
+ /** Visual style for text-like FieldFlow fields. */
15
+ export type FieldFlowVariant = 'outlined' | 'filled' | 'underline' | 'floating';
16
+
12
17
  export type FieldFlowFieldType =
13
18
  | 'text'
14
19
  | 'email'