@nori-ui/core 1.3.0 → 1.4.0

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.cjs CHANGED
@@ -10644,6 +10644,436 @@ var Separator = /* @__PURE__ */ __name(({
10644
10644
  }
10645
10645
  );
10646
10646
  }, "Separator");
10647
+ var SIZE_PERCENT = {
10648
+ sm: "25%",
10649
+ md: "50%",
10650
+ lg: "75%",
10651
+ full: "100%"
10652
+ };
10653
+ var SheetContext = React.createContext(null);
10654
+ var useSheetContext = /* @__PURE__ */ __name((label) => {
10655
+ const ctx = React.useContext(SheetContext);
10656
+ if (!ctx) {
10657
+ throw new Error(`<${label}> must be rendered inside a <Sheet>.`);
10658
+ }
10659
+ return ctx;
10660
+ }, "useSheetContext");
10661
+ var SheetRoot = /* @__PURE__ */ __name(({
10662
+ open,
10663
+ defaultOpen = false,
10664
+ onOpenChange,
10665
+ side = "bottom",
10666
+ size = "md",
10667
+ dismissible = true,
10668
+ children
10669
+ }) => {
10670
+ const [inner, setInner] = React.useState(defaultOpen);
10671
+ const isControlled = open !== void 0;
10672
+ const current = isControlled ? open : inner;
10673
+ const setOpen = React.useCallback(
10674
+ (next) => {
10675
+ if (!isControlled) {
10676
+ setInner(next);
10677
+ }
10678
+ onOpenChange?.(next);
10679
+ },
10680
+ [isControlled, onOpenChange]
10681
+ );
10682
+ const baseId = React.useId();
10683
+ const triggerRef = React.useRef(null);
10684
+ const ctxValue = {
10685
+ open: current,
10686
+ setOpen,
10687
+ titleId: `${baseId}-title`,
10688
+ descriptionId: `${baseId}-description`,
10689
+ triggerRef,
10690
+ side,
10691
+ size,
10692
+ dismissible
10693
+ };
10694
+ return /* @__PURE__ */ jsxRuntime.jsx(SheetContext.Provider, { value: ctxValue, children });
10695
+ }, "SheetRoot");
10696
+ var SheetTrigger = /* @__PURE__ */ __name(({ asChild = true, children, className, testID }) => {
10697
+ const ctx = useSheetContext("SheetTrigger");
10698
+ const onPress = React.useCallback(() => ctx.setOpen(true), [ctx]);
10699
+ if (asChild && React.isValidElement(children)) {
10700
+ const child = children;
10701
+ const fire = /* @__PURE__ */ __name((existing) => (event) => {
10702
+ existing?.(event);
10703
+ ctx.setOpen(true);
10704
+ }, "fire");
10705
+ return /* @__PURE__ */ jsxRuntime.jsx(
10706
+ Slot,
10707
+ {
10708
+ ref: (node) => {
10709
+ ctx.triggerRef.current = node;
10710
+ },
10711
+ onClick: fire(child.props.onClick),
10712
+ onPress: fire(child.props.onPress),
10713
+ ...testID !== void 0 ? { "data-testid": testID } : {},
10714
+ ...className !== void 0 ? { className } : {},
10715
+ children: child
10716
+ }
10717
+ );
10718
+ }
10719
+ return /* @__PURE__ */ jsxRuntime.jsx(
10720
+ reactNative.Pressable,
10721
+ {
10722
+ ref: (node) => {
10723
+ ctx.triggerRef.current = node;
10724
+ },
10725
+ onPress,
10726
+ ...testID !== void 0 ? { testID } : {},
10727
+ ...className !== void 0 ? { className } : {},
10728
+ children: wrapStringChildren5(children)
10729
+ }
10730
+ );
10731
+ }, "SheetTrigger");
10732
+ var SheetHeader = /* @__PURE__ */ __name(({ children, className }) => {
10733
+ const colors = useThemeColors();
10734
+ return /* @__PURE__ */ jsxRuntime.jsx(
10735
+ reactNative.View,
10736
+ {
10737
+ className: cn("flex-col gap-1", className),
10738
+ style: {
10739
+ flexDirection: "column",
10740
+ gap: px(colors.spacing["1"]),
10741
+ paddingHorizontal: px(colors.spacing["6"]),
10742
+ paddingTop: px(colors.spacing["6"]),
10743
+ paddingBottom: px(colors.spacing["2"])
10744
+ },
10745
+ children
10746
+ }
10747
+ );
10748
+ }, "SheetHeader");
10749
+ var SheetTitle = /* @__PURE__ */ __name(({ children, className }) => {
10750
+ const ctx = useSheetContext("SheetTitle");
10751
+ const colors = useThemeColors();
10752
+ return /* @__PURE__ */ jsxRuntime.jsx(
10753
+ reactNative.Text,
10754
+ {
10755
+ nativeID: ctx.titleId,
10756
+ id: ctx.titleId,
10757
+ role: "heading",
10758
+ "aria-level": 2,
10759
+ className: cn("text-lg font-semibold text-semantic-text-default", className),
10760
+ style: {
10761
+ color: colors.semantic.text.default,
10762
+ fontFamily: colors.fontFamily.display,
10763
+ fontSize: px(colors.fontSize.lg),
10764
+ fontWeight: colors.fontWeight.semibold
10765
+ },
10766
+ children
10767
+ }
10768
+ );
10769
+ }, "SheetTitle");
10770
+ var SheetDescription = /* @__PURE__ */ __name(({ children, className }) => {
10771
+ const ctx = useSheetContext("SheetDescription");
10772
+ const colors = useThemeColors();
10773
+ return /* @__PURE__ */ jsxRuntime.jsx(
10774
+ reactNative.Text,
10775
+ {
10776
+ nativeID: ctx.descriptionId,
10777
+ id: ctx.descriptionId,
10778
+ className: cn("text-sm text-semantic-text-muted", className),
10779
+ style: {
10780
+ color: colors.semantic.text.muted,
10781
+ fontFamily: colors.fontFamily.body,
10782
+ fontSize: px(colors.fontSize.sm),
10783
+ lineHeight: px(colors.fontSize.sm) * Number(colors.lineHeight.normal)
10784
+ },
10785
+ children
10786
+ }
10787
+ );
10788
+ }, "SheetDescription");
10789
+ var SheetBody = /* @__PURE__ */ __name(({ children, className }) => {
10790
+ const colors = useThemeColors();
10791
+ return /* @__PURE__ */ jsxRuntime.jsx(
10792
+ reactNative.View,
10793
+ {
10794
+ className: cn("flex-1", className),
10795
+ style: {
10796
+ flex: 1,
10797
+ paddingHorizontal: px(colors.spacing["6"]),
10798
+ paddingVertical: px(colors.spacing["4"])
10799
+ },
10800
+ children
10801
+ }
10802
+ );
10803
+ }, "SheetBody");
10804
+ var SheetFooter = /* @__PURE__ */ __name(({ children, className }) => {
10805
+ const colors = useThemeColors();
10806
+ return /* @__PURE__ */ jsxRuntime.jsx(
10807
+ reactNative.View,
10808
+ {
10809
+ className: cn("flex-row items-center justify-end gap-2", className),
10810
+ style: {
10811
+ flexDirection: "row",
10812
+ alignItems: "center",
10813
+ justifyContent: "flex-end",
10814
+ gap: px(colors.spacing["2"]),
10815
+ paddingHorizontal: px(colors.spacing["6"]),
10816
+ paddingBottom: px(colors.spacing["6"]),
10817
+ paddingTop: px(colors.spacing["2"])
10818
+ },
10819
+ children
10820
+ }
10821
+ );
10822
+ }, "SheetFooter");
10823
+ var SheetClose = /* @__PURE__ */ __name(({
10824
+ asChild = true,
10825
+ children,
10826
+ className,
10827
+ testID,
10828
+ accessibilityLabel = "Close"
10829
+ }) => {
10830
+ const ctx = useSheetContext("SheetClose");
10831
+ const onPress = React.useCallback(() => ctx.setOpen(false), [ctx]);
10832
+ if (asChild && React.isValidElement(children)) {
10833
+ const child = children;
10834
+ const fire = /* @__PURE__ */ __name((existing) => (event) => {
10835
+ existing?.(event);
10836
+ ctx.setOpen(false);
10837
+ }, "fire");
10838
+ return /* @__PURE__ */ jsxRuntime.jsx(
10839
+ Slot,
10840
+ {
10841
+ onClick: fire(child.props.onClick),
10842
+ onPress: fire(child.props.onPress),
10843
+ ...testID !== void 0 ? { "data-testid": testID } : {},
10844
+ ...className !== void 0 ? { className } : {},
10845
+ children: child
10846
+ }
10847
+ );
10848
+ }
10849
+ return /* @__PURE__ */ jsxRuntime.jsx(
10850
+ reactNative.Pressable,
10851
+ {
10852
+ onPress,
10853
+ role: "button",
10854
+ accessibilityRole: "button",
10855
+ accessibilityLabel,
10856
+ "aria-label": accessibilityLabel,
10857
+ ...testID !== void 0 ? { testID } : {},
10858
+ ...className !== void 0 ? { className } : {},
10859
+ children: wrapStringChildren5(children)
10860
+ }
10861
+ );
10862
+ }, "SheetClose");
10863
+ function wrapStringChildren5(children) {
10864
+ if (typeof children === "string" || typeof children === "number") {
10865
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { children });
10866
+ }
10867
+ return children;
10868
+ }
10869
+ __name(wrapStringChildren5, "wrapStringChildren");
10870
+ var SCRIM_COLOR3 = "rgba(0, 0, 0, 0.40)";
10871
+ var FOCUSABLE_SELECTOR3 = 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';
10872
+ var SheetPanel = /* @__PURE__ */ __name(({ children, className, testID }) => {
10873
+ const ctx = useSheetContext("SheetPanel");
10874
+ const colors = useThemeColors();
10875
+ const panelRef = React.useRef(null);
10876
+ const overlayDomRef = React.useRef(null);
10877
+ const [entered, setEntered] = React.useState(false);
10878
+ React.useEffect(() => {
10879
+ if (reactNative.Platform.OS !== "web") {
10880
+ setEntered(true);
10881
+ return;
10882
+ }
10883
+ if (!ctx.open) {
10884
+ setEntered(false);
10885
+ return;
10886
+ }
10887
+ const id = requestAnimationFrame(() => setEntered(true));
10888
+ return () => cancelAnimationFrame(id);
10889
+ }, [ctx.open]);
10890
+ React.useEffect(() => {
10891
+ if (reactNative.Platform.OS !== "web") {
10892
+ return;
10893
+ }
10894
+ const node = overlayDomRef.current;
10895
+ if (!node) {
10896
+ return;
10897
+ }
10898
+ node.style.transitionProperty = "background-color";
10899
+ node.style.transitionDuration = "200ms";
10900
+ node.style.transitionTimingFunction = "ease-out";
10901
+ node.style.backgroundColor = entered ? SCRIM_COLOR3 : "rgba(0,0,0,0)";
10902
+ }, [entered]);
10903
+ React.useEffect(() => {
10904
+ if (!ctx.open || reactNative.Platform.OS !== "web" || typeof document === "undefined") {
10905
+ return;
10906
+ }
10907
+ const previouslyFocused = document.activeElement;
10908
+ const prevBodyOverflow = document.body.style.overflow;
10909
+ document.body.style.overflow = "hidden";
10910
+ const focusFirst = /* @__PURE__ */ __name(() => {
10911
+ const node = panelRef.current;
10912
+ if (!node) {
10913
+ return;
10914
+ }
10915
+ const focusable = node.querySelectorAll(FOCUSABLE_SELECTOR3);
10916
+ const first = focusable[0];
10917
+ if (first) {
10918
+ first.focus();
10919
+ } else {
10920
+ node.setAttribute("tabindex", "-1");
10921
+ node.focus();
10922
+ }
10923
+ }, "focusFirst");
10924
+ focusFirst();
10925
+ const onKeyDown = /* @__PURE__ */ __name((event) => {
10926
+ if (event.key === "Escape") {
10927
+ event.preventDefault();
10928
+ ctx.setOpen(false);
10929
+ return;
10930
+ }
10931
+ if (event.key !== "Tab") {
10932
+ return;
10933
+ }
10934
+ const node = panelRef.current;
10935
+ if (!node) {
10936
+ return;
10937
+ }
10938
+ const focusable = Array.from(node.querySelectorAll(FOCUSABLE_SELECTOR3)).filter(
10939
+ (el) => el.offsetParent !== null || el === document.activeElement
10940
+ );
10941
+ if (focusable.length === 0) {
10942
+ event.preventDefault();
10943
+ return;
10944
+ }
10945
+ const first = focusable[0];
10946
+ const last = focusable[focusable.length - 1];
10947
+ if (!first || !last) {
10948
+ return;
10949
+ }
10950
+ if (event.shiftKey) {
10951
+ if (document.activeElement === first || !node.contains(document.activeElement)) {
10952
+ event.preventDefault();
10953
+ last.focus();
10954
+ }
10955
+ } else if (document.activeElement === last) {
10956
+ event.preventDefault();
10957
+ first.focus();
10958
+ }
10959
+ }, "onKeyDown");
10960
+ document.addEventListener("keydown", onKeyDown);
10961
+ return () => {
10962
+ document.removeEventListener("keydown", onKeyDown);
10963
+ document.body.style.overflow = prevBodyOverflow;
10964
+ const restoreTo = ctx.triggerRef.current ?? previouslyFocused;
10965
+ restoreTo?.focus?.();
10966
+ };
10967
+ }, [ctx.open, ctx.setOpen, ctx.triggerRef]);
10968
+ const onBackdropPress = React.useCallback(() => {
10969
+ if (ctx.dismissible) {
10970
+ ctx.setOpen(false);
10971
+ }
10972
+ }, [ctx]);
10973
+ const isHorizontal = ctx.side === "left" || ctx.side === "right";
10974
+ const dim = typeof ctx.size === "number" ? ctx.size : SIZE_PERCENT[ctx.size];
10975
+ const panelStyle = {
10976
+ position: "absolute",
10977
+ backgroundColor: colors.semantic.background.elevated,
10978
+ ...isHorizontal ? { top: 0, bottom: 0 } : { left: 0, right: 0 },
10979
+ ...ctx.side === "bottom" && { bottom: 0 },
10980
+ ...ctx.side === "top" && { top: 0 },
10981
+ ...ctx.side === "left" && { left: 0 },
10982
+ ...ctx.side === "right" && { right: 0 }
10983
+ };
10984
+ const translateStyle = reactNative.Platform.OS === "web" ? {
10985
+ transform: entered ? "translateX(0) translateY(0)" : translateOffscreen(ctx.side),
10986
+ transitionProperty: "transform",
10987
+ transitionDuration: "280ms",
10988
+ transitionTimingFunction: "cubic-bezier(0.16, 1, 0.3, 1)"
10989
+ } : {};
10990
+ const overlayStyle = {
10991
+ position: reactNative.Platform.OS === "web" ? "fixed" : "absolute",
10992
+ top: 0,
10993
+ left: 0,
10994
+ right: 0,
10995
+ bottom: 0,
10996
+ ...reactNative.Platform.OS === "web" ? { zIndex: 50 } : { backgroundColor: SCRIM_COLOR3 }
10997
+ };
10998
+ const sizeStyle = isHorizontal ? { width: dim, height: "100%" } : { height: dim, width: "100%" };
10999
+ return /* @__PURE__ */ jsxRuntime.jsx(
11000
+ reactNative.Modal,
11001
+ {
11002
+ visible: ctx.open,
11003
+ transparent: true,
11004
+ animationType: reactNative.Platform.OS === "web" ? "none" : ctx.side === "bottom" || ctx.side === "top" ? "slide" : "fade",
11005
+ onRequestClose: () => ctx.setOpen(false),
11006
+ children: /* @__PURE__ */ jsxRuntime.jsx(
11007
+ reactNative.Pressable,
11008
+ {
11009
+ accessibilityRole: "none",
11010
+ "aria-hidden": true,
11011
+ ref: (node) => {
11012
+ overlayDomRef.current = node;
11013
+ },
11014
+ style: overlayStyle,
11015
+ onPress: onBackdropPress,
11016
+ children: /* @__PURE__ */ jsxRuntime.jsx(
11017
+ reactNative.Pressable,
11018
+ {
11019
+ onPress: (event) => event.stopPropagation?.(),
11020
+ ref: (node) => {
11021
+ panelRef.current = node;
11022
+ },
11023
+ role: "dialog",
11024
+ accessibilityRole: "none",
11025
+ "aria-modal": true,
11026
+ "aria-labelledby": ctx.titleId,
11027
+ "aria-describedby": ctx.descriptionId,
11028
+ "data-side": ctx.side,
11029
+ ...testID !== void 0 ? { testID } : {},
11030
+ className: cn("bg-semantic-background-elevated", className),
11031
+ style: [
11032
+ panelStyle,
11033
+ sizeStyle,
11034
+ translateStyle,
11035
+ {
11036
+ shadowColor: "#000",
11037
+ shadowOffset: { width: 0, height: -2 },
11038
+ shadowOpacity: 0.15,
11039
+ shadowRadius: 20,
11040
+ elevation: 24,
11041
+ ...ctx.side === "bottom" ? { borderTopLeftRadius: 16, borderTopRightRadius: 16 } : {},
11042
+ ...ctx.side === "top" ? { borderBottomLeftRadius: 16, borderBottomRightRadius: 16 } : {}
11043
+ }
11044
+ ],
11045
+ children
11046
+ }
11047
+ )
11048
+ }
11049
+ )
11050
+ }
11051
+ );
11052
+ }, "SheetPanel");
11053
+ var Sheet = Object.assign(SheetRoot, {
11054
+ Trigger: SheetTrigger,
11055
+ Panel: SheetPanel,
11056
+ Header: SheetHeader,
11057
+ Title: SheetTitle,
11058
+ Description: SheetDescription,
11059
+ Body: SheetBody,
11060
+ Footer: SheetFooter,
11061
+ Close: SheetClose
11062
+ });
11063
+ var Drawer = Sheet;
11064
+ function translateOffscreen(side) {
11065
+ switch (side) {
11066
+ case "bottom":
11067
+ return "translateY(100%)";
11068
+ case "top":
11069
+ return "translateY(-100%)";
11070
+ case "left":
11071
+ return "translateX(-100%)";
11072
+ case "right":
11073
+ return "translateX(100%)";
11074
+ }
11075
+ }
11076
+ __name(translateOffscreen, "translateOffscreen");
10647
11077
  var PULSE_DURATION_MS = 900;
10648
11078
  var PULSE_MIN = 0.55;
10649
11079
  var PULSE_MAX = 1;
@@ -12557,17 +12987,17 @@ var TooltipTrigger = /* @__PURE__ */ __name(({ asChild = true, children, classNa
12557
12987
  },
12558
12988
  ...testID !== void 0 ? { testID } : {},
12559
12989
  ...className !== void 0 ? { className } : {},
12560
- children: wrapStringChildren5(children)
12990
+ children: wrapStringChildren6(children)
12561
12991
  }
12562
12992
  );
12563
12993
  }, "TooltipTrigger");
12564
- function wrapStringChildren5(children) {
12994
+ function wrapStringChildren6(children) {
12565
12995
  if (typeof children === "string" || typeof children === "number") {
12566
12996
  return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { children });
12567
12997
  }
12568
12998
  return children;
12569
12999
  }
12570
- __name(wrapStringChildren5, "wrapStringChildren");
13000
+ __name(wrapStringChildren6, "wrapStringChildren");
12571
13001
  var GAP2 = 4;
12572
13002
  var MIN_WIDTH2 = 0;
12573
13003
  function computePosition2(rect, side, align, contentSize) {
@@ -12875,6 +13305,7 @@ exports.Checkbox = Checkbox;
12875
13305
  exports.ContextMenu = ContextMenu;
12876
13306
  exports.DatePicker = DatePicker;
12877
13307
  exports.Dialog = Dialog;
13308
+ exports.Drawer = Drawer;
12878
13309
  exports.DropdownMenu = DropdownMenu;
12879
13310
  exports.Field = Field;
12880
13311
  exports.FloatButton = FloatButton;
@@ -12894,6 +13325,15 @@ exports.Radio = Radio;
12894
13325
  exports.SegmentedControl = SegmentedControl;
12895
13326
  exports.Select = Select;
12896
13327
  exports.Separator = Separator;
13328
+ exports.Sheet = Sheet;
13329
+ exports.SheetBody = SheetBody;
13330
+ exports.SheetClose = SheetClose;
13331
+ exports.SheetDescription = SheetDescription;
13332
+ exports.SheetFooter = SheetFooter;
13333
+ exports.SheetHeader = SheetHeader;
13334
+ exports.SheetPanel = SheetPanel;
13335
+ exports.SheetTitle = SheetTitle;
13336
+ exports.SheetTrigger = SheetTrigger;
12897
13337
  exports.Skeleton = Skeleton;
12898
13338
  exports.Slider = Slider;
12899
13339
  exports.SliderGestureProvider = SliderGestureProvider;