@herca/rn-kit 0.1.100 → 0.1.102
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/lib/module/Icon/Icon.js +17 -1
- package/lib/module/Icon/Icon.js.map +1 -1
- package/lib/module/Icon/icons/BarCode.js +22 -0
- package/lib/module/Icon/icons/BarCode.js.map +1 -0
- package/lib/module/Icon/icons/BoxSearchOutline.js +22 -0
- package/lib/module/Icon/icons/BoxSearchOutline.js.map +1 -0
- package/lib/module/Icon/icons/CubeScan.js +34 -0
- package/lib/module/Icon/icons/CubeScan.js.map +1 -0
- package/lib/module/Icon/icons/Devices.js +27 -0
- package/lib/module/Icon/icons/Devices.js.map +1 -0
- package/lib/module/Icon/icons/Global.js +46 -0
- package/lib/module/Icon/icons/Global.js.map +1 -0
- package/lib/module/Icon/icons/Hierarchy3.js +31 -0
- package/lib/module/Icon/icons/Hierarchy3.js.map +1 -0
- package/lib/module/Icon/icons/ScanQr.js +22 -0
- package/lib/module/Icon/icons/ScanQr.js.map +1 -0
- package/lib/module/Icon/icons/UserSquareOutline.js +25 -0
- package/lib/module/Icon/icons/UserSquareOutline.js.map +1 -0
- package/lib/module/Input/InputFile.js +178 -68
- package/lib/module/Input/InputFile.js.map +1 -1
- package/lib/module/Input/README_INPUT_FILE.md +179 -105
- package/lib/module/Input/TextArea.js +2 -0
- package/lib/module/Input/TextArea.js.map +1 -1
- package/lib/module/Input/helpers/uploadFile.js +60 -0
- package/lib/module/Input/helpers/uploadFile.js.map +1 -0
- package/lib/module/Input/partials/InputFile/CardTriggerSmall.js +1 -0
- package/lib/module/Input/partials/InputFile/CardTriggerSmall.js.map +1 -1
- package/lib/module/Input/partials/InputFile/ItemPreview.js +15 -4
- package/lib/module/Input/partials/InputFile/ItemPreview.js.map +1 -1
- package/lib/module/Tab/Tab.js +3 -1
- package/lib/module/Tab/Tab.js.map +1 -1
- package/lib/typescript/src/Icon/Icon.d.ts.map +1 -1
- package/lib/typescript/src/Icon/icons/BarCode.d.ts +9 -0
- package/lib/typescript/src/Icon/icons/BarCode.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/BoxSearchOutline.d.ts +9 -0
- package/lib/typescript/src/Icon/icons/BoxSearchOutline.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/CubeScan.d.ts +9 -0
- package/lib/typescript/src/Icon/icons/CubeScan.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/Devices.d.ts +8 -0
- package/lib/typescript/src/Icon/icons/Devices.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/Global.d.ts +9 -0
- package/lib/typescript/src/Icon/icons/Global.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/Hierarchy3.d.ts +9 -0
- package/lib/typescript/src/Icon/icons/Hierarchy3.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/ScanQr.d.ts +9 -0
- package/lib/typescript/src/Icon/icons/ScanQr.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/UserSquareOutline.d.ts +9 -0
- package/lib/typescript/src/Icon/icons/UserSquareOutline.d.ts.map +1 -0
- package/lib/typescript/src/Icon/type.d.ts +1 -1
- package/lib/typescript/src/Icon/type.d.ts.map +1 -1
- package/lib/typescript/src/Input/InputFile.d.ts +3 -48
- package/lib/typescript/src/Input/InputFile.d.ts.map +1 -1
- package/lib/typescript/src/Input/TextArea.d.ts +1 -1
- package/lib/typescript/src/Input/TextArea.d.ts.map +1 -1
- package/lib/typescript/src/Input/helpers/uploadFile.d.ts +3 -0
- package/lib/typescript/src/Input/helpers/uploadFile.d.ts.map +1 -0
- package/lib/typescript/src/Input/partials/InputFile/CardTriggerSmall.d.ts.map +1 -1
- package/lib/typescript/src/Input/partials/InputFile/ItemPreview.d.ts +4 -2
- package/lib/typescript/src/Input/partials/InputFile/ItemPreview.d.ts.map +1 -1
- package/lib/typescript/src/Input/type.d.ts +91 -0
- package/lib/typescript/src/Input/type.d.ts.map +1 -1
- package/lib/typescript/src/Tab/Tab.d.ts.map +1 -1
- package/lib/typescript/src/Tab/type.d.ts +2 -0
- package/lib/typescript/src/Tab/type.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/Icon/Icon.tsx +16 -0
- package/src/Icon/icons/BarCode.tsx +19 -0
- package/src/Icon/icons/BoxSearchOutline.tsx +23 -0
- package/src/Icon/icons/CubeScan.tsx +35 -0
- package/src/Icon/icons/Devices.tsx +26 -0
- package/src/Icon/icons/Global.tsx +55 -0
- package/src/Icon/icons/Hierarchy3.tsx +31 -0
- package/src/Icon/icons/ScanQr.tsx +19 -0
- package/src/Icon/icons/UserSquareOutline.tsx +27 -0
- package/src/Icon/type.tsx +9 -1
- package/src/Input/InputFile.tsx +235 -111
- package/src/Input/README_INPUT_FILE.md +179 -105
- package/src/Input/TextArea.tsx +2 -1
- package/src/Input/helpers/uploadFile.ts +77 -0
- package/src/Input/partials/InputFile/CardTriggerSmall.tsx +1 -0
- package/src/Input/partials/InputFile/ItemPreview.tsx +25 -4
- package/src/Input/type.tsx +105 -0
- package/src/Tab/Tab.tsx +2 -0
- package/src/Tab/type.tsx +5 -0
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
# 📂 InputFile Component
|
|
2
2
|
|
|
3
|
-
Komponen `InputFile` digunakan untuk mengunggah, menampilkan, mengganti, menghapus
|
|
4
|
-
Mendukung **camera**, **gallery**, dan **document picker** dengan tampilan preview dan konfirmasi aksi.
|
|
3
|
+
Komponen `InputFile` digunakan untuk mengunggah, menampilkan, mengganti, dan menghapus dokumen atau gambar di aplikasi React Native. Mendukung **camera**, **gallery**, dan **document picker** dengan fitur upload otomatis ke server, validasi ukuran file, loading state, dan konfirmasi aksi.
|
|
5
4
|
|
|
6
5
|
---
|
|
7
6
|
|
|
8
7
|
## ✨ Fitur
|
|
9
8
|
|
|
10
9
|
- Upload file dari **kamera**, **galeri**, atau **dokumen perangkat**.
|
|
10
|
+
- **Auto-upload ke server** setiap kali file dipilih via `uploadConfig`.
|
|
11
|
+
- **Validasi ukuran file** per file sebelum diproses.
|
|
12
|
+
- **Loading state** (`uploading: true`) selama proses upload berlangsung.
|
|
13
|
+
- **Error state** otomatis jika upload gagal (HTTP error / network error).
|
|
11
14
|
- Preview file (gambar atau dokumen).
|
|
12
15
|
- Mendukung **multiple file upload**.
|
|
13
16
|
- Ganti file (replace) atau hapus file dengan konfirmasi.
|
|
@@ -20,17 +23,18 @@ Mendukung **camera**, **gallery**, dan **document picker** dengan tampilan previ
|
|
|
20
23
|
|
|
21
24
|
## 📦 Dependencies
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
| Library | Kegunaan |
|
|
27
|
+
| ----------------------------------------------------------------------------------------------------- | ------------------------------- |
|
|
28
|
+
| [`@react-native-documents/picker`](https://github.com/react-native-documents/picker) | Pick file dari storage |
|
|
29
|
+
| [`@react-native-documents/viewer`](https://github.com/react-native-documents/viewer) | Preview dokumen |
|
|
30
|
+
| [`react-native-image-picker`](https://github.com/react-native-image-picker/react-native-image-picker) | Akses kamera & galeri |
|
|
31
|
+
| [`react-native-blob-util`](https://github.com/RonRadtke/react-native-blob-util) | Upload file multipart ke server |
|
|
28
32
|
|
|
29
33
|
---
|
|
30
34
|
|
|
31
35
|
## 🚀 Penggunaan
|
|
32
36
|
|
|
33
|
-
### Variant Default (
|
|
37
|
+
### Variant Default (tanpa upload otomatis)
|
|
34
38
|
|
|
35
39
|
```tsx
|
|
36
40
|
import InputFile from '@/components/Input/InputFile';
|
|
@@ -41,7 +45,6 @@ export default function ExampleScreen() {
|
|
|
41
45
|
|
|
42
46
|
return (
|
|
43
47
|
<InputFile
|
|
44
|
-
variant="default" // atau bisa dihilangkan (default)
|
|
45
48
|
title="Upload Dokumen"
|
|
46
49
|
description="Format file: JPG, PNG, PDF"
|
|
47
50
|
hint="Maksimal ukuran file 5MB"
|
|
@@ -54,25 +57,46 @@ export default function ExampleScreen() {
|
|
|
54
57
|
label: 'Nama Dokumen',
|
|
55
58
|
placeholder: 'Masukkan nama dokumen',
|
|
56
59
|
}}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
onChange={(newFiles) => setFiles(newFiles)}
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Variant Default (dengan auto-upload ke server)
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
import InputFile from '@/components/Input/InputFile';
|
|
70
|
+
import { useState } from 'react';
|
|
71
|
+
|
|
72
|
+
export default function ExampleScreen() {
|
|
73
|
+
const [files, setFiles] = useState<any[]>([]);
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<InputFile
|
|
77
|
+
title="Upload KTP"
|
|
78
|
+
description="Format file: JPG, PNG, PDF. Maksimal 5MB."
|
|
79
|
+
multiple={false}
|
|
80
|
+
value={files}
|
|
81
|
+
uploadConfig={{
|
|
82
|
+
url: 'https://api.example.com/upload',
|
|
83
|
+
method: 'POST',
|
|
84
|
+
fieldName: 'file',
|
|
85
|
+
headers: { Authorization: 'Bearer your-token' },
|
|
86
|
+
maxSize: 5 * 1024 * 1024, // 5MB
|
|
87
|
+
maxSizeErrorMessage: 'File tidak boleh lebih dari 5MB',
|
|
88
|
+
errorMessage: 'Gagal mengupload file, coba lagi',
|
|
89
|
+
onUploadSuccess: (results) => {
|
|
90
|
+
console.log('Upload berhasil:', results);
|
|
65
91
|
},
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
title: 'Hapus File?',
|
|
69
|
-
description: 'Apakah kamu yakin ingin menghapus file ini?',
|
|
70
|
-
confirmBtn: {
|
|
71
|
-
confirm: 'Ya, Hapus',
|
|
72
|
-
cancel: 'Batal',
|
|
92
|
+
onError: (file, errorMsg) => {
|
|
93
|
+
console.warn('Upload gagal:', file, errorMsg);
|
|
73
94
|
},
|
|
74
95
|
}}
|
|
75
|
-
onChange={(
|
|
96
|
+
onChange={(updatedFiles) => {
|
|
97
|
+
// updatedFiles berisi FileItem[] dengan uploadedData dari server
|
|
98
|
+
setFiles(updatedFiles);
|
|
99
|
+
}}
|
|
76
100
|
/>
|
|
77
101
|
);
|
|
78
102
|
}
|
|
@@ -96,7 +120,7 @@ export default function ExampleScreen() {
|
|
|
96
120
|
value={files}
|
|
97
121
|
hasError={false}
|
|
98
122
|
onChange={(newFiles) => setFiles(newFiles)}
|
|
99
|
-
// ❌ description, hint, useChangeLabel, changeLableProps
|
|
123
|
+
// ❌ description, hint, useChangeLabel, changeLableProps tidak tersedia di variant small
|
|
100
124
|
/>
|
|
101
125
|
);
|
|
102
126
|
}
|
|
@@ -108,80 +132,99 @@ export default function ExampleScreen() {
|
|
|
108
132
|
|
|
109
133
|
### Base Props (Tersedia di Semua Variant)
|
|
110
134
|
|
|
111
|
-
| Prop | Tipe
|
|
112
|
-
| ------------------- |
|
|
113
|
-
| `title` | `string`
|
|
114
|
-
| `accept` | `string[]`
|
|
115
|
-
| `multiple` | `boolean`
|
|
116
|
-
| `value` | `any[]`
|
|
117
|
-
| `onChange` | `(files: any[]) => void`
|
|
118
|
-
| `btnChooseFileText` | `string`
|
|
119
|
-
| `
|
|
120
|
-
| `
|
|
121
|
-
| `
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
|
128
|
-
|
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
| `
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
#### Small Variant (`variant: 'small'`)
|
|
135
|
+
| Prop | Tipe | Default | Deskripsi |
|
|
136
|
+
| ------------------- | -------------------------- | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
137
|
+
| `title` | `string` | `"Upload File"` | Judul input file. |
|
|
138
|
+
| `accept` | `string[]` | `["application/pdf", "image/jpeg", "image/png"]` | Tipe MIME file yang diizinkan. |
|
|
139
|
+
| `multiple` | `boolean` | `false` | Jika `true`, memungkinkan memilih banyak file sekaligus. |
|
|
140
|
+
| `value` | `any[]` | `[]` | Daftar file yang sudah dipilih (state dari parent). |
|
|
141
|
+
| `onChange` | `(files: any[]) => void` | `undefined` | Callback saat daftar file berubah (add, replace, delete). Menerima `FileItem[]` (dengan `uploadedData` jika `uploadConfig` diset). |
|
|
142
|
+
| `btnChooseFileText` | `string` | `"Choose File"` | Label tombol untuk memilih file. |
|
|
143
|
+
| `uploadConfig` | `UploadConfig` | `undefined` | Konfigurasi upload otomatis ke server. Jika tidak diset, file hanya disimpan di local state. |
|
|
144
|
+
| `modalPickFileText` | `ModalPickFileText` | `undefined` | Teks kustom pada modal pemilihan sumber file. |
|
|
145
|
+
| `modalDeleteText` | `ModalOption & confirmBtn` | `undefined` | Teks kustom pada modal konfirmasi hapus file. |
|
|
146
|
+
| `hasError` | `boolean` | `false` | Menampilkan state error pada input. |
|
|
147
|
+
|
|
148
|
+
### Default Variant Props (`variant?: 'default'`)
|
|
149
|
+
|
|
150
|
+
| Prop | Tipe | Default | Deskripsi |
|
|
151
|
+
| ------------------ | ------------------ | ----------------------------------------- | ------------------------------------------------------------ |
|
|
152
|
+
| `variant` | `'default'` | `'default'` | Variant default dengan fitur lengkap. |
|
|
153
|
+
| `description` | `string` | `"File harus berformat JPG, PNG dan PDF"` | Deskripsi singkat tentang file yang diterima. |
|
|
154
|
+
| `hint` | `string` | `undefined` | Teks hint tambahan di bawah input. |
|
|
155
|
+
| `useChangeLabel` | `boolean` | `false` | Jika `true`, menampilkan input untuk memberi nama pada file. |
|
|
156
|
+
| `changeLableProps` | `ChangeLabelProps` | `undefined` | Kustomisasi label dan placeholder input nama dokumen. |
|
|
157
|
+
|
|
158
|
+
### Small Variant Props (`variant: 'small'`)
|
|
136
159
|
|
|
137
160
|
| Prop | Tipe | Default | Deskripsi |
|
|
138
161
|
| --------- | --------- | ------- | ------------------------------------- |
|
|
139
|
-
| `variant` | `'small'` |
|
|
162
|
+
| `variant` | `'small'` | — | Variant compact tanpa fitur tambahan. |
|
|
140
163
|
|
|
141
|
-
> ⚠️
|
|
164
|
+
> ⚠️ Props `description`, `hint`, `useChangeLabel`, dan `changeLableProps` **tidak tersedia** di variant `small`. TypeScript akan error jika props ini digunakan bersama `variant: 'small'`.
|
|
142
165
|
|
|
143
166
|
---
|
|
144
167
|
|
|
145
|
-
##
|
|
168
|
+
## 🔧 UploadConfig
|
|
146
169
|
|
|
147
|
-
|
|
170
|
+
Konfigurasi untuk mengaktifkan auto-upload ke server setiap kali file dipilih.
|
|
148
171
|
|
|
149
172
|
```ts
|
|
150
|
-
interface
|
|
151
|
-
|
|
152
|
-
|
|
173
|
+
interface UploadConfig {
|
|
174
|
+
url: string;
|
|
175
|
+
method?: 'POST' | 'PUT' | 'PATCH'; // default: 'POST'
|
|
176
|
+
fieldName?: string; // default: 'file'
|
|
177
|
+
headers?: Record<string, string>;
|
|
178
|
+
maxSize?: number; // dalam bytes, misal 5MB = 5 * 1024 * 1024
|
|
179
|
+
maxSizeErrorMessage?: string; // pesan error jika file melebihi maxSize
|
|
180
|
+
errorMessage?: string; // pesan error jika upload gagal
|
|
181
|
+
onUploadSuccess?: (results: UploadedFile<unknown>[]) => void;
|
|
182
|
+
onError?: (file: FileItem, error: string) => void;
|
|
153
183
|
}
|
|
154
184
|
```
|
|
155
185
|
|
|
156
|
-
###
|
|
186
|
+
### Alur Upload
|
|
157
187
|
|
|
158
|
-
```ts
|
|
159
|
-
interface ModalPickFileText {
|
|
160
|
-
title?: string;
|
|
161
|
-
description?: string;
|
|
162
|
-
camera?: ModalOption;
|
|
163
|
-
gallery?: ModalOption;
|
|
164
|
-
document?: ModalOption;
|
|
165
|
-
}
|
|
166
188
|
```
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
};
|
|
176
|
-
};
|
|
189
|
+
User pick file
|
|
190
|
+
→ validasi maxSize
|
|
191
|
+
→ gagal: tampilkan internalErrorMessage, stop
|
|
192
|
+
→ lolos: set uploading: true di UI
|
|
193
|
+
→ upload ke server
|
|
194
|
+
→ sukses: set uploadedData, uploading: false
|
|
195
|
+
→ gagal (HTTP error / network): set error: true, hint: errorMessage, uploading: false
|
|
196
|
+
→ onChange dipanggil dengan FileItem[] terbaru
|
|
177
197
|
```
|
|
178
198
|
|
|
179
|
-
### `
|
|
199
|
+
### Data yang diterima `onChange` saat uploadConfig aktif
|
|
200
|
+
|
|
201
|
+
`onChange` menerima `FileItem[]` dimana setiap item berisi data asli file **plus** `uploadedData` dari server:
|
|
180
202
|
|
|
181
203
|
```ts
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
204
|
+
// contoh item di dalam array onChange
|
|
205
|
+
{
|
|
206
|
+
// data asli dari picker/camera/gallery
|
|
207
|
+
uri: "file:///...",
|
|
208
|
+
fileName: "foto.jpg",
|
|
209
|
+
fileSize: 105629,
|
|
210
|
+
width: 562,
|
|
211
|
+
height: 1000,
|
|
212
|
+
type: "image/jpg",
|
|
213
|
+
|
|
214
|
+
// ditambahkan oleh komponen
|
|
215
|
+
uploading: false,
|
|
216
|
+
error: false,
|
|
217
|
+
uploadedData: {
|
|
218
|
+
message: "File berhasil diunggah",
|
|
219
|
+
data: {
|
|
220
|
+
url: "https://cdn.example.com/uploads/foto.jpg",
|
|
221
|
+
path: "uploads/foto.jpg",
|
|
222
|
+
name: "foto.jpg",
|
|
223
|
+
extension: "jpg",
|
|
224
|
+
size: 105629,
|
|
225
|
+
mime_type: "image/jpeg"
|
|
226
|
+
}
|
|
227
|
+
}
|
|
185
228
|
}
|
|
186
229
|
```
|
|
187
230
|
|
|
@@ -208,12 +251,58 @@ export interface ChangeLabelProps {
|
|
|
208
251
|
placeholder?: string;
|
|
209
252
|
}
|
|
210
253
|
|
|
254
|
+
export interface PickedFile {
|
|
255
|
+
uri: string;
|
|
256
|
+
name: string;
|
|
257
|
+
type: string;
|
|
258
|
+
size?: number;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export interface ImageAsset {
|
|
262
|
+
uri?: string;
|
|
263
|
+
fileName?: string;
|
|
264
|
+
type?: string;
|
|
265
|
+
fileSize?: number;
|
|
266
|
+
width?: number;
|
|
267
|
+
height?: number;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export interface UploadedFile<UploadedData> {
|
|
271
|
+
id: string;
|
|
272
|
+
originalName: string;
|
|
273
|
+
customName?: string;
|
|
274
|
+
uploadedData: UploadedData | null;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export interface UploadConfig {
|
|
278
|
+
url: string;
|
|
279
|
+
method?: 'POST' | 'PUT' | 'PATCH';
|
|
280
|
+
fieldName?: string;
|
|
281
|
+
headers?: Record<string, string>;
|
|
282
|
+
maxSize?: number;
|
|
283
|
+
maxSizeErrorMessage?: string;
|
|
284
|
+
errorMessage?: string;
|
|
285
|
+
onUploadSuccess?: (results: UploadedFile<unknown>[]) => void;
|
|
286
|
+
onError?: (file: FileItem, error: string) => void;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export type FileItemExtras = {
|
|
290
|
+
labelFile?: string;
|
|
291
|
+
hint?: string;
|
|
292
|
+
error?: boolean;
|
|
293
|
+
uploading?: boolean;
|
|
294
|
+
uploadedData?: unknown;
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
export type FileItem = (PickedFile | ImageAsset) & FileItemExtras;
|
|
298
|
+
|
|
211
299
|
type BaseInputFileProps = {
|
|
212
300
|
title?: string;
|
|
213
301
|
accept?: string[];
|
|
214
302
|
multiple?: boolean;
|
|
215
303
|
onChange?: (files: any) => void;
|
|
216
304
|
value?: any[];
|
|
305
|
+
uploadConfig?: UploadConfig;
|
|
217
306
|
modalPickFileText?: ModalPickFileText;
|
|
218
307
|
btnChooseFileText?: string;
|
|
219
308
|
modalDeleteText?: ModalOption & {
|
|
@@ -246,29 +335,14 @@ type InputFileProps = DefaultVariantProps | SmallVariantProps;
|
|
|
246
335
|
|
|
247
336
|
---
|
|
248
337
|
|
|
249
|
-
### Variant Default
|
|
250
|
-
|
|
251
|
-
- **Card input awal** → tombol pilih file + icon ilustrasi + description + hint.
|
|
252
|
-
- **Preview file** → menampilkan nama, ukuran, icon (atau thumbnail jika image).
|
|
253
|
-
- **Input label** (jika `useChangeLabel: true`) → input text untuk memberi nama dokumen.
|
|
254
|
-
- **Aksi file**:
|
|
255
|
-
- 🔄 Replace
|
|
256
|
-
- ❌ Delete
|
|
257
|
-
- 👁 Preview (buka dokumen dengan `viewDocument`)
|
|
258
|
-
|
|
259
|
-
### Variant Small
|
|
260
|
-
|
|
261
|
-
- **Compact card** → tombol pilih file dengan tampilan lebih ringkas.
|
|
262
|
-
- **Preview file** → tampilan minimal tanpa label/hint tambahan.
|
|
263
|
-
- **Aksi file**: sama seperti variant default (replace, delete, preview).
|
|
264
|
-
|
|
265
|
-
---
|
|
266
|
-
|
|
267
338
|
## 🛠 Catatan
|
|
268
339
|
|
|
269
|
-
1. Pastikan permission kamera & storage sudah diatur (
|
|
270
|
-
2.
|
|
271
|
-
3.
|
|
272
|
-
4.
|
|
273
|
-
5.
|
|
274
|
-
6.
|
|
340
|
+
1. Pastikan permission kamera & storage sudah diatur di `Info.plist` (iOS) dan `AndroidManifest.xml` (Android).
|
|
341
|
+
2. `uploadConfig.maxSize` divalidasi **sebelum** file diupload. File yang melebihi batas tidak akan diproses sama sekali.
|
|
342
|
+
3. Upload menggunakan `multipart/form-data`. Pastikan server menerima format ini.
|
|
343
|
+
4. HTTP error (4xx, 5xx) akan di-treat sebagai upload gagal — `uploadedData` akan bernilai `null` dan `error: true` di-set pada file tersebut.
|
|
344
|
+
5. Saat `uploading: true`, komponen menampilkan loading indicator di preview file. Pastikan `ItemPreview` menangani prop ini.
|
|
345
|
+
6. `useEffect` yang sync `value` ke internal state tidak akan berjalan selama ada file yang sedang uploading, untuk mencegah state reset di tengah proses upload.
|
|
346
|
+
7. Untuk **multiple upload**, semua file diupload secara paralel via `Promise.all`.
|
|
347
|
+
8. **Variant `small`** cocok untuk form compact tanpa deskripsi dan hint tambahan.
|
|
348
|
+
9. **Variant `default`** cocok untuk form yang membutuhkan instruksi detail dan fitur labeling dokumen.
|
|
@@ -12,6 +12,7 @@ export default function TextArea({
|
|
|
12
12
|
style,
|
|
13
13
|
hint,
|
|
14
14
|
onChangeText,
|
|
15
|
+
required,
|
|
15
16
|
...props
|
|
16
17
|
}) {
|
|
17
18
|
const handleOnChangeText = value => {
|
|
@@ -20,6 +21,7 @@ export default function TextArea({
|
|
|
20
21
|
return /*#__PURE__*/_jsxs(View, {
|
|
21
22
|
style: styles.gap,
|
|
22
23
|
children: [label ? /*#__PURE__*/_jsx(LabelForm, {
|
|
24
|
+
required: required,
|
|
23
25
|
title: label
|
|
24
26
|
}) : null, /*#__PURE__*/_jsx(View, {
|
|
25
27
|
style: [styles.container, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["StyleSheet","TextInput","View","LabelForm","Color","Typography","jsx","_jsx","jsxs","_jsxs","TextArea","height","label","hasError","style","hint","onChangeText","props","handleOnChangeText","value","styles","gap","children","title","container","borderColor","danger","gray","editable","multiline","numberOfLines","input","textAlignVertical","placeholderTextColor","color","variant","create","position","borderRadius","borderWidth","backgroundColor","base","white100","fontSize","padding","flex"],"sourceRoot":"../../../src","sources":["Input/TextArea.tsx"],"mappings":";;AAAA,SAASA,UAAU,EAAEC,SAAS,EAAEC,IAAI,QAAQ,cAAc;AAC1D,OAAOC,SAAS,MAAM,2BAAwB;AAC9C,OAAOC,KAAK,MAAM,mBAAgB;AAClC,OAAOC,UAAU,MAAM,6BAA0B;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAGlD,eAAe,SAASC,QAAQA,CAAC;EAC/BC,MAAM,GAAG,GAAG;EACZC,KAAK;EACLC,QAAQ;EACRC,KAAK;EACLC,IAAI;EACJC,YAAY;
|
|
1
|
+
{"version":3,"names":["StyleSheet","TextInput","View","LabelForm","Color","Typography","jsx","_jsx","jsxs","_jsxs","TextArea","height","label","hasError","style","hint","onChangeText","required","props","handleOnChangeText","value","styles","gap","children","title","container","borderColor","danger","gray","editable","multiline","numberOfLines","input","textAlignVertical","placeholderTextColor","color","variant","create","position","borderRadius","borderWidth","backgroundColor","base","white100","fontSize","padding","flex"],"sourceRoot":"../../../src","sources":["Input/TextArea.tsx"],"mappings":";;AAAA,SAASA,UAAU,EAAEC,SAAS,EAAEC,IAAI,QAAQ,cAAc;AAC1D,OAAOC,SAAS,MAAM,2BAAwB;AAC9C,OAAOC,KAAK,MAAM,mBAAgB;AAClC,OAAOC,UAAU,MAAM,6BAA0B;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAGlD,eAAe,SAASC,QAAQA,CAAC;EAC/BC,MAAM,GAAG,GAAG;EACZC,KAAK;EACLC,QAAQ;EACRC,KAAK;EACLC,IAAI;EACJC,YAAY;EACZC,QAAQ;EACR,GAAGC;AACU,CAAC,EAAE;EAChB,MAAMC,kBAAkB,GAAIC,KAAa,IAAK;IAC5CJ,YAAY,GAAGI,KAAK,CAAC;EACvB,CAAC;EAED,oBACEX,KAAA,CAACP,IAAI;IAACY,KAAK,EAAEO,MAAM,CAACC,GAAI;IAAAC,QAAA,GACrBX,KAAK,gBAAGL,IAAA,CAACJ,SAAS;MAACc,QAAQ,EAAEA,QAAS;MAACO,KAAK,EAAEZ;IAAM,CAAE,CAAC,GAAG,IAAI,eAE/DL,IAAA,CAACL,IAAI;MACHY,KAAK,EAAE,CACLO,MAAM,CAACI,SAAS,EAChB;QACEC,WAAW,EAAEb,QAAQ,GAAGT,KAAK,CAACuB,MAAM,CAAC,GAAG,CAAC,GAAGvB,KAAK,CAACwB,IAAI,CAAC,GAAG,CAAC;QAC3DjB;MACF,CAAC,CACD;MAAAY,QAAA,eAEFhB,IAAA,CAACN,SAAS;QACRe,YAAY,EAAEG,kBAAmB;QACjCU,QAAQ;QACRC,SAAS;QACTC,aAAa,EAAE,EAAG;QAClBjB,KAAK,EAAE,CAACO,MAAM,CAACW,KAAK,EAAElB,KAAK,CAAE;QAC7BmB,iBAAiB,EAAC,KAAK;QACvBC,oBAAoB,EAAE9B,KAAK,CAACwB,IAAI,CAAC,GAAG,CAAE;QAAA,GAClCV;MAAK,CACV;IAAC,CACE,CAAC,EACNH,IAAI,gBACHR,IAAA,CAACF,UAAU;MAAC8B,KAAK,EAAEtB,QAAQ,GAAGT,KAAK,CAACuB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAG;MAACS,OAAO,EAAC,IAAI;MAAAb,QAAA,EAC/DR;IAAI,CACK,CAAC,GACX,IAAI;EAAA,CACJ,CAAC;AAEX;AAEA,MAAMM,MAAM,GAAGrB,UAAU,CAACqC,MAAM,CAAC;EAC/Bf,GAAG,EAAE;IACHA,GAAG,EAAE;EACP,CAAC;EACDG,SAAS,EAAE;IACTa,QAAQ,EAAE,UAAU;IACpBC,YAAY,EAAE,CAAC;IACfC,WAAW,EAAE,CAAC;IACdC,eAAe,EAAErC,KAAK,CAACsC,IAAI,CAACC;EAC9B,CAAC;EACDX,KAAK,EAAE;IACLY,QAAQ,EAAE,EAAE;IACZT,KAAK,EAAE,MAAM;IACbU,OAAO,EAAE,EAAE;IACXZ,iBAAiB,EAAE,KAAK;IACxBa,IAAI,EAAE;EACR;AACF,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// utils/uploadFile.ts
|
|
4
|
+
import ReactNativeBlobUtil from 'react-native-blob-util';
|
|
5
|
+
export async function uploadFile(file, config) {
|
|
6
|
+
const {
|
|
7
|
+
url,
|
|
8
|
+
method = 'POST',
|
|
9
|
+
fieldName = 'file',
|
|
10
|
+
headers = {},
|
|
11
|
+
errorMessage = 'Upload failed',
|
|
12
|
+
onError
|
|
13
|
+
} = config;
|
|
14
|
+
const uri = 'uri' in file ? file.uri : file.uri;
|
|
15
|
+
const name = 'name' in file ? file.name : file.fileName ?? 'file';
|
|
16
|
+
const type = 'type' in file ? file.type ?? 'application/octet-stream' : file.type ?? 'image/jpeg';
|
|
17
|
+
if (!uri) throw new Error('File URI is missing');
|
|
18
|
+
const id = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
19
|
+
try {
|
|
20
|
+
const response = await ReactNativeBlobUtil.fetch(method, url, {
|
|
21
|
+
'Content-Type': 'multipart/form-data',
|
|
22
|
+
...headers
|
|
23
|
+
}, [{
|
|
24
|
+
name: fieldName,
|
|
25
|
+
filename: name,
|
|
26
|
+
type,
|
|
27
|
+
data: ReactNativeBlobUtil.wrap(uri.replace('file://', ''))
|
|
28
|
+
}]);
|
|
29
|
+
const statusCode = response.respInfo.status;
|
|
30
|
+
if (statusCode < 200 || statusCode >= 300) {
|
|
31
|
+
const errorBody = response.json();
|
|
32
|
+
const message = errorBody?.message ?? errorMessage;
|
|
33
|
+
onError?.(file, message);
|
|
34
|
+
return {
|
|
35
|
+
id,
|
|
36
|
+
originalName: name ?? '',
|
|
37
|
+
customName: file.labelFile,
|
|
38
|
+
uploadedData: null
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const json = response.json();
|
|
42
|
+
const uploadedData = json;
|
|
43
|
+
return {
|
|
44
|
+
id,
|
|
45
|
+
originalName: String(name ?? 'Attachment'),
|
|
46
|
+
customName: file.labelFile,
|
|
47
|
+
uploadedData
|
|
48
|
+
};
|
|
49
|
+
} catch (err) {
|
|
50
|
+
const message = err?.message ?? errorMessage;
|
|
51
|
+
onError?.(file, message);
|
|
52
|
+
return {
|
|
53
|
+
id,
|
|
54
|
+
originalName: String(name ?? 'Attachment'),
|
|
55
|
+
customName: file.labelFile,
|
|
56
|
+
uploadedData: null
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=uploadFile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["ReactNativeBlobUtil","uploadFile","file","config","url","method","fieldName","headers","errorMessage","onError","uri","name","fileName","type","Error","id","Date","now","Math","random","toString","slice","response","fetch","filename","data","wrap","replace","statusCode","respInfo","status","errorBody","json","message","originalName","customName","labelFile","uploadedData","String","err"],"sourceRoot":"../../../../src","sources":["Input/helpers/uploadFile.ts"],"mappings":";;AAAA;AACA,OAAOA,mBAAmB,MAAM,wBAAwB;AAGxD,OAAO,eAAeC,UAAUA,CAC9BC,IAAc,EACdC,MAAoB,EACM;EAC1B,MAAM;IACJC,GAAG;IACHC,MAAM,GAAG,MAAM;IACfC,SAAS,GAAG,MAAM;IAClBC,OAAO,GAAG,CAAC,CAAC;IACZC,YAAY,GAAG,eAAe;IAC9BC;EACF,CAAC,GAAGN,MAAM;EAEV,MAAMO,GAAG,GAAG,KAAK,IAAIR,IAAI,GAAGA,IAAI,CAACQ,GAAG,GAAGR,IAAI,CAACQ,GAAG;EAC/C,MAAMC,IAAI,GAAG,MAAM,IAAIT,IAAI,GAAGA,IAAI,CAACS,IAAI,GAAIT,IAAI,CAACU,QAAQ,IAAI,MAAO;EAEnE,MAAMC,IAAI,GACR,MAAM,IAAIX,IAAI,GACTA,IAAI,CAACW,IAAI,IAAI,0BAA0B,GACvCX,IAAI,CAACW,IAAI,IAAI,YAAa;EAEjC,IAAI,CAACH,GAAG,EAAE,MAAM,IAAII,KAAK,CAAC,qBAAqB,CAAC;EAEhD,MAAMC,EAAE,GAAG,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC,IAAIC,IAAI,CAACC,MAAM,CAAC,CAAC,CAACC,QAAQ,CAAC,EAAE,CAAC,CAACC,KAAK,CAAC,CAAC,CAAC,EAAE;EAEjE,IAAI;IACF,MAAMC,QAAQ,GAAG,MAAMtB,mBAAmB,CAACuB,KAAK,CAC9ClB,MAAM,EACND,GAAG,EACH;MAAE,cAAc,EAAE,qBAAqB;MAAE,GAAGG;IAAQ,CAAC,EACrD,CACE;MACEI,IAAI,EAAEL,SAAS;MACfkB,QAAQ,EAAEb,IAAI;MACdE,IAAI;MACJY,IAAI,EAAEzB,mBAAmB,CAAC0B,IAAI,CAAChB,GAAG,CAACiB,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;IAC3D,CAAC,CAEL,CAAC;IAED,MAAMC,UAAU,GAAGN,QAAQ,CAACO,QAAQ,CAACC,MAAM;IAC3C,IAAIF,UAAU,GAAG,GAAG,IAAIA,UAAU,IAAI,GAAG,EAAE;MACzC,MAAMG,SAAS,GAAGT,QAAQ,CAACU,IAAI,CAAC,CAAC;MACjC,MAAMC,OAAO,GAAGF,SAAS,EAAEE,OAAO,IAAIzB,YAAY;MAClDC,OAAO,GAAGP,IAAI,EAAE+B,OAAO,CAAC;MACxB,OAAO;QACLlB,EAAE;QACFmB,YAAY,EAAEvB,IAAI,IAAI,EAAE;QACxBwB,UAAU,EAAEjC,IAAI,CAACkC,SAAS;QAC1BC,YAAY,EAAE;MAChB,CAAC;IACH;IAEA,MAAML,IAAI,GAAGV,QAAQ,CAACU,IAAI,CAAC,CAAC;IAC5B,MAAMK,YAAY,GAAGL,IAAS;IAE9B,OAAO;MACLjB,EAAE;MACFmB,YAAY,EAAEI,MAAM,CAAC3B,IAAI,IAAI,YAAY,CAAC;MAC1CwB,UAAU,EAAEjC,IAAI,CAACkC,SAAS;MAC1BC;IACF,CAAC;EACH,CAAC,CAAC,OAAOE,GAAQ,EAAE;IACjB,MAAMN,OAAO,GAAGM,GAAG,EAAEN,OAAO,IAAIzB,YAAY;IAC5CC,OAAO,GAAGP,IAAI,EAAE+B,OAAO,CAAC;IACxB,OAAO;MACLlB,EAAE;MACFmB,YAAY,EAAEI,MAAM,CAAC3B,IAAI,IAAI,YAAY,CAAC;MAC1CwB,UAAU,EAAEjC,IAAI,CAACkC,SAAS;MAC1BC,YAAY,EAAE;IAChB,CAAC;EACH;AACF","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Image","ScrollView","StyleSheet","TouchableOpacity","View","Card","Color","Typography","Button","layouting","ItemPreview","spacing","jsx","_jsx","jsxs","_jsxs","CardTriggerSmall","title","textButton","onChooseFile","files","onDelete","onPreview","onReplace","hasError","Component","length","style","flex","row","gap","children","styles","card","grow","backgroundColor","gray","borderColor","danger","undefined","titleWrapper","col","onPress","source","require","image","imageSmall","variant","weight","color","size","contentContainerStyle","align","center","horizontal","map","file","index","create","borderStyle","flexDirection","alignItems","justifyContent","flexShrink","width","height"],"sourceRoot":"../../../../../src","sources":["Input/partials/InputFile/CardTriggerSmall.tsx"],"mappings":"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
|
|
1
|
+
{"version":3,"names":["Image","ScrollView","StyleSheet","TouchableOpacity","View","Card","Color","Typography","Button","layouting","ItemPreview","spacing","jsx","_jsx","jsxs","_jsxs","CardTriggerSmall","title","textButton","onChooseFile","files","onDelete","onPreview","onReplace","hasError","Component","length","style","flex","row","gap","children","styles","card","grow","backgroundColor","gray","borderColor","danger","undefined","titleWrapper","col","onPress","source","require","image","imageSmall","variant","weight","color","size","contentContainerStyle","align","center","horizontal","map","file","index","loading","uploading","create","borderStyle","flexDirection","alignItems","justifyContent","flexShrink","width","height"],"sourceRoot":"../../../../../src","sources":["Input/partials/InputFile/CardTriggerSmall.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import { Image, StyleSheet, TouchableOpacity, View } from 'react-native';
|
|
3
|
+
import { ActivityIndicator, Image, StyleSheet, TouchableOpacity, View } from 'react-native';
|
|
4
4
|
import Card from "../../../Ui/Card.js";
|
|
5
5
|
import Color from "../../../Color/Color.js";
|
|
6
6
|
import Typography from "../../../Typography/Typography.js";
|
|
@@ -12,7 +12,8 @@ export default function ItemPreview({
|
|
|
12
12
|
index,
|
|
13
13
|
onDelete,
|
|
14
14
|
onReplace,
|
|
15
|
-
variant = 'default'
|
|
15
|
+
variant = 'default',
|
|
16
|
+
loading = false
|
|
16
17
|
}) {
|
|
17
18
|
const Wrapper = variant === 'default' ? Card : View;
|
|
18
19
|
return /*#__PURE__*/_jsx(Wrapper, {
|
|
@@ -22,7 +23,12 @@ export default function ItemPreview({
|
|
|
22
23
|
activeOpacity: 0.7,
|
|
23
24
|
children: [/*#__PURE__*/_jsxs(View, {
|
|
24
25
|
style: styles.containerListItem,
|
|
25
|
-
children: [
|
|
26
|
+
children: [loading && /*#__PURE__*/_jsx(View, {
|
|
27
|
+
style: [styles.previewImage, styles.loading],
|
|
28
|
+
children: /*#__PURE__*/_jsx(ActivityIndicator, {
|
|
29
|
+
color: Color.primary[1000]
|
|
30
|
+
})
|
|
31
|
+
}), !loading && file?.type?.startsWith('image') && /*#__PURE__*/_jsxs(View, {
|
|
26
32
|
style: (variant === 'small' ? styles.previewImageSmall : {}, variant === 'small' && file.error ? styles.previewImageError : {}),
|
|
27
33
|
children: [variant === 'small' && /*#__PURE__*/_jsx(BtnIcon, {
|
|
28
34
|
onPress: () => onDelete(index)
|
|
@@ -32,7 +38,7 @@ export default function ItemPreview({
|
|
|
32
38
|
},
|
|
33
39
|
style: [styles.previewImage, variant === 'small' && file.error ? styles.previewImageSmallError : {}]
|
|
34
40
|
})]
|
|
35
|
-
}), !file
|
|
41
|
+
}), !loading && !file?.type?.startsWith('image') && /*#__PURE__*/_jsxs(View, {
|
|
36
42
|
style: [styles.previewImage, variant === 'small' ? styles.previewImageSmall : {}, variant === 'small' && file.error ? styles.previewImageError : {}],
|
|
37
43
|
children: [variant === 'small' && /*#__PURE__*/_jsx(BtnIcon, {
|
|
38
44
|
onPress: () => onDelete(index)
|
|
@@ -126,6 +132,11 @@ const styles = StyleSheet.create({
|
|
|
126
132
|
gap: 12,
|
|
127
133
|
flexShrink: 0
|
|
128
134
|
},
|
|
135
|
+
loading: {
|
|
136
|
+
borderWidth: 1,
|
|
137
|
+
borderColor: Color.gray[200],
|
|
138
|
+
backgroundColor: Color.gray[50]
|
|
139
|
+
},
|
|
129
140
|
// small
|
|
130
141
|
previewImageSmall: {
|
|
131
142
|
borderWidth: 1,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Image","StyleSheet","TouchableOpacity","View","Card","Color","Typography","Icon","jsx","_jsx","jsxs","_jsxs","ItemPreview","file","onPress","index","onDelete","onReplace","variant","Wrapper","children","style","styles","containerPreview","activeOpacity","containerListItem","type","startsWith","previewImageSmall","error","previewImageError","BtnIcon","source","uri","
|
|
1
|
+
{"version":3,"names":["ActivityIndicator","Image","StyleSheet","TouchableOpacity","View","Card","Color","Typography","Icon","jsx","_jsx","jsxs","_jsxs","ItemPreview","file","onPress","index","onDelete","onReplace","variant","loading","Wrapper","children","style","styles","containerPreview","activeOpacity","containerListItem","previewImage","color","primary","type","startsWith","previewImageSmall","error","previewImageError","BtnIcon","source","uri","previewImageSmallError","name","size","fileDetails","weight","gray","numberOfLines","fileSize","toFixed","action","danger","actionDelete","create","flexDirection","alignItems","gap","flex","width","height","borderRadius","justifyContent","flexShrink","borderWidth","borderColor","backgroundColor","position","top","right","zIndex","padding"],"sourceRoot":"../../../../../src","sources":["Input/partials/InputFile/ItemPreview.tsx"],"mappings":";;AAAA,SACEA,iBAAiB,EACjBC,KAAK,EACLC,UAAU,EACVC,gBAAgB,EAChBC,IAAI,QACC,cAAc;AACrB,OAAOC,IAAI,MAAM,qBAAkB;AACnC,OAAOC,KAAK,MAAM,yBAAsB;AACxC,OAAOC,UAAU,MAAM,mCAAgC;AACvD,OAAOC,IAAI,MAAM,wBAAe;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAajC,eAAe,SAASC,WAAWA,CAAC;EAClCC,IAAI;EACJC,OAAO;EACPC,KAAK;EACLC,QAAQ;EACRC,SAAS;EACTC,OAAO,GAAG,SAAS;EACnBC,OAAO,GAAG;AACL,CAAC,EAAE;EACR,MAAMC,OAAO,GAAGF,OAAO,KAAK,SAAS,GAAGd,IAAI,GAAGD,IAAI;EAEnD,oBACEM,IAAA,CAACW,OAAO;IAAAC,QAAA,eACNV,KAAA,CAACT,gBAAgB;MACfY,OAAO,EAAEA,OAAQ;MACjBQ,KAAK,EAAEC,MAAM,CAACC,gBAAiB;MAC/BC,aAAa,EAAE,GAAI;MAAAJ,QAAA,gBAEnBV,KAAA,CAACR,IAAI;QAACmB,KAAK,EAAEC,MAAM,CAACG,iBAAkB;QAAAL,QAAA,GACnCF,OAAO,iBACNV,IAAA,CAACN,IAAI;UAACmB,KAAK,EAAE,CAACC,MAAM,CAACI,YAAY,EAAEJ,MAAM,CAACJ,OAAO,CAAE;UAAAE,QAAA,eACjDZ,IAAA,CAACV,iBAAiB;YAAC6B,KAAK,EAAEvB,KAAK,CAACwB,OAAO,CAAC,IAAI;UAAE,CAAE;QAAC,CAC7C,CACP,EAEA,CAACV,OAAO,IAAIN,IAAI,EAAEiB,IAAI,EAAEC,UAAU,CAAC,OAAO,CAAC,iBAC1CpB,KAAA,CAACR,IAAI;UACHmB,KAAK,GACFJ,OAAO,KAAK,OAAO,GAAGK,MAAM,CAACS,iBAAiB,GAAG,CAAC,CAAC,EACpDd,OAAO,KAAK,OAAO,IAAIL,IAAI,CAACoB,KAAK,GAC7BV,MAAM,CAACW,iBAAiB,GACxB,CAAC,CAAC,CACP;UAAAb,QAAA,GAEAH,OAAO,KAAK,OAAO,iBAClBT,IAAA,CAAC0B,OAAO;YAACrB,OAAO,EAAEA,CAAA,KAAME,QAAQ,CAACD,KAAK;UAAE,CAAE,CAC3C,eAEDN,IAAA,CAACT,KAAK;YACJoC,MAAM,EAAE;cAAEC,GAAG,EAAExB,IAAI,CAACwB;YAAI,CAAE;YAC1Bf,KAAK,EAAE,CACLC,MAAM,CAACI,YAAY,EACnBT,OAAO,KAAK,OAAO,IAAIL,IAAI,CAACoB,KAAK,GAC7BV,MAAM,CAACe,sBAAsB,GAC7B,CAAC,CAAC;UACN,CACH,CAAC;QAAA,CACE,CACP,EAEA,CAACnB,OAAO,IAAI,CAACN,IAAI,EAAEiB,IAAI,EAAEC,UAAU,CAAC,OAAO,CAAC,iBAC3CpB,KAAA,CAACR,IAAI;UACHmB,KAAK,EAAE,CACLC,MAAM,CAACI,YAAY,EACnBT,OAAO,KAAK,OAAO,GAAGK,MAAM,CAACS,iBAAiB,GAAG,CAAC,CAAC,EACnDd,OAAO,KAAK,OAAO,IAAIL,IAAI,CAACoB,KAAK,GAC7BV,MAAM,CAACW,iBAAiB,GACxB,CAAC,CAAC,CACN;UAAAb,QAAA,GAEDH,OAAO,KAAK,OAAO,iBAClBT,IAAA,CAAC0B,OAAO;YAACrB,OAAO,EAAEA,CAAA,KAAME,QAAQ,CAACD,KAAK;UAAE,CAAE,CAC3C,eAEDN,IAAA,CAACF,IAAI;YACHgC,IAAI,EAAE1B,IAAI,CAACiB,IAAI,KAAK,iBAAiB,GAAG,UAAU,GAAG,UAAW;YAChEU,IAAI,EAAE3B,IAAI,CAACiB,IAAI,KAAK,iBAAiB,GAAG,EAAE,GAAG,EAAG;YAChDF,KAAK,EAAEvB,KAAK,CAACwB,OAAO,CAAC,IAAI;UAAE,CAC5B,CAAC;QAAA,CACE,CACP,EAEAX,OAAO,KAAK,SAAS,iBACpBP,KAAA,CAACR,IAAI;UAACmB,KAAK,EAAEC,MAAM,CAACkB,WAAY;UAAApB,QAAA,gBAC9BZ,IAAA,CAACH,UAAU;YACTY,OAAO,EAAC,IAAI;YACZwB,MAAM,EAAC,UAAU;YACjBd,KAAK,EAAEvB,KAAK,CAACsC,IAAI,CAAC,GAAG,CAAE;YACvBC,aAAa,EAAE,CAAE;YAAAvB,QAAA,EAEhBR,IAAI,CAAC0B,IAAI,IAAI,SAASxB,KAAK,GAAG,CAAC;UAAE,CACxB,CAAC,eAEbJ,KAAA,CAACL,UAAU;YAACY,OAAO,EAAC,IAAI;YAACwB,MAAM,EAAC,SAAS;YAACd,KAAK,EAAEvB,KAAK,CAACsC,IAAI,CAAC,GAAG,CAAE;YAAAtB,QAAA,GAC9D,CAAC,CAACR,IAAI,EAAE2B,IAAI,IAAI3B,IAAI,EAAEgC,QAAQ,IAAI,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC,EAAEC,OAAO,CAC5D,CACF,CAAC,EAAC,IAEJ;UAAA,CAAY,CAAC;QAAA,CACT,CACP;MAAA,CACG,CAAC,EAGN5B,OAAO,KAAK,SAAS,iBACpBP,KAAA,CAACR,IAAI;QAACmB,KAAK,EAAEC,MAAM,CAACwB,MAAO;QAAA1B,QAAA,GACxBR,IAAI,CAACoB,KAAK,iBACTxB,IAAA,CAACF,IAAI;UACHgC,IAAI,EAAC,sBAAsB;UAC3BX,KAAK,EAAEvB,KAAK,CAAC2C,MAAM,CAAC,GAAG,CAAE;UACzBR,IAAI,EAAE;QAAG,CACV,CACF,eAED/B,IAAA,CAACP,gBAAgB;UAACY,OAAO,EAAEA,CAAA,KAAMG,SAAS,CAACF,KAAK,CAAE;UAAAM,QAAA,eAChDZ,IAAA,CAACF,IAAI;YAACgC,IAAI,EAAC,cAAc;YAACC,IAAI,EAAE,EAAG;YAACZ,KAAK,EAAEvB,KAAK,CAACsC,IAAI,CAAC,GAAG;UAAE,CAAE;QAAC,CAC9C,CAAC,eAEnBlC,IAAA,CAACP,gBAAgB;UAACY,OAAO,EAAEA,CAAA,KAAME,QAAQ,CAACD,KAAK,CAAE;UAAAM,QAAA,eAC/CZ,IAAA,CAACF,IAAI;YAACgC,IAAI,EAAC,OAAO;YAACC,IAAI,EAAE,EAAG;YAACZ,KAAK,EAAEvB,KAAK,CAACsC,IAAI,CAAC,GAAG;UAAE,CAAE;QAAC,CACvC,CAAC;MAAA,CACf,CACP;IAAA,CACe;EAAC,CACZ,CAAC;AAEd;AAEA,MAAMR,OAAO,GAAGA,CAAC;EAAErB;AAAgC,CAAC,KAAK;EACvD,oBACEL,IAAA,CAACP,gBAAgB;IACfoB,KAAK,EAAEC,MAAM,CAAC0B,YAAa;IAC3BnC,OAAO,EAAEA,OAAQ;IACjBW,aAAa,EAAE,GAAI;IAAAJ,QAAA,eAEnBZ,IAAA,CAACF,IAAI;MAACgC,IAAI,EAAC,WAAW;MAACX,KAAK,EAAC,OAAO;MAACY,IAAI,EAAE;IAAG,CAAE;EAAC,CACjC,CAAC;AAEvB,CAAC;AAED,MAAMjB,MAAM,GAAGtB,UAAU,CAACiD,MAAM,CAAC;EAC/BxB,iBAAiB,EAAE;IACjByB,aAAa,EAAE,KAAK;IACpBC,UAAU,EAAE,QAAQ;IACpBC,GAAG,EAAE,CAAC;IACNC,IAAI,EAAE;EACR,CAAC;EACD3B,YAAY,EAAE;IACZ4B,KAAK,EAAE,EAAE;IACTC,MAAM,EAAE,EAAE;IACVC,YAAY,EAAE,CAAC;IACfL,UAAU,EAAE,QAAQ;IACpBM,cAAc,EAAE;EAClB,CAAC;EACDlC,gBAAgB,EAAE;IAChB2B,aAAa,EAAE,KAAK;IACpBO,cAAc,EAAE,eAAe;IAC/BN,UAAU,EAAE,QAAQ;IACpBC,GAAG,EAAE;EACP,CAAC;EACDZ,WAAW,EAAE;IACXiB,cAAc,EAAE,QAAQ;IACxBL,GAAG,EAAE,CAAC;IACNC,IAAI,EAAE;EACR,CAAC;EACDP,MAAM,EAAE;IACNI,aAAa,EAAE,KAAK;IACpBC,UAAU,EAAE,QAAQ;IACpBC,GAAG,EAAE,EAAE;IACPM,UAAU,EAAE;EACd,CAAC;EAEDxC,OAAO,EAAE;IACPyC,WAAW,EAAE,CAAC;IACdC,WAAW,EAAExD,KAAK,CAACsC,IAAI,CAAC,GAAG,CAAC;IAC5BmB,eAAe,EAAEzD,KAAK,CAACsC,IAAI,CAAC,EAAE;EAChC,CAAC;EAED;EACAX,iBAAiB,EAAE;IACjB4B,WAAW,EAAE,CAAC;IACdC,WAAW,EAAExD,KAAK,CAACsC,IAAI,CAAC,GAAG,CAAC;IAC5Bc,YAAY,EAAE,CAAC;IACfM,QAAQ,EAAE;EACZ,CAAC;EACD7B,iBAAiB,EAAE;IACjB2B,WAAW,EAAExD,KAAK,CAAC2C,MAAM,CAAC,GAAG;EAC/B,CAAC;EACDC,YAAY,EAAE;IACZc,QAAQ,EAAE,UAAU;IACpBC,GAAG,EAAE,GAAG;IACRC,KAAK,EAAE,GAAG;IACVH,eAAe,EAAEzD,KAAK,CAACwB,OAAO,CAAC,IAAI,CAAC;IACpCqC,MAAM,EAAE,CAAC;IACTC,OAAO,EAAE,CAAC;IACVV,YAAY,EAAE;EAChB,CAAC;EACDnB,sBAAsB,EAAE;IAAEsB,WAAW,EAAE,CAAC;IAAEC,WAAW,EAAExD,KAAK,CAAC2C,MAAM,CAAC,GAAG;EAAE;AAC3E,CAAC,CAAC","ignoreList":[]}
|
package/lib/module/Tab/Tab.js
CHANGED
|
@@ -10,7 +10,8 @@ const Tab = ({
|
|
|
10
10
|
children,
|
|
11
11
|
current = 0,
|
|
12
12
|
onChangeTab,
|
|
13
|
-
renderHeader
|
|
13
|
+
renderHeader,
|
|
14
|
+
refreshControl
|
|
14
15
|
}) => {
|
|
15
16
|
const items = Children.toArray(children).filter(isValidElement);
|
|
16
17
|
const [activeIndex, setActiveIndex] = useState(current);
|
|
@@ -81,6 +82,7 @@ const Tab = ({
|
|
|
81
82
|
return /*#__PURE__*/_jsx(View, {
|
|
82
83
|
style: styles.container,
|
|
83
84
|
children: renderHeader ? /*#__PURE__*/_jsxs(ScrollView, {
|
|
85
|
+
refreshControl: refreshControl,
|
|
84
86
|
stickyHeaderIndices: [renderHeader ? 1 : 0] // bikin tabBar sticky
|
|
85
87
|
,
|
|
86
88
|
contentContainerStyle: styles.scrollViewContainer,
|