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