@petnow/ui 4.0.2 → 4.1.0

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 (54) hide show
  1. package/dist/Popup-D9fn8MGc.js +90 -0
  2. package/dist/Popup-D9fn8MGc.js.map +1 -0
  3. package/dist/TailwindUtil-aZk2bbTo.js +71 -0
  4. package/dist/TailwindUtil-aZk2bbTo.js.map +1 -0
  5. package/dist/index.es.js +25 -5523
  6. package/dist/v0/checkbox.js +36 -0
  7. package/dist/v0/checkbox.js.map +1 -0
  8. package/dist/v0/radio.js +16 -0
  9. package/dist/v0/radio.js.map +1 -0
  10. package/dist/v0/tabs.js +62 -0
  11. package/dist/v0/tabs.js.map +1 -0
  12. package/dist/v0/toggle.js +20 -0
  13. package/dist/v0/toggle.js.map +1 -0
  14. package/dist/v1/badge.js +338 -0
  15. package/dist/v1/badge.js.map +1 -0
  16. package/dist/v1/chip.js +53 -0
  17. package/dist/v1/chip.js.map +1 -0
  18. package/dist/v1/cta-button.js +62 -0
  19. package/dist/v1/cta-button.js.map +1 -0
  20. package/dist/v1/icons/action/cancel-filled.js +22 -0
  21. package/dist/v1/icons/action/cancel-filled.js.map +1 -0
  22. package/dist/v1/icons/action/cancel.js +19 -0
  23. package/dist/v1/icons/action/cancel.js.map +1 -0
  24. package/dist/v1/icons/action/chevron-down.js +19 -0
  25. package/dist/v1/icons/action/chevron-down.js.map +1 -0
  26. package/dist/v1/icons/action/chevron-left.js +19 -0
  27. package/dist/v1/icons/action/chevron-left.js.map +1 -0
  28. package/dist/v1/icons/action/chevron-right.js +19 -0
  29. package/dist/v1/icons/action/chevron-right.js.map +1 -0
  30. package/dist/v1/icons/action/chevron-up.js +19 -0
  31. package/dist/v1/icons/action/chevron-up.js.map +1 -0
  32. package/dist/v1/icons/action/filter.js +19 -0
  33. package/dist/v1/icons/action/filter.js.map +1 -0
  34. package/dist/v1/icons/action/retry.js +19 -0
  35. package/dist/v1/icons/action/retry.js.map +1 -0
  36. package/dist/v1/icons/action/sorting.js +19 -0
  37. package/dist/v1/icons/action/sorting.js.map +1 -0
  38. package/dist/v1/icons/static/close.js +19 -0
  39. package/dist/v1/icons/static/close.js.map +1 -0
  40. package/dist/v1/icons/static/delete.js +30 -0
  41. package/dist/v1/icons/static/delete.js.map +1 -0
  42. package/dist/v1/icons/static/recent.js +32 -0
  43. package/dist/v1/icons/static/recent.js.map +1 -0
  44. package/dist/v1/icons/static/report.js +28 -0
  45. package/dist/v1/icons/static/report.js.map +1 -0
  46. package/dist/v1/icons/static/shield-done.js +21 -0
  47. package/dist/v1/icons/static/shield-done.js.map +1 -0
  48. package/dist/v1/popup.js +5 -0
  49. package/dist/v1/text-field.js +286 -0
  50. package/dist/v1/text-field.js.map +1 -0
  51. package/package.json +95 -4
  52. package/dist/index.es.js.map +0 -1
  53. package/dist/index.umd.js +0 -57
  54. package/dist/index.umd.js.map +0 -1
@@ -0,0 +1,286 @@
1
+ "use client";
2
+ import { t as e } from "../TailwindUtil-aZk2bbTo.js";
3
+ import { CTAButton as t } from "./cta-button.js";
4
+ import { CancelFilledIcon as n } from "./icons/action/cancel-filled.js";
5
+ import { ChevronLeftIcon as r } from "./icons/action/chevron-left.js";
6
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
7
+ import * as o from "react";
8
+ import { cva as s } from "class-variance-authority";
9
+ //#region src/components/v1/text-field/TextField.tsx
10
+ var c = s("flex items-center rounded-[4px] bg-surface-base-neutral-2 border transition-colors duration-200", {
11
+ variants: {
12
+ size: {
13
+ large: "gap-2 p-[15px] min-h-[56px]",
14
+ small: "gap-3 p-[11px] min-h-[48px]"
15
+ },
16
+ hasError: {
17
+ true: "border-border-prominent-error",
18
+ false: "border-transparent"
19
+ },
20
+ disabled: {
21
+ true: "opacity-50",
22
+ false: ""
23
+ }
24
+ },
25
+ defaultVariants: {
26
+ size: "large",
27
+ disabled: !1,
28
+ hasError: !1
29
+ }
30
+ }), l = s("", {
31
+ variants: {
32
+ size: {
33
+ large: "text-body-16-regular",
34
+ small: "text-caption-12-medium"
35
+ },
36
+ hasError: {
37
+ true: "text-text-prominent-error",
38
+ false: "text-text-base-neutral-2"
39
+ }
40
+ },
41
+ defaultVariants: {
42
+ size: "large",
43
+ hasError: !1
44
+ }
45
+ }), u = o.forwardRef(({ onChange: t, subtitle: r, isRequired: s = !1, assistiveText: u, errorText: d, disabled: f = !1, multiLine: p = !1, className: m, rightElement: h, showCounter: g = !1, value: _, maxLength: v, size: y = "large", ...b }, x) => {
46
+ let S = !!d, C = o.useRef(null);
47
+ o.useImperativeHandle(x, () => C.current);
48
+ let w = o.useCallback(() => {
49
+ C.current?.focus();
50
+ }, []), T = (typeof _ == "string" ? _ : "").length, E = b, D = b, O = y === "large" ? "text-title-20-regular" : "text-body-16-regular", k = y === "large" ? "text-title-18-bold" : "text-title-14-bold", A = y === "large" ? "text-body-16-regular" : "text-caption-12-medium";
51
+ return /* @__PURE__ */ a("div", {
52
+ className: e("flex flex-col gap-2", m),
53
+ children: [
54
+ r && /* @__PURE__ */ a("span", {
55
+ className: e(k, "text-text-base-neutral-5"),
56
+ children: [r, s && /* @__PURE__ */ i("span", {
57
+ className: "text-text-prominent-accent-1",
58
+ children: "*"
59
+ })]
60
+ }),
61
+ /* @__PURE__ */ a("div", {
62
+ onClick: f ? void 0 : w,
63
+ className: e("group overflow-hidden", c({
64
+ size: y,
65
+ disabled: f,
66
+ hasError: S
67
+ }), !f && !S && "focus-within:border-border-base-neutral-4", p && "h-[120px] items-start"),
68
+ children: [
69
+ p ? /* @__PURE__ */ i("textarea", {
70
+ ...D,
71
+ onChange: t,
72
+ ref: C,
73
+ value: _,
74
+ maxLength: v,
75
+ disabled: f,
76
+ className: e("text-text-base-neutral-5 placeholder:text-text-base-neutral-2 h-full min-h-[24px] min-w-0 flex-1 border-none bg-transparent py-0 outline-none", O, "resize-none overflow-y-auto")
77
+ }) : /* @__PURE__ */ i("input", {
78
+ ...E,
79
+ onChange: t,
80
+ ref: C,
81
+ value: _,
82
+ maxLength: v,
83
+ disabled: f,
84
+ className: e("text-text-base-neutral-5 placeholder:text-text-base-neutral-2 min-h-[24px] min-w-0 flex-1 border-none bg-transparent py-0 outline-none", O, "overflow-hidden text-ellipsis whitespace-nowrap")
85
+ }),
86
+ h && /* @__PURE__ */ i("div", {
87
+ className: "shrink-0",
88
+ children: h
89
+ }),
90
+ /* @__PURE__ */ i("button", {
91
+ type: "button",
92
+ onClick: () => t && t({ target: { value: "" } }),
93
+ tabIndex: -1,
94
+ disabled: f,
95
+ className: e("hidden shrink-0", {
96
+ flex: S,
97
+ "group-focus-within:flex": !f && T > 0
98
+ }),
99
+ children: /* @__PURE__ */ i(n, { className: "text-icon-base-neutral-3 h-6 w-6 shrink-0 cursor-pointer" })
100
+ })
101
+ ]
102
+ }),
103
+ (u || d || v && g) && /* @__PURE__ */ a("div", {
104
+ className: "flex items-center justify-between gap-2",
105
+ children: [(u || d) && /* @__PURE__ */ i("span", {
106
+ className: e(A, l({
107
+ size: y,
108
+ hasError: S
109
+ })),
110
+ children: d || u
111
+ }), v && g && /* @__PURE__ */ a("span", {
112
+ className: e("ml-auto", A, l({
113
+ size: y,
114
+ hasError: S
115
+ })),
116
+ children: [
117
+ T,
118
+ "/",
119
+ v
120
+ ]
121
+ })]
122
+ })
123
+ ]
124
+ });
125
+ });
126
+ u.displayName = "TextFieldNormal";
127
+ var d = s("flex items-center justify-between rounded-[4px] bg-surface-base-neutral-2 border transition-colors duration-200", {
128
+ variants: {
129
+ size: {
130
+ large: "gap-2 p-[15px] min-h-[56px]",
131
+ small: "gap-3 p-[11px] min-h-[48px]"
132
+ },
133
+ hasError: {
134
+ true: "border-border-prominent-error",
135
+ false: "border-transparent"
136
+ },
137
+ disabled: {
138
+ true: "opacity-50",
139
+ false: ""
140
+ }
141
+ },
142
+ defaultVariants: { size: "large" }
143
+ }), f = ({ label: t, placeholder: n, value: o, isRequired: s = !1, disabled: c = !1, assistiveText: u, errorText: f, onPress: p, className: m, size: h = "large" }) => {
144
+ let g = !!f, _ = h === "large" ? "text-title-18-bold" : "text-title-14-bold", v = h === "large" ? "text-title-20-regular" : "text-body-16-regular";
145
+ return /* @__PURE__ */ a("div", {
146
+ className: e("flex w-full flex-col gap-2", m),
147
+ children: [
148
+ t && /* @__PURE__ */ a("div", {
149
+ className: "flex items-start",
150
+ children: [/* @__PURE__ */ i("span", {
151
+ className: e(_, "text-text-base-neutral-5"),
152
+ children: t
153
+ }), s && /* @__PURE__ */ i("span", {
154
+ className: e(_, "text-text-prominent-accent-1"),
155
+ children: "*"
156
+ })]
157
+ }),
158
+ /* @__PURE__ */ a("button", {
159
+ type: "button",
160
+ className: d({
161
+ size: h,
162
+ hasError: g,
163
+ disabled: c
164
+ }),
165
+ onClick: p,
166
+ disabled: c,
167
+ children: [/* @__PURE__ */ i("span", {
168
+ className: e(v, "flex-1", o ? "text-text-base-neutral-5" : "text-text-base-neutral-2"),
169
+ style: {
170
+ textAlign: "left",
171
+ overflow: "hidden",
172
+ textOverflow: "ellipsis"
173
+ },
174
+ children: o || n
175
+ }), /* @__PURE__ */ i(r, { className: "text-icon-base-neutral-3 rotate-270" })]
176
+ }),
177
+ (u || f) && /* @__PURE__ */ i("div", {
178
+ className: "flex items-start gap-2",
179
+ children: /* @__PURE__ */ i("span", {
180
+ className: l({
181
+ size: h,
182
+ hasError: g
183
+ }),
184
+ children: f || u
185
+ })
186
+ })
187
+ ]
188
+ });
189
+ }, p = o.forwardRef(({ onChange: r, subtitle: s, isRequired: u = !1, assistiveText: d, errorText: f, disabled: p = !1, multiLine: m = !1, className: h, showCounter: g = !1, value: _, maxLength: v, size: y = "large", fieldRightElement: b, buttonText: x, onButtonClick: S, buttonDisabled: C = !1, ...w }, T) => {
190
+ let E = !!f, D = o.useRef(null);
191
+ o.useImperativeHandle(T, () => D.current);
192
+ let O = o.useCallback(() => {
193
+ D.current?.focus();
194
+ }, []), k = (typeof _ == "string" ? _ : "").length, A = w, j = w, M = y === "large" ? "text-title-20-regular" : "text-body-16-regular", N = y === "large" ? "text-title-18-bold" : "text-title-14-bold", P = y === "large" ? "text-body-16-regular" : "text-caption-12-medium";
195
+ return /* @__PURE__ */ a("div", {
196
+ className: e("flex flex-col gap-2", h),
197
+ children: [
198
+ s && /* @__PURE__ */ a("span", {
199
+ className: e(N, "text-text-base-neutral-5"),
200
+ children: [s, u && /* @__PURE__ */ i("span", {
201
+ className: "text-text-prominent-accent-1",
202
+ children: "*"
203
+ })]
204
+ }),
205
+ /* @__PURE__ */ a("div", {
206
+ className: "flex items-center gap-2",
207
+ children: [/* @__PURE__ */ a("div", {
208
+ onClick: p ? void 0 : O,
209
+ className: e("group flex-1 overflow-hidden", c({
210
+ size: y,
211
+ disabled: p,
212
+ hasError: E
213
+ }), !p && !E && "focus-within:border-border-base-neutral-4", m && "h-[120px] items-start"),
214
+ children: [
215
+ m ? /* @__PURE__ */ i("textarea", {
216
+ ...j,
217
+ onChange: r,
218
+ ref: D,
219
+ value: _,
220
+ maxLength: v,
221
+ disabled: p,
222
+ className: e("text-text-base-neutral-5 placeholder:text-text-base-neutral-2 min-h-[24px] min-w-0 flex-1 border-none bg-transparent py-0 outline-none", M, "resize-none overflow-y-auto")
223
+ }) : /* @__PURE__ */ i("input", {
224
+ ...A,
225
+ onChange: r,
226
+ ref: D,
227
+ value: _,
228
+ maxLength: v,
229
+ disabled: p,
230
+ className: e("text-text-base-neutral-5 placeholder:text-text-base-neutral-2 min-h-[24px] min-w-0 flex-1 border-none bg-transparent py-0 outline-none", M, "overflow-hidden text-ellipsis whitespace-nowrap")
231
+ }),
232
+ b && /* @__PURE__ */ i("div", {
233
+ className: "shrink-0",
234
+ children: b
235
+ }),
236
+ /* @__PURE__ */ i("button", {
237
+ type: "button",
238
+ onClick: () => r && r({ target: { value: "" } }),
239
+ tabIndex: -1,
240
+ disabled: p,
241
+ className: e("hidden shrink-0", {
242
+ flex: E,
243
+ "group-focus-within:flex": !p && k > 0
244
+ }),
245
+ children: /* @__PURE__ */ i(n, { className: "text-icon-base-neutral-3 h-6 w-6 shrink-0 cursor-pointer" })
246
+ })
247
+ ]
248
+ }), /* @__PURE__ */ i("div", {
249
+ className: "shrink-0",
250
+ children: /* @__PURE__ */ i(t, {
251
+ label: x,
252
+ onClick: S,
253
+ size: "medium",
254
+ hierarchy: "tertiary",
255
+ disabled: C || p
256
+ })
257
+ })]
258
+ }),
259
+ (d || f || v && g) && /* @__PURE__ */ a("div", {
260
+ className: "flex items-center justify-between gap-2",
261
+ children: [(d || f) && /* @__PURE__ */ i("span", {
262
+ className: e(P, l({
263
+ size: y,
264
+ hasError: E
265
+ })),
266
+ children: f || d
267
+ }), v && g && /* @__PURE__ */ a("span", {
268
+ className: e("ml-auto", P, l({
269
+ size: y,
270
+ hasError: E
271
+ })),
272
+ children: [
273
+ k,
274
+ "/",
275
+ v
276
+ ]
277
+ })]
278
+ })
279
+ ]
280
+ });
281
+ });
282
+ p.displayName = "TextFieldWithButton";
283
+ //#endregion
284
+ export { u as TextFieldNormal, f as TextFieldSelect, p as TextFieldWithButton };
285
+
286
+ //# sourceMappingURL=text-field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-field.js","names":[],"sources":["../../src/components/v1/text-field/TextField.tsx"],"sourcesContent":["\"use client\";\n\nimport { cva, VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nimport { CTAButton } from \"../cta-button/CTAButton\";\nimport { CancelFilledIcon } from \"../icons/action/CancelFilledIcon\";\nimport { ChevronLeftIcon } from \"../icons/action/ChevronLeftIcon\";\n\nimport { cn } from \"@/utils/TailwindUtil\";\n\n// TextField Normal 컴포넌트 스타일 정의\nconst textFieldNormalContainerVariants = cva(\n \"flex items-center rounded-[4px] bg-surface-base-neutral-2 border transition-colors duration-200\",\n {\n variants: {\n size: {\n large: \"gap-2 p-[15px] min-h-[56px]\",\n small: \"gap-3 p-[11px] min-h-[48px]\",\n },\n hasError: {\n true: \"border-border-prominent-error\",\n false: \"border-transparent\",\n },\n disabled: {\n true: \"opacity-50\",\n false: \"\",\n },\n },\n defaultVariants: {\n size: \"large\",\n disabled: false,\n hasError: false,\n },\n },\n);\n\nconst textFieldAssistiveAreaVariants = cva(\"\", {\n variants: {\n size: {\n large: \"text-body-16-regular\",\n small: \"text-caption-12-medium\",\n },\n hasError: {\n true: \"text-text-prominent-error\",\n false: \"text-text-base-neutral-2\",\n },\n },\n defaultVariants: {\n size: \"large\",\n hasError: false,\n },\n});\n\ninterface TextFieldNormalProps extends Omit<React.InputHTMLAttributes<HTMLInputElement | HTMLTextAreaElement>, \"size\"> {\n subtitle?: string;\n isRequired?: boolean;\n assistiveText?: string | React.ReactNode;\n errorText?: string;\n disabled?: boolean;\n multiLine?: boolean;\n className?: string;\n rightElement?: React.ReactNode;\n showCounter?: boolean;\n size?: \"large\" | \"small\";\n}\n\nconst TextFieldNormal = React.forwardRef<HTMLInputElement | HTMLTextAreaElement, TextFieldNormalProps>(\n (\n {\n onChange,\n subtitle,\n isRequired = false,\n assistiveText,\n errorText,\n disabled = false,\n multiLine = false,\n className,\n rightElement,\n showCounter = false,\n value,\n maxLength,\n size = \"large\",\n ...inputProps\n },\n ref,\n ) => {\n const hasError = !!errorText;\n const inputRef = React.useRef<HTMLInputElement | HTMLTextAreaElement>(null);\n\n React.useImperativeHandle(ref, () => inputRef.current as HTMLInputElement | HTMLTextAreaElement);\n\n const handleContainerClick = React.useCallback(() => {\n inputRef.current?.focus();\n }, []);\n\n const stringValue = typeof value === \"string\" ? value : \"\";\n const currentLength = stringValue.length;\n\n const inputPropsForInput = inputProps as React.ComponentPropsWithoutRef<\"input\">;\n const inputPropsForTextarea = inputProps as React.ComponentPropsWithoutRef<\"textarea\">;\n\n // 사이즈별 폰트 크기\n const inputFontSize = size === \"large\" ? \"text-title-20-regular\" : \"text-body-16-regular\";\n const subtitleFontSize = size === \"large\" ? \"text-title-18-bold\" : \"text-title-14-bold\";\n const assistiveFontSize = size === \"large\" ? \"text-body-16-regular\" : \"text-caption-12-medium\";\n\n return (\n <div className={cn(\"flex flex-col gap-2\", className)}>\n {subtitle && (\n <span className={cn(subtitleFontSize, \"text-text-base-neutral-5\")}>\n {subtitle}\n {isRequired && <span className=\"text-text-prominent-accent-1\">*</span>}\n </span>\n )}\n\n <div\n onClick={disabled ? undefined : handleContainerClick}\n className={cn(\n \"group overflow-hidden\",\n textFieldNormalContainerVariants({ size, disabled, hasError }),\n !disabled && !hasError && \"focus-within:border-border-base-neutral-4\",\n multiLine && \"h-[120px] items-start\",\n )}\n >\n {multiLine ? (\n <textarea\n {...inputPropsForTextarea}\n onChange={onChange}\n ref={inputRef as React.Ref<HTMLTextAreaElement>}\n value={value}\n maxLength={maxLength}\n disabled={disabled}\n className={cn(\n \"text-text-base-neutral-5 placeholder:text-text-base-neutral-2 h-full min-h-[24px] min-w-0 flex-1 border-none bg-transparent py-0 outline-none\",\n inputFontSize,\n \"resize-none overflow-y-auto\",\n )}\n />\n ) : (\n <input\n {...inputPropsForInput}\n onChange={onChange}\n ref={inputRef as React.Ref<HTMLInputElement>}\n value={value}\n maxLength={maxLength}\n disabled={disabled}\n className={cn(\n \"text-text-base-neutral-5 placeholder:text-text-base-neutral-2 min-h-[24px] min-w-0 flex-1 border-none bg-transparent py-0 outline-none\",\n inputFontSize,\n \"overflow-hidden text-ellipsis whitespace-nowrap\",\n )}\n />\n )}\n\n {rightElement && <div className=\"shrink-0\">{rightElement}</div>}\n\n <button\n type=\"button\"\n onClick={() =>\n onChange &&\n onChange({ target: { value: \"\" } } as React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>)\n }\n tabIndex={-1}\n disabled={disabled}\n className={cn(\"hidden shrink-0\", {\n flex: hasError,\n \"group-focus-within:flex\": !disabled && currentLength > 0,\n })}\n >\n <CancelFilledIcon className=\"text-icon-base-neutral-3 h-6 w-6 shrink-0 cursor-pointer\" />\n </button>\n </div>\n\n {(assistiveText || errorText || (maxLength && showCounter)) && (\n <div className=\"flex items-center justify-between gap-2\">\n {(assistiveText || errorText) && (\n <span className={cn(assistiveFontSize, textFieldAssistiveAreaVariants({ size, hasError }))}>\n {errorText || assistiveText}\n </span>\n )}\n {maxLength && showCounter && (\n <span className={cn(\"ml-auto\", assistiveFontSize, textFieldAssistiveAreaVariants({ size, hasError }))}>\n {currentLength}/{maxLength}\n </span>\n )}\n </div>\n )}\n </div>\n );\n },\n);\nTextFieldNormal.displayName = \"TextFieldNormal\";\n\n// TextField Select 컴포넌트\nconst textFieldSelectVariants = cva(\n \"flex items-center justify-between rounded-[4px] bg-surface-base-neutral-2 border transition-colors duration-200\",\n {\n variants: {\n size: {\n large: \"gap-2 p-[15px] min-h-[56px]\",\n small: \"gap-3 p-[11px] min-h-[48px]\",\n },\n hasError: {\n true: \"border-border-prominent-error\",\n false: \"border-transparent\",\n },\n disabled: {\n true: \"opacity-50\",\n false: \"\",\n },\n },\n defaultVariants: {\n size: \"large\",\n },\n },\n);\n\ninterface TextFieldSelectProps extends VariantProps<typeof textFieldSelectVariants> {\n label?: string;\n placeholder: string;\n value?: string;\n isRequired?: boolean;\n disabled?: boolean;\n assistiveText?: string | React.ReactNode;\n errorText?: string;\n onPress?: () => void;\n className?: string;\n size?: \"large\" | \"small\";\n}\n\nconst TextFieldSelect = ({\n label,\n placeholder,\n value,\n isRequired = false,\n disabled = false,\n assistiveText,\n errorText,\n onPress,\n className,\n size = \"large\",\n}: TextFieldSelectProps) => {\n const hasError = !!errorText;\n\n // 사이즈별 폰트 크기\n const labelFontSize = size === \"large\" ? \"text-title-18-bold\" : \"text-title-14-bold\";\n const valueFontSize = size === \"large\" ? \"text-title-20-regular\" : \"text-body-16-regular\";\n\n return (\n <div className={cn(\"flex w-full flex-col gap-2\", className)}>\n {/* Label with optional asterisk */}\n {label && (\n <div className=\"flex items-start\">\n <span className={cn(labelFontSize, \"text-text-base-neutral-5\")}>{label}</span>\n {isRequired && <span className={cn(labelFontSize, \"text-text-prominent-accent-1\")}>*</span>}\n </div>\n )}\n {/* Select Field */}\n <button\n type=\"button\"\n className={textFieldSelectVariants({ size, hasError, disabled })}\n onClick={onPress}\n disabled={disabled}\n >\n <span\n className={cn(valueFontSize, \"flex-1\", value ? \"text-text-base-neutral-5\" : \"text-text-base-neutral-2\")}\n style={{ textAlign: \"left\", overflow: \"hidden\", textOverflow: \"ellipsis\" }}\n >\n {value || placeholder}\n </span>\n <ChevronLeftIcon className=\"text-icon-base-neutral-3 rotate-270\" />\n </button>\n {/* Assistive/Error Text */}\n {(assistiveText || errorText) && (\n <div className=\"flex items-start gap-2\">\n <span className={textFieldAssistiveAreaVariants({ size, hasError })}>{errorText || assistiveText}</span>\n </div>\n )}\n </div>\n );\n};\n\n// TextField With Button 컴포넌트\ninterface TextFieldWithButtonProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement | HTMLTextAreaElement>, \"size\"> {\n subtitle?: string;\n isRequired?: boolean;\n assistiveText?: string | React.ReactNode;\n errorText?: string;\n disabled?: boolean;\n multiLine?: boolean;\n className?: string;\n showCounter?: boolean;\n size?: \"large\" | \"small\";\n fieldRightElement?: React.ReactNode;\n buttonText: string;\n onButtonClick: () => void;\n buttonDisabled?: boolean;\n}\n\nconst TextFieldWithButton = React.forwardRef<HTMLInputElement | HTMLTextAreaElement, TextFieldWithButtonProps>(\n (\n {\n onChange,\n subtitle,\n isRequired = false,\n assistiveText,\n errorText,\n disabled = false,\n multiLine = false,\n className,\n showCounter = false,\n value,\n maxLength,\n size = \"large\",\n fieldRightElement,\n buttonText,\n onButtonClick,\n buttonDisabled = false,\n ...inputProps\n },\n ref,\n ) => {\n const hasError = !!errorText;\n const inputRef = React.useRef<HTMLInputElement | HTMLTextAreaElement>(null);\n\n React.useImperativeHandle(ref, () => inputRef.current as HTMLInputElement | HTMLTextAreaElement);\n\n const handleContainerClick = React.useCallback(() => {\n inputRef.current?.focus();\n }, []);\n\n const stringValue = typeof value === \"string\" ? value : \"\";\n const currentLength = stringValue.length;\n\n const inputPropsForInput = inputProps as React.ComponentPropsWithoutRef<\"input\">;\n const inputPropsForTextarea = inputProps as React.ComponentPropsWithoutRef<\"textarea\">;\n\n // 사이즈별 폰트 크기\n const inputFontSize = size === \"large\" ? \"text-title-20-regular\" : \"text-body-16-regular\";\n const subtitleFontSize = size === \"large\" ? \"text-title-18-bold\" : \"text-title-14-bold\";\n const assistiveFontSize = size === \"large\" ? \"text-body-16-regular\" : \"text-caption-12-medium\";\n\n return (\n <div className={cn(\"flex flex-col gap-2\", className)}>\n {subtitle && (\n <span className={cn(subtitleFontSize, \"text-text-base-neutral-5\")}>\n {subtitle}\n {isRequired && <span className=\"text-text-prominent-accent-1\">*</span>}\n </span>\n )}\n\n <div className=\"flex items-center gap-2\">\n <div\n onClick={disabled ? undefined : handleContainerClick}\n className={cn(\n \"group flex-1 overflow-hidden\",\n textFieldNormalContainerVariants({ size, disabled, hasError }),\n !disabled && !hasError && \"focus-within:border-border-base-neutral-4\",\n multiLine && \"h-[120px] items-start\",\n )}\n >\n {multiLine ? (\n <textarea\n {...inputPropsForTextarea}\n onChange={onChange}\n ref={inputRef as React.Ref<HTMLTextAreaElement>}\n value={value}\n maxLength={maxLength}\n disabled={disabled}\n className={cn(\n \"text-text-base-neutral-5 placeholder:text-text-base-neutral-2 min-h-[24px] min-w-0 flex-1 border-none bg-transparent py-0 outline-none\",\n inputFontSize,\n \"resize-none overflow-y-auto\",\n )}\n />\n ) : (\n <input\n {...inputPropsForInput}\n onChange={onChange}\n ref={inputRef as React.Ref<HTMLInputElement>}\n value={value}\n maxLength={maxLength}\n disabled={disabled}\n className={cn(\n \"text-text-base-neutral-5 placeholder:text-text-base-neutral-2 min-h-[24px] min-w-0 flex-1 border-none bg-transparent py-0 outline-none\",\n inputFontSize,\n \"overflow-hidden text-ellipsis whitespace-nowrap\",\n )}\n />\n )}\n\n {fieldRightElement && <div className=\"shrink-0\">{fieldRightElement}</div>}\n\n <button\n type=\"button\"\n onClick={() =>\n onChange &&\n onChange({ target: { value: \"\" } } as React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>)\n }\n tabIndex={-1}\n disabled={disabled}\n className={cn(\"hidden shrink-0\", {\n flex: hasError,\n \"group-focus-within:flex\": !disabled && currentLength > 0,\n })}\n >\n <CancelFilledIcon className=\"text-icon-base-neutral-3 h-6 w-6 shrink-0 cursor-pointer\" />\n </button>\n </div>\n\n <div className=\"shrink-0\">\n <CTAButton\n label={buttonText}\n onClick={onButtonClick}\n size=\"medium\"\n hierarchy=\"tertiary\"\n disabled={buttonDisabled || disabled}\n />\n </div>\n </div>\n\n {(assistiveText || errorText || (maxLength && showCounter)) && (\n <div className=\"flex items-center justify-between gap-2\">\n {(assistiveText || errorText) && (\n <span className={cn(assistiveFontSize, textFieldAssistiveAreaVariants({ size, hasError }))}>\n {errorText || assistiveText}\n </span>\n )}\n {maxLength && showCounter && (\n <span className={cn(\"ml-auto\", assistiveFontSize, textFieldAssistiveAreaVariants({ size, hasError }))}>\n {currentLength}/{maxLength}\n </span>\n )}\n </div>\n )}\n </div>\n );\n },\n);\nTextFieldWithButton.displayName = \"TextFieldWithButton\";\n\nexport { TextFieldNormal, TextFieldSelect, TextFieldWithButton };\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@petnow/ui",
3
- "version": "4.0.2",
3
+ "version": "4.1.0",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite",
@@ -27,6 +27,7 @@
27
27
  "react-daum-postcode": "^3.2.0",
28
28
  "react-icons": "^5.5.0",
29
29
  "react-swipeable-views": "^0.14.1",
30
+ "shadcn": "^4.1.0",
30
31
  "tailwind-merge": "^3.3.1",
31
32
  "tw-animate-css": "^1.4.0"
32
33
  },
@@ -62,7 +63,6 @@
62
63
  "prettier-plugin-tailwindcss": "^0.6.14",
63
64
  "react": "^19.0.0",
64
65
  "react-dom": "^19.0.0",
65
- "shadcn": "^4.0.8",
66
66
  "storybook": "10.3.1",
67
67
  "tailwindcss": "^4.1.14",
68
68
  "ts-jest": "^29.4.6",
@@ -79,8 +79,99 @@
79
79
  "exports": {
80
80
  ".": {
81
81
  "types": "./dist/index.d.ts",
82
- "import": "./dist/index.es.js",
83
- "require": "./dist/index.umd.js"
82
+ "import": "./dist/index.es.js"
83
+ },
84
+ "./v0/radio": {
85
+ "types": "./dist/src/components/v0/radio/Radio.d.ts",
86
+ "import": "./dist/v0/radio.js"
87
+ },
88
+ "./v0/tabs": {
89
+ "types": "./dist/src/components/v0/tabs/Tabs.d.ts",
90
+ "import": "./dist/v0/tabs.js"
91
+ },
92
+ "./v0/checkbox": {
93
+ "types": "./dist/src/components/v0/checkbox/Checkbox.d.ts",
94
+ "import": "./dist/v0/checkbox.js"
95
+ },
96
+ "./v0/toggle": {
97
+ "types": "./dist/src/components/v0/toggle/Toggle.d.ts",
98
+ "import": "./dist/v0/toggle.js"
99
+ },
100
+ "./v1/badge": {
101
+ "types": "./dist/src/components/v1/badge/Badge.d.ts",
102
+ "import": "./dist/v1/badge.js"
103
+ },
104
+ "./v1/chip": {
105
+ "types": "./dist/src/components/v1/chip/Chip.d.ts",
106
+ "import": "./dist/v1/chip.js"
107
+ },
108
+ "./v1/cta-button": {
109
+ "types": "./dist/src/components/v1/cta-button/CTAButton.d.ts",
110
+ "import": "./dist/v1/cta-button.js"
111
+ },
112
+ "./v1/popup": {
113
+ "types": "./dist/src/components/v1/popup/Popup.d.ts",
114
+ "import": "./dist/v1/popup.js"
115
+ },
116
+ "./v1/text-field": {
117
+ "types": "./dist/src/components/v1/text-field/TextField.d.ts",
118
+ "import": "./dist/v1/text-field.js"
119
+ },
120
+ "./v1/icons/action/cancel-filled": {
121
+ "types": "./dist/src/components/v1/icons/action/CancelFilledIcon.d.ts",
122
+ "import": "./dist/v1/icons/action/cancel-filled.js"
123
+ },
124
+ "./v1/icons/action/cancel": {
125
+ "types": "./dist/src/components/v1/icons/action/CancelIcon.d.ts",
126
+ "import": "./dist/v1/icons/action/cancel.js"
127
+ },
128
+ "./v1/icons/action/chevron-down": {
129
+ "types": "./dist/src/components/v1/icons/action/ChevronDownIcon.d.ts",
130
+ "import": "./dist/v1/icons/action/chevron-down.js"
131
+ },
132
+ "./v1/icons/action/chevron-left": {
133
+ "types": "./dist/src/components/v1/icons/action/ChevronLeftIcon.d.ts",
134
+ "import": "./dist/v1/icons/action/chevron-left.js"
135
+ },
136
+ "./v1/icons/action/chevron-right": {
137
+ "types": "./dist/src/components/v1/icons/action/ChevronRightIcon.d.ts",
138
+ "import": "./dist/v1/icons/action/chevron-right.js"
139
+ },
140
+ "./v1/icons/action/chevron-up": {
141
+ "types": "./dist/src/components/v1/icons/action/ChevronUpIcon.d.ts",
142
+ "import": "./dist/v1/icons/action/chevron-up.js"
143
+ },
144
+ "./v1/icons/action/filter": {
145
+ "types": "./dist/src/components/v1/icons/action/FilterIcon.d.ts",
146
+ "import": "./dist/v1/icons/action/filter.js"
147
+ },
148
+ "./v1/icons/action/retry": {
149
+ "types": "./dist/src/components/v1/icons/action/RetryIcon.d.ts",
150
+ "import": "./dist/v1/icons/action/retry.js"
151
+ },
152
+ "./v1/icons/action/sorting": {
153
+ "types": "./dist/src/components/v1/icons/action/SortingIcon.d.ts",
154
+ "import": "./dist/v1/icons/action/sorting.js"
155
+ },
156
+ "./v1/icons/static/close": {
157
+ "types": "./dist/src/components/v1/icons/static/CloseIcon.d.ts",
158
+ "import": "./dist/v1/icons/static/close.js"
159
+ },
160
+ "./v1/icons/static/delete": {
161
+ "types": "./dist/src/components/v1/icons/static/DeleteIcon.d.ts",
162
+ "import": "./dist/v1/icons/static/delete.js"
163
+ },
164
+ "./v1/icons/static/recent": {
165
+ "types": "./dist/src/components/v1/icons/static/RecentIcon.d.ts",
166
+ "import": "./dist/v1/icons/static/recent.js"
167
+ },
168
+ "./v1/icons/static/report": {
169
+ "types": "./dist/src/components/v1/icons/static/ReportIcon.d.ts",
170
+ "import": "./dist/v1/icons/static/report.js"
171
+ },
172
+ "./v1/icons/static/shield-done": {
173
+ "types": "./dist/src/components/v1/icons/static/ShieldDoneIcon.d.ts",
174
+ "import": "./dist/v1/icons/static/shield-done.js"
84
175
  },
85
176
  "./package.json": "./package.json",
86
177
  "./dist/*": "./dist/*",