@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.
Files changed (115) hide show
  1. package/lib/module/Accordion/Accordion.js +11 -2
  2. package/lib/module/Accordion/Accordion.js.map +1 -1
  3. package/lib/module/Accordion/AccordionItem.js +1 -0
  4. package/lib/module/Accordion/AccordionItem.js.map +1 -1
  5. package/lib/module/Accordion/README.md +14 -11
  6. package/lib/module/BadgeIcon/BadgeIcon.js +117 -0
  7. package/lib/module/BadgeIcon/BadgeIcon.js.map +1 -0
  8. package/lib/module/BadgeIcon/README.md +77 -0
  9. package/lib/module/BadgeIcon/type.js +2 -0
  10. package/lib/module/BadgeIcon/type.js.map +1 -0
  11. package/lib/module/BottomSheet/BottomSheet.js +1 -1
  12. package/lib/module/BottomSheet/BottomSheet.js.map +1 -1
  13. package/lib/module/CheckBox/CheckBox.js +65 -32
  14. package/lib/module/CheckBox/CheckBox.js.map +1 -1
  15. package/lib/module/CheckBox/CheckBoxList.js +10 -2
  16. package/lib/module/CheckBox/CheckBoxList.js.map +1 -1
  17. package/lib/module/CheckBox/README_CHECKBOX.md +10 -7
  18. package/lib/module/CheckBox/README_CHECKBOXLIST.md +13 -7
  19. package/lib/module/CheckBox/type.js +2 -0
  20. package/lib/module/CheckBox/type.js.map +1 -0
  21. package/lib/module/Icon/Icon.js +13 -1
  22. package/lib/module/Icon/Icon.js.map +1 -1
  23. package/lib/module/Icon/README.md +7 -0
  24. package/lib/module/Icon/icons/CopyFill.js +25 -0
  25. package/lib/module/Icon/icons/CopyFill.js.map +1 -0
  26. package/lib/module/Icon/icons/CopyTextFill.js +22 -0
  27. package/lib/module/Icon/icons/CopyTextFill.js.map +1 -0
  28. package/lib/module/Icon/icons/DiscountFill.js +23 -0
  29. package/lib/module/Icon/icons/DiscountFill.js.map +1 -0
  30. package/lib/module/Icon/icons/LocationPinFill.js +21 -0
  31. package/lib/module/Icon/icons/LocationPinFill.js.map +1 -0
  32. package/lib/module/Icon/icons/RadioButton.js +0 -1
  33. package/lib/module/Icon/icons/RadioButton.js.map +1 -1
  34. package/lib/module/Icon/icons/RotateSquareFill.js +21 -0
  35. package/lib/module/Icon/icons/RotateSquareFill.js.map +1 -0
  36. package/lib/module/Icon/icons/ShieldFillChecked.js +22 -0
  37. package/lib/module/Icon/icons/ShieldFillChecked.js.map +1 -0
  38. package/lib/module/Input/Input.js +19 -23
  39. package/lib/module/Input/Input.js.map +1 -1
  40. package/lib/module/Input/README_INPUT.md +17 -15
  41. package/lib/module/Tab/README.md +49 -6
  42. package/lib/module/Timeline/README.md +18 -19
  43. package/lib/module/Timeline/TimelineItem.js +14 -9
  44. package/lib/module/Timeline/TimelineItem.js.map +1 -1
  45. package/lib/module/index.js +1 -0
  46. package/lib/module/index.js.map +1 -1
  47. package/lib/typescript/src/Accordion/Accordion.d.ts +1 -1
  48. package/lib/typescript/src/Accordion/Accordion.d.ts.map +1 -1
  49. package/lib/typescript/src/Accordion/AccordionItem.d.ts.map +1 -1
  50. package/lib/typescript/src/Accordion/type.d.ts +1 -0
  51. package/lib/typescript/src/Accordion/type.d.ts.map +1 -1
  52. package/lib/typescript/src/BadgeIcon/BadgeIcon.d.ts +20 -0
  53. package/lib/typescript/src/BadgeIcon/BadgeIcon.d.ts.map +1 -0
  54. package/lib/typescript/src/BadgeIcon/type.d.ts +11 -0
  55. package/lib/typescript/src/BadgeIcon/type.d.ts.map +1 -0
  56. package/lib/typescript/src/BottomSheet/BottomSheet.d.ts.map +1 -1
  57. package/lib/typescript/src/CheckBox/CheckBox.d.ts +4 -0
  58. package/lib/typescript/src/CheckBox/CheckBox.d.ts.map +1 -1
  59. package/lib/typescript/src/CheckBox/CheckBoxList.d.ts +3 -0
  60. package/lib/typescript/src/CheckBox/CheckBoxList.d.ts.map +1 -1
  61. package/lib/typescript/src/CheckBox/type.d.ts +2 -0
  62. package/lib/typescript/src/CheckBox/type.d.ts.map +1 -0
  63. package/lib/typescript/src/Icon/Icon.d.ts.map +1 -1
  64. package/lib/typescript/src/Icon/icons/CopyFill.d.ts +9 -0
  65. package/lib/typescript/src/Icon/icons/CopyFill.d.ts.map +1 -0
  66. package/lib/typescript/src/Icon/icons/CopyTextFill.d.ts +9 -0
  67. package/lib/typescript/src/Icon/icons/CopyTextFill.d.ts.map +1 -0
  68. package/lib/typescript/src/Icon/icons/DiscountFill.d.ts +8 -0
  69. package/lib/typescript/src/Icon/icons/DiscountFill.d.ts.map +1 -0
  70. package/lib/typescript/src/Icon/icons/LocationPinFill.d.ts +8 -0
  71. package/lib/typescript/src/Icon/icons/LocationPinFill.d.ts.map +1 -0
  72. package/lib/typescript/src/Icon/icons/RotateSquareFill.d.ts +8 -0
  73. package/lib/typescript/src/Icon/icons/RotateSquareFill.d.ts.map +1 -0
  74. package/lib/typescript/src/Icon/icons/ShieldFillChecked.d.ts +9 -0
  75. package/lib/typescript/src/Icon/icons/ShieldFillChecked.d.ts.map +1 -0
  76. package/lib/typescript/src/Icon/type.d.ts +1 -1
  77. package/lib/typescript/src/Icon/type.d.ts.map +1 -1
  78. package/lib/typescript/src/Input/Input.d.ts.map +1 -1
  79. package/lib/typescript/src/Input/type.d.ts +1 -0
  80. package/lib/typescript/src/Input/type.d.ts.map +1 -1
  81. package/lib/typescript/src/Timeline/TimelineItem.d.ts +5 -1
  82. package/lib/typescript/src/Timeline/TimelineItem.d.ts.map +1 -1
  83. package/lib/typescript/src/index.d.ts +1 -0
  84. package/lib/typescript/src/index.d.ts.map +1 -1
  85. package/package.json +1 -1
  86. package/src/Accordion/Accordion.tsx +15 -3
  87. package/src/Accordion/AccordionItem.tsx +5 -1
  88. package/src/Accordion/README.md +14 -11
  89. package/src/Accordion/type.tsx +1 -0
  90. package/src/BadgeIcon/BadgeIcon.tsx +126 -0
  91. package/src/BadgeIcon/README.md +77 -0
  92. package/src/BadgeIcon/type.tsx +21 -0
  93. package/src/BottomSheet/BottomSheet.tsx +5 -1
  94. package/src/CheckBox/CheckBox.tsx +45 -29
  95. package/src/CheckBox/CheckBoxList.tsx +12 -0
  96. package/src/CheckBox/README_CHECKBOX.md +10 -7
  97. package/src/CheckBox/README_CHECKBOXLIST.md +13 -7
  98. package/src/CheckBox/type.ts +9 -0
  99. package/src/Icon/Icon.tsx +12 -0
  100. package/src/Icon/README.md +7 -0
  101. package/src/Icon/icons/CopyFill.tsx +23 -0
  102. package/src/Icon/icons/CopyTextFill.tsx +29 -0
  103. package/src/Icon/icons/DiscountFill.tsx +26 -0
  104. package/src/Icon/icons/LocationPinFill.tsx +28 -0
  105. package/src/Icon/icons/RadioButton.tsx +1 -1
  106. package/src/Icon/icons/RotateSquareFill.tsx +22 -0
  107. package/src/Icon/icons/ShieldFillChecked.tsx +23 -0
  108. package/src/Icon/type.tsx +6 -0
  109. package/src/Input/Input.tsx +17 -25
  110. package/src/Input/README_INPUT.md +17 -15
  111. package/src/Input/type.tsx +1 -0
  112. package/src/Tab/README.md +49 -6
  113. package/src/Timeline/README.md +18 -19
  114. package/src/Timeline/TimelineItem.tsx +15 -10
  115. 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 {
@@ -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={[{ marginRight: iconRight ? 8 : 0 }]}
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: 8,
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
- zIndex: 1,
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 | 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
- | `...rest` | `TextInputProps` | Props lain dari React Native `TextInput` |
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
+ ```
@@ -13,6 +13,7 @@ export interface InputProps extends TextInputProps {
13
13
  onChangeText?: (val: string) => void;
14
14
  secureTextEntry?: boolean;
15
15
  iconRightColor?: string;
16
+ prefix?: React.ReactNode;
16
17
  }
17
18
 
18
19
  export interface TextAreaProps extends InputProps {
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
- * ✅ 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)
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
- * Tap pada header tab untuk berpindah
37
- * Swipe kiri/kanan untuk berpindah antar tab
79
+ - Tap pada header tab untuk berpindah
80
+ - Swipe kiri/kanan untuk berpindah antar tab
38
81
 
39
82
  ### 2. Konten Scrollable
40
83
 
@@ -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` | ✅ | — | Satu atau beberapa `TimelineItem`. |
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
- - Bullet dirender dengan komponen Icon (name="RadioButton") memakai warna dari color.
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
- - onLayout pada wrapper konten mengukur tinggi aktual item.
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
- - Komponen dibangun dengan flexDirection: 'row', bullet di kiri, konten di kanan (flex: 1).
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>{renderDashes(Math.floor((contentHeight - 20) / 6))}</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';