@cdx-ui/components 0.0.1-alpha.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.
Files changed (146) hide show
  1. package/README.md +34 -0
  2. package/lib/commonjs/components/Box/Box.js +30 -0
  3. package/lib/commonjs/components/Box/Box.js.map +1 -0
  4. package/lib/commonjs/components/Box/index.js +17 -0
  5. package/lib/commonjs/components/Box/index.js.map +1 -0
  6. package/lib/commonjs/components/Button/index.js +155 -0
  7. package/lib/commonjs/components/Button/index.js.map +1 -0
  8. package/lib/commonjs/components/Button/styles.js +312 -0
  9. package/lib/commonjs/components/Button/styles.js.map +1 -0
  10. package/lib/commonjs/components/Input/BaseInput.js +13 -0
  11. package/lib/commonjs/components/Input/BaseInput.js.map +1 -0
  12. package/lib/commonjs/components/Input/BaseInput.web.js +50 -0
  13. package/lib/commonjs/components/Input/BaseInput.web.js.map +1 -0
  14. package/lib/commonjs/components/Input/index.js +142 -0
  15. package/lib/commonjs/components/Input/index.js.map +1 -0
  16. package/lib/commonjs/components/Input/styles.js +62 -0
  17. package/lib/commonjs/components/Input/styles.js.map +1 -0
  18. package/lib/commonjs/components/Select/index.js +213 -0
  19. package/lib/commonjs/components/Select/index.js.map +1 -0
  20. package/lib/commonjs/components/Select/styles.js +120 -0
  21. package/lib/commonjs/components/Select/styles.js.map +1 -0
  22. package/lib/commonjs/components/Spinner/Spinner.js +15 -0
  23. package/lib/commonjs/components/Spinner/Spinner.js.map +1 -0
  24. package/lib/commonjs/components/Spinner/index.js +17 -0
  25. package/lib/commonjs/components/Spinner/index.js.map +1 -0
  26. package/lib/commonjs/components/Stack/HStack.js +45 -0
  27. package/lib/commonjs/components/Stack/HStack.js.map +1 -0
  28. package/lib/commonjs/components/Stack/VStack.js +45 -0
  29. package/lib/commonjs/components/Stack/VStack.js.map +1 -0
  30. package/lib/commonjs/components/Stack/index.js +20 -0
  31. package/lib/commonjs/components/Stack/index.js.map +1 -0
  32. package/lib/commonjs/components/Text/Text.js +30 -0
  33. package/lib/commonjs/components/Text/Text.js.map +1 -0
  34. package/lib/commonjs/components/Text/index.js +17 -0
  35. package/lib/commonjs/components/Text/index.js.map +1 -0
  36. package/lib/commonjs/components/index.js +83 -0
  37. package/lib/commonjs/components/index.js.map +1 -0
  38. package/lib/commonjs/index.js +17 -0
  39. package/lib/commonjs/index.js.map +1 -0
  40. package/lib/commonjs/package.json +1 -0
  41. package/lib/commonjs/styles.css +6 -0
  42. package/lib/commonjs/utils/WrapStringChild.js +22 -0
  43. package/lib/commonjs/utils/WrapStringChild.js.map +1 -0
  44. package/lib/module/components/Box/Box.js +26 -0
  45. package/lib/module/components/Box/Box.js.map +1 -0
  46. package/lib/module/components/Box/index.js +4 -0
  47. package/lib/module/components/Box/index.js.map +1 -0
  48. package/lib/module/components/Button/index.js +151 -0
  49. package/lib/module/components/Button/index.js.map +1 -0
  50. package/lib/module/components/Button/styles.js +309 -0
  51. package/lib/module/components/Button/styles.js.map +1 -0
  52. package/lib/module/components/Input/BaseInput.js +4 -0
  53. package/lib/module/components/Input/BaseInput.js.map +1 -0
  54. package/lib/module/components/Input/BaseInput.web.js +45 -0
  55. package/lib/module/components/Input/BaseInput.web.js.map +1 -0
  56. package/lib/module/components/Input/index.js +138 -0
  57. package/lib/module/components/Input/index.js.map +1 -0
  58. package/lib/module/components/Input/styles.js +58 -0
  59. package/lib/module/components/Input/styles.js.map +1 -0
  60. package/lib/module/components/Select/index.js +209 -0
  61. package/lib/module/components/Select/index.js.map +1 -0
  62. package/lib/module/components/Select/styles.js +117 -0
  63. package/lib/module/components/Select/styles.js.map +1 -0
  64. package/lib/module/components/Spinner/Spinner.js +11 -0
  65. package/lib/module/components/Spinner/Spinner.js.map +1 -0
  66. package/lib/module/components/Spinner/index.js +4 -0
  67. package/lib/module/components/Spinner/index.js.map +1 -0
  68. package/lib/module/components/Stack/HStack.js +41 -0
  69. package/lib/module/components/Stack/HStack.js.map +1 -0
  70. package/lib/module/components/Stack/VStack.js +41 -0
  71. package/lib/module/components/Stack/VStack.js.map +1 -0
  72. package/lib/module/components/Stack/index.js +5 -0
  73. package/lib/module/components/Stack/index.js.map +1 -0
  74. package/lib/module/components/Text/Text.js +26 -0
  75. package/lib/module/components/Text/Text.js.map +1 -0
  76. package/lib/module/components/Text/index.js +4 -0
  77. package/lib/module/components/Text/index.js.map +1 -0
  78. package/lib/module/components/index.js +9 -0
  79. package/lib/module/components/index.js.map +1 -0
  80. package/lib/module/index.js +4 -0
  81. package/lib/module/index.js.map +1 -0
  82. package/lib/module/styles.css +6 -0
  83. package/lib/module/utils/WrapStringChild.js +18 -0
  84. package/lib/module/utils/WrapStringChild.js.map +1 -0
  85. package/lib/typescript/components/Box/Box.d.ts +8 -0
  86. package/lib/typescript/components/Box/Box.d.ts.map +1 -0
  87. package/lib/typescript/components/Box/index.d.ts +2 -0
  88. package/lib/typescript/components/Box/index.d.ts.map +1 -0
  89. package/lib/typescript/components/Button/index.d.ts +41 -0
  90. package/lib/typescript/components/Button/index.d.ts.map +1 -0
  91. package/lib/typescript/components/Button/styles.d.ts +23 -0
  92. package/lib/typescript/components/Button/styles.d.ts.map +1 -0
  93. package/lib/typescript/components/Input/BaseInput.d.ts +2 -0
  94. package/lib/typescript/components/Input/BaseInput.d.ts.map +1 -0
  95. package/lib/typescript/components/Input/BaseInput.web.d.ts +3 -0
  96. package/lib/typescript/components/Input/BaseInput.web.d.ts.map +1 -0
  97. package/lib/typescript/components/Input/index.d.ts +32 -0
  98. package/lib/typescript/components/Input/index.d.ts.map +1 -0
  99. package/lib/typescript/components/Input/styles.d.ts +17 -0
  100. package/lib/typescript/components/Input/styles.d.ts.map +1 -0
  101. package/lib/typescript/components/Select/index.d.ts +45 -0
  102. package/lib/typescript/components/Select/index.d.ts.map +1 -0
  103. package/lib/typescript/components/Select/styles.d.ts +22 -0
  104. package/lib/typescript/components/Select/styles.d.ts.map +1 -0
  105. package/lib/typescript/components/Spinner/Spinner.d.ts +5 -0
  106. package/lib/typescript/components/Spinner/Spinner.d.ts.map +1 -0
  107. package/lib/typescript/components/Spinner/index.d.ts +2 -0
  108. package/lib/typescript/components/Spinner/index.d.ts.map +1 -0
  109. package/lib/typescript/components/Stack/HStack.d.ts +20 -0
  110. package/lib/typescript/components/Stack/HStack.d.ts.map +1 -0
  111. package/lib/typescript/components/Stack/VStack.d.ts +20 -0
  112. package/lib/typescript/components/Stack/VStack.d.ts.map +1 -0
  113. package/lib/typescript/components/Stack/index.d.ts +3 -0
  114. package/lib/typescript/components/Stack/index.d.ts.map +1 -0
  115. package/lib/typescript/components/Text/Text.d.ts +11 -0
  116. package/lib/typescript/components/Text/Text.d.ts.map +1 -0
  117. package/lib/typescript/components/Text/index.d.ts +2 -0
  118. package/lib/typescript/components/Text/index.d.ts.map +1 -0
  119. package/lib/typescript/components/index.d.ts +7 -0
  120. package/lib/typescript/components/index.d.ts.map +1 -0
  121. package/lib/typescript/index.d.ts +2 -0
  122. package/lib/typescript/index.d.ts.map +1 -0
  123. package/lib/typescript/utils/WrapStringChild.d.ts +10 -0
  124. package/lib/typescript/utils/WrapStringChild.d.ts.map +1 -0
  125. package/package.json +90 -0
  126. package/src/components/Box/Box.tsx +21 -0
  127. package/src/components/Box/index.ts +1 -0
  128. package/src/components/Button/index.tsx +186 -0
  129. package/src/components/Button/styles.ts +410 -0
  130. package/src/components/Input/BaseInput.tsx +1 -0
  131. package/src/components/Input/BaseInput.web.tsx +41 -0
  132. package/src/components/Input/index.tsx +161 -0
  133. package/src/components/Input/styles.ts +83 -0
  134. package/src/components/Select/index.tsx +215 -0
  135. package/src/components/Select/styles.ts +168 -0
  136. package/src/components/Spinner/Spinner.tsx +10 -0
  137. package/src/components/Spinner/index.ts +1 -0
  138. package/src/components/Stack/HStack.tsx +42 -0
  139. package/src/components/Stack/VStack.tsx +46 -0
  140. package/src/components/Stack/index.ts +2 -0
  141. package/src/components/Text/Text.tsx +58 -0
  142. package/src/components/Text/index.ts +1 -0
  143. package/src/components/index.ts +6 -0
  144. package/src/index.ts +1 -0
  145. package/src/styles.css +6 -0
  146. package/src/utils/WrapStringChild.tsx +25 -0
@@ -0,0 +1,410 @@
1
+ import { Platform } from 'react-native';
2
+ import { cva, type VariantProps } from 'class-variance-authority';
3
+
4
+ // TODO: Split into 2 files
5
+ // TODO: Create cva wrapper
6
+
7
+ export const buttonRootVariants = cva(
8
+ [
9
+ 'flex-row items-center justify-center',
10
+ 'rounded-md',
11
+ 'transition-colors duration-150', // TODO: Transition not working on mobile
12
+ 'data-[disabled=true]:opacity-60 data-[disabled=true]:cursor-not-allowed data-[disabled=true]:pointer-events-none',
13
+ 'data-[focus-visible=true]:ring-2 data-[focus-visible=true]:ring-ring data-[focus-visible=true]:ring-offset-2 data-[focus-visible=true]:ring-offset-bg',
14
+ ],
15
+ {
16
+ variants: {
17
+ variant: {
18
+ solid: [],
19
+ subtle: [],
20
+ outline: [
21
+ 'bg-transparent border border-border',
22
+ 'data-[hover=true]:bg-surface',
23
+ 'data-[active=true]:bg-surface-raised',
24
+ ],
25
+ ghost: [
26
+ 'bg-transparent',
27
+ 'data-[hover=true]:bg-surface',
28
+ 'data-[active=true]:bg-surface-raised',
29
+ ],
30
+ },
31
+ color: {
32
+ primary: [],
33
+ secondary: [],
34
+ success: [],
35
+ danger: [],
36
+ },
37
+ size: {
38
+ sm: 'h-8 px-3 gap-1.5',
39
+ md: 'h-10 px-4 gap-2',
40
+ lg: 'h-12 px-6 gap-2.5',
41
+ },
42
+ fullWidth: {
43
+ true: 'w-full',
44
+ false: '',
45
+ },
46
+ },
47
+ compoundVariants: [
48
+ {
49
+ variant: 'solid',
50
+ color: 'primary',
51
+ className: [
52
+ 'bg-blue-500',
53
+ Platform.select({
54
+ default: 'data-[active=true]:bg-blue-700',
55
+ web: 'data-[hover=true]:bg-blue-600 data-[active=true]:data-[hover=true]:bg-blue-700',
56
+ }),
57
+ ],
58
+ },
59
+ {
60
+ variant: 'solid',
61
+ color: 'secondary',
62
+ className: [
63
+ 'bg-amber-500',
64
+ Platform.select({
65
+ default: 'data-[active=true]:bg-amber-700',
66
+ web: 'data-[hover=true]:bg-amber-600 data-[active=true]:data-[hover=true]:bg-amber-700',
67
+ }),
68
+ ],
69
+ },
70
+ {
71
+ variant: 'solid',
72
+ color: 'success',
73
+ className: [
74
+ 'bg-green-500',
75
+ Platform.select({
76
+ default: 'data-[active=true]:bg-green-700',
77
+ web: 'data-[hover=true]:bg-green-600 data-[active=true]:data-[hover=true]:bg-green-700',
78
+ }),
79
+ ],
80
+ },
81
+ {
82
+ variant: 'solid',
83
+ color: 'danger',
84
+ className: [
85
+ 'bg-red-500',
86
+ Platform.select({
87
+ default: 'data-[active=true]:bg-red-700',
88
+ web: 'data-[hover=true]:bg-red-600 data-[active=true]:data-[hover=true]:bg-red-700',
89
+ }),
90
+ ],
91
+ },
92
+ {
93
+ variant: 'subtle',
94
+ color: 'primary',
95
+ className: [
96
+ 'bg-blue-100',
97
+ Platform.select({
98
+ default: 'data-[active=true]:bg-blue-200',
99
+ web: 'data-[hover=true]:bg-blue-200 data-[active=true]:data-[hover=true]:bg-blue-300',
100
+ }),
101
+ ],
102
+ },
103
+ {
104
+ variant: 'subtle',
105
+ color: 'secondary',
106
+ className: [
107
+ 'bg-amber-200',
108
+ Platform.select({
109
+ default: 'data-[active=true]:bg-amber-300',
110
+ web: 'data-[hover=true]:bg-amber-300 data-[active=true]:data-[hover=true]:bg-amber-400',
111
+ }),
112
+ ],
113
+ },
114
+ {
115
+ variant: 'subtle',
116
+ color: 'success',
117
+ className: [
118
+ 'bg-green-200',
119
+ Platform.select({
120
+ default: 'data-[active=true]:bg-green-300',
121
+ web: 'data-[hover=true]:bg-green-300 data-[active=true]:data-[hover=true]:bg-green-400',
122
+ }),
123
+ ],
124
+ },
125
+ {
126
+ variant: 'subtle',
127
+ color: 'danger',
128
+ className: [
129
+ 'bg-red-200',
130
+ Platform.select({
131
+ default: 'data-[active=true]:bg-red-300',
132
+ web: 'data-[hover=true]:bg-red-300 data-[active=true]:data-[hover=true]:bg-red-400',
133
+ }),
134
+ ],
135
+ },
136
+ {
137
+ variant: 'outline',
138
+ color: 'primary',
139
+ className: [
140
+ 'border-blue-500',
141
+ Platform.select({
142
+ default: 'data-[active=true]:border-blue-700 data-[active=true]:bg-blue-100',
143
+ web: 'data-[hover=true]:border-blue-600 data-[hover=true]:bg-blue-100 data-[active=true]:data-[hover=true]:border-blue-700 data-[active=true]:data-[hover=true]:bg-blue-200',
144
+ }),
145
+ ],
146
+ },
147
+ {
148
+ variant: 'outline',
149
+ color: 'secondary',
150
+ className: [
151
+ 'border-amber-500',
152
+ Platform.select({
153
+ default: 'data-[active=true]:border-amber-700 data-[active=true]:bg-amber-50',
154
+ web: 'data-[hover=true]:border-amber-600 data-[hover=true]:bg-amber-50 data-[active=true]:data-[hover=true]:border-amber-700 data-[active=true]:data-[hover=true]:bg-amber-100',
155
+ }),
156
+ ],
157
+ },
158
+ {
159
+ variant: 'outline',
160
+ color: 'success',
161
+ className: [
162
+ 'border-green-500',
163
+ Platform.select({
164
+ default: 'data-[active=true]:border-green-700 data-[active=true]:bg-green-100',
165
+ web: 'data-[hover=true]:border-green-600 data-[hover=true]:bg-green-100 data-[active=true]:data-[hover=true]:border-green-700 data-[active=true]:data-[hover=true]:bg-green-200',
166
+ }),
167
+ ],
168
+ },
169
+ {
170
+ variant: 'outline',
171
+ color: 'danger',
172
+ className: [
173
+ 'border-red-500',
174
+ Platform.select({
175
+ default: 'data-[active=true]:border-red-700 data-[active=true]:bg-red-100',
176
+ web: 'data-[hover=true]:border-red-600 data-[hover=true]:bg-red-100 data-[active=true]:data-[hover=true]:border-red-700 data-[active=true]:data-[hover=true]:bg-red-200',
177
+ }),
178
+ ],
179
+ },
180
+ {
181
+ variant: 'ghost',
182
+ color: 'primary',
183
+ className: [
184
+ 'bg-transparent',
185
+ Platform.select({
186
+ default: 'data-[active=true]:bg-blue-100',
187
+ web: 'data-[hover=true]:bg-blue-50 data-[active=true]:data-[hover=true]:bg-blue-100',
188
+ }),
189
+ ],
190
+ },
191
+ {
192
+ variant: 'ghost',
193
+ color: 'secondary',
194
+ className: [
195
+ 'bg-transparent',
196
+ Platform.select({
197
+ default: 'data-[active=true]:bg-amber-100',
198
+ web: 'data-[hover=true]:bg-amber-50 data-[active=true]:data-[hover=true]:bg-amber-100',
199
+ }),
200
+ ],
201
+ },
202
+ {
203
+ variant: 'ghost',
204
+ color: 'success',
205
+ className: [
206
+ 'bg-transparent',
207
+ Platform.select({
208
+ default: 'data-[active=true]:bg-green-100',
209
+ web: 'data-[hover=true]:bg-green-50 data-[active=true]:data-[hover=true]:bg-green-100',
210
+ }),
211
+ ],
212
+ },
213
+ {
214
+ variant: 'ghost',
215
+ color: 'danger',
216
+ className: [
217
+ 'bg-transparent',
218
+ Platform.select({
219
+ default: 'data-[active=true]:bg-red-100',
220
+ web: 'data-[hover=true]:bg-red-50 data-[active=true]:data-[hover=true]:bg-red-100',
221
+ }),
222
+ ],
223
+ },
224
+ ],
225
+ defaultVariants: {
226
+ variant: 'solid',
227
+ color: 'primary',
228
+ size: 'md',
229
+ fullWidth: false,
230
+ },
231
+ },
232
+ );
233
+
234
+ export const buttonTextVariants = cva(['font-medium', 'text-center'], {
235
+ variants: {
236
+ variant: {
237
+ solid: 'text-white',
238
+ subtle: [],
239
+ outline: [],
240
+ ghost: [],
241
+ },
242
+ color: {
243
+ primary: [],
244
+ secondary: [],
245
+ success: [],
246
+ danger: [],
247
+ },
248
+ size: {
249
+ sm: 'text-sm',
250
+ md: 'text-base',
251
+ lg: 'text-lg',
252
+ },
253
+ },
254
+ compoundVariants: [
255
+ {
256
+ variant: 'subtle',
257
+ color: 'primary',
258
+ className: 'text-blue-950',
259
+ },
260
+ {
261
+ variant: 'subtle',
262
+ color: 'secondary',
263
+ className: 'text-amber-950',
264
+ },
265
+ {
266
+ variant: 'subtle',
267
+ color: 'success',
268
+ className: 'text-green-950',
269
+ },
270
+ {
271
+ variant: 'subtle',
272
+ color: 'danger',
273
+ className: 'text-red-950',
274
+ },
275
+ {
276
+ variant: ['outline', 'ghost'],
277
+ color: 'primary',
278
+ className: [
279
+ 'text-blue-500',
280
+ Platform.select({
281
+ default: 'data-[active=true]:text-blue-700',
282
+ web: 'data-[hover=true]:text-blue-600 data-[active=true]:data-[hover=true]:text-blue-700',
283
+ }),
284
+ ],
285
+ },
286
+ {
287
+ variant: ['outline', 'ghost'],
288
+ color: 'secondary',
289
+ className: [
290
+ 'text-amber-600',
291
+ Platform.select({
292
+ default: 'data-[active=true]:text-amber-800',
293
+ web: 'data-[hover=true]:text-amber-700 data-[active=true]:data-[hover=true]:text-amber-800',
294
+ }),
295
+ ],
296
+ },
297
+ {
298
+ variant: ['outline', 'ghost'],
299
+ color: 'success',
300
+ className: [
301
+ 'text-green-600',
302
+ Platform.select({
303
+ default: 'data-[active=true]:text-green-800',
304
+ web: 'data-[hover=true]:text-green-700 data-[active=true]:data-[hover=true]:text-green-800',
305
+ }),
306
+ ],
307
+ },
308
+ {
309
+ variant: ['outline', 'ghost'],
310
+ color: 'danger',
311
+ className: [
312
+ 'text-red-500',
313
+ Platform.select({
314
+ default: 'data-[active=true]:text-red-700',
315
+ web: 'data-[hover=true]:text-red-600 data-[active=true]:data-[hover=true]:text-red-700',
316
+ }),
317
+ ],
318
+ },
319
+ ],
320
+ defaultVariants: {
321
+ variant: 'solid',
322
+ color: 'primary',
323
+ size: 'md',
324
+ },
325
+ });
326
+
327
+ export const buttonSpinnerVariants = cva([], {
328
+ variants: {
329
+ variant: {
330
+ solid: 'accent-white',
331
+ subtle: [],
332
+ outline: [],
333
+ ghost: [],
334
+ },
335
+ color: {
336
+ primary: [],
337
+ secondary: [],
338
+ success: [],
339
+ danger: [],
340
+ },
341
+ },
342
+ compoundVariants: [
343
+ {
344
+ variant: 'subtle',
345
+ color: 'primary',
346
+ className: 'accent-blue-950',
347
+ },
348
+ {
349
+ variant: 'subtle',
350
+ color: 'secondary',
351
+ className: 'accent-amber-950',
352
+ },
353
+ {
354
+ variant: 'subtle',
355
+ color: 'success',
356
+ className: 'accent-green-950',
357
+ },
358
+ {
359
+ variant: 'subtle',
360
+ color: 'danger',
361
+ className: 'accent-red-950',
362
+ },
363
+ {
364
+ variant: ['outline', 'ghost'],
365
+ color: 'primary',
366
+ className: 'accent-blue-500',
367
+ },
368
+ {
369
+ variant: ['outline', 'ghost'],
370
+ color: 'secondary',
371
+ className: 'accent-amber-600',
372
+ },
373
+ {
374
+ variant: ['outline', 'ghost'],
375
+ color: 'success',
376
+ className: 'accent-green-600',
377
+ },
378
+ {
379
+ variant: ['outline', 'ghost'],
380
+ color: 'danger',
381
+ className: 'accent-red-500',
382
+ },
383
+ ],
384
+ defaultVariants: {
385
+ variant: 'solid',
386
+ color: 'primary',
387
+ },
388
+ });
389
+
390
+ export const buttonGroupVariants = cva([], {
391
+ variants: {
392
+ flexDirection: {
393
+ row: Platform.select({ web: 'flex-row', default: '' }),
394
+ column: Platform.select({ web: 'flex-col', default: '' }),
395
+ 'row-reverse': Platform.select({ web: 'flex-row-reverse', default: '' }),
396
+ 'column-reverse': Platform.select({ web: 'flex-col-reverse', default: '' }),
397
+ },
398
+ isAttached: {
399
+ true: 'gap-0',
400
+ false: 'gap-2',
401
+ },
402
+ },
403
+ defaultVariants: {
404
+ flexDirection: 'row',
405
+ isAttached: false,
406
+ },
407
+ });
408
+
409
+ export type ButtonVariantProps = VariantProps<typeof buttonRootVariants>;
410
+ export type ButtonGroupVariantProps = VariantProps<typeof buttonGroupVariants>;
@@ -0,0 +1 @@
1
+ export { TextInput as BaseInput } from 'react-native';
@@ -0,0 +1,41 @@
1
+ import React, { forwardRef } from 'react';
2
+ import { TextInput } from 'react-native';
3
+
4
+ export const BaseInput = forwardRef<any, any>((props, ref) => {
5
+ if (props.type === 'file') {
6
+ return React.createElement('input', {
7
+ ref,
8
+ type: 'file',
9
+ accept: props.accept || undefined,
10
+ multiple: props.multiple || undefined,
11
+ capture: props.capture || undefined,
12
+ disabled: props.disabled || undefined,
13
+ 'aria-label': props['aria-label'],
14
+ 'aria-required': props['aria-required'] || undefined,
15
+ 'aria-invalid': props['aria-invalid'] || undefined,
16
+ 'aria-disabled': props['aria-disabled'] || undefined,
17
+ onChange: (e: any) => {
18
+ const files = e.target.files;
19
+ if (files && props.onFiles) {
20
+ props.onFiles(Array.from(files));
21
+ }
22
+ },
23
+ onFocus: props.onFocus,
24
+ onBlur: props.onBlur,
25
+ style: {
26
+ flex: 1,
27
+ minWidth: 0,
28
+ border: 'none',
29
+ outline: 'none',
30
+ background: 'transparent',
31
+ cursor: props.disabled ? 'not-allowed' : 'pointer',
32
+ fontSize: 'inherit',
33
+ fontFamily: 'inherit',
34
+ },
35
+ });
36
+ }
37
+
38
+ return <TextInput ref={ref} {...props} />;
39
+ });
40
+
41
+ BaseInput.displayName = 'BaseInput';
@@ -0,0 +1,161 @@
1
+ import { forwardRef, type ReactNode } from 'react';
2
+ import { type TextInput, View, type ViewProps } from 'react-native';
3
+ import {
4
+ createInput,
5
+ type IInputFieldProps,
6
+ type IInputProps,
7
+ type IInputSlotProps,
8
+ } from '@cdx-ui/primitives';
9
+ import { cn, useStyleContext, withStyleContext } from '@cdx-ui/utils';
10
+ import { BaseInput } from './BaseInput';
11
+ import {
12
+ type InputVariantProps,
13
+ inputFieldPlaceholderVariants,
14
+ inputFieldVariants,
15
+ inputIconVariants,
16
+ inputRootVariants,
17
+ inputSlotVariants,
18
+ } from './styles';
19
+
20
+ const SCOPE = 'INPUT';
21
+
22
+ const Root = withStyleContext(View, SCOPE);
23
+
24
+ const useInputStyleContext = () => useStyleContext(SCOPE) as InputVariantProps;
25
+
26
+ const InputPrimitive = createInput({
27
+ Root,
28
+ Icon: View,
29
+ Slot: View,
30
+ Field: BaseInput,
31
+ });
32
+
33
+ // =============================================================================
34
+ // INPUT (ROOT)
35
+ // =============================================================================
36
+
37
+ export interface InputProps extends ViewProps, IInputFieldProps, InputVariantProps {
38
+ className?: string;
39
+ children?: ReactNode;
40
+ }
41
+
42
+ const InputRoot = forwardRef<View, InputProps>(
43
+ ({ variant = 'outline', size = 'md', className, children, style, ...props }, ref) => {
44
+ const computedClassName = cn(inputRootVariants({ variant, size }), className);
45
+
46
+ return (
47
+ <InputPrimitive
48
+ ref={ref}
49
+ className={computedClassName}
50
+ style={style}
51
+ context={{ variant, size }}
52
+ {...props}
53
+ >
54
+ {children}
55
+ </InputPrimitive>
56
+ );
57
+ },
58
+ );
59
+
60
+ InputRoot.displayName = 'Input';
61
+
62
+ // =============================================================================
63
+ // INPUT FIELD
64
+ // =============================================================================
65
+
66
+ export type InputFieldProps = IInputProps & {
67
+ className?: string;
68
+ placeholderTextColorClassName?: string;
69
+ };
70
+
71
+ const InputField = forwardRef<TextInput, InputFieldProps>(
72
+ ({ className, placeholderTextColorClassName, style, ...rest }, ref) => {
73
+ const { size } = useInputStyleContext();
74
+
75
+ const computedClassName = cn(inputFieldVariants({ size }), className);
76
+ const computedPlaceholderColorClassName = cn(
77
+ inputFieldPlaceholderVariants(),
78
+ placeholderTextColorClassName,
79
+ );
80
+
81
+ return (
82
+ <InputPrimitive.Field
83
+ ref={ref}
84
+ className={computedClassName}
85
+ placeholderTextColorClassName={computedPlaceholderColorClassName}
86
+ style={style}
87
+ {...rest}
88
+ />
89
+ );
90
+ },
91
+ );
92
+
93
+ InputField.displayName = 'Input.Field';
94
+
95
+ // =============================================================================
96
+ // INPUT SLOT
97
+ // =============================================================================
98
+
99
+ export interface InputSlotProps extends ViewProps, IInputSlotProps {
100
+ className?: string;
101
+ children?: ReactNode;
102
+ }
103
+
104
+ const InputSlot = forwardRef<View, InputSlotProps>(
105
+ ({ className, children, style, ...props }, ref) => {
106
+ const { size } = useInputStyleContext();
107
+
108
+ const computedClassName = cn(inputSlotVariants({ size }), className);
109
+
110
+ return (
111
+ <InputPrimitive.Slot ref={ref} className={computedClassName} style={style} {...props}>
112
+ {children}
113
+ </InputPrimitive.Slot>
114
+ );
115
+ },
116
+ );
117
+
118
+ InputSlot.displayName = 'Input.Slot';
119
+
120
+ // =============================================================================
121
+ // INPUT ICON
122
+ // =============================================================================
123
+
124
+ export interface InputIconProps extends ViewProps {
125
+ className?: string;
126
+ children?: ReactNode;
127
+ }
128
+
129
+ const InputIcon = forwardRef<View, InputIconProps>(
130
+ ({ className, children, style, ...props }, ref) => {
131
+ const { size } = useInputStyleContext();
132
+
133
+ const computedClassName = cn(inputIconVariants({ size }), className);
134
+
135
+ return (
136
+ <InputPrimitive.Icon ref={ref} className={computedClassName} style={style} {...props}>
137
+ {children}
138
+ </InputPrimitive.Icon>
139
+ );
140
+ },
141
+ );
142
+
143
+ InputIcon.displayName = 'Input.Icon';
144
+
145
+ // =============================================================================
146
+ // COMPOUND EXPORT
147
+ // =============================================================================
148
+
149
+ type InputCompoundComponent = typeof InputRoot & {
150
+ Field: typeof InputField;
151
+ Slot: typeof InputSlot;
152
+ Icon: typeof InputIcon;
153
+ };
154
+
155
+ export const Input = Object.assign(InputRoot, {
156
+ Field: InputField,
157
+ Slot: InputSlot,
158
+ Icon: InputIcon,
159
+ }) as InputCompoundComponent;
160
+
161
+ export type { InputVariantProps };
@@ -0,0 +1,83 @@
1
+ import { cva, type VariantProps } from 'class-variance-authority';
2
+
3
+ export const inputRootVariants = cva(
4
+ [
5
+ 'w-full flex-row items-center',
6
+ 'border border-neutral-border-strong bg-neutral-surface shadow-sm',
7
+ 'data-[disabled=true]:opacity-60 data-[disabled=true]:cursor-not-allowed data-[disabled=true]:bg-interactive-disabled-background data-[disabled=true]:border-interactive-disabled',
8
+ 'data-[focus=true]:border-interactive-focus',
9
+ 'data-[invalid=true]:border-red-500',
10
+ ],
11
+ {
12
+ variants: {
13
+ variant: {
14
+ outline: [
15
+ 'rounded-md px-3',
16
+ 'web:focus-within:border-interactive-focus web:focus-within:ring-3 web:focus-within:ring-blue-300/50',
17
+ 'web:data-[invalid=true]:focus-within:border-red-500 web:data-[invalid=true]:focus-within:ring-red-300/50',
18
+ ],
19
+ underlined:
20
+ 'rounded-none border-t-0 border-l-0 border-r-0 border-b-neutral-border data-[focus=true]:border-b-interactive-focus shadow-none',
21
+ },
22
+ size: {
23
+ sm: 'h-9 py-1',
24
+ md: 'h-11 py-1.5',
25
+ lg: 'h-12 py-2',
26
+ },
27
+ },
28
+ defaultVariants: {
29
+ variant: 'outline',
30
+ size: 'md',
31
+ },
32
+ },
33
+ );
34
+
35
+ export const inputFieldVariants = cva(
36
+ [
37
+ 'flex-1 bg-transparent text-neutral-text-primary',
38
+ 'placeholder:text-neutral-placeholder',
39
+ 'web:outline-none',
40
+ ],
41
+ {
42
+ variants: {
43
+ size: {
44
+ sm: 'text-sm leading-none',
45
+ md: 'text-base leading-none',
46
+ lg: 'text-lg leading-none',
47
+ },
48
+ },
49
+ defaultVariants: {
50
+ size: 'sm',
51
+ },
52
+ },
53
+ );
54
+
55
+ export const inputSlotVariants = cva(['items-center justify-center'], {
56
+ variants: {
57
+ size: {
58
+ sm: 'h-4 w-4',
59
+ md: 'h-5 w-5',
60
+ lg: 'h-6 w-6',
61
+ },
62
+ },
63
+ defaultVariants: {
64
+ size: 'sm',
65
+ },
66
+ });
67
+
68
+ export const inputIconVariants = cva(['text-neutral-text-tertiary'], {
69
+ variants: {
70
+ size: {
71
+ sm: 'h-4 w-4',
72
+ md: 'h-5 w-5',
73
+ lg: 'h-5 w-5',
74
+ },
75
+ },
76
+ defaultVariants: {
77
+ size: 'sm',
78
+ },
79
+ });
80
+
81
+ export const inputFieldPlaceholderVariants = cva(['accent-neutral-placeholder']);
82
+
83
+ export type InputVariantProps = VariantProps<typeof inputRootVariants>;