@kaushverse/pickify 1.2.6 → 1.2.8

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.mjs CHANGED
@@ -15,7 +15,7 @@ function PickerModal({
15
15
  selectedValue,
16
16
  options,
17
17
  groups = [],
18
- styles: styles2,
18
+ styles: styles3,
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
- styles2?.container
76
+ styles3?.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
- styles2?.doneBtn
85
+ styles3?.doneBtn
86
86
  ],
87
87
  onPress: handleClose,
88
- children: /* @__PURE__ */ jsx(Text, { style: [defaultStyles.doneText, styles2?.doneText], children: "Done" })
88
+ children: /* @__PURE__ */ jsx(Text, { style: [defaultStyles.doneText, styles3?.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
- styles2?.tab,
101
+ styles3?.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
- styles2?.tabText
111
+ styles3?.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: styles2?.inputContainer, children: [
143
- label && /* @__PURE__ */ jsx(Text, { style: [defaultStyles.label, styles2?.label, labelStyle], children: label }),
142
+ /* @__PURE__ */ jsxs(View, { style: styles3?.inputContainer, children: [
143
+ label && /* @__PURE__ */ jsx(Text, { style: [defaultStyles.label, styles3?.label, labelStyle], children: label }),
144
144
  /* @__PURE__ */ jsxs(
145
145
  TouchableOpacity,
146
146
  {
147
147
  style: [
148
148
  defaultStyles.selectBox,
149
- styles2?.selectBox,
149
+ styles3?.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
- styles2?.selectText,
160
+ styles3?.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, styles2?.error, errorStyle], children: error })
174
+ error && /* @__PURE__ */ jsx(Text, { style: [defaultStyles.error, styles3?.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
  ] });
@@ -472,7 +472,7 @@ function MultiPickerModal({
472
472
  renderInputIcon,
473
473
  renderGroupIcon,
474
474
  renderItemIcon,
475
- styles: styles2
475
+ styles: styles3
476
476
  }) {
477
477
  const [internalVisible, setInternalVisible] = useState3(false);
478
478
  const [modalKey, setModalKey] = useState3(0);
@@ -533,7 +533,7 @@ function MultiPickerModal({
533
533
  selected: selectedValues.includes(item.value),
534
534
  onPress: () => handleSelect(item.value),
535
535
  renderItemIcon,
536
- styles: styles2?.item
536
+ styles: styles3?.item
537
537
  },
538
538
  item.value
539
539
  ))
@@ -548,7 +548,7 @@ function MultiPickerModal({
548
548
  selected: selectedValues.includes(item.value),
549
549
  onPress: () => handleSelect(item.value),
550
550
  renderItemIcon,
551
- styles: styles2?.item
551
+ styles: styles3?.item
552
552
  },
553
553
  item.value
554
554
  ));
@@ -564,11 +564,11 @@ function MultiPickerModal({
564
564
  ]
565
565
  };
566
566
  return /* @__PURE__ */ jsxs4(Fragment2, { children: [
567
- label && /* @__PURE__ */ jsx4(Text4, { style: [defaultStyles3.label, styles2?.label], children: label }),
567
+ label && /* @__PURE__ */ jsx4(Text4, { style: [defaultStyles3.label, styles3?.label], children: label }),
568
568
  /* @__PURE__ */ jsxs4(
569
569
  TouchableOpacity4,
570
570
  {
571
- style: [defaultStyles3.box, styles2?.selectBox],
571
+ style: [defaultStyles3.box, styles3?.selectBox],
572
572
  onPress: open,
573
573
  activeOpacity: 0.7,
574
574
  children: [
@@ -577,7 +577,7 @@ function MultiPickerModal({
577
577
  {
578
578
  style: [
579
579
  defaultStyles3.text,
580
- styles2?.selectText,
580
+ styles3?.selectText,
581
581
  !selectedValues?.length && defaultStyles3.placeholder
582
582
  ],
583
583
  numberOfLines: 1,
@@ -592,7 +592,7 @@ function MultiPickerModal({
592
592
  ]
593
593
  }
594
594
  ),
595
- error && /* @__PURE__ */ jsx4(Text4, { style: [defaultStyles3.error, styles2?.error], children: error }),
595
+ error && /* @__PURE__ */ jsx4(Text4, { style: [defaultStyles3.error, styles3?.error], children: error }),
596
596
  /* @__PURE__ */ jsx4(
597
597
  Modal2,
598
598
  {
@@ -600,12 +600,12 @@ function MultiPickerModal({
600
600
  transparent: true,
601
601
  animationType: "none",
602
602
  onRequestClose: close,
603
- children: /* @__PURE__ */ jsx4(View4, { style: [defaultStyles3.overlay, styles2?.overlay], children: /* @__PURE__ */ jsxs4(
603
+ children: /* @__PURE__ */ jsx4(View4, { style: [defaultStyles3.overlay, styles3?.overlay], children: /* @__PURE__ */ jsxs4(
604
604
  Animated2.View,
605
605
  {
606
606
  style: [
607
607
  defaultStyles3.container,
608
- styles2?.container,
608
+ styles3?.container,
609
609
  modalAnimatedStyle
610
610
  ],
611
611
  children: [
@@ -613,9 +613,9 @@ function MultiPickerModal({
613
613
  TouchableOpacity4,
614
614
  {
615
615
  onPress: close,
616
- style: [defaultStyles3.done, styles2?.doneBtn],
616
+ style: [defaultStyles3.done, styles3?.doneBtn],
617
617
  activeOpacity: 0.7,
618
- children: /* @__PURE__ */ jsx4(Text4, { style: [defaultStyles3.doneText, styles2?.doneText], children: "Done" })
618
+ children: /* @__PURE__ */ jsx4(Text4, { style: [defaultStyles3.doneText, styles3?.doneText], children: "Done" })
619
619
  }
620
620
  ),
621
621
  /* @__PURE__ */ jsx4(
@@ -697,7 +697,13 @@ var defaultStyles3 = StyleSheet4.create({
697
697
  });
698
698
 
699
699
  // src/core/FloatingButton.tsx
700
- import React4 from "react";
700
+ import {
701
+ forwardRef,
702
+ useImperativeHandle,
703
+ useRef as useRef3,
704
+ useState as useState4,
705
+ useEffect as useEffect4
706
+ } from "react";
701
707
  import {
702
708
  Animated as Animated3,
703
709
  StyleSheet as StyleSheet5,
@@ -705,104 +711,128 @@ import {
705
711
  View as View5
706
712
  } from "react-native";
707
713
  import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
708
- var FloatingButton = class extends React4.Component {
709
- animation = new Animated3.Value(0);
710
- open = false;
711
- toggleMenu = () => {
712
- Animated3.spring(this.animation, {
713
- toValue: this.open ? 0 : 1,
714
- useNativeDriver: true,
715
- damping: 12,
716
- mass: 0.6,
717
- stiffness: 180
718
- }).start();
719
- this.open = !this.open;
720
- };
721
- renderAction = (action, index) => {
714
+ var FloatingButton = forwardRef(
715
+ (props, ref) => {
722
716
  const {
717
+ actions,
723
718
  mode = "vertical",
724
719
  radius = 100,
725
- actions,
720
+ renderMainIcon,
726
721
  renderItemIcon,
727
- styles: styles2
728
- } = this.props;
729
- let translateX = 0;
730
- let translateY = 0;
731
- if (mode === "vertical") {
732
- translateY = -60 * (index + 1);
733
- translateX = 0;
734
- }
735
- if (mode === "horizontal") {
736
- translateX = -60 * (index + 1);
737
- translateY = 0;
738
- }
739
- if (mode === "circle") {
740
- const totalActions = actions.length;
741
- const startAngle = -Math.PI / 3;
742
- const endAngle = -Math.PI * 0.8;
743
- const angle = startAngle + index / (totalActions - 1 || 1) * (endAngle - startAngle);
744
- const baseRadius = radius * 0.65;
745
- const adjustedRadius = index === actions.length - 1 ? baseRadius * 0.8 : baseRadius;
746
- translateX = adjustedRadius * Math.cos(angle);
747
- translateY = adjustedRadius * Math.sin(angle);
748
- }
749
- const animStyle = {
750
- transform: [
751
- {
752
- translateX: this.animation.interpolate({
753
- inputRange: [0, 1],
754
- outputRange: [0, translateX]
755
- })
756
- },
757
- {
758
- translateY: this.animation.interpolate({
759
- inputRange: [0, 1],
760
- outputRange: [0, translateY]
761
- })
762
- },
763
- {
764
- scale: this.animation.interpolate({
765
- inputRange: [0, 0.5, 1],
766
- outputRange: [0, 1.2, 1]
767
- })
768
- }
769
- ],
770
- opacity: this.animation
722
+ styles: customStyles,
723
+ style,
724
+ mainIconName = "add",
725
+ open: controlledOpen,
726
+ onToggle,
727
+ animationConfig = {}
728
+ } = props;
729
+ const animation = useRef3(new Animated3.Value(0)).current;
730
+ const [internalOpen, setInternalOpen] = useState4(false);
731
+ const isOpen = controlledOpen !== void 0 ? controlledOpen : internalOpen;
732
+ useEffect4(() => {
733
+ Animated3.spring(animation, {
734
+ toValue: isOpen ? 1 : 0,
735
+ useNativeDriver: true,
736
+ damping: 12,
737
+ mass: 0.6,
738
+ stiffness: 180,
739
+ ...animationConfig
740
+ }).start();
741
+ }, [isOpen, animation, animationConfig]);
742
+ useImperativeHandle(ref, () => ({
743
+ openMenu: () => {
744
+ if (controlledOpen === void 0) setInternalOpen(true);
745
+ onToggle?.(true);
746
+ },
747
+ closeMenu: () => {
748
+ if (controlledOpen === void 0) setInternalOpen(false);
749
+ onToggle?.(false);
750
+ },
751
+ toggleMenu: () => {
752
+ const newState = !isOpen;
753
+ if (controlledOpen === void 0) setInternalOpen(newState);
754
+ onToggle?.(newState);
755
+ }
756
+ }));
757
+ const toggleMenu = () => {
758
+ const newState = !isOpen;
759
+ if (controlledOpen === void 0) setInternalOpen(newState);
760
+ onToggle?.(newState);
771
761
  };
772
- return /* @__PURE__ */ jsx5(
773
- TouchableWithoutFeedback,
774
- {
775
- onPress: () => {
776
- this.toggleMenu();
777
- action.onPress?.();
778
- action.navigateTo?.();
779
- },
780
- children: /* @__PURE__ */ jsx5(
781
- Animated3.View,
762
+ const renderAction = (action, index) => {
763
+ let translateX = 0;
764
+ let translateY = 0;
765
+ if (mode === "vertical") {
766
+ translateY = -60 * (index + 1);
767
+ translateX = 0;
768
+ } else if (mode === "horizontal") {
769
+ translateX = -60 * (index + 1);
770
+ translateY = 0;
771
+ } else if (mode === "circle") {
772
+ const totalActions = actions.length;
773
+ const startAngle = -Math.PI / 3;
774
+ const endAngle = -Math.PI * 0.8;
775
+ const angle = startAngle + index / (totalActions - 1 || 1) * (endAngle - startAngle);
776
+ const baseRadius = radius * 0.65;
777
+ const adjustedRadius = index === actions.length - 1 ? baseRadius * 0.8 : baseRadius;
778
+ translateX = adjustedRadius * Math.cos(angle);
779
+ translateY = adjustedRadius * Math.sin(angle);
780
+ }
781
+ const animStyle = {
782
+ transform: [
782
783
  {
783
- style: [
784
- defaultStyles4.secondary,
785
- styles2?.secondaryButton,
786
- { backgroundColor: action.color || "#F02A4B" },
787
- animStyle
788
- ],
789
- children: renderItemIcon?.({
790
- name: action.icon,
791
- size: 20,
792
- color: action.iconColor || "#FFF"
784
+ translateX: animation.interpolate({
785
+ inputRange: [0, 1],
786
+ outputRange: [0, translateX]
787
+ })
788
+ },
789
+ {
790
+ translateY: animation.interpolate({
791
+ inputRange: [0, 1],
792
+ outputRange: [0, translateY]
793
+ })
794
+ },
795
+ {
796
+ scale: animation.interpolate({
797
+ inputRange: [0, 0.5, 1],
798
+ outputRange: [0, 1.2, 1]
793
799
  })
794
800
  }
795
- )
796
- },
797
- index
798
- );
799
- };
800
- render() {
801
- const { actions, renderMainIcon, styles: styles2, style, mainIconName } = this.props;
801
+ ],
802
+ opacity: animation
803
+ };
804
+ return /* @__PURE__ */ jsx5(
805
+ TouchableWithoutFeedback,
806
+ {
807
+ onPress: () => {
808
+ toggleMenu();
809
+ action.onPress?.();
810
+ action.navigateTo?.();
811
+ },
812
+ children: /* @__PURE__ */ jsx5(
813
+ Animated3.View,
814
+ {
815
+ style: [
816
+ defaultStyles4.secondary,
817
+ customStyles?.secondaryButton,
818
+ { backgroundColor: action.color || "#F02A4B" },
819
+ animStyle
820
+ ],
821
+ children: renderItemIcon?.({
822
+ name: action.icon,
823
+ size: 20,
824
+ color: action.iconColor || "#FFF"
825
+ })
826
+ }
827
+ )
828
+ },
829
+ index
830
+ );
831
+ };
802
832
  const rotation = {
803
833
  transform: [
804
834
  {
805
- rotate: this.animation.interpolate({
835
+ rotate: animation.interpolate({
806
836
  inputRange: [0, 1],
807
837
  outputRange: ["0deg", "45deg"]
808
838
  })
@@ -812,42 +842,41 @@ var FloatingButton = class extends React4.Component {
812
842
  const scale = {
813
843
  transform: [
814
844
  {
815
- scale: this.animation.interpolate({
845
+ scale: animation.interpolate({
816
846
  inputRange: [0, 0.5, 1],
817
847
  outputRange: [1, 1.1, 1]
818
848
  })
819
849
  }
820
850
  ]
821
851
  };
822
- const mainIcon = mainIconName || "add";
823
- return /* @__PURE__ */ jsxs5(View5, { style: [defaultStyles4.container, styles2?.container, style], children: [
852
+ return /* @__PURE__ */ jsxs5(View5, { style: [defaultStyles4.container, customStyles?.container, style], children: [
824
853
  /* @__PURE__ */ jsx5(
825
854
  Animated3.View,
826
855
  {
827
856
  style: [
828
857
  defaultStyles4.circleContainer,
829
- styles2?.circleContainer,
858
+ customStyles?.circleContainer,
830
859
  {
831
860
  transform: [
832
861
  {
833
- scale: this.animation.interpolate({
862
+ scale: animation.interpolate({
834
863
  inputRange: [0, 1],
835
864
  outputRange: [0, 1]
836
865
  })
837
866
  }
838
867
  ],
839
- opacity: this.animation
868
+ opacity: animation
840
869
  }
841
870
  ],
842
- children: actions.map(this.renderAction)
871
+ children: actions.map(renderAction)
843
872
  }
844
873
  ),
845
- /* @__PURE__ */ jsx5(TouchableWithoutFeedback, { onPress: this.toggleMenu, children: /* @__PURE__ */ jsx5(
874
+ /* @__PURE__ */ jsx5(TouchableWithoutFeedback, { onPress: toggleMenu, children: /* @__PURE__ */ jsx5(
846
875
  Animated3.View,
847
876
  {
848
877
  style: [defaultStyles4.mainButtonWrapper, rotation, scale],
849
- children: /* @__PURE__ */ jsx5(View5, { style: [defaultStyles4.button, styles2?.mainButton], children: renderMainIcon?.({
850
- name: mainIcon,
878
+ children: /* @__PURE__ */ jsx5(View5, { style: [defaultStyles4.button, customStyles?.mainButton], children: renderMainIcon?.({
879
+ name: mainIconName,
851
880
  size: 26,
852
881
  color: "#FFF"
853
882
  }) })
@@ -855,7 +884,7 @@ var FloatingButton = class extends React4.Component {
855
884
  ) })
856
885
  ] });
857
886
  }
858
- };
887
+ );
859
888
  var defaultStyles4 = StyleSheet5.create({
860
889
  container: {
861
890
  position: "absolute",
@@ -872,10 +901,7 @@ var defaultStyles4 = StyleSheet5.create({
872
901
  alignItems: "center",
873
902
  justifyContent: "center",
874
903
  shadowColor: "#000",
875
- shadowOffset: {
876
- width: 0,
877
- height: 2
878
- },
904
+ shadowOffset: { width: 0, height: 2 },
879
905
  shadowOpacity: 0.25,
880
906
  shadowRadius: 3.84,
881
907
  elevation: 5
@@ -906,15 +932,134 @@ var defaultStyles4 = StyleSheet5.create({
906
932
  alignItems: "center",
907
933
  justifyContent: "center",
908
934
  shadowColor: "#000",
909
- shadowOffset: {
910
- width: 0,
911
- height: 2
912
- },
935
+ shadowOffset: { width: 0, height: 2 },
913
936
  shadowOpacity: 0.25,
914
937
  shadowRadius: 3.84,
915
938
  elevation: 5
916
939
  }
917
940
  });
941
+ var FloatingButton_default = FloatingButton;
942
+
943
+ // src/core/AnimatedSearchBar.tsx
944
+ import { useEffect as useEffect5, useRef as useRef4, useState as useState5 } from "react";
945
+ import {
946
+ View as View6,
947
+ TextInput,
948
+ Animated as Animated4,
949
+ StyleSheet as StyleSheet6
950
+ } from "react-native";
951
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
952
+ function AnimatedSearchBar({
953
+ data,
954
+ onSearch,
955
+ renderLeftIcon,
956
+ renderRightIcons
957
+ }) {
958
+ const [index, setIndex] = useState5(0);
959
+ const translateY = useRef4(new Animated4.Value(20)).current;
960
+ const opacity = useRef4(new Animated4.Value(0)).current;
961
+ const animate = () => {
962
+ translateY.setValue(20);
963
+ opacity.setValue(0);
964
+ Animated4.sequence([
965
+ Animated4.parallel([
966
+ Animated4.timing(translateY, {
967
+ toValue: 0,
968
+ duration: 400,
969
+ useNativeDriver: true
970
+ }),
971
+ Animated4.timing(opacity, {
972
+ toValue: 1,
973
+ duration: 400,
974
+ useNativeDriver: true
975
+ })
976
+ ]),
977
+ Animated4.delay(1200),
978
+ Animated4.parallel([
979
+ Animated4.timing(translateY, {
980
+ toValue: -20,
981
+ duration: 400,
982
+ useNativeDriver: true
983
+ }),
984
+ Animated4.timing(opacity, {
985
+ toValue: 0,
986
+ duration: 400,
987
+ useNativeDriver: true
988
+ })
989
+ ])
990
+ ]).start(() => {
991
+ setIndex((prev) => (prev + 1) % data.length);
992
+ });
993
+ };
994
+ useEffect5(() => {
995
+ if (data.length) animate();
996
+ }, [index]);
997
+ const current = data[index];
998
+ return /* @__PURE__ */ jsxs6(View6, { style: styles2.container, children: [
999
+ /* @__PURE__ */ jsx6(View6, { style: styles2.left, children: renderLeftIcon() }),
1000
+ /* @__PURE__ */ jsxs6(View6, { style: styles2.inputContainer, children: [
1001
+ /* @__PURE__ */ jsx6(
1002
+ TextInput,
1003
+ {
1004
+ style: styles2.input,
1005
+ placeholder: "",
1006
+ onChangeText: onSearch
1007
+ }
1008
+ ),
1009
+ /* @__PURE__ */ jsxs6(
1010
+ Animated4.Text,
1011
+ {
1012
+ style: [
1013
+ styles2.placeholder,
1014
+ {
1015
+ transform: [{ translateY }],
1016
+ opacity
1017
+ }
1018
+ ],
1019
+ children: [
1020
+ "Search for",
1021
+ " ",
1022
+ /* @__PURE__ */ jsx6(Animated4.Text, { style: { color: current?.color || "#999" }, children: current?.text })
1023
+ ]
1024
+ }
1025
+ )
1026
+ ] }),
1027
+ /* @__PURE__ */ jsx6(View6, { style: styles2.right, children: renderRightIcons?.() })
1028
+ ] });
1029
+ }
1030
+ var styles2 = StyleSheet6.create({
1031
+ container: {
1032
+ flexDirection: "row",
1033
+ alignItems: "center",
1034
+ backgroundColor: "#111",
1035
+ borderRadius: 12,
1036
+ paddingHorizontal: 10,
1037
+ height: 50
1038
+ },
1039
+ left: {
1040
+ paddingRight: 8,
1041
+ borderRightWidth: 1,
1042
+ borderColor: "#333"
1043
+ },
1044
+ inputContainer: {
1045
+ flex: 1,
1046
+ justifyContent: "center",
1047
+ paddingHorizontal: 10
1048
+ },
1049
+ input: {
1050
+ color: "#fff",
1051
+ height: "100%"
1052
+ },
1053
+ placeholder: {
1054
+ position: "absolute",
1055
+ color: "#888",
1056
+ fontSize: 14
1057
+ },
1058
+ right: {
1059
+ flexDirection: "row",
1060
+ gap: 10
1061
+ }
1062
+ });
918
1063
 
919
1064
  // src/utils/groupOptions.ts
920
1065
  var groupOptions = (options, config) => {
@@ -924,7 +1069,8 @@ var groupOptions = (options, config) => {
924
1069
  })).filter((g) => g.data.length > 0);
925
1070
  };
926
1071
  export {
927
- FloatingButton,
1072
+ AnimatedSearchBar,
1073
+ FloatingButton_default as FloatingButton,
928
1074
  MultiPickerGroup,
929
1075
  MultiPickerItem,
930
1076
  MultiPickerModal,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaushverse/pickify",
3
- "version": "1.2.6",
3
+ "version": "1.2.8",
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",