ripal-ui 1.0.86 → 1.1.2

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.
@@ -0,0 +1,70 @@
1
+ import React, { useState } from 'react';
2
+ import { View, Pressable } from 'react-native';
3
+ import Inline from './Inline';
4
+ import Text from './Text';
5
+ import config from '../config';
6
+
7
+ type ColorPickerProps = {
8
+ value?: string;
9
+ label?: string;
10
+ onChange?: (color: string) => void;
11
+ };
12
+
13
+ const ColorPicker: React.FC<ColorPickerProps> = ({
14
+ value = '#fff',
15
+ label = 'Pilih Warna',
16
+ onChange = () => {}
17
+ }) => {
18
+ const [isPicking, setPicking] = useState(false);
19
+
20
+ return (
21
+ <View style={{ gap: 5 }}>
22
+ <Inline>
23
+ <Text style={{ flexGrow: 1, fontSize: 11 }}>{label}</Text>
24
+ <Pressable
25
+ style={{
26
+ backgroundColor: value,
27
+ height: 24,
28
+ aspectRatio: 16 / 9,
29
+ borderRadius: 8,
30
+ borderWidth: 1,
31
+ borderColor: '#ddd',
32
+ padding: 4
33
+ }}
34
+ onPress={() => setPicking(true)}
35
+ />
36
+ </Inline>
37
+
38
+ {isPicking && (
39
+ <View style={{ marginTop: 20 }}>
40
+ {Object.entries(config.colors).map((item, i) => {
41
+ if (typeof item[1] === 'object') {
42
+ return (
43
+ <Inline key={i} gap={0}>
44
+ {Object.entries(item[1] as Record<string, string>).map((sub, s) => (
45
+ <Pressable
46
+ key={s}
47
+ style={{
48
+ flexBasis: 30,
49
+ flexGrow: 1,
50
+ aspectRatio: 1,
51
+ backgroundColor: sub[1]
52
+ }}
53
+ onPress={() => {
54
+ onChange(sub[1]);
55
+ setPicking(false);
56
+ }}
57
+ />
58
+ ))}
59
+ </Inline>
60
+ );
61
+ }
62
+ return null;
63
+ })}
64
+ </View>
65
+ )}
66
+ </View>
67
+ );
68
+ };
69
+
70
+ export default ColorPicker;
@@ -14,6 +14,7 @@ interface InputProps {
14
14
  mode?: TextInputProps["keyboardType"]; // Use keyboardType from TextInputProps
15
15
  secureTextEntry?: boolean;
16
16
  multiline?: boolean;
17
+ gap?: number;
17
18
  onChangeText: (text: string) => void; // Function to handle text changes
18
19
  }
19
20
 
@@ -23,6 +24,7 @@ const Input: React.FC<InputProps> = ({
23
24
  left = null,
24
25
  right = null,
25
26
  height = 50,
27
+ gap = 20,
26
28
  placeholder = null,
27
29
  mode = "default",
28
30
  multiline = false,
@@ -43,6 +45,7 @@ const Input: React.FC<InputProps> = ({
43
45
  ...styles.input,
44
46
  borderColor: isFocused ? config.colors.primary : config.colors.slate[200],
45
47
  }}
48
+ gap={gap}
46
49
  >
47
50
  {left !== null && left}
48
51
  <TextInput
@@ -0,0 +1,133 @@
1
+ import React, { useRef } from 'react';
2
+ import {
3
+ View,
4
+ StyleSheet,
5
+ PanResponder,
6
+ Animated,
7
+ Dimensions,
8
+ GestureResponderEvent,
9
+ PanResponderGestureState
10
+ } from 'react-native';
11
+ import config from '../config';
12
+
13
+ type SliderProps = {
14
+ start?: number;
15
+ end?: number;
16
+ value?: number;
17
+ rounded?: number;
18
+ trackColor?: string;
19
+ color?: string;
20
+ height?: number;
21
+ thumbOpacity?: number;
22
+ thumbColor?: string;
23
+ onChange?: (value: number) => void;
24
+ setScrollEnabled?: (enabled: boolean) => void;
25
+ };
26
+
27
+ const Slider: React.FC<SliderProps> = ({
28
+ start = 0,
29
+ end = 100,
30
+ value = 25,
31
+ rounded = 8,
32
+ trackColor = '#ecf0f1',
33
+ color = config.colors.primary,
34
+ height = 40,
35
+ onChange,
36
+ thumbOpacity = 0.7,
37
+ thumbColor = '#fff',
38
+ setScrollEnabled = () => {}
39
+ }) => {
40
+ const pan = useRef(new Animated.ValueXY()).current;
41
+ const screenWidth = Dimensions.get('window').width;
42
+
43
+ const panResponder = useRef(
44
+ PanResponder.create({
45
+ onStartShouldSetPanResponder: () => true,
46
+ onMoveShouldSetPanResponder: (_: GestureResponderEvent, gestureState: PanResponderGestureState) => {
47
+ return Math.abs(gestureState.dx) > Math.abs(gestureState.dy);
48
+ },
49
+ onPanResponderGrant: () => {
50
+ setScrollEnabled(false);
51
+ },
52
+ onPanResponderMove: (_: GestureResponderEvent, gestureState: PanResponderGestureState) => {
53
+ const clampedX = Math.max(0, Math.min(screenWidth, gestureState.moveX));
54
+ let percent = clampedX / screenWidth;
55
+ let newValue = Math.round(start + percent * (end - start));
56
+ onChange?.(newValue);
57
+ },
58
+ onPanResponderRelease: () => {
59
+ setScrollEnabled(true);
60
+ Animated.spring(pan, {
61
+ toValue: { x: 0, y: 0 },
62
+ useNativeDriver: false
63
+ }).start();
64
+ },
65
+ onPanResponderTerminate: () => {
66
+ setScrollEnabled(true);
67
+ Animated.spring(pan, {
68
+ toValue: { x: 0, y: 0 },
69
+ useNativeDriver: false
70
+ }).start();
71
+ },
72
+ onPanResponderTerminationRequest: () => false
73
+ })
74
+ ).current;
75
+
76
+ return (
77
+ <View
78
+ style={[styles.touchArea, { height }]}
79
+ {...panResponder.panHandlers}
80
+ >
81
+ <View
82
+ style={[
83
+ styles.container,
84
+ { height, backgroundColor: trackColor, borderRadius: rounded }
85
+ ]}
86
+ >
87
+ <View
88
+ style={{
89
+ backgroundColor: color,
90
+ width: `${value / (end - start) * 100}%`,
91
+ height,
92
+ alignItems: 'flex-end',
93
+ justifyContent: 'center',
94
+ borderRadius: rounded
95
+ }}
96
+ >
97
+ <View
98
+ style={{
99
+ ...styles.thumb,
100
+ height: (60 / 100) * height,
101
+ marginRight: (rounded / height) * 100 > 25 ? 20 : 10,
102
+ opacity: thumbOpacity,
103
+ backgroundColor: thumbColor
104
+ }}
105
+ />
106
+ </View>
107
+ </View>
108
+ </View>
109
+ );
110
+ };
111
+
112
+ const styles = StyleSheet.create({
113
+ touchArea: {
114
+ width: '100%'
115
+ },
116
+ container: {
117
+ width: '100%',
118
+ position: 'relative'
119
+ },
120
+ thumb_dot: {
121
+ width: 4,
122
+ height: 4,
123
+ backgroundColor: '#fff',
124
+ borderRadius: 9
125
+ },
126
+ thumb: {
127
+ width: 3,
128
+ backgroundColor: '#fff',
129
+ borderRadius: 9
130
+ }
131
+ });
132
+
133
+ export default Slider;
package/elements/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { default as Button } from './Button';
2
+ export { default as ColorPicker } from './ColorPicker';
2
3
  export { Dialog, DialogActions } from './Dialog';
3
4
  export { default as Dropdown } from './Dropdown';
4
5
  export { default as Inline } from './Inline';
@@ -6,6 +7,7 @@ export { default as Input } from './Input';
6
7
  export { default as ProgressBar } from './ProgressBar';
7
8
  export { default as Separator } from './Separator';
8
9
  export { default as Skeleton } from './Skeleton';
10
+ export { default as Slider } from './Slider';
9
11
  export { default as Switch } from './Switch';
10
12
  export { default as Text } from './Text';
11
13
  export { default as Toast } from './Toast';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ripal-ui",
3
- "version": "1.0.86",
3
+ "version": "1.1.02",
4
4
  "description": "A collection of React elements and components",
5
5
  "main": "index.js",
6
6
  "scripts": {