@exem-ui/react 0.3.4-next.20260819010838 → 0.3.4-next.20260828070546

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -813,7 +813,17 @@ type MessageBoxComponent = React__default.FC<MessageBoxRootProps> & {
813
813
  };
814
814
  declare const MessageBox: MessageBoxComponent;
815
815
 
816
- interface LoadingProps extends VariantProps<typeof containerVariants>, VariantProps<typeof spinnerVariants>, Omit<React__default.HTMLAttributes<HTMLDivElement>, 'children'> {
816
+ declare const containerVariants: (props?: ({
817
+ position?: "fixed" | "absolute" | null | undefined;
818
+ blockInteraction?: boolean | null | undefined;
819
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
820
+ declare const spinnerSizes: {
821
+ readonly small: 24;
822
+ readonly medium: 36;
823
+ readonly large: 48;
824
+ };
825
+ type LoadingSize = keyof typeof spinnerSizes;
826
+ interface LoadingProps extends VariantProps<typeof containerVariants>, Omit<React__default.ComponentPropsWithRef<'div'>, 'children'> {
817
827
  /**
818
828
  * 로딩 표시 여부
819
829
  * @default true
@@ -829,6 +839,8 @@ interface LoadingProps extends VariantProps<typeof containerVariants>, VariantPr
829
839
  * @default false
830
840
  */
831
841
  blockInteraction?: boolean;
842
+ /** 스피너 크기 */
843
+ size?: LoadingSize;
832
844
  /** 컨테이너 추가 클래스 */
833
845
  containerClassName?: string;
834
846
  /** 오버레이 추가 클래스 */
@@ -836,43 +848,29 @@ interface LoadingProps extends VariantProps<typeof containerVariants>, VariantPr
836
848
  /** 스피너 추가 클래스 */
837
849
  spinnerClassName?: string;
838
850
  }
839
- type LoadingComponent = React__default.ForwardRefExoticComponent<LoadingProps & React__default.RefAttributes<HTMLDivElement>>;
840
- declare const containerVariants: (props?: ({
841
- position?: "fixed" | "absolute" | null | undefined;
842
- blockInteraction?: boolean | null | undefined;
843
- } & class_variance_authority_types.ClassProp) | undefined) => string;
844
- declare const spinnerVariants: (props?: ({
845
- size?: "small" | "medium" | "large" | null | undefined;
846
- } & class_variance_authority_types.ClassProp) | undefined) => string;
847
851
  /**
848
852
  * 비동기 작업 중 로딩 상태를 표시하는 오버레이 컴포넌트입니다.
849
853
  *
850
854
  * @example
851
855
  * ```tsx
852
- * // 기본 사용 (전체 화면 고정)
853
856
  * <Loading isLoading />
854
- *
855
- * // 특정 영역 내 로딩 (absolute 위치)
856
- * <div style={{ position: 'relative' }}>
857
- * <Loading isLoading position="absolute" size="small" />
858
- * </div>
857
+ * <Loading isLoading position="absolute" size="small" />
859
858
  * ```
860
- *
861
- * @see {@link LoadingProps} props 상세
862
859
  */
863
- declare const Loading: LoadingComponent;
860
+ declare function Loading({ isLoading, dim, blockInteraction, position, size, containerClassName, overlayClassName, spinnerClassName, className, ref, 'aria-label': ariaLabel, ...props }: LoadingProps): react_jsx_runtime.JSX.Element | null;
861
+ type LoadingComponent = typeof Loading;
864
862
 
865
863
  declare const trackVariants: (props?: ({
866
864
  size?: "small" | "medium" | "large" | null | undefined;
867
865
  } & class_variance_authority_types.ClassProp) | undefined) => string;
868
- interface ProgressProps extends VariantProps<typeof trackVariants>, Omit<React__default.HTMLAttributes<HTMLDivElement>, 'children'> {
866
+ interface ProgressProps extends VariantProps<typeof trackVariants>, Omit<React__default.ComponentPropsWithRef<'div'>, 'children'> {
869
867
  /**
870
868
  * 현재 진행 값
871
869
  * @default 0
872
870
  */
873
871
  value?: number;
874
872
  /**
875
- * 최대 값
873
+ * 최대 값. 0 이하면 값이 max로 보정되어 완료 상태가 되므로 양수만 사용합니다.
876
874
  * @default 100
877
875
  */
878
876
  max?: number;
@@ -881,17 +879,9 @@ interface ProgressProps extends VariantProps<typeof trackVariants>, Omit<React__
881
879
  /** 게이지(채움) 추가 클래스 */
882
880
  gaugeClassName?: string;
883
881
  }
884
- type ProgressComponent = React__default.ForwardRefExoticComponent<ProgressProps & React__default.RefAttributes<HTMLDivElement>>;
885
- /**
886
- * 작업 진행률을 시각적으로 표시하는 바 컴포넌트입니다.
887
- *
888
- * @example
889
- * ```tsx
890
- * <Progress value={60} />
891
- * <Progress value={30} max={100} size="large" />
892
- * ```
893
- */
894
- declare const Progress: ProgressComponent;
882
+ /** 작업 진행률을 시각적으로 표시하는 바 컴포넌트입니다. */
883
+ declare function Progress({ value, max, size, trackClassName, gaugeClassName, className, ref, 'aria-label': ariaLabel, 'aria-valuetext': ariaValueText, ...props }: ProgressProps): react_jsx_runtime.JSX.Element;
884
+ type ProgressComponent = typeof Progress;
895
885
 
896
886
  type ToasterRootProps = React$1.ComponentProps<typeof Toaster$1>;
897
887
  type ToasterContainerProps = {
package/dist/index.d.ts CHANGED
@@ -813,7 +813,17 @@ type MessageBoxComponent = React__default.FC<MessageBoxRootProps> & {
813
813
  };
814
814
  declare const MessageBox: MessageBoxComponent;
815
815
 
816
- interface LoadingProps extends VariantProps<typeof containerVariants>, VariantProps<typeof spinnerVariants>, Omit<React__default.HTMLAttributes<HTMLDivElement>, 'children'> {
816
+ declare const containerVariants: (props?: ({
817
+ position?: "fixed" | "absolute" | null | undefined;
818
+ blockInteraction?: boolean | null | undefined;
819
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
820
+ declare const spinnerSizes: {
821
+ readonly small: 24;
822
+ readonly medium: 36;
823
+ readonly large: 48;
824
+ };
825
+ type LoadingSize = keyof typeof spinnerSizes;
826
+ interface LoadingProps extends VariantProps<typeof containerVariants>, Omit<React__default.ComponentPropsWithRef<'div'>, 'children'> {
817
827
  /**
818
828
  * 로딩 표시 여부
819
829
  * @default true
@@ -829,6 +839,8 @@ interface LoadingProps extends VariantProps<typeof containerVariants>, VariantPr
829
839
  * @default false
830
840
  */
831
841
  blockInteraction?: boolean;
842
+ /** 스피너 크기 */
843
+ size?: LoadingSize;
832
844
  /** 컨테이너 추가 클래스 */
833
845
  containerClassName?: string;
834
846
  /** 오버레이 추가 클래스 */
@@ -836,43 +848,29 @@ interface LoadingProps extends VariantProps<typeof containerVariants>, VariantPr
836
848
  /** 스피너 추가 클래스 */
837
849
  spinnerClassName?: string;
838
850
  }
839
- type LoadingComponent = React__default.ForwardRefExoticComponent<LoadingProps & React__default.RefAttributes<HTMLDivElement>>;
840
- declare const containerVariants: (props?: ({
841
- position?: "fixed" | "absolute" | null | undefined;
842
- blockInteraction?: boolean | null | undefined;
843
- } & class_variance_authority_types.ClassProp) | undefined) => string;
844
- declare const spinnerVariants: (props?: ({
845
- size?: "small" | "medium" | "large" | null | undefined;
846
- } & class_variance_authority_types.ClassProp) | undefined) => string;
847
851
  /**
848
852
  * 비동기 작업 중 로딩 상태를 표시하는 오버레이 컴포넌트입니다.
849
853
  *
850
854
  * @example
851
855
  * ```tsx
852
- * // 기본 사용 (전체 화면 고정)
853
856
  * <Loading isLoading />
854
- *
855
- * // 특정 영역 내 로딩 (absolute 위치)
856
- * <div style={{ position: 'relative' }}>
857
- * <Loading isLoading position="absolute" size="small" />
858
- * </div>
857
+ * <Loading isLoading position="absolute" size="small" />
859
858
  * ```
860
- *
861
- * @see {@link LoadingProps} props 상세
862
859
  */
863
- declare const Loading: LoadingComponent;
860
+ declare function Loading({ isLoading, dim, blockInteraction, position, size, containerClassName, overlayClassName, spinnerClassName, className, ref, 'aria-label': ariaLabel, ...props }: LoadingProps): react_jsx_runtime.JSX.Element | null;
861
+ type LoadingComponent = typeof Loading;
864
862
 
865
863
  declare const trackVariants: (props?: ({
866
864
  size?: "small" | "medium" | "large" | null | undefined;
867
865
  } & class_variance_authority_types.ClassProp) | undefined) => string;
868
- interface ProgressProps extends VariantProps<typeof trackVariants>, Omit<React__default.HTMLAttributes<HTMLDivElement>, 'children'> {
866
+ interface ProgressProps extends VariantProps<typeof trackVariants>, Omit<React__default.ComponentPropsWithRef<'div'>, 'children'> {
869
867
  /**
870
868
  * 현재 진행 값
871
869
  * @default 0
872
870
  */
873
871
  value?: number;
874
872
  /**
875
- * 최대 값
873
+ * 최대 값. 0 이하면 값이 max로 보정되어 완료 상태가 되므로 양수만 사용합니다.
876
874
  * @default 100
877
875
  */
878
876
  max?: number;
@@ -881,17 +879,9 @@ interface ProgressProps extends VariantProps<typeof trackVariants>, Omit<React__
881
879
  /** 게이지(채움) 추가 클래스 */
882
880
  gaugeClassName?: string;
883
881
  }
884
- type ProgressComponent = React__default.ForwardRefExoticComponent<ProgressProps & React__default.RefAttributes<HTMLDivElement>>;
885
- /**
886
- * 작업 진행률을 시각적으로 표시하는 바 컴포넌트입니다.
887
- *
888
- * @example
889
- * ```tsx
890
- * <Progress value={60} />
891
- * <Progress value={30} max={100} size="large" />
892
- * ```
893
- */
894
- declare const Progress: ProgressComponent;
882
+ /** 작업 진행률을 시각적으로 표시하는 바 컴포넌트입니다. */
883
+ declare function Progress({ value, max, size, trackClassName, gaugeClassName, className, ref, 'aria-label': ariaLabel, 'aria-valuetext': ariaValueText, ...props }: ProgressProps): react_jsx_runtime.JSX.Element;
884
+ type ProgressComponent = typeof Progress;
895
885
 
896
886
  type ToasterRootProps = React$1.ComponentProps<typeof Toaster$1>;
897
887
  type ToasterContainerProps = {
package/dist/index.js CHANGED
@@ -13,6 +13,7 @@ var reactDayPicker = require('react-day-picker');
13
13
  var DropdownMenuPrimitive = require('@radix-ui/react-dropdown-menu');
14
14
  var DialogPrimitive = require('@radix-ui/react-dialog');
15
15
  var reResizable = require('re-resizable');
16
+ var progress = require('@base-ui/react/progress');
16
17
  var sonner = require('sonner');
17
18
 
18
19
  function _interopNamespace(e) {
@@ -959,6 +960,16 @@ var Switch = React.forwardRef(
959
960
  }
960
961
  );
961
962
  Switch.displayName = SwitchPrimitives__namespace.Root.displayName;
963
+ function mergeClassNames(base, user) {
964
+ if (!user) {
965
+ return base;
966
+ }
967
+ const merged = { ...base };
968
+ for (const key in user) {
969
+ merged[key] = utils.cn(base[key], user[key]);
970
+ }
971
+ return merged;
972
+ }
962
973
  function DatePickerChevron({ orientation }) {
963
974
  if (orientation === "left") {
964
975
  return /* @__PURE__ */ jsxRuntime.jsx(chunk6MFMQCL5_js.ChevronLeft, { type: "regular", className: "size-5" });
@@ -987,7 +998,6 @@ function DatePickerDayButton({
987
998
  }
988
999
  function DatePicker({ type = "single", showOutsideDays = true, ...rest }) {
989
1000
  const dayPickerProps = { ...rest, mode: type };
990
- const defaultClassNames = reactDayPicker.getDefaultClassNames();
991
1001
  const [month, setMonth] = React.useState(
992
1002
  dayPickerProps.month ?? dayPickerProps.defaultMonth ?? /* @__PURE__ */ new Date()
993
1003
  );
@@ -1003,6 +1013,41 @@ function DatePicker({ type = "single", showOutsideDays = true, ...rest }) {
1003
1013
  }
1004
1014
  dayPickerProps.onDayClick?.(day, modifiers, e);
1005
1015
  };
1016
+ const dayPickerClassNames = {
1017
+ root: "rounded-medium",
1018
+ months: "relative",
1019
+ month: "flex flex-col gap-2",
1020
+ month_caption: "flex h-7 items-center px-0.5",
1021
+ caption_label: "text-body-2 font-semibold text-text-primary",
1022
+ nav: "absolute right-0 top-0 flex h-7 items-center gap-2",
1023
+ button_previous: "flex size-7 items-center justify-center rounded-medium hover:bg-elevation-elevation-2",
1024
+ button_next: "flex size-7 items-center justify-center rounded-medium hover:bg-elevation-elevation-2",
1025
+ weekday: "size-8 text-body-3 font-regular text-text-tertiary",
1026
+ month_grid: "border-separate border-spacing-x-0 border-spacing-y-1",
1027
+ week: "overflow-hidden rounded-medium",
1028
+ day: "size-8 text-body-2 font-medium text-text-secondary",
1029
+ day_button: "size-8 cursor-pointer rounded-full hover:border hover:border-border-focused",
1030
+ outside: "!text-text-disabled",
1031
+ selected: utils.cn(
1032
+ "[&>button]:bg-solid-primary-default",
1033
+ "[&>button]:text-text-inverse",
1034
+ "[&>button]:border-0",
1035
+ "[&>button]:hover:border-0"
1036
+ ),
1037
+ range_start: utils.cn(
1038
+ "rounded-none",
1039
+ isRangeComplete && "[background:linear-gradient(to_right,transparent_50%,var(--color-elevation-elevation-2)_50%)]"
1040
+ ),
1041
+ range_end: utils.cn(
1042
+ "rounded-none",
1043
+ isRangeComplete && "[background:linear-gradient(to_left,transparent_50%,var(--color-elevation-elevation-2)_50%)]"
1044
+ ),
1045
+ range_middle: utils.cn(
1046
+ "bg-elevation-elevation-2 rounded-none",
1047
+ "[&>button]:!bg-transparent",
1048
+ "[&>button]:!text-text-secondary"
1049
+ )
1050
+ };
1006
1051
  return /* @__PURE__ */ jsxRuntime.jsx(
1007
1052
  reactDayPicker.DayPicker,
1008
1053
  {
@@ -1025,64 +1070,11 @@ function DatePicker({ type = "single", showOutsideDays = true, ...rest }) {
1025
1070
  DayButton: DatePickerDayButton,
1026
1071
  ...dayPickerProps.components
1027
1072
  },
1028
- classNames: {
1029
- root: utils.cn(
1030
- defaultClassNames.root,
1031
- "rounded-medium border border-border-primary bg-background-overlay p-4 shadow-medium"
1032
- ),
1033
- months: utils.cn(defaultClassNames.months, "relative"),
1034
- month: utils.cn(defaultClassNames.month, "flex flex-col gap-2"),
1035
- month_caption: utils.cn(defaultClassNames.month_caption, "flex h-7 items-center px-0.5"),
1036
- caption_label: "text-body-2 font-semibold text-text-primary",
1037
- nav: utils.cn(defaultClassNames.nav, "absolute right-0 top-0 flex h-7 items-center gap-2"),
1038
- button_previous: utils.cn(
1039
- defaultClassNames.button_previous,
1040
- "flex size-7 items-center justify-center rounded-medium hover:bg-elevation-elevation-2"
1041
- ),
1042
- button_next: utils.cn(
1043
- defaultClassNames.button_next,
1044
- "flex size-7 items-center justify-center rounded-medium hover:bg-elevation-elevation-2"
1045
- ),
1046
- weekday: utils.cn(
1047
- defaultClassNames.weekday,
1048
- "size-8 text-body-3 font-regular text-text-tertiary"
1049
- ),
1050
- month_grid: utils.cn(
1051
- defaultClassNames.month_grid,
1052
- "border-separate border-spacing-x-0 border-spacing-y-1"
1053
- ),
1054
- week: utils.cn(defaultClassNames.week, "overflow-hidden rounded-medium"),
1055
- day: utils.cn(defaultClassNames.day, "size-8 text-body-2 font-medium text-text-secondary"),
1056
- day_button: utils.cn(
1057
- defaultClassNames.day_button,
1058
- "size-8 cursor-pointer rounded-full hover:border hover:border-border-focused"
1059
- ),
1060
- outside: "!text-text-disabled",
1061
- selected: utils.cn(
1062
- "[&>button]:bg-solid-primary-default",
1063
- "[&>button]:text-text-inverse",
1064
- "[&>button]:border-0",
1065
- "[&>button]:hover:border-0"
1066
- ),
1067
- range_start: utils.cn(
1068
- "rounded-none",
1069
- isRangeComplete && "[background:linear-gradient(to_right,transparent_50%,var(--color-elevation-elevation-2)_50%)]"
1070
- ),
1071
- range_end: utils.cn(
1072
- "rounded-none",
1073
- isRangeComplete && "[background:linear-gradient(to_left,transparent_50%,var(--color-elevation-elevation-2)_50%)]"
1074
- ),
1075
- range_middle: utils.cn(
1076
- "bg-elevation-elevation-2 rounded-none",
1077
- "[&>button]:!bg-transparent",
1078
- "[&>button]:!text-text-secondary"
1079
- ),
1080
- ...dayPickerProps.classNames
1081
- },
1082
- modifiersClassNames: {
1083
- today: "rdp-calendar-today",
1084
- ...dayPickerProps.modifiersClassNames
1085
- }
1073
+ classNames: mergeClassNames(dayPickerClassNames, dayPickerProps.classNames),
1074
+ modifiersClassNames: mergeClassNames(
1075
+ { today: "rdp-calendar-today" },
1076
+ dayPickerProps.modifiersClassNames
1077
+ )
1086
1078
  }
1087
1079
  );
1088
1080
  }
@@ -2084,83 +2076,69 @@ var containerVariants4 = utils.cva("inset-0 z-[49] flex items-center justify-cen
2084
2076
  blockInteraction: false
2085
2077
  }
2086
2078
  });
2087
- var overlayVariants = utils.cva("absolute inset-0 transition-opacity duration-150", {
2088
- variants: {
2089
- visible: {
2090
- true: "opacity-100",
2091
- false: "opacity-0"
2092
- },
2093
- tone: {
2094
- // 대비감 높은 톤 설정 추후 디자인 시스템에서 추가 되어야함
2095
- auto: "bg-black/30 dark:bg-white/10",
2096
- dark: "bg-black/50",
2097
- light: "bg-white/70",
2098
- brand: "bg-primary/20"
2099
- }
2100
- },
2101
- defaultVariants: {
2102
- visible: true,
2103
- tone: "auto"
2104
- }
2105
- });
2106
- var spinnerVariants = utils.cva(
2107
- "z-50 shrink-0 animate-spin rounded-full border-elevation-elevation-4 border-t-transparent",
2079
+ var overlayVariants = utils.cva(
2080
+ "absolute inset-0 bg-component-dim transition-opacity duration-150 motion-reduce:transition-none",
2108
2081
  {
2109
2082
  variants: {
2110
- size: {
2111
- small: "size-6 border-2",
2112
- medium: "size-9 border-[3px]",
2113
- large: "size-12 border-4"
2083
+ visible: {
2084
+ true: "opacity-100",
2085
+ false: "opacity-0"
2114
2086
  }
2115
2087
  },
2116
2088
  defaultVariants: {
2117
- size: "large"
2089
+ visible: true
2118
2090
  }
2119
2091
  }
2120
2092
  );
2121
- var Loading = React.forwardRef(
2122
- ({
2123
- isLoading = true,
2124
- dim = true,
2125
- blockInteraction = false,
2126
- position = "fixed",
2127
- size = "medium",
2128
- containerClassName,
2129
- overlayClassName,
2130
- spinnerClassName,
2131
- className,
2132
- ...props
2133
- }, ref) => {
2134
- if (!isLoading) {
2135
- return null;
2136
- }
2137
- return /* @__PURE__ */ jsxRuntime.jsxs(
2138
- "div",
2139
- {
2140
- ref,
2141
- role: "status",
2142
- "aria-busy": "true",
2143
- className: utils.cn(
2144
- containerVariants4({ position, blockInteraction }),
2145
- containerClassName,
2146
- className
2147
- ),
2148
- ...props,
2149
- children: [
2150
- /* @__PURE__ */ jsxRuntime.jsx(
2151
- "div",
2152
- {
2153
- "aria-hidden": "true",
2154
- className: utils.cn(overlayVariants({ visible: dim }), overlayClassName)
2155
- }
2156
- ),
2157
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative z-50 flex size-full items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: utils.cn(spinnerVariants({ size }), spinnerClassName) }) })
2158
- ]
2159
- }
2160
- );
2093
+ var spinnerBaseClassName = "relative z-50 shrink-0 animate-spin text-elevation-elevation-4 motion-reduce:animate-none";
2094
+ var spinnerSizes = {
2095
+ small: 24,
2096
+ medium: 36,
2097
+ large: 48
2098
+ };
2099
+ function Loading2({
2100
+ isLoading = true,
2101
+ dim = true,
2102
+ blockInteraction = false,
2103
+ position = "fixed",
2104
+ size = "medium",
2105
+ containerClassName,
2106
+ overlayClassName,
2107
+ spinnerClassName,
2108
+ className,
2109
+ ref,
2110
+ "aria-label": ariaLabel = "Loading",
2111
+ ...props
2112
+ }) {
2113
+ if (!isLoading) {
2114
+ return null;
2161
2115
  }
2162
- );
2163
- Loading.displayName = "Loading";
2116
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2117
+ progress.Progress.Root,
2118
+ {
2119
+ ref,
2120
+ value: null,
2121
+ "aria-label": ariaLabel,
2122
+ className: utils.cn(
2123
+ containerVariants4({ position, blockInteraction }),
2124
+ containerClassName,
2125
+ className
2126
+ ),
2127
+ ...props,
2128
+ children: [
2129
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": "true", className: utils.cn(overlayVariants({ visible: dim }), overlayClassName) }),
2130
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative z-50 flex size-full items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
2131
+ progress.Progress.Indicator,
2132
+ {
2133
+ "aria-hidden": "true",
2134
+ render: /* @__PURE__ */ jsxRuntime.jsx(chunk6MFMQCL5_js.Loading, { size: spinnerSizes[size] }),
2135
+ className: utils.cn(spinnerBaseClassName, spinnerClassName)
2136
+ }
2137
+ ) })
2138
+ ]
2139
+ }
2140
+ );
2141
+ }
2164
2142
  var trackVariants = utils.cva("w-full overflow-hidden rounded-full bg-elevation-elevation-3", {
2165
2143
  variants: {
2166
2144
  size: {
@@ -2173,44 +2151,42 @@ var trackVariants = utils.cva("w-full overflow-hidden rounded-full bg-elevation-
2173
2151
  size: "large"
2174
2152
  }
2175
2153
  });
2176
- var gaugeVariants = utils.cva("h-full rounded-full bg-icon-accent transition-[width] duration-300", {
2177
- variants: {
2178
- size: {
2179
- small: "",
2180
- medium: "",
2181
- large: ""
2154
+ var gaugeBaseClassName = "h-full rounded-full bg-icon-accent transition-[width] duration-300";
2155
+ var percentFormatter = new Intl.NumberFormat(void 0, { style: "percent" });
2156
+ function Progress({
2157
+ value = 0,
2158
+ max = 100,
2159
+ size = "medium",
2160
+ trackClassName,
2161
+ gaugeClassName,
2162
+ className,
2163
+ ref,
2164
+ "aria-label": ariaLabel = "Progress",
2165
+ "aria-valuetext": ariaValueText,
2166
+ ...props
2167
+ }) {
2168
+ const clampedValue = Math.min(Math.max(value, 0), max);
2169
+ const percent = max > 0 ? clampedValue / max : 0;
2170
+ return /* @__PURE__ */ jsxRuntime.jsx(
2171
+ progress.Progress.Root,
2172
+ {
2173
+ ref,
2174
+ value: clampedValue,
2175
+ max,
2176
+ "aria-label": ariaLabel,
2177
+ "aria-valuetext": ariaValueText ?? percentFormatter.format(percent),
2178
+ className: utils.cn(trackVariants({ size }), trackClassName, className),
2179
+ ...props,
2180
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2181
+ progress.Progress.Indicator,
2182
+ {
2183
+ className: utils.cn(gaugeBaseClassName, gaugeClassName),
2184
+ style: max > 0 ? void 0 : { width: "0%" }
2185
+ }
2186
+ )
2182
2187
  }
2183
- },
2184
- defaultVariants: {
2185
- size: "medium"
2186
- }
2187
- });
2188
- var Progress = React.forwardRef(
2189
- ({ value = 0, max = 100, size = "medium", trackClassName, gaugeClassName, className, ...props }, ref) => {
2190
- const clampedValue = Math.min(Math.max(value, 0), max);
2191
- const percent = max > 0 ? clampedValue / max * 100 : 0;
2192
- return /* @__PURE__ */ jsxRuntime.jsx(
2193
- "div",
2194
- {
2195
- ref,
2196
- role: "progressbar",
2197
- "aria-valuenow": clampedValue,
2198
- "aria-valuemin": 0,
2199
- "aria-valuemax": max,
2200
- className: utils.cn(trackVariants({ size }), trackClassName, className),
2201
- ...props,
2202
- children: /* @__PURE__ */ jsxRuntime.jsx(
2203
- "div",
2204
- {
2205
- className: utils.cn(gaugeVariants({ size }), gaugeClassName),
2206
- style: { width: `${percent}%` }
2207
- }
2208
- )
2209
- }
2210
- );
2211
- }
2212
- );
2213
- Progress.displayName = "Progress";
2188
+ );
2189
+ }
2214
2190
  var positionFix = `
2215
2191
  [data-sonner-toaster][data-x-position='center'] [data-sonner-toast] {
2216
2192
  left: calc(var(--width) / 2) !important;
@@ -2653,7 +2629,7 @@ exports.DatePicker = DatePicker;
2653
2629
  exports.DoubleTag = DoubleTag;
2654
2630
  exports.Dropdown = Dropdown;
2655
2631
  exports.IconButton = IconButton;
2656
- exports.Loading = Loading;
2632
+ exports.Loading = Loading2;
2657
2633
  exports.MessageBox = MessageBox;
2658
2634
  exports.Modal = Modal;
2659
2635
  exports.Progress = Progress;
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ConditionalTooltip, overlayListVariants, commonInputVariants, textFieldVariants, ScrollArea } from './chunk-4JSE66SD.mjs';
2
2
  export { ColorPalette, ColorPaletteColors, Combobox, ComboboxContent, ComboboxDescription, ComboboxEmpty, ComboboxInput, ComboboxItem, ComboboxLabel, ComboboxList, ComboboxSearch, ComboboxTrigger, ComboboxValue, DEFAULT_COLOR, ScrollArea, ScrollBar, Segment, Select, Tabs, Tooltip, colorPaletteColorClasses, getColorPaletteColor, isInPalette } from './chunk-4JSE66SD.mjs';
3
- import { X, MoreHorizontal, iconSizes, Minus, Check, Person, Warning, Info, Error as Error$1, ChevronLeft, ChevronRight } from './chunk-4QQPDTTI.mjs';
3
+ import { X, MoreHorizontal, iconSizes, Minus, Check, Person, Loading, Warning, Info, Error as Error$1, ChevronLeft, ChevronRight } from './chunk-4QQPDTTI.mjs';
4
4
  import { cva, cn } from '@exem-ui/core/utils';
5
5
  import * as React from 'react';
6
6
  import { forwardRef, Fragment, cloneElement, useId, createContext, useContext, useState } from 'react';
@@ -9,10 +9,11 @@ import { Slot } from '@radix-ui/react-slot';
9
9
  import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
10
10
  import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
11
11
  import * as SwitchPrimitives from '@radix-ui/react-switch';
12
- import { getDefaultClassNames, DayPicker } from 'react-day-picker';
12
+ import { DayPicker } from 'react-day-picker';
13
13
  import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
14
14
  import * as DialogPrimitive from '@radix-ui/react-dialog';
15
15
  import { Resizable } from 're-resizable';
16
+ import { Progress as Progress$1 } from '@base-ui/react/progress';
16
17
  import { toast as toast$1, Toaster as Toaster$1 } from 'sonner';
17
18
 
18
19
  var SIZE_CONFIG = {
@@ -934,6 +935,16 @@ var Switch = forwardRef(
934
935
  }
935
936
  );
936
937
  Switch.displayName = SwitchPrimitives.Root.displayName;
938
+ function mergeClassNames(base, user) {
939
+ if (!user) {
940
+ return base;
941
+ }
942
+ const merged = { ...base };
943
+ for (const key in user) {
944
+ merged[key] = cn(base[key], user[key]);
945
+ }
946
+ return merged;
947
+ }
937
948
  function DatePickerChevron({ orientation }) {
938
949
  if (orientation === "left") {
939
950
  return /* @__PURE__ */ jsx(ChevronLeft, { type: "regular", className: "size-5" });
@@ -962,7 +973,6 @@ function DatePickerDayButton({
962
973
  }
963
974
  function DatePicker({ type = "single", showOutsideDays = true, ...rest }) {
964
975
  const dayPickerProps = { ...rest, mode: type };
965
- const defaultClassNames = getDefaultClassNames();
966
976
  const [month, setMonth] = useState(
967
977
  dayPickerProps.month ?? dayPickerProps.defaultMonth ?? /* @__PURE__ */ new Date()
968
978
  );
@@ -978,6 +988,41 @@ function DatePicker({ type = "single", showOutsideDays = true, ...rest }) {
978
988
  }
979
989
  dayPickerProps.onDayClick?.(day, modifiers, e);
980
990
  };
991
+ const dayPickerClassNames = {
992
+ root: "rounded-medium",
993
+ months: "relative",
994
+ month: "flex flex-col gap-2",
995
+ month_caption: "flex h-7 items-center px-0.5",
996
+ caption_label: "text-body-2 font-semibold text-text-primary",
997
+ nav: "absolute right-0 top-0 flex h-7 items-center gap-2",
998
+ button_previous: "flex size-7 items-center justify-center rounded-medium hover:bg-elevation-elevation-2",
999
+ button_next: "flex size-7 items-center justify-center rounded-medium hover:bg-elevation-elevation-2",
1000
+ weekday: "size-8 text-body-3 font-regular text-text-tertiary",
1001
+ month_grid: "border-separate border-spacing-x-0 border-spacing-y-1",
1002
+ week: "overflow-hidden rounded-medium",
1003
+ day: "size-8 text-body-2 font-medium text-text-secondary",
1004
+ day_button: "size-8 cursor-pointer rounded-full hover:border hover:border-border-focused",
1005
+ outside: "!text-text-disabled",
1006
+ selected: cn(
1007
+ "[&>button]:bg-solid-primary-default",
1008
+ "[&>button]:text-text-inverse",
1009
+ "[&>button]:border-0",
1010
+ "[&>button]:hover:border-0"
1011
+ ),
1012
+ range_start: cn(
1013
+ "rounded-none",
1014
+ isRangeComplete && "[background:linear-gradient(to_right,transparent_50%,var(--color-elevation-elevation-2)_50%)]"
1015
+ ),
1016
+ range_end: cn(
1017
+ "rounded-none",
1018
+ isRangeComplete && "[background:linear-gradient(to_left,transparent_50%,var(--color-elevation-elevation-2)_50%)]"
1019
+ ),
1020
+ range_middle: cn(
1021
+ "bg-elevation-elevation-2 rounded-none",
1022
+ "[&>button]:!bg-transparent",
1023
+ "[&>button]:!text-text-secondary"
1024
+ )
1025
+ };
981
1026
  return /* @__PURE__ */ jsx(
982
1027
  DayPicker,
983
1028
  {
@@ -1000,64 +1045,11 @@ function DatePicker({ type = "single", showOutsideDays = true, ...rest }) {
1000
1045
  DayButton: DatePickerDayButton,
1001
1046
  ...dayPickerProps.components
1002
1047
  },
1003
- classNames: {
1004
- root: cn(
1005
- defaultClassNames.root,
1006
- "rounded-medium border border-border-primary bg-background-overlay p-4 shadow-medium"
1007
- ),
1008
- months: cn(defaultClassNames.months, "relative"),
1009
- month: cn(defaultClassNames.month, "flex flex-col gap-2"),
1010
- month_caption: cn(defaultClassNames.month_caption, "flex h-7 items-center px-0.5"),
1011
- caption_label: "text-body-2 font-semibold text-text-primary",
1012
- nav: cn(defaultClassNames.nav, "absolute right-0 top-0 flex h-7 items-center gap-2"),
1013
- button_previous: cn(
1014
- defaultClassNames.button_previous,
1015
- "flex size-7 items-center justify-center rounded-medium hover:bg-elevation-elevation-2"
1016
- ),
1017
- button_next: cn(
1018
- defaultClassNames.button_next,
1019
- "flex size-7 items-center justify-center rounded-medium hover:bg-elevation-elevation-2"
1020
- ),
1021
- weekday: cn(
1022
- defaultClassNames.weekday,
1023
- "size-8 text-body-3 font-regular text-text-tertiary"
1024
- ),
1025
- month_grid: cn(
1026
- defaultClassNames.month_grid,
1027
- "border-separate border-spacing-x-0 border-spacing-y-1"
1028
- ),
1029
- week: cn(defaultClassNames.week, "overflow-hidden rounded-medium"),
1030
- day: cn(defaultClassNames.day, "size-8 text-body-2 font-medium text-text-secondary"),
1031
- day_button: cn(
1032
- defaultClassNames.day_button,
1033
- "size-8 cursor-pointer rounded-full hover:border hover:border-border-focused"
1034
- ),
1035
- outside: "!text-text-disabled",
1036
- selected: cn(
1037
- "[&>button]:bg-solid-primary-default",
1038
- "[&>button]:text-text-inverse",
1039
- "[&>button]:border-0",
1040
- "[&>button]:hover:border-0"
1041
- ),
1042
- range_start: cn(
1043
- "rounded-none",
1044
- isRangeComplete && "[background:linear-gradient(to_right,transparent_50%,var(--color-elevation-elevation-2)_50%)]"
1045
- ),
1046
- range_end: cn(
1047
- "rounded-none",
1048
- isRangeComplete && "[background:linear-gradient(to_left,transparent_50%,var(--color-elevation-elevation-2)_50%)]"
1049
- ),
1050
- range_middle: cn(
1051
- "bg-elevation-elevation-2 rounded-none",
1052
- "[&>button]:!bg-transparent",
1053
- "[&>button]:!text-text-secondary"
1054
- ),
1055
- ...dayPickerProps.classNames
1056
- },
1057
- modifiersClassNames: {
1058
- today: "rdp-calendar-today",
1059
- ...dayPickerProps.modifiersClassNames
1060
- }
1048
+ classNames: mergeClassNames(dayPickerClassNames, dayPickerProps.classNames),
1049
+ modifiersClassNames: mergeClassNames(
1050
+ { today: "rdp-calendar-today" },
1051
+ dayPickerProps.modifiersClassNames
1052
+ )
1061
1053
  }
1062
1054
  );
1063
1055
  }
@@ -2059,83 +2051,69 @@ var containerVariants4 = cva("inset-0 z-[49] flex items-center justify-center",
2059
2051
  blockInteraction: false
2060
2052
  }
2061
2053
  });
2062
- var overlayVariants = cva("absolute inset-0 transition-opacity duration-150", {
2063
- variants: {
2064
- visible: {
2065
- true: "opacity-100",
2066
- false: "opacity-0"
2067
- },
2068
- tone: {
2069
- // 대비감 높은 톤 설정 추후 디자인 시스템에서 추가 되어야함
2070
- auto: "bg-black/30 dark:bg-white/10",
2071
- dark: "bg-black/50",
2072
- light: "bg-white/70",
2073
- brand: "bg-primary/20"
2074
- }
2075
- },
2076
- defaultVariants: {
2077
- visible: true,
2078
- tone: "auto"
2079
- }
2080
- });
2081
- var spinnerVariants = cva(
2082
- "z-50 shrink-0 animate-spin rounded-full border-elevation-elevation-4 border-t-transparent",
2054
+ var overlayVariants = cva(
2055
+ "absolute inset-0 bg-component-dim transition-opacity duration-150 motion-reduce:transition-none",
2083
2056
  {
2084
2057
  variants: {
2085
- size: {
2086
- small: "size-6 border-2",
2087
- medium: "size-9 border-[3px]",
2088
- large: "size-12 border-4"
2058
+ visible: {
2059
+ true: "opacity-100",
2060
+ false: "opacity-0"
2089
2061
  }
2090
2062
  },
2091
2063
  defaultVariants: {
2092
- size: "large"
2064
+ visible: true
2093
2065
  }
2094
2066
  }
2095
2067
  );
2096
- var Loading = forwardRef(
2097
- ({
2098
- isLoading = true,
2099
- dim = true,
2100
- blockInteraction = false,
2101
- position = "fixed",
2102
- size = "medium",
2103
- containerClassName,
2104
- overlayClassName,
2105
- spinnerClassName,
2106
- className,
2107
- ...props
2108
- }, ref) => {
2109
- if (!isLoading) {
2110
- return null;
2111
- }
2112
- return /* @__PURE__ */ jsxs(
2113
- "div",
2114
- {
2115
- ref,
2116
- role: "status",
2117
- "aria-busy": "true",
2118
- className: cn(
2119
- containerVariants4({ position, blockInteraction }),
2120
- containerClassName,
2121
- className
2122
- ),
2123
- ...props,
2124
- children: [
2125
- /* @__PURE__ */ jsx(
2126
- "div",
2127
- {
2128
- "aria-hidden": "true",
2129
- className: cn(overlayVariants({ visible: dim }), overlayClassName)
2130
- }
2131
- ),
2132
- /* @__PURE__ */ jsx("div", { className: "relative z-50 flex size-full items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: cn(spinnerVariants({ size }), spinnerClassName) }) })
2133
- ]
2134
- }
2135
- );
2068
+ var spinnerBaseClassName = "relative z-50 shrink-0 animate-spin text-elevation-elevation-4 motion-reduce:animate-none";
2069
+ var spinnerSizes = {
2070
+ small: 24,
2071
+ medium: 36,
2072
+ large: 48
2073
+ };
2074
+ function Loading2({
2075
+ isLoading = true,
2076
+ dim = true,
2077
+ blockInteraction = false,
2078
+ position = "fixed",
2079
+ size = "medium",
2080
+ containerClassName,
2081
+ overlayClassName,
2082
+ spinnerClassName,
2083
+ className,
2084
+ ref,
2085
+ "aria-label": ariaLabel = "Loading",
2086
+ ...props
2087
+ }) {
2088
+ if (!isLoading) {
2089
+ return null;
2136
2090
  }
2137
- );
2138
- Loading.displayName = "Loading";
2091
+ return /* @__PURE__ */ jsxs(
2092
+ Progress$1.Root,
2093
+ {
2094
+ ref,
2095
+ value: null,
2096
+ "aria-label": ariaLabel,
2097
+ className: cn(
2098
+ containerVariants4({ position, blockInteraction }),
2099
+ containerClassName,
2100
+ className
2101
+ ),
2102
+ ...props,
2103
+ children: [
2104
+ /* @__PURE__ */ jsx("div", { "aria-hidden": "true", className: cn(overlayVariants({ visible: dim }), overlayClassName) }),
2105
+ /* @__PURE__ */ jsx("div", { className: "relative z-50 flex size-full items-center justify-center", children: /* @__PURE__ */ jsx(
2106
+ Progress$1.Indicator,
2107
+ {
2108
+ "aria-hidden": "true",
2109
+ render: /* @__PURE__ */ jsx(Loading, { size: spinnerSizes[size] }),
2110
+ className: cn(spinnerBaseClassName, spinnerClassName)
2111
+ }
2112
+ ) })
2113
+ ]
2114
+ }
2115
+ );
2116
+ }
2139
2117
  var trackVariants = cva("w-full overflow-hidden rounded-full bg-elevation-elevation-3", {
2140
2118
  variants: {
2141
2119
  size: {
@@ -2148,44 +2126,42 @@ var trackVariants = cva("w-full overflow-hidden rounded-full bg-elevation-elevat
2148
2126
  size: "large"
2149
2127
  }
2150
2128
  });
2151
- var gaugeVariants = cva("h-full rounded-full bg-icon-accent transition-[width] duration-300", {
2152
- variants: {
2153
- size: {
2154
- small: "",
2155
- medium: "",
2156
- large: ""
2129
+ var gaugeBaseClassName = "h-full rounded-full bg-icon-accent transition-[width] duration-300";
2130
+ var percentFormatter = new Intl.NumberFormat(void 0, { style: "percent" });
2131
+ function Progress({
2132
+ value = 0,
2133
+ max = 100,
2134
+ size = "medium",
2135
+ trackClassName,
2136
+ gaugeClassName,
2137
+ className,
2138
+ ref,
2139
+ "aria-label": ariaLabel = "Progress",
2140
+ "aria-valuetext": ariaValueText,
2141
+ ...props
2142
+ }) {
2143
+ const clampedValue = Math.min(Math.max(value, 0), max);
2144
+ const percent = max > 0 ? clampedValue / max : 0;
2145
+ return /* @__PURE__ */ jsx(
2146
+ Progress$1.Root,
2147
+ {
2148
+ ref,
2149
+ value: clampedValue,
2150
+ max,
2151
+ "aria-label": ariaLabel,
2152
+ "aria-valuetext": ariaValueText ?? percentFormatter.format(percent),
2153
+ className: cn(trackVariants({ size }), trackClassName, className),
2154
+ ...props,
2155
+ children: /* @__PURE__ */ jsx(
2156
+ Progress$1.Indicator,
2157
+ {
2158
+ className: cn(gaugeBaseClassName, gaugeClassName),
2159
+ style: max > 0 ? void 0 : { width: "0%" }
2160
+ }
2161
+ )
2157
2162
  }
2158
- },
2159
- defaultVariants: {
2160
- size: "medium"
2161
- }
2162
- });
2163
- var Progress = forwardRef(
2164
- ({ value = 0, max = 100, size = "medium", trackClassName, gaugeClassName, className, ...props }, ref) => {
2165
- const clampedValue = Math.min(Math.max(value, 0), max);
2166
- const percent = max > 0 ? clampedValue / max * 100 : 0;
2167
- return /* @__PURE__ */ jsx(
2168
- "div",
2169
- {
2170
- ref,
2171
- role: "progressbar",
2172
- "aria-valuenow": clampedValue,
2173
- "aria-valuemin": 0,
2174
- "aria-valuemax": max,
2175
- className: cn(trackVariants({ size }), trackClassName, className),
2176
- ...props,
2177
- children: /* @__PURE__ */ jsx(
2178
- "div",
2179
- {
2180
- className: cn(gaugeVariants({ size }), gaugeClassName),
2181
- style: { width: `${percent}%` }
2182
- }
2183
- )
2184
- }
2185
- );
2186
- }
2187
- );
2188
- Progress.displayName = "Progress";
2163
+ );
2164
+ }
2189
2165
  var positionFix = `
2190
2166
  [data-sonner-toaster][data-x-position='center'] [data-sonner-toast] {
2191
2167
  left: calc(var(--width) / 2) !important;
@@ -2526,4 +2502,4 @@ var buttonize = (fn) => {
2526
2502
  };
2527
2503
  };
2528
2504
 
2529
- export { Avatar, Badge, Breadcrumb, Button, ButtonGroup, Checkbox, DatePicker, DoubleTag, Dropdown, IconButton, Loading, MessageBox, Modal, Progress, Radio, Sheet, Star, Switch, Tag, TextArea, TextField, ToastProvider, Toaster, buttonize, toast, useToast };
2505
+ export { Avatar, Badge, Breadcrumb, Button, ButtonGroup, Checkbox, DatePicker, DoubleTag, Dropdown, IconButton, Loading2 as Loading, MessageBox, Modal, Progress, Radio, Sheet, Star, Switch, Tag, TextArea, TextField, ToastProvider, Toaster, buttonize, toast, useToast };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exem-ui/react",
3
- "version": "0.3.4-next.20260819010838",
3
+ "version": "0.3.4-next.20260828070546",
4
4
  "description": "Exem Design System - React Components",
5
5
  "author": "Exem Design Team",
6
6
  "license": "Apache-2.0",
@@ -100,7 +100,7 @@
100
100
  "tailwind-merge": "^3.3.1",
101
101
  "tailwind-scrollbar-hide": "^4.0.0",
102
102
  "tiny-invariant": "^1.3.3",
103
- "@exem-ui/core": "0.3.3-next.20260819010838"
103
+ "@exem-ui/core": "0.3.3-next.20260828070546"
104
104
  },
105
105
  "devDependencies": {
106
106
  "@eslint/js": "^9.15.0",
@@ -136,7 +136,7 @@
136
136
  "tsup": "^8.5.0",
137
137
  "typescript": "^5.8.2",
138
138
  "typescript-eslint": "^8.16.0",
139
- "@exem-ui/tailwindcss3": "0.3.2-next.20260819010838"
139
+ "@exem-ui/tailwindcss3": "0.3.2-next.20260828070546"
140
140
  },
141
141
  "scripts": {
142
142
  "generate": "node scripts/generate-icons.js",