@shoplflow/base 0.46.26 → 0.46.28

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
@@ -765,6 +765,7 @@ var MODAL_SIZE_L = 768;
765
765
  var MODAL_SIZE_XL = 1040;
766
766
  var MODAL_SIZE_XXL = 1280;
767
767
  var MODAL_SIZE_XXXL = 1600;
768
+ var MODAL_TOP_BOTTOM_MARGIN = 64;
768
769
  var getModalWidthFromSize = (size2) => {
769
770
  switch (size2) {
770
771
  case "XXS":
@@ -816,14 +817,13 @@ var getFullScreenModal = () => {
816
817
  `;
817
818
  };
818
819
  var checkMaxHeight = (height, viewport) => {
819
- const topBottomMargin = 64;
820
820
  if (height > 1200) {
821
- return 1200 - topBottomMargin;
821
+ return 1200 - MODAL_TOP_BOTTOM_MARGIN;
822
822
  }
823
823
  if (height > viewport) {
824
- return viewport - topBottomMargin;
824
+ return viewport - MODAL_TOP_BOTTOM_MARGIN;
825
825
  }
826
- return height - topBottomMargin;
826
+ return height - MODAL_TOP_BOTTOM_MARGIN;
827
827
  };
828
828
  var Container = styled6__default.default.div`
829
829
  ${({ hasChangeAnimation }) => hasChangeAnimation && react$1.css`
@@ -840,9 +840,14 @@ var Container = styled6__default.default.div`
840
840
  box-shadow: ${exports.boxShadowTokens.dropShadow};
841
841
  overflow: hidden;
842
842
  flex-grow: 1;
843
- height: ${({ height, viewport }) => height ? `${checkMaxHeight(height, viewport)}px` : "initial"};
843
+ height: ${({ height, viewport, $fillViewportHeight }) => {
844
+ if ($fillViewportHeight) {
845
+ return `${viewport - MODAL_TOP_BOTTOM_MARGIN}px`;
846
+ }
847
+ return typeof height === "number" ? `${checkMaxHeight(height, viewport)}px` : "initial";
848
+ }};
844
849
  min-height: 180px;
845
- max-height: 1200px;
850
+ max-height: ${({ $fillViewportHeight }) => $fillViewportHeight ? "none" : "1200px"};
846
851
 
847
852
  width: ${({ sizeVar }) => getModalWidthFromSize(sizeVar)}px;
848
853
  max-width: ${({ sizeVar }) => getModalWidthFromSize(sizeVar)}px;
@@ -934,6 +939,12 @@ var useViewportSizeObserver = () => {
934
939
  }, []);
935
940
  return size2;
936
941
  };
942
+ exports.ModalHandlerContext = React.createContext({
943
+ addModal: utils.noop,
944
+ removeModal: utils.noop
945
+ });
946
+ exports.ModalContext = React.createContext([]);
947
+ exports.ModalOutsideClickContext = React.createContext(null);
937
948
  var ModalOptionContext = React.createContext({
938
949
  topHeight: 0,
939
950
  bottomHeight: 0,
@@ -969,9 +980,11 @@ var ModalOptionContextProvider = ({ children }) => {
969
980
  var ModalContainer = (_a) => {
970
981
  var _b = _a, { children, height, outsideClick = utils.noop } = _b, rest = __objRest(_b, ["children", "height", "outsideClick"]);
971
982
  const ref = utils.useParentElementClick(outsideClick);
983
+ const dismissCtx = React.useContext(exports.ModalOutsideClickContext);
972
984
  const { height: windowHeight } = useViewportSizeObserver();
973
985
  const topBottomMargin = 64;
974
- const heightWidthMargin = height ? height + topBottomMargin : void 0;
986
+ const fillViewportHeight = height === "100%" && rest.sizeVar !== "FULL";
987
+ const heightWidthMargin = typeof height === "number" ? height + topBottomMargin : fillViewportHeight ? windowHeight : void 0;
975
988
  const childrenArray = React__namespace.default.Children.toArray(children);
976
989
  const findHeader = childrenArray.find((child) => {
977
990
  if (!React__namespace.default.isValidElement(child)) {
@@ -989,6 +1002,14 @@ var ModalContainer = (_a) => {
989
1002
  return child;
990
1003
  }
991
1004
  });
1005
+ React.useEffect(() => {
1006
+ if (!dismissCtx) {
1007
+ return;
1008
+ }
1009
+ return dismissCtx.registerOutsideClick(() => {
1010
+ outsideClick(null);
1011
+ });
1012
+ }, [dismissCtx, outsideClick]);
992
1013
  const addPropInChildren = React__namespace.default.Children.map(childrenArray, (child) => {
993
1014
  if (!React__namespace.default.isValidElement(child)) {
994
1015
  return child;
@@ -997,10 +1018,24 @@ var ModalContainer = (_a) => {
997
1018
  isIncludeHeader: Boolean(findHeader),
998
1019
  isIncludeFooter: Boolean(findFooter),
999
1020
  sizeVar: rest.sizeVar,
1000
- height: heightWidthMargin
1021
+ height: heightWidthMargin,
1022
+ fillViewportHeight
1001
1023
  });
1002
1024
  });
1003
- return /* @__PURE__ */ jsxRuntime.jsx(Container, __spreadProps(__spreadValues({ ref }, rest), { height: heightWidthMargin, viewport: windowHeight, "data-shoplflow": "Modal", children: /* @__PURE__ */ jsxRuntime.jsx(ModalOptionContextProvider, { children: addPropInChildren }) }));
1025
+ return /* @__PURE__ */ jsxRuntime.jsx(
1026
+ Container,
1027
+ __spreadProps(__spreadValues({
1028
+ ref
1029
+ }, rest), {
1030
+ height: heightWidthMargin,
1031
+ $fillViewportHeight: fillViewportHeight,
1032
+ viewport: windowHeight,
1033
+ "data-shoplflow": "Modal",
1034
+ role: "dialog",
1035
+ "aria-modal": true,
1036
+ children: /* @__PURE__ */ jsxRuntime.jsx(ModalOptionContextProvider, { children: addPropInChildren })
1037
+ })
1038
+ );
1004
1039
  };
1005
1040
  var ModalContainer_default = ModalContainer;
1006
1041
  var ModalFooter = ({ children, padding }) => {
@@ -1050,6 +1085,7 @@ var ModalBody = ({
1050
1085
  isIncludeFooter = false,
1051
1086
  sizeVar,
1052
1087
  height: modalContainerHeight,
1088
+ fillViewportHeight = false,
1053
1089
  padding
1054
1090
  }) => {
1055
1091
  const { height: windowHeight } = useViewportSizeObserver();
@@ -1073,6 +1109,9 @@ var ModalBody = ({
1073
1109
  if (sizeVar === "FULL") {
1074
1110
  return windowHeight - headerFooterHeight - heightToDeduct;
1075
1111
  }
1112
+ if (fillViewportHeight) {
1113
+ return windowHeight - topBottomMargin - headerFooterHeight - heightToDeduct;
1114
+ }
1076
1115
  if (modalContainerHeight) {
1077
1116
  if (modalContainerHeight <= 1200) {
1078
1117
  if (windowHeight < modalContainerHeight) {
@@ -1089,6 +1128,9 @@ var ModalBody = ({
1089
1128
  if (sizeVar === "FULL") {
1090
1129
  return windowHeight;
1091
1130
  }
1131
+ if (fillViewportHeight) {
1132
+ return windowHeight - topBottomMargin - headerFooterHeight;
1133
+ }
1092
1134
  if (modalContainerHeight) {
1093
1135
  if (modalContainerHeight > 1200) {
1094
1136
  return 1200 - topBottomMargin - headerFooterHeight;
@@ -1193,13 +1235,6 @@ var ModalBottom = ({ children }) => {
1193
1235
  }, [bottomRef, setBottomHeight, clearBottomHeight]);
1194
1236
  return /* @__PURE__ */ jsxRuntime.jsx(BottomContainer, { ref: setBottomRef, children });
1195
1237
  };
1196
- exports.ModalHandlerContext = React.createContext({
1197
- addModal: utils.noop,
1198
- removeModal: utils.noop
1199
- });
1200
- exports.ModalContext = React.createContext([]);
1201
-
1202
- // src/components/Modal/hooks/useModalValue.ts
1203
1238
  exports.useModalValue = () => {
1204
1239
  const modal = React.useContext(exports.ModalContext);
1205
1240
  return {
@@ -1215,6 +1250,27 @@ exports.useHandleModal = () => {
1215
1250
  };
1216
1251
  var ModalProvider = ({ children }) => {
1217
1252
  const [openedModals, setOpenedModals] = React.useState([]);
1253
+ const dismissStackRef = React.useRef([]);
1254
+ const registerOutsideClick = React.useCallback((fn) => {
1255
+ dismissStackRef.current.push(fn);
1256
+ return () => {
1257
+ const idx = dismissStackRef.current.lastIndexOf(fn);
1258
+ if (idx !== -1) {
1259
+ dismissStackRef.current.splice(idx, 1);
1260
+ }
1261
+ };
1262
+ }, []);
1263
+ const requestOutsideClick = React.useCallback(() => {
1264
+ const top = dismissStackRef.current[dismissStackRef.current.length - 1];
1265
+ top == null ? void 0 : top();
1266
+ }, []);
1267
+ const dismissRegistry = React.useMemo(
1268
+ () => ({
1269
+ registerOutsideClick,
1270
+ requestOutsideClick
1271
+ }),
1272
+ [registerOutsideClick, requestOutsideClick]
1273
+ );
1218
1274
  const addModal = (component, id, zIndex) => {
1219
1275
  setOpenedModals((modals) => {
1220
1276
  if (modals) {
@@ -1262,14 +1318,17 @@ var ModalProvider = ({ children }) => {
1262
1318
  };
1263
1319
  const dispatch = React.useMemo(() => ({ addModal, removeModal }), []);
1264
1320
  React.useEffect(() => {
1265
- if (openedModals.length !== 1) {
1266
- return;
1321
+ if (openedModals.length > 0) {
1322
+ document.body.style.overflow = "hidden";
1323
+ } else {
1324
+ document.body.style.overflow = "";
1267
1325
  }
1268
- document.body.style.cssText = "overflow:hidden";
1326
+ }, [openedModals.length]);
1327
+ React.useEffect(() => {
1269
1328
  return () => {
1270
- document.body.style.cssText = "overflow:unset";
1329
+ document.body.style.overflow = "";
1271
1330
  };
1272
- }, [openedModals.length]);
1331
+ }, []);
1273
1332
  React.useEffect(() => {
1274
1333
  const closeAllModals = () => {
1275
1334
  setOpenedModals([]);
@@ -1279,7 +1338,7 @@ var ModalProvider = ({ children }) => {
1279
1338
  window.removeEventListener("popstate", closeAllModals);
1280
1339
  };
1281
1340
  }, []);
1282
- return /* @__PURE__ */ jsxRuntime.jsx(exports.ModalContext.Provider, { value: openedModals, children: /* @__PURE__ */ jsxRuntime.jsx(exports.ModalHandlerContext.Provider, { value: dispatch, children }) });
1341
+ return /* @__PURE__ */ jsxRuntime.jsx(exports.ModalContext.Provider, { value: openedModals, children: /* @__PURE__ */ jsxRuntime.jsx(exports.ModalOutsideClickContext.Provider, { value: dismissRegistry, children: /* @__PURE__ */ jsxRuntime.jsx(exports.ModalHandlerContext.Provider, { value: dispatch, children }) }) });
1283
1342
  };
1284
1343
  var ModalProvider_default = ModalProvider;
1285
1344
 
@@ -5025,41 +5084,29 @@ var PaginationWrapper = styled6__default.default.div`
5025
5084
  width: 100%;
5026
5085
  justify-content: space-between;
5027
5086
 
5028
- /* Shopl: Figma pagenation bar 양끝은 흐름 배치, 네비는 전체 기준 absolute 중앙 (node 13760:25910) */
5087
+ /* Shopl: 좌/우 아이템 폭과 개수와 무관하게 네비를 고정 중앙에 둔다. */
5029
5088
  ${({ $centerNav }) => $centerNav && react$1.css`
5030
- position: relative;
5031
- justify-content: space-between;
5089
+ display: grid;
5090
+ grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
5091
+ align-items: center;
5092
+ column-gap: 8px;
5032
5093
 
5033
- /* div → nav → div 이므로 nth-of-type(2)는 두 번째 div(우측)만 잡힘 → 반드시 nth-child */
5034
5094
  & > *:nth-child(1) {
5035
- position: relative;
5036
- z-index: 2;
5037
- flex-shrink: 0;
5038
5095
  display: flex;
5039
5096
  align-items: center;
5040
5097
  justify-content: flex-start;
5098
+ min-width: 0;
5099
+ overflow: hidden;
5041
5100
  }
5042
5101
  & > *:nth-child(2) {
5043
- position: absolute;
5044
- left: 50%;
5045
- top: 50%;
5046
- z-index: 1;
5047
- transform: translate(-50%, -50%);
5048
- width: max-content;
5049
- max-width: 100%;
5050
- pointer-events: none;
5051
-
5052
- & > * {
5053
- pointer-events: auto;
5054
- }
5102
+ justify-self: center;
5055
5103
  }
5056
5104
  & > *:nth-child(3) {
5057
- position: relative;
5058
- z-index: 2;
5059
- flex-shrink: 0;
5060
5105
  display: flex;
5061
5106
  align-items: center;
5062
5107
  justify-content: flex-end;
5108
+ min-width: 0;
5109
+ overflow: hidden;
5063
5110
  }
5064
5111
  `}
5065
5112
 
@@ -7779,6 +7826,24 @@ var SpaceMarginWrapper = styled6__default.default(framerMotion.motion.div)`
7779
7826
  `;
7780
7827
  var ModalPortal = () => {
7781
7828
  const modal = React.useContext(exports.ModalContext);
7829
+ const dismissRegistry = React.useContext(exports.ModalOutsideClickContext);
7830
+ React.useEffect(() => {
7831
+ if (!dismissRegistry) {
7832
+ return;
7833
+ }
7834
+ const onKeyDown = (event) => {
7835
+ if (event.key !== "Escape") {
7836
+ return;
7837
+ }
7838
+ if (modal.length === 0) {
7839
+ return;
7840
+ }
7841
+ event.preventDefault();
7842
+ dismissRegistry.requestOutsideClick();
7843
+ };
7844
+ document.addEventListener("keydown", onKeyDown);
7845
+ return () => document.removeEventListener("keydown", onKeyDown);
7846
+ }, [dismissRegistry, modal.length]);
7782
7847
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: reactDom$1.createPortal(
7783
7848
  /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: modal.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(BackDrop_default, { zIndex: item.zIndex, children: /* @__PURE__ */ jsxRuntime.jsx(SpaceMarginWrapper, { children: item.component }) }, index)) }),
7784
7849
  document.body
package/dist/index.d.cts CHANGED
@@ -490,11 +490,16 @@ interface ModalContainerProps extends ModalContainerOptionProps, SizeVariantProp
490
490
  interface ModalContainerOptionProps {
491
491
  /**
492
492
  * 모달의 높이를 설정합니다.
493
+ * - number: px 기준 높이
494
+ * - '100%': 뷰포트 높이에서 상하 여백(64px)을 제외한 높이
495
+ * (sizeVar='FULL'에서는 적용되지 않습니다.)
493
496
  */
494
- height?: number;
497
+ height?: number | '100%';
495
498
  /**
496
- * 모달의 외부를 클릭했을 때 실행되는 함수입니다.
497
- * @param args
499
+ * 모달 컨테이너 바깥(백드롭 등)을 클릭했을 때 실행됩니다.
500
+ * Escape 키를 눌렀을 때도 같은 함수가 호출됩니다. 모달이 여러 겹이면 Escape는 스택 최상단(가장 최근에 연) 모달에만 적용됩니다.
501
+ *
502
+ * @param args 바깥 클릭 시 전달되는 클릭 이벤트(`Event`).
498
503
  */
499
504
  outsideClick?: (args?: any) => void;
500
505
  }
@@ -512,6 +517,7 @@ interface ModalBodyOptionProps {
512
517
  isIncludeHeader?: boolean;
513
518
  isIncludeFooter?: boolean;
514
519
  height?: number;
520
+ fillViewportHeight?: boolean;
515
521
  sizeVar?: ModalSizeType;
516
522
  padding?: CSSProperties['padding'];
517
523
  }
@@ -548,6 +554,14 @@ type ModalHandlerContext = {
548
554
  declare const ModalHandlerContext: react.Context<ModalHandlerContext>;
549
555
  type ModalContext = ModalStateType[];
550
556
  declare const ModalContext: react.Context<ModalContext>;
557
+ /** ESC 시 최상단 모달의 outsideClick과 동일한 경로를 호출하기 위한 등록소 */
558
+ type ModalOutsideClickHandlers = {
559
+ /** 레이어 마운트 시 outsideClick과 동일한 닫기 동작 등록, 언마운트 시 해제 */
560
+ registerOutsideClick: (fn: () => void) => () => void;
561
+ /** ESC 시 최상단 레이어에 대해 위와 동일한 동작 실행 */
562
+ requestOutsideClick: () => void;
563
+ };
564
+ declare const ModalOutsideClickContext: react.Context<ModalOutsideClickHandlers | null>;
551
565
 
552
566
  declare const useModalValue: () => {
553
567
  modal: ModalContext;
@@ -559,10 +573,10 @@ declare const useHandleModal: () => {
559
573
  };
560
574
 
561
575
  declare const Modal: {
562
- Container: ({ children, height, outsideClick, ...rest }: ModalContainerProps) => react_jsx_runtime.JSX.Element;
576
+ Container: ({ children, height, outsideClick, ...rest }: ModalContainerProps) => JSX.Element;
563
577
  Header: ModalHeaderType;
564
578
  Top: ({ children }: ModalTopProps) => react_jsx_runtime.JSX.Element;
565
- Body: ({ children, isIncludeHeader, isIncludeFooter, sizeVar, height: modalContainerHeight, padding, }: ModalBodyProps) => react_jsx_runtime.JSX.Element;
579
+ Body: ({ children, isIncludeHeader, isIncludeFooter, sizeVar, height: modalContainerHeight, fillViewportHeight, padding, }: ModalBodyProps) => react_jsx_runtime.JSX.Element;
566
580
  Bottom: ({ children }: ModalBottomProps) => react_jsx_runtime.JSX.Element;
567
581
  Footer: ModalFooterType;
568
582
  };
@@ -1790,4 +1804,4 @@ type HelperTextProps = HelperTextOptionProps & Omit<TextProps, 'typography'>;
1790
1804
 
1791
1805
  declare const HelperText: ({ type, position, color, ...rest }: HelperTextProps) => react_jsx_runtime.JSX.Element;
1792
1806
 
1793
- export { AnnualDatepicker, AnnualDatepickerProps, AsProp, Avatar, AvatarOptionProps, AvatarProps, AvatarSizeVariantType, AvatarSizeVariants, BackDropOptionProps, BackDropProps, BorderRadiusTokens, BoxShadowTokens, BulletHelperTextOptionProps, Button, ButtonComponent, ButtonOptionProps, ButtonProps, ButtonSizeVariantType, ButtonSizeVariants, ButtonStyleVariantType, ButtonStyleVariants, CHECKBOX_SYMBOL_KEY, Callout, CalloutIconProps, CalloutOptionProps, CalloutProps, CalloutType, CalloutTypes, Checkbox, CheckboxOptionProps, CheckboxProps, CheckboxStyleVariantType, CheckboxStyleVariants, ChildrenProps, ChipButton, ChipButtonOptionProps, ChipButtonProps, ChipButtonSizeVariantType, ChipButtonSizeVariants, ChipButtonStyleVariantType, ChipButtonStyleVariants, ChipToggle, ChipToggleOptionProps, ChipToggleProps, ChipToggleSizeVariantType, ChipToggleSizeVariants, ChipToggleStyleVariantType, ChipToggleStyleVariants, ColorTokens, DangerouslySetInnerHTML, DayCalendarType, DayDatepicker, DayDatepickerHeaderCustomProps, DayDatepickerOptionProps, DayDatepickerProps, DayDatepickerSizeVariantType, DayDatepickerSizeVariants, DomainType, Dropdown, DropdownButton, DropdownButtonContext, DropdownButtonContextType, DropdownButtonOptionProps, DropdownButtonProps, DropdownButtonSizeVariantType, DropdownButtonSizeVariants, DropdownButtonStyleVariantType, DropdownButtonStyleVariants, DropdownContentProps, DropdownItem, DropdownOptionProps, DropdownOptionVariantType, DropdownOptionVariants, DropdownProps, DropdownSizeVariantType, DropdownStyleVariantType, DropdownTriggerButtonProps, FontWeightTokens, HelperText, HelperTextOptionProps, HelperTextProps, Icon, IconButton, IconButtonComponent, IconButtonOptionProps, IconButtonProps, IconButtonSizeVariantType, IconButtonSizeVariants, IconButtonStyleVariantType, IconButtonStyleVariants, IconOptionProps, IconProps, IconSizeVariants, IconSizeVariantsType, Input, InputButton, InputButtonOptionProps, InputButtonProps, InputOptionProps, InputProps, InputSizeVariantType, InputSizeVariants, List, ListContent2ColumnsProps, ListOptionProps, ListProps, ListText2RowsProps, MODAL_FOOTER_KEY, MODAL_HEADER_KEY, MemoizedSearchBarComponent, Menu, MenuOptionProps, MenuProps, MenuSizeVariantType, MenuSizeVariants, MinusBoxOptionProps, MinusBoxProps, MinusButton, Modal, ModalBodyOptionProps, ModalBodyProps, ModalBottomProps, ModalContainerOptionProps, ModalContainerProps, ModalContext, ModalFooterOptionProps, ModalFooterProps, ModalFooterType, ModalHandlerContext, ModalHeaderOptionProps, ModalHeaderProps, ModalHeaderType, ModalPortal as ModalProvider, ModalSize, ModalSizeType, ModalStateType, ModalTopProps, MonthClickDateInfo, MonthDatepicker, MonthDatepickerProps, MonthDatepickerStyleType, MotionStack, MotionStackComponentType, MotionStackContainer, MotionStackContainerComponentType, NormalHelperTextOptionProps, NumberCombobox, NumberComboboxErrorType, NumberComboboxInputType, NumberComboboxOptionProps, NumberComboboxProps, NumberComboboxSizeVariantType, NumberComboboxSizeVariants, Pagination, PaginationOptionProps, PaginationProps, PaginationSizeSelectorProps, PolymorphicComponentProps, PolymorphicRef, Popper, PopperOptionProps, PopperPortal, PopperPortalProps, PopperProps, PopperTrigger, PopperTriggerProps, RADIO_SYMBOL_KEY, Radio, RadioOptionProps, RadioProps, RemoveModalProps, SLIDER_Z_INDEX, ScrollArea, ScrollAreaOptionProps, ScrollAreaProps, ScrollbarRefType, SearchBar, SearchBarBaseProps, SearchBarCategoryProps, SearchBarComponent, SearchBarInputProps, SearchBarProps, SearchType, SelectInputButton, SelectInputButtonOptionProps, SelectInputButtonProps, ShoplflowProvider, ShoplflowProviderProps, Skeleton, SkeletonProps, Slider, SliderBounds, SliderProps, SpacingTokens, SplitButton, SplitButtonContext, SplitButtonContextType, SplitButtonOptionProps, SplitButtonProps, SplitButtonSizeVariantType, SplitButtonSizeVariants, SplitButtonStyleVariantType, SplitButtonStyleVariants, Stack, StackComponentType, StackContainer, StackContainerComponentType, StackContainerGenericProps, StackContainerOptionProps, StackContainerProps, StackGenericProps, StackOptionProps, StackProps, StyledIcon, StyledStack, StyledStackContainer, Switch, SwitchOptionProps, SwitchProps, SwitchSizeVariantType, SwitchSizeVariants, TREE_SYMBOL_KEY, TabOptionProps, TabProps, TabSizeVariantType, TabSizeVariants, TabStyleVariantType, TabStyleVariants, TabStyledProps, TabTextStyledProps, Tabs, TabsContext, TabsContextType, TabsOptionProps, TabsProps, Tag, TagOptionProps, TagProps, TagSizeVariantType, TagSizeVariants, TagStyleVariantType, TagStyleVariants, Text, Text2Rows, TextArea, TextAreaOptionProps, TextAreaProps, TextOptionProps, TextProps, ToggleButton, ToggleButtonInnerRadioOptionProps, ToggleButtonInnerRadioProps, ToggleButtonOptionProps, ToggleButtonProps, ToggleButtonSizeVariantType, ToggleButtonSizeVariants, Tooltip, TooltipContentProps, TooltipOptionProps, TooltipProps, Tree, TreeItem, TreeItemOptionProps, TreeItemProps, TreeOptionProps, TreeProps, TypographyTokens, WeekClickDateInfo, WeekDatepicker, WeekDatepickerProps, WeekDatepickerStyleType, YearSelectProps, borderRadiusTokens, boxShadowTokens, colorTokens, fontWeightTokens, getDomain, spacingTokens, typographyTokens, useDomain, useDropdownButtonContext, useHandleModal, useModalValue, useSplitButtonContext, useTabs };
1807
+ export { AnnualDatepicker, AnnualDatepickerProps, AsProp, Avatar, AvatarOptionProps, AvatarProps, AvatarSizeVariantType, AvatarSizeVariants, BackDropOptionProps, BackDropProps, BorderRadiusTokens, BoxShadowTokens, BulletHelperTextOptionProps, Button, ButtonComponent, ButtonOptionProps, ButtonProps, ButtonSizeVariantType, ButtonSizeVariants, ButtonStyleVariantType, ButtonStyleVariants, CHECKBOX_SYMBOL_KEY, Callout, CalloutIconProps, CalloutOptionProps, CalloutProps, CalloutType, CalloutTypes, Checkbox, CheckboxOptionProps, CheckboxProps, CheckboxStyleVariantType, CheckboxStyleVariants, ChildrenProps, ChipButton, ChipButtonOptionProps, ChipButtonProps, ChipButtonSizeVariantType, ChipButtonSizeVariants, ChipButtonStyleVariantType, ChipButtonStyleVariants, ChipToggle, ChipToggleOptionProps, ChipToggleProps, ChipToggleSizeVariantType, ChipToggleSizeVariants, ChipToggleStyleVariantType, ChipToggleStyleVariants, ColorTokens, DangerouslySetInnerHTML, DayCalendarType, DayDatepicker, DayDatepickerHeaderCustomProps, DayDatepickerOptionProps, DayDatepickerProps, DayDatepickerSizeVariantType, DayDatepickerSizeVariants, DomainType, Dropdown, DropdownButton, DropdownButtonContext, DropdownButtonContextType, DropdownButtonOptionProps, DropdownButtonProps, DropdownButtonSizeVariantType, DropdownButtonSizeVariants, DropdownButtonStyleVariantType, DropdownButtonStyleVariants, DropdownContentProps, DropdownItem, DropdownOptionProps, DropdownOptionVariantType, DropdownOptionVariants, DropdownProps, DropdownSizeVariantType, DropdownStyleVariantType, DropdownTriggerButtonProps, FontWeightTokens, HelperText, HelperTextOptionProps, HelperTextProps, Icon, IconButton, IconButtonComponent, IconButtonOptionProps, IconButtonProps, IconButtonSizeVariantType, IconButtonSizeVariants, IconButtonStyleVariantType, IconButtonStyleVariants, IconOptionProps, IconProps, IconSizeVariants, IconSizeVariantsType, Input, InputButton, InputButtonOptionProps, InputButtonProps, InputOptionProps, InputProps, InputSizeVariantType, InputSizeVariants, List, ListContent2ColumnsProps, ListOptionProps, ListProps, ListText2RowsProps, MODAL_FOOTER_KEY, MODAL_HEADER_KEY, MemoizedSearchBarComponent, Menu, MenuOptionProps, MenuProps, MenuSizeVariantType, MenuSizeVariants, MinusBoxOptionProps, MinusBoxProps, MinusButton, Modal, ModalBodyOptionProps, ModalBodyProps, ModalBottomProps, ModalContainerOptionProps, ModalContainerProps, ModalContext, ModalFooterOptionProps, ModalFooterProps, ModalFooterType, ModalHandlerContext, ModalHeaderOptionProps, ModalHeaderProps, ModalHeaderType, ModalOutsideClickContext, ModalOutsideClickHandlers, ModalPortal as ModalProvider, ModalSize, ModalSizeType, ModalStateType, ModalTopProps, MonthClickDateInfo, MonthDatepicker, MonthDatepickerProps, MonthDatepickerStyleType, MotionStack, MotionStackComponentType, MotionStackContainer, MotionStackContainerComponentType, NormalHelperTextOptionProps, NumberCombobox, NumberComboboxErrorType, NumberComboboxInputType, NumberComboboxOptionProps, NumberComboboxProps, NumberComboboxSizeVariantType, NumberComboboxSizeVariants, Pagination, PaginationOptionProps, PaginationProps, PaginationSizeSelectorProps, PolymorphicComponentProps, PolymorphicRef, Popper, PopperOptionProps, PopperPortal, PopperPortalProps, PopperProps, PopperTrigger, PopperTriggerProps, RADIO_SYMBOL_KEY, Radio, RadioOptionProps, RadioProps, RemoveModalProps, SLIDER_Z_INDEX, ScrollArea, ScrollAreaOptionProps, ScrollAreaProps, ScrollbarRefType, SearchBar, SearchBarBaseProps, SearchBarCategoryProps, SearchBarComponent, SearchBarInputProps, SearchBarProps, SearchType, SelectInputButton, SelectInputButtonOptionProps, SelectInputButtonProps, ShoplflowProvider, ShoplflowProviderProps, Skeleton, SkeletonProps, Slider, SliderBounds, SliderProps, SpacingTokens, SplitButton, SplitButtonContext, SplitButtonContextType, SplitButtonOptionProps, SplitButtonProps, SplitButtonSizeVariantType, SplitButtonSizeVariants, SplitButtonStyleVariantType, SplitButtonStyleVariants, Stack, StackComponentType, StackContainer, StackContainerComponentType, StackContainerGenericProps, StackContainerOptionProps, StackContainerProps, StackGenericProps, StackOptionProps, StackProps, StyledIcon, StyledStack, StyledStackContainer, Switch, SwitchOptionProps, SwitchProps, SwitchSizeVariantType, SwitchSizeVariants, TREE_SYMBOL_KEY, TabOptionProps, TabProps, TabSizeVariantType, TabSizeVariants, TabStyleVariantType, TabStyleVariants, TabStyledProps, TabTextStyledProps, Tabs, TabsContext, TabsContextType, TabsOptionProps, TabsProps, Tag, TagOptionProps, TagProps, TagSizeVariantType, TagSizeVariants, TagStyleVariantType, TagStyleVariants, Text, Text2Rows, TextArea, TextAreaOptionProps, TextAreaProps, TextOptionProps, TextProps, ToggleButton, ToggleButtonInnerRadioOptionProps, ToggleButtonInnerRadioProps, ToggleButtonOptionProps, ToggleButtonProps, ToggleButtonSizeVariantType, ToggleButtonSizeVariants, Tooltip, TooltipContentProps, TooltipOptionProps, TooltipProps, Tree, TreeItem, TreeItemOptionProps, TreeItemProps, TreeOptionProps, TreeProps, TypographyTokens, WeekClickDateInfo, WeekDatepicker, WeekDatepickerProps, WeekDatepickerStyleType, YearSelectProps, borderRadiusTokens, boxShadowTokens, colorTokens, fontWeightTokens, getDomain, spacingTokens, typographyTokens, useDomain, useDropdownButtonContext, useHandleModal, useModalValue, useSplitButtonContext, useTabs };
package/dist/index.d.ts CHANGED
@@ -490,11 +490,16 @@ interface ModalContainerProps extends ModalContainerOptionProps, SizeVariantProp
490
490
  interface ModalContainerOptionProps {
491
491
  /**
492
492
  * 모달의 높이를 설정합니다.
493
+ * - number: px 기준 높이
494
+ * - '100%': 뷰포트 높이에서 상하 여백(64px)을 제외한 높이
495
+ * (sizeVar='FULL'에서는 적용되지 않습니다.)
493
496
  */
494
- height?: number;
497
+ height?: number | '100%';
495
498
  /**
496
- * 모달의 외부를 클릭했을 때 실행되는 함수입니다.
497
- * @param args
499
+ * 모달 컨테이너 바깥(백드롭 등)을 클릭했을 때 실행됩니다.
500
+ * Escape 키를 눌렀을 때도 같은 함수가 호출됩니다. 모달이 여러 겹이면 Escape는 스택 최상단(가장 최근에 연) 모달에만 적용됩니다.
501
+ *
502
+ * @param args 바깥 클릭 시 전달되는 클릭 이벤트(`Event`).
498
503
  */
499
504
  outsideClick?: (args?: any) => void;
500
505
  }
@@ -512,6 +517,7 @@ interface ModalBodyOptionProps {
512
517
  isIncludeHeader?: boolean;
513
518
  isIncludeFooter?: boolean;
514
519
  height?: number;
520
+ fillViewportHeight?: boolean;
515
521
  sizeVar?: ModalSizeType;
516
522
  padding?: CSSProperties['padding'];
517
523
  }
@@ -548,6 +554,14 @@ type ModalHandlerContext = {
548
554
  declare const ModalHandlerContext: react.Context<ModalHandlerContext>;
549
555
  type ModalContext = ModalStateType[];
550
556
  declare const ModalContext: react.Context<ModalContext>;
557
+ /** ESC 시 최상단 모달의 outsideClick과 동일한 경로를 호출하기 위한 등록소 */
558
+ type ModalOutsideClickHandlers = {
559
+ /** 레이어 마운트 시 outsideClick과 동일한 닫기 동작 등록, 언마운트 시 해제 */
560
+ registerOutsideClick: (fn: () => void) => () => void;
561
+ /** ESC 시 최상단 레이어에 대해 위와 동일한 동작 실행 */
562
+ requestOutsideClick: () => void;
563
+ };
564
+ declare const ModalOutsideClickContext: react.Context<ModalOutsideClickHandlers | null>;
551
565
 
552
566
  declare const useModalValue: () => {
553
567
  modal: ModalContext;
@@ -559,10 +573,10 @@ declare const useHandleModal: () => {
559
573
  };
560
574
 
561
575
  declare const Modal: {
562
- Container: ({ children, height, outsideClick, ...rest }: ModalContainerProps) => react_jsx_runtime.JSX.Element;
576
+ Container: ({ children, height, outsideClick, ...rest }: ModalContainerProps) => JSX.Element;
563
577
  Header: ModalHeaderType;
564
578
  Top: ({ children }: ModalTopProps) => react_jsx_runtime.JSX.Element;
565
- Body: ({ children, isIncludeHeader, isIncludeFooter, sizeVar, height: modalContainerHeight, padding, }: ModalBodyProps) => react_jsx_runtime.JSX.Element;
579
+ Body: ({ children, isIncludeHeader, isIncludeFooter, sizeVar, height: modalContainerHeight, fillViewportHeight, padding, }: ModalBodyProps) => react_jsx_runtime.JSX.Element;
566
580
  Bottom: ({ children }: ModalBottomProps) => react_jsx_runtime.JSX.Element;
567
581
  Footer: ModalFooterType;
568
582
  };
@@ -1790,4 +1804,4 @@ type HelperTextProps = HelperTextOptionProps & Omit<TextProps, 'typography'>;
1790
1804
 
1791
1805
  declare const HelperText: ({ type, position, color, ...rest }: HelperTextProps) => react_jsx_runtime.JSX.Element;
1792
1806
 
1793
- export { AnnualDatepicker, AnnualDatepickerProps, AsProp, Avatar, AvatarOptionProps, AvatarProps, AvatarSizeVariantType, AvatarSizeVariants, BackDropOptionProps, BackDropProps, BorderRadiusTokens, BoxShadowTokens, BulletHelperTextOptionProps, Button, ButtonComponent, ButtonOptionProps, ButtonProps, ButtonSizeVariantType, ButtonSizeVariants, ButtonStyleVariantType, ButtonStyleVariants, CHECKBOX_SYMBOL_KEY, Callout, CalloutIconProps, CalloutOptionProps, CalloutProps, CalloutType, CalloutTypes, Checkbox, CheckboxOptionProps, CheckboxProps, CheckboxStyleVariantType, CheckboxStyleVariants, ChildrenProps, ChipButton, ChipButtonOptionProps, ChipButtonProps, ChipButtonSizeVariantType, ChipButtonSizeVariants, ChipButtonStyleVariantType, ChipButtonStyleVariants, ChipToggle, ChipToggleOptionProps, ChipToggleProps, ChipToggleSizeVariantType, ChipToggleSizeVariants, ChipToggleStyleVariantType, ChipToggleStyleVariants, ColorTokens, DangerouslySetInnerHTML, DayCalendarType, DayDatepicker, DayDatepickerHeaderCustomProps, DayDatepickerOptionProps, DayDatepickerProps, DayDatepickerSizeVariantType, DayDatepickerSizeVariants, DomainType, Dropdown, DropdownButton, DropdownButtonContext, DropdownButtonContextType, DropdownButtonOptionProps, DropdownButtonProps, DropdownButtonSizeVariantType, DropdownButtonSizeVariants, DropdownButtonStyleVariantType, DropdownButtonStyleVariants, DropdownContentProps, DropdownItem, DropdownOptionProps, DropdownOptionVariantType, DropdownOptionVariants, DropdownProps, DropdownSizeVariantType, DropdownStyleVariantType, DropdownTriggerButtonProps, FontWeightTokens, HelperText, HelperTextOptionProps, HelperTextProps, Icon, IconButton, IconButtonComponent, IconButtonOptionProps, IconButtonProps, IconButtonSizeVariantType, IconButtonSizeVariants, IconButtonStyleVariantType, IconButtonStyleVariants, IconOptionProps, IconProps, IconSizeVariants, IconSizeVariantsType, Input, InputButton, InputButtonOptionProps, InputButtonProps, InputOptionProps, InputProps, InputSizeVariantType, InputSizeVariants, List, ListContent2ColumnsProps, ListOptionProps, ListProps, ListText2RowsProps, MODAL_FOOTER_KEY, MODAL_HEADER_KEY, MemoizedSearchBarComponent, Menu, MenuOptionProps, MenuProps, MenuSizeVariantType, MenuSizeVariants, MinusBoxOptionProps, MinusBoxProps, MinusButton, Modal, ModalBodyOptionProps, ModalBodyProps, ModalBottomProps, ModalContainerOptionProps, ModalContainerProps, ModalContext, ModalFooterOptionProps, ModalFooterProps, ModalFooterType, ModalHandlerContext, ModalHeaderOptionProps, ModalHeaderProps, ModalHeaderType, ModalPortal as ModalProvider, ModalSize, ModalSizeType, ModalStateType, ModalTopProps, MonthClickDateInfo, MonthDatepicker, MonthDatepickerProps, MonthDatepickerStyleType, MotionStack, MotionStackComponentType, MotionStackContainer, MotionStackContainerComponentType, NormalHelperTextOptionProps, NumberCombobox, NumberComboboxErrorType, NumberComboboxInputType, NumberComboboxOptionProps, NumberComboboxProps, NumberComboboxSizeVariantType, NumberComboboxSizeVariants, Pagination, PaginationOptionProps, PaginationProps, PaginationSizeSelectorProps, PolymorphicComponentProps, PolymorphicRef, Popper, PopperOptionProps, PopperPortal, PopperPortalProps, PopperProps, PopperTrigger, PopperTriggerProps, RADIO_SYMBOL_KEY, Radio, RadioOptionProps, RadioProps, RemoveModalProps, SLIDER_Z_INDEX, ScrollArea, ScrollAreaOptionProps, ScrollAreaProps, ScrollbarRefType, SearchBar, SearchBarBaseProps, SearchBarCategoryProps, SearchBarComponent, SearchBarInputProps, SearchBarProps, SearchType, SelectInputButton, SelectInputButtonOptionProps, SelectInputButtonProps, ShoplflowProvider, ShoplflowProviderProps, Skeleton, SkeletonProps, Slider, SliderBounds, SliderProps, SpacingTokens, SplitButton, SplitButtonContext, SplitButtonContextType, SplitButtonOptionProps, SplitButtonProps, SplitButtonSizeVariantType, SplitButtonSizeVariants, SplitButtonStyleVariantType, SplitButtonStyleVariants, Stack, StackComponentType, StackContainer, StackContainerComponentType, StackContainerGenericProps, StackContainerOptionProps, StackContainerProps, StackGenericProps, StackOptionProps, StackProps, StyledIcon, StyledStack, StyledStackContainer, Switch, SwitchOptionProps, SwitchProps, SwitchSizeVariantType, SwitchSizeVariants, TREE_SYMBOL_KEY, TabOptionProps, TabProps, TabSizeVariantType, TabSizeVariants, TabStyleVariantType, TabStyleVariants, TabStyledProps, TabTextStyledProps, Tabs, TabsContext, TabsContextType, TabsOptionProps, TabsProps, Tag, TagOptionProps, TagProps, TagSizeVariantType, TagSizeVariants, TagStyleVariantType, TagStyleVariants, Text, Text2Rows, TextArea, TextAreaOptionProps, TextAreaProps, TextOptionProps, TextProps, ToggleButton, ToggleButtonInnerRadioOptionProps, ToggleButtonInnerRadioProps, ToggleButtonOptionProps, ToggleButtonProps, ToggleButtonSizeVariantType, ToggleButtonSizeVariants, Tooltip, TooltipContentProps, TooltipOptionProps, TooltipProps, Tree, TreeItem, TreeItemOptionProps, TreeItemProps, TreeOptionProps, TreeProps, TypographyTokens, WeekClickDateInfo, WeekDatepicker, WeekDatepickerProps, WeekDatepickerStyleType, YearSelectProps, borderRadiusTokens, boxShadowTokens, colorTokens, fontWeightTokens, getDomain, spacingTokens, typographyTokens, useDomain, useDropdownButtonContext, useHandleModal, useModalValue, useSplitButtonContext, useTabs };
1807
+ export { AnnualDatepicker, AnnualDatepickerProps, AsProp, Avatar, AvatarOptionProps, AvatarProps, AvatarSizeVariantType, AvatarSizeVariants, BackDropOptionProps, BackDropProps, BorderRadiusTokens, BoxShadowTokens, BulletHelperTextOptionProps, Button, ButtonComponent, ButtonOptionProps, ButtonProps, ButtonSizeVariantType, ButtonSizeVariants, ButtonStyleVariantType, ButtonStyleVariants, CHECKBOX_SYMBOL_KEY, Callout, CalloutIconProps, CalloutOptionProps, CalloutProps, CalloutType, CalloutTypes, Checkbox, CheckboxOptionProps, CheckboxProps, CheckboxStyleVariantType, CheckboxStyleVariants, ChildrenProps, ChipButton, ChipButtonOptionProps, ChipButtonProps, ChipButtonSizeVariantType, ChipButtonSizeVariants, ChipButtonStyleVariantType, ChipButtonStyleVariants, ChipToggle, ChipToggleOptionProps, ChipToggleProps, ChipToggleSizeVariantType, ChipToggleSizeVariants, ChipToggleStyleVariantType, ChipToggleStyleVariants, ColorTokens, DangerouslySetInnerHTML, DayCalendarType, DayDatepicker, DayDatepickerHeaderCustomProps, DayDatepickerOptionProps, DayDatepickerProps, DayDatepickerSizeVariantType, DayDatepickerSizeVariants, DomainType, Dropdown, DropdownButton, DropdownButtonContext, DropdownButtonContextType, DropdownButtonOptionProps, DropdownButtonProps, DropdownButtonSizeVariantType, DropdownButtonSizeVariants, DropdownButtonStyleVariantType, DropdownButtonStyleVariants, DropdownContentProps, DropdownItem, DropdownOptionProps, DropdownOptionVariantType, DropdownOptionVariants, DropdownProps, DropdownSizeVariantType, DropdownStyleVariantType, DropdownTriggerButtonProps, FontWeightTokens, HelperText, HelperTextOptionProps, HelperTextProps, Icon, IconButton, IconButtonComponent, IconButtonOptionProps, IconButtonProps, IconButtonSizeVariantType, IconButtonSizeVariants, IconButtonStyleVariantType, IconButtonStyleVariants, IconOptionProps, IconProps, IconSizeVariants, IconSizeVariantsType, Input, InputButton, InputButtonOptionProps, InputButtonProps, InputOptionProps, InputProps, InputSizeVariantType, InputSizeVariants, List, ListContent2ColumnsProps, ListOptionProps, ListProps, ListText2RowsProps, MODAL_FOOTER_KEY, MODAL_HEADER_KEY, MemoizedSearchBarComponent, Menu, MenuOptionProps, MenuProps, MenuSizeVariantType, MenuSizeVariants, MinusBoxOptionProps, MinusBoxProps, MinusButton, Modal, ModalBodyOptionProps, ModalBodyProps, ModalBottomProps, ModalContainerOptionProps, ModalContainerProps, ModalContext, ModalFooterOptionProps, ModalFooterProps, ModalFooterType, ModalHandlerContext, ModalHeaderOptionProps, ModalHeaderProps, ModalHeaderType, ModalOutsideClickContext, ModalOutsideClickHandlers, ModalPortal as ModalProvider, ModalSize, ModalSizeType, ModalStateType, ModalTopProps, MonthClickDateInfo, MonthDatepicker, MonthDatepickerProps, MonthDatepickerStyleType, MotionStack, MotionStackComponentType, MotionStackContainer, MotionStackContainerComponentType, NormalHelperTextOptionProps, NumberCombobox, NumberComboboxErrorType, NumberComboboxInputType, NumberComboboxOptionProps, NumberComboboxProps, NumberComboboxSizeVariantType, NumberComboboxSizeVariants, Pagination, PaginationOptionProps, PaginationProps, PaginationSizeSelectorProps, PolymorphicComponentProps, PolymorphicRef, Popper, PopperOptionProps, PopperPortal, PopperPortalProps, PopperProps, PopperTrigger, PopperTriggerProps, RADIO_SYMBOL_KEY, Radio, RadioOptionProps, RadioProps, RemoveModalProps, SLIDER_Z_INDEX, ScrollArea, ScrollAreaOptionProps, ScrollAreaProps, ScrollbarRefType, SearchBar, SearchBarBaseProps, SearchBarCategoryProps, SearchBarComponent, SearchBarInputProps, SearchBarProps, SearchType, SelectInputButton, SelectInputButtonOptionProps, SelectInputButtonProps, ShoplflowProvider, ShoplflowProviderProps, Skeleton, SkeletonProps, Slider, SliderBounds, SliderProps, SpacingTokens, SplitButton, SplitButtonContext, SplitButtonContextType, SplitButtonOptionProps, SplitButtonProps, SplitButtonSizeVariantType, SplitButtonSizeVariants, SplitButtonStyleVariantType, SplitButtonStyleVariants, Stack, StackComponentType, StackContainer, StackContainerComponentType, StackContainerGenericProps, StackContainerOptionProps, StackContainerProps, StackGenericProps, StackOptionProps, StackProps, StyledIcon, StyledStack, StyledStackContainer, Switch, SwitchOptionProps, SwitchProps, SwitchSizeVariantType, SwitchSizeVariants, TREE_SYMBOL_KEY, TabOptionProps, TabProps, TabSizeVariantType, TabSizeVariants, TabStyleVariantType, TabStyleVariants, TabStyledProps, TabTextStyledProps, Tabs, TabsContext, TabsContextType, TabsOptionProps, TabsProps, Tag, TagOptionProps, TagProps, TagSizeVariantType, TagSizeVariants, TagStyleVariantType, TagStyleVariants, Text, Text2Rows, TextArea, TextAreaOptionProps, TextAreaProps, TextOptionProps, TextProps, ToggleButton, ToggleButtonInnerRadioOptionProps, ToggleButtonInnerRadioProps, ToggleButtonOptionProps, ToggleButtonProps, ToggleButtonSizeVariantType, ToggleButtonSizeVariants, Tooltip, TooltipContentProps, TooltipOptionProps, TooltipProps, Tree, TreeItem, TreeItemOptionProps, TreeItemProps, TreeOptionProps, TreeProps, TypographyTokens, WeekClickDateInfo, WeekDatepicker, WeekDatepickerProps, WeekDatepickerStyleType, YearSelectProps, borderRadiusTokens, boxShadowTokens, colorTokens, fontWeightTokens, getDomain, spacingTokens, typographyTokens, useDomain, useDropdownButtonContext, useHandleModal, useModalValue, useSplitButtonContext, useTabs };
package/dist/index.js CHANGED
@@ -738,6 +738,7 @@ var MODAL_SIZE_L = 768;
738
738
  var MODAL_SIZE_XL = 1040;
739
739
  var MODAL_SIZE_XXL = 1280;
740
740
  var MODAL_SIZE_XXXL = 1600;
741
+ var MODAL_TOP_BOTTOM_MARGIN = 64;
741
742
  var getModalWidthFromSize = (size2) => {
742
743
  switch (size2) {
743
744
  case "XXS":
@@ -789,14 +790,13 @@ var getFullScreenModal = () => {
789
790
  `;
790
791
  };
791
792
  var checkMaxHeight = (height, viewport) => {
792
- const topBottomMargin = 64;
793
793
  if (height > 1200) {
794
- return 1200 - topBottomMargin;
794
+ return 1200 - MODAL_TOP_BOTTOM_MARGIN;
795
795
  }
796
796
  if (height > viewport) {
797
- return viewport - topBottomMargin;
797
+ return viewport - MODAL_TOP_BOTTOM_MARGIN;
798
798
  }
799
- return height - topBottomMargin;
799
+ return height - MODAL_TOP_BOTTOM_MARGIN;
800
800
  };
801
801
  var Container = styled6.div`
802
802
  ${({ hasChangeAnimation }) => hasChangeAnimation && css`
@@ -813,9 +813,14 @@ var Container = styled6.div`
813
813
  box-shadow: ${boxShadowTokens.dropShadow};
814
814
  overflow: hidden;
815
815
  flex-grow: 1;
816
- height: ${({ height, viewport }) => height ? `${checkMaxHeight(height, viewport)}px` : "initial"};
816
+ height: ${({ height, viewport, $fillViewportHeight }) => {
817
+ if ($fillViewportHeight) {
818
+ return `${viewport - MODAL_TOP_BOTTOM_MARGIN}px`;
819
+ }
820
+ return typeof height === "number" ? `${checkMaxHeight(height, viewport)}px` : "initial";
821
+ }};
817
822
  min-height: 180px;
818
- max-height: 1200px;
823
+ max-height: ${({ $fillViewportHeight }) => $fillViewportHeight ? "none" : "1200px"};
819
824
 
820
825
  width: ${({ sizeVar }) => getModalWidthFromSize(sizeVar)}px;
821
826
  max-width: ${({ sizeVar }) => getModalWidthFromSize(sizeVar)}px;
@@ -907,6 +912,12 @@ var useViewportSizeObserver = () => {
907
912
  }, []);
908
913
  return size2;
909
914
  };
915
+ var ModalHandlerContext = createContext({
916
+ addModal: noop,
917
+ removeModal: noop
918
+ });
919
+ var ModalContext = createContext([]);
920
+ var ModalOutsideClickContext = createContext(null);
910
921
  var ModalOptionContext = createContext({
911
922
  topHeight: 0,
912
923
  bottomHeight: 0,
@@ -942,9 +953,11 @@ var ModalOptionContextProvider = ({ children }) => {
942
953
  var ModalContainer = (_a) => {
943
954
  var _b = _a, { children, height, outsideClick = noop } = _b, rest = __objRest(_b, ["children", "height", "outsideClick"]);
944
955
  const ref = useParentElementClick(outsideClick);
956
+ const dismissCtx = useContext(ModalOutsideClickContext);
945
957
  const { height: windowHeight } = useViewportSizeObserver();
946
958
  const topBottomMargin = 64;
947
- const heightWidthMargin = height ? height + topBottomMargin : void 0;
959
+ const fillViewportHeight = height === "100%" && rest.sizeVar !== "FULL";
960
+ const heightWidthMargin = typeof height === "number" ? height + topBottomMargin : fillViewportHeight ? windowHeight : void 0;
948
961
  const childrenArray = React__default.Children.toArray(children);
949
962
  const findHeader = childrenArray.find((child) => {
950
963
  if (!React__default.isValidElement(child)) {
@@ -962,6 +975,14 @@ var ModalContainer = (_a) => {
962
975
  return child;
963
976
  }
964
977
  });
978
+ useEffect(() => {
979
+ if (!dismissCtx) {
980
+ return;
981
+ }
982
+ return dismissCtx.registerOutsideClick(() => {
983
+ outsideClick(null);
984
+ });
985
+ }, [dismissCtx, outsideClick]);
965
986
  const addPropInChildren = React__default.Children.map(childrenArray, (child) => {
966
987
  if (!React__default.isValidElement(child)) {
967
988
  return child;
@@ -970,10 +991,24 @@ var ModalContainer = (_a) => {
970
991
  isIncludeHeader: Boolean(findHeader),
971
992
  isIncludeFooter: Boolean(findFooter),
972
993
  sizeVar: rest.sizeVar,
973
- height: heightWidthMargin
994
+ height: heightWidthMargin,
995
+ fillViewportHeight
974
996
  });
975
997
  });
976
- return /* @__PURE__ */ jsx(Container, __spreadProps(__spreadValues({ ref }, rest), { height: heightWidthMargin, viewport: windowHeight, "data-shoplflow": "Modal", children: /* @__PURE__ */ jsx(ModalOptionContextProvider, { children: addPropInChildren }) }));
998
+ return /* @__PURE__ */ jsx(
999
+ Container,
1000
+ __spreadProps(__spreadValues({
1001
+ ref
1002
+ }, rest), {
1003
+ height: heightWidthMargin,
1004
+ $fillViewportHeight: fillViewportHeight,
1005
+ viewport: windowHeight,
1006
+ "data-shoplflow": "Modal",
1007
+ role: "dialog",
1008
+ "aria-modal": true,
1009
+ children: /* @__PURE__ */ jsx(ModalOptionContextProvider, { children: addPropInChildren })
1010
+ })
1011
+ );
977
1012
  };
978
1013
  var ModalContainer_default = ModalContainer;
979
1014
  var ModalFooter = ({ children, padding }) => {
@@ -1023,6 +1058,7 @@ var ModalBody = ({
1023
1058
  isIncludeFooter = false,
1024
1059
  sizeVar,
1025
1060
  height: modalContainerHeight,
1061
+ fillViewportHeight = false,
1026
1062
  padding
1027
1063
  }) => {
1028
1064
  const { height: windowHeight } = useViewportSizeObserver();
@@ -1046,6 +1082,9 @@ var ModalBody = ({
1046
1082
  if (sizeVar === "FULL") {
1047
1083
  return windowHeight - headerFooterHeight - heightToDeduct;
1048
1084
  }
1085
+ if (fillViewportHeight) {
1086
+ return windowHeight - topBottomMargin - headerFooterHeight - heightToDeduct;
1087
+ }
1049
1088
  if (modalContainerHeight) {
1050
1089
  if (modalContainerHeight <= 1200) {
1051
1090
  if (windowHeight < modalContainerHeight) {
@@ -1062,6 +1101,9 @@ var ModalBody = ({
1062
1101
  if (sizeVar === "FULL") {
1063
1102
  return windowHeight;
1064
1103
  }
1104
+ if (fillViewportHeight) {
1105
+ return windowHeight - topBottomMargin - headerFooterHeight;
1106
+ }
1065
1107
  if (modalContainerHeight) {
1066
1108
  if (modalContainerHeight > 1200) {
1067
1109
  return 1200 - topBottomMargin - headerFooterHeight;
@@ -1166,13 +1208,6 @@ var ModalBottom = ({ children }) => {
1166
1208
  }, [bottomRef, setBottomHeight, clearBottomHeight]);
1167
1209
  return /* @__PURE__ */ jsx(BottomContainer, { ref: setBottomRef, children });
1168
1210
  };
1169
- var ModalHandlerContext = createContext({
1170
- addModal: noop,
1171
- removeModal: noop
1172
- });
1173
- var ModalContext = createContext([]);
1174
-
1175
- // src/components/Modal/hooks/useModalValue.ts
1176
1211
  var useModalValue = () => {
1177
1212
  const modal = useContext(ModalContext);
1178
1213
  return {
@@ -1188,6 +1223,27 @@ var useHandleModal = () => {
1188
1223
  };
1189
1224
  var ModalProvider = ({ children }) => {
1190
1225
  const [openedModals, setOpenedModals] = useState([]);
1226
+ const dismissStackRef = useRef([]);
1227
+ const registerOutsideClick = useCallback((fn) => {
1228
+ dismissStackRef.current.push(fn);
1229
+ return () => {
1230
+ const idx = dismissStackRef.current.lastIndexOf(fn);
1231
+ if (idx !== -1) {
1232
+ dismissStackRef.current.splice(idx, 1);
1233
+ }
1234
+ };
1235
+ }, []);
1236
+ const requestOutsideClick = useCallback(() => {
1237
+ const top = dismissStackRef.current[dismissStackRef.current.length - 1];
1238
+ top == null ? void 0 : top();
1239
+ }, []);
1240
+ const dismissRegistry = useMemo(
1241
+ () => ({
1242
+ registerOutsideClick,
1243
+ requestOutsideClick
1244
+ }),
1245
+ [registerOutsideClick, requestOutsideClick]
1246
+ );
1191
1247
  const addModal = (component, id, zIndex) => {
1192
1248
  setOpenedModals((modals) => {
1193
1249
  if (modals) {
@@ -1235,14 +1291,17 @@ var ModalProvider = ({ children }) => {
1235
1291
  };
1236
1292
  const dispatch = useMemo(() => ({ addModal, removeModal }), []);
1237
1293
  useEffect(() => {
1238
- if (openedModals.length !== 1) {
1239
- return;
1294
+ if (openedModals.length > 0) {
1295
+ document.body.style.overflow = "hidden";
1296
+ } else {
1297
+ document.body.style.overflow = "";
1240
1298
  }
1241
- document.body.style.cssText = "overflow:hidden";
1299
+ }, [openedModals.length]);
1300
+ useEffect(() => {
1242
1301
  return () => {
1243
- document.body.style.cssText = "overflow:unset";
1302
+ document.body.style.overflow = "";
1244
1303
  };
1245
- }, [openedModals.length]);
1304
+ }, []);
1246
1305
  useEffect(() => {
1247
1306
  const closeAllModals = () => {
1248
1307
  setOpenedModals([]);
@@ -1252,7 +1311,7 @@ var ModalProvider = ({ children }) => {
1252
1311
  window.removeEventListener("popstate", closeAllModals);
1253
1312
  };
1254
1313
  }, []);
1255
- return /* @__PURE__ */ jsx(ModalContext.Provider, { value: openedModals, children: /* @__PURE__ */ jsx(ModalHandlerContext.Provider, { value: dispatch, children }) });
1314
+ return /* @__PURE__ */ jsx(ModalContext.Provider, { value: openedModals, children: /* @__PURE__ */ jsx(ModalOutsideClickContext.Provider, { value: dismissRegistry, children: /* @__PURE__ */ jsx(ModalHandlerContext.Provider, { value: dispatch, children }) }) });
1256
1315
  };
1257
1316
  var ModalProvider_default = ModalProvider;
1258
1317
 
@@ -4998,41 +5057,29 @@ var PaginationWrapper = styled6.div`
4998
5057
  width: 100%;
4999
5058
  justify-content: space-between;
5000
5059
 
5001
- /* Shopl: Figma pagenation bar 양끝은 흐름 배치, 네비는 전체 기준 absolute 중앙 (node 13760:25910) */
5060
+ /* Shopl: 좌/우 아이템 폭과 개수와 무관하게 네비를 고정 중앙에 둔다. */
5002
5061
  ${({ $centerNav }) => $centerNav && css`
5003
- position: relative;
5004
- justify-content: space-between;
5062
+ display: grid;
5063
+ grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
5064
+ align-items: center;
5065
+ column-gap: 8px;
5005
5066
 
5006
- /* div → nav → div 이므로 nth-of-type(2)는 두 번째 div(우측)만 잡힘 → 반드시 nth-child */
5007
5067
  & > *:nth-child(1) {
5008
- position: relative;
5009
- z-index: 2;
5010
- flex-shrink: 0;
5011
5068
  display: flex;
5012
5069
  align-items: center;
5013
5070
  justify-content: flex-start;
5071
+ min-width: 0;
5072
+ overflow: hidden;
5014
5073
  }
5015
5074
  & > *:nth-child(2) {
5016
- position: absolute;
5017
- left: 50%;
5018
- top: 50%;
5019
- z-index: 1;
5020
- transform: translate(-50%, -50%);
5021
- width: max-content;
5022
- max-width: 100%;
5023
- pointer-events: none;
5024
-
5025
- & > * {
5026
- pointer-events: auto;
5027
- }
5075
+ justify-self: center;
5028
5076
  }
5029
5077
  & > *:nth-child(3) {
5030
- position: relative;
5031
- z-index: 2;
5032
- flex-shrink: 0;
5033
5078
  display: flex;
5034
5079
  align-items: center;
5035
5080
  justify-content: flex-end;
5081
+ min-width: 0;
5082
+ overflow: hidden;
5036
5083
  }
5037
5084
  `}
5038
5085
 
@@ -7752,6 +7799,24 @@ var SpaceMarginWrapper = styled6(motion.div)`
7752
7799
  `;
7753
7800
  var ModalPortal = () => {
7754
7801
  const modal = useContext(ModalContext);
7802
+ const dismissRegistry = useContext(ModalOutsideClickContext);
7803
+ useEffect(() => {
7804
+ if (!dismissRegistry) {
7805
+ return;
7806
+ }
7807
+ const onKeyDown = (event) => {
7808
+ if (event.key !== "Escape") {
7809
+ return;
7810
+ }
7811
+ if (modal.length === 0) {
7812
+ return;
7813
+ }
7814
+ event.preventDefault();
7815
+ dismissRegistry.requestOutsideClick();
7816
+ };
7817
+ document.addEventListener("keydown", onKeyDown);
7818
+ return () => document.removeEventListener("keydown", onKeyDown);
7819
+ }, [dismissRegistry, modal.length]);
7755
7820
  return /* @__PURE__ */ jsx(Fragment, { children: createPortal(
7756
7821
  /* @__PURE__ */ jsx(AnimatePresence, { children: modal.map((item, index) => /* @__PURE__ */ jsx(BackDrop_default, { zIndex: item.zIndex, children: /* @__PURE__ */ jsx(SpaceMarginWrapper, { children: item.component }) }, index)) }),
7757
7822
  document.body
@@ -7793,4 +7858,4 @@ classnames/index.js:
7793
7858
  *)
7794
7859
  */
7795
7860
 
7796
- export { AnnualDatepicker_default as AnnualDatepicker, Avatar_default as Avatar, AvatarSizeVariants, Button_default as Button, ButtonSizeVariants, ButtonStyleVariants, CHECKBOX_SYMBOL_KEY, Callout_default as Callout, CalloutTypes, Checkbox_default as Checkbox, CheckboxStyleVariants, ChipButton_default as ChipButton, ChipButtonSizeVariants, ChipButtonStyleVariants, ChipToggle_default as ChipToggle, ChipToggleSizeVariants, ChipToggleStyleVariants, DayDatepicker_default as DayDatepicker, DayDatepickerSizeVariants, Dropdown_default as Dropdown, DropdownButton_default as DropdownButton, DropdownButtonContext, DropdownButtonSizeVariants, DropdownButtonStyleVariants, DropdownOptionVariants, HelperText_default as HelperText, Icon_default as Icon, IconButton_default as IconButton, IconButtonSizeVariants, IconButtonStyleVariants, IconSizeVariants, Input_default as Input, InputButton_default as InputButton, InputSizeVariants, List_default as List, MODAL_FOOTER_KEY, MODAL_HEADER_KEY, Menu_default as Menu, MenuSizeVariants, MinusButton_default as MinusButton, Modal, ModalContext, ModalHandlerContext, ModalPortal_default as ModalProvider, ModalSize, MonthDatepicker_default as MonthDatepicker, MotionStack, MotionStackContainer, NumberCombobox_default as NumberCombobox, NumberComboboxSizeVariants, Pagination_default as Pagination, Popper_default as Popper, PopperPortal, PopperTrigger, RADIO_SYMBOL_KEY, Radio_default as Radio, SLIDER_Z_INDEX, ScrollArea_default as ScrollArea, SearchBar2 as SearchBar, SelectInputButton_default as SelectInputButton, ShoplflowProvider_default as ShoplflowProvider, Skeleton_default as Skeleton, Slider_default as Slider, SplitButton_default as SplitButton, SplitButtonContext, SplitButtonSizeVariants, SplitButtonStyleVariants, Stack_default as Stack, StackContainer_default as StackContainer, StyledIcon, StyledStack, StyledStackContainer, Switch_default as Switch, SwitchSizeVariants, TREE_SYMBOL_KEY, TabSizeVariants, TabStyleVariants, Tabs_default as Tabs, TabsContext, Tag_default as Tag, TagSizeVariants, TagStyleVariants, Text_default as Text, Text2Rows, TextArea_default as TextArea, ToggleButton_default as ToggleButton, ToggleButtonSizeVariants, Tooltip_default as Tooltip, Tree_default as Tree, TreeItem, WeekDatepicker_default as WeekDatepicker, borderRadiusTokens, boxShadowTokens, colorTokens, fontWeightTokens, getDomain, spacingTokens, typographyTokens, useDomain, useDropdownButtonContext, useHandleModal, useModalValue, useSplitButtonContext, useTabs };
7861
+ export { AnnualDatepicker_default as AnnualDatepicker, Avatar_default as Avatar, AvatarSizeVariants, Button_default as Button, ButtonSizeVariants, ButtonStyleVariants, CHECKBOX_SYMBOL_KEY, Callout_default as Callout, CalloutTypes, Checkbox_default as Checkbox, CheckboxStyleVariants, ChipButton_default as ChipButton, ChipButtonSizeVariants, ChipButtonStyleVariants, ChipToggle_default as ChipToggle, ChipToggleSizeVariants, ChipToggleStyleVariants, DayDatepicker_default as DayDatepicker, DayDatepickerSizeVariants, Dropdown_default as Dropdown, DropdownButton_default as DropdownButton, DropdownButtonContext, DropdownButtonSizeVariants, DropdownButtonStyleVariants, DropdownOptionVariants, HelperText_default as HelperText, Icon_default as Icon, IconButton_default as IconButton, IconButtonSizeVariants, IconButtonStyleVariants, IconSizeVariants, Input_default as Input, InputButton_default as InputButton, InputSizeVariants, List_default as List, MODAL_FOOTER_KEY, MODAL_HEADER_KEY, Menu_default as Menu, MenuSizeVariants, MinusButton_default as MinusButton, Modal, ModalContext, ModalHandlerContext, ModalOutsideClickContext, ModalPortal_default as ModalProvider, ModalSize, MonthDatepicker_default as MonthDatepicker, MotionStack, MotionStackContainer, NumberCombobox_default as NumberCombobox, NumberComboboxSizeVariants, Pagination_default as Pagination, Popper_default as Popper, PopperPortal, PopperTrigger, RADIO_SYMBOL_KEY, Radio_default as Radio, SLIDER_Z_INDEX, ScrollArea_default as ScrollArea, SearchBar2 as SearchBar, SelectInputButton_default as SelectInputButton, ShoplflowProvider_default as ShoplflowProvider, Skeleton_default as Skeleton, Slider_default as Slider, SplitButton_default as SplitButton, SplitButtonContext, SplitButtonSizeVariants, SplitButtonStyleVariants, Stack_default as Stack, StackContainer_default as StackContainer, StyledIcon, StyledStack, StyledStackContainer, Switch_default as Switch, SwitchSizeVariants, TREE_SYMBOL_KEY, TabSizeVariants, TabStyleVariants, Tabs_default as Tabs, TabsContext, Tag_default as Tag, TagSizeVariants, TagStyleVariants, Text_default as Text, Text2Rows, TextArea_default as TextArea, ToggleButton_default as ToggleButton, ToggleButtonSizeVariants, Tooltip_default as Tooltip, Tree_default as Tree, TreeItem, WeekDatepicker_default as WeekDatepicker, borderRadiusTokens, boxShadowTokens, colorTokens, fontWeightTokens, getDomain, spacingTokens, typographyTokens, useDomain, useDropdownButtonContext, useHandleModal, useModalValue, useSplitButtonContext, useTabs };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shoplflow/base",
3
- "version": "0.46.26",
3
+ "version": "0.46.28",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -92,9 +92,9 @@
92
92
  "react-datepicker": "^7.3.0",
93
93
  "react-dom": "^18.2.0",
94
94
  "simplebar-react": "^3.2.6",
95
- "@shoplflow/hada-assets": "^0.1.10",
96
95
  "@shoplflow/shopl-assets": "^0.12.43",
97
- "@shoplflow/utils": "^0.8.0"
96
+ "@shoplflow/utils": "^0.8.0",
97
+ "@shoplflow/hada-assets": "^0.1.10"
98
98
  },
99
99
  "homepage": "https://github.com/shopl/shoplflow#readme",
100
100
  "scripts": {