@kaushverse/pickify 1.0.0 → 1.0.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.
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React from 'react';
3
- import { ViewStyle, TextStyle } from 'react-native';
3
+ import { TextStyle, ViewStyle } from 'react-native';
4
4
 
5
5
  type Option = {
6
6
  label: string;
@@ -25,9 +25,18 @@ type PickerStyles = {
25
25
  doneText?: TextStyle;
26
26
  selectTab?: ViewStyle;
27
27
  selectTabText?: TextStyle;
28
+ inputContainer?: ViewStyle;
29
+ label?: TextStyle;
30
+ selectBox?: ViewStyle;
31
+ selectText?: TextStyle;
32
+ error?: TextStyle;
28
33
  };
29
34
  type Props = {
30
- visible: boolean;
35
+ labelStyle?: TextStyle;
36
+ selectBoxStyle?: ViewStyle;
37
+ selectTextStyle?: TextStyle;
38
+ errorStyle?: TextStyle;
39
+ visible?: boolean;
31
40
  selectedValue: string;
32
41
  options: Option[];
33
42
  groups?: Group[];
@@ -45,8 +54,10 @@ type Props = {
45
54
  onClose: () => void;
46
55
  };
47
56
 
48
- declare function PickerModal({ visible, selectedValue, options, groups, styles, theme, renderTab, renderItem, renderContainer, onSelect, onClose, renderIcon, variant, }: Props & {
49
- variant?: "tabs" | "input";
57
+ declare function PickerModal({ visible, selectedValue, options, groups, styles, theme, renderTab, renderItem, renderContainer, onSelect, onClose, renderIcon, label, placeholder, error, labelStyle, selectBoxStyle, selectTextStyle, errorStyle }: Props & {
58
+ label?: string;
59
+ placeholder?: string;
60
+ error?: string;
50
61
  }): react_jsx_runtime.JSX.Element;
51
62
 
52
63
  declare const groupOptions: (options: Option[], config: Record<string, string[]>) => Group[];
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React from 'react';
3
- import { ViewStyle, TextStyle } from 'react-native';
3
+ import { TextStyle, ViewStyle } from 'react-native';
4
4
 
5
5
  type Option = {
6
6
  label: string;
@@ -25,9 +25,18 @@ type PickerStyles = {
25
25
  doneText?: TextStyle;
26
26
  selectTab?: ViewStyle;
27
27
  selectTabText?: TextStyle;
28
+ inputContainer?: ViewStyle;
29
+ label?: TextStyle;
30
+ selectBox?: ViewStyle;
31
+ selectText?: TextStyle;
32
+ error?: TextStyle;
28
33
  };
29
34
  type Props = {
30
- visible: boolean;
35
+ labelStyle?: TextStyle;
36
+ selectBoxStyle?: ViewStyle;
37
+ selectTextStyle?: TextStyle;
38
+ errorStyle?: TextStyle;
39
+ visible?: boolean;
31
40
  selectedValue: string;
32
41
  options: Option[];
33
42
  groups?: Group[];
@@ -45,8 +54,10 @@ type Props = {
45
54
  onClose: () => void;
46
55
  };
47
56
 
48
- declare function PickerModal({ visible, selectedValue, options, groups, styles, theme, renderTab, renderItem, renderContainer, onSelect, onClose, renderIcon, variant, }: Props & {
49
- variant?: "tabs" | "input";
57
+ declare function PickerModal({ visible, selectedValue, options, groups, styles, theme, renderTab, renderItem, renderContainer, onSelect, onClose, renderIcon, label, placeholder, error, labelStyle, selectBoxStyle, selectTextStyle, errorStyle }: Props & {
58
+ label?: string;
59
+ placeholder?: string;
60
+ error?: string;
50
61
  }): react_jsx_runtime.JSX.Element;
51
62
 
52
63
  declare const groupOptions: (options: Option[], config: Record<string, string[]>) => Group[];
package/dist/index.js CHANGED
@@ -43,11 +43,18 @@ function PickerModal({
43
43
  onSelect,
44
44
  onClose,
45
45
  renderIcon,
46
- variant = "tabs"
46
+ label,
47
+ placeholder = "Select",
48
+ error,
49
+ labelStyle,
50
+ selectBoxStyle,
51
+ selectTextStyle,
52
+ errorStyle
47
53
  }) {
48
54
  const [activeTab, setActiveTab] = (0, import_react.useState)(0);
55
+ const [open, setOpen] = (0, import_react.useState)(false);
56
+ const isVisible = visible ?? open;
49
57
  const hasGroups = groups.length > 0;
50
- const isInputVariant = variant === "input";
51
58
  const currentOptions = hasGroups ? groups[activeTab]?.data || [] : options;
52
59
  (0, import_react.useEffect)(() => {
53
60
  if (!hasGroups) return;
@@ -55,10 +62,21 @@ function PickerModal({
55
62
  (group) => group.data.some((item) => item.value === selectedValue)
56
63
  );
57
64
  if (index !== -1) setActiveTab(index);
58
- }, [selectedValue, visible]);
65
+ }, [selectedValue, isVisible]);
59
66
  const primary = theme?.primaryColor || "#6366f1";
60
67
  const bg = theme?.backgroundColor || "#fff";
61
68
  const text = theme?.textColor || "#111827";
69
+ const getLabel = () => {
70
+ const all = hasGroups ? groups.flatMap((g) => g.data) : options;
71
+ return all.find((o) => o.value === selectedValue)?.label;
72
+ };
73
+ const handleClose = () => {
74
+ setOpen(false);
75
+ onClose?.();
76
+ };
77
+ const handleOpen = () => {
78
+ setOpen(true);
79
+ };
62
80
  const content = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
63
81
  import_react_native.View,
64
82
  {
@@ -76,11 +94,11 @@ function PickerModal({
76
94
  { backgroundColor: primary },
77
95
  styles?.doneBtn
78
96
  ],
79
- onPress: onClose,
97
+ onPress: handleClose,
80
98
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Text, { style: [defaultStyles.doneText, styles?.doneText], children: "Done" })
81
99
  }
82
100
  ),
83
- hasGroups && !isInputVariant && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, children: groups.map((tab, index) => {
101
+ hasGroups && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, children: groups.map((tab, index) => {
84
102
  const isActive = activeTab === index;
85
103
  if (renderTab) {
86
104
  return renderTab(tab, isActive, () => setActiveTab(index));
@@ -91,9 +109,7 @@ function PickerModal({
91
109
  style: [
92
110
  defaultStyles.tab,
93
111
  styles?.tab,
94
- isActive && {
95
- backgroundColor: primary
96
- }
112
+ isActive && { backgroundColor: primary }
97
113
  ],
98
114
  onPress: () => setActiveTab(index),
99
115
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -111,50 +127,64 @@ function PickerModal({
111
127
  tab.label
112
128
  );
113
129
  }) }),
114
- hasGroups && isInputVariant && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, children: groups.map((tab, index) => {
115
- const isActive = activeTab === index;
116
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
117
- import_react_native.TouchableOpacity,
118
- {
119
- style: [
120
- defaultStyles.selectTab,
121
- styles?.selectTab,
122
- isActive && { borderColor: primary }
123
- ],
124
- onPress: () => setActiveTab(index),
125
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: defaultStyles.selectTabInner, children: [
126
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
127
- import_react_native.Text,
128
- {
129
- style: [defaultStyles.selectTabText, styles?.selectTabText],
130
- children: tab.label
131
- }
132
- ),
133
- renderIcon?.({
134
- name: "chevron-down",
135
- size: 18,
136
- color: "#6B7280"
137
- })
138
- ] })
139
- },
140
- tab.label
141
- );
142
- }) }),
143
130
  renderItem ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.ScrollView, { style: { maxHeight: 250 }, children: currentOptions.map(
144
131
  (item) => renderItem(item, selectedValue === item.value)
145
- ) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_picker.Picker, { selectedValue, onValueChange: onSelect, children: currentOptions.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
146
- import_picker.Picker.Item,
132
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
133
+ import_picker.Picker,
147
134
  {
148
- label: item.label,
149
- value: item.value,
150
- color: text
151
- },
152
- item.value
153
- )) })
135
+ selectedValue,
136
+ onValueChange: (val) => onSelect(val),
137
+ children: currentOptions.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
138
+ import_picker.Picker.Item,
139
+ {
140
+ label: item.label,
141
+ value: item.value,
142
+ color: text
143
+ },
144
+ item.value
145
+ ))
146
+ }
147
+ )
154
148
  ]
155
149
  }
156
150
  );
157
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Modal, { visible, transparent: true, animationType: "slide", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: defaultStyles.modalOverlay, children: renderContainer ? renderContainer(content) : content }) });
151
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
152
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: styles?.inputContainer, children: [
153
+ label && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Text, { style: [defaultStyles.label, styles?.label, labelStyle], children: label }),
154
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
155
+ import_react_native.TouchableOpacity,
156
+ {
157
+ style: [
158
+ defaultStyles.selectBox,
159
+ styles?.selectBox,
160
+ selectBoxStyle,
161
+ error && { borderColor: "red" }
162
+ ],
163
+ onPress: handleOpen,
164
+ children: [
165
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
166
+ import_react_native.Text,
167
+ {
168
+ style: [
169
+ defaultStyles.selectText,
170
+ styles?.selectText,
171
+ selectTextStyle
172
+ ],
173
+ children: getLabel() || placeholder
174
+ }
175
+ ),
176
+ renderIcon?.({
177
+ name: "chevron-down",
178
+ size: 18,
179
+ color: "#6B7280"
180
+ })
181
+ ]
182
+ }
183
+ ),
184
+ error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Text, { style: [defaultStyles.error, styles?.error, errorStyle], children: error })
185
+ ] }),
186
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Modal, { visible: isVisible, transparent: true, animationType: "slide", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: defaultStyles.modalOverlay, children: renderContainer ? renderContainer(content) : content }) })
187
+ ] });
158
188
  }
159
189
  var defaultStyles = import_react_native.StyleSheet.create({
160
190
  modalOverlay: {
@@ -167,20 +197,12 @@ var defaultStyles = import_react_native.StyleSheet.create({
167
197
  borderTopRightRadius: 20,
168
198
  padding: 20
169
199
  },
170
- /* ---------- NORMAL TABS ---------- */
171
- tab: {
172
- paddingHorizontal: 16,
173
- paddingVertical: 8,
174
- borderRadius: 20,
175
- marginRight: 8,
176
- backgroundColor: "#f3f4f6"
177
- },
178
- tabText: {
179
- fontSize: 13,
180
- fontWeight: "500"
200
+ label: {
201
+ fontSize: 16,
202
+ marginBottom: 6
181
203
  },
182
- /* ---------- INPUT STYLE TABS ---------- */
183
- selectTab: {
204
+ /* ---------- INPUT ---------- */
205
+ selectBox: {
184
206
  height: 48,
185
207
  borderWidth: 1,
186
208
  borderColor: "#E5E7EB",
@@ -190,16 +212,28 @@ var defaultStyles = import_react_native.StyleSheet.create({
190
212
  justifyContent: "space-between",
191
213
  alignItems: "center"
192
214
  },
193
- selectTabInner: {
194
- flexDirection: "row",
195
- justifyContent: "space-between",
196
- alignItems: "center"
197
- },
198
- selectTabText: {
215
+ selectText: {
199
216
  fontSize: 16,
200
217
  fontWeight: "500"
201
218
  },
202
- /* ---------- DONE BUTTON ---------- */
219
+ error: {
220
+ color: "red",
221
+ fontSize: 12,
222
+ marginTop: 4
223
+ },
224
+ /* ---------- TABS ---------- */
225
+ tab: {
226
+ paddingHorizontal: 16,
227
+ paddingVertical: 8,
228
+ borderRadius: 20,
229
+ marginRight: 8,
230
+ backgroundColor: "#f3f4f6"
231
+ },
232
+ tabText: {
233
+ fontSize: 13,
234
+ fontWeight: "500"
235
+ },
236
+ /* ---------- DONE ---------- */
203
237
  doneBtn: {
204
238
  alignSelf: "flex-end",
205
239
  paddingHorizontal: 14,
package/dist/index.mjs CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  ScrollView
10
10
  } from "react-native";
11
11
  import { Picker } from "@react-native-picker/picker";
12
- import { jsx, jsxs } from "react/jsx-runtime";
12
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
13
  function PickerModal({
14
14
  visible,
15
15
  selectedValue,
@@ -23,11 +23,18 @@ function PickerModal({
23
23
  onSelect,
24
24
  onClose,
25
25
  renderIcon,
26
- variant = "tabs"
26
+ label,
27
+ placeholder = "Select",
28
+ error,
29
+ labelStyle,
30
+ selectBoxStyle,
31
+ selectTextStyle,
32
+ errorStyle
27
33
  }) {
28
34
  const [activeTab, setActiveTab] = useState(0);
35
+ const [open, setOpen] = useState(false);
36
+ const isVisible = visible ?? open;
29
37
  const hasGroups = groups.length > 0;
30
- const isInputVariant = variant === "input";
31
38
  const currentOptions = hasGroups ? groups[activeTab]?.data || [] : options;
32
39
  useEffect(() => {
33
40
  if (!hasGroups) return;
@@ -35,10 +42,21 @@ function PickerModal({
35
42
  (group) => group.data.some((item) => item.value === selectedValue)
36
43
  );
37
44
  if (index !== -1) setActiveTab(index);
38
- }, [selectedValue, visible]);
45
+ }, [selectedValue, isVisible]);
39
46
  const primary = theme?.primaryColor || "#6366f1";
40
47
  const bg = theme?.backgroundColor || "#fff";
41
48
  const text = theme?.textColor || "#111827";
49
+ const getLabel = () => {
50
+ const all = hasGroups ? groups.flatMap((g) => g.data) : options;
51
+ return all.find((o) => o.value === selectedValue)?.label;
52
+ };
53
+ const handleClose = () => {
54
+ setOpen(false);
55
+ onClose?.();
56
+ };
57
+ const handleOpen = () => {
58
+ setOpen(true);
59
+ };
42
60
  const content = /* @__PURE__ */ jsxs(
43
61
  View,
44
62
  {
@@ -56,11 +74,11 @@ function PickerModal({
56
74
  { backgroundColor: primary },
57
75
  styles?.doneBtn
58
76
  ],
59
- onPress: onClose,
77
+ onPress: handleClose,
60
78
  children: /* @__PURE__ */ jsx(Text, { style: [defaultStyles.doneText, styles?.doneText], children: "Done" })
61
79
  }
62
80
  ),
63
- hasGroups && !isInputVariant && /* @__PURE__ */ jsx(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, children: groups.map((tab, index) => {
81
+ hasGroups && /* @__PURE__ */ jsx(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, children: groups.map((tab, index) => {
64
82
  const isActive = activeTab === index;
65
83
  if (renderTab) {
66
84
  return renderTab(tab, isActive, () => setActiveTab(index));
@@ -71,9 +89,7 @@ function PickerModal({
71
89
  style: [
72
90
  defaultStyles.tab,
73
91
  styles?.tab,
74
- isActive && {
75
- backgroundColor: primary
76
- }
92
+ isActive && { backgroundColor: primary }
77
93
  ],
78
94
  onPress: () => setActiveTab(index),
79
95
  children: /* @__PURE__ */ jsx(
@@ -91,50 +107,64 @@ function PickerModal({
91
107
  tab.label
92
108
  );
93
109
  }) }),
94
- hasGroups && isInputVariant && /* @__PURE__ */ jsx(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, children: groups.map((tab, index) => {
95
- const isActive = activeTab === index;
96
- return /* @__PURE__ */ jsx(
97
- TouchableOpacity,
98
- {
99
- style: [
100
- defaultStyles.selectTab,
101
- styles?.selectTab,
102
- isActive && { borderColor: primary }
103
- ],
104
- onPress: () => setActiveTab(index),
105
- children: /* @__PURE__ */ jsxs(View, { style: defaultStyles.selectTabInner, children: [
106
- /* @__PURE__ */ jsx(
107
- Text,
108
- {
109
- style: [defaultStyles.selectTabText, styles?.selectTabText],
110
- children: tab.label
111
- }
112
- ),
113
- renderIcon?.({
114
- name: "chevron-down",
115
- size: 18,
116
- color: "#6B7280"
117
- })
118
- ] })
119
- },
120
- tab.label
121
- );
122
- }) }),
123
110
  renderItem ? /* @__PURE__ */ jsx(ScrollView, { style: { maxHeight: 250 }, children: currentOptions.map(
124
111
  (item) => renderItem(item, selectedValue === item.value)
125
- ) }) : /* @__PURE__ */ jsx(Picker, { selectedValue, onValueChange: onSelect, children: currentOptions.map((item) => /* @__PURE__ */ jsx(
126
- Picker.Item,
112
+ ) }) : /* @__PURE__ */ jsx(
113
+ Picker,
127
114
  {
128
- label: item.label,
129
- value: item.value,
130
- color: text
131
- },
132
- item.value
133
- )) })
115
+ selectedValue,
116
+ onValueChange: (val) => onSelect(val),
117
+ children: currentOptions.map((item) => /* @__PURE__ */ jsx(
118
+ Picker.Item,
119
+ {
120
+ label: item.label,
121
+ value: item.value,
122
+ color: text
123
+ },
124
+ item.value
125
+ ))
126
+ }
127
+ )
134
128
  ]
135
129
  }
136
130
  );
137
- return /* @__PURE__ */ jsx(Modal, { visible, transparent: true, animationType: "slide", children: /* @__PURE__ */ jsx(View, { style: defaultStyles.modalOverlay, children: renderContainer ? renderContainer(content) : content }) });
131
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
132
+ /* @__PURE__ */ jsxs(View, { style: styles?.inputContainer, children: [
133
+ label && /* @__PURE__ */ jsx(Text, { style: [defaultStyles.label, styles?.label, labelStyle], children: label }),
134
+ /* @__PURE__ */ jsxs(
135
+ TouchableOpacity,
136
+ {
137
+ style: [
138
+ defaultStyles.selectBox,
139
+ styles?.selectBox,
140
+ selectBoxStyle,
141
+ error && { borderColor: "red" }
142
+ ],
143
+ onPress: handleOpen,
144
+ children: [
145
+ /* @__PURE__ */ jsx(
146
+ Text,
147
+ {
148
+ style: [
149
+ defaultStyles.selectText,
150
+ styles?.selectText,
151
+ selectTextStyle
152
+ ],
153
+ children: getLabel() || placeholder
154
+ }
155
+ ),
156
+ renderIcon?.({
157
+ name: "chevron-down",
158
+ size: 18,
159
+ color: "#6B7280"
160
+ })
161
+ ]
162
+ }
163
+ ),
164
+ error && /* @__PURE__ */ jsx(Text, { style: [defaultStyles.error, styles?.error, errorStyle], children: error })
165
+ ] }),
166
+ /* @__PURE__ */ jsx(Modal, { visible: isVisible, transparent: true, animationType: "slide", children: /* @__PURE__ */ jsx(View, { style: defaultStyles.modalOverlay, children: renderContainer ? renderContainer(content) : content }) })
167
+ ] });
138
168
  }
139
169
  var defaultStyles = StyleSheet.create({
140
170
  modalOverlay: {
@@ -147,20 +177,12 @@ var defaultStyles = StyleSheet.create({
147
177
  borderTopRightRadius: 20,
148
178
  padding: 20
149
179
  },
150
- /* ---------- NORMAL TABS ---------- */
151
- tab: {
152
- paddingHorizontal: 16,
153
- paddingVertical: 8,
154
- borderRadius: 20,
155
- marginRight: 8,
156
- backgroundColor: "#f3f4f6"
157
- },
158
- tabText: {
159
- fontSize: 13,
160
- fontWeight: "500"
180
+ label: {
181
+ fontSize: 16,
182
+ marginBottom: 6
161
183
  },
162
- /* ---------- INPUT STYLE TABS ---------- */
163
- selectTab: {
184
+ /* ---------- INPUT ---------- */
185
+ selectBox: {
164
186
  height: 48,
165
187
  borderWidth: 1,
166
188
  borderColor: "#E5E7EB",
@@ -170,16 +192,28 @@ var defaultStyles = StyleSheet.create({
170
192
  justifyContent: "space-between",
171
193
  alignItems: "center"
172
194
  },
173
- selectTabInner: {
174
- flexDirection: "row",
175
- justifyContent: "space-between",
176
- alignItems: "center"
177
- },
178
- selectTabText: {
195
+ selectText: {
179
196
  fontSize: 16,
180
197
  fontWeight: "500"
181
198
  },
182
- /* ---------- DONE BUTTON ---------- */
199
+ error: {
200
+ color: "red",
201
+ fontSize: 12,
202
+ marginTop: 4
203
+ },
204
+ /* ---------- TABS ---------- */
205
+ tab: {
206
+ paddingHorizontal: 16,
207
+ paddingVertical: 8,
208
+ borderRadius: 20,
209
+ marginRight: 8,
210
+ backgroundColor: "#f3f4f6"
211
+ },
212
+ tabText: {
213
+ fontSize: 13,
214
+ fontWeight: "500"
215
+ },
216
+ /* ---------- DONE ---------- */
183
217
  doneBtn: {
184
218
  alignSelf: "flex-end",
185
219
  paddingHorizontal: 14,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaushverse/pickify",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "A fully customizable React Native picker with search, multi-select, grouping, and async support.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",