@herca/rn-kit 0.1.84 → 0.1.85
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/DatePicker/README_TIMEPICKER.md +24 -18
- package/lib/module/DatePicker/TimePicker.js +11 -2
- package/lib/module/DatePicker/TimePicker.js.map +1 -1
- package/lib/typescript/src/DatePicker/TimePicker.d.ts +5 -1
- package/lib/typescript/src/DatePicker/TimePicker.d.ts.map +1 -1
- package/package.json +1 -8
- package/src/DatePicker/README_TIMEPICKER.md +24 -18
- package/src/DatePicker/TimePicker.tsx +14 -2
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
# TimePickerWheel
|
|
2
2
|
|
|
3
|
-
**TimePickerWheel** adalah komponen pemilih waktu berbentuk
|
|
3
|
+
**TimePickerWheel** adalah komponen pemilih waktu berbentuk _wheel_ (picker bergulir) untuk **React Native**. Komponen ini menampilkan dua kolom (jam & menit) yang dapat digulir secara vertikal, dibungkus di dalam komponen **BottomSheet**.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
## API Reference
|
|
8
8
|
|
|
9
|
-
| Prop | Tipe | Default
|
|
10
|
-
| ---------- | --------------------------------------------------- |
|
|
11
|
-
| `isOpen` | `boolean` | `false`
|
|
12
|
-
| `onClose` | `() => void` | `-`
|
|
13
|
-
| `onChange` | `(value: { hour: number; minute: number }) => void` | `-`
|
|
9
|
+
| Prop | Tipe | Default | Deskripsi |
|
|
10
|
+
| ---------- | --------------------------------------------------- | ---------------------- | --------------------------------------------------------------------------------------------- |
|
|
11
|
+
| `isOpen` | `boolean` | `false` | Menentukan apakah **BottomSheet** terbuka. |
|
|
12
|
+
| `onClose` | `() => void` | `-` | Callback saat pengguna menutup **BottomSheet** atau menekan tombol **Batal**. |
|
|
13
|
+
| `onChange` | `(value: { hour: number; minute: number }) => void` | `-` | Callback saat pengguna menekan tombol **Pilih**. Objek yang dikirim berisi `hour` & `minute`. |
|
|
14
|
+
| `value` | `{ hour: number; minute: number }` | `{hour: 0, minute: 0}` | Props untuk mengontrol value dari parent |
|
|
14
15
|
|
|
15
|
-
### Bentuk
|
|
16
|
+
### Bentuk _value_ `onChange`
|
|
16
17
|
|
|
17
18
|
```ts
|
|
18
19
|
{
|
|
19
|
-
hour: number;
|
|
20
|
+
hour: number; // 0–23
|
|
20
21
|
minute: number; // 0–59
|
|
21
22
|
}
|
|
22
23
|
```
|
|
@@ -25,9 +26,9 @@
|
|
|
25
26
|
|
|
26
27
|
## Cara Kerja Singkat
|
|
27
28
|
|
|
28
|
-
1. **Wheel Padding** – Komponen menambahkan elemen
|
|
29
|
+
1. **Wheel Padding** – Komponen menambahkan elemen _dummy_ di atas & bawah daftar agar item tengah selalu berada di posisi highlight.
|
|
29
30
|
2. **Highlight** – Baris tengah diberi `backgroundColor` khusus (`Color.primary[50]`) untuk menonjolkan pilihan aktif.
|
|
30
|
-
3. **Snapping** – Properti `snapToInterval={ITEM_HEIGHT}` memastikan scroll
|
|
31
|
+
3. **Snapping** – Properti `snapToInterval={ITEM_HEIGHT}` memastikan scroll _wheel_ berhenti tepat di setiap item.
|
|
31
32
|
4. **Sync & Loop** – Setelah scroll selesai, komponen menghitung indeks nyata (0‑23 untuk jam, 0‑59 untuk menit) agar wheel terasa tak terbatas.
|
|
32
33
|
|
|
33
34
|
---
|
|
@@ -45,11 +46,16 @@ export default function Example() {
|
|
|
45
46
|
null
|
|
46
47
|
);
|
|
47
48
|
|
|
48
|
-
const formatted = time
|
|
49
|
+
const formatted = time
|
|
50
|
+
? `${time.hour.toString().padStart(2, '0')}:${time.minute.toString().padStart(2, '0')}`
|
|
51
|
+
: '—';
|
|
49
52
|
|
|
50
53
|
return (
|
|
51
54
|
<View style={{ flex: 1 }}>
|
|
52
|
-
<Button
|
|
55
|
+
<Button
|
|
56
|
+
title={`Pilih Waktu (${formatted})`}
|
|
57
|
+
onPress={() => setOpen(true)}
|
|
58
|
+
/>
|
|
53
59
|
|
|
54
60
|
<TimePickerWheel
|
|
55
61
|
isOpen={open}
|
|
@@ -68,16 +74,16 @@ export default function Example() {
|
|
|
68
74
|
|
|
69
75
|
## Kustomisasi Tampilan
|
|
70
76
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
77
|
+
- **Jumlah Items Terlihat** (`VISIBLE_ITEMS`): Default 5. Ubah nilai konstanta untuk menambah/kurangi tinggi wheel.
|
|
78
|
+
- **Tinggi Item** (`ITEM_HEIGHT`): Default 40. Pengaturan ini mempengaruhi `snapToInterval`.
|
|
79
|
+
- **Warna & Tipografi**: Edit style `selectedItemText`, `itemText`, dan `highlight` untuk menyesuaikan brand guideline.
|
|
74
80
|
|
|
75
81
|
---
|
|
76
82
|
|
|
77
83
|
## Tips Implementasi
|
|
78
84
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
85
|
+
- Selalu panggil `onClose` setelah menangani hasil `onChange` agar **BottomSheet** menutup.
|
|
86
|
+
- Jika Anda ingin menetapkan waktu awal sebelum picker dibuka, setel `selectedHour` & `selectedMinute` memakai `useState` lalu buka picker.
|
|
87
|
+
- Komponen ini tidak membatasi kombinasi jam‑menit (mis. langkah 5 menit). Tambahkan logika tambahan jika diperlukan.
|
|
82
88
|
|
|
83
89
|
---
|
|
@@ -25,12 +25,13 @@ export default function TimePickerWheel({
|
|
|
25
25
|
isOpen,
|
|
26
26
|
onClose,
|
|
27
27
|
onChange,
|
|
28
|
+
value,
|
|
28
29
|
title = 'Pilih Waktu',
|
|
29
30
|
cancelLabel = 'Batal',
|
|
30
31
|
confirmLabel = 'Pilih'
|
|
31
32
|
}) {
|
|
32
|
-
const [selectedHour, setSelectedHour] = useState(0);
|
|
33
|
-
const [selectedMinute, setSelectedMinute] = useState(0);
|
|
33
|
+
const [selectedHour, setSelectedHour] = useState(value?.hour ?? 0);
|
|
34
|
+
const [selectedMinute, setSelectedMinute] = useState(value?.minute ?? 0);
|
|
34
35
|
const hourRef = useRef(null);
|
|
35
36
|
const minuteRef = useRef(null);
|
|
36
37
|
const hourScrollY = useRef(new Animated.Value(0)).current;
|
|
@@ -41,6 +42,14 @@ export default function TimePickerWheel({
|
|
|
41
42
|
// Posisi tengah untuk initial scroll
|
|
42
43
|
const MIDDLE_HOUR_INDEX = Math.floor(hours.length / 2 / 24) * 24;
|
|
43
44
|
const MIDDLE_MINUTE_INDEX = Math.floor(minutes.length / 2 / 60) * 60;
|
|
45
|
+
|
|
46
|
+
// Update state ketika value prop berubah
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (value) {
|
|
49
|
+
setSelectedHour(value.hour);
|
|
50
|
+
setSelectedMinute(value.minute);
|
|
51
|
+
}
|
|
52
|
+
}, [value]);
|
|
44
53
|
useEffect(() => {
|
|
45
54
|
if (isOpen) {
|
|
46
55
|
setTimeout(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useEffect","useRef","useState","Animated","Dimensions","StyleSheet","View","BottomSheet","Button","Color","Typography","AnimatedItem","jsx","_jsx","jsxs","_jsxs","ITEM_HEIGHT","SCREEN_WIDTH","get","width","VISIBLE_ITEMS","MIDDLE_INDEX","Math","floor","INFINITE_CYCLES","generateInfiniteData","max","cycles","base","Array","from","length","_","i","flatMap","TimePickerWheel","isOpen","onClose","onChange","title","cancelLabel","confirmLabel","selectedHour","setSelectedHour","selectedMinute","setSelectedMinute","hourRef","minuteRef","hourScrollY","Value","current","minuteScrollY","hours","minutes","MIDDLE_HOUR_INDEX","MIDDLE_MINUTE_INDEX","setTimeout","scrollToIndex","index","animated","getItemLayout","offset","ref","handleScrollEnd","event","type","offsetY","nativeEvent","contentOffset","y","round","realValue","distanceFromStart","distanceFromEnd","newCenter","handleScrollToIndexFailed","info","wait","Promise","resolve","then","averageItemLength","handleSubmit","
|
|
1
|
+
{"version":3,"names":["React","useEffect","useRef","useState","Animated","Dimensions","StyleSheet","View","BottomSheet","Button","Color","Typography","AnimatedItem","jsx","_jsx","jsxs","_jsxs","ITEM_HEIGHT","SCREEN_WIDTH","get","width","VISIBLE_ITEMS","MIDDLE_INDEX","Math","floor","INFINITE_CYCLES","generateInfiniteData","max","cycles","base","Array","from","length","_","i","flatMap","TimePickerWheel","isOpen","onClose","onChange","value","title","cancelLabel","confirmLabel","selectedHour","setSelectedHour","hour","selectedMinute","setSelectedMinute","minute","hourRef","minuteRef","hourScrollY","Value","current","minuteScrollY","hours","minutes","MIDDLE_HOUR_INDEX","MIDDLE_MINUTE_INDEX","setTimeout","scrollToIndex","index","animated","getItemLayout","offset","ref","handleScrollEnd","event","type","offsetY","nativeEvent","contentOffset","y","round","realValue","distanceFromStart","distanceFromEnd","newCenter","handleScrollToIndexFailed","info","wait","Promise","resolve","then","averageItemLength","handleSubmit","renderHourItem","item","scrollY","renderMinuteItem","footer","style","styles","children","flex1","variant","onPress","color","size","weight","gray","center","hintTime","container","highlightOverlay","pointerEvents","highlight","scrollContainer","pickerColumn","FlatList","data","renderItem","keyExtractor","showsVerticalScrollIndicator","snapToInterval","decelerationRate","onMomentumScrollEnd","e","onScroll","useNativeDriver","scrollEventThrottle","onScrollToIndexFailed","initialNumToRender","maxToRenderPerBatch","windowSize","removeClippedSubviews","contentContainerStyle","scrollContent","create","position","height","marginBottom","flexDirection","gap","flex","justifyContent","paddingVertical","overflow","zIndex","top","left","right","bottom","backgroundColor","primary"],"sourceRoot":"../../../src","sources":["DatePicker/TimePicker.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -5,10 +5,14 @@ interface TimePickerProps {
|
|
|
5
5
|
hour: number;
|
|
6
6
|
minute: number;
|
|
7
7
|
}) => void;
|
|
8
|
+
value?: {
|
|
9
|
+
hour: number;
|
|
10
|
+
minute: number;
|
|
11
|
+
};
|
|
8
12
|
title?: string;
|
|
9
13
|
confirmLabel?: string;
|
|
10
14
|
cancelLabel?: string;
|
|
11
15
|
}
|
|
12
|
-
export default function TimePickerWheel({ isOpen, onClose, onChange, title, cancelLabel, confirmLabel, }: TimePickerProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export default function TimePickerWheel({ isOpen, onClose, onChange, value, title, cancelLabel, confirmLabel, }: TimePickerProps): import("react/jsx-runtime").JSX.Element;
|
|
13
17
|
export {};
|
|
14
18
|
//# sourceMappingURL=TimePicker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimePicker.d.ts","sourceRoot":"","sources":["../../../../src/DatePicker/TimePicker.tsx"],"names":[],"mappings":"AAuBA,UAAU,eAAe;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAOD,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EACtC,MAAM,EACN,OAAO,EACP,QAAQ,EACR,KAAqB,EACrB,WAAqB,EACrB,YAAsB,GACvB,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"TimePicker.d.ts","sourceRoot":"","sources":["../../../../src/DatePicker/TimePicker.tsx"],"names":[],"mappings":"AAuBA,UAAU,eAAe;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7D,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAOD,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EACtC,MAAM,EACN,OAAO,EACP,QAAQ,EACR,KAAK,EACL,KAAqB,EACrB,WAAqB,EACrB,YAAsB,GACvB,EAAE,eAAe,2CAgPjB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@herca/rn-kit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.85",
|
|
4
4
|
"description": "React Native UI Kit",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -111,13 +111,6 @@
|
|
|
111
111
|
"example"
|
|
112
112
|
],
|
|
113
113
|
"packageManager": "yarn@3.6.1",
|
|
114
|
-
"jest": {
|
|
115
|
-
"preset": "react-native",
|
|
116
|
-
"modulePathIgnorePatterns": [
|
|
117
|
-
"<rootDir>/example/node_modules",
|
|
118
|
-
"<rootDir>/lib/"
|
|
119
|
-
]
|
|
120
|
-
},
|
|
121
114
|
"commitlint": {
|
|
122
115
|
"extends": [
|
|
123
116
|
"@commitlint/config-conventional"
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
# TimePickerWheel
|
|
2
2
|
|
|
3
|
-
**TimePickerWheel** adalah komponen pemilih waktu berbentuk
|
|
3
|
+
**TimePickerWheel** adalah komponen pemilih waktu berbentuk _wheel_ (picker bergulir) untuk **React Native**. Komponen ini menampilkan dua kolom (jam & menit) yang dapat digulir secara vertikal, dibungkus di dalam komponen **BottomSheet**.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
## API Reference
|
|
8
8
|
|
|
9
|
-
| Prop | Tipe | Default
|
|
10
|
-
| ---------- | --------------------------------------------------- |
|
|
11
|
-
| `isOpen` | `boolean` | `false`
|
|
12
|
-
| `onClose` | `() => void` | `-`
|
|
13
|
-
| `onChange` | `(value: { hour: number; minute: number }) => void` | `-`
|
|
9
|
+
| Prop | Tipe | Default | Deskripsi |
|
|
10
|
+
| ---------- | --------------------------------------------------- | ---------------------- | --------------------------------------------------------------------------------------------- |
|
|
11
|
+
| `isOpen` | `boolean` | `false` | Menentukan apakah **BottomSheet** terbuka. |
|
|
12
|
+
| `onClose` | `() => void` | `-` | Callback saat pengguna menutup **BottomSheet** atau menekan tombol **Batal**. |
|
|
13
|
+
| `onChange` | `(value: { hour: number; minute: number }) => void` | `-` | Callback saat pengguna menekan tombol **Pilih**. Objek yang dikirim berisi `hour` & `minute`. |
|
|
14
|
+
| `value` | `{ hour: number; minute: number }` | `{hour: 0, minute: 0}` | Props untuk mengontrol value dari parent |
|
|
14
15
|
|
|
15
|
-
### Bentuk
|
|
16
|
+
### Bentuk _value_ `onChange`
|
|
16
17
|
|
|
17
18
|
```ts
|
|
18
19
|
{
|
|
19
|
-
hour: number;
|
|
20
|
+
hour: number; // 0–23
|
|
20
21
|
minute: number; // 0–59
|
|
21
22
|
}
|
|
22
23
|
```
|
|
@@ -25,9 +26,9 @@
|
|
|
25
26
|
|
|
26
27
|
## Cara Kerja Singkat
|
|
27
28
|
|
|
28
|
-
1. **Wheel Padding** – Komponen menambahkan elemen
|
|
29
|
+
1. **Wheel Padding** – Komponen menambahkan elemen _dummy_ di atas & bawah daftar agar item tengah selalu berada di posisi highlight.
|
|
29
30
|
2. **Highlight** – Baris tengah diberi `backgroundColor` khusus (`Color.primary[50]`) untuk menonjolkan pilihan aktif.
|
|
30
|
-
3. **Snapping** – Properti `snapToInterval={ITEM_HEIGHT}` memastikan scroll
|
|
31
|
+
3. **Snapping** – Properti `snapToInterval={ITEM_HEIGHT}` memastikan scroll _wheel_ berhenti tepat di setiap item.
|
|
31
32
|
4. **Sync & Loop** – Setelah scroll selesai, komponen menghitung indeks nyata (0‑23 untuk jam, 0‑59 untuk menit) agar wheel terasa tak terbatas.
|
|
32
33
|
|
|
33
34
|
---
|
|
@@ -45,11 +46,16 @@ export default function Example() {
|
|
|
45
46
|
null
|
|
46
47
|
);
|
|
47
48
|
|
|
48
|
-
const formatted = time
|
|
49
|
+
const formatted = time
|
|
50
|
+
? `${time.hour.toString().padStart(2, '0')}:${time.minute.toString().padStart(2, '0')}`
|
|
51
|
+
: '—';
|
|
49
52
|
|
|
50
53
|
return (
|
|
51
54
|
<View style={{ flex: 1 }}>
|
|
52
|
-
<Button
|
|
55
|
+
<Button
|
|
56
|
+
title={`Pilih Waktu (${formatted})`}
|
|
57
|
+
onPress={() => setOpen(true)}
|
|
58
|
+
/>
|
|
53
59
|
|
|
54
60
|
<TimePickerWheel
|
|
55
61
|
isOpen={open}
|
|
@@ -68,16 +74,16 @@ export default function Example() {
|
|
|
68
74
|
|
|
69
75
|
## Kustomisasi Tampilan
|
|
70
76
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
77
|
+
- **Jumlah Items Terlihat** (`VISIBLE_ITEMS`): Default 5. Ubah nilai konstanta untuk menambah/kurangi tinggi wheel.
|
|
78
|
+
- **Tinggi Item** (`ITEM_HEIGHT`): Default 40. Pengaturan ini mempengaruhi `snapToInterval`.
|
|
79
|
+
- **Warna & Tipografi**: Edit style `selectedItemText`, `itemText`, dan `highlight` untuk menyesuaikan brand guideline.
|
|
74
80
|
|
|
75
81
|
---
|
|
76
82
|
|
|
77
83
|
## Tips Implementasi
|
|
78
84
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
85
|
+
- Selalu panggil `onClose` setelah menangani hasil `onChange` agar **BottomSheet** menutup.
|
|
86
|
+
- Jika Anda ingin menetapkan waktu awal sebelum picker dibuka, setel `selectedHour` & `selectedMinute` memakai `useState` lalu buka picker.
|
|
87
|
+
- Komponen ini tidak membatasi kombinasi jam‑menit (mis. langkah 5 menit). Tambahkan logika tambahan jika diperlukan.
|
|
82
88
|
|
|
83
89
|
---
|
|
@@ -25,6 +25,7 @@ interface TimePickerProps {
|
|
|
25
25
|
isOpen: boolean;
|
|
26
26
|
onClose?: () => void;
|
|
27
27
|
onChange?: (value: { hour: number; minute: number }) => void;
|
|
28
|
+
value?: { hour: number; minute: number };
|
|
28
29
|
title?: string;
|
|
29
30
|
confirmLabel?: string;
|
|
30
31
|
cancelLabel?: string;
|
|
@@ -39,12 +40,15 @@ export default function TimePickerWheel({
|
|
|
39
40
|
isOpen,
|
|
40
41
|
onClose,
|
|
41
42
|
onChange,
|
|
43
|
+
value,
|
|
42
44
|
title = 'Pilih Waktu',
|
|
43
45
|
cancelLabel = 'Batal',
|
|
44
46
|
confirmLabel = 'Pilih',
|
|
45
47
|
}: TimePickerProps) {
|
|
46
|
-
const [selectedHour, setSelectedHour] = useState<number>(0);
|
|
47
|
-
const [selectedMinute, setSelectedMinute] = useState<number>(
|
|
48
|
+
const [selectedHour, setSelectedHour] = useState<number>(value?.hour ?? 0);
|
|
49
|
+
const [selectedMinute, setSelectedMinute] = useState<number>(
|
|
50
|
+
value?.minute ?? 0
|
|
51
|
+
);
|
|
48
52
|
|
|
49
53
|
const hourRef = useRef<FlatList<any> | null>(null);
|
|
50
54
|
const minuteRef = useRef<FlatList<any> | null>(null);
|
|
@@ -59,6 +63,14 @@ export default function TimePickerWheel({
|
|
|
59
63
|
const MIDDLE_HOUR_INDEX = Math.floor(hours.length / 2 / 24) * 24;
|
|
60
64
|
const MIDDLE_MINUTE_INDEX = Math.floor(minutes.length / 2 / 60) * 60;
|
|
61
65
|
|
|
66
|
+
// Update state ketika value prop berubah
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
if (value) {
|
|
69
|
+
setSelectedHour(value.hour);
|
|
70
|
+
setSelectedMinute(value.minute);
|
|
71
|
+
}
|
|
72
|
+
}, [value]);
|
|
73
|
+
|
|
62
74
|
useEffect(() => {
|
|
63
75
|
if (isOpen) {
|
|
64
76
|
setTimeout(() => {
|