@herca/rn-kit 0.1.7 → 0.1.9
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 +12 -7
- package/lib/module/Accordion/README.md +1 -0
- package/lib/module/Alert/README.md +1 -0
- package/lib/module/Avatar/README_AVATAR.md +1 -1
- package/lib/module/Avatar/README_AVATARGROUP.md +3 -1
- package/lib/module/BottomSheet/README.md +1 -1
- package/lib/module/Button/README.md +3 -1
- package/lib/module/Calendar/README.md +1 -0
- package/lib/module/CheckBox/README_CHECKBOXLIST.md +1 -0
- package/lib/module/Chip/README.md +2 -1
- package/lib/module/Color/README.md +97 -46
- package/lib/module/DatePicker/{README.md → README_DATEPICKER.md} +1 -0
- package/lib/module/DatePicker/README_MONTHPICKER.md +90 -0
- package/lib/module/DatePicker/README_TIMEPICKER.md +83 -0
- package/lib/module/DatePicker/README_YEARPICKER.md +106 -0
- package/lib/module/Drawing/Drawing.js +16 -4
- package/lib/module/Drawing/Drawing.js.map +1 -1
- package/lib/module/DropDown/README.md +107 -0
- package/lib/module/Label/README.md +65 -0
- package/lib/module/RadioButton/README.md +2 -1
- package/lib/module/Step/Step.js.map +1 -1
- package/lib/module/Tab/README.md +74 -0
- package/lib/module/Tab/Tab.js +97 -0
- package/lib/module/Tab/Tab.js.map +1 -0
- package/lib/module/Tab/TabItem.js +9 -0
- package/lib/module/Tab/TabItem.js.map +1 -0
- package/lib/module/Tab/type.js +4 -0
- package/lib/module/Tab/type.js.map +1 -0
- package/lib/module/Ui/README_DEVIDER.md +62 -0
- package/lib/module/Ui/README_FOOTER.md +0 -0
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/Drawing/Drawing.d.ts.map +1 -1
- package/lib/typescript/src/Step/Step.d.ts.map +1 -1
- package/lib/typescript/src/Tab/Tab.d.ts +5 -0
- package/lib/typescript/src/Tab/Tab.d.ts.map +1 -0
- package/lib/typescript/src/Tab/TabItem.d.ts +3 -0
- package/lib/typescript/src/Tab/TabItem.d.ts.map +1 -0
- package/lib/typescript/src/Tab/type.d.ts +11 -0
- package/lib/typescript/src/Tab/type.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +3 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +8 -2
- package/src/Accordion/README.md +1 -0
- package/src/Alert/README.md +1 -0
- package/src/Avatar/README_AVATAR.md +1 -1
- package/src/Avatar/README_AVATARGROUP.md +3 -1
- package/src/BottomSheet/README.md +1 -1
- package/src/Button/README.md +3 -1
- package/src/Calendar/README.md +1 -0
- package/src/CheckBox/README_CHECKBOXLIST.md +1 -0
- package/src/Chip/README.md +2 -1
- package/src/Color/README.md +97 -46
- package/src/DatePicker/{README.md → README_DATEPICKER.md} +1 -0
- package/src/DatePicker/README_MONTHPICKER.md +90 -0
- package/src/DatePicker/README_TIMEPICKER.md +83 -0
- package/src/DatePicker/README_YEARPICKER.md +106 -0
- package/src/Drawing/Drawing.tsx +14 -0
- package/src/DropDown/README.md +107 -0
- package/src/Label/README.md +65 -0
- package/src/RadioButton/README.md +2 -1
- package/src/Step/Step.tsx +0 -1
- package/src/Tab/README.md +74 -0
- package/src/Tab/Tab.tsx +112 -0
- package/src/Tab/TabItem.tsx +6 -0
- package/src/Tab/type.tsx +11 -0
- package/src/Ui/README_DEVIDER.md +62 -0
- package/src/Ui/README_FOOTER.md +0 -0
- package/src/index.tsx +8 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Label
|
|
2
|
+
|
|
3
|
+
**Label** adalah komponen kecil berbentuk badge untuk menampilkan status, kategori, atau metadata ringkas. Komponen ini mendukung ikon, variasi warna, dan konten kustom.
|
|
4
|
+
|
|
5
|
+
## API Reference
|
|
6
|
+
|
|
7
|
+
| Prop | Tipe | Default | Deskripsi |
|
|
8
|
+
| ---------- | ------------------------------------------------------------------------------------------------ | ----------- | ------------------------------------------------------------------------------ |
|
|
9
|
+
| `label` | `string` | `''` | Teks yang ditampilkan jika `children` tidak disediakan. |
|
|
10
|
+
| `children` | `React.ReactNode` | `undefined` | Menampilkan elemen kustom sebagai isi label. Jika ada, `label` akan diabaikan. |
|
|
11
|
+
| `color` | `'default' \| 'success' \| 'danger' \| 'primary' \| 'warning' \| 'info' \| 'purple' \| 'orange'` | `'default'` | Variasi warna latar dan teks. |
|
|
12
|
+
| `icon` | `IconNameProps` | `undefined` | Menampilkan ikon di sebelah kiri teks. |
|
|
13
|
+
| `size` | `'small' \| 'medium'` | `'medium'` | (Belum digunakan – untuk ekspansi ukuran ke depan.) |
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Warna yang Didukung
|
|
18
|
+
|
|
19
|
+
| Warna | Background | Teks |
|
|
20
|
+
| --------- | ------------------- | -------------------- |
|
|
21
|
+
| `default` | `Color.gray[50]` | `Color.gray[900]` |
|
|
22
|
+
| `success` | `Color.success[50]` | `Color.success[300]` |
|
|
23
|
+
| `danger` | `Color.danger[50]` | `Color.danger[300]` |
|
|
24
|
+
| `primary` | `Color.primary[50]` | `Color.primary[300]` |
|
|
25
|
+
| `warning` | `Color.warning[50]` | `Color.warning[300]` |
|
|
26
|
+
| `info` | `Color.info[50]` | `Color.info[300]` |
|
|
27
|
+
| `purple` | `Color.purple[50]` | `Color.purple[300]` |
|
|
28
|
+
| `orange` | `Color.orange[50]` | `Color.orange[300]` |
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Contoh Penggunaan
|
|
33
|
+
|
|
34
|
+
### Label Sederhana
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
<Label label="Active" color="success" />
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Label dengan Ikon
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
<Label label="Error" color="danger" icon="AlertCircle" />
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Kustom Isi (Children)
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
<Label color="primary">
|
|
50
|
+
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
|
51
|
+
<Icon name="Check" color={Color.primary[300]} size={12} />
|
|
52
|
+
<Text style={{ color: Color.primary[300], marginLeft: 4 }}>Custom</Text>
|
|
53
|
+
</View>
|
|
54
|
+
</Label>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Catatan Tambahan
|
|
60
|
+
|
|
61
|
+
* Jika Anda memberikan `children`, maka `label` dan `icon` akan diabaikan.
|
|
62
|
+
* Komponen ini menggunakan `alignSelf: 'flex-start'` agar ukuran label tidak penuh.
|
|
63
|
+
* Prop `size` belum aktif, namun sudah disiapkan jika ke depan ingin mendukung skala `small`/`large`.
|
|
64
|
+
|
|
65
|
+
---
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# 📦 RadioButton – Komponen React Native
|
|
2
2
|
|
|
3
3
|
Komponen `RadioButton` ini digunakan untuk menampilkan daftar pilihan dalam bentuk radio button di aplikasi React Native.
|
|
4
|
-
|
|
4
|
+
<img src="../../assets/doc/RadioButton/RadioButton.png" width=200>
|
|
5
|
+
|
|
5
6
|
|
|
6
7
|
## 📄 Import
|
|
7
8
|
|
package/src/Step/Step.tsx
CHANGED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# 📱 Komponen Tab Kustom untuk React Native
|
|
2
|
+
|
|
3
|
+
Komponen tab ringan dan fleksibel untuk React Native yang mendukung:
|
|
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)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 💡 Contoh Penggunaan
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
import Tab from './Tab';
|
|
16
|
+
import TabItem from './TabItem';
|
|
17
|
+
import HomeScreen from './screens/Home';
|
|
18
|
+
import ProfileScreen from './screens/Profile';
|
|
19
|
+
|
|
20
|
+
export default function App() {
|
|
21
|
+
return (
|
|
22
|
+
<Tab>
|
|
23
|
+
<TabItem name="Beranda" component={HomeScreen} />
|
|
24
|
+
<TabItem name="Profil" component={ProfileScreen} />
|
|
25
|
+
</Tab>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## ✨ Fitur
|
|
33
|
+
|
|
34
|
+
### 1. Navigasi Tab
|
|
35
|
+
|
|
36
|
+
* Tap pada header tab untuk berpindah
|
|
37
|
+
* Swipe kiri/kanan untuk berpindah antar tab
|
|
38
|
+
|
|
39
|
+
### 2. Konten Scrollable
|
|
40
|
+
|
|
41
|
+
Setiap tab dibungkus dalam `ScrollView` vertikal, sehingga bisa discroll ke bawah jika konten panjang.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 🧩 Props
|
|
46
|
+
|
|
47
|
+
### `TabProps`
|
|
48
|
+
|
|
49
|
+
| Properti | Tipe | Keterangan |
|
|
50
|
+
| -------------- | ------------------------- | ----------------------------- |
|
|
51
|
+
| `children` | `React.ReactNode` | Daftar elemen `<TabItem />` |
|
|
52
|
+
| `current?` | `number` | Indeks tab aktif (default: 0) |
|
|
53
|
+
| `onChangeTab?` | `(index: number) => void` | Callback saat tab berpindah |
|
|
54
|
+
|
|
55
|
+
### `TabItemProps`
|
|
56
|
+
|
|
57
|
+
| Properti | Tipe | Keterangan |
|
|
58
|
+
| ----------- | --------------------- | ---------------------------------- |
|
|
59
|
+
| `name` | `string` | Nama/tab label yang ditampilkan |
|
|
60
|
+
| `component` | `React.ComponentType` | Komponen yang akan dirender di tab |
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 🧪 Contoh Screen
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
const HomeScreen = () => (
|
|
68
|
+
<View style={{ padding: 20 }}>
|
|
69
|
+
<Text>Selamat datang di tab Beranda!</Text>
|
|
70
|
+
</View>
|
|
71
|
+
);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
package/src/Tab/Tab.tsx
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
useCallback,
|
|
3
|
+
useState,
|
|
4
|
+
useEffect,
|
|
5
|
+
useRef,
|
|
6
|
+
Children,
|
|
7
|
+
isValidElement,
|
|
8
|
+
} from 'react';
|
|
9
|
+
import { View, Pressable, StyleSheet } from 'react-native';
|
|
10
|
+
import PagerView from 'react-native-pager-view';
|
|
11
|
+
import Color from '../Color/Color';
|
|
12
|
+
import Typography from '../Typography/Typography';
|
|
13
|
+
import type { TabItemProps, TabProps } from './type';
|
|
14
|
+
|
|
15
|
+
const Tab: React.FC<TabProps> = ({ children, current = 0, onChangeTab }) => {
|
|
16
|
+
const items = Children.toArray(children).filter(
|
|
17
|
+
isValidElement
|
|
18
|
+
) as React.ReactElement<TabItemProps>[];
|
|
19
|
+
|
|
20
|
+
const [activeIndex, setActiveIndex] = useState<number>(current);
|
|
21
|
+
const pagerRef = useRef<PagerView>(null);
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
setActiveIndex(current);
|
|
25
|
+
pagerRef.current?.setPageWithoutAnimation(current);
|
|
26
|
+
}, [current]);
|
|
27
|
+
|
|
28
|
+
const updateActive = useCallback(
|
|
29
|
+
(index: number) => {
|
|
30
|
+
if (index !== activeIndex) {
|
|
31
|
+
setActiveIndex(index);
|
|
32
|
+
onChangeTab?.(index);
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
[activeIndex, onChangeTab]
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const handleHeaderPress = (index: number) => {
|
|
39
|
+
pagerRef.current?.setPage(index);
|
|
40
|
+
updateActive(index);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
if (items.length === 0) return null;
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<View style={styles.container}>
|
|
47
|
+
{/* Header */}
|
|
48
|
+
<View style={styles.headerContainer}>
|
|
49
|
+
{items.map((item, index) => {
|
|
50
|
+
const isActive = index === activeIndex;
|
|
51
|
+
return (
|
|
52
|
+
<Pressable
|
|
53
|
+
key={index}
|
|
54
|
+
style={[
|
|
55
|
+
styles.tabButton,
|
|
56
|
+
isActive ? styles.tabActive : styles.tabInactive,
|
|
57
|
+
]}
|
|
58
|
+
onPress={() => handleHeaderPress(index)}
|
|
59
|
+
>
|
|
60
|
+
<Typography
|
|
61
|
+
center
|
|
62
|
+
variant="t2"
|
|
63
|
+
weight="semibold"
|
|
64
|
+
color={isActive ? Color.base.white100 : Color.gray[700]}
|
|
65
|
+
>
|
|
66
|
+
{item.props.name}
|
|
67
|
+
</Typography>
|
|
68
|
+
</Pressable>
|
|
69
|
+
);
|
|
70
|
+
})}
|
|
71
|
+
</View>
|
|
72
|
+
<PagerView
|
|
73
|
+
ref={pagerRef}
|
|
74
|
+
style={styles.pager}
|
|
75
|
+
initialPage={current}
|
|
76
|
+
onPageSelected={(e) => updateActive(e.nativeEvent.position)}
|
|
77
|
+
>
|
|
78
|
+
{items.map((item, index) => {
|
|
79
|
+
const Comp = item.props.component;
|
|
80
|
+
return (
|
|
81
|
+
<View key={index} collapsable={false} style={{ flex: 1 }}>
|
|
82
|
+
{Comp ? <Comp /> : null}
|
|
83
|
+
</View>
|
|
84
|
+
);
|
|
85
|
+
})}
|
|
86
|
+
</PagerView>
|
|
87
|
+
</View>
|
|
88
|
+
);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export default Tab;
|
|
92
|
+
|
|
93
|
+
const styles = StyleSheet.create({
|
|
94
|
+
container: { flex: 1 },
|
|
95
|
+
headerContainer: {
|
|
96
|
+
flexDirection: 'row',
|
|
97
|
+
backgroundColor: Color.gray[100],
|
|
98
|
+
padding: 4,
|
|
99
|
+
borderRadius: 8,
|
|
100
|
+
},
|
|
101
|
+
tabButton: {
|
|
102
|
+
flex: 1,
|
|
103
|
+
borderRadius: 8,
|
|
104
|
+
paddingVertical: 6,
|
|
105
|
+
paddingHorizontal: 16,
|
|
106
|
+
justifyContent: 'center',
|
|
107
|
+
alignItems: 'center',
|
|
108
|
+
},
|
|
109
|
+
tabActive: { backgroundColor: Color.primary[1000] },
|
|
110
|
+
tabInactive: { backgroundColor: Color.gray[100] },
|
|
111
|
+
pager: { flex: 1 },
|
|
112
|
+
});
|
package/src/Tab/type.tsx
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React, { type ReactElement } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface TabItemProps {
|
|
4
|
+
name: string | number;
|
|
5
|
+
component: React.ComponentType<any>;
|
|
6
|
+
}
|
|
7
|
+
export interface TabProps {
|
|
8
|
+
children: ReactElement<TabItemProps> | ReactElement<TabItemProps>[];
|
|
9
|
+
current?: number;
|
|
10
|
+
onChangeTab?: (e: any) => void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Divider
|
|
2
|
+
|
|
3
|
+
**Divider** adalah komponen garis horizontal sederhana yang digunakan untuk memisahkan konten secara visual dalam antarmuka pengguna.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Instalasi
|
|
8
|
+
|
|
9
|
+
Komponen ini tidak memerlukan dependensi eksternal. Hanya menggunakan:
|
|
10
|
+
|
|
11
|
+
* `Color` – untuk warna garis.
|
|
12
|
+
* `View` dan `StyleSheet` dari `react-native`.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## API Reference
|
|
17
|
+
|
|
18
|
+
Tidak memiliki properti (props) khusus. Komponen ini dapat digunakan langsung dan bisa dikustomisasi melalui `style` eksternal jika diperlukan.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Contoh Penggunaan
|
|
23
|
+
|
|
24
|
+
### Divider Default
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import Divider from '@/components/Divider/Divider';
|
|
28
|
+
|
|
29
|
+
<View>
|
|
30
|
+
<Text>Bagian Atas</Text>
|
|
31
|
+
<Divider />
|
|
32
|
+
<Text>Bagian Bawah</Text>
|
|
33
|
+
</View>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Divider dengan Margin
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
<View style={{ marginVertical: 12 }}>
|
|
40
|
+
<Divider />
|
|
41
|
+
</View>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Divider yang Dikustomisasi
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
<Divider style={{ backgroundColor: 'red', height: 2 }} />
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
> Catatan: Untuk mengubah gaya `Divider`, bungkus komponen dengan `View` tambahan atau tambahkan prop `style` melalui wrapper jika perlu.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Style Default
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
{
|
|
58
|
+
height: 1,
|
|
59
|
+
backgroundColor: Color.gray[200],
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
File without changes
|
package/src/index.tsx
CHANGED
|
@@ -10,6 +10,12 @@ export type { AccordionRenderHeaderProps } from './Accordion/type';
|
|
|
10
10
|
export { default as Button } from './Button/Button';
|
|
11
11
|
export { default as Color } from './Color/Color';
|
|
12
12
|
export { default as Typography } from './Typography/Typography';
|
|
13
|
+
export type {
|
|
14
|
+
fontSizeMap,
|
|
15
|
+
fontWeightMap,
|
|
16
|
+
lineHeightMap,
|
|
17
|
+
TypographyVariantProps,
|
|
18
|
+
} from './Typography/type';
|
|
13
19
|
export { default as BottomSheet } from './BottomSheet/BottomSheet';
|
|
14
20
|
export { default as Container } from './Ui/Container';
|
|
15
21
|
export { default as Card } from './Ui/Card';
|
|
@@ -61,6 +67,8 @@ export { default as MonthPicker } from './DatePicker/MonthPicker';
|
|
|
61
67
|
export { default as TimePicker } from './DatePicker/TimePicker';
|
|
62
68
|
export { default as Step } from './Step/Step';
|
|
63
69
|
export { default as StepItem } from './Step/StepItem';
|
|
70
|
+
export { default as Tab } from './Tab/Tab';
|
|
71
|
+
export { default as TabItem } from './Tab/TabItem';
|
|
64
72
|
export { default as Toast } from './Toast/Toast';
|
|
65
73
|
export { default as TextArea } from './Input/TextArea';
|
|
66
74
|
// export { default as PdfView } from './FileView/PdfView';
|