@korsolutions/ui 0.0.19 → 0.0.21

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.
Files changed (53) hide show
  1. package/dist/components/index.d.mts +73 -4
  2. package/dist/components/index.mjs +156 -8
  3. package/dist/hooks/index.d.mts +32 -2
  4. package/dist/hooks/index.mjs +79 -2
  5. package/dist/{index-BLsiF42Z.d.mts → index-pCM7YTs1.d.mts} +165 -9
  6. package/dist/index.d.mts +3 -3
  7. package/dist/index.mjs +3 -2
  8. package/dist/primitives/index.d.mts +3 -2
  9. package/dist/primitives/index.mjs +3 -2
  10. package/dist/{primitives-CyDqzNcp.mjs → primitives-DNeYBN-3.mjs} +330 -12
  11. package/dist/{toast-manager-BOORCQn8.mjs → toast-manager-BfoJ-_dB.mjs} +1 -1
  12. package/dist/use-numeric-mask-B9WZG25o.d.mts +33 -0
  13. package/dist/use-numeric-mask-BQlz1Pus.mjs +113 -0
  14. package/dist/use-relative-position-BTKEyT1F.mjs +106 -0
  15. package/dist/use-relative-position-DBzhrBU7.d.mts +61 -0
  16. package/package.json +1 -1
  17. package/src/components/button/button.tsx +7 -4
  18. package/src/components/dropdown-menu/dropdown-menu.tsx +49 -0
  19. package/src/components/dropdown-menu/variants/default.tsx +40 -0
  20. package/src/components/dropdown-menu/variants/index.ts +5 -0
  21. package/src/components/index.ts +3 -1
  22. package/src/components/input/index.ts +2 -0
  23. package/src/components/input/numeric-input.tsx +73 -0
  24. package/src/components/popover/popover.tsx +51 -0
  25. package/src/components/popover/variants/default.tsx +26 -0
  26. package/src/components/popover/variants/index.ts +5 -0
  27. package/src/hooks/index.ts +4 -1
  28. package/src/hooks/use-currency-mask.ts +141 -0
  29. package/src/hooks/use-numeric-mask.ts +202 -0
  30. package/src/hooks/use-relative-position.ts +188 -0
  31. package/src/primitives/button/button-root.tsx +2 -4
  32. package/src/primitives/dropdown-menu/context.ts +25 -0
  33. package/src/primitives/dropdown-menu/dropdown-menu-button.tsx +47 -0
  34. package/src/primitives/dropdown-menu/dropdown-menu-content.tsx +39 -0
  35. package/src/primitives/dropdown-menu/dropdown-menu-divider.tsx +18 -0
  36. package/src/primitives/dropdown-menu/dropdown-menu-overlay.tsx +29 -0
  37. package/src/primitives/dropdown-menu/dropdown-menu-portal.tsx +21 -0
  38. package/src/primitives/dropdown-menu/dropdown-menu-root.tsx +35 -0
  39. package/src/primitives/dropdown-menu/dropdown-menu-trigger.tsx +47 -0
  40. package/src/primitives/dropdown-menu/index.ts +26 -0
  41. package/src/primitives/dropdown-menu/types.ts +13 -0
  42. package/src/primitives/index.ts +2 -0
  43. package/src/primitives/popover/context.ts +25 -0
  44. package/src/primitives/popover/index.ts +24 -0
  45. package/src/primitives/popover/popover-close.tsx +29 -0
  46. package/src/primitives/popover/popover-content.tsx +39 -0
  47. package/src/primitives/popover/popover-overlay.tsx +37 -0
  48. package/src/primitives/popover/popover-portal.tsx +21 -0
  49. package/src/primitives/popover/popover-root.tsx +35 -0
  50. package/src/primitives/popover/popover-trigger.tsx +47 -0
  51. package/src/primitives/popover/types.ts +7 -0
  52. package/src/utils/get-ref-layout.ts +16 -0
  53. /package/src/hooks/{useScreenSize.ts → use-screen-size.ts} +0 -0
@@ -1,2 +1,3 @@
1
- import { $ as FieldStyles, A as CardTitleProps, B as SelectValueProps, C as EmptyMediaProps, D as CardStyles, E as CardRootProps, F as SelectRootProps, G as ButtonStyles, H as ButtonPrimitive, I as SelectStyles, J as InputPrimitiveBaseProps, K as ButtonPrimitiveLabelProps, L as SelectOptionProps, M as SelectPrimitive, N as SelectPortalProps, O as CardFooterProps, P as SelectRootBaseProps, Q as FieldPrimitiveRootProps, R as SelectContentProps, S as EmptyTitleProps, T as CardPrimitive, U as ButtonPrimitiveRootProps, V as SelectTriggerProps, W as ButtonState, X as InputStyles, Y as InputPrimitiveProps, Z as FieldPrimitive, _ as AvatarImageProps, a as BadgePrimitive, b as EmptyRootProps, c as BadgeLabelProps, d as ToastStyles, et as FieldErrorProps, f as ToastDescriptionProps, g as AvatarStyles, h as AvatarRootProps, i as TextareaStyles, j as CardHeaderProps, k as CardBodyProps, l as ToastPrimitive, m as AvatarPrimitive, n as TextareaPrimitiveBaseProps, nt as FieldLabelProps, o as BadgeRootProps, p as ToastTitleProps, q as InputPrimitive, r as TextareaPrimitiveProps, s as BadgeStyles, t as TextareaPrimitive, tt as FieldDescriptionProps, u as ToastRootProps, v as AvatarFallbackProps, w as EmptyDescriptionProps, x as EmptyStyles, y as EmptyPrimitive, z as SelectOverlayProps } from "../index-BLsiF42Z.mjs";
2
- export { AvatarFallbackProps, AvatarImageProps, AvatarPrimitive, AvatarRootProps, AvatarStyles, BadgeLabelProps, BadgePrimitive, BadgeRootProps, BadgeStyles, ButtonPrimitive, ButtonPrimitiveLabelProps, ButtonPrimitiveRootProps, ButtonState, ButtonStyles, CardBodyProps, CardFooterProps, CardHeaderProps, CardPrimitive, CardRootProps, CardStyles, CardTitleProps, EmptyDescriptionProps, EmptyMediaProps, EmptyPrimitive, EmptyRootProps, EmptyStyles, EmptyTitleProps, FieldDescriptionProps, FieldErrorProps, FieldLabelProps, FieldPrimitive, FieldPrimitiveRootProps, FieldStyles, InputPrimitive, InputPrimitiveBaseProps, InputPrimitiveProps, InputStyles, SelectContentProps, SelectOptionProps, SelectOverlayProps, SelectPortalProps, SelectPrimitive, SelectRootBaseProps, SelectRootProps, SelectStyles, SelectTriggerProps, SelectValueProps, TextareaPrimitive, TextareaPrimitiveBaseProps, TextareaPrimitiveProps, TextareaStyles, ToastDescriptionProps, ToastPrimitive, ToastRootProps, ToastStyles, ToastTitleProps };
1
+ import { $ as SelectPortalProps, A as ToastRootProps, B as EmptyRootProps, C as TextareaPrimitiveProps, D as BadgeStyles, E as BadgeRootProps, F as AvatarRootProps, G as CardPrimitive, H as EmptyTitleProps, I as AvatarStyles, J as CardFooterProps, K as CardRootProps, L as AvatarImageProps, M as ToastDescriptionProps, N as ToastTitleProps, O as BadgeLabelProps, P as AvatarPrimitive, Q as SelectPrimitive, R as AvatarFallbackProps, S as TextareaPrimitiveBaseProps, St as FieldLabelProps, T as BadgePrimitive, U as EmptyMediaProps, V as EmptyStyles, W as EmptyDescriptionProps, X as CardTitleProps, Y as CardBodyProps, Z as CardHeaderProps, _ as DropdownMenuDividerProps, _t as FieldPrimitive, a as PopoverPortalProps, at as SelectOverlayProps, b as DropdownMenuTriggerProps, bt as FieldErrorProps, c as PopoverOverlayProps, ct as ButtonPrimitive, d as PopoverTriggerRef, dt as ButtonStyles, et as SelectRootBaseProps, f as DropdownMenuPrimitive, ft as ButtonPrimitiveLabelProps, g as DropdownMenuOverlayProps, gt as InputStyles, h as DropdownMenuStyles, ht as InputPrimitiveProps, i as PopoverCloseProps, it as SelectContentProps, j as ToastStyles, k as ToastPrimitive, l as PopoverContentProps, lt as ButtonPrimitiveRootProps, m as DropdownMenuRootProps, mt as InputPrimitiveBaseProps, n as PopoverContext, nt as SelectStyles, o as PopoverRootProps, ot as SelectValueProps, p as DropdownMenuPortalProps, pt as InputPrimitive, q as CardStyles, r as usePopover, rt as SelectOptionProps, st as SelectTriggerProps, t as PopoverPrimitive, tt as SelectRootProps, u as PopoverTriggerProps, ut as ButtonState, v as DropdownMenuButtonProps, vt as FieldPrimitiveRootProps, w as TextareaStyles, x as TextareaPrimitive, xt as FieldDescriptionProps, y as DropdownMenuContentProps, yt as FieldStyles, z as EmptyPrimitive } from "../index-pCM7YTs1.mjs";
2
+ import "../use-relative-position-DBzhrBU7.mjs";
3
+ export { AvatarFallbackProps, AvatarImageProps, AvatarPrimitive, AvatarRootProps, AvatarStyles, BadgeLabelProps, BadgePrimitive, BadgeRootProps, BadgeStyles, ButtonPrimitive, ButtonPrimitiveLabelProps, ButtonPrimitiveRootProps, ButtonState, ButtonStyles, CardBodyProps, CardFooterProps, CardHeaderProps, CardPrimitive, CardRootProps, CardStyles, CardTitleProps, DropdownMenuButtonProps, DropdownMenuContentProps, DropdownMenuDividerProps, DropdownMenuOverlayProps, DropdownMenuPortalProps, DropdownMenuPrimitive, DropdownMenuRootProps, DropdownMenuStyles, DropdownMenuTriggerProps, EmptyDescriptionProps, EmptyMediaProps, EmptyPrimitive, EmptyRootProps, EmptyStyles, EmptyTitleProps, FieldDescriptionProps, FieldErrorProps, FieldLabelProps, FieldPrimitive, FieldPrimitiveRootProps, FieldStyles, InputPrimitive, InputPrimitiveBaseProps, InputPrimitiveProps, InputStyles, PopoverCloseProps, PopoverContentProps, PopoverContext, PopoverOverlayProps, PopoverPortalProps, PopoverPrimitive, PopoverRootProps, PopoverTriggerProps, PopoverTriggerRef, SelectContentProps, SelectOptionProps, SelectOverlayProps, SelectPortalProps, SelectPrimitive, SelectRootBaseProps, SelectRootProps, SelectStyles, SelectTriggerProps, SelectValueProps, TextareaPrimitive, TextareaPrimitiveBaseProps, TextareaPrimitiveProps, TextareaStyles, ToastDescriptionProps, ToastPrimitive, ToastRootProps, ToastStyles, ToastTitleProps, usePopover };
@@ -1,3 +1,4 @@
1
- import { a as EmptyPrimitive, c as ButtonPrimitive, i as AvatarPrimitive, l as InputPrimitive, n as BadgePrimitive, o as CardPrimitive, r as ToastPrimitive, s as SelectPrimitive, t as TextareaPrimitive, u as FieldPrimitive } from "../primitives-CyDqzNcp.mjs";
1
+ import { a as BadgePrimitive, c as EmptyPrimitive, d as ButtonPrimitive, f as InputPrimitive, i as TextareaPrimitive, l as CardPrimitive, n as usePopover, o as ToastPrimitive, p as FieldPrimitive, r as DropdownMenuPrimitive, s as AvatarPrimitive, t as PopoverPrimitive, u as SelectPrimitive } from "../primitives-DNeYBN-3.mjs";
2
+ import "../use-relative-position-BTKEyT1F.mjs";
2
3
 
3
- export { AvatarPrimitive, BadgePrimitive, ButtonPrimitive, CardPrimitive, EmptyPrimitive, FieldPrimitive, InputPrimitive, SelectPrimitive, TextareaPrimitive, ToastPrimitive };
4
+ export { AvatarPrimitive, BadgePrimitive, ButtonPrimitive, CardPrimitive, DropdownMenuPrimitive, EmptyPrimitive, FieldPrimitive, InputPrimitive, PopoverPrimitive, SelectPrimitive, TextareaPrimitive, ToastPrimitive, usePopover };
@@ -1,4 +1,5 @@
1
- import React, { createContext, useContext, useEffect, useState, useSyncExternalStore } from "react";
1
+ import { n as DEFAULT_POSITION, r as useRelativePosition, t as DEFAULT_LAYOUT } from "./use-relative-position-BTKEyT1F.mjs";
2
+ import React, { createContext, forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useRef, useState, useSyncExternalStore } from "react";
2
3
  import { ActivityIndicator, Image, Pressable, StyleSheet, Text, TextInput, View } from "react-native";
3
4
  import { Fragment, jsx } from "react/jsx-runtime";
4
5
 
@@ -122,14 +123,14 @@ const FieldPrimitive = {
122
123
 
123
124
  //#endregion
124
125
  //#region src/primitives/input/input.tsx
125
- const calculateState$4 = (props, isFocused) => {
126
+ const calculateState$5 = (props, isFocused) => {
126
127
  if (props.isDisabled) return "disabled";
127
128
  if (isFocused) return "focused";
128
129
  return "default";
129
130
  };
130
131
  function InputPrimitive(props) {
131
132
  const [isFocused, setIsFocused] = useState(false);
132
- const state = calculateState$4(props, isFocused);
133
+ const state = calculateState$5(props, isFocused);
133
134
  const composedStyles = [
134
135
  props.styles?.default?.style,
135
136
  props.styles?.[state]?.style,
@@ -168,7 +169,7 @@ const useButtonPrimitive = () => {
168
169
 
169
170
  //#endregion
170
171
  //#region src/primitives/button/button-root.tsx
171
- const calculateState$3 = (props, isHovered) => {
172
+ const calculateState$4 = (props, isHovered) => {
172
173
  if (props.isDisabled) return "disabled";
173
174
  if (props.isLoading) return "loading";
174
175
  if (isHovered) return "hovered";
@@ -176,7 +177,7 @@ const calculateState$3 = (props, isHovered) => {
176
177
  };
177
178
  function ButtonRoot(props) {
178
179
  const [isHovered, setIsHovered] = useState(false);
179
- const state = calculateState$3(props, isHovered);
180
+ const state = calculateState$4(props, isHovered);
180
181
  const calculatedStyle = [
181
182
  props.styles?.root?.default,
182
183
  props.styles?.root?.[state],
@@ -246,7 +247,7 @@ const useSelect = () => {
246
247
 
247
248
  //#endregion
248
249
  //#region src/primitives/select/select-root.tsx
249
- const calculateState$2 = (props) => {
250
+ const calculateState$3 = (props) => {
250
251
  if (props.isDisabled) return "disabled";
251
252
  return "default";
252
253
  };
@@ -254,7 +255,7 @@ function SelectRoot(props) {
254
255
  const [isOpen, setIsOpen] = useState(false);
255
256
  const [triggerLayout, setTriggerLayout] = useState(null);
256
257
  const [options, setOptions] = useState([]);
257
- const state = calculateState$2(props);
258
+ const state = calculateState$3(props);
258
259
  const composedStyles = calculateComposedStyles(props.styles, state, "root", props.style);
259
260
  const Component = props.render ?? View;
260
261
  return /* @__PURE__ */ jsx(SelectContext.Provider, {
@@ -370,7 +371,7 @@ function SelectContent(props) {
370
371
 
371
372
  //#endregion
372
373
  //#region src/primitives/select/select-option.tsx
373
- const calculateState$1 = (selectState, hovered, selected) => {
374
+ const calculateState$2 = (selectState, hovered, selected) => {
374
375
  if (selectState === "disabled") return "disabled";
375
376
  if (selected) return "selected";
376
377
  if (hovered) return "hovered";
@@ -380,7 +381,7 @@ function SelectOption(props) {
380
381
  const [isHovered, setIsHovered] = useState(false);
381
382
  const select = useSelect();
382
383
  const isSelected = select.value === props.value;
383
- const optionState = calculateState$1(select.state, isHovered, isSelected);
384
+ const optionState = calculateState$2(select.state, isHovered, isSelected);
384
385
  const composedStyles = calculateComposedStyles(select.styles, optionState, "option", props.style);
385
386
  useEffect(() => {
386
387
  select.setOptions((prev) => {
@@ -706,14 +707,14 @@ const BadgePrimitive = {
706
707
 
707
708
  //#endregion
708
709
  //#region src/primitives/textarea/textarea.tsx
709
- const calculateState = (props, isFocused) => {
710
+ const calculateState$1 = (props, isFocused) => {
710
711
  if (props.isDisabled) return "disabled";
711
712
  if (isFocused) return "focused";
712
713
  return "default";
713
714
  };
714
715
  function TextareaPrimitive(props) {
715
716
  const [isFocused, setIsFocused] = useState(false);
716
- const state = calculateState(props, isFocused);
717
+ const state = calculateState$1(props, isFocused);
717
718
  const composedStyles = [
718
719
  props.styles?.default?.style,
719
720
  props.styles?.[state]?.style,
@@ -743,4 +744,321 @@ function TextareaPrimitive(props) {
743
744
  }
744
745
 
745
746
  //#endregion
746
- export { EmptyPrimitive as a, ButtonPrimitive as c, PortalHost as d, AvatarPrimitive as i, InputPrimitive as l, BadgePrimitive as n, CardPrimitive as o, ToastPrimitive as r, SelectPrimitive as s, TextareaPrimitive as t, FieldPrimitive as u };
747
+ //#region src/primitives/dropdown-menu/context.ts
748
+ const DropdownMenuContext = createContext(void 0);
749
+ const useDropdownMenu = () => {
750
+ const context = useContext(DropdownMenuContext);
751
+ if (!context) throw new Error("useDropdownMenu must be used within a DropdownMenuRoot");
752
+ return context;
753
+ };
754
+
755
+ //#endregion
756
+ //#region src/primitives/dropdown-menu/dropdown-menu-root.tsx
757
+ function DropdownMenuRoot(props) {
758
+ const [isOpen, setIsOpen] = useState(false);
759
+ const [triggerPosition, setTriggerPosition] = useState(DEFAULT_POSITION);
760
+ const [contentLayout, setContentLayout] = useState(DEFAULT_LAYOUT);
761
+ return /* @__PURE__ */ jsx(DropdownMenuContext.Provider, {
762
+ value: {
763
+ isOpen,
764
+ setIsOpen,
765
+ triggerPosition,
766
+ setTriggerPosition,
767
+ contentLayout,
768
+ setContentLayout,
769
+ styles: props.styles
770
+ },
771
+ children: props.children
772
+ });
773
+ }
774
+
775
+ //#endregion
776
+ //#region src/primitives/dropdown-menu/dropdown-menu-trigger.tsx
777
+ const DropdownMenuTrigger = forwardRef((props, ref) => {
778
+ const dropdownMenu = useDropdownMenu();
779
+ const triggerRef = useRef(null);
780
+ const onTriggerPress = async () => {
781
+ triggerRef.current?.measure((_x, _y, width, height, pageX, pageY) => {
782
+ dropdownMenu.setTriggerPosition({
783
+ height,
784
+ width,
785
+ pageX,
786
+ pageY
787
+ });
788
+ });
789
+ dropdownMenu.setIsOpen((prev) => !prev);
790
+ };
791
+ useImperativeHandle(ref, () => ({
792
+ open: () => dropdownMenu.setIsOpen(true),
793
+ close: () => dropdownMenu.setIsOpen(false)
794
+ }));
795
+ return React.cloneElement(props.children, {
796
+ ref: triggerRef,
797
+ onPress: onTriggerPress,
798
+ role: "button",
799
+ accessible: true,
800
+ accessibilityRole: "button",
801
+ accessibilityState: { expanded: dropdownMenu.isOpen },
802
+ ...props.children.props
803
+ });
804
+ });
805
+ DropdownMenuTrigger.displayName = "DropdownMenuTrigger";
806
+
807
+ //#endregion
808
+ //#region src/primitives/dropdown-menu/dropdown-menu-content.tsx
809
+ function DropdownMenuContent(props) {
810
+ const menu = useDropdownMenu();
811
+ const composedStyle = [
812
+ useRelativePosition({
813
+ align: "start",
814
+ avoidCollisions: true,
815
+ triggerPosition: menu.triggerPosition,
816
+ contentLayout: menu.contentLayout,
817
+ alignOffset: 0,
818
+ side: "bottom",
819
+ sideOffset: 0
820
+ }),
821
+ menu.styles?.content,
822
+ props.style
823
+ ];
824
+ return /* @__PURE__ */ jsx(props.render ?? View, {
825
+ ...props,
826
+ onLayout: (e) => {
827
+ menu.setContentLayout(e.nativeEvent.layout);
828
+ },
829
+ style: composedStyle
830
+ });
831
+ }
832
+
833
+ //#endregion
834
+ //#region src/primitives/dropdown-menu/dropdown-menu-button.tsx
835
+ const calculateState = (isHovered) => {
836
+ if (isHovered) return "hovered";
837
+ return "default";
838
+ };
839
+ function DropdownMenuButton(props) {
840
+ const menu = useDropdownMenu();
841
+ const [isHovered, setIsHovered] = useState(false);
842
+ const state = calculateState(isHovered);
843
+ const composedStyle = [
844
+ menu.styles?.button?.default,
845
+ menu.styles?.button?.[state],
846
+ props.style
847
+ ];
848
+ const handlePress = () => {
849
+ props.onPress?.();
850
+ menu.setIsOpen((prev) => !prev);
851
+ };
852
+ return /* @__PURE__ */ jsx(props.render ?? Text, {
853
+ ...props,
854
+ onPress: handlePress,
855
+ onMouseEnter: () => setIsHovered(true),
856
+ onMouseLeave: () => setIsHovered(false),
857
+ style: composedStyle,
858
+ children: props.children
859
+ });
860
+ }
861
+
862
+ //#endregion
863
+ //#region src/primitives/dropdown-menu/dropdown-menu-divider.tsx
864
+ function DropdownMenuDivider(props) {
865
+ const composedStyle = [useDropdownMenu().styles?.divider, props.style];
866
+ return /* @__PURE__ */ jsx(props.render ?? View, {
867
+ ...props,
868
+ style: composedStyle
869
+ });
870
+ }
871
+
872
+ //#endregion
873
+ //#region src/primitives/dropdown-menu/dropdown-menu-portal.tsx
874
+ function DropdownMenuPortal(props) {
875
+ const menu = useDropdownMenu();
876
+ if (!menu.isOpen) return null;
877
+ return /* @__PURE__ */ jsx(Portal, {
878
+ name: "dropdown-menu-portal",
879
+ children: /* @__PURE__ */ jsx(DropdownMenuContext.Provider, {
880
+ value: menu,
881
+ children: props.children
882
+ })
883
+ });
884
+ }
885
+
886
+ //#endregion
887
+ //#region src/primitives/dropdown-menu/dropdown-menu-overlay.tsx
888
+ function DropdownMenuOverlay(props) {
889
+ const menu = useDropdownMenu();
890
+ const composedStyle = [
891
+ StyleSheet.absoluteFill,
892
+ menu.styles?.overlay,
893
+ props.style
894
+ ];
895
+ return /* @__PURE__ */ jsx(props.render ?? Pressable, {
896
+ onPress: () => {
897
+ menu.setIsOpen(false);
898
+ },
899
+ style: composedStyle,
900
+ children: props.children
901
+ });
902
+ }
903
+
904
+ //#endregion
905
+ //#region src/primitives/dropdown-menu/index.ts
906
+ const DropdownMenuPrimitive = {
907
+ Root: DropdownMenuRoot,
908
+ Trigger: DropdownMenuTrigger,
909
+ Portal: DropdownMenuPortal,
910
+ Overlay: DropdownMenuOverlay,
911
+ Content: DropdownMenuContent,
912
+ Button: DropdownMenuButton,
913
+ Divider: DropdownMenuDivider
914
+ };
915
+
916
+ //#endregion
917
+ //#region src/primitives/popover/context.ts
918
+ const PopoverContext = createContext(void 0);
919
+ const usePopover = () => {
920
+ const context = useContext(PopoverContext);
921
+ if (!context) throw new Error("usePopover must be used within a PopoverRoot");
922
+ return context;
923
+ };
924
+
925
+ //#endregion
926
+ //#region src/primitives/popover/popover-root.tsx
927
+ function PopoverRoot(props) {
928
+ const [isOpen, setIsOpen] = useState(false);
929
+ const [contentLayout, setContentLayout] = useState(DEFAULT_LAYOUT);
930
+ const [triggerPosition, setTriggerPosition] = useState(DEFAULT_POSITION);
931
+ return /* @__PURE__ */ jsx(PopoverContext.Provider, {
932
+ value: {
933
+ isOpen,
934
+ setIsOpen,
935
+ contentLayout,
936
+ setContentLayout,
937
+ triggerPosition,
938
+ setTriggerPosition,
939
+ styles: props.styles
940
+ },
941
+ children: props.children
942
+ });
943
+ }
944
+
945
+ //#endregion
946
+ //#region src/primitives/popover/popover-trigger.tsx
947
+ const PopoverTrigger = forwardRef((props, ref) => {
948
+ const popover = usePopover();
949
+ const triggerRef = useRef(null);
950
+ const onTriggerPress = async () => {
951
+ triggerRef.current?.measure((_x, _y, width, height, pageX, pageY) => {
952
+ popover.setTriggerPosition({
953
+ height,
954
+ width,
955
+ pageX,
956
+ pageY
957
+ });
958
+ });
959
+ popover.setIsOpen((prev) => !prev);
960
+ };
961
+ useImperativeHandle(ref, () => ({
962
+ open: () => popover.setIsOpen(true),
963
+ close: () => popover.setIsOpen(false)
964
+ }));
965
+ return React.cloneElement(props.children, {
966
+ ref: triggerRef,
967
+ onPress: onTriggerPress,
968
+ role: "button",
969
+ accessible: true,
970
+ accessibilityRole: "button",
971
+ accessibilityState: { expanded: popover.isOpen },
972
+ ...props.children.props
973
+ });
974
+ });
975
+ PopoverTrigger.displayName = "PopoverTrigger";
976
+
977
+ //#endregion
978
+ //#region src/primitives/popover/popover-portal.tsx
979
+ function PopoverPortal(props) {
980
+ const popover = usePopover();
981
+ if (!popover.isOpen) return null;
982
+ return /* @__PURE__ */ jsx(Portal, {
983
+ name: "popover-portal",
984
+ children: /* @__PURE__ */ jsx(PopoverContext.Provider, {
985
+ value: popover,
986
+ children: props.children
987
+ })
988
+ });
989
+ }
990
+
991
+ //#endregion
992
+ //#region src/primitives/popover/popover-overlay.tsx
993
+ function PopoverOverlay(props) {
994
+ const { closeOnPress = true, ...restProps } = props;
995
+ const popover = usePopover();
996
+ const composedStyle = [
997
+ StyleSheet.absoluteFill,
998
+ popover.styles?.overlay,
999
+ props.style
1000
+ ];
1001
+ return /* @__PURE__ */ jsx(props.render ?? Pressable, {
1002
+ ...restProps,
1003
+ onPress: () => {
1004
+ if (closeOnPress) popover.setIsOpen(false);
1005
+ props.onPress?.();
1006
+ },
1007
+ style: composedStyle,
1008
+ children: props.children
1009
+ });
1010
+ }
1011
+
1012
+ //#endregion
1013
+ //#region src/primitives/popover/popover-content.tsx
1014
+ function PopoverContent(props) {
1015
+ const popover = usePopover();
1016
+ const composedStyle = [
1017
+ useRelativePosition({
1018
+ align: "start",
1019
+ avoidCollisions: true,
1020
+ triggerPosition: popover.triggerPosition,
1021
+ contentLayout: popover.contentLayout,
1022
+ alignOffset: 0,
1023
+ side: "bottom",
1024
+ sideOffset: 0
1025
+ }),
1026
+ popover.styles?.content,
1027
+ props.style
1028
+ ];
1029
+ return /* @__PURE__ */ jsx(props.render ?? View, {
1030
+ ...props,
1031
+ onLayout: (e) => {
1032
+ popover.setContentLayout(e.nativeEvent.layout);
1033
+ },
1034
+ style: composedStyle
1035
+ });
1036
+ }
1037
+
1038
+ //#endregion
1039
+ //#region src/primitives/popover/popover-close.tsx
1040
+ function PopoverClose(props) {
1041
+ const popover = usePopover();
1042
+ return /* @__PURE__ */ jsx(props.render ?? Pressable, {
1043
+ ...props,
1044
+ onPress: () => {
1045
+ popover.setIsOpen(false);
1046
+ props.onPress?.();
1047
+ },
1048
+ style: props.style
1049
+ });
1050
+ }
1051
+
1052
+ //#endregion
1053
+ //#region src/primitives/popover/index.ts
1054
+ const PopoverPrimitive = {
1055
+ Root: PopoverRoot,
1056
+ Trigger: PopoverTrigger,
1057
+ Portal: PopoverPortal,
1058
+ Overlay: PopoverOverlay,
1059
+ Content: PopoverContent,
1060
+ Close: PopoverClose
1061
+ };
1062
+
1063
+ //#endregion
1064
+ export { BadgePrimitive as a, EmptyPrimitive as c, ButtonPrimitive as d, InputPrimitive as f, TextareaPrimitive as i, CardPrimitive as l, PortalHost as m, usePopover as n, ToastPrimitive as o, FieldPrimitive as p, DropdownMenuPrimitive as r, AvatarPrimitive as s, PopoverPrimitive as t, SelectPrimitive as u };
@@ -1,4 +1,4 @@
1
- import { r as ToastPrimitive } from "./primitives-CyDqzNcp.mjs";
1
+ import { o as ToastPrimitive } from "./primitives-DNeYBN-3.mjs";
2
2
  import React, { createContext, useContext, useEffect, useState, useSyncExternalStore } from "react";
3
3
  import { StyleSheet, View, useColorScheme } from "react-native";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -0,0 +1,33 @@
1
+ //#region src/hooks/use-numeric-mask.d.ts
2
+ type NumericMaskFormat = "currency" | "decimal" | "integer" | "percentage";
3
+ interface UseNumericMaskOptions {
4
+ format?: NumericMaskFormat;
5
+ locale?: string;
6
+ currency?: string;
7
+ precision?: number;
8
+ min?: number;
9
+ max?: number;
10
+ allowNegative?: boolean;
11
+ onChange?: (value: number | null) => void;
12
+ }
13
+ interface UseNumericMaskReturn {
14
+ value: string;
15
+ numericValue: number | null;
16
+ onChangeText: (text: string) => void;
17
+ onBlur: () => void;
18
+ onFocus: () => void;
19
+ keyboardType: "numeric" | "decimal-pad" | "number-pad";
20
+ setValue: (value: number | null) => void;
21
+ }
22
+ declare function useNumericMask({
23
+ format,
24
+ locale,
25
+ currency,
26
+ precision,
27
+ min,
28
+ max,
29
+ allowNegative,
30
+ onChange
31
+ }?: UseNumericMaskOptions): UseNumericMaskReturn;
32
+ //#endregion
33
+ export { useNumericMask as i, UseNumericMaskOptions as n, UseNumericMaskReturn as r, NumericMaskFormat as t };
@@ -0,0 +1,113 @@
1
+ import { useCallback, useState } from "react";
2
+
3
+ //#region src/hooks/use-numeric-mask.ts
4
+ function useNumericMask({ format = "decimal", locale = "en-US", currency = "USD", precision = 2, min, max, allowNegative = true, onChange } = {}) {
5
+ const [numericValue, setNumericValue] = useState(null);
6
+ const [displayValue, setDisplayValue] = useState("");
7
+ const [isFocused, setIsFocused] = useState(false);
8
+ const effectivePrecision = format === "integer" ? 0 : precision;
9
+ const formatValue = useCallback((num) => {
10
+ if (num === null || isNaN(num)) return "";
11
+ switch (format) {
12
+ case "currency": return new Intl.NumberFormat(locale, {
13
+ style: "currency",
14
+ currency,
15
+ minimumFractionDigits: effectivePrecision,
16
+ maximumFractionDigits: effectivePrecision
17
+ }).format(num);
18
+ case "percentage": return new Intl.NumberFormat(locale, {
19
+ style: "percent",
20
+ minimumFractionDigits: effectivePrecision,
21
+ maximumFractionDigits: effectivePrecision
22
+ }).format(num / 100);
23
+ case "integer": return new Intl.NumberFormat(locale, {
24
+ minimumFractionDigits: 0,
25
+ maximumFractionDigits: 0
26
+ }).format(num);
27
+ case "decimal":
28
+ default: return new Intl.NumberFormat(locale, {
29
+ minimumFractionDigits: effectivePrecision,
30
+ maximumFractionDigits: effectivePrecision
31
+ }).format(num);
32
+ }
33
+ }, [
34
+ format,
35
+ locale,
36
+ currency,
37
+ effectivePrecision
38
+ ]);
39
+ const parseValue = useCallback((text) => {
40
+ let cleaned = text.replace(/[^\d.-]/g, "");
41
+ if (!allowNegative) cleaned = cleaned.replace(/-/g, "");
42
+ const parsed = parseFloat(cleaned);
43
+ if (isNaN(parsed) || cleaned === "" || cleaned === "-") return null;
44
+ let constrained = parsed;
45
+ if (min !== void 0 && constrained < min) constrained = min;
46
+ if (max !== void 0 && constrained > max) constrained = max;
47
+ return constrained;
48
+ }, [
49
+ min,
50
+ max,
51
+ allowNegative
52
+ ]);
53
+ const handleChangeText = useCallback((text) => {
54
+ if (isFocused) {
55
+ let cleaned = text.replace(/[^\d.-]/g, "");
56
+ if (!allowNegative && cleaned.includes("-")) return;
57
+ if (allowNegative) {
58
+ if ((cleaned.match(/-/g) || []).length > 1 || cleaned.includes("-") && cleaned.indexOf("-") !== 0) return;
59
+ }
60
+ if (effectivePrecision >= 0) {
61
+ const decimalIndex = cleaned.indexOf(".");
62
+ if (decimalIndex !== -1) {
63
+ if (cleaned.substring(decimalIndex + 1).length > effectivePrecision) return;
64
+ }
65
+ if ((cleaned.match(/\./g) || []).length > 1) return;
66
+ if (format === "integer" && cleaned.includes(".")) return;
67
+ }
68
+ }
69
+ setDisplayValue(text);
70
+ const value = parseValue(text);
71
+ setNumericValue(value);
72
+ onChange?.(value);
73
+ }, [
74
+ parseValue,
75
+ onChange,
76
+ isFocused,
77
+ effectivePrecision,
78
+ allowNegative,
79
+ format
80
+ ]);
81
+ const handleBlur = useCallback(() => {
82
+ setIsFocused(false);
83
+ if (numericValue !== null) setDisplayValue(formatValue(numericValue));
84
+ else setDisplayValue("");
85
+ }, [numericValue, formatValue]);
86
+ const handleFocus = useCallback(() => {
87
+ setIsFocused(true);
88
+ if (numericValue !== null) setDisplayValue(numericValue.toString());
89
+ }, [numericValue]);
90
+ const setValue = useCallback((value) => {
91
+ setNumericValue(value);
92
+ if (value !== null) if (isFocused) setDisplayValue(value.toString());
93
+ else setDisplayValue(formatValue(value));
94
+ else setDisplayValue("");
95
+ onChange?.(value);
96
+ }, [
97
+ isFocused,
98
+ formatValue,
99
+ onChange
100
+ ]);
101
+ return {
102
+ value: displayValue,
103
+ numericValue,
104
+ onChangeText: handleChangeText,
105
+ onBlur: handleBlur,
106
+ onFocus: handleFocus,
107
+ keyboardType: format === "integer" ? allowNegative ? "numeric" : "number-pad" : "decimal-pad",
108
+ setValue
109
+ };
110
+ }
111
+
112
+ //#endregion
113
+ export { useNumericMask as t };