@herca/rn-kit 0.1.33 → 0.1.35
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/Accordion/Accordion.js +11 -2
- package/lib/module/Accordion/Accordion.js.map +1 -1
- package/lib/module/Accordion/AccordionItem.js +1 -0
- package/lib/module/Accordion/AccordionItem.js.map +1 -1
- package/lib/module/Accordion/README.md +14 -11
- package/lib/module/BadgeIcon/BadgeIcon.js +117 -0
- package/lib/module/BadgeIcon/BadgeIcon.js.map +1 -0
- package/lib/module/BadgeIcon/README.md +77 -0
- package/lib/module/BadgeIcon/type.js +2 -0
- package/lib/module/BadgeIcon/type.js.map +1 -0
- package/lib/module/BottomSheet/BottomSheet.js +1 -1
- package/lib/module/BottomSheet/BottomSheet.js.map +1 -1
- package/lib/module/CheckBox/CheckBox.js +65 -32
- package/lib/module/CheckBox/CheckBox.js.map +1 -1
- package/lib/module/CheckBox/CheckBoxList.js +10 -2
- package/lib/module/CheckBox/CheckBoxList.js.map +1 -1
- package/lib/module/CheckBox/README_CHECKBOX.md +10 -7
- package/lib/module/CheckBox/README_CHECKBOXLIST.md +13 -7
- package/lib/module/CheckBox/type.js +2 -0
- package/lib/module/CheckBox/type.js.map +1 -0
- package/lib/module/Icon/Icon.js +13 -1
- package/lib/module/Icon/Icon.js.map +1 -1
- package/lib/module/Icon/README.md +7 -0
- package/lib/module/Icon/icons/CopyFill.js +25 -0
- package/lib/module/Icon/icons/CopyFill.js.map +1 -0
- package/lib/module/Icon/icons/CopyTextFill.js +22 -0
- package/lib/module/Icon/icons/CopyTextFill.js.map +1 -0
- package/lib/module/Icon/icons/DiscountFill.js +23 -0
- package/lib/module/Icon/icons/DiscountFill.js.map +1 -0
- package/lib/module/Icon/icons/LocationPinFill.js +21 -0
- package/lib/module/Icon/icons/LocationPinFill.js.map +1 -0
- package/lib/module/Icon/icons/RadioButton.js +0 -1
- package/lib/module/Icon/icons/RadioButton.js.map +1 -1
- package/lib/module/Icon/icons/RotateSquareFill.js +21 -0
- package/lib/module/Icon/icons/RotateSquareFill.js.map +1 -0
- package/lib/module/Icon/icons/ShieldFillChecked.js +22 -0
- package/lib/module/Icon/icons/ShieldFillChecked.js.map +1 -0
- package/lib/module/Input/Input.js +19 -23
- package/lib/module/Input/Input.js.map +1 -1
- package/lib/module/Input/README_INPUT.md +17 -15
- package/lib/module/Tab/README.md +49 -6
- package/lib/module/Timeline/README.md +18 -19
- package/lib/module/Timeline/TimelineItem.js +14 -9
- package/lib/module/Timeline/TimelineItem.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/Accordion/Accordion.d.ts +1 -1
- package/lib/typescript/src/Accordion/Accordion.d.ts.map +1 -1
- package/lib/typescript/src/Accordion/AccordionItem.d.ts.map +1 -1
- package/lib/typescript/src/Accordion/type.d.ts +1 -0
- package/lib/typescript/src/Accordion/type.d.ts.map +1 -1
- package/lib/typescript/src/BadgeIcon/BadgeIcon.d.ts +20 -0
- package/lib/typescript/src/BadgeIcon/BadgeIcon.d.ts.map +1 -0
- package/lib/typescript/src/BadgeIcon/type.d.ts +11 -0
- package/lib/typescript/src/BadgeIcon/type.d.ts.map +1 -0
- package/lib/typescript/src/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/lib/typescript/src/CheckBox/CheckBox.d.ts +4 -0
- package/lib/typescript/src/CheckBox/CheckBox.d.ts.map +1 -1
- package/lib/typescript/src/CheckBox/CheckBoxList.d.ts +3 -0
- package/lib/typescript/src/CheckBox/CheckBoxList.d.ts.map +1 -1
- package/lib/typescript/src/CheckBox/type.d.ts +2 -0
- package/lib/typescript/src/CheckBox/type.d.ts.map +1 -0
- package/lib/typescript/src/Icon/Icon.d.ts.map +1 -1
- package/lib/typescript/src/Icon/icons/CopyFill.d.ts +9 -0
- package/lib/typescript/src/Icon/icons/CopyFill.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/CopyTextFill.d.ts +9 -0
- package/lib/typescript/src/Icon/icons/CopyTextFill.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/DiscountFill.d.ts +8 -0
- package/lib/typescript/src/Icon/icons/DiscountFill.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/LocationPinFill.d.ts +8 -0
- package/lib/typescript/src/Icon/icons/LocationPinFill.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/RotateSquareFill.d.ts +8 -0
- package/lib/typescript/src/Icon/icons/RotateSquareFill.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/ShieldFillChecked.d.ts +9 -0
- package/lib/typescript/src/Icon/icons/ShieldFillChecked.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/Input.d.ts.map +1 -1
- package/lib/typescript/src/Input/type.d.ts +1 -0
- package/lib/typescript/src/Input/type.d.ts.map +1 -1
- package/lib/typescript/src/Timeline/TimelineItem.d.ts +5 -1
- package/lib/typescript/src/Timeline/TimelineItem.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/Accordion/Accordion.tsx +15 -3
- package/src/Accordion/AccordionItem.tsx +5 -1
- package/src/Accordion/README.md +14 -11
- package/src/Accordion/type.tsx +1 -0
- package/src/BadgeIcon/BadgeIcon.tsx +126 -0
- package/src/BadgeIcon/README.md +77 -0
- package/src/BadgeIcon/type.tsx +21 -0
- package/src/BottomSheet/BottomSheet.tsx +5 -1
- package/src/CheckBox/CheckBox.tsx +45 -29
- package/src/CheckBox/CheckBoxList.tsx +12 -0
- package/src/CheckBox/README_CHECKBOX.md +10 -7
- package/src/CheckBox/README_CHECKBOXLIST.md +13 -7
- package/src/CheckBox/type.ts +9 -0
- package/src/Icon/Icon.tsx +12 -0
- package/src/Icon/README.md +7 -0
- package/src/Icon/icons/CopyFill.tsx +23 -0
- package/src/Icon/icons/CopyTextFill.tsx +29 -0
- package/src/Icon/icons/DiscountFill.tsx +26 -0
- package/src/Icon/icons/LocationPinFill.tsx +28 -0
- package/src/Icon/icons/RadioButton.tsx +1 -1
- package/src/Icon/icons/RotateSquareFill.tsx +22 -0
- package/src/Icon/icons/ShieldFillChecked.tsx +23 -0
- package/src/Icon/type.tsx +6 -0
- package/src/Input/Input.tsx +17 -25
- package/src/Input/README_INPUT.md +17 -15
- package/src/Input/type.tsx +1 -0
- package/src/Tab/README.md +49 -6
- package/src/Timeline/README.md +18 -19
- package/src/Timeline/TimelineItem.tsx +15 -10
- package/src/index.tsx +1 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import Svg, { Path } from 'react-native-svg';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
size?: number;
|
|
6
|
+
color?: string;
|
|
7
|
+
style?: object;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const ShieldCheckedFill: React.FC<Props> = ({
|
|
11
|
+
size = 24,
|
|
12
|
+
color = '#000',
|
|
13
|
+
style,
|
|
14
|
+
}) => (
|
|
15
|
+
<Svg width={size} height={size} viewBox="0 0 20 20" fill="none" style={style}>
|
|
16
|
+
<Path
|
|
17
|
+
d="M10.0151 1.66602C8.14839 2.59185 6.66667 3.33268 2.5 4.16602C2.5 5.11352 2.5 8.08428 2.5 9.07344C2.5 14.6293 7.2225 17.4068 10 18.3327C12.7775 17.4068 17.5 14.6293 17.5 9.07344C17.5 8.05261 17.5 5.16102 17.5 4.16602C13.3333 3.33268 11.8517 2.59185 10.0151 1.66602ZM12.9517 8.77437L9.61833 12.1077C9.49666 12.2294 9.33664 12.291 9.17664 12.291C9.01663 12.291 8.85661 12.2302 8.73494 12.1077L7.06828 10.441C6.82411 10.1969 6.82411 9.80101 7.06828 9.55684C7.31244 9.31268 7.70831 9.31268 7.95247 9.55684L9.17745 10.7818L12.0691 7.89018C12.3133 7.64601 12.7091 7.64601 12.9533 7.89018C13.1975 8.13434 13.1958 8.53021 12.9517 8.77437Z"
|
|
18
|
+
fill={color}
|
|
19
|
+
/>
|
|
20
|
+
</Svg>
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
export default ShieldCheckedFill;
|
package/src/Icon/type.tsx
CHANGED
|
@@ -61,6 +61,12 @@ export type IconNameProps =
|
|
|
61
61
|
| 'Italic'
|
|
62
62
|
| 'UnderLine'
|
|
63
63
|
| 'settings-slider'
|
|
64
|
+
| 'location-pin-fill'
|
|
65
|
+
| 'discount-fill'
|
|
66
|
+
| 'rotate-square-fill'
|
|
67
|
+
| 'copy-fill'
|
|
68
|
+
| 'copy-text-fill'
|
|
69
|
+
| 'shield-checked-fill'
|
|
64
70
|
| 'whatsapp-fill';
|
|
65
71
|
|
|
66
72
|
export interface IconProps {
|
package/src/Input/Input.tsx
CHANGED
|
@@ -20,6 +20,7 @@ const Input: React.FC<InputProps> = ({
|
|
|
20
20
|
onPressIconRight,
|
|
21
21
|
secureTextEntry = false,
|
|
22
22
|
iconRightColor,
|
|
23
|
+
prefix,
|
|
23
24
|
...rest
|
|
24
25
|
}) => {
|
|
25
26
|
const [inputValue, setInputValue] = useState(value || '');
|
|
@@ -49,26 +50,16 @@ const Input: React.FC<InputProps> = ({
|
|
|
49
50
|
]}
|
|
50
51
|
>
|
|
51
52
|
{icon && (
|
|
52
|
-
<TouchableOpacity
|
|
53
|
-
onPress={onPressIconLeft}
|
|
54
|
-
style={styles.iconLeft}
|
|
55
|
-
hitSlop={10}
|
|
56
|
-
>
|
|
53
|
+
<TouchableOpacity onPress={onPressIconLeft} hitSlop={10}>
|
|
57
54
|
<Icon name={icon} size={20} color="#888" />
|
|
58
55
|
</TouchableOpacity>
|
|
59
56
|
)}
|
|
60
57
|
|
|
58
|
+
{prefix && <View style={styles.prefixContainer}>{prefix}</View>}
|
|
59
|
+
|
|
61
60
|
<TextInput
|
|
62
61
|
{...rest}
|
|
63
|
-
style={[
|
|
64
|
-
styles.input,
|
|
65
|
-
icon && { paddingLeft: 40 },
|
|
66
|
-
showRightIcons && { paddingRight: 40 },
|
|
67
|
-
showRightIcons &&
|
|
68
|
-
clearButton &&
|
|
69
|
-
inputValue !== '' && { paddingRight: 65 },
|
|
70
|
-
style,
|
|
71
|
-
]}
|
|
62
|
+
style={[styles.input, style]}
|
|
72
63
|
secureTextEntry={secureTextEntry}
|
|
73
64
|
value={inputValue}
|
|
74
65
|
onChangeText={handleChange}
|
|
@@ -80,7 +71,7 @@ const Input: React.FC<InputProps> = ({
|
|
|
80
71
|
{clearButton && inputValue !== '' && (
|
|
81
72
|
<TouchableOpacity
|
|
82
73
|
onPress={handleClear}
|
|
83
|
-
style={
|
|
74
|
+
style={iconRight && styles.mr8}
|
|
84
75
|
>
|
|
85
76
|
<Icon name="x-circle" size={20} color="#aaa" />
|
|
86
77
|
</TouchableOpacity>
|
|
@@ -118,31 +109,32 @@ const styles = StyleSheet.create({
|
|
|
118
109
|
position: 'relative',
|
|
119
110
|
height: 40,
|
|
120
111
|
borderRadius: 8,
|
|
121
|
-
gap:
|
|
112
|
+
gap: 4,
|
|
113
|
+
paddingHorizontal: 12,
|
|
122
114
|
borderWidth: 1,
|
|
123
115
|
backgroundColor: Color.base.white100,
|
|
124
116
|
justifyContent: 'center',
|
|
117
|
+
flexDirection: 'row',
|
|
118
|
+
alignItems: 'center',
|
|
125
119
|
},
|
|
126
120
|
input: {
|
|
127
121
|
height: 37,
|
|
128
|
-
paddingHorizontal: 12,
|
|
129
122
|
paddingTop: 0,
|
|
130
123
|
paddingBottom: 0,
|
|
131
124
|
fontSize: 16,
|
|
132
125
|
color: '#333',
|
|
133
126
|
flex: 1,
|
|
134
127
|
},
|
|
135
|
-
iconLeft: {
|
|
136
|
-
position: 'absolute',
|
|
137
|
-
left: 12,
|
|
138
|
-
zIndex: 1,
|
|
139
|
-
},
|
|
140
128
|
rightContainer: {
|
|
141
|
-
position: 'absolute',
|
|
142
|
-
right: 12,
|
|
143
129
|
flexDirection: 'row',
|
|
144
130
|
alignItems: 'center',
|
|
145
|
-
|
|
131
|
+
},
|
|
132
|
+
prefixContainer: {
|
|
133
|
+
justifyContent: 'center',
|
|
134
|
+
flexDirection: 'row',
|
|
135
|
+
},
|
|
136
|
+
mr8: {
|
|
137
|
+
marginRight: 8,
|
|
146
138
|
},
|
|
147
139
|
});
|
|
148
140
|
|
|
@@ -6,21 +6,22 @@ Komponen `Input` ini adalah komponen input teks yang dapat dikustomisasi dengan
|
|
|
6
6
|
|
|
7
7
|
## 🔧 Props
|
|
8
8
|
|
|
9
|
-
| Prop
|
|
10
|
-
|
|
11
|
-
| `label`
|
|
12
|
-
| `value`
|
|
13
|
-
| `onChange`
|
|
14
|
-
| `icon`
|
|
15
|
-
| `iconRight`
|
|
16
|
-
| `clearButton`
|
|
17
|
-
| `hasError`
|
|
18
|
-
| `hint`
|
|
19
|
-
| `onPressIconLeft`
|
|
20
|
-
| `onPressIconRight` | `() => void`
|
|
21
|
-
| `secureTextEntry
|
|
22
|
-
| `style`
|
|
23
|
-
|
|
|
9
|
+
| Prop | Tipe | Deskripsi |
|
|
10
|
+
| ------------------ | ------------------------- | --------------------------------------------------------------------- |
|
|
11
|
+
| `label` | `string` | Label yang ditampilkan di atas input |
|
|
12
|
+
| `value` | `string` | Nilai dari input (kontrol dari luar) |
|
|
13
|
+
| `onChange` | `(value: string) => void` | Fungsi yang dipanggil saat nilai berubah |
|
|
14
|
+
| `icon` | `string` | Nama ikon (kiri) dari library `Icon` |
|
|
15
|
+
| `iconRight` | `string` | Nama ikon kanan dari library `Icon` |
|
|
16
|
+
| `clearButton` | `boolean` | Menampilkan tombol `x` untuk menghapus input |
|
|
17
|
+
| `hasError` | `boolean` | Menandai input error, border akan berubah merah |
|
|
18
|
+
| `hint` | `string` | Menampilkan teks kecil di bawah input, bisa untuk error atau petunjuk |
|
|
19
|
+
| `onPressIconLeft` | `() => void` | Fungsi saat ikon kiri diklik |
|
|
20
|
+
| `onPressIconRight` | `() => void` | Fungsi saat ikon kanan diklik |
|
|
21
|
+
| `secureTextEntry` | `boolean` | Jika `true`, menyembunyikan input (untuk password) |
|
|
22
|
+
| `style` | `ViewStyle` | Style tambahan untuk input |
|
|
23
|
+
| `prefix` | `React.ReactNode` | Slot `react node` yang bisa diisi oleh seluruh komponen react |
|
|
24
|
+
| `...rest` | `TextInputProps` | Props lain dari React Native `TextInput` |
|
|
24
25
|
|
|
25
26
|
---
|
|
26
27
|
|
|
@@ -49,3 +50,4 @@ export default function MyForm() {
|
|
|
49
50
|
</View>
|
|
50
51
|
);
|
|
51
52
|
}
|
|
53
|
+
```
|
package/src/Input/type.tsx
CHANGED
package/src/Tab/README.md
CHANGED
|
@@ -2,13 +2,56 @@
|
|
|
2
2
|
|
|
3
3
|
Komponen tab ringan dan fleksibel untuk React Native yang mendukung:
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
- ✅ Swipe kiri/kanan antar tab
|
|
6
|
+
- ✅ Scroll vertikal di dalam konten tiap tab
|
|
7
|
+
- ✅ Tampilan tab yang bisa disesuaikan
|
|
8
|
+
- ✅ Tanpa dependensi eksternal (tidak butuh react-navigation)
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
+
## ⚙️ Instalasi
|
|
13
|
+
|
|
14
|
+
Komponen tab ini dibangun menggunakan [react-native-pager-view](https://github.com/callstack/react-native-pager-view) untuk mengatur perpindahan tab secara swipe kiri/kanan.
|
|
15
|
+
Pastikan Anda menginstal dependensi ini sebelum menggunakan komponen.
|
|
16
|
+
|
|
17
|
+
### 1. Install Dependensi
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
# Menggunakan npm
|
|
21
|
+
npm install react-native-pager-view
|
|
22
|
+
|
|
23
|
+
# Menggunakan yarn
|
|
24
|
+
yarn add react-native-pager-view
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### 2. Konfigurasi Platform
|
|
28
|
+
|
|
29
|
+
#### iOS
|
|
30
|
+
|
|
31
|
+
Setelah instalasi, jalankan perintah berikut untuk meng-install pod:
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
cd ios && pod install && cd ..
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Tidak ada konfigurasi tambahan untuk iOS, namun pastikan proyek Anda sudah menggunakan **minimum iOS 11** atau sesuai rekomendasi React Native agar kompatibel.
|
|
38
|
+
|
|
39
|
+
#### Android
|
|
40
|
+
|
|
41
|
+
`react-native-pager-view` akan otomatis ter-link di Android tanpa perlu langkah tambahan.
|
|
42
|
+
Namun, Anda perlu memastikan bahwa **minimum SDK version** Anda adalah 21 atau lebih tinggi.
|
|
43
|
+
Periksa file `android/app/build.gradle`:
|
|
44
|
+
|
|
45
|
+
```gradle
|
|
46
|
+
android {
|
|
47
|
+
defaultConfig {
|
|
48
|
+
minSdkVersion = 21
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Jika nilai `minSdkVersion` di bawah 21, tingkatkan agar komponen dapat berjalan dengan baik.
|
|
54
|
+
|
|
12
55
|
## 💡 Contoh Penggunaan
|
|
13
56
|
|
|
14
57
|
```tsx
|
|
@@ -33,8 +76,8 @@ export default function App() {
|
|
|
33
76
|
|
|
34
77
|
### 1. Navigasi Tab
|
|
35
78
|
|
|
36
|
-
|
|
37
|
-
|
|
79
|
+
- Tap pada header tab untuk berpindah
|
|
80
|
+
- Swipe kiri/kanan untuk berpindah antar tab
|
|
38
81
|
|
|
39
82
|
### 2. Konten Scrollable
|
|
40
83
|
|
package/src/Timeline/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# 🗂️ Timeline & TimelineItem
|
|
2
|
+
|
|
2
3
|
Timeline menampilkan rangkaian peristiwa secara vertikal—mirip “stepper” atau “activity feed”.
|
|
3
4
|
Setiap node diwakili oleh TimelineItem yang menampilkan titik (bullet icon) dan garis vertikal terhubung.
|
|
4
5
|
|
|
@@ -31,50 +32,48 @@ export default function OrderHistory() {
|
|
|
31
32
|
</Timeline>
|
|
32
33
|
);
|
|
33
34
|
}
|
|
34
|
-
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
## Props
|
|
38
38
|
|
|
39
39
|
### Timeline
|
|
40
|
+
|
|
40
41
|
| Prop | Type | Wajib | Default | Deskripsi |
|
|
41
42
|
| ---------- | ----------- | ----- | ------- | ---------------------------------- |
|
|
42
|
-
| `children` | `ReactNode` | ✅
|
|
43
|
-
|
|
43
|
+
| `children` | `ReactNode` | ✅ | — | Satu atau beberapa `TimelineItem`. |
|
|
44
44
|
|
|
45
45
|
### TimelineItem
|
|
46
|
-
| Prop | Type | Wajib | Default | Deskripsi |
|
|
47
|
-
| ---------- | ------------------------------------------------------------- | ----- | ----------- | ----------------------------------------------------- |
|
|
48
|
-
| `children` | `ReactNode` | ✅ | — | Konten untuk node timeline: teks, ikon tambahan, dsb. |
|
|
49
|
-
| `color` | `'primary' \| 'success' \| 'warning' \| 'danger' \| 'purple'` | ❌ | `'primary'` | Skema warna titik (`RadioButton`) dan garis vertikal. |
|
|
50
46
|
|
|
47
|
+
| Prop | Type | Wajib | Default | Deskripsi |
|
|
48
|
+
| ---------- | --------------------------------------------------------------------------------- | ----- | ----------- | ---------------------------------------------------------------- |
|
|
49
|
+
| `children` | `ReactNode` | ✅ | — | Konten untuk node timeline: teks, ikon tambahan, dsb. |
|
|
50
|
+
| `color` | `'primary' \| 'success' \| 'warning' \| 'danger' \| 'purple'\| 'info'\| 'orange'` | ❌ | `'primary'` | Skema warna titik (`RadioButton`) dan garis vertikal. |
|
|
51
|
+
| `isLast` | `boolean` | ❌ | `false` | Menentukan apakah garis garis di kiri itu dimunculkan atau tidak |
|
|
51
52
|
|
|
52
53
|
## ⚙️ Cara Kerja
|
|
53
54
|
|
|
54
55
|
1. Bullet & Line
|
|
56
|
+
- Bullet dirender dengan komponen Icon (name="RadioButton") memakai warna dari color.
|
|
55
57
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
- Garis vertikal (borderLeftWidth: 1) menggunakan borderStyle: 'dashed'. Tingginya dihitung secara dinamis (contentHeight - 20) agar garis mulai tepat di bawah bullet.
|
|
58
|
+
- Garis vertikal (borderLeftWidth: 1) menggunakan borderStyle: 'dashed'. Tingginya dihitung secara dinamis (contentHeight - 20) agar garis mulai tepat di bawah bullet.
|
|
59
59
|
|
|
60
60
|
2. Penghitungan Tinggi
|
|
61
|
+
- onLayout pada wrapper konten mengukur tinggi aktual item.
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
- Hasil pengukuran dipakai untuk menyesuaikan panjang garis, menjaga visual konsisten meskipun konten memiliki tinggi berbeda.
|
|
63
|
+
- Hasil pengukuran dipakai untuk menyesuaikan panjang garis, menjaga visual konsisten meskipun konten memiliki tinggi berbeda.
|
|
65
64
|
|
|
66
65
|
3. Layout
|
|
66
|
+
- Komponen dibangun dengan flexDirection: 'row', bullet di kiri, konten di kanan (flex: 1).
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
- Margin horizontal (marginRight: 8) menjaga jarak antara bullet dan konten.
|
|
68
|
+
- Margin horizontal (marginRight: 8) menjaga jarak antara bullet dan konten.
|
|
71
69
|
|
|
72
70
|
## 💡 Tips Penggunaan
|
|
71
|
+
|
|
73
72
|
- Item Terakhir Tanpa Garis
|
|
74
|
-
Bila ingin menghilangkan garis pada item terakhir, buat prop opsional mis. isLast dan kondisikan tinggi garis menjadi 0.
|
|
73
|
+
Bila ingin menghilangkan garis pada item terakhir, buat prop opsional mis. isLast dan kondisikan tinggi garis menjadi 0.
|
|
75
74
|
|
|
76
75
|
- Interaktif
|
|
77
|
-
Anda bebas menambahkan tombol, TouchableOpacity, atau ikon status di dalam children.
|
|
76
|
+
Anda bebas menambahkan tombol, TouchableOpacity, atau ikon status di dalam children.
|
|
78
77
|
|
|
79
78
|
- Kustomisasi Warna
|
|
80
|
-
Untuk warna tambahan, update COLOR_MAP dan tipe ColorKey pada TimelineItem.
|
|
79
|
+
Untuk warna tambahan, update COLOR_MAP dan tipe ColorKey pada TimelineItem.
|
|
@@ -9,30 +9,27 @@ const COLOR_MAP = {
|
|
|
9
9
|
success: Color.success[500],
|
|
10
10
|
purple: Color.purple[500],
|
|
11
11
|
danger: Color.danger[500],
|
|
12
|
+
info: Color.info[500],
|
|
13
|
+
default: Color.gray[700],
|
|
14
|
+
orange: Color.orange[500],
|
|
12
15
|
};
|
|
13
16
|
type ColorKey = keyof typeof COLOR_MAP;
|
|
14
17
|
|
|
15
18
|
interface TimelineItemProps {
|
|
16
19
|
children: React.ReactNode;
|
|
17
20
|
color?: ColorKey;
|
|
21
|
+
isLast?: boolean;
|
|
18
22
|
}
|
|
19
23
|
|
|
20
24
|
export default function TimelineItem({
|
|
21
25
|
children,
|
|
22
26
|
color = 'primary',
|
|
27
|
+
isLast = false,
|
|
23
28
|
}: TimelineItemProps) {
|
|
24
29
|
const [contentHeight, setContentHeight] = useState(0);
|
|
25
30
|
const renderDashes = (count: number) => {
|
|
26
31
|
return Array.from({ length: count }).map((_, index) => (
|
|
27
|
-
<View
|
|
28
|
-
key={index}
|
|
29
|
-
style={{
|
|
30
|
-
width: 1,
|
|
31
|
-
height: 4,
|
|
32
|
-
backgroundColor: Color.gray[400],
|
|
33
|
-
marginVertical: 2,
|
|
34
|
-
}}
|
|
35
|
-
/>
|
|
32
|
+
<View key={index} style={styles.dashes} />
|
|
36
33
|
));
|
|
37
34
|
};
|
|
38
35
|
|
|
@@ -40,7 +37,9 @@ export default function TimelineItem({
|
|
|
40
37
|
<View style={styles.container}>
|
|
41
38
|
<View style={styles.contentLeft}>
|
|
42
39
|
<Icon name="RadioButton" color={COLOR_MAP[color]} />
|
|
43
|
-
<View>
|
|
40
|
+
<View>
|
|
41
|
+
{!isLast && renderDashes(Math.floor((contentHeight - 20) / 6))}
|
|
42
|
+
</View>
|
|
44
43
|
</View>
|
|
45
44
|
<View
|
|
46
45
|
style={styles.flex}
|
|
@@ -73,4 +72,10 @@ const styles = StyleSheet.create({
|
|
|
73
72
|
flex: {
|
|
74
73
|
flex: 1,
|
|
75
74
|
},
|
|
75
|
+
dashes: {
|
|
76
|
+
width: 1,
|
|
77
|
+
height: 4,
|
|
78
|
+
backgroundColor: Color.gray[400],
|
|
79
|
+
marginVertical: 2,
|
|
80
|
+
},
|
|
76
81
|
});
|
package/src/index.tsx
CHANGED
|
@@ -86,3 +86,4 @@ export { ToastProvider, useToast } from './Toast/ToastContext';
|
|
|
86
86
|
export { default as Skeleton } from './Skeleton/Skeleton';
|
|
87
87
|
export type { SkeletonProps } from './Skeleton/type';
|
|
88
88
|
export { default as CounterButton } from './CounterButton/CounterButton';
|
|
89
|
+
export { default as BadgeIcon } from './BadgeIcon/BadgeIcon';
|