@seed-design/lynx-react 0.1.1-alpha.0 → 0.2.0-alpha.2

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 (180) hide show
  1. package/lib/components/ActionButton/ActionButton.d.ts +40 -9
  2. package/lib/components/ActionButton/ActionButton.d.ts.map +1 -1
  3. package/lib/components/ActionButton/ActionButton.jsx +132 -14
  4. package/lib/components/BottomSheet/BottomSheet.d.ts +92 -0
  5. package/lib/components/BottomSheet/BottomSheet.d.ts.map +1 -0
  6. package/lib/components/BottomSheet/BottomSheet.jsx +178 -0
  7. package/lib/components/BottomSheet/BottomSheet.namespace.d.ts +2 -0
  8. package/lib/components/BottomSheet/BottomSheet.namespace.d.ts.map +1 -0
  9. package/lib/components/BottomSheet/BottomSheet.namespace.js +1 -0
  10. package/lib/components/BottomSheet/index.d.ts +3 -0
  11. package/lib/components/BottomSheet/index.d.ts.map +1 -0
  12. package/lib/components/BottomSheet/index.js +2 -0
  13. package/lib/components/Checkbox/Checkbox.d.ts +51 -0
  14. package/lib/components/Checkbox/Checkbox.d.ts.map +1 -0
  15. package/lib/components/Checkbox/Checkbox.jsx +121 -0
  16. package/lib/components/Checkbox/Checkbox.namespace.d.ts +2 -0
  17. package/lib/components/Checkbox/Checkbox.namespace.d.ts.map +1 -0
  18. package/lib/components/Checkbox/Checkbox.namespace.js +1 -0
  19. package/lib/components/Checkbox/index.d.ts +3 -0
  20. package/lib/components/Checkbox/index.d.ts.map +1 -0
  21. package/lib/components/Checkbox/index.js +2 -0
  22. package/lib/components/ProgressCircle/ProgressCircle.d.ts +10 -9
  23. package/lib/components/ProgressCircle/ProgressCircle.d.ts.map +1 -1
  24. package/lib/components/ProgressCircle/ProgressCircle.jsx +8 -14
  25. package/lib/components/ProgressCircle/ProgressCircle.namespace.d.ts +2 -0
  26. package/lib/components/ProgressCircle/ProgressCircle.namespace.d.ts.map +1 -0
  27. package/lib/components/ProgressCircle/ProgressCircle.namespace.js +1 -0
  28. package/lib/components/ProgressCircle/index.d.ts +2 -1
  29. package/lib/components/ProgressCircle/index.d.ts.map +1 -1
  30. package/lib/components/ProgressCircle/index.js +2 -1
  31. package/lib/components/RadioGroup/RadioGroup.d.ts +50 -0
  32. package/lib/components/RadioGroup/RadioGroup.d.ts.map +1 -0
  33. package/lib/components/RadioGroup/RadioGroup.jsx +144 -0
  34. package/lib/components/RadioGroup/RadioGroup.namespace.d.ts +2 -0
  35. package/lib/components/RadioGroup/RadioGroup.namespace.d.ts.map +1 -0
  36. package/lib/components/RadioGroup/RadioGroup.namespace.js +1 -0
  37. package/lib/components/RadioGroup/index.d.ts +3 -0
  38. package/lib/components/RadioGroup/index.d.ts.map +1 -0
  39. package/lib/components/RadioGroup/index.js +2 -0
  40. package/lib/components/Switch/Switch.d.ts +27 -0
  41. package/lib/components/Switch/Switch.d.ts.map +1 -0
  42. package/lib/components/Switch/Switch.jsx +75 -0
  43. package/lib/components/Switch/Switch.namespace.d.ts +2 -0
  44. package/lib/components/Switch/Switch.namespace.d.ts.map +1 -0
  45. package/lib/components/Switch/Switch.namespace.js +1 -0
  46. package/lib/components/Switch/index.d.ts +3 -0
  47. package/lib/components/Switch/index.d.ts.map +1 -0
  48. package/lib/components/Switch/index.js +2 -0
  49. package/lib/components/TagGroup/TagGroup.d.ts +40 -0
  50. package/lib/components/TagGroup/TagGroup.d.ts.map +1 -0
  51. package/lib/components/TagGroup/TagGroup.jsx +54 -0
  52. package/lib/components/TagGroup/TagGroup.namespace.d.ts +2 -0
  53. package/lib/components/TagGroup/TagGroup.namespace.d.ts.map +1 -0
  54. package/lib/components/TagGroup/TagGroup.namespace.js +1 -0
  55. package/lib/components/TagGroup/index.d.ts +3 -0
  56. package/lib/components/TagGroup/index.d.ts.map +1 -0
  57. package/lib/components/TagGroup/index.js +2 -0
  58. package/lib/components/index.d.ts +8 -0
  59. package/lib/components/index.d.ts.map +1 -0
  60. package/lib/components/index.js +7 -0
  61. package/lib/hooks/index.d.ts +4 -0
  62. package/lib/hooks/index.d.ts.map +1 -0
  63. package/lib/hooks/index.js +3 -0
  64. package/lib/hooks/use-controllable-state.d.ts +15 -0
  65. package/lib/hooks/use-controllable-state.d.ts.map +1 -0
  66. package/lib/hooks/use-controllable-state.js +27 -0
  67. package/lib/hooks/use-icon-color.d.ts +15 -0
  68. package/lib/hooks/use-icon-color.d.ts.map +1 -0
  69. package/lib/hooks/use-icon-color.js +37 -0
  70. package/lib/hooks/use-press-tap.d.ts +24 -0
  71. package/lib/hooks/use-press-tap.d.ts.map +1 -0
  72. package/lib/hooks/use-press-tap.js +35 -0
  73. package/lib/index.d.ts +3 -4
  74. package/lib/index.d.ts.map +1 -1
  75. package/lib/index.js +3 -4
  76. package/lib/utils/create-slot-recipe-context.d.ts +26 -0
  77. package/lib/utils/create-slot-recipe-context.d.ts.map +1 -0
  78. package/lib/utils/create-slot-recipe-context.jsx +76 -0
  79. package/lib/utils/get-seed-class-name.d.ts.map +1 -0
  80. package/lib/utils/index.d.ts +5 -0
  81. package/lib/utils/index.d.ts.map +1 -0
  82. package/lib/utils/index.js +4 -0
  83. package/lib/utils/resolve-recipe-token.d.ts +38 -0
  84. package/lib/utils/resolve-recipe-token.d.ts.map +1 -0
  85. package/lib/utils/resolve-recipe-token.js +47 -0
  86. package/lib/utils/split-multiple-variants-props.d.ts +29 -0
  87. package/lib/utils/split-multiple-variants-props.d.ts.map +1 -0
  88. package/lib/utils/split-multiple-variants-props.js +34 -0
  89. package/package.json +12 -9
  90. package/src/components/ActionButton/ActionButton.tsx +290 -31
  91. package/src/components/ActionButton/__tests__/ActionButton.test.tsx +35 -0
  92. package/src/components/BottomSheet/BottomSheet.namespace.ts +24 -0
  93. package/src/components/BottomSheet/BottomSheet.tsx +386 -0
  94. package/src/components/BottomSheet/__tests__/BottomSheet.test.tsx +119 -0
  95. package/src/components/BottomSheet/index.ts +27 -0
  96. package/src/components/Checkbox/Checkbox.namespace.ts +12 -0
  97. package/src/components/Checkbox/Checkbox.tsx +291 -0
  98. package/src/components/Checkbox/index.ts +14 -0
  99. package/src/components/ProgressCircle/ProgressCircle.namespace.ts +5 -0
  100. package/src/components/ProgressCircle/ProgressCircle.tsx +14 -13
  101. package/src/components/ProgressCircle/index.ts +9 -1
  102. package/src/components/RadioGroup/RadioGroup.namespace.ts +12 -0
  103. package/src/components/RadioGroup/RadioGroup.tsx +338 -0
  104. package/src/components/RadioGroup/index.ts +14 -0
  105. package/src/components/Switch/Switch.namespace.ts +10 -0
  106. package/src/components/Switch/Switch.tsx +191 -0
  107. package/src/components/Switch/index.ts +12 -0
  108. package/src/components/TagGroup/TagGroup.namespace.ts +8 -0
  109. package/src/components/TagGroup/TagGroup.tsx +125 -0
  110. package/src/components/TagGroup/index.ts +10 -0
  111. package/src/components/__tests__/ProgressCircle.test.ts +33 -0
  112. package/src/components/__tests__/exports.test.ts +38 -0
  113. package/src/components/__tests__/switch.test.ts +34 -0
  114. package/src/components/index.ts +7 -0
  115. package/src/hooks/__tests__/use-controllable-state.test.ts +120 -0
  116. package/src/hooks/__tests__/use-press-tap.test.ts +129 -0
  117. package/src/hooks/index.ts +3 -0
  118. package/src/hooks/use-controllable-state.ts +38 -0
  119. package/src/hooks/use-icon-color.ts +51 -0
  120. package/src/hooks/use-press-tap.ts +54 -0
  121. package/src/index.ts +3 -4
  122. package/src/utils/__tests__/create-slot-recipe-context.test.tsx +228 -0
  123. package/src/utils/__tests__/split-multiple-variants-props.test.ts +61 -0
  124. package/src/utils/create-slot-recipe-context.tsx +147 -0
  125. package/src/utils/index.ts +4 -0
  126. package/src/utils/resolve-recipe-token.ts +47 -0
  127. package/src/utils/split-multiple-variants-props.ts +59 -0
  128. package/lib/components/Box/Box.d.ts +0 -10
  129. package/lib/components/Box/Box.d.ts.map +0 -1
  130. package/lib/components/Box/Box.jsx +0 -19
  131. package/lib/components/Box/index.d.ts +0 -2
  132. package/lib/components/Box/index.d.ts.map +0 -1
  133. package/lib/components/Box/index.js +0 -1
  134. package/lib/components/Flex/Flex.d.ts +0 -33
  135. package/lib/components/Flex/Flex.d.ts.map +0 -1
  136. package/lib/components/Flex/Flex.jsx +0 -7
  137. package/lib/components/Flex/index.d.ts +0 -2
  138. package/lib/components/Flex/index.d.ts.map +0 -1
  139. package/lib/components/Flex/index.js +0 -1
  140. package/lib/components/List/List.d.ts +0 -9
  141. package/lib/components/List/List.d.ts.map +0 -1
  142. package/lib/components/List/List.jsx +0 -17
  143. package/lib/components/List/index.d.ts +0 -2
  144. package/lib/components/List/index.d.ts.map +0 -1
  145. package/lib/components/List/index.js +0 -1
  146. package/lib/components/ListItem/ListItem.d.ts +0 -8
  147. package/lib/components/ListItem/ListItem.d.ts.map +0 -1
  148. package/lib/components/ListItem/ListItem.jsx +0 -11
  149. package/lib/components/ListItem/index.d.ts +0 -2
  150. package/lib/components/ListItem/index.d.ts.map +0 -1
  151. package/lib/components/ListItem/index.js +0 -1
  152. package/lib/components/ScrollView/ScrollView.d.ts +0 -9
  153. package/lib/components/ScrollView/ScrollView.d.ts.map +0 -1
  154. package/lib/components/ScrollView/ScrollView.jsx +0 -17
  155. package/lib/components/ScrollView/index.d.ts +0 -2
  156. package/lib/components/ScrollView/index.d.ts.map +0 -1
  157. package/lib/components/ScrollView/index.js +0 -1
  158. package/lib/components/Stack/Stack.d.ts +0 -6
  159. package/lib/components/Stack/Stack.d.ts.map +0 -1
  160. package/lib/components/Stack/Stack.jsx +0 -10
  161. package/lib/components/Stack/index.d.ts +0 -2
  162. package/lib/components/Stack/index.d.ts.map +0 -1
  163. package/lib/components/Stack/index.js +0 -1
  164. package/lib/components/Text/Text.d.ts +0 -30
  165. package/lib/components/Text/Text.d.ts.map +0 -1
  166. package/lib/components/Text/Text.jsx +0 -49
  167. package/lib/components/Text/index.d.ts +0 -2
  168. package/lib/components/Text/index.d.ts.map +0 -1
  169. package/lib/components/Text/index.js +0 -1
  170. package/lib/get-seed-class-name.d.ts.map +0 -1
  171. package/lib/utils/dynamic-style.d.ts +0 -13
  172. package/lib/utils/dynamic-style.d.ts.map +0 -1
  173. package/lib/utils/dynamic-style.js +0 -26
  174. package/lib/utils/styled.d.ts +0 -120
  175. package/lib/utils/styled.d.ts.map +0 -1
  176. package/lib/utils/styled.jsx +0 -131
  177. package/src/utils/dynamic-style.ts +0 -26
  178. /package/lib/{get-seed-class-name.d.ts → utils/get-seed-class-name.d.ts} +0 -0
  179. /package/lib/{get-seed-class-name.js → utils/get-seed-class-name.js} +0 -0
  180. /package/src/{get-seed-class-name.ts → utils/get-seed-class-name.ts} +0 -0
@@ -0,0 +1,291 @@
1
+ import * as React from "react";
2
+ import { cloneElement, isValidElement, type CSSProperties, type ReactElement } from "react";
3
+ import clsx from "clsx";
4
+ import type { MainThread } from "@lynx-js/types";
5
+
6
+ import { checkbox } from "@seed-design/lynx-css/recipes/checkbox";
7
+ import type { CheckboxVariantProps } from "@seed-design/lynx-css/recipes/checkbox";
8
+ import { checkmark } from "@seed-design/lynx-css/recipes/checkmark";
9
+ import type { CheckmarkVariantProps } from "@seed-design/lynx-css/recipes/checkmark";
10
+ import { checkboxGroup } from "@seed-design/lynx-css/recipes/checkbox-group";
11
+ import { vars as checkmarkVars } from "@seed-design/lynx-css/vars/component/checkmark";
12
+
13
+ import { useControllableState } from "../../hooks/use-controllable-state";
14
+ import { useIconColor } from "../../hooks/use-icon-color";
15
+ import { usePressTap } from "../../hooks/use-press-tap";
16
+ import { capitalize, resolveRecipeToken } from "../../utils/resolve-recipe-token";
17
+ import { splitMultipleVariantsProps } from "../../utils/split-multiple-variants-props";
18
+
19
+ /**
20
+ * @platform Lynx
21
+ *
22
+ * 웹 대비 미지원 기능:
23
+ * - HiddenInput / name / value / required / invalid: Lynx에 native form 제출 모델이 없음
24
+ * - focus / focusVisible: Lynx에 키보드 포커스 개념이 없음
25
+ * - onChange (raw DOM event): 의미 없음. 토글 이벤트는 onCheckedChange로만 노출
26
+ * - weight="default" | "stronger" 호환 매핑: Lynx 신규 컴포넌트이므로 처음부터 "regular" | "bold" 만 노출
27
+ *
28
+ * Indicator 는 `@karrotmarket/lynx-monochrome-icon` 의 monochrome icon 컴포넌트를
29
+ * 받는다. 내부에서 `<image tint-color=...>` 로 렌더되므로 `useIconColor` 훅이
30
+ * recipe 의 `color` 토큰을 `tint-color` 로 동기화한다. raw SVG 주입은 Lynx 범위 밖.
31
+ */
32
+
33
+ type CheckboxSize = NonNullable<CheckboxVariantProps["size"]>;
34
+ type CheckboxWeight = NonNullable<CheckboxVariantProps["weight"]>;
35
+ type CheckmarkTone = NonNullable<CheckmarkVariantProps["tone"]>;
36
+ type CheckmarkVariant = NonNullable<CheckmarkVariantProps["variant"]>;
37
+
38
+ interface CheckboxContextValue {
39
+ checked: boolean;
40
+ indeterminate: boolean;
41
+ disabled: boolean;
42
+ pressed: boolean;
43
+ size: CheckboxSize;
44
+ weight: CheckboxWeight;
45
+ tone: CheckmarkTone;
46
+ variant: CheckmarkVariant;
47
+ }
48
+
49
+ const CheckboxContext = React.createContext<CheckboxContextValue | null>(null);
50
+
51
+ function useCheckboxContext(consumer: string): CheckboxContextValue {
52
+ const ctx = React.useContext(CheckboxContext);
53
+ if (!ctx) {
54
+ throw new Error(`<${consumer}/> must be rendered inside <CheckboxRoot/>.`);
55
+ }
56
+ return ctx;
57
+ }
58
+
59
+ const CheckmarkIconClassContext = React.createContext<string | null>(null);
60
+
61
+ function useCheckmarkIconClass(consumer: string): string {
62
+ const ctx = React.useContext(CheckmarkIconClassContext);
63
+ if (!ctx) {
64
+ throw new Error(`<${consumer}/> must be rendered inside <CheckboxControl/>.`);
65
+ }
66
+ return ctx;
67
+ }
68
+
69
+ ////////////////////////////////////////////////////////////////////////////////////
70
+
71
+ export interface CheckboxRootProps
72
+ extends CheckboxVariantProps,
73
+ Omit<CheckmarkVariantProps, "size" | "checked" | "disabled" | "indeterminate"> {
74
+ children?: React.ReactNode;
75
+ className?: string;
76
+ checked?: boolean;
77
+ defaultChecked?: boolean;
78
+ indeterminate?: boolean;
79
+ disabled?: boolean;
80
+ onCheckedChange?: (checked: boolean) => void;
81
+ }
82
+
83
+ export const CheckboxRoot = React.forwardRef<unknown, CheckboxRootProps>((props, ref) => {
84
+ const {
85
+ children,
86
+ className,
87
+ checked: checkedProp,
88
+ defaultChecked = false,
89
+ indeterminate = false,
90
+ disabled = false,
91
+ onCheckedChange,
92
+ ...restProps
93
+ } = props;
94
+ const [{ checkbox: checkboxVariantProps, checkmark: checkmarkVariantProps }, nativeProps] =
95
+ splitMultipleVariantsProps(restProps, { checkbox, checkmark });
96
+ const weight: CheckboxWeight = checkboxVariantProps.weight ?? "regular";
97
+ const size: CheckboxSize = checkboxVariantProps.size ?? "medium";
98
+ const tone: CheckmarkTone = checkmarkVariantProps.tone ?? "brand";
99
+ const variant: CheckmarkVariant = checkmarkVariantProps.variant ?? "square";
100
+
101
+ const [checked, setChecked] = useControllableState({
102
+ value: checkedProp,
103
+ defaultValue: defaultChecked,
104
+ onChange: onCheckedChange,
105
+ });
106
+
107
+ const { pressed, ...pressHandlers } = usePressTap({
108
+ disabled,
109
+ onTap: () => setChecked(!checked),
110
+ });
111
+
112
+ const rootClassName = checkbox({ weight, size, disabled }).root;
113
+
114
+ const ctx = React.useMemo<CheckboxContextValue>(
115
+ () => ({ checked, indeterminate, disabled, pressed, size, weight, tone, variant }),
116
+ [checked, indeterminate, disabled, pressed, size, weight, tone, variant],
117
+ );
118
+
119
+ return (
120
+ <CheckboxContext.Provider value={ctx}>
121
+ <view
122
+ {...(ref ? { ref: ref as React.Ref<SVGViewElement> } : {})}
123
+ className={clsx(rootClassName, className)}
124
+ {...pressHandlers}
125
+ {...nativeProps}
126
+ >
127
+ {children}
128
+ </view>
129
+ </CheckboxContext.Provider>
130
+ );
131
+ });
132
+ CheckboxRoot.displayName = "CheckboxRoot";
133
+
134
+ ////////////////////////////////////////////////////////////////////////////////////
135
+
136
+ export interface CheckboxControlProps
137
+ extends Pick<CheckmarkVariantProps, "tone" | "variant" | "size"> {
138
+ children?: React.ReactNode;
139
+ className?: string;
140
+ }
141
+
142
+ export const CheckboxControl = React.forwardRef<unknown, CheckboxControlProps>((props, ref) => {
143
+ const [variantProps, restProps] = checkmark.splitVariantProps(props);
144
+ const { children, className, ...nativeProps } = restProps;
145
+ const {
146
+ checked,
147
+ indeterminate,
148
+ disabled,
149
+ pressed,
150
+ tone: ctxTone,
151
+ variant: ctxVariant,
152
+ size: ctxSize,
153
+ } = useCheckboxContext("CheckboxControl");
154
+
155
+ const tone: CheckmarkTone = variantProps.tone ?? ctxTone;
156
+ const variant: CheckmarkVariant = variantProps.variant ?? ctxVariant;
157
+ const size: CheckboxSize = (variantProps.size as CheckboxSize | undefined) ?? ctxSize;
158
+
159
+ const classes = React.useMemo(
160
+ () => checkmark({ variant, tone, size, checked, disabled, indeterminate, pressed }),
161
+ [variant, tone, size, checked, disabled, indeterminate, pressed],
162
+ );
163
+
164
+ return (
165
+ <CheckmarkIconClassContext.Provider value={classes.icon}>
166
+ <view
167
+ {...(ref ? { ref: ref as React.Ref<SVGViewElement> } : {})}
168
+ className={clsx(classes.root, className)}
169
+ {...nativeProps}
170
+ >
171
+ {children}
172
+ </view>
173
+ </CheckmarkIconClassContext.Provider>
174
+ );
175
+ });
176
+ CheckboxControl.displayName = "CheckboxControl";
177
+
178
+ ////////////////////////////////////////////////////////////////////////////////////
179
+
180
+ type IconElementProps = {
181
+ className?: string;
182
+ style?: CSSProperties;
183
+ ref?: React.Ref<MainThread.Element>;
184
+ };
185
+
186
+ export interface CheckboxIndicatorProps {
187
+ /** Icon rendered when neither checked nor indeterminate. Optional. */
188
+ unchecked?: ReactElement<IconElementProps>;
189
+ /** Icon rendered when `checked=true` and `indeterminate=false`. */
190
+ checked: ReactElement<IconElementProps>;
191
+ /** Icon rendered when `indeterminate=true`. */
192
+ indeterminate?: ReactElement<IconElementProps>;
193
+ className?: string;
194
+ style?: CSSProperties;
195
+ }
196
+
197
+ export function CheckboxIndicator(props: CheckboxIndicatorProps) {
198
+ const {
199
+ unchecked,
200
+ checked: checkedIcon,
201
+ indeterminate: indeterminateIcon,
202
+ className,
203
+ style,
204
+ } = props;
205
+ const { checked, indeterminate, disabled, pressed, tone, variant, size } =
206
+ useCheckboxContext("CheckboxIndicator");
207
+ const iconClassName = useCheckmarkIconClass("CheckboxIndicator");
208
+ const { ref: tintRef } = useIconColor([
209
+ checked,
210
+ indeterminate,
211
+ disabled,
212
+ pressed,
213
+ tone,
214
+ variant,
215
+ size,
216
+ ]);
217
+
218
+ if (process.env.NODE_ENV !== "production" && indeterminate && !indeterminateIcon) {
219
+ console.warn(
220
+ "[seed-design] CheckboxIndicator: `indeterminate` prop must be provided when the checkbox is in an indeterminate state.",
221
+ );
222
+ }
223
+
224
+ const icon = indeterminate ? indeterminateIcon : checked ? checkedIcon : unchecked;
225
+ if (!icon || !isValidElement<IconElementProps>(icon)) return null;
226
+
227
+ // lynx-monochrome-icon 이 `<image style={{ width, height, ...style }}>` 로 자체 default size 를 박으므로
228
+ // recipe 토큰에서 꺼낸 사이즈를 inline 으로 주입해 덮는다.
229
+ const iconSize = resolveRecipeToken(checkmarkVars, [
230
+ `variant${capitalize(variant)}Size${capitalize(size)}`,
231
+ "enabled",
232
+ "icon",
233
+ "size",
234
+ ]);
235
+
236
+ return cloneElement(icon, {
237
+ className: clsx(iconClassName, icon.props.className, className),
238
+ style: iconSize
239
+ ? { width: iconSize, height: iconSize, ...icon.props.style, ...style }
240
+ : { ...icon.props.style, ...style },
241
+ ref: tintRef,
242
+ });
243
+ }
244
+ CheckboxIndicator.displayName = "CheckboxIndicator";
245
+
246
+ ////////////////////////////////////////////////////////////////////////////////////
247
+
248
+ export interface CheckboxLabelProps {
249
+ children?: React.ReactNode;
250
+ className?: string;
251
+ }
252
+
253
+ export const CheckboxLabel = React.forwardRef<unknown, CheckboxLabelProps>((props, ref) => {
254
+ const { children, className, ...nativeProps } = props;
255
+ const { disabled, weight, size } = useCheckboxContext("CheckboxLabel");
256
+ const labelClassName = checkbox({ weight, size, disabled }).label;
257
+
258
+ return (
259
+ <text
260
+ {...(ref ? { ref: ref as React.Ref<SVGTextElement> } : {})}
261
+ className={clsx(labelClassName, className)}
262
+ {...nativeProps}
263
+ >
264
+ {children}
265
+ </text>
266
+ );
267
+ });
268
+ CheckboxLabel.displayName = "CheckboxLabel";
269
+
270
+ ////////////////////////////////////////////////////////////////////////////////////
271
+
272
+ export interface CheckboxGroupProps {
273
+ children?: React.ReactNode;
274
+ className?: string;
275
+ }
276
+
277
+ export const CheckboxGroup = React.forwardRef<unknown, CheckboxGroupProps>((props, ref) => {
278
+ const { children, className, ...nativeProps } = props;
279
+ const classes = checkboxGroup();
280
+
281
+ return (
282
+ <view
283
+ {...(ref ? { ref: ref as React.Ref<SVGViewElement> } : {})}
284
+ className={clsx(classes, className)}
285
+ {...nativeProps}
286
+ >
287
+ {children}
288
+ </view>
289
+ );
290
+ });
291
+ CheckboxGroup.displayName = "CheckboxGroup";
@@ -0,0 +1,14 @@
1
+ export {
2
+ CheckboxRoot,
3
+ CheckboxControl,
4
+ CheckboxIndicator,
5
+ CheckboxLabel,
6
+ CheckboxGroup,
7
+ type CheckboxRootProps,
8
+ type CheckboxControlProps,
9
+ type CheckboxIndicatorProps,
10
+ type CheckboxLabelProps,
11
+ type CheckboxGroupProps,
12
+ } from "./Checkbox";
13
+
14
+ export * as Checkbox from "./Checkbox.namespace";
@@ -0,0 +1,5 @@
1
+ export {
2
+ ProgressCircleRange as Range,
3
+ ProgressCircleRoot as Root,
4
+ type ProgressCircleRootProps as RootProps,
5
+ } from "./ProgressCircle";
@@ -1,3 +1,4 @@
1
+ import type * as React from "@lynx-js/react";
1
2
  import {
2
3
  createContext,
3
4
  runOnMainThread,
@@ -11,8 +12,8 @@ import clsx from "clsx";
11
12
  import { progressCircle } from "@seed-design/lynx-css/recipes/progress-circle";
12
13
  import type { ProgressCircleVariantProps } from "@seed-design/lynx-css/recipes/progress-circle";
13
14
 
14
- type Tone = "neutral" | "brand" | "staticWhite";
15
- type Size = "24" | "40";
15
+ type Tone = "neutral" | "brand" | "staticWhite" | "inherit";
16
+ type Size = "14" | "16" | "18" | "24" | "40";
16
17
 
17
18
  interface ProgressCircleContextValue {
18
19
  tone: Tone;
@@ -110,7 +111,7 @@ const TRANSITION_DURATION = 300;
110
111
 
111
112
  // --- Components ---
112
113
 
113
- export interface RootProps extends ProgressCircleVariantProps {
114
+ export interface ProgressCircleRootProps extends ProgressCircleVariantProps {
114
115
  minValue?: number;
115
116
  maxValue?: number;
116
117
  value?: number;
@@ -118,6 +119,8 @@ export interface RootProps extends ProgressCircleVariantProps {
118
119
  className?: string;
119
120
  }
120
121
 
122
+ export type RootProps = ProgressCircleRootProps;
123
+
121
124
  /**
122
125
  * Lynx에서 SVG를 사용할 수 없어 CSS clip-path 기반 pie sector로 구현.
123
126
  *
@@ -128,7 +131,7 @@ export interface RootProps extends ProgressCircleVariantProps {
128
131
  *
129
132
  * Lynx SVG + stroke-dasharray 지원 시 CSS-only 애니메이션으로 전환 예정.
130
133
  */
131
- function Root(props: RootProps) {
134
+ export const ProgressCircleRoot = (props: ProgressCircleRootProps) => {
132
135
  const size: Size = (props.size as Size) ?? "40";
133
136
  const tone: Tone = (props.tone as Tone) ?? "neutral";
134
137
  const numSize = Number(size);
@@ -160,9 +163,9 @@ function Root(props: RootProps) {
160
163
  </view>
161
164
  </ProgressCircleContext.Provider>
162
165
  );
163
- }
166
+ };
164
167
 
165
- function Range() {
168
+ export const ProgressCircleRange = () => {
166
169
  const { numSize, isDeterminate, progress, classes } = useProgressCircleCtx();
167
170
 
168
171
  if (!isDeterminate) {
@@ -170,7 +173,7 @@ function Range() {
170
173
  }
171
174
 
172
175
  return <DeterminateRange numSize={numSize} progress={progress} classes={classes} />;
173
- }
176
+ };
174
177
 
175
178
  type Classes = ReturnType<typeof progressCircle>;
176
179
 
@@ -258,7 +261,7 @@ function DeterminateRange({
258
261
  return () => {
259
262
  runOnMainThread(cancelAnimation)();
260
263
  };
261
- }, [progress]);
264
+ }, [progress, numSize]);
262
265
 
263
266
  return (
264
267
  <>
@@ -354,7 +357,7 @@ function IndeterminateRange({ numSize, classes }: { numSize: number; classes: Cl
354
357
  return () => {
355
358
  runOnMainThread(stopLoop)();
356
359
  };
357
- }, []);
360
+ }, [numSize]);
358
361
 
359
362
  const initialClipPath = 'path("M 0 0 Z")';
360
363
 
@@ -403,7 +406,5 @@ function IndeterminateRange({ numSize, classes }: { numSize: number; classes: Cl
403
406
  );
404
407
  }
405
408
 
406
- export const ProgressCircle = {
407
- Root,
408
- Range,
409
- };
409
+ ProgressCircleRoot.displayName = "ProgressCircleRoot";
410
+ ProgressCircleRange.displayName = "ProgressCircleRange";
@@ -1 +1,9 @@
1
- export { ProgressCircle, type RootProps as ProgressCircleProps } from "./ProgressCircle";
1
+ export {
2
+ ProgressCircleRange,
3
+ ProgressCircleRoot,
4
+ type ProgressCircleRootProps,
5
+ type ProgressCircleRootProps as ProgressCircleProps,
6
+ type RootProps,
7
+ } from "./ProgressCircle";
8
+
9
+ export * as ProgressCircle from "./ProgressCircle.namespace";
@@ -0,0 +1,12 @@
1
+ export {
2
+ RadioGroupItem as Item,
3
+ RadioGroupItemControl as ItemControl,
4
+ RadioGroupItemIndicator as ItemIndicator,
5
+ RadioGroupItemLabel as ItemLabel,
6
+ RadioGroupRoot as Root,
7
+ type RadioGroupItemControlProps as ItemControlProps,
8
+ type RadioGroupItemIndicatorProps as ItemIndicatorProps,
9
+ type RadioGroupItemLabelProps as ItemLabelProps,
10
+ type RadioGroupItemProps as ItemProps,
11
+ type RadioGroupRootProps as RootProps,
12
+ } from "./RadioGroup";