@kaushverse/pickify 1.1.9 → 1.1.10

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
@@ -151,9 +151,6 @@ type Props = {
151
151
  styles?: FloatingButtonStyles;
152
152
  style?: ViewStyle;
153
153
  mainIconName?: string;
154
- spacing?: number;
155
- offsetX?: number;
156
- offsetY?: number;
157
154
  };
158
155
  declare class FloatingButton extends React$1.Component<Props> {
159
156
  animation: Animated.Value;
package/dist/index.d.ts CHANGED
@@ -151,9 +151,6 @@ type Props = {
151
151
  styles?: FloatingButtonStyles;
152
152
  style?: ViewStyle;
153
153
  mainIconName?: string;
154
- spacing?: number;
155
- offsetX?: number;
156
- offsetY?: number;
157
154
  };
158
155
  declare class FloatingButton extends React$1.Component<Props> {
159
156
  animation: Animated.Value;
package/dist/index.js CHANGED
@@ -293,39 +293,27 @@ function MultiPickerGroup({
293
293
  }) {
294
294
  const [open, setOpen] = (0, import_react2.useState)(false);
295
295
  const [contentHeight, setContentHeight] = (0, import_react2.useState)(0);
296
- const [isMounted, setIsMounted] = (0, import_react2.useState)(false);
296
+ const [isMeasured, setIsMeasured] = (0, import_react2.useState)(false);
297
297
  const animatedHeight = (0, import_react2.useRef)(new import_react_native2.Animated.Value(0)).current;
298
- const animationRef = (0, import_react2.useRef)(null);
299
298
  (0, import_react2.useEffect)(() => {
300
- setIsMounted(true);
301
- return () => {
302
- if (animationRef.current) {
303
- animationRef.current.stop();
304
- }
305
- };
306
- }, []);
307
- (0, import_react2.useEffect)(() => {
308
- if (defaultOpen && contentHeight > 0 && !open) {
299
+ if (defaultOpen && contentHeight > 0 && !isMeasured) {
300
+ setIsMeasured(true);
309
301
  animatedHeight.setValue(contentHeight);
310
302
  setOpen(true);
311
303
  }
312
- }, [defaultOpen, contentHeight]);
304
+ }, [contentHeight, defaultOpen, isMeasured]);
313
305
  const toggle = () => {
314
306
  if (contentHeight === 0) return;
315
- if (animationRef.current) {
316
- animationRef.current.stop();
317
- }
318
- const toValue = open ? 0 : contentHeight;
319
- animationRef.current = import_react_native2.Animated.timing(animatedHeight, {
307
+ const newOpenState = !open;
308
+ const toValue = newOpenState ? contentHeight : 0;
309
+ import_react_native2.Animated.timing(animatedHeight, {
320
310
  toValue,
321
- duration: 200,
311
+ duration: 250,
322
312
  useNativeDriver: false
313
+ }).start(() => {
314
+ setOpen(newOpenState);
323
315
  });
324
- animationRef.current.start(() => {
325
- setOpen(!open);
326
- animationRef.current = null;
327
- });
328
- setOpen(!open);
316
+ setOpen(newOpenState);
329
317
  };
330
318
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles.group, children: [
331
319
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
@@ -350,11 +338,9 @@ function MultiPickerGroup({
350
338
  style: styles.hidden,
351
339
  pointerEvents: "none",
352
340
  onLayout: (e) => {
353
- if (isMounted) {
354
- const height = e.nativeEvent.layout.height;
355
- if (height > 0 && height !== contentHeight) {
356
- setContentHeight(height);
357
- }
341
+ const height = e.nativeEvent.layout.height;
342
+ if (height > 0 && height !== contentHeight) {
343
+ setContentHeight(height);
358
344
  }
359
345
  },
360
346
  children
@@ -385,8 +371,8 @@ var styles = import_react_native2.StyleSheet.create({
385
371
  flexDirection: "row",
386
372
  justifyContent: "space-between",
387
373
  alignItems: "center",
388
- paddingVertical: 14,
389
- paddingHorizontal: 12,
374
+ paddingVertical: 12,
375
+ paddingHorizontal: 8,
390
376
  backgroundColor: "#F9FAFB",
391
377
  borderRadius: 8
392
378
  },
@@ -399,8 +385,8 @@ var styles = import_react_native2.StyleSheet.create({
399
385
  overflow: "hidden"
400
386
  },
401
387
  content: {
402
- paddingTop: 8,
403
- paddingHorizontal: 12,
388
+ marginTop: 6,
389
+ paddingHorizontal: 8,
404
390
  paddingBottom: 4
405
391
  },
406
392
  hidden: {
@@ -483,7 +469,6 @@ var defaultStyles2 = import_react_native3.StyleSheet.create({
483
469
 
484
470
  // src/core/MultiPickerModal.tsx
485
471
  var import_jsx_runtime4 = require("react/jsx-runtime");
486
- var { height: SCREEN_HEIGHT } = import_react_native4.Dimensions.get("window");
487
472
  function MultiPickerModal({
488
473
  visible,
489
474
  setVisible,
@@ -501,67 +486,36 @@ function MultiPickerModal({
501
486
  }) {
502
487
  const [internalVisible, setInternalVisible] = (0, import_react3.useState)(false);
503
488
  const [modalKey, setModalKey] = (0, import_react3.useState)(0);
504
- const slideAnim = (0, import_react3.useRef)(new import_react_native4.Animated.Value(SCREEN_HEIGHT)).current;
505
- const backdropAnim = (0, import_react3.useRef)(new import_react_native4.Animated.Value(0)).current;
506
- const isAnimating = (0, import_react3.useRef)(false);
489
+ const slideAnim = (0, import_react3.useRef)(new import_react_native4.Animated.Value(0)).current;
507
490
  const isControlled = visible !== void 0 && setVisible !== void 0;
508
491
  const isVisible = isControlled ? visible : internalVisible;
509
492
  (0, import_react3.useEffect)(() => {
510
493
  if (isVisible) {
511
494
  setModalKey((prev) => prev + 1);
512
- openModal();
495
+ import_react_native4.Animated.spring(slideAnim, {
496
+ toValue: 1,
497
+ useNativeDriver: true,
498
+ damping: 15,
499
+ mass: 0.8,
500
+ stiffness: 150
501
+ }).start();
513
502
  } else {
514
- closeModal();
515
- }
516
- }, [isVisible]);
517
- const openModal = () => {
518
- if (isAnimating.current) return;
519
- isAnimating.current = true;
520
- import_react_native4.Animated.parallel([
521
503
  import_react_native4.Animated.spring(slideAnim, {
522
504
  toValue: 0,
523
505
  useNativeDriver: true,
524
- damping: 20,
506
+ damping: 15,
525
507
  mass: 0.8,
526
- stiffness: 200
527
- }),
528
- import_react_native4.Animated.timing(backdropAnim, {
529
- toValue: 1,
530
- duration: 200,
531
- useNativeDriver: true
532
- })
533
- ]).start(() => {
534
- isAnimating.current = false;
535
- });
536
- };
537
- const closeModal = () => {
538
- if (isAnimating.current) return;
539
- isAnimating.current = true;
540
- import_react_native4.Animated.parallel([
541
- import_react_native4.Animated.timing(slideAnim, {
542
- toValue: SCREEN_HEIGHT,
543
- duration: 250,
544
- useNativeDriver: true
545
- }),
546
- import_react_native4.Animated.timing(backdropAnim, {
547
- toValue: 0,
548
- duration: 200,
549
- useNativeDriver: true
550
- })
551
- ]).start(() => {
552
- isAnimating.current = false;
553
- if (!isControlled) {
554
- setInternalVisible(false);
555
- }
556
- });
557
- };
508
+ stiffness: 150
509
+ }).start();
510
+ }
511
+ }, [isVisible]);
558
512
  const open = () => {
559
513
  if (isControlled) setVisible(true);
560
514
  else setInternalVisible(true);
561
515
  };
562
516
  const close = () => {
563
517
  if (isControlled) setVisible(false);
564
- else closeModal();
518
+ else setInternalVisible(false);
565
519
  };
566
520
  const handleSelect = (val) => {
567
521
  const updated = toggleValue(selectedValues, val);
@@ -572,14 +526,11 @@ function MultiPickerModal({
572
526
  const all = groups.length ? groups.flatMap((g) => g.data) : options;
573
527
  const selectedItems = all.filter((o) => selectedValues.includes(o.value)).map((o) => o.label);
574
528
  if (selectedItems.length === 0) return placeholder;
575
- if (selectedItems.length > 2) {
576
- return `${selectedItems.slice(0, 2).join(", ")} +${selectedItems.length - 2}`;
577
- }
578
529
  return selectedItems.join(", ");
579
530
  };
580
531
  const renderList = () => {
581
532
  if (groups.length > 0) {
582
- return groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
533
+ return groups.map((group, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
583
534
  MultiPickerGroup,
584
535
  {
585
536
  label: group.label,
@@ -612,14 +563,15 @@ function MultiPickerModal({
612
563
  item.value
613
564
  ));
614
565
  };
615
- const backdropStyle = {
616
- backgroundColor: backdropAnim.interpolate({
617
- inputRange: [0, 1],
618
- outputRange: ["rgba(0,0,0,0)", "rgba(0,0,0,0.5)"]
619
- })
620
- };
621
- const modalStyle = {
622
- transform: [{ translateY: slideAnim }]
566
+ const modalAnimatedStyle = {
567
+ transform: [
568
+ {
569
+ translateY: slideAnim.interpolate({
570
+ inputRange: [0, 1],
571
+ outputRange: [600, 0]
572
+ })
573
+ }
574
+ ]
623
575
  };
624
576
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
625
577
  label && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: [defaultStyles3.label, styles2?.label], children: label }),
@@ -644,7 +596,7 @@ function MultiPickerModal({
644
596
  ),
645
597
  renderInputIcon?.({
646
598
  name: "chevron-down",
647
- size: 20,
599
+ size: 18,
648
600
  color: "#6B7280"
649
601
  })
650
602
  ]
@@ -658,45 +610,35 @@ function MultiPickerModal({
658
610
  transparent: true,
659
611
  animationType: "none",
660
612
  onRequestClose: close,
661
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.Animated.View, { style: [defaultStyles3.overlay, backdropStyle], children: [
662
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
663
- import_react_native4.TouchableOpacity,
664
- {
665
- style: defaultStyles3.backdropTouchable,
666
- activeOpacity: 1,
667
- onPress: close
668
- }
669
- ),
670
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
671
- import_react_native4.Animated.View,
672
- {
673
- style: [defaultStyles3.container, styles2?.container, modalStyle],
674
- children: [
675
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.View, { style: defaultStyles3.header, children: [
676
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.View, { style: defaultStyles3.handle }),
677
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: defaultStyles3.headerTitle, children: "Select Options" }),
678
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
679
- import_react_native4.TouchableOpacity,
680
- {
681
- onPress: close,
682
- style: defaultStyles3.doneBtn,
683
- activeOpacity: 0.7,
684
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: defaultStyles3.doneText, children: "Done" })
685
- }
686
- )
687
- ] }),
688
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
689
- import_react_native4.ScrollView,
690
- {
691
- showsVerticalScrollIndicator: false,
692
- contentContainerStyle: defaultStyles3.scrollContent,
693
- children: renderList()
694
- }
695
- )
696
- ]
697
- }
698
- )
699
- ] })
613
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.View, { style: [defaultStyles3.overlay, styles2?.overlay], children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
614
+ import_react_native4.Animated.View,
615
+ {
616
+ style: [
617
+ defaultStyles3.container,
618
+ styles2?.container,
619
+ modalAnimatedStyle
620
+ ],
621
+ children: [
622
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
623
+ import_react_native4.TouchableOpacity,
624
+ {
625
+ onPress: close,
626
+ style: [defaultStyles3.done, styles2?.doneBtn],
627
+ activeOpacity: 0.7,
628
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: [defaultStyles3.doneText, styles2?.doneText], children: "Done" })
629
+ }
630
+ ),
631
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
632
+ import_react_native4.ScrollView,
633
+ {
634
+ showsVerticalScrollIndicator: false,
635
+ contentContainerStyle: defaultStyles3.scrollContent,
636
+ children: renderList()
637
+ }
638
+ )
639
+ ]
640
+ }
641
+ ) })
700
642
  }
701
643
  )
702
644
  ] });
@@ -733,71 +675,34 @@ var defaultStyles3 = import_react_native4.StyleSheet.create({
733
675
  },
734
676
  overlay: {
735
677
  flex: 1,
736
- justifyContent: "flex-end"
737
- },
738
- backdropTouchable: {
739
- position: "absolute",
740
- top: 0,
741
- left: 0,
742
- right: 0,
743
- bottom: 0
678
+ justifyContent: "flex-end",
679
+ backgroundColor: "rgba(0,0,0,0.4)"
744
680
  },
745
681
  container: {
746
- backgroundColor: "#FFFFFF",
682
+ backgroundColor: "#fff",
683
+ padding: 20,
747
684
  borderTopLeftRadius: 20,
748
685
  borderTopRightRadius: 20,
749
686
  maxHeight: "70%",
750
- minHeight: "40%",
751
- shadowColor: "#000",
752
- shadowOffset: {
753
- width: 0,
754
- height: -2
755
- },
756
- shadowOpacity: 0.1,
757
- shadowRadius: 4,
758
- elevation: 5
759
- },
760
- header: {
761
- flexDirection: "row",
762
- justifyContent: "space-between",
763
- alignItems: "center",
764
- paddingHorizontal: 20,
765
- paddingTop: 12,
766
- paddingBottom: 16,
767
- borderBottomWidth: 1,
768
- borderBottomColor: "#F0F0F0"
687
+ minHeight: "40%"
769
688
  },
770
- handle: {
771
- width: 40,
772
- height: 4,
773
- backgroundColor: "#E5E7EB",
774
- borderRadius: 2,
775
- position: "absolute",
776
- top: 8,
777
- alignSelf: "center"
778
- },
779
- headerTitle: {
780
- fontSize: 16,
781
- fontWeight: "600",
782
- color: "#1F2937",
783
- flex: 1,
784
- textAlign: "center"
689
+ scrollContent: {
690
+ paddingBottom: 20
785
691
  },
786
- doneBtn: {
787
- paddingVertical: 6,
788
- paddingHorizontal: 12,
692
+ done: {
789
693
  backgroundColor: "#6366f1",
790
- borderRadius: 8
694
+ paddingVertical: 10,
695
+ paddingHorizontal: 14,
696
+ borderRadius: 10,
697
+ alignSelf: "flex-end",
698
+ marginBottom: 16,
699
+ minWidth: 80,
700
+ alignItems: "center"
791
701
  },
792
702
  doneText: {
793
- color: "#FFFFFF",
703
+ color: "#fff",
794
704
  fontWeight: "600",
795
705
  fontSize: 14
796
- },
797
- scrollContent: {
798
- paddingHorizontal: 20,
799
- paddingTop: 12,
800
- paddingBottom: 24
801
706
  }
802
707
  });
803
708
 
@@ -805,7 +710,6 @@ var defaultStyles3 = import_react_native4.StyleSheet.create({
805
710
  var import_react4 = __toESM(require("react"));
806
711
  var import_react_native5 = require("react-native");
807
712
  var import_jsx_runtime5 = require("react/jsx-runtime");
808
- var { width: SCREEN_WIDTH, height: SCREEN_HEIGHT2 } = import_react_native5.Dimensions.get("window");
809
713
  var FloatingButton = class extends import_react4.default.Component {
810
714
  animation = new import_react_native5.Animated.Value(0);
811
715
  open = false;
@@ -813,8 +717,8 @@ var FloatingButton = class extends import_react4.default.Component {
813
717
  import_react_native5.Animated.spring(this.animation, {
814
718
  toValue: this.open ? 0 : 1,
815
719
  useNativeDriver: true,
816
- damping: 15,
817
- mass: 0.8,
720
+ damping: 12,
721
+ mass: 0.6,
818
722
  stiffness: 180
819
723
  }).start();
820
724
  this.open = !this.open;
@@ -825,28 +729,26 @@ var FloatingButton = class extends import_react4.default.Component {
825
729
  radius = 100,
826
730
  actions,
827
731
  renderItemIcon,
828
- styles: styles2,
829
- spacing = 75
830
- // Default spacing between buttons
732
+ styles: styles2
831
733
  } = this.props;
832
734
  let translateX = 0;
833
735
  let translateY = 0;
834
736
  if (mode === "vertical") {
835
- translateY = -spacing * (index + 1);
737
+ translateY = -70 * (index + 1);
836
738
  translateX = 0;
837
739
  }
838
740
  if (mode === "horizontal") {
839
- translateX = -spacing * (index + 1);
741
+ translateX = -70 * (index + 1);
840
742
  translateY = 0;
841
743
  }
842
744
  if (mode === "circle") {
843
745
  const totalActions = actions.length;
844
- const startAngle = Math.PI * 0.85;
845
- const endAngle = Math.PI * 0.15;
846
- const angle = startAngle - index / (totalActions - 1 || 1) * (startAngle - endAngle);
847
- const adjustedRadius = radius;
848
- translateX = -adjustedRadius * Math.cos(angle);
849
- translateY = -adjustedRadius * Math.sin(angle);
746
+ const startAngle = -Math.PI / 3;
747
+ const endAngle = -Math.PI * 0.8;
748
+ const angle = startAngle + index / (totalActions - 1 || 1) * (endAngle - startAngle);
749
+ const adjustedRadius = radius * 0.65;
750
+ translateX = adjustedRadius * Math.cos(angle);
751
+ translateY = adjustedRadius * Math.sin(angle);
850
752
  }
851
753
  const animStyle = {
852
754
  transform: [
@@ -900,15 +802,7 @@ var FloatingButton = class extends import_react4.default.Component {
900
802
  );
901
803
  };
902
804
  render() {
903
- const {
904
- renderMainIcon,
905
- styles: styles2,
906
- style,
907
- mainIconName,
908
- mode = "vertical",
909
- offsetX = 24,
910
- offsetY = 100
911
- } = this.props;
805
+ const { actions, renderMainIcon, styles: styles2, style, mainIconName } = this.props;
912
806
  const rotation = {
913
807
  transform: [
914
808
  {
@@ -930,26 +824,32 @@ var FloatingButton = class extends import_react4.default.Component {
930
824
  ]
931
825
  };
932
826
  const mainIcon = mainIconName || "add";
933
- const containerStyle = [
934
- defaultStyles4.container,
935
- styles2?.container,
936
- style,
937
- {
938
- bottom: offsetY,
939
- right: offsetX
940
- }
941
- ];
942
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native5.View, { style: containerStyle, children: [
943
- this.props.actions.map(this.renderAction),
944
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.TouchableWithoutFeedback, { onPress: this.toggleMenu, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
827
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native5.View, { style: [defaultStyles4.container, styles2?.container, style], children: [
828
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
945
829
  import_react_native5.Animated.View,
946
830
  {
947
831
  style: [
948
- defaultStyles4.mainButtonWrapper,
949
- styles2?.mainButton,
950
- rotation,
951
- scale
832
+ defaultStyles4.circleContainer,
833
+ styles2?.circleContainer,
834
+ {
835
+ transform: [
836
+ {
837
+ scale: this.animation.interpolate({
838
+ inputRange: [0, 1],
839
+ outputRange: [0, 1]
840
+ })
841
+ }
842
+ ],
843
+ opacity: this.animation
844
+ }
952
845
  ],
846
+ children: actions.map(this.renderAction)
847
+ }
848
+ ),
849
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.TouchableWithoutFeedback, { onPress: this.toggleMenu, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
850
+ import_react_native5.Animated.View,
851
+ {
852
+ style: [defaultStyles4.mainButtonWrapper, rotation, scale],
953
853
  children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.View, { style: [defaultStyles4.button, styles2?.mainButton], children: renderMainIcon?.({
954
854
  name: mainIcon,
955
855
  size: 26,
@@ -963,34 +863,44 @@ var FloatingButton = class extends import_react4.default.Component {
963
863
  var defaultStyles4 = import_react_native5.StyleSheet.create({
964
864
  container: {
965
865
  position: "absolute",
866
+ bottom: 100,
867
+ right: 20,
966
868
  alignItems: "center",
967
- justifyContent: "center",
968
- zIndex: 1e3
869
+ justifyContent: "center"
969
870
  },
970
871
  mainButtonWrapper: {
971
- width: 56,
972
- height: 56,
973
- borderRadius: 28,
872
+ width: 60,
873
+ height: 60,
874
+ borderRadius: 30,
974
875
  backgroundColor: "#F02A4B",
975
876
  alignItems: "center",
976
877
  justifyContent: "center",
977
878
  shadowColor: "#000",
978
879
  shadowOffset: {
979
880
  width: 0,
980
- height: 4
881
+ height: 2
981
882
  },
982
- shadowOpacity: 0.3,
983
- shadowRadius: 4.65,
984
- elevation: 8
883
+ shadowOpacity: 0.25,
884
+ shadowRadius: 3.84,
885
+ elevation: 5
985
886
  },
986
887
  button: {
987
- width: 56,
988
- height: 56,
989
- borderRadius: 28,
888
+ width: 60,
889
+ height: 60,
890
+ borderRadius: 30,
990
891
  backgroundColor: "#F02A4B",
991
892
  alignItems: "center",
992
893
  justifyContent: "center"
993
894
  },
895
+ circleContainer: {
896
+ position: "absolute",
897
+ width: 200,
898
+ height: 200,
899
+ right: -70,
900
+ bottom: -70,
901
+ alignItems: "center",
902
+ justifyContent: "center"
903
+ },
994
904
  secondary: {
995
905
  position: "absolute",
996
906
  width: 48,
package/dist/index.mjs CHANGED
@@ -246,8 +246,7 @@ import {
246
246
  TouchableOpacity as TouchableOpacity4,
247
247
  StyleSheet as StyleSheet4,
248
248
  ScrollView as ScrollView2,
249
- Animated as Animated2,
250
- Dimensions
249
+ Animated as Animated2
251
250
  } from "react-native";
252
251
 
253
252
  // src/utils/toggleValue.ts
@@ -273,39 +272,27 @@ function MultiPickerGroup({
273
272
  }) {
274
273
  const [open, setOpen] = useState2(false);
275
274
  const [contentHeight, setContentHeight] = useState2(0);
276
- const [isMounted, setIsMounted] = useState2(false);
275
+ const [isMeasured, setIsMeasured] = useState2(false);
277
276
  const animatedHeight = useRef(new Animated.Value(0)).current;
278
- const animationRef = useRef(null);
279
277
  useEffect2(() => {
280
- setIsMounted(true);
281
- return () => {
282
- if (animationRef.current) {
283
- animationRef.current.stop();
284
- }
285
- };
286
- }, []);
287
- useEffect2(() => {
288
- if (defaultOpen && contentHeight > 0 && !open) {
278
+ if (defaultOpen && contentHeight > 0 && !isMeasured) {
279
+ setIsMeasured(true);
289
280
  animatedHeight.setValue(contentHeight);
290
281
  setOpen(true);
291
282
  }
292
- }, [defaultOpen, contentHeight]);
283
+ }, [contentHeight, defaultOpen, isMeasured]);
293
284
  const toggle = () => {
294
285
  if (contentHeight === 0) return;
295
- if (animationRef.current) {
296
- animationRef.current.stop();
297
- }
298
- const toValue = open ? 0 : contentHeight;
299
- animationRef.current = Animated.timing(animatedHeight, {
286
+ const newOpenState = !open;
287
+ const toValue = newOpenState ? contentHeight : 0;
288
+ Animated.timing(animatedHeight, {
300
289
  toValue,
301
- duration: 200,
290
+ duration: 250,
302
291
  useNativeDriver: false
292
+ }).start(() => {
293
+ setOpen(newOpenState);
303
294
  });
304
- animationRef.current.start(() => {
305
- setOpen(!open);
306
- animationRef.current = null;
307
- });
308
- setOpen(!open);
295
+ setOpen(newOpenState);
309
296
  };
310
297
  return /* @__PURE__ */ jsxs2(View2, { style: styles.group, children: [
311
298
  /* @__PURE__ */ jsxs2(
@@ -330,11 +317,9 @@ function MultiPickerGroup({
330
317
  style: styles.hidden,
331
318
  pointerEvents: "none",
332
319
  onLayout: (e) => {
333
- if (isMounted) {
334
- const height = e.nativeEvent.layout.height;
335
- if (height > 0 && height !== contentHeight) {
336
- setContentHeight(height);
337
- }
320
+ const height = e.nativeEvent.layout.height;
321
+ if (height > 0 && height !== contentHeight) {
322
+ setContentHeight(height);
338
323
  }
339
324
  },
340
325
  children
@@ -365,8 +350,8 @@ var styles = StyleSheet2.create({
365
350
  flexDirection: "row",
366
351
  justifyContent: "space-between",
367
352
  alignItems: "center",
368
- paddingVertical: 14,
369
- paddingHorizontal: 12,
353
+ paddingVertical: 12,
354
+ paddingHorizontal: 8,
370
355
  backgroundColor: "#F9FAFB",
371
356
  borderRadius: 8
372
357
  },
@@ -379,8 +364,8 @@ var styles = StyleSheet2.create({
379
364
  overflow: "hidden"
380
365
  },
381
366
  content: {
382
- paddingTop: 8,
383
- paddingHorizontal: 12,
367
+ marginTop: 6,
368
+ paddingHorizontal: 8,
384
369
  paddingBottom: 4
385
370
  },
386
371
  hidden: {
@@ -463,7 +448,6 @@ var defaultStyles2 = StyleSheet3.create({
463
448
 
464
449
  // src/core/MultiPickerModal.tsx
465
450
  import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
466
- var { height: SCREEN_HEIGHT } = Dimensions.get("window");
467
451
  function MultiPickerModal({
468
452
  visible,
469
453
  setVisible,
@@ -481,67 +465,36 @@ function MultiPickerModal({
481
465
  }) {
482
466
  const [internalVisible, setInternalVisible] = useState3(false);
483
467
  const [modalKey, setModalKey] = useState3(0);
484
- const slideAnim = useRef2(new Animated2.Value(SCREEN_HEIGHT)).current;
485
- const backdropAnim = useRef2(new Animated2.Value(0)).current;
486
- const isAnimating = useRef2(false);
468
+ const slideAnim = useRef2(new Animated2.Value(0)).current;
487
469
  const isControlled = visible !== void 0 && setVisible !== void 0;
488
470
  const isVisible = isControlled ? visible : internalVisible;
489
471
  useEffect3(() => {
490
472
  if (isVisible) {
491
473
  setModalKey((prev) => prev + 1);
492
- openModal();
474
+ Animated2.spring(slideAnim, {
475
+ toValue: 1,
476
+ useNativeDriver: true,
477
+ damping: 15,
478
+ mass: 0.8,
479
+ stiffness: 150
480
+ }).start();
493
481
  } else {
494
- closeModal();
495
- }
496
- }, [isVisible]);
497
- const openModal = () => {
498
- if (isAnimating.current) return;
499
- isAnimating.current = true;
500
- Animated2.parallel([
501
482
  Animated2.spring(slideAnim, {
502
483
  toValue: 0,
503
484
  useNativeDriver: true,
504
- damping: 20,
485
+ damping: 15,
505
486
  mass: 0.8,
506
- stiffness: 200
507
- }),
508
- Animated2.timing(backdropAnim, {
509
- toValue: 1,
510
- duration: 200,
511
- useNativeDriver: true
512
- })
513
- ]).start(() => {
514
- isAnimating.current = false;
515
- });
516
- };
517
- const closeModal = () => {
518
- if (isAnimating.current) return;
519
- isAnimating.current = true;
520
- Animated2.parallel([
521
- Animated2.timing(slideAnim, {
522
- toValue: SCREEN_HEIGHT,
523
- duration: 250,
524
- useNativeDriver: true
525
- }),
526
- Animated2.timing(backdropAnim, {
527
- toValue: 0,
528
- duration: 200,
529
- useNativeDriver: true
530
- })
531
- ]).start(() => {
532
- isAnimating.current = false;
533
- if (!isControlled) {
534
- setInternalVisible(false);
535
- }
536
- });
537
- };
487
+ stiffness: 150
488
+ }).start();
489
+ }
490
+ }, [isVisible]);
538
491
  const open = () => {
539
492
  if (isControlled) setVisible(true);
540
493
  else setInternalVisible(true);
541
494
  };
542
495
  const close = () => {
543
496
  if (isControlled) setVisible(false);
544
- else closeModal();
497
+ else setInternalVisible(false);
545
498
  };
546
499
  const handleSelect = (val) => {
547
500
  const updated = toggleValue(selectedValues, val);
@@ -552,14 +505,11 @@ function MultiPickerModal({
552
505
  const all = groups.length ? groups.flatMap((g) => g.data) : options;
553
506
  const selectedItems = all.filter((o) => selectedValues.includes(o.value)).map((o) => o.label);
554
507
  if (selectedItems.length === 0) return placeholder;
555
- if (selectedItems.length > 2) {
556
- return `${selectedItems.slice(0, 2).join(", ")} +${selectedItems.length - 2}`;
557
- }
558
508
  return selectedItems.join(", ");
559
509
  };
560
510
  const renderList = () => {
561
511
  if (groups.length > 0) {
562
- return groups.map((group) => /* @__PURE__ */ jsx4(
512
+ return groups.map((group, index) => /* @__PURE__ */ jsx4(
563
513
  MultiPickerGroup,
564
514
  {
565
515
  label: group.label,
@@ -592,14 +542,15 @@ function MultiPickerModal({
592
542
  item.value
593
543
  ));
594
544
  };
595
- const backdropStyle = {
596
- backgroundColor: backdropAnim.interpolate({
597
- inputRange: [0, 1],
598
- outputRange: ["rgba(0,0,0,0)", "rgba(0,0,0,0.5)"]
599
- })
600
- };
601
- const modalStyle = {
602
- transform: [{ translateY: slideAnim }]
545
+ const modalAnimatedStyle = {
546
+ transform: [
547
+ {
548
+ translateY: slideAnim.interpolate({
549
+ inputRange: [0, 1],
550
+ outputRange: [600, 0]
551
+ })
552
+ }
553
+ ]
603
554
  };
604
555
  return /* @__PURE__ */ jsxs4(Fragment2, { children: [
605
556
  label && /* @__PURE__ */ jsx4(Text4, { style: [defaultStyles3.label, styles2?.label], children: label }),
@@ -624,7 +575,7 @@ function MultiPickerModal({
624
575
  ),
625
576
  renderInputIcon?.({
626
577
  name: "chevron-down",
627
- size: 20,
578
+ size: 18,
628
579
  color: "#6B7280"
629
580
  })
630
581
  ]
@@ -638,45 +589,35 @@ function MultiPickerModal({
638
589
  transparent: true,
639
590
  animationType: "none",
640
591
  onRequestClose: close,
641
- children: /* @__PURE__ */ jsxs4(Animated2.View, { style: [defaultStyles3.overlay, backdropStyle], children: [
642
- /* @__PURE__ */ jsx4(
643
- TouchableOpacity4,
644
- {
645
- style: defaultStyles3.backdropTouchable,
646
- activeOpacity: 1,
647
- onPress: close
648
- }
649
- ),
650
- /* @__PURE__ */ jsxs4(
651
- Animated2.View,
652
- {
653
- style: [defaultStyles3.container, styles2?.container, modalStyle],
654
- children: [
655
- /* @__PURE__ */ jsxs4(View4, { style: defaultStyles3.header, children: [
656
- /* @__PURE__ */ jsx4(View4, { style: defaultStyles3.handle }),
657
- /* @__PURE__ */ jsx4(Text4, { style: defaultStyles3.headerTitle, children: "Select Options" }),
658
- /* @__PURE__ */ jsx4(
659
- TouchableOpacity4,
660
- {
661
- onPress: close,
662
- style: defaultStyles3.doneBtn,
663
- activeOpacity: 0.7,
664
- children: /* @__PURE__ */ jsx4(Text4, { style: defaultStyles3.doneText, children: "Done" })
665
- }
666
- )
667
- ] }),
668
- /* @__PURE__ */ jsx4(
669
- ScrollView2,
670
- {
671
- showsVerticalScrollIndicator: false,
672
- contentContainerStyle: defaultStyles3.scrollContent,
673
- children: renderList()
674
- }
675
- )
676
- ]
677
- }
678
- )
679
- ] })
592
+ children: /* @__PURE__ */ jsx4(View4, { style: [defaultStyles3.overlay, styles2?.overlay], children: /* @__PURE__ */ jsxs4(
593
+ Animated2.View,
594
+ {
595
+ style: [
596
+ defaultStyles3.container,
597
+ styles2?.container,
598
+ modalAnimatedStyle
599
+ ],
600
+ children: [
601
+ /* @__PURE__ */ jsx4(
602
+ TouchableOpacity4,
603
+ {
604
+ onPress: close,
605
+ style: [defaultStyles3.done, styles2?.doneBtn],
606
+ activeOpacity: 0.7,
607
+ children: /* @__PURE__ */ jsx4(Text4, { style: [defaultStyles3.doneText, styles2?.doneText], children: "Done" })
608
+ }
609
+ ),
610
+ /* @__PURE__ */ jsx4(
611
+ ScrollView2,
612
+ {
613
+ showsVerticalScrollIndicator: false,
614
+ contentContainerStyle: defaultStyles3.scrollContent,
615
+ children: renderList()
616
+ }
617
+ )
618
+ ]
619
+ }
620
+ ) })
680
621
  }
681
622
  )
682
623
  ] });
@@ -713,71 +654,34 @@ var defaultStyles3 = StyleSheet4.create({
713
654
  },
714
655
  overlay: {
715
656
  flex: 1,
716
- justifyContent: "flex-end"
717
- },
718
- backdropTouchable: {
719
- position: "absolute",
720
- top: 0,
721
- left: 0,
722
- right: 0,
723
- bottom: 0
657
+ justifyContent: "flex-end",
658
+ backgroundColor: "rgba(0,0,0,0.4)"
724
659
  },
725
660
  container: {
726
- backgroundColor: "#FFFFFF",
661
+ backgroundColor: "#fff",
662
+ padding: 20,
727
663
  borderTopLeftRadius: 20,
728
664
  borderTopRightRadius: 20,
729
665
  maxHeight: "70%",
730
- minHeight: "40%",
731
- shadowColor: "#000",
732
- shadowOffset: {
733
- width: 0,
734
- height: -2
735
- },
736
- shadowOpacity: 0.1,
737
- shadowRadius: 4,
738
- elevation: 5
739
- },
740
- header: {
741
- flexDirection: "row",
742
- justifyContent: "space-between",
743
- alignItems: "center",
744
- paddingHorizontal: 20,
745
- paddingTop: 12,
746
- paddingBottom: 16,
747
- borderBottomWidth: 1,
748
- borderBottomColor: "#F0F0F0"
666
+ minHeight: "40%"
749
667
  },
750
- handle: {
751
- width: 40,
752
- height: 4,
753
- backgroundColor: "#E5E7EB",
754
- borderRadius: 2,
755
- position: "absolute",
756
- top: 8,
757
- alignSelf: "center"
758
- },
759
- headerTitle: {
760
- fontSize: 16,
761
- fontWeight: "600",
762
- color: "#1F2937",
763
- flex: 1,
764
- textAlign: "center"
668
+ scrollContent: {
669
+ paddingBottom: 20
765
670
  },
766
- doneBtn: {
767
- paddingVertical: 6,
768
- paddingHorizontal: 12,
671
+ done: {
769
672
  backgroundColor: "#6366f1",
770
- borderRadius: 8
673
+ paddingVertical: 10,
674
+ paddingHorizontal: 14,
675
+ borderRadius: 10,
676
+ alignSelf: "flex-end",
677
+ marginBottom: 16,
678
+ minWidth: 80,
679
+ alignItems: "center"
771
680
  },
772
681
  doneText: {
773
- color: "#FFFFFF",
682
+ color: "#fff",
774
683
  fontWeight: "600",
775
684
  fontSize: 14
776
- },
777
- scrollContent: {
778
- paddingHorizontal: 20,
779
- paddingTop: 12,
780
- paddingBottom: 24
781
685
  }
782
686
  });
783
687
 
@@ -787,11 +691,9 @@ import {
787
691
  Animated as Animated3,
788
692
  StyleSheet as StyleSheet5,
789
693
  TouchableWithoutFeedback,
790
- View as View5,
791
- Dimensions as Dimensions2
694
+ View as View5
792
695
  } from "react-native";
793
696
  import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
794
- var { width: SCREEN_WIDTH, height: SCREEN_HEIGHT2 } = Dimensions2.get("window");
795
697
  var FloatingButton = class extends React4.Component {
796
698
  animation = new Animated3.Value(0);
797
699
  open = false;
@@ -799,8 +701,8 @@ var FloatingButton = class extends React4.Component {
799
701
  Animated3.spring(this.animation, {
800
702
  toValue: this.open ? 0 : 1,
801
703
  useNativeDriver: true,
802
- damping: 15,
803
- mass: 0.8,
704
+ damping: 12,
705
+ mass: 0.6,
804
706
  stiffness: 180
805
707
  }).start();
806
708
  this.open = !this.open;
@@ -811,28 +713,26 @@ var FloatingButton = class extends React4.Component {
811
713
  radius = 100,
812
714
  actions,
813
715
  renderItemIcon,
814
- styles: styles2,
815
- spacing = 75
816
- // Default spacing between buttons
716
+ styles: styles2
817
717
  } = this.props;
818
718
  let translateX = 0;
819
719
  let translateY = 0;
820
720
  if (mode === "vertical") {
821
- translateY = -spacing * (index + 1);
721
+ translateY = -70 * (index + 1);
822
722
  translateX = 0;
823
723
  }
824
724
  if (mode === "horizontal") {
825
- translateX = -spacing * (index + 1);
725
+ translateX = -70 * (index + 1);
826
726
  translateY = 0;
827
727
  }
828
728
  if (mode === "circle") {
829
729
  const totalActions = actions.length;
830
- const startAngle = Math.PI * 0.85;
831
- const endAngle = Math.PI * 0.15;
832
- const angle = startAngle - index / (totalActions - 1 || 1) * (startAngle - endAngle);
833
- const adjustedRadius = radius;
834
- translateX = -adjustedRadius * Math.cos(angle);
835
- translateY = -adjustedRadius * Math.sin(angle);
730
+ const startAngle = -Math.PI / 3;
731
+ const endAngle = -Math.PI * 0.8;
732
+ const angle = startAngle + index / (totalActions - 1 || 1) * (endAngle - startAngle);
733
+ const adjustedRadius = radius * 0.65;
734
+ translateX = adjustedRadius * Math.cos(angle);
735
+ translateY = adjustedRadius * Math.sin(angle);
836
736
  }
837
737
  const animStyle = {
838
738
  transform: [
@@ -886,15 +786,7 @@ var FloatingButton = class extends React4.Component {
886
786
  );
887
787
  };
888
788
  render() {
889
- const {
890
- renderMainIcon,
891
- styles: styles2,
892
- style,
893
- mainIconName,
894
- mode = "vertical",
895
- offsetX = 24,
896
- offsetY = 100
897
- } = this.props;
789
+ const { actions, renderMainIcon, styles: styles2, style, mainIconName } = this.props;
898
790
  const rotation = {
899
791
  transform: [
900
792
  {
@@ -916,26 +808,32 @@ var FloatingButton = class extends React4.Component {
916
808
  ]
917
809
  };
918
810
  const mainIcon = mainIconName || "add";
919
- const containerStyle = [
920
- defaultStyles4.container,
921
- styles2?.container,
922
- style,
923
- {
924
- bottom: offsetY,
925
- right: offsetX
926
- }
927
- ];
928
- return /* @__PURE__ */ jsxs5(View5, { style: containerStyle, children: [
929
- this.props.actions.map(this.renderAction),
930
- /* @__PURE__ */ jsx5(TouchableWithoutFeedback, { onPress: this.toggleMenu, children: /* @__PURE__ */ jsx5(
811
+ return /* @__PURE__ */ jsxs5(View5, { style: [defaultStyles4.container, styles2?.container, style], children: [
812
+ /* @__PURE__ */ jsx5(
931
813
  Animated3.View,
932
814
  {
933
815
  style: [
934
- defaultStyles4.mainButtonWrapper,
935
- styles2?.mainButton,
936
- rotation,
937
- scale
816
+ defaultStyles4.circleContainer,
817
+ styles2?.circleContainer,
818
+ {
819
+ transform: [
820
+ {
821
+ scale: this.animation.interpolate({
822
+ inputRange: [0, 1],
823
+ outputRange: [0, 1]
824
+ })
825
+ }
826
+ ],
827
+ opacity: this.animation
828
+ }
938
829
  ],
830
+ children: actions.map(this.renderAction)
831
+ }
832
+ ),
833
+ /* @__PURE__ */ jsx5(TouchableWithoutFeedback, { onPress: this.toggleMenu, children: /* @__PURE__ */ jsx5(
834
+ Animated3.View,
835
+ {
836
+ style: [defaultStyles4.mainButtonWrapper, rotation, scale],
939
837
  children: /* @__PURE__ */ jsx5(View5, { style: [defaultStyles4.button, styles2?.mainButton], children: renderMainIcon?.({
940
838
  name: mainIcon,
941
839
  size: 26,
@@ -949,34 +847,44 @@ var FloatingButton = class extends React4.Component {
949
847
  var defaultStyles4 = StyleSheet5.create({
950
848
  container: {
951
849
  position: "absolute",
850
+ bottom: 100,
851
+ right: 20,
952
852
  alignItems: "center",
953
- justifyContent: "center",
954
- zIndex: 1e3
853
+ justifyContent: "center"
955
854
  },
956
855
  mainButtonWrapper: {
957
- width: 56,
958
- height: 56,
959
- borderRadius: 28,
856
+ width: 60,
857
+ height: 60,
858
+ borderRadius: 30,
960
859
  backgroundColor: "#F02A4B",
961
860
  alignItems: "center",
962
861
  justifyContent: "center",
963
862
  shadowColor: "#000",
964
863
  shadowOffset: {
965
864
  width: 0,
966
- height: 4
865
+ height: 2
967
866
  },
968
- shadowOpacity: 0.3,
969
- shadowRadius: 4.65,
970
- elevation: 8
867
+ shadowOpacity: 0.25,
868
+ shadowRadius: 3.84,
869
+ elevation: 5
971
870
  },
972
871
  button: {
973
- width: 56,
974
- height: 56,
975
- borderRadius: 28,
872
+ width: 60,
873
+ height: 60,
874
+ borderRadius: 30,
976
875
  backgroundColor: "#F02A4B",
977
876
  alignItems: "center",
978
877
  justifyContent: "center"
979
878
  },
879
+ circleContainer: {
880
+ position: "absolute",
881
+ width: 200,
882
+ height: 200,
883
+ right: -70,
884
+ bottom: -70,
885
+ alignItems: "center",
886
+ justifyContent: "center"
887
+ },
980
888
  secondary: {
981
889
  position: "absolute",
982
890
  width: 48,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaushverse/pickify",
3
- "version": "1.1.9",
3
+ "version": "1.1.10",
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",