@herca/rn-kit 0.1.25 → 0.1.26
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 +2 -1
- package/lib/module/Badge/Badge.js.map +1 -1
- package/lib/module/Badge/type.js +2 -0
- package/lib/module/Icon/Icon.js +21 -1
- package/lib/module/Icon/Icon.js.map +1 -1
- package/lib/module/Icon/README.md +36 -26
- package/lib/module/Icon/icons/AtSign.js +22 -0
- package/lib/module/Icon/icons/AtSign.js.map +1 -0
- package/lib/module/Icon/icons/BriefcaseOutline.js +22 -0
- package/lib/module/Icon/icons/BriefcaseOutline.js.map +1 -0
- package/lib/module/Icon/icons/Edit.js +22 -0
- package/lib/module/Icon/icons/Edit.js.map +1 -0
- package/lib/module/Icon/icons/GlobeEarth.js +22 -0
- package/lib/module/Icon/icons/GlobeEarth.js.map +1 -0
- package/lib/module/Icon/icons/LockFill.js +22 -0
- package/lib/module/Icon/icons/LockFill.js.map +1 -0
- package/lib/module/Icon/icons/LogoHercaHris.js +64 -0
- package/lib/module/Icon/icons/LogoHercaHris.js.map +1 -0
- package/lib/module/Icon/icons/QuestionCircleOutline.js +22 -0
- package/lib/module/Icon/icons/QuestionCircleOutline.js.map +1 -0
- package/lib/module/Icon/icons/Scanner.js +3 -3
- package/lib/module/Icon/icons/Scanner.js.map +1 -1
- package/lib/module/Icon/icons/Search.js +2 -2
- package/lib/module/Icon/icons/Search.js.map +1 -1
- package/lib/module/Icon/icons/ShieldFill.js +22 -0
- package/lib/module/Icon/icons/ShieldFill.js.map +1 -0
- package/lib/module/Icon/icons/Users.js +22 -0
- package/lib/module/Icon/icons/Users.js.map +1 -0
- package/lib/module/Icon/icons/WhatsappFill.js +22 -0
- package/lib/module/Icon/icons/WhatsappFill.js.map +1 -0
- package/lib/module/Input/Input.js +17 -14
- package/lib/module/Input/Input.js.map +1 -1
- package/lib/module/Input/InputOtp.js +25 -8
- package/lib/module/Input/InputOtp.js.map +1 -1
- package/lib/module/Input/README_INPUT_OTP.md +59 -0
- package/lib/module/index.js +0 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/Badge/Badge.d.ts.map +1 -1
- package/lib/typescript/src/Badge/type.d.ts +8 -0
- package/lib/typescript/src/Badge/type.d.ts.map +1 -1
- package/lib/typescript/src/Icon/Icon.d.ts.map +1 -1
- package/lib/typescript/src/Icon/icons/AtSign.d.ts +9 -0
- package/lib/typescript/src/Icon/icons/AtSign.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/BriefcaseOutline.d.ts +9 -0
- package/lib/typescript/src/Icon/icons/BriefcaseOutline.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/Edit.d.ts +9 -0
- package/lib/typescript/src/Icon/icons/Edit.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/GlobeEarth.d.ts +9 -0
- package/lib/typescript/src/Icon/icons/GlobeEarth.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/LockFill.d.ts +9 -0
- package/lib/typescript/src/Icon/icons/LockFill.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/LogoHercaHris.d.ts +8 -0
- package/lib/typescript/src/Icon/icons/LogoHercaHris.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/QuestionCircleOutline.d.ts +9 -0
- package/lib/typescript/src/Icon/icons/QuestionCircleOutline.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/Scanner.d.ts.map +1 -1
- package/lib/typescript/src/Icon/icons/ShieldFill.d.ts +9 -0
- package/lib/typescript/src/Icon/icons/ShieldFill.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/Users.d.ts +9 -0
- package/lib/typescript/src/Icon/icons/Users.d.ts.map +1 -0
- package/lib/typescript/src/Icon/icons/WhatsappFill.d.ts +9 -0
- package/lib/typescript/src/Icon/icons/WhatsappFill.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/InputOtp.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/index.d.ts +3 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/Badge/Badge.tsx +1 -10
- package/src/Badge/type.tsx +10 -0
- package/src/Icon/Icon.tsx +20 -0
- package/src/Icon/README.md +36 -26
- package/src/Icon/icons/AtSign.tsx +19 -0
- package/src/Icon/icons/BriefcaseOutline.tsx +29 -0
- package/src/Icon/icons/Edit.tsx +23 -0
- package/src/Icon/icons/GlobeEarth.tsx +19 -0
- package/src/Icon/icons/LockFill.tsx +19 -0
- package/src/Icon/icons/LogoHercaHris.tsx +71 -0
- package/src/Icon/icons/QuestionCircleOutline.tsx +23 -0
- package/src/Icon/icons/Scanner.tsx +2 -8
- package/src/Icon/icons/Search.tsx +2 -2
- package/src/Icon/icons/ShieldFill.tsx +19 -0
- package/src/Icon/icons/Users.tsx +19 -0
- package/src/Icon/icons/WhatsappFill.tsx +23 -0
- package/src/Icon/type.tsx +11 -1
- package/src/Input/Input.tsx +22 -14
- package/src/Input/InputOtp.tsx +28 -8
- package/src/Input/README_INPUT_OTP.md +59 -0
- package/src/Input/type.tsx +1 -0
- package/src/index.tsx +8 -1
package/src/Input/InputOtp.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useRef } from 'react';
|
|
1
|
+
import React, { useRef, useState } from 'react';
|
|
2
2
|
import { View, TextInput, StyleSheet } from 'react-native';
|
|
3
3
|
import Color from '../Color/Color';
|
|
4
4
|
import LabelForm from '../LabelForm/LabelForm';
|
|
@@ -21,6 +21,11 @@ const InputOtp: React.FC<InputOtpProps> = ({
|
|
|
21
21
|
}) => {
|
|
22
22
|
const inputs = useRef<Array<TextInput | null>>([]);
|
|
23
23
|
const values = useRef<string[]>(Array(length).fill(''));
|
|
24
|
+
const [useFlexGrow, setUseFlexGrow] = useState<boolean>(false);
|
|
25
|
+
|
|
26
|
+
const containerWidth = useRef(0);
|
|
27
|
+
const itemWidth = 48;
|
|
28
|
+
const itemGap = 10;
|
|
24
29
|
|
|
25
30
|
const handleChange = (text: string, index: number) => {
|
|
26
31
|
values.current[index] = text;
|
|
@@ -44,7 +49,15 @@ const InputOtp: React.FC<InputOtpProps> = ({
|
|
|
44
49
|
return (
|
|
45
50
|
<View style={styles.gap4}>
|
|
46
51
|
{label ? <LabelForm title={label} /> : null}
|
|
47
|
-
<View
|
|
52
|
+
<View
|
|
53
|
+
style={styles.container}
|
|
54
|
+
onLayout={(e) => {
|
|
55
|
+
// cek apakah lebar container itu cukup untuk menampilkan semua input
|
|
56
|
+
containerWidth.current = e.nativeEvent.layout.width;
|
|
57
|
+
const totalNeededWidth = length * itemWidth + (length - 1) * itemGap;
|
|
58
|
+
setUseFlexGrow(totalNeededWidth > containerWidth.current);
|
|
59
|
+
}}
|
|
60
|
+
>
|
|
48
61
|
{Array(length)
|
|
49
62
|
.fill(0)
|
|
50
63
|
.map((_, i) => (
|
|
@@ -52,19 +65,26 @@ const InputOtp: React.FC<InputOtpProps> = ({
|
|
|
52
65
|
key={i}
|
|
53
66
|
style={[
|
|
54
67
|
styles.input,
|
|
55
|
-
|
|
68
|
+
// eslint-disable-next-line react-native/no-inline-styles
|
|
69
|
+
{
|
|
70
|
+
borderColor: hasError ? Color.danger[500] : Color.gray[200],
|
|
71
|
+
width: useFlexGrow ? undefined : itemWidth, //jika cukup gunakan 48px
|
|
72
|
+
flexGrow: useFlexGrow ? 1 : 0, //jika tidak cukup, flexgrow 0
|
|
73
|
+
},
|
|
56
74
|
]}
|
|
57
75
|
keyboardType="number-pad"
|
|
58
76
|
maxLength={1}
|
|
59
77
|
onChangeText={(text) => handleChange(text, i)}
|
|
60
78
|
onKeyPress={(e) => handleKeyPress(e, i)}
|
|
61
|
-
ref={(ref) =>
|
|
79
|
+
ref={(ref) => {
|
|
80
|
+
inputs.current[i] = ref;
|
|
81
|
+
}}
|
|
62
82
|
/>
|
|
63
83
|
))}
|
|
64
84
|
</View>
|
|
65
85
|
|
|
66
86
|
{hint ? (
|
|
67
|
-
<Typography color={hasError ? Color.danger[500] : ''} variant="
|
|
87
|
+
<Typography color={hasError ? Color.danger[500] : ''} variant="t3">
|
|
68
88
|
{hint}
|
|
69
89
|
</Typography>
|
|
70
90
|
) : null}
|
|
@@ -81,16 +101,16 @@ const styles = StyleSheet.create({
|
|
|
81
101
|
container: {
|
|
82
102
|
flexDirection: 'row',
|
|
83
103
|
gap: 10,
|
|
84
|
-
justifyContent: '
|
|
104
|
+
justifyContent: 'flex-start',
|
|
85
105
|
},
|
|
86
106
|
input: {
|
|
87
|
-
|
|
107
|
+
flexGrow: 1,
|
|
88
108
|
height: 48,
|
|
89
109
|
borderWidth: 1,
|
|
90
110
|
borderRadius: 8,
|
|
91
111
|
textAlign: 'center',
|
|
92
112
|
color: Color.base.black100,
|
|
93
113
|
fontSize: 12,
|
|
94
|
-
fontWeight:
|
|
114
|
+
fontWeight: 500,
|
|
95
115
|
},
|
|
96
116
|
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# InputOtp Component
|
|
2
|
+
|
|
3
|
+
`InputOtp` adalah komponen React Native untuk input kode OTP (One-Time Password) dengan tampilan kotak-kotak input terpisah. Komponen ini responsif dan otomatis menyesuaikan ukuran input berdasarkan lebar container agar tampil rapi di berbagai ukuran layar.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Fitur
|
|
8
|
+
|
|
9
|
+
- Menampilkan sejumlah input kotak sesuai panjang OTP (`length`).
|
|
10
|
+
- Input numeric 1 karakter per kotak.
|
|
11
|
+
- Fokus otomatis berpindah ke kotak berikutnya saat input.
|
|
12
|
+
- Fokus kembali ke kotak sebelumnya saat tekan backspace pada kotak kosong.
|
|
13
|
+
- Responsif: menggunakan lebar statis jika cukup ruang, atau `flexGrow` jika ruang terbatas.
|
|
14
|
+
- Label dan hint opsional.
|
|
15
|
+
- Warna border berubah saat error (`hasError`).
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Instalasi
|
|
20
|
+
|
|
21
|
+
Salin file `InputOtp.tsx` ke proyek React Native Anda dan import sesuai kebutuhan.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Props
|
|
26
|
+
|
|
27
|
+
| Nama | Tipe | Default | Deskripsi |
|
|
28
|
+
|------------|-----------------------------|---------|----------------------------------------------------------------|
|
|
29
|
+
| `length` | `number` | 6 | Jumlah kotak input OTP yang ingin ditampilkan |
|
|
30
|
+
| `onChange` | `(otp: string) => void` | - | Callback saat isi OTP berubah, menerima OTP lengkap sebagai string |
|
|
31
|
+
| `label` | `string` | - | Label yang tampil di atas kotak input |
|
|
32
|
+
| `hint` | `string` | - | Pesan kecil di bawah input (misal instruksi atau error) |
|
|
33
|
+
| `hasError` | `boolean` | false | Jika `true`, border input berubah warna merah (indikasi error) |
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Contoh Penggunaan
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
import React, { useState } from 'react';
|
|
41
|
+
import { View } from 'react-native';
|
|
42
|
+
import InputOtp from './InputOtp';
|
|
43
|
+
|
|
44
|
+
export default function OtpVerificationScreen() {
|
|
45
|
+
const [otp, setOtp] = useState('');
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<View style={{ padding: 16 }}>
|
|
49
|
+
<InputOtp
|
|
50
|
+
length={6}
|
|
51
|
+
label="Masukkan Kode OTP"
|
|
52
|
+
hint="Kode akan dikirim via SMS"
|
|
53
|
+
hasError={otp.length < 6}
|
|
54
|
+
onChange={setOtp}
|
|
55
|
+
/>
|
|
56
|
+
</View>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
```
|
package/src/Input/type.tsx
CHANGED
|
@@ -12,6 +12,7 @@ export interface InputProps extends TextInputProps {
|
|
|
12
12
|
onPressIconRight?: (val?: GestureResponderEvent) => void;
|
|
13
13
|
onChangeText?: (val: string) => void;
|
|
14
14
|
secureTextEntry?: boolean;
|
|
15
|
+
iconRightColor?: string;
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
export interface TextAreaProps extends InputProps {
|
package/src/index.tsx
CHANGED
|
@@ -9,6 +9,7 @@ export { default as AccordionItem } from './Accordion/AccordionItem';
|
|
|
9
9
|
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
|
+
export type { ColorVariantType } from './Color/type';
|
|
12
13
|
export { default as Typography } from './Typography/Typography';
|
|
13
14
|
export type {
|
|
14
15
|
fontSizeMap,
|
|
@@ -42,9 +43,9 @@ export { default as InputOtp } from './Input/InputOtp';
|
|
|
42
43
|
export { default as Switch } from './Input/Switch';
|
|
43
44
|
export { default as CheckBox } from './CheckBox/CheckBox';
|
|
44
45
|
export { default as CheckBoxList } from './CheckBox/CheckBoxList';
|
|
45
|
-
export { default as CounterButton } from './CounterButton/CounterButton';
|
|
46
46
|
export { default as RadioButton } from './RadioButton/RadioButton';
|
|
47
47
|
export { default as Icon } from './Icon/Icon';
|
|
48
|
+
export type { IconNameProps } from './Icon/type';
|
|
48
49
|
export { default as Modal } from './Modal/Modal';
|
|
49
50
|
export { default as Label } from './Label/Label';
|
|
50
51
|
export { default as List } from './List/List';
|
|
@@ -53,6 +54,12 @@ export { default as Loading } from './Loading/Loading';
|
|
|
53
54
|
export { default as Avatar } from './Avatar/Avatar';
|
|
54
55
|
export { default as AvatarGroup } from './Avatar/AvatarGroup';
|
|
55
56
|
export { default as Badge } from './Badge/Badge';
|
|
57
|
+
export type {
|
|
58
|
+
Variant as BadgeVariant,
|
|
59
|
+
Size as BadgeSize,
|
|
60
|
+
HexColor as BadgeColor,
|
|
61
|
+
SizeStyle as BadgeSizeStyle,
|
|
62
|
+
} from './Badge/type';
|
|
56
63
|
export { default as Alert } from './Alert/Alert';
|
|
57
64
|
export { default as Timeline } from './Timeline/Timeline';
|
|
58
65
|
export { default as TimelineItem } from './Timeline/TimelineItem';
|