@uniai-fe/uds-primitives 0.0.18 → 0.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +9 -5
  2. package/dist/styles.css +55 -1017
  3. package/package.json +1 -6
  4. package/src/components/alternate/styles/index.scss +0 -2
  5. package/src/components/badge/styles/index.scss +1 -3
  6. package/src/components/button/styles/button.scss +0 -1
  7. package/src/components/button/styles/round-button.scss +0 -2
  8. package/src/components/button/styles/text-button.scss +0 -2
  9. package/src/components/calendar/styles/index.scss +0 -2
  10. package/src/components/checkbox/styles/index.scss +1 -3
  11. package/src/components/chip/styles/index.scss +1 -3
  12. package/src/components/drawer/styles/index.scss +1 -3
  13. package/src/components/dropdown/styles/index.scss +0 -2
  14. package/src/components/input/styles/index.scss +2 -3
  15. package/src/components/label/styles/index.scss +0 -2
  16. package/src/components/navigation/styles/index.scss +1 -3
  17. package/src/components/pagination/styles/index.scss +0 -2
  18. package/src/components/radio/styles/index.scss +1 -3
  19. package/src/components/scrollbar/styles/index.scss +0 -2
  20. package/src/components/segmented-control/markup/Container.tsx +255 -0
  21. package/src/components/segmented-control/markup/Indicator.tsx +31 -0
  22. package/src/components/segmented-control/markup/List.tsx +125 -0
  23. package/src/components/segmented-control/markup/index.ts +1 -1
  24. package/src/components/segmented-control/styles/index.scss +51 -50
  25. package/src/components/segmented-control/types/index.ts +48 -10
  26. package/src/components/select/styles/index.scss +0 -2
  27. package/src/components/spinner/styles/index.scss +0 -2
  28. package/src/components/tab/styles/index.scss +0 -2
  29. package/src/components/table/styles/index.scss +0 -2
  30. package/src/index.scss +2 -4
  31. package/src/index.tsx +1 -2
  32. package/src/components/dialog/hooks/index.ts +0 -4
  33. package/src/components/dialog/img/.gitkeep +0 -0
  34. package/src/components/dialog/index.scss +0 -1
  35. package/src/components/dialog/index.tsx +0 -6
  36. package/src/components/dialog/markup/ConfirmDialog.tsx +0 -339
  37. package/src/components/dialog/markup/NoticeDialog.tsx +0 -209
  38. package/src/components/dialog/markup/index.tsx +0 -4
  39. package/src/components/dialog/styles/base.scss +0 -153
  40. package/src/components/dialog/styles/confirm.scss +0 -58
  41. package/src/components/dialog/styles/index.scss +0 -3
  42. package/src/components/dialog/styles/notice.scss +0 -65
  43. package/src/components/dialog/types/index.ts +0 -113
  44. package/src/components/dialog/utils/index.ts +0 -4
  45. package/src/components/segmented-control/markup/SegmentedControl.tsx +0 -129
  46. package/src/theme/ThemeProvider.tsx +0 -25
  47. package/src/theme/config.ts +0 -29
  48. package/src/theme/index.ts +0 -3
  49. package/src/theme/overrides.scss +0 -215
@@ -1,5 +1,3 @@
1
- @use "@uniai-fe/uds-foundation/css";
2
-
3
1
  .segmented-control {
4
2
  --segmented-height: 34px;
5
3
  --segmented-padding: 2px;
@@ -10,96 +8,98 @@
10
8
  --segmented-label-color: var(--color-label-neutral, #797e86);
11
9
  --segmented-label-active-color: var(--color-label-strong, #181a1b);
12
10
  --segmented-disabled-opacity: 0.4;
11
+ --segmented-gap: 2px;
13
12
  --segmented-item-padding-x: 22px;
14
13
  --segmented-item-padding-y: 4px;
15
14
  --segmented-item-font-size: var(--font-heading-xxsmall-size, 15px);
16
15
  --segmented-item-font-weight: var(--font-heading-xxsmall-weight, 500);
17
16
  --segmented-item-line-height: var(--font-heading-xxsmall-line-height, 1.5);
18
- display: grid;
19
- grid-auto-flow: column;
20
- grid-auto-columns: 1fr;
21
- align-items: stretch;
17
+ position: relative;
18
+ display: block;
19
+ box-sizing: border-box;
22
20
  padding: var(--segmented-padding);
23
21
  border-radius: var(--segmented-radius);
24
22
  background: var(--segmented-bg);
25
23
  width: fit-content;
26
- height: var(--segmented-height);
27
- font-size: 0;
24
+ min-height: var(--segmented-height);
28
25
  isolation: isolate;
29
- }
30
-
31
- .segmented-control:where(.rt-SegmentedControlRoot) {
32
- /* Radix Theme 기본 inline-grid를 덮어 동일한 sizing 시스템에서만 layout이 될 수 있도록 한다. */
33
- display: grid;
26
+ overflow: hidden;
34
27
  }
35
28
 
36
29
  .segmented-control:where([data-keep-selected="true"]) {
37
30
  --segmented-disabled-opacity: 0.3;
38
31
  }
39
32
 
40
- .segmented-control :where(.rt-SegmentedControlIndicator) {
41
- border-radius: calc(var(--segmented-radius) - var(--segmented-padding));
42
- background: transparent;
43
- box-shadow: none;
44
- overflow: hidden;
45
- }
46
-
47
- .segmented-control :where(.rt-SegmentedControlIndicator)::before {
48
- content: "";
33
+ .segmented-control-indicator {
49
34
  position: absolute;
50
- inset: var(--segmented-padding);
35
+ top: var(--segmented-padding);
36
+ bottom: var(--segmented-padding);
37
+ left: 0;
38
+ width: 0px;
39
+ height: calc(100% - (var(--segmented-padding) * 2));
40
+ margin: 0;
51
41
  border-radius: calc(var(--segmented-radius) - var(--segmented-padding));
52
42
  background: var(--segmented-indicator-bg);
53
43
  box-shadow: var(--segmented-indicator-shadow);
44
+ transition:
45
+ transform 0.2s ease,
46
+ width 0.2s ease,
47
+ opacity 0.2s ease;
48
+ pointer-events: none;
49
+ z-index: 0;
54
50
  }
55
51
 
56
- .segmented-control :where(.rt-SegmentedControlItemSeparator) {
57
- display: none;
52
+ .segmented-control-indicator[data-visible="false"] {
53
+ opacity: 0;
58
54
  }
59
55
 
60
- .segmented-control :where(.rt-SegmentedControlItem) {
61
- background: transparent;
62
- padding: 0;
63
- border: none;
64
- min-width: 0;
56
+ .segmented-control-list {
65
57
  display: flex;
58
+ column-gap: var(--segmented-gap);
59
+ row-gap: 0;
60
+ margin: 0;
61
+ padding: 0;
62
+ list-style: none;
63
+ position: relative;
64
+ z-index: 1;
66
65
  }
67
66
 
68
- .segmented-control :where(.rt-SegmentedControlItemLabel) {
69
- gap: 0;
70
- height: fit-content;
67
+ .segmented-control-item {
68
+ list-style: none;
69
+ margin: 0;
71
70
  padding: 0;
72
- font-size: 0;
73
71
  }
74
72
 
75
- .segmented-control-item {
73
+ .segmented-control-button {
74
+ position: relative;
75
+ z-index: 1;
76
+ display: flex;
77
+ align-items: center;
78
+ justify-content: center;
76
79
  width: 100%;
77
- height: 100%;
78
80
  border: none;
79
81
  background: transparent;
80
82
  cursor: pointer;
81
- .rt-SegmentedControlItemLabel {
82
- display: flex;
83
- align-items: center;
84
- justify-content: center;
85
- padding: var(--segmented-item-padding-y) var(--segmented-item-padding-x);
86
- border-radius: calc(var(--segmented-radius) - var(--segmented-padding));
87
- }
83
+ min-width: 0;
84
+ border-radius: calc(var(--segmented-radius) - var(--segmented-padding));
85
+ padding: var(--segmented-item-padding-y) var(--segmented-item-padding-x);
86
+ transition: color 0.2s ease;
88
87
  }
89
- .segmented-control-item:where([data-disabled="true"]) {
88
+
89
+ .segmented-control-button:where([data-disabled="true"]) {
90
90
  cursor: not-allowed;
91
91
  opacity: var(--segmented-disabled-opacity);
92
92
  }
93
93
 
94
- .segmented-control-item:where(:focus-visible) {
94
+ .segmented-control-button:where(:focus-visible) {
95
95
  outline: 2px solid var(--color-focus-ring, var(--color-primary-default));
96
96
  outline-offset: 2px;
97
97
  }
98
98
 
99
- .segmented-control-item-label {
100
- // display: flex;
101
- // align-items: center;
102
- // justify-content: center;
99
+ .segmented-control-button-label {
100
+ display: flex;
101
+ align-items: center;
102
+ justify-content: center;
103
103
  font-size: var(--segmented-item-font-size);
104
104
  font-weight: var(--segmented-item-font-weight);
105
105
  line-height: var(--segmented-item-line-height);
@@ -108,6 +108,7 @@
108
108
  transition: color 0.2s ease;
109
109
  }
110
110
 
111
- .segmented-control-item:where([data-state="on"]) .segmented-control-item-label {
111
+ .segmented-control-button:where([data-state="on"])
112
+ .segmented-control-button-label {
112
113
  color: var(--segmented-label-active-color);
113
114
  }
@@ -1,5 +1,11 @@
1
- import type { ComponentPropsWithoutRef } from "react";
2
- import type { SegmentedControl as RadixSegmentedControlNamespace } from "@radix-ui/themes";
1
+ import type {
2
+ ComponentPropsWithoutRef,
3
+ FocusEvent,
4
+ KeyboardEvent,
5
+ MouseEvent,
6
+ MutableRefObject,
7
+ PointerEvent,
8
+ } from "react";
3
9
 
4
10
  /**
5
11
  * SegmentedControl value 타입. 문자열 value를 사용한다.
@@ -18,21 +24,53 @@ export interface SegmentedControlOption {
18
24
  disabled?: boolean;
19
25
  }
20
26
 
21
- type RadixSegmentedControlRootProps = ComponentPropsWithoutRef<
22
- typeof RadixSegmentedControlNamespace.Root
23
- >;
24
-
25
27
  /**
26
- * SegmentedControl props. Radix Root props에서 children을 제거하고 options/ariaLabel 강제한다.
28
+ * SegmentedControl props. native div props options/ariaLabel/keepSelected 등을 확장한다.
27
29
  * @property {SegmentedControlOption[]} options 렌더할 옵션 배열.
28
30
  * @property {string} ariaLabel 스크린리더용 라벨. 필수.
29
31
  * @property {boolean} [keepSelected=true] 선택된 항목을 다시 클릭했을 때 해제하지 않고 유지할지 여부.
30
32
  */
31
- export interface SegmentedControlProps extends Omit<
32
- RadixSegmentedControlRootProps,
33
+ type SegmentedControlRootProps = Omit<
34
+ ComponentPropsWithoutRef<"div">,
33
35
  "children"
34
- > {
36
+ >;
37
+
38
+ export interface SegmentedControlProps extends SegmentedControlRootProps {
35
39
  options: SegmentedControlOption[];
36
40
  ariaLabel: string;
37
41
  keepSelected?: boolean;
42
+ value?: SegmentedControlValue;
43
+ defaultValue?: SegmentedControlValue;
44
+ onValueChange?: (value: SegmentedControlValue) => void;
45
+ }
46
+
47
+ export interface SegmentedControlIndicatorRect {
48
+ width: number;
49
+ left: number;
50
+ }
51
+
52
+ export interface SegmentedControlIndicatorProps {
53
+ rect: SegmentedControlIndicatorRect;
54
+ visible: boolean;
55
+ }
56
+
57
+ export type SegmentedControlButtonEvent =
58
+ | MouseEvent<HTMLButtonElement>
59
+ | PointerEvent<HTMLButtonElement>
60
+ | KeyboardEvent<HTMLButtonElement>
61
+ | FocusEvent<HTMLButtonElement>;
62
+
63
+ export interface SegmentedControlListProps {
64
+ options: SegmentedControlOption[];
65
+ keepSelected: boolean;
66
+ selectedValue?: SegmentedControlValue;
67
+ focusableIndex: number;
68
+ fallbackIndex: number;
69
+ itemRefs: MutableRefObject<Array<HTMLButtonElement | null>>;
70
+ onSelect: (value: SegmentedControlValue | undefined) => void;
71
+ onFocusItemAt: (index: number) => void;
72
+ onArrowNavigate: (
73
+ event: KeyboardEvent<HTMLButtonElement>,
74
+ currentIndex: number,
75
+ ) => void;
38
76
  }
@@ -1,3 +1 @@
1
- @use "@uniai-fe/uds-foundation/css";
2
-
3
1
  /* TODO(select): 스타일을 SOT 토큰 값으로 정의한다. */
@@ -1,3 +1 @@
1
- @use "@uniai-fe/uds-foundation/css";
2
-
3
1
  /* TODO(spinner): 스타일을 SOT 토큰 값으로 정의한다. */
@@ -1,5 +1,3 @@
1
- @use "@uniai-fe/uds-foundation/css";
2
-
3
1
  .tab-root {
4
2
  /* Figma node 694:4619 측정값을 CSS 변수로 고정해 Storybook과 실 서비스 간 시각 편차를 줄인다. */
5
3
  --tab-label-font-size: var(--font-heading-xsmall-size, 17px);
@@ -1,3 +1 @@
1
- @use "@uniai-fe/uds-foundation/css";
2
-
3
1
  /* TODO(table): 스타일을 SOT 토큰 값으로 정의한다. */
package/src/index.scss CHANGED
@@ -1,7 +1,5 @@
1
- @use "@uniai-fe/uds-foundation/css";
2
- @use "./theme/overrides.scss";
3
-
4
- /* 모든 primitives component SCSS를 한 번에 노출해 서비스 import 부담을 줄인다. */
1
+ /* 모든 primitives component SCSS를 한 번에 노출해 서비스 import 부담을 줄인다.
2
+ foundation CSS(`@uniai-fe/uds-foundation/css`)는 소비자가 별도로 한 번만 로드해야 한다. */
5
3
  @use "./components/alternate";
6
4
  @use "./components/badge";
7
5
  @use "./components/button";
package/src/index.tsx CHANGED
@@ -1,7 +1,6 @@
1
1
  // dayjs 초기화를 가장 먼저 수행해 날짜 계열 컴포넌트가 동일 컨텍스트를 사용한다.
2
2
  import "./init/dayjs";
3
-
4
- export * from "./theme";
3
+ // ThemeProvider는 foundation provider에서만 export한다(one-source 규칙).
5
4
 
6
5
  // 루트 배럴: 카테고리별 export를 집계한다.
7
6
  export * from "./components/button";
@@ -1,4 +0,0 @@
1
- /**
2
- * TODO(dialog): 접근성/상태 계산 hook을 정의한다.
3
- */
4
- export {};
File without changes
@@ -1 +0,0 @@
1
- @use "./styles/index.scss";
@@ -1,6 +0,0 @@
1
- import "./index.scss";
2
-
3
- export * from "./markup";
4
- export * from "./hooks";
5
- export type * from "./types";
6
- export * from "./utils";
@@ -1,339 +0,0 @@
1
- import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
2
- import { VisuallyHidden } from "@radix-ui/react-visually-hidden";
3
- import clsx from "clsx";
4
- import { createContext, forwardRef, useContext, useState } from "react";
5
- import type {
6
- ConfirmDialogActionProps,
7
- ConfirmDialogCancelProps,
8
- ConfirmDialogContentProps,
9
- ConfirmDialogDescriptionProps,
10
- ConfirmDialogOverlayProps,
11
- ConfirmDialogSectionProps,
12
- ConfirmDialogTitleProps,
13
- ConfirmDialogRootProps,
14
- } from "../types";
15
- import type { PointerEvent } from "react";
16
-
17
- type ConfirmDialogInternalContextValue = {
18
- requestClose: () => void;
19
- };
20
-
21
- const ConfirmDialogInternalContext = createContext<
22
- ConfirmDialogInternalContextValue | undefined
23
- >(undefined);
24
-
25
- const useConfirmDialogInternalContext = () => {
26
- const context = useContext(ConfirmDialogInternalContext);
27
- if (!context) {
28
- throw new Error(
29
- "ConfirmDialog components must be used within ConfirmDialogRoot",
30
- );
31
- }
32
- return context;
33
- };
34
-
35
- /**
36
- * ConfirmDialogRoot; AlertDialog 루트
37
- * @component
38
- * @param {ConfirmDialogRootProps} props
39
- * @param {boolean} [props.open] 제어형 open 상태.
40
- * @param {boolean} [props.defaultOpen] 비제어 초기 open 상태.
41
- * @param {(open: boolean) => void} [props.onOpenChange] open 변경 콜백.
42
- */
43
- const ConfirmDialogRoot = ({
44
- open: openProp,
45
- defaultOpen,
46
- onOpenChange,
47
- children,
48
- ...restProps
49
- }: ConfirmDialogRootProps) => {
50
- const isControlled = openProp !== undefined;
51
- const [uncontrolledOpen, setUncontrolledOpen] = useState(
52
- defaultOpen ?? false,
53
- );
54
- const resolvedOpen = isControlled ? openProp : uncontrolledOpen;
55
-
56
- const handleOpenChange = (nextOpen: boolean) => {
57
- if (!isControlled) {
58
- setUncontrolledOpen(nextOpen);
59
- }
60
- onOpenChange?.(nextOpen);
61
- };
62
-
63
- return (
64
- <ConfirmDialogInternalContext.Provider
65
- value={{
66
- requestClose: () => handleOpenChange(false),
67
- }}
68
- >
69
- <AlertDialogPrimitive.Root
70
- {...restProps}
71
- open={resolvedOpen}
72
- onOpenChange={handleOpenChange}
73
- >
74
- {children}
75
- </AlertDialogPrimitive.Root>
76
- </ConfirmDialogInternalContext.Provider>
77
- );
78
- };
79
- const ConfirmDialogTrigger = AlertDialogPrimitive.Trigger;
80
- const ConfirmDialogPortal = AlertDialogPrimitive.Portal;
81
-
82
- /**
83
- * ConfirmDialogOverlay; 취소 성격의 바깥 dim
84
- * @component
85
- * @param {ConfirmDialogOverlayProps} props
86
- * @param {string} [props.className] overlay className.
87
- * @param {boolean} [props.disableOutsideClose=false] dim 클릭으로 닫힘 방지 여부.
88
- */
89
- const ConfirmDialogOverlay = forwardRef<
90
- HTMLDivElement,
91
- ConfirmDialogOverlayProps
92
- >(
93
- (
94
- { className, disableOutsideClose = false, onPointerDown, ...props },
95
- forwardedRef,
96
- ) => {
97
- const { requestClose } = useConfirmDialogInternalContext();
98
-
99
- const handlePointerDown = (event: PointerEvent<HTMLDivElement>) => {
100
- onPointerDown?.(event);
101
- if (event.defaultPrevented) {
102
- return;
103
- }
104
- if (disableOutsideClose) {
105
- return;
106
- }
107
- requestClose();
108
- };
109
-
110
- return (
111
- <AlertDialogPrimitive.Overlay
112
- {...props}
113
- ref={forwardedRef}
114
- className={clsx("dialog-overlay confirm-dialog-overlay", className)}
115
- data-variant="confirm"
116
- onPointerDown={handlePointerDown}
117
- />
118
- );
119
- },
120
- );
121
-
122
- ConfirmDialogOverlay.displayName = "ConfirmDialogOverlay";
123
-
124
- /**
125
- * ConfirmDialogContent; AlertDialog 패널
126
- * @component
127
- * @param {ConfirmDialogContentProps} props
128
- * @param {string} [props.className] content className.
129
- * @param {React.ReactNode} [props.children] 패널 내용.
130
- */
131
- const ConfirmDialogContent = forwardRef<
132
- HTMLDivElement,
133
- ConfirmDialogContentProps
134
- >(({ className, children, ...props }, forwardedRef) => (
135
- <AlertDialogPrimitive.Content
136
- {...props}
137
- ref={forwardedRef}
138
- className={clsx("dialog-content confirm-dialog-content", className)}
139
- data-variant="confirm"
140
- >
141
- {children}
142
- </AlertDialogPrimitive.Content>
143
- ));
144
-
145
- ConfirmDialogContent.displayName = "ConfirmDialogContent";
146
-
147
- /**
148
- * ConfirmDialogTitle; AlertDialog 제목
149
- * @component
150
- * @param {ConfirmDialogTitleProps} props
151
- * @param {string} [props.className] title className.
152
- * @param {boolean} [props.visuallyHidden=false] 제목 시각적 숨김 여부.
153
- * @param {React.ReactNode} [props.children] 제목 텍스트.
154
- */
155
- const ConfirmDialogTitle = forwardRef<
156
- HTMLHeadingElement,
157
- ConfirmDialogTitleProps
158
- >(({ className, visuallyHidden = false, children, ...props }, forwardedRef) => {
159
- const titleNode = (
160
- <AlertDialogPrimitive.Title
161
- {...props}
162
- ref={forwardedRef}
163
- className={clsx("dialog-title confirm-dialog-title", className)}
164
- data-variant="confirm"
165
- >
166
- {children}
167
- </AlertDialogPrimitive.Title>
168
- );
169
-
170
- if (visuallyHidden) {
171
- return <VisuallyHidden asChild>{titleNode}</VisuallyHidden>;
172
- }
173
-
174
- return titleNode;
175
- });
176
-
177
- ConfirmDialogTitle.displayName = "ConfirmDialogTitle";
178
-
179
- /**
180
- * ConfirmDialogDescription; AlertDialog 설명
181
- * @component
182
- * @param {ConfirmDialogDescriptionProps} props
183
- * @param {string} [props.className] description className.
184
- * @param {boolean} [props.visuallyHidden=false] 설명 시각적 숨김 여부.
185
- * @param {React.ReactNode} [props.children] 설명 텍스트.
186
- */
187
- const ConfirmDialogDescription = forwardRef<
188
- HTMLParagraphElement,
189
- ConfirmDialogDescriptionProps
190
- >(({ className, visuallyHidden = false, children, ...props }, forwardedRef) => {
191
- const descriptionNode = (
192
- <AlertDialogPrimitive.Description
193
- {...props}
194
- ref={forwardedRef}
195
- className={clsx(
196
- "dialog-description confirm-dialog-description",
197
- className,
198
- )}
199
- data-variant="confirm"
200
- >
201
- {children}
202
- </AlertDialogPrimitive.Description>
203
- );
204
-
205
- if (visuallyHidden) {
206
- return <VisuallyHidden asChild>{descriptionNode}</VisuallyHidden>;
207
- }
208
-
209
- return descriptionNode;
210
- });
211
-
212
- ConfirmDialogDescription.displayName = "ConfirmDialogDescription";
213
-
214
- /**
215
- * ConfirmDialogHeader; 헤더 영역
216
- * @component
217
- * @param {ConfirmDialogSectionProps} props
218
- * @param {string} [props.className] 섹션 className.
219
- * @param {React.ReactNode} [props.children] 헤더 콘텐츠.
220
- */
221
- const ConfirmDialogHeader = forwardRef<
222
- HTMLDivElement,
223
- ConfirmDialogSectionProps
224
- >(({ className, ...props }, forwardedRef) => (
225
- <div
226
- {...props}
227
- ref={forwardedRef}
228
- className={clsx("dialog-section confirm-dialog-header", className)}
229
- data-section="header"
230
- />
231
- ));
232
-
233
- ConfirmDialogHeader.displayName = "ConfirmDialogHeader";
234
-
235
- /**
236
- * ConfirmDialogBody; 본문 영역
237
- * @component
238
- * @param {ConfirmDialogSectionProps} props
239
- * @param {string} [props.className] 섹션 className.
240
- * @param {React.ReactNode} [props.children] 본문 콘텐츠.
241
- */
242
- const ConfirmDialogBody = forwardRef<HTMLDivElement, ConfirmDialogSectionProps>(
243
- ({ className, ...props }, forwardedRef) => (
244
- <div
245
- {...props}
246
- ref={forwardedRef}
247
- className={clsx("dialog-section confirm-dialog-body", className)}
248
- data-section="body"
249
- />
250
- ),
251
- );
252
-
253
- ConfirmDialogBody.displayName = "ConfirmDialogBody";
254
-
255
- /**
256
- * ConfirmDialogActions; 버튼 영역
257
- * @component
258
- * @param {ConfirmDialogSectionProps} props
259
- * @param {string} [props.className] 섹션 className.
260
- * @param {React.ReactNode} [props.children] 버튼 콘텐츠.
261
- */
262
- const ConfirmDialogActions = forwardRef<
263
- HTMLDivElement,
264
- ConfirmDialogSectionProps
265
- >(({ className, ...props }, forwardedRef) => (
266
- <div
267
- {...props}
268
- ref={forwardedRef}
269
- className={clsx("dialog-section confirm-dialog-actions", className)}
270
- data-section="actions"
271
- />
272
- ));
273
-
274
- ConfirmDialogActions.displayName = "ConfirmDialogActions";
275
-
276
- /**
277
- * ConfirmDialogCancelButton; AlertDialog Cancel wrapper
278
- * @component
279
- * @param {ConfirmDialogCancelProps} props
280
- * @param {string} [props.className] button className.
281
- * @param {boolean} [props.asChild=false] slot mode 사용 여부.
282
- */
283
- const ConfirmDialogCancel = forwardRef<
284
- HTMLButtonElement,
285
- ConfirmDialogCancelProps
286
- >(({ className, asChild, ...props }, forwardedRef) => (
287
- <AlertDialogPrimitive.Cancel
288
- {...props}
289
- asChild={asChild}
290
- ref={forwardedRef}
291
- className={clsx(
292
- !asChild && "dialog-button confirm-dialog-cancel",
293
- className,
294
- )}
295
- data-native-element={asChild ? undefined : "true"}
296
- />
297
- ));
298
-
299
- ConfirmDialogCancel.displayName = "ConfirmDialogCancel";
300
-
301
- /**
302
- * ConfirmDialogActionButton; AlertDialog Action wrapper
303
- * @component
304
- * @param {ConfirmDialogActionProps} props
305
- * @param {string} [props.className] button className.
306
- * @param {boolean} [props.asChild=false] slot mode 사용 여부.
307
- */
308
- const ConfirmDialogAction = forwardRef<
309
- HTMLButtonElement,
310
- ConfirmDialogActionProps
311
- >(({ className, asChild, ...props }, forwardedRef) => (
312
- <AlertDialogPrimitive.Action
313
- {...props}
314
- asChild={asChild}
315
- ref={forwardedRef}
316
- className={clsx(
317
- !asChild && "dialog-button confirm-dialog-action",
318
- className,
319
- )}
320
- data-native-element={asChild ? undefined : "true"}
321
- />
322
- ));
323
-
324
- ConfirmDialogAction.displayName = "ConfirmDialogAction";
325
-
326
- export {
327
- ConfirmDialogRoot,
328
- ConfirmDialogTrigger,
329
- ConfirmDialogPortal,
330
- ConfirmDialogOverlay,
331
- ConfirmDialogContent,
332
- ConfirmDialogTitle,
333
- ConfirmDialogDescription,
334
- ConfirmDialogHeader,
335
- ConfirmDialogBody,
336
- ConfirmDialogActions,
337
- ConfirmDialogCancel,
338
- ConfirmDialogAction,
339
- };