@uniai-fe/uds-primitives 0.1.13 → 0.2.1

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 (114) hide show
  1. package/README.md +2 -2
  2. package/dist/styles.css +1112 -385
  3. package/package.json +12 -15
  4. package/src/components/button/index.scss +1 -0
  5. package/src/components/button/markup/{ButtonRounded.tsx → Rounded.tsx} +1 -1
  6. package/src/components/button/markup/{ButtonText.tsx → Text.tsx} +1 -1
  7. package/src/components/button/markup/index.ts +3 -3
  8. package/src/components/button/styles/button.scss +113 -229
  9. package/src/components/button/styles/round-button.scss +11 -14
  10. package/src/components/button/styles/text-button.scss +23 -23
  11. package/src/components/button/styles/variables.scss +145 -0
  12. package/src/components/dropdown/index.tsx +3 -3
  13. package/src/components/dropdown/markup/Template.tsx +57 -0
  14. package/src/components/dropdown/markup/foundation/Container.tsx +125 -0
  15. package/src/components/dropdown/markup/foundation/MenuItem.tsx +107 -0
  16. package/src/components/dropdown/markup/foundation/MenuList.tsx +27 -0
  17. package/src/components/dropdown/markup/foundation/Provider.tsx +46 -0
  18. package/src/components/dropdown/markup/foundation/Root.tsx +30 -0
  19. package/src/components/dropdown/markup/foundation/Trigger.tsx +34 -0
  20. package/src/components/dropdown/markup/foundation/index.tsx +25 -0
  21. package/src/components/dropdown/markup/index.tsx +8 -2
  22. package/src/components/dropdown/styles/dropdown.scss +166 -0
  23. package/src/components/dropdown/styles/index.scss +2 -0
  24. package/src/components/dropdown/styles/variables.scss +40 -0
  25. package/src/components/dropdown/types/base.ts +31 -0
  26. package/src/components/dropdown/types/index.ts +2 -4
  27. package/src/components/dropdown/types/props.ts +170 -0
  28. package/src/components/dropdown/utils/index.ts +1 -4
  29. package/src/components/dropdown/utils/refs.ts +20 -0
  30. package/src/components/form/index.scss +1 -0
  31. package/src/components/form/index.tsx +18 -2
  32. package/src/components/form/markup/form-field/Body.tsx +18 -0
  33. package/src/components/form/markup/form-field/Container.tsx +58 -0
  34. package/src/components/form/markup/form-field/Footer.tsx +21 -0
  35. package/src/components/form/markup/form-field/Header.tsx +39 -0
  36. package/src/components/form/markup/form-field/Template.tsx +56 -0
  37. package/src/components/form/markup/form-field/index.tsx +22 -0
  38. package/src/components/form/styles/form-field/layout.scss +67 -0
  39. package/src/components/form/styles/form-field/variables.scss +17 -0
  40. package/src/components/form/styles/index.scss +2 -0
  41. package/src/components/form/types/index.ts +1 -0
  42. package/src/components/form/types/props.ts +125 -0
  43. package/src/components/form/utils/form-field.ts +42 -0
  44. package/src/components/input/hooks/index.ts +1 -4
  45. package/src/components/input/hooks/useDigitField.ts +63 -0
  46. package/src/components/input/img/calendar/calendar.svg +7 -0
  47. package/src/components/input/img/calendar/chevron-down.svg +3 -0
  48. package/src/components/input/img/calendar/chevron-left.svg +3 -0
  49. package/src/components/input/img/calendar/chevron-right.svg +3 -0
  50. package/src/components/input/img/calendar/chevron-up.svg +3 -0
  51. package/src/components/input/index.tsx +2 -1
  52. package/src/components/input/markup/calendar/Base.tsx +329 -0
  53. package/src/components/input/markup/calendar/index.tsx +8 -0
  54. package/src/components/input/markup/{text/InputUtilityButton.tsx → foundation/Button.tsx} +5 -15
  55. package/src/components/input/markup/foundation/Input.tsx +245 -0
  56. package/src/components/input/markup/foundation/SideSlot.tsx +30 -0
  57. package/src/components/input/markup/foundation/StatusIcon.tsx +21 -0
  58. package/src/components/input/markup/foundation/Utility.tsx +103 -0
  59. package/src/components/input/markup/foundation/index.tsx +15 -0
  60. package/src/components/input/markup/index.tsx +11 -1
  61. package/src/components/input/markup/text/AuthCode.tsx +41 -59
  62. package/src/components/input/markup/text/Email.tsx +25 -115
  63. package/src/components/input/markup/text/Password.tsx +30 -39
  64. package/src/components/input/markup/text/Phone.tsx +35 -122
  65. package/src/components/input/markup/text/Search.tsx +17 -18
  66. package/src/components/input/markup/text/index.ts +15 -12
  67. package/src/components/input/styles/calendar.scss +110 -0
  68. package/src/components/input/styles/foundation.scss +345 -0
  69. package/src/components/input/styles/index.scss +4 -476
  70. package/src/components/input/styles/text.scss +89 -0
  71. package/src/components/input/styles/variables.scss +41 -0
  72. package/src/components/input/types/calendar.ts +208 -0
  73. package/src/components/input/types/foundation.ts +194 -0
  74. package/src/components/input/types/hooks.ts +43 -0
  75. package/src/components/input/types/index.ts +5 -87
  76. package/src/components/input/types/text.ts +203 -0
  77. package/src/components/input/types/verification.ts +23 -0
  78. package/src/components/input/utils/index.tsx +1 -0
  79. package/src/components/input/utils/verification.tsx +35 -0
  80. package/src/components/select/hooks/index.ts +43 -2
  81. package/src/components/select/img/chevron/primary/large.svg +3 -0
  82. package/src/components/select/img/chevron/primary/medium.svg +3 -0
  83. package/src/components/select/img/chevron/primary/small.svg +3 -0
  84. package/src/components/select/img/chevron/secondary/large.svg +3 -0
  85. package/src/components/select/img/chevron/secondary/medium.svg +3 -0
  86. package/src/components/select/img/chevron/secondary/small.svg +3 -0
  87. package/src/components/select/img/remove.svg +3 -0
  88. package/src/components/select/index.scss +2 -1
  89. package/src/components/select/index.tsx +5 -0
  90. package/src/components/select/markup/Default.tsx +154 -0
  91. package/src/components/select/markup/foundation/Base.tsx +90 -0
  92. package/src/components/select/markup/foundation/Container.tsx +30 -0
  93. package/src/components/select/markup/foundation/Icon.tsx +78 -0
  94. package/src/components/select/markup/foundation/Selected.tsx +34 -0
  95. package/src/components/select/markup/foundation/index.ts +2 -0
  96. package/src/components/select/markup/index.tsx +36 -2
  97. package/src/components/select/markup/multiple/Multiple.tsx +205 -0
  98. package/src/components/select/markup/multiple/SelectedChip.tsx +58 -0
  99. package/src/components/select/markup/multiple/index.ts +2 -0
  100. package/src/components/select/styles/select.scss +316 -0
  101. package/src/components/select/styles/variables.scss +91 -0
  102. package/src/components/select/types/base.ts +34 -0
  103. package/src/components/select/types/icon.ts +45 -0
  104. package/src/components/select/types/index.ts +6 -4
  105. package/src/components/select/types/multiple.ts +57 -0
  106. package/src/components/select/types/option.ts +43 -0
  107. package/src/components/select/types/props.ts +209 -0
  108. package/src/components/select/types/trigger.ts +196 -0
  109. package/src/index.scss +3 -2
  110. package/src/components/input/markup/text/Base.tsx +0 -454
  111. package/src/components/input/utils/index.ts +0 -60
  112. package/src/components/select/styles/index.scss +0 -0
  113. /package/src/components/button/markup/{ButtonDefault.tsx → Base.tsx} +0 -0
  114. /package/src/components/form/{Provider.tsx → markup/Provider.tsx} +0 -0
@@ -1,454 +0,0 @@
1
- import clsx from "clsx";
2
- import type { ForwardedRef, PointerEvent as ReactPointerEvent } from "react";
3
- import {
4
- ChangeEvent,
5
- FocusEvent,
6
- MouseEvent,
7
- forwardRef,
8
- useCallback,
9
- useEffect,
10
- useId,
11
- useMemo,
12
- useRef,
13
- useState,
14
- } from "react";
15
- import type { InputProps } from "../../types";
16
- import {
17
- INPUT_AFFIX_CLASSNAME,
18
- INPUT_ELEMENT_CLASSNAME,
19
- INPUT_FIELD_CLASSNAME,
20
- composeInputBoxClassName,
21
- composeInputClassName,
22
- } from "../../utils";
23
- import ErrorIcon from "../../img/error.svg";
24
- import ResetIcon from "../../img/reset.svg";
25
- import SuccessIcon from "../../img/success.svg";
26
-
27
- const setForwardedRef = <T,>(ref: ForwardedRef<T>, value: T | null): void => {
28
- if (!ref) {
29
- return;
30
- }
31
- if (typeof ref === "function") {
32
- ref(value);
33
- return;
34
- }
35
- ref.current = value;
36
- };
37
-
38
- /**
39
- * Native `<input>` 기반 텍스트 필드.
40
- * priority/size/state 축과 left/right/clear/status 슬롯, label/helper 피드백 슬롯을 모두 제공하며
41
- * react-hook-form `register` 결과를 그대로 전달받아 내부 ref/onChange/onBlur에 병합한다.
42
- *
43
- * @component
44
- * @param {InputProps} props Input 컴포넌트 공통 props
45
- * @param {"primary" | "secondary" | "tertiary"} [props.priority="primary"] 디자인 토큰 우선순위
46
- * @param {"small" | "medium" | "large"} [props.size="medium"] 높이/타이포 세트
47
- * @param {"default" | "active" | "focused" | "success" | "error" | "disabled"} [props.state="default"] 시각 상태
48
- * @param {boolean} [props.block=false] true면 width 100%
49
- * @param {React.ReactNode} [props.left] 입력 왼쪽 슬롯(아이콘/텍스트)
50
- * @param {React.ReactNode} [props.right] 입력 오른쪽 슬롯
51
- * @param {React.ReactNode} [props.clearIcon] 입력값 초기화 아이콘. 지정하지 않으면 기본 Reset 아이콘
52
- * @param {React.ReactNode} [props.successIcon] success 상태 아이콘 override
53
- * @param {React.ReactNode} [props.errorIcon] error 상태 아이콘 override
54
- * @param {React.ReactNode} [props.label] 상단 또는 inline label 콘텐츠
55
- * @param {React.ReactNode} [props.helper] helper 텍스트 콘텐츠
56
- * @param {boolean} [props.hideHelper] true면 helper 영역 숨김
57
- * @param {string} [props.inputClassName] 실제 `<input>` 요소 className
58
- * @param {string} [props.boxClassName] `.input-box` className
59
- * @param {ComponentPropsWithoutRef<"label">} [props.labelProps] label 추가 속성
60
- * @param {ComponentPropsWithoutRef<"div">} [props.helperProps] helper container 속성
61
- * @param {boolean} [props.disabled] native disabled
62
- * @param {string} [props.id] 외부 id. label htmlFor와 공유된다
63
- * @param {string} [props.className] root `.input` className
64
- * @param {UseFormRegisterReturn} [props.register] react-hook-form register 반환값
65
- * @param {string} [props.name] native name. register 사용 시 자동으로 병합
66
- * @param {InputState} [props.data-simulated-state] Storybook 등에서 시각 상태 강제용
67
- * @param {(event: ChangeEvent<HTMLInputElement>) => void} [props.onChange] change 핸들러
68
- * @param {(event: FocusEvent<HTMLInputElement>) => void} [props.onFocus] focus 핸들러
69
- * @param {(event: FocusEvent<HTMLInputElement>) => void} [props.onBlur] blur 핸들러
70
- * @param {string | number | readonly string[]} [props.value] 제어형 값
71
- * @param {string | number | readonly string[]} [props.defaultValue] 비제어 초기값
72
- * @param {string} [props.type="text"] native input type
73
- */
74
- const Text = forwardRef<HTMLInputElement, InputProps>(
75
- (
76
- {
77
- priority = "primary",
78
- size = "medium",
79
- state: stateProp = "default",
80
- block = false,
81
- left,
82
- right,
83
- clear,
84
- success,
85
- error,
86
- label,
87
- helper,
88
- hideHelper,
89
- inputClassName,
90
- boxClassName,
91
- helperProps,
92
- labelProps,
93
- disabled,
94
- id,
95
- className,
96
- register,
97
- "data-simulated-state": simulatedState,
98
- value,
99
- defaultValue,
100
- name,
101
- onChange,
102
- onFocus,
103
- onBlur,
104
- type = "text",
105
- ...restProps
106
- },
107
- forwardedRef,
108
- ) => {
109
- const generatedId = useId();
110
- const registerRef = register?.ref;
111
- const registerOnChange = register?.onChange;
112
- const registerOnBlur = register?.onBlur;
113
- const inputRef = useRef<HTMLInputElement | null>(null);
114
- const [isFocused, setIsFocused] = useState(false);
115
- const [hasValue, setHasValue] = useState(() => {
116
- const initial = value ?? defaultValue;
117
- return initial !== undefined && initial !== null
118
- ? String(initial).length > 0
119
- : false;
120
- });
121
- const [isClearInteracting, setIsClearInteracting] = useState(false);
122
-
123
- useEffect(() => {
124
- if (stateProp === "disabled" || disabled) {
125
- setIsFocused(false);
126
- }
127
- }, [disabled, stateProp]);
128
-
129
- useEffect(() => {
130
- if (value !== undefined && value !== null) {
131
- setHasValue(String(value).length > 0);
132
- }
133
- }, [value]);
134
-
135
- const resolvedState = useMemo(
136
- () => (disabled ? "disabled" : stateProp),
137
- [disabled, stateProp],
138
- );
139
- const visualState = useMemo(() => {
140
- if (resolvedState === "disabled") {
141
- return "disabled";
142
- }
143
- if (resolvedState === "loading") {
144
- return "loading";
145
- }
146
- if (resolvedState === "error") {
147
- return "error";
148
- }
149
- return isFocused ? "active" : resolvedState;
150
- }, [isFocused, resolvedState]);
151
-
152
- const fieldId = useMemo(
153
- () => id ?? labelProps?.htmlFor ?? generatedId,
154
- [generatedId, id, labelProps?.htmlFor],
155
- );
156
- const helperElementId = useMemo(() => {
157
- if (!helper || hideHelper) {
158
- return undefined;
159
- }
160
- return helperProps?.id ?? `${fieldId}-helper-text`;
161
- }, [fieldId, helperProps?.id, helper, hideHelper]);
162
-
163
- const defaultStatusIcon = useMemo(() => {
164
- if (resolvedState === "success") {
165
- return <SuccessIcon aria-hidden="true" />;
166
- }
167
- if (resolvedState === "error") {
168
- return <ErrorIcon aria-hidden="true" />;
169
- }
170
- return null;
171
- }, [resolvedState]);
172
-
173
- const statusSlot = useMemo(() => {
174
- if (resolvedState === "success") {
175
- return success ?? defaultStatusIcon;
176
- }
177
- if (resolvedState === "error") {
178
- return error ?? defaultStatusIcon;
179
- }
180
- return null;
181
- }, [defaultStatusIcon, error, resolvedState, success]);
182
-
183
- const defaultClearIcon = useMemo(() => {
184
- // 기존에는 focus 상태에서만 clear 아이콘을 보여줬지만
185
- // 값이 있는 모든 상황에서 초기화할 수 있도록 제한을 해제한다.
186
- return <ResetIcon aria-hidden="true" />;
187
- }, []);
188
-
189
- const effectiveClearIcon = clear ?? defaultClearIcon;
190
- const shouldBlockClear =
191
- resolvedState === "disabled" ||
192
- resolvedState === "loading" ||
193
- restProps.readOnly;
194
- const showClearIcon = Boolean(
195
- effectiveClearIcon &&
196
- hasValue &&
197
- !shouldBlockClear &&
198
- (isFocused || isClearInteracting),
199
- );
200
- const isDisabled = resolvedState === "disabled";
201
- const labelFor = labelProps?.htmlFor ?? fieldId;
202
- const containerClassName = useMemo(
203
- () =>
204
- composeInputClassName({
205
- priority,
206
- size,
207
- state: visualState,
208
- block,
209
- className,
210
- }),
211
- [priority, block, className, size, visualState],
212
- );
213
- const fieldBoxClassName = useMemo(
214
- () =>
215
- composeInputBoxClassName({
216
- priority,
217
- size,
218
- state: visualState,
219
- block,
220
- className: boxClassName,
221
- }),
222
- [priority, block, size, visualState, boxClassName],
223
- );
224
- const helperClassName = useMemo(
225
- () => clsx("input-helper-text", helperProps?.className),
226
- [helperProps?.className],
227
- );
228
- const shouldRenderInlineLabel = priority === "tertiary" && Boolean(label);
229
- const labelClassName = useMemo(
230
- () =>
231
- clsx(
232
- "input-label",
233
- shouldRenderInlineLabel && "input-label--visually-hidden",
234
- labelProps?.className,
235
- ),
236
- [labelProps?.className, shouldRenderInlineLabel],
237
- );
238
- const inputElementClassName = useMemo(
239
- () => clsx(INPUT_ELEMENT_CLASSNAME, inputClassName),
240
- [inputClassName],
241
- );
242
-
243
- const mergedRef = useCallback(
244
- (node: HTMLInputElement | null) => {
245
- inputRef.current = node;
246
- setForwardedRef(forwardedRef, node);
247
- registerRef?.(node);
248
- },
249
- [forwardedRef, registerRef],
250
- );
251
-
252
- const handleFocus = useCallback(
253
- (event: FocusEvent<HTMLInputElement>) => {
254
- setIsFocused(true);
255
- onFocus?.(event);
256
- },
257
- [onFocus],
258
- );
259
-
260
- const handleBlur = useCallback(
261
- (event: FocusEvent<HTMLInputElement>) => {
262
- setIsFocused(false);
263
- registerOnBlur?.(event);
264
- onBlur?.(event);
265
- },
266
- [onBlur, registerOnBlur],
267
- );
268
-
269
- const handleChange = useCallback(
270
- (event: ChangeEvent<HTMLInputElement>) => {
271
- setHasValue(event.currentTarget.value.length > 0);
272
- registerOnChange?.(event);
273
- onChange?.(event);
274
- },
275
- [onChange, registerOnChange],
276
- );
277
-
278
- const dispatchNativeInputEvent = useCallback(() => {
279
- const inputEl = inputRef.current;
280
- if (!inputEl) {
281
- return;
282
- }
283
- const nativeSetter = Object.getOwnPropertyDescriptor(
284
- HTMLInputElement.prototype,
285
- "value",
286
- )?.set;
287
- nativeSetter?.call(inputEl, "");
288
- const changeEvent = new Event("input", { bubbles: true });
289
- inputEl.dispatchEvent(changeEvent);
290
- }, []);
291
-
292
- const handleClear = useCallback(
293
- (
294
- event:
295
- | MouseEvent<HTMLButtonElement>
296
- | ReactPointerEvent<HTMLButtonElement>,
297
- ) => {
298
- event.preventDefault();
299
- dispatchNativeInputEvent();
300
- setHasValue(false);
301
- setIsClearInteracting(false);
302
- const inputEl = inputRef.current;
303
- inputEl?.focus();
304
- // 일부 브라우저(특히 로그인 필드)가 focus 직후 자동완성을 재삽입하는 경우가 있어
305
- // 다음 프레임에서 한 번 더 초기화해 값을 비워 둔다.
306
- requestAnimationFrame(() => {
307
- dispatchNativeInputEvent();
308
- });
309
- },
310
- [dispatchNativeInputEvent],
311
- );
312
-
313
- const handleClearPointerDown = useCallback(() => {
314
- setIsClearInteracting(true);
315
- }, []);
316
-
317
- const handleClearPointerLeave = useCallback(() => {
318
- setIsClearInteracting(false);
319
- }, []);
320
-
321
- const handleClearPointerUp = useCallback(
322
- (event: ReactPointerEvent<HTMLButtonElement>) => {
323
- setIsClearInteracting(false);
324
- // pointerup 이벤트에서 onClick이 호출되지 않는 환경(모바일) 대응
325
- handleClear(event);
326
- },
327
- [handleClear],
328
- );
329
-
330
- const inputName = register?.name ?? name;
331
-
332
- return (
333
- <div
334
- className={containerClassName}
335
- data-priority={priority}
336
- data-size={size}
337
- data-state={visualState}
338
- data-block={block ? "true" : undefined}
339
- data-simulated-state={simulatedState}
340
- >
341
- {label ? (
342
- <label
343
- {...labelProps}
344
- className={labelClassName}
345
- htmlFor={labelFor}
346
- data-slot="label"
347
- data-priority={priority}
348
- data-state={visualState}
349
- >
350
- {label}
351
- </label>
352
- ) : null}
353
- <div className={fieldBoxClassName} data-slot="box">
354
- <div
355
- className={INPUT_FIELD_CLASSNAME}
356
- data-state={visualState}
357
- data-priority={priority}
358
- data-size={size}
359
- data-block={block ? "true" : undefined}
360
- >
361
- <div className="input-field__control">
362
- {shouldRenderInlineLabel ? (
363
- <div
364
- className="input-inline-label"
365
- aria-hidden="true"
366
- data-slot="inline-label"
367
- >
368
- {label}
369
- </div>
370
- ) : null}
371
- {left ? (
372
- <div
373
- className={`${INPUT_AFFIX_CLASSNAME} ${INPUT_AFFIX_CLASSNAME}--left`}
374
- data-slot="left"
375
- >
376
- {left}
377
- </div>
378
- ) : null}
379
- <input
380
- {...restProps}
381
- id={fieldId}
382
- ref={mergedRef}
383
- className={inputElementClassName}
384
- disabled={isDisabled}
385
- aria-invalid={resolvedState === "error" ? true : undefined}
386
- aria-describedby={helperElementId}
387
- type={type}
388
- value={value}
389
- defaultValue={defaultValue}
390
- name={inputName}
391
- onChange={handleChange}
392
- onFocus={handleFocus}
393
- onBlur={handleBlur}
394
- />
395
- </div>
396
- {right || showClearIcon || statusSlot ? (
397
- <div className="input-field__utilities">
398
- {right ? (
399
- <div
400
- className={`${INPUT_AFFIX_CLASSNAME} ${INPUT_AFFIX_CLASSNAME}--right`}
401
- data-slot="right"
402
- >
403
- {right}
404
- </div>
405
- ) : null}
406
- {showClearIcon ? (
407
- <button
408
- type="button"
409
- className={`${INPUT_AFFIX_CLASSNAME} ${INPUT_AFFIX_CLASSNAME}--clear`}
410
- data-slot="clear"
411
- data-visible="true"
412
- onClick={handleClear}
413
- onPointerDown={handleClearPointerDown}
414
- onPointerLeave={handleClearPointerLeave}
415
- onPointerUp={handleClearPointerUp}
416
- onPointerCancel={handleClearPointerLeave}
417
- aria-label="입력 내용 지우기"
418
- >
419
- {effectiveClearIcon}
420
- </button>
421
- ) : null}
422
- {statusSlot ? (
423
- <div
424
- className={`${INPUT_AFFIX_CLASSNAME} ${INPUT_AFFIX_CLASSNAME}--status`}
425
- data-slot="status"
426
- data-state={resolvedState}
427
- >
428
- {statusSlot}
429
- </div>
430
- ) : null}
431
- </div>
432
- ) : null}
433
- </div>
434
- </div>
435
- {helper && !hideHelper ? (
436
- <div
437
- {...helperProps}
438
- className={helperClassName}
439
- id={helperElementId}
440
- data-slot="helper"
441
- data-priority={priority}
442
- data-state={visualState}
443
- >
444
- {helper}
445
- </div>
446
- ) : null}
447
- </div>
448
- );
449
- },
450
- );
451
-
452
- Text.displayName = "TextInput";
453
-
454
- export { Text };
@@ -1,60 +0,0 @@
1
- import clsx from "clsx";
2
- import type { InputClassNameOptions } from "../types";
3
-
4
- const INPUT_CLASSNAME = "input";
5
- const INPUT_BOX_CLASSNAME = "input-box";
6
- const INPUT_FIELD_CLASSNAME = "input-field";
7
- const INPUT_ELEMENT_CLASSNAME = "input-element";
8
- const INPUT_AFFIX_CLASSNAME = "input-affix";
9
-
10
- /**
11
- * container `.input` element className을 조립한다.
12
- */
13
- const composeInputClassName = ({
14
- priority,
15
- size,
16
- state,
17
- block,
18
- className,
19
- }: InputClassNameOptions) =>
20
- clsx(
21
- INPUT_CLASSNAME,
22
- `${INPUT_CLASSNAME}--priority-${priority}`,
23
- `${INPUT_CLASSNAME}--size-${size}`,
24
- {
25
- [`${INPUT_CLASSNAME}--state-${state}`]: state !== "default",
26
- [`${INPUT_CLASSNAME}--block`]: block,
27
- },
28
- className,
29
- );
30
-
31
- /**
32
- * 박스(wrapper) `.input-box` className을 조립한다.
33
- */
34
- const composeInputBoxClassName = ({
35
- priority,
36
- size,
37
- state,
38
- block,
39
- className,
40
- }: InputClassNameOptions) =>
41
- clsx(
42
- INPUT_BOX_CLASSNAME,
43
- `${INPUT_BOX_CLASSNAME}--priority-${priority}`,
44
- `${INPUT_BOX_CLASSNAME}--size-${size}`,
45
- {
46
- [`${INPUT_BOX_CLASSNAME}--state-${state}`]: state !== "default",
47
- [`${INPUT_BOX_CLASSNAME}--block`]: block,
48
- },
49
- className,
50
- );
51
-
52
- export {
53
- INPUT_AFFIX_CLASSNAME,
54
- INPUT_BOX_CLASSNAME,
55
- INPUT_CLASSNAME,
56
- INPUT_ELEMENT_CLASSNAME,
57
- INPUT_FIELD_CLASSNAME,
58
- composeInputBoxClassName,
59
- composeInputClassName,
60
- };
File without changes