@uniai-fe/uds-primitives 0.0.7 → 0.0.9

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 (56) hide show
  1. package/README.md +64 -5
  2. package/dist/styles.css +220 -303
  3. package/package.json +4 -4
  4. package/src/components/badge/markup/Badge.tsx +10 -0
  5. package/src/components/badge/styles/index.scss +2 -2
  6. package/src/components/badge/types/index.ts +1 -1
  7. package/src/components/button/index.scss +3 -1
  8. package/src/components/button/index.tsx +9 -1
  9. package/src/components/button/markup/ButtonDefault.tsx +162 -0
  10. package/src/components/button/markup/ButtonRounded.tsx +48 -0
  11. package/src/components/button/markup/ButtonText.tsx +49 -0
  12. package/src/components/button/markup/index.ts +3 -0
  13. package/src/components/button/styles/{index.scss → button.scss} +202 -424
  14. package/src/components/button/styles/round-button.scss +56 -0
  15. package/src/components/button/styles/text-button.scss +96 -0
  16. package/src/components/button/types/index.ts +110 -35
  17. package/src/components/button/types/templates.ts +33 -0
  18. package/src/components/button/utils/index.ts +19 -19
  19. package/src/components/checkbox/markup/Checkbox.tsx +20 -2
  20. package/src/components/checkbox/types/checkbox.ts +16 -0
  21. package/src/components/chip/markup/Chip.tsx +8 -0
  22. package/src/components/dialog/markup/{confirm-dialog.tsx → ConfirmDialog.tsx} +23 -0
  23. package/src/components/dialog/markup/{notice-dialog.tsx → NoticeDialog.tsx} +18 -0
  24. package/src/components/dialog/markup/index.tsx +2 -2
  25. package/src/components/dialog/types/index.ts +43 -0
  26. package/src/components/drawer/markup/{drawer.tsx → Drawer.tsx} +58 -0
  27. package/src/components/drawer/markup/index.tsx +1 -1
  28. package/src/components/drawer/types/index.ts +24 -0
  29. package/src/components/input/markup/text/Base.tsx +32 -3
  30. package/src/components/input/markup/text/Identification.tsx +15 -2
  31. package/src/components/input/markup/text/Password.tsx +35 -2
  32. package/src/components/input/markup/text/Phone.tsx +38 -2
  33. package/src/components/input/markup/text/Search.tsx +30 -1
  34. package/src/components/input/styles/index.scss +6 -6
  35. package/src/components/input/types/index.ts +22 -1
  36. package/src/components/input/utils/index.ts +6 -0
  37. package/src/components/navigation/markup/mobile/BottomNavigation.tsx +11 -0
  38. package/src/components/navigation/types/index.ts +22 -0
  39. package/src/components/pagination/markup/Carousel.tsx +1 -0
  40. package/src/components/pagination/markup/Count.tsx +1 -0
  41. package/src/components/pagination/markup/Pagination.tsx +2 -0
  42. package/src/components/radio/markup/Radio.tsx +16 -2
  43. package/src/components/radio/markup/RadioCard.tsx +8 -0
  44. package/src/components/radio/markup/RadioCardGroup.tsx +8 -0
  45. package/src/components/radio/types/radio.ts +39 -0
  46. package/src/components/segmented-control/markup/SegmentedControl.tsx +12 -0
  47. package/src/components/segmented-control/types/index.ts +16 -0
  48. package/src/components/tab/markup/TabContent.tsx +5 -0
  49. package/src/components/tab/markup/TabList.tsx +19 -2
  50. package/src/components/tab/markup/TabRoot.tsx +50 -4
  51. package/src/components/tab/markup/TabTrigger.tsx +9 -1
  52. package/src/components/tab/styles/index.scss +28 -10
  53. package/src/components/tab/types/index.ts +10 -0
  54. package/src/components/tab/utils/tab-context.ts +8 -2
  55. package/src/components/button/markup/Button.tsx +0 -175
  56. package/src/components/button/markup/index.tsx +0 -1
@@ -0,0 +1,56 @@
1
+ @use "@uniai-fe/uds-foundation/css";
2
+
3
+ .button.button-template-round {
4
+ min-width: auto;
5
+ padding-block: var(
6
+ --theme-button-round-padding-block,
7
+ var(--spacing-padding-2, 4px)
8
+ );
9
+ padding-inline: var(
10
+ --theme-button-round-padding-inline-medium,
11
+ var(--spacing-padding-6, 16px)
12
+ );
13
+ gap: var(--spacing-gap-2, 8px);
14
+ }
15
+
16
+ .button.button-template-round-size-small {
17
+ min-height: var(
18
+ --theme-button-round-min-height-small,
19
+ var(--theme-size-small-2, 24px)
20
+ );
21
+ padding-inline: var(
22
+ --theme-button-round-padding-inline-small,
23
+ var(--spacing-padding-5, 12px)
24
+ );
25
+ border-radius: var(
26
+ --theme-button-round-radius-small,
27
+ var(--theme-radius-xlarge-2, 16px)
28
+ );
29
+ }
30
+
31
+ .button.button-template-round-size-medium {
32
+ min-height: var(
33
+ --theme-button-round-min-height-medium,
34
+ var(--theme-size-small-3, 32px)
35
+ );
36
+ padding-inline: var(
37
+ --theme-button-round-padding-inline-medium,
38
+ var(--spacing-padding-6, 16px)
39
+ );
40
+ border-radius: var(
41
+ --theme-button-round-radius-medium,
42
+ var(--theme-radius-xlarge-2, 16px)
43
+ );
44
+ }
45
+
46
+ .button.button-template-round-size-large {
47
+ min-height: var(
48
+ --theme-button-round-min-height-large,
49
+ var(--theme-size-medium-1, 40px)
50
+ );
51
+ padding-inline: var(
52
+ --theme-button-round-padding-inline-large,
53
+ var(--spacing-padding-7, 20px)
54
+ );
55
+ border-radius: var(--theme-button-round-radius-large, 30px);
56
+ }
@@ -0,0 +1,96 @@
1
+ @use "@uniai-fe/uds-foundation/css";
2
+
3
+ .button.button-template-text {
4
+ min-width: auto;
5
+ border-color: transparent;
6
+ background-color: transparent;
7
+ padding-block: var(
8
+ --theme-button-text-padding-block,
9
+ var(--spacing-padding-4, 8px)
10
+ );
11
+ padding-inline: var(
12
+ --theme-button-text-padding-inline-small,
13
+ var(--spacing-padding-4, 8px)
14
+ );
15
+ border-width: 0;
16
+ gap: var(--spacing-gap-1, 4px);
17
+ border-radius: var(
18
+ --theme-button-text-radius,
19
+ var(--theme-radius-small, 4px)
20
+ );
21
+ }
22
+
23
+ .button.button-template-text-size-small {
24
+ min-height: var(
25
+ --theme-button-text-min-height-small,
26
+ var(--theme-size-small-1, 20px)
27
+ );
28
+ padding-inline: var(
29
+ --theme-button-text-padding-inline-small,
30
+ var(--spacing-padding-4, 8px)
31
+ );
32
+ }
33
+
34
+ .button.button-template-text-size-medium {
35
+ min-height: var(
36
+ --theme-button-text-min-height-medium,
37
+ var(--theme-size-small-2, 24px)
38
+ );
39
+ padding-inline: var(
40
+ --theme-button-text-padding-inline-medium,
41
+ var(--spacing-padding-5, 12px)
42
+ );
43
+ }
44
+
45
+ .button.button-template-text-size-large {
46
+ min-height: var(
47
+ --theme-button-text-min-height-large,
48
+ var(--theme-size-small-3, 32px)
49
+ );
50
+ padding-inline: var(
51
+ --theme-button-text-padding-inline-large,
52
+ var(--spacing-padding-5, 12px)
53
+ );
54
+ }
55
+
56
+ .button.button-template-text:disabled {
57
+ background-color: transparent;
58
+ border-color: transparent;
59
+ }
60
+
61
+ .button.button-template-text.button-priority-secondary {
62
+ color: var(
63
+ --theme-button-color-primary-default,
64
+ var(--color-primary-default)
65
+ );
66
+
67
+ &:hover:not(:disabled),
68
+ &[data-user-action="hover"]:not(:disabled) {
69
+ background-color: var(
70
+ --color-bg-alternative-cool-gray,
71
+ var(--color-cool-gray-95)
72
+ );
73
+ }
74
+
75
+ &:active:not(:disabled),
76
+ &[data-user-action="pressed"]:not(:disabled) {
77
+ background-color: var(--color-secondary-strong, var(--color-blue-90));
78
+ }
79
+ }
80
+
81
+ .button.button-template-text.button-priority-tertiary {
82
+ color: var(--theme-button-color-cool-gray-10, var(--color-cool-gray-10));
83
+
84
+ &:hover:not(:disabled),
85
+ &[data-user-action="hover"]:not(:disabled) {
86
+ background-color: var(
87
+ --color-bg-alternative-cool-gray,
88
+ var(--color-cool-gray-95)
89
+ );
90
+ }
91
+
92
+ &:active:not(:disabled),
93
+ &[data-user-action="pressed"]:not(:disabled) {
94
+ background-color: var(--color-bg-surface-strong, var(--color-cool-gray-20));
95
+ }
96
+ }
@@ -1,49 +1,116 @@
1
- import type { ComponentPropsWithoutRef, ReactNode, ReactElement } from "react";
1
+ import type { ComponentPropsWithoutRef, ElementType, ReactNode } from "react";
2
2
 
3
3
  /**
4
- * 버튼 variant/axes는 `modules/_context/design-system/sot/current/components/assets-index.json`
5
- * 의 button 항목을 그대로 반영한다.
4
+ * 지원하는 priority 축. semantic color 세트를 결정할 때 사용한다.
5
+ */
6
+ export const BUTTON_PRIORITIES = ["primary", "secondary", "tertiary"] as const;
7
+ /**
8
+ * scale은 fill/size 조합을 묶어 버튼 spacing/height/타이포를 설정한다.
9
+ */
10
+ export const BUTTON_SCALES = [
11
+ "solid-xlarge",
12
+ "solid-large",
13
+ "solid-medium",
14
+ "solid-small",
15
+ "outlined-xlarge",
16
+ "outlined-large",
17
+ "outlined-medium",
18
+ "outlined-small",
19
+ ] as const;
20
+ /**
21
+ * state는 디자인 토큰에서 정의한 3단계만 노출한다.
6
22
  */
7
- export const BUTTON_VARIANTS = ["solid", "outlined", "text-button"] as const;
8
- export const BUTTON_INTENTS = ["primary", "secondary", "teritary"] as const;
9
- export const BUTTON_SIZES = ["xlarge", "large", "medium", "small"] as const;
10
- export const BUTTON_SHAPES = ["default", "round"] as const;
11
23
  export const BUTTON_STATES = ["default", "readonly", "disabled"] as const;
12
- export const BUTTON_SIMULATED_STATES = ["hover", "pressed"] as const;
24
+ /**
25
+ * data-user-action attribute로 강제 표현할 수 있는 상호작용 모드.
26
+ */
27
+ export const BUTTON_USER_ACTIONS = ["hover", "pressed"] as const;
13
28
 
14
- export type ButtonVariant = (typeof BUTTON_VARIANTS)[number];
15
- export type ButtonIntent = (typeof BUTTON_INTENTS)[number];
16
- export type ButtonSize = (typeof BUTTON_SIZES)[number];
17
- export type ButtonShape = (typeof BUTTON_SHAPES)[number];
29
+ export type ButtonPriority = (typeof BUTTON_PRIORITIES)[number];
30
+ export type ButtonScale = (typeof BUTTON_SCALES)[number];
18
31
  export type ButtonState = (typeof BUTTON_STATES)[number];
19
- export type ButtonSimulatedState = (typeof BUTTON_SIMULATED_STATES)[number];
32
+ export type ButtonUserAction = (typeof BUTTON_USER_ACTIONS)[number];
20
33
  export type ButtonIconSlot = "none" | "left" | "right";
21
34
 
35
+ export type ButtonFill = "solid" | "outlined";
36
+ export type ButtonSize = "xlarge" | "large" | "medium" | "small";
37
+ export type ButtonScaleGroup = ButtonFill;
38
+
39
+ type ButtonScaleConfig = {
40
+ fill: ButtonFill;
41
+ group: ButtonScaleGroup;
42
+ size: ButtonSize;
43
+ };
44
+
45
+ const createScaleConfig = (
46
+ fill: ButtonFill,
47
+ size: ButtonSize,
48
+ group: ButtonScaleGroup,
49
+ ): ButtonScaleConfig => ({
50
+ fill,
51
+ size,
52
+ group,
53
+ });
54
+
55
+ /**
56
+ * scale 별 fill/size/group 메타데이터. className이나 slot 로직이 동일한 source를 참고할 수 있다.
57
+ */
58
+ export const BUTTON_SCALE_CONFIG: Record<ButtonScale, ButtonScaleConfig> = {
59
+ "solid-xlarge": createScaleConfig("solid", "xlarge", "solid"),
60
+ "solid-large": createScaleConfig("solid", "large", "solid"),
61
+ "solid-medium": createScaleConfig("solid", "medium", "solid"),
62
+ "solid-small": createScaleConfig("solid", "small", "solid"),
63
+ "outlined-xlarge": createScaleConfig("outlined", "xlarge", "outlined"),
64
+ "outlined-large": createScaleConfig("outlined", "large", "outlined"),
65
+ "outlined-medium": createScaleConfig("outlined", "medium", "outlined"),
66
+ "outlined-small": createScaleConfig("outlined", "small", "outlined"),
67
+ };
68
+
69
+ /**
70
+ * 인터랙션 제약을 위해 fill 축으로 scale을 그룹화한 매핑.
71
+ */
72
+ export const BUTTON_SCALE_GROUPS: Record<ButtonScaleGroup, ButtonScale[]> = {
73
+ solid: ["solid-xlarge", "solid-large", "solid-medium", "solid-small"],
74
+ outlined: [
75
+ "outlined-xlarge",
76
+ "outlined-large",
77
+ "outlined-medium",
78
+ "outlined-small",
79
+ ],
80
+ };
81
+
82
+ /**
83
+ * 우선순위 default. (primary)
84
+ */
85
+ export const DEFAULT_BUTTON_PRIORITY: ButtonPriority = "primary";
86
+ /**
87
+ * scale default. (solid-medium)
88
+ */
89
+ export const DEFAULT_BUTTON_SCALE: ButtonScale = "solid-medium";
90
+
22
91
  type NativeButtonProps = ComponentPropsWithoutRef<"button">;
23
- export interface ButtonProps extends Omit<
24
- NativeButtonProps,
25
- "children" | "prefix" | "suffix"
26
- > {
27
- /**
28
- * 버튼 내용. 문자열이면 `<span class="button-label">`로 자동 감싼다.
29
- */
30
- children?: ReactNode;
92
+ type AnchorProps = ComponentPropsWithoutRef<"a">;
93
+
94
+ type SharedElementProps = Omit<NativeButtonProps, "children"> &
95
+ Omit<AnchorProps, "children">;
96
+
97
+ export interface ButtonProps extends SharedElementProps {
31
98
  /**
32
- * SOT에서 정의한 버튼 스타일 축(solid/outlined/text-button).
99
+ * 렌더링할 요소. 기본값은 button.
33
100
  */
34
- variant?: ButtonVariant;
101
+ as?: ElementType;
35
102
  /**
36
- * UX priority(semantic color). foundation semantic 색과 매핑된다.
103
+ * 버튼 내용. 문자열이면 `<span class="button-label">`로 자동 감싼다.
37
104
  */
38
- intent?: ButtonIntent;
105
+ children?: ReactNode;
39
106
  /**
40
- * 디자인 토큰 사이즈 alias(small~xlarge). Theme size 단계와 매핑된다.
107
+ * 레이아웃/spacing 집합. ) `solid-large`, `outlined-medium`.
41
108
  */
42
- size?: ButtonSize;
109
+ scale?: ButtonScale;
43
110
  /**
44
- * radius alias. round는 full radius를 사용한다.
111
+ * semantic color priority.
45
112
  */
46
- shape?: ButtonShape;
113
+ priority?: ButtonPriority;
47
114
  /**
48
115
  * UI state: readonly/disabled 를 명시적으로 설정할 수 있다.
49
116
  */
@@ -65,15 +132,23 @@ export interface ButtonProps extends Omit<
65
132
  */
66
133
  icon?: ReactNode;
67
134
  /**
68
- * 라벨 앞에 표시할 prefix 슬롯.
135
+ * 라벨 왼쪽에 표시할 슬롯.
69
136
  */
70
- prefix?: ReactElement;
137
+ left?: ReactNode;
71
138
  /**
72
- * 라벨 뒤에 표시할 suffix 슬롯.
139
+ * 라벨 오른쪽에 표시할 슬롯.
73
140
  */
74
- suffix?: ReactElement;
141
+ right?: ReactNode;
75
142
  /**
76
- * Storybook에서 hover/pressed 상태를 강제로 보여주기 위한 data attribute.
143
+ * Storybook 등에서 hover/pressed 상태를 강제로 보여줄 사용하는 data attribute.
77
144
  */
78
- "data-simulated-state"?: ButtonSimulatedState;
145
+ "data-user-action"?: ButtonUserAction;
79
146
  }
147
+
148
+ export type {
149
+ TextButtonProps,
150
+ TextButtonPriority,
151
+ TextButtonSize,
152
+ RoundButtonProps,
153
+ RoundButtonSize,
154
+ } from "./templates";
@@ -0,0 +1,33 @@
1
+ import type { ButtonPriority, ButtonProps } from ".";
2
+
3
+ /**
4
+ * TextButton 컴포넌트에서 허용하는 size 축.
5
+ */
6
+ export type TextButtonSize = "small" | "medium" | "large";
7
+ /**
8
+ * TextButton은 secondary/tertiary priority만 허용한다.
9
+ */
10
+ export type TextButtonPriority = Exclude<ButtonPriority, "primary">;
11
+
12
+ /**
13
+ * TextButton 템플릿 props. scale/priority는 템플릿에서 내부적으로 제어하므로 제거했다.
14
+ */
15
+ export interface TextButtonProps extends Omit<
16
+ ButtonProps,
17
+ "scale" | "priority"
18
+ > {
19
+ size?: TextButtonSize;
20
+ priority?: TextButtonPriority;
21
+ }
22
+
23
+ /**
24
+ * RoundButton 컴포넌트에서 지원하는 size 축.
25
+ */
26
+ export type RoundButtonSize = "small" | "medium" | "large";
27
+
28
+ /**
29
+ * RoundButton 템플릿 props. scale은 템플릿 안에서 size에 따라 파생된다.
30
+ */
31
+ export interface RoundButtonProps extends Omit<ButtonProps, "scale"> {
32
+ size?: RoundButtonSize;
33
+ }
@@ -1,18 +1,18 @@
1
1
  import clsx from "clsx";
2
2
  import type {
3
+ ButtonFill,
3
4
  ButtonIconSlot,
4
- ButtonIntent,
5
- ButtonShape,
5
+ ButtonPriority,
6
+ ButtonScale,
6
7
  ButtonSize,
7
8
  ButtonState,
8
- ButtonVariant,
9
9
  } from "../types";
10
10
 
11
11
  type ButtonClassNameOptions = {
12
- variant: ButtonVariant;
13
- intent: ButtonIntent;
12
+ scale: ButtonScale;
13
+ fill: ButtonFill;
14
+ priority: ButtonPriority;
14
15
  size: ButtonSize;
15
- shape: ButtonShape;
16
16
  block: boolean;
17
17
  loading: boolean;
18
18
  iconSlot: ButtonIconSlot;
@@ -24,13 +24,13 @@ type ButtonClassNameOptions = {
24
24
  const BUTTON_CLASSNAME = "button";
25
25
 
26
26
  /**
27
- * 버튼 클래스 조합 helper: variant/intent/size 별 modifier를 한 곳에서 관리한다.
27
+ * 버튼 클래스 조합 helper: scale/fill/priority/size 별 modifier를 한 곳에서 관리한다.
28
28
  */
29
29
  const composeButtonClassName = ({
30
- variant,
31
- intent,
30
+ scale,
31
+ fill,
32
+ priority,
32
33
  size,
33
- shape,
34
34
  block,
35
35
  loading,
36
36
  iconSlot,
@@ -40,16 +40,16 @@ const composeButtonClassName = ({
40
40
  }: ButtonClassNameOptions) =>
41
41
  clsx(
42
42
  BUTTON_CLASSNAME,
43
- `${BUTTON_CLASSNAME}--variant-${variant}`,
44
- `${BUTTON_CLASSNAME}--intent-${intent}`,
45
- `${BUTTON_CLASSNAME}--size-${size}`,
46
- `${BUTTON_CLASSNAME}--shape-${shape}`,
43
+ `${BUTTON_CLASSNAME}-scale-${scale}`,
44
+ `${BUTTON_CLASSNAME}-fill-${fill}`,
45
+ `${BUTTON_CLASSNAME}-priority-${priority}`,
46
+ `${BUTTON_CLASSNAME}-size-${size}`,
47
47
  {
48
- [`${BUTTON_CLASSNAME}--state-${state}`]: state !== "default",
49
- [`${BUTTON_CLASSNAME}--block`]: block,
50
- [`${BUTTON_CLASSNAME}--loading`]: loading,
51
- [`${BUTTON_CLASSNAME}--icon-${iconSlot}`]: iconSlot !== "none",
52
- [`${BUTTON_CLASSNAME}--icon-only`]: iconOnly,
48
+ [`${BUTTON_CLASSNAME}-state-${state}`]: state !== "default",
49
+ [`${BUTTON_CLASSNAME}-block`]: block,
50
+ [`${BUTTON_CLASSNAME}-loading`]: loading,
51
+ [`${BUTTON_CLASSNAME}-icon-${iconSlot}`]: iconSlot !== "none",
52
+ [`${BUTTON_CLASSNAME}-icon-only`]: iconOnly,
53
53
  },
54
54
  className,
55
55
  );
@@ -19,7 +19,14 @@ const getIndicatorIcon = (size: CheckboxSize) =>
19
19
  * 체크박스 컴포넌트; Radix Checkbox thin wrapper
20
20
  * @component
21
21
  * @param {CheckboxProps} props
22
- * @param {CheckboxSize} [props.size] medium, large
22
+ * @param {"medium" | "large"} [props.size="medium"] indicator/label spacing 크기.
23
+ * @param {boolean} [props.checked] 제어형 체크 상태.
24
+ * @param {boolean} [props.defaultChecked] 비제어 초기 체크 상태.
25
+ * @param {boolean} [props.disabled] disabled 상태.
26
+ * @param {(checked: CheckboxPrimitive.CheckedState) => void} [props.onCheckedChange]
27
+ * 체크 상태 변경 핸들러.
28
+ * @param {string} [props.className] root className.
29
+ * @param {string} [props.name] form name.
23
30
  * @example
24
31
  * <Checkbox size="medium" checked />
25
32
  */
@@ -51,7 +58,18 @@ export const Checkbox = forwardRef<HTMLButtonElement, CheckboxProps>(
51
58
  * 체크박스 필드 컴포넌트; label/helper 텍스트 래퍼
52
59
  * @component
53
60
  * @param {CheckboxFieldProps} props
54
- * @param {CheckboxSize} [props.size] medium, large
61
+ * @param {"medium" | "large"} [props.size="medium"] indicator 크기.
62
+ * @param {React.ReactNode} [props.label] `<label>` 텍스트/노드.
63
+ * @param {React.ReactNode} [props.helperText] helper 텍스트.
64
+ * @param {ComponentPropsWithoutRef<"label">} [props.labelProps] label attr.
65
+ * @param {ComponentPropsWithoutRef<"p">} [props.helperTextProps] helper attr.
66
+ * @param {string} [props.fieldClassName] `.checkbox-field` className.
67
+ * @param {string} [props.labelWrapperClassName] 라벨 wrapper className.
68
+ * @param {boolean} [props.checked] 제어형 체크 상태.
69
+ * @param {boolean} [props.defaultChecked] 비제어 초기 체크 상태.
70
+ * @param {(checked: CheckboxPrimitive.CheckedState) => void} [props.onCheckedChange]
71
+ * 체크 상태 변경 핸들러.
72
+ * @param {boolean} [props.disabled] disabled 상태.
55
73
  * @example
56
74
  * <CheckboxField label="약관 동의" helperText="필수" checked />
57
75
  */
@@ -1,16 +1,32 @@
1
1
  import type { ComponentPropsWithoutRef, ReactNode } from "react";
2
2
  import type * as CheckboxPrimitive from "@radix-ui/react-checkbox";
3
3
 
4
+ /**
5
+ * 지원하는 checkbox 사이즈. medium/large 두 단계.
6
+ */
4
7
  export type CheckboxSize = "medium" | "large";
5
8
 
6
9
  export type CheckboxPrimitiveProps = ComponentPropsWithoutRef<
7
10
  typeof CheckboxPrimitive.Root
8
11
  >;
9
12
 
13
+ /**
14
+ * Radix Checkbox Root에 size/className 확장을 더한 props.
15
+ * @property {"medium" | "large"} [size="medium"] indicator/box 크기.
16
+ */
10
17
  export interface CheckboxProps extends CheckboxPrimitiveProps {
11
18
  size?: CheckboxSize;
12
19
  }
13
20
 
21
+ /**
22
+ * label/helperText 등을 포함하는 CheckboxField 래퍼 props.
23
+ * @property {React.ReactNode} [label] `<label>`로 연결되는 텍스트/노드.
24
+ * @property {React.ReactNode} [helperText] label 하단 추가 설명.
25
+ * @property {ComponentPropsWithoutRef<"p">} [helperTextProps] helper container attr.
26
+ * @property {ComponentPropsWithoutRef<"label">} [labelProps] label attr.
27
+ * @property {string} [fieldClassName] `.checkbox-field` className override.
28
+ * @property {string} [labelWrapperClassName] label wrapper className.
29
+ */
14
30
  export interface CheckboxFieldProps extends CheckboxProps {
15
31
  label?: ReactNode;
16
32
  helperText?: ReactNode;
@@ -14,6 +14,14 @@ const isChipInputProps = (props: ChipProps): props is ChipInputProps =>
14
14
 
15
15
  /**
16
16
  * Chip 종류별로 interactive/input 구조가 달라 별도 분기한다.
17
+ * @component
18
+ * @param {ChipProps} props
19
+ * @param {"filter" | "filter-rounded" | "assist" | "input"} [props.kind="filter"] chip kind.
20
+ * @param {boolean} [props.selected] 선택 상태. filter 계열에서 aria-pressed로 노출.
21
+ * @param {React.ReactNode} [props.leading] assist kind 전용 leading slot.
22
+ * @param {string} [props.removeButtonLabel="선택 항목 삭제"] input kind 제거 버튼 라벨.
23
+ * @param {(event: MouseEvent<HTMLButtonElement>) => void} [props.onRemove] input kind 제거 핸들러.
24
+ * @param {string} [props.className] root className.
17
25
  */
18
26
  const Chip = forwardRef<HTMLElement, ChipProps>((props, ref) => {
19
27
  if (isChipInputProps(props)) {
@@ -36,6 +36,9 @@ const useConfirmDialogInternalContext = () => {
36
36
  * ConfirmDialogRoot; AlertDialog 루트
37
37
  * @component
38
38
  * @param {ConfirmDialogRootProps} props
39
+ * @param {boolean} [props.open] 제어형 open 상태.
40
+ * @param {boolean} [props.defaultOpen] 비제어 초기 open 상태.
41
+ * @param {(open: boolean) => void} [props.onOpenChange] open 변경 콜백.
39
42
  */
40
43
  const ConfirmDialogRoot = ({
41
44
  open: openProp,
@@ -80,6 +83,8 @@ const ConfirmDialogPortal = AlertDialogPrimitive.Portal;
80
83
  * ConfirmDialogOverlay; 취소 성격의 바깥 dim
81
84
  * @component
82
85
  * @param {ConfirmDialogOverlayProps} props
86
+ * @param {string} [props.className] overlay className.
87
+ * @param {boolean} [props.disableOutsideClose=false] dim 클릭으로 닫힘 방지 여부.
83
88
  */
84
89
  const ConfirmDialogOverlay = forwardRef<
85
90
  HTMLDivElement,
@@ -120,6 +125,8 @@ ConfirmDialogOverlay.displayName = "ConfirmDialogOverlay";
120
125
  * ConfirmDialogContent; AlertDialog 패널
121
126
  * @component
122
127
  * @param {ConfirmDialogContentProps} props
128
+ * @param {string} [props.className] content className.
129
+ * @param {React.ReactNode} [props.children] 패널 내용.
123
130
  */
124
131
  const ConfirmDialogContent = forwardRef<
125
132
  HTMLDivElement,
@@ -141,6 +148,9 @@ ConfirmDialogContent.displayName = "ConfirmDialogContent";
141
148
  * ConfirmDialogTitle; AlertDialog 제목
142
149
  * @component
143
150
  * @param {ConfirmDialogTitleProps} props
151
+ * @param {string} [props.className] title className.
152
+ * @param {boolean} [props.visuallyHidden=false] 제목 시각적 숨김 여부.
153
+ * @param {React.ReactNode} [props.children] 제목 텍스트.
144
154
  */
145
155
  const ConfirmDialogTitle = forwardRef<
146
156
  HTMLHeadingElement,
@@ -170,6 +180,9 @@ ConfirmDialogTitle.displayName = "ConfirmDialogTitle";
170
180
  * ConfirmDialogDescription; AlertDialog 설명
171
181
  * @component
172
182
  * @param {ConfirmDialogDescriptionProps} props
183
+ * @param {string} [props.className] description className.
184
+ * @param {boolean} [props.visuallyHidden=false] 설명 시각적 숨김 여부.
185
+ * @param {React.ReactNode} [props.children] 설명 텍스트.
173
186
  */
174
187
  const ConfirmDialogDescription = forwardRef<
175
188
  HTMLParagraphElement,
@@ -202,6 +215,8 @@ ConfirmDialogDescription.displayName = "ConfirmDialogDescription";
202
215
  * ConfirmDialogHeader; 헤더 영역
203
216
  * @component
204
217
  * @param {ConfirmDialogSectionProps} props
218
+ * @param {string} [props.className] 섹션 className.
219
+ * @param {React.ReactNode} [props.children] 헤더 콘텐츠.
205
220
  */
206
221
  const ConfirmDialogHeader = forwardRef<
207
222
  HTMLDivElement,
@@ -221,6 +236,8 @@ ConfirmDialogHeader.displayName = "ConfirmDialogHeader";
221
236
  * ConfirmDialogBody; 본문 영역
222
237
  * @component
223
238
  * @param {ConfirmDialogSectionProps} props
239
+ * @param {string} [props.className] 섹션 className.
240
+ * @param {React.ReactNode} [props.children] 본문 콘텐츠.
224
241
  */
225
242
  const ConfirmDialogBody = forwardRef<HTMLDivElement, ConfirmDialogSectionProps>(
226
243
  ({ className, ...props }, forwardedRef) => (
@@ -239,6 +256,8 @@ ConfirmDialogBody.displayName = "ConfirmDialogBody";
239
256
  * ConfirmDialogActions; 버튼 영역
240
257
  * @component
241
258
  * @param {ConfirmDialogSectionProps} props
259
+ * @param {string} [props.className] 섹션 className.
260
+ * @param {React.ReactNode} [props.children] 버튼 콘텐츠.
242
261
  */
243
262
  const ConfirmDialogActions = forwardRef<
244
263
  HTMLDivElement,
@@ -258,6 +277,8 @@ ConfirmDialogActions.displayName = "ConfirmDialogActions";
258
277
  * ConfirmDialogCancelButton; AlertDialog Cancel wrapper
259
278
  * @component
260
279
  * @param {ConfirmDialogCancelProps} props
280
+ * @param {string} [props.className] button className.
281
+ * @param {boolean} [props.asChild=false] slot mode 사용 여부.
261
282
  */
262
283
  const ConfirmDialogCancel = forwardRef<
263
284
  HTMLButtonElement,
@@ -281,6 +302,8 @@ ConfirmDialogCancel.displayName = "ConfirmDialogCancel";
281
302
  * ConfirmDialogActionButton; AlertDialog Action wrapper
282
303
  * @component
283
304
  * @param {ConfirmDialogActionProps} props
305
+ * @param {string} [props.className] button className.
306
+ * @param {boolean} [props.asChild=false] slot mode 사용 여부.
284
307
  */
285
308
  const ConfirmDialogAction = forwardRef<
286
309
  HTMLButtonElement,
@@ -14,6 +14,9 @@ import type {
14
14
  * NoticeDialogRoot; 공통 Dialog 상태 제어 루트
15
15
  * @component
16
16
  * @param {NoticeDialogRootProps} props
17
+ * @param {boolean} [props.open] 제어형 open 상태.
18
+ * @param {boolean} [props.defaultOpen] 비제어 초기 open 상태.
19
+ * @param {(open: boolean) => void} [props.onOpenChange] open 변경 콜백.
17
20
  */
18
21
  const NoticeDialogRoot = DialogPrimitive.Root;
19
22
  const NoticeDialogTrigger = DialogPrimitive.Trigger;
@@ -24,6 +27,7 @@ const NoticeDialogClose = DialogPrimitive.Close;
24
27
  * NoticeDialogOverlay; dim 영역
25
28
  * @component
26
29
  * @param {NoticeDialogOverlayProps} props
30
+ * @param {string} [props.className] overlay className.
27
31
  */
28
32
  const NoticeDialogOverlay = forwardRef<
29
33
  HTMLDivElement,
@@ -43,6 +47,8 @@ NoticeDialogOverlay.displayName = "NoticeDialogOverlay";
43
47
  * NoticeDialogContent; 콘텐츠 패널
44
48
  * @component
45
49
  * @param {NoticeDialogContentProps} props
50
+ * @param {string} [props.className] content className.
51
+ * @param {React.ReactNode} [props.children] panel 내용.
46
52
  */
47
53
  const NoticeDialogContent = forwardRef<
48
54
  HTMLDivElement,
@@ -64,6 +70,9 @@ NoticeDialogContent.displayName = "NoticeDialogContent";
64
70
  * NoticeDialogTitle; Dialog 제목
65
71
  * @component
66
72
  * @param {NoticeDialogTitleProps} props
73
+ * @param {string} [props.className] title className.
74
+ * @param {boolean} [props.visuallyHidden=false] 제목을 시각적으로 숨길지 여부.
75
+ * @param {React.ReactNode} [props.children] 제목 텍스트.
67
76
  */
68
77
  const NoticeDialogTitle = forwardRef<
69
78
  HTMLHeadingElement,
@@ -93,6 +102,9 @@ NoticeDialogTitle.displayName = "NoticeDialogTitle";
93
102
  * NoticeDialogDescription; Dialog 설명
94
103
  * @component
95
104
  * @param {NoticeDialogDescriptionProps} props
105
+ * @param {string} [props.className] description className.
106
+ * @param {boolean} [props.visuallyHidden=false] 설명을 시각적으로 숨길지 여부.
107
+ * @param {React.ReactNode} [props.children] 설명 텍스트.
96
108
  */
97
109
  const NoticeDialogDescription = forwardRef<
98
110
  HTMLParagraphElement,
@@ -125,6 +137,8 @@ NoticeDialogDescription.displayName = "NoticeDialogDescription";
125
137
  * NoticeDialogHeader; 헤더 레이아웃
126
138
  * @component
127
139
  * @param {NoticeDialogSectionProps} props
140
+ * @param {string} [props.className] 섹션 className.
141
+ * @param {React.HTMLAttributes<HTMLDivElement>["children"]} [props.children] 헤더 콘텐츠.
128
142
  */
129
143
  const NoticeDialogHeader = forwardRef<HTMLDivElement, NoticeDialogSectionProps>(
130
144
  ({ className, ...props }, forwardedRef) => (
@@ -143,6 +157,8 @@ NoticeDialogHeader.displayName = "NoticeDialogHeader";
143
157
  * NoticeDialogBody; 본문 영역
144
158
  * @component
145
159
  * @param {NoticeDialogSectionProps} props
160
+ * @param {string} [props.className] 섹션 className.
161
+ * @param {React.ReactNode} [props.children] 본문 콘텐츠.
146
162
  */
147
163
  const NoticeDialogBody = forwardRef<HTMLDivElement, NoticeDialogSectionProps>(
148
164
  ({ className, ...props }, forwardedRef) => (
@@ -161,6 +177,8 @@ NoticeDialogBody.displayName = "NoticeDialogBody";
161
177
  * NoticeDialogActions; 버튼 영역
162
178
  * @component
163
179
  * @param {NoticeDialogSectionProps} props
180
+ * @param {string} [props.className] 섹션 className.
181
+ * @param {React.ReactNode} [props.children] 버튼 콘텐츠.
164
182
  */
165
183
  const NoticeDialogActions = forwardRef<
166
184
  HTMLDivElement,