@herca/rn-kit 0.1.60 → 0.1.62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/lib/module/BottomSheet/BottomSheet.js +6 -4
- package/lib/module/BottomSheet/BottomSheet.js.map +1 -1
- package/lib/module/Input/InputSelect.js +125 -4
- package/lib/module/Input/InputSelect.js.map +1 -1
- package/lib/module/Input/README_INPUT_SELECT.md +392 -0
- package/lib/module/Modal/Modal.js +17 -8
- package/lib/module/Modal/Modal.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/styles/border.js +42 -0
- package/lib/module/styles/border.js.map +1 -0
- package/lib/module/styles/layouting.js +71 -0
- package/lib/module/styles/layouting.js.map +1 -0
- package/lib/module/styles/sizing.js +22 -0
- package/lib/module/styles/sizing.js.map +1 -0
- package/lib/module/styles/spacing.js +166 -0
- package/lib/module/styles/spacing.js.map +1 -0
- package/lib/module/styles/theme.js +47 -0
- package/lib/module/styles/theme.js.map +1 -0
- package/lib/typescript/src/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/lib/typescript/src/Input/InputSelect.d.ts +27 -1
- package/lib/typescript/src/Input/InputSelect.d.ts.map +1 -1
- package/lib/typescript/src/Modal/Modal.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/styles/border.d.ts +38 -0
- package/lib/typescript/src/styles/border.d.ts.map +1 -0
- package/lib/typescript/src/styles/layouting.d.ts +68 -0
- package/lib/typescript/src/styles/layouting.d.ts.map +1 -0
- package/lib/typescript/src/styles/sizing.d.ts +19 -0
- package/lib/typescript/src/styles/sizing.d.ts.map +1 -0
- package/lib/typescript/src/styles/spacing.d.ts +160 -0
- package/lib/typescript/src/styles/spacing.d.ts.map +1 -0
- package/lib/typescript/src/styles/theme.d.ts +43 -0
- package/lib/typescript/src/styles/theme.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/BottomSheet/BottomSheet.tsx +6 -4
- package/src/Input/InputSelect.tsx +183 -3
- package/src/Input/README_INPUT_SELECT.md +392 -0
- package/src/Modal/Modal.tsx +17 -8
- package/src/index.tsx +2 -0
- package/src/styles/border.ts +29 -0
- package/src/styles/layouting.ts +37 -0
- package/src/styles/sizing.ts +12 -0
- package/src/styles/spacing.ts +76 -0
- package/src/styles/theme.ts +46 -0
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
# InputSelect Component
|
|
2
|
+
|
|
3
|
+
Komponen dropdown/select yang fleksibel dengan dukungan modal, badge, subtitle, dan clear button. Dapat digunakan untuk single atau multiple selection dengan berbagai customization.
|
|
4
|
+
|
|
5
|
+
## Instalasi
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @herca/rn-kit
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Import
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import InputSelect from '@/components/InputSelect';
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Penggunaan Dasar
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { useState } from 'react';
|
|
21
|
+
import InputSelect from '@/components/InputSelect';
|
|
22
|
+
|
|
23
|
+
export default function Example() {
|
|
24
|
+
const [selected, setSelected] = useState('');
|
|
25
|
+
|
|
26
|
+
const options = [
|
|
27
|
+
{ label: 'Option 1', value: '1' },
|
|
28
|
+
{ label: 'Option 2', value: '2' },
|
|
29
|
+
{ label: 'Option 3', value: '3' },
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<InputSelect
|
|
34
|
+
label="Pilih Opsi"
|
|
35
|
+
placeholder="Silakan pilih..."
|
|
36
|
+
value={selected}
|
|
37
|
+
options={options}
|
|
38
|
+
selectProps={{
|
|
39
|
+
onSubmit: (val) => setSelected(val[0]?.value),
|
|
40
|
+
}}
|
|
41
|
+
/>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Props
|
|
47
|
+
|
|
48
|
+
### Required Props
|
|
49
|
+
|
|
50
|
+
| Prop | Type | Deskripsi |
|
|
51
|
+
| ------- | -------- | ------------------------ |
|
|
52
|
+
| `label` | `string` | Label untuk input select |
|
|
53
|
+
|
|
54
|
+
### Optional Props
|
|
55
|
+
|
|
56
|
+
| Prop | Type | Default | Deskripsi |
|
|
57
|
+
| --------------- | ----------------------------------- | ------------------ | ---------------------------------------------------- |
|
|
58
|
+
| `placeholder` | `string` | `'Select here...'` | Teks placeholder ketika tidak ada nilai yang dipilih |
|
|
59
|
+
| `options` | `ChipOptionProps[]` | `undefined` | Daftar opsi yang dapat dipilih |
|
|
60
|
+
| `value` | `string` | `undefined` | Nilai yang dipilih saat ini |
|
|
61
|
+
| `selectProps` | `SelectPropsWithoutData` | `undefined` | Props tambahan untuk komponen Select |
|
|
62
|
+
| `icon` | `IconNameProps` | `undefined` | Nama icon yang ditampilkan di sebelah kiri |
|
|
63
|
+
| `iconColor` | `string` | `undefined` | Warna icon sebelah kiri |
|
|
64
|
+
| `hasError` | `boolean` | `false` | Menampilkan state error dengan border merah |
|
|
65
|
+
| `hint` | `string` | `undefined` | Teks hint/bantuan di bawah input |
|
|
66
|
+
| `onClear` | `() => void` | `undefined` | Callback ketika tombol clear ditekan |
|
|
67
|
+
| `onSelectClick` | `() => void` | `undefined` | Callback ketika input ditekan |
|
|
68
|
+
| `onSelectClose` | `() => void` | `undefined` | Callback ketika modal ditutup |
|
|
69
|
+
| `subtitle` | `string` | `undefined` | Subtitle tambahan di bawah value |
|
|
70
|
+
| `badge` | `{ value: string; color: Variant }` | `undefined` | Badge yang ditampilkan di samping value |
|
|
71
|
+
| `useModal` | `boolean` | `true` | Gunakan modal untuk menampilkan opsi |
|
|
72
|
+
|
|
73
|
+
### Pressable Props
|
|
74
|
+
|
|
75
|
+
Komponen ini extends dari `Pressable`, sehingga menerima semua props dari `React.ComponentProps<typeof Pressable>`:
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
<InputSelect
|
|
79
|
+
label="Select"
|
|
80
|
+
disabled={false}
|
|
81
|
+
onLongPress={() => console.log('long press')}
|
|
82
|
+
// ... props lainnya
|
|
83
|
+
/>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Contoh Penggunaan
|
|
87
|
+
|
|
88
|
+
### Dengan Badge
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
<InputSelect
|
|
92
|
+
label="Status Pembayaran"
|
|
93
|
+
value="paid"
|
|
94
|
+
badge={{
|
|
95
|
+
value: 'Lunas',
|
|
96
|
+
color: 'success',
|
|
97
|
+
}}
|
|
98
|
+
options={[
|
|
99
|
+
{ label: 'Dibayar', value: 'paid' },
|
|
100
|
+
{ label: 'Tertunda', value: 'pending' },
|
|
101
|
+
{ label: 'Ditolak', value: 'rejected' },
|
|
102
|
+
]}
|
|
103
|
+
selectProps={{
|
|
104
|
+
onSubmit: (val) => console.log(val),
|
|
105
|
+
}}
|
|
106
|
+
/>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Dengan Error State
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
<InputSelect
|
|
113
|
+
label="Email Provider"
|
|
114
|
+
hasError={true}
|
|
115
|
+
hint="Pilih email provider yang valid"
|
|
116
|
+
placeholder="Contoh: Gmail, Outlook"
|
|
117
|
+
options={[
|
|
118
|
+
{ label: 'Gmail', value: 'gmail' },
|
|
119
|
+
{ label: 'Outlook', value: 'outlook' },
|
|
120
|
+
]}
|
|
121
|
+
/>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Dengan Icon dan Subtitle
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
<InputSelect
|
|
128
|
+
label="Lokasi Kerja"
|
|
129
|
+
icon="MapPin"
|
|
130
|
+
iconColor="#0066CC"
|
|
131
|
+
value="jakarta"
|
|
132
|
+
subtitle="Kantor Pusat"
|
|
133
|
+
options={[
|
|
134
|
+
{ label: 'Jakarta', value: 'jakarta', icon: 'MapPin' },
|
|
135
|
+
{ label: 'Surabaya', value: 'surabaya', icon: 'MapPin' },
|
|
136
|
+
]}
|
|
137
|
+
/>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Dengan Clear Button
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
<InputSelect
|
|
144
|
+
label="Kategori"
|
|
145
|
+
value={category}
|
|
146
|
+
onClear={() => setCategory('')}
|
|
147
|
+
options={categoryOptions}
|
|
148
|
+
selectProps={{
|
|
149
|
+
onSubmit: (val) => setCategory(val[0]?.value),
|
|
150
|
+
}}
|
|
151
|
+
/>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Menggunakan Select Props untuk Advanced Config
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
<InputSelect
|
|
158
|
+
label="Multiple Selection"
|
|
159
|
+
options={options}
|
|
160
|
+
selectProps={{
|
|
161
|
+
multiple: true,
|
|
162
|
+
required: true,
|
|
163
|
+
loading: false,
|
|
164
|
+
delaySearch: 300,
|
|
165
|
+
onSearch: (query) => console.log('Search:', query),
|
|
166
|
+
onRefresh: () => fetchOptions(),
|
|
167
|
+
}}
|
|
168
|
+
/>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Tanpa Modal (Arrow Right)
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
<InputSelect
|
|
175
|
+
label="Navigasi ke Detail"
|
|
176
|
+
useModal={false}
|
|
177
|
+
value="selected-item"
|
|
178
|
+
onSelectClick={() => navigation.navigate('DetailScreen')}
|
|
179
|
+
/>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## State Management
|
|
183
|
+
|
|
184
|
+
Komponen ini menggunakan internal state untuk mengelola nilai. Untuk kontrol penuh dari parent component:
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
import { useState } from 'react';
|
|
188
|
+
|
|
189
|
+
export default function Form() {
|
|
190
|
+
const [selectedValue, setSelectedValue] = useState('');
|
|
191
|
+
|
|
192
|
+
const handleSelectChange = (val) => {
|
|
193
|
+
setSelectedValue(val[0]?.value || '');
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
return (
|
|
197
|
+
<InputSelect
|
|
198
|
+
label="Pilih Item"
|
|
199
|
+
value={selectedValue}
|
|
200
|
+
options={options}
|
|
201
|
+
selectProps={{
|
|
202
|
+
onSubmit: handleSelectChange,
|
|
203
|
+
}}
|
|
204
|
+
/>
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Styling & Customization
|
|
210
|
+
|
|
211
|
+
### Custom Border Color
|
|
212
|
+
|
|
213
|
+
```tsx
|
|
214
|
+
<InputSelect
|
|
215
|
+
label="Custom Style"
|
|
216
|
+
hasError={true} // Border merah
|
|
217
|
+
value="selected"
|
|
218
|
+
// atau
|
|
219
|
+
value="selected" // Border biru
|
|
220
|
+
/>
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Custom Spacing
|
|
224
|
+
|
|
225
|
+
Komponen menggunakan spacing dari style config:
|
|
226
|
+
|
|
227
|
+
- Gap antar elements: `spacing.gap[4]`
|
|
228
|
+
- Padding: `paddingVertical: 10, paddingHorizontal: 12`
|
|
229
|
+
- Border radius: `borderRadius: 8`
|
|
230
|
+
|
|
231
|
+
Untuk override, gunakan prop `style` dari Pressable:
|
|
232
|
+
|
|
233
|
+
```tsx
|
|
234
|
+
<InputSelect label="Custom" style={{ paddingHorizontal: 16 }} />
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## TypeScript
|
|
238
|
+
|
|
239
|
+
```tsx
|
|
240
|
+
import InputSelect from '@/components/InputSelect';
|
|
241
|
+
import type { ChipOptionProps } from '@herca/rn-kit';
|
|
242
|
+
|
|
243
|
+
const options: ChipOptionProps[] = [
|
|
244
|
+
{ label: 'Opsi 1', value: '1' },
|
|
245
|
+
{ label: 'Opsi 2', value: '2' },
|
|
246
|
+
];
|
|
247
|
+
|
|
248
|
+
<InputSelect
|
|
249
|
+
label="Type Safe"
|
|
250
|
+
options={options}
|
|
251
|
+
value="1"
|
|
252
|
+
selectProps={{
|
|
253
|
+
multiple: false,
|
|
254
|
+
}}
|
|
255
|
+
/>;
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Event Callbacks
|
|
259
|
+
|
|
260
|
+
### onSelectClick
|
|
261
|
+
|
|
262
|
+
Dipanggil ketika user menekan input (hanya jika `useModal = true`):
|
|
263
|
+
|
|
264
|
+
```tsx
|
|
265
|
+
<InputSelect
|
|
266
|
+
label="Select"
|
|
267
|
+
onSelectClick={() => {
|
|
268
|
+
console.log('Modal akan dibuka');
|
|
269
|
+
}}
|
|
270
|
+
/>
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### onSelectClose
|
|
274
|
+
|
|
275
|
+
Dipanggil ketika modal ditutup:
|
|
276
|
+
|
|
277
|
+
```tsx
|
|
278
|
+
<InputSelect
|
|
279
|
+
label="Select"
|
|
280
|
+
onSelectClose={() => {
|
|
281
|
+
console.log('Modal ditutup');
|
|
282
|
+
}}
|
|
283
|
+
/>
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### onClear
|
|
287
|
+
|
|
288
|
+
Dipanggil ketika user menekan tombol clear:
|
|
289
|
+
|
|
290
|
+
```tsx
|
|
291
|
+
<InputSelect
|
|
292
|
+
label="Select"
|
|
293
|
+
onClear={() => {
|
|
294
|
+
console.log('Nilai di-clear');
|
|
295
|
+
}}
|
|
296
|
+
/>
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Best Practices
|
|
300
|
+
|
|
301
|
+
1. **Selalu berikan label yang deskriptif**
|
|
302
|
+
|
|
303
|
+
```tsx
|
|
304
|
+
<InputSelect label="Pilih Departemen" /> ✅
|
|
305
|
+
<InputSelect label="Item" /> ❌
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
2. **Gunakan hint untuk memberikan konteks tambahan**
|
|
309
|
+
|
|
310
|
+
```tsx
|
|
311
|
+
<InputSelect
|
|
312
|
+
label="Role"
|
|
313
|
+
hint="Pilih role yang sesuai dengan fungsi pengguna"
|
|
314
|
+
/>
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
3. **Validasi dan tampilkan error state**
|
|
318
|
+
|
|
319
|
+
```tsx
|
|
320
|
+
<InputSelect
|
|
321
|
+
label="Email"
|
|
322
|
+
hasError={!isValid}
|
|
323
|
+
hint={!isValid ? 'Email harus dipilih' : undefined}
|
|
324
|
+
/>
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
4. **Untuk multiple selection, gunakan selectProps.multiple**
|
|
328
|
+
|
|
329
|
+
```tsx
|
|
330
|
+
<InputSelect label="Tags" selectProps={{ multiple: true }} />
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
5. **Manfaatkan subtitle untuk informasi sekunder**
|
|
334
|
+
```tsx
|
|
335
|
+
<InputSelect label="Cabang" value="jakarta-pusat" subtitle="Kantor Pusat" />
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
## Accessibility
|
|
339
|
+
|
|
340
|
+
- Label selalu ditampilkan untuk clarity
|
|
341
|
+
- Error state ditunjukkan dengan visual feedback (border merah) dan text hint
|
|
342
|
+
- Icon dan button memiliki ukuran yang cukup untuk touch targets
|
|
343
|
+
- Color contrast mengikuti WCAG guidelines
|
|
344
|
+
|
|
345
|
+
## Troubleshooting
|
|
346
|
+
|
|
347
|
+
### Modal tidak membuka
|
|
348
|
+
|
|
349
|
+
```tsx
|
|
350
|
+
// Pastikan useModal = true (default)
|
|
351
|
+
<InputSelect useModal={true} />
|
|
352
|
+
|
|
353
|
+
// Atau jika ingin custom behavior
|
|
354
|
+
<InputSelect
|
|
355
|
+
useModal={false}
|
|
356
|
+
onSelectClick={() => {
|
|
357
|
+
// Handle custom behavior
|
|
358
|
+
}}
|
|
359
|
+
/>
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Value tidak update
|
|
363
|
+
|
|
364
|
+
```tsx
|
|
365
|
+
// Pastikan meng-update melalui selectProps.onSubmit
|
|
366
|
+
selectProps={{
|
|
367
|
+
onSubmit: (val) => {
|
|
368
|
+
// Update state parent
|
|
369
|
+
setSelectedValue(val[0]?.value);
|
|
370
|
+
}
|
|
371
|
+
}}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Clear button tidak muncul
|
|
375
|
+
|
|
376
|
+
```tsx
|
|
377
|
+
// Clear button hanya muncul jika:
|
|
378
|
+
// 1. onClear prop ada
|
|
379
|
+
// 2. value tidak kosong
|
|
380
|
+
<InputSelect value="selected" onClear={() => setSelected('')} />
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
## Related Components
|
|
384
|
+
|
|
385
|
+
- [`Select`](./Select.md) - Base select component dengan modal
|
|
386
|
+
- [`Chip`](./Chip.md) - Komponen untuk menampilkan options
|
|
387
|
+
- [`Badge`](./Badge.md) - Komponen untuk menampilkan badge
|
|
388
|
+
- [`Input`](./Input.md) - Text input component
|
|
389
|
+
|
|
390
|
+
## License
|
|
391
|
+
|
|
392
|
+
MIT
|
package/src/Modal/Modal.tsx
CHANGED
|
@@ -39,7 +39,7 @@ const ModalPopUp: React.FC<ModalPopUpProps> = ({
|
|
|
39
39
|
containerStyle,
|
|
40
40
|
modalStyle,
|
|
41
41
|
}) => {
|
|
42
|
-
const [isVisible, setIsVisible] = useState(
|
|
42
|
+
const [isVisible, setIsVisible] = useState(isOpen);
|
|
43
43
|
const scaleAnim = useState(() => new Animated.Value(0))[0];
|
|
44
44
|
|
|
45
45
|
const showModal = useCallback(() => {
|
|
@@ -53,16 +53,24 @@ const ModalPopUp: React.FC<ModalPopUpProps> = ({
|
|
|
53
53
|
}, [scaleAnim]);
|
|
54
54
|
|
|
55
55
|
const hideModal = useCallback(() => {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
Animated.spring(scaleAnim, {
|
|
57
|
+
toValue: 0,
|
|
58
|
+
useNativeDriver: true,
|
|
59
|
+
}).start(() => {
|
|
60
|
+
setIsVisible(false);
|
|
61
|
+
onClose?.(false);
|
|
62
|
+
});
|
|
63
|
+
}, [scaleAnim, onClose]);
|
|
60
64
|
|
|
61
65
|
const handleBackdropPress = useCallback(() => {
|
|
62
66
|
if (closable) {
|
|
63
|
-
|
|
67
|
+
if (onRequestClose) {
|
|
68
|
+
onRequestClose();
|
|
69
|
+
} else {
|
|
70
|
+
hideModal();
|
|
71
|
+
}
|
|
64
72
|
}
|
|
65
|
-
}, [closable, hideModal]);
|
|
73
|
+
}, [closable, onRequestClose, hideModal]);
|
|
66
74
|
|
|
67
75
|
useEffect(() => {
|
|
68
76
|
if (isOpen) {
|
|
@@ -70,7 +78,8 @@ const ModalPopUp: React.FC<ModalPopUpProps> = ({
|
|
|
70
78
|
} else {
|
|
71
79
|
hideModal();
|
|
72
80
|
}
|
|
73
|
-
|
|
81
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
82
|
+
}, [isOpen]);
|
|
74
83
|
|
|
75
84
|
const modalContentStyle = StyleSheet.flatten([
|
|
76
85
|
{
|
package/src/index.tsx
CHANGED
|
@@ -88,3 +88,5 @@ export type { SkeletonProps } from './Skeleton/type';
|
|
|
88
88
|
export { default as CounterButton } from './CounterButton/CounterButton';
|
|
89
89
|
export { default as BadgeIcon } from './BadgeIcon/BadgeIcon';
|
|
90
90
|
export { default as PdfView } from './FileView/PdfView';
|
|
91
|
+
export { default as InputSelect } from './Input/InputSelect';
|
|
92
|
+
export type { ChipValue } from './Chip/type';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
import Color from '../Color/Color';
|
|
3
|
+
|
|
4
|
+
export const border = {
|
|
5
|
+
w: StyleSheet.create({
|
|
6
|
+
0: { borderWidth: 0 },
|
|
7
|
+
1: { borderWidth: 1 },
|
|
8
|
+
}),
|
|
9
|
+
bottom: StyleSheet.create({
|
|
10
|
+
1: { borderBottomWidth: 1 },
|
|
11
|
+
}),
|
|
12
|
+
|
|
13
|
+
right: StyleSheet.create({
|
|
14
|
+
1: { borderRightWidth: 1 },
|
|
15
|
+
}),
|
|
16
|
+
|
|
17
|
+
radius: StyleSheet.create({
|
|
18
|
+
8: { borderRadius: 8 },
|
|
19
|
+
}),
|
|
20
|
+
|
|
21
|
+
color: {
|
|
22
|
+
primary: StyleSheet.create({
|
|
23
|
+
300: { borderColor: Color.primary[300] },
|
|
24
|
+
}),
|
|
25
|
+
danger: StyleSheet.create({
|
|
26
|
+
300: { borderColor: Color.danger[300] },
|
|
27
|
+
}),
|
|
28
|
+
},
|
|
29
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
|
|
3
|
+
export const layouting = {
|
|
4
|
+
flex: StyleSheet.create({
|
|
5
|
+
1: { flex: 1 },
|
|
6
|
+
grow: { flexGrow: 1 },
|
|
7
|
+
shrink: { flexShrink: 1 },
|
|
8
|
+
row: { flexDirection: 'row' },
|
|
9
|
+
rowCenter: {
|
|
10
|
+
flexDirection: 'row',
|
|
11
|
+
alignItems: 'center',
|
|
12
|
+
},
|
|
13
|
+
wrap: { flexWrap: 'wrap' },
|
|
14
|
+
nowrap: { flexWrap: 'nowrap' },
|
|
15
|
+
}),
|
|
16
|
+
|
|
17
|
+
align: StyleSheet.create({
|
|
18
|
+
center: { alignItems: 'center' },
|
|
19
|
+
start: { alignItems: 'flex-start' },
|
|
20
|
+
end: { alignItems: 'flex-end' },
|
|
21
|
+
}),
|
|
22
|
+
|
|
23
|
+
justify: StyleSheet.create({
|
|
24
|
+
between: { justifyContent: 'space-between' },
|
|
25
|
+
end: { justifyContent: 'flex-end' },
|
|
26
|
+
center: { justifyContent: 'center' },
|
|
27
|
+
start: { justifyContent: 'flex-start' },
|
|
28
|
+
}),
|
|
29
|
+
text: StyleSheet.create({
|
|
30
|
+
verticalTop: { textAlignVertical: 'top' },
|
|
31
|
+
left: { textAlign: 'left' },
|
|
32
|
+
uppercase: { textTransform: 'uppercase' },
|
|
33
|
+
}),
|
|
34
|
+
display: StyleSheet.create({
|
|
35
|
+
none: { display: 'none' },
|
|
36
|
+
}),
|
|
37
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
|
|
3
|
+
export const spacing = {
|
|
4
|
+
// padding
|
|
5
|
+
p: StyleSheet.create({
|
|
6
|
+
0: { padding: 0 },
|
|
7
|
+
8: { padding: 8 },
|
|
8
|
+
12: { padding: 12 },
|
|
9
|
+
}),
|
|
10
|
+
px: StyleSheet.create({
|
|
11
|
+
0: { paddingHorizontal: 0 },
|
|
12
|
+
4: { paddingHorizontal: 4 },
|
|
13
|
+
8: { paddingHorizontal: 8 },
|
|
14
|
+
12: { paddingHorizontal: 12 },
|
|
15
|
+
24: { paddingHorizontal: 24 },
|
|
16
|
+
}),
|
|
17
|
+
py: StyleSheet.create({
|
|
18
|
+
0: { paddingVertical: 0 },
|
|
19
|
+
4: { paddingVertical: 4 },
|
|
20
|
+
8: { paddingVertical: 8 },
|
|
21
|
+
10: { paddingVertical: 10 },
|
|
22
|
+
12: { paddingVertical: 12 },
|
|
23
|
+
36: { paddingVertical: 36 },
|
|
24
|
+
}),
|
|
25
|
+
pt: StyleSheet.create({
|
|
26
|
+
10: { paddingTop: 10 },
|
|
27
|
+
12: { paddingTop: 12 },
|
|
28
|
+
14: { paddingTop: 14 },
|
|
29
|
+
}),
|
|
30
|
+
pb: StyleSheet.create({
|
|
31
|
+
0: { paddingBottom: 0 },
|
|
32
|
+
8: { paddingBottom: 8 },
|
|
33
|
+
12: { paddingBottom: 12 },
|
|
34
|
+
14: { paddingBottom: 14 },
|
|
35
|
+
24: { paddingBottom: 24 },
|
|
36
|
+
32: { paddingBottom: 32 },
|
|
37
|
+
46: { paddingBottom: 46 },
|
|
38
|
+
215: { paddingBottom: 215 },
|
|
39
|
+
262: { paddingBottom: 262 },
|
|
40
|
+
}),
|
|
41
|
+
pr: StyleSheet.create({
|
|
42
|
+
25: { paddingRight: 25 },
|
|
43
|
+
}),
|
|
44
|
+
|
|
45
|
+
// margin
|
|
46
|
+
mt: StyleSheet.create({
|
|
47
|
+
12: { marginTop: 12 },
|
|
48
|
+
4: { marginTop: 4 },
|
|
49
|
+
}),
|
|
50
|
+
mb: StyleSheet.create({
|
|
51
|
+
10: { marginBottom: 10 },
|
|
52
|
+
12: { marginBottom: 12 },
|
|
53
|
+
20: { marginBottom: 20 },
|
|
54
|
+
8: { marginBottom: 8 },
|
|
55
|
+
4: { marginBottom: 4 },
|
|
56
|
+
}),
|
|
57
|
+
mr: StyleSheet.create({
|
|
58
|
+
8: { marginRight: 8 },
|
|
59
|
+
16: { marginRight: 16 },
|
|
60
|
+
22: { marginRight: 22 },
|
|
61
|
+
}),
|
|
62
|
+
my: StyleSheet.create({
|
|
63
|
+
12: { marginVertical: 12 },
|
|
64
|
+
}),
|
|
65
|
+
|
|
66
|
+
// gap
|
|
67
|
+
gap: StyleSheet.create({
|
|
68
|
+
16: { gap: 16 },
|
|
69
|
+
12: { gap: 12 },
|
|
70
|
+
10: { gap: 10 },
|
|
71
|
+
8: { gap: 8 },
|
|
72
|
+
6: { gap: 6 },
|
|
73
|
+
4: { gap: 4 },
|
|
74
|
+
2: { gap: 2 },
|
|
75
|
+
}),
|
|
76
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Color } from '@herca/rn-kit';
|
|
2
|
+
import { StyleSheet } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export const theme = {
|
|
5
|
+
chipFiltering: StyleSheet.create({
|
|
6
|
+
chipsSelectWrapper: {
|
|
7
|
+
flex: 1,
|
|
8
|
+
},
|
|
9
|
+
chipFilterContainer: {
|
|
10
|
+
paddingLeft: 8,
|
|
11
|
+
gap: 8,
|
|
12
|
+
},
|
|
13
|
+
chipsWrapper: {
|
|
14
|
+
flexDirection: 'row',
|
|
15
|
+
alignItems: 'center',
|
|
16
|
+
},
|
|
17
|
+
chipFilterSelectWrapper: {
|
|
18
|
+
borderRightWidth: 1,
|
|
19
|
+
paddingRight: 10,
|
|
20
|
+
borderColor: Color.primary[200],
|
|
21
|
+
},
|
|
22
|
+
}),
|
|
23
|
+
loadData: StyleSheet.create({
|
|
24
|
+
loadMoreLoadingWrapper: {
|
|
25
|
+
alignItems: 'center',
|
|
26
|
+
paddingVertical: 10,
|
|
27
|
+
},
|
|
28
|
+
}),
|
|
29
|
+
ticketCard: StyleSheet.create({
|
|
30
|
+
ticketInfoWraper: {
|
|
31
|
+
flexDirection: 'row',
|
|
32
|
+
alignItems: 'center',
|
|
33
|
+
justifyContent: 'space-between',
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
ticketFooter: {
|
|
37
|
+
marginTop: 8,
|
|
38
|
+
},
|
|
39
|
+
}),
|
|
40
|
+
btn: StyleSheet.create({
|
|
41
|
+
iconBtn: {
|
|
42
|
+
padding: 6,
|
|
43
|
+
borderRadius: 8,
|
|
44
|
+
},
|
|
45
|
+
}),
|
|
46
|
+
};
|