@kaushverse/pickify 1.0.4 → 1.0.7

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,5 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import React from 'react';
2
+ import React$1 from 'react';
3
3
  import { TextStyle, ViewStyle } from 'react-native';
4
4
 
5
5
  type Option = {
@@ -43,14 +43,14 @@ type Props = {
43
43
  groups?: Group[];
44
44
  styles?: PickerStyles;
45
45
  theme?: Theme;
46
- renderTab?: (tab: Group, isActive: boolean, onPress: () => void) => React.ReactNode;
47
- renderItem?: (item: Option, isSelected: boolean) => React.ReactNode;
48
- renderContainer?: (children: React.ReactNode) => React.ReactNode;
46
+ renderTab?: (tab: Group, isActive: boolean, onPress: () => void) => React$1.ReactNode;
47
+ renderItem?: (item: Option, isSelected: boolean) => React$1.ReactNode;
48
+ renderContainer?: (children: React$1.ReactNode) => React$1.ReactNode;
49
49
  renderIcon?: (props: {
50
50
  name: string;
51
51
  size: number;
52
52
  color: string;
53
- }) => React.ReactNode;
53
+ }) => React$1.ReactNode;
54
54
  onSelect: (value: string) => void;
55
55
  onClose: () => void;
56
56
  };
@@ -61,6 +61,40 @@ declare function PickerModal({ visible, selectedValue, options, groups, styles,
61
61
  error?: string;
62
62
  }): react_jsx_runtime.JSX.Element;
63
63
 
64
+ type MultiOption = {
65
+ label: string;
66
+ value: string;
67
+ };
68
+ type MultiGroup = {
69
+ label: string;
70
+ data: MultiOption[];
71
+ };
72
+ type MultiPickerProps = {
73
+ visible?: boolean;
74
+ setVisible?: (val: boolean) => void;
75
+ selectedValues: string[];
76
+ options: MultiOption[];
77
+ groups?: MultiGroup[];
78
+ onChange: (val: string[]) => void;
79
+ label?: string;
80
+ placeholder?: string;
81
+ error?: string;
82
+ renderIcon?: (props: {
83
+ name: string;
84
+ size: number;
85
+ color: string;
86
+ }) => React.ReactNode;
87
+ styles?: {
88
+ container?: ViewStyle;
89
+ selectBox?: ViewStyle;
90
+ selectText?: TextStyle;
91
+ };
92
+ };
93
+
94
+ declare function MultiPickerModal({ visible, setVisible, selectedValues, options, groups, onChange, label, placeholder, error, renderIcon, }: MultiPickerProps): react_jsx_runtime.JSX.Element;
95
+
64
96
  declare const groupOptions: (options: Option[], config: Record<string, string[]>) => Group[];
65
97
 
66
- export { type Group, type Option, PickerModal, type PickerStyles, type Props, type Theme, groupOptions };
98
+ declare const toggleValue: (arr: string[], value: string) => string[];
99
+
100
+ export { type Group, type MultiGroup, type MultiOption, MultiPickerModal, type MultiPickerProps, type Option, PickerModal, type PickerStyles, type Props, type Theme, groupOptions, toggleValue };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import React from 'react';
2
+ import React$1 from 'react';
3
3
  import { TextStyle, ViewStyle } from 'react-native';
4
4
 
5
5
  type Option = {
@@ -43,14 +43,14 @@ type Props = {
43
43
  groups?: Group[];
44
44
  styles?: PickerStyles;
45
45
  theme?: Theme;
46
- renderTab?: (tab: Group, isActive: boolean, onPress: () => void) => React.ReactNode;
47
- renderItem?: (item: Option, isSelected: boolean) => React.ReactNode;
48
- renderContainer?: (children: React.ReactNode) => React.ReactNode;
46
+ renderTab?: (tab: Group, isActive: boolean, onPress: () => void) => React$1.ReactNode;
47
+ renderItem?: (item: Option, isSelected: boolean) => React$1.ReactNode;
48
+ renderContainer?: (children: React$1.ReactNode) => React$1.ReactNode;
49
49
  renderIcon?: (props: {
50
50
  name: string;
51
51
  size: number;
52
52
  color: string;
53
- }) => React.ReactNode;
53
+ }) => React$1.ReactNode;
54
54
  onSelect: (value: string) => void;
55
55
  onClose: () => void;
56
56
  };
@@ -61,6 +61,40 @@ declare function PickerModal({ visible, selectedValue, options, groups, styles,
61
61
  error?: string;
62
62
  }): react_jsx_runtime.JSX.Element;
63
63
 
64
+ type MultiOption = {
65
+ label: string;
66
+ value: string;
67
+ };
68
+ type MultiGroup = {
69
+ label: string;
70
+ data: MultiOption[];
71
+ };
72
+ type MultiPickerProps = {
73
+ visible?: boolean;
74
+ setVisible?: (val: boolean) => void;
75
+ selectedValues: string[];
76
+ options: MultiOption[];
77
+ groups?: MultiGroup[];
78
+ onChange: (val: string[]) => void;
79
+ label?: string;
80
+ placeholder?: string;
81
+ error?: string;
82
+ renderIcon?: (props: {
83
+ name: string;
84
+ size: number;
85
+ color: string;
86
+ }) => React.ReactNode;
87
+ styles?: {
88
+ container?: ViewStyle;
89
+ selectBox?: ViewStyle;
90
+ selectText?: TextStyle;
91
+ };
92
+ };
93
+
94
+ declare function MultiPickerModal({ visible, setVisible, selectedValues, options, groups, onChange, label, placeholder, error, renderIcon, }: MultiPickerProps): react_jsx_runtime.JSX.Element;
95
+
64
96
  declare const groupOptions: (options: Option[], config: Record<string, string[]>) => Group[];
65
97
 
66
- export { type Group, type Option, PickerModal, type PickerStyles, type Props, type Theme, groupOptions };
98
+ declare const toggleValue: (arr: string[], value: string) => string[];
99
+
100
+ export { type Group, type MultiGroup, type MultiOption, MultiPickerModal, type MultiPickerProps, type Option, PickerModal, type PickerStyles, type Props, type Theme, groupOptions, toggleValue };
package/dist/index.js CHANGED
@@ -20,8 +20,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ MultiPickerModal: () => MultiPickerModal,
23
24
  PickerModal: () => PickerModal,
24
- groupOptions: () => groupOptions
25
+ groupOptions: () => groupOptions,
26
+ toggleValue: () => toggleValue
25
27
  });
26
28
  module.exports = __toCommonJS(index_exports);
27
29
 
@@ -35,7 +37,7 @@ function PickerModal({
35
37
  selectedValue,
36
38
  options,
37
39
  groups = [],
38
- styles,
40
+ styles: styles4,
39
41
  theme,
40
42
  renderTab,
41
43
  renderItem,
@@ -93,7 +95,7 @@ function PickerModal({
93
95
  style: [
94
96
  defaultStyles.container,
95
97
  { backgroundColor: bg },
96
- styles?.container
98
+ styles4?.container
97
99
  ],
98
100
  children: [
99
101
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -102,10 +104,10 @@ function PickerModal({
102
104
  style: [
103
105
  defaultStyles.doneBtn,
104
106
  { backgroundColor: primary },
105
- styles?.doneBtn
107
+ styles4?.doneBtn
106
108
  ],
107
109
  onPress: handleClose,
108
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Text, { style: [defaultStyles.doneText, styles?.doneText], children: "Done" })
110
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Text, { style: [defaultStyles.doneText, styles4?.doneText], children: "Done" })
109
111
  }
110
112
  ),
111
113
  hasGroups && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, children: groups.map((tab, index) => {
@@ -118,7 +120,7 @@ function PickerModal({
118
120
  {
119
121
  style: [
120
122
  defaultStyles.tab,
121
- styles?.tab,
123
+ styles4?.tab,
122
124
  isActive && { backgroundColor: primary }
123
125
  ],
124
126
  onPress: () => setActiveTab(index),
@@ -128,7 +130,7 @@ function PickerModal({
128
130
  style: [
129
131
  defaultStyles.tabText,
130
132
  { color: isActive ? "#fff" : text },
131
- styles?.tabText
133
+ styles4?.tabText
132
134
  ],
133
135
  children: tab.label
134
136
  }
@@ -159,14 +161,14 @@ function PickerModal({
159
161
  }
160
162
  );
161
163
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
162
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: styles?.inputContainer, children: [
163
- label && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Text, { style: [defaultStyles.label, styles?.label, labelStyle], children: label }),
164
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: styles4?.inputContainer, children: [
165
+ label && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Text, { style: [defaultStyles.label, styles4?.label, labelStyle], children: label }),
164
166
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
165
167
  import_react_native.TouchableOpacity,
166
168
  {
167
169
  style: [
168
170
  defaultStyles.selectBox,
169
- styles?.selectBox,
171
+ styles4?.selectBox,
170
172
  selectBoxStyle,
171
173
  error && { borderColor: "red" }
172
174
  ],
@@ -177,7 +179,7 @@ function PickerModal({
177
179
  {
178
180
  style: [
179
181
  defaultStyles.selectText,
180
- styles?.selectText,
182
+ styles4?.selectText,
181
183
  selectTextStyle
182
184
  ],
183
185
  children: getLabel() || placeholder
@@ -191,7 +193,7 @@ function PickerModal({
191
193
  ]
192
194
  }
193
195
  ),
194
- error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Text, { style: [defaultStyles.error, styles?.error, errorStyle], children: error })
196
+ error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Text, { style: [defaultStyles.error, styles4?.error, errorStyle], children: error })
195
197
  ] }),
196
198
  /* @__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 }) })
197
199
  ] });
@@ -257,6 +259,213 @@ var defaultStyles = import_react_native.StyleSheet.create({
257
259
  }
258
260
  });
259
261
 
262
+ // src/core/MultiPickerModal.tsx
263
+ var import_react3 = require("react");
264
+ var import_react_native4 = require("react-native");
265
+
266
+ // src/utils/toggleValue.ts
267
+ var toggleValue = (arr, value) => {
268
+ return arr.includes(value) ? arr.filter((v) => v !== value) : [...arr, value];
269
+ };
270
+
271
+ // src/components/MultiPickerGroup.tsx
272
+ var import_react2 = require("react");
273
+ var import_react_native2 = require("react-native");
274
+ var import_jsx_runtime2 = require("react/jsx-runtime");
275
+ function MultiPickerGroup({
276
+ label,
277
+ children,
278
+ renderIcon
279
+ }) {
280
+ const [open, setOpen] = (0, import_react2.useState)(true);
281
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles.group, children: [
282
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.TouchableOpacity, { style: styles.header, onPress: () => setOpen(!open), children: [
283
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: styles.title, children: label }),
284
+ renderIcon ? renderIcon({
285
+ name: open ? "chevron-up" : "chevron-down",
286
+ size: 18,
287
+ color: "#6B7280"
288
+ }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: styles.fallback, children: open ? "\u2303" : "\u2304" })
289
+ ] }),
290
+ open && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: { marginTop: 6 }, children })
291
+ ] });
292
+ }
293
+ var styles = import_react_native2.StyleSheet.create({
294
+ group: {
295
+ marginBottom: 12
296
+ },
297
+ header: {
298
+ flexDirection: "row",
299
+ justifyContent: "space-between",
300
+ alignItems: "center"
301
+ },
302
+ title: {
303
+ fontWeight: "600",
304
+ fontSize: 14
305
+ },
306
+ fallback: {
307
+ fontSize: 16,
308
+ color: "#6B7280"
309
+ }
310
+ });
311
+
312
+ // src/components/MultiPickerItem.tsx
313
+ var import_react_native3 = require("react-native");
314
+ var import_jsx_runtime3 = require("react/jsx-runtime");
315
+ function MultiPickerItem({
316
+ label,
317
+ selected,
318
+ onPress
319
+ }) {
320
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.TouchableOpacity, { style: styles2.item, onPress, children: [
321
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { style: styles2.label, children: label }),
322
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.View, { style: [styles2.circle, selected && styles2.active], children: selected && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { style: styles2.check, children: "\u2713" }) })
323
+ ] });
324
+ }
325
+ var styles2 = import_react_native3.StyleSheet.create({
326
+ item: {
327
+ flexDirection: "row",
328
+ justifyContent: "space-between",
329
+ alignItems: "center",
330
+ paddingVertical: 12
331
+ },
332
+ label: {
333
+ fontSize: 15
334
+ },
335
+ circle: {
336
+ width: 22,
337
+ height: 22,
338
+ borderRadius: 999,
339
+ borderWidth: 2,
340
+ borderColor: "#ccc",
341
+ justifyContent: "center",
342
+ alignItems: "center"
343
+ },
344
+ active: {
345
+ backgroundColor: "#22c55e",
346
+ borderColor: "#22c55e"
347
+ },
348
+ check: {
349
+ color: "#fff",
350
+ fontSize: 12,
351
+ fontWeight: "bold"
352
+ }
353
+ });
354
+
355
+ // src/core/MultiPickerModal.tsx
356
+ var import_jsx_runtime4 = require("react/jsx-runtime");
357
+ function MultiPickerModal({
358
+ visible,
359
+ setVisible,
360
+ selectedValues,
361
+ options = [],
362
+ groups = [],
363
+ onChange,
364
+ label,
365
+ placeholder = "Select",
366
+ error,
367
+ renderIcon
368
+ }) {
369
+ const [internalVisible, setInternalVisible] = (0, import_react3.useState)(false);
370
+ const isControlled = visible !== void 0 && setVisible !== void 0;
371
+ const isVisible = isControlled ? visible : internalVisible;
372
+ const open = () => {
373
+ if (isControlled) setVisible(true);
374
+ else setInternalVisible(true);
375
+ };
376
+ const close = () => {
377
+ if (isControlled) setVisible(false);
378
+ else setInternalVisible(false);
379
+ };
380
+ const handleSelect = (val) => {
381
+ const updated = toggleValue(selectedValues, val);
382
+ onChange(updated);
383
+ };
384
+ const getLabel = () => {
385
+ if (selectedValues.length === 0) return placeholder;
386
+ const all = groups.length ? groups.flatMap((g) => g.data) : options;
387
+ return all.filter((o) => selectedValues.includes(o.value)).map((o) => o.label).join(", ");
388
+ };
389
+ const renderList = () => {
390
+ if (groups.length > 0) {
391
+ return groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MultiPickerGroup, { label: group.label, children: group.data.map((item) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
392
+ MultiPickerItem,
393
+ {
394
+ label: item.label,
395
+ selected: selectedValues.includes(item.value),
396
+ onPress: () => handleSelect(item.value)
397
+ },
398
+ item.value
399
+ )) }, group.label));
400
+ }
401
+ return options.map((item) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
402
+ MultiPickerItem,
403
+ {
404
+ label: item.label,
405
+ selected: selectedValues.includes(item.value),
406
+ onPress: () => handleSelect(item.value)
407
+ },
408
+ item.value
409
+ ));
410
+ };
411
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
412
+ label && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: styles3.label, children: label }),
413
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.TouchableOpacity, { style: styles3.box, onPress: open, children: [
414
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: styles3.text, children: getLabel() }),
415
+ renderIcon ? renderIcon({
416
+ name: "chevron-down",
417
+ size: 18,
418
+ color: "#6B7280"
419
+ }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { children: "\u2304" })
420
+ ] }),
421
+ error && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: styles3.error, children: error }),
422
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Modal, { visible: isVisible, transparent: true, animationType: "slide", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.View, { style: styles3.overlay, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.View, { style: styles3.container, children: [
423
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.TouchableOpacity, { onPress: close, style: styles3.done, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: { color: "#fff" }, children: "Done" }) }),
424
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.ScrollView, { children: renderList() })
425
+ ] }) }) })
426
+ ] });
427
+ }
428
+ var styles3 = import_react_native4.StyleSheet.create({
429
+ label: {
430
+ marginBottom: 6,
431
+ fontSize: 14
432
+ },
433
+ box: {
434
+ borderWidth: 1,
435
+ borderColor: "#E5E7EB",
436
+ borderRadius: 12,
437
+ padding: 12,
438
+ flexDirection: "row",
439
+ justifyContent: "space-between"
440
+ },
441
+ text: {
442
+ fontSize: 15
443
+ },
444
+ error: {
445
+ color: "red",
446
+ marginTop: 4
447
+ },
448
+ overlay: {
449
+ flex: 1,
450
+ justifyContent: "flex-end",
451
+ backgroundColor: "rgba(0,0,0,0.3)"
452
+ },
453
+ container: {
454
+ backgroundColor: "#fff",
455
+ padding: 20,
456
+ borderTopLeftRadius: 20,
457
+ borderTopRightRadius: 20,
458
+ maxHeight: "70%"
459
+ },
460
+ done: {
461
+ backgroundColor: "#6366f1",
462
+ padding: 10,
463
+ borderRadius: 10,
464
+ alignSelf: "flex-end",
465
+ marginBottom: 10
466
+ }
467
+ });
468
+
260
469
  // src/utils/groupOptions.ts
261
470
  var groupOptions = (options, config) => {
262
471
  return Object.entries(config).map(([label, values]) => ({
@@ -266,6 +475,8 @@ var groupOptions = (options, config) => {
266
475
  };
267
476
  // Annotate the CommonJS export names for ESM import in node:
268
477
  0 && (module.exports = {
478
+ MultiPickerModal,
269
479
  PickerModal,
270
- groupOptions
480
+ groupOptions,
481
+ toggleValue
271
482
  });
package/dist/index.mjs CHANGED
@@ -15,7 +15,7 @@ function PickerModal({
15
15
  selectedValue,
16
16
  options,
17
17
  groups = [],
18
- styles,
18
+ styles: styles4,
19
19
  theme,
20
20
  renderTab,
21
21
  renderItem,
@@ -73,7 +73,7 @@ function PickerModal({
73
73
  style: [
74
74
  defaultStyles.container,
75
75
  { backgroundColor: bg },
76
- styles?.container
76
+ styles4?.container
77
77
  ],
78
78
  children: [
79
79
  /* @__PURE__ */ jsx(
@@ -82,10 +82,10 @@ function PickerModal({
82
82
  style: [
83
83
  defaultStyles.doneBtn,
84
84
  { backgroundColor: primary },
85
- styles?.doneBtn
85
+ styles4?.doneBtn
86
86
  ],
87
87
  onPress: handleClose,
88
- children: /* @__PURE__ */ jsx(Text, { style: [defaultStyles.doneText, styles?.doneText], children: "Done" })
88
+ children: /* @__PURE__ */ jsx(Text, { style: [defaultStyles.doneText, styles4?.doneText], children: "Done" })
89
89
  }
90
90
  ),
91
91
  hasGroups && /* @__PURE__ */ jsx(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, children: groups.map((tab, index) => {
@@ -98,7 +98,7 @@ function PickerModal({
98
98
  {
99
99
  style: [
100
100
  defaultStyles.tab,
101
- styles?.tab,
101
+ styles4?.tab,
102
102
  isActive && { backgroundColor: primary }
103
103
  ],
104
104
  onPress: () => setActiveTab(index),
@@ -108,7 +108,7 @@ function PickerModal({
108
108
  style: [
109
109
  defaultStyles.tabText,
110
110
  { color: isActive ? "#fff" : text },
111
- styles?.tabText
111
+ styles4?.tabText
112
112
  ],
113
113
  children: tab.label
114
114
  }
@@ -139,14 +139,14 @@ function PickerModal({
139
139
  }
140
140
  );
141
141
  return /* @__PURE__ */ jsxs(Fragment, { children: [
142
- /* @__PURE__ */ jsxs(View, { style: styles?.inputContainer, children: [
143
- label && /* @__PURE__ */ jsx(Text, { style: [defaultStyles.label, styles?.label, labelStyle], children: label }),
142
+ /* @__PURE__ */ jsxs(View, { style: styles4?.inputContainer, children: [
143
+ label && /* @__PURE__ */ jsx(Text, { style: [defaultStyles.label, styles4?.label, labelStyle], children: label }),
144
144
  /* @__PURE__ */ jsxs(
145
145
  TouchableOpacity,
146
146
  {
147
147
  style: [
148
148
  defaultStyles.selectBox,
149
- styles?.selectBox,
149
+ styles4?.selectBox,
150
150
  selectBoxStyle,
151
151
  error && { borderColor: "red" }
152
152
  ],
@@ -157,7 +157,7 @@ function PickerModal({
157
157
  {
158
158
  style: [
159
159
  defaultStyles.selectText,
160
- styles?.selectText,
160
+ styles4?.selectText,
161
161
  selectTextStyle
162
162
  ],
163
163
  children: getLabel() || placeholder
@@ -171,7 +171,7 @@ function PickerModal({
171
171
  ]
172
172
  }
173
173
  ),
174
- error && /* @__PURE__ */ jsx(Text, { style: [defaultStyles.error, styles?.error, errorStyle], children: error })
174
+ error && /* @__PURE__ */ jsx(Text, { style: [defaultStyles.error, styles4?.error, errorStyle], children: error })
175
175
  ] }),
176
176
  /* @__PURE__ */ jsx(Modal, { visible: isVisible, transparent: true, animationType: "slide", children: /* @__PURE__ */ jsx(View, { style: defaultStyles.modalOverlay, children: renderContainer ? renderContainer(content) : content }) })
177
177
  ] });
@@ -237,6 +237,220 @@ var defaultStyles = StyleSheet.create({
237
237
  }
238
238
  });
239
239
 
240
+ // src/core/MultiPickerModal.tsx
241
+ import { useState as useState3 } from "react";
242
+ import {
243
+ Modal as Modal2,
244
+ View as View4,
245
+ Text as Text4,
246
+ TouchableOpacity as TouchableOpacity4,
247
+ StyleSheet as StyleSheet4,
248
+ ScrollView as ScrollView2
249
+ } from "react-native";
250
+
251
+ // src/utils/toggleValue.ts
252
+ var toggleValue = (arr, value) => {
253
+ return arr.includes(value) ? arr.filter((v) => v !== value) : [...arr, value];
254
+ };
255
+
256
+ // src/components/MultiPickerGroup.tsx
257
+ import { useState as useState2 } from "react";
258
+ import { View as View2, Text as Text2, TouchableOpacity as TouchableOpacity2, StyleSheet as StyleSheet2 } from "react-native";
259
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
260
+ function MultiPickerGroup({
261
+ label,
262
+ children,
263
+ renderIcon
264
+ }) {
265
+ const [open, setOpen] = useState2(true);
266
+ return /* @__PURE__ */ jsxs2(View2, { style: styles.group, children: [
267
+ /* @__PURE__ */ jsxs2(TouchableOpacity2, { style: styles.header, onPress: () => setOpen(!open), children: [
268
+ /* @__PURE__ */ jsx2(Text2, { style: styles.title, children: label }),
269
+ renderIcon ? renderIcon({
270
+ name: open ? "chevron-up" : "chevron-down",
271
+ size: 18,
272
+ color: "#6B7280"
273
+ }) : /* @__PURE__ */ jsx2(Text2, { style: styles.fallback, children: open ? "\u2303" : "\u2304" })
274
+ ] }),
275
+ open && /* @__PURE__ */ jsx2(View2, { style: { marginTop: 6 }, children })
276
+ ] });
277
+ }
278
+ var styles = StyleSheet2.create({
279
+ group: {
280
+ marginBottom: 12
281
+ },
282
+ header: {
283
+ flexDirection: "row",
284
+ justifyContent: "space-between",
285
+ alignItems: "center"
286
+ },
287
+ title: {
288
+ fontWeight: "600",
289
+ fontSize: 14
290
+ },
291
+ fallback: {
292
+ fontSize: 16,
293
+ color: "#6B7280"
294
+ }
295
+ });
296
+
297
+ // src/components/MultiPickerItem.tsx
298
+ import { TouchableOpacity as TouchableOpacity3, View as View3, Text as Text3, StyleSheet as StyleSheet3 } from "react-native";
299
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
300
+ function MultiPickerItem({
301
+ label,
302
+ selected,
303
+ onPress
304
+ }) {
305
+ return /* @__PURE__ */ jsxs3(TouchableOpacity3, { style: styles2.item, onPress, children: [
306
+ /* @__PURE__ */ jsx3(Text3, { style: styles2.label, children: label }),
307
+ /* @__PURE__ */ jsx3(View3, { style: [styles2.circle, selected && styles2.active], children: selected && /* @__PURE__ */ jsx3(Text3, { style: styles2.check, children: "\u2713" }) })
308
+ ] });
309
+ }
310
+ var styles2 = StyleSheet3.create({
311
+ item: {
312
+ flexDirection: "row",
313
+ justifyContent: "space-between",
314
+ alignItems: "center",
315
+ paddingVertical: 12
316
+ },
317
+ label: {
318
+ fontSize: 15
319
+ },
320
+ circle: {
321
+ width: 22,
322
+ height: 22,
323
+ borderRadius: 999,
324
+ borderWidth: 2,
325
+ borderColor: "#ccc",
326
+ justifyContent: "center",
327
+ alignItems: "center"
328
+ },
329
+ active: {
330
+ backgroundColor: "#22c55e",
331
+ borderColor: "#22c55e"
332
+ },
333
+ check: {
334
+ color: "#fff",
335
+ fontSize: 12,
336
+ fontWeight: "bold"
337
+ }
338
+ });
339
+
340
+ // src/core/MultiPickerModal.tsx
341
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
342
+ function MultiPickerModal({
343
+ visible,
344
+ setVisible,
345
+ selectedValues,
346
+ options = [],
347
+ groups = [],
348
+ onChange,
349
+ label,
350
+ placeholder = "Select",
351
+ error,
352
+ renderIcon
353
+ }) {
354
+ const [internalVisible, setInternalVisible] = useState3(false);
355
+ const isControlled = visible !== void 0 && setVisible !== void 0;
356
+ const isVisible = isControlled ? visible : internalVisible;
357
+ const open = () => {
358
+ if (isControlled) setVisible(true);
359
+ else setInternalVisible(true);
360
+ };
361
+ const close = () => {
362
+ if (isControlled) setVisible(false);
363
+ else setInternalVisible(false);
364
+ };
365
+ const handleSelect = (val) => {
366
+ const updated = toggleValue(selectedValues, val);
367
+ onChange(updated);
368
+ };
369
+ const getLabel = () => {
370
+ if (selectedValues.length === 0) return placeholder;
371
+ const all = groups.length ? groups.flatMap((g) => g.data) : options;
372
+ return all.filter((o) => selectedValues.includes(o.value)).map((o) => o.label).join(", ");
373
+ };
374
+ const renderList = () => {
375
+ if (groups.length > 0) {
376
+ return groups.map((group) => /* @__PURE__ */ jsx4(MultiPickerGroup, { label: group.label, children: group.data.map((item) => /* @__PURE__ */ jsx4(
377
+ MultiPickerItem,
378
+ {
379
+ label: item.label,
380
+ selected: selectedValues.includes(item.value),
381
+ onPress: () => handleSelect(item.value)
382
+ },
383
+ item.value
384
+ )) }, group.label));
385
+ }
386
+ return options.map((item) => /* @__PURE__ */ jsx4(
387
+ MultiPickerItem,
388
+ {
389
+ label: item.label,
390
+ selected: selectedValues.includes(item.value),
391
+ onPress: () => handleSelect(item.value)
392
+ },
393
+ item.value
394
+ ));
395
+ };
396
+ return /* @__PURE__ */ jsxs4(Fragment2, { children: [
397
+ label && /* @__PURE__ */ jsx4(Text4, { style: styles3.label, children: label }),
398
+ /* @__PURE__ */ jsxs4(TouchableOpacity4, { style: styles3.box, onPress: open, children: [
399
+ /* @__PURE__ */ jsx4(Text4, { style: styles3.text, children: getLabel() }),
400
+ renderIcon ? renderIcon({
401
+ name: "chevron-down",
402
+ size: 18,
403
+ color: "#6B7280"
404
+ }) : /* @__PURE__ */ jsx4(Text4, { children: "\u2304" })
405
+ ] }),
406
+ error && /* @__PURE__ */ jsx4(Text4, { style: styles3.error, children: error }),
407
+ /* @__PURE__ */ jsx4(Modal2, { visible: isVisible, transparent: true, animationType: "slide", children: /* @__PURE__ */ jsx4(View4, { style: styles3.overlay, children: /* @__PURE__ */ jsxs4(View4, { style: styles3.container, children: [
408
+ /* @__PURE__ */ jsx4(TouchableOpacity4, { onPress: close, style: styles3.done, children: /* @__PURE__ */ jsx4(Text4, { style: { color: "#fff" }, children: "Done" }) }),
409
+ /* @__PURE__ */ jsx4(ScrollView2, { children: renderList() })
410
+ ] }) }) })
411
+ ] });
412
+ }
413
+ var styles3 = StyleSheet4.create({
414
+ label: {
415
+ marginBottom: 6,
416
+ fontSize: 14
417
+ },
418
+ box: {
419
+ borderWidth: 1,
420
+ borderColor: "#E5E7EB",
421
+ borderRadius: 12,
422
+ padding: 12,
423
+ flexDirection: "row",
424
+ justifyContent: "space-between"
425
+ },
426
+ text: {
427
+ fontSize: 15
428
+ },
429
+ error: {
430
+ color: "red",
431
+ marginTop: 4
432
+ },
433
+ overlay: {
434
+ flex: 1,
435
+ justifyContent: "flex-end",
436
+ backgroundColor: "rgba(0,0,0,0.3)"
437
+ },
438
+ container: {
439
+ backgroundColor: "#fff",
440
+ padding: 20,
441
+ borderTopLeftRadius: 20,
442
+ borderTopRightRadius: 20,
443
+ maxHeight: "70%"
444
+ },
445
+ done: {
446
+ backgroundColor: "#6366f1",
447
+ padding: 10,
448
+ borderRadius: 10,
449
+ alignSelf: "flex-end",
450
+ marginBottom: 10
451
+ }
452
+ });
453
+
240
454
  // src/utils/groupOptions.ts
241
455
  var groupOptions = (options, config) => {
242
456
  return Object.entries(config).map(([label, values]) => ({
@@ -245,6 +459,8 @@ var groupOptions = (options, config) => {
245
459
  })).filter((g) => g.data.length > 0);
246
460
  };
247
461
  export {
462
+ MultiPickerModal,
248
463
  PickerModal,
249
- groupOptions
464
+ groupOptions,
465
+ toggleValue
250
466
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaushverse/pickify",
3
- "version": "1.0.4",
3
+ "version": "1.0.7",
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",